ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
(Generate patch)

Comparing ray/src/util/glareval.c (file contents):
Revision 1.3 by greg, Tue Mar 19 17:06:27 1991 UTC vs.
Revision 1.10 by greg, Fri Apr 5 14:41:55 1991 UTC

# Line 20 | Line 20 | static char SCCSid[] = "$SunId$ LBL";
20   #define vfork           fork
21   #endif
22  
23 < #define NSCANS          64              /* number of scanlines to buffer */
23 > #define MAXSBUF         1023980 /* maximum total size of scanline buffer */
24 > #define HSIZE           317     /* size of scanline hash table */
25 > #define NRETIRE         16      /* number of scanlines to retire at once */
26  
27   int     rt_pid = -1;            /* process id for rtrace */
28   int     fd_tort, fd_fromrt;     /* pipe descriptors */
# Line 28 | Line 30 | int    fd_tort, fd_fromrt;     /* pipe descriptors */
30   FILE    *pictfp = NULL;         /* picture file pointer */
31   double  exposure;               /* picture exposure */
32   int     pxsiz, pysiz;           /* picture dimensions */
33 < int     curpos;                 /* current scanline */
34 < long    *scanpos;               /* scanline positions */
35 < struct {
36 <        long    lused;          /* for LRU replacement */
33 >
34 > static int      curpos;         /* current scanline */
35 > static long     *scanpos;       /* scanline positions */
36 >
37 > typedef struct scan {
38          int     y;              /* scanline position */
39 <        COLR    *sl;            /* scanline contents */
40 < } scan[NSCANS];         /* buffered scanlines */
39 >        long    lused;          /* for LRU replacement */
40 >        struct scan     *next;  /* next in this hash or free list */
41 >        /* followed by the scanline data */
42 > } SCAN;                 /* buffered scanline */
43  
44 + #define scandata(sl)    ((COLR *)((sl)+1))
45 + #define shash(y)        ((y)%HSIZE)
46 +
47 + static SCAN     *freelist;              /* scanline free list */
48 + static SCAN     *hashtab[HSIZE];        /* scanline hash table */
49 +
50   static long     ncall = 0L;     /* number of calls to getpictscan */
51   static long     nread = 0L;     /* number of scanlines read */
52  
53 + SCAN    *scanretire();
54  
55 + extern long     ftell();
56 +
57 +
58 + SCAN *
59 + claimscan(y)                    /* claim scanline from buffers */
60 + int     y;
61 + {
62 +        int     hi = shash(y);
63 +        SCAN    *slast;
64 +        register SCAN   *sl;
65 +
66 +        for (sl = hashtab[hi]; sl != NULL; sl = sl->next)
67 +                if (sl->y == y)                         /* active scanline */
68 +                        return(sl);
69 +        for (slast = NULL, sl = freelist; sl != NULL; slast = sl, sl = sl->next)
70 +                if (sl->y == -1 || sl->y == y || sl->next == NULL) {
71 +                        if (slast == NULL)              /* remove from free */
72 +                                freelist = sl->next;
73 +                        else
74 +                                slast->next = sl->next;
75 +                        if (sl->y == y) {               /* reclaim */
76 +                                sl->next = hashtab[hi];
77 +                                hashtab[hi] = sl;
78 +                        }
79 +                        return(sl);
80 +                }
81 +        return(scanretire());           /* need more free scanlines */
82 + }
83 +
84 +
85   COLR *
86   getpictscan(y)                  /* get picture scanline */
87   int     y;
88   {
89 <        extern long     ftell();
48 <        int     minused;
89 >        register SCAN   *sl;
90          register int    i;
91                                          /* first check our buffers */
92 <        ncall++;
93 <        minused = 0;
94 <        for (i = 0; i < NSCANS; i++) {
95 <                if (scan[i].y == y) {
96 <                        scan[i].lused = ncall;
97 <                        return(scan[i].sl);
98 <                }
99 <                if (scan[i].lused < scan[minused].lused)
100 <                        minused = i;
101 <        }
102 <                                        /* not there, read it in */
103 <        if (scanpos[y] == -1) {                 /* need to search */
104 <                while (curpos > y) {
92 >        sl = claimscan(y);
93 >        if (sl == NULL)
94 >                memerr("claimscan()");
95 >        sl->lused = ncall++;
96 >        if (sl->y == y)                 /* scan hit */
97 >                return(scandata(sl));
98 >                                        /* else read in replacement */
99 >        if (scanpos[y] < 0) {                   /* need to search */
100 >                for (i = y+1; i < curpos; i++)
101 >                        if (scanpos[i] >= 0) {
102 >                                if (fseek(pictfp, scanpos[i], 0) < 0)
103 >                                        goto seekerr;
104 >                                curpos = i;
105 >                                break;
106 >                        }
107 >                while (curpos >= y) {
108                          scanpos[curpos] = ftell(pictfp);
109 <                        if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
109 >                        if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
110                                  goto readerr;
111 +                        nread++;
112                          curpos--;
113                  }
114 <        } else if (fseek(pictfp, scanpos[y], 0) < 0) {
115 <                fprintf(stderr, "%s: picture seek error\n", progname);
116 <                exit(1);
114 >        } else {
115 >                if (curpos != y && fseek(pictfp, scanpos[y], 0) < 0)
116 >                        goto seekerr;
117 >                if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
118 >                        goto readerr;
119 >                nread++;
120 >                curpos = y-1;
121          }
122 <        if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
123 <                goto readerr;
124 <        nread++;
125 <        curpos = y-1;
126 <        scan[minused].lused = ncall;
78 <        scan[minused].y = y;
79 <        return(scan[minused].sl);
122 >        sl->y = y;
123 >        i = shash(y);                   /* add to hash list */
124 >        sl->next = hashtab[i];
125 >        hashtab[i] = sl;
126 >        return(scandata(sl));
127   readerr:
128          fprintf(stderr, "%s: picture read error\n", progname);
129          exit(1);
130 + seekerr:
131 +        fprintf(stderr, "%s: picture seek error\n", progname);
132 +        exit(1);
133   }
134  
135  
136 + #ifdef DEBUG
137   pict_stats()                    /* print out picture read statistics */
138   {
139          static long     lastcall = 0L;  /* ncall at last report */
# Line 90 | Line 141 | pict_stats()                   /* print out picture read statistics */
141  
142          if (ncall == lastcall)
143                  return;
144 <        fprintf(stderr, "%s: %ld scanlines read, %ld reused\n",
145 <                        progname, nread-lastread,
95 <                        (ncall-lastcall)-(nread-lastread));
144 >        fprintf(stderr, "%s: %ld scanlines read in %ld calls\n",
145 >                        progname, nread-lastread, ncall-lastcall);
146          lastcall = ncall;
147          lastread = nread;
148   }
149 + #endif
150  
151  
152   double
# Line 129 | Line 180 | int    vh, vv;
180  
181          if (compdir(dir, vh, vv) < 0)
182                  return(-1.0);
183 +        npixinvw++;
184          if ((res = pict_val(dir)) >= 0.0)
185                  return(res);
186 <        if (rt_pid == -1)
186 >        if (rt_pid == -1) {
187 >                npixmiss++;
188                  return(-1.0);
189 +        }
190          rt_buf[0] = ourview.vp[0];
191          rt_buf[1] = ourview.vp[1];
192          rt_buf[2] = ourview.vp[2];
# Line 154 | Line 208 | float  *vb;
208          FVECT   dir;
209          register int    vh;
210  
211 + #ifdef DEBUG
212          if (verbose)
213                  fprintf(stderr, "%s: computing view span at %d...\n",
214                                  progname, vv);
215 + #endif
216          n = 0;
217          for (vh = -hsize; vh <= hsize; vh++) {
218                  if (compdir(dir, vh, vv) < 0) { /* off viewable region */
219                          vb[vh+hsize] = -1.0;
220                          continue;
221                  }
222 +                npixinvw++;
223                  if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
224                          continue;
225 <                if (rt_pid == -1)               /* missing information */
225 >                if (rt_pid == -1) {             /* missing information */
226 >                        npixmiss++;
227                          continue;
228 +                }
229                                                  /* send to rtrace */
230                  if (n >= MAXPIX) {                      /* flush */
231                          rt_compute(rt_buf, n);
# Line 181 | Line 240 | float  *vb;
240                  rt_buf[6*n+5] = dir[2];
241                  buf_vh[n++] = vh;
242          }
243 + #ifdef DEBUG
244          if (verbose)
245                  pict_stats();
246 + #endif
247          if (n > 0) {                            /* process pending buffer */
248                  rt_compute(rt_buf, n);
249                  while (n-- > 0)
# Line 197 | Line 258 | int    np;
258   {
259          static float    nbuf[6] = {0.,0.,0.,0.,0.,0.};
260  
261 + #ifdef DEBUG
262          if (verbose && np > 1)
263                  fprintf(stderr, "%s: sending %d samples to rtrace...\n",
264                                  progname, np);
265 + #endif
266          if (writebuf(fd_tort,(char *)pb,6*sizeof(float)*np) < 6*sizeof(float)*np
267                  || writebuf(fd_tort,(char *)nbuf,sizeof(nbuf)) < sizeof(nbuf)) {
268                  fprintf(stderr, "%s: error writing to rtrace process\n",
# Line 238 | Line 301 | char   *fn;
301                  fprintf("%s: bad picture resolution\n", fn);
302                  exit(1);
303          }
304 <        scanpos = (long *)malloc(pysiz*sizeof(long));
242 <        if (scanpos == NULL)
243 <                memerr("scanline positions");
244 <        for (i = 0; i < pysiz; i++)
245 <                scanpos[i] = -1L;
246 <        for (i = 0; i < NSCANS; i++) {
247 <                scan[i].lused = -1;
248 <                scan[i].y = -1;
249 <                scan[i].sl = (COLR *)malloc(pxsiz*sizeof(COLR));
250 <                if (scan[i].sl == NULL)
251 <                        memerr("scanline buffers");
252 <        }
253 <        curpos = pysiz-1;
304 >        initscans();
305   }
306  
307  
# Line 261 | Line 312 | close_pict()                   /* done with picture */
312          if (pictfp == NULL)
313                  return;
314          fclose(pictfp);
315 <        free((char *)scanpos);
265 <        for (i = 0; i < NSCANS; i++)
266 <                free((char *)scan[i].sl);
315 >        donescans();
316          pictfp = NULL;
317   }
318  
# Line 354 | Line 403 | int    siz;
403          if (cc < 0)
404                  return(cc);
405          return(siz-nrem);
406 + }
407 +
408 +
409 + SCAN *
410 + scanretire()                    /* retire old scanlines to free list */
411 + {
412 +        SCAN    *sold[NRETIRE];
413 +        int     n;
414 +        int     h;
415 +        register SCAN   *sl;
416 +        register int    i;
417 +                                        /* grab the NRETIRE oldest scanlines */
418 +        sold[n = 0] = NULL;
419 +        for (h = 0; h < HSIZE; h++)
420 +                for (sl = hashtab[h]; sl != NULL; sl = sl->next) {
421 +                        for (i = n; i && sold[i-1]->lused > sl->lused; i--)
422 +                                if (i < NRETIRE)
423 +                                        sold[i] = sold[i-1];
424 +                        if (i < NRETIRE) {
425 +                                sold[i] = sl;
426 +                                if (n < NRETIRE)        /* grow list */
427 +                                        n++;
428 +                        }
429 +                }
430 +                                        /* put scanlines into free list */
431 +        for (i = 0; i < n; i++) {
432 +                h = shash(sold[i]->y);
433 +                sl = hashtab[h];
434 +                if (sl == sold[i])
435 +                        hashtab[h] = sl->next;
436 +                else {
437 +                        while (sl->next != sold[i])     /* IS in list */
438 +                                sl = sl->next;
439 +                        sl->next = sold[i]->next;
440 +                }
441 +                if (i > 0) {            /* save oldest as return value */
442 +                        sold[i]->next = freelist;
443 +                        freelist = sold[i];
444 +                }
445 +        }
446 +        return(sold[0]);
447 + }
448 +
449 +
450 + static char     *scan_buf;
451 +
452 +
453 + initscans()                             /* initialize scanline buffers */
454 + {
455 +        int     scansize;
456 +        register SCAN   *ptr;
457 +        register int    i;
458 +                                        /* initialize positions */
459 +        scanpos = (long *)malloc(pysiz*sizeof(long));
460 +        if (scanpos == NULL)
461 +                memerr("scanline positions");
462 +        for (i = pysiz-1; i >= 0; i--)
463 +                scanpos[i] = -1L;
464 +        curpos = pysiz-1;
465 +                                        /* clear hash table */
466 +        for (i = 0; i < HSIZE; i++)
467 +                hashtab[i] = NULL;
468 +                                        /* allocate scanline buffers */
469 +        scansize = sizeof(SCAN) + pxsiz*sizeof(COLR);
470 + #ifdef ALIGN
471 +        scansize = scansize+(sizeof(ALIGN)-1)) & ~(sizeof(ALIGN)-1);
472 + #endif
473 +        i = MAXSBUF / scansize;         /* compute number to allocate */
474 +        if (i > HSIZE)
475 +                i = HSIZE;
476 +        scan_buf = malloc(i*scansize);  /* get in one big chunk */
477 +        if (scan_buf == NULL)
478 +                memerr("scanline buffers");
479 +        ptr = (SCAN *)scan_buf;
480 +        freelist = NULL;                /* build our free list */
481 +        while (i-- > 0) {
482 +                ptr->y = -1;
483 +                ptr->lused = -1;
484 +                ptr->next = freelist;
485 +                freelist = ptr;
486 +                ptr = (SCAN *)((char *)ptr + scansize); /* beware of C bugs */
487 +        }
488 + }
489 +
490 +
491 + donescans()                             /* free up scanlines */
492 + {
493 +        free(scan_buf);
494 +        free((char *)scanpos);
495   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines