This commit is contained in:
John Cupitt 2010-04-11 20:24:04 +00:00
parent eb4d3f9fd5
commit fb965a7136
5 changed files with 74 additions and 34 deletions

11
TODO
View File

@ -1,17 +1,8 @@
- we need to be able to stop a threadpool from outside
when a request comes in to vips_sink_screen(), we want to stop the
vips_threadpool() currently executing and start a new one
perhaps progress should have a 'stop' param as well?
can progress be NULL?
- im_prepare_thread() can go? I think it was only used by im_render()

View File

@ -341,7 +341,7 @@ flood_around( Flood *flood, Scan *scan )
x1a, x2a, scan->y + scan->dir,
scan->dir );
x = x2a;
x = x2a + 1;
tp = (PEL *) IM_IMAGE_ADDR( flood->test, x, scan->y );
}
}

View File

@ -226,12 +226,7 @@ render_dirty_remove( Render *render )
if( g_slist_find( render_dirty_all, render ) ) {
render_dirty_all = g_slist_remove( render_dirty_all, render );
/* We know this can't block since there is at least 1 item in
* the render_dirty_all list (us). Except that
* render_dirty_get() does a _down() before it locks so this
* could block if we run inbetween :-( possible deadlock.
*/
im_semaphore_down( &render_dirty_sem );
im_semaphore_upn( &render_dirty_sem, -1 );
}
g_mutex_unlock( render_dirty_lock );

View File

@ -54,6 +54,7 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/* A have-threads we can test in if().
*/
#ifdef HAVE_THREADS
@ -67,16 +68,16 @@ static const int have_threads = 0;
typedef enum {
/* On the dirty list .. contains no pixels
*/
TILE_DIRTY,
TILE_DIRTY,
/* Valid pixels, on the painted hash..
*/
TILE_PAINTED,
/* Currently being worked on .. not on the dirty list, but contains
* no valid pixels.
*/
TILE_WORKING,
/* Valid pixels, not on dirty.
*/
TILE_PAINTED
TILE_WORKING
} TileState;
/* A tile in our cache.
@ -121,14 +122,19 @@ typedef struct _Render {
/* Tile cache.
*/
GHashTable *cache; /* All our tiles, hash from x/y pos */
int ntiles; /* Number of cache tiles */
GSList *cache; /* All our tiles */
int ntiles; /* Number of tiles */
int access_ticks; /* Inc. on each access ... used for LRU */
/* List of tiles which are to be painted.
/* List of dirty tiles. Most recent at the front.
*/
GMutex *dirty_lock; /* Lock before we read/write the dirty list */
GSList *dirty; /* Tiles which need painting */
GSList *dirty;
/* Hash of painted tiles. Look up by x/y position.
*/
GMutex *painted_lock; /* Lock before we read/write the painted hash */
GHashTable *painted;
} Render;
/* The BG thread which sits waiting to do some rendering.
@ -167,16 +173,21 @@ render_free( Render *render )
render_dirty_remove( render );
/* Free cache.
*/
IM_FREEF( g_hash_table_destroy, render->cache );
render->ntiles = 0;
IM_FREEF( g_slist_free, render->dirty );
g_mutex_free( render->ref_count_lock );
g_mutex_free( render->dirty_lock );
g_mutex_free( render->read_lock );
im_slist_map2( render->cache,
(VSListMap2Fn) tile_free, NULL, NULL );
IM_FREEF( g_slist_free, render->cache );
render->ntiles = 0;
IM_FREEF( g_slist_free, render->dirty );
g_mutex_free( render->dirty_lock );
IM_FREEF( g_hash_table_destroy, render->painted );
g_mutex_free( render->painted_lock );
im_free( render );
return( 0 );
@ -248,6 +259,47 @@ render_dirty_get( void )
return( render );
}
static int
render_allocate( VipsThreadState *state, void *a, gboolean *stop )
{
Render *render = (Render *) a;
RenderThreadState *rstate = (RenderThreadState *) state;
if( render_rescheule ) {
*stop = TRUE;
return( 0 );
}
return( 0 );
}
static int
render_work( VipsThreadState *state, void *a )
{
Render *render = (Render *) a;
RenderThreadState *rstate = (RenderThreadState *) state;
return( 0 );
}
/* Process a render with dirty tiles. Stop when we've done all the tiles,
* or when we're asked to reschedule.
*/
static int
render_process( Render *render )
{
render_reschedule = FALSE;
vips_threadpool_run( render->im,
sink_thread_state_new,
render_allocate,
render_work,
NULL,
render );
render_reschedule = FALSE;
}
/* Do a single tile. Take a dirty tile from the dirty list and fill with
* pixels.
*/

View File

@ -98,6 +98,8 @@ im_label_regions( IMAGE *test, IMAGE *mask, int *segments )
*/
if( im_flood_other( test, t[1],
x, y, serial, NULL ) )
// if( im_flood_other_old( t[1], test,
// x, y, serial ) )
return( -1 );
serial += 1;