From 384f9ff0b02a19d6fb0aeef8272d4e12b0855819 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 21 Apr 2006 15:55:01 +0000 Subject: [PATCH] GeomVertexReader/Writer should not hold lock --- panda/src/gobj/geomVertexData.cxx | 5 +- panda/src/gobj/geomVertexReader.I | 151 +++++++++++++------------- panda/src/gobj/geomVertexReader.cxx | 94 +++++++++------- panda/src/gobj/geomVertexReader.h | 16 ++- panda/src/gobj/geomVertexWriter.I | 159 ++++++++++++++-------------- panda/src/gobj/geomVertexWriter.cxx | 93 +++++++++------- panda/src/gobj/geomVertexWriter.h | 16 ++- 7 files changed, 289 insertions(+), 245 deletions(-) diff --git a/panda/src/gobj/geomVertexData.cxx b/panda/src/gobj/geomVertexData.cxx index 1e46c635ec..2c43581a8f 100644 --- a/panda/src/gobj/geomVertexData.cxx +++ b/panda/src/gobj/geomVertexData.cxx @@ -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)); } diff --git a/panda/src/gobj/geomVertexReader.I b/panda/src/gobj/geomVertexReader.I index 9455800404..1fc03bbcff 100644 --- a/panda/src/gobj/geomVertexReader.I +++ b/panda/src/gobj/geomVertexReader.I @@ -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 ©) : - _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 ©) : _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 ©) { - 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 ©) { //////////////////////////////////////////////////////////////////// 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 diff --git a/panda/src/gobj/geomVertexReader.cxx b/panda/src/gobj/geomVertexReader.cxx index 9294d377ec..e1f711cf70 100644 --- a/panda/src/gobj/geomVertexReader.cxx +++ b/panda/src/gobj/geomVertexReader.cxx @@ -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; } diff --git a/panda/src/gobj/geomVertexReader.h b/panda/src/gobj/geomVertexReader.h index 8e69e555b7..7762b4214b 100644 --- a/panda/src/gobj/geomVertexReader.h +++ b/panda/src/gobj/geomVertexReader.h @@ -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; diff --git a/panda/src/gobj/geomVertexWriter.I b/panda/src/gobj/geomVertexWriter.I index fdd8e1344c..caf9c1c4a2 100644 --- a/panda/src/gobj/geomVertexWriter.I +++ b/panda/src/gobj/geomVertexWriter.I @@ -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 ©) : - _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 ©) : _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 ©) { - _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 ©) { //////////////////////////////////////////////////////////////////// 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(); } diff --git a/panda/src/gobj/geomVertexWriter.cxx b/panda/src/gobj/geomVertexWriter.cxx index 5294f6a83f..9c49494b59 100644 --- a/panda/src/gobj/geomVertexWriter.cxx +++ b/panda/src/gobj/geomVertexWriter.cxx @@ -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; } diff --git a/panda/src/gobj/geomVertexWriter.h b/panda/src/gobj/geomVertexWriter.h index 59fbcac276..35ee8b281d 100644 --- a/panda/src/gobj/geomVertexWriter.h +++ b/panda/src/gobj/geomVertexWriter.h @@ -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;