graphicsEngine.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. // Filename: graphicsEngine.h
  2. // Created by: drose (24Feb02)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #ifndef GRAPHICSENGINE_H
  15. #define GRAPHICSENGINE_H
  16. #include "pandabase.h"
  17. #include "graphicsWindow.h"
  18. #include "graphicsBuffer.h"
  19. #include "frameBufferProperties.h"
  20. #include "graphicsThreadingModel.h"
  21. #include "sceneSetup.h"
  22. #include "pointerTo.h"
  23. #include "thread.h"
  24. #include "pmutex.h"
  25. #include "reMutex.h"
  26. #include "lightReMutex.h"
  27. #include "conditionVar.h"
  28. #include "pStatCollector.h"
  29. #include "pset.h"
  30. #include "ordered_vector.h"
  31. #include "indirectLess.h"
  32. #include "loader.h"
  33. #include "referenceCount.h"
  34. class Pipeline;
  35. class DisplayRegion;
  36. class GraphicsPipe;
  37. class FrameBufferProperties;
  38. class Texture;
  39. ////////////////////////////////////////////////////////////////////
  40. // Class : GraphicsEngine
  41. // Description : This class is the main interface to controlling the
  42. // render process. There is typically only one
  43. // GraphicsEngine in an application, and it synchronizes
  44. // rendering to all all of the active windows; although
  45. // it is possible to have multiple GraphicsEngine
  46. // objects if multiple synchronicity groups are
  47. // required.
  48. //
  49. // The GraphicsEngine is responsible for managing the
  50. // various cull and draw threads. The application
  51. // simply calls engine->render_frame() and considers it
  52. // done.
  53. ////////////////////////////////////////////////////////////////////
  54. class EXPCL_PANDA_DISPLAY GraphicsEngine : public ReferenceCount {
  55. PUBLISHED:
  56. GraphicsEngine(Pipeline *pipeline = NULL);
  57. ~GraphicsEngine();
  58. void set_threading_model(const GraphicsThreadingModel &threading_model);
  59. GraphicsThreadingModel get_threading_model() const;
  60. INLINE const ReMutex &get_render_lock() const;
  61. INLINE void set_auto_flip(bool auto_flip);
  62. INLINE bool get_auto_flip() const;
  63. INLINE void set_portal_cull(bool value);
  64. INLINE bool get_portal_cull() const;
  65. INLINE void set_default_loader(Loader *loader);
  66. INLINE Loader *get_default_loader() const;
  67. GraphicsOutput *make_output(GraphicsPipe *pipe,
  68. const string &name, int sort,
  69. const FrameBufferProperties &fb_prop,
  70. const WindowProperties &win_prop,
  71. int flags, GraphicsStateGuardian *gsg = NULL,
  72. GraphicsOutput *host = NULL);
  73. // Syntactic shorthand versions of make_output
  74. INLINE GraphicsOutput *make_buffer(GraphicsOutput *host,
  75. const string &name, int sort,
  76. int x_size, int y_size);
  77. INLINE GraphicsOutput *make_buffer(GraphicsStateGuardian *gsg,
  78. const string &name, int sort,
  79. int x_size, int y_size);
  80. INLINE GraphicsOutput *make_parasite(GraphicsOutput *host,
  81. const string &name, int sort,
  82. int x_size, int y_size);
  83. bool remove_window(GraphicsOutput *window);
  84. void remove_all_windows();
  85. void reset_all_windows(bool swapchain);
  86. bool is_empty() const;
  87. int get_num_windows() const;
  88. GraphicsOutput *get_window(int n) const;
  89. MAKE_SEQ(get_windows, get_num_windows, get_window);
  90. BLOCKING void render_frame();
  91. BLOCKING void open_windows();
  92. BLOCKING void sync_frame();
  93. BLOCKING void ready_flip();
  94. BLOCKING void flip_frame();
  95. bool extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg);
  96. static GraphicsEngine *get_global_ptr();
  97. public:
  98. enum ThreadState {
  99. TS_wait,
  100. TS_do_frame,
  101. TS_do_flip,
  102. TS_do_release,
  103. TS_do_windows,
  104. TS_terminate,
  105. TS_done
  106. };
  107. void texture_uploaded(Texture *tex);
  108. public:
  109. static void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
  110. GraphicsStateGuardian *gsg, Thread *current_thread);
  111. private:
  112. typedef ov_set< PT(GraphicsOutput), IndirectLess<GraphicsOutput> > Windows;
  113. typedef pset< PT(GraphicsStateGuardian) > GSGs;
  114. static bool scene_root_func(const PandaNode *node);
  115. bool is_scene_root(const PandaNode *node);
  116. void set_window_sort(GraphicsOutput *window, int sort);
  117. void cull_and_draw_together(const Windows &wlist, Thread *current_thread);
  118. void cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
  119. Thread *current_thread);
  120. void cull_to_bins(const Windows &wlist, Thread *current_thread);
  121. void cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
  122. void draw_bins(const Windows &wlist, Thread *current_thread);
  123. void draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
  124. void make_contexts(const Windows &wlist, Thread *current_thread);
  125. void process_events(const Windows &wlist, Thread *current_thread);
  126. void ready_flip_windows(const Windows &wlist, Thread *current_thread);
  127. void flip_windows(const Windows &wlist, Thread *current_thread);
  128. void do_sync_frame(Thread *current_thread);
  129. void do_ready_flip(Thread *current_thread);
  130. void do_flip_frame(Thread *current_thread);
  131. INLINE void close_gsg(GraphicsPipe *pipe, GraphicsStateGuardian *gsg);
  132. PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg,
  133. DisplayRegionPipelineReader *dr);
  134. void do_draw(CullResult *cull_result, SceneSetup *scene_setup,
  135. GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
  136. void do_add_window(GraphicsOutput *window,
  137. const GraphicsThreadingModel &threading_model);
  138. void do_add_gsg(GraphicsStateGuardian *gsg, GraphicsPipe *pipe,
  139. const GraphicsThreadingModel &threading_model);
  140. void do_remove_window(GraphicsOutput *window, Thread *current_thread);
  141. void do_resort_windows();
  142. void terminate_threads(Thread *current_thread);
  143. void auto_adjust_capabilities(GraphicsStateGuardian *gsg);
  144. #ifdef DO_PSTATS
  145. typedef map<TypeHandle, PStatCollector> CyclerTypeCounters;
  146. CyclerTypeCounters _all_cycler_types;
  147. CyclerTypeCounters _dirty_cycler_types;
  148. static void pstats_count_cycler_type(TypeHandle type, int count, void *data);
  149. static void pstats_count_dirty_cycler_type(TypeHandle type, int count, void *data);
  150. #endif // DO_PSTATS
  151. static const RenderState *get_invert_polygon_state();
  152. // The WindowRenderer class records the stages of the pipeline that
  153. // each thread (including the main thread, a.k.a. "app") should
  154. // process, and the list of windows for each stage.
  155. // There is one WindowRenderer instance for app, and another
  156. // instance for each thread (the thread-specific WindowRenderers are
  157. // actually instances of RenderThread, below, which inherits from
  158. // WindowRenderer).
  159. // The idea is that each window is associated with one or more
  160. // WindowRenderer objects, according to the threads in which its
  161. // rendering tasks (window, cull, and draw) are divided into.
  162. // The "window" task is responsible for doing any updates to the
  163. // window itself, such as size and placement, and is wholly
  164. // responsible for any API calls to the windowing system itself,
  165. // unrelated to OpenGL-type calls. This is normally done in app
  166. // (the design of X-Windows is such that all X calls must be issued
  167. // in the same thread).
  168. // The "cull" task is responsible for crawling through the scene
  169. // graph and discovering all of the Geoms that are within the
  170. // viewing frustum. It assembles all such Geoms, along with their
  171. // computed net state and transform, in a linked list of
  172. // CullableObjects, which it stores for the "draw" task, next.
  173. // The "draw" task is responsible for walking through the list of
  174. // CullableObjects recorded by the cull task, and issuing the
  175. // appropriate graphics commands to draw them.
  176. // There is an additional task, not often used, called "cdraw".
  177. // This task, if activated, will crawl through the scene graph and
  178. // issue graphics commands immediately, as each Geom is discovered.
  179. // It is only rarely used because it cannot perform sorting beyond
  180. // basic scene graph order, making it less useful than a separate
  181. // cull and draw task.
  182. // It is possible for all three of the normal tasks: window, cull,
  183. // and draw, to be handled by the same thread. This is the normal,
  184. // single-threaded model: all tasks are handled by the app thread.
  185. // In this case, the window will be added to _app's _window, _cull,
  186. // and _draw lists.
  187. // On the other hand, a window's tasks may also be distributed among
  188. // as many as three threads. For instance, if the window is listed
  189. // on _app's _window list, but on thread A's _cull list, and thread
  190. // B's _draw list, then the window task will be handled in the app
  191. // thread, while the cull task will be handled by thread A, and the
  192. // draw task will be handled (in parallel) by thread B. (In order
  193. // for this to work, it will be necessary that thread A and B are
  194. // configured to view different stages of the graphics pipeline.
  195. // This is a more advanced topic than there is room to discuss in
  196. // this comment.)
  197. // Manipulation of the various window lists in each WindowRenderer
  198. // object is always performed in the app thread. The auxiliary
  199. // threads are slaves to the app thread, and they can only perform
  200. // one of a handful of specified tasks, none of which includes
  201. // adding or removing windows from its lists. The full set of tasks
  202. // that a WindowRenderer may perform is enumerated in ThreadState,
  203. // above; see RenderThread::thread_main().
  204. // There is a pair of condition variables for each thread, _cv_start
  205. // and _cv_done, that is used to synchronize requests made by app to
  206. // a particular thread. The usual procedure to request a thread to
  207. // perform a particular task is the following: the app thread waits
  208. // on the thread's _cv_done variable, stores the value corresponding
  209. // to the desired task in the thread's _thread_state value, then
  210. // signals the thread's _cv_start variable. The thread, in turn,
  211. // will perform its requested task, set its _thread_state to
  212. // TS_wait, and signal _cv_done. See examples in the code,
  213. // e.g. open_windows(), for more details on this process.
  214. // It is of course not necessary to signal any threads in order to
  215. // perform tasks listed in the _app WindowRenderer. For this object
  216. // only, we simply call the appropriate methods on _app when we want
  217. // the tasks to be performed.
  218. class WindowRenderer {
  219. public:
  220. WindowRenderer(const string &name);
  221. void add_gsg(GraphicsStateGuardian *gsg);
  222. void add_window(Windows &wlist, GraphicsOutput *window);
  223. void remove_window(GraphicsOutput *window);
  224. void resort_windows();
  225. void do_frame(GraphicsEngine *engine, Thread *current_thread);
  226. void do_windows(GraphicsEngine *engine, Thread *current_thread);
  227. void do_ready_flip(GraphicsEngine *engine, Thread *current_thread);
  228. void do_flip(GraphicsEngine *engine, Thread *current_thread);
  229. void do_release(GraphicsEngine *engine, Thread *current_thread);
  230. void do_close(GraphicsEngine *engine, Thread *current_thread);
  231. void do_pending(GraphicsEngine *engine, Thread *current_thread);
  232. bool any_done_gsgs() const;
  233. public:
  234. Windows _cull; // cull stage
  235. Windows _cdraw; // cull-and-draw-together stage
  236. Windows _draw; // draw stage
  237. Windows _window; // window stage, i.e. process windowing events
  238. // These are not kept sorted.
  239. Windows _pending_close; // moved from _window, pending close.
  240. GSGs _gsgs; // draw stage
  241. LightReMutex _wl_lock;
  242. };
  243. class RenderThread : public Thread, public WindowRenderer {
  244. public:
  245. RenderThread(const string &name, GraphicsEngine *engine);
  246. virtual void thread_main();
  247. GraphicsEngine *_engine;
  248. Mutex _cv_mutex;
  249. ConditionVar _cv_start;
  250. ConditionVar _cv_done;
  251. ThreadState _thread_state;
  252. };
  253. WindowRenderer *get_window_renderer(const string &name, int pipeline_stage);
  254. Pipeline *_pipeline;
  255. Windows _windows;
  256. bool _windows_sorted;
  257. unsigned int _window_sort_index;
  258. bool _needs_open_windows;
  259. WindowRenderer _app;
  260. typedef pmap<string, PT(RenderThread) > Threads;
  261. Threads _threads;
  262. GraphicsThreadingModel _threading_model;
  263. bool _auto_flip;
  264. bool _portal_enabled; //toggle to portal culling on/off
  265. PT(Loader) _default_loader;
  266. enum FlipState {
  267. FS_draw, // Still drawing.
  268. FS_sync, // All windows are done drawing.
  269. FS_flip, // All windows are done drawing and have flipped.
  270. };
  271. FlipState _flip_state;
  272. bool _singular_warning_last_frame;
  273. bool _singular_warning_this_frame;
  274. ReMutex _lock;
  275. ReMutex _public_lock;
  276. class LoadedTexture {
  277. public:
  278. PT(Texture) _tex;
  279. UpdateSeq _image_modified;
  280. };
  281. typedef pvector<LoadedTexture> LoadedTextures;
  282. LoadedTextures _loaded_textures;
  283. Mutex _loaded_textures_lock;
  284. static PT(GraphicsEngine) _global_ptr;
  285. static PStatCollector _wait_pcollector;
  286. static PStatCollector _cycle_pcollector;
  287. static PStatCollector _app_pcollector;
  288. static PStatCollector _render_frame_pcollector;
  289. static PStatCollector _do_frame_pcollector;
  290. static PStatCollector _yield_pcollector;
  291. static PStatCollector _cull_pcollector;
  292. static PStatCollector _cull_setup_pcollector;
  293. static PStatCollector _cull_sort_pcollector;
  294. static PStatCollector _draw_pcollector;
  295. static PStatCollector _sync_pcollector;
  296. static PStatCollector _flip_pcollector;
  297. static PStatCollector _flip_begin_pcollector;
  298. static PStatCollector _flip_end_pcollector;
  299. static PStatCollector _transform_states_pcollector;
  300. static PStatCollector _transform_states_unused_pcollector;
  301. static PStatCollector _render_states_pcollector;
  302. static PStatCollector _render_states_unused_pcollector;
  303. static PStatCollector _cyclers_pcollector;
  304. static PStatCollector _dirty_cyclers_pcollector;
  305. static PStatCollector _delete_pcollector;
  306. static PStatCollector _sw_sprites_pcollector;
  307. static PStatCollector _vertex_data_small_pcollector;
  308. static PStatCollector _vertex_data_independent_pcollector;
  309. static PStatCollector _vertex_data_pending_pcollector;
  310. static PStatCollector _vertex_data_resident_pcollector;
  311. static PStatCollector _vertex_data_compressed_pcollector;
  312. static PStatCollector _vertex_data_used_disk_pcollector;
  313. static PStatCollector _vertex_data_unused_disk_pcollector;
  314. static PStatCollector _cnode_volume_pcollector;
  315. static PStatCollector _gnode_volume_pcollector;
  316. static PStatCollector _geom_volume_pcollector;
  317. static PStatCollector _node_volume_pcollector;
  318. static PStatCollector _volume_pcollector;
  319. static PStatCollector _test_pcollector;
  320. static PStatCollector _volume_polygon_pcollector;
  321. static PStatCollector _test_polygon_pcollector;
  322. static PStatCollector _volume_plane_pcollector;
  323. static PStatCollector _test_plane_pcollector;
  324. static PStatCollector _volume_sphere_pcollector;
  325. static PStatCollector _test_sphere_pcollector;
  326. static PStatCollector _volume_box_pcollector;
  327. static PStatCollector _test_box_pcollector;
  328. static PStatCollector _volume_tube_pcollector;
  329. static PStatCollector _test_tube_pcollector;
  330. static PStatCollector _volume_inv_sphere_pcollector;
  331. static PStatCollector _test_inv_sphere_pcollector;
  332. static PStatCollector _volume_geom_pcollector;
  333. static PStatCollector _test_geom_pcollector;
  334. static PStatCollector _occlusion_untested_pcollector;
  335. static PStatCollector _occlusion_passed_pcollector;
  336. static PStatCollector _occlusion_failed_pcollector;
  337. static PStatCollector _occlusion_tests_pcollector;
  338. friend class WindowRenderer;
  339. friend class GraphicsOutput;
  340. };
  341. #include "graphicsEngine.I"
  342. #endif