/* aynchronous screen sink
 *
 * 1/1/10
 * 	- from im_render.c
 */

/*

    This file is part of VIPS.
    
    VIPS is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 */

/*

    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk

 */

/* Verbose debugging output.
#define VIPS_DEBUG
 */

/* Trace allocate/free.
#define VIPS_DEBUG_AMBER
 */

/* Trace reschedule
#define VIPS_DEBUG_GREEN
 */

/* Trace serious problems.
#define VIPS_DEBUG_RED
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /*HAVE_UNISTD_H*/

#include <vips/vips.h>
#include <vips/thread.h>
#include <vips/debug.h>

#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/

/* A have-threads we can test in if().
 */
#ifdef HAVE_THREADS
static const int have_threads = 1;
#else /*!HAVE_THREADS*/
static const int have_threads = 0;
#endif /*HAVE_THREADS*/

#ifdef VIPS_DEBUG_AMBER
static int render_num_renders = 0;
#endif /*VIPS_DEBUG_AMBER*/

/* A tile in our cache. 
 */
typedef struct {
	struct _Render *render;

	Rect area;		/* Place here (unclipped) */
	REGION *region;		/* REGION with the pixels */

	/* The tile contains calculated pixels. Though the region may have been
	 * invalidated behind our backs: we have to check that too.
	 */
	gboolean painted;

	/* The tile is on the dirty list. This saves us having to search the
	 * dirty list all the time.
	 */
	gboolean dirty;

	/* Time of last use, for LRU flush 
	 */
	int ticks;
} Tile;

/* Per-call state.
 */
typedef struct _Render {
	/* Reference count this, since we use these things from several
	 * threads. We can't easily use the gobject ref count system since we
	 * need a lock around operations.
	 */
	int ref_count;
	GMutex *ref_count_lock;	

	/* Parameters.
	 */
	VipsImage *in;		/* Image we render */
	VipsImage *out;		/* Write tiles here on demand */
	VipsImage *mask;	/* Set valid pixels here */
	int tile_width;		/* Tile size */
	int tile_height;
	int max_tiles;		/* Maximum number of tiles */
	int priority;		/* Larger numbers done sooner */
	VipsSinkNotify notify;	/* Tell caller about paints here */
	void *a;

	/* Lock here before reading or modifying the tile structure. 
	 */
	GMutex *lock;	

	/* Tile cache.
	 */
	GSList *all;		/* All our tiles */
	int ntiles;		/* Number of tiles */
	int ticks;		/* Inc. on each access ... used for LRU */

	/* List of dirty tiles. Most recent at the front.
	 */
	GSList *dirty;		

	/* Hash of tiles with positions. Tiles can be dirty or painted.
	 */
	GHashTable *tiles;
} Render;

/* Our per-thread state.
 */
typedef struct _RenderThreadState {
	VipsThreadState parent_object;

	/* The tile that should be calculated.
	 */
	Tile *tile;
} RenderThreadState;

typedef struct _RenderThreadStateClass {
	VipsThreadStateClass parent_class;

} RenderThreadStateClass;

G_DEFINE_TYPE( RenderThreadState, render_thread_state, VIPS_TYPE_THREAD_STATE );

/* The BG thread which sits waiting to do some calculations.
 */
static GThread *render_thread = NULL;

/* Number of renders with dirty tiles. render_thread queues up on this.
 */
static im_semaphore_t render_dirty_sem;

/* All the renders with dirty tiles.
 */
static GMutex *render_dirty_lock = NULL;
static GSList *render_dirty_all = NULL;

/* Set this to make the bg thread stop and reschedule.
 */
static gboolean render_reschedule = FALSE;

static void
render_thread_state_class_init( RenderThreadStateClass *class )
{
	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );

	object_class->nickname = "renderthreadstate";
	object_class->description = _( "per-thread state for render" );
}

static void
render_thread_state_init( RenderThreadState *state )
{
	state->tile = NULL;
}

static VipsThreadState *
render_thread_state_new( VipsImage *im, void *a )
{
	return( VIPS_THREAD_STATE( vips_object_new( 
		render_thread_state_get_type(), 
		vips_thread_state_set, im, a ) ) );
}

