Skip flush in GrDrawingManager if the specifed proxy doesn't have any work

This is rather ham-fisted but I would like to have a short-term fix for the "always-flush" perf regressions.

Change-Id: Id359ad5a01a290e7e6c06f7ccc1c385ad47d2c06
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206277
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2019-04-08 12:55:53 -04:00 committed by Skia Commit-Bot
parent f58e49f8e9
commit 4187ac5e47
7 changed files with 63 additions and 0 deletions

View File

@ -113,6 +113,16 @@ protected:
private:
friend class GrDrawingManager; // for resetFlag, TopoSortTraits & gatherProxyIntervals
virtual bool onIsUsed(GrSurfaceProxy*) const = 0;
bool isUsed(GrSurfaceProxy* proxy) const {
if (proxy == fTarget.get()) {
return true;
}
return this->onIsUsed(proxy);
}
void addDependency(GrOpList* dependedOn);
void addDependent(GrOpList* dependent);
SkDEBUGCODE(bool isDependedent(const GrOpList* dependent) const;)

View File

@ -72,6 +72,16 @@ void GrDrawingManager::OpListDAG::removeOpLists(int startIndex, int stopIndex) {
}
}
bool GrDrawingManager::OpListDAG::isUsed(GrSurfaceProxy* proxy) const {
for (int i = 0; i < fOpLists.count(); ++i) {
if (fOpLists[i] && fOpLists[i]->isUsed(proxy)) {
return true;
}
}
return false;
}
void GrDrawingManager::OpListDAG::add(sk_sp<GrOpList> opList) {
fOpLists.emplace_back(std::move(opList));
}
@ -209,6 +219,10 @@ GrSemaphoresSubmitted GrDrawingManager::flush(GrSurfaceProxy* proxy,
SkDEBUGCODE(this->validate());
if (SkSurface::kNone_FlushFlags == flags && !numSemaphores && proxy && !fDAG.isUsed(proxy)) {
return GrSemaphoresSubmitted::kNo;
}
auto direct = fContext->priv().asDirectContext();
if (!direct) {
return GrSemaphoresSubmitted::kNo; // Can't flush while DDL recording

View File

@ -118,6 +118,8 @@ private:
bool empty() const { return fOpLists.empty(); }
int numOpLists() const { return fOpLists.count(); }
bool isUsed(GrSurfaceProxy*) const;
GrOpList* opList(int index) { return fOpLists[index].get(); }
const GrOpList* opList(int index) const { return fOpLists[index].get(); }

View File

@ -610,6 +610,21 @@ void GrRenderTargetOpList::purgeOpsWithUninstantiatedProxies() {
}
}
bool GrRenderTargetOpList::onIsUsed(GrSurfaceProxy* proxyToCheck) const {
bool used = false;
auto visit = [ proxyToCheck, &used ] (GrSurfaceProxy* p) {
if (p == proxyToCheck) {
used = true;
}
};
for (const OpChain& recordedOp : fOpChains) {
recordedOp.visitProxies(visit, GrOp::VisitorType::kOther);
}
return used;
}
void GrRenderTargetOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
for (int i = 0; i < fDeferredProxies.count(); ++i) {

View File

@ -126,6 +126,8 @@ private:
// however, requires that the RTC be able to coordinate with the op list to achieve similar ends
friend class GrRenderTargetContext;
bool onIsUsed(GrSurfaceProxy*) const override;
// Must only be called if native stencil buffer clearing is enabled
void setStencilLoadOp(GrLoadOp op);
// Must only be called if native color buffer clearing is enabled.

View File

@ -180,6 +180,24 @@ void GrTextureOpList::purgeOpsWithUninstantiatedProxies() {
}
}
bool GrTextureOpList::onIsUsed(GrSurfaceProxy* proxyToCheck) const {
bool used = false;
auto visit = [ proxyToCheck, &used ] (GrSurfaceProxy* p) {
if (p == proxyToCheck) {
used = true;
}
};
for (int i = 0; i < fRecordedOps.count(); ++i) {
const GrOp* op = fRecordedOps[i].get();
if (op) {
op->visitProxies(visit, GrOp::VisitorType::kOther);
}
}
return used;
}
void GrTextureOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
// Add the interval for all the writes to this opList's target

View File

@ -59,6 +59,8 @@ public:
SkDEBUGCODE(void dump(bool printDependencies) const override;)
private:
bool onIsUsed(GrSurfaceProxy*) const override;
void deleteOp(int index);
void deleteOps();