32 (
"max-independent-vertex-data", -1,
33 PRC_DESC(
"Specifies the maximum number of bytes of all vertex data "
34 "that is independent of the paging system. This is an "
35 "initial buffer before max-ram-vertex-data, specifically "
36 "designed for vertex datas that are dynamic in nature and "
37 "may change size or be created and destroyed frequently."));
40 (
"vertex-data-page-size", 262144,
41 PRC_DESC(
"The number of bytes to allocate at a time for vertex data. "
42 "This also controls the page size that is compressed or written "
43 "to disk when vertex data pages are evicted from memory."));
45 SimpleLru GeomVertexArrayData::_independent_lru(
"independent", max_independent_vertex_data);
46 SimpleLru GeomVertexArrayData::_small_lru(
"small", max_independent_vertex_data);
52 TypeHandle GeomVertexArrayData::CData::_type_handle;
53 TypeHandle GeomVertexArrayDataHandle::_type_handle;
81 GeomVertexArrayData::UsageHint usage_hint) :
83 _array_format(array_format),
84 _cycler(CData(usage_hint)),
88 nassertv(_array_format->is_registered());
98 _array_format(copy._array_format),
99 _cycler(copy._cycler),
104 set_lru_size(get_data_size_bytes());
105 nassertv(_array_format->is_registered());
115 CopyOnWriteObject::operator = (copy);
116 SimpleLruPage::operator = (copy);
120 _array_format = copy._array_format;
121 _cycler = copy._cycler;
123 OPEN_ITERATE_ALL_STAGES(_cycler) {
127 CLOSE_ITERATE_ALL_STAGES(_cycler);
129 nassertv(_array_format->is_registered());
135 GeomVertexArrayData::
136 ~GeomVertexArrayData() {
151 if (handle->get_usage_hint() != other_handle->get_usage_hint()) {
152 return (
int)handle->
get_usage_hint() - (int)other_handle->get_usage_hint();
154 if (handle->get_array_format() != other_handle->get_array_format()) {
155 return handle->get_array_format() < other_handle->get_array_format() ? -1 : 1;
157 if (handle->get_data_size_bytes() != other_handle->get_data_size_bytes()) {
158 return (
int)handle->get_data_size_bytes() - (int)other_handle->get_data_size_bytes();
160 return memcmp(handle->get_read_pointer(
true),
161 other_handle->get_read_pointer(
true),
162 handle->get_data_size_bytes());
173 CDWriter cdata(_cycler,
true);
174 cdata->_usage_hint = usage_hint;
181 void GeomVertexArrayData::
182 output(std::ostream &out)
const {
189 void GeomVertexArrayData::
190 write(std::ostream &out,
int indent_level)
const {
191 _array_format->write_with_data(out, indent_level,
this);
213 if (_contexts ==
nullptr) {
216 Contexts::const_iterator ci;
217 ci = _contexts->find(prepared_objects);
218 if (ci != _contexts->end()) {
238 if (_contexts ==
nullptr) {
241 Contexts::const_iterator ci;
242 ci = _contexts->find(prepared_objects);
243 if (ci != _contexts->end()) {
248 if (vbc !=
nullptr) {
249 (*_contexts)[prepared_objects] = vbc;
260 if (_contexts !=
nullptr) {
261 Contexts::iterator ci;
262 ci = _contexts->find(prepared_objects);
263 if (ci != _contexts->end()) {
282 if (_contexts !=
nullptr) {
288 num_freed = (int)_contexts->size();
290 Contexts::const_iterator ci;
291 for (ci = temp.begin(); ci != temp.end(); ++ci) {
299 nassertr(_contexts ==
nullptr, num_freed);
330 cdata->_buffer.page_out(_book);
339 void GeomVertexArrayData::
341 nassertv(_contexts !=
nullptr);
343 Contexts::iterator ci;
344 ci = _contexts->find(prepared_objects);
345 if (ci != _contexts->end()) {
346 _contexts->erase(ci);
347 if (_contexts->empty()) {
354 nassert_raise(
"unknown PreparedGraphicsObjects");
363 void GeomVertexArrayData::
364 reverse_data_endianness(
unsigned char *dest,
const unsigned char *source,
366 int num_columns = _array_format->get_num_columns();
369 for (
size_t pi = 0; pi < size; pi += _array_format->get_stride()) {
372 for (
int ci = 0; ci < num_columns; ++ci) {
375 if (component_bytes > 1) {
380 for (
int cj = 0; cj < num_components; ++cj) {
383 nd.store_value(dest + ci, component_bytes);
384 ci += component_bytes;
418 PTA_uchar data = PTA_uchar::empty_array(size, get_class_type());
419 const unsigned char *source_data =
457 GeomVertexArrayFormat::register_format(_array_format);
460 _array_format = new_array_format;
462 PT(BamAuxData) aux_data = (BamAuxData *)manager->
get_aux_data(
this,
"");
463 if (aux_data !=
nullptr) {
464 if (aux_data->_endian_reversed) {
467 reverse_data_endianness(new_buffer.
get_write_pointer(), cdata->_buffer.get_read_pointer(
true), cdata->_buffer.get_size());
468 cdata->_buffer.swap(new_buffer);
472 set_lru_size(cdata->_buffer.get_size());
487 object->fillin(scan, manager);
497 void GeomVertexArrayData::
508 GeomVertexArrayData::CData::
517 return new CData(*
this);
524 void GeomVertexArrayData::CData::
533 dg.
append_data(_buffer.get_read_pointer(
true), _buffer.get_size());
537 unsigned char *new_data = (
unsigned char *)alloca(_buffer.get_size());
538 array_data->reverse_data_endianness(new_data, _buffer.get_read_pointer(
true), _buffer.get_size());
547 void GeomVertexArrayData::CData::
550 _usage_hint = (UsageHint)scan.
get_uint8();
555 READ_PTA(manager, scan, array_data->
read_raw_data, new_data);
556 _buffer.unclean_realloc(new_data.size());
557 _buffer.set_size(new_data.size());
558 memcpy(_buffer.get_write_pointer(), &new_data[0], new_data.size());
563 _buffer.unclean_realloc(size);
564 _buffer.set_size(size);
566 const unsigned char *source_data =
568 memcpy(_buffer.get_write_pointer(), source_data + scan.
get_current_index(), size);
572 bool endian_reversed =
false;
577 if (array_data->_array_format ==
nullptr) {
580 endian_reversed =
true;
585 array_data->reverse_data_endianness(new_buffer.get_write_pointer(), _buffer.get_read_pointer(
true), _buffer.get_size());
586 _buffer.swap(new_buffer);
590 if (endian_reversed) {
591 PT(BamAuxData) aux_data =
new BamAuxData;
592 aux_data->_endian_reversed = endian_reversed;
596 array_data->set_lru_size(_buffer.get_size());
606 nassertr(_writable,
nullptr);
609 return _cdata->_buffer.get_write_pointer();
615 bool GeomVertexArrayDataHandle::
616 set_num_rows(
int n) {
617 nassertr(_writable,
false);
620 int stride = _object->_array_format->get_stride();
621 size_t new_size = n * stride;
622 size_t orig_size = _cdata->_buffer.get_size();
624 if (gobj_cat.is_spam()) {
626 << _object <<
".set_num_rows(" << n <<
"), size = " << new_size <<
"\n";
629 if (new_size != orig_size) {
630 size_t orig_reserved_size = _cdata->_buffer.get_reserved_size();
631 if (new_size > orig_reserved_size) {
635 nassertr(new_reserved_size >= new_size,
false);
637 _cdata->_buffer.clean_realloc(new_reserved_size);
639 }
else if (new_size == 0) {
643 _cdata->_buffer.clear();
646 _cdata->_buffer.set_size(new_size);
649 if (new_size > orig_size) {
650 memset(_cdata->_buffer.get_write_pointer() + orig_size, 0,
651 new_size - orig_size);
656 if (get_current_thread()->get_pipeline_stage() == 0) {
657 _object->set_lru_size(_cdata->_buffer.get_size());
660 nassertr(get_num_rows() == n,
true);
664 nassertr(get_num_rows() == n,
false);
671 bool GeomVertexArrayDataHandle::
672 unclean_set_num_rows(
int n) {
673 nassertr(_writable,
false);
676 int stride = _object->_array_format->get_stride();
677 size_t new_size = n * stride;
678 size_t orig_size = _cdata->_buffer.get_size();
679 size_t orig_reserved_size = _cdata->_buffer.get_reserved_size();
681 if (new_size != orig_size || new_size != orig_reserved_size) {
687 _cdata->_buffer.unclean_realloc(new_size);
688 _cdata->_buffer.set_size(new_size);
693 if (new_size != orig_size) {
696 if (get_current_thread()->get_pipeline_stage() == 0) {
697 _object->set_lru_size(_cdata->_buffer.get_size());
709 bool GeomVertexArrayDataHandle::
710 reserve_num_rows(
int n) {
711 nassertr(_writable,
false);
714 int stride = _object->_array_format->get_stride();
715 size_t new_reserved_size = n * stride;
716 new_reserved_size = max(_cdata->_buffer.get_size(), new_reserved_size);
717 size_t orig_reserved_size = _cdata->_buffer.get_reserved_size();
719 if (gobj_cat.is_debug()) {
721 << _object <<
".reserve_num_rows(" << n <<
"), size = " << new_reserved_size <<
"\n";
724 if (new_reserved_size != orig_reserved_size) {
728 _cdata->_buffer.clean_realloc(new_reserved_size);
743 size_t size = other->_cdata->_buffer.get_size();
744 const unsigned char *source = other->_cdata->_buffer.get_read_pointer(
true);
757 size_t from_start,
size_t from_size) {
761 size_t from_buffer_orig_size = from_buffer.
get_size();
762 from_start = min(from_start, from_buffer_orig_size);
763 from_size = min(from_size, from_buffer_orig_size - from_start);
767 from_start, from_size);
778 _cdata->_buffer.unclean_realloc(size);
779 _cdata->_buffer.set_size(size);
781 unsigned char *dest = _cdata->_buffer.get_write_pointer();
782 memcpy(dest, source, size);
786 if (get_current_thread()->get_pipeline_stage() == 0) {
787 _object->set_lru_size(_cdata->_buffer.get_size());
798 const unsigned char *source,
799 size_t from_start,
size_t from_size) {
804 size_t to_buffer_orig_size = to_buffer.
get_size();
805 to_start = min(to_start, to_buffer_orig_size);
806 to_size = min(to_size, to_buffer_orig_size - to_start);
808 if (from_size < to_size) {
811 memmove(pointer + to_start + to_size,
812 pointer + to_start + from_size,
813 to_buffer_orig_size - (to_start + to_size));
814 to_buffer.
set_size(to_buffer_orig_size + from_size - to_size);
816 }
else if (to_size < from_size) {
818 size_t needed_size = to_buffer_orig_size + from_size - to_size;
820 if (needed_size > to_buffer_orig_reserved_size) {
827 memmove(pointer + to_start + to_size,
828 pointer + to_start + from_size,
829 to_buffer_orig_size - (to_start + to_size));
834 source + from_start, from_size);
837 if (get_current_thread()->get_pipeline_stage() == 0) {
838 _object->set_lru_size(_cdata->_buffer.get_size());
848 set_data(
const vector_uchar &data) {
852 _cdata->_buffer.unclean_realloc(data.size());
853 _cdata->_buffer.set_size(data.size());
854 memcpy(_cdata->_buffer.get_write_pointer(), data.data(), data.size());
858 if (get_current_thread()->get_pipeline_stage() == 0) {
859 _object->set_lru_size(_cdata->_buffer.get_size());
870 set_subdata(
size_t start,
size_t size,
const vector_uchar &data) {
875 size_t to_buffer_orig_size = to_buffer.
get_size();
876 start = min(start, to_buffer_orig_size);
877 size = min(size, to_buffer_orig_size - start);
879 size_t from_size = data.size();
881 if (from_size < size) {
884 memmove(pointer + start + from_size,
885 pointer + start + size,
886 to_buffer_orig_size - (start + size));
887 to_buffer.
set_size(to_buffer_orig_size + from_size - size);
889 }
else if (size < from_size) {
891 size_t needed_size = to_buffer_orig_size + from_size - size;
893 if (needed_size > to_buffer_orig_reserved_size) {
900 memmove(pointer + start + from_size,
901 pointer + start + size,
902 to_buffer_orig_size - (start + size));
909 if (get_current_thread()->get_pipeline_stage() == 0) {
910 _object->set_lru_size(_cdata->_buffer.get_size());