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
This commit is contained in:
Martin Gräßlin 2011-06-26 12:01:13 +02:00
parent bb8b92f93d
commit cd82616ece
2 changed files with 49 additions and 28 deletions

View file

@ -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);

View file

@ -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;