From 8d8d73a940317c5706923a79c5a39a59af1f8f7f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 24 Nov 2013 20:49:47 -0800 Subject: [PATCH] start of statistics, convert level key into class --- libraries/voxels/src/VoxelPacket.cpp | 30 ++++++++++++++----- libraries/voxels/src/VoxelPacket.h | 43 +++++++++++++++++++--------- libraries/voxels/src/VoxelTree.cpp | 2 +- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/libraries/voxels/src/VoxelPacket.cpp b/libraries/voxels/src/VoxelPacket.cpp index bbd53e070c..bd7ec7230c 100644 --- a/libraries/voxels/src/VoxelPacket.cpp +++ b/libraries/voxels/src/VoxelPacket.cpp @@ -10,6 +10,10 @@ #include "VoxelPacket.h" bool VoxelPacket::_debug = false; +uint64_t VoxelPacket::_bytesOfOctalCodes = 0; +uint64_t VoxelPacket::_bytesOfBitMasks = 0; +uint64_t VoxelPacket::_bytesOfColor = 0; + VoxelPacket::VoxelPacket(bool enableCompression, int maxFinalizedSize) { @@ -82,17 +86,22 @@ bool VoxelPacket::updatePriorBytes(int offset, const unsigned char* replacementB bool VoxelPacket::startSubTree(const unsigned char* octcode) { bool success = false; int possibleStartAt = _bytesInUse; + int length = 0; if (octcode) { - int length = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(octcode)); + length = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(octcode)); success = append(octcode, length); // handles checking compression } else { // NULL case, means root node, which is 0 unsigned char byte = 0; + length = 1; success = append(byte); // handles checking compression } if (success) { _subTreeAt = possibleStartAt; } + if (success) { + _bytesOfOctalCodes += length; + } return success; } @@ -139,13 +148,13 @@ void VoxelPacket::discardSubTree() { _dirty = true; } -int VoxelPacket::startLevel() { - int key = _bytesInUse; +LevelDetails VoxelPacket::startLevel() { + LevelDetails key(_bytesInUse,0,0,0); return key; } -void VoxelPacket::discardLevel(int key) { - int bytesInLevel = _bytesInUse - key; +void VoxelPacket::discardLevel(LevelDetails key) { + int bytesInLevel = _bytesInUse - key._startIndex; if (_debug) { printf("discardLevel() BEFORE _dirty=%s bytesInLevel=%d _compressedBytes=%d _bytesInUse=%d\n", @@ -162,7 +171,7 @@ void VoxelPacket::discardLevel(int key) { } } -bool VoxelPacket::endLevel(int key) { +bool VoxelPacket::endLevel(LevelDetails key) { bool success = true; // if we are dirty (something has changed) then try a compression test in the following cases... @@ -189,7 +198,11 @@ bool VoxelPacket::endLevel(int key) { } bool VoxelPacket::appendBitMask(unsigned char bitmask) { - return append(bitmask); // handles checking compression + bool success = append(bitmask); // handles checking compression + if (success) { + _bytesOfBitMasks++; + } + return success; } bool VoxelPacket::appendColor(const nodeColor& color) { @@ -206,6 +219,9 @@ bool VoxelPacket::appendColor(const nodeColor& color) { } } } + if (success) { + _bytesOfColor += BYTES_PER_COLOR; + } return success; } diff --git a/libraries/voxels/src/VoxelPacket.h b/libraries/voxels/src/VoxelPacket.h index 6c5a3aebd5..bb8b8bbb02 100644 --- a/libraries/voxels/src/VoxelPacket.h +++ b/libraries/voxels/src/VoxelPacket.h @@ -7,16 +7,8 @@ // TO DO: // // * add stats tracking for number of bytes of octal code, bitmasks, and colors in a packet. -// -// * determine why we sometimes don't fill packets very well (rarely) mid-scene... sometimes it appears as if -// the "next node" would encode with more bytes than can fit in the remainder of the packet. this might be -// several tens or hundreds of bytes, but theoretically other voxels would have fit. This happens in the 0100 -// scene a couple times. -// this is happening because of nodes that are not recursed for good reason like: -// - being occluded -// - being previously in view -// - being out of view, etc. -// in these cases, the node is not re-added to the bag... so, we can probably just keep going... +// - this is challenging, because you need to support the rollback of statistics when +// you discard a level or discard // // * further testing of compression to determine optimal configuration for performance and compression // * improve semantics for "reshuffle" - current approach will work for now and with compression @@ -38,6 +30,23 @@ const int VOXEL_PACKET_TEST_UNCOMPRESSED_THRESHOLD = 4000; const int VOXEL_PACKET_TEST_UNCOMPRESSED_CHANGE_THRESHOLD = 20; const int VOXEL_PACKET_COMPRESSION_DEFAULT = false; +class LevelDetails { + LevelDetails(int startIndex, int bytesOfOctalCodes, int bytesOfBitmasks, int bytesOfColor) : + _startIndex(startIndex), + _bytesOfOctalCodes(bytesOfOctalCodes), + _bytesOfBitmasks(bytesOfBitmasks), + _bytesOfColor(bytesOfColor) { + } + + friend class VoxelPacket; + +private: + int _startIndex; + int _bytesOfOctalCodes; + int _bytesOfBitmasks; + int _bytesOfColor; +}; + class VoxelPacket { public: VoxelPacket(bool enableCompression = false, int maxFinalizedSize = MAX_VOXEL_PACKET_SIZE); @@ -57,14 +66,14 @@ public: void discardSubTree(); /// starts a level marker. returns an opaque key which can be used to discard the level - int startLevel(); + LevelDetails startLevel(); /// discards all content back to a previous marker key - void discardLevel(int key); + void discardLevel(LevelDetails key); /// ends a level, and performs any expensive finalization. may fail if finalization creates a stream which is too large /// if the finalization would fail, the packet will automatically discard the previous level. - bool endLevel(int key); + bool endLevel(LevelDetails key); /// appends a bitmask to the end of the stream, may fail if new data stream is too long to fit in packet bool appendBitMask(unsigned char bitmask); @@ -126,8 +135,14 @@ private: int _compressedBytes; int _bytesInUseLastCheck; bool _dirty; - + + // statistics... + static uint64_t _bytesOfOctalCodes; + static uint64_t _bytesOfBitMasks; + static uint64_t _bytesOfColor; + static bool _debug; + }; #endif /* defined(__hifi__VoxelPacket__) */ \ No newline at end of file diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index f923c9ca5b..06bdc12f02 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1261,7 +1261,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, const int BYTES_PER_COLOR = 3; // Make our local buffer large enough to handle writing at this level in case we need to. - int thisLevelKey = packet->startLevel(); + LevelDetails thisLevelKey = packet->startLevel(); int inViewCount = 0; int inViewNotLeafCount = 0;