diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index cff5df50c..ff9e1749a 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -300,6 +300,19 @@ cogl_onscreen_bind (CoglOnscreen *onscreen) COGL_ONSCREEN_GET_CLASS (onscreen)->bind (onscreen); } +void +cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen, + const int *rectangles, + int n_rectangles) +{ + CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); + + if (!klass->queue_damage_region) + return; + + klass->queue_damage_region (onscreen, rectangles, n_rectangles); +} + void cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, const int *rectangles, diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h index 7284e04d5..677893493 100644 --- a/cogl/cogl/cogl-onscreen.h +++ b/cogl/cogl/cogl-onscreen.h @@ -74,6 +74,10 @@ struct _CoglOnscreenClass CoglFrameInfo *info, gpointer user_data); + void (* queue_damage_region) (CoglOnscreen *onscreen, + const int *rectangles, + int n_rectangles); + gboolean (* direct_scanout) (CoglOnscreen *onscreen, CoglScanout *scanout, CoglFrameInfo *info, @@ -227,6 +231,23 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen, COGL_EXPORT int cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen); +/** + * cogl_onscreen_queue_damage_region: + * @onscreen: A #CoglOnscreen framebuffer + * @rectangles: An array of integer 4-tuples representing damaged + * rectangles as (x, y, width, height) tuples. + * @n_rectangles: The number of 4-tuples to be read from @rectangles + * + * Implementation for https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt + * This immediately queues state to OpenGL that will be used for the + * next swap. + * This needs to be called every frame. + */ +COGL_EXPORT void +cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen, + const int *rectangles, + int n_rectangles); + /** * cogl_onscreen_swap_buffers_with_damage: * @onscreen: A #CoglOnscreen framebuffer diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.c b/cogl/cogl/winsys/cogl-onscreen-egl.c index 20b3c60ef..8a587049e 100644 --- a/cogl/cogl/winsys/cogl-onscreen-egl.c +++ b/cogl/cogl/winsys/cogl-onscreen-egl.c @@ -242,6 +242,31 @@ cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen, g_warning ("Error reported by eglSwapBuffersRegion"); } +static void +cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen, + const int *rectangles, + int n_rectangles) +{ + CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); + CoglOnscreenEglPrivate *priv = + cogl_onscreen_egl_get_instance_private (onscreen_egl); + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *context = cogl_framebuffer_get_context (framebuffer); + CoglRenderer *renderer = context->display->renderer; + CoglRendererEGL *egl_renderer = renderer->winsys; + + g_return_if_fail (n_rectangles > 0); + + if (!egl_renderer->pf_eglSetDamageRegion) + return; + + if (egl_renderer->pf_eglSetDamageRegion (egl_renderer->edpy, + priv->egl_surface, + rectangles, + n_rectangles) == EGL_FALSE) + g_warning ("Error reported by eglSetDamageRegion"); +} + static void cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen, const int *rectangles, @@ -345,6 +370,8 @@ cogl_onscreen_egl_class_init (CoglOnscreenEglClass *klass) object_class->dispose = cogl_onscreen_egl_dispose; onscreen_class->bind = cogl_onscreen_egl_bind; + onscreen_class->queue_damage_region = + cogl_onscreen_egl_queue_damage_region; onscreen_class->swap_buffers_with_damage = cogl_onscreen_egl_swap_buffers_with_damage; onscreen_class->swap_region = cogl_onscreen_egl_swap_region; diff --git a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h index e10c01938..53d9bd27b 100644 --- a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h +++ b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h @@ -116,6 +116,17 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersWithDamage, EGLint n_rects)) COGL_WINSYS_FEATURE_END () +COGL_WINSYS_FEATURE_BEGIN (partial_update, + "KHR\0", + "partial_update\0", + COGL_EGL_WINSYS_FEATURE_BUFFER_AGE) +COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSetDamageRegion, + (EGLDisplay dpy, + EGLSurface surface, + const EGLint *rects, + EGLint n_rects)) +COGL_WINSYS_FEATURE_END () + #if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) COGL_WINSYS_FEATURE_BEGIN (fence_sync, "KHR\0",