diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp index c938567425..98a8835409 100644 --- a/libraries/render-utils/src/HighlightEffect.cpp +++ b/libraries/render-utils/src/HighlightEffect.cpp @@ -104,11 +104,10 @@ void PrepareDrawHighlight::run(const render::RenderContextPointer& renderContext gpu::PipelinePointer DrawHighlightMask::_stencilMaskPipeline; gpu::PipelinePointer DrawHighlightMask::_stencilMaskFillPipeline; -gpu::BufferPointer DrawHighlightMask::_boundsBuffer; DrawHighlightMask::DrawHighlightMask(unsigned int highlightIndex, render::ShapePlumberPointer shapePlumber, HighlightSharedParametersPointer parameters) : - _highlightIndex{ highlightIndex }, + _highlightPassIndex{ highlightIndex }, _shapePlumber { shapePlumber }, _sharedParameters{ parameters } { } @@ -147,7 +146,7 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c } auto highlightStage = renderContext->_scene->getStage(render::HighlightStage::getName()); - auto highlightId = _sharedParameters->_highlightIds[_highlightIndex]; + auto highlightId = _sharedParameters->_highlightIds[_highlightPassIndex]; if (!inShapes.empty() && !render::HighlightStage::isIndexInvalid(highlightId)) { auto ressources = inputs.get1(); @@ -221,8 +220,8 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c // Draw stencil mask with object bounding boxes const auto highlightWidthLoc = _stencilMaskPipeline->getProgram()->getUniforms().findLocation("outlineWidth"); - const auto sqrt3 = 1.74f; - const float blurPixelWidth = 2.0f * sqrt3 * HighlightSharedParameters::getBlurPixelWidth(highlight._style, args->_viewport.w); + const auto securityMargin = 2.0f; + const float blurPixelWidth = 2.0f * securityMargin * HighlightSharedParameters::getBlurPixelWidth(highlight._style, args->_viewport.w); const auto framebufferSize = ressources->getSourceFrameSize(); auto stencilPipeline = highlight._style.isFilled() ? _stencilMaskFillPipeline : _stencilMaskPipeline; @@ -242,7 +241,7 @@ gpu::PipelinePointer DrawHighlight::_pipeline; gpu::PipelinePointer DrawHighlight::_pipelineFilled; DrawHighlight::DrawHighlight(unsigned int highlightIndex, HighlightSharedParametersPointer parameters) : - _highlightIndex{ highlightIndex }, + _highlightPassIndex{ highlightIndex }, _sharedParameters{ parameters } { } @@ -261,9 +260,9 @@ void DrawHighlight::run(const render::RenderContextPointer& renderContext, const auto args = renderContext->args; auto highlightStage = renderContext->_scene->getStage(render::HighlightStage::getName()); - auto highlightId = _sharedParameters->_highlightIds[_highlightIndex]; + auto highlightId = _sharedParameters->_highlightIds[_highlightPassIndex]; if (!render::HighlightStage::isIndexInvalid(highlightId)) { - auto& highlight = highlightStage->getHighlight(_sharedParameters->_highlightIds[_highlightIndex]); + auto& highlight = highlightStage->getHighlight(highlightId); auto pipeline = getPipeline(highlight._style); { auto& shaderParameters = _configuration.edit(); @@ -427,12 +426,13 @@ const gpu::PipelinePointer& DebugHighlight::getDepthPipeline() { } void SelectionToHighlight::run(const render::RenderContextPointer& renderContext, Outputs& outputs) { - auto highlightStage = renderContext->_scene->getStage(render::HighlightStage::getName()); + auto scene = renderContext->_scene; + auto highlightStage = scene->getStage(render::HighlightStage::getName()); outputs.clear(); _sharedParameters->_highlightIds.fill(render::HighlightStage::INVALID_INDEX); - for (auto i = 0; i < HighlightSharedParameters::MAX_HIGHLIGHT_COUNT; i++) { + for (auto i = 0; i < HighlightSharedParameters::MAX_PASS_COUNT; i++) { std::ostringstream stream; if (i > 0) { stream << "highlightList" << i; @@ -440,17 +440,19 @@ void SelectionToHighlight::run(const render::RenderContextPointer& renderContext stream << "contextOverlayHighlightList"; } auto selectionName = stream.str(); - auto highlightId = highlightStage->getHighlightIdBySelection(selectionName); - if (!render::HighlightStage::isIndexInvalid(highlightId)) { - _sharedParameters->_highlightIds[outputs.size()] = highlightId; - outputs.emplace_back(selectionName); + if (!scene->isSelectionEmpty(selectionName)) { + auto highlightId = highlightStage->getHighlightIdBySelection(selectionName); + if (!render::HighlightStage::isIndexInvalid(highlightId)) { + _sharedParameters->_highlightIds[outputs.size()] = highlightId; + outputs.emplace_back(selectionName); + } } } } void ExtractSelectionName::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) { - if (_highlightIndex < inputs.size()) { - outputs = inputs[_highlightIndex]; + if (_highlightPassIndex < inputs.size()) { + outputs = inputs[_highlightPassIndex]; } else { outputs.clear(); } @@ -487,7 +489,7 @@ void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, ren const auto highlightRessources = task.addJob("PrepareHighlight", primaryFramebuffer); render::Varying highlight0Rect; - for (auto i = 0; i < HighlightSharedParameters::MAX_HIGHLIGHT_COUNT; i++) { + for (auto i = 0; i < HighlightSharedParameters::MAX_PASS_COUNT; i++) { const auto selectionName = task.addJob("ExtractSelectionName", highlightSelectionNames, i); const auto groupItems = addSelectItemJobs(task, selectionName, items); const auto highlightedItemIDs = task.addJob("HighlightMetaToSubItemIDs", groupItems); diff --git a/libraries/render-utils/src/HighlightEffect.h b/libraries/render-utils/src/HighlightEffect.h index 0531c03efd..90a8e730ce 100644 --- a/libraries/render-utils/src/HighlightEffect.h +++ b/libraries/render-utils/src/HighlightEffect.h @@ -50,12 +50,12 @@ class HighlightSharedParameters { public: enum { - MAX_HIGHLIGHT_COUNT = 8 + MAX_PASS_COUNT = 8 }; HighlightSharedParameters(); - std::array _highlightIds; + std::array _highlightIds; static float getBlurPixelWidth(const render::HighlightStyle& style, int frameBufferHeight); }; @@ -100,13 +100,13 @@ public: using Outputs = std::string; using JobModel = render::Job::ModelIO; - ExtractSelectionName(unsigned int highlightIndex) : _highlightIndex{ highlightIndex } {} + ExtractSelectionName(unsigned int highlightIndex) : _highlightPassIndex{ highlightIndex } {} void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); private: - unsigned int _highlightIndex; + unsigned int _highlightPassIndex; }; @@ -123,11 +123,11 @@ public: protected: - unsigned int _highlightIndex; + unsigned int _highlightPassIndex; render::ShapePlumberPointer _shapePlumber; HighlightSharedParametersPointer _sharedParameters; - - static gpu::BufferPointer _boundsBuffer; + gpu::BufferPointer _boundsBuffer; + static gpu::PipelinePointer _stencilMaskPipeline; static gpu::PipelinePointer _stencilMaskFillPipeline; }; @@ -162,7 +162,7 @@ private: static gpu::PipelinePointer _pipeline; static gpu::PipelinePointer _pipelineFilled; - unsigned int _highlightIndex; + unsigned int _highlightPassIndex; HighlightParameters _parameters; HighlightSharedParametersPointer _sharedParameters; HighlightConfigurationBuffer _configuration; diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 9cdaa89cf6..88e25b6d27 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -426,7 +426,7 @@ void Scene::resetItemTransition(ItemID itemId) { } } -// THis fucntion is thread safe +// This function is thread safe Selection Scene::getSelection(const Selection::Name& name) const { std::unique_lock lock(_selectionsMutex); auto found = _selections.find(name); @@ -437,6 +437,17 @@ Selection Scene::getSelection(const Selection::Name& name) const { } } +// This function is thread safe +bool Scene::isSelectionEmpty(const Selection::Name& name) const { + std::unique_lock lock(_selectionsMutex); + auto found = _selections.find(name); + if (found == _selections.end()) { + return false; + } else { + return (*found).second.isEmpty(); + } +} + void Scene::resetSelections(const Transaction::SelectionResets& transactions) { for (auto selection : transactions) { auto found = _selections.find(selection.getName()); diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 4bf38b89cc..af6204acb4 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -143,6 +143,10 @@ public: // Thread safe Selection getSelection(const Selection::Name& name) const; + // Check if a particular selection is empty (returns true if doesn't exist) + // Thread safe + bool isSelectionEmpty(const Selection::Name& name) const; + // This next call are NOT threadsafe, you have to call them from the correct thread to avoid any potential issues // Access a particular item form its ID