static void *
tile_free( Tile *tile )
{
	VIPS_DEBUG_MSG_AMBER( "tile_free\n" );

	IM_FREEF( im_region_free, tile->region );
	im_free( tile );

	return( NULL );
}

static int
render_free( Render *render )
{
	VIPS_DEBUG_MSG_AMBER( "render_free: %p\n", render );

	g_assert( render->ref_count == 0 );

	g_mutex_lock( render_dirty_lock );
	if( g_slist_find( render_dirty_all, render ) ) {
		render_dirty_all = g_slist_remove( render_dirty_all, render );

		/* We could im_semaphore_upn( &render_dirty_sem, -1 ), but
		 * what's the point. We'd just wake up the bg thread
		 * for no reason.
		 */
	}
	g_mutex_unlock( render_dirty_lock );

	g_mutex_free( render->ref_count_lock );
	g_mutex_free( render->lock );

	im_slist_map2( render->all, (VSListMap2Fn) tile_free, NULL, NULL );
	IM_FREEF( g_slist_free, render->all );
	render->ntiles = 0;
	IM_FREEF( g_slist_free, render->dirty );
	IM_FREEF( g_hash_table_destroy, render->tiles );

	im_free( render );

#ifdef VIPS_DEBUG_AMBER
	render_num_renders -= 1;
#endif /*VIPS_DEBUG_AMBER*/

	return( 0 );
}

/* Ref and unref a Render ... free on last unref.
 */
static int
render_ref( Render *render )
{
	g_mutex_lock( render->ref_count_lock );
	g_assert( render->ref_count != 0 );
	render->ref_count += 1;
	g_mutex_unlock( render->ref_count_lock );

	return( 0 );
}

static int
render_unref( Render *render )
{
	int kill;

	g_mutex_lock( render->ref_count_lock );
	g_assert( render->ref_count > 0 );
	render->ref_count -= 1;
	kill = render->ref_count == 0;
	g_mutex_unlock( render->ref_count_lock );

	if( kill )
		render_free( render );

	return( 0 );
}

/* Wait for a render with dirty tiles. 
 */
static Render *
render_dirty_get( void )
{
	Render *render;

	/* Wait for a render with dirty tiles.
	 */
	im_semaphore_down( &render_dirty_sem );

	g_mutex_lock( render_dirty_lock );

	/* Just take the head of the jobs list ... we sort when we add. If
	 * render_free() is called between our semaphore letting us in
	 * and the _lock(), render_dirty_all can be NULL.
	 */
	render = NULL;
	if( render_dirty_all ) {
		render = (Render *) render_dirty_all->data;

		/* Ref the render to make sure it can't die while we're
		 * working on it.
		 */
		render_ref( render );

		render_dirty_all = g_slist_remove( render_dirty_all, render );
	}

	g_mutex_unlock( render_dirty_lock );

	return( render );
}

/* Get the next tile to paint off the dirty list.
 */
static Tile *
render_tile_dirty_get( Render *render )
{
	Tile *tile;

	if( !render->dirty )
		tile = NULL;
	else {
		tile = (Tile *) render->dirty->data;
		g_assert( tile->dirty );
		render->dirty = g_slist_remove( render->dirty, tile );
		tile->dirty = FALSE;
	}

	return( tile );
}

/* Pick a dirty tile to reuse. We could potentially get the tile that
 * render_work() is working on in the background :-( but I don't think we'll
 * get a crash, just a mis-paint. It should be vanishingly impossible anyway.
 */
static Tile *
render_tile_dirty_reuse( Render *render )
{
	Tile *tile;

	if( !render->dirty )
		tile = NULL;
	else {
		tile = (Tile *) g_slist_last( render->dirty )->data;
		render->dirty = g_slist_remove( render->dirty, tile );
		g_assert( tile->dirty );
		tile->dirty = FALSE;

		VIPS_DEBUG_MSG( "render_tile_get_dirty_reuse: "
			"reusing dirty %p\n", tile );
	}

	return( tile );
}

/* Add a tile to the dirty list.
 */
static void
tile_dirty_set( Tile *tile )
{
	Render *render = tile->render;

	if( !tile->dirty ) {
		g_assert( !g_slist_find( render->dirty, tile ) );
		render->dirty = g_slist_prepend( render->dirty, tile );
		tile->dirty = TRUE;
		tile->painted = FALSE;
	}
	else
		g_assert( g_slist_find( render->dirty, tile ) );
}

/* Bump a tile to the front of the dirty list, if it's there.
 */
static void
tile_dirty_bump( Tile *tile )
{
	Render *render = tile->render;

	if( tile->dirty ) {
		g_assert( g_slist_find( render->dirty, tile ) );

		render->dirty = g_slist_remove( render->dirty, tile );
		render->dirty = g_slist_prepend( render->dirty, tile );
	}
	else
		g_assert( !g_slist_find( render->dirty, tile ) );
}

static int 
render_allocate( VipsThreadState *state, void *a, gboolean *stop )
{
	Render *render = (Render *) a;
	RenderThreadState *rstate = (RenderThreadState *) state;
	Tile *tile;

	g_mutex_lock( render->lock );

	if( render_reschedule || 
		!(tile = render_tile_dirty_get( render )) ) {
		VIPS_DEBUG_MSG_GREEN( "render_allocate: stopping\n" );
		*stop = TRUE;
		rstate->tile = NULL;
	}
	else 
		rstate->tile = tile;

	g_mutex_unlock( render->lock );

	return( 0 );
}

static int 
render_work( VipsThreadState *state, void *a )
{
	Render *render = (Render *) a;
	RenderThreadState *rstate = (RenderThreadState *) state;
	Tile *tile = rstate->tile;

	g_assert( tile );

	VIPS_DEBUG_MSG( "calculating tile %p %dx%d\n", 
		tile, tile->area.left, tile->area.top );

	if( im_prepare_to( state->reg, tile->region, 
		&tile->area, tile->area.left, tile->area.top ) ) {
		VIPS_DEBUG_MSG_RED( "render_work: im_prepare_to() failed\n" ); 
		return( -1 );
	}
	tile->painted = TRUE;

	/* Now clients can update.
	 */
	if( render->notify ) 
		render->notify( render->out, &tile->area, render->a );

	return( 0 );
}

static int       
render_dirty_sort( Render *a, Render *b )
{
	return( b->priority - a->priority );
}

/* Add to the jobs list, if it has work to be done.
 */
static void
render_dirty_put( Render *render )
{
	g_mutex_lock( render_dirty_lock );

	if( render->dirty ) {
		if( !g_slist_find( render_dirty_all, render ) ) {
			render_dirty_all = g_slist_prepend( render_dirty_all, 
				render );
			render_dirty_all = g_slist_sort( render_dirty_all,
				(GCompareFunc) render_dirty_sort );

			/* Ask the bg thread to stop and reschedule, if it's
			 * running.
			 */
			VIPS_DEBUG_MSG_GREEN( "render_dirty_put: "
				"reschedule\n" );
			render_reschedule = TRUE;

			im_semaphore_up( &render_dirty_sem );
		}
	}

	g_mutex_unlock( render_dirty_lock );
}

/* Main loop for RenderThreads.
 */
static void *
render_thread_main( void *client )
{
	for(;;) {
		Render *render;

		if( (render = render_dirty_get()) ) {
			/* Ignore errors, I'm not sure what we'd do with them
			 * anyway.
			 */
			VIPS_DEBUG_MSG_GREEN( "render_thread_main: "
				"threadpool start\n" );

			render_reschedule = FALSE;
			if( vips_threadpool_run( render->in,
				render_thread_state_new,
				render_allocate,
				render_work,
				NULL,
				render ) )
				VIPS_DEBUG_MSG_RED( "render_thread_main: "
					"threadpool_run failed\n" );

			VIPS_DEBUG_MSG_GREEN( "render_thread_main: "
				"threadpool return\n" );

			/* Add back to the jobs list, if we need to.
			 */
			render_dirty_put( render );

			/* _get() does a ref to make sure we keep the render
			 * alive during processing ... unref before we loop.
			 * This can kill off the render.
			 */
			render_unref( render );
		}
	}

	return( NULL );
}

/* Create our set of RenderThread. Assume we're single-threaded here.
 */
