Panda3D
Loading...
Searching...
No Matches
vertexDataBuffer.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file vertexDataBuffer.cxx
10 * @author drose
11 * @date 2007-05-14
12 */
13
14#include "vertexDataBuffer.h"
15#include "config_gobj.h"
16#include "pStatTimer.h"
17
18TypeHandle VertexDataBuffer::_type_handle;
19
20/**
21 *
22 */
23void VertexDataBuffer::
24operator = (const VertexDataBuffer &copy) {
25 LightMutexHolder holder(_lock);
26 LightMutexHolder holder2(copy._lock);
27
28 if (_resident_data != nullptr) {
29 nassertv(_reserved_size != 0);
30 get_class_type().deallocate_array(_resident_data);
31 _resident_data = nullptr;
32 }
33 if (copy._resident_data != nullptr && copy._size != 0) {
34 // We only allocate _size bytes, not the full _reserved_size allocated by
35 // the original copy.
36 _resident_data = (unsigned char *)get_class_type().allocate_array(copy._size);
37 memcpy(_resident_data, copy._resident_data, copy._size);
38 }
39 _size = copy._size;
40 _reserved_size = copy._size;
41 _block = copy._block;
42 nassertv(_reserved_size >= _size);
43}
44
45/**
46 * Swaps the data buffers between this one and the other one.
47 */
49swap(VertexDataBuffer &other) {
50 LightMutexHolder holder(_lock);
51 LightMutexHolder holder2(other._lock);
52
53 unsigned char *resident_data = _resident_data;
54 size_t size = _size;
55 size_t reserved_size = _reserved_size;
56
57 _block.swap(other._block);
58
59 _resident_data = other._resident_data;
60 _size = other._size;
61 _reserved_size = other._reserved_size;
62
63 other._resident_data = resident_data;
64 other._size = size;
65 other._reserved_size = reserved_size;
66 nassertv(_reserved_size >= _size);
67}
68
69/**
70 * Changes the reserved size of the buffer, preserving its data (except for
71 * any data beyond the new end of the buffer, if the buffer is being reduced).
72 * If the buffer is expanded, the new data is uninitialized.
73 *
74 * Assumes the lock is already held.
75 */
76void VertexDataBuffer::
77do_clean_realloc(size_t reserved_size) {
78 if (reserved_size != _reserved_size) {
79 if (reserved_size == 0 || _size == 0) {
80 do_unclean_realloc(reserved_size);
81 return;
82 }
83
84 if (gobj_cat.is_debug()) {
85 gobj_cat.debug()
86 << this << ".clean_realloc(" << reserved_size << ")\n";
87 }
88
89 // Page in if we're currently paged out.
90 if (_reserved_size != 0 && _resident_data == nullptr) {
91 do_page_in();
92 }
93
94 if (_reserved_size == 0) {
95 nassertv(_resident_data == nullptr);
96 _resident_data = (unsigned char *)get_class_type().allocate_array(reserved_size);
97 } else {
98 nassertv(_resident_data != nullptr);
99 _resident_data = (unsigned char *)get_class_type().reallocate_array(_resident_data, reserved_size);
100 }
101 nassertv(_resident_data != nullptr);
102 _reserved_size = reserved_size;
103 }
104
105 _size = std::min(_size, _reserved_size);
106}
107
108/**
109 * Changes the reserved size of the buffer, without regard to preserving its
110 * data. This implicitly resets the size to 0.
111 *
112 * Assumes the lock is already held.
113 */
114void VertexDataBuffer::
115do_unclean_realloc(size_t reserved_size) {
116 if (reserved_size != _reserved_size || _resident_data == nullptr) {
117 if (gobj_cat.is_debug()) {
118 gobj_cat.debug()
119 << this << ".unclean_realloc(" << reserved_size << ")\n";
120 }
121
122 // If we're paged out, discard the page.
123 _block = nullptr;
124
125 if (_resident_data != nullptr) {
126 nassertv(_reserved_size != 0);
127
128 get_class_type().deallocate_array(_resident_data);
129 _resident_data = nullptr;
130 _reserved_size = 0;
131 }
132
133 if (reserved_size != 0) {
134 nassertv(_resident_data == nullptr);
135 _resident_data = (unsigned char *)get_class_type().allocate_array(reserved_size);
136 }
137
138 _reserved_size = reserved_size;
139 }
140
141 _size = 0;
142}
143
144/**
145 * Moves the buffer out of independent memory and puts it on a page in the
146 * indicated book. The buffer may still be directly accessible as long as its
147 * page remains resident. Any subsequent attempt to rewrite the buffer will
148 * implicitly move it off of the page and back into independent memory.
149 *
150 * Assumes the lock is already held.
151 */
152void VertexDataBuffer::
153do_page_out(VertexDataBook &book) {
154 if (_block != nullptr || _reserved_size == 0) {
155 // We're already paged out.
156 return;
157 }
158 nassertv(_resident_data != nullptr);
159
160 if (_size == 0) {
161 // It's an empty buffer. Just deallocate it; don't bother to create a
162 // block.
163 get_class_type().deallocate_array(_resident_data);
164 _resident_data = nullptr;
165 _reserved_size = 0;
166
167 } else {
168 // It's a nonempty buffer, so write _size bytes (but not the full
169 // _reserved_size bytes) to a block.
170 _block = book.alloc(_size);
171 nassertv(_block != nullptr);
172 unsigned char *pointer = _block->get_pointer(true);
173 nassertv(pointer != nullptr);
174 memcpy(pointer, _resident_data, _size);
175
176 get_class_type().deallocate_array(_resident_data);
177 _resident_data = nullptr;
178
179 _reserved_size = _size;
180 }
181 nassertv(_reserved_size >= _size);
182}
183
184/**
185 * Moves the buffer off of its current page and into independent memory. If
186 * the page is not already resident, it is forced resident first.
187 *
188 * Assumes the lock is already held.
189 */
190void VertexDataBuffer::
191do_page_in() {
192 if (_resident_data != nullptr || _reserved_size == 0) {
193 // We're already paged in.
194 return;
195 }
196
197 nassertv(_block != nullptr);
198 nassertv(_reserved_size == _size);
199
200 _resident_data = (unsigned char *)get_class_type().allocate_array(_size);
201 nassertv(_resident_data != nullptr);
202
203 memcpy(_resident_data, _block->get_pointer(true), _size);
204}
Similar to MutexHolder, but for a light mutex.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
void deallocate_array(void *ptr)
Deallocates memory, subtracting it from the total amount of memory allocated for this type.
void * reallocate_array(void *ptr, size_t size)
Reallocates memory, adjusting the total amount of memory allocated for this type.
void * allocate_array(size_t size)
Allocates memory, adding it to the total amount of memory allocated for this type.
A collection of VertexDataPages, which can be used to allocate new VertexDataBlock objects.
VertexDataBlock * alloc(size_t size)
Allocates and returns a new VertexDataBuffer of the requested size.
A block of bytes that stores the actual raw vertex data referenced by a GeomVertexArrayData object.
void swap(VertexDataBuffer &other)
Swaps the data buffers between this one and the other one.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.