1 /*
2     Copyright (c) 2005-2021 Intel Corporation
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8         http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15 */
16 
17 /*
18     The original source for this example is
19     Copyright (c) 1994-2008 John E. Stone
20     All rights reserved.
21 
22     Redistribution and use in source and binary forms, with or without
23     modification, are permitted provided that the following conditions
24     are met:
25     1. Redistributions of source code must retain the above copyright
26        notice, this list of conditions and the following disclaimer.
27     2. Redistributions in binary form must reproduce the above copyright
28        notice, this list of conditions and the following disclaimer in the
29        documentation and/or other materials provided with the distribution.
30     3. The name of the author may not be used to endorse or promote products
31        derived from this software without specific prior written permission.
32 
33     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34     OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36     ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43     SUCH DAMAGE.
44 */
45 
46 #include <omp.h>
47 #include "machine.hpp"
48 #include "types.hpp"
49 #include "macros.hpp"
50 #include "vector.hpp"
51 #include "tgafile.hpp"
52 #include "trace.hpp"
53 #include "light.hpp"
54 #include "shade.hpp"
55 #include "camera.hpp"
56 #include "util.hpp"
57 #include "intersect.hpp"
58 #include "global.hpp"
59 #include "ui.hpp"
60 #include "tachyon_video.hpp"
61 
62 // shared but read-only so could be private too
63 static thr_parms *all_parms;
64 static scenedef scene;
65 static int startx;
66 static int stopx;
67 static int starty;
68 static int stopy;
69 static flt jitterscale;
70 static int totaly;
71 
render_one_pixel(int x,int y,unsigned int * local_mbox,unsigned int & serial,int startx,int stopx,int starty,int stopy)72 static color_t render_one_pixel(int x,
73                                 int y,
74                                 unsigned int *local_mbox,
75                                 unsigned int &serial,
76                                 int startx,
77                                 int stopx,
78                                 int starty,
79                                 int stopy) {
80     /* private vars moved inside loop */
81     ray primary, sample;
82     color col, avcol;
83     int R, G, B;
84     intersectstruct local_intersections;
85     int alias;
86     /* end private */
87 
88     primary = camray(&scene, x, y);
89     primary.intstruct = &local_intersections;
90     primary.flags = RT_RAY_REGULAR;
91 
92     serial++;
93     primary.serial = serial;
94     primary.mbox = local_mbox;
95     primary.maxdist = FHUGE;
96     primary.scene = &scene;
97     col = trace(&primary);
98 
99     serial = primary.serial;
100 
101     /* perform antialiasing if enabled.. */
102     if (scene.antialiasing > 0) {
103         for (alias = 0; alias < scene.antialiasing; alias++) {
104             serial++; /* increment serial number */
105             sample = primary; /* copy the regular primary ray to start with */
106             sample.serial = serial;
107 
108 #pragma omp critical
109             {
110                 sample.d.x += ((rand() % 100) - 50) / jitterscale;
111                 sample.d.y += ((rand() % 100) - 50) / jitterscale;
112                 sample.d.z += ((rand() % 100) - 50) / jitterscale;
113             }
114 
115             avcol = trace(&sample);
116 
117             serial = sample.serial; /* update our overall serial # */
118 
119             col.r += avcol.r;
120             col.g += avcol.g;
121             col.b += avcol.b;
122         }
123 
124         col.r /= (scene.antialiasing + 1.0);
125         col.g /= (scene.antialiasing + 1.0);
126         col.b /= (scene.antialiasing + 1.0);
127     }
128 
129     /* Handle overexposure and underexposure here... */
130     R = (int)(col.r * 255);
131     if (R > 255)
132         R = 255;
133     else if (R < 0)
134         R = 0;
135 
136     G = (int)(col.g * 255);
137     if (G > 255)
138         G = 255;
139     else if (G < 0)
140         G = 0;
141 
142     B = (int)(col.b * 255);
143     if (B > 255)
144         B = 255;
145     else if (B < 0)
146         B = 0;
147 
148     return video->get_color(R, G, B);
149 }
150 
parallel_thread(void)151 static void parallel_thread(void) {
152     // thread-local storage
153     unsigned int serial = 1;
154     unsigned int mboxsize = sizeof(unsigned int) * (max_objectid() + 20);
155     unsigned int *local_mbox = (unsigned int *)alloca(mboxsize);
156     memset(local_mbox, 0, mboxsize);
157 
158 #pragma omp for nowait schedule(runtime)
159     for (int y = starty; y < stopy; y++) {
160         if (!video->running)
161             continue;
162         drawing_area drawing(startx, totaly - y, stopx - startx, 1);
163         for (int x = startx; x < stopx; x++) {
164             color_t c = render_one_pixel(x, y, local_mbox, serial, startx, stopx, starty, stopy);
165             drawing.put_pixel(c);
166         }
167         video->next_frame();
168     }
169 }
170 
thread_trace(thr_parms * parms)171 void *thread_trace(thr_parms *parms) {
172     // shared but read-only so could be private too
173     all_parms = parms;
174     scene = parms->scene;
175     startx = parms->startx;
176     stopx = parms->stopx;
177     starty = parms->starty;
178     stopy = parms->stopy;
179     jitterscale = 40.0 * (scene.hres + scene.vres);
180     totaly = parms->scene.vres - 1;
181 
182 #pragma omp parallel
183     parallel_thread();
184 
185     return (nullptr);
186 }
187