[xiph-commits] r12486 - trunk/sushivision

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Fri Feb 16 22:51:03 PST 2007


Author: xiphmont
Date: 2007-02-16 22:51:00 -0800 (Fri, 16 Feb 2007)
New Revision: 12486

Modified:
   trunk/sushivision/example_fractal.c
   trunk/sushivision/internal.h
   trunk/sushivision/main.c
   trunk/sushivision/panel-1d.c
   trunk/sushivision/panel-1d.h
   trunk/sushivision/panel-2d.c
   trunk/sushivision/panel-2d.h
Log:
Move panel2d's grid resample helpers to panel and thread cache storage in preparation for progressive remapping.



Modified: trunk/sushivision/example_fractal.c
===================================================================
--- trunk/sushivision/example_fractal.c	2007-02-16 23:28:36 UTC (rev 12485)
+++ trunk/sushivision/example_fractal.c	2007-02-17 06:51:00 UTC (rev 12486)
@@ -54,12 +54,12 @@
 
   s=sushiv_new_instance();
 
-  sushiv_new_dimension(s,0,"Re(c)",
+  sushiv_new_dimension_discrete(s,0,"Re(c)",
 		       5,(double []){-2.25,-0.75,0,0.25,0.75},
-		       NULL,0);
-  sushiv_new_dimension(s,1,"Im(c)",
+				NULL,1,1000,0);
+  sushiv_new_dimension_discrete(s,1,"Im(c)",
 		       5,(double []){-2,-1,0,1,2},
-		       NULL,0);
+				NULL,1,1000,0);
 
   sushiv_new_dimension(s,2,"Re(z0)",
 		       5,(double []){-2.25,-1,0,1,2.25},

Modified: trunk/sushivision/internal.h
===================================================================
--- trunk/sushivision/internal.h	2007-02-16 23:28:36 UTC (rev 12485)
+++ trunk/sushivision/internal.h	2007-02-17 06:51:00 UTC (rev 12486)
@@ -57,9 +57,9 @@
 } sushiv_panel_undo_t;
 
 typedef union {
-  _sushiv_compute_cache_1d p1;
-  _sushiv_compute_cache_2d p2;
-} _sushiv_compute_cache;
+  _sushiv_bythread_cache_1d p1;
+  _sushiv_bythread_cache_2d p2;
+} _sushiv_bythread_cache;
 
 struct sushiv_panel_internal {
   GtkWidget *toplevel;
@@ -91,9 +91,9 @@
 
   // function bundles 
   void (*realize)(sushiv_panel_t *p);
-  int (*map_action)(sushiv_panel_t *p);
+  int (*map_action)(sushiv_panel_t *p, _sushiv_bythread_cache *c);
   int (*legend_action)(sushiv_panel_t *p);
-  int (*compute_action)(sushiv_panel_t *p, _sushiv_compute_cache *c);
+  int (*compute_action)(sushiv_panel_t *p, _sushiv_bythread_cache *c);
   void (*request_compute)(sushiv_panel_t *p);
   void (*crosshair_action)(sushiv_panel_t *p);
 

Modified: trunk/sushivision/main.c
===================================================================
--- trunk/sushivision/main.c	2007-02-16 23:28:36 UTC (rev 12485)
+++ trunk/sushivision/main.c	2007-02-17 06:51:00 UTC (rev 12486)
@@ -88,7 +88,7 @@
 static void *worker_thread(void *dummy){
   /* set up temporary working space for function rendering; this saves
      continuously recreating it in the loop below */
-  _sushiv_compute_cache **c; // [instance][panel]
+  _sushiv_bythread_cache **c; // [instance][panel]
   int i,j;
   
   c = calloc(instances,sizeof(*c));
@@ -118,7 +118,7 @@
 
 	    if(p->private->map_active){
 	      spinner_set_busy(p->private->spinner);
-	      flag |= p->private->map_action(p); // may drop lock internally
+	      flag |= p->private->map_action(p,&c[j][i]); // may drop lock internally
 	      if(!p->private->map_active)
 		set_map_throttle_time(p);
 	    }

Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c	2007-02-16 23:28:36 UTC (rev 12485)
+++ trunk/sushivision/panel-1d.c	2007-02-17 06:51:00 UTC (rev 12486)
@@ -520,7 +520,7 @@
 		       double x_max, 
 		       int w, 
 		       double *dim_vals,
-		       _sushiv_compute_cache_1d *c){
+		       _sushiv_bythread_cache_1d *c){
   sushiv_panel1d_t *p1 = p->subtype->p1;
   double work[w];
   int i,j,fn=p->sushi->functions;
@@ -874,7 +874,7 @@
   update_context_menus(p);
 }
 
-void _maintain_cache_1d(sushiv_panel_t *p, _sushiv_compute_cache_1d *c, int w){
+void _maintain_cache_1d(sushiv_panel_t *p, _sushiv_bythread_cache_1d *c, int w){
   
   /* toplevel initialization */
   if(c->fout == 0){
@@ -907,7 +907,7 @@
 }
 
 // subtype entry point for plot remaps; lock held
-int _sushiv_panel1d_map_redraw(sushiv_panel_t *p){
+int _sushiv_panel1d_map_redraw(sushiv_panel_t *p, _sushiv_bythread_cache *c){
   Plot *plot = PLOT(p->private->graph);
 
   if(p->private->map_progress_count)return 0;
@@ -932,7 +932,7 @@
 
 // subtype entry point for recomputation; lock held
 int _sushiv_panel1d_compute(sushiv_panel_t *p,
-			    _sushiv_compute_cache *c){
+			    _sushiv_bythread_cache *c){
   sushiv_panel1d_t *p1 = p->subtype->p1;
   Plot *plot;
   

Modified: trunk/sushivision/panel-1d.h
===================================================================
--- trunk/sushivision/panel-1d.h	2007-02-16 23:28:36 UTC (rev 12485)
+++ trunk/sushivision/panel-1d.h	2007-02-17 06:51:00 UTC (rev 12486)
@@ -70,5 +70,5 @@
   double **fout; // [function number][outval_number*x]
   int storage_width;
 
-} _sushiv_compute_cache_1d;
+} _sushiv_bythread_cache_1d;
 

Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c	2007-02-16 23:28:36 UTC (rev 12485)
+++ trunk/sushivision/panel-2d.c	2007-02-17 06:51:00 UTC (rev 12486)
@@ -44,7 +44,7 @@
 				     double x_min, 
 				     double x_max, 
 				     double *dim_vals, 
-				     _sushiv_compute_cache_2d *c){
+				     _sushiv_bythread_cache_2d *c){
 
   sushiv_panel2d_t *p2 = p->subtype->p2;
   int i,j;
@@ -280,6 +280,57 @@
   return (float)xymul/total;
 }
 
+/* x resample helpers are put in the per-thread cache because locking it would
+   be relatively expensive. */
+// call while locked
+static void resample_helpers_manage_x(sushiv_panel_t *p, _sushiv_bythread_cache_2d *c){
+  sushiv_panel2d_t *p2 = p->subtype->p2;
+  if(p->private->plot_serialno != c->serialno){
+    int pw = p2->x.pixels;
+    c->serialno = p->private->plot_serialno;
+
+    if(c->xdelA)
+      free(c->xdelA);
+    if(c->xdelB)
+      free(c->xdelB);
+    if(c->xnumA)
+      free(c->xnumA);
+    if(c->xnumB)
+      free(c->xnumB);
+    
+    c->xdelA = calloc(pw,sizeof(*c->xdelA));
+    c->xdelB = calloc(pw,sizeof(*c->xdelB));
+    c->xnumA = calloc(pw,sizeof(*c->xnumA));
+    c->xnumB = calloc(pw,sizeof(*c->xnumB));
+    c->xscalemul = resample_helpers_init(&p2->x, &p2->x_v, c->xdelA, c->xdelB, c->xnumA, c->xnumB, 17);
+  }
+}
+
+/* y resample is in the panel struct as per-row access is already locked */
+// call while locked
+static void resample_helpers_manage_y(sushiv_panel_t *p){
+  sushiv_panel2d_t *p2 = p->subtype->p2;
+  if(p->private->plot_serialno != p2->resample_serialno){
+    int ph = p2->y.pixels;
+    p2->resample_serialno = p->private->plot_serialno;
+
+    if(p2->ydelA)
+      free(p2->ydelA);
+    if(p2->ydelB)
+      free(p2->ydelB);
+    if(p2->ynumA)
+      free(p2->ynumA);
+    if(p2->ynumB)
+      free(p2->ynumB);
+    
+    p2->ydelA = calloc(ph,sizeof(*p2->ydelA));
+    p2->ydelB = calloc(ph,sizeof(*p2->ydelB));
+    p2->ynumA = calloc(ph,sizeof(*p2->ynumA));
+    p2->ynumB = calloc(ph,sizeof(*p2->ynumB));
+    p2->yscalemul = resample_helpers_init(&p2->y, &p2->y_v, p2->ydelA, p2->ydelB, p2->ynumA, p2->ynumB, 15);
+  }
+}
+
 static inline void l_mapping_calc( void (*m)(int,int, lcolor*), 
 				   int low,
 				   float range,
@@ -297,67 +348,73 @@
 
 /* the data rectangle is data width/height mapped deltas.  we render
    and subsample at the same time. */
-/* enter with no locks; only data is not replicated local storage. */
-static int resample_render_y_plane(sushiv_panel_t *p, int plot_serialno, int map_serialno,
+/* enter unlocked */
+static int resample_render_y_plane(sushiv_panel_t *p, _sushiv_bythread_cache_2d *c,
+				   int plot_serialno, int map_serialno,
 				   mapping *map, float obj_alpha,
-				   ucolor *panel, scalespace panelx, scalespace panely,
-				   int *in_data, scalespace datax, scalespace datay){
-  int pw = panelx.pixels;
-  int dw = datax.pixels;
-  int ph = panely.pixels;
-  int dh = datay.pixels;
+				   ucolor *panel, int *in_data){
+  sushiv_panel2d_t *p2 = p->subtype->p2;
   int i,j;
   int ol_alpha = rint(obj_alpha * (256.f*256.f*256.f));
   int ol_low = rint(map->low * (256.f*256.f*256.f));
   float ol_range = map->i_range * (1.f/256.f);
-  if(!in_data)return 0;
+  if(!in_data || !c)return 1;
 
-  int *data = malloc(dw*dh*sizeof(*data));
+  int *data = NULL;
   
   gdk_threads_enter ();
   if(plot_serialno != p->private->plot_serialno) goto abort;
+
+  int pw = p2->x.pixels;
+  int dw = p2->x_v.pixels;
+  int ph = p2->y.pixels;
+  int dh = p2->y_v.pixels;
+  
+  data = malloc(dw*dh*sizeof(*data));
   memcpy(data,in_data,dw*dh*sizeof(*data));
-  gdk_threads_leave ();
 
   if(ph!=dh || pw!=dw){
     /* resampled row computation */
 
+    resample_helpers_manage_y(p);
+    resample_helpers_manage_x(p,c);
+
+    float idel = p2->yscalemul * c->xscalemul;
+
+    gdk_threads_leave ();
+
     /* by column */
-    unsigned char   xdelA[pw];
-    unsigned char   xdelB[pw];
-    int   xnumA[pw];
-    int   xnumB[pw];
-    float xsc = resample_helpers_init(&panelx, &datax, xdelA, xdelB, xnumA, xnumB, 17);
+    unsigned char *xdelA = c->xdelA;
+    unsigned char *xdelB = c->xdelB;
+    int *xnumA = c->xnumA;
+    int *xnumB = c->xnumB;
 
-    /* by row */
-    unsigned char   ydelA[ph];
-    unsigned char   ydelB[ph];
-    int   ynumA[ph];
-    int   ynumB[ph];
-    float ysc = resample_helpers_init(&panely, &datay, ydelA, ydelB, ynumA, ynumB, 15);
-
-    float idel = ysc * xsc;
     ucolor *mix = panel;
     int xy=0;
 
     /* by panel row */
     for(i=0;i<ph;i++){
 
-      int yend=ynumB[i];
-
       gdk_threads_enter ();  
       if(plot_serialno != p->private->plot_serialno ||
 	 map_serialno != p->private->map_serialno)
 	goto abort;
       spinner_set_busy(p->private->spinner);
+
+      int ydelA=p2->ydelA[i];
+      int ydelB=p2->ydelB[i];
+      
+      int ynumA=p2->ynumA[i];
+      int yend=p2->ynumB[i];
+      
       gdk_threads_leave();
       
       /* by panel col */
       for(j=0;j<pw;j++){
 	
 	lcolor out = (lcolor){0,0,0,0}; 
-	int ydel = ydelA[i];
-	int y = ynumA[i];
+	int ydel = ydelA;
+	int y = ynumA;
 
 	int xstart = y*dw + xnumA[j];
 	int xend = y*dw + xnumB[j];
@@ -392,7 +449,7 @@
 	if(y<yend){
 	  dx = xstart += dw;
 	  xend += dw;
-	  ydel = ydelB[i];
+	  ydel = ydelB;
 	  l_mapping_calc(map->mapfunc, ol_low, ol_range, data[dx++], ol_alpha, ydel*xA, &out);
 	  
 	  for(; dx < xend-1; dx++)
@@ -413,6 +470,8 @@
     }
   }else{
     /* non-resampling render */
+
+    gdk_threads_leave ();
     for(i=0;i<ph;i++){
       int *dline = data+i*dw;
 
@@ -447,21 +506,17 @@
 }
 
 // enter with lock
-static int _sushiv_panel2d_remap(sushiv_panel_t *p){
+static int _sushiv_panel2d_remap(sushiv_panel_t *p, _sushiv_bythread_cache_2d *thread_cache){
   sushiv_panel2d_t *p2 = p->subtype->p2;
   Plot *plot = PLOT(p->private->graph);
-  int pw,ph,i;
+  int i;
 
   if(!plot) return 0;
 
-  // marshall all the locked data we'll need
-  scalespace x = p2->x;
-  scalespace y = p2->y;
-  scalespace x_v = p2->x_v;
-  scalespace y_v = p2->y_v;
+  int pw = plot->x.pixels;
+  int ph = plot->y.pixels;
+  ucolor *c = malloc(pw*ph*sizeof(*c));
 
-  ucolor *c = malloc(x.pixels*y.pixels*sizeof(*c));
-
   double alphadel[p->objectives];
   mapping mappings[p->objectives];
   int plot_serialno = p->private->plot_serialno; 
@@ -472,9 +527,6 @@
   memcpy(mappings, p2->mappings, sizeof(mappings));
   memcpy(y_rects, p2->y_map, sizeof(y_rects));
   
-  pw = plot->x.pixels;
-  ph = plot->y.pixels;
-
   /* exit for computation */
   gdk_threads_leave();
   
@@ -492,10 +544,10 @@
 
     /**** render Y plane */
     int o_ynum = p2->y_obj_from_panel[i];
-    if (!resample_render_y_plane(p, plot_serialno, map_serialno, 
+    if (!resample_render_y_plane(p, thread_cache, 
+				 plot_serialno, map_serialno, 
 				 mappings+i, alphadel[i],
-				 c, x, y,
-				 y_rects[o_ynum], x_v, y_v)){
+				 c, y_rects[o_ynum])){
       gdk_threads_enter ();  
       goto abort;
     }
@@ -987,7 +1039,7 @@
   p->private->update_menus(p);
 }
 
-void _maintain_cache_2d(sushiv_panel_t *p, _sushiv_compute_cache_2d *c, int w){
+void _maintain_compute_cache_2d(sushiv_panel_t *p, _sushiv_bythread_cache_2d *c, int w){
   sushiv_panel2d_t *p2 = p->subtype->p2;
   
   /* toplevel initialization */
@@ -1022,12 +1074,12 @@
 
 
 // subtype entry point for plot remaps; lock held
-static int _sushiv_panel2d_map_redraw(sushiv_panel_t *p){
+static int _sushiv_panel2d_map_redraw(sushiv_panel_t *p, _sushiv_bythread_cache *c){
   Plot *plot = PLOT(p->private->graph);
 
   if(p->private->map_progress_count)return 0;
   p->private->map_progress_count++;
-  if(_sushiv_panel2d_remap(p))
+  if(_sushiv_panel2d_remap(p,&c->p2))
     _sushiv_panel_clean_map(p);
   plot_expose_request(plot);
   return 1;
@@ -1047,7 +1099,7 @@
 
 // subtype entry point for recomputation; lock held
 static int _sushiv_panel2d_compute(sushiv_panel_t *p,
-				   _sushiv_compute_cache *c){
+				   _sushiv_bythread_cache *c){
 
   sushiv_panel2d_t *p2 = p->subtype->p2;
   Plot *plot;
@@ -1107,6 +1159,7 @@
 
     p->private->plot_progress_count++;
     p->private->plot_serialno++; // we're about to free the old data rectangles
+
     if(memcmp(&sx_v,&old_xv,sizeof(sx_v)) || memcmp(&sy_v,&old_yv,sizeof(sy_v))){
       
       // maintain data planes
@@ -1131,7 +1184,7 @@
       // wrap the remap so that it does not give up the lock and allow
       // itself to be interrupted
       gdk_threads_enter ();
-      _sushiv_panel2d_remap(p); // do it now, don't queue it
+      _sushiv_panel2d_remap(p,&c->p2); // do it now, don't queue it
       gdk_threads_leave ();      
 
       gdk_threads_leave ();      
@@ -1155,7 +1208,7 @@
 
   if(p->private->plot_progress_count>dh) return 0;
 
-  _maintain_cache_2d(p,&c->p2,dw);
+  _maintain_compute_cache_2d(p,&c->p2,dw);
   
   d = p->dimensions;
 

Modified: trunk/sushivision/panel-2d.h
===================================================================
--- trunk/sushivision/panel-2d.h	2007-02-16 23:28:36 UTC (rev 12485)
+++ trunk/sushivision/panel-2d.h	2007-02-17 06:51:00 UTC (rev 12486)
@@ -38,7 +38,15 @@
   int *y_obj_to_panel; /* maps from position in condensed list to position in full list */
   int *y_obj_from_panel; /* maps from position in full list to position in condensed list */
   int *y_fout_offset; 
-  
+
+  /* cached resampling helpers */
+  int resample_serialno;
+  unsigned char *ydelA;
+  unsigned char *ydelB;
+  int *ynumA;
+  int *ynumB;
+  float yscalemul;
+
   /* scales and data -> display scale mapping */
   scalespace x;
   scalespace x_v;
@@ -72,8 +80,16 @@
   double *fout; // [function number * outval_number]
 
   int **y_map; // [y_obj_list[i]][px]
-
   int storage_width;
 
-} _sushiv_compute_cache_2d;
+  /* cached resampling helpers; x is here becasue locking overhead
+     would be prohibitive to share between threads */
+  int serialno;
+  unsigned char *xdelA;
+  unsigned char *xdelB;
+  int *xnumA;
+  int *xnumB;
+  float xscalemul;
+  
+} _sushiv_bythread_cache_2d;
 



More information about the commits mailing list