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