1 //******************************************************************************
2 ///
3 /// @file backend/control/scene.h
4 ///
5 /// @todo   What's in here?
6 ///
7 /// @copyright
8 /// @parblock
9 ///
10 /// Persistence of Vision Ray Tracer ('POV-Ray') version 3.8.
11 /// Copyright 1991-2021 Persistence of Vision Raytracer Pty. Ltd.
12 ///
13 /// POV-Ray is free software: you can redistribute it and/or modify
14 /// it under the terms of the GNU Affero General Public License as
15 /// published by the Free Software Foundation, either version 3 of the
16 /// License, or (at your option) any later version.
17 ///
18 /// POV-Ray is distributed in the hope that it will be useful,
19 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
20 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 /// GNU Affero General Public License for more details.
22 ///
23 /// You should have received a copy of the GNU Affero General Public License
24 /// along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 ///
26 /// ----------------------------------------------------------------------------
27 ///
28 /// POV-Ray is based on the popular DKB raytracer version 2.12.
29 /// DKBTrace was originally written by David K. Buck.
30 /// DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
31 ///
32 /// @endparblock
33 ///
34 //------------------------------------------------------------------------------
35 // SPDX-License-Identifier: AGPL-3.0-or-later
36 //******************************************************************************
37 
38 #ifndef POVRAY_BACKEND_SCENE_H
39 #define POVRAY_BACKEND_SCENE_H
40 
41 // Module config header file must be the first file included within POV-Ray unit header files
42 #include "backend/configbackend.h"
43 
44 // Standard C++ header files
45 #include <map>
46 #include <string>
47 #include <vector>
48 
49 // Boost header files
50 #if POV_MULTITHREADED
51 #include <boost/thread.hpp>
52 #endif
53 
54 // POV-Ray header files (core module)
55 #include "core/scene/tracethreaddata.h"
56 
57 // POV-Ray header files (backend module)
58 #include "backend/control/renderbackend.h"
59 #include "backend/scene/backendscenedata.h"
60 #include "backend/support/taskqueue.h"
61 
62 namespace pov
63 {
64 
65 using namespace pov_base;
66 
67 class View;
68 
69 /// Class governing the rendering of a scene.
70 ///
71 /// @todo   Change the class name into something more expressive.
72 ///
73 class Scene
74 {
75     public:
76         /**
77          *  Create a new POV-Ray scene. The scene is created with all
78          *  default values and it empty. Only after a scene file has
79          *  been parsed views can be created. Each scene may only be
80          *  parsed once, and it is assumed that the scene structure
81          *  remains static after parsing is complete. However, for
82          *  each scene,once parsed, many views many be created, and
83          *  each view may specify different render quality, size and
84          *  camera parameters. This limitation may be lifted in the
85          *  future to better support animationss and for example
86          *  motion blur, but this can only be supported in POV-Ray
87          *  4.0 when all the rendering code is rewritten!
88          *  @param  backendAddr     Address of the backend that owns this scene.
89          *  @param  frontendAddr    Address of the frontend that owns this scene.
90          *  @param  sid             Id of this scene to include with
91          *                          POVMS messages sent to the frontend.
92          */
93         Scene(POVMSAddress backendAddr, POVMSAddress frontendAddr, RenderBackend::SceneId sid);
94 
95         /**
96          *  Destructor. Parsing will be stopped as necessary.
97          */
98         ~Scene();
99 
100         /**
101          *  Start parsing a POV-Ray scene. Be aware that this
102          *  method is asynchronous! Threads will be started
103          *  to perform the parsing and this method will return.
104          *  The frontend is notified by messages of the state
105          *  of parsing and all warnings and errors found.
106          *  Options shall be in a kPOVObjectClass_ParserOptions
107          *  POVMS obect, which is created when parsing the INI
108          *  file or command line in the frontend.
109          *  @param  parseOptions    Options to use for parsing.
110          */
111         void StartParser(POVMS_Object& parseOptions);
112 
113         /**
114          *  Stop parsing a POV-Ray scene. Parsing may take a few
115          *  seconds to stop. Internally stopping is performed by
116          *  throwing an exception at well-defined points.
117          *  If parsing is not in progress, no action is taken.
118          */
119         void StopParser();
120 
121         /**
122          *  Pause parsing. Parsing may take a few seconds to
123          *  pause. Internally pausing is performed by checking
124          *  flag at well-defined points, and if it is true, a
125          *  loop will repeatedly set the parser thread to sleep
126          *  for a few milliseconds until the pause flag is
127          *  cleared again or parsing is stopped.
128          *  If parsing is not in progress, no action is taken.
129          */
130         void PauseParser();
131 
132         /**
133          *  Resume parsing that has previously been stopped.
134          *  If parsing is not paussed, no action is taken.
135          */
136         void ResumeParser();
137 
138         /**
139          *  Determine if any parser thread is currently running.
140          *  @return                 True if running, false otherwise.
141          */
142         bool IsParsing();
143 
144         /**
145          *  Determine if parsing is paused.
146          *  @return                 True if paused, false otherwise.
147          */
148         bool IsPaused();
149 
150         /**
151          *  Determine if a previously run parser thread failed.
152          *  @return                 True if failed, false otherwise.
153          */
154         bool Failed();
155 
156         /**
157          *  Create a new view of a parsed scene. Note that this method
158          *  may only be called after a scene has been parsed successfully.
159          *  Note that the view does remain valid even if the scene that
160          *  created it is deleted!
161          *  @param  width           Width of the view in pixels.
162          *  @param  height          Height of the view in pixels.
163          *  @param  vid             Id of this view to include with
164          *                          POVMS messages sent to the frontend.
165          *  @return                 New view bound to the scene's data.
166          */
167         shared_ptr<View> NewView(unsigned int width, unsigned int height, RenderBackend::ViewId vid);
168 
169         /**
170          *  Get the POVMS frontend address to send messages to the frontend.
171          *  @return                 Frontend address.
172          */
GetFrontendAddress()173         POVMSAddress GetFrontendAddress() const { return sceneData->frontendAddress; }
174 
175         /**
176          *  Get the current parser statistics for the scene.
177          *  Note that this will query each thread, compute the total
178          *  and return it.
179          *  @param  stats           On return, the current statistics.
180          */
181         void GetStatistics(POVMS_Object& stats);
182     private:
183         /// running and pending parser tasks for this scene
184         TaskQueue parserTasks;
185         /// scene thread data (e.g. statistics)
186         vector<TraceThreadData *> sceneThreadData;
187         /// scene data
188         shared_ptr<BackendSceneData> sceneData;
189         /// stop request flag
190         bool stopRequsted;
191         /// parser control thread
192         boost::thread *parserControlThread;
193 
194         /**
195          *  Send the parser statistics upon completion of a parsing.
196          *  @param   taskq          The task queue that executed this method.
197          */
198         void SendStatistics(TaskQueue& taskq);
199 
200         /**
201          *  Send done message (including compatibility data) after parsing.
202          *  @param   taskq          The task queue that executed this method.
203          */
204         void SendDoneMessage(TaskQueue& taskq);
205 
206         /**
207          *  Thread controlling the parser task queue.
208          */
209         void ParserControlThread();
210 };
211 
212 } // end of namespace
213 
214 #endif // POVRAY_BACKEND_SCENE_H
215