aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2015-06-24 06:54:10 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-06-24 06:54:10 -0700
commit1b8e1b5c499e31a671232c8ccb10e778e0d8b154 (patch)
tree75f4194d8fe6fbd04ffef72fd0da912646b996d2 /src
parent8bcc7a00febd737f7e82513bd5e4a697526626de (diff)
Refactor GrBufferAllocPools to use resource cache
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrBatchTarget.cpp19
-rw-r--r--src/gpu/GrBatchTarget.h16
-rw-r--r--src/gpu/GrBufferAllocPool.cpp124
-rw-r--r--src/gpu/GrBufferAllocPool.h32
-rw-r--r--src/gpu/GrCaps.cpp2
-rw-r--r--src/gpu/GrGpu.cpp12
-rw-r--r--src/gpu/GrIndexBuffer.h17
-rw-r--r--src/gpu/GrResourceProvider.cpp57
-rw-r--r--src/gpu/GrResourceProvider.h3
-rw-r--r--src/gpu/GrVertexBuffer.h17
-rw-r--r--src/gpu/gl/GrGLCaps.cpp5
11 files changed, 161 insertions, 143 deletions
diff --git a/src/gpu/GrBatchTarget.cpp b/src/gpu/GrBatchTarget.cpp
index 31b4cc9f47..b6dadd699b 100644
--- a/src/gpu/GrBatchTarget.cpp
+++ b/src/gpu/GrBatchTarget.cpp
@@ -10,27 +10,16 @@
#include "GrBatchAtlas.h"
#include "GrPipeline.h"
-static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15;
-static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
-
-static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11;
-static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4;
-
GrBatchTarget::GrBatchTarget(GrGpu* gpu)
: fGpu(gpu)
+ , fVertexPool(gpu)
+ , fIndexPool(gpu)
, fFlushBuffer(kFlushBufferInitialSizeInBytes)
, fIter(fFlushBuffer)
, fNumberOfDraws(0)
, fCurrentToken(0)
, fLastFlushedToken(0)
, fInlineUpdatesIndex(0) {
-
- fVertexPool.reset(SkNEW_ARGS(GrVertexBufferAllocPool, (fGpu,
- DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
- DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)));
- fIndexPool.reset(SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu,
- DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
- DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)));
}
void GrBatchTarget::flushNext(int n) {
@@ -65,11 +54,11 @@ void GrBatchTarget::flushNext(int n) {
void* GrBatchTarget::makeVertSpace(size_t vertexSize, int vertexCount,
const GrVertexBuffer** buffer, int* startVertex) {
- return fVertexPool->makeSpace(vertexSize, vertexCount, buffer, startVertex);
+ return fVertexPool.makeSpace(vertexSize, vertexCount, buffer, startVertex);
}
uint16_t* GrBatchTarget::makeIndexSpace(int indexCount,
const GrIndexBuffer** buffer, int* startIndex) {
- return reinterpret_cast<uint16_t*>(fIndexPool->makeSpace(indexCount, buffer, startIndex));
+ return reinterpret_cast<uint16_t*>(fIndexPool.makeSpace(indexCount, buffer, startIndex));
}
diff --git a/src/gpu/GrBatchTarget.h b/src/gpu/GrBatchTarget.h
index 80a8b9bad3..19cfb09cb7 100644
--- a/src/gpu/GrBatchTarget.h
+++ b/src/gpu/GrBatchTarget.h
@@ -115,26 +115,26 @@ public:
const GrIndexBuffer** buffer, int* startIndex);
// A helper for draws which overallocate and then return data to the pool
- void putBackIndices(size_t indices) { fIndexPool->putBack(indices * sizeof(uint16_t)); }
+ void putBackIndices(size_t indices) { fIndexPool.putBack(indices * sizeof(uint16_t)); }
void putBackVertices(size_t vertices, size_t vertexStride) {
- fVertexPool->putBack(vertices * vertexStride);
+ fVertexPool.putBack(vertices * vertexStride);
}
void reset() {
- fVertexPool->reset();
- fIndexPool->reset();
+ fVertexPool.reset();
+ fIndexPool.reset();
}
private:
void unmapVertexAndIndexBuffers() {
- fVertexPool->unmap();
- fIndexPool->unmap();
+ fVertexPool.unmap();
+ fIndexPool.unmap();
}
GrGpu* fGpu;
- SkAutoTDelete<GrVertexBufferAllocPool> fVertexPool;
- SkAutoTDelete<GrIndexBufferAllocPool> fIndexPool;
+ GrVertexBufferAllocPool fVertexPool;
+ GrIndexBufferAllocPool fIndexPool;
typedef void* TBufferAlign; // This wouldn't be enough align if a command used long double.
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index be88b32cb1..e9172108f3 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -9,8 +9,10 @@
#include "GrBufferAllocPool.h"
#include "GrCaps.h"
+#include "GrContext.h"
#include "GrGpu.h"
#include "GrIndexBuffer.h"
+#include "GrResourceProvider.h"
#include "GrTypes.h"
#include "GrVertexBuffer.h"
@@ -22,6 +24,9 @@
static void VALIDATE(bool = false) {}
#endif
+static const size_t MIN_VERTEX_BUFFER_SIZE = 1 << 15;
+static const size_t MIN_INDEX_BUFFER_SIZE = 1 << 12;
+
// page size
#define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 15)
@@ -37,9 +42,8 @@ do {
GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
BufferType bufferType,
- size_t blockSize,
- int preallocBufferCnt)
- : fBlocks(SkTMax(8, 2*preallocBufferCnt)) {
+ size_t blockSize)
+ : fBlocks(8) {
fGpu = SkRef(gpu);
@@ -49,19 +53,10 @@ GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
fBytesInUse = 0;
- fPreallocBuffersInUse = 0;
- fPreallocBufferStartIdx = 0;
- for (int i = 0; i < preallocBufferCnt; ++i) {
- GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize);
- if (buffer) {
- *fPreallocBuffers.append() = buffer;
- }
- }
fGeometryBufferMapThreshold = gpu->caps()->geometryBufferMapThreshold();
}
-GrBufferAllocPool::~GrBufferAllocPool() {
- VALIDATE();
+void GrBufferAllocPool::deleteBlocks() {
if (fBlocks.count()) {
GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
if (buffer->isMapped()) {
@@ -71,34 +66,22 @@ GrBufferAllocPool::~GrBufferAllocPool() {
while (!fBlocks.empty()) {
this->destroyBlock();
}
- fPreallocBuffers.unrefAll();
+ SkASSERT(!fBufferPtr);
+}
+
+GrBufferAllocPool::~GrBufferAllocPool() {
+ VALIDATE();
+ this->deleteBlocks();
fGpu->unref();
}
void GrBufferAllocPool::reset() {
VALIDATE();
fBytesInUse = 0;
- if (fBlocks.count()) {
- GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
- if (buffer->isMapped()) {
- UNMAP_BUFFER(fBlocks.back());
- }
- }
- // fPreallocBuffersInUse will be decremented down to zero in the while loop
- int preallocBuffersInUse = fPreallocBuffersInUse;
- while (!fBlocks.empty()) {
- this->destroyBlock();
- }
- if (fPreallocBuffers.count()) {
- // must set this after above loop.
- fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
- preallocBuffersInUse) %
- fPreallocBuffers.count();
- }
+ this->deleteBlocks();
// we may have created a large cpu mirror of a large VB. Reset the size
- // to match our pre-allocated VBs.
+ // to match our minimum.
fCpuData.reset(fMinBlockSize);
- SkASSERT(0 == fPreallocBuffersInUse);
VALIDATE();
}
@@ -170,8 +153,7 @@ void* GrBufferAllocPool::makeSpace(size_t size,
if (fBufferPtr) {
BufferBlock& back = fBlocks.back();
size_t usedBytes = back.fBuffer->gpuMemorySize() - back.fBytesFree;
- size_t pad = GrSizeAlignUpPad(usedBytes,
- alignment);
+ size_t pad = GrSizeAlignUpPad(usedBytes, alignment);
if ((size + pad) <= back.fBytesFree) {
memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
usedBytes += pad;
@@ -209,12 +191,6 @@ void* GrBufferAllocPool::makeSpace(size_t size,
void GrBufferAllocPool::putBack(size_t bytes) {
VALIDATE();
- // if the putBack unwinds all the preallocated buffers then we will
- // advance the starting index. As blocks are destroyed fPreallocBuffersInUse
- // will be decremented. I will reach zero if all blocks using preallocated
- // buffers are released.
- int preallocBuffersInUse = fPreallocBuffersInUse;
-
while (bytes) {
// caller shouldn't try to put back more than they've taken
SkASSERT(!fBlocks.empty());
@@ -236,11 +212,7 @@ void GrBufferAllocPool::putBack(size_t bytes) {
break;
}
}
- if (!fPreallocBuffersInUse && fPreallocBuffers.count()) {
- fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
- preallocBuffersInUse) %
- fPreallocBuffers.count();
- }
+
VALIDATE();
}
@@ -253,24 +225,13 @@ bool GrBufferAllocPool::createBlock(size_t requestSize) {
BufferBlock& block = fBlocks.push_back();
- if (size == fMinBlockSize &&
- fPreallocBuffersInUse < fPreallocBuffers.count()) {
-
- uint32_t nextBuffer = (fPreallocBuffersInUse +
- fPreallocBufferStartIdx) %
- fPreallocBuffers.count();
- block.fBuffer = fPreallocBuffers[nextBuffer];
- block.fBuffer->ref();
- ++fPreallocBuffersInUse;
- } else {
- block.fBuffer = this->createBuffer(size);
- if (NULL == block.fBuffer) {
- fBlocks.pop_back();
- return false;
- }
+ block.fBuffer = this->getBuffer(size);
+ if (NULL == block.fBuffer) {
+ fBlocks.pop_back();
+ return false;
}
- block.fBytesFree = size;
+ block.fBytesFree = block.fBuffer->gpuMemorySize();
if (fBufferPtr) {
SkASSERT(fBlocks.count() > 1);
BufferBlock& prev = fBlocks.fromBack(1);
@@ -297,7 +258,7 @@ bool GrBufferAllocPool::createBlock(size_t requestSize) {
}
if (NULL == fBufferPtr) {
- fBufferPtr = fCpuData.reset(size);
+ fBufferPtr = fCpuData.reset(block.fBytesFree);
}
VALIDATE(true);
@@ -309,15 +270,7 @@ void GrBufferAllocPool::destroyBlock() {
SkASSERT(!fBlocks.empty());
BufferBlock& block = fBlocks.back();
- if (fPreallocBuffersInUse > 0) {
- uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
- fPreallocBufferStartIdx +
- (fPreallocBuffers.count() - 1)) %
- fPreallocBuffers.count();
- if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) {
- --fPreallocBuffersInUse;
- }
- }
+
SkASSERT(!block.fBuffer->isMapped());
block.fBuffer->unref();
fBlocks.pop_back();
@@ -345,24 +298,22 @@ void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize)
VALIDATE(true);
}
-GrGeometryBuffer* GrBufferAllocPool::createBuffer(size_t size) {
+GrGeometryBuffer* GrBufferAllocPool::getBuffer(size_t size) {
+
+ GrResourceProvider* rp = fGpu->getContext()->resourceProvider();
+
if (kIndex_BufferType == fBufferType) {
- return fGpu->createIndexBuffer(size, true);
+ return rp->getIndexBuffer(size, /* dynamic = */ true, /* duringFlush = */ true);
} else {
SkASSERT(kVertex_BufferType == fBufferType);
- return fGpu->createVertexBuffer(size, true);
+ return rp->getVertexBuffer(size, /* dynamic = */ true, /* duringFlush = */ true);
}
}
////////////////////////////////////////////////////////////////////////////////
-GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu,
- size_t bufferSize,
- int preallocBufferCnt)
- : GrBufferAllocPool(gpu,
- kVertex_BufferType,
- bufferSize,
- preallocBufferCnt) {
+GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu)
+ : GrBufferAllocPool(gpu, kVertex_BufferType, MIN_VERTEX_BUFFER_SIZE) {
}
void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
@@ -389,13 +340,8 @@ void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
////////////////////////////////////////////////////////////////////////////////
-GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu,
- size_t bufferSize,
- int preallocBufferCnt)
- : GrBufferAllocPool(gpu,
- kIndex_BufferType,
- bufferSize,
- preallocBufferCnt) {
+GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu)
+ : GrBufferAllocPool(gpu, kIndex_BufferType, MIN_INDEX_BUFFER_SIZE) {
}
void* GrIndexBufferAllocPool::makeSpace(int indexCount,
diff --git a/src/gpu/GrBufferAllocPool.h b/src/gpu/GrBufferAllocPool.h
index cd5d1971da..bbcb8a5d7c 100644
--- a/src/gpu/GrBufferAllocPool.h
+++ b/src/gpu/GrBufferAllocPool.h
@@ -64,16 +64,12 @@ protected:
* @param bufferSize The minimum size of created buffers.
* This value will be clamped to some
* reasonable minimum.
- * @param preallocBufferCnt The pool will allocate this number of
- * buffers at bufferSize and keep them until it
- * is destroyed.
*/
GrBufferAllocPool(GrGpu* gpu,
BufferType bufferType,
- size_t bufferSize = 0,
- int preallocBufferCnt = 0);
+ size_t bufferSize = 0);
- virtual ~GrBufferAllocPool();
+ virtual ~GrBufferAllocPool();
/**
* Returns a block of memory to hold data. A buffer designated to hold the
@@ -99,7 +95,7 @@ protected:
const GrGeometryBuffer** buffer,
size_t* offset);
- GrGeometryBuffer* createBuffer(size_t size);
+ GrGeometryBuffer* getBuffer(size_t size);
private:
struct BufferBlock {
@@ -109,6 +105,7 @@ private:
bool createBlock(size_t requestSize);
void destroyBlock();
+ void deleteBlocks();
void flushCpuData(const BufferBlock& block, size_t flushSize);
#ifdef SK_DEBUG
void validate(bool unusedBlockAllowed = false) const;
@@ -117,15 +114,10 @@ private:
size_t fBytesInUse;
GrGpu* fGpu;
- SkTDArray<GrGeometryBuffer*> fPreallocBuffers;
size_t fMinBlockSize;
BufferType fBufferType;
SkTArray<BufferBlock> fBlocks;
- int fPreallocBuffersInUse;
- // We attempt to cycle through the preallocated buffers rather than
- // always starting from the first.
- int fPreallocBufferStartIdx;
SkAutoMalloc fCpuData;
void* fBufferPtr;
size_t fGeometryBufferMapThreshold;
@@ -142,13 +134,8 @@ public:
* Constructor
*
* @param gpu The GrGpu used to create the vertex buffers.
- * @param bufferSize The minimum size of created VBs. This value
- * will be clamped to some reasonable minimum.
- * @param preallocBufferCnt The pool will allocate this number of VBs at
- * bufferSize and keep them until it is
- * destroyed.
*/
- GrVertexBufferAllocPool(GrGpu* gpu, size_t bufferSize = 0, int preallocBufferCnt = 0);
+ GrVertexBufferAllocPool(GrGpu* gpu);
/**
* Returns a block of memory to hold vertices. A buffer designated to hold
@@ -191,15 +178,8 @@ public:
* Constructor
*
* @param gpu The GrGpu used to create the index buffers.
- * @param bufferSize The minimum size of created IBs. This value
- * will be clamped to some reasonable minimum.
- * @param preallocBufferCnt The pool will allocate this number of VBs at
- * bufferSize and keep them until it is
- * destroyed.
*/
- GrIndexBufferAllocPool(GrGpu* gpu,
- size_t bufferSize = 0,
- int preallocBufferCnt = 0);
+ GrIndexBufferAllocPool(GrGpu* gpu);
/**
* Returns a block of memory to hold indices. A buffer designated to hold
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index f2e88b01c4..900bd65cc2 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -86,6 +86,7 @@ GrCaps::GrCaps(const GrContextOptions& options) {
fStencilWrapOpsSupport = false;
fDiscardRenderTargetSupport = false;
fReuseScratchTextures = true;
+ fReuseScratchBuffers = true;
fGpuTracingSupport = false;
fCompressedTexSubImageSupport = false;
fOversizedStencilSupport = false;
@@ -146,6 +147,7 @@ SkString GrCaps::dump() const {
r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]);
r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
+ r.appendf("Reuse Scratch Buffers : %s\n", gNY[fReuseScratchBuffers]);
r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]);
r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]);
r.appendf("Oversized Stencil Support : %s\n", gNY[fOversizedStencilSupport]);
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index d46d09d5c7..728fb88062 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -199,12 +199,20 @@ GrRenderTarget* GrGpu::wrapBackendRenderTarget(const GrBackendRenderTargetDesc&
GrVertexBuffer* GrGpu::createVertexBuffer(size_t size, bool dynamic) {
this->handleDirtyContext();
- return this->onCreateVertexBuffer(size, dynamic);
+ GrVertexBuffer* vb = this->onCreateVertexBuffer(size, dynamic);
+ if (!this->caps()->reuseScratchBuffers()) {
+ vb->resourcePriv().removeScratchKey();
+ }
+ return vb;
}
GrIndexBuffer* GrGpu::createIndexBuffer(size_t size, bool dynamic) {
this->handleDirtyContext();
- return this->onCreateIndexBuffer(size, dynamic);
+ GrIndexBuffer* ib = this->onCreateIndexBuffer(size, dynamic);
+ if (!this->caps()->reuseScratchBuffers()) {
+ ib->resourcePriv().removeScratchKey();
+ }
+ return ib;
}
void GrGpu::clear(const SkIRect* rect,
diff --git a/src/gpu/GrIndexBuffer.h b/src/gpu/GrIndexBuffer.h
index 4dfd1c1b07..bf64ff87d2 100644
--- a/src/gpu/GrIndexBuffer.h
+++ b/src/gpu/GrIndexBuffer.h
@@ -13,8 +13,18 @@
#include "GrGeometryBuffer.h"
+
class GrIndexBuffer : public GrGeometryBuffer {
public:
+ static void ComputeScratchKey(size_t size, bool dynamic, GrScratchKey* key) {
+ static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
+
+ GrScratchKey::Builder builder(key, kType, 2);
+
+ builder[0] = SkToUInt(size);
+ builder[1] = dynamic ? 1 : 0;
+ }
+
/**
* Retrieves the maximum number of quads that could be rendered
* from the index buffer (using kTriangles_GrPrimitiveType).
@@ -25,7 +35,12 @@ public:
}
protected:
GrIndexBuffer(GrGpu* gpu, size_t gpuMemorySize, bool dynamic, bool cpuBacked)
- : INHERITED(gpu, gpuMemorySize, dynamic, cpuBacked) {}
+ : INHERITED(gpu, gpuMemorySize, dynamic, cpuBacked) {
+ GrScratchKey key;
+ ComputeScratchKey(gpuMemorySize, dynamic, &key);
+ this->setScratchKey(key);
+ }
+
private:
typedef GrGeometryBuffer INHERITED;
};
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 4b9d265129..3c447bded6 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -28,7 +28,7 @@ const GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16
const GrUniqueKey& key) {
size_t bufferSize = patternSize * reps * sizeof(uint16_t);
- GrIndexBuffer* buffer = this->gpu()->createIndexBuffer(bufferSize, /* dynamic = */ false);
+ GrIndexBuffer* buffer = this->getIndexBuffer(bufferSize, /* dynamic = */ false, true);
if (!buffer) {
return NULL;
}
@@ -83,3 +83,58 @@ GrPathRange* GrResourceProvider::createGlyphs(const SkTypeface* tf, const SkDesc
return this->gpu()->pathRendering()->createGlyphs(tf, desc, stroke);
}
+GrIndexBuffer* GrResourceProvider::getIndexBuffer(size_t size, bool dynamic,
+ bool calledDuringFlush) {
+ if (this->isAbandoned()) {
+ return NULL;
+ }
+
+ if (dynamic) {
+ // bin by pow2 with a reasonable min
+ static const uint32_t MIN_SIZE = 1 << 12;
+ size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size)));
+
+ GrScratchKey key;
+ GrIndexBuffer::ComputeScratchKey(size, dynamic, &key);
+ uint32_t scratchFlags = 0;
+ if (calledDuringFlush) {
+ scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
+ } else {
+ scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
+ }
+ GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, scratchFlags);
+ if (resource) {
+ return static_cast<GrIndexBuffer*>(resource);
+ }
+ }
+
+ return this->gpu()->createIndexBuffer(size, dynamic);
+}
+
+GrVertexBuffer* GrResourceProvider::getVertexBuffer(size_t size, bool dynamic,
+ bool calledDuringFlush) {
+ if (this->isAbandoned()) {
+ return NULL;
+ }
+
+ if (dynamic) {
+ // bin by pow2 with a reasonable min
+ static const uint32_t MIN_SIZE = 1 << 15;
+ size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size)));
+
+ GrScratchKey key;
+ GrVertexBuffer::ComputeScratchKey(size, dynamic, &key);
+ uint32_t scratchFlags = 0;
+ if (calledDuringFlush) {
+ scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
+ } else {
+ scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
+ }
+ GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, scratchFlags);
+ if (resource) {
+ return static_cast<GrVertexBuffer*>(resource);
+ }
+ }
+
+ return this->gpu()->createVertexBuffer(size, dynamic);
+}
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 2962ad3788..f0b79b97f5 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -86,6 +86,9 @@ public:
using GrTextureProvider::findAndRefResourceByUniqueKey;
using GrTextureProvider::abandon;
+ GrIndexBuffer* getIndexBuffer(size_t size, bool dynamic, bool calledDuringFlush);
+ GrVertexBuffer* getVertexBuffer(size_t size, bool dynamic, bool calledDuringFlush);
+
private:
const GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
int patternSize,
diff --git a/src/gpu/GrVertexBuffer.h b/src/gpu/GrVertexBuffer.h
index 3f2ada2a2c..3c12cd76d2 100644
--- a/src/gpu/GrVertexBuffer.h
+++ b/src/gpu/GrVertexBuffer.h
@@ -14,9 +14,24 @@
#include "GrGeometryBuffer.h"
class GrVertexBuffer : public GrGeometryBuffer {
+public:
+ static void ComputeScratchKey(size_t size, bool dynamic, GrScratchKey* key) {
+ static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
+
+ GrScratchKey::Builder builder(key, kType, 2);
+
+ builder[0] = SkToUInt(size);
+ builder[1] = dynamic ? 1 : 0;
+ }
+
protected:
GrVertexBuffer(GrGpu* gpu, size_t gpuMemorySize, bool dynamic, bool cpuBacked)
- : INHERITED(gpu, gpuMemorySize, dynamic, cpuBacked) {}
+ : INHERITED(gpu, gpuMemorySize, dynamic, cpuBacked) {
+ GrScratchKey key;
+ ComputeScratchKey(gpuMemorySize, dynamic, &key);
+ this->setScratchKey(key);
+ }
+
private:
typedef GrGeometryBuffer INHERITED;
};
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index b23619d8b6..0c53006bd2 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -414,6 +414,11 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
kQualcomm_GrGLVendor != ctxInfo.vendor();
+#if 0
+ fReuseScratchBuffers = kARM_GrGLVendor != ctxInfo.vendor() &&
+ kQualcomm_GrGLVendor != ctxInfo.vendor();
+#endif
+
if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxSampleCount);
} else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {