diff options
authorDaniel Stone <>2019-02-08 05:29:05 +0000
committerDaniel Stone <>2019-06-26 12:28:03 +0100
commitdf2095fa35fe84e4ebc30754dd9f25e50bd1aa47 (patch)
parent0a86a81cc251330b15e213fde8434f291e35bf88 (diff)
gl-renderer: Support EGL_KHR_partial_update
partial_update is an EGL extension which allows us to inform the driver ahead of time the limits of the areas we'll be writing to. This helps performance for GPU hardware which renders into a local tile buffer: informing the driver of the rendering extents means it can avoid fetching unchanged tiles into the tile buffer and subsequently writing them out. The extension complements rather than replaces EGL_EXT_buffer_age (used before partial_update to know which areas we need to update) and EGL_KHR_swap_buffers_with_damage (used after partial_update to inform the winsys of the changed region). Note however that partial_update deals in buffer-damage regions ('what has changed since the last time I used _this_ buffer?'), whereas swap_buffers_with_damage deals in surface-damage regions ('what has changed since the last time I rendered?'). An explanatory diagram can be found in the specification: Fixes: #134 Signed-off-by: Daniel Stone <>
1 files changed, 16 insertions, 2 deletions
diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c
index 2c03f2ab..3de711ea 100644
--- a/libweston/renderer-gl/gl-renderer.c
+++ b/libweston/renderer-gl/gl-renderer.c
@@ -1480,8 +1480,8 @@ gl_renderer_repaint_output(struct weston_output *output,
/* In fan debug mode, redraw everything to make sure that we clear any
* fans left over from previous draws on this buffer.
- * This precludes the use of EGL_EXT_swap_buffers_with_damage, since
- * we damage the whole area. */
+ * This precludes the use of EGL_EXT_swap_buffers_with_damage and
+ * EGL_KHR_partial_update, since we damage the whole area. */
if (gr->fan_debug) {
pixman_region32_t undamaged;
@@ -1509,6 +1509,20 @@ gl_renderer_repaint_output(struct weston_output *output,
pixman_region32_union(&total_damage, &previous_damage, output_damage);
border_status |= go->border_status;
+ if (gr->has_egl_partial_update && !gr->fan_debug) {
+ int n_egl_rects;
+ EGLint *egl_rects;
+ /* For partial_update, we need to pass the region which has
+ * changed since we last rendered into this specific buffer;
+ * this is total_damage. */
+ pixman_region_to_egl_y_invert(output, &total_damage,
+ &egl_rects, &n_egl_rects);
+ gr->set_damage_region(gr->egl_display, go->egl_surface,
+ egl_rects, n_egl_rects);
+ free(egl_rects);
+ }
repaint_views(output, &total_damage);