maintain RenderTask dependencies through merge

If they are not maintained, then the merge leaves links to
deleted RenderTarget nodes. This creates confusion while
trying to debug.

Change-Id: I9d98a4ed2887573ddc5dfa2bae1bb22d30879c5a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/402641
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Adlai Holler <adlai@google.com>
This commit is contained in:
Herb Derby 2021-04-29 14:01:12 -04:00 committed by Skia Commit-Bot
parent 048b5a2967
commit f5b03fcdd2
3 changed files with 52 additions and 21 deletions

View File

@ -715,38 +715,44 @@ int GrOpsTask::mergeFrom(SkSpan<const sk_sp<GrRenderTask>> tasks) {
return 0;
}
SkSpan<const sk_sp<GrOpsTask>> opsTasks(
SkSpan<const sk_sp<GrOpsTask>> mergingNodes(
reinterpret_cast<const sk_sp<GrOpsTask>*>(tasks.data()), SkToSizeT(mergedCount));
int addlDeferredProxyCount = 0;
int addlProxyCount = 0;
int addlOpChainCount = 0;
for (const auto& opsTask : opsTasks) {
addlDeferredProxyCount += opsTask->fDeferredProxies.count();
addlProxyCount += opsTask->fSampledProxies.count();
addlOpChainCount += opsTask->fOpChains.count();
fClippedContentBounds.join(opsTask->fClippedContentBounds);
fTotalBounds.join(opsTask->fTotalBounds);
fRenderPassXferBarriers |= opsTask->fRenderPassXferBarriers;
fUsesMSAASurface |= opsTask->fUsesMSAASurface;
SkDEBUGCODE(fNumClips += opsTask->fNumClips);
for (const auto& toMerge : mergingNodes) {
addlDeferredProxyCount += toMerge->fDeferredProxies.count();
addlProxyCount += toMerge->fSampledProxies.count();
addlOpChainCount += toMerge->fOpChains.count();
fClippedContentBounds.join(toMerge->fClippedContentBounds);
fTotalBounds.join(toMerge->fTotalBounds);
fRenderPassXferBarriers |= toMerge->fRenderPassXferBarriers;
fUsesMSAASurface |= toMerge->fUsesMSAASurface;
SkDEBUGCODE(fNumClips += toMerge->fNumClips);
}
fLastClipStackGenID = SK_InvalidUniqueID;
fDeferredProxies.reserve_back(addlDeferredProxyCount);
fSampledProxies.reserve_back(addlProxyCount);
fOpChains.reserve_back(addlOpChainCount);
for (const auto& opsTask : opsTasks) {
fDeferredProxies.move_back_n(opsTask->fDeferredProxies.count(),
opsTask->fDeferredProxies.data());
fSampledProxies.move_back_n(opsTask->fSampledProxies.count(),
opsTask->fSampledProxies.data());
fOpChains.move_back_n(opsTask->fOpChains.count(),
opsTask->fOpChains.data());
opsTask->fDeferredProxies.reset();
opsTask->fSampledProxies.reset();
opsTask->fOpChains.reset();
for (const auto& toMerge : mergingNodes) {
for (GrRenderTask* renderTask : toMerge->dependents()) {
renderTask->replaceDependency(toMerge.get(), this);
}
fMustPreserveStencil = opsTasks.back()->fMustPreserveStencil;
for (GrRenderTask* renderTask : toMerge->dependencies()) {
renderTask->replaceDependent(toMerge.get(), this);
}
fDeferredProxies.move_back_n(toMerge->fDeferredProxies.count(),
toMerge->fDeferredProxies.data());
fSampledProxies.move_back_n(toMerge->fSampledProxies.count(),
toMerge->fSampledProxies.data());
fOpChains.move_back_n(toMerge->fOpChains.count(),
toMerge->fOpChains.data());
toMerge->fDeferredProxies.reset();
toMerge->fSampledProxies.reset();
toMerge->fOpChains.reset();
}
fMustPreserveStencil = mergingNodes.back()->fMustPreserveStencil;
return mergedCount;
}

View File

@ -220,6 +220,26 @@ void GrRenderTask::addDependency(GrDrawingManager* drawingMgr, GrSurfaceProxy* d
}
}
void GrRenderTask::replaceDependency(const GrRenderTask* toReplace, GrRenderTask* replaceWith) {
for (auto& target : fDependencies) {
if (target == toReplace) {
target = replaceWith;
replaceWith->fDependents.push_back(this);
break;
}
}
}
void GrRenderTask::replaceDependent(const GrRenderTask* toReplace, GrRenderTask* replaceWith) {
for (auto& target : fDependents) {
if (target == toReplace) {
target = replaceWith;
replaceWith->fDependencies.push_back(this);
break;
}
}
}
bool GrRenderTask::dependsOn(const GrRenderTask* dependedOn) const {
for (int i = 0; i < fDependencies.count(); ++i) {
if (fDependencies[i] == dependedOn) {

View File

@ -79,6 +79,11 @@ public:
void addDependenciesFromOtherTask(GrRenderTask* otherTask);
SkSpan<GrRenderTask*> dependencies() { return SkSpan<GrRenderTask*>(fDependencies); }
SkSpan<GrRenderTask*> dependents() { return SkSpan<GrRenderTask*>(fDependents); }
void replaceDependency(const GrRenderTask* toReplace, GrRenderTask* replaceWith);
void replaceDependent(const GrRenderTask* toReplace, GrRenderTask* replaceWith);
/*
* Does this renderTask depend on 'dependedOn'?