Skip to content

DependencyForwardSceneIndex sends Redundant dirty notices #4007

@lanierd-adsk

Description

@lanierd-adsk

name: Fix Redundant Dirty Notices
overview: "HdDependencyForwardingSceneIndex emits redundant PrimsDirtied notices for the same prim: one combined entry (extent, primvars/normals, primvars/points) plus three separate per-locator entries. Fix by consolidating the output so downstream receives a single notice per prim."
todos: []
isProject: false

Fix Redundant Dirty Notifications in HdDependencyForwardingSceneIndex

Summary

During blend-shape or skinned animation, the Scene Index Notice Logger shows 4 dirtied notices for the same mesh prim instead of 1:

  1. extent, primvars/normals, primvars/points (combined)
  2. extent
  3. primvars/normals
  4. primvars/points
Image

Downstream consumers may process the mesh multiple times per frame, adding unnecessary cost especially when each primvars/points notice triggers a full mesh rebuild.


Root Cause

File: AdskUsd/pxr/imaging/hd/dependencyForwardingSceneIndex.cpp

In _PrimsDirtied (lines 105-126):

for (const DirtiedPrimEntry &entry : entries) {
    for (const HdDataSourceLocator &sourceLocator : entry.dirtyLocators) {
        _PrimDirtied(entry.primPath, sourceLocator, &visited, &affectedEntries);
    }
}
if (affectedEntries.empty()) {
    _SendPrimsDirtied(entries);
} else {
    affectedEntries.insert(affectedEntries.begin(), entries.begin(), entries.end());
    _SendPrimsDirty(affectedEntries);
}
  • The loop calls _PrimDirtied for each locator; _PrimDirtied appends {primPath, singleLocator} to affectedEntries
  • When affectedEntries is non-empty, the output merges the original entries (multi-locator) with affectedEntries (per-locator)
  • Result: same prim appears with both the combined locator set and each individual locator

Fix Strategy

Consolidate the output so each prim appears at most once with a merged locator set:

  1. When building affectedEntries from _PrimDirtied, merge locators by prim path instead of emitting one entry per locator
  2. Or: do not prepend the original entries when they are already represented in affectedEntries (avoid duplicate coverage for the same prim)
  3. Or: after the loop, merge entries that share the same primPath into a single entry with the union of their locators

The fix must preserve dependency-forwarding behavior: when prim A depends on prim B, dirtying B must still propagate to A. The redundancy is only in emitting both {path, {a,b,c}} and {path, a}, {path, b}, {path, c} for the same prim.


Implementation Approach

  1. Merge entries by prim path before sending: iterate over affectedEntries + original entries, group by primPath, and union locators. Emit one DirtiedPrimEntry per prim with the combined locator set.

  2. Alternative: In the else branch, do not insert the original entries at the beginning. Instead, merge each original entry's locators into the corresponding affectedEntries for that prim (or add the prim if not yet in affectedEntries). Then send only the merged result.

  3. Verify: Use the Scene Index Notice Logger to confirm a single dirtied notice per prim per frame during blend-shape playback.


Files to Modify

File Change
AdskUsd/pxr/imaging/hd/dependencyForwardingSceneIndex.cpp Consolidate _PrimsDirtied output to one entry per prim with merged locators

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions