[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