From 26ee584fd7617edd86962d283dc3d099a9e35af3 Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Tue, 11 Aug 2015 10:09:40 -0400 Subject: [PATCH] evas-wayland-egl: Add support for partial update extension Summary: if EGL_KHR_partial_update extension is implemented in the driver, set damage region. This is done before the draw calls. Signed-off-by: Chris Michael --- .../evas/engines/wayland_egl/evas_engine.c | 11 ++- .../evas/engines/wayland_egl/evas_engine.h | 1 + .../evas/engines/wayland_egl/evas_wl_main.c | 94 +++++++++++-------- 3 files changed, 68 insertions(+), 38 deletions(-) diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index 47ac0e24ee..750d443db6 100644 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -74,6 +74,7 @@ void *(*glsym_eglCreateImage) (EGLDisplay a, EGLContext b, EGLenum c, EGLClientB void (*glsym_eglDestroyImage) (EGLDisplay a, void *b) = NULL; void (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL; unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL; +unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL; /* local variables */ static Eina_Bool initted = EINA_FALSE; @@ -167,6 +168,8 @@ gl_symbols(void) glsym_func_uint); FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", glsym_func_uint); + FINDSYM(glsym_eglSetDamageRegionKHR, "eglSetDamageRegionKHR", + glsym_func_uint); done = EINA_TRUE; } @@ -187,10 +190,16 @@ gl_extn_veto(Render_Engine *re) { extn_have_buffer_age = EINA_FALSE; glsym_eglSwapBuffersWithDamage = NULL; + glsym_eglSetDamageRegionKHR = NULL; } if (!strstr(str, "EGL_EXT_buffer_age")) { - extn_have_buffer_age = EINA_FALSE; + if (!strstr(str, "EGL_KHR_partial_update")) + extn_have_buffer_age = EINA_FALSE; + } + if (!strstr(str, "EGL_KHR_partial_update")) + { + glsym_eglSetDamageRegionKHR = NULL; } if (!strstr(str, "EGL_NOK_texture_from_pixmap")) { diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.h b/src/modules/evas/engines/wayland_egl/evas_engine.h index 9815a160fc..a4ccbf8087 100644 --- a/src/modules/evas/engines/wayland_egl/evas_engine.h +++ b/src/modules/evas/engines/wayland_egl/evas_engine.h @@ -105,6 +105,7 @@ extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock; extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock; extern unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c); +extern unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d); Outbuf *eng_window_new(Evas *evas, Evas_Engine_Info_Wayland_Egl *einfo, int w, int h, Render_Engine_Swap_Mode swap_mode); void eng_window_free(Outbuf *gw); diff --git a/src/modules/evas/engines/wayland_egl/evas_wl_main.c b/src/modules/evas/engines/wayland_egl/evas_wl_main.c index a7dfff888d..ff94c53866 100644 --- a/src/modules/evas/engines/wayland_egl/evas_wl_main.c +++ b/src/modules/evas/engines/wayland_egl/evas_wl_main.c @@ -400,6 +400,59 @@ eng_outbuf_region_first_rect(Outbuf *ob) return EINA_FALSE; } +static void +_convert_glcoords(int *result, Outbuf *ob, int x, int y, int w, int h) +{ + + switch (ob->rot) + { + case 0: + result[0] = x; + result[1] = ob->gl_context->h - (y + h); + result[2] = w; + result[3] = h; + break; + case 90: + result[0] = y; + result[1] = x; + result[2] = h; + result[3] = w; + break; + case 180: + result[0] = ob->gl_context->w - (x + w); + result[1] = y; + result[2] = w; + result[3] = h; + break; + case 270: + result[0] = ob->gl_context->h - (y + h); + result[1] = ob->gl_context->w - (x + w); + result[2] = h; + result[3] = w; + break; + default: + result[0] = x; + result[1] = ob->gl_context->h - (y + h); + result[2] = w; + result[3] = h; + break; + } +} + +static void +_damage_rect_set(Outbuf *ob, int x, int y, int w, int h) +{ + int rects[4]; + + if ((x == 0) && (y == 0) && + (((w == ob->gl_context->w) && (h == ob->gl_context->h)) || + ((h == ob->gl_context->w) && (w == ob->gl_context->h)))) + return; + + _convert_glcoords(rects, ob, x, y, w, h); + glsym_eglSetDamageRegionKHR(ob->egl_disp, ob->egl_surface[0], rects, 1); +} + void * eng_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx EINA_UNUSED, int *cy EINA_UNUSED, int *cw EINA_UNUSED, int *ch EINA_UNUSED) { @@ -412,6 +465,9 @@ eng_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx EIN ob->gl_context->master_clip.y = y; ob->gl_context->master_clip.w = w; ob->gl_context->master_clip.h = h; + + if (glsym_eglSetDamageRegionKHR) + _damage_rect_set(ob, x, y, w, h); } return ob->gl_context->def_surface; @@ -465,43 +521,7 @@ eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode) result = alloca(sizeof(EGLint) * 4 * num); EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) { - int gw, gh; - - gw = ob->gl_context->w; - gh = ob->gl_context->h; - switch (ob->rot) - { - case 0: - result[i + 0] = r->x; - result[i + 1] = gh - (r->y + r->h); - result[i + 2] = r->w; - result[i + 3] = r->h; - break; - case 90: - result[i + 0] = r->y; - result[i + 1] = r->x; - result[i + 2] = r->h; - result[i + 3] = r->w; - break; - case 180: - result[i + 0] = gw - (r->x + r->w); - result[i + 1] = r->y; - result[i + 2] = r->w; - result[i + 3] = r->h; - break; - case 270: - result[i + 0] = gh - (r->y + r->h); - result[i + 1] = gw - (r->x + r->w); - result[i + 2] = r->h; - result[i + 3] = r->w; - break; - default: - result[i + 0] = r->x; - result[i + 1] = gh - (r->y + r->h); - result[i + 2] = r->w; - result[i + 3] = r->h; - break; - } + _convert_glcoords(&result[i], ob, r->x, r->y, r->w, r->h); i += 4; } glsym_eglSwapBuffersWithDamage(ob->egl_disp, ob->egl_surface[0],