ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RtraceSimulManager.h
Revision: 2.4
Committed: Wed Aug 2 00:04:31 2023 UTC (10 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4
Changes since 2.3: +12 -3 lines
Log Message:
feat: further fleshing out thread model

File Contents

# User Rev Content
1 greg 2.4 /* RCSid $Id: RtraceSimulManager.h,v 2.3 2023/07/31 23:14:02 greg Exp $ */
2 greg 2.1 /*
3     * RtraceSimulManager.h
4     *
5     * Rtrace simulation manager class declaration (along with base class)
6     * Enqueuing rays will block caller iff #rays >= ThreadsAvail()
7     * Reporting call-backs made from EnqueBundle() and FlushQueue()
8     *
9     * Created by Greg Ward on 11/10/22.
10     */
11    
12     #ifndef RtraceSimulManager_h
13     #define RtraceSimulManager_h
14    
15     #include "ray.h"
16    
17     extern char * octname; // global octree name
18    
19     /// Ray reporting callback method
20     typedef void RayReportCall(RAY *r, void *cd);
21    
22     /// Multi-threaded simulation manager base class
23     class RadSimulManager {
24     int nThreads; // number of active threads
25 greg 2.4 protected:
26     // Assign ray to subthread (fails if NThreads()<2)
27     bool SplitRay(RAY *r);
28 greg 2.1 public:
29     RadSimulManager(const char *octn = NULL) {
30     LoadOctree(octn);
31     nThreads = 1;
32     }
33     ~RadSimulManager() {
34     Cleanup();
35     }
36     /// Load octree and prepare renderer
37     bool LoadOctree(const char *octn);
38 greg 2.3 /// How many cores are there?
39     static int GetNCores();
40 greg 2.1 /// Set number of computation threads (0 => #cores)
41     int SetThreadCount(int nt = 0);
42     /// Check thread count (1 means no multi-threading)
43     int NThreads() const {
44     return nThreads;
45     }
46     /// How many threads are currently unoccupied?
47     int ThreadsAvailable() const;
48     /// Are we ready?
49     bool Ready() const {
50     return (octname && nsceneobjs > 0);
51     }
52 greg 2.4 /// Process a ray (in subthread), optional result
53     bool ProcessRay(RAY *r);
54     /// Wait for next result (or fail)
55     bool WaitResult(RAY *r);
56 greg 2.1 /// Close octree, free data, return status
57 greg 2.3 int Cleanup(bool everything = false);
58 greg 2.1 };
59    
60     /// Flags to control rendering operations
61     enum {RTdoFIFO=1, RTtraceSources=2, RTlimDist=4, RTimmIrrad=8, RTmask=15};
62    
63     /// rtrace-like simulation manager (at most one such object)
64     class RtraceSimulManager : public RadSimulManager {
65     RayReportCall * cookedCall; // callback for cooked primary rays
66     void * ccData; // client data for cooked primary rays
67     RayReportCall * traceCall; // call for every ray in tree
68     void * tcData; // client data for traced rays
69     int curFlags; // current operating flags
70     // Call-back for global ray-tracing context
71     static void RTracer(RAY *r);
72     // Check for changes to render flags, etc.
73     bool UpdateMode();
74     protected:
75 greg 2.4 // Add a ray result to FIFO, flushing what we can
76     int QueueResult(const RAY &ra);
77 greg 2.1 RNUMBER lastRayID; // last ray ID assigned
78     public:
79     int rtFlags; // operation (RT*) flags
80     RtraceSimulManager(RayReportCall *cb = NULL, void *cd = NULL,
81     const char *octn = NULL) : RadSimulManager(octn) {
82     lastRayID = 0;
83     rtFlags = curFlags = 0;
84     SetCookedCall(cb, cd);
85     traceCall = NULL; tcData = NULL;
86     }
87 greg 2.3 ~RtraceSimulManager() {
88     FlushQueue();
89     }
90 greg 2.2 /// Set number of computation threads (0 => #cores)
91     int SetThreadCount(int nt = 0) {
92     if (nt <= 0) nt = GetNCores();
93     if (nt == NThreads()) return nt;
94     FlushQueue();
95     return RadSimulManager::SetThreadCount(nt);
96     }
97 greg 2.1 /// Add ray bundle to queue w/ optional 1st ray ID
98     int EnqueueBundle(const FVECT orig_direc[], int n,
99     RNUMBER rID0 = 0);
100     /// Enqueue a single ray w/ optional ray ID
101     bool EnqueueRay(const FVECT org, const FVECT dir,
102     RNUMBER rID = 0) {
103     if (dir == org+1)
104 greg 2.3 return(EnqueueBundle((const FVECT *)org, 1, rID) > 0);
105 greg 2.1 FVECT orgdir[2];
106     VCOPY(orgdir[0], org); VCOPY(orgdir[1], dir);
107 greg 2.3 return(EnqueueBundle(orgdir, 1, rID) > 0);
108 greg 2.1 }
109     /// Set/change cooked ray callback & FIFO flag
110     void SetCookedCall(RayReportCall *cb, void *cd = NULL) {
111     if (cookedCall && (cookedCall != cb) | (ccData != cd))
112     FlushQueue();
113     cookedCall = cb;
114     ccData = cd;
115     }
116     /// Set/change trace callback
117     void SetTraceCall(RayReportCall *cb, void *cd = NULL) {
118     traceCall = cb;
119     tcData = cd;
120     }
121     /// Are we ready?
122     bool Ready() const {
123     return (cookedCall != NULL) | (traceCall != NULL) &&
124     RadSimulManager::Ready();
125     }
126 greg 2.4 /// Finish pending rays and complete callbacks (return #sent)
127     int FlushQueue();
128 greg 2.1 /// Close octree, free data, return status
129 greg 2.3 int Cleanup(bool everything = false) {
130 greg 2.1 SetCookedCall(NULL);
131     SetTraceCall(NULL);
132     rtFlags = 0;
133     UpdateMode();
134     lastRayID = 0;
135 greg 2.3 return RadSimulManager::Cleanup(everything);
136 greg 2.1 }
137     };
138    
139     /// Determine if vector is all zeroes
140     inline bool
141     IsZeroVec(const FVECT vec)
142     {
143     return (vec[0] == 0.0) & (vec[1] == 0.0) & (vec[2] == 0.0);
144     }
145    
146     #endif /* RtraceSimulManager_h */