[xiph-commits] r12464 - trunk/sushivision

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Tue Feb 13 21:41:12 PST 2007


Author: xiphmont
Date: 2007-02-13 21:41:10 -0800 (Tue, 13 Feb 2007)
New Revision: 12464

Modified:
   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
   trunk/sushivision/panel.c
Log:
Rearchitect/unify map and legend render to follow the same pattern as 
cooperative computation through the worker threads; sets the groundwork 
for multithreaded map render in 2d panels with massive discrete data 
panes.

Also clean up some minor wasted computation time, and allow 2-d render to 
abort out if interrupted.



Modified: trunk/sushivision/internal.h
===================================================================
--- trunk/sushivision/internal.h	2007-02-14 01:12:30 UTC (rev 12463)
+++ trunk/sushivision/internal.h	2007-02-14 05:41:10 UTC (rev 12464)
@@ -66,18 +66,28 @@
   sushiv_dim_widget_t **dim_scales;
 
   int realized;
-  int maps_dirty;
-  int legend_dirty;
-  int maps_rendering;
-  int legend_rendering;
-  int panel_dirty;
 
+  int map_active;
+  int map_progress_count;
+  int map_complete_count;
+  int map_serialno;
+
+  int legend_active;
+  int legend_progress_count;
+  int legend_complete_count;
+  int legend_serialno;
+
+  int plot_active;
+  int plot_progress_count;
+  int plot_complete_count;
+  int plot_serialno;
+
   time_t last_map_throttle;
 
   // function bundles 
   void (*realize)(sushiv_panel_t *p);
-  void (*map_redraw)(sushiv_panel_t *p);
-  void (*legend_redraw)(sushiv_panel_t *p);
+  int (*map_action)(sushiv_panel_t *p);
+  int (*legend_action)(sushiv_panel_t *p);
   int (*compute_action)(sushiv_panel_t *p, _sushiv_compute_cache *c);
   void (*request_compute)(sushiv_panel_t *p);
   void (*crosshair_action)(sushiv_panel_t *p);
@@ -101,18 +111,16 @@
 			     int *objectives,
 			     int *dimensions,
 			     unsigned flags);
+
 extern void set_map_throttle_time(sushiv_panel_t *p);
-
-
 extern void _sushiv_panel_dirty_map(sushiv_panel_t *p);
 extern void _sushiv_panel_dirty_map_throttled(sushiv_panel_t *p);
 extern void _sushiv_panel_dirty_legend(sushiv_panel_t *p);
-extern void _sushiv_panel_dirty_panel(sushiv_panel_t *p);
+extern void _sushiv_panel_dirty_plot(sushiv_panel_t *p);
+extern void _sushiv_panel_clean_map(sushiv_panel_t *p);
+extern void _sushiv_panel_clean_legend(sushiv_panel_t *p);
+extern void _sushiv_panel_clean_plot(sushiv_panel_t *p);
 
-extern void _maintain_cache(sushiv_panel_t *p, _sushiv_compute_cache *c, int w);
-extern int _sushiv_panel_cooperative_compute(sushiv_panel_t *p,
-					     _sushiv_compute_cache *c);
-
 extern void _sushiv_panel_undo_log(sushiv_panel_t *p);
 extern void _sushiv_panel_undo_push(sushiv_panel_t *p);
 extern void _sushiv_panel_undo_suspend(sushiv_panel_t *p);

Modified: trunk/sushivision/main.c
===================================================================
--- trunk/sushivision/main.c	2007-02-14 01:12:30 UTC (rev 12463)
+++ trunk/sushivision/main.c	2007-02-14 05:41:10 UTC (rev 12464)
@@ -114,49 +114,33 @@
 
 	  // pending remap work?
 	  gdk_threads_enter();
