--- ray/src/hd/rhd_odraw.c 1998/12/20 20:37:53 3.2 +++ ray/src/hd/rhd_odraw.c 1998/12/22 17:05:54 3.5 @@ -58,9 +58,10 @@ int n; int nbytes, i, j, k, nextsamp, count, blockdiv; int res[2]; - if (odNViews) { /* deallocate view structures */ - for (i = 0; i < odNViews; i++) { + if (odNViews > 0) { /* deallocate view structures */ + for (i = odNViews; i--; ) { free((char *)odView[i].bmap); + free((char *)odView[i].pmap); if (odView[i].emap != NULL) free((char *)odView[i].emap); } @@ -109,8 +110,6 @@ int n; if (blockdiv < 8) blockdiv = 8; nextsamp = 0; count /= blockdiv*blockdiv; /* # blocks */ while (i--) { /* initialize each view */ - odView[i].emap = NULL; - odView[i].dmap = NULL; dev_auxview(i, res); odView[i].hhi = res[0]; odView[i].hlow = (res[0] + blockdiv/2) / blockdiv; @@ -118,6 +117,12 @@ int n; odView[i].vhi = res[1]; odView[i].vlow = (res[1] + blockdiv/2) / blockdiv; 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)); + if (odView[i].pmap == NULL) + return(0); j = odView[i].hlow*odView[i].vlow; odView[i].bmap = (struct ODblock *)malloc( j * sizeof(struct ODblock)); @@ -126,6 +131,7 @@ int n; DCHECK(count<=0 | nextsamp>=n, CONSISTENCY, "counter botch in odInit"); if (!i) count = j; + odView[i].sfirst = nextsamp; while (j--) { /* initialize blocks & free lists */ odView[i].bmap[j].pthresh = FHUGE; odView[i].bmap[j].first = k = nextsamp; @@ -137,6 +143,7 @@ int n; odS.nextfree(k-1) = ENDFREE; odView[i].bmap[j].nused = 0; } + odView[i].snext = nextsamp; } CLR4ALL(odS.redraw, odS.nsamp); /* clear redraw flags */ for (i = odS.nsamp; i--; ) { /* clear values */ @@ -179,7 +186,11 @@ double prox; if (prox > bp->pthresh) return(-1); /* worse than free list occupants */ /* check for duplicate pixel */ - for (i = bp->first+bp->nsamp; i-- > bp->first; ) + if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh)) + i = bp->first + bp->nsamp; + else + i = -1; + while (i-- > bp->first) if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */ /* search free list for it */ if (i == bp->free) @@ -197,8 +208,12 @@ double prox; 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) + CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + + odS.ip[i][0]); bp->free = odS.nextfree(i); bp->nused++; goto gotit; @@ -222,10 +237,12 @@ double prox; bp->nused--; } i = si[0]; /* use worst sample */ + CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + odS.ip[i][0]); gotit: odS.ip[i][0] = hh; odS.ip[i][1] = vh; odS.closeness(i) = prox; + SET4(odView[vn].pmap, vh*odView[vn].hhi + hh); return(i); } @@ -409,9 +426,7 @@ GLfloat *dm; odUpdate(vn) /* update this view */ int vn; { - int i, j; - register struct ODblock *bp; - register int k; + register int i, j; DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, "bad view number in odUpdate"); @@ -424,35 +439,44 @@ int vn; return; if (tmComputeMapping(0.,0.,0.) != TM_E_OK) return; - for (k = odS.nsamp; k--; ) /* redraw all */ - if (odS.ip[k][0] >= 0) - SET4(odS.redraw, k); + for (i = odS.nsamp; i--; ) /* redraw all */ + if (odS.ip[i][0] >= 0) + SET4(odS.redraw, i); } if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK) return; needmapping = 0; /* reset flag */ } - /* draw each block in view */ - for (j = odView[vn].vlow; j--; ) - for (i = 0; i < odView[vn].hlow; i++) { - /* get block */ - bp = odView[vn].bmap + j*odView[vn].hlow + i; - /* do quick, conservative flag check */ - for (k = (bp->first+bp->nsamp+31)>>5; - k-- > bp->first>>5; ) - if (odS.redraw[k]) - break; /* non-zero flag */ - if (k < bp->first>>5) - continue; /* no flags set */ - for (k = bp->nsamp; k--; ) /* sample by sample */ - if (CHK4(odS.redraw, bp->first+k)) { - odDrawBlockSamp(vn, i, j, bp->first+k); - CLR4(odS.redraw, bp->first+k); - } + /* this code segment was too slow */ +#if 0 + for (i = odView[vn].sfirst; i < odView[vn].snext; i++) + if (CHK4(odS.redraw, i)) { + odDrawSamp(vn, i); + CLR4(odS.redraw, i); } +#endif + /* redraw samples at each end */ + for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++) + if (CHK4(odS.redraw, i)) { + odDrawSamp(vn, i); + CLR4(odS.redraw, i); + } + for (i = odView[vn].snext-31; i < odView[vn].snext; i++) + if (CHK4(odS.redraw, i)) { + odDrawSamp(vn, i); + CLR4(odS.redraw, i); + } + /* faster flag checks in middle */ + for (j = odView[vn].snext>>5; j-- > (odView[vn].sfirst+0x1f)>>5; ) + for (i = 0; odS.redraw[j]; i++) /* skips faster */ + if (odS.redraw[j] & 1L<hlow + h; - DCHECK(odS.ip[id][0]*vp->hlow/vp->hhi != h | - odS.ip[id][1]*vp->vlow/vp->vhi != v, - CONSISTENCY, "bad sample position in odDrawBlockSamp"); + blockindex = getblock(vp, odS.ip[id][0], odS.ip[id][1]); + DCHECK(blockindex<0, CONSISTENCY, "bad sample handed to odDrawSamp"); DCHECK(vp->bmap[blockindex].nused <= 0, - CONSISTENCY, "bad in-use count in odDrawBlockSamp"); + CONSISTENCY, "bad in-use count in odDrawSamp"); /* create triangle fan */ size = 1./sqrt((double)vp->bmap[blockindex].nused); narms = make_arms(arm, odS.ip[id], vp, size);