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