-	  if(p->private->maps_dirty && !p->private->maps_rendering){
-	    p->private->maps_dirty = 0;
-	    p->private->maps_rendering = 1;
-	    flag = 1;
-	    plot_set_busy(PLOT(p->private->graph));
+	  if(p->private->realized && p->private->graph){
 
-	    gdk_threads_leave ();
-	    p->private->map_redraw(p);
-	    gdk_threads_enter ();
-
-	    p->private->maps_rendering = 0;
-	    set_map_throttle_time(p);
-	  }
-
-	  // pending legend work?
-	  if(p->private->legend_dirty && !p->private->legend_rendering){
-	    p->private->legend_dirty = 0;
-	    p->private->legend_rendering = 1;
-	    flag = 1;
-	    plot_set_busy(PLOT(p->private->graph));
+	    if(p->private->map_active){
+	      plot_set_busy(PLOT(p->private->graph));
+	      flag |= p->private->map_action(p); // may drop lock internally
+	      if(!p->private->map_active)
+		set_map_throttle_time(p);
+	    }
 	    
-	    gdk_threads_leave ();
-	    p->private->legend_redraw(p);
-	    gdk_threads_enter ();
-
-	    p->private->legend_rendering = 0;
+	    // pending legend work?
+	    if(p->private->legend_active){
+	      plot_set_busy(PLOT(p->private->graph));
+	      flag |= p->private->legend_action(p); // may drop lock internally
+	    }
+	    
+	    // pending computation work?
+	    if(p->private->plot_active){
+	      plot_set_busy(PLOT(p->private->graph));
+	      flag |= p->private->compute_action(p,&c[j][i]); // may drop lock internally
+	    }
+	    
+	    if(!p->private->plot_active &&
+	       !p->private->legend_active &&
+	       !p->private->map_active)
+	      plot_set_idle(PLOT(p->private->graph));
 	  }
 	  gdk_threads_leave ();
-
-	  // pending computation work?
-	  if(p->private->panel_dirty)
-	    flag |= _sushiv_panel_cooperative_compute(p,
-						      &c[j][i]);
-
-	  gdk_threads_enter ();
-	  if(!flag && 
-	     !p->private->panel_dirty &&
-	     !p->private->legend_rendering &&
-	     !p->private->legend_dirty &&
-	     !p->private->maps_rendering &&
-	     !p->private->maps_dirty)
-	    plot_set_idle(PLOT(p->private->graph));
-	  gdk_threads_leave ();
 	}
       }
       if(flag==1)continue;

Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c	2007-02-14 01:12:30 UTC (rev 12463)
+++ trunk/sushivision/panel-1d.c	2007-02-14 05:41:10 UTC (rev 12464)
@@ -327,7 +327,6 @@
 	d = p1->link_x->subtype->p2->x_d;
       else
 	d = p1->link_y->subtype->p2->y_d;
-
       
       // add each dimension to the legend
       // display decimal precision relative to display scales
@@ -373,28 +372,6 @@
   }
 }
 
-void _sushiv_panel1d_map_redraw(sushiv_panel_t *p){
-  Plot *plot = PLOT(p->private->graph);
-
-  gdk_threads_enter (); // misuse me as a global mutex
-  
-  _sushiv_panel1d_remap(p);
-  if(plot)
-    plot_expose_request(plot);
- 
-  gdk_threads_leave (); // misuse me as a global mutex
-}
-
-void _sushiv_panel1d_legend_redraw(sushiv_panel_t *p){
-  Plot *plot = PLOT(p->private->graph);
-
-  gdk_threads_enter (); // misuse me as a global mutex
-  update_legend(p);
-  if(plot)
-    plot_draw_scales(plot);
-  gdk_threads_leave (); // misuse me as a global mutex
-}
-
 static void mapchange_callback_1d(GtkWidget *w,gpointer in){
   sushiv_objective_list_t *optr = (sushiv_objective_list_t *)in;
   sushiv_panel_t *p = optr->p;
@@ -583,7 +560,7 @@
       }
       
       gdk_threads_enter (); // misuse me as a global mutex
-      if(p1->serialno == serialno){
+      if(p->private->plot_serialno == serialno){
 	/* store result in panel */
 	memcpy(p1->data_vec[i],work,w*sizeof(*work));
 	gdk_threads_leave (); // misuse me as a global mutex 
@@ -686,9 +663,7 @@
       for(j=0;j<dw;j++)
 	p1->data_vec[i][j]=NAN;
 
-    p1->serialno++;
-    p1->last_line = 0;
-    _sushiv_panel_dirty_panel(p);
+    _sushiv_panel_dirty_plot(p);
   }
 }
 
@@ -931,8 +906,33 @@
   }
 }
 
-int _sushiv_panel_cooperative_compute_1d(sushiv_panel_t *p,
-					 _sushiv_compute_cache *c){
+// subtype entry point for plot remaps; lock held
+int _sushiv_panel1d_map_redraw(sushiv_panel_t *p){
+  Plot *plot = PLOT(p->private->graph);
+
+  if(p->private->map_progress_count)return 0;
+  p->private->map_progress_count++;
+  _sushiv_panel1d_remap(p);
+  _sushiv_panel_clean_map(p);
+  plot_expose_request(plot);
+  return 1;
+}
+
+// subtype entry point for legend redraws; lock held
+int _sushiv_panel1d_legend_redraw(sushiv_panel_t *p){
+  Plot *plot = PLOT(p->private->graph);
+
+  if(p->private->legend_progress_count)return 0;
+  p->private->legend_progress_count++;
+  update_legend(p);
+  _sushiv_panel_clean_legend(p);
+  plot_draw_scales(plot);
+  return 1;
+}
+
+// subtype entry point for recomputation; lock held
+int _sushiv_panel1d_compute(sushiv_panel_t *p,
+			    _sushiv_compute_cache *c){
   sushiv_panel1d_t *p1 = p->subtype->p1;
   Plot *plot;
   
@@ -940,15 +940,12 @@
   int serialno;
   double x_min, x_max;
   int x_d=-1;
-  int render_scale_flag = 0;
   scalespace sy;
 
   scalespace sx;
   scalespace sxv;
   scalespace sxi;
 
-  // lock during setup
-  gdk_threads_enter ();
   dw = p1->data_size;
   w = p1->panel_w;
   h = p1->panel_h;
@@ -959,16 +956,14 @@
   sxv = p1->x_v;
   sxi = p1->x_i;
   
-  if(p1->last_line){
-    gdk_threads_leave ();
+  if(p->private->plot_progress_count)
     return 0;
-  }
 
+  serialno = p->private->plot_serialno;
+  p->private->plot_progress_count++;
+  d = p->dimensions;
   plot = PLOT(p->private->graph);
   
-  serialno = p1->serialno;
-  d = p->dimensions;
-
   /* render using local dimension array; several threads will be
      computing objectives */
   double dim_vals[p->sushi->dimensions];
@@ -990,13 +985,6 @@
     plot->y_v = sy;
   }
 
-  // Bulletproofing; shouldn't ever come up
-  if(x_d==-1){
-    gdk_threads_leave ();
-    fprintf(stderr,"Invalid/missing x dimension setting in 1d panel x_d\n");
-    return 0;
-  }
-
   // Initialize local dimension value array
   for(i=0;i<p->sushi->dimensions;i++){
     sushiv_dimension_t *dim = p->sushi->dimension_list[i];
@@ -1004,35 +992,19 @@
   }
 
   _maintain_cache_1d(p,&c->p1,dw);
+  
+  /* unlock for computation */
+  gdk_threads_leave ();
 
-  // update scales if we're just starting
-  if(p1->last_line==0){
-    render_scale_flag = 1;
-  }
-
-  if(plot->w.allocation.height == h &&
-     serialno == p1->serialno){
-    p1->last_line++;
-    
-    /* unlock for computation */
-    gdk_threads_leave ();
-    
-    if(render_scale_flag){
-      plot_draw_scales(plot);
-      render_scale_flag = 0;
-    }
-    
-    /* compute */
-    compute_1d(p, serialno, x_d, x_min, x_max, dw, dim_vals, &c->p1);
-    gdk_threads_enter ();
-    _sushiv_panel_dirty_map(p);
-    _sushiv_panel_dirty_legend(p);
-    p->private->panel_dirty = 0;
-    gdk_threads_leave ();
-
-  }else
-    gdk_threads_leave ();
-
+  plot_draw_scales(plot);
+  compute_1d(p, serialno, x_d, x_min, x_max, dw, dim_vals, &c->p1);
+  
+  gdk_threads_enter ();
+  
+  _sushiv_panel_dirty_map(p);
+  _sushiv_panel_dirty_legend(p);
+  _sushiv_panel_clean_plot(p);
+  
   return 1;
 }
 
@@ -1527,9 +1499,9 @@
     p1->flip=1;
 
   p->private->realize = _sushiv_realize_panel1d;
-  p->private->map_redraw = _sushiv_panel1d_map_redraw;
-  p->private->legend_redraw = _sushiv_panel1d_legend_redraw;
-  p->private->compute_action = _sushiv_panel_cooperative_compute_1d;
+  p->private->map_action = _sushiv_panel1d_map_redraw;
+  p->private->legend_action = _sushiv_panel1d_legend_redraw;
+  p->private->compute_action = _sushiv_panel1d_compute;
   p->private->request_compute = _mark_recompute_1d;
   p->private->crosshair_action = crosshair_callback;
 

Modified: trunk/sushivision/panel-1d.h
===================================================================
--- trunk/sushivision/panel-1d.h	2007-02-14 01:12:30 UTC (rev 12463)
+++ trunk/sushivision/panel-1d.h	2007-02-14 05:41:10 UTC (rev 12464)
@@ -33,7 +33,6 @@
   int panel_w;
   int panel_h;
   int data_size;
-  int serialno;
   double **data_vec;
 
   scalespace y;
@@ -64,10 +63,6 @@
   sushiv_dimension_t *x_d;
   sushiv_dim_widget_t *x_scale;
   int x_dnum; // number of dimension within panel, not global instance
-
-  int last_line;
-
-  int peak_count;
 } sushiv_panel1d_t;
 
 typedef struct {

Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c	2007-02-14 01:12:30 UTC (rev 12463)
+++ trunk/sushivision/panel-2d.c	2007-02-14 05:41:10 UTC (rev 12464)
@@ -83,7 +83,7 @@
   }
 
   gdk_threads_enter ();
-  if(p2->serialno == serialno){
+  if(p->private->plot_serialno == serialno){
     for(j=0;j<p2->y_obj_num;j++){
       int *d = p2->y_map[j] + y*dw;
       int *td = c->y_map[j];
@@ -297,10 +297,10 @@
 /* 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 void resample_render_y_plane(sushiv_panel2d_t *p2, int serialno, 
-				    mapping *map, float obj_alpha,
-				    ucolor *panel, scalespace panelx, scalespace panely,
-				    int *in_data, scalespace datax, scalespace datay){
+static int resample_render_y_plane(sushiv_panel_t *p, 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;
@@ -309,12 +309,12 @@
   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;
+  if(!in_data)return 0;
 
   int *data = malloc(dw*dh*sizeof(*data));
   
   gdk_threads_enter ();
-  if(serialno != p2->serialno) goto abort;
+  if(plot_serialno != p->private->plot_serialno) goto abort;
   memcpy(data,in_data,dw*dh*sizeof(*data));
   gdk_threads_leave ();
 
@@ -347,6 +347,12 @@
       /* by panel col */
       for(j=0;j<pw;j++){
 	
+	gdk_threads_enter ();  
+	if(plot_serialno != p->private->plot_serialno ||
+	   map_serialno != p->private->map_serialno)
+	  goto abort;
+	gdk_threads_leave();
+
 	lcolor out = (lcolor){0,0,0,0}; 
 	int ydel = ydelA[i];
 	int y = ynumA[i];
@@ -409,6 +415,12 @@
       int *dline = data+i*dw;
       
       for(j=0;j<pw;j++){
+	gdk_threads_enter ();  
+	if(plot_serialno != p->private->plot_serialno ||
+	   map_serialno != p->private->map_serialno)
+	  goto abort;
+	gdk_threads_leave();
+
 	lcolor out = (lcolor){0,0,0,0};
 	l_mapping_calc(map->mapfunc, ol_low, ol_range, dline[j], ol_alpha, 255, &out);
 	
@@ -423,21 +435,20 @@
     }
   }
   free(data);
-  return;
+  return 1;
  abort:
   gdk_threads_leave ();
   if(data)free(data);
+  return 0;
 }
 
-static void _sushiv_panel2d_remap(sushiv_panel_t *p){
+static int _sushiv_panel2d_remap(sushiv_panel_t *p){
   sushiv_panel2d_t *p2 = p->subtype->p2;
   Plot *plot = PLOT(p->private->graph);
   int pw,ph,i;
 
-  if(!plot) return;
+  if(!plot) return 0;
 
-  gdk_threads_enter ();
-    
   // marshall all the locked data we'll need
   scalespace x = p2->x;
   scalespace y = p2->y;
@@ -448,7 +459,8 @@
 
   double alphadel[p->objectives];
   mapping mappings[p->objectives];
-  int serialno = p2->serialno;
+  int plot_serialno = p->private->plot_serialno; 
+  int map_serialno = p->private->map_serialno; 
   int *y_rects[p2->y_obj_num];
 
   memcpy(alphadel, p2->alphadel, sizeof(alphadel));
@@ -457,36 +469,52 @@
   
   pw = plot->x.pixels;
   ph = plot->y.pixels;
+
+  /* exit for computation */
   gdk_threads_leave();
   
   /* background checks */
   render_checks(pw,ph,c);
-  
+
+  gdk_threads_enter ();  
+  if(plot_serialno != p->private->plot_serialno ||
+     map_serialno != p->private->map_serialno)
+    goto abort;
+  gdk_threads_leave();
+
   /* by objective */
   for(i=0;i<p->objectives;i++){
 
     /**** render Y plane */
     int o_ynum = p2->y_obj_from_panel[i];
-    resample_render_y_plane(p2, serialno, 
-			    mappings+i, alphadel[i],
-			    c, x, y,
-			    y_rects[o_ynum], x_v, y_v);
-    
+    if (!resample_render_y_plane(p, plot_serialno, map_serialno, 
+				 mappings+i, alphadel[i],
+				 c, x, y,
+				 y_rects[o_ynum], x_v, y_v))
+      goto abort;
+
     /**** render Z plane */
     
     /**** render vector plane */
 
   }
 
-  gdk_threads_enter ();
-  if(serialno == p2->serialno){
-    u_int32_t *dr = plot->datarect;
-    u_int32_t *cp = (u_int32_t *)c;
-    for(i=0;i<pw*ph;i++)
-      dr[i] = cp[i];
-  }
-  gdk_threads_leave();
+  gdk_threads_enter ();  
+  if(plot_serialno != p->private->plot_serialno ||
+     map_serialno != p->private->map_serialno)
+    goto abort;
+
+  u_int32_t *dr = plot->datarect;
+  u_int32_t *cp = (u_int32_t *)c;
+  for(i=0;i<pw*ph;i++)
+    dr[i] = cp[i];
+
   free(c);
+  return 1;
+
+ abort:
+  free(c);
+  return 0;
 }
 
 static void update_legend(sushiv_panel_t *p){  
@@ -536,25 +564,6 @@
   gdk_threads_leave ();
 }
 
-static void _sushiv_panel2d_map_redraw(sushiv_panel_t *p){
-  Plot *plot = PLOT(p->private->graph);
-
-  _sushiv_panel2d_remap(p);
-
-  if(plot)
-    plot_expose_request(plot);
-
-}
-
-static void _sushiv_panel2d_legend_redraw(sushiv_panel_t *p){
-  Plot *plot = PLOT(p->private->graph);
-
-  update_legend(p);
-
-  if(plot)
-    plot_draw_scales(plot);
-}
-
 static void mapchange_callback_2d(GtkWidget *w,gpointer in){
   sushiv_objective_list_t *optr = (sushiv_objective_list_t *)in;
   //sushiv_objective_t *o = optr->o;
@@ -596,8 +605,9 @@
     slider_val_to_del(p2->range_scales[onum],
 		      slider_get_value(p2->range_scales[onum],1));
 
-  //redraw the plot
-  _sushiv_panel_dirty_map(p);
+  // redraw the plot on motion
+  if(buttonstate == 1)
+    _sushiv_panel_dirty_map(p);
   if(buttonstate == 2)
     _sushiv_panel_undo_resume(p);
 }
@@ -861,18 +871,11 @@
 // call only from main gtk thread
 static void _mark_recompute_2d(sushiv_panel_t *p){
   if(!p->private->realized) return;
-  sushiv_panel2d_t *p2 = p->subtype->p2;
   Plot *plot = PLOT(p->private->graph);
 
   if(plot && GTK_WIDGET_REALIZED(GTK_WIDGET(plot))){
-
-    p2->serialno++;
-    p2->last_line = 0;
-    p2->completed_lines = 0;
-    p2->scaling_in_progress = 0; 
-    
     _sushiv_panel1d_mark_recompute_linked(p);   
-    _sushiv_panel_dirty_panel(p);
+    _sushiv_panel_dirty_plot(p);
   }
 }
 
@@ -936,8 +939,7 @@
     update_xy_availability(p);
 
     clear_pane(p);
-    _sushiv_panel2d_map_redraw(p);
-    
+    _sushiv_panel2d_remap(p); // do it now, don't queue
     _mark_recompute_2d(p);
     update_crosshairs(p);
 
@@ -1042,12 +1044,34 @@
 }
 
 
-// called from one/all of the worker threads; the idea is that several
-// of the threads will all call this and they collectively interleave
-// ongoing computation of the pane
-static int _sushiv_panel_cooperative_compute_2d(sushiv_panel_t *p,
-						_sushiv_compute_cache *c){
+// subtype entry point for plot remaps; lock held
+static int _sushiv_panel2d_map_redraw(sushiv_panel_t *p){
+  Plot *plot = PLOT(p->private->graph);
 
+  if(p->private->map_progress_count)return 0;
+  p->private->map_progress_count++;
+  if(_sushiv_panel2d_remap(p))
+    _sushiv_panel_clean_map(p);
+  plot_expose_request(plot);
+  return 1;
+}
+
+// subtype entry point for legend redraws; lock held
+static int _sushiv_panel2d_legend_redraw(sushiv_panel_t *p){
+  Plot *plot = PLOT(p->private->graph);
+
+  if(p->private->legend_progress_count)return 0;
+  p->private->legend_progress_count++;
+  update_legend(p);
+  _sushiv_panel_clean_legend(p);
+  plot_draw_scales(plot);
+  return 1;
+}
+
+// subtype entry point for recomputation; lock held
+static int _sushiv_panel2d_compute(sushiv_panel_t *p,
+				   _sushiv_compute_cache *c){
+
   sushiv_panel2d_t *p2 = p->subtype->p2;
   Plot *plot;
   
@@ -1059,18 +1083,16 @@
   scalespace sx,sx_v,sx_i;
   scalespace sy,sy_v,sy_i;
 
-  // lock during setup
-  gdk_threads_enter ();
   plot = PLOT(p->private->graph);
   pw = plot->x.pixels;
   ph = plot->y.pixels;
-
+  
   x_d = p2->x_d->number;
   y_d = p2->y_d->number;
 
   // beginning of computation init
-  if(p2->last_line==0){
-  
+  if(p->private->plot_progress_count==0){
+    
     scalespace old_xv = p2->x_v;
     scalespace old_yv = p2->y_v;
 
@@ -1106,11 +1128,9 @@
     plot->x_v = sx_v;
     plot->y_v = sy_v;
 
-    p2->last_line++;
-    ++p2->serialno; // we're about to free the old data rectangles
-    
+    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))){
-      p2->scaling_in_progress = 1;
       
       // maintain data planes
       for(i=0;i<p2->y_obj_num;i++){
@@ -1119,9 +1139,6 @@
 	int *oldmap = p2->y_map[i];
 	int j;
 	
-	p2->y_map[i] = NULL;
-	//gdk_threads_leave ();
-	
 	for(j=0;j<sx_v.pixels*sy_v.pixels;j++)
 	  newmap[j]=-1;
 	
@@ -1134,14 +1151,16 @@
 
 	p2->y_map[i] = newmap; 
       }
-      
-      p2->scaling_in_progress = 0;
-      _sushiv_panel2d_map_redraw(p);
-      gdk_threads_leave ();
-      plot_draw_scales(plot);
+      // 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
+      gdk_threads_leave ();      
 
-    }else
-      gdk_threads_leave ();
+      gdk_threads_leave ();      
+      plot_draw_scales(plot); // this should happen outside lock
+      gdk_threads_enter ();      
+    }
 
     return 1;
   }else{
@@ -1151,16 +1170,13 @@
     sy = p2->y;
     sy_v = p2->y_v;
     sy_i = p2->y_i;
-    serialno = p2->serialno; 
+    serialno = p->private->plot_serialno; 
   }
 
   dw = sx_v.pixels;
   dh = sy_v.pixels;
 
-  if(p2->last_line>dh){
-    gdk_threads_leave ();
-    return 0;
-  }
+  if(p->private->plot_progress_count>dh) return 0;
 
   _maintain_cache_2d(p,&c->p2,dw);
   
@@ -1169,6 +1185,8 @@
   /* render using local dimension array; several threads will be
      computing objectives */
   double dim_vals[p->sushi->dimensions];
+  int y = v_swizzle(p->private->plot_progress_count-1,dh);
+  p->private->plot_progress_count++;
 
   x_min = scalespace_value(&p2->x_i,0);
   x_max = scalespace_value(&p2->x_i,dw);
@@ -1182,44 +1200,32 @@
     dim_vals[i]=dim->val;
   }
 
-  /* iterate */
-  /* by line */
-  if(p2->last_line<=dh &&
-     serialno == p2->serialno){
-    int y = v_swizzle(p2->last_line-1,dh);
-
-    p2->last_line++;
+  /* unlock for computation */
+  gdk_threads_leave ();
     
-    /* unlock for computation */
-    gdk_threads_leave ();
-    
-    dim_vals[y_d]= (y_max - y_min) / dh * y + y_min;
-    
-    /* compute line */
-    compute_one_data_line_2d(p, serialno, dw, y, x_d, x_min, x_max, dim_vals, &c->p2);
+  dim_vals[y_d]= (y_max - y_min) / dh * y + y_min;
+  compute_one_data_line_2d(p, serialno, dw, y, x_d, x_min, x_max, dim_vals, &c->p2);
 
-    gdk_threads_enter ();
+  gdk_threads_enter ();
 
-    if(p2->serialno == serialno){
-      p2->completed_lines++;
-      if(p2->completed_lines>=dh){ 
-	_sushiv_panel_dirty_map(p);
-	_sushiv_panel_dirty_legend(p);
-	p->private->panel_dirty = 0;
-      }else{
-	_sushiv_panel_dirty_map_throttled(p);
-      }
+  if(p->private->plot_serialno == serialno){
+    p->private->plot_complete_count++;
+    if(p->private->plot_complete_count>=dh){ 
+      _sushiv_panel_dirty_map(p);
+      _sushiv_panel_dirty_legend(p);
+      _sushiv_panel_clean_plot(p);
+    }else{
+      _sushiv_panel_dirty_map_throttled(p);
     }
   }
-  
-  gdk_threads_leave ();
+
   return 1;
 }
 
 static void recompute_callback_2d(void *ptr){
   sushiv_panel_t *p = (sushiv_panel_t *)ptr;
   _mark_recompute_2d(p);
-  _sushiv_panel_cooperative_compute_2d(p,NULL); // initial scale setup
+  _sushiv_panel2d_compute(p,NULL); // initial scale setup
 }
 
 static void panel2d_undo_log(sushiv_panel_undo_t *u, sushiv_panel_t *p){
@@ -1635,9 +1641,9 @@
   }
 
   p->private->realize = _sushiv_realize_panel2d;
-  p->private->map_redraw = _sushiv_panel2d_map_redraw;
-  p->private->legend_redraw = _sushiv_panel2d_legend_redraw;
-  p->private->compute_action = _sushiv_panel_cooperative_compute_2d;
+  p->private->map_action = _sushiv_panel2d_map_redraw;
+  p->private->legend_action = _sushiv_panel2d_legend_redraw;
+  p->private->compute_action = _sushiv_panel2d_compute;
   p->private->request_compute = _mark_recompute_2d;
   p->private->crosshair_action = _sushiv_panel2d_crosshairs_callback;
 

Modified: trunk/sushivision/panel-2d.h
===================================================================
--- trunk/sushivision/panel-2d.h	2007-02-14 01:12:30 UTC (rev 12463)
+++ trunk/sushivision/panel-2d.h	2007-02-14 05:41:10 UTC (rev 12464)
@@ -26,9 +26,6 @@
   GtkWidget *popmenu;
   GtkWidget *graphmenu;
 
-  int serialno;              // timestamps access to map planes, widget pixels
-  int scaling_in_progress;
-
   /* only run those functions used by this panel */
   int used_functions;
   sushiv_function_t **used_function_list;
@@ -69,11 +66,6 @@
   int x_dnum; // panel, not global list context
   int y_dnum; // panel, not global list context
 
-  int last_line;
-  int completed_lines;
-
-  int peak_count;
-
 } sushiv_panel2d_t;
 
 typedef struct {

Modified: trunk/sushivision/panel.c
===================================================================
--- trunk/sushivision/panel.c	2007-02-14 01:12:30 UTC (rev 12463)
+++ trunk/sushivision/panel.c	2007-02-14 05:41:10 UTC (rev 12464)
@@ -42,13 +42,6 @@
   }
 }
 
-int _sushiv_panel_cooperative_compute(sushiv_panel_t *p,
-				      _sushiv_compute_cache *c){
-  if(p->private->realized)
-    return p->private->compute_action(p,c);
-  return 0;
-}
-
 void set_map_throttle_time(sushiv_panel_t *p){
   struct timeval now;
   gettimeofday(&now,NULL);
@@ -70,7 +63,7 @@
 
 // the following is slightly odd; we want map and legend updates to
 // fire when the UI is otherwise idle (only good way to do event
-// compression in gtk), but we don't want it processed int he main UI
+// compression in gtk), but we don't want it processed in the main UI
 // thread because of render latencies.  Thus we have a map/legend
 // chain register an idle handler that then wakes the worker threads
 // and has them render the map/legend changes
@@ -78,7 +71,10 @@
 static gboolean _idle_map_fire(gpointer ptr){
   sushiv_panel_t *p = (sushiv_panel_t *)ptr;
   gdk_threads_enter ();
-  p->private->maps_dirty = 1;
+  p->private->map_active = 1;
+  p->private->map_serialno++;
+  p->private->map_progress_count=0;
+  p->private->map_complete_count=0;
   gdk_threads_leave ();
   _sushiv_wake_workers();
   return FALSE;
@@ -87,18 +83,25 @@
 static gboolean _idle_legend_fire(gpointer ptr){
   sushiv_panel_t *p = (sushiv_panel_t *)ptr;
   gdk_threads_enter ();
-  p->private->legend_dirty = 1;
+  p->private->legend_active = 1;
+  p->private->legend_serialno++;
+  p->private->legend_progress_count=0;
+  p->private->legend_complete_count=0;
   gdk_threads_leave ();
   _sushiv_wake_workers();
   return FALSE;
 }
 
-void _sushiv_panel_dirty_panel(sushiv_panel_t *p){
+/* use these to request a render/compute action.  Do panel
+   subtype-specific setup, then wake workers with one of the below */
+void _sushiv_panel_dirty_plot(sushiv_panel_t *p){
   gdk_threads_enter ();
-  p->private->panel_dirty = 1;
+  p->private->plot_active = 1;
+  p->private->plot_serialno++;
+  p->private->plot_progress_count=0;
+  p->private->plot_complete_count=0;
   gdk_threads_leave ();
   _sushiv_wake_workers();
-  return FALSE;
 }
 
 void _sushiv_panel_dirty_map(sushiv_panel_t *p){
@@ -109,7 +112,7 @@
 
 void _sushiv_panel_dirty_map_throttled(sushiv_panel_t *p){
   gdk_threads_enter ();
-  if(test_throttle_time(p))
+  if(!p->private->map_active && test_throttle_time(p))
      g_idle_add(_idle_map_fire,p);
   gdk_threads_leave ();
 }
@@ -120,6 +123,25 @@
   gdk_threads_leave ();
 }
 
+/* use these to signal a computation is completed */
+void _sushiv_panel_clean_plot(sushiv_panel_t *p){
+  gdk_threads_enter ();
+  p->private->plot_active = 0;
+  gdk_threads_leave ();
+}
+
+void _sushiv_panel_clean_map(sushiv_panel_t *p){
+  gdk_threads_enter ();
+  p->private->map_active = 0;
+  gdk_threads_leave ();
+}
+
+void _sushiv_panel_clean_legend(sushiv_panel_t *p){
+  gdk_threads_enter ();
+  p->private->legend_active = 0;
+  gdk_threads_leave ();
+}
+
 int _sushiv_new_panel(sushiv_instance_t *s,
 		      int number,
 		      const char *name, 



More information about the commits mailing list