GeomVertexReader/Writer should not hold lock

This commit is contained in:
David Rose 2006-04-21 15:55:01 +00:00
parent 7e063748f6
commit 384f9ff0b0
7 changed files with 289 additions and 245 deletions

View File

@ -1891,8 +1891,11 @@ make_array_writers() {
nassertv(!_got_array_writers);
_array_writers.reserve(_cdata->_arrays.size());
GeomVertexData::Arrays::const_iterator ai;
GeomVertexData::Arrays::iterator ai;
for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
if ((*ai)->get_ref_count() > 1) {
(*ai) = new GeomVertexArrayData(*(*ai));
}
_array_writers.push_back(new GeomVertexArrayDataPipelineWriter(*ai, _force_to_0, _current_thread));
}

View File

@ -27,9 +27,8 @@
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader() :
_data_reader(NULL),
_array_reader(NULL),
_owns_reader(false)
_vertex_data(NULL),
_current_thread(Thread::get_current_thread())
{
initialize();
}
@ -42,9 +41,8 @@ GeomVertexReader() :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data) :
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_thread())),
_array_reader(NULL),
_owns_reader(true)
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
{
initialize();
}
@ -58,9 +56,8 @@ GeomVertexReader(const GeomVertexData *vertex_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_thread())),
_array_reader(NULL),
_owns_reader(true)
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
{
initialize();
set_column(name);
@ -75,10 +72,9 @@ GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data,
const InternalName *name) :
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_thread())),
_array_reader(NULL),
_owns_reader(true)
const InternalName *name) :
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
{
initialize();
set_column(name);
@ -92,9 +88,8 @@ GeomVertexReader(const GeomVertexData *vertex_data,
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexArrayData *array_data) :
_data_reader(NULL),
_array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_thread())),
_owns_reader(true)
_array_data(array_data),
_current_thread(Thread::get_current_thread())
{
initialize();
}
@ -107,9 +102,8 @@ GeomVertexReader(const GeomVertexArrayData *array_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexArrayData *array_data, int column) :
_data_reader(NULL),
_array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_thread())),
_owns_reader(true)
_array_data(array_data),
_current_thread(Thread::get_current_thread())
{
initialize();
set_column(column);
@ -123,28 +117,29 @@ GeomVertexReader(const GeomVertexArrayData *array_data, int column) :
// reader specifically to process the named data type.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexDataPipelineReader *data_reader,
GeomVertexReader(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name) :
_data_reader(data_reader),
_array_reader(NULL),
_owns_reader(false)
_vertex_data(data_reader->get_object()),
_current_thread(data_reader->get_current_thread())
{
initialize();
set_column(name);
const GeomVertexFormat *format = data_reader->get_format();
set_vertex_column(format->get_array_with(name),
format->get_column(name),
data_reader);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::Copy Constructor
// Access: Published
// Description: The copy constructor steals ownership of the reader
// pointer.
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexReader &copy) :
_data_reader(copy._data_reader),
_vertex_data(copy._vertex_data),
_array(copy._array),
_array_reader(copy._array_reader),
_owns_reader(copy._owns_reader),
_array_data(copy._array_data),
_current_thread(copy._current_thread),
_packer(copy._packer),
_stride(copy._stride),
_pointer_begin(copy._pointer_begin),
@ -152,33 +147,25 @@ GeomVertexReader(const GeomVertexReader &copy) :
_pointer(copy._pointer),
_start_row(copy._start_row)
{
((GeomVertexReader &)copy)._owns_reader = false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::Copy Assignment Operator
// Access: Published
// Description: The copy constructor steals ownership of the reader
// pointer.
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexReader::
operator = (const GeomVertexReader &copy) {
if (_owns_reader) {
clear_reader();
}
_data_reader = copy._data_reader;
_vertex_data = copy._vertex_data;
_array = copy._array;
_array_reader = copy._array_reader;
_owns_reader = copy._owns_reader;
_array_data = copy._array_data;
_current_thread = copy._current_thread;
_packer = copy._packer;
_stride = copy._stride;
_pointer_begin = copy._pointer_begin;
_pointer_end = copy._pointer_end;
_pointer = copy._pointer;
_start_row = copy._start_row;
((GeomVertexReader &)copy)._owns_reader = false;
}
////////////////////////////////////////////////////////////////////
@ -188,9 +175,6 @@ operator = (const GeomVertexReader &copy) {
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
~GeomVertexReader() {
if (_owns_reader) {
clear_reader();
}
}
////////////////////////////////////////////////////////////////////
@ -202,10 +186,7 @@ INLINE GeomVertexReader::
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexData *GeomVertexReader::
get_vertex_data() const {
if (_data_reader != (GeomVertexDataPipelineReader *)NULL) {
return _data_reader->get_object();
}
return NULL;
return _vertex_data;
}
////////////////////////////////////////////////////////////////////
@ -216,7 +197,18 @@ get_vertex_data() const {
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomVertexReader::
get_array_data() const {
return _array_reader->get_object();
return _array_data;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::get_current_thread
// Access: Published
// Description: Returns the Thread pointer of the currently-executing
// thread, as passed to the constructor of this object.
////////////////////////////////////////////////////////////////////
INLINE Thread *GeomVertexReader::
get_current_thread() const {
return _current_thread;
}
////////////////////////////////////////////////////////////////////
@ -234,12 +226,18 @@ get_array_data() const {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexReader::
set_column(int column) {
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
return set_column(_data_reader->get_format()->get_array_with(column),
_data_reader->get_format()->get_column(column));
if (_vertex_data != (const GeomVertexData *)NULL) {
GeomVertexDataPipelineReader reader(_vertex_data, _current_thread);
reader.check_array_readers();
const GeomVertexFormat *format = reader.get_format();
return set_vertex_column(format->get_array_with(column),
format->get_column(column),
&reader);
}
if (_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL) {
return set_column(0, _array_reader->get_array_format()->get_column(column));
if (_array_data != (const GeomVertexArrayData *)NULL) {
GeomVertexArrayDataPipelineReader reader(_array_data, _current_thread);
return set_array_column(reader.get_array_format()->get_column(column),
&reader);
}
return false;
}
@ -277,12 +275,18 @@ set_column(const string &name) {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexReader::
set_column(const InternalName *name) {
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
return set_column(_data_reader->get_format()->get_array_with(name),
_data_reader->get_format()->get_column(name));
if (_vertex_data != (const GeomVertexData *)NULL) {
GeomVertexDataPipelineReader reader(_vertex_data, _current_thread);
reader.check_array_readers();
const GeomVertexFormat *format = reader.get_format();
return set_vertex_column(format->get_array_with(name),
format->get_column(name),
&reader);
}
if (_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL) {
return set_column(0, _array_reader->get_array_format()->get_column(name));
if (_array_data != (const GeomVertexArrayData *)NULL) {
GeomVertexArrayDataPipelineReader reader(_array_data, _current_thread);
return set_array_column(reader.get_array_format()->get_column(name),
&reader);
}
return false;
@ -500,16 +504,9 @@ get_packer() const {
// and sets the internal pointer to the indicated row.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexReader::
set_pointer(int row) {
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
_pointer_begin = array_reader->get_data();
_pointer_end = _pointer_begin + array_reader->get_data_size_bytes();
} else {
_pointer_begin = _array_reader->get_data();
_pointer_end = _pointer_begin + _array_reader->get_data_size_bytes();
}
set_pointer(int row, const GeomVertexArrayDataPipelineReader *array_reader) {
_pointer_begin = array_reader->get_data();
_pointer_end = _pointer_begin + array_reader->get_data_size_bytes();
quick_set_pointer(row);
}
@ -525,11 +522,11 @@ quick_set_pointer(int row) {
nassertv(has_column());
#ifdef _DEBUG
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
nassertv(_pointer_begin == array_reader->get_data());
if (_vertex_data != (const GeomVertexData *)NULL) {
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertv(_pointer_begin == array_data->get_data());
} else {
nassertv(_pointer_begin == _array_reader->get_data());
nassertv(_pointer_begin == _array_data->get_data());
}
#endif
@ -546,11 +543,11 @@ INLINE const unsigned char *GeomVertexReader::
inc_pointer() {
#ifdef _DEBUG
nassertr(_pointer < _pointer_end, empty_buffer);
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL){
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
nassertr(_pointer >= array_reader->get_data().p() && _pointer < array_reader->get_data().p() + array_reader->get_data_size_bytes(), empty_buffer);
if (_vertex_data != (const GeomVertexData *)NULL){
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
} else {
nassertr(_pointer >= _array_reader->get_data().p() && _pointer < _array_reader->get_data().p() + _array_reader->get_data_size_bytes(), empty_buffer);
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
}
#endif

View File

@ -40,11 +40,6 @@ const unsigned char GeomVertexReader::empty_buffer[100] = { 0 };
////////////////////////////////////////////////////////////////////
bool GeomVertexReader::
set_column(int array, const GeomVertexColumn *column) {
if (_data_reader == (const GeomVertexDataPipelineReader *)NULL &&
_array_reader == (const GeomVertexArrayDataPipelineReader *)NULL) {
return false;
}
if (column == (const GeomVertexColumn *)NULL) {
// Clear the data type.
_array = -1;
@ -56,25 +51,18 @@ set_column(int array, const GeomVertexColumn *column) {
return false;
}
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
#ifndef NDEBUG
_array = -1;
_packer = NULL;
nassertr(array >= 0 && array < _data_reader->get_num_arrays(), false);
#endif
_array = array;
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
_stride = array_reader->get_array_format()->get_stride();
} else {
_stride = _array_reader->get_array_format()->get_stride();
if (_vertex_data != (const GeomVertexData *)NULL) {
GeomVertexDataPipelineReader reader(_vertex_data, _current_thread);
reader.check_array_readers();
return set_vertex_column(array, column, &reader);
}
if (_array_data != (const GeomVertexArrayData *)NULL) {
GeomVertexArrayDataPipelineReader reader(_array_data, _current_thread);
return set_array_column(column, &reader);
}
_packer = column->_packer;
set_pointer(_start_row);
return true;
// No data is associated with the Reader.
return false;
}
////////////////////////////////////////////////////////////////////
@ -103,10 +91,6 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
void GeomVertexReader::
initialize() {
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
_data_reader->check_array_readers();
}
_array = 0;
_packer = NULL;
_pointer_begin = NULL;
@ -116,23 +100,51 @@ initialize() {
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::clear_reader
// Function: GeomVertexReader::set_vertex_column
// Access: Private
// Description: Destructs the GeomVertexDataPipelineReader, when
// necessary, for instance when this object destructs.
// Description: Internal method to set the column to column from the
// indicated array, assuming we have a GeomVertexData
////////////////////////////////////////////////////////////////////
void GeomVertexReader::
clear_reader() {
nassertv(_owns_reader);
bool GeomVertexReader::
set_vertex_column(int array, const GeomVertexColumn *column,
const GeomVertexDataPipelineReader *data_reader) {
nassertr(column != (const GeomVertexColumn *)NULL, false);
nassertr(_vertex_data != (const GeomVertexData *)NULL, false);
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
delete (GeomVertexDataPipelineReader *)_data_reader;
_data_reader = NULL;
} else {
nassertv(_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL);
delete (GeomVertexArrayDataPipelineReader *)_array_reader;
_array_reader = NULL;
}
#ifndef NDEBUG
_array = -1;
_packer = NULL;
nassertr(array >= 0 && array < _vertex_data->get_num_arrays(), false);
#endif
_owns_reader = false;
_array = array;
const GeomVertexArrayDataPipelineReader *array_reader =
data_reader->get_array_reader(_array);
_stride = array_reader->get_array_format()->get_stride();
_packer = column->_packer;
set_pointer(_start_row, array_reader);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::set_array_column
// Access: Private
// Description: Internal method to set the column to column from the
// indicated array, assuming we have a
// GeomVertexArrayData.
////////////////////////////////////////////////////////////////////
bool GeomVertexReader::
set_array_column(const GeomVertexColumn *column,
const GeomVertexArrayDataPipelineReader *array_reader) {
nassertr(column != (const GeomVertexColumn *)NULL, false);
nassertr(_array_data != (const GeomVertexArrayData *)NULL, false);
_stride = array_reader->get_array_format()->get_stride();
_packer = column->_packer;
set_pointer(_start_row, array_reader);
return true;
}

View File

@ -80,6 +80,7 @@ PUBLISHED:
INLINE const GeomVertexData *get_vertex_data() const;
INLINE const GeomVertexArrayData *get_array_data() const;
INLINE Thread *get_current_thread() const;
INLINE bool set_column(int column);
INLINE bool set_column(const string &name);
@ -113,22 +114,27 @@ protected:
private:
void initialize();
void clear_reader();
INLINE void set_pointer(int row);
INLINE void set_pointer(int row,
const GeomVertexArrayDataPipelineReader *array_reader);
INLINE void quick_set_pointer(int row);
INLINE const unsigned char *inc_pointer();
bool set_vertex_column(int array, const GeomVertexColumn *column,
const GeomVertexDataPipelineReader *data_reader);
bool set_array_column(const GeomVertexColumn *column,
const GeomVertexArrayDataPipelineReader *array_reader);
// It is important that we only store *one* of the following two
// pointers. If we are storing a GeomVertexData/array index, we
// must not keep a pointer to the particular ArrayData we are
// working on (if we do, it may result in an extra copy of the data
// due to holding the reference count).
const GeomVertexDataPipelineReader *_data_reader;
CPT(GeomVertexData) _vertex_data;
int _array;
const GeomVertexArrayDataPipelineReader *_array_reader;
bool _owns_reader;
CPT(GeomVertexArrayData) _array_data;
Thread *_current_thread;
GeomVertexColumn::Packer *_packer;
int _stride;

View File

@ -27,9 +27,8 @@
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter() :
_data_writer(NULL),
_array_writer(NULL),
_owns_writer(false)
_vertex_data(NULL),
_current_thread(Thread::get_current_thread())
{
initialize();
}
@ -42,9 +41,8 @@ GeomVertexWriter() :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data) :
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, true, Thread::get_current_thread())),
_array_writer(NULL),
_owns_writer(true)
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
{
initialize();
}
@ -58,9 +56,8 @@ GeomVertexWriter(GeomVertexData *vertex_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, true, Thread::get_current_thread())),
_array_writer(NULL),
_owns_writer(true)
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
{
initialize();
set_column(name);
@ -75,9 +72,8 @@ GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, true, Thread::get_current_thread())),
_array_writer(NULL),
_owns_writer(true)
_vertex_data(vertex_data),
_current_thread(Thread::get_current_thread())
{
initialize();
set_column(name);
@ -91,9 +87,8 @@ GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexArrayData *array_data) :
_data_writer(NULL),
_array_writer(new GeomVertexArrayDataPipelineWriter(array_data, true, Thread::get_current_thread())),
_owns_writer(true)
_array_data(array_data),
_current_thread(Thread::get_current_thread())
{
initialize();
}
@ -106,9 +101,8 @@ GeomVertexWriter(GeomVertexArrayData *array_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexArrayData *array_data, int column) :
_data_writer(NULL),
_array_writer(new GeomVertexArrayDataPipelineWriter(array_data, true, Thread::get_current_thread())),
_owns_writer(true)
_array_data(array_data),
_current_thread(Thread::get_current_thread())
{
initialize();
set_column(column);
@ -122,28 +116,29 @@ GeomVertexWriter(GeomVertexArrayData *array_data, int column) :
// writer specifically to process the named data type.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer,
GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer,
const InternalName *name) :
_data_writer(data_writer),
_array_writer(NULL),
_owns_writer(false)
_vertex_data(data_writer->get_object()),
_current_thread(data_writer->get_current_thread())
{
initialize();
set_column(name);
const GeomVertexFormat *format = data_writer->get_format();
set_vertex_column(format->get_array_with(name),
format->get_column(name),
data_writer);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::Copy Constructor
// Access: Published
// Description: The copy constructor steals ownership of the writer
// pointer.
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(const GeomVertexWriter &copy) :
_data_writer(copy._data_writer),
_vertex_data(copy._vertex_data),
_array(copy._array),
_array_writer(copy._array_writer),
_owns_writer(copy._owns_writer),
_array_data(copy._array_data),
_current_thread(copy._current_thread),
_packer(copy._packer),
_stride(copy._stride),
_pointer_begin(copy._pointer_begin),
@ -151,29 +146,25 @@ GeomVertexWriter(const GeomVertexWriter &copy) :
_pointer(copy._pointer),
_start_row(copy._start_row)
{
((GeomVertexWriter &)copy)._owns_writer = false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::Copy Assignment Operator
// Access: Published
// Description: The copy constructor steals ownership of the writer
// pointer.
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexWriter::
operator = (const GeomVertexWriter &copy) {
_data_writer = copy._data_writer;
_vertex_data = copy._vertex_data;
_array = copy._array;
_array_writer = copy._array_writer;
_owns_writer = copy._owns_writer;
_array_data = copy._array_data;
_current_thread = copy._current_thread;
_packer = copy._packer;
_stride = copy._stride;
_pointer_begin = copy._pointer_begin;
_pointer_end = copy._pointer_end;
_pointer = copy._pointer;
_start_row = copy._start_row;
((GeomVertexWriter &)copy)._owns_writer = false;
}
////////////////////////////////////////////////////////////////////
@ -183,9 +174,6 @@ operator = (const GeomVertexWriter &copy) {
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
~GeomVertexWriter() {
if (_owns_writer) {
clear_writer();
}
}
////////////////////////////////////////////////////////////////////
@ -197,10 +185,7 @@ INLINE GeomVertexWriter::
////////////////////////////////////////////////////////////////////
INLINE GeomVertexData *GeomVertexWriter::
get_vertex_data() const {
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
return _data_writer->get_object();
}
return NULL;
return _vertex_data;
}
////////////////////////////////////////////////////////////////////
@ -211,7 +196,18 @@ get_vertex_data() const {
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData *GeomVertexWriter::
get_array_data() const {
return _array_writer->get_object();
return _array_data;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::get_current_thread
// Access: Published
// Description: Returns the Thread pointer of the currently-executing
// thread, as passed to the constructor of this object.
////////////////////////////////////////////////////////////////////
INLINE Thread *GeomVertexWriter::
get_current_thread() const {
return _current_thread;
}
////////////////////////////////////////////////////////////////////
@ -229,12 +225,18 @@ get_array_data() const {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexWriter::
set_column(int column) {
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
return set_column(_data_writer->get_format()->get_array_with(column),
_data_writer->get_format()->get_column(column));
if (_vertex_data != (GeomVertexData *)NULL) {
GeomVertexDataPipelineWriter writer(_vertex_data, true, _current_thread);
writer.check_array_writers();
const GeomVertexFormat *format = writer.get_format();
return set_vertex_column(format->get_array_with(column),
format->get_column(column),
&writer);
}
if (_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL) {
return set_column(0, _array_writer->get_array_format()->get_column(column));
if (_array_data != (GeomVertexArrayData *)NULL) {
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
return set_array_column(writer.get_array_format()->get_column(column),
&writer);
}
return false;
}
@ -272,14 +274,19 @@ set_column(const string &name) {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexWriter::
set_column(const InternalName *name) {
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
return set_column(_data_writer->get_format()->get_array_with(name),
_data_writer->get_format()->get_column(name));
if (_vertex_data != (GeomVertexData *)NULL) {
GeomVertexDataPipelineWriter writer(_vertex_data, true, _current_thread);
writer.check_array_writers();
const GeomVertexFormat *format = writer.get_format();
return set_vertex_column(format->get_array_with(name),
format->get_column(name),
&writer);
}
if (_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL) {
return set_column(0, _array_writer->get_array_format()->get_column(name));
if (_array_data != (GeomVertexArrayData *)NULL) {
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
return set_array_column(writer.get_array_format()->get_column(name),
&writer);
}
return false;
}
@ -801,17 +808,9 @@ get_packer() const {
// and sets the internal pointer to the indicated row.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexWriter::
set_pointer(int row) {
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
_data_writer->modify_array(_array);
GeomVertexArrayDataPipelineWriter *array_data = _data_writer->get_array_writer(_array);
_pointer_begin = array_data->modify_data();
_pointer_end = _pointer_begin + array_data->get_data_size_bytes();
} else {
_pointer_begin = _array_writer->modify_data();
_pointer_end = _pointer_begin + _array_writer->get_data_size_bytes();
}
set_pointer(int row, GeomVertexArrayDataPipelineWriter *array_writer) {
_pointer_begin = array_writer->modify_data();
_pointer_end = _pointer_begin + array_writer->get_data_size_bytes();
quick_set_pointer(row);
}
@ -827,11 +826,11 @@ quick_set_pointer(int row) {
nassertv(has_column());
#ifdef _DEBUG
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
GeomVertexArrayDataPipelineWriter *array_writer = _data_writer->get_array_writer(_array);
nassertv(_pointer_begin == array_writer->get_data());
if (_vertex_data != (const GeomVertexData *)NULL) {
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertv(_pointer_begin == array_data->get_data());
} else {
nassertv(_pointer_begin == _array_writer->get_data());
nassertv(_pointer_begin == _array_data->get_data());
}
#endif
@ -848,11 +847,11 @@ INLINE unsigned char *GeomVertexWriter::
inc_pointer() {
#ifdef _DEBUG
nassertr(_pointer < _pointer_end, empty_buffer);
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL){
GeomVertexArrayDataPipelineWriter *array_writer = _data_writer->get_array_writer(_array);
nassertr(_pointer >= array_writer->get_data().p() && _pointer < array_writer->get_data().p() + array_writer->get_data_size_bytes(), empty_buffer);
if (_vertex_data != (GeomVertexData *)NULL){
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
} else {
nassertr(_pointer >= _array_writer->get_data().p() && _pointer < _array_writer->get_data().p() + _array_writer->get_data_size_bytes(), empty_buffer);
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
}
#endif
@ -874,12 +873,16 @@ inc_add_pointer() {
if (_pointer >= _pointer_end) {
// Reset the data pointer.
int write_row = get_write_row();
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
_data_writer->set_num_rows(max(write_row + 1, _data_writer->get_num_rows()));
if (_vertex_data != (GeomVertexData *)NULL) {
GeomVertexDataPipelineWriter writer(_vertex_data, true, _current_thread);
writer.check_array_writers();
writer.set_num_rows(max(write_row + 1, writer.get_num_rows()));
set_pointer(write_row, writer.get_array_writer(_array));
} else {
_array_writer->set_num_rows(max(write_row + 1, _array_writer->get_num_rows()));
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
writer.set_num_rows(max(write_row + 1, writer.get_num_rows()));
set_pointer(write_row, &writer);
}
set_pointer(write_row);
}
return inc_pointer();
}

View File

@ -40,8 +40,8 @@ unsigned char GeomVertexWriter::empty_buffer[100] = { 0 };
////////////////////////////////////////////////////////////////////
bool GeomVertexWriter::
set_column(int array, const GeomVertexColumn *column) {
if (_data_writer == (GeomVertexDataPipelineWriter *)NULL &&
_array_writer == (GeomVertexArrayDataPipelineWriter *)NULL) {
if (_vertex_data == (GeomVertexData *)NULL &&
_array_data == (GeomVertexArrayData *)NULL) {
return false;
}
@ -56,25 +56,18 @@ set_column(int array, const GeomVertexColumn *column) {
return false;
}
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
#ifndef NDEBUG
_array = -1;
_packer = NULL;
nassertr(array >= 0 && array < _data_writer->get_num_arrays(), false);
#endif
_array = array;
GeomVertexArrayDataPipelineWriter *array_writer =_data_writer->get_array_writer(_array);
_stride = array_writer->get_array_format()->get_stride();
} else {
_stride = _array_writer->get_array_format()->get_stride();
if (_vertex_data != (GeomVertexData *)NULL) {
GeomVertexDataPipelineWriter writer(_vertex_data, true, _current_thread);
writer.check_array_writers();
return set_vertex_column(array, column, &writer);
}
if (_array_data != (GeomVertexArrayData *)NULL) {
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
return set_array_column(column, &writer);
}
_packer = column->_packer;
set_pointer(_start_row);
return true;
// No data is associated with the Writer.
return false;
}
////////////////////////////////////////////////////////////////////
@ -103,10 +96,6 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
void GeomVertexWriter::
initialize() {
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
_data_writer->check_array_writers();
}
_array = 0;
_packer = NULL;
_pointer_begin = NULL;
@ -116,23 +105,51 @@ initialize() {
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::clear_writer
// Function: GeomVertexWriter::set_vertex_column
// Access: Private
// Description: Destructs the GeomVertexDataPipelineWriter, when
// necessary, for instance when this object destructs.
// Description: Internal method to set the column to column from the
// indicated array, assuming we have a GeomVertexData
////////////////////////////////////////////////////////////////////
void GeomVertexWriter::
clear_writer() {
nassertv(_owns_writer);
bool GeomVertexWriter::
set_vertex_column(int array, const GeomVertexColumn *column,
GeomVertexDataPipelineWriter *data_writer) {
nassertr(column != (const GeomVertexColumn *)NULL, false);
nassertr(_vertex_data != (GeomVertexData *)NULL, false);
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
delete _data_writer;
_data_writer = NULL;
} else {
nassertv(_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL);
delete _array_writer;
_array_writer = NULL;
}
#ifndef NDEBUG
_array = -1;
_packer = NULL;
nassertr(array >= 0 && array < _vertex_data->get_num_arrays(), false);
#endif
_owns_writer = false;
_array = array;
GeomVertexArrayDataPipelineWriter *array_writer =
data_writer->get_array_writer(_array);
_stride = array_writer->get_array_format()->get_stride();
_packer = column->_packer;
set_pointer(_start_row, array_writer);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::set_array_column
// Access: Private
// Description: Internal method to set the column to column from the
// indicated array, assuming we have a
// GeomVertexArrayData.
////////////////////////////////////////////////////////////////////
bool GeomVertexWriter::
set_array_column(const GeomVertexColumn *column,
GeomVertexArrayDataPipelineWriter *array_writer) {
nassertr(column != (const GeomVertexColumn *)NULL, false);
nassertr(_array_data != (GeomVertexArrayData *)NULL, false);
_stride = array_writer->get_array_format()->get_stride();
_packer = column->_packer;
set_pointer(_start_row, array_writer);
return true;
}

View File

@ -93,6 +93,7 @@ PUBLISHED:
INLINE GeomVertexData *get_vertex_data() const;
INLINE GeomVertexArrayData *get_array_data() const;
INLINE Thread *get_current_thread() const;
INLINE bool set_column(int column);
INLINE bool set_column(const string &name);
@ -150,23 +151,28 @@ private:
class Writer;
void initialize();
void clear_writer();
INLINE void set_pointer(int row);
INLINE void set_pointer(int row,
GeomVertexArrayDataPipelineWriter *array_writer);
INLINE void quick_set_pointer(int row);
INLINE unsigned char *inc_pointer();
INLINE unsigned char *inc_add_pointer();
bool set_vertex_column(int array, const GeomVertexColumn *column,
GeomVertexDataPipelineWriter *data_writer);
bool set_array_column(const GeomVertexColumn *column,
GeomVertexArrayDataPipelineWriter *array_writer);
// It is important that we only store *one* of the following two
// pointers. If we are storing a GeomVertexData/array index, we
// must not keep a pointer to the particular ArrayData we are
// working on (if we do, it may result in an extra copy of the data
// due to holding the reference count).
GeomVertexDataPipelineWriter *_data_writer;
PT(GeomVertexData) _vertex_data;
int _array;
GeomVertexArrayDataPipelineWriter *_array_writer;
bool _owns_writer;
PT(GeomVertexArrayData) _array_data;
Thread *_current_thread;
GeomVertexColumn::Packer *_packer;
int _stride;