cleaning up semantics of VoxelPacket

This commit is contained in:
ZappoMan 2013-11-22 20:08:58 -08:00
parent 9d8f0b82df
commit 0cd0012aab
4 changed files with 63 additions and 44 deletions

View file

@ -386,7 +386,7 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod
_myServer->getServerTree().lockForRead();
nodeData->stats.encodeStarted();
int packetStartsAt = _tempPacket.getNextByteUncompressed();
int packetStartsAt = _tempPacket.getUncompressedByteOffset();
bytesWritten = _myServer->getServerTree().encodeTreeBitstream(subTree,
_tempOutputBuffer, MAX_VOXEL_PACKET_SIZE - 1,
@ -428,7 +428,7 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod
// if bytesWritten == 0 it means either the subTree couldn't fit or we had an empty bag... Both cases
// mean we should send the previous packet contents and reset it.
if (_tempPacket.hasContent() && bytesWritten == 0) {
nodeData->writeToPacket(_tempPacket.getCompressedData(), _tempPacket.getCompressedSize());
nodeData->writeToPacket(_tempPacket.getFinalizedData(), _tempPacket.getFinalizedSize());
packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent);
_tempPacket.reset();
}

View file

@ -45,17 +45,15 @@ bool VoxelPacket::append(unsigned char byte) {
return success;
}
bool VoxelPacket::setByte(int offset, unsigned char byte) {
bool VoxelPacket::updatePriorBitMask(int offset, unsigned char bitmask) {
bool success = false;
if (offset >= 0 && offset < _bytesInUse) {
_buffer[offset] = byte;
_buffer[offset] = bitmask;
success = true;
}
return success;
}
bool VoxelPacket::startSubTree(const unsigned char* octcode) {
bool success = false;
int possibleStartAt = _bytesInUse;
@ -83,10 +81,22 @@ void VoxelPacket::discardSubTree() {
_bytesAvailable += bytesInSubTree;
}
void VoxelPacket::startLevel() {
_levelAt = _bytesInUse;
int VoxelPacket::startLevel() {
int key = _bytesInUse;
return key;
}
void VoxelPacket::discardLevel(int key) {
int bytesInLevel = _bytesInUse - key;
_bytesInUse -= bytesInLevel;
_bytesAvailable += bytesInLevel;
}
void VoxelPacket::endLevel() {
// nothing to do
}
bool VoxelPacket::appendBitMask(unsigned char bitmask) {
bool success = false;
if (_bytesAvailable > 0) {
@ -111,12 +121,3 @@ bool VoxelPacket::appendColor(rgbColor color) {
return success;
}
void VoxelPacket::endLevel() {
_levelAt = _bytesInUse;
}
void VoxelPacket::discardLevel() {
int bytesInLevel = _bytesInUse - _levelAt;
_bytesInUse -= bytesInLevel;
_bytesAvailable += bytesInLevel;
}

View file

@ -23,31 +23,49 @@ public:
void endSubTree();
void discardSubTree();
void startLevel();
bool appendBitMask(unsigned char bitmask);
bool appendColor(rgbColor color);
void discardLevel();
void endLevel();
/// starts a level marker. returns an opaque key which can be used to discard the level
int startLevel();
/// discards all content back to a previous marker key
void discardLevel(int key);
/// sets a single raw byte from previously appended portion of the uncompressed stream, might fail if the new byte would
/// cause packet to be less compressed, or if offset was out of range.
bool setByte(int offset, unsigned char byte);
/// ends a level without discarding it
void endLevel();
unsigned char* getCompressedData() { return &_buffer[0]; } /// get pointer to start of compressed stream
int getCompressedSize() const { return _bytesInUse; } /// the size of the packet in compressed form
bool appendBitMask(unsigned char bitmask);
/// returns the offset of the next uncompressed byte to be written
int getNextByteUncompressed() const { return _bytesInUse; }
/// updates the value of a bitmask from a previously appended portion of the uncompressed stream, might fail if the new
/// bitmask would cause packet to be less compressed, or if offset was out of range.
bool updatePriorBitMask(int offset, unsigned char bitmask);
bool appendColor(rgbColor color);
/// returns a byte offset from beginning of the uncompressed stream based on offset from end.
/// Positive offsetFromEnd returns that many bytes before the end of uncompressed stream
int getUncompressedByteOffset(int offsetFromEnd = 0) const { return _bytesInUse - offsetFromEnd; }
/// get access to the finalized data (it may be compressed or rewritten into optimal form)
unsigned char* getFinalizedData() { return &_buffer[0]; } /// get pointer to start of finalized stream
/// get size of the finalized data (it may be compressed or rewritten into optimal form)
int getFinalizedSize() const { return _bytesInUse; } /// the size of the packet in compressed form
////////////////////////////////////
// XXXBHG: Questions...
// Slice Reshuffle...
//
// 1) getEndOfBuffer() is used by recursive slice shuffling... is there a safer API for that? This usage would probably
// break badly with compression... Especially since we do a memcpy into the uncompressed buffer, we'd need to
// add an "updateBytes()" method... which could definitely fail on compression.... It would also break any RLE we
// might implement, since the order of the colors would clearly change.
//
// 2) add stats tracking for number of bytes of octal code, bitmasks, and colors in a packet.
/// has some content been written to the packet
bool hasContent() const { return (_bytesInUse > 0); }
/// returns a byte offset from beginning of stream based on offset from end.
/// Positive offsetFromEnd returns that many bytes before the end
int getByteOffset(int offsetFromEnd) const {
return _bytesInUse - offsetFromEnd;
}
unsigned char* getStartOfBuffer() { return &_buffer[0]; } /// get pointer to the start of stream buffer
unsigned char* getEndOfBuffer() { return &_buffer[_bytesInUse]; } /// get pointer to current end of stream buffer

View file

@ -1292,7 +1292,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
// Make our local buffer large enough to handle writing at this level in case we need to.
unsigned char thisLevelBuffer[MAX_LEVEL_BYTES];
unsigned char* writeToThisLevelBuffer = &thisLevelBuffer[0];
packet->startLevel();
int thisLevelKey = packet->startLevel();
int inViewCount = 0;
int inViewNotLeafCount = 0;
@ -1582,7 +1582,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
// if we were unable to fit this level in our packet, then rewind and add it to the node bag for
// sending later...
if (!continueThisLevel) {
packet->discardLevel();
packet->discardLevel(thisLevelKey);
bag.insert(node);
// don't need to check node here, because we can't get here with no node
@ -1605,7 +1605,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
// write something, we keep them in the bits, if they don't, we take them out.
//
// we know the last thing we wrote to the packet was our childrenExistInPacketBits. Let's remember where that was!
int childExistsPlaceHolder = packet->getByteOffset(sizeof(childrenExistInPacketBits));
int childExistsPlaceHolder = packet->getUncompressedByteOffset(sizeof(childrenExistInPacketBits));
unsigned char* childExistsPlaceHolderOLD = outputBuffer-sizeof(childrenExistInPacketBits);
// we are also going to recurse these child trees in "distance" sorted order, but we need to pack them in the
@ -1682,7 +1682,7 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node,
// repair the child exists mask
*childExistsPlaceHolderOLD = childrenExistInPacketBits;
packet->setByte(childExistsPlaceHolder, childrenExistInPacketBits);
packet->updatePriorBitMask(childExistsPlaceHolder, childrenExistInPacketBits);
// If this is the last of the child exists bits, then we're actually be rolling out the entire tree
if (params.stats && childrenExistInPacketBits == 0) {
@ -1952,7 +1952,7 @@ void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) {
while (!nodeBag.isEmpty()) {
VoxelNode* subTree = nodeBag.extract();
int packetStartsAt = packet.getNextByteUncompressed();
int packetStartsAt = packet.getUncompressedByteOffset();
lockForRead(); // do tree locking down here so that we have shorter slices and less thread contention
EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS);
@ -1963,8 +1963,8 @@ void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) {
// and reinsert the node in our bag and try again...
if (bytesWritten == 0) {
if (packet.hasContent()) {
printf("writeToSVOFile()... WRITING %d bytes...\n", packet.getCompressedSize());
file.write((const char*)packet.getCompressedData(), packet.getCompressedSize());
printf("writeToSVOFile()... WRITING %d bytes...\n", packet.getFinalizedSize());
file.write((const char*)packet.getFinalizedData(), packet.getFinalizedSize());
lastPacketWritten = true;
}
packet.reset(); // is there a better way to do this? could we fit more?
@ -1998,8 +1998,8 @@ void VoxelTree::writeToSVOFile(const char* fileName, VoxelNode* node) {
}
if (!lastPacketWritten) {
printf("writeToSVOFile()... END OF LOOP WRITING %d bytes...\n", packet.getCompressedSize());
file.write((const char*)packet.getCompressedData(), packet.getCompressedSize());
printf("writeToSVOFile()... END OF LOOP WRITING %d bytes...\n", packet.getFinalizedSize());
file.write((const char*)packet.getFinalizedData(), packet.getFinalizedSize());
}
}