From 87a44bafc9b9c6d9dff307ff823de0cd0ad33e80 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 28 Oct 2013 12:37:47 -0700 Subject: [PATCH 1/6] added population data back for SIMPLE_CHILD_ARRAY implementation --- libraries/voxels/src/VoxelNode.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 456a2d8e58..3eb6047242 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -690,12 +690,23 @@ void VoxelNode::deleteAllChildren() { void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) { #ifdef SIMPLE_CHILD_ARRAY + int previousChildCount = getChildCount(); if (child) { setAtBit(_childBitmask, childIndex); } else { clearAtBit(_childBitmask, childIndex); } + int newChildCount = getChildCount(); + + // store the child in our child array _simpleChildArray[childIndex] = child; + + // track our population data + if (previousChildCount != newChildCount) { + _childrenCount[previousChildCount]--; + _childrenCount[newChildCount]++; + } + #else PerformanceWarning warn(false,"setChildAtIndex",false,&_setChildAtIndexTime,&_setChildAtIndexCalls); From 03b2ace488c5fe89ca589b915c748d0dd672b953 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 28 Oct 2013 12:54:37 -0700 Subject: [PATCH 2/6] moved blended _children union into BLENDED_UNION_CHILDREN --- .../voxel-server-library/src/VoxelServer.cpp | 16 +++++++++++--- libraries/voxels/src/VoxelNode.cpp | 21 +++++++++++++++---- libraries/voxels/src/VoxelNode.h | 21 ++++++++++++------- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index 1167ef8b46..a7fe8869d9 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -136,7 +136,9 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, "%s", "\r\n"); mg_printf(connection, "%s", "VoxelNode Children Encoding Statistics...\r\n"); - mg_printf(connection, " Single or No Children: %10.llu nodes (%5.2f%%)\r\n", + +#ifdef BLENDED_UNION_CHILDREN + mg_printf(connection, " Single or No Children: %10.llu nodes (%5.2f%%)\r\n", VoxelNode::getSingleChildrenCount(), ((float)VoxelNode::getSingleChildrenCount()/(float)nodeCount) * AS_PERCENT); mg_printf(connection, " Two Children as Offset: %10.llu nodes (%5.2f%%)\r\n", VoxelNode::getTwoChildrenOffsetCount(), @@ -150,14 +152,19 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, " Three Children as External: %10.llu nodes (%5.2f%%)\r\n", VoxelNode::getThreeChildrenExternalCount(), ((float)VoxelNode::getThreeChildrenExternalCount()/(float)nodeCount) * AS_PERCENT); - mg_printf(connection, " Children as External Array: %10.llu nodes (%5.2f%%)\r\n", +#endif + mg_printf(connection, " Children as External Array: %10.llu nodes (%5.2f%%)\r\n", VoxelNode::getExternalChildrenCount(), ((float)VoxelNode::getExternalChildrenCount()/(float)nodeCount) * AS_PERCENT); - uint64_t checkSum = VoxelNode::getSingleChildrenCount() + +#ifdef BLENDED_UNION_CHILDREN + uint64_t checkSum = VoxelNode::getSingleChildrenCount() + VoxelNode::getTwoChildrenOffsetCount() + VoxelNode::getTwoChildrenExternalCount() + VoxelNode::getThreeChildrenOffsetCount() + VoxelNode::getThreeChildrenExternalCount() + VoxelNode::getExternalChildrenCount(); +#else + uint64_t checkSum = VoxelNode::getExternalChildrenCount(); +#endif mg_printf(connection, "%s", " ----------------\r\n"); mg_printf(connection, " Total: %10.llu nodes\r\n", checkSum); @@ -175,11 +182,14 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, " Total: %10.llu nodes\r\n", checkSum); mg_printf(connection, "%s", "\r\n"); + +#ifdef BLENDED_UNION_CHILDREN mg_printf(connection, "%s", "In other news....\r\n"); mg_printf(connection, "could store 4 children internally: %10.llu nodes\r\n", VoxelNode::getCouldStoreFourChildrenInternally()); mg_printf(connection, "could NOT store 4 children internally: %10.llu nodes\r\n", VoxelNode::getCouldNotStoreFourChildrenInternally()); +#endif return 1; } else { diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 3eb6047242..a1f6d9aa7e 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -65,8 +65,11 @@ void VoxelNode::init(unsigned char * octalCode) { // set up the _children union _childBitmask = 0; _childrenExternal = false; + +#ifdef BLENDED_UNION_CHILDREN _children.external = NULL; _singleChildrenCount++; +#endif _childrenCount[0]++; // default pointers to child nodes to NULL @@ -314,20 +317,25 @@ uint64_t VoxelNode::_getChildAtIndexCalls = 0; uint64_t VoxelNode::_setChildAtIndexTime = 0; uint64_t VoxelNode::_setChildAtIndexCalls = 0; +#ifdef BLENDED_UNION_CHILDREN uint64_t VoxelNode::_singleChildrenCount = 0; uint64_t VoxelNode::_twoChildrenOffsetCount = 0; uint64_t VoxelNode::_twoChildrenExternalCount = 0; uint64_t VoxelNode::_threeChildrenOffsetCount = 0; uint64_t VoxelNode::_threeChildrenExternalCount = 0; -uint64_t VoxelNode::_externalChildrenCount = 0; -uint64_t VoxelNode::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint64_t VoxelNode::_couldStoreFourChildrenInternally = 0; uint64_t VoxelNode::_couldNotStoreFourChildrenInternally = 0; +#endif + +uint64_t VoxelNode::_externalChildrenCount = 0; +uint64_t VoxelNode::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const { #ifdef SIMPLE_CHILD_ARRAY return _simpleChildArray[childIndex]; -#else +#endif // SIMPLE_CHILD_ARRAY + +#ifdef BLENDED_UNION_CHILDREN PerformanceWarning warn(false,"getChildAtIndex",false,&_getChildAtIndexTime,&_getChildAtIndexCalls); VoxelNode* result = NULL; int childCount = getChildCount(); @@ -439,6 +447,7 @@ VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const { #endif } +#ifdef BLENDED_UNION_CHILDREN void VoxelNode::storeTwoChildren(VoxelNode* childOne, VoxelNode* childTwo) { int64_t offsetOne = (uint8_t*)childOne - (uint8_t*)this; int64_t offsetTwo = (uint8_t*)childTwo - (uint8_t*)this; @@ -633,6 +642,7 @@ void VoxelNode::checkStoreFourChildren(VoxelNode* childOne, VoxelNode* childTwo, _couldNotStoreFourChildrenInternally++; } } +#endif void VoxelNode::deleteAllChildren() { // first delete all the VoxelNode objects... @@ -643,6 +653,7 @@ void VoxelNode::deleteAllChildren() { } } +#ifdef BLENDED_UNION_CHILDREN // now, reset our internal state and ANY and all population data int childCount = getChildCount(); switch (childCount) { @@ -686,6 +697,7 @@ void VoxelNode::deleteAllChildren() { delete[] _children.external; } _children.single = NULL; +#endif // BLENDED_UNION_CHILDREN } void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) { @@ -707,7 +719,8 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) { _childrenCount[newChildCount]++; } -#else +#endif +#ifdef BLENDED_UNION_CHILDREN PerformanceWarning warn(false,"setChildAtIndex",false,&_setChildAtIndexTime,&_setChildAtIndexCalls); // Here's how we store things... diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index c9e892ebb9..07a49e75b9 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -131,16 +131,18 @@ public: static uint64_t getSetChildAtIndexTime() { return _setChildAtIndexTime; } static uint64_t getSetChildAtIndexCalls() { return _setChildAtIndexCalls; } +#ifdef BLENDED_UNION_CHILDREN static uint64_t getSingleChildrenCount() { return _singleChildrenCount; } static uint64_t getTwoChildrenOffsetCount() { return _twoChildrenOffsetCount; } static uint64_t getTwoChildrenExternalCount() { return _twoChildrenExternalCount; } static uint64_t getThreeChildrenOffsetCount() { return _threeChildrenOffsetCount; } static uint64_t getThreeChildrenExternalCount() { return _threeChildrenExternalCount; } - static uint64_t getExternalChildrenCount() { return _externalChildrenCount; } - static uint64_t getChildrenCount(int childCount) { return _childrenCount[childCount]; } - static uint64_t getCouldStoreFourChildrenInternally() { return _couldStoreFourChildrenInternally; } static uint64_t getCouldNotStoreFourChildrenInternally() { return _couldNotStoreFourChildrenInternally; } +#endif + + static uint64_t getExternalChildrenCount() { return _externalChildrenCount; } + static uint64_t getChildrenCount(int childCount) { return _childrenCount[childCount]; } #ifdef HAS_AUDIT_CHILDREN void auditChildren(const char* label) const; @@ -149,6 +151,8 @@ public: private: void deleteAllChildren(); void setChildAtIndex(int childIndex, VoxelNode* child); + +#ifdef BLENDED_UNION_CHILDREN void storeTwoChildren(VoxelNode* childOne, VoxelNode* childTwo); void retrieveTwoChildren(VoxelNode*& childOne, VoxelNode*& childTwo); void storeThreeChildren(VoxelNode* childOne, VoxelNode* childTwo, VoxelNode* childThree); @@ -156,7 +160,7 @@ private: void decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, int64_t& offsetThree) const; void encodeThreeOffsets(int64_t offsetOne, int64_t offsetTwo, int64_t offsetThree); void checkStoreFourChildren(VoxelNode* childOne, VoxelNode* childTwo, VoxelNode* childThree, VoxelNode* childFour); - +#endif void calculateAABox(); void init(unsigned char * octalCode); void notifyDeleteHooks(); @@ -177,12 +181,14 @@ private: VoxelNode* _simpleChildArray[8]; /// Only used when HAS_AUDIT_CHILDREN is enabled to help debug children encoding #endif +#ifdef BLENDED_UNION_CHILDREN union children_t { VoxelNode* single; int32_t offsetsTwoChildren[2]; uint64_t offsetsThreeChildrenEncoded; VoxelNode** external; } _children; +#endif //def BLENDED_UNION_CHILDREN #ifdef HAS_AUDIT_CHILDREN VoxelNode* _childrenArray[8]; /// Only used when HAS_AUDIT_CHILDREN is enabled to help debug children encoding @@ -237,16 +243,17 @@ private: static uint64_t _setChildAtIndexTime; static uint64_t _setChildAtIndexCalls; +#ifdef BLENDED_UNION_CHILDREN static uint64_t _singleChildrenCount; static uint64_t _twoChildrenOffsetCount; static uint64_t _twoChildrenExternalCount; static uint64_t _threeChildrenOffsetCount; static uint64_t _threeChildrenExternalCount; - static uint64_t _externalChildrenCount; - static uint64_t _childrenCount[NUMBER_OF_CHILDREN + 1]; - static uint64_t _couldStoreFourChildrenInternally; static uint64_t _couldNotStoreFourChildrenInternally; +#endif + static uint64_t _externalChildrenCount; + static uint64_t _childrenCount[NUMBER_OF_CHILDREN + 1]; }; #endif /* defined(__hifi__VoxelNode__) */ \ No newline at end of file From f12064c6472231e8db7ca0abad7f9bac92798950 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 28 Oct 2013 13:24:25 -0700 Subject: [PATCH 3/6] clean up voxel server stats page --- .../voxel-server-library/src/VoxelServer.cpp | 80 ++++++++++++------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index a7fe8869d9..d5667d6249 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -108,36 +108,74 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { const struct mg_request_info* ri = mg_get_request_info(connection); if (strcmp(ri->uri, "/") == 0 && strcmp(ri->request_method, "GET") == 0) { + uint64_t checkSum; // return a 200 mg_printf(connection, "%s", "HTTP/1.0 200 OK\r\n\r\n"); mg_printf(connection, "%s", "Your Voxel Server is running.\r\n"); mg_printf(connection, "%s", "Current Statistics\r\n"); mg_printf(connection, "%s", "\r\n"); - mg_printf(connection, "Voxel Node Memory Usage: %8.2f MB\r\n", VoxelNode::getVoxelMemoryUsage() / 1000000.f); - mg_printf(connection, "Octcode Memory Usage: %8.2f MB\r\n", VoxelNode::getOctcodeMemoryUsage() / 1000000.f); - mg_printf(connection, "External Children Memory Usage: %8.2f MB\r\n", - VoxelNode::getExternalChildrenMemoryUsage() / 1000000.f); + + const char* memoryScaleLabel; + const float MEGABYTES = 1000000.f; + const float GIGABYTES = 1000000000.f; + float memoryScale; + if (VoxelNode::getTotalMemoryUsage() / MEGABYTES < 1000.0f) { + memoryScaleLabel = "MB"; + memoryScale = MEGABYTES; + } else { + memoryScaleLabel = "GB"; + memoryScale = GIGABYTES; + } + + mg_printf(connection, "Voxel Node Memory Usage: %8.2f %s\r\n", + VoxelNode::getVoxelMemoryUsage() / memoryScale, memoryScaleLabel); + mg_printf(connection, "Octcode Memory Usage: %8.2f %s\r\n", + VoxelNode::getOctcodeMemoryUsage() / memoryScale, memoryScaleLabel); + mg_printf(connection, "External Children Memory Usage: %8.2f %s\r\n", + VoxelNode::getExternalChildrenMemoryUsage() / memoryScale, memoryScaleLabel); mg_printf(connection, "%s", " -----------\r\n"); - mg_printf(connection, " Total: %8.2f MB\r\n", VoxelNode::getTotalMemoryUsage() / 1000000.f); + mg_printf(connection, " Total: %8.2f %s\r\n", + VoxelNode::getTotalMemoryUsage() / memoryScale, memoryScaleLabel); + + mg_printf(connection, "\r\nVoxelNode size... %ld bytes\r\n", sizeof(VoxelNode)); unsigned long nodeCount = VoxelNode::getNodeCount(); unsigned long internalNodeCount = VoxelNode::getInternalNodeCount(); unsigned long leafNodeCount = VoxelNode::getLeafNodeCount(); + + + QLocale locale(QLocale::English); const float AS_PERCENT = 100.0; mg_printf(connection, "%s", "\r\n"); mg_printf(connection, "%s", "Current Nodes in scene\r\n"); - mg_printf(connection, " Total Nodes: %10.lu nodes\r\n", nodeCount); - mg_printf(connection, " Internal Nodes: %10.lu nodes (%5.2f%%)\r\n", - internalNodeCount, ((float)internalNodeCount/(float)nodeCount) * AS_PERCENT); - mg_printf(connection, " Leaf Nodes: %10.lu nodes (%5.2f%%)\r\n", - leafNodeCount, ((float)leafNodeCount/(float)nodeCount) * AS_PERCENT); + mg_printf(connection, " Total Nodes: %s nodes\r\n", + locale.toString((uint)nodeCount).rightJustified(16, ' ').toLocal8Bit().constData()); + mg_printf(connection, " Internal Nodes: %s nodes (%5.2f%%)\r\n", + locale.toString((uint)internalNodeCount).rightJustified(16, ' ').toLocal8Bit().constData(), + ((float)internalNodeCount/(float)nodeCount) * AS_PERCENT); + mg_printf(connection, " Leaf Nodes: %s nodes (%5.2f%%)\r\n", + locale.toString((uint)leafNodeCount).rightJustified(16, ' ').toLocal8Bit().constData(), + ((float)leafNodeCount/(float)nodeCount) * AS_PERCENT); + mg_printf(connection, "%s", "\r\n"); + mg_printf(connection, "%s", "VoxelNode Children Population Statistics...\r\n"); + checkSum = 0; + for (int i=0; i <= NUMBER_OF_CHILDREN; i++) { + checkSum += VoxelNode::getChildrenCount(i); + mg_printf(connection, " Nodes with %d children: %s nodes (%5.2f%%)\r\n", i, + locale.toString((uint)VoxelNode::getChildrenCount(i)).rightJustified(16, ' ').toLocal8Bit().constData(), + ((float)VoxelNode::getChildrenCount(i)/(float)nodeCount) * AS_PERCENT); + } + mg_printf(connection, "%s", " ----------------------\r\n"); + mg_printf(connection, " Total: %s nodes\r\n", + locale.toString((uint)checkSum).rightJustified(16, ' ').toLocal8Bit().constData()); + +#ifdef BLENDED_UNION_CHILDREN mg_printf(connection, "%s", "\r\n"); mg_printf(connection, "%s", "VoxelNode Children Encoding Statistics...\r\n"); -#ifdef BLENDED_UNION_CHILDREN mg_printf(connection, " Single or No Children: %10.llu nodes (%5.2f%%)\r\n", VoxelNode::getSingleChildrenCount(), ((float)VoxelNode::getSingleChildrenCount()/(float)nodeCount) * AS_PERCENT); mg_printf(connection, " Two Children as Offset: %10.llu nodes (%5.2f%%)\r\n", @@ -152,38 +190,20 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, " Three Children as External: %10.llu nodes (%5.2f%%)\r\n", VoxelNode::getThreeChildrenExternalCount(), ((float)VoxelNode::getThreeChildrenExternalCount()/(float)nodeCount) * AS_PERCENT); -#endif mg_printf(connection, " Children as External Array: %10.llu nodes (%5.2f%%)\r\n", VoxelNode::getExternalChildrenCount(), ((float)VoxelNode::getExternalChildrenCount()/(float)nodeCount) * AS_PERCENT); -#ifdef BLENDED_UNION_CHILDREN - uint64_t checkSum = VoxelNode::getSingleChildrenCount() + + checkSum = VoxelNode::getSingleChildrenCount() + VoxelNode::getTwoChildrenOffsetCount() + VoxelNode::getTwoChildrenExternalCount() + VoxelNode::getThreeChildrenOffsetCount() + VoxelNode::getThreeChildrenExternalCount() + VoxelNode::getExternalChildrenCount(); -#else - uint64_t checkSum = VoxelNode::getExternalChildrenCount(); -#endif mg_printf(connection, "%s", " ----------------\r\n"); mg_printf(connection, " Total: %10.llu nodes\r\n", checkSum); mg_printf(connection, " Expected: %10.lu nodes\r\n", nodeCount); - - mg_printf(connection, "%s", "\r\n"); - mg_printf(connection, "%s", "VoxelNode Children Population Statistics...\r\n"); - checkSum = 0; - for (int i=0; i <= NUMBER_OF_CHILDREN; i++) { - checkSum += VoxelNode::getChildrenCount(i); - mg_printf(connection, " Nodes with %d children: %10.llu nodes (%5.2f%%)\r\n", i, - VoxelNode::getChildrenCount(i), ((float)VoxelNode::getChildrenCount(i)/(float)nodeCount) * AS_PERCENT); - } - mg_printf(connection, "%s", " ----------------\r\n"); - mg_printf(connection, " Total: %10.llu nodes\r\n", checkSum); mg_printf(connection, "%s", "\r\n"); - -#ifdef BLENDED_UNION_CHILDREN mg_printf(connection, "%s", "In other news....\r\n"); mg_printf(connection, "could store 4 children internally: %10.llu nodes\r\n", VoxelNode::getCouldStoreFourChildrenInternally()); From 97070607eaad994267dfad5441447d49d0f77bab Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 28 Oct 2013 14:43:27 -0700 Subject: [PATCH 4/6] added SIMPLE_EXTERNAL_CHILDREN mode, which saves on most of our child VoxelNode children storage without being too complicated --- libraries/voxels/src/VoxelNode.cpp | 82 +++++++++++++++++++++++++++++- libraries/voxels/src/VoxelNode.h | 18 +++++-- 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index a1f6d9aa7e..4ba90c87c0 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -83,7 +83,11 @@ void VoxelNode::init(unsigned char * octalCode) { for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { _simpleChildArray[i] = NULL; } -#endif +#endif + +#ifdef SIMPLE_EXTERNAL_CHILDREN + _children.single = NULL; +#endif _unknownBufferIndex = true; setBufferIndex(GLBUFFER_INDEX_UNKNOWN); @@ -335,6 +339,31 @@ VoxelNode* VoxelNode::getChildAtIndex(int childIndex) const { return _simpleChildArray[childIndex]; #endif // SIMPLE_CHILD_ARRAY +#ifdef SIMPLE_EXTERNAL_CHILDREN + int childCount = getChildCount(); + + switch (childCount) { + case 0: { + return NULL; + } break; + + case 1: { + // if our single child is the one being requested, return it, otherwise + // return null + int firstIndex = getNthBit(_childBitmask, 1); + if (firstIndex == childIndex) { + return _children.single; + } else { + return NULL; + } + } break; + + default : { + return _children.external[childIndex]; + } break; + } +#endif // def SIMPLE_EXTERNAL_CHILDREN + #ifdef BLENDED_UNION_CHILDREN PerformanceWarning warn(false,"getChildAtIndex",false,&_getChildAtIndexTime,&_getChildAtIndexCalls); VoxelNode* result = NULL; @@ -718,8 +747,57 @@ void VoxelNode::setChildAtIndex(int childIndex, VoxelNode* child) { _childrenCount[previousChildCount]--; _childrenCount[newChildCount]++; } - #endif + +#ifdef SIMPLE_EXTERNAL_CHILDREN + + int firstIndex = getNthBit(_childBitmask, 1); + int secondIndex = getNthBit(_childBitmask, 2); + + int previousChildCount = getChildCount(); + if (child) { + setAtBit(_childBitmask, childIndex); + } else { + clearAtBit(_childBitmask, childIndex); + } + int newChildCount = getChildCount(); + + // track our population data + if (previousChildCount != newChildCount) { + _childrenCount[previousChildCount]--; + _childrenCount[newChildCount]++; + } + + if ((previousChildCount == 0 || previousChildCount == 1) && newChildCount == 0) { + _children.single = NULL; + } else if (previousChildCount == 0 && newChildCount == 1) { + _children.single = child; + } else if (previousChildCount == 1 && newChildCount == 2) { + VoxelNode* previousChild = _children.single; + _children.external = new VoxelNode*[NUMBER_OF_CHILDREN]; + memset(_children.external, 0, sizeof(VoxelNode*) * NUMBER_OF_CHILDREN); + _children.external[firstIndex] = previousChild; + _children.external[childIndex] = child; + + _externalChildrenMemoryUsage += NUMBER_OF_CHILDREN * sizeof(VoxelNode*); + + } else if (previousChildCount == 2 && newChildCount == 1) { + assert(child == NULL); // we are removing a child, so this must be true! + VoxelNode* previousFirstChild = _children.external[firstIndex]; + VoxelNode* previousSecondChild = _children.external[secondIndex]; + delete[] _children.external; + _externalChildrenMemoryUsage -= NUMBER_OF_CHILDREN * sizeof(VoxelNode*); + if (childIndex == firstIndex) { + _children.single = previousSecondChild; + } else { + _children.single = previousFirstChild; + } + } else { + _children.external[childIndex] = child; + } + +#endif // def SIMPLE_EXTERNAL_CHILDREN + #ifdef BLENDED_UNION_CHILDREN PerformanceWarning warn(false,"setChildAtIndex",false,&_setChildAtIndexTime,&_setChildAtIndexCalls); diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 07a49e75b9..17760f0514 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -10,7 +10,8 @@ #define __hifi__VoxelNode__ //#define HAS_AUDIT_CHILDREN -#define SIMPLE_CHILD_ARRAY +//#define SIMPLE_CHILD_ARRAY +#define SIMPLE_EXTERNAL_CHILDREN #include #include "AABox.h" @@ -144,9 +145,11 @@ public: static uint64_t getExternalChildrenCount() { return _externalChildrenCount; } static uint64_t getChildrenCount(int childCount) { return _childrenCount[childCount]; } +#ifdef BLENDED_UNION_CHILDREN #ifdef HAS_AUDIT_CHILDREN void auditChildren(const char* label) const; #endif // def HAS_AUDIT_CHILDREN +#endif // def BLENDED_UNION_CHILDREN private: void deleteAllChildren(); @@ -178,7 +181,14 @@ private: /// Client and server, pointers to child nodes, various encodings #ifdef SIMPLE_CHILD_ARRAY - VoxelNode* _simpleChildArray[8]; /// Only used when HAS_AUDIT_CHILDREN is enabled to help debug children encoding + VoxelNode* _simpleChildArray[8]; /// Only used when SIMPLE_CHILD_ARRAY is enabled +#endif + +#ifdef SIMPLE_EXTERNAL_CHILDREN + union children_t { + VoxelNode* single; + VoxelNode** external; + } _children; #endif #ifdef BLENDED_UNION_CHILDREN @@ -188,12 +198,12 @@ private: uint64_t offsetsThreeChildrenEncoded; VoxelNode** external; } _children; -#endif //def BLENDED_UNION_CHILDREN - #ifdef HAS_AUDIT_CHILDREN VoxelNode* _childrenArray[8]; /// Only used when HAS_AUDIT_CHILDREN is enabled to help debug children encoding #endif // def HAS_AUDIT_CHILDREN +#endif //def BLENDED_UNION_CHILDREN + uint32_t _glBufferIndex : 24, /// Client only, vbo index for this voxel if being rendered, 3 bytes _voxelSystemIndex : 8; /// Client only, index to the VoxelSystem rendering this voxel, 1 bytes From 4874eda317e6350d5cadd7ff1ab42a5a8fd22dd1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 28 Oct 2013 22:16:36 -0700 Subject: [PATCH 5/6] add mutex for _nodesRequestingJurisdictions to fix crash --- libraries/voxels/src/JurisdictionSender.cpp | 12 ++++++++++-- libraries/voxels/src/JurisdictionSender.h | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index 150d04440f..d00d09b9e9 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -21,16 +21,22 @@ JurisdictionSender::JurisdictionSender(JurisdictionMap* map, PacketSenderNotify* ReceivedPacketProcessor(), _jurisdictionMap(map) { + pthread_mutex_init(&_requestingNodeMutex, 0); } +JurisdictionSender::~JurisdictionSender() { + pthread_mutex_destroy(&_requestingNodeMutex); +} + + void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); if (node) { QUuid nodeUUID = node->getUUID(); - lock(); + lockRequestingNodes(); _nodesRequestingJurisdictions.insert(nodeUUID); - unlock(); + unlockRequestingNodes(); } } } @@ -52,6 +58,7 @@ bool JurisdictionSender::process() { } int nodeCount = 0; + lockRequestingNodes(); for (std::set::iterator nodeIterator = _nodesRequestingJurisdictions.begin(); nodeIterator != _nodesRequestingJurisdictions.end(); nodeIterator++) { @@ -66,6 +73,7 @@ bool JurisdictionSender::process() { _nodesRequestingJurisdictions.erase(nodeIterator); } } + unlockRequestingNodes(); // set our packets per second to be the number of nodes setPacketsPerSecond(nodeCount); diff --git a/libraries/voxels/src/JurisdictionSender.h b/libraries/voxels/src/JurisdictionSender.h index 9678eb15e2..2cf3a6b932 100644 --- a/libraries/voxels/src/JurisdictionSender.h +++ b/libraries/voxels/src/JurisdictionSender.h @@ -25,6 +25,7 @@ public: static const int DEFAULT_PACKETS_PER_SECOND = 1; JurisdictionSender(JurisdictionMap* map, PacketSenderNotify* notify = NULL); + ~JurisdictionSender(); void setJurisdiction(JurisdictionMap* map) { _jurisdictionMap = map; } @@ -33,7 +34,15 @@ public: protected: virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + /// Locks all the resources of the thread. + void lockRequestingNodes() { pthread_mutex_lock(&_requestingNodeMutex); } + + /// Unlocks all the resources of the thread. + void unlockRequestingNodes() { pthread_mutex_unlock(&_requestingNodeMutex); } + + private: + pthread_mutex_t _requestingNodeMutex; JurisdictionMap* _jurisdictionMap; std::set _nodesRequestingJurisdictions; }; From 3329d690ac8eecee731961fb0f275241314fb189 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 29 Oct 2013 10:53:33 -0700 Subject: [PATCH 6/6] flip mirror tools --- interface/src/ui/RearMirrorTools.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/RearMirrorTools.cpp b/interface/src/ui/RearMirrorTools.cpp index 302c58d8a3..046d497a02 100644 --- a/interface/src/ui/RearMirrorTools.cpp +++ b/interface/src/ui/RearMirrorTools.cpp @@ -84,16 +84,16 @@ void RearMirrorTools::displayIcon(QRect bounds, int left, int top, GLuint textur glBindTexture(GL_TEXTURE_2D, textureId); glBegin(GL_QUADS); { - glTexCoord2f(0, 0); + glTexCoord2f(0, 1); glVertex2f(left, top); - glTexCoord2f(1, 0); + glTexCoord2f(1, 1); glVertex2f(ICON_SIZE + left, top); - glTexCoord2f(1, 1); + glTexCoord2f(1, 0); glVertex2f(ICON_SIZE + left, twp); - glTexCoord2f(0, 1); + glTexCoord2f(0, 0); glVertex2f(left, twp); } glEnd();