History

don't do gross things if data is being written while GPU is copying it

Stephen Birarda committed 13 years ago

Commit 80170bd1 parent b50f10f2 files · +65 −47Browse files

Showing the changes to interface/src/VoxelSystem.cpp (1 of 2 files). Show all

Unified · Split

interface/src/VoxelSystem.cpp+56−43
@@ -39,12 +39,16 @@ GLubyte identityIndices[] = { 0,1,2, 0,2,3, · 38 unmodified lines
3939 VoxelSystem::VoxelSystem() {
4040 voxelsRendered = 0;
4141 tree = new VoxelTree();
42+ pthread_mutex_init(&bufferWriteLock, NULL);
4243 }
4344
4445 VoxelSystem::~VoxelSystem() {
45− delete[] verticesArray;
46− delete[] colorsArray;
46+ delete[] readVerticesArray;
47+ delete[] writeVerticesArray;
48+ delete[] readColorsArray;
49+ delete[] writeColorsArray;
4750 delete tree;
51+ pthread_mutex_destroy(&bufferWriteLock);
4852 }
4953
5054 //////////////////////////////////////////////////////////////////////////////////////////
@@ -57,14 +61,8 @@ VoxelSystem::~VoxelSystem() { · 6 unmodified lines
5761 void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) {
5862
5963 tree->loadVoxelsFile(fileName,wantColorRandomizer);
60−
61− // reset the verticesEndPointer so we're writing to the beginning of the array
62− verticesEndPointer = verticesArray;
63− // call recursive function to populate in memory arrays
64− // it will return the number of voxels added
65− voxelsRendered = treeToArrays(tree->rootNode);
66− // set the boolean if there are any voxels to be rendered so we re-fill the VBOs
67− voxelsToRender = (voxelsRendered > 0);
64+
65+ copyWrittenDataToReadArrays();
6866 }
6967
7068 //////////////////////////////////////////////////////////////////////////////////////////
@@ -77,14 +75,7 @@ void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) · 6 unmodified lines
7775 void VoxelSystem::createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer) {
7876
7977 tree->createSphere(r,xc,yc,zc,s,solid,wantColorRandomizer);
80−
81− // reset the verticesEndPointer so we're writing to the beginning of the array
82− verticesEndPointer = verticesArray;
83− // call recursive function to populate in memory arrays
84− // it will return the number of voxels added
85− voxelsRendered = treeToArrays(tree->rootNode);
86− // set the boolean if there are any voxels to be rendered so we re-fill the VBOs
87− voxelsToRender = (voxelsRendered > 0);
78+ setupNewVoxelsForDrawing();
8879 }
8980
9081
@@ -95,20 +86,32 @@ void VoxelSystem::parseData(void *data, int size) { · 4 unmodified lines
9586 // ask the VoxelTree to read the bitstream into the tree
9687 tree->readBitstreamToTree(voxelData, size - 1);
9788
89+ setupNewVoxelsForDrawing();
90+}
91+
92+void VoxelSystem::setupNewVoxelsForDrawing() {
9893 // reset the verticesEndPointer so we're writing to the beginning of the array
99− verticesEndPointer = verticesArray;
100−
94+ writeVerticesEndPointer = writeVerticesArray;
10195 // call recursive function to populate in memory arrays
10296 // it will return the number of voxels added
103− int newVoxels = treeToArrays(tree->rootNode);
97+ voxelsRendered = treeToArrays(tree->rootNode);
10498
105− if (newVoxels > voxelsRendered) {
106−
107− voxelsRendered = newVoxels;
108−
109− // set the boolean if there are any voxels to be rendered so we re-fill the VBOs
110− voxelsToRender = true;
111− }
99+ // copy the newly written data to the arrays designated for reading
100+ copyWrittenDataToReadArrays();
101+}
102+
103+void VoxelSystem::copyWrittenDataToReadArrays() {
104+ // lock on the buffer write lock so we can't modify the data when the GPU is reading it
105+ pthread_mutex_lock(&bufferWriteLock);
106+ // store a pointer to the current end so it doesn't change during copy
107+ GLfloat *endOfCurrentVerticesData = writeVerticesEndPointer;
108+ // copy the vertices and colors
109+ memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat));
110+ memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte));
111+
112+ // set the read vertices end pointer to the correct spot so the GPU knows how much to pull
113+ readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray);
114+ pthread_mutex_unlock(&bufferWriteLock);
112115 }
113116
114117 int VoxelSystem::treeToArrays(VoxelNode *currentNode) {
@@ -130,10 +133,10 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode) { · 15 unmodified lines
130133 // populate the array with points for the 8 vertices
131134 // and RGB color for each added vertex
132135 for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) {
133− *verticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);
134− *(colorsArray + (verticesEndPointer - verticesArray)) = currentNode->color[j % 3];
136+ *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale);
137+ *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->color[j % 3];
135138
136− verticesEndPointer++;
139+ writeVerticesEndPointer++;
137140 }
138141
139142 voxelsAdded++;
@@ -151,8 +154,10 @@ VoxelSystem* VoxelSystem::clone() const { · 11 unmodified lines
151154
152155 void VoxelSystem::init() {
153156 // prep the data structures for incoming voxel data
154− verticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
155− colorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
157+ writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
158+ readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
159+ writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
160+ readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
156161
157162 GLuint *indicesArray = new GLuint[INDICES_PER_VOXEL * MAX_VOXELS_PER_SYSTEM];
158163
@@ -195,16 +200,24 @@ void VoxelSystem::render() { · 36 unmodified lines
195200
196201 glPushMatrix();
197202
198− if (voxelsToRender) {
199− glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
200− glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
201− glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLfloat), verticesArray);
202−
203− glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
204− glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
205− glBufferSubData(GL_ARRAY_BUFFER, 0, (verticesEndPointer - verticesArray) * sizeof(GLubyte), colorsArray);
206−
207− voxelsToRender = false;
203+
204+ if (readVerticesEndPointer != readVerticesArray) {
205+ // try to lock on the buffer write
206+ // just avoid pulling new data if it is currently being written
207+ if (pthread_mutex_trylock(&bufferWriteLock) == 0) {
208+
209+ glBindBuffer(GL_ARRAY_BUFFER, vboVerticesID);
210+ glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
211+ glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLfloat), readVerticesArray);
212+
213+ glBindBuffer(GL_ARRAY_BUFFER, vboColorsID);
214+ glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * MAX_VOXELS_PER_SYSTEM, NULL, GL_DYNAMIC_DRAW);
215+ glBufferSubData(GL_ARRAY_BUFFER, 0, (readVerticesEndPointer - readVerticesArray) * sizeof(GLubyte), readColorsArray);
216+
217+ readVerticesEndPointer = readVerticesArray;
218+
219+ pthread_mutex_unlock(&bufferWriteLock);
220+ }
208221 }
209222
210223 // tell OpenGL where to find vertex and color information