EGL_BUFFER_PRESERVED is what you get when buffer_age is 1. I'm sure we can clip the redraw to just the damage region when that happens.
Kristian On Wed, Mar 6, 2013 at 3:24 AM, Pekka Paalanen <[email protected]> wrote: > On Tue, 5 Mar 2013 17:30:30 +0200 > Ander Conselvan de Oliveira <[email protected]> > wrote: > >> Now that we have EXT_buffer_age in mesa, we should stop assuming double >> buffering and use the buffer age instead. >> >> Note: this will cause system without the extension to repaint the whole >> screen every frame. > > Ok, that might hurt the rpi backend when it is using GL to composite. > It makes the extra step to set EGL_SWAP_BEHAVIOR to > EGL_BUFFER_PRESERVED, so it can support the old double-buffering assumption. > I do not recall if it has EXT_buffer_age, but I would assume it doesn't. > > Would it be easy to add a flag to get the strictly double-buffered > behaviour if a backend wishes so? > > If not, then don't worry about it. > > > Thanks, > pq > >> --- >> src/gl-renderer.c | 86 >> ++++++++++++++++++++++++++++++++++++++++------------- >> 1 file changed, 66 insertions(+), 20 deletions(-) >> >> diff --git a/src/gl-renderer.c b/src/gl-renderer.c >> index 4c1bc23..fdde9ae 100644 >> --- a/src/gl-renderer.c >> +++ b/src/gl-renderer.c >> @@ -46,10 +46,11 @@ struct gl_shader { >> GLint color_uniform; >> }; >> >> +#define BUFFER_DAMAGE_COUNT 2 >> + >> struct gl_output_state { >> EGLSurface egl_surface; >> - int current_buffer; >> - pixman_region32_t buffer_damage[2]; >> + pixman_region32_t buffer_damage[BUFFER_DAMAGE_COUNT]; >> }; >> >> struct gl_surface_state { >> @@ -95,6 +96,8 @@ struct gl_renderer { >> >> int has_egl_image_external; >> >> + int has_egl_buffer_age; >> + >> struct gl_shader texture_shader_rgba; >> struct gl_shader texture_shader_rgbx; >> struct gl_shader texture_shader_egl_external; >> @@ -742,12 +745,10 @@ draw_surface(struct weston_surface *es, struct >> weston_output *output, >> struct weston_compositor *ec = es->compositor; >> struct gl_renderer *gr = get_renderer(ec); >> struct gl_surface_state *gs = get_surface_state(es); >> - struct gl_output_state *go = get_output_state(output); >> /* repaint bounding region in global coordinates: */ >> pixman_region32_t repaint; >> /* non-opaque region in surface coordinates: */ >> pixman_region32_t surface_blend; >> - pixman_region32_t *buffer_damage; >> GLint filter; >> int i; >> >> @@ -759,9 +760,6 @@ draw_surface(struct weston_surface *es, struct >> weston_output *output, >> if (!pixman_region32_not_empty(&repaint)) >> goto out; >> >> - buffer_damage = &go->buffer_damage[go->current_buffer]; >> - pixman_region32_subtract(buffer_damage, buffer_damage, &repaint); >> - >> glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); >> >> if (ec->fan_debug) { >> @@ -948,6 +946,51 @@ draw_border(struct weston_output *output) >> } >> >> static void >> +output_get_buffer_damage(struct weston_output *output, >> + pixman_region32_t *buffer_damage) >> +{ >> + struct gl_output_state *go = get_output_state(output); >> + struct gl_renderer *gr = get_renderer(output->compositor); >> + EGLint buffer_age = 0; >> + EGLBoolean ret; >> + int i; >> + >> + if (gr->has_egl_buffer_age) { >> + ret = eglQuerySurface(gr->egl_display, go->egl_surface, >> + EGL_BUFFER_AGE_EXT, &buffer_age); >> + if (ret == EGL_FALSE) { >> + weston_log("buffer age query failed.\n"); >> + gl_renderer_print_egl_error_state(); >> + } >> + } >> + >> + if (buffer_age == 0 || buffer_age - 1 > BUFFER_DAMAGE_COUNT) >> + pixman_region32_copy(buffer_damage, &output->region); >> + else >> + for (i = 0; i < buffer_age - 1; i++) >> + pixman_region32_union(buffer_damage, buffer_damage, >> + &go->buffer_damage[i]); >> +} >> + >> +static void >> +output_rotate_damage(struct weston_output *output, >> + pixman_region32_t *output_damage) >> +{ >> + struct gl_output_state *go = get_output_state(output); >> + struct gl_renderer *gr = get_renderer(output->compositor); >> + int i; >> + >> + if (!gr->has_egl_buffer_age) >> + return; >> + >> + for (i = BUFFER_DAMAGE_COUNT - 1; i >= 1; i--) >> + pixman_region32_copy(&go->buffer_damage[i], >> + &go->buffer_damage[i - 1]); >> + >> + pixman_region32_copy(&go->buffer_damage[0], output_damage); >> +} >> + >> +static void >> gl_renderer_repaint_output(struct weston_output *output, >> pixman_region32_t *output_damage) >> { >> @@ -956,8 +999,8 @@ gl_renderer_repaint_output(struct weston_output *output, >> struct gl_renderer *gr = get_renderer(compositor); >> EGLBoolean ret; >> static int errored; >> - int32_t width, height, i; >> - pixman_region32_t total_damage; >> + int32_t width, height; >> + pixman_region32_t buffer_damage, total_damage; >> >> width = output->current->width + >> output->border.left + output->border.right; >> @@ -983,18 +1026,18 @@ gl_renderer_repaint_output(struct weston_output >> *output, >> pixman_region32_fini(&undamaged); >> } >> >> - for (i = 0; i < 2; i++) >> - pixman_region32_union(&go->buffer_damage[i], >> - &go->buffer_damage[i], >> - output_damage); >> - >> pixman_region32_init(&total_damage); >> - pixman_region32_copy(&total_damage, >> - &go->buffer_damage[go->current_buffer]); >> + pixman_region32_init(&buffer_damage); >> + >> + output_get_buffer_damage(output, &buffer_damage); >> + output_rotate_damage(output, output_damage); >> + >> + pixman_region32_union(&total_damage, &buffer_damage, output_damage); >> >> repaint_surfaces(output, &total_damage); >> >> pixman_region32_fini(&total_damage); >> + pixman_region32_fini(&buffer_damage); >> >> if (gr->border.texture) >> draw_border(output); >> @@ -1009,8 +1052,6 @@ gl_renderer_repaint_output(struct weston_output >> *output, >> gl_renderer_print_egl_error_state(); >> } >> >> - go->current_buffer ^= 1; >> - >> } >> >> static int >> @@ -1620,8 +1661,7 @@ gl_renderer_output_create(struct weston_output *output, >> return -1; >> } >> >> - go->current_buffer = 0; >> - for (i = 0; i < 2; i++) >> + for (i = 0; i < BUFFER_DAMAGE_COUNT; i++) >> pixman_region32_init(&go->buffer_damage[i]); >> >> output->renderer_state = go; >> @@ -1931,6 +1971,12 @@ gl_renderer_setup(struct weston_compositor *ec, >> EGLSurface egl_surface) >> gr->has_bind_display = 0; >> } >> >> + if (strstr(extensions, "EGL_EXT_buffer_age")) >> + gr->has_egl_buffer_age = 1; >> + else >> + weston_log("warning: EGL_EXT_buffer_age not supported. " >> + "Performance could be affected.\n"); >> + >> glActiveTexture(GL_TEXTURE0); >> >> if (compile_shaders(ec)) > > _______________________________________________ > wayland-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
