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 private:
173  INLINE void check_hash() const;
174  bool validate_filled_slots() const;
175  INLINE bool do_cache_unref() const;
176  INLINE bool do_node_unref() const;
177  INLINE void calc_hash();
178  void do_calc_hash();
179 
180  class CompositionCycleDescEntry {
181  public:
182  INLINE CompositionCycleDescEntry(const RenderState *obj,
183  const RenderState *result,
184  bool inverted);
185 
186  const RenderState *_obj;
187  const RenderState *_result;
188  bool _inverted;
189  };
191 
192  static CPT(RenderState) return_new(RenderState *state);
193  static CPT(RenderState) return_unique(RenderState *state);
194  CPT(RenderState) do_compose(const RenderState *other) const;
195  CPT(RenderState) do_invert_compose(const RenderState *other) const;
196  void detect_and_break_cycles();
197  static bool r_detect_cycles(const RenderState *start_state,
198  const RenderState *current_state,
199  int length, UpdateSeq this_seq,
200  CompositionCycleDesc *cycle_desc);
201  static bool r_detect_reverse_cycles(const RenderState *start_state,
202  const RenderState *current_state,
203  int length, UpdateSeq this_seq,
204  CompositionCycleDesc *cycle_desc);
205 
206  void release_new();
207  void remove_cache_pointers();
208 
209  void determine_bin_index();
210  void determine_cull_callback();
211  void fill_default();
212 
213  INLINE void set_destructing();
214  INLINE bool is_destructing() const;
215 
216  INLINE void consider_update_pstats(int old_referenced_bits) const;
217  static void update_pstats(int old_referenced_bits, int new_referenced_bits);
218 
219 public:
220  static void init_states();
221 
222  // If this state contains an "auto" ShaderAttrib, then an explicit
223  // ShaderAttrib will be synthesized by the runtime and stored here. I can't
224  // declare this as a ShaderAttrib because that would create a circular
225  // include-file dependency problem. Aaargh.
226  mutable CPT(RenderAttrib) _generated_shader;
227  mutable UpdateSeq _generated_shader_seq;
228 
229 private:
230  // This mutex protects _states. It also protects any modification to the
231  // cache, which is encoded in _composition_cache and
232  // _invert_composition_cache.
233  static LightReMutex *_states_lock;
235  static States *_states;
236  static const RenderState *_empty_state;
237 
238  // This iterator records the entry corresponding to this RenderState object
239  // in the above global set. We keep the index around so we can remove it
240  // when the RenderState destructs.
241  int _saved_entry;
242 
243  // This data structure manages the job of caching the composition of two
244  // RenderStates. It's complicated because we have to be sure to remove the
245  // entry if *either* of the input RenderStates destructs. To implement
246  // this, we always record Composition entries in pairs, one in each of the
247  // two involved RenderState objects.
248  class Composition {
249  public:
250  INLINE Composition();
251  INLINE Composition(const Composition &copy);
252 
253  // _result is reference counted if and only if it is not the same pointer
254  // as this.
255  const RenderState *_result;
256  };
257 
258  // The first element of the map is the object we compose with. This is not
259  // reference counted within this map; instead we store a companion pointer
260  // in the other object, and remove the references explicitly when either
261  // object destructs.
263  CompositionCache _composition_cache;
264  CompositionCache _invert_composition_cache;
265 
266  // This is here to provide a quick cache of GSG + RenderState -> GeomMunger
267  // for the cull phase. It is here because it is faster to look up the GSG
268  // in the RenderState pointer than vice-versa, since there are likely to be
269  // far fewer GSG's than RenderStates. The code to manage this map lives in
270  // GraphicsStateGuardian::get_geom_munger().
271  typedef SimpleHashMap<size_t, PT(GeomMunger), size_t_hash> Mungers;
272  mutable Mungers _mungers;
273  mutable int _last_mi;
274 
275  // Similarly, this is a cache of munged states. This map is managed by
276  // StateMunger::munge_state().
277  typedef SimpleHashMap<size_t, WCPT(RenderState), size_t_hash> MungedStates;
278  mutable MungedStates _munged_states;
279 
280  // This is used to mark nodes as we visit them to detect cycles.
281  UpdateSeq _cycle_detect;
282  static UpdateSeq _last_cycle_detect;
283 
284  // This keeps track of our current position through the garbage collection
285  // cycle.
286  static size_t _garbage_index;
287 
288  static PStatCollector _cache_update_pcollector;
289  static PStatCollector _garbage_collect_pcollector;
290  static PStatCollector _state_compose_pcollector;
291  static PStatCollector _state_invert_pcollector;
292  static PStatCollector _state_break_cycles_pcollector;
293  static PStatCollector _state_validate_pcollector;
294 
295  static PStatCollector _node_counter;
296  static PStatCollector _cache_counter;
297 
298 private:
299  // This is the actual data within the RenderState: a set of max_slots
300  // RenderAttribs.
301  class Attribute {
302  public:
303  INLINE Attribute(const RenderAttrib *attrib, int override);
304  INLINE Attribute(int override = 0);
305  INLINE Attribute(const Attribute &copy);
306  INLINE void operator = (const Attribute &copy);
307  INLINE void set(const RenderAttrib *attrib, int override);
308  INLINE int compare_to(const Attribute &other) const;
309 
310  CPT(RenderAttrib) _attrib;
311  int _override;
312  };
313  Attribute _attributes[RenderAttribRegistry::_max_slots];
314 
315  // We also store a bitmask of the non-NULL attributes in the above array.
316  // This is redundant, but it is a useful cache.
317  SlotMask _filled_slots;
318 
319  // We cache the index to the associated CullBin, if there happens to be a
320  // CullBinAttrib in the state.
321  int _bin_index;
322  int _draw_order;
323  size_t _hash;
324 
325  enum Flags {
326  F_checked_bin_index = 0x000001,
327  F_checked_cull_callback = 0x000002,
328  F_has_cull_callback = 0x000004,
329  F_is_destructing = 0x000008,
330  F_hash_known = 0x000010,
331  };
332  unsigned int _flags;
333 
334  vector_int *_read_overrides; // Only used during bam reading.
335 
336  // This mutex protects _flags, and all of the above computed values.
337  LightMutex _lock;
338 
339  static CacheStats _cache_stats;
340 
341 public:
342  static void register_with_read_factory();
343  virtual void write_datagram(BamWriter *manager, Datagram &dg);
344  virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
345  static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager);
346  virtual void finalize(BamReader *manager);
347 
348 protected:
349  static TypedWritable *make_from_bam(const FactoryParams &params);
350  void fillin(DatagramIterator &scan, BamReader *manager);
351 
352 public:
353  static TypeHandle get_class_type() {
354  return _type_handle;
355  }
356  static void init_type() {
357  NodeCachedReferenceCount::init_type();
358  register_type(_type_handle, "RenderState",
359  NodeCachedReferenceCount::get_class_type());
360  }
361  virtual TypeHandle get_type() const {
362  return get_class_type();
363  }
364  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
365 
366 private:
367  static TypeHandle _type_handle;
368 
369  friend class GraphicsStateGuardian;
370  friend class RenderAttribRegistry;
371  friend class Extension<RenderState>;
372  friend class ShaderGenerator;
373  friend class StateMunger;
374 };
375 
376 // We can safely redefine this as a no-op.
377 template<>
378 INLINE void PointerToBase<RenderState>::update_type(To *ptr) {}
379 
380 INLINE std::ostream &operator << (std::ostream &out, const RenderState &state) {
381  state.output(out);
382  return out;
383 }
384 
385 #include "renderState.I"
386 
387 #endif
This is just a simple derivative of GeomMunger that adds the ability to munge states.
Definition: stateMunger.h:26
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
This class further specializes CachedTypedWritableReferenceCount to also add a node_ref_count,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
Definition: geomMunger.h:50
This is the base class for PointerTo and ConstPointerTo.
Definition: pointerToBase.h:29
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight reentrant mutex.
Definition: lightReMutex.h:30
This collects together the pieces of data that are accumulated for each node while walking the scene ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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:81
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
This is our own Panda specialization on the default STL list.
Definition: plist.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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().
This class is used to associate each RenderAttrib with a different slot index at runtime,...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
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:34
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
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
An STL function object class, this is intended to be used on any ordered collection of class objects ...
Definition: stl_compares.h:73
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is used to track the utilization of the TransformState and RenderState caches,...
Definition: cacheStats.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Encapsulates all the communication with a particular instance of a given rendering backend.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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:81
This is a sequence number that increments monotonically.
Definition: updateSeq.h:37
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition: lightMutex.h:39
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
virtual bool unref() const
Explicitly decrements the reference count.