[xiph-commits] r13915 - trunk/sushivision
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Fri Sep 28 19:24:29 PDT 2007
Author: xiphmont
Date: 2007-09-28 19:24:28 -0700 (Fri, 28 Sep 2007)
New Revision: 13915
Modified:
trunk/sushivision/panel-2d.c
trunk/sushivision/plane-2d.c
trunk/sushivision/plane.h
trunk/sushivision/slider.c
trunk/sushivision/slider.h
Log:
Nothing to see here
Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c 2007-09-28 19:49:36 UTC (rev 13914)
+++ trunk/sushivision/panel-2d.c 2007-09-29 02:24:28 UTC (rev 13915)
@@ -246,13 +246,13 @@
// image map render
if(p->map_render){
- status = plane_loop(p,&p->image_next_plane,map_work);
+ status = plane_loop(p,&p->image_next_plane,image_work);
if(status == STATUS_WORKING) return done_working(p);
if(status == STATUS_IDLE) p->map_render = 0;
}
// computation work
- status = plane_loop(p,&p->data_next_plane,compute);
+ status = plane_loop(p,&p->data_next_plane,data_work);
if(status == STATUS_WORKING) return done_working(p);
return done_idle(p);
}
Modified: trunk/sushivision/plane-2d.c
===================================================================
--- trunk/sushivision/plane-2d.c 2007-09-28 19:49:36 UTC (rev 13914)
+++ trunk/sushivision/plane-2d.c 2007-09-29 02:24:28 UTC (rev 13915)
@@ -109,83 +109,13 @@
return (float)xymul/total;
}
-typedef struct {
- int n;
- int neg;
- float al;
- float lo;
- float hi;
- float *vals;
- float *muls;
- float *offs;
-} slider_map;
-
-void slidermap_init(slidermap_t *m, sv_slider_t *s){
- sv_slice_t *sl = SLICE(s->slices[0]);
- sv_slice_t *sa = SLICE(s->slices[1]);
- sv_slice_t *sh = SLICE(s->slices[2]);
- float ldel = _sv_slider_val_to_del(s,sl->thumb_val);
- float hdel = _sv_slider_val_to_del(s,sh->thumb_val);
-
- m->n = s->labels;
- m->neg = s->neg;
- m->lo = sl->thumb_val;
- m->al = sa->thumb_val;
- m->hi = sh->thumb_val;
-
- if(m->vals)free(m->vals);
- if(m->muls)free(m->muls);
- if(m->offs)free(m->offs);
-
- m->vals = calloc(m->n,sizeof(*m->vals));
- m->muls = calloc(m->n-1,sizeof(*m->muls));
- m->offs = calloc(m->n-1,sizeof(*m->offs));
-
- for(j=0;j<m->n-1;j++){
- float labeldel = 1./(s->label_vals[j+1]-s->label_vals[j]);
- m->muls[j] = labeldel * s->idelrange * s->labelinv;
- m->offs[j] = (j-s->label_vals[j]*s->labeldel-
- s->lodel*(s->labels-1))*s->idelrange*s->labelinv;
- m->vals[j] = s->vals[j];
- }
- m->vals[j] = s->vals[j];
-
-}
-
-double slider_to_mapdel(slider_map *s,float v){
- int j=s->n-1;
-
- if(isnan(v))return NAN;
-
- if(s->neg){
-
- if(v > s->al)return NAN;
- if(v >= s->lo)return 0.;
- if(v <= s->hi)return 1.;
- while(--j)
- if(v<=s->vals[j])break;
-
- }else{
-
- if(v < s->al)return NAN;
- if(v <= s->lo)return 0.;
- if(v >= s->hi)return 1.;
- while(--j)
- if(v>s->vals[j])break;
-
- }
-
- return v*s->muls[j] + s->offs[j];
-}
-
static void slow_scale(sv_plane_t *pl,
sv_ucolor_t *work,
int dw, int dh,
int iw, int ih,
void (*mapfunc)(int,int, _sv_lcolor_t *),
- float alpha, int i){
-
- // sv_slider_t *scale= pl->scale; XXXXXXXXXXXx
+ int i){
+
sv_ucolor_t *image = pl->image;
sv_ccolor_t *cwork = work;
@@ -208,8 +138,11 @@
int *xnumA = pl->resample_xnumA;
int *xnumB = pl->resample_xnumB;
+ // although the slider map is only locked against heap changes,
+ // the calculation is well formed such that data inconsistencies
+ // are guaranteed to be cosmetic only and short lived.
for(j=0;j<lh*dw;j++)
- data[j] = _sv_slider_val_to_mapdel(scale, in_data[j])*65535.f;
+ data[j] = _sv_slidermap_to_mapdel(pl->scale, in_data[j])*65535.f;
/* by panel col */
for(j=0;j<pw;j++){
@@ -445,7 +378,7 @@
}
pthread_rwlock_wrlock(pl->panel_m);
- pthread_mutex_lock(pl->status_m);
+ //pthread_mutex_lock(pl->status_m); don't need two exclusive locks!
if(p->comp_serialno == serialno){
@@ -467,7 +400,7 @@
map = NULL;
}
- pthread_mutex_unlock(pl->status_m);
+ //pthread_mutex_unlock(pl->status_m);
pthread_rwlock_unlock(pl->panel_m);
if(map)free(map);
@@ -592,7 +525,7 @@
yscalemul = slow_scale_map(newy, pl->pending_data_y, ydelA, ydelB, ynumA, ynumB, 15);
pthread_rwlock_wrlock(pl->panel_m);
- pthread_mutex_lock(pl->status_m);
+ //pthread_mutex_lock(pl->status_m);
if(p->comp_serialno == serialno){
pl->image_x = p->bg->image_x;
@@ -617,7 +550,7 @@
pl->image_incomplete=0;
}
- pthread_mutex_unlock(pl->status_m);
+ //pthread_mutex_unlock(pl->status_m);
pthread_rwlock_unlock(pl->panel_m);
if(map)free(map);
@@ -676,7 +609,7 @@
}
pthread_rwlock_wrlock(pl->panel_m);
- pthread_mutex_lock(pl->status_m);
+ //pthread_mutex_lock(pl->status_m);
if(p->comp_serialno == serialno){
@@ -700,7 +633,7 @@
map = NULL;
}
- pthread_mutex_unlock(pl->status_m);
+ //pthread_mutex_unlock(pl->status_m);
pthread_rwlock_unlock(pl->panel_m);
if(old_map)free(old_map);
@@ -801,7 +734,7 @@
pthread_rwlock_unlock(pl->panel_m);
pthread_rwlock_wrlock(pl->panel_m);
- pthread_mutex_lock(pl->status_m);
+ //pthread_mutex_lock(pl->status_m);
if(p->comp_serialno == serialno){
pl->data_x = p->bg->data_x;
@@ -813,7 +746,7 @@
pl->map = NULL;
}
- pthread_mutex_unlock(pl->status_m);
+ //pthread_mutex_unlock(pl->status_m);
pthread_rwlock_unlock(pl->panel_m);
if(map)free(map);
@@ -845,21 +778,18 @@
if(pl->image_next>=h)pl->image_next=0;
if(pl->image_flags[i]){
+ sv_scalespace_t dx = pl->data_x;
+ sv_scalespace_t dy = pl->data_y;
+ sv_scalespace_t ix = pl->image_x;
+ sv_scalespace_t iy = pl->image_y;
+ void (*mapping)(int, int, _sv_lcolor_t *)=mapfunc[pl->image_mapnum];
pl->image_flags[i]=0;
pl->waiting--;
- pthread_mutex_unlock(pl->status_m);
-
- slow_scale(pl, work,
-
- sv_scalespace_t dx, sv_scalespace_t dy,
- sv_scalespace_t ix, sv_scalespace_t iy,
- void (*mapfunc)(int,int, _sv_lcolor_t *),
- float alpha, int i){
-
- map_one_line(pl,p,i,work);
-
+ pthread_mutex_unlock(pl->status_m);
+ slow_scale(dx,dy,ix,iy,mapping,i);
pthread_mutex_lock(pl->status_m);
+
if(p->comp_serialno == serialno &&
pl->map_serialno == mapno){
@@ -884,14 +814,68 @@
static int data_work(sv_plane_t *in, sv_panel_t *p){
sv_plane_2d_t *pl = (sv_plane_2d_t *)in;
+ // each plane is associated with a single objective, however
+ // multiple objectives may be associated with a given computation.
+ // This is an optimization for dealing with multiple display
+ // ojectives drawing from different output values of the exact same
+ // input computation. The plane types sharing a computation may be
+ // different, but the input dimension value vector will be identical.
+ // if this is a 'slave' plane in the computation chain, return idle;
+ // some other plane is doing the calculation for us.
+ if(pl->c.share_prev)return STATUS_IDLE;
+
+ // marshal iterators, dimension value vector
+
+
+
+
+
+
}
// called from GTK/API
static void plane_remap(sv_plane_t *in, sv_panel_t *p){
sv_plane_2d_t *pl = (sv_plane_2d_t *)in;
+ int i,flag=1;
+ // check to see if scale vals have changed or just scale settings
+ // scalemap is strictly read-only in the worker threads, so there's
+ // no need to lock this comparison beyond the GDK lock.
+ if(pl->scale.n == pl->scale_widget->labels){
+ flag=0;
+ for(i=0;i<pl->scale.n;i++)
+ if(pl->scale.vals[i] != pl->scale_widget->label_vals[i]){
+ flag=1;
+ break;
+ }
+ }
+ if(flag){
+ // the actual scale changed so updating the cached information
+ // requires complete write locking for heap work
+ pthread_rwlock_wrlock(pl->panel_m);
+
+ _sv_slidermap_clear(&pl->slider);
+ _sv_slidermap_init(&pl->slider,&pl->slider_widget);
+ wake_workers();
+ }else{
+ // no scale change
+ pthread_mutex_lock(pl->status_m);
+ _sv_slidermap_partial_update(&pl->slider,&pl->slider_widget);
+ }
+
+ p->map_render=1;
+ for(i=0;i<pl->image_y.pixels;i++)
+ pl->image_flags[i]=1;
+ pl->image_mapnum = gtk_combo_box_get_active(GTK_COMBO_BOX(pl->range_rulldown));
+
+ if(flag){
+ pthread_rwlock_unlock(pl->panel_m);
+ }else{
+ pthread_mutex_unlock(pl->status_m);
+ }
+
}
// called from GTK/API
@@ -918,7 +902,9 @@
if(pl->mapping)_sv_mapping_free(pl->mapping);
if(pl->scale)_sv_slider_free(pl->scale);
if(pl->range_pulldown)gtk_widget_destroy(pl->range_pulldown);
-
+
+ _sv_slidermap_clear(&pl->slider);
+
free(pl);
}
}
@@ -936,6 +922,13 @@
}
+
+
+
+
+
+
+
// enter unlocked
static void _sv_planez_compute_line(sv_panel_t *p,
_sv_plane2d_t *z,
Modified: trunk/sushivision/plane.h
===================================================================
--- trunk/sushivision/plane.h 2007-09-28 19:49:36 UTC (rev 13914)
+++ trunk/sushivision/plane.h 2007-09-29 02:24:28 UTC (rev 13915)
@@ -77,6 +77,7 @@
sv_ucolor_t *image;
sv_ucolor_t *pending_image;
int *map;
+ slider_map_t scale;
// status
sv_scalespace_t data_x;
@@ -93,10 +94,10 @@
sv_scalespace_t image_y;
int image_task;
int image_next;
+ int image_mapnum;
int *image_flags;
+ int image_remap_request;
- // remap payload
-
// resampling helpers
unsigned char *resample_xdelA;
unsigned char *resample_xdelB;
@@ -112,7 +113,7 @@
// ui elements; use gdk lock
sv_mapping_t *mapping;
- sv_slider_t *scale;
+ sv_slider_t *scale_widget;
GtkWidget *range_pulldown;
double alphadel;
Modified: trunk/sushivision/slider.c
===================================================================
--- trunk/sushivision/slider.c 2007-09-28 19:49:36 UTC (rev 13914)
+++ trunk/sushivision/slider.c 2007-09-29 02:24:28 UTC (rev 13915)
@@ -27,7 +27,7 @@
#include <gdk/gdkkeysyms.h>
#include "internal.h"
-static double val_to_pixel(_sv_slider_t *s, double val);
+static float val_to_pixel(_sv_slider_t *s, float val);
static int total_slice_width(_sv_slider_t *s){
int i;
@@ -70,8 +70,8 @@
/* guess where I came from. */
static void rounded_rectangle (cairo_t *c,
- double x, double y, double w, double h,
- double radius)
+ float x, float y, float w, float h,
+ float radius)
{
cairo_move_to (c, x+radius, y);
cairo_arc (c, x+w-radius, y+radius, radius, M_PI * 1.5, M_PI * 2);
@@ -80,14 +80,14 @@
cairo_arc (c, x+radius, y+radius, radius, M_PI, M_PI * 1.5);
}
-static double shades[] = {1.15, 0.95, 0.896, 0.82, 0.7, 0.665, 0.5, 0.45, 0.4};
+static float shades[] = {1.15, 0.95, 0.896, 0.82, 0.7, 0.665, 0.5, 0.45, 0.4};
static void bg_set(GtkWidget *w, cairo_t *c){
_sv_slice_t *sl = SLICE(w);
GdkColor *bg = &w->style->bg[sl->thumb_state?GTK_STATE_ACTIVE:GTK_STATE_NORMAL];
- double shade_r=bg->red/65535.;
- double shade_g=bg->green/65535.;
- double shade_b=bg->blue/65535.;
+ float shade_r=bg->red/65535.;
+ float shade_g=bg->green/65535.;
+ float shade_b=bg->blue/65535.;
cairo_set_source_rgb (c, shade_r,shade_g,shade_b);
}
@@ -95,9 +95,9 @@
static void fg_shade(GtkWidget *w, cairo_t *c, int shade){
_sv_slice_t *sl = SLICE(w);
GdkColor *fg = &w->style->fg[sl->thumb_state?GTK_STATE_ACTIVE:GTK_STATE_NORMAL];
- double shade_r=fg->red*shades[shade]/65535;
- double shade_g=fg->green*shades[shade]/65535;
- double shade_b=fg->blue*shades[shade]/65535;
+ float shade_r=fg->red*shades[shade]/65535;
+ float shade_g=fg->green*shades[shade]/65535;
+ float shade_b=fg->blue*shades[shade]/65535;
cairo_set_source_rgb (c, shade_r,shade_g,shade_b);
}
@@ -105,9 +105,9 @@
static void parent_shade(_sv_slider_t *s, cairo_t *c, int shade){
GtkWidget *parent=gtk_widget_get_parent(s->slices[0]);
GdkColor *bg = &parent->style->bg[GTK_STATE_NORMAL];
- double shade_r=bg->red*shades[shade]/65535;
- double shade_g=bg->green*shades[shade]/65535;
- double shade_b=bg->blue*shades[shade]/65535;
+ float shade_r=bg->red*shades[shade]/65535;
+ float shade_g=bg->green*shades[shade]/65535;
+ float shade_b=bg->blue*shades[shade]/65535;
cairo_set_source_rgb (c, shade_r,shade_g,shade_b);
}
@@ -120,9 +120,9 @@
GdkColor *text = &s->slices[0]->style->text[0];
GdkColor *bg = &parent->style->bg[0];
int textborder=1;
- double textr=text->red;
- double textg=text->green;
- double textb=text->blue;
+ float textr=text->red;
+ float textg=text->green;
+ float textb=text->blue;
int x=0;
int y=0;
@@ -149,21 +149,19 @@
cairo_surface_flush(s->background);
// Create trough innards
- if(s->gradient){
+ if(s->gradient>=0){
// background map gradient
// this happens 'under' cairo
u_int32_t *pixel=s->backdata+ty*s->w;
for(i=tx;i<tx+tw;i++){
_sv_lcolor_t outc = {0,0,0,0};
-
- s->mapfunc(rint(val*65536.f),255,&outc);
-
- //return m->mixfunc( (_sv_ucolor_t)(u_int32_t)((outc.a<<24) + (outc.r<<16) + (outc.g<<8) + outc.b),
- // (_sv_ucolor_t)mix).u | 0xff000000;
-
- pixel[i]=_sv_mapping_calc(s->gradient,_sv_slider_pixel_to_mapdel(s,i), pixel[i]);
-
+
+ mapfunc[s->gradient](rint(_sv_slider_pixel_to_mapdel(s,i)*65536.f),255,&outc);
+
+ pixel[i] = mixfunc[s->gradient]( (_sv_ucolor_t)(u_int32_t)((outc.a<<24) + (outc.r<<16) + (outc.g<<8) + outc.b),
+ (_sv_ucolor_t)pixel[i]).u | 0xff000000;
+ }
for(i=ty+1;i<ty+th;i++){
memcpy(pixel+w,pixel,w*4);
pixel+=s->w;
@@ -258,9 +256,9 @@
// thumbs
for(i=0;i<s->num_slices;i++){
GtkWidget *sl = s->slices[i];
- double x = rint(val_to_pixel(s,((_sv_slice_t *)(s->slices[i]))->thumb_val))+.5;
+ float x = rint(val_to_pixel(s,((_sv_slice_t *)(s->slices[i]))->thumb_val))+.5;
- double rad = 2.;
+ float rad = 2.;
float y = rint(h/2)+.5;
float xd = y*.575;
@@ -447,10 +445,10 @@
s->realized = 1;
}
-static double val_to_pixel(_sv_slider_t *s,double v){
+static float val_to_pixel(_sv_slider_t *s,float v){
int j;
- double ret=0;
- double neg = (s->neg? -1.: 1.);
+ float ret=0;
+ float neg = (s->neg? -1.: 1.);
int tx=s->xpad;
int tw=s->w - tx*2;
@@ -464,9 +462,9 @@
for(j=0;j<s->labels;j++){
if(v>=s->label_vals[j]*neg && v<=s->label_vals[j+1]*neg){
v*=neg;
- double del=(v-s->label_vals[j])/(s->label_vals[j+1]-s->label_vals[j]);
- double pixlo=rint((double)(j)/(s->labels-1)*tw);
- double pixhi=rint((double)(j+1)/(s->labels-1)*tw);
+ float del=(v-s->label_vals[j])/(s->label_vals[j+1]-s->label_vals[j]);
+ float pixlo=rint((float)(j)/(s->labels-1)*tw);
+ float pixhi=rint((float)(j+1)/(s->labels-1)*tw);
ret=pixlo*(1.-del)+pixhi*del+tx;
break;
}
@@ -476,7 +474,7 @@
return ret;
}
-double _sv_slider_val_to_del(_sv_slider_t *s,double v){
+float _sv_slider_val_to_del(_sv_slider_t *s,float v){
if(isnan(v))return NAN;
int j=s->labels-1;
@@ -493,7 +491,7 @@
}
-double _sv_slider_val_to_mapdel(_sv_slider_t *s,double v){
+float _sv_slider_val_to_mapdel(_sv_slider_t *s,float v){
int j=s->labels-1;
if(isnan(v))return NAN;
@@ -579,12 +577,12 @@
cairo_surface_destroy(dummy);
}
-static double slice_adjust_pixel(_sv_slider_t *s,int slicenum, double x){
- double width = slice_width(s,slicenum);
+static float slice_adjust_pixel(_sv_slider_t *s,int slicenum, float x){
+ float width = slice_width(s,slicenum);
return x+width;
}
-static double quant(_sv_slider_t *s, double val){
+static float quant(_sv_slider_t *s, float val){
if(s->quant_denom!=0.){
val *= s->quant_denom;
val /= s->quant_num;
@@ -597,10 +595,10 @@
return val;
}
-double _sv_slider_pixel_to_val(_sv_slider_t *s,double x){
+float _sv_slider_pixel_to_val(_sv_slider_t *s,float x){
int tx=s->xpad;
int tw=s->w - tx*2;
- double del = (double)(x-tx)/tw;
+ float del = (float)(x-tx)/tw;
if(del<0)
return quant(s,s->label_vals[0]);
if(del>=1.)
@@ -608,7 +606,7 @@
return _sv_slider_del_to_val(s,del);
}
-double _sv_slider_pixel_to_del(_sv_slider_t *s,double x){
+float _sv_slider_pixel_to_del(_sv_slider_t *s,float x){
int tx=s->xpad;
int tw=s->w - tx*2;
x-=tx;
@@ -621,7 +619,7 @@
return x/tw;
}
-double _sv_slider_pixel_to_mapdel(_sv_slider_t *s,double x){
+float _sv_slider_pixel_to_mapdel(_sv_slider_t *s,float x){
int tx=s->xpad;
int tw=s->w - tx*2;
x = ((x-tx)/tw - s->lodel)*s->idelrange;
@@ -631,7 +629,7 @@
return x;
}
-double _sv_slider_del_to_val(_sv_slider_t *s, double del){
+float _sv_slider_del_to_val(_sv_slider_t *s, float del){
int base;
if(isnan(del))return del;
@@ -645,8 +643,8 @@
void _sv_slider_vals_bound(_sv_slider_t *s,int slicenum){
int i,flag=-1;
_sv_slice_t *center = SLICE(s->slices[slicenum]);
- double min = (s->neg ? s->label_vals[s->labels-1] : s->label_vals[0]);
- double max = (s->neg ? s->label_vals[0] : s->label_vals[s->labels-1]);
+ float min = (s->neg ? s->label_vals[s->labels-1] : s->label_vals[0]);
+ float max = (s->neg ? s->label_vals[0] : s->label_vals[s->labels-1]);
int flip = (s->neg? 1: 0);
if(center->thumb_val < min)
@@ -784,8 +782,8 @@
_sv_slice_t *sl = SLICE(s->slices[0]);
_sv_slice_t *sa = SLICE(s->slices[1]);
_sv_slice_t *sh = SLICE(s->slices[2]);
- double ldel = _sv_slider_val_to_del(s,sl->thumb_val);
- double hdel = _sv_slider_val_to_del(s,sh->thumb_val);
+ float ldel = _sv_slider_val_to_del(s,sl->thumb_val);
+ float hdel = _sv_slider_val_to_del(s,sh->thumb_val);
s->al = sa->thumb_val;
@@ -795,9 +793,6 @@
s->idelrange = 1./(hdel-ldel);
s->lodel = ldel;
-
- _sv_mapping_set_lo(s->gradient,ldel);
- _sv_mapping_set_hi(s->gradient,hdel);
_sv_slider_draw_background(s);
_sv_slider_draw(s);
}
@@ -806,7 +801,7 @@
}
void _sv_slider_motion(_sv_slider_t *s,int slicenum,int x,int y){
- double altered[s->num_slices];
+ float altered[s->num_slices];
int i, grabflag=0;
_sv_slice_t *sl = SLICE(s->slices[slicenum]);
int px = (s->flip?sl->widget.allocation.height-y-1 : x);
@@ -863,7 +858,7 @@
switch(event->keyval){
case GDK_Left:
{
- double x = val_to_pixel(s,sl->thumb_val);
+ float x = val_to_pixel(s,sl->thumb_val);
while(sl->thumb_val > s->label_vals[0] &&
sl->thumb_val == _sv_slider_pixel_to_val(s,x))x--;
if(shift)
@@ -886,7 +881,7 @@
case GDK_Right:
{
- double x = val_to_pixel(s,sl->thumb_val);
+ float x = val_to_pixel(s,sl->thumb_val);
while(sl->thumb_val < s->label_vals[s->labels-1] &&
sl->thumb_val == _sv_slider_pixel_to_val(s,x))x++;
if(shift)
@@ -910,7 +905,7 @@
return FALSE; // keep processing
}
-_sv_slider_t *_sv_slider_new(_sv_slice_t **slices, int num_slices, char **labels, double *label_vals, int num_labels,
+_sv_slider_t *_sv_slider_new(_sv_slice_t **slices, int num_slices, char **labels, float *label_vals, int num_labels,
unsigned flags){
int i;
_sv_slider_t *ret = calloc(1,sizeof(*ret));
@@ -948,11 +943,12 @@
ret->hi = ret->label_vals[ret->labels-1];
ret->lodel = 0.;
ret->idelrange = 1.;
+ ret->gradient = -1;
return ret;
}
-void _sv_slider_set_gradient(_sv_slider_t *s, _sv_mapping_t *m){
+void _sv_slider_set_gradient(_sv_slider_t *s, int m){
s->gradient = m;
if(s->realized){
_sv_slider_draw_background(s);
@@ -965,7 +961,7 @@
_sv_slice_set_active(SLICE(s->slices[thumbnum]),activep);
}
-double _sv_slider_get_value(_sv_slider_t *s, int thumbnum){
+float _sv_slider_get_value(_sv_slider_t *s, int thumbnum){
GtkWidget *w;
if(thumbnum >= s->num_slices)return 0;
if(thumbnum < 0)return 0;
@@ -973,7 +969,7 @@
return SLICE(w)->thumb_val;
}
-void _sv_slider_set_value(_sv_slider_t *s, int thumbnum, double v){
+void _sv_slider_set_value(_sv_slider_t *s, int thumbnum, float v){
GtkWidget *w;
if(thumbnum >= s->num_slices)return;
if(thumbnum < 0)return;
@@ -982,19 +978,19 @@
update_gradient(s);
}
-void _sv_slider_set_quant(_sv_slider_t *s,double num, double denom){
+void _sv_slider_set_quant(_sv_slider_t *s,float num, float denom){
s->quant_num=num;
s->quant_denom=denom;
}
-double _sv_slider_print_height(_sv_slider_t *s){
+float _sv_slider_print_height(_sv_slider_t *s){
return (s->slices[0]->allocation.height - s->ypad*2)*1.2;
}
void _sv_slider_print(_sv_slider_t *s, cairo_t *c, int w, int h){
cairo_save(c);
- double ypad = h*.1;
- double neg = (s->neg? -1.: 1.);
+ float ypad = h*.1;
+ float neg = (s->neg? -1.: 1.);
// set clip region
cairo_rectangle(c,0,ypad,w,h-ypad*2);
@@ -1003,8 +999,8 @@
// determine start/end deltas
// eliminate label sections that are completely unused
int slices = s->num_slices;
- double lo = (slices>0?SLICE(s->slices[0])->thumb_val:s->label_vals[0]) * neg;
- double hi = (slices>0?SLICE(s->slices[slices-1])->thumb_val:s->label_vals[s->labels-1]) * neg;
+ float lo = (slices>0?SLICE(s->slices[0])->thumb_val:s->label_vals[0]) * neg;
+ float hi = (slices>0?SLICE(s->slices[slices-1])->thumb_val:s->label_vals[s->labels-1]) * neg;
// alpha could push up the unused area
if(slices==3 && SLICE(s->slices[1])->thumb_val*neg>lo)
@@ -1032,9 +1028,9 @@
break;
}
- double lodel = 1. / (s->labels-1) * firstlabel;
- double hidel = 1. / (s->labels-1) * lastlabel;
- double alphadel = (slices==3 ?
+ float lodel = 1. / (s->labels-1) * firstlabel;
+ float hidel = 1. / (s->labels-1) * lastlabel;
+ float alphadel = (slices==3 ?
_sv_slider_val_to_del(s,SLICE(s->slices[1])->thumb_val):0.);
// create background image
@@ -1062,9 +1058,13 @@
for(y=0;y<h;y++){
_sv_ucolor_t *line = (_sv_ucolor_t *)cairo_image_surface_get_data(image) + w*y;
for(x=0;x<w;x++){
- double del = (hidel - lodel) / (w-1) * x + lodel;
- if(del>=alphadel)
- line[x].u = _sv_mapping_calc(s->gradient, del, line[x].u);
+ float del = (hidel - lodel) / (w-1) * x + lodel;
+ _sv_lcolor_t outc = {0,0,0,0};
+
+ mapfunc[s->gradient](rint(del*65536.f),255,&outc);
+ line[x] = mixfunc[s->gradient]( (_sv_ucolor_t)(u_int32_t)((outc.a<<24) + (outc.r<<16) + (outc.g<<8) + outc.b),
+ (_sv_ucolor_t)line[x]).u | 0xff000000;
+
}
}
@@ -1084,8 +1084,8 @@
// add labels
cairo_set_font_size(c,h-ypad*2-3);
for(i=firstlabel;i<=lastlabel;i++){
- double x = (double)(i-firstlabel) / (lastlabel - firstlabel) * (w-1);
- double y;
+ float x = (float)(i-firstlabel) / (lastlabel - firstlabel) * (w-1);
+ float y;
cairo_text_extents_t ex;
cairo_move_to(c,x+.5,ypad);
@@ -1118,3 +1118,103 @@
cairo_restore(c);
}
+
+// Slidermaps concentrate the data needed for map delta computations
+// outside of the GDK lock. Like with other rendering data, writes to
+// the slidermap (aside from heap changes) are not locked against
+// reads as any momentary inconsistency is a) cosmetic and b) will be
+// flushed immediately and replaced
+
+void _sv_slidermap_init(slider_map_t *m, sv_slider_t *s){
+ sv_slice_t *sl = SLICE(s->slices[0]);
+ sv_slice_t *sa = SLICE(s->slices[1]);
+ sv_slice_t *sh = SLICE(s->slices[2]);
+
+ m->n = s->labels;
+ m->neg = s->neg;
+ m->lo = sl->thumb_val;
+ m->al = sa->thumb_val;
+ m->hi = sh->thumb_val;
+
+ if(m->vals)free(m->vals);
+ if(m->muls)free(m->muls);
+ if(m->offs)free(m->offs);
+
+ m->vals = calloc(m->n,sizeof(*m->vals));
+ m->muls = calloc(m->n-1,sizeof(*m->muls));
+ m->offs = calloc(m->n-1,sizeof(*m->offs));
+
+ for(j=0;j<m->n-1;j++){
+ float labeldel = 1./(s->label_vals[j+1]-s->label_vals[j]);
+ m->muls[j] = labeldel * s->idelrange * s->labelinv;
+ m->offs[j] = (j-s->label_vals[j]*s->labeldel-
+ s->lodel*(s->labels-1))*s->idelrange*s->labelinv;
+ m->vals[j] = s->vals[j];
+ }
+ m->vals[j] = s->vals[j];
+
+}
+
+// assumes no scale change. We don't automagically check for scale
+// changes here as a scale update requires a different locking
+// strategy at higher levels from just acting on a thumb val change
+void _sv_slidermap_partial_update(slider_map_t *m, sv_slider_t *s){
+ sv_slice_t *sl = SLICE(s->slices[0]);
+ sv_slice_t *sa = SLICE(s->slices[1]);
+ sv_slice_t *sh = SLICE(s->slices[2]);
+
+ // not a complete check, but will prevent bounds errors.
+ if(m->n != s->labels){
+ fprintf(stderr,"sushivision: internal error; slidermap_partial_update called when full\n"
+ "\tupdate (with additional locking) required.\n");
+ return;
+ }
+
+ m->lo = sl->thumb_val;
+ m->al = sa->thumb_val;
+ m->hi = sh->thumb_val;
+
+ for(j=0;j<m->n-1;j++){
+ float labeldel = 1./(s->label_vals[j+1]-s->label_vals[j]);
+ m->muls[j] = labeldel * s->idelrange * s->labelinv;
+ m->offs[j] = (j-s->label_vals[j]*s->labeldel-
+ s->lodel*(s->labels-1))*s->idelrange*s->labelinv;
+ m->vals[j] = s->vals[j];
+ }
+ m->vals[j] = s->vals[j];
+
+}
+
+void _sv_slidermap_clear(slider_map_t *m){
+ if(m->vals)free(m->vals);
+ if(m->muls)free(m->muls);
+ if(m->offs)free(m->offs);
+ memset(m,0,sizeof(m));
+}
+
+float _sv_slidermap_to_mapdel(slider_map_t *s,float v){
+ int j=s->n-1;
+
+ if(isnan(v))return NAN;
+
+ if(s->neg){
+
+ if(v > s->al && s->al < s->lo)return NAN;
+ if(v >= s->lo)return 0.;
+ if(v <= s->hi)return 1.;
+ while(--j)
+ if(v<=s->vals[j])break;
+
+ }else{
+
+ if(v < s->al && s->al > s->lo)return NAN;
+ if(v <= s->lo)return 0.;
+ if(v >= s->hi)return 1.;
+ while(--j)
+ if(v>s->vals[j])break;
+
+ }
+
+ return v*s->muls[j] + s->offs[j];
+}
+
Modified: trunk/sushivision/slider.h
===================================================================
--- trunk/sushivision/slider.h 2007-09-28 19:49:36 UTC (rev 13914)
+++ trunk/sushivision/slider.h 2007-09-29 02:24:28 UTC (rev 13915)
@@ -32,24 +32,35 @@
cairo_surface_t *foreground;
int w;
int h;
- _sv_mapping_t *gradient;
+ int gradient;
int xpad;
int ypad;
char **label;
- double *label_vals;
+ float *label_vals;
int labels;
int neg;
int flags;
// computation helpers
- double lodel;
- double idelrange;
+ float lodel;
+ float idelrange;
- double quant_num;
- double quant_denom;
+ float quant_num;
+ float quant_denom;
};
+typedef struct {
+ int n;
+ int neg;
+ float al;
+ float lo;
+ float hi;
+ float *vals;
+ float *muls;
+ float *offs;
+} slider_map_t;
+
#define _SV_SLIDER_FLAG_INDEPENDENT_MIDDLE 0x1
#define _SV_SLIDER_FLAG_VERTICAL 0x80
@@ -58,11 +69,11 @@
extern void _sv_slider_expose_slice(_sv_slider_t *s, int slicenum);
extern void _sv_slider_expose(_sv_slider_t *s);
extern void _sv_slider_size_request_slice(_sv_slider_t *s,GtkRequisition *requisition);
-extern double _sv_slider_pixel_to_val(_sv_slider_t *slider,double x);
-extern double _sv_slider_pixel_to_del(_sv_slider_t *slider,double x);
-extern double _sv_slider_pixel_to_mapdel(_sv_slider_t *s,double x);
-extern double _sv_slider_val_to_del(_sv_slider_t *slider,double v);
-extern double _sv_slider_val_to_mapdel(_sv_slider_t *slider,double v);
+extern float _sv_slider_pixel_to_val(_sv_slider_t *slider,float x);
+extern float _sv_slider_pixel_to_del(_sv_slider_t *slider,float x);
+extern float _sv_slider_pixel_to_mapdel(_sv_slider_t *s,float x);
+extern float _sv_slider_val_to_del(_sv_slider_t *slider,float v);
+extern float _sv_slider_val_to_mapdel(_sv_slider_t *slider,float v);
extern void _sv_slider_vals_bound(_sv_slider_t *slider,int slicenum);
extern int _sv_slider_lightme(_sv_slider_t *slider,int slicenum,int x,int y);
extern void _sv_slider_unlight(_sv_slider_t *slider);
@@ -71,14 +82,19 @@
extern void _sv_slider_motion(_sv_slider_t *s,int slicenum,int x,int y);
extern gboolean _sv_slider_key_press(_sv_slider_t *slider,GdkEventKey *event,int slicenum);
extern _sv_slider_t *_sv_slider_new(_sv_slice_t **slices, int num_slices,
- char **labels, double *label_vals, int num_labels,
+ char **labels, float *label_vals, int num_labels,
unsigned flags);
extern void _sv_slider_set_thumb_active(_sv_slider_t *s, int thumbnum, int activep);
-extern void _sv_slider_set_gradient(_sv_slider_t *s, _sv_mapping_t *m);
-extern double _sv_slider_get_value(_sv_slider_t *s, int thumbnum);
-extern void _sv_slider_set_value(_sv_slider_t *s, int thumbnum, double v);
-extern double _sv_slider_del_to_val(_sv_slider_t *s, double del);
-extern void _sv_slider_set_quant(_sv_slider_t *s, double n, double d);
+extern void _sv_slider_set_gradient(_sv_slider_t *s, int m);
+extern float _sv_slider_get_value(_sv_slider_t *s, int thumbnum);
+extern void _sv_slider_set_value(_sv_slider_t *s, int thumbnum, float v);
+extern float _sv_slider_del_to_val(_sv_slider_t *s, float del);
+extern void _sv_slider_set_quant(_sv_slider_t *s, float n, float d);
extern void _sv_slider_print(_sv_slider_t *s, cairo_t *c, int w, int h);
-extern double _sv_slider_print_height(_sv_slider_t *s);
+extern float _sv_slider_print_height(_sv_slider_t *s);
+extern void _sv_slidermap_init(slider_map_t *m, sv_slider_t *s);
+extern void _sv_slidermap_partial_update(slider_map_t *m, sv_slider_t *s);
+extern void _sv_slidermap_clear(slider_map_t *m);
+extern float _sv_slidermap_to_mapdel(slider_map_t *s,float v);
+
More information about the commits
mailing list