aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2018-07-24 11:04:18 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-24 15:31:15 +0000
commit20d4e546d8cb34f8944ef00d249416a047c95524 (patch)
tree98fd2038df62c53eb14935e68644359c609f3dd0 /src
parent734b2a859784af0b16dbbe07570e6d2f5da34e76 (diff)
Reduce arbitrary opList splitting when sorting (take 2)
The original CL (https://skia-review.googlesource.com/c/skia/+/141243 (Reduce arbitrary opList splitting when sorting)) was reverted due to Gold image diffs and perf regressions on Android. The image diffs should be fixed by: https://skia-review.googlesource.com/c/skia/+/142163 (Fix explicit allocation bug) Change-Id: I4bcc59820daf440de81f48e8970b47a6c8ec2bbb Reviewed-on: https://skia-review.googlesource.com/142102 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrDrawingManager.cpp42
-rw-r--r--src/gpu/GrOpList.cpp41
-rw-r--r--src/gpu/GrRenderTargetOpList.h3
3 files changed, 76 insertions, 10 deletions
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 8b0fb22f6b..366f285cf3 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -427,11 +427,22 @@ sk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* r
SkASSERT(fContext);
if (!fOpLists.empty()) {
- // This is a temporary fix for the partial-MDB world. In that world we're not
- // reordering so ops that (in the single opList world) would've just glommed onto the
- // end of the single opList but referred to a far earlier RT need to appear in their
- // own opList.
- fOpLists.back()->makeClosed(*fContext->contextPriv().caps());
+ if (fSortRenderTargets) {
+ // In this case we need to close all the opLists that rely on the current contents of
+ // 'rtp'. That is bc we're going to update the content of the proxy so they need to be
+ // split in case they use both the old and new content. (This is a bit of an overkill:
+ // they really only need to be split if they ever reference proxy's contents again but
+ // that is hard to predict/handle).
+ if (GrOpList* lastOpList = rtp->getLastOpList()) {
+ lastOpList->closeThoseWhoDependOnMe(*fContext->contextPriv().caps());
+ }
+ } else {
+ // This is a temporary fix for the partial-MDB world. In that world we're not
+ // reordering so ops that (in the single opList world) would've just glommed onto the
+ // end of the single opList but referred to a far earlier RT need to appear in their
+ // own opList.
+ fOpLists.back()->makeClosed(*fContext->contextPriv().caps());
+ }
}
auto resourceProvider = fContext->contextPriv().resourceProvider();
@@ -454,11 +465,22 @@ sk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(GrTextureProxy* textur
SkASSERT(fContext);
if (!fOpLists.empty()) {
- // This is a temporary fix for the partial-MDB world. In that world we're not
- // reordering so ops that (in the single opList world) would've just glommed onto the
- // end of the single opList but referred to a far earlier RT need to appear in their
- // own opList.
- fOpLists.back()->makeClosed(*fContext->contextPriv().caps());
+ if (fSortRenderTargets) {
+ // In this case we need to close all the opLists that rely on the current contents of
+ // 'rtp'. That is bc we're going to update the content of the proxy so they need to be
+ // split in case they use both the old and new content. (This is a bit of an overkill:
+ // they really only need to be split if they ever reference proxy's contents again but
+ // that is hard to predict/handle).
+ if (GrOpList* lastOpList = textureProxy->getLastOpList()) {
+ lastOpList->closeThoseWhoDependOnMe(*fContext->contextPriv().caps());
+ }
+ } else {
+ // This is a temporary fix for the partial-MDB world. In that world we're not
+ // reordering so ops that (in the single opList world) would've just glommed onto the
+ // end of the single opList but referred to a far earlier RT need to appear in their
+ // own opList.
+ fOpLists.back()->makeClosed(*fContext->contextPriv().caps());
+ }
}
sk_sp<GrTextureOpList> opList(new GrTextureOpList(fContext->contextPriv().resourceProvider(),
diff --git a/src/gpu/GrOpList.cpp b/src/gpu/GrOpList.cpp
index 313c38f14c..12d15afe6a 100644
--- a/src/gpu/GrOpList.cpp
+++ b/src/gpu/GrOpList.cpp
@@ -96,6 +96,9 @@ void GrOpList::addDependency(GrOpList* dependedOn) {
}
fDependencies.push_back(dependedOn);
+ dependedOn->addDependent(this);
+
+ SkDEBUGCODE(this->validate());
}
// Convert from a GrSurface-based dependency to a GrOpList one
@@ -134,6 +137,38 @@ bool GrOpList::dependsOn(const GrOpList* dependedOn) const {
return false;
}
+void GrOpList::addDependent(GrOpList* dependent) {
+ fDependents.push_back(dependent);
+}
+
+#ifdef SK_DEBUG
+bool GrOpList::isDependedent(const GrOpList* dependent) const {
+ for (int i = 0; i < fDependents.count(); ++i) {
+ if (fDependents[i] == dependent) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void GrOpList::validate() const {
+ // TODO: check for loops and duplicates
+
+ for (int i = 0; i < fDependencies.count(); ++i) {
+ SkASSERT(fDependencies[i]->isDependedent(this));
+ }
+}
+#endif
+
+void GrOpList::closeThoseWhoDependOnMe(const GrCaps& caps) {
+ for (int i = 0; i < fDependents.count(); ++i) {
+ if (!fDependents[i]->isClosed()) {
+ fDependents[i]->makeClosed(caps);
+ }
+ }
+}
+
bool GrOpList::isInstantiated() const {
return fTarget.get()->priv().isInstantiated();
}
@@ -158,6 +193,12 @@ void GrOpList::dump(bool printDependencies) const {
SkDebugf("%d, ", fDependencies[i]->fUniqueID);
}
SkDebugf("\n");
+
+ SkDebugf("(%d) Rely On Me: ", fDependents.count());
+ for (int i = 0; i < fDependents.count(); ++i) {
+ SkDebugf("%d, ", fDependents[i]->fUniqueID);
+ }
+ SkDebugf("\n");
}
}
#endif
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index 8629a7cb1f..81bd6f16e4 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -87,6 +87,9 @@ public:
op->visitProxies(addDependency);
clip.visitProxies(addDependency);
+ if (dstProxy.proxy()) {
+ addDependency(dstProxy.proxy());
+ }
return this->recordOp(std::move(op), caps, clip.doesClip() ? &clip : nullptr, &dstProxy);
}