diff --git a/compositor/compositor-drm.c b/compositor/compositor-drm.c index 0e45ff70..0f54e3bd 100644 --- a/compositor/compositor-drm.c +++ b/compositor/compositor-drm.c @@ -71,8 +71,6 @@ struct drm_output { struct gbm_bo *bo[2]; uint32_t current; - struct wlsc_surface *scanout_surface; - uint32_t fs_surf_fb_id; uint32_t pending_fs_surf_fb_id; }; @@ -107,9 +105,8 @@ drm_output_present(struct wlsc_output *output_base) output->current ^= 1; - if (output->scanout_surface != NULL) { - output->scanout_surface = NULL; - fb_id = output->fs_surf_fb_id; + if (output->pending_fs_surf_fb_id != 0) { + fb_id = output->pending_fs_surf_fb_id; } else { fb_id = output->fb_id[output->current ^ 1]; } @@ -130,16 +127,16 @@ page_flip_handler(int fd, unsigned int frame, (struct drm_compositor *) output->base.compositor; uint32_t msecs; - if (output->pending_fs_surf_fb_id) { - drmModeRmFB(c->drm.fd, output->pending_fs_surf_fb_id); - output->pending_fs_surf_fb_id = 0; - } - if (output->fs_surf_fb_id) { - output->pending_fs_surf_fb_id = output->fs_surf_fb_id; + drmModeRmFB(c->drm.fd, output->fs_surf_fb_id); output->fs_surf_fb_id = 0; } + if (output->pending_fs_surf_fb_id) { + output->fs_surf_fb_id = output->pending_fs_surf_fb_id; + output->pending_fs_surf_fb_id = 0; + } + msecs = sec * 1000 + usec / 1000; wlsc_output_finish_frame(&output->base, msecs); } @@ -184,8 +181,7 @@ drm_output_prepare_scanout_surface(struct wlsc_output *output_base, if (ret) return -1; - output->fs_surf_fb_id = fb_id; - output->scanout_surface = es; + output->pending_fs_surf_fb_id = fb_id; return 0; } @@ -535,7 +531,6 @@ create_output_for_connector(struct drm_compositor *ec, return -1; } - output->scanout_surface = NULL; output->base.prepare_render = drm_output_prepare_render; output->base.present = drm_output_present; output->base.prepare_scanout_surface = diff --git a/compositor/compositor.c b/compositor/compositor.c index 17b347ed..c1765b40 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -228,17 +228,17 @@ output_handle_scanout_buffer_destroy(struct wl_listener *listener, } static void -output_handle_old_scanout_buffer_destroy(struct wl_listener *listener, - struct wl_resource *resource, - uint32_t time) +output_handle_pending_scanout_buffer_destroy(struct wl_listener *listener, + struct wl_resource *resource, + uint32_t time) { struct wlsc_output *output = container_of(listener, struct wlsc_output, - old_scanout_buffer_destroy_listener); + pending_scanout_buffer_destroy_listener); struct wl_buffer *buffer = (struct wl_buffer *) resource; - if (output->old_scanout_buffer == buffer) - output->old_scanout_buffer = NULL; + if (output->pending_scanout_buffer == buffer) + output->pending_scanout_buffer = NULL; } @@ -859,23 +859,16 @@ setup_scanout_surface(struct wlsc_output *output, struct wlsc_surface *es) { if (es->visual != WLSC_RGB_VISUAL || output->prepare_scanout_surface(output, es) != 0) - return 0; - - output->old_scanout_buffer = output->scanout_buffer; - output->scanout_buffer = es->buffer; - output->scanout_buffer->busy_count++; + return -1; - if (output->old_scanout_buffer) { - wl_list_remove(&output->old_scanout_buffer_destroy_listener.link); - wl_list_insert(output->old_scanout_buffer->resource.destroy_listener_list.prev, - &output->old_scanout_buffer_destroy_listener.link); - } + /* assert output->pending_scanout_buffer == NULL */ + output->pending_scanout_buffer = es->buffer; + output->pending_scanout_buffer->busy_count++; - wl_list_remove(&output->scanout_buffer_destroy_listener.link); - wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev, - &output->scanout_buffer_destroy_listener.link); + wl_list_insert(output->pending_scanout_buffer->resource.destroy_listener_list.prev, + &output->pending_scanout_buffer_destroy_listener.link); - return 1; + return 0; } static void @@ -920,7 +913,7 @@ wlsc_output_repaint(struct wlsc_output *output) es = container_of(ec->surface_list.next, struct wlsc_surface, link); - if (setup_scanout_surface(output, es)) { + if (setup_scanout_surface(output, es) == 0) { /* We're drawing nothing now, * draw the damaged regions later. */ pixman_region32_union(&ec->damage, &ec->damage, &total_damage); @@ -990,8 +983,20 @@ idle_repaint(void *data) WL_EXPORT void wlsc_output_finish_frame(struct wlsc_output *output, int msecs) { - wlsc_buffer_post_release(output->old_scanout_buffer); - output->old_scanout_buffer = NULL; + if (output->scanout_buffer) { + wlsc_buffer_post_release(output->scanout_buffer); + wl_list_remove(&output->scanout_buffer_destroy_listener.link); + output->scanout_buffer = NULL; + } + + if (output->pending_scanout_buffer) { + output->scanout_buffer = output->pending_scanout_buffer; + wl_list_remove(&output->pending_scanout_buffer_destroy_listener.link); + wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev, + &output->scanout_buffer_destroy_listener.link); + output->pending_scanout_buffer = NULL; + } + output->repaint_scheduled = 0; if (output->repaint_needed) @@ -1943,9 +1948,9 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c, output_handle_scanout_buffer_destroy; wl_list_init(&output->scanout_buffer_destroy_listener.link); - output->old_scanout_buffer_destroy_listener.func = - output_handle_old_scanout_buffer_destroy; - wl_list_init(&output->old_scanout_buffer_destroy_listener.link); + output->pending_scanout_buffer_destroy_listener.func = + output_handle_pending_scanout_buffer_destroy; + wl_list_init(&output->pending_scanout_buffer_destroy_listener.link); wl_list_init(&output->frame_callback_list); diff --git a/compositor/compositor.h b/compositor/compositor.h index d63017c8..9a210b99 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -85,8 +85,8 @@ struct wlsc_output { struct wl_list mode_list; struct wl_buffer *scanout_buffer; struct wl_listener scanout_buffer_destroy_listener; - struct wl_buffer *old_scanout_buffer; - struct wl_listener old_scanout_buffer_destroy_listener; + struct wl_buffer *pending_scanout_buffer; + struct wl_listener pending_scanout_buffer_destroy_listener; int (*prepare_render)(struct wlsc_output *output); int (*present)(struct wlsc_output *output);