aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Loup A. Griffais <pgriffais@nvidia.com>2011-10-16 08:09:16 (GMT)
committerMartin Gräßlin <mgraesslin@kde.org>2011-10-26 17:24:02 (GMT)
commitc8306ed8e1c220c3a49c452da43c1eb165151905 (patch)
treeadb7a9ff4036c2cd33ae3ed50328ac0d8bb6f182
parentc10419b6f85af4a6d2c7539c594abc7224535c03 (diff)
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
-rw-r--r--kwin/libkwineffects/kwinglutils_funcs.cpp7
-rw-r--r--kwin/libkwineffects/kwinglutils_funcs.h2
-rw-r--r--kwin/scene_opengl_egl.cpp10
3 files changed, 16 insertions, 3 deletions
diff --git a/kwin/libkwineffects/kwinglutils_funcs.cpp b/kwin/libkwineffects/kwinglutils_funcs.cpp
index 57cedf0..43079f4 100644
--- a/kwin/libkwineffects/kwinglutils_funcs.cpp
+++ b/kwin/libkwineffects/kwinglutils_funcs.cpp
@@ -291,6 +291,7 @@ namespace KWin
// EGL
eglCreateImageKHR_func eglCreateImageKHR;
eglDestroyImageKHR_func eglDestroyImageKHR;
+eglPostSubBufferNV_func eglPostSubBufferNV;
// GLES
glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOES;
@@ -305,6 +306,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/kwin/libkwineffects/kwinglutils_funcs.h b/kwin/libkwineffects/kwinglutils_funcs.h
index 88dab76..e58c56b 100644
--- a/kwin/libkwineffects/kwinglutils_funcs.h
+++ b/kwin/libkwineffects/kwinglutils_funcs.h
@@ -392,8 +392,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/kwin/scene_opengl_egl.cpp b/kwin/scene_opengl_egl.cpp
index 0b902ef..775deb9 100644
--- a/kwin/scene_opengl_egl.cpp
+++ b/kwin/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
@@ -199,9 +202,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);
}