diff --git a/resources.qrc b/resources.qrc
index 2c73d4d9d0..4ddc63a92d 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -4,5 +4,6 @@
lanczos-fragment.glsl
scene-vertex.glsl
scene-fragment.glsl
+ scene-generic-vertex.glsl
diff --git a/scene-generic-vertex.glsl b/scene-generic-vertex.glsl
new file mode 100644
index 0000000000..d05062cb70
--- /dev/null
+++ b/scene-generic-vertex.glsl
@@ -0,0 +1,19 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+uniform mat4 projection;
+uniform mat4 modelview;
+uniform mat4 windowTransformation;
+
+// passed in vertex - only x and y are used
+attribute vec4 vertex;
+// passed in texCoords - to be forwarded
+attribute vec2 texCoord;
+
+// texCoords passed to fragment shader
+varying vec2 varyingTexCoords;
+
+void main() {
+ varyingTexCoords = texCoord;
+ gl_Position = vertex*(windowTransformation*modelview)*projection;
+}
diff --git a/scene_opengl.cpp b/scene_opengl.cpp
index 7fb95aa2fa..c957fc8c57 100644
--- a/scene_opengl.cpp
+++ b/scene_opengl.cpp
@@ -92,6 +92,7 @@ Sources and other compositing managers:
#include
#include
#include
+#include
namespace KWin
{
@@ -115,6 +116,59 @@ XShmSegmentInfo SceneOpenGL::shm;
#include "scene_opengl_glx.cpp"
#endif
+
+bool SceneOpenGL::setupSceneShaders()
+{
+ m_sceneShader = new GLShader(":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl");
+ if (m_sceneShader->isValid()) {
+ m_sceneShader->bind();
+ m_sceneShader->setUniform("sample", 0);
+ m_sceneShader->setUniform("displaySize", QVector2D(displayWidth(), displayHeight()));
+ m_sceneShader->setUniform("debug", debug ? 1 : 0);
+ m_sceneShader->unbind();
+ kDebug(1212) << "Scene Shader is valid";
+ }
+ else {
+ delete m_sceneShader;
+ m_sceneShader = NULL;
+ kDebug(1212) << "Scene Shader is not valid";
+ return false;
+ }
+ m_genericSceneShader = new GLShader( ":/resources/scene-generic-vertex.glsl", ":/resources/scene-fragment.glsl" );
+ if (m_genericSceneShader->isValid()) {
+ m_genericSceneShader->bind();
+ m_genericSceneShader->setUniform("sample", 0);
+ m_genericSceneShader->setUniform("debug", debug ? 1 : 0);
+ QMatrix4x4 projection;
+ float fovy = 60.0f;
+ float aspect = 1.0f;
+ float zNear = 0.1f;
+ float zFar = 100.0f;
+ float ymax = zNear * tan(fovy * M_PI / 360.0f);
+ float ymin = -ymax;
+ float xmin = ymin * aspect;
+ float xmax = ymax * aspect;
+ projection.frustum(xmin, xmax, ymin, ymax, zNear, zFar);
+ m_genericSceneShader->setUniform("projection", projection);
+ QMatrix4x4 modelview;
+ float scaleFactor = 1.1 * tan( fovy * M_PI / 360.0f )/ymax;
+ modelview.translate(xmin*scaleFactor, ymax*scaleFactor, -1.1);
+ modelview.scale((xmax-xmin)*scaleFactor/displayWidth(), -(ymax-ymin)*scaleFactor/displayHeight(), 0.001);
+ m_genericSceneShader->setUniform("modelview", modelview);
+ m_genericSceneShader->unbind();
+ kDebug(1212) << "Generic Scene Shader is valid";
+ }
+ else {
+ delete m_genericSceneShader;
+ m_genericSceneShader = NULL;
+ delete m_sceneShader;
+ m_sceneShader = NULL;
+ kDebug(1212) << "Generic Scene Shader is not valid";
+ return false;
+ }
+ return true;
+}
+
bool SceneOpenGL::initFailed() const
{
return !init_ok;
@@ -458,20 +512,51 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
int y = toplevel->y();
double z = 0.0;
bool sceneShader = false;
- if( !data.shader && !( mask & PAINT_WINDOW_TRANSFORMED ) && !( mask & PAINT_SCREEN_TRANSFORMED ) )
- {
+ if (!data.shader) {
// set the shader for uniform initialising in paint decoration
- data.shader = static_cast(scene)->m_sceneShader;
- sceneShader = true;
- data.shader->bind();
- data.shader->setUniform("geometry", QVector4D(x, y, toplevel->width(), toplevel->height()));
+ if ((mask & PAINT_WINDOW_TRANSFORMED) || (mask & PAINT_SCREEN_TRANSFORMED)) {
+ data.shader = static_cast(scene)->m_genericSceneShader;
+ data.shader->bind();
+ } else {
+ data.shader = static_cast(scene)->m_sceneShader;
+ data.shader->bind();
+ data.shader->setUniform("geometry", QVector4D(x, y, toplevel->width(), toplevel->height()));
}
- if( mask & PAINT_WINDOW_TRANSFORMED )
- {
+ sceneShader = true;
+ }
+ if (mask & PAINT_WINDOW_TRANSFORMED) {
x += data.xTranslate;
y += data.yTranslate;
z += data.zTranslate;
+ QMatrix4x4 windowTransformation;
+ windowTransformation.translate(x, y, z);
+ if ((mask & PAINT_WINDOW_TRANSFORMED ) && ( data.xScale != 1 || data.yScale != 1 || data.zScale != 1)) {
+ windowTransformation.scale(data.xScale, data.yScale, data.zScale);
}
+ if ((mask & PAINT_WINDOW_TRANSFORMED) && data.rotation) {
+ windowTransformation.translate(data.rotation->xRotationPoint, data.rotation->yRotationPoint, data.rotation->zRotationPoint);
+ qreal xAxis = 0.0;
+ qreal yAxis = 0.0;
+ qreal zAxis = 0.0;
+ switch( data.rotation->axis )
+ {
+ case RotationData::XAxis:
+ xAxis = 1.0;
+ break;
+ case RotationData::YAxis:
+ yAxis = 1.0;
+ break;
+ case RotationData::ZAxis:
+ zAxis = 1.0;
+ break;
+ }
+ windowTransformation.rotate(data.rotation->angle, xAxis, yAxis, zAxis);
+ windowTransformation.translate(-data.rotation->xRotationPoint, -data.rotation->yRotationPoint, -data.rotation->zRotationPoint);
+ }
+ if (sceneShader) {
+ data.shader->setUniform("windowTransformation", windowTransformation);
+ }
+ }
if( !sceneShader )
{
#ifndef KWIN_HAVE_OPENGLES
diff --git a/scene_opengl.h b/scene_opengl.h
index b47b745fd7..690db41f71 100644
--- a/scene_opengl.h
+++ b/scene_opengl.h
@@ -69,6 +69,7 @@ class SceneOpenGL
bool selfCheck();
void selfCheckSetup();
bool selfCheckFinish();
+ bool setupSceneShaders();
GC gcroot;
class FBConfigInfo
{
@@ -104,6 +105,7 @@ class SceneOpenGL
bool init_ok;
bool selfCheckDone;
GLShader* m_sceneShader;
+ GLShader* m_genericSceneShader;
bool debug;
};
diff --git a/scene_opengl_egl.cpp b/scene_opengl_egl.cpp
index febc7a28c6..c76fd1a0be 100644
--- a/scene_opengl_egl.cpp
+++ b/scene_opengl_egl.cpp
@@ -32,30 +32,18 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
, init_ok( false )
, selfCheckDone( true )
, m_sceneShader( NULL )
+ , m_genericSceneShader( NULL )
{
if( !initRenderingContext() )
return;
initGL();
debug = qstrcmp( qgetenv( "KWIN_GL_DEBUG" ), "1" ) == 0;
-
- m_sceneShader = new GLShader( ":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl" );
- if( m_sceneShader->isValid() )
- {
- m_sceneShader->bind();
- m_sceneShader->setUniform( "sample", 0 );
- m_sceneShader->setUniform( "displaySize", QVector2D(displayWidth(), displayHeight()));
- m_sceneShader->setUniform( "debug", debug ? 1 : 0 );
- m_sceneShader->unbind();
- kDebug(1212) << "Scene Shader is valid";
- }
- else
- {
- delete m_sceneShader;
- m_sceneShader = NULL;
- kDebug(1212) << "Scene Shader is not valid";
+ if (!setupSceneShaders()) {
+ kError( 1212 ) << "Shaders not valid, ES compositing not possible";
return;
- }
+ }
+
if( checkGLError( "Init" ))
{
diff --git a/scene_opengl_glx.cpp b/scene_opengl_glx.cpp
index 0a237a9124..3a559c95f0 100644
--- a/scene_opengl_glx.cpp
+++ b/scene_opengl_glx.cpp
@@ -40,6 +40,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
, init_ok( false )
, selfCheckDone( false )
, m_sceneShader( NULL )
+ , m_genericSceneShader( NULL )
{
if( !Extensions::glxAvailable())
{
@@ -99,24 +100,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
GLPlatform::instance()->detect();
if( GLPlatform::instance()->supports( GLSL ) )
{
- m_sceneShader = new GLShader( ":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl" );
- if( m_sceneShader->isValid() )
- {
- m_sceneShader->bind();
- m_sceneShader->setUniform( "sample", 0 );
- m_sceneShader->setUniform( "displaySize", QVector2D(displayWidth(), displayHeight()));
- m_sceneShader->setUniform( "debug", debug ? 1 : 0 );
- m_sceneShader->bindAttributeLocation( 0, "vertex" );
- m_sceneShader->bindAttributeLocation( 1, "texCoord" );
- m_sceneShader->unbind();
- kDebug(1212) << "Scene Shader is valid";
- }
- else
- {
- delete m_sceneShader;
- m_sceneShader = NULL;
- kDebug(1212) << "Scene Shader is not valid";
- }
+ setupSceneShader();
}
// OpenGL scene setup