610 lines
23 KiB
Plaintext
610 lines
23 KiB
Plaintext
// Filename: renderState.I
|
|
// Created by: drose (21Feb02)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::is_empty
|
|
// Access: Published
|
|
// Description: Returns true if the state is empty, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
is_empty() const {
|
|
return _filled_slots.is_zero();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::has_cull_callback
|
|
// Access: Published
|
|
// Description: Returns true if any of the RenderAttribs in this
|
|
// state request a cull_callback(), false if none of
|
|
// them do.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
has_cull_callback() const {
|
|
if ((_flags & F_checked_cull_callback) == 0) {
|
|
// We pretend this function is const, even though it transparently
|
|
// modifies the internal shader cache.
|
|
((RenderState *)this)->determine_cull_callback();
|
|
}
|
|
return (_flags & F_has_cull_callback) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::remove_attrib
|
|
// Access: Published
|
|
// Description: Returns a new RenderState object that represents the
|
|
// same as the source state, with the indicated
|
|
// RenderAttrib removed.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CPT(RenderState) RenderState::
|
|
remove_attrib(TypeHandle type) const {
|
|
RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr();
|
|
int slot = reg->get_slot(type);
|
|
return remove_attrib(slot);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::has_attrib
|
|
// Access: Published
|
|
// Description: Returns true if an attrib of the indicated type is
|
|
// present, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
has_attrib(TypeHandle type) const {
|
|
return get_attrib(type) != (RenderAttrib *)NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::has_attrib
|
|
// Access: Published
|
|
// Description: Returns true if an attrib of the indicated type is
|
|
// present, false otherwise.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
has_attrib(int slot) const {
|
|
return get_attrib(slot) != (RenderAttrib *)NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_attrib
|
|
// Access: Published
|
|
// Description: Looks for a RenderAttrib of the indicated type in the
|
|
// state, and returns it if it is found, or NULL if it
|
|
// is not.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const RenderAttrib *RenderState::
|
|
get_attrib(TypeHandle type) const {
|
|
RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr();
|
|
int slot = reg->get_slot(type);
|
|
return _attributes[slot]._attrib;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_attrib
|
|
// Access: Published
|
|
// Description: Returns the RenderAttrib with the indicated slot
|
|
// index, or NULL if there is no such RenderAttrib in
|
|
// the state.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const RenderAttrib *RenderState::
|
|
get_attrib(int slot) const {
|
|
return _attributes[slot]._attrib;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_attrib_def
|
|
// Access: Published
|
|
// Description: Returns the RenderAttrib with the indicated slot
|
|
// index, or the default attrib for that slot if there
|
|
// is no such RenderAttrib in the state.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const RenderAttrib *RenderState::
|
|
get_attrib_def(int slot) const {
|
|
if (_attributes[slot]._attrib != (RenderAttrib *)NULL) {
|
|
return _attributes[slot]._attrib;
|
|
}
|
|
return make_full_default()->get_attrib(slot);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_override
|
|
// Access: Published
|
|
// Description: Looks for a RenderAttrib of the indicated type in the
|
|
// state, and returns its override value if it is found,
|
|
// or 0 if it is not.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_override(TypeHandle type) const {
|
|
RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr();
|
|
int slot = reg->get_slot(type);
|
|
return _attributes[slot]._override;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_override
|
|
// Access: Published
|
|
// Description: Looks for a RenderAttrib of the indicated type in the
|
|
// state, and returns its override value if it is found,
|
|
// or 0 if it is not.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_override(int slot) const {
|
|
return _attributes[slot]._override;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_unique
|
|
// Access: Published
|
|
// Description: Returns the pointer to the unique RenderState in
|
|
// the cache that is equivalent to this one. This may
|
|
// be the same pointer as this object, or it may be a
|
|
// different pointer; but it will be an equivalent
|
|
// object, and it will be a shared pointer. This may be
|
|
// called from time to time to improve cache benefits.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE CPT(RenderState) RenderState::
|
|
get_unique() const {
|
|
return return_unique((RenderState *)this);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::cache_ref
|
|
// Access: Published
|
|
// Description: Overrides this method to update PStats appropriately.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void RenderState::
|
|
cache_ref() const {
|
|
#ifdef DO_PSTATS
|
|
int old_referenced_bits = get_referenced_bits();
|
|
NodeCachedReferenceCount::cache_ref();
|
|
consider_update_pstats(old_referenced_bits);
|
|
#else // DO_PSTATS
|
|
NodeCachedReferenceCount::cache_ref();
|
|
#endif // DO_PSTATS
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::cache_unref
|
|
// Access: Published
|
|
// Description: Overrides this method to update PStats appropriately.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
cache_unref() const {
|
|
#ifdef DO_PSTATS
|
|
int old_referenced_bits = get_referenced_bits();
|
|
bool result = do_cache_unref();
|
|
consider_update_pstats(old_referenced_bits);
|
|
return result;
|
|
#else // DO_PSTATS
|
|
return do_cache_unref();
|
|
#endif // DO_PSTATS
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::node_ref
|
|
// Access: Published
|
|
// Description: Overrides this method to update PStats appropriately.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void RenderState::
|
|
node_ref() const {
|
|
#ifdef DO_PSTATS
|
|
int old_referenced_bits = get_referenced_bits();
|
|
NodeCachedReferenceCount::node_ref();
|
|
consider_update_pstats(old_referenced_bits);
|
|
#else // DO_PSTATS
|
|
NodeCachedReferenceCount::node_ref();
|
|
#endif // DO_PSTATS
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::node_unref
|
|
// Access: Published
|
|
// Description: Overrides this method to update PStats appropriately.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
node_unref() const {
|
|
#ifdef DO_PSTATS
|
|
int old_referenced_bits = get_referenced_bits();
|
|
bool result = do_node_unref();
|
|
consider_update_pstats(old_referenced_bits);
|
|
return result;
|
|
#else // DO_PSTATS
|
|
return do_node_unref();
|
|
#endif // DO_PSTATS
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_composition_cache_num_entries
|
|
// Access: Published
|
|
// Description: Returns the number of entries in the composition
|
|
// cache for this RenderState. This is the number of
|
|
// other RenderStates whose composition with this one
|
|
// has been cached. This number is not useful for any
|
|
// practical reason other than performance analysis.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_composition_cache_num_entries() const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
return _composition_cache.get_num_entries();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_invert_composition_cache_num_entries
|
|
// Access: Published
|
|
// Description: Returns the number of entries in the
|
|
// invert_composition cache for this RenderState.
|
|
// This is similar to the composition cache, but it
|
|
// records cache entries for the invert_compose()
|
|
// operation. See get_composition_cache_num_entries().
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_invert_composition_cache_num_entries() const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
return _invert_composition_cache.get_num_entries();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_composition_cache_size
|
|
// Access: Published
|
|
// Description: Returns the number of slots in the composition
|
|
// cache for this RenderState. You may use this as
|
|
// an upper bound when walking through all of the
|
|
// composition cache results via
|
|
// get_composition_cache_source() or result().
|
|
//
|
|
// This has no practical value other than for examining
|
|
// the cache for performance analysis.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_composition_cache_size() const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
return _composition_cache.get_size();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_composition_cache_source
|
|
// Access: Published
|
|
// Description: Returns the source RenderState of the nth element
|
|
// in the composition cache. Returns NULL if there
|
|
// doesn't happen to be an entry in the nth element.
|
|
// See get_composition_cache_result().
|
|
//
|
|
// This has no practical value other than for examining
|
|
// the cache for performance analysis.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const RenderState *RenderState::
|
|
get_composition_cache_source(int n) const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
if (!_composition_cache.has_element(n)) {
|
|
return NULL;
|
|
}
|
|
return _composition_cache.get_key(n);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_composition_cache_result
|
|
// Access: Published
|
|
// Description: Returns the result RenderState of the nth element
|
|
// in the composition cache. Returns NULL if there
|
|
// doesn't happen to be an entry in the nth element.
|
|
//
|
|
// In general,
|
|
// a->compose(a->get_composition_cache_source(n)) ==
|
|
// a->get_composition_cache_result(n).
|
|
//
|
|
// This has no practical value other than for examining
|
|
// the cache for performance analysis.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const RenderState *RenderState::
|
|
get_composition_cache_result(int n) const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
if (!_composition_cache.has_element(n)) {
|
|
return NULL;
|
|
}
|
|
return _composition_cache.get_data(n)._result;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_invert_composition_cache_size
|
|
// Access: Published
|
|
// Description: Returns the number of slots in the composition
|
|
// cache for this RenderState. You may use this as
|
|
// an upper bound when walking through all of the
|
|
// composition cache results via
|
|
// get_invert_composition_cache_source() or result().
|
|
//
|
|
// This has no practical value other than for examining
|
|
// the cache for performance analysis.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_invert_composition_cache_size() const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
return _invert_composition_cache.get_size();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_invert_composition_cache_source
|
|
// Access: Published
|
|
// Description: Returns the source RenderState of the nth element
|
|
// in the invert composition cache. Returns NULL if
|
|
// there doesn't happen to be an entry in the nth
|
|
// element. See get_invert_composition_cache_result().
|
|
//
|
|
// This has no practical value other than for examining
|
|
// the cache for performance analysis.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const RenderState *RenderState::
|
|
get_invert_composition_cache_source(int n) const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
if (!_invert_composition_cache.has_element(n)) {
|
|
return NULL;
|
|
}
|
|
return _invert_composition_cache.get_key(n);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_invert_composition_cache_result
|
|
// Access: Published
|
|
// Description: Returns the result RenderState of the nth element
|
|
// in the invert composition cache. Returns NULL if
|
|
// there doesn't happen to be an entry in the nth
|
|
// element.
|
|
//
|
|
// In general,
|
|
// a->invert_compose(a->get_invert_composition_cache_source(n))
|
|
// == a->get_invert_composition_cache_result(n).
|
|
//
|
|
// This has no practical value other than for examining
|
|
// the cache for performance analysis.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const RenderState *RenderState::
|
|
get_invert_composition_cache_result(int n) const {
|
|
LightReMutexHolder holder(*_states_lock);
|
|
if (!_invert_composition_cache.has_element(n)) {
|
|
return NULL;
|
|
}
|
|
return _invert_composition_cache.get_data(n)._result;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_draw_order
|
|
// Access: Published
|
|
// Description: Returns the draw order indicated by the
|
|
// CullBinAttrib, if any, associated by this state (or 0
|
|
// if there is no CullBinAttrib). See get_bin_index().
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_draw_order() const {
|
|
if ((_flags & F_checked_bin_index) == 0) {
|
|
// We pretend this function is const, even though it transparently
|
|
// modifies the internal draw_order cache.
|
|
((RenderState *)this)->determine_bin_index();
|
|
}
|
|
return _draw_order;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::get_bin_index
|
|
// Access: Published
|
|
// Description: Returns the bin index indicated by the CullBinAttrib,
|
|
// if any, associated by this state (or the default bin
|
|
// index if there is no CullBinAttrib). This function
|
|
// is provided as an optimization for determining this
|
|
// at render time.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::
|
|
get_bin_index() const {
|
|
if ((_flags & F_checked_bin_index) == 0) {
|
|
// We pretend this function is const, even though it transparently
|
|
// modifies the internal bin_index cache.
|
|
((RenderState *)this)->determine_bin_index();
|
|
}
|
|
return _bin_index;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::set_destructing
|
|
// Access: Private
|
|
// Description: This function should only be called from the
|
|
// destructor; it indicates that this RenderState
|
|
// object is beginning destruction. It is only used as
|
|
// a sanity check, and is only meaningful when NDEBUG is
|
|
// not defined.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void RenderState::
|
|
set_destructing() {
|
|
#ifndef NDEBUG
|
|
_flags |= F_is_destructing;
|
|
#endif
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::is_destructing
|
|
// Access: Private
|
|
// Description: Returns true if the RenderState object is
|
|
// currently within its destructor
|
|
// (i.e. set_destructing() has been called). This is
|
|
// only used as a sanity check, and is only meaningful
|
|
// when NDEBUG is not defined.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
is_destructing() const {
|
|
#ifndef NDEBUG
|
|
return (_flags & F_is_destructing) != 0;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::consider_update_pstats
|
|
// Access: Private
|
|
// Description: Calls update_pstats() if the state of the referenced
|
|
// bits has changed from the indicated value.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void RenderState::
|
|
consider_update_pstats(int old_referenced_bits) const {
|
|
#ifdef DO_PSTATS
|
|
int new_referenced_bits = get_referenced_bits();
|
|
if (old_referenced_bits != new_referenced_bits) {
|
|
update_pstats(old_referenced_bits, new_referenced_bits);
|
|
}
|
|
#endif // DO_PSTATS
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Composition::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE RenderState::Composition::
|
|
Composition() {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Composition::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE RenderState::Composition::
|
|
Composition(const RenderState::Composition ©) :
|
|
_result(copy._result)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Attribute::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE RenderState::Attribute::
|
|
Attribute(const RenderAttrib *attrib, int override) :
|
|
_attrib(attrib),
|
|
_override(override)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Attribute::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE RenderState::Attribute::
|
|
Attribute(int override) :
|
|
_override(override)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Attribute::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE RenderState::Attribute::
|
|
Attribute(const Attribute ©) :
|
|
_attrib(copy._attrib),
|
|
_override(copy._override)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Attribute::Copy Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void RenderState::Attribute::
|
|
operator = (const Attribute ©) {
|
|
_attrib = copy._attrib;
|
|
_override = copy._override;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Attribute::compare_to
|
|
// Access: Public
|
|
// Description: Provides an indication of whether a particular
|
|
// attribute is equivalent to another one, for purposes
|
|
// of generating unique RenderStates. This should
|
|
// compare all properties of the Attribute.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int RenderState::Attribute::
|
|
compare_to(const Attribute &other) const {
|
|
if (_attrib != other._attrib) {
|
|
return _attrib < other._attrib ? -1 : 1;
|
|
}
|
|
return _override - other._override;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::Attribute::set
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void RenderState::Attribute::
|
|
set(const RenderAttrib *attrib, int override) {
|
|
_attrib = attrib;
|
|
_override = override;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::flush_level
|
|
// Access: Public, Static
|
|
// Description: Flushes the PStatCollectors used during traversal.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void RenderState::
|
|
flush_level() {
|
|
_node_counter.flush_level();
|
|
_cache_counter.flush_level();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::do_node_unref
|
|
// Access: Private
|
|
// Description: Reimplements NodeReferenceCount::node_unref(). We do
|
|
// this because we have a non-virtual unref() method.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
do_node_unref() const {
|
|
node_unref_only();
|
|
return unref();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::do_cache_unref
|
|
// Access: Private
|
|
// Description: Reimplements
|
|
// CachedTypedWritableReferenceCount::cache_unref(). We
|
|
// do this because we have a non-virtual unref() method.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool RenderState::
|
|
do_cache_unref() const {
|
|
cache_unref_only();
|
|
return unref();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: RenderState::CompositionCycleDescEntry::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE RenderState::CompositionCycleDescEntry::
|
|
CompositionCycleDescEntry(const RenderState *obj,
|
|
const RenderState *result,
|
|
bool inverted) :
|
|
_obj(obj),
|
|
_result(result),
|
|
_inverted(inverted)
|
|
{
|
|
}
|
|
|