static int
render_thread_create( void )
{
	if( !have_threads )
		return( 0 );

	if( !render_dirty_lock ) {
		render_dirty_lock = g_mutex_new();
		im_semaphore_init( &render_dirty_sem, 0, "render_dirty_sem" );
	}

	if( !render_thread && have_threads ) {
		if( !(render_thread = g_thread_create_full( 
			render_thread_main, NULL, 
			IM__DEFAULT_STACK_SIZE, TRUE, FALSE, 
			G_THREAD_PRIORITY_NORMAL, NULL )) ) {
			im_error( "im_render", 
				"%s", _( "unable to create thread" ) );
			return( -1 );
		}
	}

	return( 0 );
}

static guint
tile_hash( gconstpointer key )
{
	Rect *rect = (Rect *) key;

	int x = rect->left / rect->width;
	int y = rect->top / rect->height;

	return( x << 16 ^ y );
}

static gboolean
tile_equal( gconstpointer a, gconstpointer b )
{
	Rect *rect1 = (Rect *) a;
	Rect *rect2 = (Rect *) b;

	return( rect1->left == rect2->left &&
		rect1->top == rect2->top );
}

static int
render_close_cb( Render *render )
{
	VIPS_DEBUG_MSG_AMBER( "render_close_cb\n" );

	render_unref( render );

	/* If this render is being worked on, we want to jog the bg thread, 
	 * make it drop it's ref and think again.
	 */
	VIPS_DEBUG_MSG_GREEN( "render_close_cb: reschedule\n" );
	render_reschedule = TRUE;

	return( 0 );
}

static Render *
render_new( VipsImage *in, VipsImage *out, VipsImage *mask, 
	int tile_width, int tile_height, 
	int max_tiles, 
	int priority,
	VipsSinkNotify notify, void *a )
{
	Render *render;

	/* Don't use auto-free for render, we do our own lifetime management
	 * with _ref() and _unref().
	 */
	if( !(render = IM_NEW( NULL, Render )) )
		return( NULL );

	render->ref_count = 1;
	render->ref_count_lock = g_mutex_new();

	render->in = in;
	render->out = out;
	render->mask = mask;
	render->tile_width = tile_width;
	render->tile_height = tile_height;
	render->max_tiles = max_tiles;
	render->priority = priority;
	render->notify = notify;
	render->a = a;

	render->lock = g_mutex_new();

	render->all = NULL;
	render->ntiles = 0;
	render->ticks = 0;

	render->tiles = g_hash_table_new( tile_hash, tile_equal ); 

	render->dirty = NULL;

	/* Both out and mask must close before we can free the render.
	 */

	if( im_add_close_callback( out, 
                (im_callback_fn) render_close_cb, render, NULL ) ) {
                (void) render_unref( render );
                return( NULL );
        }

	if( mask ) {
		if( im_add_close_callback( mask, 
			(im_callback_fn) render_close_cb, render, NULL ) ) {
			(void) render_unref( render );
			return( NULL );
		}
		render_ref( render );
	}

	VIPS_DEBUG_MSG_AMBER( "render_new: %p\n", render );

#ifdef VIPS_DEBUG_AMBER
	render_num_renders += 1;
#endif /*VIPS_DEBUG_AMBER*/

	return( render );
}

/* Make a Tile.
 */
static Tile *
tile_new( Render *render )
{
	Tile *tile;

	VIPS_DEBUG_MSG_AMBER( "tile_new\n" );

	/* Don't use auto-free: we need to make sure we free the tile after
	 * Render.
	 */
	if( !(tile = IM_NEW( NULL, Tile )) )
		return( NULL );

	tile->render = render;
	tile->area.left = 0;
	tile->area.top = 0;
	tile->area.width = render->tile_width;
	tile->area.height = render->tile_height;
	tile->region = NULL;
	tile->painted = FALSE;
	tile->dirty = FALSE;
	tile->ticks = render->ticks;

	if( !(tile->region = im_region_create( render->in )) ) {
		(void) tile_free( tile );
		return( NULL );
	}

	render->all = g_slist_prepend( render->all, tile );
	render->ntiles += 1;

	return( tile );
}

/* Search the cache for a tile by position.
 */
