mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 12:13:40 +02:00
fix to runaway saving file and optimizations to general encoding paths
This commit is contained in:
parent
0acbefb6a2
commit
66a2f58192
8 changed files with 96 additions and 15 deletions
|
@ -349,6 +349,7 @@ int OctreeSendThread::packetDistributor(OctreeQueryNode* nodeData, bool viewFrus
|
|||
// track completed scenes and send out the stats packet accordingly
|
||||
nodeData->stats.sceneCompleted();
|
||||
nodeData->setLastRootTimestamp(_myServer->getOctree()->getRoot()->getLastChanged());
|
||||
_myServer->getOctree()->releaseSceneEncodeData(&nodeData->extraEncodeData);
|
||||
|
||||
// TODO: add these to stats page
|
||||
//::endSceneSleepTime = _usleepTime;
|
||||
|
|
|
@ -516,6 +516,14 @@ void EntityTree::removeNewlyCreatedHook(NewlyCreatedEntityHook* hook) {
|
|||
}
|
||||
|
||||
|
||||
void EntityTree::releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const {
|
||||
foreach(void* extraData, *extraEncodeData) {
|
||||
EntityTreeElementExtraEncodeData* thisExtraEncodeData = static_cast<EntityTreeElementExtraEncodeData*>(extraData);
|
||||
delete thisExtraEncodeData;
|
||||
}
|
||||
extraEncodeData->clear();
|
||||
}
|
||||
|
||||
void EntityTree::changeEntityState(EntityItem* const entity,
|
||||
EntityItem::SimulationState oldState, EntityItem::SimulationState newState) {
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
// the root at least needs to store the number of entities in the packet/buffer
|
||||
virtual int minimumRequiredRootDataBytes() const { return sizeof(uint16_t); }
|
||||
virtual bool suppressEmptySubtrees() const { return false; }
|
||||
virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const;
|
||||
|
||||
virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const
|
||||
{ return thisVersion >= VERSION_ENTITIES_HAS_FILE_BREAKS; }
|
||||
|
|
|
@ -94,7 +94,7 @@ void EntityTreeElement::initializeExtraEncodeData(EncodeBitstreamParams& params)
|
|||
}
|
||||
}
|
||||
|
||||
bool EntityTreeElement::shouldIncludeChild(int childIndex, EncodeBitstreamParams& params) const {
|
||||
bool EntityTreeElement::shouldIncludeChildData(int childIndex, EncodeBitstreamParams& params) const {
|
||||
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
|
||||
assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes
|
||||
|
||||
|
@ -114,6 +114,30 @@ bool EntityTreeElement::shouldIncludeChild(int childIndex, EncodeBitstreamParams
|
|||
return false;
|
||||
}
|
||||
|
||||
bool EntityTreeElement::shouldRecurseChildTree(int childIndex, EncodeBitstreamParams& params) const {
|
||||
EntityTreeElement* childElement = getChildAtIndex(childIndex);
|
||||
if (childElement->alreadyFullyEncoded(params)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // if we don't know otherwise than recurse!
|
||||
}
|
||||
|
||||
bool EntityTreeElement::alreadyFullyEncoded(EncodeBitstreamParams& params) const {
|
||||
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
|
||||
assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes
|
||||
|
||||
if (extraEncodeData->contains(this)) {
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(this));
|
||||
|
||||
// If we know that ALL subtrees below us have already been recursed, then we don't
|
||||
// need to recurse this child.
|
||||
return entityTreeElementExtraEncodeData->subtreeCompleted;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntityTreeElement::updateEncodedData(int childIndex, AppendState childAppendState, EncodeBitstreamParams& params) const {
|
||||
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
|
||||
assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes
|
||||
|
@ -133,6 +157,12 @@ void EntityTreeElement::updateEncodedData(int childIndex, AppendState childAppen
|
|||
|
||||
|
||||
void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params, OctreeElementBag* bag) const {
|
||||
const bool wantDebug = false;
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << "EntityTreeElement::elementEncodeComplete() element:" << getAACube();
|
||||
}
|
||||
|
||||
OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData;
|
||||
assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes
|
||||
assert(extraEncodeData->contains(this));
|
||||
|
@ -152,10 +182,10 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params, Oct
|
|||
// 1) it's ok for our child trees to not yet be fully encoded/complete...
|
||||
// SO LONG AS... the our child's node is in the bag ready for encoding
|
||||
|
||||
bool someChildTreeNotComplete = false;
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
EntityTreeElement* childElement = getChildAtIndex(i);
|
||||
if (childElement) {
|
||||
bool isThisChildReallyComplete = thisExtraEncodeData->childCompleted[i];
|
||||
|
||||
// why would this ever fail???
|
||||
// If we've encoding this element before... but we're coming back a second time in an attempt to
|
||||
|
@ -163,20 +193,44 @@ void EntityTreeElement::elementEncodeComplete(EncodeBitstreamParams& params, Oct
|
|||
if (extraEncodeData->contains(childElement)) {
|
||||
EntityTreeElementExtraEncodeData* childExtraEncodeData
|
||||
= static_cast<EntityTreeElementExtraEncodeData*>(extraEncodeData->value(childElement));
|
||||
|
||||
for (int ii = 0; ii < NUMBER_OF_CHILDREN; ii++) {
|
||||
if (!childExtraEncodeData->childCompleted[ii]) {
|
||||
isThisChildReallyComplete = false;
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << "checking child: " << childElement->getAACube();
|
||||
qDebug() << " childElement->isLeaf():" << childElement->isLeaf();
|
||||
qDebug() << " childExtraEncodeData->elementCompleted:" << childExtraEncodeData->elementCompleted;
|
||||
qDebug() << " childExtraEncodeData->subtreeCompleted:" << childExtraEncodeData->subtreeCompleted;
|
||||
}
|
||||
|
||||
if (childElement->isLeaf() && childExtraEncodeData->elementCompleted) {
|
||||
if (wantDebug) {
|
||||
qDebug() << " CHILD IS LEAF -- AND CHILD ELEMENT DATA COMPLETED!!!";
|
||||
}
|
||||
childExtraEncodeData->subtreeCompleted = true;
|
||||
}
|
||||
|
||||
if (isThisChildReallyComplete) {
|
||||
extraEncodeData->remove(childElement);
|
||||
delete childExtraEncodeData;
|
||||
if (!childExtraEncodeData->elementCompleted || !childExtraEncodeData->subtreeCompleted) {
|
||||
someChildTreeNotComplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << "for this element: " << getAACube();
|
||||
qDebug() << " WAS elementCompleted:" << thisExtraEncodeData->elementCompleted;
|
||||
qDebug() << " WAS subtreeCompleted:" << thisExtraEncodeData->subtreeCompleted;
|
||||
}
|
||||
|
||||
thisExtraEncodeData->subtreeCompleted = !someChildTreeNotComplete;
|
||||
|
||||
if (wantDebug) {
|
||||
qDebug() << " NOW elementCompleted:" << thisExtraEncodeData->elementCompleted;
|
||||
qDebug() << " NOW subtreeCompleted:" << thisExtraEncodeData->subtreeCompleted;
|
||||
|
||||
if (thisExtraEncodeData->subtreeCompleted) {
|
||||
qDebug() << " YEAH!!!!! >>>>>>>>>>>>>> NOW subtreeCompleted:" << thisExtraEncodeData->subtreeCompleted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData* packetData,
|
||||
|
|
|
@ -40,10 +40,12 @@ class EntityTreeElementExtraEncodeData {
|
|||
public:
|
||||
EntityTreeElementExtraEncodeData() :
|
||||
elementCompleted(false),
|
||||
subtreeCompleted(false),
|
||||
entities() {
|
||||
memset(childCompleted, 0, sizeof(childCompleted));
|
||||
}
|
||||
bool elementCompleted;
|
||||
bool subtreeCompleted;
|
||||
bool childCompleted[NUMBER_OF_CHILDREN];
|
||||
QMap<EntityItemID, EntityPropertyFlags> entities;
|
||||
};
|
||||
|
@ -51,6 +53,7 @@ public:
|
|||
inline QDebug operator<<(QDebug debug, const EntityTreeElementExtraEncodeData* data) {
|
||||
debug << "{";
|
||||
debug << " elementCompleted: " << data->elementCompleted << ", ";
|
||||
debug << " subtreeCompleted: " << data->subtreeCompleted << ", ";
|
||||
debug << " childCompleted[]: ";
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
debug << " " << i << ":" << data->childCompleted[i] << ", ";
|
||||
|
@ -109,10 +112,13 @@ public:
|
|||
|
||||
virtual void debugExtraEncodeData(EncodeBitstreamParams& params) const;
|
||||
virtual void initializeExtraEncodeData(EncodeBitstreamParams& params) const;
|
||||
virtual bool shouldIncludeChild(int childIndex, EncodeBitstreamParams& params) const;
|
||||
virtual bool shouldIncludeChildData(int childIndex, EncodeBitstreamParams& params) const;
|
||||
virtual bool shouldRecurseChildTree(int childIndex, EncodeBitstreamParams& params) const;
|
||||
virtual void updateEncodedData(int childIndex, AppendState childAppendState, EncodeBitstreamParams& params) const;
|
||||
virtual void elementEncodeComplete(EncodeBitstreamParams& params, OctreeElementBag* bag) const;
|
||||
|
||||
bool alreadyFullyEncoded(EncodeBitstreamParams& params) const;
|
||||
|
||||
|
||||
/// Override to serialize the state of this element. This is used for persistance and for transmission across the network.
|
||||
virtual OctreeElement::AppendState appendElementData(OctreePacketData* packetData, EncodeBitstreamParams& params) const;
|
||||
|
|
|
@ -1401,7 +1401,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
|||
// the childrenDataBits were set up by the in view/LOD logic, it may contain children that we've already
|
||||
// processed and sent the data bits for. Let our tree subclass determine if it really wants to send the
|
||||
// data for this child at this point
|
||||
if (childElement && element->shouldIncludeChild(i, params)) {
|
||||
if (childElement && element->shouldIncludeChildData(i, params)) {
|
||||
|
||||
int bytesBeforeChild = packetData->getUncompressedSize();
|
||||
|
||||
|
@ -1553,8 +1553,15 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
|||
// recursing, by returning TRUE in recurseChildrenWithData().
|
||||
|
||||
if (recurseChildrenWithData() || !params.viewFrustum || !oneAtBit(childrenDataBits, originalIndex)) {
|
||||
childTreeBytesOut = encodeTreeBitstreamRecursion(childElement, packetData, bag, params,
|
||||
thisLevel, nodeLocationThisView);
|
||||
|
||||
// Allow the datatype a chance to determine if it really wants to recurse this tree. Usually this
|
||||
// will be true. But if the tree has already been encoded, we will skip this.
|
||||
if (element->shouldRecurseChildTree(originalIndex, params)) {
|
||||
childTreeBytesOut = encodeTreeBitstreamRecursion(childElement, packetData, bag, params,
|
||||
thisLevel, nodeLocationThisView);
|
||||
} else {
|
||||
childTreeBytesOut = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// remember this for reshuffling
|
||||
|
@ -1964,6 +1971,8 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) {
|
|||
}
|
||||
file.write((const char*)packetData.getFinalizedData(), packetData.getFinalizedSize());
|
||||
}
|
||||
|
||||
releaseSceneEncodeData(&extraEncodeData);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
|
|
@ -235,6 +235,7 @@ public:
|
|||
virtual bool rootElementHasData() const { return false; }
|
||||
virtual int minimumRequiredRootDataBytes() const { return 0; }
|
||||
virtual bool suppressEmptySubtrees() const { return true; }
|
||||
virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const { }
|
||||
|
||||
/// some versions of the SVO file will include breaks with buffer lengths between each buffer chunk in the SVO
|
||||
/// file. If the Octree subclass expects this for this particular version of the file, it should override this
|
||||
|
@ -275,7 +276,7 @@ public:
|
|||
|
||||
int encodeTreeBitstream(OctreeElement* element, OctreePacketData* packetData, OctreeElementBag& bag,
|
||||
EncodeBitstreamParams& params) ;
|
||||
|
||||
|
||||
bool isDirty() const { return _isDirty; }
|
||||
void clearDirtyBit() { _isDirty = false; }
|
||||
void setDirtyBit() { _isDirty = true; }
|
||||
|
|
|
@ -93,7 +93,8 @@ public:
|
|||
|
||||
virtual void debugExtraEncodeData(EncodeBitstreamParams& params) const { }
|
||||
virtual void initializeExtraEncodeData(EncodeBitstreamParams& params) const { }
|
||||
virtual bool shouldIncludeChild(int childIndex, EncodeBitstreamParams& params) const { return true; }
|
||||
virtual bool shouldIncludeChildData(int childIndex, EncodeBitstreamParams& params) const { return true; }
|
||||
virtual bool shouldRecurseChildTree(int childIndex, EncodeBitstreamParams& params) const { return true; }
|
||||
|
||||
virtual void updateEncodedData(int childIndex, AppendState childAppendState, EncodeBitstreamParams& params) const { }
|
||||
virtual void elementEncodeComplete(EncodeBitstreamParams& params, OctreeElementBag* bag) const { }
|
||||
|
|
Loading…
Reference in a new issue