[Cogl] [PATCH 2/3] cogland: Don't redraw constantly
Robert Bragg
robert at sixbynine.org
Fri Mar 22 08:26:24 PDT 2013
This looks good to land to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
- Robert
On Fri, Mar 22, 2013 at 2:47 PM, Neil Roberts <neil at linux.intel.com> wrote:
> Instead of always drawing at 60FPS without ever going idle, Cogland
> now only redraws when a client commits a frame or a surface is
> destroyed. This is acheived using an idle handler on the glib main
> loop.
> ---
> examples/cogland.c | 135 +++++++++++++++++++++++++++++------------------------
> 1 file changed, 75 insertions(+), 60 deletions(-)
>
> diff --git a/examples/cogland.c b/examples/cogland.c
> index 98e0efe..45de95a 100644
> --- a/examples/cogland.c
> +++ b/examples/cogland.c
> @@ -108,6 +108,8 @@ struct _CoglandCompositor
> GSource *wayland_event_source;
>
> GList *surfaces;
> +
> + unsigned int redraw_idle;
> };
>
> static CoglBool option_multiple_outputs = FALSE;
> @@ -264,6 +266,73 @@ wayland_event_source_new (struct wl_display *display)
> return &source->source;
> }
>
> +typedef struct _CoglandFrameCallback
> +{
> + struct wl_list link;
> +
> + /* Pointer back to the compositor */
> + CoglandCompositor *compositor;
> +
> + struct wl_resource resource;
> +} CoglandFrameCallback;
> +
> +static CoglBool
> +paint_cb (void *user_data)
> +{
> + CoglandCompositor *compositor = user_data;
> + GList *l;
> +
> + for (l = compositor->outputs; l; l = l->next)
> + {
> + CoglandOutput *output = l->data;
> + CoglFramebuffer *fb = COGL_FRAMEBUFFER (output->onscreen);
> + GList *l2;
> +
> + cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
> +
> + cogl_framebuffer_draw_primitive (fb, compositor->triangle_pipeline,
> + compositor->triangle);
> +
> + for (l2 = compositor->surfaces; l2; l2 = l2->next)
> + {
> + CoglandSurface *surface = l2->data;
> +
> + if (surface->texture)
> + {
> + CoglTexture2D *texture = surface->texture;
> + CoglPipeline *pipeline =
> + cogl_pipeline_new (compositor->cogl_context);
> + cogl_pipeline_set_layer_texture (pipeline, 0,
> + COGL_TEXTURE (texture));
> + cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1);
> + cogl_object_unref (pipeline);
> + }
> + }
> + cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
> + }
> +
> + while (!wl_list_empty (&compositor->frame_callbacks))
> + {
> + CoglandFrameCallback *callback =
> + wl_container_of (compositor->frame_callbacks.next, callback, link);
> +
> + wl_resource_post_event (&callback->resource,
> + WL_CALLBACK_DONE, get_time ());
> + wl_resource_destroy (&callback->resource);
> + }
> +
> + compositor->redraw_idle = 0;
> +
> + return G_SOURCE_REMOVE;
> +}
> +
> +static void
> +cogland_queue_redraw (CoglandCompositor *compositor)
> +{
> + if (compositor->redraw_idle == 0)
> + compositor->redraw_idle = g_idle_add (paint_cb, compositor);
> +}
> +
> static void
> shm_buffer_damaged (CoglandSurface *surface,
> int32_t x,
> @@ -335,6 +404,8 @@ cogland_surface_detach_buffer (CoglandSurface *surface)
> cogl_object_unref (surface->texture);
> surface->texture = NULL;
> }
> +
> + cogland_queue_redraw (surface->compositor);
> }
> }
>
> @@ -399,16 +470,6 @@ cogland_surface_damage (struct wl_client *client,
> region_add (&surface->pending.damage, x, y, width, height);
> }
>
> -typedef struct _CoglandFrameCallback
> -{
> - struct wl_list link;
> -
> - /* Pointer back to the compositor */
> - CoglandCompositor *compositor;
> -
> - struct wl_resource resource;
> -} CoglandFrameCallback;
> -
> static void
> destroy_frame_callback (struct wl_resource *callback_resource)
> {
> @@ -520,6 +581,8 @@ cogland_surface_commit (struct wl_client *client,
> wl_list_insert_list (&compositor->frame_callbacks,
> &surface->pending.frame_callback_list);
> wl_list_init (&surface->pending.frame_callback_list);
> +
> + cogland_queue_redraw (compositor);
> }
>
> static void
> @@ -752,54 +815,6 @@ cogland_compositor_create_output (CoglandCompositor *compositor,
> compositor->outputs = g_list_prepend (compositor->outputs, output);
> }
>
> -static CoglBool
> -paint_cb (void *user_data)
> -{
> - CoglandCompositor *compositor = user_data;
> - GList *l;
> -
> - for (l = compositor->outputs; l; l = l->next)
> - {
> - CoglandOutput *output = l->data;
> - CoglFramebuffer *fb = COGL_FRAMEBUFFER (output->onscreen);
> - GList *l2;
> -
> - cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
> -
> - cogl_framebuffer_draw_primitive (fb, compositor->triangle_pipeline,
> - compositor->triangle);
> -
> - for (l2 = compositor->surfaces; l2; l2 = l2->next)
> - {
> - CoglandSurface *surface = l2->data;
> -
> - if (surface->texture)
> - {
> - CoglTexture2D *texture = surface->texture;
> - CoglPipeline *pipeline =
> - cogl_pipeline_new (compositor->cogl_context);
> - cogl_pipeline_set_layer_texture (pipeline, 0,
> - COGL_TEXTURE (texture));
> - cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1);
> - cogl_object_unref (pipeline);
> - }
> - }
> - cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
> - }
> -
> - while (!wl_list_empty (&compositor->frame_callbacks))
> - {
> - CoglandFrameCallback *callback =
> - wl_container_of (compositor->frame_callbacks.next, callback, link);
> -
> - wl_resource_post_event (&callback->resource,
> - WL_CALLBACK_DONE, get_time ());
> - wl_resource_destroy (&callback->resource);
> - }
> -
> - return TRUE;
> -}
> -
> const static struct wl_compositor_interface cogland_compositor_interface =
> {
> cogland_compositor_create_surface,
> @@ -1074,13 +1089,13 @@ main (int argc, char **argv)
> 3, triangle_vertices);
> compositor.triangle_pipeline = cogl_pipeline_new (compositor.cogl_context);
>
> - g_timeout_add (16, paint_cb, &compositor);
> -
> cogl_source = cogl_glib_source_new (compositor.cogl_context,
> G_PRIORITY_DEFAULT);
>
> g_source_attach (cogl_source, NULL);
>
> + cogland_queue_redraw (&compositor);
> +
> g_main_loop_run (loop);
>
> return 0;
> --
> 1.7.11.3.g3c3efa5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list