From 895b1fdcb2a4423fc1de281d9eb0df9b618e9a7a Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 19 Nov 2013 15:22:05 +0200 Subject: [PATCH] gl-renderer: Attach buffer during surface state creation if possible When a renderer switch happens, it is possible that when the surface state is created, a buffer for the given surface is already available. In that case, run the attach routine so that the pixel contents are properly set. Otherwise, it would only be set when a new attach request is made for that surface. Also, change the drm backend so that it keeps the buffer reference in the weston_surface when running with the pixman renderer. The pixman renderer keeps a reference to it anyway, so it is never released early. This makes the renderer transition seamless, without leaving a black screen as before. --- src/compositor-drm.c | 26 ++++++++++++++++---------- src/gl-renderer.c | 8 +++++++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 5cb0fab9..e89c768a 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -1056,18 +1056,24 @@ drm_assign_planes(struct weston_output *output) pixman_region32_init(&overlap); primary = &c->base.primary_plane; - /* Flag all visible surfaces as keep_buffer = 1 */ - wl_list_for_each(ev, &c->base.view_list, link) - ev->surface->keep_buffer = 1; - wl_list_for_each_safe(ev, next, &c->base.view_list, link) { - /* test whether this buffer can ever go into a plane: - * non-shm, or small enough to be a cursor + struct weston_surface *es = ev->surface; + + /* Test whether this buffer can ever go into a plane: + * non-shm, or small enough to be a cursor. + * + * Also, keep a reference when using the pixman renderer. + * That makes it possible to do a seamless switch to the GL + * renderer and since the pixman renderer keeps a reference + * to the buffer anyway, there is no side effects. */ - if (!ev->surface->buffer_ref.buffer || - (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) && - (ev->geometry.width > 64 || ev->geometry.height > 64))) - ev->surface->keep_buffer = 0; + if (c->use_pixman || + (es->buffer_ref.buffer && + (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) || + (ev->geometry.width <= 64 && ev->geometry.height <= 64)))) + es->keep_buffer = 1; + else + es->keep_buffer = 0; pixman_region32_init(&surface_overlap); pixman_region32_intersect(&surface_overlap, &overlap, diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 5e1b3961..218fca40 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -883,7 +883,8 @@ gl_renderer_flush_damage(struct weston_surface *surface) if (!texture_used) return; - if (!pixman_region32_not_empty(&gs->texture_damage)) + if (!pixman_region32_not_empty(&gs->texture_damage) && + !gs->needs_full_upload) goto done; switch (wl_shm_buffer_get_format(buffer->shm_buffer)) { @@ -1240,6 +1241,11 @@ gl_renderer_create_surface(struct weston_surface *surface) wl_signal_add(&gr->destroy_signal, &gs->renderer_destroy_listener); + if (surface->buffer_ref.buffer) { + gl_renderer_attach(surface, surface->buffer_ref.buffer); + gl_renderer_flush_damage(surface); + } + return 0; }