From cd82616ecebd66b59d22915847137536c02cc7e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sun, 26 Jun 2011 12:01:13 +0200 Subject: [PATCH] Remove PaintClipper from OpenGL Scene rendering Construct window quads which will end on the screen instead of rendering the windows several times and using scissoring to restrict to the area which will end on screen. REVIEW: 101765 --- libkwineffects/kwinglutils.cpp | 34 +++++---------------------- scene_opengl.cpp | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/libkwineffects/kwinglutils.cpp b/libkwineffects/kwinglutils.cpp index 3e5121e9ff..f8a6058eb8 100644 --- a/libkwineffects/kwinglutils.cpp +++ b/libkwineffects/kwinglutils.cpp @@ -1073,9 +1073,9 @@ GLVertexBuffer *GLVertexBufferPrivate::streamingBuffer = NULL; void GLVertexBufferPrivate::legacyPainting(QRegion region, GLenum primitiveMode) { #ifdef KWIN_HAVE_OPENGLES - Q_UNUSED(region) Q_UNUSED(primitiveMode) #else + Q_UNUSED(region) // Enable arrays glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(dimension, GL_FLOAT, 0, legacyVertices.constData()); @@ -1088,15 +1088,7 @@ void GLVertexBufferPrivate::legacyPainting(QRegion region, GLenum primitiveMode) glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF()); } - // Clip using scissoring - if (region != infiniteRegion()) { - PaintClipper pc(region); - for (PaintClipper::Iterator iterator; !iterator.isDone(); iterator.next()) { - glDrawArrays(primitiveMode, 0, numberVertices); - } - } else { - glDrawArrays(primitiveMode, 0, numberVertices); - } + glDrawArrays(primitiveMode, 0, numberVertices); glDisableClientState(GL_VERTEX_ARRAY); if (!legacyTexCoords.isEmpty()) { @@ -1107,6 +1099,7 @@ void GLVertexBufferPrivate::legacyPainting(QRegion region, GLenum primitiveMode) void GLVertexBufferPrivate::corePainting(const QRegion& region, GLenum primitiveMode) { + Q_UNUSED(region) GLShader *shader = ShaderManager::instance()->getBoundShader(); GLint vertexAttrib = shader->attributeLocation("vertex"); GLint texAttrib = shader->attributeLocation("texCoord"); @@ -1128,15 +1121,7 @@ void GLVertexBufferPrivate::corePainting(const QRegion& region, GLenum primitive glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); } - // Clip using scissoring - if (region != infiniteRegion()) { - PaintClipper pc(region); - for (PaintClipper::Iterator iterator; !iterator.isDone(); iterator.next()) { - glDrawArrays(primitiveMode, 0, numberVertices); - } - } else { - glDrawArrays(primitiveMode, 0, numberVertices); - } + glDrawArrays(primitiveMode, 0, numberVertices); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -1149,9 +1134,9 @@ void GLVertexBufferPrivate::corePainting(const QRegion& region, GLenum primitive void GLVertexBufferPrivate::fallbackPainting(const QRegion& region, GLenum primitiveMode) { #ifdef KWIN_HAVE_OPENGLES - Q_UNUSED(region) Q_UNUSED(primitiveMode) #else + Q_UNUSED(region) glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, buffers[ 0 ]); @@ -1165,14 +1150,7 @@ void GLVertexBufferPrivate::fallbackPainting(const QRegion& region, GLenum primi } // Clip using scissoring - if (region != infiniteRegion()) { - PaintClipper pc(region); - for (PaintClipper::Iterator iterator; !iterator.isDone(); iterator.next()) { - glDrawArrays(primitiveMode, 0, numberVertices); - } - } else { - glDrawArrays(primitiveMode, 0, numberVertices); - } + glDrawArrays(primitiveMode, 0, numberVertices); glBindBuffer(GL_ARRAY_BUFFER, 0); diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 5464e318b5..0f83d2c8a6 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -476,6 +476,49 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData if (region.isEmpty()) return; + if (region != infiniteRegion() && !(mask & PAINT_WINDOW_TRANSFORMED)) { + WindowQuadList quads; + const QRegion filterRegion = region.translated(-x(), -y()); + const QRectF bounding = QRectF(filterRegion.boundingRect()); + // first step: split all quads according to the bounding rect + foreach (const WindowQuad &quad, data.quads) { + const QRectF quadRect(QPointF(quad.left(), quad.top()), QPointF(quad.right(), quad.bottom())); + // case 1: completely contains + if (bounding.contains(quadRect)) { + quads << quad; + continue; + } + // case 2: intersection + if (bounding.intersects(quadRect)) { + const QRectF intersected = bounding.intersected(quadRect); + quads << quad.makeSubQuad(intersected.left(), intersected.top(), intersected.right(), intersected.bottom()); + } + } + if (filterRegion.numRects() > 1) { + // second step: split all quads in bounding rect with the actual rects in the region + WindowQuadList tempList; + foreach (const WindowQuad &quad, quads) { + foreach (const QRect &r, filterRegion.rects()) { + const QRectF rf(r); + const QRectF quadRect(QPointF(quad.left(), quad.top()), QPointF(quad.right(), quad.bottom())); + // case 1: completely contains, include and do not check other rects + if (rf.contains(quadRect)) { + tempList << quad; + break; + } + // case 2: intersection + if (rf.intersects(quadRect)) { + const QRectF intersected = rf.intersected(quadRect); + tempList << quad.makeSubQuad(intersected.left(), intersected.top(), intersected.right(), intersected.bottom()); + } + } + } + data.quads = tempList; + } else { + data.quads = quads; + } + } + if (!bindTexture()) return;