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

Comparing ray/src/rt/rayfifo.c (file contents):
Revision 2.2 by greg, Sat Dec 12 19:01:00 2009 UTC vs.
Revision 2.6 by greg, Wed May 2 20:42:21 2018 UTC

# Line 20 | Line 20 | static const char RCSid[] = "$Id$";
20   *  is desired, a negative value may be returned.
21   *
22   *  The ray_fifo_in() call takes a ray that has been initialized in
23 < *  the same manner as for the ray_trace() call, i.e., the origin,
24 < *  direction, and maximum length have been assigned. The ray number
25 < *  will be set according to the number of rays traced since the
23 > *  the same manner as for the ray_pqueue() call, i.e., rayorigin()
24 > *  has been called and the origin, direction and maximum distance
25 > *  have all been assigned.  However, the ray number will be reset
26 > *  by ray_fifo_in() according to the number of rays traced since the
27   *  last call to ray_fifo_flush().  This final call completes all
28   *  pending ray calculations and frees the FIFO buffer.  If any of
29   *  the automatic calls to the ray_fifo_out callback return a
# Line 35 | Line 36 | static const char RCSid[] = "$Id$";
36   #include  "ray.h"
37   #include  <string.h>
38  
39 + #ifndef MAXFIFO
40 + #define MAXFIFO         4096                    /* clear FIFO past this */
41 + #endif
42 +
43   int             (*ray_fifo_out)(RAY *r) = NULL; /* ray output callback */
44  
45   static RAY      *r_fifo_buf = NULL;             /* circular FIFO out buffer */
46   static int      r_fifo_len = 0;                 /* allocated FIFO length */
47   static RNUMBER  r_fifo_start = 1;               /* first awaited ray */
48   static RNUMBER  r_fifo_end = 1;                 /* one past FIFO last */
49 + static RNUMBER  r_fifo_next = 1;                /* next ray assignment */
50  
51   #define r_fifo(rn)      (&r_fifo_buf[(rn)&(r_fifo_len-1)])
52  
# Line 53 | Line 59 | ray_fifo_growbuf(void) /* double buffer size (or set t
59          int     i;
60  
61          if (r_fifo_buf == NULL)
62 <                r_fifo_len = 1<<4;
62 >                r_fifo_len = 1<<5;              /* must be power of two */
63          else
64                  r_fifo_len <<= 1;
65                                                  /* allocate new */
# Line 79 | Line 85 | ray_fifo_push(         /* send finished ray to output (or que
85  
86          if (ray_fifo_out == NULL)
87                  error(INTERNAL, "ray_fifo_out is NULL");
88 <        if ((r->rno < r_fifo_start) | (r->rno >= r_fifo_end))
89 <                error(INTERNAL, "unexpected ray number in ray_fifo_push");
88 >        if ((r->rno < r_fifo_start) | (r->rno >= r_fifo_next))
89 >                error(INTERNAL, "unexpected ray number in ray_fifo_push()");
90  
85        if (r->rno - r_fifo_start >= r_fifo_len)
86                ray_fifo_growbuf();             /* need more space */
87
91          if (r->rno > r_fifo_start) {            /* insert into output queue */
92 +                while (r->rno - r_fifo_start >= r_fifo_len)
93 +                        ray_fifo_growbuf();     /* need more space */
94                  *r_fifo(r->rno) = *r;
95 +                if (r->rno >= r_fifo_end)
96 +                        r_fifo_end = r->rno + 1;
97                  return(0);
98          }
99                          /* r->rno == r_fifo_start, so transfer ray(s) */
100          do {
101 <                if ((rv = (*ray_fifo_out)(r)) < 0)
101 >                rv = (*ray_fifo_out)(r);
102 >                r->rno = 0;                     /* flag this entry complete */
103 >                if (rv < 0)
104                          return(-1);
105                  nsent += rv;
106                  if (++r_fifo_start < r_fifo_end)
107                          r = r_fifo(r_fifo_start);
108 +                else if (r_fifo_start > r_fifo_end)
109 +                        r_fifo_end = r_fifo_start;
110          } while (r->rno == r_fifo_start);
111  
112          return(nsent);
# Line 107 | Line 118 | ray_fifo_in(           /* add ray to FIFO */
118          RAY     *r
119   )
120   {
121 <        int     rv, rval = 0;
121 >        static int      incall = 0;             /* prevent recursion */
122 >        int             rv, rval = 0;
123  
124 <        if (r_fifo_start >= 1L<<30) {           /* reset our counter */
124 >        if (incall++)
125 >                error(INTERNAL, "recursive call to ray_fifo_in()");
126 >
127 >                                                /* need to reset our FIFO? */
128 >        if ((r_fifo_start >= 1L<<30) | (r_fifo_len > MAXFIFO)) {
129                  if ((rv = ray_fifo_flush()) < 0)
130 <                        return(-1);
130 >                        {--incall; return(-1);}
131                  rval += rv;
132          }
133                                                  /* queue ray */
134 <        rayorigin(r, PRIMARY, NULL, NULL);
119 <        r->rno = r_fifo_end++;
134 >        r->rno = r_fifo_next++;
135          if ((rv = ray_pqueue(r)) < 0)
136 <                return(-1);
136 >                {--incall; return(-1);}
137  
138          if (!rv)                                /* no result this time? */
139 <                return(rval);
139 >                {--incall; return(rval);}
140          
141          do {                                    /* else send/queue result */
142                  if ((rv = ray_fifo_push(r)) < 0)
143 <                        return(-1);
143 >                        {--incall; return(-1);}
144                  rval += rv;
145  
146          } while (ray_presult(r, -1) > 0);       /* empty in-core queue */
147  
148 <        return(rval);
148 >        --incall; return(rval);
149   }
150  
151  
# Line 144 | Line 159 | ray_fifo_flush(void)   /* flush everything and release b
159                          (rv = ray_fifo_push(&myRay)) >= 0)
160                  rval += rv;
161  
162 <        if (rv < 0)                             /* check for error */
162 >        if (rv < 0)                             /* check for exception */
163                  return(-1);
164  
165          if (r_fifo_start != r_fifo_end)
166 <                error(INTERNAL, "could not empty queue in ray_fifo_flush");
166 >                error(INTERNAL, "could not empty queue in ray_fifo_flush()");
167  
168 <        free(r_fifo_buf);
169 <        r_fifo_buf = NULL;
170 <        r_fifo_len = 0;
171 <        r_fifo_end = r_fifo_start = 1;
168 >        if (r_fifo_buf != NULL) {
169 >                free(r_fifo_buf);
170 >                r_fifo_buf = NULL; r_fifo_len = 0;
171 >        }
172 >        r_fifo_next = r_fifo_end = r_fifo_start = 1;
173  
174          return(rval);
175   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines