From 4e9a1eeb5036efeb27e3a98ba706ff8fc9225529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 14 Oct 2016 15:29:50 +0200 Subject: [PATCH] Fix glBlitFramebuffer for per-output rendering Summary: This is similar to ff6e042c7f9617004fefe63dd657fc2abf374c15 just for GLRenderTarget instead of GLVertexBuffer. The reasoning is the same: on Wayland KWin has one native window per screen and needs to adjust the blit target depending on the area. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D3056 --- libkwineffects/kwinglutils.cpp | 6 ++++-- libkwineffects/kwinglutils.h | 11 +++++++++++ scene_opengl.cpp | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libkwineffects/kwinglutils.cpp b/libkwineffects/kwinglutils.cpp index 271461c4c4..3a9c344d1a 100644 --- a/libkwineffects/kwinglutils.cpp +++ b/libkwineffects/kwinglutils.cpp @@ -1129,6 +1129,7 @@ bool GLRenderTarget::sSupported = false; bool GLRenderTarget::s_blitSupported = false; QStack GLRenderTarget::s_renderTargets = QStack(); QSize GLRenderTarget::s_virtualScreenSize; +QRect GLRenderTarget::s_virtualScreenGeometry; void GLRenderTarget::initStatic() { @@ -1327,10 +1328,11 @@ void GLRenderTarget::blitFromFramebuffer(const QRect &source, const QRect &desti GLRenderTarget::pushRenderTarget(this); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - const QRect s = source.isNull() ? QRect(0, 0, s_virtualScreenSize.width(), s_virtualScreenSize.height()) : source; + const QRect s = source.isNull() ? s_virtualScreenGeometry : source; const QRect d = destination.isNull() ? QRect(0, 0, mTexture.width(), mTexture.height()) : destination; - glBlitFramebuffer(s.x(), s_virtualScreenSize.height() - s.y() - s.height(), s.x() + s.width(), s_virtualScreenSize.height() - s.y(), + glBlitFramebuffer(s.x() - s_virtualScreenGeometry.x(), s_virtualScreenGeometry.height() - s_virtualScreenGeometry.y() - s.y() - s.height(), + s.x() - s_virtualScreenGeometry.x() + s.width(), s_virtualScreenGeometry.height() - s_virtualScreenGeometry.y() - s.y(), d.x(), mTexture.height() - d.y() - d.height(), d.x() + d.width(), mTexture.height() - d.y(), GL_COLOR_BUFFER_BIT, filter); GLRenderTarget::popRenderTarget(); diff --git a/libkwineffects/kwinglutils.h b/libkwineffects/kwinglutils.h index c3df01f17b..6e386a7134 100644 --- a/libkwineffects/kwinglutils.h +++ b/libkwineffects/kwinglutils.h @@ -511,6 +511,16 @@ public: 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; + } + protected: void initFBO(); @@ -523,6 +533,7 @@ private: static bool s_blitSupported; static QStack s_renderTargets; static QSize s_virtualScreenSize; + static QRect s_virtualScreenGeometry; GLTexture mTexture; bool mValid; diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 36c6fcfe27..56cebc06cc 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -700,6 +700,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) // prepare rendering makes context current on the output QRegion repaint = m_backend->prepareRenderingForScreen(i); GLVertexBuffer::setVirtualScreenGeometry(geo); + GLRenderTarget::setVirtualScreenGeometry(geo); const GLenum status = glGetGraphicsResetStatus(); if (status != GL_NO_ERROR) { @@ -727,6 +728,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) return 0; } GLVertexBuffer::setVirtualScreenGeometry(screens()->geometry()); + GLRenderTarget::setVirtualScreenGeometry(screens()->geometry()); int mask = 0; updateProjectionMatrix();