[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