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.
dev
Ander Conselvan de Oliveira 11 years ago committed by Kristian Høgsberg
parent 65796816b9
commit 895b1fdcb2
  1. 26
      src/compositor-drm.c
  2. 8
      src/gl-renderer.c

@ -1056,18 +1056,24 @@ drm_assign_planes(struct weston_output *output)
pixman_region32_init(&overlap); pixman_region32_init(&overlap);
primary = &c->base.primary_plane; 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) { wl_list_for_each_safe(ev, next, &c->base.view_list, link) {
/* test whether this buffer can ever go into a plane: struct weston_surface *es = ev->surface;
* non-shm, or small enough to be a cursor
/* 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 || if (c->use_pixman ||
(wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) && (es->buffer_ref.buffer &&
(ev->geometry.width > 64 || ev->geometry.height > 64))) (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
ev->surface->keep_buffer = 0; (ev->geometry.width <= 64 && ev->geometry.height <= 64))))
es->keep_buffer = 1;
else
es->keep_buffer = 0;
pixman_region32_init(&surface_overlap); pixman_region32_init(&surface_overlap);
pixman_region32_intersect(&surface_overlap, &overlap, pixman_region32_intersect(&surface_overlap, &overlap,

@ -883,7 +883,8 @@ gl_renderer_flush_damage(struct weston_surface *surface)
if (!texture_used) if (!texture_used)
return; return;
if (!pixman_region32_not_empty(&gs->texture_damage)) if (!pixman_region32_not_empty(&gs->texture_damage) &&
!gs->needs_full_upload)
goto done; goto done;
switch (wl_shm_buffer_get_format(buffer->shm_buffer)) { 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, wl_signal_add(&gr->destroy_signal,
&gs->renderer_destroy_listener); &gs->renderer_destroy_listener);
if (surface->buffer_ref.buffer) {
gl_renderer_attach(surface, surface->buffer_ref.buffer);
gl_renderer_flush_damage(surface);
}
return 0; return 0;
} }

Loading…
Cancel
Save