add copy_data_from version that takes a Python buffer object

This commit is contained in:
rdb 2013-10-29 12:14:47 +00:00
parent 2fdf53efb8
commit 4a91704958
4 changed files with 192 additions and 21 deletions

View File

@ -839,22 +839,12 @@ reserve_num_rows(int n) {
void GeomVertexArrayDataHandle::
copy_data_from(const GeomVertexArrayDataHandle *other) {
nassertv(_writable);
mark_used();
other->mark_used();
size_t size = other->_cdata->_buffer.get_size();
_cdata->_buffer.unclean_realloc(size);
_cdata->_buffer.set_size(size);
unsigned char *dest = _cdata->_buffer.get_write_pointer();
const unsigned char *source = other->_cdata->_buffer.get_read_pointer(true);
memcpy(dest, source, size);
_cdata->_modified = Geom::get_next_modified();
if (get_current_thread()->get_pipeline_stage() == 0) {
_object->set_lru_size(_cdata->_buffer.get_size());
}
copy_data_from(source, size);
}
////////////////////////////////////////////////////////////////////
@ -869,20 +859,61 @@ void GeomVertexArrayDataHandle::
copy_subdata_from(size_t to_start, size_t to_size,
const GeomVertexArrayDataHandle *other,
size_t from_start, size_t from_size) {
nassertv(_writable);
mark_used();
other->mark_used();
VertexDataBuffer &to_buffer = _cdata->_buffer;
size_t to_buffer_orig_size = to_buffer.get_size();
to_start = min(to_start, to_buffer_orig_size);
to_size = min(to_size, to_buffer_orig_size - to_start);
const VertexDataBuffer &from_buffer = other->_cdata->_buffer;
size_t from_buffer_orig_size = from_buffer.get_size();
from_start = min(from_start, from_buffer_orig_size);
from_size = min(from_size, from_buffer_orig_size - from_start);
copy_subdata_from(to_start, to_size,
other->get_read_pointer(true),
from_start, from_size);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::copy_data_from
// Access: Public
// Description: Copies the entire data array from the buffer.
////////////////////////////////////////////////////////////////////
void GeomVertexArrayDataHandle::
copy_data_from(const unsigned char *source, size_t size) {
nassertv(_writable);
mark_used();
_cdata->_buffer.unclean_realloc(size);
_cdata->_buffer.set_size(size);
unsigned char *dest = _cdata->_buffer.get_write_pointer();
memcpy(dest, source, size);
_cdata->_modified = Geom::get_next_modified();
if (get_current_thread()->get_pipeline_stage() == 0) {
_object->set_lru_size(_cdata->_buffer.get_size());
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::copy_subdata_from
// Access: Public
// Description: Copies a portion of the data array from the buffer
// into a portion of the data array of this object.
// If to_size != from_size, the size of this data
// array is adjusted accordingly.
////////////////////////////////////////////////////////////////////
void GeomVertexArrayDataHandle::
copy_subdata_from(size_t to_start, size_t to_size,
const unsigned char *source,
size_t from_start, size_t from_size) {
nassertv(_writable);
mark_used();
VertexDataBuffer &to_buffer = _cdata->_buffer;
size_t to_buffer_orig_size = to_buffer.get_size();
to_start = min(to_start, to_buffer_orig_size);
to_size = min(to_size, to_buffer_orig_size - to_start);
if (from_size < to_size) {
// Reduce the array.
unsigned char *pointer = to_buffer.get_write_pointer();
@ -909,8 +940,7 @@ copy_subdata_from(size_t to_start, size_t to_size,
// Now copy the data.
memcpy(to_buffer.get_write_pointer() + to_start,
other->get_read_pointer(true) + from_start,
from_size);
source + from_start, from_size);
_cdata->_modified = Geom::get_next_modified();
if (get_current_thread()->get_pipeline_stage() == 0) {

View File

@ -114,9 +114,11 @@ PUBLISHED:
static void lru_epoch();
INLINE static VertexDataBook &get_book();
#if PY_VERSION_HEX >= 0x02060000
EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
#endif
public:
virtual void evict_lru();
@ -292,6 +294,18 @@ PUBLISHED:
const GeomVertexArrayDataHandle *other,
size_t from_start, size_t from_size);
void copy_data_from(const unsigned char *source, size_t size);
void copy_subdata_from(size_t to_start, size_t to_size,
const unsigned char *source,
size_t from_start, size_t from_size);
EXTENSION(void copy_data_from(PyObject *buffer));
EXTENSION(void copy_subdata_from(size_t to_start, size_t to_size,
PyObject *buffer));
EXTENSION(void copy_subdata_from(size_t to_start, size_t to_size,
PyObject *buffer,
size_t from_start, size_t from_size));
INLINE string get_data() const;
void set_data(const string &data);
INLINE string get_subdata(size_t start, size_t size) const;

View File

@ -21,6 +21,7 @@ struct InternalBufferData {
string _format;
};
#if PY_VERSION_HEX >= 0x02060000
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::__getbuffer__
// Access: Published
@ -165,3 +166,110 @@ __releasebuffer__(PyObject *self, Py_buffer *view) const {
delete data;
view->internal = NULL;
}
#endif // PY_VERSION_HEX >= 0x02060000
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::copy_data_from
// Access: Published
// Description: Copies all data from the given buffer object.
// The array is rescaled as necessary.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_data_from(PyObject *buffer) {
#if PY_VERSION_HEX < 0x02060000
PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");
#else
if (!PyObject_CheckBuffer(buffer)) {
PyErr_SetString(PyExc_TypeError, "buffer object expected");
return;
}
Py_buffer view;
if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
return;
}
_this->copy_data_from((const unsigned char *) view.buf, view.len);
PyBuffer_Release(&view);
#endif
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::copy_subdata_from
// Access: Public
// Description: Copies the entire data array from the buffer
// into a portion of the data array of this object.
// If to_size is not the size of the given buffer,
// the size of this dat array is adjusted accordingly.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_subdata_from(size_t to_start, size_t to_size, PyObject *buffer) {
#if PY_VERSION_HEX < 0x02060000
PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");
#else
if (!PyObject_CheckBuffer(buffer)) {
PyErr_SetString(PyExc_TypeError, "buffer object expected");
return;
}
Py_buffer view;
if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
return;
}
_this->copy_subdata_from(to_start, to_size,
(const unsigned char *) view.buf,
0, (size_t) view.len);
PyBuffer_Release(&view);
#endif
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataHandle::copy_subdata_from
// Access: Public
// Description: Copies a portion of the data array from the buffer
// into a portion of the data array of this object.
// If to_size != from_size, the size of this data
// array is adjusted accordingly.
////////////////////////////////////////////////////////////////////
void Extension<GeomVertexArrayDataHandle>::
copy_subdata_from(size_t to_start, size_t to_size,
PyObject *buffer,
size_t from_start, size_t from_size) {
#if PY_VERSION_HEX < 0x02060000
PyErr_SetString(PyExc_TypeError, "buffer interface not supported before Python 2.6");
#else
if (!PyObject_CheckBuffer(buffer)) {
PyErr_SetString(PyExc_TypeError, "buffer object expected");
return;
}
Py_buffer view;
if (PyObject_GetBuffer(buffer, &view, PyBUF_CONTIG_RO) == -1) {
PyErr_SetString(PyExc_TypeError, "contiguous buffer object expected");
return;
}
size_t from_buffer_orig_size = (size_t) view.len;
from_start = min(from_start, from_buffer_orig_size);
from_size = min(from_size, from_buffer_orig_size - from_start);
_this->copy_subdata_from(to_start, to_size,
(const unsigned char *) view.buf,
from_start, from_size);
PyBuffer_Release(&view);
#endif
}

View File

@ -32,9 +32,28 @@
template<>
class Extension<GeomVertexArrayData> : public ExtensionBase<GeomVertexArrayData> {
public:
#if PY_VERSION_HEX >= 0x02060000
int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
void __releasebuffer__(PyObject *self, Py_buffer *view) const;
#endif
};
////////////////////////////////////////////////////////////////////
// Class : Extension<GeomVertexArrayDataHandle>
// Description : This class defines the extension methods for
// GeomVertexArrayDataHandle, which are called instead
// of any C++ methods with the same prototype.
////////////////////////////////////////////////////////////////////
template<>
class Extension<GeomVertexArrayDataHandle> : public ExtensionBase<GeomVertexArrayDataHandle> {
public:
void copy_data_from(PyObject *buffer);
void copy_subdata_from(size_t to_start, size_t to_size,
PyObject *buffer);
void copy_subdata_from(size_t to_start, size_t to_size,
PyObject *buffer,
size_t from_start, size_t from_size);
};
#endif // HAVE_PYTHON