[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