summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2013-05-08 11:37:28 -0400
committerKristian Høgsberg <krh@bitplanet.net>2013-05-08 11:39:59 -0400
commit9e885d4bec1e2512335c2e52a768ff0a02f2677c (patch)
tree5c0bfedfff6bcd6b49a35b2b68cddb72d918ee0d
parentfe7aa90ed4f9536fc7c26cb87bbc89dafd950077 (diff)
simple-egl: Add support for EGL_EXT_swap_buffer_with_damage
This new EGL extension lets us communicate the damage area to the compositor by using eglSwapBuffersWithDamge() instead of the regular eglSwapBuffer(). http://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_swap_buffers_with_damage.txt
-rw-r--r--clients/simple-egl.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/clients/simple-egl.c b/clients/simple-egl.c
index f4468b7a..54dfe936 100644
--- a/clients/simple-egl.c
+++ b/clients/simple-egl.c
@@ -36,6 +36,12 @@
#include <GLES2/gl2.h>
#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
struct window;
struct seat;
@@ -58,6 +64,8 @@ struct display {
EGLConfig conf;
} egl;
struct window *window;
+
+ PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;
};
struct geometry {
@@ -107,6 +115,7 @@ init_egl(struct display *display, int opaque)
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
+ const char *extensions;
EGLint config_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@@ -141,6 +150,18 @@ init_egl(struct display *display, int opaque)
EGL_NO_CONTEXT, context_attribs);
assert(display->egl.ctx);
+ display->swap_buffers_with_damage = NULL;
+ extensions = eglQueryString(display->egl.dpy, EGL_EXTENSIONS);
+ if (extensions &&
+ strstr(extensions, "EGL_EXT_swap_buffers_with_damage") &&
+ strstr(extensions, "EGL_EXT_buffer_age"))
+ display->swap_buffers_with_damage =
+ (PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)
+ eglGetProcAddress("eglSwapBuffersWithDamageEXT");
+
+ if (display->swap_buffers_with_damage)
+ printf("has EGL_EXT_buffer_age and EGL_EXT_swap_buffers_with_damage\n");
+
}
static void
@@ -346,6 +367,7 @@ static void
redraw(void *data, struct wl_callback *callback, uint32_t time)
{
struct window *window = data;
+ struct display *display = window->display;
static const GLfloat verts[3][2] = {
{ -0.5, -0.5 },
{ 0.5, -0.5 },
@@ -366,6 +388,8 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
static const int32_t speed_div = 5;
static uint32_t start_time = 0;
struct wl_region *region;
+ EGLint rect[4];
+ EGLint buffer_age = 0;
assert(window->callback == callback);
window->callback = NULL;
@@ -385,6 +409,10 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
rotation[2][0] = -sin(angle);
rotation[2][2] = cos(angle);
+ if (display->swap_buffers_with_damage)
+ eglQuerySurface(display->egl.dpy, window->egl_surface,
+ EGL_BUFFER_AGE_EXT, &buffer_age);
+
glViewport(0, 0, window->geometry.width, window->geometry.height);
glUniformMatrix4fv(window->gl.rotation_uniform, 1, GL_FALSE,
@@ -417,7 +445,17 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
window->callback = wl_surface_frame(window->surface);
wl_callback_add_listener(window->callback, &frame_listener, window);
- eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
+ if (display->swap_buffers_with_damage && buffer_age > 0) {
+ rect[0] = window->geometry.width / 4 - 1;
+ rect[1] = window->geometry.height / 4 - 1;
+ rect[2] = window->geometry.width / 2 + 2;
+ rect[3] = window->geometry.height / 2 + 2;
+ display->swap_buffers_with_damage(display->egl.dpy,
+ window->egl_surface,
+ rect, 1);
+ } else {
+ eglSwapBuffers(display->egl.dpy, window->egl_surface);
+ }
}
static const struct wl_callback_listener frame_listener = {