Skip to content

Commit

Permalink
Merge pull request #558 from Autodesk/krickw/MAYA-104542/handle_rprim…
Browse files Browse the repository at this point in the history
…_purpose_changed

MAYA-104542 Handle rprim purpose changing to a hidden purpose correctly
  • Loading branch information
Krystian Ligenza authored Jun 8, 2020
2 parents f4fbba0 + 7665260 commit 4ea2f25
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 27 deletions.
43 changes: 43 additions & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,20 @@ void HdVP2Mesh::Sync(
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.
auto* const param = static_cast<HdVP2RenderParam*>(_delegate->GetRenderParam());
ProxyRenderDelegate& drawScene = param->GetDrawScene();
if (!drawScene.DrawRenderTag(delegate->GetRenderIndex().GetRenderTag(GetId()))) {
_HideAllDrawItems(reprToken);
// clearing visibility here is wrong. It is a work around to handle purpose changing
// marking visibility dirty instead of render tag. See UsdImagingGprimAdapter::ProcessPropertyChange
// for where this happens.
*dirtyBits &= ~( HdChangeTracker::DirtyRenderTag | HdChangeTracker::DirtyVisibility );
return;
}

MProfilingScope profilingScope(HdVP2RenderDelegate::sProfilerCategory,
MProfiler::kColorC_L2, _rprimId.asChar(), "HdVP2Mesh::Sync");

Expand Down Expand Up @@ -1522,6 +1536,35 @@ void HdVP2Mesh::_UpdateDrawItem(
});
}

void HdVP2Mesh::_HideAllDrawItems(const TfToken& reprToken) {
HdReprSharedPtr const& curRepr = _GetRepr(reprToken);
if (!curRepr) {
return;
}

_MeshReprConfig::DescArray reprDescs = _GetReprDesc(reprToken);

// For each relevant draw item, update dirty buffer sources.
int drawItemIndex = 0;
for (size_t descIdx = 0; descIdx < reprDescs.size(); ++descIdx) {
const HdMeshReprDesc& desc = reprDescs[descIdx];
if (desc.geomStyle == HdMeshGeomStyleInvalid) {
continue;
}

auto* drawItem = static_cast<HdVP2DrawItem*>(curRepr->GetDrawItem(drawItemIndex++));
if (!drawItem)
continue;
MHWRender::MRenderItem* renderItem = drawItem->GetRenderItem();
if (!renderItem)
continue;

_delegate->GetVP2ResourceRegistry().EnqueueCommit([renderItem]() {
renderItem->enable(false);
});
}
}

