fix im_cache

This commit is contained in:
John Cupitt 2010-11-25 17:20:14 +00:00
parent 1cb6c3a40f
commit 197877e32c
4 changed files with 52 additions and 27 deletions

View File

@ -50,6 +50,7 @@
- update C++/Python binding - update C++/Python binding
- oop, bool constants are always (int) now, so (^-1) works for unsigned types, - oop, bool constants are always (int) now, so (^-1) works for unsigned types,
thanks Nicolas thanks Nicolas
- much lower memuse for im_cache() in complex pipelines
12/5/10 started 7.22.2 12/5/10 started 7.22.2
- the conditional image of ifthenelse can be any format, a (!=0) is added if - the conditional image of ifthenelse can be any format, a (!=0) is added if

3
TODO
View File

@ -1,3 +1,6 @@
- see Haida's mail re. cfitsio and higher dimensions - see Haida's mail re. cfitsio and higher dimensions

View File

@ -229,16 +229,15 @@ im_demand_type im_char2dhint( const char *str )
{ return( char2enum( &enumdhint, str ) ); } { return( char2enum( &enumdhint, str ) ); }
static void * static void *
print_one_line_region( REGION *r, int *n2, gint64 *total ) add_unique( REGION *r, gint64 *total, GSList **seen )
{ {
if( r->type == IM_REGION_BUFFER && r->buffer ) { if( r->type == IM_REGION_BUFFER &&
printf( "\t*** %d) %zd malloced bytes\n", r->buffer &&
*n2, r->buffer->bsize ); !g_slist_find( *seen, r->buffer ) ) {
*seen = g_slist_prepend( *seen, r->buffer );
*total += r->buffer->bsize; *total += r->buffer->bsize;
} }
*n2 += 1;
return( NULL ); return( NULL );
} }
@ -247,36 +246,37 @@ print_one_line_region( REGION *r, int *n2, gint64 *total )
static void * static void *
print_one_line( IMAGE *im, int *n, gint64 *total ) print_one_line( IMAGE *im, int *n, gint64 *total )
{ {
printf( "%2d) %p, %s, %s: %dx%d, %d bands, %s\n", gint64 size;
printf( "%d, %p, %s, %s, %d, %d, %d, %s, ",
*n, *n,
im, im,
im_dtype2char( im->dtype ), im->filename, im_dtype2char( im->dtype ),
im->filename,
im->Xsize, im->Ysize, im->Bands, im->Xsize, im->Ysize, im->Bands,
im_BandFmt2char( im->BandFmt ) ); im_BandFmt2char( im->BandFmt ) );
*n += 1; *n += 1;
size = 0;
if( im->dtype == IM_SETBUF && im->data ) { if( im->dtype == IM_SETBUF && im->data ) {
gint64 size = (gint64) IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize; size = (gint64) IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize;
printf( "\t*** %" G_GINT64_FORMAT " malloced bytes\n", size );
*total += size;
} }
*total += size;
printf( "%" G_GINT64_FORMAT ", ", size );
printf( "%d, ", g_slist_length( im->regions ) );
size = 0;
if( im->regions ) { if( im->regions ) {
int n2; GSList *seen;
gint64 total2;
printf( "\t%d regions\n", g_slist_length( im->regions ) ); seen = NULL;
n2 = 0;
total2 = 0;
(void) im_slist_map2( im->regions, (void) im_slist_map2( im->regions,
(VSListMap2Fn) print_one_line_region, &n2, &total2 ); (VSListMap2Fn) add_unique, &size, &seen );
if( total2 ) g_slist_free( seen );
printf( "\t*** using total of %" G_GINT64_FORMAT
" bytes\n", total2 );
*total += total2;
} }
*total += size;
printf( "%" G_GINT64_FORMAT "\n", size );
return( NULL ); return( NULL );
} }
@ -295,11 +295,13 @@ void
im__print_all( void ) im__print_all( void )
{ {
if( im__open_images ) { if( im__open_images ) {
int n = 0; int n;
gint64 total = 0; gint64 total;
n = 0;
total = 0; total = 0;
printf( "%d images\n", g_slist_length( im__open_images ) ); printf( "n, p, dtype, file, xsize, ysize, bands, fmt, " );
printf( "isize, nreg, rsize\n" );
(void) im_slist_map2( im__open_images, (void) im_slist_map2( im__open_images,
(VSListMap2Fn) print_one_line, &n, &total ); (VSListMap2Fn) print_one_line, &n, &total );
if( total ) if( total )

View File

@ -2,6 +2,9 @@
* *
* 1/1/10 * 1/1/10
* - from im_render.c * - from im_render.c
* 25/11/10
* - in synchronous mode, use a single region for input and save huge
* mem use
*/ */
/* /*
@ -141,6 +144,11 @@ typedef struct _Render {
/* Hash of tiles with positions. Tiles can be dirty or painted. /* Hash of tiles with positions. Tiles can be dirty or painted.
*/ */
GHashTable *tiles; GHashTable *tiles;
/* In synchronous mode (notify == NULL), generate tiles with this
* REGION.
*/
REGION *synchronous_reg;
} Render; } Render;
/* Our per-thread state. /* Our per-thread state.
@ -237,6 +245,7 @@ render_free( Render *render )
render->ntiles = 0; render->ntiles = 0;
IM_FREEF( g_slist_free, render->dirty ); IM_FREEF( g_slist_free, render->dirty );
IM_FREEF( g_hash_table_destroy, render->tiles ); IM_FREEF( g_hash_table_destroy, render->tiles );
IM_FREEF( im_region_free, render->synchronous_reg );
im_free( render ); im_free( render );
@ -615,6 +624,8 @@ render_new( VipsImage *in, VipsImage *out, VipsImage *mask,
render->tiles = g_hash_table_new( tile_hash, tile_equal ); render->tiles = g_hash_table_new( tile_hash, tile_equal );
render->synchronous_reg = NULL;
render->dirty = NULL; render->dirty = NULL;
/* Both out and mask must close before we can free the render. /* Both out and mask must close before we can free the render.
@ -635,6 +646,13 @@ render_new( VipsImage *in, VipsImage *out, VipsImage *mask,
render_ref( render ); render_ref( render );
} }
/* In synchronous mode we need a region to generate pixels with.
*/
if( !notify ) {
if( !(render->synchronous_reg = im_region_create( in )) )
return( NULL );
}
VIPS_DEBUG_MSG_AMBER( "render_new: %p\n", render ); VIPS_DEBUG_MSG_AMBER( "render_new: %p\n", render );
#ifdef VIPS_DEBUG_AMBER #ifdef VIPS_DEBUG_AMBER
@ -770,7 +788,8 @@ tile_queue( Tile *tile )
"painting tile %p %dx%d synchronously\n", "painting tile %p %dx%d synchronously\n",
tile, tile->area.left, tile->area.top ); tile, tile->area.left, tile->area.top );
if( im_prepare( tile->region, &tile->area ) ) if( im_prepare_to( render->synchronous_reg, tile->region,
&tile->area, tile->area.left, tile->area.top ) )
VIPS_DEBUG_MSG_RED( "tile_queue: prepare failed\n" ); VIPS_DEBUG_MSG_RED( "tile_queue: prepare failed\n" );
tile->painted = TRUE; tile->painted = TRUE;