[libkwineffects/kwinglutils] Calculate correct srcY0 and srcY1 in GLRenderTarget::blitFromFramebuffer

Summary:
There are several spaces that have to be considered in `GLRenderTarget::blitFromFramebuffer`:
* KWin logical space: the origin is located at the global top-left corner
* display space: the origin is located at the top-left corner of monitor/display
* OpenGL screen space: the origin is located at the bottom-left corner of monitor/display

Given `s`, which is in the KWin logical space, we have to transform it to the display space, then to the OpenGL screen space:

* KWin logical space -> display space: `y' = s.y() - s_virtualScreenGeometry.y()`
* display space -> OpenGL screen space: `y'' = s_virtualScreenGeometry.height() - y'`

Overall, `srcY0` and `srcY1` should be written as follows:

```
srcY0 = s_virtualScreenGeometry.height() - (s.y() - s_virtualScreenGeometry.y() + s.height())
srcY1 = s_virtualScreenGeometry.height() - (s.y() - s_virtualScreenGeometry.y())
```

Test Plan:
Tweak background contrast effect to use GLRenderTarget::blitFromFramebuffer

```
diff --git a/effects/backgroundcontrast/contrast.cpp b/effects/backgroundcontrast/contrast.cpp
index f920fcd88..5247d83b8 100644
--- a/effects/backgroundcontrast/contrast.cpp
+++ b/effects/backgroundcontrast/contrast.cpp
@@ -447,11 +447,10 @@ void ContrastEffect::doContrast(EffectWindow *w, const QRegion& shape, const QRe
     GLTexture scratch(GL_RGBA8, r.width() * scale, r.height() * scale);
     scratch.setFilter(GL_LINEAR);
     scratch.setWrapMode(GL_CLAMP_TO_EDGE);
-    scratch.bind();

-    const QRect sg = GLRenderTarget::virtualScreenGeometry();
-    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (r.x() - sg.x()) * scale, (sg.height() - sg.y() - r.y() - r.height()) * scale,
-                        scratch.width(), scratch.height());
+    GLRenderTarget scratchTarget(scratch);
+    scratchTarget.blitFromFramebuffer(r);
+    scratch.bind();

     // Draw the texture on the offscreen framebuffer object, while blurring it horizontally

```

GLRenderTarget::blitFromFramebuffer without this change:
{F5817883, layout=center, size=full}

Reviewers: #kwin, fredrik, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kpiwowarski, davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D12452
This commit is contained in:
Alex Nemeth 2018-05-29 15:21:59 +02:00 committed by David Edmundson
parent 2419c949bf
commit 982316072d

View file

@ -1301,9 +1301,9 @@ void GLRenderTarget::blitFromFramebuffer(const QRect &source, const QRect &desti
const QRect d = destination.isNull() ? QRect(0, 0, mTexture.width(), mTexture.height()) : destination;
glBlitFramebuffer((s.x() - s_virtualScreenGeometry.x()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() - s_virtualScreenGeometry.y() + s.y() - s.height()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() - (s.y() - s_virtualScreenGeometry.y() + s.height())) * s_virtualScreenScale,
(s.x() - s_virtualScreenGeometry.x() + s.width()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() - s_virtualScreenGeometry.y() + s.y()) * s_virtualScreenScale,
(s_virtualScreenGeometry.height() - (s.y() - s_virtualScreenGeometry.y())) * s_virtualScreenScale,
d.x(), mTexture.height() - d.y() - d.height(), d.x() + d.width(), mTexture.height() - d.y(),
GL_COLOR_BUFFER_BIT, filter);
GLRenderTarget::popRenderTarget();