static Tile *
render_tile_lookup( Render *render, Rect *area )
{
	return( (Tile *) g_hash_table_lookup( render->tiles, area ) );
}

/* Add a new tile to the table.
 */
static void
render_tile_add( Tile *tile, Rect *area )
{
	Render *render = tile->render;

	g_assert( !render_tile_lookup( render, area ) );

	tile->area = *area;
	tile->painted = FALSE;

	/* Ignore buffer allocate errors, there's not much we could do with 
	 * them.
	 */
	if( im_region_buffer( tile->region, &tile->area ) )
		VIPS_DEBUG_MSG_RED( "render_tile_add: "
			"buffer allocate failed\n" ); 

	g_hash_table_insert( render->tiles, &tile->area, tile );
}

/* Move a tile to a new position.
 */
static void
render_tile_move( Tile *tile, Rect *area )
{
	Render *render = tile->render;

	g_assert( render_tile_lookup( render, &tile->area ) );

	if( tile->area.left != area->left ||
		tile->area.top != area->top ) {
		g_assert( !render_tile_lookup( render, area ) );

		g_hash_table_remove( render->tiles, &tile->area );
		render_tile_add( tile, area );
	}
}

/* We've looked at a tile ... bump to end of LRU and front of dirty.
 */
static void
tile_touch( Tile *tile )
{
	Render *render = tile->render;

	tile->ticks = render->ticks;
	render->ticks += 1;
	tile_dirty_bump( tile );
}

/* Queue a tile for calculation. 
 */
static void
tile_queue( Tile *tile )
{
	Render *render = tile->render;

	VIPS_DEBUG_MSG( "tile_queue: adding tile %p %dx%d to dirty\n",
		tile, tile->area.left, tile->area.top );

	tile->painted = FALSE;
	tile_touch( tile );

	if( render->notify && have_threads ) {
		/* Add to the list of renders with dirty tiles. The bg 
		 * thread will pick it up and paint it. It can be already on
		 * the dirty list.
		 */
		tile_dirty_set( tile ); 
		render_dirty_put( render );
	}
	else {
		/* No threads, or no notify ... paint the tile ourselves 
		 * sychronously. No need to notify the client since they'll 
		 * never see black tiles.
		 */
		VIPS_DEBUG_MSG( "tile_queue: "
			"painting tile %p %dx%d synchronously\n",
			tile, tile->area.left, tile->area.top );

		if( im_prepare( tile->region, &tile->area ) )
			VIPS_DEBUG_MSG_RED( "tile_queue: prepare failed\n" ); 

		tile->painted = TRUE;
	}
}

static void 
tile_test_clean_ticks( Rect *key, Tile *value, Tile **best )
{
	if( value->painted )
		if( !*best || value->ticks < (*best)->ticks )
			*best = value;
}

/* Pick a painted tile to reuse. Search for LRU (slow!).
 */
static Tile *
render_tile_get_painted( Render *render )
{
	Tile *tile;

	tile = NULL;
	g_hash_table_foreach( render->tiles,
		(GHFunc) tile_test_clean_ticks, &tile );

	if( tile ) {
		VIPS_DEBUG_MSG( "render_tile_get_painted: "
			"reusing painted %p\n", tile );
	}

	return( tile );
}

/* Ask for an area of calculated pixels. Get from cache, request calculation,
 * or if we've no threads or no notify, calculate immediately.
 */
static Tile *
render_tile_request( Render *render, Rect *area )
{
	Tile *tile;

	VIPS_DEBUG_MSG( "render_tile_request: asking for %dx%d\n",
		area->left, area->top );

	if( (tile = render_tile_lookup( render, area )) ) {
		/* We already have a tile at this position. If it's invalid,
		 * ask for a repaint.
		 */
		if( tile->region->invalid ) 
			tile_queue( tile );
		else
			tile_touch( tile );
	}
	else if( render->ntiles < render->max_tiles || 
		render->max_tiles == -1 ) {
		/* We have fewer tiles than teh max. We can just make a new 
		 * tile.
		 */
		if( !(tile = tile_new( render )) ) 
			return( NULL );

		render_tile_add( tile, area );

		tile_queue( tile );
	}
	else {
		/* Need to reuse a tile. Try for an old painted tile first, 
		 * then if that fails, reuse a dirty tile. 
		 */
		if( !(tile = render_tile_get_painted( render )) &&
			!(tile = render_tile_dirty_reuse( render )) ) {
			VIPS_DEBUG_MSG( "render_tile_request: "
				"no tiles to reuse\n" );
			return( NULL );
		}

		render_tile_move( tile, area );

		tile_queue( tile );
	}

	return( tile );
}

/* Copy what we can from the tile into the region.
 */
static void
tile_copy( Tile *tile, REGION *to )
{
	Rect ovlap;
	int y;

	/* Find common pixels.
	 */
	im_rect_intersectrect( &tile->area, &to->valid, &ovlap );
	g_assert( !im_rect_isempty( &ovlap ) );

	/* If the tile is painted, copy over the pixels. Otherwise, fill with
	 * zero. 
	 */
	if( tile->painted && !tile->region->invalid ) {
		int len = IM_IMAGE_SIZEOF_PEL( to->im ) * ovlap.width;

		VIPS_DEBUG_MSG( "tile_copy: "
			"copying calculated pixels for %p %dx%d\n",
			tile, tile->area.left, tile->area.top ); 

		for( y = ovlap.top; y < IM_RECT_BOTTOM( &ovlap ); y++ ) {
			PEL *p = (PEL *) IM_REGION_ADDR( tile->region, 
				ovlap.left, y );
			PEL *q = (PEL *) IM_REGION_ADDR( to, ovlap.left, y );

			memcpy( q, p, len );
		}
	}
	else {
		VIPS_DEBUG_MSG( "tile_copy: zero filling for %p %dx%d\n",
			tile, tile->area.left, tile->area.top ); 
		im_region_paint( to, &ovlap, 0 );
	}
}

/* Loop over the output region, filling with data from cache.
 */
static int
region_fill( REGION *out, void *seq, void *a, void *b )
{
	Render *render = (Render *) a;
	Rect *r = &out->valid;
	int x, y;

	/* Find top left of tiles we need.
	 */
	int xs = (r->left / render->tile_width) * render->tile_width;
	int ys = (r->top / render->tile_height) * render->tile_height;

	VIPS_DEBUG_MSG( "region_fill: left = %d, top = %d, "
		"width = %d, height = %d\n",
                r->left, r->top, r->width, r->height );

	g_mutex_lock( render->lock );

	/* 

		FIXME ... if r fits inside a single tile, we could skip the 
		copy.

	 */

	for( y = ys; y < IM_RECT_BOTTOM( r ); y += render->tile_height )
		for( x = xs; x < IM_RECT_RIGHT( r ); x += render->tile_width ) {
			Rect area;
			Tile *tile;

			area.left = x;
			area.top = y;
			area.width = render->tile_width;
			area.height = render->tile_height;

			tile = render_tile_request( render, &area );
			if( tile )
				tile_copy( tile, out );
			else
				VIPS_DEBUG_MSG_RED( "region_fill: argh!\n" );
		}

	g_mutex_unlock( render->lock );

	return( 0 );
}

/* The mask image is 255 / 0 for the state of painted for each tile.
 */
static int
mask_fill( REGION *out, void *seq, void *a, void *b )
{
#ifdef HAVE_THREADS
	Render *render = (Render *) a;
	Rect *r = &out->valid;
	int x, y;

	/* Find top left of tiles we need.
	 */
	int xs = (r->left / render->tile_width) * render->tile_width;
	int ys = (r->top / render->tile_height) * render->tile_height;

	VIPS_DEBUG_MSG( "mask_fill: left = %d, top = %d, "
		"width = %d, height = %d\n",
                r->left, r->top, r->width, r->height );

	g_mutex_lock( render->lock );

	for( y = ys; y < IM_RECT_BOTTOM( r ); y += render->tile_height )
		for( x = xs; x < IM_RECT_RIGHT( r ); x += render->tile_width ) {
			Rect area;
			Tile *tile;
			int value;

			area.left = x;
			area.top = y;
			area.width = render->tile_width;
			area.height = render->tile_height;

			tile = render_tile_lookup( render, &area );
			value = (tile &&
                                tile->painted && 
				!tile->region->invalid) ? 255 : 0;

			/* Only mark painted tiles containing valid pixels.
			 */
			im_region_paint( out, &area, value ); 
		}

	g_mutex_unlock( render->lock );
#else /*!HAVE_THREADS*/
	im_region_paint( out, &out->valid, 255 );
#endif /*HAVE_THREADS*/

	return( 0 );
}

