From 2570e9ec61a00461520aa6434ca4371e442434b5 Mon Sep 17 00:00:00 2001 From: "Pierre-Loup A. Griffais" Date: Sun, 16 Oct 2011 01:09:16 -0700 Subject: [PATCH] kwin-gles: add support for EGL_NV_post_sub_buffer The EGL path had no support for presenting sub-regions of the screen, we can leverage EGL_NV_post_sub_buffer for that. This wouldn't be a win if we didn't have to opt-out of flipping. REVIEW: 102889 --- libkwineffects/kwinglutils_funcs.cpp | 7 +++++++ libkwineffects/kwinglutils_funcs.h | 2 ++ scene_opengl_egl.cpp | 10 +++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/libkwineffects/kwinglutils_funcs.cpp b/libkwineffects/kwinglutils_funcs.cpp index 33c8c7c9dd..0c66dc148e 100644 --- a/libkwineffects/kwinglutils_funcs.cpp +++ b/libkwineffects/kwinglutils_funcs.cpp @@ -296,6 +296,7 @@ namespace KWin // EGL eglCreateImageKHR_func eglCreateImageKHR; eglDestroyImageKHR_func eglDestroyImageKHR; +eglPostSubBufferNV_func eglPostSubBufferNV; // GLES glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOES; @@ -310,6 +311,12 @@ void eglResolveFunctions() eglCreateImageKHR = NULL; eglDestroyImageKHR = NULL; } + + if (hasGLExtension("EGL_NV_post_sub_buffer")) { + eglPostSubBufferNV = (eglPostSubBufferNV_func)eglGetProcAddress("eglPostSubBufferNV"); + } else { + eglPostSubBufferNV = NULL; + } } void glResolveFunctions() diff --git a/libkwineffects/kwinglutils_funcs.h b/libkwineffects/kwinglutils_funcs.h index 2f5829c09d..cbd40fc1dd 100644 --- a/libkwineffects/kwinglutils_funcs.h +++ b/libkwineffects/kwinglutils_funcs.h @@ -358,8 +358,10 @@ void KWIN_EXPORT glResolveFunctions(); // EGL typedef EGLImageKHR(*eglCreateImageKHR_func)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*); typedef EGLBoolean(*eglDestroyImageKHR_func)(EGLDisplay, EGLImageKHR); +typedef EGLBoolean (*eglPostSubBufferNV_func)(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); extern KWIN_EXPORT eglCreateImageKHR_func eglCreateImageKHR; extern KWIN_EXPORT eglDestroyImageKHR_func eglDestroyImageKHR; +extern KWIN_EXPORT eglPostSubBufferNV_func eglPostSubBufferNV; // GLES typedef GLvoid(*glEGLImageTargetTexture2DOES_func)(GLenum, GLeglImageOES); diff --git a/scene_opengl_egl.cpp b/scene_opengl_egl.cpp index c3fa845491..09a6feded9 100644 --- a/scene_opengl_egl.cpp +++ b/scene_opengl_egl.cpp @@ -26,6 +26,7 @@ EGLDisplay dpy; EGLConfig config; EGLSurface surface; EGLContext ctx; +int surfaceHasSubPost; SceneOpenGL::SceneOpenGL(Workspace* ws) : Scene(ws) @@ -108,6 +109,8 @@ bool SceneOpenGL::initRenderingContext() eglSurfaceAttrib(dpy, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); + eglQuerySurface(dpy, surface, EGL_POST_SUB_BUFFER_SUPPORTED_NV, &surfaceHasSubPost); + const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE @@ -200,9 +203,10 @@ void SceneOpenGL::flushBuffer(int mask, QRegion damage) { Q_UNUSED(damage) glFlush(); - if (mask & PAINT_SCREEN_REGION) { - // TODO: implement me properly - eglSwapBuffers(dpy, surface); + if (mask & PAINT_SCREEN_REGION && surfaceHasSubPost && eglPostSubBufferNV) { + QRect damageRect = damage.boundingRect(); + + eglPostSubBufferNV(dpy, surface, damageRect.left(), displayHeight() - damageRect.bottom() - 1, damageRect.width(), damageRect.height()); } else { eglSwapBuffers(dpy, surface); }