aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-11-01 17:32:39 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-11-02 12:22:41 +0000
commit8186cbee6cffb45c0c8ecade2f2c75a1fd8db0f8 (patch)
tree8e2e294f6b3aaa59a60fafadfc3f8bd987751f58
parentce54bcecc2a64dbda2417c0ee6bcb68f1a21c047 (diff)
Make the intervals in GrResourceAllocator use SkArenaAlloc
Change-Id: I3190396fe34c01c232654fcb225dbf76df3137b4 Reviewed-on: https://skia-review.googlesource.com/66463 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r--src/gpu/GrDrawingManager.cpp2
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp12
-rw-r--r--src/gpu/GrResourceAllocator.cpp17
-rw-r--r--src/gpu/GrResourceAllocator.h26
-rw-r--r--src/gpu/GrTextureOpList.cpp12
5 files changed, 51 insertions, 18 deletions
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 6076609bb9..9b15f3c4b5 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -171,12 +171,12 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
}
#endif
-#ifdef MDB_ALLOC_RESOURCES
GrResourceAllocator alloc(fContext->resourceProvider());
for (int i = 0; i < fOpLists.count(); ++i) {
fOpLists[i]->gatherProxyIntervals(&alloc);
}
+#ifdef MDB_ALLOC_RESOURCES
alloc.assign();
#endif
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index af870caffd..09486c7c99 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -257,6 +257,10 @@ bool GrRenderTargetOpList::copySurface(const GrCaps& caps,
}
void GrRenderTargetOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
+ if (!fRecordedOps.count()) {
+ return;
+ }
+
unsigned int cur = alloc->numOps();
// Add the interval for all the writes to this opList's target
@@ -266,12 +270,12 @@ void GrRenderTargetOpList::gatherProxyIntervals(GrResourceAllocator* alloc) cons
alloc->addInterval(p);
};
for (int i = 0; i < fRecordedOps.count(); ++i) {
- SkASSERT(alloc->curOp() == cur+i);
-
const GrOp* op = fRecordedOps[i].fOp.get(); // only diff from the GrTextureOpList version
- op->visitProxies(gather);
+ if (op) {
+ op->visitProxies(gather);
- alloc->incOps();
+ alloc->incOps();
+ }
}
}
diff --git a/src/gpu/GrResourceAllocator.cpp b/src/gpu/GrResourceAllocator.cpp
index ba62854a3a..62f780b177 100644
--- a/src/gpu/GrResourceAllocator.cpp
+++ b/src/gpu/GrResourceAllocator.cpp
@@ -17,13 +17,19 @@ void GrResourceAllocator::addInterval(GrSurfaceProxy* proxy,
if (Interval* intvl = fIntvlHash.find(proxy->uniqueID().asUInt())) {
// Revise the interval for an existing use
- SkASSERT(intvl->fEnd < start);
+ //SkASSERT(intvl->fEnd <= end);
intvl->fEnd = end;
return;
}
- // TODO: given the usage pattern an arena allocation scheme would work well here
- Interval* newIntvl = new Interval(proxy, start, end);
+ Interval* newIntvl;
+ if (fFreeIntervalList) {
+ newIntvl = fFreeIntervalList;
+ fFreeIntervalList = newIntvl->fNext;
+ newIntvl->resetTo(proxy, start, end);
+ } else {
+ newIntvl = fIntervalAllocator.make<Interval>(proxy, start, end);
+ }
fIntvlList.insertByIncreasingStart(newIntvl);
fIntvlHash.add(newIntvl);
@@ -109,7 +115,10 @@ void GrResourceAllocator::expire(unsigned int curIndex) {
while (!fActiveIntvls.empty() && fActiveIntvls.peekHead()->fEnd < curIndex) {
Interval* temp = fActiveIntvls.popHead();
this->freeUpSurface(temp->fProxy->priv().peekSurface());
- delete temp;
+
+ // Add temp to the free interval list so it can be reused
+ temp->fNext = fFreeIntervalList;
+ fFreeIntervalList = temp;
}
}
diff --git a/src/gpu/GrResourceAllocator.h b/src/gpu/GrResourceAllocator.h
index 966359c85e..3be4836ca9 100644
--- a/src/gpu/GrResourceAllocator.h
+++ b/src/gpu/GrResourceAllocator.h
@@ -11,6 +11,8 @@
#include "GrGpuResourcePriv.h"
#include "GrSurface.h"
#include "GrSurfaceProxy.h"
+
+#include "SkArenaAlloc.h"
#include "SkTDynamicHash.h"
#include "SkTMultiMap.h"
@@ -86,6 +88,16 @@ private:
SkASSERT(proxy);
}
+ void resetTo(GrSurfaceProxy* proxy, unsigned int start, unsigned int end) {
+ SkASSERT(proxy);
+
+ fProxy = proxy;
+ fProxyID = proxy->uniqueID().asUInt();
+ fStart = start;
+ fEnd = end;
+ fNext = nullptr;
+ }
+
// for SkTDynamicHash
static const uint32_t& GetKey(const Interval& intvl) {
return intvl.fProxyID;
@@ -103,11 +115,8 @@ private:
public:
IntervalList() = default;
~IntervalList() {
- while (fHead) {
- Interval* temp = fHead;
- fHead = temp->fNext;
- delete temp;
- }
+ // The only time we delete an IntervalList is in the GrResourceAllocator dtor.
+ // Since the arena allocator will clean up for us we don't bother here.
}
bool empty() const { return !SkToBool(fHead); }
@@ -120,6 +129,9 @@ private:
Interval* fHead = nullptr;
};
+ // Gathered statistics indicate that 99% of flushes will be covered by <= 12 Intervals
+ static const int kInitialArenaSize = 12 * sizeof(Interval);
+
GrResourceProvider* fResourceProvider;
FreePoolMultiMap fFreePool; // Recently created/used GrSurfaces
IntvlHash fIntvlHash; // All the intervals, hashed by proxyID
@@ -129,6 +141,10 @@ private:
// (sorted by increasing end)
unsigned int fNumOps = 0;
SkDEBUGCODE(bool fAssigned = false;)
+
+ char fStorage[kInitialArenaSize];
+ SkArenaAlloc fIntervalAllocator { fStorage, kInitialArenaSize, 0 };
+ Interval* fFreeIntervalList = nullptr;
};
#endif // GrResourceAllocator_DEFINED
diff --git a/src/gpu/GrTextureOpList.cpp b/src/gpu/GrTextureOpList.cpp
index cf003098cd..9a3d15be97 100644
--- a/src/gpu/GrTextureOpList.cpp
+++ b/src/gpu/GrTextureOpList.cpp
@@ -124,6 +124,10 @@ bool GrTextureOpList::copySurface(const GrCaps& caps,
}
void GrTextureOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
+ if (!fRecordedOps.count()) {
+ return;
+ }
+
unsigned int cur = alloc->numOps();
// Add the interval for all the writes to this opList's target
@@ -133,12 +137,12 @@ void GrTextureOpList::gatherProxyIntervals(GrResourceAllocator* alloc) const {
alloc->addInterval(p);
};
for (int i = 0; i < fRecordedOps.count(); ++i) {
- SkASSERT(alloc->curOp() == cur+i);
-
const GrOp* op = fRecordedOps[i].get(); // only diff from the GrRenderTargetOpList version
- op->visitProxies(gather);
+ if (op) {
+ op->visitProxies(gather);
- alloc->incOps();
+ alloc->incOps();
+ }
}
}