compositor: don't release the front buffer after page flip

On repaint, wlsc_output_repaint will replace output->scanout_buffer with
the new front buffer and then output->present() will cause this buffer
to be displayed. When wlsc_output_finish_frame is called, the
compositor will send a release buffer event for output->scanout_buffer
which is actually the front buffer now.

This patch changes this code to release the previous scanout_buffer
instead of the front buffer on wlsc_output_finish_frame.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
dev
Ander Conselvan de Oliveira 13 years ago committed by Kristian Høgsberg
parent 3b19966f19
commit f1621d2945
  1. 31
      compositor/compositor.c
  2. 2
      compositor/compositor.h

@ -227,6 +227,21 @@ output_handle_scanout_buffer_destroy(struct wl_listener *listener,
output->scanout_buffer = NULL; output->scanout_buffer = NULL;
} }
static void
output_handle_old_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);
struct wl_buffer *buffer = (struct wl_buffer *) resource;
if (output->old_scanout_buffer == buffer)
output->old_scanout_buffer = NULL;
}
WL_EXPORT struct wlsc_surface * WL_EXPORT struct wlsc_surface *
wlsc_surface_create(struct wlsc_compositor *compositor, wlsc_surface_create(struct wlsc_compositor *compositor,
int32_t x, int32_t y, int32_t width, int32_t height) int32_t x, int32_t y, int32_t width, int32_t height)
@ -846,9 +861,16 @@ setup_scanout_surface(struct wlsc_output *output, struct wlsc_surface *es)
output->prepare_scanout_surface(output, es) != 0) output->prepare_scanout_surface(output, es) != 0)
return 0; return 0;
output->old_scanout_buffer = output->scanout_buffer;
output->scanout_buffer = es->buffer; output->scanout_buffer = es->buffer;
output->scanout_buffer->busy_count++; output->scanout_buffer->busy_count++;
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);
}
wl_list_remove(&output->scanout_buffer_destroy_listener.link); wl_list_remove(&output->scanout_buffer_destroy_listener.link);
wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev, wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
&output->scanout_buffer_destroy_listener.link); &output->scanout_buffer_destroy_listener.link);
@ -968,8 +990,8 @@ idle_repaint(void *data)
WL_EXPORT void WL_EXPORT void
wlsc_output_finish_frame(struct wlsc_output *output, int msecs) wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
{ {
wlsc_buffer_post_release(output->scanout_buffer); wlsc_buffer_post_release(output->old_scanout_buffer);
output->scanout_buffer = NULL; output->old_scanout_buffer = NULL;
output->repaint_scheduled = 0; output->repaint_scheduled = 0;
if (output->repaint_needed) if (output->repaint_needed)
@ -1920,6 +1942,11 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
output->scanout_buffer_destroy_listener.func = output->scanout_buffer_destroy_listener.func =
output_handle_scanout_buffer_destroy; output_handle_scanout_buffer_destroy;
wl_list_init(&output->scanout_buffer_destroy_listener.link); 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);
wl_list_init(&output->frame_callback_list); wl_list_init(&output->frame_callback_list);
output->resource.object.interface = &wl_output_interface; output->resource.object.interface = &wl_output_interface;

@ -85,6 +85,8 @@ struct wlsc_output {
struct wl_list mode_list; struct wl_list mode_list;
struct wl_buffer *scanout_buffer; struct wl_buffer *scanout_buffer;
struct wl_listener scanout_buffer_destroy_listener; struct wl_listener scanout_buffer_destroy_listener;
struct wl_buffer *old_scanout_buffer;
struct wl_listener old_scanout_buffer_destroy_listener;
int (*prepare_render)(struct wlsc_output *output); int (*prepare_render)(struct wlsc_output *output);
int (*present)(struct wlsc_output *output); int (*present)(struct wlsc_output *output);

Loading…
Cancel
Save