From 3c1911050521feea4ffc9e45ff169a21a2443a8b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 14 Mar 2008 17:01:58 +0000 Subject: [PATCH] stuff --- ChangeLog | 2 + libsrc/colour/colour.c | 27 +++++++---- libsrc/iofuncs/im_render.c | 98 +++++++++++++++++++++++++++++--------- 3 files changed, 95 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 88ff952c..719915f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ 7/3/08 started 7.15.0 - MAGIC constants should be tagged as unsigned - write MAGIC correctly on sparc/powerpc machines (thanks Joe) +- oop, we were still making fade threads even when not fading +- tiny cond jump fixes for valgrind in colour.c 25/1/08 started 7.14.0 - bump all version numbers for new stable diff --git a/libsrc/colour/colour.c b/libsrc/colour/colour.c index 158a2897..1675e787 100644 --- a/libsrc/colour/colour.c +++ b/libsrc/colour/colour.c @@ -21,6 +21,8 @@ * - some reformatting * 23/7/07 * - tiny cleanup for make_hI() prevents cond jump on ui in valgrind + * 14/3/08 + * - more tiny cond jump valgrind fixes */ /* @@ -724,18 +726,22 @@ im_col_C2Cucs( float C ) static void make_CI( void ) { - int i, j=0; - float C, Cl[ 3001]; + int i; + float C; + float Cl[3001]; for( i = 0; i < 3001; i++ ) { C = i / 10.0; - Cl[ i ] = (c4 * C + c5 * (log( c6 + c7 * C )) + c8); + Cl[i] = (c4 * C + c5 * (log( c6 + c7 * C )) + c8); } - for( i = 0; i < 3001; i++ ) - { - while ( (Cl[j]<=i/10.0) && ( j<3001) ) j++; - CI[i] = (j-1)/10.0 + (i/10.0-Cl[j-1]) / ((Cl[j]-Cl[j-1])*10.0); + for( i = 0; i < 3001; i++ ) { + int j; + + for( j = 0; j < 3001 && Cl[j] <= i / 10.0; j++ ) + ; + CI[i] = (j - 1) / 10.0 + + (i / 10.0 - Cl[j - 1]) / ((Cl[j] - Cl[j - 1]) * 10.0); } } @@ -868,7 +874,7 @@ make_hI( void ) } } -/* Inverse of above using table. +/* Inverse of above, using table. */ float im_col_Chucs2h( float C, float hucs ) @@ -883,13 +889,14 @@ im_col_Chucs2h( float C, float hucs ) if( r > 100 ) r = 100; - known = floor(hucs); + known = floor( hucs ); if( known < 0 ) known = 0; if( known > 360 ) known = 360; - return( hI[r][known] + (hI[r][known+1]-hI[r][known])*(hucs-known) ); + return( hI[r][known] + + (hI[r][(known + 1) % 360] - hI[r][known]) * (hucs - known) ); } /* Make the lookup tables for ucs. diff --git a/libsrc/iofuncs/im_render.c b/libsrc/iofuncs/im_render.c index ce6efbc5..3bb2d024 100644 --- a/libsrc/iofuncs/im_render.c +++ b/libsrc/iofuncs/im_render.c @@ -28,6 +28,9 @@ * should be simpler & more reliable * 23/4/07 * - oop, race condition fixed + * 14/3/08 + * - oop, still making fade threads even when not fading + * - more instrumenting */ /* @@ -59,9 +62,10 @@ /* Turn on debugging output. #define DEBUG #define DEBUG_REUSE -#define DEBUG_TG #define DEBUG_MAKE #define DEBUG_PAINT +#define DEBUG_TG +#define DEBUG_FADE */ #ifdef HAVE_CONFIG_H @@ -97,6 +101,16 @@ static const int have_threads = 1; static const int have_threads = 0; #endif /*HAVE_THREADS*/ +#ifdef DEBUG_TG +static int threadgroup_count = 0; +static int threadgroup_active = 0; +#endif /*DEBUG_TG*/ + +#ifdef DEBUG_FADE +static int fade_count = 0; +static int fade_active = 0; +#endif /*DEBUG_FADE*/ + /* A manager thread. We have a fixed number of these taking jobs off the list * of current renders with dirty tiles, doing a tile, and putting the render * back. @@ -263,6 +277,11 @@ render_free( Render *render ) (void) g_thread_join( render->fade_gthread ); render->fade_gthread = NULL; render->fade_kill = 0; + +#ifdef DEBUG_FADE + fade_active -= 1; + printf( "render_free: %d fade active\n", fade_active ); +#endif /*DEBUG_FADE*/ } IM_FREEF( im_threadgroup_free, render->tg ); @@ -352,7 +371,7 @@ render_dirty_get( void ) return( render ); } -/* Do a single tile. Take a dirty tile from the dirty list, fill with pixels, +/* Do a single tile. Take a dirty tile from the dirty list, fill with pixels * and add to the fade list. */ static void @@ -384,6 +403,11 @@ render_dirty_process( Render *render ) printf( "render_paint_tile: " "%p starting threadgroup\n", render ); + threadgroup_count += 1; + printf( "render_paint_tile: %d\n", threadgroup_count ); + threadgroup_active += 1; + printf( "render_dirty_put: %d active\n", + threadgroup_active ); #endif /*DEBUG_TG*/ } @@ -416,17 +440,31 @@ render_dirty_process( Render *render ) im_error_buffer() ); #endif /*DEBUG_PAINT*/ - g_mutex_lock( render->fade_lock ); - - render->fade = g_slist_prepend( render->fade, tile ); - tile->time = render->time; - tile->state = TILE_PAINTED_FADING; - - /* Hand tile over to another thread. + /* Are we fading? Hand the tile over to the fade thread. */ - im__region_no_ownership( tile->region ); + if( render->fade_gthread ) { + g_mutex_lock( render->fade_lock ); - g_mutex_unlock( render->fade_lock ); + render->fade = g_slist_prepend( render->fade, tile ); + tile->time = render->time; + tile->state = TILE_PAINTED_FADING; + + /* Hand tile over to another thread. + */ + im__region_no_ownership( tile->region ); + + g_mutex_unlock( render->fade_lock ); + } + else { + /* Not fading. Tell the user we're done ourselves. + */ + tile->time = render->time; + tile->state = TILE_PAINTED; + im__region_no_ownership( tile->region ); + if( render->notify ) + render->notify( render->out, + &tile->area, render->client ); + } } } @@ -457,6 +495,8 @@ render_dirty_put( Render *render ) */ #ifdef DEBUG_TG printf( "render_dirty_put: %p stopping threadgroup\n", render ); + threadgroup_active -= 1; + printf( "render_dirty_put: %d active\n", threadgroup_active ); #endif /*DEBUG_TG*/ IM_FREEF( im_threadgroup_free, render->tg ); } @@ -571,12 +611,6 @@ render_fade( void *client ) GSList *p; GSList *next; -#ifdef OS_WIN32 - Sleep( 1000 / render->fps ); -#else /*!OS_WIN32*/ - usleep( 1000000 / render->fps ); -#endif /*!OS_WIN32*/ - if( render->fade_kill ) break; @@ -610,6 +644,15 @@ render_fade( void *client ) &tile->area, render->client ); } g_mutex_unlock( render->fade_lock ); + + /* Sleep at the end of the loop, so if we have fading turned + * off there's no wait. + */ +#ifdef OS_WIN32 + Sleep( 1000 / render->fps ); +#else /*!OS_WIN32*/ + usleep( 1000000 / render->fps ); +#endif /*!OS_WIN32*/ } return( NULL ); @@ -669,15 +712,23 @@ render_new( IMAGE *in, IMAGE *out, IMAGE *mask, return( NULL ); } - /* Only need the fade thread for fps != 0. + /* Only need the fade thread if we're going to fade: ie. steps > 1. */ - if( have_threads && fps && - !(render->fade_gthread = g_thread_create_full( + if( have_threads && steps > 1 ) { + if( !(render->fade_gthread = g_thread_create_full( render_fade, render, IM__DEFAULT_STACK_SIZE, TRUE, FALSE, G_THREAD_PRIORITY_NORMAL, NULL )) ) { - im_error( "im_render", _( "unable to create thread" ) ); - return( NULL ); + im_error( "im_render", _( "unable to create thread" ) ); + return( NULL ); + } + +#ifdef DEBUG_FADE + fade_count += 1; + fade_active += 1; + printf( "render_new: creating fade thread %d\n", fade_count ); + printf( "render_new: %d active\n", fade_active ); +#endif /*DEBUG_FADE*/ } return( render ); @@ -1125,6 +1176,9 @@ im_render_fade( IMAGE *in, IMAGE *out, IMAGE *mask, if( render_thread_create() ) return( -1 ); + /* Don't allow fps == 0, since we divide by this value to get wait + * time. + */ if( width <= 0 || height <= 0 || max < -1 || fps <= 0 || steps < 0 ) { im_error( "im_render", _( "bad parameters" ) ); return( -1 );