[gegl] bin: give names to states in renderer_task and recurse some states
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] bin: give names to states in renderer_task and recurse some states
- Date: Wed, 15 May 2019 09:41:33 +0000 (UTC)
commit b5825bcb8a4c45324035982a89d6c292fba29044
Author: Øyvind Kolås <pippin gimp org>
Date: Wed May 15 00:19:00 2019 +0200
bin: give names to states in renderer_task and recurse some states
By recursing through the states in the render path we execute all the non-core
parts serially at a slightly higher efficiency than returning to the main loop.
bin/ui-core.c | 255 +++++++++++++++++++++++++++++++---------------------------
1 file changed, 137 insertions(+), 118 deletions(-)
---
diff --git a/bin/ui-core.c b/bin/ui-core.c
index c74d9a472..0a6f6201d 100644
--- a/bin/ui-core.c
+++ b/bin/ui-core.c
@@ -793,7 +793,26 @@ store_index (GeState *state, const char *path);
static void load_path_inner (GeState *o, char *path);
-gchar *pos_hash (GeState *o);
+static gchar *pos_hash (GeState *o)
+{
+ GChecksum *hash;
+ char *ret;
+ gchar *frame_recipe;
+ frame_recipe = gegl_serialize (NULL, o->sink, NULL, GEGL_SERIALIZE_BAKE_ANIM);
+ hash = g_checksum_new (G_CHECKSUM_MD5);
+ g_checksum_update (hash, (void*)frame_recipe, -1);
+ g_checksum_update (hash, (void*)o->src_path, -1); /*
+ we add this in to make the identical source-buffer based recipies hash to different results
+ for now this hack doesn't matter since the frame_recipe is unused
+ would be better to rely only on hash of recipe and have recipe be complete thus using real gegl:load
+ */
+ ret = g_strdup (g_checksum_get_string(hash));
+ g_checksum_free (hash);
+ //fprintf (stderr, "{%s}\n\n", frame_recipe);
+ g_free (frame_recipe);
+ return ret;
+}
+
static int has_quit = 0;
static gboolean renderer_task (gpointer data)
@@ -806,24 +825,27 @@ static gboolean renderer_task (gpointer data)
static GeglAudioFragment *cached_audio = NULL;
+#define TASK_BASE 0
+#define TASK_RENDER 1
+#define TASK_RENDER_DONE 2
+#define TASK_THUMB 3
+#define TASK_PCM_FRAME_CACHE 4
+
switch (o->renderer_state)
{
- case 0:
+ case TASK_BASE:
if (renderer == GEGL_RENDERER_BLIT||
renderer == GEGL_RENDERER_BLIT_MIPMAP)
{
- o->renderer_state = 4;
+ o->renderer_state = TASK_THUMB;
break;
}
if (renderer_dirty)
{
renderer_dirty = 0;
- if (o->cached_buffer)
- {
- g_object_unref (o->cached_buffer);
- o->cached_buffer = NULL;
- }
+
+ g_clear_object (&o->cached_buffer);
if (o->processor_node != o->sink)
{
o->processor = gegl_node_new_processor (o->sink, NULL);
@@ -837,25 +859,18 @@ static gboolean renderer_task (gpointer data)
gegl_processor_set_rectangle (o->processor, &rect);
}
}
- o->renderer_state = 1;
+ o->renderer_state = TASK_RENDER;
if (hash)
g_free (hash);
- hash = pos_hash (o);
+ hash = NULL;
g_clear_object (&cached_audio);
//if (o->frame_cache)
+ /* we always check for cache - this makes the cache kick-in when turned off but cached entries are
valid */
{
char path[1024];
- sprintf (path, "/tmp/gegl/%s", hash);
- if (g_file_test (path, G_FILE_TEST_EXISTS))
- {
- if (o->cached_buffer)
- g_object_unref (o->cached_buffer);
- o->cached_buffer = gegl_buffer_open (path); /* maybe load is faster? */
- fprintf (stderr, "!");
- o->renderer_state = 3;
- }
+ hash = pos_hash (o);
sprintf (path, "/tmp/gegl/%s.pcm", hash);
if (g_file_test (path, G_FILE_TEST_EXISTS))
{
@@ -875,80 +890,102 @@ static gboolean renderer_task (gpointer data)
{
case '\0':case ' ':
if (word->len > 0)
- {
- switch (element_no++)
- {
- case 0:
- gegl_audio_fragment_set_sample_rate (cached_audio, g_strtod (word->str, NULL));
- break;
- case 1:
- channels = g_strtod (word->str, NULL);
- gegl_audio_fragment_set_channels (cached_audio, channels);
- break;
- case 2:
- gegl_audio_fragment_set_channel_layout (cached_audio, g_strtod (word->str, NULL));
- break;
- case 3:
- gegl_audio_fragment_set_sample_count (cached_audio, g_strtod (word->str, NULL));
- break;
- default:
- {
- int sample_no = element_no - 4;
- int channel_no = sample_no % channels;
- sample_no/=2;
- if (sample_no < max_samples)
- cached_audio->data[channel_no][sample_no] = g_strtod (word->str, NULL);
- }
- break;
- }
- }
-
- g_string_assign (word, "");
- break;
- default:
- g_string_append_c (word, p[0]);
- break;
- }
- }
- g_string_free (word, TRUE);
-
-
+ {
+ switch (element_no++)
+ {
+ case 0:
+ gegl_audio_fragment_set_sample_rate (cached_audio, g_strtod (word->str, NULL));
+ break;
+ case 1:
+ channels = g_strtod (word->str, NULL);
+ gegl_audio_fragment_set_channels (cached_audio, channels);
+ break;
+ case 2:
+ gegl_audio_fragment_set_channel_layout (cached_audio, g_strtod (word->str, NULL));
+ break;
+ case 3:
+ gegl_audio_fragment_set_sample_count (cached_audio, g_strtod (word->str, NULL));
+ break;
+ default:
+ {
+ int sample_no = element_no - 4;
+ int channel_no = sample_no % channels;
+ sample_no/=2;
+ if (sample_no < max_samples)
+ cached_audio->data[channel_no][sample_no] = g_strtod (word->str, NULL);
+ }
+ break;
+ }
+ }
+ g_string_assign (word, "");
+ break;
+ default:
+ g_string_append_c (word, p[0]);
+ break;
+ }
+ }
+ g_string_free (word, TRUE);
g_free (contents);
}
}
-
+ sprintf (path, "/tmp/gegl/%s", hash);
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ {
+ if (o->cached_buffer)
+ g_object_unref (o->cached_buffer);
+ o->cached_buffer = gegl_buffer_open (path);
+ /* maybe load is faster? */
+ o->renderer_state = TASK_RENDER_DONE;
+ renderer_task (o);
+ }
}
}
else
+ {
if (thumb_queue)
{
- o->renderer_state = 4;
- break;
+ o->renderer_state = TASK_THUMB;
}
else
- g_usleep (4000);
- //break; // fallthrough
- case 1:
+ {
+ g_usleep (4000);
+ o->renderer_state = TASK_BASE;
+ }
+ }
+
+
+ if (o->renderer_state == TASK_RENDER)
+ renderer_task (o); /* recursively invoke next state in same iteration of task */
+
+
+ break;
+ case TASK_RENDER:
if (o->cached_buffer)
{
if (o->renderer_state)
- o->renderer_state = 3;
+ {
+ o->renderer_state = TASK_RENDER_DONE;
+ renderer_task (o);
+ }
}
else
{
if (gegl_processor_work (o->processor, &progress))
{
if (o->renderer_state)
- o->renderer_state = 1;
+ o->renderer_state = TASK_RENDER;
}
else
{
if (o->renderer_state)
- o->renderer_state = 3;
+ {
+ o->renderer_state = TASK_RENDER_DONE;
+ renderer_task (o);
+ }
}
}
break;
- case 3:
+ case TASK_RENDER_DONE:
mrg_gegl_dirty ();
switch (renderer)
{
@@ -961,13 +998,15 @@ static gboolean renderer_task (gpointer data)
break;
}
-
if ((o->frame_cache && !o->cached_buffer) || o->is_video )
- o->renderer_state = 5;
+ {
+ o->renderer_state = TASK_PCM_FRAME_CACHE;
+ renderer_task (o);
+ }
else
- o->renderer_state = 0;
+ o->renderer_state = TASK_BASE;
break;
- case 4:
+ case TASK_THUMB:
if (thumb_queue)
{
@@ -1011,11 +1050,11 @@ static gboolean renderer_task (gpointer data)
g_usleep (1000);
}
- o->renderer_state = 0;
+ o->renderer_state = TASK_BASE;
break;
- case 5:
+ case TASK_PCM_FRAME_CACHE:
if (o->frame_cache && !o->cached_buffer) // store cached render of frame
{
char path[1024];
@@ -1073,33 +1112,32 @@ static gboolean renderer_task (gpointer data)
}
}
- if (audio != cached_audio && o->frame_cache) {
- int i, c;
- GString *str = g_string_new ("");
- int sample_count = gegl_audio_fragment_get_sample_count (audio);
- int channels = gegl_audio_fragment_get_channels (audio);
- char path[1024];
- sprintf (path, "/tmp/gegl/%s.pcm", hash);
-
- g_string_append_printf (str, "%i %i %i %i",
- gegl_audio_fragment_get_sample_rate (audio),
- gegl_audio_fragment_get_channels (audio),
- gegl_audio_fragment_get_channel_layout (audio),
- gegl_audio_fragment_get_sample_count (audio));
-
- for (i = 0; i < sample_count; i++)
- for (c = 0; c < channels; c++)
- g_string_append_printf (str, " %0.5f", audio->data[c][i]);
-
- g_file_set_contents (path, str->str, -1, NULL);
- g_string_free (str, TRUE);
-
+ if (audio != cached_audio && o->frame_cache)
+ {
+ int i, c;
+ GString *str = g_string_new ("");
+ int sample_count = gegl_audio_fragment_get_sample_count (audio);
+ int channels = gegl_audio_fragment_get_channels (audio);
+ char path[1024];
+ sprintf (path, "/tmp/gegl/%s.pcm", hash);
+
+ g_string_append_printf (str, "%i %i %i %i",
+ gegl_audio_fragment_get_sample_rate (audio),
+ gegl_audio_fragment_get_channels (audio),
+ gegl_audio_fragment_get_channel_layout (audio),
+ gegl_audio_fragment_get_sample_count (audio));
+
+ for (i = 0; i < sample_count; i++)
+ for (c = 0; c < channels; c++)
+ g_string_append_printf (str, " %0.5f", audio->data[c][i]);
+
+ g_file_set_contents (path, str->str, -1, NULL);
+ g_string_free (str, TRUE);
}
-
g_object_unref (audio);
}
}
- o->renderer_state = 0;
+ o->renderer_state = TASK_BASE;
break;
}
@@ -1286,7 +1324,7 @@ int mrg_ui_main (int argc, char **argv, char **ops)
return 0;
}
-static void set_clip_position (GeState *o, double position)
+void set_clip_position (GeState *o, double position)
{
position = ceilf(position * o->fps) / o->fps; // quantize position
@@ -1519,7 +1557,7 @@ static void on_pan_drag (MrgEvent *e, void *data1, void *data2)
}
}
- o->renderer_state = 0;
+ o->renderer_state = TASK_BASE;
queue_draw (o);
mrg_event_stop_propagate (e);
}
@@ -4461,26 +4499,6 @@ static void do_commandline_run (MrgEvent *event, void *data1, void *data2)
mrg_event_stop_propagate (event);
}
-gchar *pos_hash (GeState *o)
-{
- GChecksum *hash;
- char *ret;
- gchar *frame_recipe;
- frame_recipe = gegl_serialize (NULL, o->sink, NULL, GEGL_SERIALIZE_BAKE_ANIM);
- hash = g_checksum_new (G_CHECKSUM_MD5);
- g_checksum_update (hash, (void*)frame_recipe, -1);
- g_checksum_update (hash, (void*)o->src_path, -1); /*
- we add this in to make the identical source-buffer based recipies hash to different results
- for now this hack doesn't matter since the frame_recipe is unused
- would be better to rely only on hash of recipe and have recipe be complete thus using real gegl:load
- */
- ret = g_strdup (g_checksum_get_string(hash));
- g_checksum_free (hash);
- fprintf (stderr, "{%s}\n\n", frame_recipe);
- g_free (frame_recipe);
- return ret;
-}
-
static void iterate_frame (GeState *o)
{
Mrg *mrg = o->mrg;
@@ -5655,6 +5673,7 @@ char *ui_suffix_path (const char *path)
return ret;
}
+
static int is_gegl_path (const char *path)
{
int ret = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]