Set scale on glScissor calls

Summary:
glScissor works on window co-ordinates. i.e not scaled by the viewport
We need to multiply by the scale there.

This fixes a minor visual glitch in animations when using hardware
clipping.

Test Plan:
Hardcoded my minimise animation to be really slow.
Now every frame looks perfect

Reviewers: #kwin

Subscribers: kpiwowarski, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D8490
This commit is contained in:
David Edmundson 2017-10-26 17:15:31 +01:00
parent 019d4bf425
commit 69b2c2fcea
3 changed files with 23 additions and 2 deletions

View file

@ -1950,6 +1950,7 @@ GLvoid *GLVertexBufferPrivate::mapNextFreeRange(size_t size)
// GLVertexBuffer
//*********************************
QRect GLVertexBuffer::s_virtualScreenGeometry;
qreal GLVertexBuffer::s_virtualScreenScale;
GLVertexBuffer::GLVertexBuffer(UsageHint hint)
: d(new GLVertexBufferPrivate(hint))
@ -2123,7 +2124,10 @@ void GLVertexBuffer::draw(const QRegion &region, GLenum primitiveMode, int first
} else {
// Clip using scissoring
foreach (const QRect &r, region.rects()) {
glScissor(r.x() - s_virtualScreenGeometry.x(), s_virtualScreenGeometry.height() + s_virtualScreenGeometry.y() - r.y() - r.height(), r.width(), r.height());
glScissor((r.x() - s_virtualScreenGeometry.x()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() + s_virtualScreenGeometry.y() - r.y() - r.height()) * s_virtualScreenScale,
r.width() * s_virtualScreenScale,
r.height() * s_virtualScreenScale);
glDrawElementsBaseVertex(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, nullptr, first);
}
}
@ -2135,7 +2139,10 @@ void GLVertexBuffer::draw(const QRegion &region, GLenum primitiveMode, int first
} else {
// Clip using scissoring
foreach (const QRect &r, region.rects()) {
glScissor(r.x() - s_virtualScreenGeometry.x(), s_virtualScreenGeometry.height() + s_virtualScreenGeometry.y() - r.y() - r.height(), r.width(), r.height());
glScissor((r.x() - s_virtualScreenGeometry.x()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() + s_virtualScreenGeometry.y() - r.y() - r.height()) * s_virtualScreenScale,
r.width() * s_virtualScreenScale,
r.height() * s_virtualScreenScale);
glDrawArrays(primitiveMode, first, count);
}
}

View file

@ -775,9 +775,21 @@ public:
s_virtualScreenGeometry = g;
}
/**
* The scale of the OpenGL window currently being rendered to
*
* @returns the ratio between the virtual geometry space the rendering
* system uses and the target
* @since 5.11.3
*/
static void setVirtualScreenScale(qreal s) {
s_virtualScreenScale = s;
}
private:
GLVertexBufferPrivate* const d;
static QRect s_virtualScreenGeometry;
static qreal s_virtualScreenScale;
};
} // namespace

View file

@ -755,6 +755,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
QRegion repaint = m_backend->prepareRenderingForScreen(i);
GLVertexBuffer::setVirtualScreenGeometry(geo);
GLRenderTarget::setVirtualScreenGeometry(geo);
GLVertexBuffer::setVirtualScreenScale(screens()->scale(i));
GLRenderTarget::setVirtualScreenScale(screens()->scale(i));
const GLenum status = glGetGraphicsResetStatus();
@ -785,6 +786,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
}
GLVertexBuffer::setVirtualScreenGeometry(screens()->geometry());
GLRenderTarget::setVirtualScreenGeometry(screens()->geometry());
GLVertexBuffer::setVirtualScreenScale(1);
GLRenderTarget::setVirtualScreenScale(1);
int mask = 0;