--- ray/src/hd/rhd_qtree.c 1997/12/30 17:08:37 3.15 +++ ray/src/hd/rhd_qtree.c 2005/01/07 20:33:02 3.26 @@ -1,13 +1,12 @@ -/* Copyright (c) 1997 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: rhd_qtree.c,v 3.26 2005/01/07 20:33:02 greg Exp $"; #endif - /* * Quadtree driver support routines. */ +#include + #include "standard.h" #include "rhd_qtree.h" /* quantity of leaves to free at a time */ @@ -29,8 +28,10 @@ double qtDepthEps = .05; /* epsilon to compare depths int qtMinNodesiz = 2; /* minimum node dimension (pixels) */ struct rleaves qtL; /* our pile of leaves */ -static int4 falleaves; /* our list of fallen leaves */ +int rayqleft = 0; /* rays left to queue before flush */ +static int32 falleaves; /* our list of fallen leaves */ + #define composted(li) (qtL.bl <= qtL.tl ? \ ((li) < qtL.bl || (li) >= qtL.tl) : \ ((li) < qtL.bl && (li) >= qtL.tl)) @@ -40,9 +41,14 @@ static int4 falleaves; /* our list of fallen leaves */ static RTREE **twigbundle; /* free twig blocks (NULL term.) */ static int nexttwig; /* next free twig */ +static RTREE *newtwig(void); +static void qtFreeTree(int really); +static void shaketree(RTREE *tp); +static int putleaf(int li, int drop); + static RTREE * -newtwig() /* allocate a twig */ +newtwig(void) /* allocate a twig */ { register int bi; @@ -54,7 +60,7 @@ newtwig() /* allocate a twig */ } bi = nexttwig / TBUNDLESIZ; if (twigbundle[bi] == NULL) { /* new block */ - twigbundle = (RTREE **)realloc((char *)twigbundle, + twigbundle = (RTREE **)realloc((void *)twigbundle, (bi+2)*sizeof(RTREE *)); if (twigbundle == NULL) goto memerr; @@ -67,11 +73,14 @@ newtwig() /* allocate a twig */ return(twigbundle[bi] + (nexttwig++ - bi*TBUNDLESIZ)); memerr: error(SYSTEM, "out of memory in newtwig"); + return NULL; /* pro forma return */ } -qtFreeTree(really) /* free allocated twigs */ -int really; +static void +qtFreeTree( /* free allocated twigs */ + int really +) { register int i; @@ -82,23 +91,24 @@ int really; nexttwig = 0; if (!really) { /* just clear allocated blocks */ while (i--) - bzero((char *)twigbundle[i], TBUNDLESIZ*sizeof(RTREE)); + memset((char *)twigbundle[i], '\0', TBUNDLESIZ*sizeof(RTREE)); return; } /* else "really" means free up memory */ for (i = 0; twigbundle[i] != NULL; i++) - free((char *)twigbundle[i]); - free((char *)twigbundle); + free((void *)twigbundle[i]); + free((void *)twigbundle); twigbundle = NULL; } -#define LEAFSIZ (3*sizeof(float)+sizeof(int4)+\ +#define LEAFSIZ (3*sizeof(float)+sizeof(int32)+\ sizeof(TMbright)+6*sizeof(BYTE)) -int -qtAllocLeaves(n) /* allocate space for n leaves */ -register int n; +extern int +qtAllocLeaves( /* allocate space for n leaves */ + register int n +) { unsigned nbytes; register unsigned i; @@ -120,7 +130,7 @@ register int n; return(0); /* assign larger alignment types earlier */ qtL.wp = (float (*)[3])qtL.base; - qtL.wd = (int4 *)(qtL.wp + n); + qtL.wd = (int32 *)(qtL.wp + n); qtL.brt = (TMbright *)(qtL.wd + n); qtL.chr = (BYTE (*)[3])(qtL.brt + n); qtL.rgb = (BYTE (*)[3])(qtL.chr + n); @@ -133,7 +143,8 @@ register int n; #undef LEAFSIZ -qtFreeLeaves() /* free our allocated leaves and twigs */ +extern void +qtFreeLeaves(void) /* free our allocated leaves and twigs */ { qtFreeTree(1); /* free tree also */ if (qtL.nl <= 0) @@ -144,9 +155,10 @@ qtFreeLeaves() /* free our allocated leaves and twig } -static -shaketree(tp) /* shake dead leaves from tree */ -register RTREE *tp; +static void +shaketree( /* shake dead leaves from tree */ + register RTREE *tp +) { register int i, li; @@ -163,11 +175,12 @@ register RTREE *tp; } -int -qtCompost(pct) /* free up some leaves */ -int pct; +extern int +qtCompost( /* free up some leaves */ + int pct +) { - register int4 *fl; + register int32 *fl; int nused, nclear, nmapped; /* figure out how many leaves to clear */ nclear = qtL.nl * pct / 100; @@ -197,9 +210,11 @@ int pct; } -int -qtFindLeaf(x, y) /* find closest leaf to (x,y) */ -int x, y; +extern int +qtFindLeaf( /* find closest leaf to (x,y) */ + int x, + int y +) { register RTREE *tp = &qtrunk; int li = -1; @@ -234,10 +249,11 @@ int x, y; } -static -putleaf(li, drop) /* put a leaf in our tree */ -register int li; -int drop; +static int +putleaf( /* put a leaf in our tree */ + register int li, + int drop +) { register RTREE *tp = &qtrunk; int x0=0, y0=0, x1=odev.hres, y1=odev.vres; @@ -319,44 +335,60 @@ int drop; } dropit: if (drop) { - qtL.chr[li][0] = qtL.chr[li][1] = qtL.chr[li][2] = 0; - qtL.wd[li] = falleaves; - falleaves = li; + if (li+1 == (qtL.tl ? qtL.tl : qtL.nl)) + qtL.tl = li; /* special case */ + else { + qtL.chr[li][0] = qtL.chr[li][1] = qtL.chr[li][2] = 0; + qtL.wd[li] = falleaves; + falleaves = li; + } } return(li == lo); } -dev_value(c, p, v) /* add a pixel value to our quadtree */ -COLR c; -FVECT p, v; +extern void +dev_value( /* add a pixel value to our quadtree */ + COLR c, + FVECT d, + FVECT p +) { register int li; int mapit; /* grab a leaf */ - if (falleaves >= 0) { /* check for fallen leaves */ + if (!imm_mode && falleaves >= 0) { /* check for fallen leaves */ li = falleaves; falleaves = qtL.wd[li]; mapit = qtL.tml <= qtL.tl ? (li < qtL.tml || li >= qtL.tl) : (li < qtL.tml && li >= qtL.tl) ; - } else { /* else allocate new one */ + } else { /* else allocate new one */ li = qtL.tl++; - if (qtL.tl >= qtL.nl) /* advance to next leaf in ring */ + if (qtL.tl >= qtL.nl) /* next leaf in ring */ qtL.tl = 0; - if (qtL.tl == qtL.bl) /* need to shake some free */ + if (qtL.tl == qtL.bl) /* need to shake some free */ qtCompost(LFREEPCT); - mapit = 0; /* we'll map it later */ + mapit = 0; /* we'll map it later */ } - VCOPY(qtL.wp[li], p); - qtL.wd[li] = encodedir(v); - tmCvColrs(&qtL.brt[li], qtL.chr[li], c, 1); - if (putleaf(li, 1) && mapit) - tmMapPixels(qtL.rgb+li, qtL.brt+li, qtL.chr+li, 1); + if (p == NULL) + VSUM(qtL.wp[li], odev.v.vp, d, FHUGE); + else + VCOPY(qtL.wp[li], p); + qtL.wd[li] = encodedir(d); + tmCvColrs(tmGlobal, &qtL.brt[li], qtL.chr[li], (COLR *)c, 1); + if (putleaf(li, 1)) { + if (mapit) + tmMapPixels(tmGlobal, (BYTE *)(qtL.rgb+li), qtL.brt+li, + (BYTE *)(qtL.chr+li), 1); + if (--rayqleft == 0) + dev_flush(); /* flush output */ + } } -qtReplant() /* replant our tree using new view */ +extern void +qtReplant(void) /* replant our tree using new view */ { register int i; /* anything to replant? */ @@ -371,8 +403,10 @@ qtReplant() /* replant our tree using new view */ } -qtMapLeaves(redo) /* map our leaves to RGB */ -int redo; +extern int +qtMapLeaves( /* map our leaves to RGB */ + int redo +) { int aorg, alen, borg, blen; /* recompute mapping? */ @@ -393,19 +427,19 @@ int redo; } /* (re)compute tone mapping? */ if (qtL.tml == qtL.bl) { - tmClearHisto(); - tmAddHisto(qtL.brt+aorg, alen, 1); + tmClearHisto(tmGlobal); + tmAddHisto(tmGlobal, qtL.brt+aorg, alen, 1); if (blen > 0) - tmAddHisto(qtL.brt+borg, blen, 1); - if (tmComputeMapping(0., 0., 0.) != TM_E_OK) + tmAddHisto(tmGlobal, qtL.brt+borg, blen, 1); + if (tmComputeMapping(tmGlobal, 0., 0., 0.) != TM_E_OK) return(0); } - if (tmMapPixels(qtL.rgb+aorg, qtL.brt+aorg, - qtL.chr+aorg, alen) != TM_E_OK) + if (tmMapPixels(tmGlobal, (BYTE *)(qtL.rgb+aorg), qtL.brt+aorg, + (BYTE *)(qtL.chr+aorg), alen) != TM_E_OK) return(0); if (blen > 0) - tmMapPixels(qtL.rgb+borg, qtL.brt+borg, - qtL.chr+borg, blen); + tmMapPixels(tmGlobal, (BYTE *)(qtL.rgb+borg), qtL.brt+borg, + (BYTE *)(qtL.chr+borg), blen); qtL.tml = qtL.tl; return(1); }