open_toontown_panda3d/panda/src/pgraph/renderState.I

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 &copy) :
_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 &copy) :
_attrib(copy._attrib),
_override(copy._override)
{
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::Attribute::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void RenderState::Attribute::
operator = (const Attribute &copy) {
_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)
{
}