From 322cb2ff23bab7691f81dd62a774db19a71b143e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 10 May 2013 13:18:51 -0700 Subject: [PATCH] implemented partial VBOs support in copyWrittenDataToReadArrays() --- interface/src/VoxelSystem.cpp | 90 ++++++++++++++++++++++++++++++----- interface/src/VoxelSystem.h | 3 ++ 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index e473961c8e..65f9718e80 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -205,17 +205,86 @@ void VoxelSystem::cleanupRemovedVoxels() { } } +void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() { + // lock on the buffer write lock so we can't modify the data when the GPU is reading it + pthread_mutex_lock(&_bufferWriteLock); + int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat); + int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte); + memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices); + memcpy(_readColorsArray, _writeColorsArray, bytesOfColors ); + _voxelsInReadArrays = _voxelsInWriteArrays; + pthread_mutex_unlock(&_bufferWriteLock); +} + +void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { + // lock on the buffer write lock so we can't modify the data when the GPU is reading it + pthread_mutex_lock(&_bufferWriteLock); + + glBufferIndex segmentStart = 0; + glBufferIndex segmentEnd = 0; + bool inSegment = false; + for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { + bool thisVoxelDirty = _voxelDirtyArray[i]; + if (!inSegment) { + if (thisVoxelDirty) { + segmentStart = i; + inSegment = true; + } + } else { + if (!thisVoxelDirty) { + // If we got here because because this voxel is NOT dirty, so the last dirty voxel was the one before + // this one and so that's where the "segment" ends + segmentEnd = i - 1; + inSegment = false; + int segmentLength = (segmentEnd - segmentStart) + 1; + + GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes); + + segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + memcpy(readColorsAt, writeColorsAt, segmentSizeBytes); + } + } + } + + // if we got to the end of the array, and we're in an active dirty segment... + if (inSegment) { + segmentEnd = _voxelsInWriteArrays - 1; + int segmentLength = (segmentEnd - segmentStart) + 1; + + GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); + GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes); + + segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); + GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + memcpy(readColorsAt, writeColorsAt, segmentSizeBytes); + } + + // update our length + _voxelsInReadArrays = _voxelsInWriteArrays; + + pthread_mutex_unlock(&_bufferWriteLock); +} + void VoxelSystem::copyWrittenDataToReadArrays() { - PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); // would like to include _voxelsInArrays, _voxelsUpdated + PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); if (_voxelsDirty && _voxelsUpdated) { - // lock on the buffer write lock so we can't modify the data when the GPU is reading it - pthread_mutex_lock(&_bufferWriteLock); - int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat); - int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte); - memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices); - memcpy(_readColorsArray, _writeColorsArray, bytesOfColors ); - _voxelsInReadArrays = _voxelsInWriteArrays; - pthread_mutex_unlock(&_bufferWriteLock); + if (_renderFullVBO) { + copyWrittenDataToReadArraysFullVBOs(); + } else { + copyWrittenDataToReadArraysPartialVBOs(); + } } } @@ -493,11 +562,10 @@ void VoxelSystem::updateVBOs() { }; PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays if (_voxelsDirty) { - // updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs() if (_renderFullVBO) { updateFullVBOs(); } else { - updatePartialVBOs(); // too many small segments? + updatePartialVBOs(); } _voxelsDirty = false; } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index c17a9772bb..c0296376fc 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -97,6 +97,9 @@ private: int updateNodeInArraysAsFullVBO(VoxelNode* node); int updateNodeInArraysAsPartialVBO(VoxelNode* node); + void copyWrittenDataToReadArraysFullVBOs(); + void copyWrittenDataToReadArraysPartialVBOs(); + // these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here static float _maxDistance; static float _minDistance;