Fix scissoring of VBO rendering in multi-screen setup on Wayland
Summary: On Wayland in multi-screen a "window" is used to render to per screen. In OpenGL every "window" is at 0/0 and scissoring is in respect to the window geometry. The rendering geometry passed to VBO rendering, which performs the scissoring, is in virtual combined screen geometry space. Thus the scissoring always removes any rendering on the second screen. This results in e.g. wobbly windows not working on any additional screen on Wayland. This change makes the VBO rendering multi-screen aware by passing the current virtual window geometry in each rendering pass. That replaces the so far used virtual screen size. For single screen rendering or multi-screen rendering on X11 this doesn't change anything as there is always only one OpenGL window and the screen geoemetry starts at 0/0. Thus the subtracting of x/y geometry do not affect the scissoring at all. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D2955
This commit is contained in:
parent
196ac5eb38
commit
ff6e042c7f
3 changed files with 19 additions and 5 deletions
|
@ -2022,6 +2022,7 @@ GLvoid *GLVertexBufferPrivate::mapNextFreeRange(size_t size)
|
|||
// GLVertexBuffer
|
||||
//*********************************
|
||||
QSize GLVertexBuffer::s_virtualScreenSize;
|
||||
QRect GLVertexBuffer::s_virtualScreenGeometry;
|
||||
|
||||
GLVertexBuffer::GLVertexBuffer(UsageHint hint)
|
||||
: d(new GLVertexBufferPrivate(hint))
|
||||
|
@ -2195,7 +2196,7 @@ void GLVertexBuffer::draw(const QRegion ®ion, GLenum primitiveMode, int first
|
|||
} else {
|
||||
// Clip using scissoring
|
||||
foreach (const QRect &r, region.rects()) {
|
||||
glScissor(r.x(), s_virtualScreenSize.height() - r.y() - r.height(), r.width(), r.height());
|
||||
glScissor(r.x() - s_virtualScreenGeometry.x(), s_virtualScreenGeometry.height() - s_virtualScreenGeometry.y() - r.y() - r.height(), r.width(), r.height());
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, nullptr, first);
|
||||
}
|
||||
}
|
||||
|
@ -2207,7 +2208,7 @@ void GLVertexBuffer::draw(const QRegion ®ion, GLenum primitiveMode, int first
|
|||
} else {
|
||||
// Clip using scissoring
|
||||
foreach (const QRect &r, region.rects()) {
|
||||
glScissor(r.x(), s_virtualScreenSize.height() - r.y() - r.height(), r.width(), r.height());
|
||||
glScissor(r.x() - s_virtualScreenGeometry.x(), s_virtualScreenGeometry.height() - s_virtualScreenGeometry.y() - r.y() - r.height(), r.width(), r.height());
|
||||
glDrawArrays(primitiveMode, first, count);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -756,14 +756,27 @@ public:
|
|||
/**
|
||||
* Sets the virtual screen size to @p s.
|
||||
* @since 5.2
|
||||
* @deprecated since 5.9 use setVirtualScreenGeometry
|
||||
**/
|
||||
static void setVirtualScreenSize(const QSize &s) {
|
||||
static void KWINGLUTILS_DEPRECATED setVirtualScreenSize(const QSize &s) {
|
||||
s_virtualScreenSize = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the virtual screen geometry to @p g.
|
||||
* This is the geometry of the OpenGL window currently being rendered to
|
||||
* in the virtual geometry space the rendering geometries use.
|
||||
* @since 5.9
|
||||
**/
|
||||
static void setVirtualScreenGeometry(const QRect &g) {
|
||||
s_virtualScreenGeometry = g;
|
||||
}
|
||||
|
||||
private:
|
||||
GLVertexBufferPrivate* const d;
|
||||
// TODO: remove with next ABI break
|
||||
static QSize s_virtualScreenSize;
|
||||
static QRect s_virtualScreenGeometry;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -699,6 +699,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
|
|||
QRegion valid;
|
||||
// prepare rendering makes context current on the output
|
||||
QRegion repaint = m_backend->prepareRenderingForScreen(i);
|
||||
GLVertexBuffer::setVirtualScreenGeometry(geo);
|
||||
|
||||
const GLenum status = glGetGraphicsResetStatus();
|
||||
if (status != GL_NO_ERROR) {
|
||||
|
@ -725,6 +726,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
|
|||
handleGraphicsReset(status);
|
||||
return 0;
|
||||
}
|
||||
GLVertexBuffer::setVirtualScreenGeometry(screens()->geometry());
|
||||
|
||||
int mask = 0;
|
||||
updateProjectionMatrix();
|
||||
|
@ -919,7 +921,6 @@ void SceneOpenGL::screenGeometryChanged(const QSize &size)
|
|||
glViewport(0,0, size.width(), size.height());
|
||||
m_backend->screenGeometryChanged(size);
|
||||
GLRenderTarget::setVirtualScreenSize(size);
|
||||
GLVertexBuffer::setVirtualScreenSize(size);
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data)
|
||||
|
@ -1009,7 +1010,6 @@ SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend, QObject *parent)
|
|||
|
||||
const QSize &s = screens()->size();
|
||||
GLRenderTarget::setVirtualScreenSize(s);
|
||||
GLVertexBuffer::setVirtualScreenSize(s);
|
||||
|
||||
// push one shader on the stack so that one is always bound
|
||||
ShaderManager::instance()->pushShader(ShaderTrait::MapTexture);
|
||||
|
|
Loading…
Reference in a new issue