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
This commit is contained in:
Pierre-Loup A. Griffais 2011-10-16 01:09:16 -07:00 committed by Martin Gräßlin
parent 309ce4013a
commit 2570e9ec61
3 changed files with 16 additions and 3 deletions

View file

@ -296,6 +296,7 @@ namespace KWin
// EGL // EGL
eglCreateImageKHR_func eglCreateImageKHR; eglCreateImageKHR_func eglCreateImageKHR;
eglDestroyImageKHR_func eglDestroyImageKHR; eglDestroyImageKHR_func eglDestroyImageKHR;
eglPostSubBufferNV_func eglPostSubBufferNV;
// GLES // GLES
glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOES; glEGLImageTargetTexture2DOES_func glEGLImageTargetTexture2DOES;
@ -310,6 +311,12 @@ void eglResolveFunctions()
eglCreateImageKHR = NULL; eglCreateImageKHR = NULL;
eglDestroyImageKHR = NULL; eglDestroyImageKHR = NULL;
} }
if (hasGLExtension("EGL_NV_post_sub_buffer")) {
eglPostSubBufferNV = (eglPostSubBufferNV_func)eglGetProcAddress("eglPostSubBufferNV");
} else {
eglPostSubBufferNV = NULL;
}
} }
void glResolveFunctions() void glResolveFunctions()

View file

@ -358,8 +358,10 @@ void KWIN_EXPORT glResolveFunctions();
// EGL // EGL
typedef EGLImageKHR(*eglCreateImageKHR_func)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*); typedef EGLImageKHR(*eglCreateImageKHR_func)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
typedef EGLBoolean(*eglDestroyImageKHR_func)(EGLDisplay, EGLImageKHR); 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 eglCreateImageKHR_func eglCreateImageKHR;
extern KWIN_EXPORT eglDestroyImageKHR_func eglDestroyImageKHR; extern KWIN_EXPORT eglDestroyImageKHR_func eglDestroyImageKHR;
extern KWIN_EXPORT eglPostSubBufferNV_func eglPostSubBufferNV;
// GLES // GLES
typedef GLvoid(*glEGLImageTargetTexture2DOES_func)(GLenum, GLeglImageOES); typedef GLvoid(*glEGLImageTargetTexture2DOES_func)(GLenum, GLeglImageOES);

View file

@ -26,6 +26,7 @@ EGLDisplay dpy;
EGLConfig config; EGLConfig config;
EGLSurface surface; EGLSurface surface;
EGLContext ctx; EGLContext ctx;
int surfaceHasSubPost;
SceneOpenGL::SceneOpenGL(Workspace* ws) SceneOpenGL::SceneOpenGL(Workspace* ws)
: Scene(ws) : Scene(ws)
@ -108,6 +109,8 @@ bool SceneOpenGL::initRenderingContext()
eglSurfaceAttrib(dpy, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); eglSurfaceAttrib(dpy, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
eglQuerySurface(dpy, surface, EGL_POST_SUB_BUFFER_SUPPORTED_NV, &surfaceHasSubPost);
const EGLint context_attribs[] = { const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE EGL_NONE
@ -200,9 +203,10 @@ void SceneOpenGL::flushBuffer(int mask, QRegion damage)
{ {
Q_UNUSED(damage) Q_UNUSED(damage)
glFlush(); glFlush();
if (mask & PAINT_SCREEN_REGION) { if (mask & PAINT_SCREEN_REGION && surfaceHasSubPost && eglPostSubBufferNV) {
// TODO: implement me properly QRect damageRect = damage.boundingRect();
eglSwapBuffers(dpy, surface);
eglPostSubBufferNV(dpy, surface, damageRect.left(), displayHeight() - damageRect.bottom() - 1, damageRect.width(), damageRect.height());
} else { } else {
eglSwapBuffers(dpy, surface); eglSwapBuffers(dpy, surface);
} }