Panda3D
renderState.h
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 
15 #ifndef RENDERSTATE_H
16 #define RENDERSTATE_H
17 
18 #include "pandabase.h"
19 
20 #include "renderAttrib.h"
21 #include "nodeCachedReferenceCount.h"
22 #include "pointerTo.h"
23 #include "pvector.h"
24 #include "updateSeq.h"
25 #include "pStatCollector.h"
26 #include "renderModeAttrib.h"
27 #include "texMatrixAttrib.h"
28 #include "geomMunger.h"
29 #include "weakPointerTo.h"
30 #include "lightReMutex.h"
31 #include "lightMutex.h"
32 #include "deletedChain.h"
33 #include "simpleHashMap.h"
34 #include "cacheStats.h"
35 #include "renderAttribRegistry.h"
36 
38 class FactoryParams;
39 class ShaderAttrib;
40 
41 ////////////////////////////////////////////////////////////////////
42 // Class : RenderState
43 // Description : This represents a unique collection of RenderAttrib
44 // objects that correspond to a particular renderable
45 // state.
46 //
47 // You should not attempt to create or modify a
48 // RenderState object directly. Instead, call one of
49 // the make() functions to create one for you. And
50 // instead of modifying a RenderState object, create a
51 // new one.
52 ////////////////////////////////////////////////////////////////////
53 class EXPCL_PANDA_PGRAPH RenderState : public NodeCachedReferenceCount {
54 protected:
55  RenderState();
56 
57 private:
58  RenderState(const RenderState &copy);
59  void operator = (const RenderState &copy);
60 
61 public:
62  virtual ~RenderState();
63  ALLOC_DELETED_CHAIN(RenderState);
64 
66 
67 PUBLISHED:
68  int compare_to(const RenderState &other) const;
69  int compare_sort(const RenderState &other) const;
70  int compare_mask(const RenderState &other, SlotMask compare_mask) const;
71  INLINE size_t get_hash() const;
72 
73  INLINE bool is_empty() const;
74 
75  INLINE bool has_cull_callback() const;
76  bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
77 
78  INLINE static CPT(RenderState) make_empty();
79  INLINE static CPT(RenderState) make_full_default();
80  static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
81  static CPT(RenderState) make(const RenderAttrib *attrib1,
82  const RenderAttrib *attrib2, int override = 0);
83  static CPT(RenderState) make(const RenderAttrib *attrib1,
84  const RenderAttrib *attrib2,
85  const RenderAttrib *attrib3, int override = 0);
86  static CPT(RenderState) make(const RenderAttrib *attrib1,
87  const RenderAttrib *attrib2,
88  const RenderAttrib *attrib3,
89  const RenderAttrib *attrib4, int override = 0);
90  static CPT(RenderState) make(const RenderAttrib *attrib1,
91  const RenderAttrib *attrib2,
92  const RenderAttrib *attrib3,
93  const RenderAttrib *attrib4,
94  const RenderAttrib *attrib5, int override = 0);
95  static CPT(RenderState) make(const RenderAttrib * const *attrib,
96  int num_attribs, int override = 0);
97 
98  CPT(RenderState) compose(const RenderState *other) const;
99  CPT(RenderState) invert_compose(const RenderState *other) const;
100 
101  CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const;
102  CPT(RenderState) set_attrib(const RenderAttrib *attrib) const;
103  CPT(RenderState) set_attrib(const RenderAttrib *attrib, int override) const;
104  INLINE CPT(RenderState) remove_attrib(TypeHandle type) const;
105  CPT(RenderState) remove_attrib(int slot) const;
106 
107  CPT(RenderState) adjust_all_priorities(int adjustment) const;
108 
109  INLINE bool has_attrib(TypeHandle type) const;
110  INLINE bool has_attrib(int slot) const;
111  INLINE const RenderAttrib *get_attrib(TypeHandle type) const;
112  INLINE const RenderAttrib *get_attrib(int slot) const;
113  INLINE const RenderAttrib *get_attrib_def(int slot) const;
114  INLINE int get_override(TypeHandle type) const;
115  INLINE int get_override(int slot) const;
116 
117  INLINE CPT(RenderState) get_unique() const;
118 
119  virtual bool unref() const;
120 
121  INLINE void cache_ref() const;
122  INLINE bool cache_unref() const;
123  INLINE void node_ref() const;
124  INLINE bool node_unref() const;
125 
126  INLINE int get_composition_cache_num_entries() const;
127  INLINE int get_invert_composition_cache_num_entries() const;
128 
129  INLINE int get_composition_cache_size() const;
130  INLINE const RenderState *get_composition_cache_source(int n) const;
131  INLINE const RenderState *get_composition_cache_result(int n) const;
132  INLINE int get_invert_composition_cache_size() const;
133  INLINE const RenderState *get_invert_composition_cache_source(int n) const;
134  INLINE const RenderState *get_invert_composition_cache_result(int n) const;
135  EXTENSION(PyObject *get_composition_cache() const);
136  EXTENSION(PyObject *get_invert_composition_cache() const);
137 
138  const RenderState *get_auto_shader_state() const;
139 
140  void output(ostream &out) const;
141  void write(ostream &out, int indent_level) const;
142 
143  static int get_max_priority();
144 
145  static int get_num_states();
146  static int get_num_unused_states();
147  static int clear_cache();
148  static void clear_munger_cache();
149  static int garbage_collect();
150  static void list_cycles(ostream &out);
151  static void list_states(ostream &out);
152  static bool validate_states();
153  EXTENSION(static PyObject *get_states());
154 
155 PUBLISHED:
156  // These methods are intended for use by low-level code, but they're
157  // also handy enough to expose to high-level users.
158  INLINE int get_draw_order() const;
159  INLINE int get_bin_index() const;
160  int get_geom_rendering(int geom_rendering) const;
161 
162 public:
163  static void bin_removed(int bin_index);
164 
165  INLINE static void flush_level();
166 
167 #ifndef CPPPARSER
168  template<class AttribType>
169  INLINE bool get_attrib(const AttribType *&attrib) const;
170  template<class AttribType>
171  INLINE void get_attrib_def(const AttribType *&attrib) const;
172 #endif // CPPPARSER
173 
174 private:
175  INLINE void check_hash() const;
176  bool validate_filled_slots() const;
177  INLINE bool do_cache_unref() const;
178  INLINE bool do_node_unref() const;
179  INLINE void calc_hash();
180  void do_calc_hash();
181  void assign_auto_shader_state();
182  CPT(RenderState) do_calc_auto_shader_state();
183 
184  class CompositionCycleDescEntry {
185  public:
186  INLINE CompositionCycleDescEntry(const RenderState *obj,
187  const RenderState *result,
188  bool inverted);
189 
190  const RenderState *_obj;
191  const RenderState *_result;
192  bool _inverted;
193  };
195 
196  static CPT(RenderState) return_new(RenderState *state);
197  static CPT(RenderState) return_unique(RenderState *state);
198  CPT(RenderState) do_compose(const RenderState *other) const;
199  CPT(RenderState) do_invert_compose(const RenderState *other) const;
200  void detect_and_break_cycles();
201  static bool r_detect_cycles(const RenderState *start_state,
202  const RenderState *current_state,
203  int length, UpdateSeq this_seq,
204  CompositionCycleDesc *cycle_desc);
205  static bool r_detect_reverse_cycles(const RenderState *start_state,
206  const RenderState *current_state,
207  int length, UpdateSeq this_seq,
208  CompositionCycleDesc *cycle_desc);
209 
210  void release_new();
211  void remove_cache_pointers();
212 
213  void determine_bin_index();
214  void determine_cull_callback();
215  void fill_default();
216 
217  INLINE void set_destructing();
218  INLINE bool is_destructing() const;
219 
220  INLINE void consider_update_pstats(int old_referenced_bits) const;
221  static void update_pstats(int old_referenced_bits, int new_referenced_bits);
222 
223 public:
224  static void init_states();
225 
226  // If this state contains an "auto" ShaderAttrib, then an explicit
227  // ShaderAttrib will be synthesized by the runtime and stored here.
228  // I can't declare this as a ShaderAttrib because that would create
229  // a circular include-file dependency problem. Aaargh.
230  mutable CPT(RenderAttrib) _generated_shader;
231 
232 private:
233  // This mutex protects _states. It also protects any modification
234  // to the cache, which is encoded in _composition_cache and
235  // _invert_composition_cache.
236  static LightReMutex *_states_lock;
237  class Empty {
238  };
240  static States *_states;
241  static CPT(RenderState) _empty_state;
242  static CPT(RenderState) _full_default_state;
243 
244  // This iterator records the entry corresponding to this
245  // RenderState object in the above global set. We keep the index
246  // around so we can remove it when the RenderState destructs.
247  int _saved_entry;
248 
249  // This data structure manages the job of caching the composition of
250  // two RenderStates. It's complicated because we have to be sure to
251  // remove the entry if *either* of the input RenderStates destructs.
252  // To implement this, we always record Composition entries in pairs,
253  // one in each of the two involved RenderState objects.
254  class Composition {
255  public:
256  INLINE Composition();
257  INLINE Composition(const Composition &copy);
258 
259  // _result is reference counted if and only if it is not the same
260  // pointer as this.
261  const RenderState *_result;
262  };
263 
264  // The first element of the map is the object we compose with. This
265  // is not reference counted within this map; instead we store a
266  // companion pointer in the other object, and remove the references
267  // explicitly when either object destructs.
269  CompositionCache _composition_cache;
270  CompositionCache _invert_composition_cache;
271 
272  // This is here to provide a quick cache of GSG + RenderState ->
273  // GeomMunger for the cull phase. It is here because it is faster
274  // to look up the GSG in the RenderState pointer than vice-versa,
275  // since there are likely to be far fewer GSG's than RenderStates.
276  // The code to manage this map lives in
277  // GraphicsStateGuardian::get_geom_munger().
279  Mungers _mungers;
280  Mungers::const_iterator _last_mi;
281 
282  // This is used to mark nodes as we visit them to detect cycles.
283  UpdateSeq _cycle_detect;
284  static UpdateSeq _last_cycle_detect;
285 
286  // This keeps track of our current position through the garbage
287  // collection cycle.
288  static int _garbage_index;
289 
290  static PStatCollector _cache_update_pcollector;
291  static PStatCollector _garbage_collect_pcollector;
292  static PStatCollector _state_compose_pcollector;
293  static PStatCollector _state_invert_pcollector;
294  static PStatCollector _state_break_cycles_pcollector;
295  static PStatCollector _state_validate_pcollector;
296 
297  static PStatCollector _node_counter;
298  static PStatCollector _cache_counter;
299 
300 private:
301  // This is the actual data within the RenderState: a set of
302  // max_slots RenderAttribs.
303  class Attribute {
304  public:
305  INLINE Attribute(const RenderAttrib *attrib, int override);
306  INLINE Attribute(int override = 0);
307  INLINE Attribute(const Attribute &copy);
308  INLINE void operator = (const Attribute &copy);
309  INLINE void set(const RenderAttrib *attrib, int override);
310  INLINE int compare_to(const Attribute &other) const;
311 
312  CPT(RenderAttrib) _attrib;
313  int _override;
314  };
315  Attribute *_attributes;
316 
317  // We also store a bitmask of the non-NULL attributes in the above
318  // array. This is redundant, but it is a useful cache.
319  SlotMask _filled_slots;
320 
321  // We cache the index to the associated CullBin, if there happens to
322  // be a CullBinAttrib in the state.
323  int _bin_index;
324  int _draw_order;
325  size_t _hash;
326 
327  const RenderState *_auto_shader_state;
328 
329  enum Flags {
330  F_checked_bin_index = 0x000001,
331  F_checked_cull_callback = 0x000002,
332  F_has_cull_callback = 0x000004,
333  F_is_destructing = 0x000008,
334  F_hash_known = 0x000010,
335  };
336  unsigned int _flags;
337 
338  vector_int *_read_overrides; // Only used during bam reading.
339 
340  // This mutex protects _flags, and all of the above computed values.
341  LightMutex _lock;
342 
343  static CacheStats _cache_stats;
344 
345 public:
346  static void register_with_read_factory();
347  virtual void write_datagram(BamWriter *manager, Datagram &dg);
348  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
349  static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
350  virtual void finalize(BamReader *manager);
351 
352 protected:
353  static TypedWritable *make_from_bam(const FactoryParams &params);
354  void fillin(DatagramIterator &scan, BamReader *manager);
355 
356 public:
357  static TypeHandle get_class_type() {
358  return _type_handle;
359  }
360  static void init_type() {
361  NodeCachedReferenceCount::init_type();
362  register_type(_type_handle, "RenderState",
363  NodeCachedReferenceCount::get_class_type());
364  }
365  virtual TypeHandle get_type() const {
366  return get_class_type();
367  }
368  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
369 
370 private:
371  static TypeHandle _type_handle;
372 
373  friend class GraphicsStateGuardian;
374  friend class RenderAttribRegistry;
375  friend class Extension<RenderState>;
376 };
377 
378 INLINE ostream &operator << (ostream &out, const RenderState &state) {
379  state.output(out);
380  return out;
381 }
382 
383 #include "renderState.I"
384 
385 #endif
386 
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
This class further specializes CachedTypedWritableReferenceCount to also add a node_ref_count, for the purposes of counting the number of times the object is referenced by a "node", presumably a PandaNode.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
A lightweight reentrant mutex.
Definition: lightReMutex.h:34
This collects together the pieces of data that are accumulated for each node while walking the scene ...
void node_ref() const
Explicitly increments the reference count.
This template class implements an unordered map of keys to data, implemented as a hashtable...
Definition: simpleHashMap.h:33
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
This is our own Panda specialization on the default STL list.
Definition: plist.h:38
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
A lightweight class that represents a single element that may be timed and/or counted via stats...
bool cache_unref() const
Explicitly decrements the cache reference count and the normal reference count simultaneously.
This class is used to associate each RenderAttrib with a different slot index at runtime, so we can store a list of RenderAttribs in the RenderState object, and very quickly look them up by type.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void cache_ref() const
Explicitly increments the cache reference count and the normal reference count simultaneously.
bool node_unref() const
Explicitly decrements the node reference count and the normal reference count simultaneously.
The default class template does not define any methods.
Definition: extension.h:39
An STL function object class, this is intended to be used on any ordered collection of class objects ...
Definition: stl_compares.h:79
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
This is used to track the utilization of the TransformState and RenderState caches, for low-level performance tuning information.
Definition: cacheStats.h:28
Encapsulates all the communication with a particular instance of a given rendering backend...
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
This is a sequence number that increments monotonically.
Definition: updateSeq.h:43
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition: lightMutex.h:45
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: cullTraverser.h:48
virtual bool unref() const
Explicitly decrements the reference count.