fix sharing detection (again)

This commit is contained in:
John Cupitt 2013-12-13 12:20:05 +00:00
parent ffd04bce91
commit c782150a6d
3 changed files with 44 additions and 17 deletions

19
TODO
View File

@ -1,3 +1,20 @@
- the change to reduce region churn
https://github.com/jcupitt/libvips/commit/6ae1888ab3a078f81fc50a967b38ac2aaefe4187
has broken sharing, try:
vips sharpen k2.jpg x.jpg
no colour info in x.jpg, we no longer detect and share buffers
need to clear 'done' on the buffers?
- some malloc/free cycling in
vips sharpen in out
@ -20,6 +37,8 @@
each image needs a per-thread list of unreffed buffers ready for reuse
done in branch "reserve", fix master as noted above and merge

View File

@ -226,6 +226,9 @@ vips_buffer_undone( VipsBuffer *buffer )
buffer->done = FALSE;
buffer->cache = NULL;
buffer->area.width = 0;
buffer->area.height = 0;
#ifdef DEBUG
printf( "vips_buffer_undone: %d buffers left\n",
g_slist_length( cache_list->buffers ) );
@ -318,10 +321,11 @@ buffer_move( VipsBuffer *buffer, VipsRect *area )
g_assert( buffer->ref_count == 1 );
buffer->area = *area;
vips_buffer_undone( buffer );
g_assert( !buffer->done );
buffer->area = *area;
new_bsize = (size_t) VIPS_IMAGE_SIZEOF_PEL( im ) *
area->width * area->height;
if( buffer->bsize < new_bsize ) {

View File

@ -41,8 +41,6 @@
* - move invalid stuff to region
* 3/3/11
* - move on top of VipsObject, rename as VipsRegion
* 7/12/13
* - delay attached resource unref to reduce malloc/free cycling
*/
/*
@ -75,8 +73,8 @@
/*
#define DEBUG_MOVE
#define DEBUG_ENVIRONMENT 1
#define DEBUG_CREATE
#define DEBUG
#define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H
@ -199,7 +197,7 @@ vips_region_finalize( GObject *gobject )
/* Call a start function if no sequence is running on this VipsRegion.
*/
static int
int
vips__region_start( VipsRegion *region )
{
VipsImage *image = region->im;
@ -229,7 +227,7 @@ vips__region_start( VipsRegion *region )
/* Call a stop function if a sequence is running in this VipsRegion.
*/
static void
void
vips__region_stop( VipsRegion *region )
{
IMAGE *image = region->im;
@ -267,7 +265,7 @@ vips_region_dispose( GObject *gobject )
VipsImage *image = region->im;
#ifdef VIPS_DEBUG
printf( "vips_region_dispose: \n" );
VIPS_DEBUG_MSG( "vips_region_dispose: " );
vips_object_print_name( VIPS_OBJECT( gobject ) );
#endif /*VIPS_DEBUG*/
@ -493,10 +491,6 @@ vips_region_new( VipsImage *image )
{
VipsRegion *region;
/*
printf( "vips_region_new: on image %p\n", image );
*/
/* Ref quickly, we want to make sure we keep the image around.
* We can't use the property system, we need to be very threaded.
*/
@ -570,17 +564,18 @@ vips_region_buffer( VipsRegion *reg, VipsRect *r )
* If not, try to reuse the current buffer.
*/
if( reg->invalid ) {
if( reg->buffer )
vips_buffer_undone( reg->buffer );
reg->invalid = FALSE;
VIPS_FREEF( vips_buffer_unref, reg->buffer );
if( !(reg->buffer = vips_buffer_new( im, &clipped )) )
return( -1 );
}
else {
/* Don't unref the old buffer ... we combine buffer unref
/* Don't call vips_region_reset() ... we combine buffer unref
* and new buffer ref in one call to reduce malloc/free
* cycling.
*/
reg->invalid = FALSE;
VIPS_FREEF( vips_window_unref, reg->window );
if( !(reg->buffer =
vips_buffer_unref_ref( reg->buffer, im, &clipped )) )
return( -1 );
@ -637,11 +632,14 @@ vips_region_image( VipsRegion *reg, VipsRect *r )
if( image->data ) {
/* We have the whole image available ... easy!
*
* We can't just set valid = clipped, since this may be an
*/
if( reg->buffer )
vips_buffer_undone( reg->buffer );
reg->invalid = FALSE;
/* We can't just set valid = clipped, since this may be an
* incompletely calculated memory buffer. Just set valid to r.
*/
reg->invalid = FALSE;
reg->valid = clipped;
reg->bpl = VIPS_IMAGE_SIZEOF_LINE( image );
reg->data = VIPS_IMAGE_ADDR( image, clipped.left, clipped.top );
@ -656,6 +654,7 @@ vips_region_image( VipsRegion *reg, VipsRect *r )
reg->window->top + reg->window->height <
clipped.top + clipped.height ) {
reg->invalid = FALSE;
VIPS_FREEF( vips_window_unref, reg->window );
if( !(reg->window = vips_window_ref( image,
clipped.top, clipped.height )) )
@ -783,6 +782,11 @@ vips_region_region( VipsRegion *reg,
/* Init new stuff.
*/
if( reg->buffer ) {
vips_buffer_undone( reg->buffer );
reg->buffer->area.width = 0;
reg->buffer->area.height = 0;
}
reg->invalid = FALSE;
reg->valid = final;
reg->bpl = dest->bpl;