History

Optimized performance of newTreeToArrays() by implementing blended VBO strategy - Introduced concept of sometimes only updating the new/changed part of the VBO while other times updating the full VBO. This allows us to get the speed advantage of only partial VBO updates when nodes haven't been removed - Some debugging output related to _alwaysRenderFullVBO - added cleanupRemovedVoxels() which actually deletes the nodes that were previously removed (fixes a memory leak!!)

ZappoMan committed 13 years ago

Commit bb651371 parent cadc07c2 files · +37 −4Browse files

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

Unified · Split

interface/src/VoxelSystem.cpp+36−4
@@ -147,19 +147,37 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 146 unmodified lines
147147 // If the view frustum has changed, since last time, then remove nodes that are out of view
148148 if ((sinceLastViewCulling >= std::max(_lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) && hasViewChanged()) {
149149 _lastViewCulling = start;
150+
151+ // When we call removeOutOfView() voxels, we don't actually remove the voxels from the VBOs, but we do remove
152+ // them from tree, this makes our tree caclulations faster, but doesn't require us to fully rebuild the VBOs (which
153+ // can be expensive).
150154 removeOutOfView();
155+
156+ // Once we call cleanupRemovedVoxels() we do need to rebuild our VBOs (if anything was actually removed). So,
157+ // we should consider putting this someplace else... as this might be able to occur less frequently, and save us on
158+ // VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.
159+ cleanupRemovedVoxels();
160+
151161 double endViewCulling = usecTimestampNow();
152162 _lastViewCullingElapsed = (endViewCulling - start) / 1000.0;
153163 }
154164
155165 if (_tree->isDirty()) {
156− PerformanceWarning warn(_renderWarningsOn, "calling... newTreeToArrays()");
166+ static char buffer[64] = { 0 };
167+ if (_renderWarningsOn) {
168+ sprintf(buffer, "newTreeToArrays() _alwaysRenderFullVBO=%s", (_alwaysRenderFullVBO ? "yes" : "no"));
169+ };
170+ PerformanceWarning warn(_renderWarningsOn, buffer);
157171 _callsToTreesToArrays++;
158172 if (_alwaysRenderFullVBO) {
159173 _voxelsInWriteArrays = 0; // reset our VBO
160174 }
161175 _voxelsUpdated = newTreeToArrays(_tree->rootNode);
162176 _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean
177+
178+ // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are
179+ // ok again, until/unless we call removeOutOfView()
180+ _alwaysRenderFullVBO = false;
163181 } else {
164182 _voxelsUpdated = 0;
165183 }
@@ -176,6 +194,16 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 10 unmodified lines
176194 _setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
177195 }
178196
197+void VoxelSystem::cleanupRemovedVoxels() {
198+ PerformanceWarning warn(_renderWarningsOn, "cleanupRemovedVoxels()");
199+ if (!_removedVoxels.isEmpty()) {
200+ while (!_removedVoxels.isEmpty()) {
201+ delete _removedVoxels.extract();
202+ }
203+ _alwaysRenderFullVBO = true; // if we remove voxels, we must update our full VBOs
204+ }
205+}
206+
179207 void VoxelSystem::copyWrittenDataToReadArrays() {
180208 PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); // would like to include _voxelsInArrays, _voxelsUpdated
181209 if (_voxelsDirty && _voxelsUpdated) {
@@ -374,7 +402,11 @@ void VoxelSystem::init() { · 192 unmodified lines
374402 }
375403
376404 void VoxelSystem::updateVBOs() {
377− PerformanceWarning warn(_renderWarningsOn, "updateVBOs()"); // would like to include _callsToTreesToArrays
405+ static char buffer[40] = { 0 };
406+ if (_renderWarningsOn) {
407+ sprintf(buffer, "updateVBOs() _alwaysRenderFullVBO=%s", (_alwaysRenderFullVBO ? "yes" : "no"));
408+ };
409+ PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays
378410 if (_voxelsDirty) {
379411 if (_alwaysRenderFullVBO) {
380412 glBufferIndex segmentStart = 0;
@@ -673,9 +705,9 @@ void VoxelSystem::removeOutOfView() { · 292 unmodified lines
673705 _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
674706
675707 if (_renderWarningsOn) {
676− printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld bag.count()=%d \n",
708+ printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d \n",
677709 args.nodesScanned, args.nodesRemoved, args.nodesInside,
678− args.nodesIntersect, args.nodesOutside, args.dontRecurseBag.count()
710+ args.nodesIntersect, args.nodesOutside, _removedVoxels.count()
679711 );
680712 }
681713 }