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:
parent
048b5a2967
commit
f5b03fcdd2
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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'?
|
||||
|
Loading…
Reference in New Issue
Block a user