From: Vladimir Nadvornik Date: Tue, 14 Aug 2012 21:55:16 +0000 (+0200) Subject: update the texture with lower priority X-Git-Tag: v1.2~122 X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=commitdiff_plain;h=17567ffee44220d9b99d9c0d1bd8e5dd166620dc update the texture with lower priority --- diff --git a/src/renderer-clutter.c b/src/renderer-clutter.c index cd468d51..59f403c3 100644 --- a/src/renderer-clutter.c +++ b/src/renderer-clutter.c @@ -80,8 +80,9 @@ struct _RendererClutter gint stereo_off_x; gint stereo_off_y; - gint x_scroll; /* allow local adjustment and mirroring */ - gint y_scroll; + + GList *pending_updates; + gint idle_update; GtkWidget *widget; /* widget and stage may be shared with other renderers */ ClutterActor *stage; @@ -89,6 +90,16 @@ struct _RendererClutter ClutterActor *group; }; +typedef struct _RendererClutterAreaParam RendererClutterAreaParam; +struct _RendererClutterAreaParam { + RendererClutter *rc; + gint x; + gint y; + gint w; + gint h; +}; + + static void rc_sync_actor(RendererClutter *rc) { PixbufRenderer *pr = rc->pr; @@ -98,7 +109,7 @@ static void rc_sync_actor(RendererClutter *rc) clutter_actor_set_anchor_point(CLUTTER_ACTOR(rc->texture), 0, 0); printf("scale %d %d\n", rc->pr->width, rc->pr->height); - printf("pos %d %d %d %d\n", rc->pr->x_offset, rc->pr->y_offset, rc->x_scroll, rc->y_scroll); + printf("pos %d %d\n", rc->pr->x_offset, rc->pr->y_offset); switch (pr->orientation) { @@ -207,34 +218,85 @@ static void rc_sync_actor(RendererClutter *rc) } +#define MAX_REGION_AREA (8192 * 1024) -static void renderer_area_changed(void *renderer, gint src_x, gint src_y, gint src_w, gint src_h) +static gboolean renderer_area_changed_cb(gpointer data) { - RendererClutter *rc = (RendererClutter *)renderer; + RendererClutter *rc = (RendererClutter *)data; PixbufRenderer *pr = rc->pr; + RendererClutterAreaParam *par = rc->pending_updates->data; + gint h = MAX_REGION_AREA / par->w; + if (h == 0) h = 1; + if (h > par->h) h = par->h; - printf("renderer_area_changed %d %d %d %d\n", src_x, src_y, src_w, src_h); + + printf("renderer_area_changed_cb %d %d %d %d (%d)\n", par->x, par->y, par->w, h, par->h); if (pr->pixbuf) { CoglHandle texture = clutter_texture_get_cogl_texture(CLUTTER_TEXTURE(rc->texture)); cogl_texture_set_region(texture, - src_x, - src_y, - src_x, - src_y, - src_w, - src_h, - src_w, - src_h, + par->x, + par->y, + par->x, + par->y, + par->w, + h, + par->w, + h, gdk_pixbuf_get_has_alpha(pr->pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_rowstride(pr->pixbuf), gdk_pixbuf_get_pixels(pr->pixbuf)); + } + + par->y += h; + par->h -= h; + + if (par->h == 0) + { + rc->pending_updates = g_list_remove(rc->pending_updates, par); + g_free(par); + } + if (!rc->pending_updates) + { clutter_actor_queue_redraw(CLUTTER_ACTOR(rc->texture)); + rc->idle_update = 0; + return FALSE; } + return TRUE; +} + +static void renderer_area_changed(void *renderer, gint src_x, gint src_y, gint src_w, gint src_h) +{ + RendererClutter *rc = (RendererClutter *)renderer; + PixbufRenderer *pr = rc->pr; + + RendererClutterAreaParam *par = g_new0(RendererClutterAreaParam, 1); + par->rc = rc; + par->x = src_x; + par->y = src_y; + par->w = src_w; + par->h = src_h; + rc->pending_updates = g_list_append(rc->pending_updates, par); + if (!rc->idle_update) + { + rc->idle_update = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, renderer_area_changed_cb, rc, NULL); + } +} + +static void renderer_remove_pending_updates(RendererClutter *rc) +{ + if (rc->idle_update) g_idle_remove_by_data(rc); + rc->idle_update = 0; + while (rc->pending_updates) + { + RendererClutterAreaParam *par = rc->pending_updates->data; + rc->pending_updates = g_list_remove(rc->pending_updates, par); + g_free(par); + } } static void renderer_update_pixbuf(void *renderer, gboolean lazy) @@ -242,6 +304,8 @@ static void renderer_update_pixbuf(void *renderer, gboolean lazy) RendererClutter *rc = (RendererClutter *)renderer; PixbufRenderer *pr = rc->pr; + renderer_remove_pending_updates(rc); + if (pr->pixbuf) { gint width = gdk_pixbuf_get_width(pr->pixbuf); @@ -383,6 +447,8 @@ static void renderer_stereo_set(void *renderer, gint stereo_mode) static void renderer_free(void *renderer) { RendererClutter *rc = (RendererClutter *)renderer; + renderer_remove_pending_updates(rc); + GtkWidget *widget = gtk_bin_get_child(GTK_BIN(rc->pr)); if (widget) { @@ -430,6 +496,8 @@ RendererFuncs *renderer_clutter_new(PixbufRenderer *pr) rc->stereo_off_x = 0; rc->stereo_off_y = 0; + rc->idle_update = 0; + rc->pending_updates = NULL; rc->widget = gtk_bin_get_child(GTK_BIN(rc->pr));