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