open_toontown_panda3d/panda/src/gobj/geomVertexArrayData.I

540 lines
21 KiB
Plaintext

// Filename: geomVertexArrayData.I
// Created by: drose (17Mar05)
//
////////////////////////////////////////////////////////////////////
//
// 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: GeomVertexArrayData::get_array_format
// Access: Published
// Description: Returns the format object that describes this array.
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayFormat *GeomVertexArrayData::
get_array_format() const {
return _array_format;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_usage_hint
// Access: Published
// Description: Returns the usage hint that describes to the
// rendering backend how often the vertex data will be
// modified and/or rendered. See geomEnums.h.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData::UsageHint GeomVertexArrayData::
get_usage_hint() const {
CDReader cdata(_cycler);
return cdata->_usage_hint;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::has_column
// Access: Published
// Description: Returns true if the array has the named column,
// false otherwise. This is really just a shortcut for
// asking the same thing from the format.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexArrayData::
has_column(const InternalName *name) const {
return _array_format->has_column(name);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_num_rows
// Access: Published
// Description: Returns the number of rows stored in the array,
// based on the number of bytes and the stride. This
// should be the same for all arrays within a given
// GeomVertexData object.
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayData::
get_num_rows() const {
return get_handle()->get_num_rows();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::set_num_rows
// Access: Published
// Description: Sets the length of the array to n rows.
//
// Normally, you would not call this directly, since all
// of the arrays in a particular GeomVertexData must
// have the same number of rows; instead, call
// GeomVertexData::set_num_rows().
//
// The return value is true if the number of rows
// was changed, false if the object already contained n
// rows (or if there was some error).
//
// The new vertex data is initialized to 0, including
// the "color" column (but see
// GeomVertexData::set_num_rows()).
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexArrayData::
set_num_rows(int n) {
return modify_handle()->set_num_rows(n);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::unclean_set_num_rows
// Access: Published
// Description: This method behaves like set_num_rows(), except the
// new data is not initialized. Furthermore, after this
// call, *any* of the data in the GeomVertexArrayData
// may be uninitialized, including the earlier rows.
//
// Normally, you would not call this directly, since all
// of the arrays in a particular GeomVertexData must
// have the same number of rows; instead, call
// GeomVertexData::unclean_set_num_rows().
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexArrayData::
unclean_set_num_rows(int n) {
return modify_handle()->unclean_set_num_rows(n);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::reserve_num_rows
// Access: Published
// Description: This ensures that enough memory space for n rows is
// allocated, so that you may increase the number of
// rows to n without causing a new memory allocation.
// This is a performance optimization only; it is
// especially useful when you know ahead of time that
// you will be adding n rows to the data.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexArrayData::
reserve_num_rows(int n) {
return modify_handle()->reserve_num_rows(n);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::clear_rows
// Access: Published
// Description: Removes all of the rows in the array.
// Functionally equivalent to set_num_rows(0).
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayData::
clear_rows() {
return modify_handle()->clear_rows();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_data_size_bytes
// Access: Published
// Description: Returns the number of bytes stored in the array.
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayData::
get_data_size_bytes() const {
CDReader cdata(_cycler);
return cdata->_buffer.get_size();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_modified
// Access: Published
// Description: Returns a sequence number which is guaranteed to
// change at least every time the array vertex data is
// modified.
////////////////////////////////////////////////////////////////////
INLINE UpdateSeq GeomVertexArrayData::
get_modified() const {
CDReader cdata(_cycler);
return cdata->_modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::request_resident
// Access: Published
// Description: Returns true if the vertex data is currently resident
// in memory. If this returns true, the next call to
// get_handle()->get_read_pointer() will probably not
// block. If this returns false, the vertex data will
// be brought back into memory shortly; try again later.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexArrayData::
request_resident() const {
CPT(GeomVertexArrayDataHandle) handle = get_handle();
return handle->request_resident();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_handle
// Access: Published
// Description: Returns an object that can be used to read the actual
// data bytes stored in the array. Calling this method
// locks the data, and will block any other threads
// attempting to read or write the data, until the
// returned object destructs.
////////////////////////////////////////////////////////////////////
INLINE CPT(GeomVertexArrayDataHandle) GeomVertexArrayData::
get_handle(Thread *current_thread) const {
const CData *cdata = _cycler.read_unlocked(current_thread);
return new GeomVertexArrayDataHandle(this, current_thread,
cdata, false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::modify_handle
// Access: Published
// Description: Returns an object that can be used to read or write
// the actual data bytes stored in the array. Calling
// this method locks the data, and will block any other
// threads attempting to read or write the data, until
// the returned object destructs.
////////////////////////////////////////////////////////////////////
INLINE PT(GeomVertexArrayDataHandle) GeomVertexArrayData::
modify_handle(Thread *current_thread) {
CData *cdata = _cycler.write_upstream(true, current_thread);
return new GeomVertexArrayDataHandle(this, current_thread,
cdata, true);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_independent_lru
// Access: Published, Static
// Description: Returns a pointer to the global LRU object that
// manages the GeomVertexArrayData's that have not (yet)
// been paged out.
////////////////////////////////////////////////////////////////////
INLINE SimpleLru *GeomVertexArrayData::
get_independent_lru() {
return &_independent_lru;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_small_lru
// Access: Published, Static
// Description: Returns a pointer to the global LRU object that
// manages the GeomVertexArrayData's that are deemed too
// small to be paged out.
////////////////////////////////////////////////////////////////////
INLINE SimpleLru *GeomVertexArrayData::
get_small_lru() {
return &_small_lru;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::get_book
// Access: Published, Static
// Description: Returns the global VertexDataBook that will be
// used to allocate vertex data buffers.
////////////////////////////////////////////////////////////////////
INLINE VertexDataBook &GeomVertexArrayData::
get_book() {
return _book;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::set_lru_size
// Access: Private
// Description: Should be called when the size of the buffer changes.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayData::
set_lru_size(size_t lru_size) {
SimpleLruPage::set_lru_size(lru_size);
if ((int)lru_size <= vertex_data_small_size) {
SimpleLruPage::mark_used_lru(&_small_lru);
} else {
SimpleLruPage::mark_used_lru(&_independent_lru);
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::CData::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData::CData::
CData() :
_usage_hint(UH_unspecified),
_rw_lock("GeomVertexArrayData::CData::_rw_lock")
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::CData::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData::CData::
CData(const GeomVertexArrayData::CData &copy) :
_usage_hint(copy._usage_hint),
_buffer(copy._buffer),
_modified(copy._modified),
_rw_lock("GeomVertexArrayData::CData::_rw_lock")
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::CData::Copy Assignment
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayData::CData::
operator = (const GeomVertexArrayData::CData &copy) {
_usage_hint = copy._usage_hint;
_buffer = copy._buffer;
_modified = copy._modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::Constructor
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataHandle::
GeomVertexArrayDataHandle(const GeomVertexArrayData *object,
Thread *current_thread,
const GeomVertexArrayData::CData *cdata,
bool writable) :
_object((GeomVertexArrayData *)object),
_current_thread(current_thread),
_cdata((GeomVertexArrayData::CData *)cdata),
_writable(writable)
{
#ifdef _DEBUG
nassertv(_object->test_ref_count_nonzero());
#endif // _DEBUG
#ifdef DO_PIPELINING
_cdata->ref();
#endif // DO_PIPELINING
// We must grab the lock *after* we have incremented the reference
// count, above.
_cdata->_rw_lock.acquire();
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, get_class_type());
#endif
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::Copy Constructor
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataHandle::
GeomVertexArrayDataHandle(const GeomVertexArrayDataHandle &copy) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::Copy Assignment Operator
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayDataHandle::
operator = (const GeomVertexArrayDataHandle &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataHandle::
~GeomVertexArrayDataHandle() {
#ifdef _DEBUG
nassertv(_object->test_ref_count_nonzero());
#endif // _DEBUG
if (_writable) {
_object->_cycler.release_write(_cdata);
}
// We must release the lock *before* we decrement the reference
// count, below.
_cdata->_rw_lock.release();
#ifdef DO_PIPELINING
unref_delete((CycleData *)_cdata);
#endif // DO_PIPELINING
#ifdef _DEBUG
_object = NULL;
_cdata = NULL;
#endif // _DEBUG
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_current_thread
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE Thread *GeomVertexArrayDataHandle::
get_current_thread() const {
return _current_thread;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_read_pointer
// Access: Public
// Description: Returns a readable pointer to the beginning of the
// actual data stream, or NULL if the data is not
// currently resident. If the data is not currently
// resident, this will implicitly request it to become
// resident soon.
//
// If force is true, this method will never return NULL,
// but may block until the data is available.
////////////////////////////////////////////////////////////////////
INLINE const unsigned char *GeomVertexArrayDataHandle::
get_read_pointer(bool force) const {
mark_used();
return _cdata->_buffer.get_read_pointer(force);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_object
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomVertexArrayDataHandle::
get_object() const {
return _object;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_object
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData *GeomVertexArrayDataHandle::
get_object() {
return _object;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_array_format
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayFormat *GeomVertexArrayDataHandle::
get_array_format() const {
return _object->_array_format;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_usage_hint
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataHandle::UsageHint GeomVertexArrayDataHandle::
get_usage_hint() const {
return _cdata->_usage_hint;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_num_rows
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayDataHandle::
get_num_rows() const {
return get_data_size_bytes() / _object->_array_format->get_stride();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::clear_rows
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayDataHandle::
clear_rows() {
set_num_rows(0);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_data_size_bytes
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayDataHandle::
get_data_size_bytes() const {
return _cdata->_buffer.get_size();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_modified
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE UpdateSeq GeomVertexArrayDataHandle::
get_modified() const {
return _cdata->_modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::request_resident
// Access: Published
// Description: Returns true if the vertex data is currently resident
// in memory. If this returns true, the next call to
// get_handle()->get_read_pointer() will probably not
// block. If this returns false, the vertex data will
// be brought back into memory shortly; try again later.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexArrayDataHandle::
request_resident() const {
return (get_read_pointer(false) != (const unsigned char *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_data
// Access: Published
// Description: Returns the entire raw data of the
// GeomVertexArrayData object, formatted as a string.
// This is primarily for the benefit of high-level
// languages such as Python.
////////////////////////////////////////////////////////////////////
INLINE string GeomVertexArrayDataHandle::
get_data() const {
mark_used();
return string((const char *)_cdata->_buffer.get_read_pointer(true), _cdata->_buffer.get_size());
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::get_subdata
// Access: Published
// Description: Returns a subset of the raw data of the
// GeomVertexArrayData object, formatted as a string.
// This is primarily for the benefit of high-level
// languages such as Python.
////////////////////////////////////////////////////////////////////
INLINE string GeomVertexArrayDataHandle::
get_subdata(size_t start, size_t size) const {
mark_used();
start = min(start, _cdata->_buffer.get_size());
size = min(size, _cdata->_buffer.get_size() - start);
return string((const char *)_cdata->_buffer.get_read_pointer(true) + start, size);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::mark_used
// Access: Published
// Description: Marks the array data recently-used.
////////////////////////////////////////////////////////////////////
void GeomVertexArrayDataHandle::
mark_used() const {
_object->set_lru_size(_object->get_lru_size());
}
INLINE ostream &
operator << (ostream &out, const GeomVertexArrayData &obj) {
obj.output(out);
return out;
}