paintbox fixes
This commit is contained in:
parent
c5e3ce4408
commit
a4cdba13b2
6
TODO
6
TODO
@ -1,7 +1,5 @@
|
||||
- close callbacks could use invalidate's trick and give close callbacks more
|
||||
safety
|
||||
|
||||
could get rid of a couple of image flags too
|
||||
- how about im_invalidate_area()? we currently repaint the whole window on
|
||||
every paint action in nip2 :-(
|
||||
|
||||
- flood blob with ink == initial click loops
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
* 12/10/09
|
||||
* - gtkdoc comment
|
||||
* - im_render(), im_render_fade() moved to deprecated
|
||||
* 22/1/10
|
||||
* - drop painted tiles on invalidate
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -69,10 +71,10 @@
|
||||
|
||||
/* Turn on debugging output.
|
||||
#define DEBUG
|
||||
#define DEBUG_REUSE
|
||||
#define DEBUG_PAINT
|
||||
#define DEBUG_TG
|
||||
#define DEBUG_MAKE
|
||||
#define DEBUG_REUSE
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -83,7 +85,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -234,11 +235,7 @@ tile_free( Tile *tile )
|
||||
printf( "tile_free\n" );
|
||||
#endif /*DEBUG_MAKE*/
|
||||
|
||||
if( tile->region ) {
|
||||
(void) im_region_free( tile->region );
|
||||
tile->region = NULL;
|
||||
}
|
||||
|
||||
IM_FREEF( im_region_free, tile->region );
|
||||
im_free( tile );
|
||||
|
||||
return( NULL );
|
||||
@ -251,7 +248,7 @@ render_free( Render *render )
|
||||
printf( "render_free: %p\n", render );
|
||||
#endif /*DEBUG_MAKE*/
|
||||
|
||||
assert( render->ref_count == 0 );
|
||||
g_assert( render->ref_count == 0 );
|
||||
|
||||
render_dirty_remove( render );
|
||||
|
||||
@ -280,7 +277,7 @@ static int
|
||||
render_ref( Render *render )
|
||||
{
|
||||
g_mutex_lock( render->ref_count_lock );
|
||||
assert( render->ref_count != 0 );
|
||||
g_assert( render->ref_count != 0 );
|
||||
render->ref_count += 1;
|
||||
g_mutex_unlock( render->ref_count_lock );
|
||||
|
||||
@ -293,7 +290,7 @@ render_unref( Render *render )
|
||||
int kill;
|
||||
|
||||
g_mutex_lock( render->ref_count_lock );
|
||||
assert( render->ref_count > 0 );
|
||||
g_assert( render->ref_count > 0 );
|
||||
render->ref_count -= 1;
|
||||
kill = render->ref_count == 0;
|
||||
g_mutex_unlock( render->ref_count_lock );
|
||||
@ -325,7 +322,7 @@ render_dirty_get( void )
|
||||
if( render_dirty_all ) {
|
||||
render = (Render *) render_dirty_all->data;
|
||||
|
||||
assert( render->ref_count == 1 );
|
||||
g_assert( render->ref_count == 1 );
|
||||
|
||||
/* Ref the render to make sure it can't die while we're
|
||||
* working on it.
|
||||
@ -353,7 +350,7 @@ render_dirty_process( Render *render )
|
||||
g_mutex_lock( render->dirty_lock );
|
||||
if( render->dirty ) {
|
||||
tile = (Tile *) render->dirty->data;
|
||||
assert( tile->state == TILE_DIRTY );
|
||||
g_assert( tile->state == TILE_DIRTY );
|
||||
render->dirty = g_slist_remove( render->dirty, tile );
|
||||
tile->state = TILE_WORKING;
|
||||
}
|
||||
@ -479,7 +476,7 @@ render_thread_main( void *client )
|
||||
|
||||
render_dirty_put( render );
|
||||
|
||||
assert( render->ref_count == 1 ||
|
||||
g_assert( render->ref_count == 1 ||
|
||||
render->ref_count == 2 );
|
||||
|
||||
/* _get() does a ref to make sure we keep the render
|
||||
@ -543,7 +540,7 @@ tile_state_name( TileState state )
|
||||
case TILE_PAINTED: return( "TILE_PAINTED" );
|
||||
|
||||
default:
|
||||
assert( FALSE );
|
||||
g_assert( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,6 +557,73 @@ tile_print( Tile *tile )
|
||||
}
|
||||
#endif /*DEBUG*/
|
||||
|
||||
static void *
|
||||
tile_test_clean_ticks( Tile *this, Tile **best )
|
||||
{
|
||||
if( this->state == TILE_PAINTED )
|
||||
if( !*best || this->access_ticks < (*best)->access_ticks )
|
||||
*best = this;
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Pick a painted tile to reuse. Search for LRU (slow!).
|
||||
*/
|
||||
static Tile *
|
||||
render_tile_get_painted( Render *render )
|
||||
{
|
||||
Tile *tile;
|
||||
|
||||
tile = NULL;
|
||||
im_slist_map2( render->cache,
|
||||
(VSListMap2Fn) tile_test_clean_ticks, &tile, NULL );
|
||||
|
||||
if( tile ) {
|
||||
g_assert( tile->state == TILE_PAINTED );
|
||||
|
||||
#ifdef DEBUG_REUSE
|
||||
printf( "render_tile_get_painted: reusing painted %p\n", tile );
|
||||
|
||||
g_mutex_lock( render->dirty_lock );
|
||||
g_assert( !g_slist_find( render->dirty, tile ) );
|
||||
g_mutex_unlock( render->dirty_lock );
|
||||
#endif /*DEBUG_REUSE*/
|
||||
|
||||
tile->state = TILE_WORKING;
|
||||
}
|
||||
|
||||
return( tile );
|
||||
}
|
||||
|
||||
/* Free all painted tiles. This is triggered on "invalidate".
|
||||
*/
|
||||
static int
|
||||
render_invalidate( Render *render )
|
||||
{
|
||||
Tile *tile;
|
||||
|
||||
/* Conceptually we work like region_fill(): we free all painted tiles.
|
||||
*/
|
||||
g_mutex_lock( render->read_lock );
|
||||
|
||||
while( (tile = render_tile_get_painted( render )) ) {
|
||||
render->cache = g_slist_remove( render->cache, tile );
|
||||
|
||||
#ifdef DEBUG_REUSE
|
||||
g_mutex_lock( render->dirty_lock );
|
||||
g_assert( !g_slist_find( render->dirty, tile ) );
|
||||
g_mutex_unlock( render->dirty_lock );
|
||||
#endif /*DEBUG_REUSE*/
|
||||
|
||||
tile->render->ntiles -= 1;
|
||||
tile_free( tile );
|
||||
}
|
||||
|
||||
g_mutex_unlock( render->read_lock );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static Render *
|
||||
render_new( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||
int width, int height, int max,
|
||||
@ -605,6 +669,10 @@ render_new( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( im_add_invalidate_callback( in,
|
||||
(im_callback_fn) render_invalidate, render, NULL ) )
|
||||
return( NULL );
|
||||
|
||||
return( render );
|
||||
}
|
||||
|
||||
@ -700,7 +768,7 @@ tile_set_dirty( Tile *tile, Rect *area )
|
||||
area->left, area->top );
|
||||
#endif /*DEBUG_PAINT*/
|
||||
|
||||
assert( tile->state == TILE_WORKING );
|
||||
g_assert( tile->state == TILE_WORKING );
|
||||
|
||||
/* Touch the ticks ... we want to make sure this tile will not be
|
||||
* reused too soon, so it gets a chance to get painted.
|
||||
@ -755,48 +823,6 @@ tile_set_dirty( Tile *tile, Rect *area )
|
||||
g_mutex_unlock( render->dirty_lock );
|
||||
}
|
||||
|
||||
static void *
|
||||
tile_test_clean_ticks( Tile *this, Tile **best )
|
||||
{
|
||||
if( this->state == TILE_PAINTED )
|
||||
if( !*best || this->access_ticks < (*best)->access_ticks )
|
||||
*best = this;
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Pick a painted tile to reuse. Search for LRU (slow!).
|
||||
*/
|
||||
static Tile *
|
||||
render_tile_get_painted( Render *render )
|
||||
{
|
||||
Tile *tile;
|
||||
|
||||
tile = NULL;
|
||||
im_slist_map2( render->cache,
|
||||
(VSListMap2Fn) tile_test_clean_ticks, &tile, NULL );
|
||||
|
||||
if( tile ) {
|
||||
assert( tile->state == TILE_PAINTED );
|
||||
|
||||
#ifdef DEBUG_REUSE
|
||||
printf( "render_tile_get_painted: reusing painted %p\n", tile );
|
||||
|
||||
g_mutex_lock( render->dirty_lock );
|
||||
assert( !g_slist_find( render->dirty, tile ) );
|
||||
g_mutex_unlock( render->dirty_lock );
|
||||
|
||||
g_mutex_lock( render->fade_lock );
|
||||
assert( !g_slist_find( render->fade, tile ) );
|
||||
g_mutex_unlock( render->fade_lock );
|
||||
#endif /*DEBUG_REUSE*/
|
||||
|
||||
tile->state = TILE_WORKING;
|
||||
}
|
||||
|
||||
return( tile );
|
||||
}
|
||||
|
||||
/* Take a tile off the end of the dirty list.
|
||||
*/
|
||||
static Tile *
|
||||
@ -881,7 +907,7 @@ tile_copy( Tile *tile, REGION *to )
|
||||
/* Find common pixels.
|
||||
*/
|
||||
im_rect_intersectrect( &tile->area, &to->valid, &ovlap );
|
||||
assert( !im_rect_isempty( &ovlap ) );
|
||||
g_assert( !im_rect_isempty( &ovlap ) );
|
||||
len = IM_IMAGE_SIZEOF_PEL( to->im ) * ovlap.width;
|
||||
|
||||
/* If the tile is painted, copy over the pixels. Otherwise, fill with
|
||||
@ -975,7 +1001,7 @@ tile_paint_mask( Tile *tile, REGION *to )
|
||||
/* Find common pixels.
|
||||
*/
|
||||
im_rect_intersectrect( &tile->area, &to->valid, &ovlap );
|
||||
assert( !im_rect_isempty( &ovlap ) );
|
||||
g_assert( !im_rect_isempty( &ovlap ) );
|
||||
len = IM_IMAGE_SIZEOF_PEL( to->im ) * ovlap.width;
|
||||
|
||||
for( y = ovlap.top; y < IM_RECT_BOTTOM( &ovlap ); y++ ) {
|
||||
@ -985,7 +1011,7 @@ tile_paint_mask( Tile *tile, REGION *to )
|
||||
}
|
||||
}
|
||||
|
||||
/* The mask image is 255 .. 0 for the state of painted for each tile.
|
||||
/* 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 )
|
||||
|
Loading…
Reference in New Issue
Block a user