Fix rendering issues of subsurfaces by using proper clipping

Summary:
Rendering subsurfaces in the OpenGL compositor has always resulted in
flickering when a subsurface gets repainted and there is a window on top
of it. Looking at the code this is rather obvious: the clipping of the
main window is ignored and the complete subsurface is rendered as is and
thus also rendering above windows where it should not render.

This change passes the clip region and whether hardware clipping is used
to the rendering of subsurfaces which in turn uses it for rendering the
texture.

BUG: 385924
FIXED-IN: 5.11.3

Test Plan:
Opened systemsettings, went to decoration KCM, put a window
partially above and scrolled. Without change: strong flicker, with change:
no flicker.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D8369
This commit is contained in:
Martin Flöser 2017-10-19 21:06:11 +02:00
parent 644f595df6
commit d71792378e

View file

@ -1510,7 +1510,7 @@ QMatrix4x4 SceneOpenGL2Window::modelViewProjectionMatrix(int mask, const WindowP
return scene->projectionMatrix() * mvMatrix;
}
static void renderSubSurface(GLShader *shader, const QMatrix4x4 &mvp, const QMatrix4x4 &windowMatrix, OpenGLWindowPixmap *pixmap)
static void renderSubSurface(GLShader *shader, const QMatrix4x4 &mvp, const QMatrix4x4 &windowMatrix, OpenGLWindowPixmap *pixmap, const QRegion &region, bool hardwareClipping)
{
QMatrix4x4 newWindowMatrix = windowMatrix;
newWindowMatrix.translate(pixmap->subSurface()->position().x(), pixmap->subSurface()->position().y());
@ -1525,7 +1525,7 @@ static void renderSubSurface(GLShader *shader, const QMatrix4x4 &mvp, const QMat
shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp * newWindowMatrix);
auto texture = pixmap->texture();
texture->bind();
texture->render(QRegion(), QRect(0, 0, texture->width() / scale, texture->height() / scale));
texture->render(region, QRect(0, 0, texture->width() / scale, texture->height() / scale), hardwareClipping);
texture->unbind();
}
@ -1534,7 +1534,7 @@ static void renderSubSurface(GLShader *shader, const QMatrix4x4 &mvp, const QMat
if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) {
continue;
}
renderSubSurface(shader, mvp, newWindowMatrix, static_cast<OpenGLWindowPixmap*>(pixmap));
renderSubSurface(shader, mvp, newWindowMatrix, static_cast<OpenGLWindowPixmap*>(pixmap), region, hardwareClipping);
}
}
@ -1677,7 +1677,7 @@ void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData
if (pixmap->subSurface().isNull() || pixmap->subSurface()->surface().isNull() || !pixmap->subSurface()->surface()->isMapped()) {
continue;
}
renderSubSurface(shader, modelViewProjection, windowMatrix, static_cast<OpenGLWindowPixmap*>(pixmap));
renderSubSurface(shader, modelViewProjection, windowMatrix, static_cast<OpenGLWindowPixmap*>(pixmap), region, m_hardwareClipping);
}
if (!data.shader)