00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "geomVertexArrayData.h"
00016 #include "geom.h"
00017 #include "preparedGraphicsObjects.h"
00018 #include "reversedNumericData.h"
00019 #include "bamReader.h"
00020 #include "bamWriter.h"
00021 #include "pset.h"
00022 #include "config_gobj.h"
00023 #include "pStatTimer.h"
00024 #include "configVariableInt.h"
00025 #include "simpleAllocator.h"
00026 #include "vertexDataBuffer.h"
00027 #include "texture.h"
00028
00029 ConfigVariableInt max_independent_vertex_data
00030 ("max-independent-vertex-data", -1,
00031 PRC_DESC("Specifies the maximum number of bytes of all vertex data "
00032 "that is independent of the paging system. This is an "
00033 "initial buffer before max-ram-vertex-data, specifically "
00034 "designed for vertex datas that are dynamic in nature and "
00035 "may change size or be created and destroyed frequently."));
00036
00037 ConfigVariableInt vertex_data_page_size
00038 ("vertex-data-page-size", 262144,
00039 PRC_DESC("The number of bytes to allocate at a time for vertex data. "
00040 "This also controls the page size that is compressed or written "
00041 "to disk when vertex data pages are evicted from memory."));
00042
00043 SimpleLru GeomVertexArrayData::_independent_lru("independent", max_independent_vertex_data);
00044 SimpleLru GeomVertexArrayData::_small_lru("small", max_independent_vertex_data);
00045
00046 VertexDataBook GeomVertexArrayData::_book(vertex_data_page_size);
00047
00048
00049 TypeHandle GeomVertexArrayData::_type_handle;
00050 TypeHandle GeomVertexArrayData::CData::_type_handle;
00051 TypeHandle GeomVertexArrayDataHandle::_type_handle;
00052
00053 ALLOC_DELETED_CHAIN_DEF(GeomVertexArrayDataHandle);
00054
00055
00056
00057
00058
00059
00060
00061 GeomVertexArrayData::
00062 GeomVertexArrayData() : SimpleLruPage(0) {
00063 _contexts = NULL;
00064
00065
00066 }
00067
00068
00069
00070
00071
00072
00073 PT(CopyOnWriteObject) GeomVertexArrayData::
00074 make_cow_copy() {
00075 return new GeomVertexArrayData(*this);
00076 }
00077
00078
00079
00080
00081
00082
00083 GeomVertexArrayData::
00084 GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
00085 GeomVertexArrayData::UsageHint usage_hint) :
00086 SimpleLruPage(0),
00087 _array_format(array_format)
00088 {
00089 OPEN_ITERATE_ALL_STAGES(_cycler) {
00090 CDStageWriter cdata(_cycler, pipeline_stage);
00091 cdata->_usage_hint = usage_hint;
00092 }
00093 CLOSE_ITERATE_ALL_STAGES(_cycler);
00094
00095 _contexts = NULL;
00096
00097 set_lru_size(0);
00098 nassertv(_array_format->is_registered());
00099 }
00100
00101
00102
00103
00104
00105
00106 GeomVertexArrayData::
00107 GeomVertexArrayData(const GeomVertexArrayData ©) :
00108 CopyOnWriteObject(copy),
00109 SimpleLruPage(copy),
00110 _array_format(copy._array_format),
00111 _cycler(copy._cycler)
00112 {
00113 _contexts = NULL;
00114
00115 copy.mark_used_lru();
00116
00117 set_lru_size(get_data_size_bytes());
00118 nassertv(_array_format->is_registered());
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void GeomVertexArrayData::
00130 operator = (const GeomVertexArrayData ©) {
00131 CopyOnWriteObject::operator = (copy);
00132 SimpleLruPage::operator = (copy);
00133
00134 copy.mark_used_lru();
00135
00136 _array_format = copy._array_format;
00137 _cycler = copy._cycler;
00138
00139 OPEN_ITERATE_ALL_STAGES(_cycler) {
00140 CDStageWriter cdata(_cycler, pipeline_stage);
00141 cdata->_modified = Geom::get_next_modified();
00142 }
00143 CLOSE_ITERATE_ALL_STAGES(_cycler);
00144
00145 nassertv(_array_format->is_registered());
00146 }
00147
00148
00149
00150
00151
00152
00153 GeomVertexArrayData::
00154 ~GeomVertexArrayData() {
00155 release_all();
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 int GeomVertexArrayData::
00165 compare_to(const GeomVertexArrayData &other) const {
00166 Thread *current_thread = Thread::get_current_thread();
00167
00168 CPT(GeomVertexArrayDataHandle) handle = get_handle(current_thread);
00169 CPT(GeomVertexArrayDataHandle) other_handle = other.get_handle(current_thread);
00170
00171 if (handle->get_usage_hint() != other_handle->get_usage_hint()) {
00172 return (int)handle->get_usage_hint() - (int)other_handle->get_usage_hint();
00173 }
00174 if (handle->get_array_format() != other_handle->get_array_format()) {
00175 return handle->get_array_format() < other_handle->get_array_format() ? -1 : 1;
00176 }
00177 if (handle->get_data_size_bytes() != other_handle->get_data_size_bytes()) {
00178 return (int)handle->get_data_size_bytes() - (int)other_handle->get_data_size_bytes();
00179 }
00180 return memcmp(handle->get_read_pointer(true),
00181 other_handle->get_read_pointer(true),
00182 handle->get_data_size_bytes());
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 void GeomVertexArrayData::
00196 set_usage_hint(GeomVertexArrayData::UsageHint usage_hint) {
00197 CDWriter cdata(_cycler, true);
00198 cdata->_usage_hint = usage_hint;
00199 cdata->_modified = Geom::get_next_modified();
00200 }
00201
00202
00203
00204
00205
00206
00207 void GeomVertexArrayData::
00208 output(ostream &out) const {
00209 out << get_num_rows() << " rows: " << *get_array_format();
00210 }
00211
00212
00213
00214
00215
00216
00217 void GeomVertexArrayData::
00218 write(ostream &out, int indent_level) const {
00219 _array_format->write_with_data(out, indent_level, this);
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 void GeomVertexArrayData::
00235 prepare(PreparedGraphicsObjects *prepared_objects) {
00236 prepared_objects->enqueue_vertex_buffer(this);
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246 bool GeomVertexArrayData::
00247 is_prepared(PreparedGraphicsObjects *prepared_objects) const {
00248 if (_contexts == (Contexts *)NULL) {
00249 return false;
00250 }
00251 Contexts::const_iterator ci;
00252 ci = _contexts->find(prepared_objects);
00253 if (ci != _contexts->end()) {
00254 return true;
00255 }
00256 return prepared_objects->is_vertex_buffer_queued(this);
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 VertexBufferContext *GeomVertexArrayData::
00276 prepare_now(PreparedGraphicsObjects *prepared_objects,
00277 GraphicsStateGuardianBase *gsg) {
00278 if (_contexts == (Contexts *)NULL) {
00279 _contexts = new Contexts;
00280 }
00281 Contexts::const_iterator ci;
00282 ci = _contexts->find(prepared_objects);
00283 if (ci != _contexts->end()) {
00284 return (*ci).second;
00285 }
00286
00287 VertexBufferContext *vbc = prepared_objects->prepare_vertex_buffer_now(this, gsg);
00288 if (vbc != (VertexBufferContext *)NULL) {
00289 (*_contexts)[prepared_objects] = vbc;
00290 }
00291 return vbc;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301 bool GeomVertexArrayData::
00302 release(PreparedGraphicsObjects *prepared_objects) {
00303 if (_contexts != (Contexts *)NULL) {
00304 Contexts::iterator ci;
00305 ci = _contexts->find(prepared_objects);
00306 if (ci != _contexts->end()) {
00307 VertexBufferContext *vbc = (*ci).second;
00308 prepared_objects->release_vertex_buffer(vbc);
00309 return true;
00310 }
00311 }
00312
00313
00314 return prepared_objects->dequeue_vertex_buffer(this);
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324 int GeomVertexArrayData::
00325 release_all() {
00326 int num_freed = 0;
00327
00328 if (_contexts != (Contexts *)NULL) {
00329
00330
00331
00332
00333 Contexts temp = *_contexts;
00334 num_freed = (int)_contexts->size();
00335
00336 Contexts::const_iterator ci;
00337 for (ci = temp.begin(); ci != temp.end(); ++ci) {
00338 PreparedGraphicsObjects *prepared_objects = (*ci).first;
00339 VertexBufferContext *vbc = (*ci).second;
00340 prepared_objects->release_vertex_buffer(vbc);
00341 }
00342
00343
00344
00345 nassertr(_contexts == NULL, num_freed);
00346 }
00347
00348 return num_freed;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358 void GeomVertexArrayData::
00359 lru_epoch() {
00360 _independent_lru.begin_epoch();
00361 VertexDataPage::get_global_lru(VertexDataPage::RC_resident)->begin_epoch();
00362 VertexDataPage::get_global_lru(VertexDataPage::RC_compressed)->begin_epoch();
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 void GeomVertexArrayData::
00381 evict_lru() {
00382 dequeue_lru();
00383 CDWriter cdata(_cycler, true);
00384 cdata->_buffer.page_out(_book);
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 void GeomVertexArrayData::
00398 clear_prepared(PreparedGraphicsObjects *prepared_objects) {
00399 nassertv(_contexts != (Contexts *)NULL);
00400
00401 Contexts::iterator ci;
00402 ci = _contexts->find(prepared_objects);
00403 if (ci != _contexts->end()) {
00404 _contexts->erase(ci);
00405 if (_contexts->empty()) {
00406 delete _contexts;
00407 _contexts = NULL;
00408 }
00409 } else {
00410
00411
00412 nassertv(false);
00413 }
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 void GeomVertexArrayData::
00425 reverse_data_endianness(unsigned char *dest, const unsigned char *source,
00426 size_t size) {
00427 int num_columns = _array_format->get_num_columns();
00428
00429
00430 for (size_t pi = 0; pi < size; pi += _array_format->get_stride()) {
00431
00432
00433 for (int ci = 0; ci < num_columns; ++ci) {
00434 const GeomVertexColumn *col = _array_format->get_column(ci);
00435 int component_bytes = col->get_component_bytes();
00436 if (component_bytes > 1) {
00437
00438 size_t ci = pi + col->get_start();
00439
00440 int num_components = col->get_num_components();
00441 for (int cj = 0; cj < num_components; ++cj) {
00442
00443 ReversedNumericData nd(source + ci, component_bytes);
00444 nd.store_value(dest + ci, component_bytes);
00445 ci += component_bytes;
00446 }
00447 }
00448 }
00449 }
00450 }
00451
00452
00453
00454
00455
00456
00457
00458 void GeomVertexArrayData::
00459 register_with_read_factory() {
00460 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00461 }
00462
00463
00464
00465
00466
00467
00468
00469 void GeomVertexArrayData::
00470 write_datagram(BamWriter *manager, Datagram &dg) {
00471 CopyOnWriteObject::write_datagram(manager, dg);
00472
00473 manager->write_pointer(dg, _array_format);
00474 manager->write_cdata(dg, _cycler, this);
00475 }
00476
00477
00478
00479
00480
00481
00482
00483 PTA_uchar GeomVertexArrayData::
00484 read_raw_data(BamReader *manager, DatagramIterator &scan) {
00485 size_t size = scan.get_uint32();
00486 PTA_uchar data = PTA_uchar::empty_array(size, get_class_type());
00487 const unsigned char *source_data =
00488 (const unsigned char *)scan.get_datagram().get_data();
00489 memcpy(data, source_data + scan.get_current_index(), size);
00490 scan.skip_bytes(size);
00491
00492 return data;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502 int GeomVertexArrayData::
00503 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00504 int pi = CopyOnWriteObject::complete_pointers(p_list, manager);
00505
00506 _array_format = DCAST(GeomVertexArrayFormat, p_list[pi++]);
00507
00508 return pi;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518 void GeomVertexArrayData::
00519 finalize(BamReader *manager) {
00520
00521
00522
00523
00524
00525
00526
00527 CDWriter cdata(_cycler, true);
00528
00529 CPT(GeomVertexArrayFormat) new_array_format =
00530 GeomVertexArrayFormat::register_format(_array_format);
00531
00532 manager->change_pointer(_array_format, new_array_format);
00533 _array_format = new_array_format;
00534
00535 PT(BamAuxData) aux_data = (BamAuxData *)manager->get_aux_data(this, "");
00536 if (aux_data != (BamAuxData *)NULL) {
00537 if (aux_data->_endian_reversed) {
00538
00539 VertexDataBuffer new_buffer(cdata->_buffer.get_size());
00540 reverse_data_endianness(new_buffer.get_write_pointer(), cdata->_buffer.get_read_pointer(true), cdata->_buffer.get_size());
00541 cdata->_buffer.swap(new_buffer);
00542 }
00543 }
00544
00545 set_lru_size(cdata->_buffer.get_size());
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 TypedWritable *GeomVertexArrayData::
00557 make_from_bam(const FactoryParams ¶ms) {
00558 GeomVertexArrayData *object = new GeomVertexArrayData;
00559 DatagramIterator scan;
00560 BamReader *manager;
00561
00562 parse_params(params, scan, manager);
00563 object->fillin(scan, manager);
00564 manager->register_finalize(object);
00565
00566 return object;
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576 void GeomVertexArrayData::
00577 fillin(DatagramIterator &scan, BamReader *manager) {
00578 CopyOnWriteObject::fillin(scan, manager);
00579
00580 manager->read_pointer(scan);
00581 manager->read_cdata(scan, _cycler, this);
00582 }
00583
00584
00585
00586
00587
00588
00589 GeomVertexArrayData::CData::
00590 ~CData() {
00591 }
00592
00593
00594
00595
00596
00597
00598 CycleData *GeomVertexArrayData::CData::
00599 make_copy() const {
00600 return new CData(*this);
00601 }
00602
00603
00604
00605
00606
00607
00608
00609 void GeomVertexArrayData::CData::
00610 write_datagram(BamWriter *manager, Datagram &dg, void *extra_data) const {
00611 GeomVertexArrayData *array_data = (GeomVertexArrayData *)extra_data;
00612 dg.add_uint8(_usage_hint);
00613
00614 dg.add_uint32(_buffer.get_size());
00615
00616 if (manager->get_file_endian() == BamWriter::BE_native) {
00617
00618 dg.append_data(_buffer.get_read_pointer(true), _buffer.get_size());
00619
00620 } else {
00621
00622 unsigned char *new_data = (unsigned char *)alloca(_buffer.get_size());
00623 array_data->reverse_data_endianness(new_data, _buffer.get_read_pointer(true), _buffer.get_size());
00624 dg.append_data(new_data, _buffer.get_size());
00625 }
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635 void GeomVertexArrayData::CData::
00636 fillin(DatagramIterator &scan, BamReader *manager, void *extra_data) {
00637 GeomVertexArrayData *array_data = (GeomVertexArrayData *)extra_data;
00638 _usage_hint = (UsageHint)scan.get_uint8();
00639
00640 if (manager->get_file_minor_ver() < 8) {
00641
00642 PTA_uchar new_data;
00643 READ_PTA(manager, scan, array_data->read_raw_data, new_data);
00644 _buffer.unclean_realloc(new_data.size());
00645 _buffer.set_size(new_data.size());
00646 memcpy(_buffer.get_write_pointer(), &new_data[0], new_data.size());
00647
00648 } else {
00649
00650 size_t size = scan.get_uint32();
00651 _buffer.unclean_realloc(size);
00652 _buffer.set_size(size);
00653
00654 const unsigned char *source_data =
00655 (const unsigned char *)scan.get_datagram().get_data();
00656 memcpy(_buffer.get_write_pointer(), source_data + scan.get_current_index(), size);
00657 scan.skip_bytes(size);
00658 }
00659
00660 bool endian_reversed = false;
00661
00662 if (manager->get_file_endian() != BamReader::BE_native) {
00663
00664
00665 if (array_data->_array_format == (GeomVertexArrayFormat *)NULL) {
00666
00667
00668 endian_reversed = true;
00669 } else {
00670
00671
00672
00673 VertexDataBuffer new_buffer(_buffer.get_size());
00674 array_data->reverse_data_endianness(new_buffer.get_write_pointer(), _buffer.get_read_pointer(true), _buffer.get_size());
00675 _buffer.swap(new_buffer);
00676 }
00677 }
00678
00679 if (endian_reversed) {
00680 PT(BamAuxData) aux_data = new BamAuxData;
00681 aux_data->_endian_reversed = endian_reversed;
00682 manager->set_aux_data(array_data, "", aux_data);
00683 }
00684
00685 array_data->set_lru_size(_buffer.get_size());
00686
00687 _modified = Geom::get_next_modified();
00688 }
00689
00690
00691
00692
00693
00694
00695
00696 unsigned char *GeomVertexArrayDataHandle::
00697 get_write_pointer() {
00698 nassertr(_writable, NULL);
00699 mark_used();
00700 _cdata->_modified = Geom::get_next_modified();
00701 return _cdata->_buffer.get_write_pointer();
00702 }
00703
00704
00705
00706
00707
00708
00709 bool GeomVertexArrayDataHandle::
00710 set_num_rows(int n) {
00711 nassertr(_writable, false);
00712 mark_used();
00713
00714 int stride = _object->_array_format->get_stride();
00715 size_t new_size = n * stride;
00716 size_t orig_size = _cdata->_buffer.get_size();
00717
00718 if (gobj_cat.is_spam()) {
00719 gobj_cat.spam()
00720 << _object << ".set_num_rows(" << n << "), size = " << new_size << "\n";
00721 }
00722
00723 if (new_size != orig_size) {
00724 size_t orig_reserved_size = _cdata->_buffer.get_reserved_size();
00725 if (new_size > orig_reserved_size) {
00726
00727
00728 size_t new_reserved_size = (size_t)Texture::up_to_power_2((int)new_size);
00729 nassertr(new_reserved_size >= new_size, false);
00730
00731 _cdata->_buffer.clean_realloc(new_reserved_size);
00732
00733 } else if (new_size == 0) {
00734
00735
00736
00737 _cdata->_buffer.clear();
00738 }
00739
00740 _cdata->_buffer.set_size(new_size);
00741
00742
00743 if (new_size > orig_size) {
00744 memset(_cdata->_buffer.get_write_pointer() + orig_size, 0,
00745 new_size - orig_size);
00746 }
00747
00748 _cdata->_modified = Geom::get_next_modified();
00749
00750 if (get_current_thread()->get_pipeline_stage() == 0) {
00751 _object->set_lru_size(_cdata->_buffer.get_size());
00752 }
00753
00754 nassertr(get_num_rows() == n, true);
00755 return true;
00756 }
00757
00758 nassertr(get_num_rows() == n, false);
00759 return false;
00760 }
00761
00762
00763
00764
00765
00766
00767 bool GeomVertexArrayDataHandle::
00768 unclean_set_num_rows(int n) {
00769 nassertr(_writable, false);
00770 mark_used();
00771
00772 int stride = _object->_array_format->get_stride();
00773 size_t new_size = n * stride;
00774 size_t orig_size = _cdata->_buffer.get_size();
00775 size_t orig_reserved_size = _cdata->_buffer.get_reserved_size();
00776
00777 if (new_size != orig_size || new_size != orig_reserved_size) {
00778
00779
00780
00781
00782
00783 _cdata->_buffer.unclean_realloc(new_size);
00784 _cdata->_buffer.set_size(new_size);
00785
00786
00787
00788
00789 if (new_size != orig_size) {
00790 _cdata->_modified = Geom::get_next_modified();
00791
00792 if (get_current_thread()->get_pipeline_stage() == 0) {
00793 _object->set_lru_size(_cdata->_buffer.get_size());
00794 }
00795 }
00796 return true;
00797 }
00798
00799 return false;
00800 }
00801
00802
00803
00804
00805
00806
00807 bool GeomVertexArrayDataHandle::
00808 reserve_num_rows(int n) {
00809 nassertr(_writable, false);
00810 mark_used();
00811
00812 int stride = _object->_array_format->get_stride();
00813 size_t new_reserved_size = n * stride;
00814 new_reserved_size = max(_cdata->_buffer.get_size(), new_reserved_size);
00815 size_t orig_reserved_size = _cdata->_buffer.get_reserved_size();
00816
00817 if (gobj_cat.is_debug()) {
00818 gobj_cat.debug()
00819 << _object << ".reserve_num_rows(" << n << "), size = " << new_reserved_size << "\n";
00820 }
00821
00822 if (new_reserved_size != orig_reserved_size) {
00823
00824
00825
00826
00827 _cdata->_buffer.clean_realloc(new_reserved_size);
00828 return true;
00829 }
00830
00831 return false;
00832 }
00833
00834
00835
00836
00837
00838
00839 void GeomVertexArrayDataHandle::
00840 copy_data_from(const GeomVertexArrayDataHandle *other) {
00841 nassertv(_writable);
00842 mark_used();
00843 other->mark_used();
00844
00845 size_t size = other->_cdata->_buffer.get_size();
00846 _cdata->_buffer.unclean_realloc(size);
00847 _cdata->_buffer.set_size(size);
00848
00849 unsigned char *dest = _cdata->_buffer.get_write_pointer();
00850 const unsigned char *source = other->_cdata->_buffer.get_read_pointer(true);
00851 memcpy(dest, source, size);
00852
00853 _cdata->_modified = Geom::get_next_modified();
00854
00855 if (get_current_thread()->get_pipeline_stage() == 0) {
00856 _object->set_lru_size(_cdata->_buffer.get_size());
00857 }
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 void GeomVertexArrayDataHandle::
00869 copy_subdata_from(size_t to_start, size_t to_size,
00870 const GeomVertexArrayDataHandle *other,
00871 size_t from_start, size_t from_size) {
00872 nassertv(_writable);
00873 mark_used();
00874 other->mark_used();
00875
00876 VertexDataBuffer &to_buffer = _cdata->_buffer;
00877 size_t to_buffer_orig_size = to_buffer.get_size();
00878 to_start = min(to_start, to_buffer_orig_size);
00879 to_size = min(to_size, to_buffer_orig_size - to_start);
00880
00881 const VertexDataBuffer &from_buffer = other->_cdata->_buffer;
00882 size_t from_buffer_orig_size = from_buffer.get_size();
00883 from_start = min(from_start, from_buffer_orig_size);
00884 from_size = min(from_size, from_buffer_orig_size - from_start);
00885
00886 if (from_size < to_size) {
00887
00888 unsigned char *pointer = to_buffer.get_write_pointer();
00889 memmove(pointer + to_start + to_size,
00890 pointer + to_start + from_size,
00891 to_buffer_orig_size - (to_start + to_size));
00892 to_buffer.set_size(to_buffer_orig_size + from_size - to_size);
00893
00894 } else if (to_size < from_size) {
00895
00896 size_t needed_size = to_buffer_orig_size + from_size - to_size;
00897 size_t to_buffer_orig_reserved_size = to_buffer.get_reserved_size();
00898 if (needed_size > to_buffer_orig_reserved_size) {
00899 size_t new_reserved_size = (size_t)Texture::up_to_power_2((int)needed_size);
00900 to_buffer.clean_realloc(new_reserved_size);
00901 }
00902 to_buffer.set_size(needed_size);
00903
00904 unsigned char *pointer = to_buffer.get_write_pointer();
00905 memmove(pointer + to_start + to_size,
00906 pointer + to_start + from_size,
00907 to_buffer_orig_size - (to_start + to_size));
00908 }
00909
00910
00911 memcpy(to_buffer.get_write_pointer() + to_start,
00912 other->get_read_pointer(true) + from_start,
00913 from_size);
00914 _cdata->_modified = Geom::get_next_modified();
00915
00916 if (get_current_thread()->get_pipeline_stage() == 0) {
00917 _object->set_lru_size(_cdata->_buffer.get_size());
00918 }
00919 }
00920
00921
00922
00923
00924
00925
00926
00927
00928 void GeomVertexArrayDataHandle::
00929 set_data(const string &data) {
00930 nassertv(_writable);
00931 mark_used();
00932
00933 _cdata->_buffer.unclean_realloc(data.size());
00934 _cdata->_buffer.set_size(data.size());
00935 memcpy(_cdata->_buffer.get_write_pointer(), data.data(), data.size());
00936
00937 _cdata->_modified = Geom::get_next_modified();
00938
00939 if (get_current_thread()->get_pipeline_stage() == 0) {
00940 _object->set_lru_size(_cdata->_buffer.get_size());
00941 }
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 void GeomVertexArrayDataHandle::
00955 set_subdata(size_t start, size_t size, const string &data) {
00956 nassertv(_writable);
00957 mark_used();
00958
00959 VertexDataBuffer &to_buffer = _cdata->_buffer;
00960 size_t to_buffer_orig_size = to_buffer.get_size();
00961 start = min(start, to_buffer_orig_size);
00962 size = min(size, to_buffer_orig_size - start);
00963
00964 size_t from_size = data.size();
00965
00966 if (from_size < size) {
00967
00968 unsigned char *pointer = to_buffer.get_write_pointer();
00969 memmove(pointer + start + from_size,
00970 pointer + start + size,
00971 to_buffer_orig_size - (start + size));
00972 to_buffer.set_size(to_buffer_orig_size + from_size - size);
00973
00974 } else if (size < from_size) {
00975
00976 size_t needed_size = to_buffer_orig_size + from_size - size;
00977 size_t to_buffer_orig_reserved_size = to_buffer.get_reserved_size();
00978 if (needed_size > to_buffer_orig_reserved_size) {
00979 size_t new_reserved_size = (size_t)Texture::up_to_power_2((int)needed_size);
00980 to_buffer.clean_realloc(new_reserved_size);
00981 }
00982 to_buffer.set_size(needed_size);
00983
00984 unsigned char *pointer = to_buffer.get_write_pointer();
00985 memmove(pointer + start + from_size,
00986 pointer + start + size,
00987 to_buffer_orig_size - (start + size));
00988 }
00989
00990
00991 memcpy(to_buffer.get_write_pointer() + start, data.data(), from_size);
00992 _cdata->_modified = Geom::get_next_modified();
00993
00994 if (get_current_thread()->get_pipeline_stage() == 0) {
00995 _object->set_lru_size(_cdata->_buffer.get_size());
00996 }
00997 }