From c25b2939b125c05f293bb5f17b1f6a49f795b1fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= <fredrik@kde.org>
Date: Thu, 21 Nov 2013 10:39:29 +0100
Subject: [PATCH] kwin: Prepare the backend interface for EXT_buffer_age

Allow prepareRenderingFrame() to return a region that will be
repainted in addition to the damaged region.

Pass both the damaged region and the repainted region, which
may be larger, as parameters to endRenderingFrame().
---
 egl_wayland_backend.cpp |  9 ++++++---
 egl_wayland_backend.h   |  4 ++--
 eglonxbackend.cpp       |  9 ++++++---
 eglonxbackend.h         |  4 ++--
 glxbackend.cpp          |  8 +++++---
 glxbackend.h            |  4 ++--
 scene_opengl.cpp        |  2 +-
 scene_opengl.h          | 13 ++++++++++---
 8 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/egl_wayland_backend.cpp b/egl_wayland_backend.cpp
index 32dd2ee872..b229cdd841 100644
--- a/egl_wayland_backend.cpp
+++ b/egl_wayland_backend.cpp
@@ -816,17 +816,20 @@ SceneOpenGL::TexturePrivate *EglWaylandBackend::createBackendTexture(SceneOpenGL
     return new EglWaylandTexture(texture, this);
 }
 
-void EglWaylandBackend::prepareRenderingFrame()
+QRegion EglWaylandBackend::prepareRenderingFrame()
 {
     if (!lastDamage().isEmpty())
         present();
+
     eglWaitNative(EGL_CORE_NATIVE_ENGINE);
     startRenderTimer();
+
+    return QRegion();
 }
 
-void EglWaylandBackend::endRenderingFrame(const QRegion &damage)
+void EglWaylandBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
 {
-    setLastDamage(damage);
+    setLastDamage(renderedRegion);
     glFlush();
 }
 
diff --git a/egl_wayland_backend.h b/egl_wayland_backend.h
index 66519372f9..719da4b6e5 100644
--- a/egl_wayland_backend.h
+++ b/egl_wayland_backend.h
@@ -264,8 +264,8 @@ public:
     virtual ~EglWaylandBackend();
     virtual void screenGeometryChanged(const QSize &size);
     virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture);
-    virtual void prepareRenderingFrame();
-    virtual void endRenderingFrame(const QRegion &damage);
+    virtual QRegion prepareRenderingFrame();
+    virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion);
     Shm *shm();
 
 protected:
diff --git a/eglonxbackend.cpp b/eglonxbackend.cpp
index e28945e501..08762c5967 100644
--- a/eglonxbackend.cpp
+++ b/eglonxbackend.cpp
@@ -320,7 +320,7 @@ SceneOpenGL::TexturePrivate *EglOnXBackend::createBackendTexture(SceneOpenGL::Te
     return new EglTexture(texture, this);
 }
 
-void EglOnXBackend::prepareRenderingFrame()
+QRegion EglOnXBackend::prepareRenderingFrame()
 {
     if (gs_tripleBufferNeedsDetection) {
         // the composite timer floors the repaint frequency. This can pollute our triple buffering
@@ -330,14 +330,17 @@ void EglOnXBackend::prepareRenderingFrame()
         // fllush the buffer queue
         usleep(1000);
     }
+
     present();
     startRenderTimer();
     eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+
+    return QRegion();
 }
 
-void EglOnXBackend::endRenderingFrame(const QRegion &damage)
+void EglOnXBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
 {
-    setLastDamage(damage);
+    setLastDamage(renderedRegion);
 
     if (!blocksForRetrace()) {
         // This also sets lastDamage to empty which prevents the frame from
diff --git a/eglonxbackend.h b/eglonxbackend.h
index 9283fbe570..60ac553857 100644
--- a/eglonxbackend.h
+++ b/eglonxbackend.h
@@ -34,8 +34,8 @@ public:
     virtual ~EglOnXBackend();
     virtual void screenGeometryChanged(const QSize &size);
     virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture);
-    virtual void prepareRenderingFrame();
-    virtual void endRenderingFrame(const QRegion &damage);
+    virtual QRegion prepareRenderingFrame();
+    virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion);
 
 protected:
     virtual void present();
diff --git a/glxbackend.cpp b/glxbackend.cpp
index 70973b2917..96f6817a84 100644
--- a/glxbackend.cpp
+++ b/glxbackend.cpp
@@ -493,7 +493,7 @@ SceneOpenGL::TexturePrivate *GlxBackend::createBackendTexture(SceneOpenGL::Textu
     return new GlxTexture(texture, this);
 }
 
-void GlxBackend::prepareRenderingFrame()
+QRegion GlxBackend::prepareRenderingFrame()
 {
     if (gs_tripleBufferNeedsDetection) {
         // the composite timer floors the repaint frequency. This can pollute our triple buffering
@@ -506,11 +506,13 @@ void GlxBackend::prepareRenderingFrame()
     present();
     startRenderTimer();
     glXWaitX();
+
+    return QRegion();
 }
 
-void GlxBackend::endRenderingFrame(const QRegion &damage)
+void GlxBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
 {
-    setLastDamage(damage);
+    setLastDamage(renderedRegion);
 
     if (!blocksForRetrace()) {
         // This also sets lastDamage to empty which prevents the frame from
diff --git a/glxbackend.h b/glxbackend.h
index 11b907966f..ce3b3f4dee 100644
--- a/glxbackend.h
+++ b/glxbackend.h
@@ -44,8 +44,8 @@ public:
     virtual ~GlxBackend();
     virtual void screenGeometryChanged(const QSize &size);
     virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture);
-    virtual void prepareRenderingFrame();
-    virtual void endRenderingFrame(const QRegion &damage);
+    virtual QRegion prepareRenderingFrame();
+    virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion);
 
 protected:
     virtual void present();
diff --git a/scene_opengl.cpp b/scene_opengl.cpp
index a1bf789fd7..f3fdfbb0e1 100644
--- a/scene_opengl.cpp
+++ b/scene_opengl.cpp
@@ -372,7 +372,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
     checkGLError("Paint2");
 #endif
 
-    m_backend->endRenderingFrame(damage);
+    m_backend->endRenderingFrame(damage, damage);
 
     // do cleanup
     stacking_order.clear();
diff --git a/scene_opengl.h b/scene_opengl.h
index 699c8f2115..baad5dd958 100644
--- a/scene_opengl.h
+++ b/scene_opengl.h
@@ -461,21 +461,28 @@ public:
     }
     virtual void screenGeometryChanged(const QSize &size) = 0;
     virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture) = 0;
+
     /**
      * @brief Backend specific code to prepare the rendering of a frame including flushing the
      * previously rendered frame to the screen if the backend works this way.
+     *
+     * @return A region that if not empty will be repainted in addition to the damaged region
      **/
-    virtual void prepareRenderingFrame() = 0;
+    virtual QRegion prepareRenderingFrame() = 0;
+
     /**
      * @brief Backend specific code to handle the end of rendering a frame.
      *
-     * @param damage The actual updated region in this frame
+     * @param renderedRegion The possibly larger region that has been rendered
+     * @param damagedRegion The damaged region that should be posted
      **/
-    virtual void endRenderingFrame(const QRegion &damage) = 0;
+    virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) = 0;
+
     /**
      * @brief Compositor is going into idle mode, flushes any pending paints.
      **/
     void idle();
+
     /**
      * @return bool Whether the scene needs to flush a frame.
      **/