[gimp] app: use GimpChunkIterator in GimpProjection
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: use GimpChunkIterator in GimpProjection
- Date: Sat, 12 Jan 2019 09:55:15 +0000 (UTC)
commit 246e782858151f8956ee970da8ca2fe6811e841d
Author: Ell <ell_se yahoo com>
Date: Sat Jan 12 03:36:09 2019 -0500
app: use GimpChunkIterator in GimpProjection
Replace the custom chunking logic of GimpProjection with
GimpChunkIterator, added in the previous commit.
app/core/gimpprojection.c | 630 ++++++++--------------------------------------
1 file changed, 107 insertions(+), 523 deletions(-)
---
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index ae1e8ca5ae..bc5dfb01eb 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -35,6 +35,7 @@
#include "gimp.h"
#include "gimp-memsize.h"
+#include "gimpchunkiterator.h"
#include "gimpimage.h"
#include "gimpmarshal.h"
#include "gimppickable.h"
@@ -46,36 +47,9 @@
#include "gimp-priorities.h"
-/* whether to use adaptive render-chunk size */
-static gboolean GIMP_PROJECTION_ADAPTIVE_CHUNK_SIZE = TRUE;
-
-/* chunk size for one iteration of the chunk renderer, when the use
- * of adaptive chunk size is disabled
- */
-static gint GIMP_PROJECTION_CHUNK_WIDTH = 256;
-static gint GIMP_PROJECTION_CHUNK_HEIGHT = 128;
-
-/* the min/max adaptive chunk size */
-#define GIMP_PROJECTION_CHUNK_MIN_WIDTH 128
-#define GIMP_PROJECTION_CHUNK_MIN_HEIGHT 128
-
-#define GIMP_PROJECTION_CHUNK_MAX_WIDTH 2048
-#define GIMP_PROJECTION_CHUNK_MAX_HEIGHT 2048
-
-/* the minimal number of processed pixels on the current frame,
- * above which we calculate a new target pixel count to render
- * on the next frame
- */
-#define GIMP_PROJECTION_MIN_PIXELS_PER_UPDATE 1024
-
/* chunk size for area updates */
-static gint GIMP_PROJECTION_UPDATE_CHUNK_WIDTH = 32;
-static gint GIMP_PROJECTION_UPDATE_CHUNK_HEIGHT = 32;
-
-/* how much time, in seconds, do we allow chunk rendering to take,
- * aiming for 15fps
- */
-static gdouble GIMP_PROJECTION_CHUNK_TIME = 0.0666;
+#define GIMP_PROJECTION_UPDATE_CHUNK_WIDTH 32
+#define GIMP_PROJECTION_UPDATE_CHUNK_HEIGHT 32
enum
@@ -91,27 +65,6 @@ enum
};
-typedef struct _GimpProjectionChunkRender GimpProjectionChunkRender;
-
-struct _GimpProjectionChunkRender
-{
- guint idle_id;
-
- gint x;
- gint y;
- gint width;
- gint height;
-
- gint work_x;
- gint work_y;
- gint work_height;
-
- gint n_pixels;
- gint target_n_pixels;
-
- cairo_region_t *update_region; /* flushed update region */
-};
-
struct _GimpProjectionPrivate
{
GimpProjectable *projectable;
@@ -122,8 +75,9 @@ struct _GimpProjectionPrivate
gint priority;
cairo_region_t *update_region;
- GimpProjectionChunkRender chunk_render;
- cairo_rectangle_int_t priority_rect;
+ GeglRectangle priority_rect;
+ GimpChunkIterator *iter;
+ guint idle_id;
gboolean invalidate_preview;
};
@@ -182,19 +136,10 @@ static void gimp_projection_flush_whenever (GimpProjection *proj,
gboolean now,
gboolean direct);
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 void gimp_projection_chunk_render_init (GimpProjection *proj);
-static void gimp_projection_chunk_render_reinit (GimpProjection *proj);
-static void gimp_projection_chunk_render_merge (GimpProjection *proj);
-static gboolean gimp_projection_chunk_render_iteration(GimpProjection *proj,
- gboolean chunk);
-static gboolean gimp_projection_chunk_render_next_area(GimpProjection *proj);
-static void gimp_projection_chunk_render_set_area (GimpProjection *proj,
- gint x,
- gint y,
- gint w,
- gint h);
+static void gimp_projection_chunk_render_stop (GimpProjection *proj,
+ gboolean merge);
+static gboolean gimp_projection_chunk_render_callback (GimpProjection *proj);
+static gboolean gimp_projection_chunk_render_iteration(GimpProjection *proj);
static void gimp_projection_paint_area (GimpProjection *proj,
gboolean now,
gint x,
@@ -221,11 +166,6 @@ static void gimp_projection_projectable_bounds_changed (GimpProjectable *proje
gint old_h,
GimpProjection *proj);
-static gint gimp_projection_round_chunk_size (gdouble size,
- gboolean toward_zero);
-static gint gimp_projection_round_chunk_width (gdouble width);
-static gint gimp_projection_round_chunk_height (gdouble height);
-
G_DEFINE_TYPE_WITH_CODE (GimpProjection, gimp_projection, GIMP_TYPE_OBJECT,
G_ADD_PRIVATE (GimpProjection)
@@ -242,7 +182,6 @@ gimp_projection_class_init (GimpProjectionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
- const gchar *env;
projection_signals[UPDATE] =
g_signal_new ("update",
@@ -265,27 +204,6 @@ gimp_projection_class_init (GimpProjectionClass *klass)
gimp_object_class->get_memsize = gimp_projection_get_memsize;
g_object_class_override_property (object_class, PROP_BUFFER, "buffer");
-
- if (g_getenv ("GIMP_NO_ADAPTIVE_CHUNK_SIZE"))
- GIMP_PROJECTION_ADAPTIVE_CHUNK_SIZE = FALSE;
-
- env = g_getenv ("GIMP_DISPLAY_RENDER_BUF_SIZE");
- if (env)
- {
- gint width = atoi (env);
- gint height = width;
-
- env = strchr (env, 'x');
- if (env)
- height = atoi (env + 1);
-
- if (width > 0 && width <= 8192 &&
- height > 0 && height <= 8192)
- {
- GIMP_PROJECTION_CHUNK_WIDTH = width;
- GIMP_PROJECTION_CHUNK_HEIGHT = height;
- }
- }
}
static void
@@ -587,9 +505,8 @@ gimp_projection_set_priority_rect (GimpProjection *proj,
gint w,
gint h)
{
- cairo_rectangle_int_t rect;
- gint off_x, off_y;
- gint width, height;
+ gint off_x, off_y;
+ gint width, height;
g_return_if_fail (GIMP_IS_PROJECTION (proj));
@@ -603,58 +520,23 @@ gimp_projection_set_priority_rect (GimpProjection *proj,
x -= off_x;
y -= off_y;
- if (gimp_rectangle_intersect (x, y, w, h,
- 0, 0, width, height,
- &rect.x, &rect.y, &rect.width, &rect.height))
- {
- proj->priv->priority_rect = rect;
+ gegl_rectangle_intersect (&proj->priv->priority_rect,
+ GEGL_RECTANGLE (x, y, w, h),
+ GEGL_RECTANGLE (0, 0, width, height));
- if (proj->priv->chunk_render.idle_id)
- gimp_projection_chunk_render_reinit (proj);
+ if (proj->priv->iter)
+ {
+ gimp_chunk_iterator_set_priority_rect (proj->priv->iter,
+ &proj->priv->priority_rect);
}
}
void
gimp_projection_stop_rendering (GimpProjection *proj)
{
- GimpProjectionChunkRender *chunk_render;
- cairo_rectangle_int_t rect;
-
g_return_if_fail (GIMP_IS_PROJECTION (proj));
- chunk_render = &proj->priv->chunk_render;
-
- if (! chunk_render->idle_id)
- return;
-
- if (chunk_render->update_region)
- {
- if (proj->priv->update_region)
- {
- cairo_region_union (proj->priv->update_region,
- chunk_render->update_region);
- }
- else
- {
- proj->priv->update_region =
- cairo_region_copy (chunk_render->update_region);
- }
-
- g_clear_pointer (&chunk_render->update_region, cairo_region_destroy);
- }
-
- rect.x = chunk_render->x;
- rect.y = chunk_render->work_y;
- rect.width = chunk_render->width;
- rect.height = chunk_render->height - (chunk_render->work_y - chunk_render->y);
-
- /* FIXME this is too much, the entire current row */
- if (proj->priv->update_region)
- cairo_region_union_rectangle (proj->priv->update_region, &rect);
- else
- proj->priv->update_region = cairo_region_create_rectangle (&rect);
-
- gimp_projection_chunk_render_stop (proj);
+ gimp_projection_chunk_render_stop (proj, TRUE);
}
void
@@ -681,15 +563,15 @@ gimp_projection_finish_draw (GimpProjection *proj)
{
g_return_if_fail (GIMP_IS_PROJECTION (proj));
- if (proj->priv->chunk_render.idle_id)
+ if (proj->priv->iter)
{
- gimp_projection_chunk_render_stop (proj);
-
gimp_tile_handler_validate_begin_validate (proj->priv->validate_handler);
- while (gimp_projection_chunk_render_iteration (proj, FALSE));
+ while (gimp_projection_chunk_render_iteration (proj));
gimp_tile_handler_validate_end_validate (proj->priv->validate_handler);
+
+ gimp_projection_chunk_render_stop (proj, FALSE);
}
}
@@ -725,11 +607,9 @@ gimp_projection_allocate_buffer (GimpProjection *proj)
static void
gimp_projection_free_buffer (GimpProjection *proj)
{
- if (proj->priv->chunk_render.idle_id)
- gimp_projection_chunk_render_stop (proj);
+ gimp_projection_chunk_render_stop (proj, FALSE);
g_clear_pointer (&proj->priv->update_region, cairo_region_destroy);
- g_clear_pointer (&proj->priv->chunk_render.update_region, cairo_region_destroy);
if (proj->priv->buffer)
{
@@ -804,14 +684,15 @@ gimp_projection_flush_whenever (GimpProjection *proj,
rect.width,
rect.height);
}
+
+ /* Free the update region */
+ g_clear_pointer (&proj->priv->update_region, cairo_region_destroy);
}
else /* Asynchronous */
{
- gimp_projection_chunk_render_init (proj);
+ /* Consumes the update region */
+ gimp_projection_chunk_render_start (proj);
}
-
- /* Free the update region */
- g_clear_pointer (&proj->priv->update_region, cairo_region_destroy);
}
else if (! now && proj->priv->invalidate_preview)
{
@@ -827,343 +708,131 @@ gimp_projection_flush_whenever (GimpProjection *proj,
static void
gimp_projection_chunk_render_start (GimpProjection *proj)
{
- g_return_if_fail (proj->priv->chunk_render.idle_id == 0);
-
- proj->priv->chunk_render.idle_id =
- g_idle_add_full (GIMP_PRIORITY_PROJECTION_IDLE + proj->priv->priority,
- gimp_projection_chunk_render_callback, proj,
- NULL);
-}
-
-static void
-gimp_projection_chunk_render_stop (GimpProjection *proj)
-{
- g_return_if_fail (proj->priv->chunk_render.idle_id != 0);
-
- g_source_remove (proj->priv->chunk_render.idle_id);
- proj->priv->chunk_render.idle_id = 0;
-}
+ cairo_region_t *region = proj->priv->update_region;
-static gboolean
-gimp_projection_chunk_render_callback (gpointer data)
-{
- GimpProjection *proj = data;
- GimpProjectionChunkRender *chunk_render = &proj->priv->chunk_render;
- GTimer *timer = g_timer_new ();
- gint chunks = 0;
- gboolean retval = TRUE;
-
- /* reset the rendered pixel count, so that we count the number of pixels
- * processed during this frame
- */
- chunk_render->n_pixels = 0;
+ if (proj->priv->iter)
+ {
+ region = gimp_chunk_iterator_stop (proj->priv->iter, FALSE);
- gimp_tile_handler_validate_begin_validate (proj->priv->validate_handler);
+ proj->priv->iter = NULL;
- do
- {
- if (! gimp_projection_chunk_render_iteration (proj, TRUE))
+ if (proj->priv->update_region)
{
- gimp_projection_chunk_render_stop (proj);
-
- retval = FALSE;
+ cairo_region_union (region, proj->priv->update_region);
- break;
+ cairo_region_destroy (proj->priv->update_region);
}
-
- chunks++;
}
- while (g_timer_elapsed (timer, NULL) < GIMP_PROJECTION_CHUNK_TIME);
- gimp_tile_handler_validate_end_validate (proj->priv->validate_handler);
+ proj->priv->update_region = NULL;
- /* adjust the target number of pixels to be processed on the next frame,
- * according to the number of pixels processed during this frame and the
- * elapsed time, in order to match the desired frame rate.
- */
- if (chunk_render->n_pixels >= GIMP_PROJECTION_MIN_PIXELS_PER_UPDATE)
+ if (region && ! cairo_region_is_empty (region))
{
- chunk_render->target_n_pixels = floor (chunk_render->n_pixels *
- GIMP_PROJECTION_CHUNK_TIME /
- g_timer_elapsed (timer, NULL));
- }
+ proj->priv->iter = gimp_chunk_iterator_new (region);
- GIMP_LOG (PROJECTION, "%d chunks in %f seconds\n",
- chunks, g_timer_elapsed (timer, NULL));
- g_timer_destroy (timer);
+ gimp_chunk_iterator_set_priority_rect (proj->priv->iter,
+ &proj->priv->priority_rect);
- return retval;
-}
-
-static void
-gimp_projection_chunk_render_init (GimpProjection *proj)
-{
- GimpProjectionChunkRender *chunk_render = &proj->priv->chunk_render;
-
- chunk_render->target_n_pixels = GIMP_PROJECTION_CHUNK_WIDTH *
- GIMP_PROJECTION_CHUNK_HEIGHT;
-
- gimp_projection_chunk_render_reinit (proj);
-}
-
-static void
-gimp_projection_chunk_render_reinit (GimpProjection *proj)
-{
- GimpProjectionChunkRender *chunk_render = &proj->priv->chunk_render;
-
- /* We need to merge the ChunkRender's and the GimpProjection's
- * update_regions list to keep track of which of the updates have
- * been flushed and hence need to be drawn.
- */
- if (proj->priv->update_region)
- {
- if (chunk_render->update_region)
- {
- cairo_region_union (chunk_render->update_region,
- proj->priv->update_region);
- }
- else
+ if (! proj->priv->idle_id)
{
- chunk_render->update_region =
- cairo_region_copy (proj->priv->update_region);
+ proj->priv->idle_id = g_idle_add_full (
+ GIMP_PRIORITY_PROJECTION_IDLE + proj->priv->priority,
+ (GSourceFunc) gimp_projection_chunk_render_callback,
+ proj, NULL);
}
}
-
- /* If a chunk renderer was already running, merge the remainder of
- * its unrendered area with the update_areas list, and make it start
- * work on the next unrendered area in the list.
- */
- if (chunk_render->idle_id)
- {
- gimp_projection_chunk_render_merge (proj);
-
- gimp_projection_chunk_render_next_area (proj);
- }
- else
- {
- if (chunk_render->update_region == NULL)
- {
- g_warning ("%s: wanted to start chunk render with no update_region",
- G_STRFUNC);
- return;
- }
-
- proj->priv->chunk_render.target_n_pixels = GIMP_PROJECTION_CHUNK_WIDTH *
- GIMP_PROJECTION_CHUNK_HEIGHT;
-
- gimp_projection_chunk_render_next_area (proj);
-
- gimp_projection_chunk_render_start (proj);
- }
}
static void
-gimp_projection_chunk_render_merge (GimpProjection *proj)
+gimp_projection_chunk_render_stop (GimpProjection *proj,
+ gboolean merge)
{
- GimpProjectionChunkRender *chunk_render = &proj->priv->chunk_render;
- cairo_rectangle_int_t rect;
- gint work_h = 0;
-
- if (chunk_render->work_x != chunk_render->x)
+ if (proj->priv->idle_id)
{
- work_h = MIN (chunk_render->work_height,
- chunk_render->y + chunk_render->height -
- chunk_render->work_y);
-
- rect.x = chunk_render->work_x;
- rect.y = chunk_render->work_y;
- rect.width = chunk_render->x + chunk_render->width -
- chunk_render->work_x;
- rect.height = work_h;
-
- if (chunk_render->update_region)
- cairo_region_union_rectangle (chunk_render->update_region, &rect);
- else
- chunk_render->update_region = cairo_region_create_rectangle (&rect);
+ g_source_remove (proj->priv->idle_id);
+ proj->priv->idle_id = 0;
}
- rect.x = chunk_render->x;
- rect.y = chunk_render->work_y + work_h;
- rect.width = chunk_render->width;
- rect.height = chunk_render->y + chunk_render->height - rect.y;
-
- if (chunk_render->update_region)
- cairo_region_union_rectangle (chunk_render->update_region, &rect);
- else
- chunk_render->update_region = cairo_region_create_rectangle (&rect);
-}
-
-/* Unless specified otherwise, projection re-rendering is organised by
- * ChunkRender, which amalgamates areas to be re-rendered and breaks
- * them into bite-sized chunks which are chewed on in an idle
- * function. This greatly improves responsiveness for many GIMP
- * operations. -- Adam
- */
-static gboolean
-gimp_projection_chunk_render_iteration (GimpProjection *proj,
- gboolean chunk)
-{
- GimpProjectionChunkRender *chunk_render = &proj->priv->chunk_render;
- gint work_x = chunk_render->work_x;
- gint work_y = chunk_render->work_y;
- gint work_w;
- gint work_h;
-
- work_w = chunk_render->x + chunk_render->width - work_x;
- work_h = chunk_render->y + chunk_render->height - work_y;
-
- if (chunk)
+ if (proj->priv->iter)
{
- if (GIMP_PROJECTION_ADAPTIVE_CHUNK_SIZE)
+ if (merge)
{
- gint chunk_w;
- gint chunk_h;
-
- /* try to render in square chunks */
- chunk_h = gimp_projection_round_chunk_height (
- sqrt (chunk_render->target_n_pixels));
+ cairo_region_t *region;
- work_h = MIN (work_h, chunk_h);
+ region = gimp_chunk_iterator_stop (proj->priv->iter, FALSE);
- chunk_w = gimp_projection_round_chunk_width (
- chunk_render->target_n_pixels / work_h);
+ if (proj->priv->update_region)
+ {
+ cairo_region_union (proj->priv->update_region, region);
- work_w = MIN (work_w, chunk_w);
+ cairo_region_destroy (region);
+ }
+ else
+ {
+ proj->priv->update_region = region;
+ }
}
else
{
- work_w = MIN (work_w, GIMP_PROJECTION_CHUNK_WIDTH);
- work_h = MIN (work_h, GIMP_PROJECTION_CHUNK_HEIGHT);
+ gimp_chunk_iterator_stop (proj->priv->iter, TRUE);
}
+
+ proj->priv->iter = NULL;
}
- else
- {
- if (work_x != chunk_render->x)
- work_h = MIN (work_h, chunk_render->work_height);
- }
+}
- if (work_h != chunk_render->work_height)
+static gboolean
+gimp_projection_chunk_render_callback (GimpProjection *proj)
+{
+ if (gimp_projection_chunk_render_iteration (proj))
{
- /* if the chunk height changed in the middle of a row, merge the
- * remaining area back into the update region, and reset the current area
- * to the remainder of the row, using the new chunk height
- */
- if (work_x != chunk_render->x)
- {
- gimp_projection_chunk_render_merge (proj);
-
- gimp_projection_chunk_render_set_area (
- proj,
- work_x,
- work_y,
- chunk_render->x + chunk_render->width - work_x,
- work_h);
- }
-
- chunk_render->work_height = work_h;
+ return G_SOURCE_CONTINUE;
}
-
- gimp_projection_paint_area (proj, TRUE,
- work_x, work_y, work_w, work_h);
-
- chunk_render->n_pixels += work_w * work_h;
-
- chunk_render->work_x += work_w;
-
- if (chunk_render->work_x >= chunk_render->x + chunk_render->width)
+ else
{
- chunk_render->work_x = chunk_render->x;
-
- chunk_render->work_y += work_h;
+ proj->priv->idle_id = 0;
- if (chunk_render->work_y >= chunk_render->y + chunk_render->height)
- {
- if (! gimp_projection_chunk_render_next_area (proj))
- {
- if (proj->priv->invalidate_preview)
- {
- /* invalidate the preview here since it is constructed from
- * the projection
- */
- proj->priv->invalidate_preview = FALSE;
-
- gimp_projectable_invalidate_preview (proj->priv->projectable);
- }
-
- /* FINISHED */
- return FALSE;
- }
- }
+ return G_SOURCE_REMOVE;
}
-
- /* Still work to do. */
- return TRUE;
}
static gboolean
-gimp_projection_chunk_render_next_area (GimpProjection *proj)
+gimp_projection_chunk_render_iteration (GimpProjection *proj)
{
- GimpProjectionChunkRender *chunk_render = &proj->priv->chunk_render;
- cairo_region_t *next_region;
- cairo_rectangle_int_t rect;
-
- if (! chunk_render->update_region)
- return FALSE;
-
- if (cairo_region_is_empty (chunk_render->update_region))
+ if (gimp_chunk_iterator_next (proj->priv->iter))
{
- g_clear_pointer (&chunk_render->update_region, cairo_region_destroy);
-
- return FALSE;
- }
-
- next_region = cairo_region_copy (chunk_render->update_region);
- cairo_region_intersect_rectangle (next_region, &proj->priv->priority_rect);
+ GeglRectangle rect;
- if (cairo_region_is_empty (next_region))
- cairo_region_get_rectangle (chunk_render->update_region, 0, &rect);
- else
- cairo_region_get_rectangle (next_region, 0, &rect);
-
- cairo_region_destroy (next_region);
-
- gimp_projection_chunk_render_set_area (proj,
- rect.x, rect.y,
- rect.width, rect.height);
-
- return TRUE;
-}
+ gimp_tile_handler_validate_begin_validate (proj->priv->validate_handler);
-static void
-gimp_projection_chunk_render_set_area (GimpProjection *proj,
- gint x,
- gint y,
- gint w,
- gint h)
-{
- GimpProjectionChunkRender *chunk_render = &proj->priv->chunk_render;
- cairo_rectangle_int_t rect;
+ while (gimp_chunk_iterator_get_rect (proj->priv->iter, &rect))
+ {
+ gimp_projection_paint_area (proj, TRUE,
+ rect.x, rect.y, rect.width, rect.height);
+ }
- rect.x = x;
- rect.y = y;
- rect.width = w;
- rect.height = h;
+ gimp_tile_handler_validate_end_validate (proj->priv->validate_handler);
- if (chunk_render->update_region)
+ /* Still work to do. */
+ return TRUE;
+ }
+ else
{
- cairo_region_subtract_rectangle (chunk_render->update_region, &rect);
+ proj->priv->iter = NULL;
- if (cairo_region_is_empty (chunk_render->update_region))
- g_clear_pointer (&chunk_render->update_region, cairo_region_destroy);
- }
+ if (proj->priv->invalidate_preview)
+ {
+ /* invalidate the preview here since it is constructed from
+ * the projection
+ */
+ proj->priv->invalidate_preview = FALSE;
- chunk_render->x = rect.x;
- chunk_render->y = rect.y;
- chunk_render->width = rect.width;
- chunk_render->height = rect.height;
+ gimp_projectable_invalidate_preview (proj->priv->projectable);
+ }
- chunk_render->work_x = chunk_render->x;
- chunk_render->work_y = chunk_render->y;
+ /* FINISHED */
+ return FALSE;
+ }
}
static void
@@ -1324,10 +993,11 @@ gimp_projection_projectable_bounds_changed (GimpProjectable *projectable,
#endif
/* reallocate the buffer, and copy the old buffer to the corresponding
- * region of the new buffer. additionally, shift and clip all outstanding
- * update regions as necessary.
+ * region of the new buffer.
*/
+ gimp_projection_chunk_render_stop (proj, TRUE);
+
old_validate_handler = proj->priv->validate_handler;
proj->priv->buffer = NULL;
@@ -1357,41 +1027,6 @@ gimp_projection_projectable_bounds_changed (GimpProjectable *projectable,
cairo_region_intersect_rectangle (proj->priv->update_region, &bounds);
}
- if (proj->priv->chunk_render.idle_id)
- {
- const cairo_rectangle_int_t bounds = {0, 0, w, h};
-
- proj->priv->chunk_render.x += dx;
- proj->priv->chunk_render.y += dy;
-
- proj->priv->chunk_render.work_x += dx;
- proj->priv->chunk_render.work_y += dx;
-
- if (proj->priv->chunk_render.update_region)
- {
- cairo_region_translate
- (proj->priv->chunk_render.update_region, dx, dy);
- cairo_region_intersect_rectangle
- (proj->priv->chunk_render.update_region, &bounds);
- }
-
- if (! gimp_rectangle_intersect (proj->priv->chunk_render.x,
- proj->priv->chunk_render.y,
- proj->priv->chunk_render.width,
- proj->priv->chunk_render.height,
-
- 0, 0, w, h,
-
- &proj->priv->chunk_render.x,
- &proj->priv->chunk_render.y,
- &proj->priv->chunk_render.width,
- &proj->priv->chunk_render.height))
- {
- if (! gimp_projection_chunk_render_next_area (proj))
- gimp_projection_chunk_render_stop (proj);
- }
- }
-
if (proj->priv->priority_rect.width > 0 &&
proj->priv->priority_rect.height > 0)
{
@@ -1422,54 +1057,3 @@ gimp_projection_projectable_bounds_changed (GimpProjectable *projectable,
proj->priv->invalidate_preview = TRUE;
}
-
-static gint
-gimp_projection_round_chunk_size (gdouble size,
- gboolean toward_zero)
-{
- /* round 'size' (up or down, depending on 'toward_zero') to the closest power
- * of 2
- */
-
- if (size < 0.0)
- {
- return -gimp_projection_round_chunk_size (-size, toward_zero);
- }
- else if (size == 0.0)
- {
- return 0;
- }
- else if (size < 1.0)
- {
- return toward_zero ? 0 : 1;
- }
- else
- {
- gdouble log2_size = log (size) / G_LN2;
-
- if (toward_zero)
- log2_size = floor (log2_size);
- else
- log2_size = ceil (log2_size);
-
- return 1 << (gint) log2_size;
- }
-}
-
-static gint
-gimp_projection_round_chunk_width (gdouble width)
-{
- gint w = gimp_projection_round_chunk_size (width, FALSE);
-
- return CLAMP (w, GIMP_PROJECTION_CHUNK_MIN_WIDTH,
- GIMP_PROJECTION_CHUNK_MAX_WIDTH);
-}
-
-static gint
-gimp_projection_round_chunk_height (gdouble height)
-{
- gint h = gimp_projection_round_chunk_size (height, TRUE);
-
- return CLAMP (h, GIMP_PROJECTION_CHUNK_MIN_HEIGHT,
- GIMP_PROJECTION_CHUNK_MAX_HEIGHT);
-}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]