[PATCH] Window.c delay redraws with frame callback

Kristian Hoegsberg hoegsberg at gmail.com
Sat Mar 24 11:49:04 PDT 2012


On Fri, Mar 23, 2012 at 11:59:08PM +0100, Martin Minarik wrote:
> Don't ignore schedule redraw between idle_redraw() triggering and the
> frame callback. The frame callback now sets redraw_from_callback and
> forces window schedule redraw.
> 
> The flags prevent getting into idle_redraw again until another frame
> callback.

I ended up applying a slightly different version of this idea, but
it's a great optimization; thanks for tracking it down.

Kristian

> diff --git a/clients/window.c b/clients/window.c
> index 5d33a3c..cb3d646 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -109,7 +109,7 @@ enum {
>  	TYPE_MENU,
>  	TYPE_CUSTOM
>  };
> -
> +
>  struct window {
>  	struct display *display;
>  	struct window *parent;
> @@ -123,6 +123,8 @@ struct window {
>  	int x, y;
>  	int resize_edges;
>  	int redraw_scheduled;
> +	int redraw_queued;
> +	int redraw_from_callback;
>  	struct task redraw_task;
>  	int resize_scheduled;
>  	struct task resize_task;
> @@ -2113,6 +2115,24 @@ window_get_allocation(struct window *window,
>  	*allocation = window->allocation;
>  }
> 
> +static const struct wl_callback_listener frame_listener;
> +
> +static void redraw_frame_callback(void * data, struct wl_callback *
> callback, uint32_t time){
> +	struct window * window = data;
> +
> +	if (callback){
> +		wl_callback_destroy(callback);
> +	}
> +
> +	window->redraw_from_callback = 1;//coming from callback flag
> +	window->redraw_queued = 0;//force redraw
> +	window_schedule_redraw(window);
> +}
> +
> +static const struct wl_callback_listener frame_listener = {
> +	redraw_frame_callback,
> +};
> +
>  static void
>  widget_redraw(struct widget *widget)
>  {
> @@ -2127,13 +2147,28 @@ widget_redraw(struct widget *widget)
>  static void
>  idle_redraw(struct task *task, uint32_t events)
>  {
> +	struct wl_callback * callback;
>  	struct window *window =
>  		container_of(task, struct window, redraw_task);
> 
> -	window_create_surface(window);
> -	widget_redraw(window->widget);
> -	window_flush(window);
> +	if (!window->redraw_from_callback) {
> +
> +		callback = wl_surface_frame(window->surface);
> +		wl_callback_add_listener(callback,&frame_listener,window);
> +	}
> +
> +	if (!window->redraw_queued){
> +		if (!window->redraw_from_callback)
> +			window->redraw_queued = 1;
> +
> +		window_create_surface(window);
> +		widget_redraw(window->widget);
> +		window_flush(window);
> +	}
> +
> +	window->redraw_from_callback = 0;
>  	window->redraw_scheduled = 0;
> +
>  }
> 
>  void
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list