diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2011-10-18 17:02:07 +0300 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2011-10-24 11:59:11 -0400 |
commit | f1621d2945a6e9e2fa2bbd510261b1d521d8e074 (patch) | |
tree | 72ffc5b2a260e7c556414409233a4c042311918d | |
parent | 3b19966f192918cab39feddc746c7e4b23bee950 (diff) |
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>
-rw-r--r-- | compositor/compositor.c | 31 | ||||
-rw-r--r-- | compositor/compositor.h | 2 |
2 files changed, 31 insertions, 2 deletions
diff --git a/compositor/compositor.c b/compositor/compositor.c index c59163c..17b347e 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -227,6 +227,21 @@ output_handle_scanout_buffer_destroy(struct wl_listener *listener, 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 * wlsc_surface_create(struct wlsc_compositor *compositor, 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) return 0; + output->old_scanout_buffer = output->scanout_buffer; output->scanout_buffer = es->buffer; 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_insert(output->scanout_buffer->resource.destroy_listener_list.prev, &output->scanout_buffer_destroy_listener.link); @@ -968,8 +990,8 @@ idle_repaint(void *data) WL_EXPORT void wlsc_output_finish_frame(struct wlsc_output *output, int msecs) { - wlsc_buffer_post_release(output->scanout_buffer); - output->scanout_buffer = NULL; + wlsc_buffer_post_release(output->old_scanout_buffer); + output->old_scanout_buffer = NULL; output->repaint_scheduled = 0; 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_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); + wl_list_init(&output->frame_callback_list); output->resource.object.interface = &wl_output_interface; diff --git a/compositor/compositor.h b/compositor/compositor.h index 35aaf55..d63017c 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -85,6 +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; int (*prepare_render)(struct wlsc_output *output); int (*present)(struct wlsc_output *output); |