[gimp] app: optimize away redundant and expensive text layer re-rendering
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: optimize away redundant and expensive text layer re-rendering
- Date: Tue, 2 Mar 2010 17:44:03 +0000 (UTC)
commit 9c4864e789b05b294e5d56e59eb1e9f610150658
Author: Michael Natterer <mitch gimp org>
Date: Tue Mar 2 17:44:31 2010 +0100
app: optimize away redundant and expensive text layer re-rendering
- Add signal GimpText::changed() and emit it from
GObject::dispatch_properties_changed() after all notifications have
been emitted, so "changed" is emitted only once for any number of
properties set within a g_object_freeze/thaw_notify() pair.
- Connect GimpTextLayer to "changed" instead of "notify" so we aviod
lots of expensive re-rendering when multiple properties are set
at once.
- Connect GimpTextTool to "notify" *and* "changed", and move some
common code to the "changed" callback (e.g. we don't need to
re-frame the item for each set property).
app/text/gimptext.c | 63 +++++++++++++++++++++++++++++++++++-----------
app/text/gimptext.h | 2 +
app/text/gimptextlayer.c | 14 ++++++---
app/tools/gimptexttool.c | 36 ++++++++++++++++++++++----
4 files changed, 89 insertions(+), 26 deletions(-)
---
diff --git a/app/text/gimptext.c b/app/text/gimptext.c
index 78843db..117ed94 100644
--- a/app/text/gimptext.c
+++ b/app/text/gimptext.c
@@ -32,6 +32,7 @@
#include "text-types.h"
+#include "core/gimpmarshal.h"
#include "core/gimpstrokeoptions.h"
#include "core/gimp-utils.h"
@@ -69,18 +70,27 @@ enum
PROP_HINTING
};
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
+};
-static void gimp_text_finalize (GObject *object);
-static void gimp_text_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-static void gimp_text_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static gint64 gimp_text_get_memsize (GimpObject *object,
- gint64 *gui_size);
+
+static void gimp_text_finalize (GObject *object);
+static void gimp_text_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_text_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_text_dispatch_properties_changed (GObject *object,
+ guint n_pspecs,
+ GParamSpec **pspecs);
+static gint64 gimp_text_get_memsize (GimpObject *object,
+ gint64 *gui_size);
G_DEFINE_TYPE_WITH_CODE (GimpText, gimp_text, GIMP_TYPE_OBJECT,
@@ -88,6 +98,8 @@ G_DEFINE_TYPE_WITH_CODE (GimpText, gimp_text, GIMP_TYPE_OBJECT,
#define parent_class gimp_text_parent_class
+static guint text_signals[LAST_SIGNAL] = { 0 };
+
static void
gimp_text_class_init (GimpTextClass *klass)
@@ -98,11 +110,21 @@ gimp_text_class_init (GimpTextClass *klass)
GimpMatrix2 identity;
gchar *language;
- object_class->finalize = gimp_text_finalize;
- object_class->get_property = gimp_text_get_property;
- object_class->set_property = gimp_text_set_property;
+ text_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpTextClass, changed),
+ NULL, NULL,
+ gimp_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ object_class->finalize = gimp_text_finalize;
+ object_class->get_property = gimp_text_get_property;
+ object_class->set_property = gimp_text_set_property;
+ object_class->dispatch_properties_changed = gimp_text_dispatch_properties_changed;
- gimp_object_class->get_memsize = gimp_text_get_memsize;
+ gimp_object_class->get_memsize = gimp_text_get_memsize;
gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
gimp_matrix2_identity (&identity);
@@ -480,6 +502,17 @@ gimp_text_set_property (GObject *object,
}
}
+static void
+gimp_text_dispatch_properties_changed (GObject *object,
+ guint n_pspecs,
+ GParamSpec **pspecs)
+{
+ G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object,
+ n_pspecs, pspecs);
+
+ g_signal_emit (object, text_signals[CHANGED], 0);
+}
+
static gint64
gimp_text_get_memsize (GimpObject *object,
gint64 *gui_size)
diff --git a/app/text/gimptext.h b/app/text/gimptext.h
index 27048ac..466f825 100644
--- a/app/text/gimptext.h
+++ b/app/text/gimptext.h
@@ -70,6 +70,8 @@ struct _GimpText
struct _GimpTextClass
{
GimpObjectClass parent_class;
+
+ void (* changed) (GimpText *text);
};
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index a988c4d..e1edb1a 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -97,7 +97,7 @@ static void gimp_text_layer_push_undo (GimpDrawable *drawable,
gint width,
gint height);
-static void gimp_text_layer_text_notify (GimpTextLayer *layer);
+static void gimp_text_layer_text_changed (GimpTextLayer *layer);
static gboolean gimp_text_layer_render (GimpTextLayer *layer);
static void gimp_text_layer_render_layout (GimpTextLayer *layer,
GimpTextLayout *layout);
@@ -351,6 +351,8 @@ gimp_text_layer_push_undo (GimpDrawable *drawable,
}
+/* public functions */
+
/**
* gimp_text_layer_new:
* @image: the #GimpImage the layer should belong to
@@ -404,7 +406,7 @@ gimp_text_layer_set_text (GimpTextLayer *layer,
if (layer->text)
{
g_signal_handlers_disconnect_by_func (layer->text,
- G_CALLBACK (gimp_text_layer_text_notify),
+ G_CALLBACK (gimp_text_layer_text_changed),
layer);
g_object_unref (layer->text);
@@ -415,8 +417,8 @@ gimp_text_layer_set_text (GimpTextLayer *layer,
{
layer->text = g_object_ref (text);
- g_signal_connect_object (text, "notify",
- G_CALLBACK (gimp_text_layer_text_notify),
+ g_signal_connect_object (text, "changed",
+ G_CALLBACK (gimp_text_layer_text_changed),
layer, G_CONNECT_SWAPPED);
}
@@ -511,8 +513,10 @@ gimp_drawable_is_text_layer (GimpDrawable *drawable)
}
+/* private functions */
+
static void
-gimp_text_layer_text_notify (GimpTextLayer *layer)
+gimp_text_layer_text_changed (GimpTextLayer *layer)
{
/* If the text layer was created from a parasite, it's time to
* remove that parasite now.
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index a82d1cd..f90fdc2 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -143,9 +143,13 @@ static void gimp_text_tool_layer_notify (GimpTextLayer *layer,
static void gimp_text_tool_proxy_notify (GimpText *text,
GParamSpec *pspec,
GimpTextTool *text_tool);
+
static void gimp_text_tool_text_notify (GimpText *text,
GParamSpec *pspec,
GimpTextTool *text_tool);
+static void gimp_text_tool_text_changed (GimpText *text,
+ GimpTextTool *text_tool);
+
static gboolean gimp_text_tool_idle_apply (GimpTextTool *text_tool);
static void gimp_text_tool_apply (GimpTextTool *text_tool);
@@ -738,7 +742,6 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
gimp_text_tool_draw_selection (draw_tool,
logical_offset_x, logical_offset_y);
-
}
else
{
@@ -930,6 +933,9 @@ gimp_text_tool_connect (GimpTextTool *text_tool,
g_signal_handlers_disconnect_by_func (text_tool->text,
gimp_text_tool_text_notify,
text_tool);
+ g_signal_handlers_disconnect_by_func (text_tool->text,
+ gimp_text_tool_text_changed,
+ text_tool);
if (text_tool->pending)
gimp_text_tool_apply (text_tool);
@@ -963,6 +969,9 @@ gimp_text_tool_connect (GimpTextTool *text_tool,
g_signal_connect (text, "notify",
G_CALLBACK (gimp_text_tool_text_notify),
text_tool);
+ g_signal_connect (text, "changed",
+ G_CALLBACK (gimp_text_tool_text_changed),
+ text_tool);
}
g_signal_handlers_unblock_by_func (text_tool->buffer,
@@ -1048,11 +1057,6 @@ gimp_text_tool_text_notify (GimpText *text,
g_value_unset (&value);
}
- /* we need to redraw the rectangle in any case because whatever
- * changes to the text can change its size
- */
- gimp_text_tool_frame_item (text_tool);
-
/* if the text has changed, (probably because of an undo), we put
* the new text into the text buffer
*/
@@ -1073,6 +1077,20 @@ gimp_text_tool_text_notify (GimpText *text,
text_tool);
}
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
+}
+
+static void
+gimp_text_tool_text_changed (GimpText *text,
+ GimpTextTool *text_tool)
+{
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
+ /* we need to redraw the rectangle in any case because whatever
+ * changes to the text can change its size
+ */
+ gimp_text_tool_frame_item (text_tool);
+
gimp_text_tool_clear_layout (text_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
@@ -1184,6 +1202,9 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
g_signal_handlers_block_by_func (dest,
gimp_text_tool_text_notify,
text_tool);
+ g_signal_handlers_block_by_func (dest,
+ gimp_text_tool_text_changed,
+ text_tool);
g_object_freeze_notify (dest);
@@ -1213,6 +1234,9 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
g_signal_handlers_unblock_by_func (dest,
gimp_text_tool_text_notify,
text_tool);
+ g_signal_handlers_unblock_by_func (dest,
+ gimp_text_tool_text_changed,
+ text_tool);
if (push_undo)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]