Panda3D
renderState.I
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.I
10  * @author drose
11  * @date 2002-02-21
12  */
13 
14 /**
15  * Returns a suitable hash value for phash_map.
16  */
17 INLINE size_t RenderState::
18 get_hash() const {
19  check_hash();
20  return _hash;
21 }
22 
23 /**
24  * Returns true if the state is empty, false otherwise.
25  */
26 INLINE bool RenderState::
27 is_empty() const {
28  return _filled_slots.is_zero();
29 }
30 
31 /**
32  * Returns true if any of the RenderAttribs in this state request a
33  * cull_callback(), false if none of them do.
34  */
35 INLINE bool RenderState::
36 has_cull_callback() const {
37  if ((_flags & F_checked_cull_callback) == 0) {
38  // We pretend this function is const, even though it transparently
39  // modifies the internal shader cache.
40  ((RenderState *)this)->determine_cull_callback();
41  }
42  return (_flags & F_has_cull_callback) != 0;
43 }
44 
45 /**
46  * Returns a RenderState with no attributes set.
47  */
48 INLINE CPT(RenderState) RenderState::
49 make_empty() {
50  return _empty_state;
51 }
52 
53 /**
54  * Returns a new RenderState object that represents the same as the source
55  * state, with the indicated RenderAttrib removed.
56  */
57 INLINE CPT(RenderState) RenderState::
58 remove_attrib(TypeHandle type) const {
60  int slot = reg->get_slot(type);
61  return remove_attrib(slot);
62 }
63 
64 /**
65  * Returns true if an attrib of the indicated type is present, false
66  * otherwise.
67  */
68 INLINE bool RenderState::
69 has_attrib(TypeHandle type) const {
70  return get_attrib(type) != nullptr;
71 }
72 
73 /**
74  * Returns true if an attrib of the indicated type is present, false
75  * otherwise.
76  */
77 INLINE bool RenderState::
78 has_attrib(int slot) const {
79  return get_attrib(slot) != nullptr;
80 }
81 
82 /**
83  * Looks for a RenderAttrib of the indicated type in the state, and returns it
84  * if it is found, or NULL if it is not.
85  */
86 INLINE const RenderAttrib *RenderState::
87 get_attrib(TypeHandle type) const {
88  RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr();
89  int slot = reg->get_slot(type);
90  return _attributes[slot]._attrib;
91 }
92 
93 /**
94  * Returns the RenderAttrib with the indicated slot index, or NULL if there is
95  * no such RenderAttrib in the state.
96  */
97 ALWAYS_INLINE const RenderAttrib *RenderState::
98 get_attrib(int slot) const {
99  return _attributes[slot]._attrib;
100 }
101 
102 /**
103  * Returns the RenderAttrib with the indicated slot index, or the default
104  * attrib for that slot if there is no such RenderAttrib in the state.
105  */
106 INLINE const RenderAttrib *RenderState::
107 get_attrib_def(int slot) const {
108  if (_attributes[slot]._attrib != nullptr) {
109  return _attributes[slot]._attrib;
110  }
112  return reg->get_slot_default(slot);
113 }
114 
115 /**
116  * Looks for a RenderAttrib of the indicated type in the state, and returns
117  * its override value if it is found, or 0 if it is not.
118  */
119 INLINE int RenderState::
120 get_override(TypeHandle type) const {
121  RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr();
122  int slot = reg->get_slot(type);
123  return _attributes[slot]._override;
124 }
125 
126 /**
127  * Looks for a RenderAttrib of the indicated type in the state, and returns
128  * its override value if it is found, or 0 if it is not.
129  */
130 INLINE int RenderState::
131 get_override(int slot) const {
132  return _attributes[slot]._override;
133 }
134 
135 /**
136  * Returns the pointer to the unique RenderState in the cache that is
137  * equivalent to this one. This may be the same pointer as this object, or it
138  * may be a different pointer; but it will be an equivalent object, and it
139  * will be a shared pointer. This may be called from time to time to improve
140  * cache benefits.
141  */
142 INLINE CPT(RenderState) RenderState::
143 get_unique() const {
144  return return_unique((RenderState *)this);
145 }
146 
147 /**
148  * Overrides this method to update PStats appropriately.
149  */
150 INLINE void RenderState::
151 cache_ref() const {
152 #ifdef DO_PSTATS
153  int old_referenced_bits = get_referenced_bits();
155  consider_update_pstats(old_referenced_bits);
156 #else // DO_PSTATS
158 #endif // DO_PSTATS
159 }
160 
161 /**
162  * Overrides this method to update PStats appropriately.
163  */
164 INLINE bool RenderState::
165 cache_unref() const {
166 #ifdef DO_PSTATS
167  int old_referenced_bits = get_referenced_bits();
168  bool result = do_cache_unref();
169  consider_update_pstats(old_referenced_bits);
170  return result;
171 #else // DO_PSTATS
172  return do_cache_unref();
173 #endif // DO_PSTATS
174 }
175 
176 /**
177  * Overrides this method to update PStats appropriately.
178  */
179 INLINE void RenderState::
180 node_ref() const {
181 #ifdef DO_PSTATS
182  int old_referenced_bits = get_referenced_bits();
184  consider_update_pstats(old_referenced_bits);
185 #else // DO_PSTATS
187 #endif // DO_PSTATS
188 }
189 
190 /**
191  * Overrides this method to update PStats appropriately.
192  */
193 INLINE bool RenderState::
194 node_unref() const {
195 #ifdef DO_PSTATS
196  int old_referenced_bits = get_referenced_bits();
197  bool result = do_node_unref();
198  consider_update_pstats(old_referenced_bits);
199  return result;
200 #else // DO_PSTATS
201  return do_node_unref();
202 #endif // DO_PSTATS
203 }
204 
205 /**
206  * Returns the number of entries in the composition cache for this
207  * RenderState. This is the number of other RenderStates whose composition
208  * with this one has been cached. This number is not useful for any practical
209  * reason other than performance analysis.
210  */
211 INLINE size_t RenderState::
212 get_composition_cache_num_entries() const {
213  LightReMutexHolder holder(*_states_lock);
214  return _composition_cache.get_num_entries();
215 }
216 
217 /**
218  * Returns the number of entries in the invert_composition cache for this
219  * RenderState. This is similar to the composition cache, but it records
220  * cache entries for the invert_compose() operation. See
221  * get_composition_cache_num_entries().
222  */
223 INLINE size_t RenderState::
224 get_invert_composition_cache_num_entries() const {
225  LightReMutexHolder holder(*_states_lock);
226  return _invert_composition_cache.get_num_entries();
227 }
228 
229 /**
230  * Returns the number of slots in the composition cache for this RenderState.
231  * You may use this as an upper bound when walking through all of the
232  * composition cache results via get_composition_cache_source() or result().
233  *
234  * This has no practical value other than for examining the cache for
235  * performance analysis.
236  */
237 INLINE size_t RenderState::
238 get_composition_cache_size() const {
239  LightReMutexHolder holder(*_states_lock);
240  return _composition_cache.get_num_entries();
241 }
242 
243 /**
244  * Returns the source RenderState of the nth element in the composition cache.
245  * Returns NULL if there doesn't happen to be an entry in the nth element.
246  * See get_composition_cache_result().
247  *
248  * This has no practical value other than for examining the cache for
249  * performance analysis.
250  */
251 INLINE const RenderState *RenderState::
252 get_composition_cache_source(size_t n) const {
253  LightReMutexHolder holder(*_states_lock);
254  return _composition_cache.get_key(n);
255 }
256 
257 /**
258  * Returns the result RenderState of the nth element in the composition cache.
259  * Returns NULL if there doesn't happen to be an entry in the nth element.
260  *
261  * In general, a->compose(a->get_composition_cache_source(n)) ==
262  * a->get_composition_cache_result(n).
263  *
264  * This has no practical value other than for examining the cache for
265  * performance analysis.
266  */
267 INLINE const RenderState *RenderState::
268 get_composition_cache_result(size_t n) const {
269  LightReMutexHolder holder(*_states_lock);
270  return _composition_cache.get_data(n)._result;
271 }
272 
273 /**
274  * Returns the number of slots in the composition cache for this RenderState.
275  * You may use this as an upper bound when walking through all of the
276  * composition cache results via get_invert_composition_cache_source() or
277  * result().
278  *
279  * This has no practical value other than for examining the cache for
280  * performance analysis.
281  */
282 INLINE size_t RenderState::
283 get_invert_composition_cache_size() const {
284  LightReMutexHolder holder(*_states_lock);
285  return _invert_composition_cache.get_num_entries();
286 }
287 
288 /**
289  * Returns the source RenderState of the nth element in the invert composition
290  * cache. Returns NULL if there doesn't happen to be an entry in the nth
291  * element. See get_invert_composition_cache_result().
292  *
293  * This has no practical value other than for examining the cache for
294  * performance analysis.
295  */
296 INLINE const RenderState *RenderState::
297 get_invert_composition_cache_source(size_t n) const {
298  LightReMutexHolder holder(*_states_lock);
299  return _invert_composition_cache.get_key(n);
300 }
301 
302 /**
303  * Returns the result RenderState of the nth element in the invert composition
304  * cache. Returns NULL if there doesn't happen to be an entry in the nth
305  * element.
306  *
307  * In general, a->invert_compose(a->get_invert_composition_cache_source(n)) ==
308  * a->get_invert_composition_cache_result(n).
309  *
310  * This has no practical value other than for examining the cache for
311  * performance analysis.
312  */
313 INLINE const RenderState *RenderState::
314 get_invert_composition_cache_result(size_t n) const {
315  LightReMutexHolder holder(*_states_lock);
316  return _invert_composition_cache.get_data(n)._result;
317 }
318 
319 /**
320  * Returns the draw order indicated by the CullBinAttrib, if any, associated
321  * by this state (or 0 if there is no CullBinAttrib). See get_bin_index().
322  */
323 INLINE int RenderState::
324 get_draw_order() const {
325  if ((_flags & F_checked_bin_index) == 0) {
326  // We pretend this function is const, even though it transparently
327  // modifies the internal draw_order cache.
328  ((RenderState *)this)->determine_bin_index();
329  }
330  return _draw_order;
331 }
332 
333 /**
334  * Returns the bin index indicated by the CullBinAttrib, if any, associated by
335  * this state (or the default bin index if there is no CullBinAttrib). This
336  * function is provided as an optimization for determining this at render
337  * time.
338  */
339 INLINE int RenderState::
340 get_bin_index() const {
341  if ((_flags & F_checked_bin_index) == 0) {
342  // We pretend this function is const, even though it transparently
343  // modifies the internal bin_index cache.
344  ((RenderState *)this)->determine_bin_index();
345  }
346  return _bin_index;
347 }
348 
349 /**
350  * This function should only be called from the destructor; it indicates that
351  * this RenderState object is beginning destruction. It is only used as a
352  * sanity check, and is only meaningful when NDEBUG is not defined.
353  */
354 INLINE void RenderState::
355 set_destructing() {
356 #ifndef NDEBUG
357  _flags |= F_is_destructing;
358 #endif
359 }
360 
361 /**
362  * Returns true if the RenderState object is currently within its destructor
363  * (i.e. set_destructing() has been called). This is only used as a sanity
364  * check, and is only meaningful when NDEBUG is not defined.
365  */
366 INLINE bool RenderState::
367 is_destructing() const {
368 #ifndef NDEBUG
369  return (_flags & F_is_destructing) != 0;
370 #else
371  return false;
372 #endif
373 }
374 
375 /**
376  * Calls update_pstats() if the state of the referenced bits has changed from
377  * the indicated value.
378  */
379 INLINE void RenderState::
380 consider_update_pstats(int old_referenced_bits) const {
381 #ifdef DO_PSTATS
382  int new_referenced_bits = get_referenced_bits();
383  if (old_referenced_bits != new_referenced_bits) {
384  update_pstats(old_referenced_bits, new_referenced_bits);
385  }
386 #endif // DO_PSTATS
387 }
388 
389 /**
390  *
391  */
392 INLINE RenderState::Composition::
393 Composition() {
394 }
395 
396 /**
397  *
398  */
399 INLINE RenderState::Composition::
400 Composition(const RenderState::Composition &copy) :
401  _result(copy._result)
402 {
403 }
404 
405 /**
406  *
407  */
408 INLINE RenderState::Attribute::
409 Attribute(const RenderAttrib *attrib, int override) :
410  _attrib(attrib),
411  _override(override)
412 {
413 }
414 
415 /**
416  *
417  */
418 INLINE RenderState::Attribute::
419 Attribute(int override) :
420  _override(override)
421 {
422 }
423 
424 /**
425  *
426  */
427 INLINE RenderState::Attribute::
428 Attribute(const Attribute &copy) :
429  _attrib(copy._attrib),
430  _override(copy._override)
431 {
432 }
433 
434 /**
435  *
436  */
437 INLINE void RenderState::Attribute::
438 operator = (const Attribute &copy) {
439  _attrib = copy._attrib;
440  _override = copy._override;
441 }
442 
443 /**
444  * Provides an indication of whether a particular attribute is equivalent to
445  * another one, for purposes of generating unique RenderStates. This should
446  * compare all properties of the Attribute.
447  */
448 INLINE int RenderState::Attribute::
449 compare_to(const Attribute &other) const {
450  if (_attrib != other._attrib) {
451  if (_attrib == nullptr) {
452  return -1;
453  } else if (other._attrib == nullptr) {
454  return 1;
455  }
456 
457  int c = _attrib->compare_to(*other._attrib);
458  if (c != 0) {
459  return c;
460  }
461  }
462 
463  return _override - other._override;
464 }
465 
466 /**
467  *
468  */
469 INLINE void RenderState::Attribute::
470 set(const RenderAttrib *attrib, int override) {
471  _attrib = attrib;
472  _override = override;
473 }
474 
475 /**
476  * Flushes the PStatCollectors used during traversal.
477  */
478 INLINE void RenderState::
479 flush_level() {
480  _node_counter.flush_level();
481  _cache_counter.flush_level();
482 }
483 
484 /**
485  * Overrides this method to update PStats appropriately.
486  */
487 INLINE void RenderState::
488 cache_ref_only() const {
489 #ifdef DO_PSTATS
490  int old_referenced_bits = get_referenced_bits();
492  consider_update_pstats(old_referenced_bits);
493 #else // DO_PSTATS
495 #endif // DO_PSTATS
496 }
497 
498 /**
499  * Overrides this method to update PStats appropriately.
500  */
501 INLINE void RenderState::
502 cache_unref_only() const {
503 #ifdef DO_PSTATS
504  int old_referenced_bits = get_referenced_bits();
505  NodeCachedReferenceCount::cache_unref_only();
506  consider_update_pstats(old_referenced_bits);
507 #else // DO_PSTATS
508  NodeCachedReferenceCount::cache_unref_only();
509 #endif // DO_PSTATS
510 }
511 
512 #ifndef CPPPARSER
513 /**
514  * Handy templated version of get_attrib that casts to the right type.
515  * Returns true if the attribute was present, false otherwise.
516  */
517 template<class AttribType>
518 INLINE bool RenderState::
519 get_attrib(const AttribType *&attrib) const {
520  attrib = (const AttribType *)get_attrib((int)AttribType::get_class_slot());
521  return (attrib != nullptr);
522 }
523 template<class AttribType>
524 INLINE bool RenderState::
525 get_attrib(CPT(AttribType) &attrib) const {
526  attrib = (const AttribType *)get_attrib((int)AttribType::get_class_slot());
527  return (attrib != nullptr);
528 }
529 
530 /**
531  * Handy templated version of get_attrib_def that casts to the right type.
532  */
533 template<class AttribType>
534 INLINE void RenderState::
535 get_attrib_def(const AttribType *&attrib) const {
536  attrib = (const AttribType *)get_attrib_def((int)AttribType::get_class_slot());
537 }
538 template<class AttribType>
539 INLINE void RenderState::
540 get_attrib_def(CPT(AttribType) &attrib) const {
541  attrib = (const AttribType *)get_attrib_def((int)AttribType::get_class_slot());
542 }
543 #endif // CPPPARSER
544 
545 /**
546  * Ensures that we know the hash value.
547  */
548 INLINE void RenderState::
549 check_hash() const {
550  // This pretends to be a const function, even though it's not, because it
551  // only updates a transparent cache value.
552  if ((_flags & F_hash_known) != 0) {
553  } else {
554  ((RenderState *)this)->calc_hash();
555  }
556 }
557 
558 /**
559  * Reimplements CachedTypedWritableReferenceCount::cache_unref(). We do this
560  * because we have a non-virtual unref() method.
561  */
562 INLINE bool RenderState::
563 do_cache_unref() const {
564  NodeCachedReferenceCount::cache_unref_only();
565  return unref();
566 }
567 
568 /**
569  * Reimplements NodeReferenceCount::node_unref(). We do this because we have
570  * a non-virtual unref() method.
571  */
572 INLINE bool RenderState::
573 do_node_unref() const {
574  node_unref_only();
575  return unref();
576 }
577 
578 /**
579  * Computes the hash value.
580  */
581 INLINE void RenderState::
582 calc_hash() {
583  LightMutexHolder holder(_lock);
584  do_calc_hash();
585 }
586 
587 /**
588  *
589  */
590 INLINE RenderState::CompositionCycleDescEntry::
591 CompositionCycleDescEntry(const RenderState *obj,
592  const RenderState *result,
593  bool inverted) :
594  _obj(obj),
595  _result(result),
596  _inverted(inverted)
597 {
598 }
bool is_zero() const
Returns true if the entire bitmask is zero, false otherwise.
Definition: bitMask.I:153
void cache_ref() const
Explicitly increments 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.
Similar to MutexHolder, but for a light mutex.
Similar to MutexHolder, but for a light reentrant mutex.
void node_ref() const
Explicitly increments the reference count.
int get_referenced_bits() const
Returns the union of the values defined in the Referenced enum that represents the various things tha...
This class is used to associate each RenderAttrib with a different slot index at runtime,...
const RenderAttrib * get_slot_default(int slot) const
Returns the default RenderAttrib object associated with slot n.
static RenderAttribRegistry * quick_get_global_ptr()
Returns the global_ptr without first ensuring it has been initialized.
int get_slot(TypeHandle type_handle) const
Returns the slot number assigned to the indicated TypeHandle, or 0 if no slot number has been assigne...
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
size_t get_hash() const
Returns a suitable hash value for phash_map.
Definition: renderState.I:18
void cache_ref_only() const
Overrides this method to update PStats appropriately.
Definition: renderState.I:488
bool is_empty() const
Returns true if the state is empty, false otherwise.
Definition: renderState.I:27
bool has_cull_callback() const
Returns true if any of the RenderAttribs in this state request a cull_callback(), false if none of th...
Definition: renderState.I:36
virtual bool unref() const
Explicitly decrements the reference count.
static void flush_level()
Flushes the PStatCollectors used during traversal.
Definition: renderState.I:479
const Key & get_key(size_t n) const
Returns the key in the nth entry of the table.
const Value & get_data(size_t n) const
Returns the data in the nth entry of the table.
size_t get_num_entries() const
Returns the number of active entries in the table.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
CPT(RenderState) RenderState
Returns a RenderState with no attributes set.
Definition: renderState.I:48