Panda3D

renderState.I

00001 // Filename: renderState.I
00002 // Created by:  drose (21Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: RenderState::is_empty
00018 //       Access: Published
00019 //  Description: Returns true if the state is empty, false otherwise.
00020 ////////////////////////////////////////////////////////////////////
00021 INLINE bool RenderState::
00022 is_empty() const {
00023   return _filled_slots.is_zero();
00024 }
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: RenderState::has_cull_callback
00028 //       Access: Published
00029 //  Description: Returns true if any of the RenderAttribs in this
00030 //               state request a cull_callback(), false if none of
00031 //               them do.
00032 ////////////////////////////////////////////////////////////////////
00033 INLINE bool RenderState::
00034 has_cull_callback() const {
00035   if ((_flags & F_checked_cull_callback) == 0) {
00036     // We pretend this function is const, even though it transparently
00037     // modifies the internal shader cache.
00038     ((RenderState *)this)->determine_cull_callback();
00039   }
00040   return (_flags & F_has_cull_callback) != 0;
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: RenderState::remove_attrib
00045 //       Access: Published
00046 //  Description: Returns a new RenderState object that represents the
00047 //               same as the source state, with the indicated
00048 //               RenderAttrib removed.
00049 ////////////////////////////////////////////////////////////////////
00050 INLINE CPT(RenderState) RenderState::
00051 remove_attrib(TypeHandle type) const {
00052   RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
00053   int slot = reg->get_slot(type);
00054   return remove_attrib(slot);
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: RenderState::has_attrib
00059 //       Access: Published
00060 //  Description: Returns true if an attrib of the indicated type is
00061 //               present, false otherwise.
00062 ////////////////////////////////////////////////////////////////////
00063 INLINE bool RenderState::
00064 has_attrib(TypeHandle type) const {
00065   return get_attrib(type) != (RenderAttrib *)NULL;
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: RenderState::has_attrib
00070 //       Access: Published
00071 //  Description: Returns true if an attrib of the indicated type is
00072 //               present, false otherwise.
00073 ////////////////////////////////////////////////////////////////////
00074 INLINE bool RenderState::
00075 has_attrib(int slot) const {
00076   return get_attrib(slot) != (RenderAttrib *)NULL;
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: RenderState::get_attrib
00081 //       Access: Published
00082 //  Description: Looks for a RenderAttrib of the indicated type in the
00083 //               state, and returns it if it is found, or NULL if it
00084 //               is not.
00085 ////////////////////////////////////////////////////////////////////
00086 INLINE const RenderAttrib *RenderState::
00087 get_attrib(TypeHandle type) const {
00088   RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr();
00089   int slot = reg->get_slot(type);
00090   return _attributes[slot]._attrib;
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: RenderState::get_attrib
00095 //       Access: Published
00096 //  Description: Returns the RenderAttrib with the indicated slot
00097 //               index, or NULL if there is no such RenderAttrib in
00098 //               the state.
00099 ////////////////////////////////////////////////////////////////////
00100 INLINE const RenderAttrib *RenderState::
00101 get_attrib(int slot) const {
00102   return _attributes[slot]._attrib;
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: RenderState::get_attrib_def
00107 //       Access: Published
00108 //  Description: Returns the RenderAttrib with the indicated slot
00109 //               index, or the default attrib for that slot if there
00110 //               is no such RenderAttrib in the state.
00111 ////////////////////////////////////////////////////////////////////
00112 INLINE const RenderAttrib *RenderState::
00113 get_attrib_def(int slot) const {
00114   if (_attributes[slot]._attrib != (RenderAttrib *)NULL) {
00115     return _attributes[slot]._attrib;
00116   }
00117   return make_full_default()->get_attrib(slot);
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: RenderState::get_override
00122 //       Access: Published
00123 //  Description: Looks for a RenderAttrib of the indicated type in the
00124 //               state, and returns its override value if it is found,
00125 //               or 0 if it is not.
00126 ////////////////////////////////////////////////////////////////////
00127 INLINE int RenderState::
00128 get_override(TypeHandle type) const {
00129   RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr();
00130   int slot = reg->get_slot(type);
00131   return _attributes[slot]._override;
00132 }
00133 
00134 ////////////////////////////////////////////////////////////////////
00135 //     Function: RenderState::get_override
00136 //       Access: Published
00137 //  Description: Looks for a RenderAttrib of the indicated type in the
00138 //               state, and returns its override value if it is found,
00139 //               or 0 if it is not.
00140 ////////////////////////////////////////////////////////////////////
00141 INLINE int RenderState::
00142 get_override(int slot) const {
00143   return _attributes[slot]._override;
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: RenderState::get_unique
00148 //       Access: Published
00149 //  Description: Returns the pointer to the unique RenderState in
00150 //               the cache that is equivalent to this one.  This may
00151 //               be the same pointer as this object, or it may be a
00152 //               different pointer; but it will be an equivalent
00153 //               object, and it will be a shared pointer.  This may be
00154 //               called from time to time to improve cache benefits.
00155 ////////////////////////////////////////////////////////////////////
00156 INLINE CPT(RenderState) RenderState::
00157 get_unique() const {
00158   return return_unique((RenderState *)this);
00159 }
00160 
00161 ////////////////////////////////////////////////////////////////////
00162 //     Function: RenderState::cache_ref
00163 //       Access: Published
00164 //  Description: Overrides this method to update PStats appropriately.
00165 ////////////////////////////////////////////////////////////////////
00166 INLINE void RenderState::
00167 cache_ref() const {
00168 #ifdef DO_PSTATS
00169   int old_referenced_bits = get_referenced_bits();
00170   NodeCachedReferenceCount::cache_ref();
00171   consider_update_pstats(old_referenced_bits);
00172 #else  // DO_PSTATS
00173   NodeCachedReferenceCount::cache_ref();
00174 #endif  // DO_PSTATS
00175 }
00176 
00177 ////////////////////////////////////////////////////////////////////
00178 //     Function: RenderState::cache_unref
00179 //       Access: Published
00180 //  Description: Overrides this method to update PStats appropriately.
00181 ////////////////////////////////////////////////////////////////////
00182 INLINE bool RenderState::
00183 cache_unref() const {
00184 #ifdef DO_PSTATS
00185   int old_referenced_bits = get_referenced_bits();
00186   bool result = do_cache_unref();
00187   consider_update_pstats(old_referenced_bits);
00188   return result;
00189 #else  // DO_PSTATS
00190   return do_cache_unref();
00191 #endif  // DO_PSTATS
00192 }
00193 
00194 ////////////////////////////////////////////////////////////////////
00195 //     Function: RenderState::node_ref
00196 //       Access: Published
00197 //  Description: Overrides this method to update PStats appropriately.
00198 ////////////////////////////////////////////////////////////////////
00199 INLINE void RenderState::
00200 node_ref() const {
00201 #ifdef DO_PSTATS
00202   int old_referenced_bits = get_referenced_bits();
00203   NodeCachedReferenceCount::node_ref();
00204   consider_update_pstats(old_referenced_bits);
00205 #else  // DO_PSTATS
00206   NodeCachedReferenceCount::node_ref();
00207 #endif  // DO_PSTATS
00208 }
00209 
00210 ////////////////////////////////////////////////////////////////////
00211 //     Function: RenderState::node_unref
00212 //       Access: Published
00213 //  Description: Overrides this method to update PStats appropriately.
00214 ////////////////////////////////////////////////////////////////////
00215 INLINE bool RenderState::
00216 node_unref() const {
00217 #ifdef DO_PSTATS
00218   int old_referenced_bits = get_referenced_bits();
00219   bool result = do_node_unref();
00220   consider_update_pstats(old_referenced_bits);
00221   return result;
00222 #else  // DO_PSTATS
00223   return do_node_unref();
00224 #endif  // DO_PSTATS
00225 }
00226 
00227 ////////////////////////////////////////////////////////////////////
00228 //     Function: RenderState::get_composition_cache_num_entries
00229 //       Access: Published
00230 //  Description: Returns the number of entries in the composition
00231 //               cache for this RenderState.  This is the number of
00232 //               other RenderStates whose composition with this one
00233 //               has been cached.  This number is not useful for any
00234 //               practical reason other than performance analysis.
00235 ////////////////////////////////////////////////////////////////////
00236 INLINE int RenderState::
00237 get_composition_cache_num_entries() const {
00238   LightReMutexHolder holder(*_states_lock);
00239   return _composition_cache.get_num_entries();
00240 }
00241 
00242 ////////////////////////////////////////////////////////////////////
00243 //     Function: RenderState::get_invert_composition_cache_num_entries
00244 //       Access: Published
00245 //  Description: Returns the number of entries in the
00246 //               invert_composition cache for this RenderState.
00247 //               This is similar to the composition cache, but it
00248 //               records cache entries for the invert_compose()
00249 //               operation.  See get_composition_cache_num_entries().
00250 ////////////////////////////////////////////////////////////////////
00251 INLINE int RenderState::
00252 get_invert_composition_cache_num_entries() const {
00253   LightReMutexHolder holder(*_states_lock);
00254   return _invert_composition_cache.get_num_entries();
00255 }
00256 
00257 ////////////////////////////////////////////////////////////////////
00258 //     Function: RenderState::get_composition_cache_size
00259 //       Access: Published
00260 //  Description: Returns the number of slots in the composition
00261 //               cache for this RenderState.  You may use this as
00262 //               an upper bound when walking through all of the
00263 //               composition cache results via
00264 //               get_composition_cache_source() or result().
00265 //
00266 //               This has no practical value other than for examining
00267 //               the cache for performance analysis.
00268 ////////////////////////////////////////////////////////////////////
00269 INLINE int RenderState::
00270 get_composition_cache_size() const {
00271   LightReMutexHolder holder(*_states_lock);
00272   return _composition_cache.get_size();
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: RenderState::get_composition_cache_source
00277 //       Access: Published
00278 //  Description: Returns the source RenderState of the nth element
00279 //               in the composition cache.  Returns NULL if there
00280 //               doesn't happen to be an entry in the nth element.
00281 //               See get_composition_cache_result().
00282 //
00283 //               This has no practical value other than for examining
00284 //               the cache for performance analysis.
00285 ////////////////////////////////////////////////////////////////////
00286 INLINE const RenderState *RenderState::
00287 get_composition_cache_source(int n) const {
00288   LightReMutexHolder holder(*_states_lock);
00289   if (!_composition_cache.has_element(n)) {
00290     return NULL;
00291   }
00292   return _composition_cache.get_key(n);
00293 }
00294 
00295 ////////////////////////////////////////////////////////////////////
00296 //     Function: RenderState::get_composition_cache_result
00297 //       Access: Published
00298 //  Description: Returns the result RenderState of the nth element
00299 //               in the composition cache.  Returns NULL if there
00300 //               doesn't happen to be an entry in the nth element.
00301 //
00302 //               In general,
00303 //               a->compose(a->get_composition_cache_source(n)) ==
00304 //               a->get_composition_cache_result(n).
00305 //
00306 //               This has no practical value other than for examining
00307 //               the cache for performance analysis.
00308 ////////////////////////////////////////////////////////////////////
00309 INLINE const RenderState *RenderState::
00310 get_composition_cache_result(int n) const {
00311   LightReMutexHolder holder(*_states_lock);
00312   if (!_composition_cache.has_element(n)) {
00313     return NULL;
00314   }
00315   return _composition_cache.get_data(n)._result;
00316 }
00317 
00318 ////////////////////////////////////////////////////////////////////
00319 //     Function: RenderState::get_invert_composition_cache_size
00320 //       Access: Published
00321 //  Description: Returns the number of slots in the composition
00322 //               cache for this RenderState.  You may use this as
00323 //               an upper bound when walking through all of the
00324 //               composition cache results via
00325 //               get_invert_composition_cache_source() or result().
00326 //
00327 //               This has no practical value other than for examining
00328 //               the cache for performance analysis.
00329 ////////////////////////////////////////////////////////////////////
00330 INLINE int RenderState::
00331 get_invert_composition_cache_size() const {
00332   LightReMutexHolder holder(*_states_lock);
00333   return _invert_composition_cache.get_size();
00334 }
00335 
00336 ////////////////////////////////////////////////////////////////////
00337 //     Function: RenderState::get_invert_composition_cache_source
00338 //       Access: Published
00339 //  Description: Returns the source RenderState of the nth element
00340 //               in the invert composition cache.  Returns NULL if
00341 //               there doesn't happen to be an entry in the nth
00342 //               element.  See get_invert_composition_cache_result().
00343 //
00344 //               This has no practical value other than for examining
00345 //               the cache for performance analysis.
00346 ////////////////////////////////////////////////////////////////////
00347 INLINE const RenderState *RenderState::
00348 get_invert_composition_cache_source(int n) const {
00349   LightReMutexHolder holder(*_states_lock);
00350   if (!_invert_composition_cache.has_element(n)) {
00351     return NULL;
00352   }
00353   return _invert_composition_cache.get_key(n);
00354 }
00355 
00356 ////////////////////////////////////////////////////////////////////
00357 //     Function: RenderState::get_invert_composition_cache_result
00358 //       Access: Published
00359 //  Description: Returns the result RenderState of the nth element
00360 //               in the invert composition cache.  Returns NULL if
00361 //               there doesn't happen to be an entry in the nth
00362 //               element.
00363 //
00364 //               In general,
00365 //               a->invert_compose(a->get_invert_composition_cache_source(n))
00366 //               == a->get_invert_composition_cache_result(n).
00367 //
00368 //               This has no practical value other than for examining
00369 //               the cache for performance analysis.
00370 ////////////////////////////////////////////////////////////////////
00371 INLINE const RenderState *RenderState::
00372 get_invert_composition_cache_result(int n) const {
00373   LightReMutexHolder holder(*_states_lock);
00374   if (!_invert_composition_cache.has_element(n)) {
00375     return NULL;
00376   }
00377   return _invert_composition_cache.get_data(n)._result;
00378 }
00379 
00380 ////////////////////////////////////////////////////////////////////
00381 //     Function: RenderState::get_draw_order
00382 //       Access: Published
00383 //  Description: Returns the draw order indicated by the
00384 //               CullBinAttrib, if any, associated by this state (or 0
00385 //               if there is no CullBinAttrib).  See get_bin_index().
00386 ////////////////////////////////////////////////////////////////////
00387 INLINE int RenderState::
00388 get_draw_order() const {
00389   if ((_flags & F_checked_bin_index) == 0) {
00390     // We pretend this function is const, even though it transparently
00391     // modifies the internal draw_order cache.
00392     ((RenderState *)this)->determine_bin_index();
00393   }
00394   return _draw_order;
00395 }
00396 
00397 ////////////////////////////////////////////////////////////////////
00398 //     Function: RenderState::get_bin_index
00399 //       Access: Published
00400 //  Description: Returns the bin index indicated by the CullBinAttrib,
00401 //               if any, associated by this state (or the default bin
00402 //               index if there is no CullBinAttrib).  This function
00403 //               is provided as an optimization for determining this
00404 //               at render time.
00405 ////////////////////////////////////////////////////////////////////
00406 INLINE int RenderState::
00407 get_bin_index() const {
00408   if ((_flags & F_checked_bin_index) == 0) {
00409     // We pretend this function is const, even though it transparently
00410     // modifies the internal bin_index cache.
00411     ((RenderState *)this)->determine_bin_index();
00412   }
00413   return _bin_index;
00414 }
00415 
00416 ////////////////////////////////////////////////////////////////////
00417 //     Function: RenderState::set_destructing
00418 //       Access: Private
00419 //  Description: This function should only be called from the
00420 //               destructor; it indicates that this RenderState
00421 //               object is beginning destruction.  It is only used as
00422 //               a sanity check, and is only meaningful when NDEBUG is
00423 //               not defined.
00424 ////////////////////////////////////////////////////////////////////
00425 INLINE void RenderState::
00426 set_destructing() {
00427 #ifndef NDEBUG
00428   _flags |= F_is_destructing;
00429 #endif
00430 }
00431 
00432 ////////////////////////////////////////////////////////////////////
00433 //     Function: RenderState::is_destructing
00434 //       Access: Private
00435 //  Description: Returns true if the RenderState object is
00436 //               currently within its destructor
00437 //               (i.e. set_destructing() has been called).  This is
00438 //               only used as a sanity check, and is only meaningful
00439 //               when NDEBUG is not defined.
00440 ////////////////////////////////////////////////////////////////////
00441 INLINE bool RenderState::
00442 is_destructing() const {
00443 #ifndef NDEBUG
00444   return (_flags & F_is_destructing) != 0;
00445 #else
00446   return false;
00447 #endif
00448 }
00449 
00450 ////////////////////////////////////////////////////////////////////
00451 //     Function: RenderState::consider_update_pstats
00452 //       Access: Private
00453 //  Description: Calls update_pstats() if the state of the referenced
00454 //               bits has changed from the indicated value.
00455 ////////////////////////////////////////////////////////////////////
00456 INLINE void RenderState::
00457 consider_update_pstats(int old_referenced_bits) const {
00458 #ifdef DO_PSTATS
00459   int new_referenced_bits = get_referenced_bits();
00460   if (old_referenced_bits != new_referenced_bits) {
00461     update_pstats(old_referenced_bits, new_referenced_bits);
00462   }
00463 #endif  // DO_PSTATS
00464 }
00465 
00466 ////////////////////////////////////////////////////////////////////
00467 //     Function: RenderState::Composition::Constructor
00468 //       Access: Public
00469 //  Description: 
00470 ////////////////////////////////////////////////////////////////////
00471 INLINE RenderState::Composition::
00472 Composition() {
00473 }
00474 
00475 ////////////////////////////////////////////////////////////////////
00476 //     Function: RenderState::Composition::Copy Constructor
00477 //       Access: Public
00478 //  Description: 
00479 ////////////////////////////////////////////////////////////////////
00480 INLINE RenderState::Composition::
00481 Composition(const RenderState::Composition &copy) :
00482   _result(copy._result)
00483 {
00484 }
00485 
00486 ////////////////////////////////////////////////////////////////////
00487 //     Function: RenderState::Attribute::Constructor
00488 //       Access: Public
00489 //  Description:
00490 ////////////////////////////////////////////////////////////////////
00491 INLINE RenderState::Attribute::
00492 Attribute(const RenderAttrib *attrib, int override) :
00493   _attrib(attrib),
00494   _override(override)
00495 {
00496 }
00497 
00498 ////////////////////////////////////////////////////////////////////
00499 //     Function: RenderState::Attribute::Constructor
00500 //       Access: Public
00501 //  Description: 
00502 ////////////////////////////////////////////////////////////////////
00503 INLINE RenderState::Attribute::
00504 Attribute(int override) :
00505   _override(override)
00506 {
00507 }
00508 
00509 ////////////////////////////////////////////////////////////////////
00510 //     Function: RenderState::Attribute::Copy Constructor
00511 //       Access: Public
00512 //  Description:
00513 ////////////////////////////////////////////////////////////////////
00514 INLINE RenderState::Attribute::
00515 Attribute(const Attribute &copy) :
00516   _attrib(copy._attrib),
00517   _override(copy._override)
00518 {
00519 }
00520 
00521 ////////////////////////////////////////////////////////////////////
00522 //     Function: RenderState::Attribute::Copy Assignment Operator
00523 //       Access: Public
00524 //  Description:
00525 ////////////////////////////////////////////////////////////////////
00526 INLINE void RenderState::Attribute::
00527 operator = (const Attribute &copy) {
00528   _attrib = copy._attrib;
00529   _override = copy._override;
00530 }
00531 
00532 ////////////////////////////////////////////////////////////////////
00533 //     Function: RenderState::Attribute::compare_to
00534 //       Access: Public
00535 //  Description: Provides an indication of whether a particular
00536 //               attribute is equivalent to another one, for purposes
00537 //               of generating unique RenderStates.  This should
00538 //               compare all properties of the Attribute.
00539 ////////////////////////////////////////////////////////////////////
00540 INLINE int RenderState::Attribute::
00541 compare_to(const Attribute &other) const {
00542   if (_attrib != other._attrib) {
00543     return _attrib < other._attrib ? -1 : 1;
00544   }
00545   return _override - other._override;
00546 }
00547 
00548 ////////////////////////////////////////////////////////////////////
00549 //     Function: RenderState::Attribute::set
00550 //       Access: Public
00551 //  Description:
00552 ////////////////////////////////////////////////////////////////////
00553 INLINE void RenderState::Attribute::
00554 set(const RenderAttrib *attrib, int override) {
00555   _attrib = attrib;
00556   _override = override;
00557 }
00558 
00559 ////////////////////////////////////////////////////////////////////
00560 //     Function: RenderState::flush_level
00561 //       Access: Public, Static
00562 //  Description: Flushes the PStatCollectors used during traversal.
00563 ////////////////////////////////////////////////////////////////////
00564 INLINE void RenderState::
00565 flush_level() {
00566   _node_counter.flush_level();
00567   _cache_counter.flush_level();
00568 }
00569 
00570 ////////////////////////////////////////////////////////////////////
00571 //     Function: RenderState::do_node_unref
00572 //       Access: Private
00573 //  Description: Reimplements NodeReferenceCount::node_unref().  We do
00574 //               this because we have a non-virtual unref() method.
00575 ////////////////////////////////////////////////////////////////////
00576 INLINE bool RenderState::
00577 do_node_unref() const {
00578   node_unref_only();
00579   return unref();
00580 }
00581 
00582 ////////////////////////////////////////////////////////////////////
00583 //     Function: RenderState::do_cache_unref
00584 //       Access: Private
00585 //  Description: Reimplements
00586 //               CachedTypedWritableReferenceCount::cache_unref().  We
00587 //               do this because we have a non-virtual unref() method.
00588 ////////////////////////////////////////////////////////////////////
00589 INLINE bool RenderState::
00590 do_cache_unref() const {
00591   cache_unref_only();
00592   return unref();
00593 }
00594 
00595 ////////////////////////////////////////////////////////////////////
00596 //     Function: RenderState::CompositionCycleDescEntry::Constructor
00597 //       Access: Public
00598 //  Description: 
00599 ////////////////////////////////////////////////////////////////////
00600 INLINE RenderState::CompositionCycleDescEntry::
00601 CompositionCycleDescEntry(const RenderState *obj,
00602                           const RenderState *result,
00603                           bool inverted) :
00604   _obj(obj),
00605   _result(result),
00606   _inverted(inverted)
00607 {
00608 }
00609 
 All Classes Functions Variables Enumerations