ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RpictSimulManager.h
Revision: 2.3
Committed: Sun Aug 18 17:24:48 2024 UTC (8 months, 1 week ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +2 -2 lines
Log Message:
perf(rxpict): Improved adaptive sampling at bottom of frame

File Contents

# Content
1 /* RCSid $Id: RpictSimulManager.h,v 2.2 2024/08/18 00:37:13 greg Exp $ */
2 /*
3 * RpictSimulManager.h
4 *
5 * Rpict simulation manager class declaration
6 *
7 * Created by Greg Ward on 07/11/2024.
8 */
9
10 #ifndef RpictSimulManager_h
11 #define RpictSimulManager_h
12
13 #include "RtraceSimulManager.h"
14 #include "view.h"
15 #include "depthcodec.h"
16 #include "abitmap.h"
17
18 /// Data type flags for pixel access and output
19 enum RenderDataType {
20 RDTnone=0,
21 RDTscolor=0x1, RDTrgb=0x2, RDTxyz=0x3, RDTscolr=0x4, RDTrgbe=0x5, RDTxyze=0x6,
22 RDTcolorM=0x7,
23 RDTdfloat=0x8, RDTdshort=0x10,
24 RDTdepthM=0x18
25 };
26
27 #define RDTcolorT(f) RenderDataType((f) & RDTcolorM)
28 #define RDTdepthT(f) RenderDataType((f) & RDTdepthM)
29 #define RDTcommonE(f) (RDTcolorT(f) >= RDTscolr)
30 #define RDTnewCT(f,c) RenderDataType((f) & ~RDTcolorM | (c) & RDTcolorM)
31 #define RDTnewDT(f,d) RenderDataType((f) & ~RDTdepthM | (d) & RDTdepthM)
32
33 /// Pixel accessor (read/write to caller's buffer with possible conversion)
34 class PixelAccess {
35 union {
36 COLORV * f;
37 COLRV * b;
38 } pbase; // pixel base pointer
39 union {
40 float * f;
41 short * s;
42 } dbase; // depth base pointer
43 long rowStride; // # values to next y position
44 int dtyp; // data type flags
45 RGBPRIMP primp; // color primaries if tristimulus
46 const COLORV * CF3(int x, int y) const {
47 return pbase.f + (rowStride*y + x)*3;
48 }
49 COLORV * CF3(int x, int y) {
50 return pbase.f + (rowStride*y + x)*3;
51 }
52 const COLRV * CB3(int x, int y) const {
53 return pbase.b + (rowStride*y + x)*4;
54 }
55 COLRV * CB3(int x, int y) {
56 return pbase.b + (rowStride*y + x)*4;
57 }
58 const COLORV * SCF(int x, int y) const {
59 return pbase.f + (rowStride*y + x)*NCSAMP;
60 }
61 COLORV * SCF(int x, int y) {
62 return pbase.f + (rowStride*y + x)*NCSAMP;
63 }
64 const COLRV * SCB(int x, int y) const {
65 return pbase.b + (rowStride*y + x)*(NCSAMP+1);
66 }
67 COLRV * SCB(int x, int y) {
68 return pbase.b + (rowStride*y + x)*(NCSAMP+1);
69 }
70 public:
71 double refDepth; // reference depth
72 PixelAccess() {
73 refDepth = 1.;
74 Init();
75 }
76 PixelAccess(COLORV *rp, int ystride, float *zp=NULL) {
77 refDepth = 1.;
78 Init(rp, ystride, zp);
79 }
80 PixelAccess(COLRV *bp, int ystride, float *zp=NULL) {
81 refDepth = 1.;
82 Init(bp, ystride, zp);
83 }
84 PixelAccess(COLRV *bp, int ystride, short *dp) {
85 refDepth = 1.;
86 Init(bp, ystride, dp);
87 }
88 void Init() {
89 pbase.f = NULL; dbase.f = NULL;
90 rowStride = 0;
91 primp = NULL;
92 dtyp = 0;
93 }
94 /// Initializers default to rendering color space
95 void Init(COLORV *rp, int ystride, float *zp=NULL) {
96 pbase.f = rp; dbase.f = zp;
97 rowStride = ystride;
98 if (NCSAMP > 3) {
99 dtyp = RDTscolor; primp = NULL;
100 } else {
101 dtyp = RDTrgb; primp = stdprims;
102 }
103 if (zp) dtyp |= RDTdfloat;
104 }
105 void Init(COLRV *bp, int ystride, float *zp=NULL) {
106 pbase.b = bp; dbase.f = zp;
107 rowStride = ystride;
108 if (NCSAMP > 3) {
109 dtyp = RDTscolr; primp = NULL;
110 } else {
111 dtyp = RDTrgbe; primp = stdprims;
112 }
113 if (zp) dtyp |= RDTdfloat;
114 }
115 void Init(COLRV *bp, int ystride, short *dp) {
116 pbase.b = bp; dbase.s = dp;
117 rowStride = ystride;
118 if (NCSAMP > 3) {
119 dtyp = RDTscolr; primp = NULL;
120 } else {
121 dtyp = RDTrgbe; primp = stdprims;
122 }
123 if (dp) dtyp |= RDTdshort;
124 }
125 /// Set color space after non-empty initialization
126 bool SetColorSpace(RenderDataType cs, RGBPRIMP pr=NULL);
127 /// Get color space
128 RenderDataType ColorSpace() const {
129 return RDTcolorT(dtyp);
130 }
131 /// Get color primaries (NULL if spectral)
132 RGBPRIMP Primaries() const {
133 return primp;
134 }
135 /// Number of represented color/spectral components
136 int NC() const {
137 switch (ColorSpace()) {
138 case RDTrgb: case RDTrgbe:
139 case RDTxyz: case RDTxyze:
140 return 3;
141 case RDTscolor: case RDTscolr:
142 return NCSAMP;
143 default:;
144 }
145 return 0;
146 }
147 /// Get depth type
148 RenderDataType DepthType() const {
149 return RDTdepthT(dtyp);
150 }
151 /// Get row stride
152 long GetRowStride() const {
153 return rowStride;
154 }
155 /// Assign a pixel value (& depth) from rendered ray value
156 bool SetPixel(int x, int y, const RAY *rp);
157 /// Assign pixel color (& depth) -- may re-represent either/both
158 bool SetPixel(int x, int y, const COLORV *pv, float z=0) {
159 if (NC() == 3) {
160 if (RDTcommonE(dtyp))
161 setcolr(CB3(x,y), pv[RED], pv[GRN], pv[BLU]);
162 else
163 copycolor(CF3(x,y), pv);
164 } else if (RDTcommonE(dtyp))
165 scolor_scolr(SCB(x,y), pv);
166 else
167 copyscolor(SCF(x,y), pv);
168 if (RDTdepthT(dtyp) == RDTdfloat)
169 dbase.f[rowStride*y + x] = z;
170 else if (RDTdepthT(dtyp) == RDTdshort)
171 dbase.s[rowStride*y + x] = depth2code(z, refDepth);
172 return true;
173 }
174 /// Retrieve pixel color (& depth) -- may convert either/both
175 bool GetPixel(int x, int y, COLORV *pv, float *zp=NULL) const {
176 if (NC() == 3) {
177 if (RDTcommonE(dtyp))
178 colr_color(pv, CB3(x,y));
179 else
180 copycolor(pv, CF3(x,y));
181 } else if (RDTcommonE(dtyp))
182 scolr_scolor(pv, SCB(x,y));
183 else
184 copyscolor(pv, SCF(x,y));
185 if (!zp) return true;
186 if (RDTdepthT(dtyp) == RDTdfloat)
187 *zp = dbase.f[rowStride*y + x];
188 else if (RDTdepthT(dtyp) == RDTdshort)
189 *zp = code2depth(dbase.s[rowStride*y + x], refDepth);
190 else
191 *zp = .0f;
192 return true;
193 }
194 /// Copy pixel from one location to another (no conversion)
195 bool CopyPixel(int dx, int dy, int sx, int sy) {
196 if ((dx==sx) & (dy==sy)) return true;
197 const int nc = NC();
198 if (nc == 3) {
199 if (RDTcommonE(dtyp))
200 copycolr(CB3(dx,dy), CB3(sx,sy));
201 else
202 copycolor(CF3(dx,dy), CF3(sx,sy));
203 } else if (RDTcommonE(dtyp))
204 copyscolr(SCB(dx,dy), SCB(sx,sy));
205 else
206 copyscolor(SCF(dx,dy), SCF(sx,sy));
207 switch (RDTdepthT(dtyp)) {
208 case RDTdfloat:
209 dbase.f[rowStride*dy + dx] =
210 dbase.f[rowStride*sy + sx];
211 break;
212 case RDTdshort:
213 dbase.s[rowStride*dy + dx] =
214 dbase.s[rowStride*sy + sx];
215 break;
216 default:;
217 }
218 return true;
219 }
220 };
221
222 /// Call-back function for progress reporting
223 typedef void ProgReportCB(double pct);
224
225 /// rpict-like simulation manager (at most one such object)
226 class RpictSimulManager : protected RtraceSimulManager {
227 static RayReportCall RtCall; // our callback for cooked rays
228 VIEW vw; // frame view
229 VIEW pvw; // previous view
230 int hvres[2]; // overall picture dimensions
231 int tgsize[2]; // tile grid size
232 int thvres[2]; // tile dimensions
233 VIEW tvw, ptvw; // this tile's view (& previous)
234 PixelAccess pacc; // pixel accessor
235 char dunit[32]; // depth with units (if any)
236 ABitMap2 doneMap; // which tile pixels are done
237 COLORV * barPix; // current render bar pixels
238 float * barDepth; // current render bar depths
239 bool SetTile(const int ti[2]);
240 bool RenderRect();
241 bool ComputePixel(int x, int y);
242 bool BelowSampThresh(int x, int y, const int noff[4][2]) const;
243 void FillSquare(const int x, const int y, const int noff[4][2]);
244 void NewBar(int ht = 0);
245 bool LowerBar(int v, int ytop);
246 bool RenderBelow(int ytop, const int vstep, FILE *pfp,
247 const int dt, FILE *dfp=NULL);
248 public:
249 ProgReportCB * prCB; // progress report call-back
250 RGBPRIMP prims; // output primaries (NULL if spectral)
251 int frameNo; // frame number (0 if not sequence)
252 RpictSimulManager(const char *octn = NULL) :
253 RtraceSimulManager(RtCall, this, octn) {
254 tvw.type = vw.type = 0;
255 hvres[0] = hvres[1] = 0;
256 thvres[0] = thvres[1] = 0;
257 pacc.refDepth = 1.; dunit[0] = '1'; dunit[1] = '\0';
258 barPix = NULL; barDepth = NULL;
259 prCB = NULL;
260 prims = NULL;
261 frameNo = 0;
262 }
263 ~RpictSimulManager() {
264 NewBar();
265 }
266 /// Load octree and prepare renderer
267 bool LoadOctree(const char *octn) {
268 return RtraceSimulManager::LoadOctree(octn);
269 }
270 /// Prepare header from previous input (or clear)
271 bool NewHeader(const char *inspec=NULL) {
272 return RtraceSimulManager::NewHeader(inspec);
273 }
274 /// Add a string to header (adds newline if none)
275 bool AddHeader(const char *str) {
276 return RtraceSimulManager::AddHeader(str);
277 }
278 /// Append program line to header
279 bool AddHeader(int ac, char *av[]) {
280 return RtraceSimulManager::AddHeader(ac, av);
281 }
282 /// Get header lines if any
283 const char * GetHeader() const {
284 return RtraceSimulManager::GetHeader();
285 }
286 /// Set number of computation threads (0 => #cores)
287 int SetThreadCount(int nt = 0) {
288 return RtraceSimulManager::SetThreadCount(nt);
289 }
290 /// Check thread count (1 means no multi-threading)
291 int NThreads() const {
292 return RtraceSimulManager::NThreads();
293 }
294 /// How many threads are currently unoccupied?
295 int ThreadsAvailable() const {
296 return RtraceSimulManager::ThreadsAvailable();
297 }
298 /// Are we ready?
299 bool Ready() const {
300 return RtraceSimulManager::Ready();
301 }
302 /// Assign reference depth string (e.g., "2.5/meter")
303 bool SetReferenceDepth(const char *dstr) {
304 double dref = atof(dstr);
305 if (dref <= .0) return false;
306 strlcpy(dunit, dstr, sizeof(dunit));
307 pacc.refDepth = dref;
308 return true;
309 }
310 bool SetReferenceDepth(double dref, const char *unit=NULL) {
311 if (dref <= .0) return false;
312 if (unit) sprintf(dunit, "%g/%s", dref, unit);
313 else sprintf(dunit, "%g", dref);
314 pacc.refDepth = dref;
315 return true;
316 }
317 /// Return reference depth
318 double GetReferenceDepth(char *du=NULL) const {
319 if (du) strcpy(du, dunit);
320 return pacc.refDepth;
321 }
322 /// Set up rendering frame (call after octree loaded)
323 /// Overall dimensions may be adjusted for view,
324 /// optional pixel aspect ratio and tile grid
325 /// Increments frameNo if >0
326 bool NewFrame(const VIEW &v, int xydim[2], double *ap=NULL,
327 const int *tgrid=NULL);
328 /// Get current picture width
329 int GetWidth() const {
330 return hvres[0];
331 }
332 /// Get current picture height
333 int GetHeight() const {
334 return hvres[1];
335 }
336 /// Tile width
337 int TWidth() const {
338 return thvres[0];
339 }
340 /// Tile height
341 int THeight() const {
342 return thvres[1];
343 }
344 /// Render the specified tile in frame
345 /// Tile pixels are contiguous unless ystride != 0
346 /// Tiles numbered from lower-left at (0,0)
347 /// Pixel type influenced by this->prims assignment
348 bool RenderTile(COLORV *rp, int ystride=0, float *zp=NULL,
349 const int *tile=NULL);
350 /// Same but store as common-exponent COLR or SCOLR
351 bool RenderTile(COLRV *bp, int ystride=0, float *zp=NULL,
352 const int *tile=NULL);
353 /// Same but also use 16-bit encoded depth buffer
354 bool RenderTile(COLRV *bp, int ystride, short *dp,
355 const int *tile=NULL);
356 /// Render and write a frame to the named file
357 /// Include any header lines set prior to call
358 /// Picture file must not already exist
359 /// Write pixels to stdout if !pfname
360 /// Write depth to a command if dfname[0]=='!'
361 RenderDataType RenderFrame(const char *pfname,
362 RenderDataType dt=RDTrgbe,
363 const char *dfname=NULL);
364 /// Resume partially finished rendering
365 /// Picture file must exist with valid header
366 RenderDataType ResumeFrame(const char *pfname,
367 const char *dfname=NULL);
368 /// Close octree, free data, return status
369 int Cleanup(bool everything = false) {
370 NewBar();
371 tvw.type = vw.type = 0;
372 hvres[0] = hvres[1] = 0;
373 thvres[0] = thvres[1] = 0;
374 prims = NULL;
375 frameNo = 0;
376 return RtraceSimulManager::Cleanup(everything);
377 }
378 };
379
380 #endif /* RpictSimulManager_h */