renderState.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // Filename: renderState.h
  2. // Created by: drose (21Feb02)
  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 RENDERSTATE_H
  15. #define RENDERSTATE_H
  16. #include "pandabase.h"
  17. #include "renderAttrib.h"
  18. #include "nodeCachedReferenceCount.h"
  19. #include "pointerTo.h"
  20. #include "pvector.h"
  21. #include "updateSeq.h"
  22. #include "pStatCollector.h"
  23. #include "renderModeAttrib.h"
  24. #include "texMatrixAttrib.h"
  25. #include "geomMunger.h"
  26. #include "weakPointerTo.h"
  27. #include "lightReMutex.h"
  28. #include "lightMutex.h"
  29. #include "deletedChain.h"
  30. #include "simpleHashMap.h"
  31. #include "cacheStats.h"
  32. #include "renderAttribRegistry.h"
  33. class GraphicsStateGuardianBase;
  34. class FactoryParams;
  35. class ShaderAttrib;
  36. ////////////////////////////////////////////////////////////////////
  37. // Class : RenderState
  38. // Description : This represents a unique collection of RenderAttrib
  39. // objects that correspond to a particular renderable
  40. // state.
  41. //
  42. // You should not attempt to create or modify a
  43. // RenderState object directly. Instead, call one of
  44. // the make() functions to create one for you. And
  45. // instead of modifying a RenderState object, create a
  46. // new one.
  47. ////////////////////////////////////////////////////////////////////
  48. class EXPCL_PANDA_PGRAPH RenderState : public NodeCachedReferenceCount {
  49. protected:
  50. RenderState();
  51. private:
  52. RenderState(const RenderState &copy);
  53. void operator = (const RenderState &copy);
  54. public:
  55. virtual ~RenderState();
  56. ALLOC_DELETED_CHAIN(RenderState);
  57. typedef RenderAttribRegistry::SlotMask SlotMask;
  58. PUBLISHED:
  59. bool operator < (const RenderState &other) const;
  60. int compare_sort(const RenderState &other) const;
  61. size_t get_hash() const;
  62. INLINE bool is_empty() const;
  63. INLINE bool has_cull_callback() const;
  64. bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
  65. static CPT(RenderState) make_empty();
  66. static CPT(RenderState) make_full_default();
  67. static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
  68. static CPT(RenderState) make(const RenderAttrib *attrib1,
  69. const RenderAttrib *attrib2, int override = 0);
  70. static CPT(RenderState) make(const RenderAttrib *attrib1,
  71. const RenderAttrib *attrib2,
  72. const RenderAttrib *attrib3, int override = 0);
  73. static CPT(RenderState) make(const RenderAttrib *attrib1,
  74. const RenderAttrib *attrib2,
  75. const RenderAttrib *attrib3,
  76. const RenderAttrib *attrib4, int override = 0);
  77. static CPT(RenderState) make(const RenderAttrib * const *attrib,
  78. int num_attribs, int override = 0);
  79. CPT(RenderState) compose(const RenderState *other) const;
  80. CPT(RenderState) invert_compose(const RenderState *other) const;
  81. CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const;
  82. CPT(RenderState) set_attrib(const RenderAttrib *attrib) const;
  83. CPT(RenderState) set_attrib(const RenderAttrib *attrib, int override) const;
  84. INLINE CPT(RenderState) remove_attrib(TypeHandle type) const;
  85. CPT(RenderState) remove_attrib(int slot) const;
  86. CPT(RenderState) adjust_all_priorities(int adjustment) const;
  87. INLINE bool has_attrib(TypeHandle type) const;
  88. INLINE bool has_attrib(int slot) const;
  89. INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
  90. INLINE const RenderAttrib *get_attrib(int slot) const;
  91. INLINE const RenderAttrib *get_attrib_def(int slot) const;
  92. INLINE int get_override(TypeHandle type) const;
  93. INLINE int get_override(int slot) const;
  94. INLINE CPT(RenderState) get_unique() const;
  95. virtual bool unref() const;
  96. INLINE void cache_ref() const;
  97. INLINE bool cache_unref() const;
  98. INLINE void node_ref() const;
  99. INLINE bool node_unref() const;
  100. INLINE int get_composition_cache_num_entries() const;
  101. INLINE int get_invert_composition_cache_num_entries() const;
  102. INLINE int get_composition_cache_size() const;
  103. INLINE const RenderState *get_composition_cache_source(int n) const;
  104. INLINE const RenderState *get_composition_cache_result(int n) const;
  105. INLINE int get_invert_composition_cache_size() const;
  106. INLINE const RenderState *get_invert_composition_cache_source(int n) const;
  107. INLINE const RenderState *get_invert_composition_cache_result(int n) const;
  108. #ifdef HAVE_PYTHON
  109. PyObject *get_composition_cache() const;
  110. PyObject *get_invert_composition_cache() const;
  111. #endif // HAVE_PYTHON
  112. void output(ostream &out) const;
  113. void write(ostream &out, int indent_level) const;
  114. static int get_max_priority();
  115. static int get_num_states();
  116. static int get_num_unused_states();
  117. static int clear_cache();
  118. static void clear_munger_cache();
  119. static void list_cycles(ostream &out);
  120. static void list_states(ostream &out);
  121. static bool validate_states();
  122. #ifdef HAVE_PYTHON
  123. static PyObject *get_states();
  124. #endif // HAVE_PYTHON
  125. PUBLISHED:
  126. // These methods are intended for use by low-level code, but they're
  127. // also handy enough to expose to high-level users.
  128. INLINE int get_draw_order() const;
  129. INLINE int get_bin_index() const;
  130. int get_geom_rendering(int geom_rendering) const;
  131. public:
  132. static void bin_removed(int bin_index);
  133. INLINE static void flush_level();
  134. private:
  135. bool validate_filled_slots() const;
  136. INLINE bool do_cache_unref() const;
  137. INLINE bool do_node_unref() const;
  138. class CompositionCycleDescEntry {
  139. public:
  140. INLINE CompositionCycleDescEntry(const RenderState *obj,
  141. const RenderState *result,
  142. bool inverted);
  143. const RenderState *_obj;
  144. const RenderState *_result;
  145. bool _inverted;
  146. };
  147. typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
  148. static CPT(RenderState) return_new(RenderState *state);
  149. static CPT(RenderState) return_unique(RenderState *state);
  150. CPT(RenderState) do_compose(const RenderState *other) const;
  151. CPT(RenderState) do_invert_compose(const RenderState *other) const;
  152. static bool r_detect_cycles(const RenderState *start_state,
  153. const RenderState *current_state,
  154. int length, UpdateSeq this_seq,
  155. CompositionCycleDesc *cycle_desc);
  156. static bool r_detect_reverse_cycles(const RenderState *start_state,
  157. const RenderState *current_state,
  158. int length, UpdateSeq this_seq,
  159. CompositionCycleDesc *cycle_desc);
  160. void release_new();
  161. void remove_cache_pointers();
  162. void determine_bin_index();
  163. void determine_cull_callback();
  164. void fill_default();
  165. INLINE void set_destructing();
  166. INLINE bool is_destructing() const;
  167. INLINE void consider_update_pstats(int old_referenced_bits) const;
  168. static void update_pstats(int old_referenced_bits, int new_referenced_bits);
  169. public:
  170. static void init_states();
  171. // If this state contains an "auto" ShaderAttrib, then an explicit
  172. // ShaderAttrib will be synthesized by the runtime and stored here.
  173. // I can't declare this as a ShaderAttrib because that would create
  174. // a circular include-file dependency problem. Aaargh.
  175. CPT(RenderAttrib) _generated_shader;
  176. private:
  177. // This mutex protects _states. It also protects any modification
  178. // to the cache, which is encoded in _composition_cache and
  179. // _invert_composition_cache.
  180. static LightReMutex *_states_lock;
  181. typedef phash_set<const RenderState *, indirect_less_hash<const RenderState *> > States;
  182. static States *_states;
  183. static CPT(RenderState) _empty_state;
  184. static CPT(RenderState) _full_default_state;
  185. // This iterator records the entry corresponding to this RenderState
  186. // object in the above global set. We keep the iterator around so
  187. // we can remove it when the RenderState destructs.
  188. States::iterator _saved_entry;
  189. // This data structure manages the job of caching the composition of
  190. // two RenderStates. It's complicated because we have to be sure to
  191. // remove the entry if *either* of the input RenderStates destructs.
  192. // To implement this, we always record Composition entries in pairs,
  193. // one in each of the two involved RenderState objects.
  194. class Composition {
  195. public:
  196. INLINE Composition();
  197. INLINE Composition(const Composition &copy);
  198. // _result is reference counted if and only if it is not the same
  199. // pointer as this.
  200. const RenderState *_result;
  201. };
  202. // The first element of the map is the object we compose with. This
  203. // is not reference counted within this map; instead we store a
  204. // companion pointer in the other object, and remove the references
  205. // explicitly when either object destructs.
  206. typedef SimpleHashMap<const RenderState *, Composition, pointer_hash> CompositionCache;
  207. CompositionCache _composition_cache;
  208. CompositionCache _invert_composition_cache;
  209. // This is here to provide a quick cache of GSG + RenderState ->
  210. // GeomMunger for the cull phase. It is here because it is faster
  211. // to look up the GSG in the RenderState pointer than vice-versa,
  212. // since there are likely to be far fewer GSG's than RenderStates.
  213. // The code to manage this map lives in
  214. // GraphicsStateGuardian::get_geom_munger().
  215. typedef pmap<WCPT(GraphicsStateGuardianBase), PT(GeomMunger) > Mungers;
  216. Mungers _mungers;
  217. Mungers::const_iterator _last_mi;
  218. // This is used to mark nodes as we visit them to detect cycles.
  219. UpdateSeq _cycle_detect;
  220. static UpdateSeq _last_cycle_detect;
  221. static PStatCollector _cache_update_pcollector;
  222. static PStatCollector _state_compose_pcollector;
  223. static PStatCollector _state_invert_pcollector;
  224. static PStatCollector _node_counter;
  225. static PStatCollector _cache_counter;
  226. private:
  227. // This is the actual data within the RenderState: a set of
  228. // max_slots RenderAttribs.
  229. class Attribute {
  230. public:
  231. INLINE Attribute(const RenderAttrib *attrib, int override);
  232. INLINE Attribute(int override = 0);
  233. INLINE Attribute(const Attribute &copy);
  234. INLINE void operator = (const Attribute &copy);
  235. INLINE void set(const RenderAttrib *attrib, int override);
  236. INLINE int compare_to(const Attribute &other) const;
  237. CPT(RenderAttrib) _attrib;
  238. int _override;
  239. };
  240. Attribute *_attributes;
  241. // We also store a bitmask of the non-NULL attributes in the above
  242. // array. This is redundant, but it is a useful cache.
  243. SlotMask _filled_slots;
  244. // We cache the index to the associated CullBin, if there happens to
  245. // be a CullBinAttrib in the state.
  246. int _bin_index;
  247. int _draw_order;
  248. enum Flags {
  249. F_checked_bin_index = 0x000001,
  250. F_checked_cull_callback = 0x000002,
  251. F_has_cull_callback = 0x000004,
  252. F_is_destructing = 0x000008,
  253. };
  254. unsigned int _flags;
  255. vector_int *_read_overrides; // Only used during bam reading.
  256. // This mutex protects _flags, and all of the above computed values.
  257. LightMutex _lock;
  258. static CacheStats _cache_stats;
  259. public:
  260. static void register_with_read_factory();
  261. virtual void write_datagram(BamWriter *manager, Datagram &dg);
  262. virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
  263. static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
  264. virtual void finalize(BamReader *manager);
  265. protected:
  266. static TypedWritable *make_from_bam(const FactoryParams &params);
  267. void fillin(DatagramIterator &scan, BamReader *manager);
  268. public:
  269. static TypeHandle get_class_type() {
  270. return _type_handle;
  271. }
  272. static void init_type() {
  273. NodeCachedReferenceCount::init_type();
  274. register_type(_type_handle, "RenderState",
  275. NodeCachedReferenceCount::get_class_type());
  276. }
  277. virtual TypeHandle get_type() const {
  278. return get_class_type();
  279. }
  280. virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
  281. private:
  282. static TypeHandle _type_handle;
  283. friend class GraphicsStateGuardian;
  284. friend class RenderAttribRegistry;
  285. };
  286. INLINE ostream &operator << (ostream &out, const RenderState &state) {
  287. state.output(out);
  288. return out;
  289. }
  290. #include "renderState.I"
  291. #endif