oops, keep Render alive for longer
This commit is contained in:
parent
f652e56abe
commit
ced43ce70e
|
@ -42,7 +42,7 @@
|
||||||
* 22/1/10
|
* 22/1/10
|
||||||
* - drop painted tiles on invalidate
|
* - drop painted tiles on invalidate
|
||||||
* 10/3/10
|
* 10/3/10
|
||||||
* - keep render alive until both in and out close
|
* - better lifetime management for im_invalidate() callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -153,6 +153,13 @@ typedef struct {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Invalidate proxy. The im_invalidate() callback comes here, render can null
|
||||||
|
* out the pointer when it's not interested.
|
||||||
|
*/
|
||||||
|
typedef struct _RenderProxy {
|
||||||
|
struct _Render *render;
|
||||||
|
} RenderProxy;
|
||||||
|
|
||||||
/* Per-call state.
|
/* Per-call state.
|
||||||
*/
|
*/
|
||||||
typedef struct _Render {
|
typedef struct _Render {
|
||||||
|
@ -174,6 +181,10 @@ typedef struct _Render {
|
||||||
notify_fn notify; /* Tell caller about paints here */
|
notify_fn notify; /* Tell caller about paints here */
|
||||||
void *client;
|
void *client;
|
||||||
|
|
||||||
|
/* The invalidate proxy: NULL this out to stop the callback.
|
||||||
|
*/
|
||||||
|
RenderProxy *proxy;
|
||||||
|
|
||||||
/* Make readers single thread with this. No point allowing
|
/* Make readers single thread with this. No point allowing
|
||||||
* multi-thread read.
|
* multi-thread read.
|
||||||
*/
|
*/
|
||||||
|
@ -252,6 +263,10 @@ render_free( Render *render )
|
||||||
|
|
||||||
g_assert( render->ref_count == 0 );
|
g_assert( render->ref_count == 0 );
|
||||||
|
|
||||||
|
/* Block the invalidate callback.
|
||||||
|
*/
|
||||||
|
render->proxy->render = NULL;
|
||||||
|
|
||||||
render_dirty_remove( render );
|
render_dirty_remove( render );
|
||||||
|
|
||||||
IM_FREEF( im_threadgroup_free, render->tg );
|
IM_FREEF( im_threadgroup_free, render->tg );
|
||||||
|
@ -600,10 +615,17 @@ render_tile_get_painted( Render *render )
|
||||||
/* Free all painted tiles. This is triggered on "invalidate".
|
/* Free all painted tiles. This is triggered on "invalidate".
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
render_invalidate( Render *render )
|
render_invalidate( RenderProxy *proxy )
|
||||||
{
|
{
|
||||||
|
Render *render = proxy->render;
|
||||||
|
|
||||||
Tile *tile;
|
Tile *tile;
|
||||||
|
|
||||||
|
/* Has render been freed?
|
||||||
|
*/
|
||||||
|
if( !render )
|
||||||
|
return( 0 );
|
||||||
|
|
||||||
/* Conceptually we work like region_fill(): we free all painted tiles.
|
/* Conceptually we work like region_fill(): we free all painted tiles.
|
||||||
*/
|
*/
|
||||||
g_mutex_lock( render->read_lock );
|
g_mutex_lock( render->read_lock );
|
||||||
|
@ -640,10 +662,7 @@ render_new( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||||
if( !(render = IM_NEW( NULL, Render )) )
|
if( !(render = IM_NEW( NULL, Render )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* Both in and out need to close before we can go, so ref_count starts
|
render->ref_count = 1;
|
||||||
* at 2.
|
|
||||||
*/
|
|
||||||
render->ref_count = 2;
|
|
||||||
render->ref_count_lock = g_mutex_new();
|
render->ref_count_lock = g_mutex_new();
|
||||||
|
|
||||||
render->in = in;
|
render->in = in;
|
||||||
|
@ -656,6 +675,11 @@ render_new( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||||
render->notify = notify;
|
render->notify = notify;
|
||||||
render->client = client;
|
render->client = client;
|
||||||
|
|
||||||
|
/* This needs the same lifetime as in, since it's the arg to the
|
||||||
|
* invalidate callbcak.
|
||||||
|
*/
|
||||||
|
render->proxy = IM_NEW( in, RenderProxy );
|
||||||
|
|
||||||
render->read_lock = g_mutex_new();
|
render->read_lock = g_mutex_new();
|
||||||
|
|
||||||
render->cache = NULL;
|
render->cache = NULL;
|
||||||
|
@ -668,19 +692,17 @@ render_new( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||||
render->tg = NULL;
|
render->tg = NULL;
|
||||||
render->render_kill = FALSE;
|
render->render_kill = FALSE;
|
||||||
|
|
||||||
if( im_add_close_callback( out,
|
if( !render->proxy ||
|
||||||
(im_callback_fn) render_unref, render, NULL ) ) {
|
im_add_close_callback( out,
|
||||||
(void) render_unref( render );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
if( im_add_close_callback( in,
|
|
||||||
(im_callback_fn) render_unref, render, NULL ) ) {
|
(im_callback_fn) render_unref, render, NULL ) ) {
|
||||||
(void) render_unref( render );
|
(void) render_unref( render );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render->proxy->render = render;
|
||||||
|
|
||||||
if( im_add_invalidate_callback( in,
|
if( im_add_invalidate_callback( in,
|
||||||
(im_callback_fn) render_invalidate, render, NULL ) )
|
(im_callback_fn) render_invalidate, render->proxy, NULL ) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
return( render );
|
return( render );
|
||||||
|
|
Loading…
Reference in New Issue