[gegl] bin: throttle renderer task to when there is actual work
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] bin: throttle renderer task to when there is actual work
- Date: Wed, 16 Jan 2019 15:45:26 +0000 (UTC)
commit 10d6c75ea1125495dbf4b41b3b82424a847233da
Author: Øyvind Kolås <pippin gimp org>
Date: Sat Jan 12 00:04:11 2019 +0100
bin: throttle renderer task to when there is actual work
bin/gegl.c | 2 +
bin/mrg-gegl.c | 57 +++++++++++++++++--
bin/ui.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 195 insertions(+), 33 deletions(-)
---
diff --git a/bin/gegl.c b/bin/gegl.c
index d117d7c6b..6ea1ee135 100644
--- a/bin/gegl.c
+++ b/bin/gegl.c
@@ -408,6 +408,8 @@ int gegl_str_has_image_suffix (char *path)
g_str_has_suffix (path, ".png") ||
g_str_has_suffix (path, ".JPG") ||
g_str_has_suffix (path, ".PNG") ||
+ g_str_has_suffix (path, ".gif") ||
+ g_str_has_suffix (path, ".GIF") ||
g_str_has_suffix (path, ".tif") ||
g_str_has_suffix (path, ".tiff") ||
g_str_has_suffix (path, ".TIF") ||
diff --git a/bin/mrg-gegl.c b/bin/mrg-gegl.c
index 22f2d266d..f70d8dcdd 100644
--- a/bin/mrg-gegl.c
+++ b/bin/mrg-gegl.c
@@ -63,6 +63,21 @@ void mrg_gegl_blit (Mrg *mrg,
float scale,
float preview_multiplier);
+static float cached_x0 = 0;
+static float cached_y0 = 0;
+static float cached_width = 0;
+static float cached_height = 0;
+static float cached_u = 0;
+static float cached_v = 0;
+static float cached_scale = 0;
+static float cached_prev_mul = 0;
+static int cached_dirty = 0;
+static cairo_surface_t *cached_surface = NULL;
+
+void mrg_gegl_dirty (void)
+{
+ cached_dirty++;
+}
void mrg_gegl_buffer_blit (Mrg *mrg,
float x0, float y0,
@@ -94,6 +109,35 @@ void mrg_gegl_buffer_blit (Mrg *mrg,
if (height == -1)
height = bounds.height * width / bounds.width;
+ if (cached_x0 == x0 &&
+ cached_y0 == y0 &&
+ cached_width == width &&
+ cached_height == height &&
+ cached_u == u &&
+ cached_v == v &&
+ cached_scale == scale &&
+ cached_prev_mul == preview_multiplier &&
+ cached_dirty == 0)
+ {
+ width /= fake_factor;
+ height /= fake_factor;
+ u /= fake_factor;
+ v /= fake_factor;
+
+ surface = cached_surface;
+ }
+ else
+ {
+ cached_x0 = x0;
+ cached_y0 = y0;
+ cached_width = width;
+ cached_height = height;
+ cached_u = u;
+ cached_v = v;
+ cached_scale = scale;
+ cached_prev_mul = preview_multiplier;
+ cached_dirty = 0;
+
width /= fake_factor;
height /= fake_factor;
u /= fake_factor;
@@ -121,15 +165,19 @@ foo++;
if (icc_data)
space = babl_space_from_icc ((char*)icc_data, icc_length, BABL_ICC_INTENT_RELATIVE_COLORIMETRIC,
NULL);
fmt = babl_format_with_space ("cairo-RGB24", space);
- fmt = babl_format_with_space ("cairo-RGB24", NULL);
+ // fmt = babl_format_with_space ("cairo-RGB24", NULL);
}
gegl_buffer_get (buffer, &roi, scale / fake_factor, fmt, buf, width * 4,
GEGL_ABYSS_NONE);
- surface = cairo_image_surface_create_for_data (buf, CAIRO_FORMAT_RGB24, width, height, width * 4);
+ surface = cairo_image_surface_create_for_data (buf, CAIRO_FORMAT_RGB24, width, height, width * 4);
}
+ cairo_surface_set_device_scale (surface, 1.0/fake_factor, 1.0/fake_factor);
+ if (cached_surface)
+ cairo_surface_destroy (cached_surface);
+ cached_surface = surface;
+ }
cairo_save (cr);
- cairo_surface_set_device_scale (surface, 1.0/fake_factor, 1.0/fake_factor);
width *= fake_factor;
height *= fake_factor;
@@ -145,7 +193,8 @@ foo++;
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
- cairo_surface_destroy (surface);
+
+ //cairo_surface_destroy (surface);
cairo_restore (cr);
}
diff --git a/bin/ui.c b/bin/ui.c
index 6b4af1fed..13f4a2659 100644
--- a/bin/ui.c
+++ b/bin/ui.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*
- * Copyright (C) 2015, 2018 Øyvind Kolås pippin gimp org
+ * Copyright (C) 2015, 2018, 2019 Øyvind Kolås pippin gimp org
*/
/* The code in this file is an image viewer/editor written using microraptor
@@ -49,6 +49,7 @@ const char *css =
"";
+void mrg_gegl_dirty (void);
#include <ctype.h>
@@ -59,6 +60,7 @@ const char *css =
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
+#include <math.h>
#include <mrg.h>
#include <mrg-string.h>
#include <gegl.h>
@@ -113,6 +115,8 @@ static GeglNode *gegl_node_get_consumer_no (GeglNode *node,
int use_ui = 1;
+int renderer_dirty = 0;
+
#define printf(foo...) \
do{ MrgString *str = mrg_string_new_printf (foo);\
if (use_ui) {\
@@ -289,6 +293,11 @@ gchar *get_thumb_path (const char *path)
{
g_free (ret);
ret = g_strdup_printf ("%s/.cache/thumbnails/normal/%s.png", g_get_home_dir(), hex);
+ if (access (ret, F_OK) == -1)
+ {
+ g_free (ret);
+ ret = g_strdup_printf ("%s/.cache/thumbnails/large/%s.png", g_get_home_dir(), hex);
+ }
}
g_free (uri);
g_free (hex);
@@ -297,10 +306,10 @@ gchar *get_thumb_path (const char *path)
static void load_path (State *o);
+static void go_next (State *o);
+static void go_prev (State *o);
+static void go_parent (State *o);
-static void go_next (State *o);
-static void go_prev (State *o);
-static void go_parent (State *o);
static void get_coords (State *o, float screen_x, float screen_y,
float *gegl_x, float *gegl_y);
static void drag_preview (MrgEvent *e);
@@ -310,7 +319,7 @@ static void center (State *o);
static void gegl_ui (Mrg *mrg, void *data);
int mrg_ui_main (int argc, char **argv, char **ops);
void gegl_meta_set (const char *path, const char *meta_data);
-char * gegl_meta_get (const char *path);
+char * gegl_meta_get (const char *path);
static void on_viewer_motion (MrgEvent *e, void *data1, void *data2);
int gegl_str_has_image_suffix (char *path);
int gegl_str_has_video_suffix (char *path);
@@ -375,7 +384,8 @@ static void populate_path_list (State *o)
free (namelist);
}
-static State *hack_state = NULL; // XXX: this shoudl be factored away
+static State *hack_state = NULL; // XXX: for now we have to rely on
+ // global state to make events/scripting work
char **ops = NULL;
@@ -389,6 +399,44 @@ static void end_audio (void)
{
}
+MrgList *thumb_queue = NULL;
+typedef struct ThumbQueueItem
+{
+ char *path;
+ char *thumbpath;
+} ThumbQueueItem;
+
+
+static char *sh_esc (const char *input)
+{
+ MrgString *str = mrg_string_new ("");
+ for (const char *s = input; *s; s++)
+ {
+ switch (*s)
+ {
+ case ' ':
+ mrg_string_append_byte (str, '\\');
+ mrg_string_append_byte (str, ' ');
+ break;
+ default:
+ mrg_string_append_byte (str, *s);
+ break;
+ }
+ }
+ return mrg_string_dissolve (str);
+}
+
+static void generate_thumb (const char *path,
+ const char *thumbpath)
+{
+ char *esc_path = sh_esc (path);
+ char *command = g_strdup_printf ("gegl %s -- scale-size-keepaspect x=256 y=256 convert-space name=sRGB
png-save bitdepth=8 path=%s", esc_path, thumbpath);
+ system (command);
+ free (esc_path);
+ //fprintf (stderr, "generate thumb %s\n", path);
+}
+
+
static gboolean renderer_task (gpointer data)
{
State *o = data;
@@ -398,7 +446,9 @@ static gboolean renderer_task (gpointer data)
switch (o->renderer_state)
{
case 0:
+ if (renderer_dirty)
{
+ renderer_dirty = 0;
if (o->processor_node != o->sink)
{
o->processor = gegl_node_new_processor (o->sink, NULL);
@@ -407,17 +457,22 @@ static gboolean renderer_task (gpointer data)
g_object_unref (old_buffer);
if (old_processor)
g_object_unref (old_processor);
- }
- {
+ if(1){
GeglRectangle rect = {o->u / o->scale, o->v / o->scale, mrg_width (o->mrg) / o->scale,
mrg_height (o->mrg) / o->scale};
gegl_processor_set_rectangle (o->processor, &rect);
}
- o->renderer_state = 1;
}
+ o->renderer_state = 1;
+
+ }
+ else
+ g_usleep (4000);
break; // fallthrough
case 1:
+
+
if (gegl_processor_work (o->processor, &progress))
{
if (o->renderer_state)
@@ -426,10 +481,11 @@ static gboolean renderer_task (gpointer data)
else
{
if (o->renderer_state)
- o->renderer_state = 2;
+ o->renderer_state = 3;
}
break;
- case 2:
+ case 3:
+ mrg_gegl_dirty ();
switch (renderer)
{
case GEGL_RENDERER_IDLE:
@@ -437,9 +493,25 @@ static gboolean renderer_task (gpointer data)
break;
case GEGL_RENDERER_THREAD:
mrg_queue_draw (o->mrg, NULL);
- g_usleep (40000);
+ g_usleep (4000);
break;
}
+ o->renderer_state = 0;
+ if (thumb_queue)
+ {
+ o->renderer_state = 4;
+ }
+ break;
+ case 4:
+ {
+ ThumbQueueItem *item = thumb_queue->data;
+
+ generate_thumb (item->path, item->thumbpath);
+ mrg_list_remove (&thumb_queue, item);
+ free (item->path);
+ free (item->thumbpath);
+ }
+
o->renderer_state = 0;
break;
}
@@ -654,6 +726,7 @@ static void on_paint_drag (MrgEvent *e, void *data1, void *data2)
o->active = gegl_node_get_consumer_no (o->active, "output", NULL, 0);
break;
}
+ renderer_dirty++;
mrg_queue_draw (e->mrg, NULL);
mrg_event_stop_propagate (e);
//drag_preview (e);
@@ -722,12 +795,13 @@ static void on_move_drag (MrgEvent *e, void *data1, void *data2)
gegl_node_get (o->active, "x", &x, "y", &y, NULL);
x += e->delta_x / o->scale;
y += e->delta_y / o->scale;
- gegl_node_set (o->active, "x", floor(x), "y", floor(y), NULL);
+ gegl_node_set (o->active, "x", floorf(x), "y", floorf(y), NULL);
}
break;
case MRG_DRAG_RELEASE:
break;
}
+ renderer_dirty++;
mrg_queue_draw (e->mrg, NULL);
mrg_event_stop_propagate (e);
}
@@ -777,6 +851,7 @@ static void update_prop (const char *new_string, void *node_p)
{
GeglNode *node = node_p;
gegl_node_set (node, edited_prop, new_string, NULL);
+ renderer_dirty++;
}
@@ -785,6 +860,7 @@ static void update_prop_double (const char *new_string, void *node_p)
GeglNode *node = node_p;
gdouble value = g_strtod (new_string, NULL);
gegl_node_set (node, edited_prop, value, NULL);
+ renderer_dirty++;
}
static void update_prop_int (const char *new_string, void *node_p)
@@ -792,6 +868,7 @@ static void update_prop_int (const char *new_string, void *node_p)
GeglNode *node = node_p;
gint value = g_strtod (new_string, NULL);
gegl_node_set (node, edited_prop, value, NULL);
+ renderer_dirty++;
}
@@ -803,6 +880,7 @@ static void prop_toggle_boolean (MrgEvent *e, void *data1, void *data2)
gegl_node_get (node, propname, &value, NULL);
value = value ? FALSE : TRUE;
gegl_node_set (node, propname, value, NULL);
+ renderer_dirty++;
}
@@ -857,6 +935,23 @@ static void entry_pressed (MrgEvent *event, void *data1, void *data2)
static void run_command (MrgEvent *event, void *data1, void *data2);
+
+static void queue_thumb (const char *path, const char *thumbpath)
+{
+ ThumbQueueItem *item;
+ for (MrgList *l = thumb_queue; l; l=l->next)
+ {
+ item = l->data;
+ if (!strcmp (item->thumbpath, thumbpath))
+ return;
+ }
+ item = calloc (sizeof (ThumbQueueItem), 1);
+ item->path = strdup (path);
+ item->thumbpath = strdup (thumbpath);
+ mrg_list_append (&thumb_queue, item);
+ fprintf (stderr, "for %s wanted %s\n", path, thumbpath);
+}
+
static void ui_dir_viewer (State *o)
{
Mrg *mrg = o->mrg;
@@ -905,25 +1000,31 @@ static void ui_dir_viewer (State *o)
}
else
{
- fprintf (stderr, "for %s wanted %s\n", path, thumbpath);
+ queue_thumb (path, thumbpath);
}
g_free (thumbpath);
mrg_set_xy (mrg, x, y + dim - mrg_em(mrg));
+
+// fprintf (stderr, "%s\n", lastslash+1);
mrg_printf (mrg, "%s\n", lastslash+1);
cairo_new_path (mrg_cr(mrg));
cairo_rectangle (mrg_cr(mrg), x, y, dim, dim);
+ cairo_set_source_rgb (mrg_cr(mrg), 1, 0,0);
+ cairo_stroke_preserve (mrg_cr(mrg));
mrg_listen_full (mrg, MRG_CLICK, entry_pressed, o, path, NULL, NULL);
cairo_new_path (mrg_cr(mrg));
- y += dim;
- if (y+dim > mrg_height (mrg))
+ x += dim;
+ if (x+dim > mrg_width (mrg))
{
- y = 0;
- x += dim;
+ x = 0;
+ y += dim;
}
}
cairo_restore (cr);
+#if 0
+ cairo_save (cr);
cairo_scale (cr, mrg_width(mrg), mrg_height(mrg));
cairo_new_path (cr);
@@ -952,9 +1053,11 @@ static void ui_dir_viewer (State *o)
cairo_rectangle (cr, 0.8, 0.8, 0.2, 0.2);
mrg_listen (mrg, MRG_PRESS, run_command, "dir-pgdn", NULL);
cairo_new_path (cr);
+ cairo_restore (cr);
mrg_add_binding (mrg, "left", NULL, NULL, run_command, "dir-pgup");
- mrg_add_binding (mrg, "right", NULL, NULL, run_command, "dir-pgndn");
+ mrg_add_binding (mrg, "right", NULL, NULL, run_command, "dir-pgdn");
+#endif
}
static int slide_cb (Mrg *mrg, void *data)
@@ -1139,6 +1242,7 @@ static void node_remove (MrgEvent *e, void *data1, void *data2)
o->active = new_active;
mrg_queue_draw (o->mrg, NULL);
+ renderer_dirty++;
}
int cmd_node_add_aux(COMMAND_ARGS);
@@ -1163,6 +1267,7 @@ int cmd_node_add_aux (COMMAND_ARGS) /* "node-add-aux", 0, "", ""*/
mrg_set_cursor_pos (o->mrg, 0);
o->new_opname[0]=0;
fprintf (stderr, "add aux\n");
+ renderer_dirty++;
mrg_queue_draw (o->mrg, NULL);
return 0;
}
@@ -1188,6 +1293,7 @@ int cmd_node_add_input (COMMAND_ARGS) /* "node-add-input", 0, "", ""*/
mrg_set_cursor_pos (o->mrg, 0);
o->new_opname[0]=0;
fprintf (stderr, "add input\n");
+ renderer_dirty++;
mrg_queue_draw (o->mrg, NULL);
return 0;
}
@@ -1206,6 +1312,7 @@ static GeglNode *add_aux (State *o, GeglNode *active, const char *optype)
gegl_node_link_many (producer, ret, NULL);
}
gegl_node_connect_to (ret, "output", ref, "aux");
+ renderer_dirty++;
return ret;
}
@@ -1224,6 +1331,7 @@ static GeglNode *add_output (State *o, GeglNode *active, const char *optype)
gegl_node_link_many (ref, ret, NULL);
gegl_node_connect_to (ret, "output", consumer, consumer_name);
}
+ renderer_dirty++;
return ret;
}
@@ -1687,8 +1795,9 @@ run_command (MrgEvent *event, void *data1, void *data_2)
* mode is used.
*/
- printf ("%s\n", commandline);
- mrg_event_stop_propagate (event);
+ //printf ("%s\n", commandline);
+ if (event)
+ mrg_event_stop_propagate (event);
if (argvs_command_exist (argv[0]))
{
@@ -1916,6 +2025,7 @@ run_command (MrgEvent *event, void *data1, void *data_2)
}
arg++;
}
+ renderer_dirty++;
}
g_strfreev (argv);
@@ -1956,7 +2066,7 @@ int cmd_pick (COMMAND_ARGS) /* "pick", 0, "", "changes to pick tool"*/
int cmd_tpan (COMMAND_ARGS);
int cmd_tpan (COMMAND_ARGS) /* "tpan", 0, "", "changes to pan tool"*/
{
- tool = TOOL_PICK;
+ tool = TOOL_PAN;
return 0;
}
@@ -1995,8 +2105,9 @@ static void iterate_frame (State *o)
o->frame_no = 0;
gegl_node_set (o->source, "frame", o->frame_no, NULL);
o->prev_ms = mrg_ms (mrg);
+ renderer_dirty++;
}
- mrg_queue_draw (o->mrg, NULL);
+ mrg_queue_draw (o->mrg, NULL);
}
else if (o->is_video)
{
@@ -2007,6 +2118,7 @@ static void iterate_frame (State *o)
if (o->frame_no >= frames)
o->frame_no = 0;
gegl_node_set (o->source, "frame", o->frame_no, NULL);
+ renderer_dirty++;
mrg_queue_draw (o->mrg, NULL);
{
GeglAudioFragment *audio = NULL;
@@ -2325,9 +2437,6 @@ static void load_path (State *o)
}
path = o->path;
- fprintf (stderr, "%i %i\n", is_gegl_path(o->path), is_gegl_path(o->save_path));
- fprintf (stderr, "%s %s\n", o->path, o->save_path);
-
if (access (o->save_path, F_OK) != -1)
{
/* XXX : fix this in the fuse layer of zn! XXX XXX XXX XXX */
@@ -2353,11 +2462,13 @@ static void load_path (State *o)
"operation", "gegl:nop", NULL);
o->source = gegl_node_new_child (o->gegl,
"operation", "gegl:gif-load", "path", path, "frame", o->frame_no, NULL);
+ o->playing = 1;
gegl_node_link_many (o->source, o->sink, NULL);
}
else if (gegl_str_has_video_suffix (path))
{
o->is_video = 1;
+ o->playing = 1;
o->gegl = gegl_node_new ();
o->sink = gegl_node_new_child (o->gegl,
"operation", "gegl:nop", NULL);
@@ -2392,6 +2503,7 @@ static void load_path (State *o)
{
o->source = gegl_node_new_child (o->gegl,
"operation", "gegl:gif-load", "path", path, "frame", o->frame_no, NULL);
+ o->playing = 1;
gegl_node_link_many (o->source, prev, NULL);
}
else
@@ -2447,8 +2559,7 @@ static void load_path (State *o)
zoom_to_fit (o);
}
}
-
- o->playing = o->is_video;
+
if (o->ops)
{
GeglNode *ret_sink = NULL;
@@ -2476,7 +2587,7 @@ static void load_path (State *o)
if (o->processor)
g_object_unref (o->processor);
o->processor = gegl_node_new_processor (o->sink, NULL);
-
+ renderer_dirty++;
mrg_queue_draw (o->mrg, NULL);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]