more accurate progress reporting

computation progress used to be done incrementally based on the number
of tiles allocated. This did not take account of half tiles at image
edges, so you could sometimes see "110% complete"

it's now calculated based on the absolute number of pixels processed, so
it should always report 100% at the end.
This commit is contained in:
John Cupitt 2012-04-12 10:01:17 +01:00
parent b47ad26f50
commit 0290eb009d
7 changed files with 31 additions and 14 deletions

View File

@ -6,6 +6,7 @@
- cast to unsigned int now removes <0 values
- vips7 interface to openslide now supports :,level,associated options
- make vips8 cache smaller
- more accurate progress reporting
13/3/12 started 7.28.2
- xres/yres tiffsave args were broken

View File

@ -476,7 +476,7 @@ int vips_image_written( VipsImage *image );
void vips_image_invalidate_all( VipsImage *image );
void vips_image_preeval( VipsImage *image );
void vips_image_eval( VipsImage *image, int w, int h );
void vips_image_eval( VipsImage *image, guint64 processed );
void vips_image_posteval( VipsImage *image );
void vips_image_set_progress( VipsImage *image, gboolean progress );

View File

@ -1092,8 +1092,8 @@ vips_progress_add( VipsImage *image )
return( 0 );
}
void
vips_progress_update( VipsProgress *progress, int w, int h )
static void
vips_progress_update( VipsProgress *progress, guint64 processed )
{
float prop;
@ -1102,11 +1102,11 @@ vips_progress_update( VipsProgress *progress, int w, int h )
g_assert( progress );
progress->run = g_timer_elapsed( progress->start, NULL );
progress->npels += w * h;
progress->npels = processed;
prop = (float) progress->npels / (float) progress->tpels;
progress->percent = 100 * prop;
/* Don't estiomate eta until we are 10% in.
/* Don't estimate eta until we are 10% in.
*/
if( prop > 0.1 )
progress->eta = (1.0 / prop) * progress->run - progress->run;
@ -1135,10 +1135,10 @@ vips_image_preeval( VipsImage *image )
}
}
/* Another w * h pixels have been processed.
/* Updated the number of pixels that have been processed.
*/
void
vips_image_eval( VipsImage *image, int w, int h )
vips_image_eval( VipsImage *image, guint64 processed )
{
if( image->progress_signal ) {
VIPS_DEBUG_MSG( "vips_image_eval: %p\n", image );
@ -1146,7 +1146,7 @@ vips_image_eval( VipsImage *image, int w, int h )
g_assert( vips_object_sanity(
VIPS_OBJECT( image->progress_signal ) ) );
vips_progress_update( image->time, w, h );
vips_progress_update( image->time, processed );
/* For vips7 compat, update the ->time on the signalling image
* too, even though it may have a different width/height to
@ -1154,7 +1154,7 @@ vips_image_eval( VipsImage *image, int w, int h )
*/
if( image->progress_signal->time != image->time )
vips_progress_update( image->progress_signal->time,
w, h );
processed );
g_signal_emit( image->progress_signal,
vips_image_signals[SIG_EVAL], 0, image->time );
@ -1878,7 +1878,7 @@ vips_image_write_line( VipsImage *image, int ypos, VipsPel *linebuffer )
/* Trigger evaluation callbacks for this image.
*/
vips_image_eval( image, image->Xsize, 1 );
vips_image_eval( image, ypos * image->Xsize );
if( vips_image_get_kill( image ) )
return( -1 );

View File

@ -211,6 +211,8 @@ vips_sink_base_init( SinkBase *sink_base, VipsImage *image )
vips_get_tile_size( image,
&sink_base->tile_width, &sink_base->tile_height,
&sink_base->nlines );
sink_base->processed = 0;
}
static int
@ -283,6 +285,10 @@ vips_sink_base_allocate( VipsThreadState *state, void *a, gboolean *stop )
*/
sink_base->x += sink_base->tile_width;
/* Add the number of pixels we've just allocated to progress.
*/
sink_base->processed += state->pos.width * state->pos.height;
return( 0 );
}
@ -305,14 +311,12 @@ vips_sink_base_progress( void *a )
{
SinkBase *sink_base = (SinkBase *) a;
VIPS_DEBUG_MSG( "vips_sink_base_progress: %d x %d\n",
sink_base->tile_width, sink_base->tile_height );
VIPS_DEBUG_MSG( "vips_sink_base_progress:\n" );
/* Trigger any eval callbacks on our source image and
* check for errors.
*/
vips_image_eval( sink_base->im,
sink_base->tile_width, sink_base->tile_height );
vips_image_eval( sink_base->im, sink_base->processed );
if( vips_image_get_kill( sink_base->im ) )
return( -1 );

View File

@ -56,6 +56,10 @@ typedef struct _SinkBase {
int tile_height;
int nlines;
/* The number of pixels allocate has allocated. Used for progress
* feedback.
*/
guint64 processed;
} SinkBase;
/* Some function we can share.

View File

@ -396,6 +396,10 @@ wbuffer_allocate_fn( VipsThreadState *state, void *a, gboolean *stop )
*/
sink_base->x += sink_base->tile_width;
/* Add the number of pixels we've just allocated to progress.
*/
sink_base->processed += state->pos.width * state->pos.height;
return( 0 );
}

View File

@ -240,6 +240,10 @@ sink_memory_area_allocate_fn( VipsThreadState *state, void *a, gboolean *stop )
*/
sink_base->x += sink_base->tile_width;
/* Add the number of pixels we've just allocated to progress.
*/
sink_base->processed += state->pos.width * state->pos.height;
return( 0 );
}