[xiph-commits] r12504 - trunk/sushivision
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Wed Feb 21 16:07:45 PST 2007
Author: xiphmont
Date: 2007-02-21 16:07:42 -0800 (Wed, 21 Feb 2007)
New Revision: 12504
Modified:
trunk/sushivision/gtksucks.c
trunk/sushivision/internal.h
trunk/sushivision/panel-1d.c
trunk/sushivision/panel-2d.c
trunk/sushivision/panel.c
Log:
2d panel remap:
fix a one-off on dirty_plane height
remap abort should not be resetting render state; introduces a race
idle handlers for remap are obsolete with proper locking/abort and
introduced a todo / fire race when a remap was already in progress
(map todo vectors were altered without a serialno increment, so an
in-progress remap could modify them before aborting)
1d panel remap:
Amazing the performance benefits that can be had by dropping the global
lock now and then.
Modified: trunk/sushivision/gtksucks.c
===================================================================
--- trunk/sushivision/gtksucks.c 2007-02-21 14:37:36 UTC (rev 12503)
+++ trunk/sushivision/gtksucks.c 2007-02-22 00:07:42 UTC (rev 12504)
@@ -209,12 +209,16 @@
static pthread_mutex_t gdkm;
static pthread_mutexattr_t gdkma;
+static depth = 0;
static void recursive_gdk_lock(void){
pthread_mutex_lock(&gdkm);
+ depth++;
}
static void recursive_gdk_unlock(void){
+ depth--;
+ if(depth<0)abort();
pthread_mutex_unlock(&gdkm);
}
Modified: trunk/sushivision/internal.h
===================================================================
--- trunk/sushivision/internal.h 2007-02-21 14:37:36 UTC (rev 12503)
+++ trunk/sushivision/internal.h 2007-02-22 00:07:42 UTC (rev 12504)
@@ -124,7 +124,6 @@
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_immediate(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_plot(sushiv_panel_t *p);
Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c 2007-02-21 14:37:36 UTC (rev 12503)
+++ trunk/sushivision/panel-1d.c 2007-02-22 00:07:42 UTC (rev 12504)
@@ -63,249 +63,285 @@
static void _sushiv_panel1d_remap(sushiv_panel_t *p){
sushiv_panel1d_t *p1 = p->subtype->p1;
Plot *plot = PLOT(p->private->graph);
- cairo_surface_t *cs = plot->back;
+ cairo_surface_t *back = plot->back;
+
+ int plot_serialno = p->private->plot_serialno;
+ int map_serialno = p->private->map_serialno;
+
+ // render to a temp surface so that we can release the lock occasionally
+ cairo_surface_t *cs = cairo_surface_create_similar(back,CAIRO_CONTENT_COLOR,
+ cairo_image_surface_get_width(back),
+ cairo_image_surface_get_height(back));
cairo_t *c = cairo_create(cs);
+ int xi,i,j;
+ int pw = plot->x.pixels;
+ int ph = plot->y.pixels;
+ int dw = p1->data_size;
+ double r = (p1->flip?p1->panel_w:p1->panel_h);
+
+ scalespace rx = (p1->flip?p1->y:p1->x);
+ scalespace ry = (p1->flip?p1->x:p1->y);
+ scalespace sx = p1->x;
+ scalespace sy = p1->y;
+ scalespace sx_v = p1->x_v;
+ scalespace px = plot->x;
+ scalespace py = plot->y;
+
+ /* do the panel and plot scales match? If not, redraw the plot
+ scales */
+
+ if(memcmp(&rx,&px,sizeof(rx)) ||
+ memcmp(&ry,&py,sizeof(ry))){
- if(plot){
- int xi,i,j;
- int pw = plot->x.pixels;
- int ph = plot->y.pixels;
- int dw = p1->data_size;
- double r = (p1->flip?p1->panel_w:p1->panel_h);
+ plot->x = rx;
+ plot->y = ry;
- /* blank frame to selected bg */
- switch(p->private->bg_type){
- case SUSHIV_BG_WHITE:
- cairo_set_source_rgb (c, 1.,1.,1.);
- cairo_paint(c);
+ gdk_threads_leave();
+ plot_draw_scales(plot);
+ }else
+ gdk_threads_leave();
+
+ /* blank frame to selected bg */
+ switch(p->private->bg_type){
+ case SUSHIV_BG_WHITE:
+ cairo_set_source_rgb (c, 1.,1.,1.);
+ cairo_paint(c);
+ break;
+ case SUSHIV_BG_BLACK:
+ cairo_set_source_rgb (c, 0,0,0);
+ cairo_paint(c);
break;
- case SUSHIV_BG_BLACK:
- cairo_set_source_rgb (c, 0,0,0);
- cairo_paint(c);
- break;
- case SUSHIV_BG_CHECKS:
- for(i=0;i<ph;i++)
- render_checks((ucolor *)plot->datarect+pw*i, pw, i);
- break;
- }
+ case SUSHIV_BG_CHECKS:
+ for(i=0;i<ph;i++)
+ render_checks((ucolor *)plot->datarect+pw*i, pw, i);
+ break;
+ }
- if(p1->data_vec){
+ gdk_threads_enter();
+ if(plot_serialno != p->private->plot_serialno ||
+ map_serialno != p->private->map_serialno) goto abort;
- /* do the panel and plot scales match? If not, redraw the plot
- scales */
-
- scalespace sx = (p1->flip?p1->y:p1->x);
- scalespace sy = (p1->flip?p1->x:p1->y);
-
- if(memcmp(&sx,&plot->x,sizeof(sx)) ||
- memcmp(&sy,&plot->y,sizeof(sy))){
- plot->x = sx;
- plot->y = sy;
+ if(p1->data_vec){
+
+ /* by objective */
+ for(j=0;j<p->objectives;j++){
+ if(p1->data_vec[j]){
- plot_draw_scales(plot);
- }
-
- /* by objective */
- for(j=0;j<p->objectives;j++){
- double *data_vec = p1->data_vec[j];
double alpha = slider_get_value(p1->alpha_scale[j],0);
int linetype = p1->linetype[j];
int pointtype = p1->pointtype[j];
u_int32_t color = mapping_calc(p1->mappings+j,1.,0);
+
+ double xv[dw];
+ double yv[dw];
+ double data_vec[dw];
+
+ memcpy(data_vec,p1->data_vec[j],sizeof(data_vec));
+ gdk_threads_leave();
- if(data_vec){
- double xv[dw];
- double yv[dw];
+ /* by x */
+ for(xi=0;xi<dw;xi++){
+ double val = data_vec[xi];
+ double xpixel = xi;
+ double ypixel = NAN;
- /* by x */
- for(xi=0;xi<dw;xi++){
- double val = data_vec[xi];
- double xpixel = xi;
- double ypixel = NAN;
-
- /* map data vector bin to x pixel location in the plot */
- xpixel = scalespace_pixel(&p1->x,scalespace_value(&p1->x_v,xpixel))+.5;
-
- /* map/render result */
- if(!isnan(val))
- ypixel = scalespace_pixel(&p1->y,val)+.5;
-
- xv[xi] = xpixel;
- yv[xi] = ypixel;
+ /* map data vector bin to x pixel location in the plot */
+ xpixel = scalespace_pixel(&sx,scalespace_value(&sx_v,xpixel))+.5;
+
+ /* map/render result */
+ if(!isnan(val))
+ ypixel = scalespace_pixel(&sy,val)+.5;
+
+ xv[xi] = xpixel;
+ yv[xi] = ypixel;
+ }
+
+ /* draw areas, if any */
+ if(linetype>1 && linetype < 5){
+ double yA=-1;
+ if(linetype == 2) /* fill above */
+ yA= (p1->flip?r:-1);
+ if(linetype == 3) /* fill below */
+ yA = (p1->flip?-1:r);
+ if(linetype == 4) /* fill to zero */
+ yA = scalespace_pixel(&sy,0.)+.5;
+
+ cairo_set_source_rgba(c,
+ ((color>>16)&0xff)/255.,
+ ((color>>8)&0xff)/255.,
+ ((color)&0xff)/255.,
+ alpha*.75);
+
+ if(!isnan(yv[0])){
+ if(p1->flip){
+ cairo_move_to(c,yA,xv[0]+.5);
+ cairo_line_to(c,yv[0],xv[0]+.5);
+ }else{
+ cairo_move_to(c,xv[0]-.5,yA);
+ cairo_line_to(c,xv[0]-.5,yv[0]);
+ }
}
- /* draw areas, if any */
- if(linetype>1 && linetype < 5){
- double yA=-1;
- if(linetype == 2) /* fill above */
- yA= (p1->flip?r:-1);
- if(linetype == 3) /* fill below */
- yA = (p1->flip?-1:r);
- if(linetype == 4) /* fill to zero */
- yA = scalespace_pixel(&p1->y,0.)+.5;
+ for(i=1;i<dw;i++){
- cairo_set_source_rgba(c,
- ((color>>16)&0xff)/255.,
- ((color>>8)&0xff)/255.,
- ((color)&0xff)/255.,
- alpha*.75);
-
- if(!isnan(yv[0])){
- if(p1->flip){
- cairo_move_to(c,yA,xv[0]+.5);
- cairo_line_to(c,yv[0],xv[0]+.5);
- }else{
- cairo_move_to(c,xv[0]-.5,yA);
- cairo_line_to(c,xv[0]-.5,yv[0]);
+ if(isnan(yv[i])){
+ if(!isnan(yv[i-1])){
+ /* close off the area */
+ if(p1->flip){
+ cairo_line_to(c,yv[i-1],xv[i-1]-.5);
+ cairo_line_to(c,yA,xv[i-1]-.5);
+ }else{
+ cairo_line_to(c,xv[i-1]+.5,yv[i-1]);
+ cairo_line_to(c,xv[i-1]+.5,yA);
+ }
+ cairo_close_path(c);
}
- }
-
- for(i=1;i<dw;i++){
-
- if(isnan(yv[i])){
- if(!isnan(yv[i-1])){
- /* close off the area */
- if(p1->flip){
- cairo_line_to(c,yv[i-1],xv[i-1]-.5);
- cairo_line_to(c,yA,xv[i-1]-.5);
- }else{
- cairo_line_to(c,xv[i-1]+.5,yv[i-1]);
- cairo_line_to(c,xv[i-1]+.5,yA);
- }
- cairo_close_path(c);
+ }else{
+ if(isnan(yv[i-1])){
+ if(p1->flip){
+ cairo_move_to(c,yA,xv[i]+.5);
+ cairo_line_to(c,yv[i],xv[i]+.5);
+ }else{
+ cairo_move_to(c,xv[i]-.5,yA);
+ cairo_line_to(c,xv[i]-.5,yv[i]);
}
}else{
- if(isnan(yv[i-1])){
- if(p1->flip){
- cairo_move_to(c,yA,xv[i]+.5);
- cairo_line_to(c,yv[i],xv[i]+.5);
- }else{
- cairo_move_to(c,xv[i]-.5,yA);
- cairo_line_to(c,xv[i]-.5,yv[i]);
- }
+ if(p1->flip){
+ cairo_line_to(c,yv[i],xv[i]);
}else{
- if(p1->flip){
- cairo_line_to(c,yv[i],xv[i]);
- }else{
- cairo_line_to(c,xv[i],yv[i]);
- }
+ cairo_line_to(c,xv[i],yv[i]);
}
}
}
+ }
- if(!isnan(yv[i-1])){
- /* close off the area */
- if(p1->flip){
- cairo_line_to(c,yv[i-1],xv[i-1]-.5);
- cairo_line_to(c,yA,xv[i-1]-.5);
- }else{
- cairo_line_to(c,xv[i-1]+.5,yv[i-1]);
- cairo_line_to(c,xv[i-1]+.5,yA);
- }
- cairo_close_path(c);
+ if(!isnan(yv[i-1])){
+ /* close off the area */
+ if(p1->flip){
+ cairo_line_to(c,yv[i-1],xv[i-1]-.5);
+ cairo_line_to(c,yA,xv[i-1]-.5);
+ }else{
+ cairo_line_to(c,xv[i-1]+.5,yv[i-1]);
+ cairo_line_to(c,xv[i-1]+.5,yA);
}
+ cairo_close_path(c);
+ }
- cairo_fill(c);
- }
+ cairo_fill(c);
+ }
- /* now draw the lines */
- if(linetype != 5){
- cairo_set_source_rgba(c,
- ((color>>16)&0xff)/255.,
- ((color>>8)&0xff)/255.,
- ((color)&0xff)/255.,
- alpha);
- if(linetype == 1)
- cairo_set_line_width(c,2.);
- else
- cairo_set_line_width(c,1.);
+ /* now draw the lines */
+ if(linetype != 5){
+ cairo_set_source_rgba(c,
+ ((color>>16)&0xff)/255.,
+ ((color>>8)&0xff)/255.,
+ ((color)&0xff)/255.,
+ alpha);
+ if(linetype == 1)
+ cairo_set_line_width(c,2.);
+ else
+ cairo_set_line_width(c,1.);
- for(i=1;i<dw;i++){
+ for(i=1;i<dw;i++){
- if(!isnan(yv[i-1]) && !isnan(yv[i])){
+ if(!isnan(yv[i-1]) && !isnan(yv[i])){
- if(p1->flip){
- cairo_move_to(c,yv[i-1],xv[i-1]);
- cairo_line_to(c,yv[i],xv[i]);
- }else{
- cairo_move_to(c,xv[i-1],yv[i-1]);
- cairo_line_to(c,xv[i],yv[i]);
- }
- cairo_stroke(c);
- }
- }
+ if(p1->flip){
+ cairo_move_to(c,yv[i-1],xv[i-1]);
+ cairo_line_to(c,yv[i],xv[i]);
+ }else{
+ cairo_move_to(c,xv[i-1],yv[i-1]);
+ cairo_line_to(c,xv[i],yv[i]);
+ }
+ cairo_stroke(c);
+ }
}
+ }
- /* now draw the points */
- if(pointtype > 0 || linetype == 5){
- cairo_set_line_width(c,1.);
+ /* now draw the points */
+ if(pointtype > 0 || linetype == 5){
+ cairo_set_line_width(c,1.);
- for(i=0;i<dw;i++){
- if(!isnan(yv[i])){
- double xx,yy;
- if(p1->flip){
- xx = yv[i];
- yy = xv[i];
- }else{
- xx = xv[i];
- yy = yv[i];
- }
+ for(i=0;i<dw;i++){
+ if(!isnan(yv[i])){
+ double xx,yy;
+ if(p1->flip){
+ xx = yv[i];
+ yy = xv[i];
+ }else{
+ xx = xv[i];
+ yy = yv[i];
+ }
- cairo_set_source_rgba(c,
- ((color>>16)&0xff)/255.,
- ((color>>8)&0xff)/255.,
- ((color)&0xff)/255.,
- alpha);
+ cairo_set_source_rgba(c,
+ ((color>>16)&0xff)/255.,
+ ((color>>8)&0xff)/255.,
+ ((color)&0xff)/255.,
+ alpha);
- switch(pointtype){
- case 0: /* pixeldots */
- cairo_rectangle(c, xx-.5,yy-.5,1,1);
- cairo_fill(c);
- break;
- case 1: /* X */
- cairo_move_to(c,xx-4,yy-4);
- cairo_line_to(c,xx+4,yy+4);
- cairo_move_to(c,xx+4,yy-4);
- cairo_line_to(c,xx-4,yy+4);
- break;
- case 2: /* + */
- cairo_move_to(c,xx-4,yy);
- cairo_line_to(c,xx+4,yy);
- cairo_move_to(c,xx,yy-4);
- cairo_line_to(c,xx,yy+4);
- break;
- case 3: case 6: /* circle */
- cairo_arc(c,xx,yy,4,0,2.*M_PI);
- break;
- case 4: case 7: /* square */
- cairo_rectangle(c,xx-4,yy-4,8,8);
- break;
- case 5: case 8: /* triangle */
- cairo_move_to(c,xx,yy-5);
- cairo_line_to(c,xx-4,yy+3);
- cairo_line_to(c,xx+4,yy+3);
- cairo_close_path(c);
- break;
- }
+ switch(pointtype){
+ case 0: /* pixeldots */
+ cairo_rectangle(c, xx-.5,yy-.5,1,1);
+ cairo_fill(c);
+ break;
+ case 1: /* X */
+ cairo_move_to(c,xx-4,yy-4);
+ cairo_line_to(c,xx+4,yy+4);
+ cairo_move_to(c,xx+4,yy-4);
+ cairo_line_to(c,xx-4,yy+4);
+ break;
+ case 2: /* + */
+ cairo_move_to(c,xx-4,yy);
+ cairo_line_to(c,xx+4,yy);
+ cairo_move_to(c,xx,yy-4);
+ cairo_line_to(c,xx,yy+4);
+ break;
+ case 3: case 6: /* circle */
+ cairo_arc(c,xx,yy,4,0,2.*M_PI);
+ break;
+ case 4: case 7: /* square */
+ cairo_rectangle(c,xx-4,yy-4,8,8);
+ break;
+ case 5: case 8: /* triangle */
+ cairo_move_to(c,xx,yy-5);
+ cairo_line_to(c,xx-4,yy+3);
+ cairo_line_to(c,xx+4,yy+3);
+ cairo_close_path(c);
+ break;
+ }
- if(pointtype>5){
- cairo_fill_preserve(c);
- }
+ if(pointtype>5){
+ cairo_fill_preserve(c);
+ }
- if(pointtype>0){
- if(p->private->bg_type == SUSHIV_BG_WHITE)
- cairo_set_source_rgba(c,0.,0.,0.,alpha);
- else
- cairo_set_source_rgba(c,1.,1.,1.,alpha);
- cairo_stroke(c);
- }
+ if(pointtype>0){
+ if(p->private->bg_type == SUSHIV_BG_WHITE)
+ cairo_set_source_rgba(c,0.,0.,0.,alpha);
+ else
+ cairo_set_source_rgba(c,1.,1.,1.,alpha);
+ cairo_stroke(c);
}
}
}
}
+
+ gdk_threads_enter();
+ if(plot_serialno != p->private->plot_serialno ||
+ map_serialno != p->private->map_serialno) goto abort;
+
+
}
}
}
+
+ cairo_surface_destroy(plot->back);
+ plot->back = cs;
+ cairo_destroy(c);
+ return;
+
+ abort:
+ cairo_destroy(c);
+ cairo_surface_destroy(cs);
}
static void update_legend(sushiv_panel_t *p){
Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c 2007-02-21 14:37:36 UTC (rev 12503)
+++ trunk/sushivision/panel-2d.c 2007-02-22 00:07:42 UTC (rev 12504)
@@ -534,12 +534,11 @@
i++;
}
- if(i < p2->bg_first_line) p2->bg_first_line = i;
- if(i+1 > p2->bg_last_line) p2->bg_last_line = i+1;
-
if(i == ph)
goto done;
+ if(i < p2->bg_first_line) p2->bg_first_line = i;
+ if(i+1 > p2->bg_last_line) p2->bg_last_line = i+1;
p2->bg_next_line++;
/* gray background checks */
@@ -601,10 +600,6 @@
if(p->private->map_complete_count)
return 1; // not done yet
- // remap completed; flush background to screen
- plot_expose_request_partial (plot,0,p2->bg_first_line,
- pw,p2->bg_last_line - p2->bg_first_line);
- gdk_flush();
return 0;
}
@@ -616,6 +611,7 @@
if(!plot) goto abort;
int ph = plot->y.pixels;
+ int pw = plot->x.pixels;
int plot_serialno = p->private->plot_serialno;
int map_serialno = p->private->map_serialno;
@@ -687,6 +683,12 @@
return 0; // nothing left to dispatch
// entirely finished.
+
+ // remap completed; flush background to screen
+ plot_expose_request_partial (plot,0,p2->bg_first_line,
+ pw,p2->bg_last_line - p2->bg_first_line);
+ gdk_flush();
+
// clean bg todo list
memset(p2->bg_todo,0,ph*sizeof(*p2->bg_todo));
@@ -697,8 +699,6 @@
abort:
// reset progress to 'start over'
- p->private->map_progress_count=0;
- p->private->map_complete_count=0;
return 1;
}
@@ -743,7 +743,7 @@
}
}else{
if(p2->y_planetodo)
- if(line>0 && line<ph)
+ if(line>=0 && line<ph)
for(j=0;j<p2->y_obj_num;j++)
if(p2->y_planetodo[j])
p2->y_planetodo[j][line]=1;
@@ -1399,12 +1399,13 @@
if(remapflag){
_dirty_map_full(p);
- _sushiv_panel_dirty_map_immediate(p);
+ _sushiv_panel_dirty_map(p);
gdk_threads_leave ();
plot_draw_scales(plot); // this should happen outside lock
gdk_threads_enter ();
}
+ set_map_throttle_time(p); // swallow the first 'throttled' remap which would only be a single line;
return 1;
}else{
Modified: trunk/sushivision/panel.c
===================================================================
--- trunk/sushivision/panel.c 2007-02-21 14:37:36 UTC (rev 12503)
+++ trunk/sushivision/panel.c 2007-02-22 00:07:42 UTC (rev 12504)
@@ -155,8 +155,8 @@
};
static menuitem *menu_text[]={
- &(menuitem){"<span foreground=\"black\">black</span>",NULL,NULL,&black_text},
- &(menuitem){"<span foreground=\"white\">white</span>",NULL,NULL,&white_text},
+ &(menuitem){"<span foreground=\"black\">dark</span>",NULL,NULL,&black_text},
+ &(menuitem){"<span foreground=\"white\">light</span>",NULL,NULL,&white_text},
&(menuitem){NULL,NULL,NULL,NULL}
};
@@ -273,37 +273,6 @@
return 0;
}
-// 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 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
-
-static gboolean _idle_map_fire(gpointer ptr){
- sushiv_panel_t *p = (sushiv_panel_t *)ptr;
- gdk_threads_enter ();
- 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;
-}
-
-static gboolean _idle_legend_fire(gpointer ptr){
- sushiv_panel_t *p = (sushiv_panel_t *)ptr;
- gdk_threads_enter ();
- 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;
-}
-
/* 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){
@@ -318,26 +287,30 @@
void _sushiv_panel_dirty_map(sushiv_panel_t *p){
gdk_threads_enter ();
- g_idle_add(_idle_map_fire,p);
+ 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();
}
-void _sushiv_panel_dirty_map_immediate(sushiv_panel_t *p){
- _idle_map_fire(p);
-}
-
void _sushiv_panel_dirty_map_throttled(sushiv_panel_t *p){
gdk_threads_enter ();
if(!p->private->map_active && test_throttle_time(p)){
- _idle_map_fire(p);
+ _sushiv_panel_dirty_map(p);
}
gdk_threads_leave ();
}
void _sushiv_panel_dirty_legend(sushiv_panel_t *p){
gdk_threads_enter ();
- g_idle_add(_idle_legend_fire,p);
+ 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();
}
/* use these to signal a computation is completed */
More information about the commits
mailing list