When a renderer switch happen, 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 before a new attach request is made for that surface.
Also, make sure the DRM backend keeps the buffers around until it switches from pixman to GL. 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 96065bd..5130278 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -107,6 +107,7 @@ struct drm_compositor { int cursors_are_broken; int use_pixman; + int renderer_switch_pending; uint32_t prev_state; @@ -1060,18 +1061,20 @@ 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 + * the buffer around if we plan to switch renderers. */ - 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 ((es->buffer_ref.buffer && + (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) || + (ev->geometry.width <= 64 && ev->geometry.height <= 64) || + c->renderer_switch_pending))) + es->keep_buffer = 1; + else + es->keep_buffer = 0; pixman_region32_init(&surface_overlap); pixman_region32_intersect(&surface_overlap, &overlap, @@ -2636,6 +2639,7 @@ switch_to_gl_renderer(struct drm_compositor *c) drm_output_init_egl(output, c); c->use_pixman = 0; + c->renderer_switch_pending = 0; } struct gl_loader_thread_data { @@ -2708,6 +2712,8 @@ prepare_renderer_switch(struct drm_compositor *ec) gl_loader_thread_done, ec); ec->gl_loader_fd = sv[0]; + ec->renderer_switch_pending = 1; + return 0; } diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 06815b4..e1f9841 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -886,7 +886,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)) { @@ -1237,6 +1238,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; } -- 1.7.9.5 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel