From c8ffb130a3f949bd4d237d72b3120901e4e5a041 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 19 Feb 2019 17:36:22 -0800 Subject: [PATCH] only update sub items on change --- .../src/avatars-renderer/Avatar.cpp | 137 ++++++++++-------- .../src/avatars-renderer/Avatar.h | 12 +- .../src/RenderableEntityItem.cpp | 2 + .../src/RenderableModelEntityItem.cpp | 2 + libraries/entities/src/EntityItem.cpp | 1 + libraries/shared/src/SpatiallyNestable.cpp | 11 ++ libraries/shared/src/SpatiallyNestable.h | 4 + 7 files changed, 107 insertions(+), 62 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index d114ff09e2..395fc3b7b4 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -66,32 +66,7 @@ namespace render { template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar) { auto avatarPtr = static_pointer_cast(avatar); if (avatarPtr) { - auto bound = avatarPtr->getRenderBounds(); - auto& attachmentModels = avatarPtr->getAttachmentModels(); - for (auto& attachmentModel : attachmentModels) { - if (attachmentModel && attachmentModel->isRenderable()) { - bound += attachmentModel->getRenderableMeshBound(); - } - } - // Children - auto entityTreeRenderer = DependencyManager::get(); - EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; - if (entityTree) { - entityTree->withReadLock([&] { - avatarPtr->forEachDescendant([&](SpatiallyNestablePointer object) { - if (object && object->getNestableType() == NestableType::Entity) { - EntityItemPointer entity = std::static_pointer_cast(object); - if (entity->isVisible()) { - auto renderer = entityTreeRenderer->renderableForEntityId(object->getID()); - if (renderer) { - bound += renderer->getBound(); - } - } - } - }); - }); - } - return bound; + return avatarPtr->getRenderBounds(); } return Item::Bound(); } @@ -111,38 +86,7 @@ namespace render { subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end()); total += (uint32_t)metaSubItems.size(); } - // Attachments - auto& attachmentModels = avatarPtr->getAttachmentModels(); - for (auto& attachmentModel : attachmentModels) { - if (attachmentModel && attachmentModel->isRenderable()) { - auto& metaSubItems = attachmentModel->fetchRenderItemIDs(); - subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end()); - total += (uint32_t)metaSubItems.size(); - } - } - // Children - auto entityTreeRenderer = DependencyManager::get(); - EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; - if (entityTree) { - entityTree->withReadLock([&] { - avatarPtr->forEachDescendant([&](SpatiallyNestablePointer object) { - if (object && object->getNestableType() == NestableType::Entity) { - EntityItemPointer entity = std::static_pointer_cast(object); - if (entity->isVisible()) { - auto renderer = entityTreeRenderer->renderableForEntityId(object->getID()); - if (renderer) { - render::ItemIDs renderableSubItems; - uint32_t numRenderableSubItems = renderer->metaFetchMetaSubItems(renderableSubItems); - if (numRenderableSubItems > 0) { - subItems.insert(subItems.end(), renderableSubItems.begin(), renderableSubItems.end()); - total += numRenderableSubItems; - } - } - } - } - }); - }); - } + total += avatarPtr->appendSubMetaItems(subItems); return total; } return 0; @@ -691,12 +635,18 @@ void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& sc _skeletonModel->setVisibleInScene(_isMeshVisible, scene); processMaterials(); + bool attachmentRenderingNeedsUpdate = false; for (auto& attachmentModel : _attachmentModels) { attachmentModel->addToScene(scene, transaction); attachmentModel->setTagMask(render::hifi::TAG_ALL_VIEWS); attachmentModel->setGroupCulled(true); attachmentModel->setCanCastShadow(true); attachmentModel->setVisibleInScene(_isMeshVisible, scene); + attachmentRenderingNeedsUpdate = true; + } + + if (attachmentRenderingNeedsUpdate) { + updateAttachmentRenderIDs(); } _mustFadeIn = true; @@ -920,6 +870,7 @@ void Avatar::fixupModelsInScene(const render::ScenePointer& scene) { canTryFade = true; _isAnimatingScale = true; } + bool attachmentRenderingNeedsUpdate = false; for (auto attachmentModel : _attachmentModels) { if (attachmentModel->isRenderable() && attachmentModel->needsFixupInScene()) { attachmentModel->removeFromScene(scene, transaction); @@ -929,6 +880,7 @@ void Avatar::fixupModelsInScene(const render::ScenePointer& scene) { attachmentModel->setGroupCulled(true); attachmentModel->setCanCastShadow(true); attachmentModel->setVisibleInScene(_isMeshVisible, scene); + attachmentRenderingNeedsUpdate = true; } } @@ -951,9 +903,15 @@ void Avatar::fixupModelsInScene(const render::ScenePointer& scene) { for (auto attachmentModelToRemove : _attachmentsToRemove) { attachmentModelToRemove->removeFromScene(scene, transaction); + attachmentRenderingNeedsUpdate = true; } _attachmentsToDelete.insert(_attachmentsToDelete.end(), _attachmentsToRemove.begin(), _attachmentsToRemove.end()); _attachmentsToRemove.clear(); + + if (attachmentRenderingNeedsUpdate) { + updateAttachmentRenderIDs(); + } + scene->enqueueTransaction(transaction); } @@ -996,6 +954,11 @@ void Avatar::simulateAttachments(float deltaTime) { } } } + + if (_ancestorChainRenderableVersion != _lastAncestorChainRenderableVersion) { + _lastAncestorChainRenderableVersion = _ancestorChainRenderableVersion; + updateDescendantRenderIDs(); + } } float Avatar::getBoundingRadius() const { @@ -1673,7 +1636,6 @@ void Avatar::setAttachmentData(const QVector& attachmentData) { } } - int Avatar::parseDataFromBuffer(const QByteArray& buffer) { PerformanceTimer perfTimer("unpack"); if (!_initialized) { @@ -2149,3 +2111,60 @@ void Avatar::clearAvatarGrabData(const QUuid& id) { } }); } + +uint32_t Avatar::appendSubMetaItems(render::ItemIDs& subItems) { + return _subItemLock.resultWithReadLock([&] { + uint32_t total = 0; + + if (_attachmentRenderIDs.size() > 0) { + subItems.insert(subItems.end(), _attachmentRenderIDs.begin(), _attachmentRenderIDs.end()); + total += (uint32_t)_attachmentRenderIDs.size(); + } + + if (_descendantRenderIDs.size() > 0) { + subItems.insert(subItems.end(), _descendantRenderIDs.begin(), _descendantRenderIDs.end()); + total += (uint32_t)_descendantRenderIDs.size(); + } + + return total; + }); +} + +void Avatar::updateAttachmentRenderIDs() { + _subItemLock.withWriteLock([&] { + _attachmentRenderIDs.clear(); + for (auto& attachmentModel : _attachmentModels) { + if (attachmentModel && attachmentModel->isRenderable()) { + auto& metaSubItems = attachmentModel->fetchRenderItemIDs(); + _attachmentRenderIDs.insert(_attachmentRenderIDs.end(), metaSubItems.begin(), metaSubItems.end()); + } + } + }); +} + +void Avatar::updateDescendantRenderIDs() { + _subItemLock.withWriteLock([&] { + _descendantRenderIDs.clear(); + auto entityTreeRenderer = DependencyManager::get(); + EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; + if (entityTree) { + entityTree->withReadLock([&] { + forEachDescendant([&](SpatiallyNestablePointer object) { + if (object && object->getNestableType() == NestableType::Entity) { + EntityItemPointer entity = std::static_pointer_cast(object); + if (entity->isVisible()) { + auto renderer = entityTreeRenderer->renderableForEntityId(object->getID()); + if (renderer) { + render::ItemIDs renderableSubItems; + uint32_t numRenderableSubItems = renderer->metaFetchMetaSubItems(renderableSubItems); + if (numRenderableSubItems > 0) { + _descendantRenderIDs.insert(_descendantRenderIDs.end(), renderableSubItems.begin(), renderableSubItems.end()); + } + } + } + } + }); + }); + } + }); +} diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 7df573a38d..1e6893a410 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -149,7 +149,6 @@ public: void removeAvatarEntitiesFromTree(); virtual void simulate(float deltaTime, bool inView) = 0; virtual void simulateAttachments(float deltaTime); - const std::vector>& getAttachmentModels() const { return _attachmentModels; } virtual void render(RenderArgs* renderArgs); @@ -499,6 +498,8 @@ public: const std::vector& getMultiSphereShapes() const { return _multiSphereShapes; } void tearDownGrabs(); + uint32_t appendSubMetaItems(render::ItemIDs& subItems); + signals: void targetScaleChanged(float targetScale); @@ -639,8 +640,6 @@ protected: RateCounter<> _skeletonModelSimulationRate; RateCounter<> _jointDataSimulationRate; - -protected: class AvatarEntityDataHash { public: AvatarEntityDataHash(uint32_t h) : hash(h) {}; @@ -700,6 +699,13 @@ protected: MapOfGrabs _avatarGrabs; SetOfIDs _grabsToChange; // updated grab IDs -- changes needed to entities or physics VectorOfIDs _grabsToDelete; // deleted grab IDs -- changes needed to entities or physics + + ReadWriteLockable _subItemLock; + void updateAttachmentRenderIDs(); + render::ItemIDs _attachmentRenderIDs; + void updateDescendantRenderIDs(); + render::ItemIDs _descendantRenderIDs; + uint32_t _lastAncestorChainRenderableVersion { 0 }; }; #endif // hifi_Avatar_h diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index e2e37515bf..a6826da91b 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -320,6 +320,7 @@ bool EntityRenderer::addToScene(const ScenePointer& scene, Transaction& transact transaction.resetItem(_renderItemID, renderPayload); onAddToScene(_entity); updateInScene(scene, transaction); + _entity->bumpAncestorChainRenderableVersion(); return true; } @@ -327,6 +328,7 @@ void EntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& tra onRemoveFromScene(_entity); transaction.removeItem(_renderItemID); Item::clearID(_renderItemID); + _entity->bumpAncestorChainRenderableVersion(); } void EntityRenderer::updateInScene(const ScenePointer& scene, Transaction& transaction) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ef589507a5..e842d98714 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1321,6 +1321,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce if (!_hasModel) { if (model) { model->removeFromScene(scene, transaction); + entity->bumpAncestorChainRenderableVersion(); withWriteLock([&] { _model.reset(); }); emit DependencyManager::get()-> modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, _model); @@ -1438,6 +1439,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce render::Item::Status::Getters statusGetters; makeStatusGetters(entity, statusGetters); model->addToScene(scene, transaction, statusGetters); + entity->bumpAncestorChainRenderableVersion(); processMaterials(); } } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c0b12c4d1f..9f11b3c018 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2935,6 +2935,7 @@ void EntityItem::setVisible(bool value) { }); if (changed) { + bumpAncestorChainRenderableVersion(); emit requestRenderUpdate(); } } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 363151203a..19fafdccf4 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -67,6 +67,7 @@ const QUuid SpatiallyNestable::getParentID() const { } void SpatiallyNestable::setParentID(const QUuid& parentID) { + bumpAncestorChainRenderableVersion(); _idLock.withWriteLock([&] { if (_parentID != parentID) { _parentID = parentID; @@ -78,6 +79,7 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) { bool success = false; auto parent = getParentPointer(success); if (success && parent) { + bumpAncestorChainRenderableVersion(); parent->updateQueryAACube(); } } @@ -1417,3 +1419,12 @@ QUuid SpatiallyNestable::getEditSenderID() { }); return editSenderID; } + +void SpatiallyNestable::bumpAncestorChainRenderableVersion() const { + _ancestorChainRenderableVersion++; + bool success = false; + auto parent = getParentPointer(success); + if (success && parent) { + parent->bumpAncestorChainRenderableVersion(); + } +} \ No newline at end of file diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 9f30f27005..495c941c07 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -221,6 +221,8 @@ public: bool hasGrabs(); virtual QUuid getEditSenderID(); + void bumpAncestorChainRenderableVersion() const; + protected: QUuid _id; mutable SpatiallyNestableWeakPointer _parent; @@ -243,6 +245,8 @@ protected: mutable ReadWriteLockable _grabsLock; QSet _grabs; // upon this thing + mutable std::atomic _ancestorChainRenderableVersion { 0 }; + private: SpatiallyNestable() = delete; const NestableType _nestableType; // EntityItem or an AvatarData