From f930fe061b339b7e84f49a25db05958882b9ee38 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 4 Nov 2010 13:50:20 +0000 Subject: [PATCH] use names less in orc --- libvips/arithmetic/im_add.c | 4 +-- libvips/convolution/im_conv.c | 6 ++-- libvips/include/vips/vector.h | 19 +++++++--- libvips/iofuncs/vector.c | 64 +++++++++++++++++++++++---------- libvips/morphology/morphology.c | 35 ++++-------------- 5 files changed, 70 insertions(+), 58 deletions(-) diff --git a/libvips/arithmetic/im_add.c b/libvips/arithmetic/im_add.c index 5252a754..6a0b55d8 100644 --- a/libvips/arithmetic/im_add.c +++ b/libvips/arithmetic/im_add.c @@ -101,8 +101,8 @@ add_buffer( PEL **in, PEL *out, int width, IMAGE *im ) VipsExecutor ex; vips_executor_set_program( &ex, add_vectors[im->BandFmt], sz ); - vips_executor_set_source( &ex, 1, in[0] ); - vips_executor_set_source( &ex, 2, in[1] ); + vips_executor_set_array( &ex, "s1", in[0] ); + vips_executor_set_array( &ex, "s2", in[1] ); vips_executor_set_destination( &ex, out ); vips_executor_run( &ex ); diff --git a/libvips/convolution/im_conv.c b/libvips/convolution/im_conv.c index c8a20d01..86603bf5 100644 --- a/libvips/convolution/im_conv.c +++ b/libvips/convolution/im_conv.c @@ -850,7 +850,7 @@ convvec_gen( REGION *or, void *vseq, void *a, void *b ) int sz = IM_REGION_N_ELEMENTS( or ) * (im_iscomplex( in ) ? 2 : 1); Rect s; - int y, j; + int y; VipsExecutor convolve; VipsExecutor clip; @@ -886,9 +886,7 @@ convvec_gen( REGION *or, void *vseq, void *a, void *b ) } #endif /*DEBUG_PIXELS*/ - for( j = 0; j < mask->ysize; j++ ) - vips_executor_set_source( &convolve, j + 1, - IM_REGION_ADDR( ir, r->left, r->top + y + j ) ); + vips_executor_set_source( &convolve, ir, r->left, r->top + y ); vips_executor_run( &convolve ); #ifdef DEBUG_PIXELS diff --git a/libvips/include/vips/vector.h b/libvips/include/vips/vector.h index a07691e7..51c7530a 100644 --- a/libvips/include/vips/vector.h +++ b/libvips/include/vips/vector.h @@ -57,6 +57,12 @@ typedef struct { int n_parameter; int n_instruction; + /* The scanlines this pass needs, and the variables each needs to be + * put into. + */ + int line[10]; + int var[10]; + #ifdef HAVE_ORC /* The code we have generated. */ @@ -68,12 +74,16 @@ typedef struct { gboolean compiled; } VipsVector; +/* An executor. + */ +typedef struct { #ifdef HAVE_ORC -typedef OrcExecutor VipsExecutor; -#else /*!HAVE_ORC*/ -typedef int VipsExecutor; + OrcExecutor executor; #endif /*HAVE_ORC*/ + VipsVector *vector; +} VipsExecutor; + /* Set from the command-line. */ extern gboolean im__vector_enabled; @@ -102,7 +112,8 @@ void vips_vector_print( VipsVector *vector ); void vips_executor_set_program( VipsExecutor *executor, VipsVector *vector, int n ); -void vips_executor_set_source( VipsExecutor *executor, int n, void *value ); +void vips_executor_set_source( VipsExecutor *executor, + REGION *ir, int x, int y ); void vips_executor_set_destination( VipsExecutor *executor, void *value ); void vips_executor_set_array( VipsExecutor *executor, char *name, void *value ); diff --git a/libvips/iofuncs/vector.c b/libvips/iofuncs/vector.c index 395ec429..8adccde0 100644 --- a/libvips/iofuncs/vector.c +++ b/libvips/iofuncs/vector.c @@ -122,6 +122,15 @@ vips_vector_new_ds( const char *name, int size1, int size2 ) #ifdef HAVE_ORC vector->program = orc_program_new_ds( size1, size2 ); +{ + int var; + + /* We always make s1. + */ + var = orc_program_find_var_by_name( vector->program, "s1" ); + vector->var[0] = var; + vector->line[0] = 0; +} #endif /*HAVE_ORC*/ vector->n_source += 1; vector->n_destination += 1; @@ -195,10 +204,7 @@ void vips_vector_source_name( VipsVector *vector, char *name, int size ) { #ifdef HAVE_ORC -#ifdef DEBUG - if( orc_program_find_var_by_name( vector->program, name ) != -1 ) - printf( "argh! source %s defined twice\n", name ); -#endif /*DEBUG*/ + g_assert( orc_program_find_var_by_name( vector->program, name ) == -1 ); orc_program_add_source( vector->program, size, name ); vector->n_source += 1; @@ -206,13 +212,22 @@ vips_vector_source_name( VipsVector *vector, char *name, int size ) } void -vips_vector_source( VipsVector *vector, char *name, int number, int size ) +vips_vector_source( VipsVector *vector, char *name, int line, int size ) { #ifdef HAVE_ORC - im_snprintf( name, 256, "s%d", number ); + im_snprintf( name, 256, "s%d", line ); + + if( orc_program_find_var_by_name( vector->program, name ) == -1 ) { + int var; + int i; - if( orc_program_find_var_by_name( vector->program, name ) == -1 ) vips_vector_source_name( vector, name, size ); + + i = vector->n_source - 1; + var = orc_program_find_var_by_name( vector->program, name ); + vector->var[i] = var; + vector->line[i] = line - 1; + } #endif /*HAVE_ORC*/ } @@ -266,12 +281,17 @@ vips_vector_compile( VipsVector *vector ) void vips_vector_print( VipsVector *vector ) { + int i; + printf( "%s: ", vector->name ); if( vector->compiled ) printf( "successfully compiled\n" ); else printf( "not compiled successfully\n" ); printf( " n_source = %d\n", vector->n_source ); + for( i = 0; i < vector->n_source; i++ ) + printf( " var %d = line %d\n", + vector->var[i], vector->line[i] ); printf( " n_parameter = %d\n", vector->n_parameter ); printf( " n_destination = %d\n", vector->n_destination ); printf( " n_constant = %d\n", vector->n_constant ); @@ -283,21 +303,26 @@ void vips_executor_set_program( VipsExecutor *executor, VipsVector *vector, int n ) { #ifdef HAVE_ORC - orc_executor_set_program( executor, vector->program ); - orc_executor_set_n( executor, n ); + executor->vector = vector; + + orc_executor_set_program( &executor->executor, vector->program ); + orc_executor_set_n( &executor->executor, n ); #endif /*HAVE_ORC*/ } void -vips_executor_set_source( VipsExecutor *executor, int n, void *value ) +vips_executor_set_source( VipsExecutor *executor, REGION *ir, int x, int y ) { #ifdef HAVE_ORC - char name[256]; - OrcProgram *program = executor->program; + VipsVector *vector = executor->vector; + PEL *base = (PEL *) IM_REGION_ADDR( ir, x, y ); + int lsk = IM_REGION_LSKIP( ir ); - im_snprintf( name, 256, "s%d", n ); - if( orc_program_find_var_by_name( program, name ) != -1 ) - orc_executor_set_array_str( executor, name, value ); + int i; + + for( i = 0; i < vector->n_source; i++ ) + orc_executor_set_array( &executor->executor, + vector->var[i], base + vector->line[i] * lsk ); #endif /*HAVE_ORC*/ } @@ -305,7 +330,7 @@ void vips_executor_set_destination( VipsExecutor *executor, void *value ) { #ifdef HAVE_ORC - orc_executor_set_array_str( executor, "d1", value ); + orc_executor_set_array_str( &executor->executor, "d1", value ); #endif /*HAVE_ORC*/ } @@ -313,10 +338,11 @@ void vips_executor_set_array( VipsExecutor *executor, char *name, void *value ) { #ifdef HAVE_ORC - OrcProgram *program = executor->program; + VipsVector *vector = executor->vector; + OrcProgram *program = vector->program; if( orc_program_find_var_by_name( program, name ) != -1 ) - orc_executor_set_array_str( executor, name, value ); + orc_executor_set_array_str( &executor->executor, name, value ); #endif /*HAVE_ORC*/ } @@ -324,7 +350,7 @@ void vips_executor_run( VipsExecutor *executor ) { #ifdef HAVE_ORC - orc_executor_run( executor ); + orc_executor_run( &executor->executor ); #endif /*HAVE_ORC*/ } diff --git a/libvips/morphology/morphology.c b/libvips/morphology/morphology.c index e3a94aec..9475ebe6 100644 --- a/libvips/morphology/morphology.c +++ b/libvips/morphology/morphology.c @@ -85,6 +85,7 @@ typedef struct { /* The code we generate for this section of this mask. */ VipsVector *vector; + } Pass; /* Our parameters. @@ -627,33 +628,6 @@ erode_gen( REGION *or, void *vseq, void *a, void *b ) return( 0 ); } -static void -pass_run( Morph *morph, Pass *pass, VipsExecutor *executor, - REGION *ir, void *t1, void *t2, int x, int y ) -{ - INTMASK *mask = morph->mask; - int top = pass->first / mask->xsize; - int bottom = pass->last / mask->xsize; - - PEL *p = (PEL *) IM_REGION_ADDR( ir, x, y ); - int lsk = IM_REGION_LSKIP( ir ); - - int i; - - /* Generate all the scanline pointers this prog needs. - */ - for( i = top; i <= bottom; i++ ) - vips_executor_set_source( executor, i + 1, p + i * lsk ); - - /* It might need the result from a previous pass. - */ - vips_executor_set_array( executor, "r", t1 ); - - vips_executor_set_array( executor, "d1", t2 ); - - vips_executor_run( executor ); -} - /* The vector codepath. */ static int @@ -700,8 +674,11 @@ morph_vector_gen( REGION *or, void *vseq, void *a, void *b ) else d = seq->t2; - pass_run( morph, &morph->pass[j], &executor[j], - ir, seq->t1, d, r->left, r->top + y ); + vips_executor_set_source( executor, + ir, r->left, r->top + y ); + vips_executor_set_array( executor, "r", seq->t1 ); + vips_executor_set_array( executor, "d1", d ); + vips_executor_run( executor ); IM_SWAP( void *, seq->t1, seq->t2 ); }