/**
 * vips_sink_screen:
 * @in: input image
 * @out: output image
 * @mask: mask image indicating valid pixels
 * @tile_width: tile width
 * @tile_height: tile height
 * @max_tiles: maximum tiles to cache
 * @priority: rendering priority
 * @notify: pixels are ready notification callback
 * @a: client data for callback
 *
 * This operation renders @in in the background, making pixels available on
 * @out as they are calculated. The @notify callback is run every time a new
 * set of pixels are available. Calculated pixels are kept in a cache with
 * tiles sized @tile_width by @tile_height pixels and with at most @max_tiles 
 * tiles.
 * If @max_tiles is -1, the cache is of unlimited size (up to the maximum image
 * size).
 * The @mask image is a one-band uchar image and has 255 for pixels which are 
 * currently in cache and 0 for uncalculated pixels.
 *
 * Only a single sink is calculated at any one time, though many may be
 * alive. Use @priority to indicate which renders are more important:  
 * zero means normal
 * priority, negative numbers are low priority, positive numbers high
 * priority.
 *
 * Calls to im_prepare() on @out return immediately and hold whatever is
 * currently in cache for that #Rect (check @mask to see which parts of the
 * #Rect are valid). Any pixels in the #Rect which are not in cache are added
 * to a queue, and the @notify callback will trigger when those pixels are
 * ready.
 *
 * The @notify callback is run from one of the background threads. In the 
 * callback
 * you need to somehow send a message to the main thread that the pixels are
 * ready. In a glib-based application, this is easily done with g_idle_add().
 *
 * If @notify is %NULL then im_render_priority() runs synchronously.
 * im_prepare() on @out will always block until the pixels have been
 * calculated.
 *
 * See also: im_cache(), im_prepare(), vips_sink_disc(), vips_sink().
 *
 * Returns: 0 on sucess, -1 on error.
 */
int
vips_sink_screen( VipsImage *in, VipsImage *out, VipsImage *mask, 
	int tile_width, int tile_height, 
	int max_tiles, 
	int priority,
	VipsSinkNotify notify, void *a )
{
	Render *render;

	/* Make sure the bg work threads are ready.
	 */
	if( render_thread_create() )
		return( -1 );

	if( tile_width <= 0 || tile_height <= 0 || 
		max_tiles < -1 ) {
		im_error( "vips_sink_screen", "%s", _( "bad parameters" ) );
		return( -1 );
	}

	if( im_piocheck( in, out ) ||
		im_cp_desc( out, in ) ||
		im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
		return( -1 );
	if( mask ) {
		if( im_poutcheck( mask ) ||
			im_cp_desc( mask, in ) ||
			im_demand_hint( mask, IM_SMALLTILE, in, NULL ) )
			return( -1 );

		mask->Bands = 1;
		mask->BandFmt = IM_BANDFMT_UCHAR;
		mask->Type = IM_TYPE_B_W;
		mask->Coding = IM_CODING_NONE;
	}

	if( !(render = render_new( in, out, mask, 
		tile_width, tile_height, max_tiles, priority, notify, a )) )
		return( -1 );

	VIPS_DEBUG_MSG( "vips_sink_screen: max = %d, %p\n", max_tiles, render );

	if( im_generate( out, NULL, region_fill, NULL, render, NULL ) )
		return( -1 );
	if( mask && 
		im_generate( mask, NULL, mask_fill, NULL, render, NULL ) )
		return( -1 );

	return( 0 );
}

void
im__print_renders( void )
{
#ifdef VIPS_DEBUG_AMBER
	printf( "%d active renders\n", render_num_renders );
#endif /*VIPS_DEBUG_AMBER*/
	printf( "%d dirty renders\n", g_slist_length( render_dirty_all ) );
}
