diff --git a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp index 68faa659a1..4e62ca0e94 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp +++ b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp @@ -540,13 +540,6 @@ void HdVP2BasisCurves::Sync( HdDirtyBits* dirtyBits, TfToken const& reprToken) { - // We don't create a repr for the selection token because this token serves - // for selection state update only. Return early to reserve dirty bits so - // they can be used to sync regular reprs later. - if (reprToken == HdVP2ReprTokens->selection) { - return; - } - // We don't update the repr if it is hidden by the render tags (purpose) // of the ProxyRenderDelegate. In additional, we need to hide any already // existing render items because they should not be drawn. @@ -572,6 +565,13 @@ void HdVP2BasisCurves::Sync( const SdfPath& id = GetId(); + // Update the selection status if it changed. + if (*dirtyBits & DirtySelectionHighlight) { + _selectionStatus = drawScene.GetSelectionStatus(id); + } else { + TF_VERIFY(_selectionStatus == drawScene.GetSelectionStatus(id)); + } + if (*dirtyBits & HdChangeTracker::DirtyMaterialId) { const SdfPath materialId = delegate->GetMaterialId(id); @@ -1525,11 +1525,6 @@ void HdVP2BasisCurves::_UpdateDrawItem( */ HdDirtyBits HdVP2BasisCurves::_PropagateDirtyBits(HdDirtyBits bits) const { - // Visibility and selection result in highlight changes: - if ((bits & HdChangeTracker::DirtyVisibility) && (bits & DirtySelection)) { - bits |= DirtySelectionHighlight; - } - if (bits & HdChangeTracker::AllDirty) { // RPrim is dirty, propagate dirty bits to all draw items. for (const std::pair& pair : _reprs) { @@ -1594,26 +1589,19 @@ void HdVP2BasisCurves::_InitRepr(TfToken const& reprToken, HdDirtyBits* dirtyBit if (ARCH_UNLIKELY(!subSceneContainer)) return; - // Update selection state on demand or when it is a new Rprim. DirtySelection + // Update selection state on demand or when it is a new Rprim. DirtySelectionHighlight // will be propagated to all draw items, to trigger sync for each repr. - if (reprToken == HdVP2ReprTokens->selection || _reprs.empty()) { + if (_reprs.empty()) { const HdVP2SelectionStatus selectionStatus = param->GetDrawScene().GetSelectionStatus(GetId()); if (_selectionStatus != selectionStatus) { _selectionStatus = selectionStatus; - *dirtyBits |= DirtySelection; + *dirtyBits |= DirtySelectionHighlight; } else if (_selectionStatus == kPartiallySelected) { - *dirtyBits |= DirtySelection; + *dirtyBits |= DirtySelectionHighlight; } - - // We don't create a repr for the selection token because it serves for - // selection state update only. Return from here. - if (reprToken == HdVP2ReprTokens->selection) - return; } - // If the repr has any draw item with the DirtySelection bit, mark the - // DirtySelectionHighlight bit to invoke the synchronization call. _ReprVector::iterator it = std::find_if(_reprs.begin(), _reprs.end(), _ReprComparator(reprToken)); if (it != _reprs.end()) { @@ -1633,9 +1621,6 @@ void HdVP2BasisCurves::_InitRepr(TfToken const& reprToken, HdDirtyBits* dirtyBit // items to ensure proper Sync drawItem->SetDirtyBits(HdChangeTracker::DirtyRepr); } - if (drawItem->GetDirtyBits() & DirtySelection) { - *dirtyBits |= DirtySelectionHighlight; - } } } return; diff --git a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h index decc9bdd56..0b8fee0691 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h +++ b/lib/mayaUsd/render/vp2RenderDelegate/basisCurves.h @@ -157,7 +157,6 @@ class HdVP2BasisCurves final : public HdBasisCurves enum DirtyBits : HdDirtyBits { - DirtySelection = MayaPrimCommon::DirtySelection, DirtySelectionHighlight = MayaPrimCommon::DirtySelectionHighlight }; diff --git a/lib/mayaUsd/render/vp2RenderDelegate/mayaPrimCommon.h b/lib/mayaUsd/render/vp2RenderDelegate/mayaPrimCommon.h index f0c4251dcf..9e08a88a88 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/mayaPrimCommon.h +++ b/lib/mayaUsd/render/vp2RenderDelegate/mayaPrimCommon.h @@ -48,8 +48,7 @@ struct MayaPrimCommon { enum DirtyBits : HdDirtyBits { - DirtySelection = HdChangeTracker::CustomBitsBegin, - DirtySelectionHighlight = (DirtySelection << 1), + DirtySelectionHighlight = HdChangeTracker::CustomBitsBegin, DirtySelectionMode = (DirtySelectionHighlight << 1), DirtyBitLast = DirtySelectionMode }; diff --git a/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp b/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp index d496a91a0b..51fdd788ca 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp +++ b/lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp @@ -465,6 +465,12 @@ void HdVP2Mesh::_PrepareSharedVertexBuffers( const HdDirtyBits& rprimDirtyBits, const TfToken& reprToken) { + MProfilingScope profilingScope( + HdVP2RenderDelegate::sProfilerCategory, + MProfiler::kColorC_L2, + _rprimId.asChar(), + "HdVP2Mesh::_PrepareSharedVertexBuffers"); + // Normals have two possible sources. They could be authored by the scene delegate, // in which case we should find them in _primvarInfo, or they could be computed // normals. Compute the normal buffer if necessary. @@ -838,26 +844,22 @@ void HdVP2Mesh::Sync( HdDirtyBits* dirtyBits, const TfToken& reprToken) { - // We don't create render items for the selection repr. The selection repr - // is used when the Sync call is made during a selection pass. - // When the selection mode changes, we DO want the chance to update our - // shaded render items (to support things like point snapping to similar instances), so make - // another call to Sync but with the smoothHull repr. - if (reprToken == HdVP2ReprTokens->selection) { - if (*dirtyBits & DirtySelectionMode) { - Sync(delegate, renderParam, dirtyBits, HdReprTokens->smoothHull); - } - return; - } + const SdfPath& id = GetId(); + auto* const param = static_cast(_delegate->GetRenderParam()); + ProxyRenderDelegate& drawScene = param->GetDrawScene(); + UsdImagingDelegate* usdImagingDelegate = drawScene.GetUsdImagingDelegate(); - const SdfPath& id = GetId(); + // Update the selection status if it changed. + if (*dirtyBits & DirtySelectionHighlight) { + _selectionStatus = drawScene.GetSelectionStatus(id); + } else { + TF_VERIFY(_selectionStatus == drawScene.GetSelectionStatus(id)); + } // We don't update the repr if it is hidden by the render tags (purpose) // of the ProxyRenderDelegate. In additional, we need to hide any already // existing render items because they should not be drawn. - auto* const param = static_cast(_delegate->GetRenderParam()); - ProxyRenderDelegate& drawScene = param->GetDrawScene(); - HdRenderIndex& renderIndex = delegate->GetRenderIndex(); + HdRenderIndex& renderIndex = delegate->GetRenderIndex(); if (!drawScene.DrawRenderTag(renderIndex.GetRenderTag(id))) { _HideAllDrawItems(reprToken); *dirtyBits &= ~( @@ -884,8 +886,7 @@ void HdVP2Mesh::Sync( for (const auto& geomSubset : _meshSharedData->_topology.GetGeomSubsets()) { if (!geomSubset.materialId.IsEmpty()) { const SdfPath materialId - = dynamic_cast(delegate)->ConvertCachePathToIndexPath( - geomSubset.materialId); + = usdImagingDelegate->ConvertCachePathToIndexPath(geomSubset.materialId); HdVP2Material* material = static_cast( renderIndex.GetSprim(HdPrimTypeTokens->material, materialId)); @@ -896,15 +897,21 @@ void HdVP2Mesh::Sync( } #endif - _meshSharedData->_topology = GetMeshTopology(delegate); + { + MProfilingScope profilingScope( + HdVP2RenderDelegate::sProfilerCategory, + MProfiler::kColorC_L2, + _rprimId.asChar(), + "HdVP2Mesh::GetMeshTopology"); + _meshSharedData->_topology = GetMeshTopology(delegate); + } // subscribe to material updates from the new geom subset materials #ifdef HDVP2_MATERIAL_CONSOLIDATION_UPDATE_WORKAROUND for (const auto& geomSubset : _meshSharedData->_topology.GetGeomSubsets()) { if (!geomSubset.materialId.IsEmpty()) { const SdfPath materialId - = dynamic_cast(delegate)->ConvertCachePathToIndexPath( - geomSubset.materialId); + = usdImagingDelegate->ConvertCachePathToIndexPath(geomSubset.materialId); HdVP2Material* material = static_cast( renderIndex.GetSprim(HdPrimTypeTokens->material, materialId)); @@ -988,8 +995,7 @@ void HdVP2Mesh::Sync( for (const auto& geomSubset : _meshSharedData->_topology.GetGeomSubsets()) { addRequiredPrimvars( - dynamic_cast(delegate)->ConvertCachePathToIndexPath( - geomSubset.materialId)); + usdImagingDelegate->ConvertCachePathToIndexPath(geomSubset.materialId)); } // also, we always require points @@ -1000,6 +1006,12 @@ void HdVP2Mesh::Sync( } if (HdChangeTracker::IsTopologyDirty(*dirtyBits, id)) { + MProfilingScope profilingScope( + HdVP2RenderDelegate::sProfilerCategory, + MProfiler::kColorC_L2, + _rprimId.asChar(), + "HdVP2Mesh Create Rendering Topology"); + const HdMeshTopology& topology = _meshSharedData->_topology; const VtIntArray& faceVertexIndices = topology.GetFaceVertexIndices(); const size_t numFaceVertexIndices = faceVertexIndices.size(); @@ -1208,11 +1220,6 @@ HdDirtyBits HdVP2Mesh::_PropagateDirtyBits(HdDirtyBits bits) const bits |= HdChangeTracker::DirtyExtent; } - // Visibility and selection result in highlight changes: - if ((bits & HdChangeTracker::DirtyVisibility) && (bits & DirtySelection)) { - bits |= DirtySelectionHighlight; - } - if (bits & HdChangeTracker::AllDirty) { // RPrim is dirty, propagate dirty bits to all draw items. for (const std::pair& pair : _reprs) { @@ -1281,26 +1288,19 @@ void HdVP2Mesh::_InitRepr(const TfToken& reprToken, HdDirtyBits* dirtyBits) if (ARCH_UNLIKELY(!subSceneContainer)) return; - // Update selection state on demand or when it is a new Rprim. DirtySelection + // Update selection state when it is a new Rprim. DirtySelectionHighlight // will be propagated to all draw items, to trigger sync for each repr. - if (reprToken == HdVP2ReprTokens->selection || _reprs.empty()) { + if (_reprs.empty()) { const HdVP2SelectionStatus selectionStatus = param->GetDrawScene().GetSelectionStatus(GetId()); if (_selectionStatus != selectionStatus) { _selectionStatus = selectionStatus; - *dirtyBits |= DirtySelection; + *dirtyBits |= DirtySelectionHighlight; } else if (_selectionStatus == kPartiallySelected) { - *dirtyBits |= DirtySelection; + *dirtyBits |= DirtySelectionHighlight; } - - // We don't create a repr for the selection token because it serves for - // selection state update only. Return from here. - if (reprToken == HdVP2ReprTokens->selection) - return; } - // If the repr has any draw item with the DirtySelection bit, mark the - // DirtySelectionHighlight bit to invoke the synchronization call. _ReprVector::const_iterator it = std::find_if(_reprs.begin(), _reprs.end(), _ReprComparator(reprToken)); if (it != _reprs.end()) { @@ -1321,9 +1321,6 @@ void HdVP2Mesh::_InitRepr(const TfToken& reprToken, HdDirtyBits* dirtyBits) // items to ensure proper Sync renderItemData.SetDirtyBits(HdChangeTracker::DirtyRepr); } - if (renderItemData.GetDirtyBits() & DirtySelection) { - *dirtyBits |= DirtySelectionHighlight; - } } } } @@ -1606,6 +1603,12 @@ void HdVP2Mesh::_UpdateRepr(HdSceneDelegate* sceneDelegate, const TfToken& reprT if (ARCH_UNLIKELY(!subSceneContainer)) return; + MProfilingScope profilingScope( + HdVP2RenderDelegate::sProfilerCategory, + MProfiler::kColorC_L2, + _rprimId.asChar(), + "HdVP2Mesh::_UpdateRepr"); + _MeshReprConfig::DescArray reprDescs = _GetReprDesc(reprToken); // For each relevant draw item, update dirty buffer sources. @@ -1648,6 +1651,7 @@ void HdVP2Mesh::_UpdateDrawItem( auto* const param = static_cast(_delegate->GetRenderParam()); ProxyRenderDelegate& drawScene = param->GetDrawScene(); + UsdImagingDelegate* usdImagingDelegate = drawScene.GetUsdImagingDelegate(); #ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT // We don't need to update the shaded selected instance item when the selection mode is not @@ -1709,6 +1713,12 @@ void HdVP2Mesh::_UpdateDrawItem( if (requiresIndexUpdate && (itemDirtyBits & HdChangeTracker::DirtyTopology)) { const HdMeshTopology& topologyToUse = _meshSharedData->_renderingTopology; + MProfilingScope profilingScope( + HdVP2RenderDelegate::sProfilerCategory, + MProfiler::kColorC_L2, + _rprimId.asChar(), + "HdVP2Mesh prepare index buffer"); + if (desc.geomStyle == HdMeshGeomStyleHull) { // _trianglesFaceVertexIndices has the full triangulation calculated in // _updateRepr. Find the triangles which represent faces in the matching @@ -1795,8 +1805,7 @@ void HdVP2Mesh::_UpdateDrawItem( SdfPath cachePathMaterialId = drawItemData._geomSubset.materialId; // This is annoying! The saved materialId is a cache path, but to look up the // material in the render index we need the index path. - materialId = dynamic_cast(sceneDelegate) - ->ConvertCachePathToIndexPath(cachePathMaterialId); + materialId = usdImagingDelegate->ConvertCachePathToIndexPath(cachePathMaterialId); } const HdVP2Material* material = static_cast( renderIndex.GetSprim(HdPrimTypeTokens->material, materialId)); @@ -1938,6 +1947,12 @@ void HdVP2Mesh::_UpdateDrawItem( bool instancerWithNoInstances = false; if (!GetInstancerId().IsEmpty()) { + MProfilingScope profilingScope( + HdVP2RenderDelegate::sProfilerCategory, + MProfiler::kColorC_L2, + _rprimId.asChar(), + "HdVP2Mesh Update instances"); + // Retrieve instance transforms from the instancer. HdInstancer* instancer = renderIndex.GetInstancer(GetInstancerId()); VtMatrix4dArray transforms @@ -2092,6 +2107,10 @@ void HdVP2Mesh::_UpdateDrawItem( } } + TF_VERIFY( + stateToCommit._ufeIdentifiers.length() + == stateToCommit._instanceTransforms.length()); + if (stateToCommit._instanceTransforms.length() == 0) instancerWithNoInstances = true; } @@ -2512,6 +2531,12 @@ void HdVP2Mesh::_UpdatePrimvarSources( HdDirtyBits dirtyBits, const TfTokenVector& requiredPrimvars) { + MProfilingScope profilingScope( + HdVP2RenderDelegate::sProfilerCategory, + MProfiler::kColorC_L2, + _rprimId.asChar(), + "HdVP2Mesh::_UpdatePrimvarSources"); + const SdfPath& id = GetId(); auto updatePrimvarInfo diff --git a/lib/mayaUsd/render/vp2RenderDelegate/mesh.h b/lib/mayaUsd/render/vp2RenderDelegate/mesh.h index 52c650e7bd..775c2b0d01 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/mesh.h +++ b/lib/mayaUsd/render/vp2RenderDelegate/mesh.h @@ -187,7 +187,6 @@ class HdVP2Mesh final : public HdMesh DirtyFlatNormals = (DirtySmoothNormals << 1), //! "Forward" the enumerated types here so we don't have to keep writing MayaPrimCommon in //! the cpp file. - DirtySelection = MayaPrimCommon::DirtySelection, DirtySelectionHighlight = MayaPrimCommon::DirtySelectionHighlight, DirtySelectionMode = MayaPrimCommon::DirtySelectionMode }; diff --git a/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.cpp b/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.cpp index ca0e6ac724..ee7b714ca0 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.cpp +++ b/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.cpp @@ -95,9 +95,6 @@ const HdReprSelector kBBoxReprSelector(TfToken(), HdVP2ReprTokens->bbox); //! Representation selector for point snapping const HdReprSelector kPointsReprSelector(TfToken(), TfToken(), HdReprTokens->points); -//! Representation selector for selection update -const HdReprSelector kSelectionReprSelector(HdVP2ReprTokens->selection); - #if defined(WANT_UFE_BUILD) //! \brief Query the global selection list adjustment. MGlobal::ListAdjustment GetListAdjustment() @@ -287,17 +284,9 @@ void _ConfigureReprs() // Edge desc for bbox display. HdMesh::ConfigureRepr(HdVP2ReprTokens->bbox, reprDescEdge); - // Special token for selection update and no need to create repr. Adding - // the empty desc to remove Hydra warning. - HdMesh::ConfigureRepr(HdVP2ReprTokens->selection, HdMeshReprDesc()); - // Wireframe desc for bbox display. HdBasisCurves::ConfigureRepr(HdVP2ReprTokens->bbox, HdBasisCurvesGeomStyleWire); - // Special token for selection update and no need to create repr. Adding - // the null desc to remove Hydra warning. - HdBasisCurves::ConfigureRepr(HdVP2ReprTokens->selection, HdBasisCurvesGeomStyleInvalid); - #ifdef HAS_DEFAULT_MATERIAL_SUPPORT_API // Wire for default material: HdBasisCurves::ConfigureRepr(HdVP2ReprTokens->defaultMaterial, HdBasisCurvesGeomStyleWire); @@ -1187,14 +1176,17 @@ void ProxyRenderDelegate::_UpdateSelectionStates() const MHWRender::DisplayStatus previousStatus = _displayStatus; _displayStatus = MHWRender::MGeometryUtilities::displayStatus(_proxyShapeData->ProxyDagPath()); - SdfPathVector rootPaths; + SdfPathVector rootPaths; + const SdfPathVector* dirtyPaths = nullptr; if (_displayStatus == MHWRender::kLead || _displayStatus == MHWRender::kActive) { if (_displayStatus != previousStatus) { rootPaths.push_back(SdfPath::AbsoluteRootPath()); + dirtyPaths = &_renderIndex->GetRprimIds(); } } else if (previousStatus == MHWRender::kLead || previousStatus == MHWRender::kActive) { rootPaths.push_back(SdfPath::AbsoluteRootPath()); + dirtyPaths = &_renderIndex->GetRprimIds(); _PopulateSelection(); } else { // Append pre-update lead and active selection. @@ -1207,25 +1199,29 @@ void ProxyRenderDelegate::_UpdateSelectionStates() // Append post-update lead and active selection. AppendSelectedPrimPaths(_leadSelection, rootPaths); AppendSelectedPrimPaths(_activeSelection, rootPaths); + + dirtyPaths = &rootPaths; } if (!rootPaths.empty()) { -#ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT - // When the selection mode changes then we have to update all the selected render + // When the selection changes then we have to update all the selected render // items. Set a dirty flag on each of the rprims so they know what to update. // Avoid trying to set dirty the absolute root as it is not a Rprim. - if (_selectionModeChanged) { - HdChangeTracker& changeTracker = _renderIndex->GetChangeTracker(); - const SdfPath& absRoot = SdfPath::AbsoluteRootPath(); - for (auto path : rootPaths) { - if (path != absRoot) { - changeTracker.MarkRprimDirty(path, MayaPrimCommon::DirtySelectionMode); - } - } - } + HdDirtyBits dirtySelectionBits = MayaPrimCommon::DirtySelectionHighlight; +#ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT + // If the selection mode changes, for example into or out of point snapping, + // then we need to do a little extra work. + if (_selectionModeChanged) + dirtySelectionBits |= MayaPrimCommon::DirtySelectionMode; #endif + HdChangeTracker& changeTracker = _renderIndex->GetChangeTracker(); + for (auto path : *dirtyPaths) { + changeTracker.MarkRprimDirty(path, dirtySelectionBits); + } - HdRprimCollection collection(HdTokens->geometry, kSelectionReprSelector); + // now that the appropriate prims have been marked dirty trigger + // a sync so that they all update. + HdRprimCollection collection(HdTokens->geometry, kSmoothHullReprSelector); collection.SetRootPaths(rootPaths); _taskController->SetCollection(collection); _engine.Execute(_renderIndex.get(), &_dummyTasks); @@ -1456,6 +1452,11 @@ bool ProxyRenderDelegate::DrawRenderTag(const TfToken& renderTag) const } } +UsdImagingDelegate* ProxyRenderDelegate::GetUsdImagingDelegate() const +{ + return _sceneDelegate.get(); +} + #ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT bool ProxyRenderDelegate::SnapToSelectedObjects() const { return _snapToSelectedObjects; } bool ProxyRenderDelegate::SnapToPoints() const { return _snapToPoints; } diff --git a/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.h b/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.h index 4cd9e39683..bcb4e57d0d 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.h +++ b/lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.h @@ -179,6 +179,9 @@ class ProxyRenderDelegate : public MHWRender::MPxSubSceneOverride MAYAUSD_CORE_PUBLIC bool DrawRenderTag(const TfToken& renderTag) const; + MAYAUSD_CORE_PUBLIC + UsdImagingDelegate* GetUsdImagingDelegate() const; + #ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT MAYAUSD_CORE_PUBLIC bool SnapToSelectedObjects() const; diff --git a/lib/mayaUsd/render/vp2RenderDelegate/tokens.h b/lib/mayaUsd/render/vp2RenderDelegate/tokens.h index 52bea219d5..e5ad3a4247 100644 --- a/lib/mayaUsd/render/vp2RenderDelegate/tokens.h +++ b/lib/mayaUsd/render/vp2RenderDelegate/tokens.h @@ -24,8 +24,7 @@ PXR_NAMESPACE_OPEN_SCOPE // clang-format off #define HDVP2_REPR_TOKENS \ (bbox) \ - (defaultMaterial) \ - (selection) + (defaultMaterial) #define HDVP2_TOKENS \ (displayColorAndOpacity) \