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:
https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt

Fixes: #134

Signed-off-by: Daniel Stone <daniels@collabora.com>
dev
Daniel Stone 6 years ago
parent 0a86a81cc2
commit df2095fa35
  1. 18
      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;
pixman_region32_init(&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);
pixman_region32_fini(&total_damage);

Loading…
Cancel
Save