From c25b2939b125c05f293bb5f17b1f6a49f795b1fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= 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. **/