app: more responsiveness improvements to GimpChunkIterator
Improve GimpChunkIterator's responsiveness to changes in processing
speed.
(cherry picked from commit 91f4c809d8)
This commit is contained in:
parent
1096bdfd53
commit
4d2a5d1a94
1 changed files with 47 additions and 13 deletions
|
|
@ -42,7 +42,7 @@
|
|||
#define DEFAULT_INTERVAL (1.0 / 15.0) /* seconds */
|
||||
|
||||
/* the minimal area to process per iteration */
|
||||
#define MIN_AREA_PER_ITERATION 1024
|
||||
#define MIN_AREA_PER_ITERATION 4096
|
||||
|
||||
/* the maximal ratio between the actual processed area and the target area,
|
||||
* above which the current chunk height is readjusted, even in the middle of a
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
#define MAX_AREA_RATIO 2.0
|
||||
|
||||
/* the width of the target-area sliding window */
|
||||
#define TARGET_AREA_HISTORY_SIZE 5
|
||||
#define TARGET_AREA_HISTORY_SIZE 3
|
||||
|
||||
|
||||
struct _GimpChunkIterator
|
||||
|
|
@ -73,9 +73,11 @@ struct _GimpChunkIterator
|
|||
|
||||
gint64 iteration_time;
|
||||
|
||||
gdouble current_area;
|
||||
gdouble target_area;
|
||||
gint64 last_time;
|
||||
gint last_area;
|
||||
|
||||
gdouble target_area;
|
||||
gdouble target_area_min;
|
||||
gdouble target_area_history[TARGET_AREA_HISTORY_SIZE];
|
||||
gint target_area_history_i;
|
||||
gint target_area_history_n;
|
||||
|
|
@ -95,6 +97,7 @@ static gboolean gimp_chunk_iterator_prepare (GimpChunkIterator *i
|
|||
static void gimp_chunk_iterator_set_target_area (GimpChunkIterator *iter,
|
||||
gdouble target_area);
|
||||
static gdouble gimp_chunk_iterator_get_target_area (GimpChunkIterator *iter);
|
||||
static void gimp_chunk_iterator_reset_target_area (GimpChunkIterator *iter);
|
||||
|
||||
static void gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
|
||||
GeglRectangle *rect,
|
||||
|
|
@ -246,6 +249,8 @@ gimp_chunk_iterator_set_target_area (GimpChunkIterator *iter,
|
|||
{
|
||||
gdouble target_area_history[TARGET_AREA_HISTORY_SIZE];
|
||||
|
||||
iter->target_area_min = MIN (iter->target_area_min, target_area);
|
||||
|
||||
iter->target_area_history[iter->target_area_history_i++] = target_area;
|
||||
|
||||
iter->target_area_history_n = MAX (iter->target_area_history_n,
|
||||
|
|
@ -264,12 +269,24 @@ gimp_chunk_iterator_set_target_area (GimpChunkIterator *iter,
|
|||
static gdouble
|
||||
gimp_chunk_iterator_get_target_area (GimpChunkIterator *iter)
|
||||
{
|
||||
if (iter->target_area_history_n)
|
||||
if (iter->target_area)
|
||||
return iter->target_area;
|
||||
else
|
||||
return iter->tile_rect.width * iter->tile_rect.height;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_chunk_iterator_reset_target_area (GimpChunkIterator *iter)
|
||||
{
|
||||
if (iter->target_area_history_n)
|
||||
{
|
||||
iter->target_area = iter->target_area_min;
|
||||
iter->target_area_min = MAX_CHUNK_WIDTH * MAX_CHUNK_HEIGHT;
|
||||
iter->target_area_history_i = 0;
|
||||
iter->target_area_history_n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
|
||||
GeglRectangle *rect,
|
||||
|
|
@ -280,6 +297,9 @@ gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
|
|||
gint offset_x;
|
||||
gint offset_y;
|
||||
|
||||
if (readjust_height)
|
||||
gimp_chunk_iterator_reset_target_area (iter);
|
||||
|
||||
target_area = gimp_chunk_iterator_get_target_area (iter);
|
||||
|
||||
aspect_ratio = (gdouble) iter->tile_rect.height /
|
||||
|
|
@ -293,11 +313,12 @@ gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
|
|||
|
||||
if (readjust_height)
|
||||
{
|
||||
rect->height = ceil ((offset_y + sqrt (target_area * aspect_ratio)) /
|
||||
rect->height = RINT ((offset_y + sqrt (target_area * aspect_ratio)) /
|
||||
iter->tile_rect.height) *
|
||||
iter->tile_rect.height -
|
||||
offset_y;
|
||||
|
||||
rect->height = MAX (rect->height, iter->tile_rect.height);
|
||||
rect->height = MIN (rect->height,
|
||||
iter->current_rect.y + iter->current_rect.height -
|
||||
rect->y);
|
||||
|
|
@ -308,12 +329,13 @@ gimp_chunk_iterator_calc_rect (GimpChunkIterator *iter,
|
|||
rect->height = iter->current_height;
|
||||
}
|
||||
|
||||
rect->width = ceil ((offset_x + (gdouble) target_area /
|
||||
rect->width = RINT ((offset_x + (gdouble) target_area /
|
||||
(gdouble) rect->height) /
|
||||
iter->tile_rect.width) *
|
||||
iter->tile_rect.width -
|
||||
offset_x;
|
||||
|
||||
rect->width = MAX (rect->width, iter->tile_rect.width);
|
||||
rect->width = MIN (rect->width,
|
||||
iter->current_rect.x + iter->current_rect.width -
|
||||
rect->x);
|
||||
|
|
@ -414,7 +436,8 @@ gimp_chunk_iterator_next (GimpChunkIterator *iter)
|
|||
|
||||
iter->iteration_time = g_get_monotonic_time ();
|
||||
|
||||
iter->current_area = 0;
|
||||
iter->last_time = iter->iteration_time;
|
||||
iter->last_area = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -423,22 +446,27 @@ gboolean
|
|||
gimp_chunk_iterator_get_rect (GimpChunkIterator *iter,
|
||||
GeglRectangle *rect)
|
||||
{
|
||||
gint64 time;
|
||||
|
||||
g_return_val_if_fail (iter != NULL, FALSE);
|
||||
g_return_val_if_fail (rect != NULL, FALSE);
|
||||
|
||||
if (! gimp_chunk_iterator_prepare (iter))
|
||||
return FALSE;
|
||||
|
||||
if (iter->current_area >= MIN_AREA_PER_ITERATION)
|
||||
time = g_get_monotonic_time ();
|
||||
|
||||
if (iter->last_area >= MIN_AREA_PER_ITERATION)
|
||||
{
|
||||
gdouble interval;
|
||||
|
||||
interval = (gdouble) (g_get_monotonic_time () - iter->iteration_time) /
|
||||
G_TIME_SPAN_SECOND;
|
||||
interval = (gdouble) (time - iter->last_time) / G_TIME_SPAN_SECOND;
|
||||
|
||||
gimp_chunk_iterator_set_target_area (
|
||||
iter,
|
||||
iter->current_area * iter->interval / interval);
|
||||
iter->last_area * iter->interval / interval);
|
||||
|
||||
interval = (gdouble) (time - iter->iteration_time) / G_TIME_SPAN_SECOND;
|
||||
|
||||
if (interval > iter->interval)
|
||||
return FALSE;
|
||||
|
|
@ -455,7 +483,12 @@ gimp_chunk_iterator_get_rect (GimpChunkIterator *iter,
|
|||
if (rect->width * rect->height >=
|
||||
MAX_AREA_RATIO * gimp_chunk_iterator_get_target_area (iter))
|
||||
{
|
||||
GeglRectangle old_rect = *rect;
|
||||
|
||||
gimp_chunk_iterator_calc_rect (iter, rect, TRUE);
|
||||
|
||||
if (rect->height >= old_rect.height)
|
||||
*rect = old_rect;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -485,7 +518,8 @@ gimp_chunk_iterator_get_rect (GimpChunkIterator *iter,
|
|||
|
||||
iter->current_x += rect->width;
|
||||
|
||||
iter->current_area += rect->width * rect->height;
|
||||
iter->last_time = time;
|
||||
iter->last_area = rect->width * rect->height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue