[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