[gimp] app: remove GimpArea and use cairo_region_t instead
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: remove GimpArea and use cairo_region_t instead
- Date: Fri, 30 May 2014 23:28:07 +0000 (UTC)
commit 9b341d05bb9926ee6de7aae3d449e2f3031c7b60
Author: Michael Natterer <mitch gimp org>
Date: Sat May 31 01:22:54 2014 +0200
app: remove GimpArea and use cairo_region_t instead
This may or may not remove some logic that avoids drawing tiny update
regions, and may or may not improve things or make them worse. Will
add code that actually tile-aligns update areas later.
app/core/Makefile.am | 2 -
app/core/core-types.h | 1 -
app/core/gimparea.c | 108 --------------------------
app/core/gimparea.h | 39 ----------
app/core/gimpprojection.c | 184 ++++++++++++++++++++++++++-------------------
app/display/gimpdisplay.c | 77 ++++++++++---------
6 files changed, 149 insertions(+), 262 deletions(-)
---
diff --git a/app/core/Makefile.am b/app/core/Makefile.am
index bc0ef13..374b3a7 100644
--- a/app/core/Makefile.am
+++ b/app/core/Makefile.am
@@ -55,8 +55,6 @@ libappcore_a_sources = \
gimp-user-install.h \
gimp-utils.c \
gimp-utils.h \
- gimparea.c \
- gimparea.h \
gimpbezierdesc.h \
gimpbezierdesc.c \
gimpboundary.c \
diff --git a/app/core/core-types.h b/app/core/core-types.h
index 9076c31..d1c077b 100644
--- a/app/core/core-types.h
+++ b/app/core/core-types.h
@@ -197,7 +197,6 @@ typedef struct _GimpTagged GimpTagged; /* dummy typedef */
/* non-object types */
-typedef struct _GimpArea GimpArea;
typedef struct _GimpBoundSeg GimpBoundSeg;
typedef struct _GimpCoords GimpCoords;
typedef struct _GimpGradientSegment GimpGradientSegment;
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 4a31d06..5225d56 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -29,7 +29,6 @@
#include "gimp.h"
#include "gimp-utils.h"
-#include "gimparea.h"
#include "gimpimage.h"
#include "gimpmarshal.h"
#include "gimppickable.h"
@@ -67,14 +66,14 @@ typedef struct _GimpProjectionChunkRender GimpProjectionChunkRender;
struct _GimpProjectionChunkRender
{
- gboolean running;
- gint width;
- gint height;
- gint x;
- gint y;
- gint base_x;
- gint base_y;
- GSList *update_areas; /* flushed update areas */
+ gboolean running;
+ gint width;
+ gint height;
+ gint x;
+ gint y;
+ gint base_x;
+ gint base_y;
+ cairo_region_t *update_region; /* flushed update region */
};
@@ -87,7 +86,7 @@ struct _GimpProjectionPrivate
GeglBuffer *buffer;
gpointer validate_handler;
- GSList *update_areas;
+ cairo_region_t *update_region;
GimpProjectionChunkRender chunk_render;
guint chunk_render_idle_id;
@@ -227,11 +226,17 @@ gimp_projection_finalize (GObject *object)
if (proj->priv->chunk_render.running)
gimp_projection_chunk_render_stop (proj);
- gimp_area_list_free (proj->priv->update_areas);
- proj->priv->update_areas = NULL;
+ if (proj->priv->update_region)
+ {
+ cairo_region_destroy (proj->priv->update_region);
+ proj->priv->update_region = NULL;
+ }
- gimp_area_list_free (proj->priv->chunk_render.update_areas);
- proj->priv->chunk_render.update_areas = NULL;
+ if (proj->priv->chunk_render.update_region)
+ {
+ cairo_region_destroy (proj->priv->chunk_render.update_region);
+ proj->priv->chunk_render.update_region = NULL;
+ }
gimp_projection_free_buffer (proj);
@@ -512,9 +517,9 @@ gimp_projection_add_update_area (GimpProjection *proj,
gint w,
gint h)
{
- GimpArea *area;
- gint off_x, off_y;
- gint width, height;
+ cairo_rectangle_int_t rect;
+ gint off_x, off_y;
+ gint width, height;
gimp_projectable_get_offset (proj->priv->projectable, &off_x, &off_y);
gimp_projectable_get_size (proj->priv->projectable, &width, &height);
@@ -526,13 +531,15 @@ gimp_projection_add_update_area (GimpProjection *proj,
x -= off_x;
y -= off_y;
- area = gimp_area_new (CLAMP (x, 0, width),
- CLAMP (y, 0, height),
- CLAMP (x + w, 0, width),
- CLAMP (y + h, 0, height));
+ rect.x = CLAMP (x, 0, width);
+ rect.y = CLAMP (y, 0, height);
+ rect.width = CLAMP (x + w, 0, width) - rect.x;
+ rect.height = CLAMP (y + h, 0, height) - rect.y;
- proj->priv->update_areas = gimp_area_list_process (proj->priv->update_areas,
- area);
+ if (proj->priv->update_region)
+ cairo_region_union_rectangle (proj->priv->update_region, &rect);
+ else
+ proj->priv->update_region = cairo_region_create_rectangle (&rect);
}
static void
@@ -540,25 +547,26 @@ gimp_projection_flush_whenever (GimpProjection *proj,
gboolean now)
{
/* First the updates... */
- if (proj->priv->update_areas)
+ if (proj->priv->update_region)
{
if (now) /* Synchronous */
{
- GSList *list;
+ gint n_rects = cairo_region_num_rectangles (proj->priv->update_region);
+ gint i;
- for (list = proj->priv->update_areas; list; list = g_slist_next (list))
+ for (i = 0; i < n_rects; i++)
{
- GimpArea *area = list->data;
+ cairo_rectangle_int_t rect;
- if ((area->x1 != area->x2) && (area->y1 != area->y2))
- {
- gimp_projection_paint_area (proj,
- FALSE, /* sic! */
- area->x1,
- area->y1,
- (area->x2 - area->x1),
- (area->y2 - area->y1));
- }
+ cairo_region_get_rectangle (proj->priv->update_region,
+ i, &rect);
+
+ gimp_projection_paint_area (proj,
+ FALSE, /* sic! */
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height);
}
}
else /* Asynchronous */
@@ -566,9 +574,9 @@ gimp_projection_flush_whenever (GimpProjection *proj,
gimp_projection_chunk_render_init (proj);
}
- /* Free the update lists */
- gimp_area_list_free (proj->priv->update_areas);
- proj->priv->update_areas = NULL;
+ /* Free the update region */
+ cairo_region_destroy (proj->priv->update_region);
+ proj->priv->update_region = NULL;
}
else if (! now && proj->priv->invalidate_preview)
{
@@ -638,20 +646,22 @@ gimp_projection_chunk_render_callback (gpointer data)
static void
gimp_projection_chunk_render_init (GimpProjection *proj)
{
- GSList *list;
-
/* We need to merge the ChunkRender's and the GimpProjection's
- * update_areas list to keep track of which of the updates have been
- * flushed and hence need to be drawn.
+ * update_regions list to keep track of which of the updates have
+ * been flushed and hence need to be drawn.
*/
- for (list = proj->priv->update_areas; list; list = g_slist_next (list))
+ if (proj->priv->update_region)
{
- GimpArea *area = list->data;
-
- proj->priv->chunk_render.update_areas =
- gimp_area_list_process (proj->priv->chunk_render.update_areas,
- gimp_area_new (area->x1, area->y1,
- area->x2, area->y2));
+ if (proj->priv->chunk_render.update_region)
+ {
+ cairo_region_union (proj->priv->chunk_render.update_region,
+ proj->priv->update_region);
+ }
+ else
+ {
+ proj->priv->chunk_render.update_region =
+ cairo_region_copy (proj->priv->update_region);
+ }
}
/* If a chunk renderer was already running, merge the remainder of
@@ -660,24 +670,25 @@ gimp_projection_chunk_render_init (GimpProjection *proj)
*/
if (proj->priv->chunk_render.running)
{
- GimpArea *area =
- gimp_area_new (proj->priv->chunk_render.base_x,
- proj->priv->chunk_render.y,
- proj->priv->chunk_render.base_x + proj->priv->chunk_render.width,
- proj->priv->chunk_render.y + (proj->priv->chunk_render.height -
- (proj->priv->chunk_render.y -
- proj->priv->chunk_render.base_y)));
+ cairo_rectangle_int_t rect;
+
+ rect.x = proj->priv->chunk_render.base_x;
+ rect.y = proj->priv->chunk_render.y;
+ rect.width = proj->priv->chunk_render.width;
+ rect.height = (proj->priv->chunk_render.height -
+ (proj->priv->chunk_render.y -
+ proj->priv->chunk_render.base_y));
- proj->priv->chunk_render.update_areas =
- gimp_area_list_process (proj->priv->chunk_render.update_areas, area);
+ cairo_region_union_rectangle (proj->priv->chunk_render.update_region,
+ &rect);
gimp_projection_chunk_render_next_area (proj);
}
else
{
- if (proj->priv->chunk_render.update_areas == NULL)
+ if (proj->priv->chunk_render.update_region == NULL)
{
- g_warning ("%s: wanted to start chunk render with no update_areas",
+ g_warning ("%s: wanted to start chunk render with no update_region",
G_STRFUNC);
return;
}
@@ -702,14 +713,18 @@ gimp_projection_chunk_render_iteration (GimpProjection *proj)
gint workw = GIMP_PROJECTION_CHUNK_WIDTH;
gint workh = GIMP_PROJECTION_CHUNK_HEIGHT;
- if (workx + workw > proj->priv->chunk_render.base_x + proj->priv->chunk_render.width)
+ if (workx + workw >
+ proj->priv->chunk_render.base_x + proj->priv->chunk_render.width)
{
- workw = proj->priv->chunk_render.base_x + proj->priv->chunk_render.width - workx;
+ workw = (proj->priv->chunk_render.base_x +
+ proj->priv->chunk_render.width - workx);
}
- if (worky + workh > proj->priv->chunk_render.base_y + proj->priv->chunk_render.height)
+ if (worky + workh >
+ proj->priv->chunk_render.base_y + proj->priv->chunk_render.height)
{
- workh = proj->priv->chunk_render.base_y + proj->priv->chunk_render.height - worky;
+ workh = (proj->priv->chunk_render.base_y +
+ proj->priv->chunk_render.height - worky);
}
gimp_projection_paint_area (proj, TRUE /* sic! */,
@@ -751,22 +766,34 @@ gimp_projection_chunk_render_iteration (GimpProjection *proj)
static gboolean
gimp_projection_chunk_render_next_area (GimpProjection *proj)
{
- GimpArea *area;
+ cairo_rectangle_int_t rect;
- if (! proj->priv->chunk_render.update_areas)
+ if (! proj->priv->chunk_render.update_region)
return FALSE;
- area = proj->priv->chunk_render.update_areas->data;
+ if (cairo_region_is_empty (proj->priv->chunk_render.update_region))
+ {
+ cairo_region_destroy (proj->priv->chunk_render.update_region);
+ proj->priv->chunk_render.update_region = NULL;
- proj->priv->chunk_render.update_areas =
- g_slist_remove (proj->priv->chunk_render.update_areas, area);
+ return FALSE;
+ }
- proj->priv->chunk_render.x = proj->priv->chunk_render.base_x = area->x1;
- proj->priv->chunk_render.y = proj->priv->chunk_render.base_y = area->y1;
- proj->priv->chunk_render.width = area->x2 - area->x1;
- proj->priv->chunk_render.height = area->y2 - area->y1;
+ cairo_region_get_rectangle (proj->priv->chunk_render.update_region,
+ 0, &rect);
+ cairo_region_subtract_rectangle (proj->priv->chunk_render.update_region,
+ &rect);
- gimp_area_free (area);
+ if (cairo_region_is_empty (proj->priv->chunk_render.update_region))
+ {
+ cairo_region_destroy (proj->priv->chunk_render.update_region);
+ proj->priv->chunk_render.update_region = NULL;
+ }
+
+ proj->priv->chunk_render.x = proj->priv->chunk_render.base_x = rect.x;
+ proj->priv->chunk_render.y = proj->priv->chunk_render.base_y = rect.y;
+ proj->priv->chunk_render.width = rect.width;
+ proj->priv->chunk_render.height = rect.height;
return TRUE;
}
@@ -854,8 +881,11 @@ gimp_projection_projectable_changed (GimpProjectable *projectable,
if (proj->priv->chunk_render.running)
gimp_projection_chunk_render_stop (proj);
- gimp_area_list_free (proj->priv->update_areas);
- proj->priv->update_areas = NULL;
+ if (proj->priv->update_region)
+ {
+ cairo_region_destroy (proj->priv->update_region);
+ proj->priv->update_region = NULL;
+ }
gimp_projection_free_buffer (proj);
diff --git a/app/display/gimpdisplay.c b/app/display/gimpdisplay.c
index 06b8abe..f7d22b8 100644
--- a/app/display/gimpdisplay.c
+++ b/app/display/gimpdisplay.c
@@ -28,7 +28,6 @@
#include "config/gimpguiconfig.h"
#include "core/gimp.h"
-#include "core/gimparea.h"
#include "core/gimpcontainer.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
@@ -68,16 +67,16 @@ typedef struct _GimpDisplayPrivate GimpDisplayPrivate;
struct _GimpDisplayPrivate
{
- gint ID; /* unique identifier for this display */
+ gint ID; /* unique identifier for this display */
- GimpImage *image; /* pointer to the associated image */
- gint instance; /* the instance # of this display as
- * taken from the image at creation */
+ GimpImage *image; /* pointer to the associated image */
+ gint instance; /* the instance # of this display as
+ * taken from the image at creation */
- GtkWidget *shell;
- GSList *update_areas;
+ GtkWidget *shell;
+ cairo_region_t *update_region;
- guint64 last_flush_now;
+ guint64 last_flush_now;
};
#define GIMP_DISPLAY_GET_PRIVATE(display) \
@@ -505,10 +504,6 @@ gimp_display_delete (GimpDisplay *display)
if (active_tool && active_tool->focus_display == display)
tool_manager_focus_display_active (display->gimp, NULL);
- /* free the update area lists */
- gimp_area_list_free (private->update_areas);
- private->update_areas = NULL;
-
if (private->shell)
{
GimpDisplayShell *shell = gimp_display_get_shell (display);
@@ -657,6 +652,12 @@ gimp_display_set_image (GimpDisplay *display,
gimp_display_disconnect (display);
+ if (private->update_region)
+ {
+ cairo_region_destroy (private->update_region);
+ private->update_region = NULL;
+ }
+
gimp_image_dec_display_count (private->image);
/* set private->image before unrefing because there may be code
@@ -789,17 +790,22 @@ gimp_display_update_area (GimpDisplay *display,
}
else
{
- GimpArea *area;
- gint image_width = gimp_image_get_width (private->image);
- gint image_height = gimp_image_get_height (private->image);
+ cairo_rectangle_int_t rect;
+ gint image_width;
+ gint image_height;
+
+ image_width = gimp_image_get_width (private->image);
+ image_height = gimp_image_get_height (private->image);
- area = gimp_area_new (CLAMP (x, 0, image_width),
- CLAMP (y, 0, image_height),
- CLAMP (x + w, 0, image_width),
- CLAMP (y + h, 0, image_height));
+ rect.x = CLAMP (x, 0, image_width);
+ rect.y = CLAMP (y, 0, image_height);
+ rect.width = CLAMP (x + w, 0, image_width) - rect.x;
+ rect.height = CLAMP (y + h, 0, image_height) - rect.y;
- private->update_areas = gimp_area_list_process (private->update_areas,
- area);
+ if (private->update_region)
+ cairo_region_union_rectangle (private->update_region, &rect);
+ else
+ private->update_region = cairo_region_create_rectangle (&rect);
}
}
@@ -828,26 +834,27 @@ gimp_display_flush_whenever (GimpDisplay *display,
{
GimpDisplayPrivate *private = GIMP_DISPLAY_GET_PRIVATE (display);
- if (private->update_areas)
+ if (private->update_region)
{
- GSList *list;
+ gint n_rects = cairo_region_num_rectangles (private->update_region);
+ gint i;
- for (list = private->update_areas; list; list = g_slist_next (list))
+ for (i = 0; i < n_rects; i++)
{
- GimpArea *area = list->data;
+ cairo_rectangle_int_t rect;
- if ((area->x1 != area->x2) && (area->y1 != area->y2))
- {
- gimp_display_paint_area (display,
- area->x1,
- area->y1,
- (area->x2 - area->x1),
- (area->y2 - area->y1));
- }
+ cairo_region_get_rectangle (private->update_region,
+ i, &rect);
+
+ gimp_display_paint_area (display,
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height);
}
- gimp_area_list_free (private->update_areas);
- private->update_areas = NULL;
+ cairo_region_destroy (private->update_region);
+ private->update_region = NULL;
}
if (now)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]