[gimp/gtk3-port: 226/229] app: port projection chunk rendering to a frame clock tick callback
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gtk3-port: 226/229] app: port projection chunk rendering to a frame clock tick callback
- Date: Fri, 2 Aug 2013 19:10:49 +0000 (UTC)
commit 4e49caa65e4f5baae492678f918ec411b3ccbf63
Author: Michael Natterer <mitch gimp org>
Date: Mon Jul 29 09:12:58 2013 +0200
app: port projection chunk rendering to a frame clock tick callback
app/core/gimpprojection.c | 89 +++++++++++++++++++++++++++++------
app/core/gimpprojection.h | 40 ++++++++++++----
app/display/gimpdisplay-handlers.c | 57 +++++++++++++++++++----
3 files changed, 151 insertions(+), 35 deletions(-)
---
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 7708b76..71c12ff 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -36,10 +36,6 @@
#include "gimpprojection.h"
-/* halfway between G_PRIORITY_HIGH_IDLE and G_PRIORITY_DEFAULT_IDLE */
-#define GIMP_PROJECTION_IDLE_PRIORITY ((G_PRIORITY_HIGH_IDLE + \
- G_PRIORITY_DEFAULT_IDLE) / 2)
-
/* chunk size for one iteration of the chunk renderer */
#define GIMP_PROJECTION_CHUNK_WIDTH 256
#define GIMP_PROJECTION_CHUNK_HEIGHT 128
@@ -84,7 +80,9 @@ static void gimp_projection_flush_whenever (GimpProjection *proj,
gboolean now);
static void gimp_projection_chunk_render_start (GimpProjection *proj);
static void gimp_projection_chunk_render_stop (GimpProjection *proj);
-static gboolean gimp_projection_chunk_render_callback (gpointer data);
+static gboolean gimp_projection_chunk_render_tick (gpointer unused1,
+ gpointer unused2,
+ GimpProjection *proj);
static void gimp_projection_chunk_render_init (GimpProjection *proj);
static gboolean gimp_projection_chunk_render_iteration(GimpProjection *proj);
static gboolean gimp_projection_chunk_render_next_area(GimpProjection *proj);
@@ -172,6 +170,9 @@ gimp_projection_finalize (GObject *object)
if (proj->chunk_render.running)
gimp_projection_chunk_render_stop (proj);
+ g_list_free (proj->tick_sources);
+ proj->tick_sources = NULL;
+
gimp_area_list_free (proj->update_areas);
proj->update_areas = NULL;
@@ -388,6 +389,53 @@ gimp_projection_finish_draw (GimpProjection *proj)
}
}
+void
+gimp_projection_add_tick_source (GimpProjection *proj,
+ GimpObject *source,
+ GimpAddTickFunc add_func,
+ GimpRemoveTickFunc remove_func)
+{
+ g_return_if_fail (GIMP_IS_PROJECTION (proj));
+ g_return_if_fail (GIMP_IS_OBJECT (source));
+ g_return_if_fail (add_func != NULL);
+ g_return_if_fail (remove_func != NULL);
+
+ proj->tick_sources = g_list_append (proj->tick_sources, source);
+
+ /* need only one func strorage, they are the same for all sources */
+ proj->add_tick_func = add_func;
+ proj->remove_tick_func = remove_func;
+}
+
+void
+gimp_projection_remove_tick_source (GimpProjection *proj,
+ GimpObject *source)
+{
+ gboolean running;
+
+ g_return_if_fail (GIMP_IS_PROJECTION (proj));
+ g_return_if_fail (GIMP_IS_OBJECT (source));
+
+ running = (proj->chunk_render.running &&
+ source == proj->chunk_render_tick_source);
+
+ if (running)
+ gimp_projection_chunk_render_stop (proj);
+
+ proj->tick_sources = g_list_remove (proj->tick_sources, source);
+
+ if (! proj->tick_sources)
+ {
+ proj->add_tick_func = NULL;
+ proj->remove_tick_func = NULL;
+ }
+
+ if (running && proj->tick_sources)
+ {
+ gimp_projection_chunk_render_start (proj);
+ }
+}
+
/* private functions */
@@ -489,11 +537,14 @@ static void
gimp_projection_chunk_render_start (GimpProjection *proj)
{
g_return_if_fail (proj->chunk_render.running == FALSE);
+ g_return_if_fail (proj->tick_sources != NULL);
+
+ proj->chunk_render_tick_source = proj->tick_sources->data;
- proj->chunk_render_idle_id =
- g_idle_add_full (GIMP_PROJECTION_IDLE_PRIORITY,
- gimp_projection_chunk_render_callback, proj,
- NULL);
+ proj->chunk_render_tick_id =
+ proj->add_tick_func (proj->chunk_render_tick_source,
+ gimp_projection_chunk_render_tick,
+ proj);
proj->chunk_render.running = TRUE;
}
@@ -503,17 +554,20 @@ gimp_projection_chunk_render_stop (GimpProjection *proj)
{
g_return_if_fail (proj->chunk_render.running == TRUE);
- g_source_remove (proj->chunk_render_idle_id);
- proj->chunk_render_idle_id = 0;
+ proj->remove_tick_func (proj->chunk_render_tick_source,
+ proj->chunk_render_tick_id);
+
+ proj->chunk_render_tick_source = NULL;
+ proj->chunk_render_tick_id = 0;
proj->chunk_render.running = FALSE;
}
static gboolean
-gimp_projection_chunk_render_callback (gpointer data)
+gimp_projection_chunk_render_tick (gpointer unused1,
+ gpointer unused2,
+ GimpProjection *proj)
{
- GimpProjection *proj = data;
-
if (! gimp_projection_chunk_render_iteration (proj))
{
gimp_projection_chunk_render_stop (proj);
@@ -571,9 +625,12 @@ gimp_projection_chunk_render_init (GimpProjection *proj)
return;
}
- gimp_projection_chunk_render_next_area (proj);
+ if (proj->tick_sources)
+ {
+ gimp_projection_chunk_render_next_area (proj);
- gimp_projection_chunk_render_start (proj);
+ gimp_projection_chunk_render_start (proj);
+ }
}
}
diff --git a/app/core/gimpprojection.h b/app/core/gimpprojection.h
index 1b9b2d8..3c362b4 100644
--- a/app/core/gimpprojection.h
+++ b/app/core/gimpprojection.h
@@ -22,6 +22,16 @@
#include "gimpobject.h"
+typedef gboolean (* GimpTickCallback) (gpointer unused1,
+ gpointer unused2,
+ GimpProjection *proj);
+typedef guint (* GimpAddTickFunc) (GimpObject *source,
+ GimpTickCallback callback,
+ gpointer user_data);
+typedef void (* GimpRemoveTickFunc) (GimpObject *source,
+ guint id);
+
+
typedef struct _GimpProjectionChunkRender GimpProjectionChunkRender;
struct _GimpProjectionChunkRender
@@ -59,7 +69,12 @@ struct _GimpProjection
GSList *update_areas;
GimpProjectionChunkRender chunk_render;
- guint chunk_render_idle_id;
+ GimpObject *chunk_render_tick_source;
+ guint chunk_render_tick_id;
+
+ GList *tick_sources;
+ GimpAddTickFunc add_tick_func;
+ GimpRemoveTickFunc remove_tick_func;
gboolean invalidate_preview;
};
@@ -79,16 +94,23 @@ struct _GimpProjectionClass
GType gimp_projection_get_type (void) G_GNUC_CONST;
-GimpProjection * gimp_projection_new (GimpProjectable *projectable);
+GimpProjection * gimp_projection_new (GimpProjectable *projectable);
+
+void gimp_projection_flush (GimpProjection *proj);
+void gimp_projection_flush_now (GimpProjection *proj);
+void gimp_projection_finish_draw (GimpProjection *proj);
-void gimp_projection_flush (GimpProjection *proj);
-void gimp_projection_flush_now (GimpProjection *proj);
-void gimp_projection_finish_draw (GimpProjection *proj);
+void gimp_projection_add_tick_source (GimpProjection *proj,
+ GimpObject *source,
+ GimpAddTickFunc add_func,
+ GimpRemoveTickFunc remove_func);
+void gimp_projection_remove_tick_source (GimpProjection *proj,
+ GimpObject *source);
-gint64 gimp_projection_estimate_memsize (GimpImageBaseType type,
- GimpPrecision precision,
- gint width,
- gint height);
+gint64 gimp_projection_estimate_memsize (GimpImageBaseType type,
+ GimpPrecision precision,
+ gint width,
+ gint height);
#endif /* __GIMP_PROJECTION_H__ */
diff --git a/app/display/gimpdisplay-handlers.c b/app/display/gimpdisplay-handlers.c
index 4539f07..5d92541 100644
--- a/app/display/gimpdisplay-handlers.c
+++ b/app/display/gimpdisplay-handlers.c
@@ -23,23 +23,31 @@
#include "display-types.h"
#include "core/gimpimage.h"
+#include "core/gimpprojection.h"
#include "gimpdisplay.h"
#include "gimpdisplay-handlers.h"
+#include "gimpdisplayshell.h"
/* local function prototypes */
-static void gimp_display_update_handler (GimpProjection *projection,
- gboolean now,
- gint x,
- gint y,
- gint w,
- gint h,
- GimpDisplay *display);
-static void gimp_display_flush_handler (GimpImage *image,
- gboolean invalidate_preview,
- GimpDisplay *display);
+static void gimp_display_update_handler (GimpProjection *projection,
+ gboolean now,
+ gint x,
+ gint y,
+ gint w,
+ gint h,
+ GimpDisplay *display);
+static void gimp_display_flush_handler (GimpImage *image,
+ gboolean invalidate_preview,
+ GimpDisplay *display);
+
+static guint gimp_display_add_tick_callback (GimpObject *source,
+ GimpTickCallback callback,
+ gpointer user_data);
+static void gimp_display_remove_tick_callback (GimpObject *source,
+ guint id);
/* public functions */
@@ -62,6 +70,11 @@ gimp_display_connect (GimpDisplay *display)
g_signal_connect (image, "flush",
G_CALLBACK (gimp_display_flush_handler),
display);
+
+ gimp_projection_add_tick_source (gimp_image_get_projection (image),
+ GIMP_OBJECT (display),
+ gimp_display_add_tick_callback,
+ gimp_display_remove_tick_callback);
}
void
@@ -75,6 +88,9 @@ gimp_display_disconnect (GimpDisplay *display)
g_return_if_fail (GIMP_IS_IMAGE (image));
+ gimp_projection_remove_tick_source (gimp_image_get_projection (image),
+ GIMP_OBJECT (display));
+
g_signal_handlers_disconnect_by_func (image,
gimp_display_flush_handler,
display);
@@ -106,3 +122,24 @@ gimp_display_flush_handler (GimpImage *image,
{
gimp_display_flush (display);
}
+
+static guint
+gimp_display_add_tick_callback (GimpObject *source,
+ GimpTickCallback callback,
+ gpointer user_data)
+{
+ GimpDisplayShell *shell = gimp_display_get_shell (GIMP_DISPLAY (source));
+
+ return gtk_widget_add_tick_callback (shell->canvas,
+ (GtkTickCallback) callback,
+ user_data, NULL);
+}
+
+static void
+gimp_display_remove_tick_callback (GimpObject *source,
+ guint id)
+{
+ GimpDisplayShell *shell = gimp_display_get_shell (GIMP_DISPLAY (source));
+
+ gtk_widget_remove_tick_callback (shell->canvas, id);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]