--- ray/src/hd/rhd_odraw.c 1998/12/23 21:49:43 3.7 +++ ray/src/hd/rhd_odraw.c 2004/01/01 11:21:55 3.16 @@ -1,16 +1,12 @@ -/* Copyright (c) 1998 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: rhd_odraw.c,v 3.16 2004/01/01 11:21:55 schorsch Exp $"; #endif - /* * Routines for drawing samples using depth buffer checks. */ #include "standard.h" -#include #include #include @@ -25,6 +21,9 @@ static char SCCSid[] = "$SunId$ SGI"; #ifndef SFREEFRAC #define SFREEFRAC 0.2 /* fraction to free at a time */ #endif +#ifndef REDRAWTHRESH +#define REDRAWTHRESH 10240 /* number of samples for dissolve */ +#endif #ifndef MAXFAN #define MAXFAN 32 /* maximum arms in a triangle fan */ #endif @@ -48,23 +47,35 @@ static int needmapping; /* what needs doing with tone #define SAMP32 (32*(2*sizeof(short)+sizeof(union ODfunion)+sizeof(TMbright)+\ - 6*sizeof(BYTE))+sizeof(int4)) + 6*sizeof(BYTE))+sizeof(int32)) -int -odInit(n) /* initialize drawing routines */ -int n; +static int sampcmp(const void *s0, const void *s1); +static int odAllocBlockSamp(int vn, int hh, int vh, double prox); +static int make_arms(GLshort ar[MAXFAN][3], short cp[2], struct ODview *vp, + double sz); +static int depthchange(struct ODview *vp, int x0, int y0, int x1, int y1); +static void clip_edge(GLshort p[3], short o[2], struct ODview *vp); +static int getblock(struct ODview *vp, int h, int v); +static int blockedge(struct ODview *vp, int bi0, int bi1); +static void odDrawSamp(int vn, int id); + + +extern int +odInit( /* initialize drawing routines */ + int n +) { int nbytes, i, j, k, nextsamp, count, blockdiv; int res[2]; if (odNViews > 0) { /* deallocate view structures */ for (i = odNViews; i--; ) { - free((char *)odView[i].bmap); - free((char *)odView[i].pmap); + free((void *)odView[i].bmap); + free((void *)odView[i].pmap); if (odView[i].emap != NULL) - free((char *)odView[i].emap); + free((void *)odView[i].emap); } - free((char *)odView); + free((void *)odView); odView = NULL; odNViews = 0; } @@ -88,7 +99,7 @@ int n; return(0); /* assign larger alignment types earlier */ odS.f = (union ODfunion *)odS.base; - odS.redraw = (int4 *)(odS.f + n); + odS.redraw = (int32 *)(odS.f + n); odS.ip = (short (*)[2])(odS.redraw + n/32); odS.brt = (TMbright *)(odS.ip + n); odS.chr = (BYTE (*)[3])(odS.brt + n); @@ -118,8 +129,8 @@ int n; if (odView[i].vlow < 1) odView[i].vlow = 1; odView[i].emap = NULL; odView[i].dmap = NULL; - odView[i].pmap = (int4 *)calloc(FL4NELS(res[0]*res[1]), - sizeof(int4)); + odView[i].pmap = (int32 *)calloc(FL4NELS(res[0]*res[1]), + sizeof(int32)); if (odView[i].pmap == NULL) return(0); j = odView[i].hlow*odView[i].vlow; @@ -143,6 +154,7 @@ int n; odView[i].bmap[j].nused = 0; } odView[i].snext = nextsamp; + odView[i].n2redraw = 0; } CLR4ALL(odS.redraw, odS.nsamp); /* clear redraw flags */ for (i = odS.nsamp; i--; ) { /* clear values */ @@ -157,24 +169,28 @@ int n; int -sampcmp(s0, s1) /* sample order, descending proximity */ -int *s0, *s1; +sampcmp( /* sample order, descending proximity */ + const void *s0, + const void *s1 +) { - register double diff = odS.closeness(*s1) - odS.closeness(*s0); + register double diff = odS.closeness(*(int*)s1) - odS.closeness(*(int*)s0); return (diff > FTINY ? 1 : diff < -FTINY ? -1 : 0); } int -odAllocBlockSamp(vn, hh, vh, prox) /* allocate sample from block */ -int vn, hh, vh; -double prox; +odAllocBlockSamp( /* allocate sample from block */ + int vn, + int hh, + int vh, + double prox +) { int si[SAMPSPERBLOCK+SAMPSPERBLOCK/4]; int hl, vl; VIEW *vw; - FVECT ro, rd; int res[2]; register struct ODblock *bp; register int i, j; @@ -188,7 +204,7 @@ double prox; if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh)) i = bp->first + bp->nsamp; else - i = -1; + i = 0; while (i-- > bp->first) if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */ /* search free list for it */ @@ -203,14 +219,13 @@ double prox; bp->nused++; goto gotit; } - if (prox >= 0.999*odS.closeness(i)) + if (prox >= 0.99*odS.closeness(i)) return(-1); /* previous sample is fine */ goto gotit; } - DCHECK(i>=-1, WARNING, "pixel in presence map not found in block"); if (bp->free != ENDFREE) { /* allocate from free list */ i = bp->free; - if (odS.ip[i][0] >= 0 & odS.ip[i][1] >= 0) + if ((odS.ip[i][0] >= 0) & (odS.ip[i][1] >= 0)) CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + odS.ip[i][0]); bp->free = odS.nextfree(i); @@ -246,9 +261,12 @@ gotit: } -odSample(c, d, p) /* add a sample value */ -COLR c; -FVECT d, p; +extern void +odSample( /* add a sample value */ + COLR c, + FVECT d, + FVECT p +) { FVECT disp; double d0, d1, h, v, prox; @@ -298,18 +316,21 @@ FVECT d, p; if (id < 0) continue; /* not good enough */ /* convert color */ - tmCvColrs(&odS.brt[id], odS.chr[id], c, 1); + tmCvColrs(&odS.brt[id], odS.chr[id], (COLR *)c, 1); if (imm_mode | needmapping) /* if immediate mode */ needmapping |= NEWRGB; /* map it later */ else /* else map it now */ tmMapPixels(odS.rgb[id], &odS.brt[id], odS.chr[id], 1); SET4(odS.redraw, id); /* mark for redraw */ + odView[i].n2redraw++; } } -odRemap(newhist) /* recompute tone mapping */ -int newhist; +extern void +odRemap( /* recompute tone mapping */ + int newhist +) { needmapping |= NEWMAP|NEWRGB; if (newhist) @@ -317,7 +338,8 @@ int newhist; } -odRedrawAll() /* mark all samples for redraw */ +extern void +odRedrawAll(void) /* mark all samples for redraw */ { register int i; @@ -326,24 +348,33 @@ odRedrawAll() /* mark all samples for redraw */ for (i = odS.nsamp; i--; ) if (odS.ip[i][0] >= 0) SET4(odS.redraw, i); + /* not right, but not important */ + for (i = 0; i < odNViews; i++) + odView[i].n2redraw = odView[i].snext - odView[i].sfirst; } -odRedraw(vn, hmin, vmin, hmax, vmax) /* redraw view region */ -int vn, hmin, vmin, hmax, vmax; +extern void +odRedraw( /* redraw view region */ + int vn, + int hmin, + int vmin, + int hmax, + int vmax +) { int i, j; register struct ODblock *bp; register int k; - if (vn<0 | vn>=odNViews) + if ((vn<0) | (vn>=odNViews)) return; /* check view limits */ if (hmin < 0) hmin = 0; if (hmax >= odView[vn].hhi) hmax = odView[vn].hhi-1; if (vmin < 0) vmin = 0; if (vmax >= odView[vn].vhi) vmax = odView[vn].vhi-1; - if (hmax <= hmin | vmax <= vmin) + if ((hmax <= hmin) | (vmax <= vmin)) return; /* convert to low resolution */ hmin = hmin * odView[vn].hlow / odView[vn].hhi; @@ -355,25 +386,29 @@ int vn, hmin, vmin, hmax, vmax; for (j = vmin; j <= vmax; j++) { bp = odView[vn].bmap + j*odView[vn].hlow + i; for (k = bp->nsamp; k--; ) - if (odS.ip[bp->first+k][0] >= 0) + if (odS.ip[bp->first+k][0] >= 0) { SET4(odS.redraw, bp->first+k); + odView[vn].n2redraw++; + } } } -odDepthMap(vn, dm) /* assign depth map for view */ -int vn; -GLfloat *dm; +extern void +odDepthMap( /* assign depth map for view */ + int vn, + GLfloat *dm +) { double d0, d1; int i, j, hmin, hmax, vmin, vmax; register int k, l; if (dm == NULL) { /* free edge map */ - if (vn<0 | vn>=odNViews) + if ((vn<0) | (vn>=odNViews)) return; /* too late -- they're gone! */ if (odView[vn].emap != NULL) - free((char *)odView[vn].emap); + free((void *)odView[vn].emap); odView[vn].emap = NULL; odView[vn].dmap = NULL; return; @@ -382,8 +417,8 @@ GLfloat *dm; "bad view number in odDepthMap"); odView[vn].dmap = dm; /* initialize edge map */ if (odView[vn].emap == NULL) { - odView[vn].emap = (int4 *)malloc( - FL4NELS(odView[vn].hlow*odView[vn].vlow)*sizeof(int4)); + odView[vn].emap = (int32 *)malloc( + FL4NELS(odView[vn].hlow*odView[vn].vlow)*sizeof(int32)); if (odView[vn].emap == NULL) error(SYSTEM, "out of memory in odDepthMap"); } @@ -434,10 +469,14 @@ GLfloat *dm; } -odUpdate(vn) /* update this view */ -int vn; +extern void +odUpdate( /* update this view */ + int vn +) { - register int i, j; + static short primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1}; + int myprime; + register int i, n; DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, "bad view number in odUpdate"); @@ -454,37 +493,56 @@ int vn; needmapping &= ~NEWMAP; odRedrawAll(); /* redraw everything */ } - if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK) + if (tmMapPixels((BYTE *)(odS.rgb), odS.brt, + (BYTE *)(odS.chr), odS.nsamp) != TM_E_OK) return; needmapping &= ~NEWRGB; } - /* this code segment was too slow */ -#if 0 - for (i = odView[vn].sfirst; i < odView[vn].snext; i++) + if (odView[vn].n2redraw <= 0) + return; +#if REDRAWTHRESH + if (odView[vn].n2redraw < REDRAWTHRESH) + goto quickdraw; + /* pick a good prime step size */ + n = odView[vn].snext - odView[vn].sfirst; + for (i = 0; primes[i]<<5 >= n; i++) + ; + while ((myprime = primes[i++]) > 1) + if (n % myprime) + break; + /* dissolve in new samples */ + for (i = odView[vn].sfirst; n-- > 0; i += myprime) { + if (i >= odView[vn].snext) + i -= odView[vn].snext - odView[vn].sfirst; if (CHK4(odS.redraw, i)) { odDrawSamp(vn, i); CLR4(odS.redraw, i); } -#else - /* redraw samples at each end */ - for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++) + } + odView[vn].n2redraw = 0; + return; +quickdraw: /* quicker sparse flag checking */ +#endif + /* redraw samples at end */ + for (i = odView[vn].snext-31; i < odView[vn].snext; i++) if (CHK4(odS.redraw, i)) { odDrawSamp(vn, i); CLR4(odS.redraw, i); } - for (i = odView[vn].snext-31; i < odView[vn].snext; i++) + /* faster flag checks in middle */ + for (n = odView[vn].snext>>5; n-- > (odView[vn].sfirst+0x1f)>>5; ) + for (i = 0; odS.redraw[n]; i++) /* skips faster */ + if (odS.redraw[n] & 1L<>5; j-- > (odView[vn].sfirst+0x1f)>>5; ) - for (i = 0; odS.redraw[j]; i++) /* skips faster */ - if (odS.redraw[j] & 1L< 1, CONSISTENCY, "super-unary size in make_arms"); - na = MAXFAN*sz*sz + 0.5; /* keep area constant */ + na = MAXFAN*sz + 0.5; /* keep arc length constant */ if (na < MINFAN) na = MINFAN; hrad = FANSIZE*sz*vp->hhi/vp->hlow; vrad = FANSIZE*sz*vp->vhi/vp->vlow; @@ -549,16 +608,20 @@ double sz; static int -depthchange(vp, x0, y0, x1, y1) /* check depth discontinuity */ -register struct ODview *vp; -int x0, y0, x1, y1; +depthchange( /* check depth discontinuity */ + register struct ODview *vp, + int x0, + int y0, + int x1, + int y1 +) { register double d0, d1; DCHECK(x0<0 | x0>=vp->hhi | y0<0 | y0>=vp->vhi, CONSISTENCY, "coordinates off view in depthchange"); - if (x1<0 | x1>=vp->hhi | y1<0 | y1>=vp->vhi) + if ((x1<0) | (x1>=vp->hhi) | (y1<0) | (y1>=vp->vhi)) return(1); d0 = vp->dmap[y0*vp->hhi + x0]; @@ -568,11 +631,12 @@ int x0, y0, x1, y1; } -static -clip_edge(p, o, vp) /* clip line segment to depth edge */ -GLshort p[3]; -short o[2]; -register struct ODview *vp; +static void +clip_edge( /* clip line segment to depth edge */ + GLshort p[3], + short o[2], + register struct ODview *vp +) { int x, y, xstep, ystep, rise, rise2, run, run2, n; @@ -613,25 +677,31 @@ register struct ODview *vp; static int -getblock(vp, h, v) /* get block index */ -register struct ODview *vp; -register int h, v; +getblock( /* get block index */ + register struct ODview *vp, + register int h, + register int v +) { - if (h<0 | h>=vp->hhi | v<0 | v>=vp->vhi) + if ((h<0) | (h>=vp->hhi) | (v<0) | (v>=vp->vhi)) return(-1); return(h*vp->hlow/vp->hhi + v*vp->vlow/vp->vhi*vp->hlow); } static int -blockedge(vp, bi0, bi1) /* check for edge between blocks? */ -register struct ODview *vp; -register int bi0, bi1; +blockedge( /* check for edge between blocks? */ + register struct ODview *vp, + register int bi0, + register int bi1 +) { + if (bi1 == bi0) + return(0); /* same block */ if (bi1 < 0) return(1); /* end off view */ if (CHK4(vp->emap, bi1)) - return(1); /* end has edges */ + return(1); /* end block has edges */ if (bi1 == bi0+1 || bi1 == bi0-1 || bi1 == bi0+vp->hlow || bi1 == bi0-vp->hlow) return(0); /* end in adjacent block -- no edges */ @@ -639,9 +709,11 @@ register int bi0, bi1; } -odDrawSamp(vn, id) /* draw view sample */ -int vn; -register int id; +static void +odDrawSamp( /* draw view sample */ + int vn, + register int id +) { GLshort arm[MAXFAN][3]; int narms, blockindex;