/*! \brief Update _primvarSourceMap, our local cache of raw primvar data.
This function pulls data from the scene delegate, but defers processing.
Expand Down
2 changes: 2 additions & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class HdVP2Mesh final : public HdMesh {
const HdMeshReprDesc& desc,
bool requireSmoothNormals, bool requireFlatNormals);

void _HideAllDrawItems(const TfToken& reprToken);

void _UpdatePrimvarSources(
HdSceneDelegate* sceneDelegate,
HdDirtyBits dirtyBits,
Expand Down
66 changes: 39 additions & 27 deletions lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,20 +776,22 @@ void ProxyRenderDelegate::_UpdateRenderTags()
// are being hidden, because the render pass level filtering will prevent
// them from drawing.
// The Vp2RenderDelegate implements render tags using MRenderItem::Enable(),
// which means we do need to update individual MRenderItems when the render
// tags change.
// which means we do need to update individual MRenderItems when the displayed
// render tags change, or when the render tag on an rprim changes.
//
// To handle an rprim's render tag value changing we need to be sure that
// the dummy render task we use to draw includes all render tags. If we
// leave any tags out then when an rprim changes from a visible tag to
// a hidden one that rprim will get marked dirty, but Sync will not be
// called because the rprim doesn't match the current render tags.
//
// When we change the desired render tags on the proxyShape we'll be adding
// and/or removing some tags, so we can have existing MRenderItems that need
// to be hidden, or hidden items that need to be shown.
// This function needs to do three things:
// 1: Make sure every rprim with a render tag whose visibility changed gets
// marked dirty. This will ensure the upcoming execute call will update
// the visibility of the MRenderItems in MPxSubSceneOverride.
// 2: Make a special call to Execute() with only the render tags which have
// been removed. We need this extra call to hide the previously shown
// items.
// 3: Update the render tags with the new final render tags so that the next
// real call to execute will update all the now visible items.
// to be hidden, or hidden items that need to be shown. To do that we need
// to make sure every rprim with a render tag whose visibility changed gets
// marked dirty. This will ensure the upcoming execute call will update
// the visibility of the MRenderItems in MPxSubSceneOverride.
HdChangeTracker& changeTracker = _renderIndex->GetChangeTracker();
bool renderPurposeChanged = false;
bool proxyPurposeChanged = false;
bool guidePurposeChanged = false;
Expand All @@ -803,37 +805,28 @@ void ProxyRenderDelegate::_UpdateRenderTags()
// Build the list of render tags which were added or removed (changed)
// and the list of render tags which were removed.
TfTokenVector changedRenderTags;
TfTokenVector removedRenderTags;
if (renderPurposeChanged) {
changedRenderTags.push_back(HdRenderTagTokens->render);
if (!_proxyShapeData->DrawRenderPurpose())
removedRenderTags.push_back(HdRenderTagTokens->render);
}
if (proxyPurposeChanged) {
changedRenderTags.push_back(HdRenderTagTokens->proxy);
if (!_proxyShapeData->DrawProxyPurpose())
removedRenderTags.push_back(HdRenderTagTokens->proxy);
}
if (guidePurposeChanged) {
changedRenderTags.push_back(HdRenderTagTokens->guide);
if (!_proxyShapeData->DrawGuidePurpose())
removedRenderTags.push_back(HdRenderTagTokens->guide);
}

// Mark all the rprims which have a render tag which changed dirty
SdfPathVector rprimsToDirty = _GetFilteredRprims(*_defaultCollection, changedRenderTags);
HdChangeTracker& changeTracker = _renderIndex->GetChangeTracker();

for (auto& id : rprimsToDirty) {
changeTracker.MarkRprimDirty(id, HdChangeTracker::DirtyRenderTag);
}
}

// Make a special pass over the removed render tags so that the objects
// can hide themselves.
_taskController->SetRenderTags(removedRenderTags);
_engine.Execute(_renderIndex.get(), &_dummyTasks);

// Set the new render tags correctly.The regular execute will cause
// any newly visible rprims will update and mark themselves visible.
// When the render tag on an rprim changes we do a pass over all rprims to update
// their visibility. The frame after we do the pass over all the tags, set the tags back to
// the minimum set of tags.
if (!_taskRenderTagsValid) {
TfTokenVector renderTags
= { HdRenderTagTokens->geometry }; // always draw geometry render tag purpose.
if (_proxyShapeData->DrawRenderPurpose()) {
Expand All @@ -846,6 +839,25 @@ void ProxyRenderDelegate::_UpdateRenderTags()
renderTags.push_back(HdRenderTagTokens->guide);
}
_taskController->SetRenderTags(renderTags);
_taskRenderTagsValid = true;
}

// Vp2RenderDelegate implements render tags as a per-render item setting.
// To handle cases when an rprim changes from a displayed tag to a hidden tag
// we need to visit all the rprims and set the enable flag correctly on
// all their render items. Do visit all the rprims we need to set the
// render tags to be all the tags.
// When an rprim has it's renderTag changed the global render tag version
// id will change.
const int renderTagVersion = changeTracker.GetRenderTagVersion();
if (renderTagVersion != _renderTagVersion) {
TfTokenVector renderTags = { HdRenderTagTokens->geometry,
HdRenderTagTokens->render,
HdRenderTagTokens->proxy,
HdRenderTagTokens->guide };
_taskController->SetRenderTags(renderTags);
_taskRenderTagsValid = false;
_renderTagVersion = renderTagVersion;
}
}

Expand Down
5 changes: 5 additions & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ class ProxyRenderDelegate : public MHWRender::MPxSubSceneOverride
//! A collection of Rprims to prepare render data for specified reprs
std::unique_ptr<HdRprimCollection> _defaultCollection;

//! The render tag version used the last time render tags were updated
int _renderTagVersion { 0 }; // initialized to 1 in HdChangeTracker, so we'll always have an
// invalid version the first update.
bool _taskRenderTagsValid { false }; //!< If false the render tags on the dummy render task are not the minimum set of tags.

//! A collection of Rprims being selected
HdSelectionSharedPtr _selection;

Expand Down

0 comments on commit 4ea2f25

Please sign in to comment.