aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2016-03-25 04:55:58 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-25 04:55:59 -0700
commitf8c3ba40cf4f42b2c2ba1b473c28d7733383223e (patch)
tree00c671765311aaa35c8a9d6fa0a6b84907c871b9 /src
parentf299e7105435829c47e94f4cf6e408cad675bc77 (diff)
Revert of Consolidate GPU buffer implementations (patchset #10 id:180001 of https://codereview.chromium.org/1825393002/ )
Reason for revert: Lots of Android redness Original issue's description: > Consolidate GPU buffer implementations > > Consolidates all the different buffer implementations into a single > GrBuffer class. This will allow us to add new buffer types, use DSA in > OpenGL, track buffer bindings by unique ID, cache buffers without > respect to the type of data they have been used for previously, etc. > This change is strictly a refactor; it introduces no change in > functionality. > > BUG=skia: > GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1825393002 > > Committed: https://skia.googlesource.com/skia/+/8b1bff29675afd25843439eade634a57f68fe16f TBR=bsalomon@google.com,egdaniel@google.com,jvanverth@google.com,cdalton@nvidia.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/1831133004
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrBatchAtlas.cpp1
-rw-r--r--src/gpu/GrBatchFlushState.cpp4
-rw-r--r--src/gpu/GrBatchFlushState.h8
-rw-r--r--src/gpu/GrBuffer.h145
-rw-r--r--src/gpu/GrBufferAllocPool.cpp45
-rw-r--r--src/gpu/GrBufferAllocPool.h35
-rw-r--r--src/gpu/GrCaps.cpp2
-rw-r--r--src/gpu/GrDrawTarget.cpp1
-rw-r--r--src/gpu/GrDrawTarget.h3
-rw-r--r--src/gpu/GrGeometryBuffer.h124
-rw-r--r--src/gpu/GrGpu.cpp33
-rw-r--r--src/gpu/GrGpu.h68
-rw-r--r--src/gpu/GrIndexBuffer.h51
-rw-r--r--src/gpu/GrMesh.h22
-rw-r--r--src/gpu/GrOvalRenderer.cpp8
-rw-r--r--src/gpu/GrResourceProvider.cpp74
-rw-r--r--src/gpu/GrResourceProvider.h49
-rw-r--r--src/gpu/GrSoftwarePathRenderer.cpp1
-rw-r--r--src/gpu/GrTest.cpp10
-rwxr-xr-xsrc/gpu/GrTransferBuffer.h76
-rw-r--r--src/gpu/GrVertexBuffer.h42
-rw-r--r--src/gpu/batches/GrAAConvexPathRenderer.cpp8
-rw-r--r--src/gpu/batches/GrAADistanceFieldPathRenderer.cpp11
-rw-r--r--src/gpu/batches/GrAAFillRectBatch.cpp4
-rw-r--r--src/gpu/batches/GrAAHairLinePathRenderer.cpp15
-rw-r--r--src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp4
-rw-r--r--src/gpu/batches/GrAAStrokeRectBatch.cpp9
-rw-r--r--src/gpu/batches/GrAtlasTextBatch.cpp5
-rw-r--r--src/gpu/batches/GrAtlasTextBatch.h4
-rw-r--r--src/gpu/batches/GrDefaultPathRenderer.cpp4
-rw-r--r--src/gpu/batches/GrDrawVerticesBatch.cpp4
-rw-r--r--src/gpu/batches/GrNinePatch.cpp2
-rw-r--r--src/gpu/batches/GrNonAAFillRectBatch.cpp2
-rw-r--r--src/gpu/batches/GrNonAAStrokeRectBatch.cpp2
-rw-r--r--src/gpu/batches/GrPLSPathRenderer.cpp6
-rw-r--r--src/gpu/batches/GrTInstanceBatch.h4
-rw-r--r--src/gpu/batches/GrTessellatingPathRenderer.cpp15
-rw-r--r--src/gpu/batches/GrTestBatch.h1
-rw-r--r--src/gpu/batches/GrVertexBatch.cpp6
-rw-r--r--src/gpu/batches/GrVertexBatch.h2
-rw-r--r--src/gpu/effects/GrDashingEffect.cpp1
-rw-r--r--src/gpu/gl/GrGLBuffer.cpp336
-rw-r--r--src/gpu/gl/GrGLBuffer.h61
-rw-r--r--src/gpu/gl/GrGLBufferImpl.cpp122
-rw-r--r--src/gpu/gl/GrGLBufferImpl.h69
-rw-r--r--src/gpu/gl/GrGLCaps.cpp6
-rw-r--r--src/gpu/gl/GrGLDefines.h2
-rw-r--r--src/gpu/gl/GrGLGpu.cpp241
-rw-r--r--src/gpu/gl/GrGLGpu.h23
-rw-r--r--src/gpu/gl/GrGLIndexBuffer.cpp60
-rw-r--r--src/gpu/gl/GrGLIndexBuffer.h48
-rwxr-xr-xsrc/gpu/gl/GrGLTransferBuffer.cpp51
-rwxr-xr-xsrc/gpu/gl/GrGLTransferBuffer.h48
-rw-r--r--src/gpu/gl/GrGLVertexArray.h2
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.cpp60
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.h48
-rw-r--r--src/gpu/vk/GrVkCaps.cpp4
-rw-r--r--src/gpu/vk/GrVkGpu.cpp37
-rw-r--r--src/gpu/vk/GrVkGpu.h6
-rw-r--r--src/gpu/vk/GrVkIndexBuffer.cpp9
-rw-r--r--src/gpu/vk/GrVkIndexBuffer.h8
-rw-r--r--src/gpu/vk/GrVkTransferBuffer.cpp4
-rw-r--r--src/gpu/vk/GrVkTransferBuffer.h17
-rw-r--r--src/gpu/vk/GrVkVertexBuffer.cpp9
-rw-r--r--src/gpu/vk/GrVkVertexBuffer.h8
65 files changed, 1400 insertions, 790 deletions
diff --git a/src/gpu/GrBatchAtlas.cpp b/src/gpu/GrBatchAtlas.cpp
index 9f3c4dd983..db1b13471f 100644
--- a/src/gpu/GrBatchAtlas.cpp
+++ b/src/gpu/GrBatchAtlas.cpp
@@ -9,6 +9,7 @@
#include "GrBatchFlushState.h"
#include "GrRectanizer.h"
#include "GrTracing.h"
+#include "GrVertexBuffer.h"
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrBatchFlushState.cpp b/src/gpu/GrBatchFlushState.cpp
index f01d88852e..52261a1839 100644
--- a/src/gpu/GrBatchFlushState.cpp
+++ b/src/gpu/GrBatchFlushState.cpp
@@ -20,11 +20,11 @@ GrBatchFlushState::GrBatchFlushState(GrGpu* gpu, GrResourceProvider* resourcePro
, fLastFlushedToken(0) {}
void* GrBatchFlushState::makeVertexSpace(size_t vertexSize, int vertexCount,
- const GrBuffer** buffer, int* startVertex) {
+ const GrVertexBuffer** buffer, int* startVertex) {
return fVertexPool.makeSpace(vertexSize, vertexCount, buffer, startVertex);
}
uint16_t* GrBatchFlushState::makeIndexSpace(int indexCount,
- const GrBuffer** buffer, int* startIndex) {
+ const GrIndexBuffer** buffer, int* startIndex) {
return reinterpret_cast<uint16_t*>(fIndexPool.makeSpace(indexCount, buffer, startIndex));
}
diff --git a/src/gpu/GrBatchFlushState.h b/src/gpu/GrBatchFlushState.h
index be9d790597..1f82453c2e 100644
--- a/src/gpu/GrBatchFlushState.h
+++ b/src/gpu/GrBatchFlushState.h
@@ -76,8 +76,8 @@ public:
GrBatchToken asapToken() const { return fLastFlushedToken + 1; }
void* makeVertexSpace(size_t vertexSize, int vertexCount,
- const GrBuffer** buffer, int* startVertex);
- uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* startIndex);
+ const GrVertexBuffer** buffer, int* startVertex);
+ uint16_t* makeIndexSpace(int indexCount, const GrIndexBuffer** buffer, int* startIndex);
/** This is called after each batch has a chance to prepare its draws and before the draws
are issued. */
@@ -172,11 +172,11 @@ public:
}
void* makeVertexSpace(size_t vertexSize, int vertexCount,
- const GrBuffer** buffer, int* startVertex) {
+ const GrVertexBuffer** buffer, int* startVertex) {
return this->state()->makeVertexSpace(vertexSize, vertexCount, buffer, startVertex);
}
- uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* startIndex) {
+ uint16_t* makeIndexSpace(int indexCount, const GrIndexBuffer** buffer, int* startIndex) {
return this->state()->makeIndexSpace(indexCount, buffer, startIndex);
}
diff --git a/src/gpu/GrBuffer.h b/src/gpu/GrBuffer.h
deleted file mode 100644
index 4fadba6aa7..0000000000
--- a/src/gpu/GrBuffer.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrBuffer_DEFINED
-#define GrBuffer_DEFINED
-
-#include "GrGpuResource.h"
-
-class GrGpu;
-
-class GrBuffer : public GrGpuResource {
-public:
- /**
- * Computes a scratch key for a buffer with a "dynamic" access pattern. (Buffers with "static"
- * and "stream" access patterns are disqualified by nature from being cached and reused.)
- */
- static void ComputeScratchKeyForDynamicBuffer(GrBufferType type, size_t size,
- GrScratchKey* key) {
- static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();
- GrScratchKey::Builder builder(key, kType, 1 + (sizeof(size_t) + 3) / 4);
- // TODO: There's not always reason to cache a buffer by type. In some (all?) APIs it's just
- // a chunk of memory we can use/reuse for any type of data. We really only need to
- // differentiate between the "read" types (e.g. kGpuToCpu_BufferType) and "draw" types.
- builder[0] = type;
- builder[1] = (uint32_t)size;
- if (sizeof(size_t) > 4) {
- builder[2] = (uint32_t)((uint64_t)size >> 32);
- }
- }
-
- GrBufferType type() const { return fType; }
-
- GrAccessPattern accessPattern() const { return fAccessPattern; }
-
- /**
- * Returns true if the buffer is a wrapper around a CPU array. If true it
- * indicates that map will always succeed and will be free.
- */
- bool isCPUBacked() const { return fCPUBacked; }
-
- /**
- * Maps the buffer to be written by the CPU.
- *
- * The previous content of the buffer is invalidated. It is an error
- * to draw from the buffer while it is mapped. It may fail if the backend
- * doesn't support mapping the buffer. If the buffer is CPU backed then
- * it will always succeed and is a free operation. Once a buffer is mapped,
- * subsequent calls to map() are ignored.
- *
- * Note that buffer mapping does not go through GrContext and therefore is
- * not serialized with other operations.
- *
- * @return a pointer to the data or nullptr if the map fails.
- */
- void* map() {
- if (!fMapPtr) {
- this->onMap();
- }
- return fMapPtr;
- }
-
- /**
- * Unmaps the buffer.
- *
- * The pointer returned by the previous map call will no longer be valid.
- */
- void unmap() {
- SkASSERT(fMapPtr);
- this->onUnmap();
- fMapPtr = nullptr;
- }
-
- /**
- * Returns the same ptr that map() returned at time of map or nullptr if the
- * is not mapped.
- *
- * @return ptr to mapped buffer data or nullptr if buffer is not mapped.
- */
- void* mapPtr() const { return fMapPtr; }
-
- /**
- Queries whether the buffer has been mapped.
-
- @return true if the buffer is mapped, false otherwise.
- */
- bool isMapped() const { return SkToBool(fMapPtr); }
-
- /**
- * Updates the buffer data.
- *
- * The size of the buffer will be preserved. The src data will be
- * placed at the beginning of the buffer and any remaining contents will
- * be undefined. srcSizeInBytes must be <= to the buffer size.
- *
- * The buffer must not be mapped.
- *
- * Note that buffer updates do not go through GrContext and therefore are
- * not serialized with other operations.
- *
- * @return returns true if the update succeeds, false otherwise.
- */
- bool updateData(const void* src, size_t srcSizeInBytes) {
- SkASSERT(!this->isMapped());
- SkASSERT(srcSizeInBytes <= fGpuMemorySize);
- return this->onUpdateData(src, srcSizeInBytes);
- }
-
-protected:
- GrBuffer(GrGpu* gpu, GrBufferType type, size_t gpuMemorySize, GrAccessPattern accessPattern,
- bool cpuBacked)
- : INHERITED(gpu, kCached_LifeCycle),
- fMapPtr(nullptr),
- fType(type),
- fGpuMemorySize(gpuMemorySize), // TODO: Zero for cpu backed buffers?
- fAccessPattern(accessPattern),
- fCPUBacked(cpuBacked) {
- if (!fCPUBacked && SkIsPow2(fGpuMemorySize) && kDynamic_GrAccessPattern == fAccessPattern) {
- GrScratchKey key;
- ComputeScratchKeyForDynamicBuffer(fType, fGpuMemorySize, &key);
- this->setScratchKey(key);
- }
- }
-
- void* fMapPtr;
-
-private:
- virtual size_t onGpuMemorySize() const { return fGpuMemorySize; }
-
- virtual void onMap() = 0;
- virtual void onUnmap() = 0;
- virtual bool onUpdateData(const void* src, size_t srcSizeInBytes) = 0;
-
- GrBufferType fType;
- size_t fGpuMemorySize;
- GrAccessPattern fAccessPattern;
- bool fCPUBacked;
-
- typedef GrGpuResource INHERITED;
-};
-
-#endif
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index ac34b5cfcc..73b70bf861 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -8,12 +8,13 @@
#include "GrBufferAllocPool.h"
-#include "GrBuffer.h"
#include "GrCaps.h"
#include "GrContext.h"
#include "GrGpu.h"
+#include "GrIndexBuffer.h"
#include "GrResourceProvider.h"
#include "GrTypes.h"
+#include "GrVertexBuffer.h"
#include "SkTraceEvent.h"
@@ -40,7 +41,7 @@ do {
} while (false)
GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
- GrBufferType bufferType,
+ BufferType bufferType,
size_t blockSize)
: fBlocks(8) {
@@ -52,12 +53,12 @@ GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
fBytesInUse = 0;
- fBufferMapThreshold = gpu->caps()->bufferMapThreshold();
+ fGeometryBufferMapThreshold = gpu->caps()->geometryBufferMapThreshold();
}
void GrBufferAllocPool::deleteBlocks() {
if (fBlocks.count()) {
- GrBuffer* buffer = fBlocks.back().fBuffer;
+ GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
if (buffer->isMapped()) {
UNMAP_BUFFER(fBlocks.back());
}
@@ -108,7 +109,7 @@ void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
if (fBufferPtr) {
SkASSERT(!fBlocks.empty());
if (fBlocks.back().fBuffer->isMapped()) {
- GrBuffer* buf = fBlocks.back().fBuffer;
+ GrGeometryBuffer* buf = fBlocks.back().fBuffer;
SkASSERT(buf->mapPtr() == fBufferPtr);
} else {
SkASSERT(fCpuData == fBufferPtr);
@@ -144,7 +145,7 @@ void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
void* GrBufferAllocPool::makeSpace(size_t size,
size_t alignment,
- const GrBuffer** buffer,
+ const GrGeometryBuffer** buffer,
size_t* offset) {
VALIDATE();
@@ -251,7 +252,7 @@ bool GrBufferAllocPool::createBlock(size_t requestSize) {
// threshold.
bool attemptMap = block.fBuffer->isCPUBacked();
if (!attemptMap && GrCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags()) {
- attemptMap = size > fBufferMapThreshold;
+ attemptMap = size > fGeometryBufferMapThreshold;
}
if (attemptMap) {
@@ -294,7 +295,7 @@ void* GrBufferAllocPool::resetCpuData(size_t newSize) {
void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize) {
- GrBuffer* buffer = block.fBuffer;
+ GrGeometryBuffer* buffer = block.fBuffer;
SkASSERT(buffer);
SkASSERT(!buffer->isMapped());
SkASSERT(fCpuData == fBufferPtr);
@@ -302,7 +303,7 @@ void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize)
VALIDATE(true);
if (GrCaps::kNone_MapFlags != fGpu->caps()->mapBufferFlags() &&
- flushSize > fBufferMapThreshold) {
+ flushSize > fGeometryBufferMapThreshold) {
void* data = buffer->map();
if (data) {
memcpy(data, fBufferPtr, flushSize);
@@ -314,24 +315,30 @@ void GrBufferAllocPool::flushCpuData(const BufferBlock& block, size_t flushSize)
VALIDATE(true);
}
-GrBuffer* GrBufferAllocPool::getBuffer(size_t size) {
+GrGeometryBuffer* GrBufferAllocPool::getBuffer(size_t size) {
GrResourceProvider* rp = fGpu->getContext()->resourceProvider();
+ static const GrResourceProvider::BufferUsage kUsage = GrResourceProvider::kDynamic_BufferUsage;
// Shouldn't have to use this flag (https://bug.skia.org/4156)
static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag;
- return rp->createBuffer(fBufferType, size, kDynamic_GrAccessPattern, kFlags);
+ if (kIndex_BufferType == fBufferType) {
+ return rp->createIndexBuffer(size, kUsage, kFlags);
+ } else {
+ SkASSERT(kVertex_BufferType == fBufferType);
+ return rp->createVertexBuffer(size, kUsage, kFlags);
+ }
}
////////////////////////////////////////////////////////////////////////////////
GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu)
- : GrBufferAllocPool(gpu, kVertex_GrBufferType, MIN_VERTEX_BUFFER_SIZE) {
+ : GrBufferAllocPool(gpu, kVertex_BufferType, MIN_VERTEX_BUFFER_SIZE) {
}
void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
int vertexCount,
- const GrBuffer** buffer,
+ const GrVertexBuffer** buffer,
int* startVertex) {
SkASSERT(vertexCount >= 0);
@@ -339,11 +346,13 @@ void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
SkASSERT(startVertex);
size_t offset = 0; // assign to suppress warning
+ const GrGeometryBuffer* geomBuffer = nullptr; // assign to suppress warning
void* ptr = INHERITED::makeSpace(vertexSize * vertexCount,
vertexSize,
- buffer,
+ &geomBuffer,
&offset);
+ *buffer = (const GrVertexBuffer*) geomBuffer;
SkASSERT(0 == offset % vertexSize);
*startVertex = static_cast<int>(offset / vertexSize);
return ptr;
@@ -352,11 +361,11 @@ void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize,
////////////////////////////////////////////////////////////////////////////////
GrIndexBufferAllocPool::GrIndexBufferAllocPool(GrGpu* gpu)
- : GrBufferAllocPool(gpu, kIndex_GrBufferType, MIN_INDEX_BUFFER_SIZE) {
+ : GrBufferAllocPool(gpu, kIndex_BufferType, MIN_INDEX_BUFFER_SIZE) {
}
void* GrIndexBufferAllocPool::makeSpace(int indexCount,
- const GrBuffer** buffer,
+ const GrIndexBuffer** buffer,
int* startIndex) {
SkASSERT(indexCount >= 0);
@@ -364,11 +373,13 @@ void* GrIndexBufferAllocPool::makeSpace(int indexCount,
SkASSERT(startIndex);
size_t offset = 0; // assign to suppress warning
+ const GrGeometryBuffer* geomBuffer = nullptr; // assign to suppress warning
void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t),
sizeof(uint16_t),
- buffer,
+ &geomBuffer,
&offset);
+ *buffer = (const GrIndexBuffer*) geomBuffer;
SkASSERT(0 == offset % sizeof(uint16_t));
*startIndex = static_cast<int>(offset / sizeof(uint16_t));
return ptr;
diff --git a/src/gpu/GrBufferAllocPool.h b/src/gpu/GrBufferAllocPool.h
index 071b00b064..a3d8e45364 100644
--- a/src/gpu/GrBufferAllocPool.h
+++ b/src/gpu/GrBufferAllocPool.h
@@ -11,9 +11,8 @@
#include "SkTArray.h"
#include "SkTDArray.h"
#include "SkTypes.h"
-#include "GrTypesPriv.h"
-class GrBuffer;
+class GrGeometryBuffer;
class GrGpu;
/**
@@ -48,6 +47,16 @@ public:
protected:
/**
+ * Used to determine what type of buffers to create. We could make the
+ * createBuffer a virtual except that we want to use it in the cons for
+ * pre-allocated buffers.
+ */
+ enum BufferType {
+ kVertex_BufferType,
+ kIndex_BufferType,
+ };
+
+ /**
* Constructor
*
* @param gpu The GrGpu used to create the buffers.
@@ -57,7 +66,7 @@ protected:
* reasonable minimum.
*/
GrBufferAllocPool(GrGpu* gpu,
- GrBufferType bufferType,
+ BufferType bufferType,
size_t bufferSize = 0);
virtual ~GrBufferAllocPool();
@@ -83,15 +92,15 @@ protected:
*/
void* makeSpace(size_t size,
size_t alignment,
- const GrBuffer** buffer,
+ const GrGeometryBuffer** buffer,
size_t* offset);
- GrBuffer* getBuffer(size_t size);
+ GrGeometryBuffer* getBuffer(size_t size);
private:
struct BufferBlock {
- size_t fBytesFree;
- GrBuffer* fBuffer;
+ size_t fBytesFree;
+ GrGeometryBuffer* fBuffer;
};
bool createBlock(size_t requestSize);
@@ -106,14 +115,16 @@ private:
GrGpu* fGpu;
size_t fMinBlockSize;
- GrBufferType fBufferType;
+ BufferType fBufferType;
SkTArray<BufferBlock> fBlocks;
void* fCpuData;
void* fBufferPtr;
- size_t fBufferMapThreshold;
+ size_t fGeometryBufferMapThreshold;
};
+class GrVertexBuffer;
+
/**
* A GrBufferAllocPool of vertex buffers
*/
@@ -149,13 +160,15 @@ public:
*/
void* makeSpace(size_t vertexSize,
int vertexCount,
- const GrBuffer** buffer,
+ const GrVertexBuffer** buffer,
int* startVertex);
private:
typedef GrBufferAllocPool INHERITED;
};
+class GrIndexBuffer;
+
/**
* A GrBufferAllocPool of index buffers
*/
@@ -187,7 +200,7 @@ public:
* @return pointer to first index.
*/
void* makeSpace(int indexCount,
- const GrBuffer** buffer,
+ const GrIndexBuffer** buffer,
int* startIndex);
private:
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 857e789808..784e401328 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -116,7 +116,7 @@ GrCaps::GrCaps(const GrContextOptions& options) {
fSuppressPrints = options.fSuppressPrints;
fImmediateFlush = options.fImmediateMode;
fDrawPathMasksToCompressedTextureSupport = options.fDrawPathToCompressedTexture;
- fBufferMapThreshold = options.fBufferMapThreshold;
+ fGeometryBufferMapThreshold = options.fGeometryBufferMapThreshold;
fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite;
fUseDrawInsteadOfAllRenderTargetWrites = false;
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 39c1e32d07..08938ec0af 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -19,6 +19,7 @@
#include "GrRenderTargetPriv.h"
#include "GrSurfacePriv.h"
#include "GrTexture.h"
+#include "GrVertexBuffer.h"
#include "gl/GrGLRenderTarget.h"
#include "SkStrokeRec.h"
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index c863b455b3..9a6dbc9e71 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -13,8 +13,11 @@
#include "GrContext.h"
#include "GrPathProcessor.h"
#include "GrPrimitiveProcessor.h"
+#include "GrIndexBuffer.h"
#include "GrPathRendering.h"
#include "GrPipelineBuilder.h"
+#include "GrPipeline.h"
+#include "GrVertexBuffer.h"
#include "GrXferProcessor.h"
#include "batches/GrDrawBatch.h"
diff --git a/src/gpu/GrGeometryBuffer.h b/src/gpu/GrGeometryBuffer.h
new file mode 100644
index 0000000000..56a6cae3fb
--- /dev/null
+++ b/src/gpu/GrGeometryBuffer.h
@@ -0,0 +1,124 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrGeometryBuffer_DEFINED
+#define GrGeometryBuffer_DEFINED
+
+#include "GrGpuResource.h"
+
+class GrGpu;
+
+/**
+ * Parent class for vertex and index buffers
+ */
+class GrGeometryBuffer : public GrGpuResource {
+public:
+
+
+ /**
+ *Retrieves whether the buffer was created with the dynamic flag
+ *
+ * @return true if the buffer was created with the dynamic flag
+ */
+ bool dynamic() const { return fDynamic; }
+
+ /**
+ * Returns true if the buffer is a wrapper around a CPU array. If true it
+ * indicates that map will always succeed and will be free.
+ */
+ bool isCPUBacked() const { return fCPUBacked; }
+
+ /**
+ * Maps the buffer to be written by the CPU.
+ *
+ * The previous content of the buffer is invalidated. It is an error
+ * to draw from the buffer while it is mapped. It is an error to call map
+ * on an already mapped buffer. It may fail if the backend doesn't support
+ * mapping the buffer. If the buffer is CPU backed then it will always
+ * succeed and is a free operation. Must be matched by an unmap() call.
+ * Currently only one map at a time is supported (no nesting of
+ * map/unmap).
+ *
+ * Note that buffer mapping does not go through GrContext and therefore is
+ * not serialized with other operations.
+ *
+ * @return a pointer to the data or nullptr if the map fails.
+ */
+ void* map() { return (fMapPtr = this->onMap()); }
+
+ /**
+ * Unmaps the buffer.
+ *
+ * The pointer returned by the previous map call will no longer be valid.
+ */
+ void unmap() {
+ SkASSERT(fMapPtr);
+ this->onUnmap();
+ fMapPtr = nullptr;
+ }
+
+ /**
+ * Returns the same ptr that map() returned at time of map or nullptr if the
+ * is not mapped.
+ *
+ * @return ptr to mapped buffer data or nullptr if buffer is not mapped.
+ */
+ void* mapPtr() const { return fMapPtr; }
+
+ /**
+ Queries whether the buffer has been mapped.
+
+ @return true if the buffer is mapped, false otherwise.
+ */
+ bool isMapped() const { return SkToBool(fMapPtr); }
+
+ /**
+ * Updates the buffer data.
+ *
+ * The size of the buffer will be preserved. The src data will be
+ * placed at the beginning of the buffer and any remaining contents will
+ * be undefined. srcSizeInBytes must be <= to the buffer size.
+ *
+ * The buffer must not be mapped.
+ *
+ * Note that buffer updates do not go through GrContext and therefore are
+ * not serialized with other operations.
+ *
+ * @return returns true if the update succeeds, false otherwise.
+ */
+ bool updateData(const void* src, size_t srcSizeInBytes) {
+ SkASSERT(!this->isMapped());
+ SkASSERT(srcSizeInBytes <= fGpuMemorySize);
+ return this->onUpdateData(src, srcSizeInBytes);
+ }
+
+protected:
+ GrGeometryBuffer(GrGpu* gpu, size_t gpuMemorySize, bool dynamic, bool cpuBacked)
+ : INHERITED(gpu, kCached_LifeCycle)
+ , fMapPtr(nullptr)
+ , fGpuMemorySize(gpuMemorySize)
+ , fDynamic(dynamic)
+ , fCPUBacked(cpuBacked) {}
+
+private:
+ virtual size_t onGpuMemorySize() const { return fGpuMemorySize; }
+
+ virtual void* onMap() = 0;
+ virtual void onUnmap() = 0;
+ virtual bool onUpdateData(const void* src, size_t srcSizeInBytes) = 0;
+
+ void* fMapPtr;
+ size_t fGpuMemorySize;
+ bool fDynamic;
+ bool fCPUBacked;
+
+ typedef GrGpuResource INHERITED;
+};
+
+#endif
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 35c04caa23..177fbabc59 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -8,10 +8,10 @@
#include "GrGpu.h"
-#include "GrBuffer.h"
#include "GrCaps.h"
#include "GrContext.h"
#include "GrGpuResourcePriv.h"
+#include "GrIndexBuffer.h"
#include "GrMesh.h"
#include "GrPathRendering.h"
#include "GrPipeline.h"
@@ -20,6 +20,8 @@
#include "GrRenderTargetPriv.h"
#include "GrStencilAttachment.h"
#include "GrSurfacePriv.h"
+#include "GrTransferBuffer.h"
+#include "GrVertexBuffer.h"
#include "SkTypes.h"
GrMesh& GrMesh::operator =(const GrMesh& di) {
@@ -236,13 +238,28 @@ GrRenderTarget* GrGpu::wrapBackendTextureAsRenderTarget(const GrBackendTextureDe
return this->onWrapBackendTextureAsRenderTarget(desc, ownership);
}
-GrBuffer* GrGpu::createBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) {
+GrVertexBuffer* GrGpu::createVertexBuffer(size_t size, bool dynamic) {
this->handleDirtyContext();
- GrBuffer* buffer = this->onCreateBuffer(type, size, accessPattern);
+ GrVertexBuffer* vb = this->onCreateVertexBuffer(size, dynamic);
if (!this->caps()->reuseScratchBuffers()) {
- buffer->resourcePriv().removeScratchKey();
+ vb->resourcePriv().removeScratchKey();
}
- return buffer;
+ return vb;
+}
+
+GrIndexBuffer* GrGpu::createIndexBuffer(size_t size, bool dynamic) {
+ this->handleDirtyContext();
+ GrIndexBuffer* ib = this->onCreateIndexBuffer(size, dynamic);
+ if (!this->caps()->reuseScratchBuffers()) {
+ ib->resourcePriv().removeScratchKey();
+ }
+ return ib;
+}
+
+GrTransferBuffer* GrGpu::createTransferBuffer(size_t size, TransferType type) {
+ this->handleDirtyContext();
+ GrTransferBuffer* tb = this->onCreateTransferBuffer(size, type);
+ return tb;
}
void GrGpu::clear(const SkIRect& rect,
@@ -399,13 +416,13 @@ bool GrGpu::writePixels(GrSurface* surface,
bool GrGpu::transferPixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes) {
- SkASSERT(transferBuffer);
+ SkASSERT(buffer);
this->handleDirtyContext();
if (this->onTransferPixels(surface, left, top, width, height, config,
- transferBuffer, offset, rowBytes)) {
+ buffer, offset, rowBytes)) {
fStats.incTransfersToTexture();
return true;
}
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index a49b2c28fd..4e9b247ca3 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -20,9 +20,9 @@
#include "SkTArray.h"
class GrBatchTracker;
-class GrBuffer;
class GrContext;
class GrGLContext;
+class GrIndexBuffer;
class GrMesh;
class GrNonInstancedVertices;
class GrPath;
@@ -36,6 +36,8 @@ class GrRenderTarget;
class GrStencilAttachment;
class GrSurface;
class GrTexture;
+class GrTransferBuffer;
+class GrVertexBuffer;
class GrGpu : public SkRefCnt {
public:
@@ -127,11 +129,39 @@ public:
GrRenderTarget* wrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&, GrWrapOwnership);
/**
- * Creates a buffer.
+ * Creates a vertex buffer.
*
- * @return the buffer if successful, otherwise nullptr.
+ * @param size size in bytes of the vertex buffer
+ * @param dynamic hints whether the data will be frequently changed
+ * by either GrVertexBuffer::map() or
+ * GrVertexBuffer::updateData().
+ *
+ * @return The vertex buffer if successful, otherwise nullptr.
+ */
+ GrVertexBuffer* createVertexBuffer(size_t size, bool dynamic);
+
+ /**
+ * Creates an index buffer.
+ *
+ * @param size size in bytes of the index buffer
+ * @param dynamic hints whether the data will be frequently changed
+ * by either GrIndexBuffer::map() or
+ * GrIndexBuffer::updateData().
+ *
+ * @return The index buffer if successful, otherwise nullptr.
+ */
+ GrIndexBuffer* createIndexBuffer(size_t size, bool dynamic);
+
+ /**
+ * Creates a transfer buffer.
+ *
+ * @param size size in bytes of the index buffer
+ * @param toGpu true if used to transfer from the cpu to the gpu
+ * otherwise to be used to transfer from the gpu to the cpu
+ *
+ * @return The transfer buffer if successful, otherwise nullptr.
*/
- GrBuffer* createBuffer(GrBufferType, size_t size, GrAccessPattern);
+ GrTransferBuffer* createTransferBuffer(size_t size, TransferType type);
/**
* Resolves MSAA.
@@ -268,22 +298,22 @@ public:
size_t rowBytes);
/**
- * Updates the pixels in a rectangle of a surface using a buffer
+ * Updates the pixels in a rectangle of a surface using a GrTransferBuffer
*
- * @param surface The surface to write to.
- * @param left left edge of the rectangle to write (inclusive)
- * @param top top edge of the rectangle to write (inclusive)
- * @param width width of rectangle to write in pixels.
- * @param height height of rectangle to write in pixels.
- * @param config the pixel config of the source buffer
- * @param transferBuffer GrBuffer to read pixels from (type must be "kCpuToGpu")
- * @param offset offset from the start of the buffer
- * @param rowBytes number of bytes between consecutive rows. Zero
- * means rows are tightly packed.
+ * @param surface The surface to write to.
+ * @param left left edge of the rectangle to write (inclusive)
+ * @param top top edge of the rectangle to write (inclusive)
+ * @param width width of rectangle to write in pixels.
+ * @param height height of rectangle to write in pixels.
+ * @param config the pixel config of the source buffer
+ * @param buffer GrTransferBuffer to read pixels from
+ * @param offset offset from the start of the buffer
+ * @param rowBytes number of bytes between consecutive rows. Zero
+ * means rows are tightly packed.
*/
bool transferPixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes);
/**
@@ -528,7 +558,9 @@ private:
GrWrapOwnership) = 0;
virtual GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&,
GrWrapOwnership) = 0;
- virtual GrBuffer* onCreateBuffer(GrBufferType, size_t size, GrAccessPattern) = 0;
+ virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
+ virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0;
+ virtual GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) = 0;
// overridden by backend-specific derived class to perform the clear.
virtual void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) = 0;
@@ -570,7 +602,7 @@ private:
// overridden by backend-specific derived class to perform the surface write
virtual bool onTransferPixels(GrSurface*,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes) = 0;
// overridden by backend-specific derived class to perform the resolve
diff --git a/src/gpu/GrIndexBuffer.h b/src/gpu/GrIndexBuffer.h
new file mode 100644
index 0000000000..2e3b437adf
--- /dev/null
+++ b/src/gpu/GrIndexBuffer.h
@@ -0,0 +1,51 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrIndexBuffer_DEFINED
+#define GrIndexBuffer_DEFINED
+
+#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).
+ * @return the maximum number of quads using full size of index buffer.
+ */
+ int maxQuads() const {
+ return static_cast<int>(this->gpuMemorySize() / (sizeof(uint16_t) * 6));
+ }
+protected:
+ GrIndexBuffer(GrGpu* gpu, size_t gpuMemorySize, bool dynamic, bool cpuBacked)
+ : INHERITED(gpu, gpuMemorySize, dynamic, cpuBacked) {
+ // We currently only make buffers scratch if they're both pow2 sized and not cpuBacked.
+ if (!cpuBacked && SkIsPow2(gpuMemorySize)) {
+ GrScratchKey key;
+ ComputeScratchKey(gpuMemorySize, dynamic, &key);
+ this->setScratchKey(key);
+ }
+ }
+
+private:
+ typedef GrGeometryBuffer INHERITED;
+};
+
+#endif
diff --git a/src/gpu/GrMesh.h b/src/gpu/GrMesh.h
index 964e0b4a8e..5ff23dcfd0 100644
--- a/src/gpu/GrMesh.h
+++ b/src/gpu/GrMesh.h
@@ -8,8 +8,8 @@
#ifndef GrMesh_DEFINED
#define GrMesh_DEFINED
-#include "GrBuffer.h"
-#include "GrGpuResourceRef.h"
+#include "GrIndexBuffer.h"
+#include "GrVertexBuffer.h"
class GrNonInstancedMesh {
public:
@@ -20,8 +20,8 @@ public:
int indexCount() const { return fIndexCount; }
bool isIndexed() const { return fIndexCount > 0; }
- const GrBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
- const GrBuffer* indexBuffer() const { return fIndexBuffer.get(); }
+ const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
+ const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
protected:
GrPrimitiveType fPrimitiveType;
@@ -29,8 +29,8 @@ protected:
int fStartIndex;
int fVertexCount;
int fIndexCount;
- GrPendingIOResource<const GrBuffer, kRead_GrIOType> fVertexBuffer;
- GrPendingIOResource<const GrBuffer, kRead_GrIOType> fIndexBuffer;
+ GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
+ GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType> fIndexBuffer;
friend class GrMesh;
};
@@ -46,7 +46,7 @@ public:
GrMesh(const GrMesh& di) { (*this) = di; }
GrMesh& operator =(const GrMesh& di);
- void init(GrPrimitiveType primType, const GrBuffer* vertexBuffer, int startVertex,
+ void init(GrPrimitiveType primType, const GrVertexBuffer* vertexBuffer, int startVertex,
int vertexCount) {
SkASSERT(vertexBuffer);
SkASSERT(vertexCount);
@@ -65,8 +65,8 @@ public:
}
void initIndexed(GrPrimitiveType primType,
- const GrBuffer* vertexBuffer,
- const GrBuffer* indexBuffer,
+ const GrVertexBuffer* vertexBuffer,
+ const GrIndexBuffer* indexBuffer,
int startVertex,
int startIndex,
int vertexCount,
@@ -95,8 +95,8 @@ public:
the number of instances supported by the index buffer. To be used with
nextInstances() to draw in max-sized batches.*/
void initInstanced(GrPrimitiveType primType,
- const GrBuffer* vertexBuffer,
- const GrBuffer* indexBuffer,
+ const GrVertexBuffer* vertexBuffer,
+ const GrIndexBuffer* indexBuffer,
int startVertex,
int verticesPerInstance,
int indicesPerInstance,
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 9388f323c8..d0be27d9b0 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -1211,8 +1211,8 @@ static const int kNumRRectsInIndexBuffer = 256;
GR_DECLARE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey);
GR_DECLARE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
-static const GrBuffer* ref_rrect_index_buffer(bool strokeOnly,
- GrResourceProvider* resourceProvider) {
+static const GrIndexBuffer* ref_rrect_index_buffer(bool strokeOnly,
+ GrResourceProvider* resourceProvider) {
GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey);
GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
if (strokeOnly) {
@@ -1286,7 +1286,7 @@ private:
// drop out the middle quad if we're stroked
int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerRRect;
- SkAutoTUnref<const GrBuffer> indexBuffer(
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
ref_rrect_index_buffer(fStroked, target->resourceProvider()));
InstancedHelper helper;
@@ -1434,7 +1434,7 @@ private:
// drop out the middle quad if we're stroked
int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerRRect;
- SkAutoTUnref<const GrBuffer> indexBuffer(
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
ref_rrect_index_buffer(fStroked, target->resourceProvider()));
InstancedHelper helper;
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index a73bf752b0..79146d0911 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -7,14 +7,15 @@
#include "GrResourceProvider.h"
-#include "GrBuffer.h"
#include "GrGpu.h"
+#include "GrIndexBuffer.h"
#include "GrPathRendering.h"
#include "GrRenderTarget.h"
#include "GrRenderTargetPriv.h"
#include "GrResourceCache.h"
#include "GrResourceKey.h"
#include "GrStencilAttachment.h"
+#include "GrVertexBuffer.h"
GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
@@ -24,16 +25,16 @@ GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSin
fQuadIndexBufferKey = gQuadIndexBufferKey;
}
-const GrBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern,
- int patternSize,
- int reps,
- int vertCount,
- const GrUniqueKey& key) {
+const GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern,
+ int patternSize,
+ int reps,
+ int vertCount,
+ const GrUniqueKey& key) {
size_t bufferSize = patternSize * reps * sizeof(uint16_t);
// This is typically used in GrBatchs, so we assume kNoPendingIO.
- GrBuffer* buffer = this->createBuffer(kIndex_GrBufferType, bufferSize, kStatic_GrAccessPattern,
- kNoPendingIO_Flag);
+ GrIndexBuffer* buffer = this->createIndexBuffer(bufferSize, kStatic_BufferUsage,
+ kNoPendingIO_Flag);
if (!buffer) {
return nullptr;
}
@@ -62,7 +63,7 @@ const GrBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* p
return buffer;
}
-const GrBuffer* GrResourceProvider::createQuadIndexBuffer() {
+const GrIndexBuffer* GrResourceProvider::createQuadIndexBuffer() {
static const int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 };
@@ -88,31 +89,72 @@ GrPathRange* GrResourceProvider::createGlyphs(const SkTypeface* tf, const SkDesc
return this->gpu()->pathRendering()->createGlyphs(tf, desc, stroke);
}
-GrBuffer* GrResourceProvider::createBuffer(GrBufferType type, size_t size,
- GrAccessPattern accessPattern, uint32_t flags) {
+GrIndexBuffer* GrResourceProvider::createIndexBuffer(size_t size, BufferUsage usage,
+ uint32_t flags) {
if (this->isAbandoned()) {
return nullptr;
}
- if (kDynamic_GrAccessPattern == accessPattern) {
+ bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag);
+ bool dynamic = kDynamic_BufferUsage == usage;
+ 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;
- GrBuffer::ComputeScratchKeyForDynamicBuffer(type, size, &key);
+ GrIndexBuffer::ComputeScratchKey(size, true, &key);
uint32_t scratchFlags = 0;
- if (flags & kNoPendingIO_Flag) {
+ if (noPendingIO) {
scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
} else {
scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
}
GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, size, scratchFlags);
if (resource) {
- return static_cast<GrBuffer*>(resource);
+ return static_cast<GrIndexBuffer*>(resource);
}
}
- return this->gpu()->createBuffer(type, size, accessPattern);
+ return this->gpu()->createIndexBuffer(size, dynamic);
+}
+
+GrVertexBuffer* GrResourceProvider::createVertexBuffer(size_t size, BufferUsage usage,
+ uint32_t flags) {
+ if (this->isAbandoned()) {
+ return nullptr;
+ }
+
+ bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag);
+ bool dynamic = kDynamic_BufferUsage == usage;
+ 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;
+ GrVertexBuffer::ComputeScratchKey(size, true, &key);
+ uint32_t scratchFlags = 0;
+ if (noPendingIO) {
+ scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
+ } else {
+ scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
+ }
+ GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, size, scratchFlags);
+ if (resource) {
+ return static_cast<GrVertexBuffer*>(resource);
+ }
+ }
+ return this->gpu()->createVertexBuffer(size, dynamic);
+}
+
+GrTransferBuffer* GrResourceProvider::createTransferBuffer(size_t size, TransferType type,
+ uint32_t flags) {
+ if (this->isAbandoned()) {
+ return nullptr;
+ }
+
+ //bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag);
+ return this->gpu()->createTransferBuffer(size, type);
}
GrBatchAtlas* GrResourceProvider::createAtlas(GrPixelConfig config,
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 7b51726d10..3dfc9ba863 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -9,16 +9,18 @@
#define GrResourceProvider_DEFINED
#include "GrBatchAtlas.h"
-#include "GrBuffer.h"
+#include "GrIndexBuffer.h"
#include "GrTextureProvider.h"
#include "GrPathRange.h"
class GrBatchAtlas;
+class GrIndexBuffer;
class GrPath;
class GrRenderTarget;
class GrSingleOwner;
class GrStencilAttachment;
class GrStrokeInfo;
+class GrVertexBuffer;
class SkDescriptor;
class SkPath;
class SkTypeface;
@@ -43,7 +45,7 @@ public:
/**
* Either finds and refs, or creates an index buffer for instanced drawing with a specific
* pattern if the index buffer is not found. If the return is non-null, the caller owns
- * a ref on the returned GrBuffer.
+ * a ref on the returned GrIndexBuffer.
*
* @param pattern the pattern of indices to repeat
* @param patternSize size in bytes of the pattern
@@ -53,12 +55,12 @@ public:
*
* @return The index buffer if successful, otherwise nullptr.
*/
- const GrBuffer* findOrCreateInstancedIndexBuffer(const uint16_t* pattern,
- int patternSize,
- int reps,
- int vertCount,
- const GrUniqueKey& key) {
- if (GrBuffer* buffer = this->findAndRefTByUniqueKey<GrBuffer>(key)) {
+ const GrIndexBuffer* findOrCreateInstancedIndexBuffer(const uint16_t* pattern,
+ int patternSize,
+ int reps,
+ int vertCount,
+ const GrUniqueKey& key) {
+ if (GrIndexBuffer* buffer = this->findAndRefTByUniqueKey<GrIndexBuffer>(key)) {
return buffer;
}
return this->createInstancedIndexBuffer(pattern, patternSize, reps, vertCount, key);
@@ -67,13 +69,13 @@ public:
/**
* Returns an index buffer that can be used to render quads.
* Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
- * The max number of quads is the buffer's index capacity divided by 6.
+ * The max number of quads can be queried using GrIndexBuffer::maxQuads().
* Draw with kTriangles_GrPrimitiveType
* @ return the quad index buffer
*/
- const GrBuffer* refQuadIndexBuffer() {
- if (GrBuffer* buffer =
- this->findAndRefTByUniqueKey<GrBuffer>(fQuadIndexBufferKey)) {
+ const GrIndexBuffer* refQuadIndexBuffer() {
+ if (GrIndexBuffer* buffer =
+ this->findAndRefTByUniqueKey<GrIndexBuffer>(fQuadIndexBufferKey)) {
return buffer;
}
return this->createQuadIndexBuffer();
@@ -102,7 +104,16 @@ public:
kNoPendingIO_Flag = kNoPendingIO_ScratchTextureFlag,
};
- GrBuffer* createBuffer(GrBufferType, size_t size, GrAccessPattern, uint32_t flags);
+ enum BufferUsage {
+ /** Caller intends to specify the buffer data rarely with respect to the number of draws
+ that read the data. */
+ kStatic_BufferUsage,
+ /** Caller intends to respecify the buffer data frequently between draws. */
+ kDynamic_BufferUsage,
+ };
+ GrIndexBuffer* createIndexBuffer(size_t size, BufferUsage, uint32_t flags);
+ GrVertexBuffer* createVertexBuffer(size_t size, BufferUsage, uint32_t flags);
+ GrTransferBuffer* createTransferBuffer(size_t size, TransferType, uint32_t flags);
GrTexture* createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) {
SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
@@ -146,13 +157,13 @@ public:
GrWrapOwnership = kBorrow_GrWrapOwnership);
private:
- const GrBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
- int patternSize,
- int reps,
- int vertCount,
- const GrUniqueKey& key);
+ const GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
+ int patternSize,
+ int reps,
+ int vertCount,
+ const GrUniqueKey& key);
- const GrBuffer* createQuadIndexBuffer();
+ const GrIndexBuffer* createQuadIndexBuffer();
GrUniqueKey fQuadIndexBufferKey;
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 093bef7086..af77c205b5 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -9,6 +9,7 @@
#include "GrSoftwarePathRenderer.h"
#include "GrContext.h"
#include "GrSWMaskHelper.h"
+#include "GrVertexBuffer.h"
#include "batches/GrRectBatchFactory.h"
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index 2b6463d853..c9b26e284a 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -345,7 +345,11 @@ private:
return nullptr;
}
- GrBuffer* onCreateBuffer(GrBufferType, size_t, GrAccessPattern) override { return nullptr; }
+ GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override { return nullptr; }
+
+ GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override { return nullptr; }
+
+ GrTransferBuffer* onCreateTransferBuffer(size_t, TransferType) override { return nullptr; }
void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override {}
@@ -372,7 +376,7 @@ private:
bool onTransferPixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes) override {
return false;
}
@@ -406,7 +410,7 @@ GrContext* GrContext::CreateMockContext() {
void GrContext::initMockContext() {
GrContextOptions options;
- options.fBufferMapThreshold = 0;
+ options.fGeometryBufferMapThreshold = 0;
SkASSERT(nullptr == fGpu);
fGpu = new MockGpu(this, options);
SkASSERT(fGpu);
diff --git a/src/gpu/GrTransferBuffer.h b/src/gpu/GrTransferBuffer.h
new file mode 100755
index 0000000000..bd80666fd6
--- /dev/null
+++ b/src/gpu/GrTransferBuffer.h
@@ -0,0 +1,76 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrTransferBuffer_DEFINED
+#define GrTransferBuffer_DEFINED
+
+#include "GrGpuResource.h"
+
+class GrTransferBuffer : public GrGpuResource {
+public:
+ /**
+ * Maps the buffer to be written by the CPU.
+ *
+ * The previous content of the buffer is invalidated. It is an error
+ * to transfer to or from the buffer while it is mapped. It is an error to
+ * call map on an already mapped buffer. Must be matched by an unmap() call.
+ * Currently only one map at a time is supported (no nesting of map/unmap).
+ *
+ * Note that buffer mapping does not go through GrContext and therefore is
+ * not serialized with other operations.
+ *
+ * @return a pointer to the data or nullptr if the map fails.
+ */
+ void* map() { return (fMapPtr = this->onMap()); }
+
+ /**
+ * Unmaps the buffer.
+ *
+ * The pointer returned by the previous map call will no longer be valid.
+ */
+ void unmap() {
+ SkASSERT(fMapPtr);
+ this->onUnmap();
+ fMapPtr = nullptr;
+ }
+
+ /**
+ * Returns the same ptr that map() returned at time of map or nullptr if the
+ * is not mapped.
+ *
+ * @return ptr to mapped buffer data or nullptr if buffer is not mapped.
+ */
+ void* mapPtr() const { return fMapPtr; }
+
+ /**
+ Queries whether the buffer has been mapped.
+
+ @return true if the buffer is mapped, false otherwise.
+ */
+ bool isMapped() const { return SkToBool(fMapPtr); }
+
+protected:
+ GrTransferBuffer(GrGpu* gpu, size_t gpuMemorySize)
+ : INHERITED(gpu, kUncached_LifeCycle)
+ , fGpuMemorySize(gpuMemorySize) {
+ }
+
+private:
+ virtual size_t onGpuMemorySize() const { return fGpuMemorySize; }
+
+ virtual void* onMap() = 0;
+ virtual void onUnmap() = 0;
+
+ void* fMapPtr;
+ size_t fGpuMemorySize;
+
+ typedef GrGpuResource INHERITED;
+};
+
+#endif
diff --git a/src/gpu/GrVertexBuffer.h b/src/gpu/GrVertexBuffer.h
new file mode 100644
index 0000000000..3c62cd61ca
--- /dev/null
+++ b/src/gpu/GrVertexBuffer.h
@@ -0,0 +1,42 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrVertexBuffer_DEFINED
+#define GrVertexBuffer_DEFINED
+
+#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) {
+ // We currently only make buffers scratch if they're both pow2 sized and not cpuBacked.
+ if (!cpuBacked && SkIsPow2(gpuMemorySize)) {
+ GrScratchKey key;
+ ComputeScratchKey(gpuMemorySize, dynamic, &key);
+ this->setScratchKey(key);
+ }
+ }
+
+private:
+ typedef GrGeometryBuffer INHERITED;
+};
+
+#endif
diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp
index ba19a0db85..f6be366697 100644
--- a/src/gpu/batches/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp
@@ -814,7 +814,7 @@ private:
continue;
}
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
void* verts = target->makeVertexSpace(vertexStride, tess.numPts(), &vertexBuffer,
@@ -824,7 +824,7 @@ private:
return;
}
- const GrBuffer* indexBuffer;
+ const GrIndexBuffer* indexBuffer;
int firstIndex;
uint16_t* idxs = target->makeIndexSpace(tess.numIndices(), &indexBuffer, &firstIndex);
@@ -900,7 +900,7 @@ private:
continue;
}
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
size_t vertexStride = quadProcessor->getVertexStride();
@@ -912,7 +912,7 @@ private:
return;
}
- const GrBuffer* indexBuffer;
+ const GrIndexBuffer* indexBuffer;
int firstIndex;
uint16_t *idxs = target->makeIndexSpace(indexCount, &indexBuffer, &firstIndex);
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index 6a8ec2ff85..7e96b86550 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -10,13 +10,13 @@
#include "GrBatchFlushState.h"
#include "GrBatchTest.h"
-#include "GrBuffer.h"
#include "GrContext.h"
#include "GrPipelineBuilder.h"
#include "GrResourceProvider.h"
#include "GrSurfacePriv.h"
#include "GrSWMaskHelper.h"
#include "GrTexturePriv.h"
+#include "GrVertexBuffer.h"
#include "batches/GrVertexBatch.h"
#include "effects/GrDistanceFieldGeoProc.h"
@@ -177,8 +177,8 @@ private:
}
struct FlushInfo {
- SkAutoTUnref<const GrBuffer> fVertexBuffer;
- SkAutoTUnref<const GrBuffer> fIndexBuffer;
+ SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
+ SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
int fVertexOffset;
int fInstancesToFlush;
};
@@ -217,7 +217,7 @@ private:
size_t vertexStride = dfProcessor->getVertexStride();
SkASSERT(vertexStride == 2 * sizeof(SkPoint) + sizeof(GrColor));
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
void* vertices = target->makeVertexSpace(vertexStride,
kVerticesPerQuad * instanceCount,
&vertexBuffer,
@@ -492,8 +492,7 @@ private:
void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const {
GrMesh mesh;
- int maxInstancesPerDraw =
- static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
+ int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads();
mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad,
kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw);
diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp
index 890a18b576..9ec8ffdc4a 100644
--- a/src/gpu/batches/GrAAFillRectBatch.cpp
+++ b/src/gpu/batches/GrAAFillRectBatch.cpp
@@ -28,7 +28,7 @@ static const int kNumAAFillRectsInIndexBuffer = 256;
static const int kVertsPerAAFillRect = 8;
static const int kIndicesPerAAFillRect = 30;
-const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
+const GrIndexBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
static const uint16_t gFillAARectIdx[] = {
@@ -191,7 +191,7 @@ public:
out->setUnknownSingleComponent();
}
- static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) {
+ static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* rp) {
return get_index_buffer(rp);
}
diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
index 2cc91f9740..7d45ed71f9 100644
--- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
@@ -9,14 +9,15 @@
#include "GrBatchFlushState.h"
#include "GrBatchTest.h"
-#include "GrBuffer.h"
#include "GrCaps.h"
#include "GrContext.h"
#include "GrDefaultGeoProcFactory.h"
+#include "GrIndexBuffer.h"
#include "GrPathUtils.h"
#include "GrPipelineBuilder.h"
#include "GrProcessor.h"
#include "GrResourceProvider.h"
+#include "GrVertexBuffer.h"
#include "SkGeometry.h"
#include "SkStroke.h"
#include "SkTemplates.h"
@@ -64,7 +65,7 @@ static const int kQuadNumVertices = 5;
static const int kQuadsNumInIdxBuffer = 256;
GR_DECLARE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
-static const GrBuffer* ref_quads_index_buffer(GrResourceProvider* resourceProvider) {
+static const GrIndexBuffer* ref_quads_index_buffer(GrResourceProvider* resourceProvider) {
GR_DEFINE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
return resourceProvider->findOrCreateInstancedIndexBuffer(
kQuadIdxBufPattern, kIdxsPerQuad, kQuadsNumInIdxBuffer, kQuadNumVertices,
@@ -98,7 +99,7 @@ static const int kLineSegsNumInIdxBuffer = 256;
GR_DECLARE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
-static const GrBuffer* ref_lines_index_buffer(GrResourceProvider* resourceProvider) {
+static const GrIndexBuffer* ref_lines_index_buffer(GrResourceProvider* resourceProvider) {
GR_DEFINE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
return resourceProvider->findOrCreateInstancedIndexBuffer(
kLineSegIdxBufPattern, kIdxsPerLineSeg, kLineSegsNumInIdxBuffer, kLineSegNumVertices,
@@ -857,11 +858,11 @@ void AAHairlineBatch::onPrepareDraws(Target* target) const {
// do lines first
if (lineCount) {
- SkAutoTUnref<const GrBuffer> linesIndexBuffer(
+ SkAutoTUnref<const GrIndexBuffer> linesIndexBuffer(
ref_lines_index_buffer(target->resourceProvider()));
target->initDraw(lineGP);
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
size_t vertexStride = lineGP->getVertexStride();
@@ -890,10 +891,10 @@ void AAHairlineBatch::onPrepareDraws(Target* target) const {
}
if (quadCount || conicCount) {
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
- SkAutoTUnref<const GrBuffer> quadsIndexBuffer(
+ SkAutoTUnref<const GrIndexBuffer> quadsIndexBuffer(
ref_quads_index_buffer(target->resourceProvider()));
size_t vertexStride = sizeof(BezierVertex);
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index 1cd8daf881..120ecc76ee 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -164,7 +164,7 @@ private:
if (vertexCount == 0 || indexCount == 0) {
return;
}
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
GrMesh mesh;
int firstVertex;
void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer,
@@ -175,7 +175,7 @@ private:
}
memcpy(verts, vertices, vertexCount * vertexStride);
- const GrBuffer* indexBuffer;
+ const GrIndexBuffer* indexBuffer;
int firstIndex;
uint16_t* idxs = target->makeIndexSpace(indexCount, &indexBuffer, &firstIndex);
if (!idxs) {
diff --git a/src/gpu/batches/GrAAStrokeRectBatch.cpp b/src/gpu/batches/GrAAStrokeRectBatch.cpp
index 2ce5eca7a6..54bc495a4d 100644
--- a/src/gpu/batches/GrAAStrokeRectBatch.cpp
+++ b/src/gpu/batches/GrAAStrokeRectBatch.cpp
@@ -123,7 +123,8 @@ private:
static const int kBevelVertexCnt = 24;
static const int kNumBevelRectsInIndexBuffer = 256;
- static const GrBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, bool miterStroke);
+ static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider,
+ bool miterStroke);
GrColor color() const { return fBatch.fColor; }
bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
@@ -205,7 +206,7 @@ void AAStrokeRectBatch::onPrepareDraws(Target* target) const {
int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
int instanceCount = fGeoData.count();
- const SkAutoTUnref<const GrBuffer> indexBuffer(
+ const SkAutoTUnref<const GrIndexBuffer> indexBuffer(
GetIndexBuffer(target->resourceProvider(), this->miterStroke()));
InstancedHelper helper;
void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
@@ -234,8 +235,8 @@ void AAStrokeRectBatch::onPrepareDraws(Target* target) const {
helper.recordDraw(target);
}
-const GrBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resourceProvider,
- bool miterStroke) {
+const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resourceProvider,
+ bool miterStroke) {
if (miterStroke) {
static const uint16_t gMiterIndices[] = {
diff --git a/src/gpu/batches/GrAtlasTextBatch.cpp b/src/gpu/batches/GrAtlasTextBatch.cpp
index 654643d339..8b89039406 100644
--- a/src/gpu/batches/GrAtlasTextBatch.cpp
+++ b/src/gpu/batches/GrAtlasTextBatch.cpp
@@ -119,7 +119,7 @@ void GrAtlasTextBatch::onPrepareDraws(Target* target) const {
target->initDraw(gp);
int glyphCount = this->numGlyphs();
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
void* vertices = target->makeVertexSpace(vertexStride,
glyphCount * kVerticesPerGlyph,
@@ -181,8 +181,7 @@ void GrAtlasTextBatch::onPrepareDraws(Target* target) const {
void GrAtlasTextBatch::flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const {
GrMesh mesh;
- int maxGlyphsPerDraw =
- static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
+ int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
kVerticesPerGlyph, kIndicesPerGlyph, flushInfo->fGlyphsToFlush,
diff --git a/src/gpu/batches/GrAtlasTextBatch.h b/src/gpu/batches/GrAtlasTextBatch.h
index 01d799233e..435fb59d49 100644
--- a/src/gpu/batches/GrAtlasTextBatch.h
+++ b/src/gpu/batches/GrAtlasTextBatch.h
@@ -99,8 +99,8 @@ private:
void initBatchTracker(const GrXPOverridesForBatch& overrides) override;
struct FlushInfo {
- SkAutoTUnref<const GrBuffer> fVertexBuffer;
- SkAutoTUnref<const GrBuffer> fIndexBuffer;
+ SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
+ SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
int fGlyphsToFlush;
int fVertexOffset;
};
diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp
index 0a3dcd6a14..acaff173c6 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.cpp
+++ b/src/gpu/batches/GrDefaultPathRenderer.cpp
@@ -313,7 +313,7 @@ private:
}
// allocate vertex / index buffers
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
void* verts = target->makeVertexSpace(vertexStride, maxVertices,
@@ -324,7 +324,7 @@ private:
return;
}
- const GrBuffer* indexBuffer = nullptr;
+ const GrIndexBuffer* indexBuffer = nullptr;
int firstIndex = 0;
void* indices = nullptr;
diff --git a/src/gpu/batches/GrDrawVerticesBatch.cpp b/src/gpu/batches/GrDrawVerticesBatch.cpp
index 20d9f79290..c76ba7d1ec 100644
--- a/src/gpu/batches/GrDrawVerticesBatch.cpp
+++ b/src/gpu/batches/GrDrawVerticesBatch.cpp
@@ -106,7 +106,7 @@ void GrDrawVerticesBatch::onPrepareDraws(Target* target) const {
int instanceCount = fGeoData.count();
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
void* verts = target->makeVertexSpace(vertexStride, fVertexCount, &vertexBuffer, &firstVertex);
@@ -116,7 +116,7 @@ void GrDrawVerticesBatch::onPrepareDraws(Target* target) const {
return;
}
- const GrBuffer* indexBuffer = nullptr;
+ const GrIndexBuffer* indexBuffer = nullptr;
int firstIndex = 0;
uint16_t* indices = nullptr;
diff --git a/src/gpu/batches/GrNinePatch.cpp b/src/gpu/batches/GrNinePatch.cpp
index 17ab6c1c30..3ca004d46c 100644
--- a/src/gpu/batches/GrNinePatch.cpp
+++ b/src/gpu/batches/GrNinePatch.cpp
@@ -96,7 +96,7 @@ private:
size_t vertexStride = gp->getVertexStride();
int instanceCount = fGeoData.count();
- SkAutoTUnref<const GrBuffer> indexBuffer(
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
target->resourceProvider()->refQuadIndexBuffer());
InstancedHelper helper;
void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
diff --git a/src/gpu/batches/GrNonAAFillRectBatch.cpp b/src/gpu/batches/GrNonAAFillRectBatch.cpp
index 5e9d1769b5..09643444d0 100644
--- a/src/gpu/batches/GrNonAAFillRectBatch.cpp
+++ b/src/gpu/batches/GrNonAAFillRectBatch.cpp
@@ -26,7 +26,7 @@ public:
out->setKnownSingleComponent(0xff);
}
- static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) {
+ static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* rp) {
return rp->refQuadIndexBuffer();
}
diff --git a/src/gpu/batches/GrNonAAStrokeRectBatch.cpp b/src/gpu/batches/GrNonAAStrokeRectBatch.cpp
index 3e5311f7b9..a87ab11383 100644
--- a/src/gpu/batches/GrNonAAStrokeRectBatch.cpp
+++ b/src/gpu/batches/GrNonAAStrokeRectBatch.cpp
@@ -130,7 +130,7 @@ private:
vertexCount = kVertsPerStrokeRect;
}
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer,
diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp
index 28ad2069bf..348681f43f 100644
--- a/src/gpu/batches/GrPLSPathRenderer.cpp
+++ b/src/gpu/batches/GrPLSPathRenderer.cpp
@@ -873,7 +873,7 @@ public:
}
if (triVertices.count()) {
- const GrBuffer* triVertexBuffer;
+ const GrVertexBuffer* triVertexBuffer;
int firstTriVertex;
size_t triStride = triangleProcessor->getVertexStride();
PLSVertex* triVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
@@ -892,7 +892,7 @@ public:
}
if (quadVertices.count()) {
- const GrBuffer* quadVertexBuffer;
+ const GrVertexBuffer* quadVertexBuffer;
int firstQuadVertex;
size_t quadStride = quadProcessor->getVertexStride();
PLSVertex* quadVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
@@ -916,7 +916,7 @@ public:
SkPath::FillType::kEvenOdd_FillType,
invert,
this->usesLocalCoords()));
- const GrBuffer* rectVertexBuffer;
+ const GrVertexBuffer* rectVertexBuffer;
size_t finishStride = finishProcessor->getVertexStride();
int firstRectVertex;
static const int kRectVertexCount = 6;
diff --git a/src/gpu/batches/GrTInstanceBatch.h b/src/gpu/batches/GrTInstanceBatch.h
index fdd0662d06..22d4f52792 100644
--- a/src/gpu/batches/GrTInstanceBatch.h
+++ b/src/gpu/batches/GrTInstanceBatch.h
@@ -34,7 +34,7 @@
* const GrGeometryProcessor* CreateGP(const Geometry& seedGeometry,
* const GrXPOverridesForBatch& overrides)
*
- * const GrBuffer* GetIndexBuffer(GrResourceProvider*)
+ * const GrIndexBuffer* GetIndexBuffer(GrResourceProvider*)
*
* Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo,
* const GrXPOverridesForBatch& overrides)
@@ -101,7 +101,7 @@ private:
size_t vertexStride = gp->getVertexStride();
int instanceCount = fGeoData.count();
- SkAutoTUnref<const GrBuffer> indexBuffer(
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
Impl::GetIndexBuffer(target->resourceProvider()));
InstancedHelper helper;
void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index 4ba01884dc..c00e8ecbe6 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -45,7 +45,7 @@ private:
}
};
-bool cache_match(GrBuffer* vertexBuffer, SkScalar tol, int* actualCount) {
+bool cache_match(GrVertexBuffer* vertexBuffer, SkScalar tol, int* actualCount) {
if (!vertexBuffer) {
return false;
}
@@ -68,8 +68,8 @@ public:
}
SkPoint* lock(int vertexCount) override {
size_t size = vertexCount * sizeof(SkPoint);
- fVertexBuffer.reset(fResourceProvider->createBuffer(
- kVertex_GrBufferType, size, kStatic_GrAccessPattern, 0));
+ fVertexBuffer.reset(fResourceProvider->createVertexBuffer(
+ size, GrResourceProvider::kStatic_BufferUsage, 0));
if (!fVertexBuffer.get()) {
return nullptr;
}
@@ -89,9 +89,9 @@ public:
}
fVertices = nullptr;
}
- GrBuffer* vertexBuffer() { return fVertexBuffer.get(); }
+ GrVertexBuffer* vertexBuffer() { return fVertexBuffer.get(); }
private:
- SkAutoTUnref<GrBuffer> fVertexBuffer;
+ SkAutoTUnref<GrVertexBuffer> fVertexBuffer;
GrResourceProvider* fResourceProvider;
bool fCanMapVB;
SkPoint* fVertices;
@@ -158,7 +158,8 @@ private:
fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]);
builder.finish();
GrResourceProvider* rp = target->resourceProvider();
- SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrBuffer>(key));
+ SkAutoTUnref<GrVertexBuffer> cachedVertexBuffer(
+ rp->findAndRefTByUniqueKey<GrVertexBuffer>(key));
int actualCount;
SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
SkScalar tol = GrPathUtils::scaleToleranceToSrc(
@@ -225,7 +226,7 @@ private:
this->draw(target, gp.get());
}
- void drawVertices(Target* target, const GrGeometryProcessor* gp, const GrBuffer* vb,
+ void drawVertices(Target* target, const GrGeometryProcessor* gp, const GrVertexBuffer* vb,
int firstVertex, int count) const {
SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
diff --git a/src/gpu/batches/GrTestBatch.h b/src/gpu/batches/GrTestBatch.h
index c28f98d716..3efa3578d5 100644
--- a/src/gpu/batches/GrTestBatch.h
+++ b/src/gpu/batches/GrTestBatch.h
@@ -10,6 +10,7 @@
#include "GrBatchFlushState.h"
#include "GrGeometryProcessor.h"
+#include "GrVertexBuffer.h"
#include "batches/GrVertexBatch.h"
diff --git a/src/gpu/batches/GrVertexBatch.cpp b/src/gpu/batches/GrVertexBatch.cpp
index fc7a1e4fae..17bcf8e3af 100644
--- a/src/gpu/batches/GrVertexBatch.cpp
+++ b/src/gpu/batches/GrVertexBatch.cpp
@@ -17,14 +17,14 @@ void GrVertexBatch::onPrepare(GrBatchFlushState* state) {
}
void* GrVertexBatch::InstancedHelper::init(Target* target, GrPrimitiveType primType,
- size_t vertexStride, const GrBuffer* indexBuffer,
+ size_t vertexStride, const GrIndexBuffer* indexBuffer,
int verticesPerInstance, int indicesPerInstance,
int instancesToDraw) {
SkASSERT(target);
if (!indexBuffer) {
return nullptr;
}
- const GrBuffer* vertexBuffer;
+ const GrVertexBuffer* vertexBuffer;
int firstVertex;
int vertexCount = verticesPerInstance * instancesToDraw;
void* vertices = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
@@ -49,7 +49,7 @@ void GrVertexBatch::InstancedHelper::recordDraw(Target* target) {
void* GrVertexBatch::QuadHelper::init(Target* target, size_t vertexStride,
int quadsToDraw) {
- SkAutoTUnref<const GrBuffer> quadIndexBuffer(
+ SkAutoTUnref<const GrIndexBuffer> quadIndexBuffer(
target->resourceProvider()->refQuadIndexBuffer());
if (!quadIndexBuffer) {
SkDebugf("Could not get quad index buffer.");
diff --git a/src/gpu/batches/GrVertexBatch.h b/src/gpu/batches/GrVertexBatch.h
index 2af4dd1cad..16ba603962 100644
--- a/src/gpu/batches/GrVertexBatch.h
+++ b/src/gpu/batches/GrVertexBatch.h
@@ -35,7 +35,7 @@ protected:
/** Returns the allocated storage for the vertices. The caller should populate the before
vertices before calling issueDraws(). */
void* init(Target*, GrPrimitiveType, size_t vertexStride,
- const GrBuffer*, int verticesPerInstance, int indicesPerInstance,
+ const GrIndexBuffer*, int verticesPerInstance, int indicesPerInstance,
int instancesToDraw);
/** Call after init() to issue draws to the batch target.*/
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index 344c125f7e..51507b1e66 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -17,6 +17,7 @@
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
#include "GrStrokeInfo.h"
+#include "GrVertexBuffer.h"
#include "SkGr.h"
#include "batches/GrVertexBatch.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
diff --git a/src/gpu/gl/GrGLBuffer.cpp b/src/gpu/gl/GrGLBuffer.cpp
deleted file mode 100644
index ad56ceb729..0000000000
--- a/src/gpu/gl/GrGLBuffer.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrGLBuffer.h"
-#include "GrGLGpu.h"
-#include "SkTraceMemoryDump.h"
-
-#define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X)
-#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glGpu()->glInterface(), RET, X)
-
-#if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
- #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface)
- #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call)
- #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface)
-#else
- #define CLEAR_ERROR_BEFORE_ALLOC(iface)
- #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call)
- #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR
-#endif
-
-#ifdef SK_DEBUG
-#define VALIDATE() this->validate()
-#else
-#define VALIDATE() do {} while(false)
-#endif
-
-GrGLBuffer* GrGLBuffer::Create(GrGLGpu* gpu, GrBufferType type, size_t size,
- GrAccessPattern accessPattern) {
- static const int kIsVertexOrIndex = (1 << kVertex_GrBufferType) | (1 << kIndex_GrBufferType);
- bool cpuBacked = gpu->glCaps().useNonVBOVertexAndIndexDynamicData() &&
- kDynamic_GrAccessPattern == accessPattern &&
- ((kIsVertexOrIndex >> type) & 1);
- SkAutoTUnref<GrGLBuffer> buffer(new GrGLBuffer(gpu, type, size, accessPattern, cpuBacked));
- if (!cpuBacked && 0 == buffer->fBufferID) {
- return nullptr;
- }
- return buffer.release();
-}
-
-// GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer
-// objects are implemented as client-side-arrays on tile-deferred architectures.
-#define DYNAMIC_DRAW_PARAM GR_GL_STREAM_DRAW
-
-inline static void get_target_and_usage(GrBufferType type, GrAccessPattern accessPattern,
- const GrGLCaps& caps, GrGLenum* target, GrGLenum* usage) {
- static const GrGLenum nonXferTargets[] = {
- GR_GL_ARRAY_BUFFER,
- GR_GL_ELEMENT_ARRAY_BUFFER
- };
- GR_STATIC_ASSERT(0 == kVertex_GrBufferType);
- GR_STATIC_ASSERT(1 == kIndex_GrBufferType);
-
- static const GrGLenum drawUsages[] = {
- DYNAMIC_DRAW_PARAM, // TODO: Do we really want to use STREAM_DRAW here on non-Chromium?
- GR_GL_STATIC_DRAW,
- GR_GL_STREAM_DRAW
- };
- static const GrGLenum readUsages[] = {
- GR_GL_DYNAMIC_READ,
- GR_GL_STATIC_READ,
- GR_GL_STREAM_READ
- };
- GR_STATIC_ASSERT(0 == kDynamic_GrAccessPattern);
- GR_STATIC_ASSERT(1 == kStatic_GrAccessPattern);
- GR_STATIC_ASSERT(2 == kStream_GrAccessPattern);
- GR_STATIC_ASSERT(SK_ARRAY_COUNT(drawUsages) == 1 + kLast_GrAccessPattern);
- GR_STATIC_ASSERT(SK_ARRAY_COUNT(readUsages) == 1 + kLast_GrAccessPattern);
-
- SkASSERT(accessPattern >= 0 && accessPattern <= kLast_GrAccessPattern);
-
- switch (type) {
- case kVertex_GrBufferType:
- case kIndex_GrBufferType:
- *target = nonXferTargets[type];
- *usage = drawUsages[accessPattern];
- break;
- case kXferCpuToGpu_GrBufferType:
- if (GrGLCaps::kChromium_TransferBufferType == caps.transferBufferType()) {
- *target = GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM;
- } else {
- SkASSERT(GrGLCaps::kPBO_TransferBufferType == caps.transferBufferType());
- *target = GR_GL_PIXEL_UNPACK_BUFFER;
- }
- *usage = drawUsages[accessPattern];
- break;
- case kXferGpuToCpu_GrBufferType:
- if (GrGLCaps::kChromium_TransferBufferType == caps.transferBufferType()) {
- *target = GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
- } else {
- SkASSERT(GrGLCaps::kPBO_TransferBufferType == caps.transferBufferType());
- *target = GR_GL_PIXEL_PACK_BUFFER;
- }
- *usage = readUsages[accessPattern];
- break;
- default:
- SkFAIL("Unexpected buffer type.");
- break;
- }
-}
-
-GrGLBuffer::GrGLBuffer(GrGLGpu* gpu, GrBufferType type, size_t size, GrAccessPattern accessPattern,
- bool cpuBacked)
- : INHERITED(gpu, type, size, accessPattern, cpuBacked),
- fCPUData(nullptr),
- fTarget(0),
- fBufferID(0),
- fSizeInBytes(size),
- fUsage(0),
- fGLSizeInBytes(0) {
- if (cpuBacked) {
- if (gpu->caps()->mustClearUploadedBufferData()) {
- fCPUData = sk_calloc_throw(fSizeInBytes);
- } else {
- fCPUData = sk_malloc_flags(fSizeInBytes, SK_MALLOC_THROW);
- }
- } else {
- GL_CALL(GenBuffers(1, &fBufferID));
- fSizeInBytes = size;
- get_target_and_usage(type, accessPattern, gpu->glCaps(), &fTarget, &fUsage);
- if (fBufferID) {
- gpu->bindBuffer(fBufferID, fTarget);
- CLEAR_ERROR_BEFORE_ALLOC(gpu->glInterface());
- // make sure driver can allocate memory for this buffer
- GL_ALLOC_CALL(gpu->glInterface(), BufferData(fTarget,
- (GrGLsizeiptr) fSizeInBytes,
- nullptr, // data ptr
- fUsage));
- if (CHECK_ALLOC_ERROR(gpu->glInterface()) != GR_GL_NO_ERROR) {
- gpu->releaseBuffer(fBufferID, fTarget);
- fBufferID = 0;
- } else {
- fGLSizeInBytes = fSizeInBytes;
- }
- }
- }
- VALIDATE();
- this->registerWithCache();
-}
-
-inline GrGLGpu* GrGLBuffer::glGpu() const {
- SkASSERT(!this->wasDestroyed());
- return static_cast<GrGLGpu*>(this->getGpu());
-}
-
-inline const GrGLCaps& GrGLBuffer::glCaps() const {
- return this->glGpu()->glCaps();
-}
-
-void GrGLBuffer::onRelease() {
- if (!this->wasDestroyed()) {
- VALIDATE();
- // make sure we've not been abandoned or already released
- if (fCPUData) {
- SkASSERT(!fBufferID);
- sk_free(fCPUData);
- fCPUData = nullptr;
- } else if (fBufferID) {
- this->glGpu()->releaseBuffer(fBufferID, fTarget);
- fBufferID = 0;
- fGLSizeInBytes = 0;
- }
- fMapPtr = nullptr;
- VALIDATE();
- }
-
- INHERITED::onRelease();
-}
-
-void GrGLBuffer::onAbandon() {
- fBufferID = 0;
- fGLSizeInBytes = 0;
- fMapPtr = nullptr;
- sk_free(fCPUData);
- fCPUData = nullptr;
- VALIDATE();
- INHERITED::onAbandon();
-}
-
-void GrGLBuffer::onMap() {
- if (this->wasDestroyed()) {
- return;
- }
-
- VALIDATE();
- SkASSERT(!this->isMapped());
-
- if (0 == fBufferID) {
- fMapPtr = fCPUData;
- VALIDATE();
- return;
- }
-
- bool readOnly = (kXferGpuToCpu_GrBufferType == this->type());
-
- // Handling dirty context is done in the bindBuffer call
- switch (this->glCaps().mapBufferType()) {
- case GrGLCaps::kNone_MapBufferType:
- break;
- case GrGLCaps::kMapBuffer_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- // Let driver know it can discard the old data
- if (GR_GL_USE_BUFFER_DATA_NULL_HINT || fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
- }
- GL_CALL_RET(fMapPtr, MapBuffer(fTarget, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
- break;
- case GrGLCaps::kMapBufferRange_MapBufferType: {
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- // Make sure the GL buffer size agrees with fDesc before mapping.
- if (fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
- }
- GrGLbitfield writeAccess = GR_GL_MAP_WRITE_BIT;
- // TODO: allow the client to specify invalidation in the transfer buffer case.
- if (kXferCpuToGpu_GrBufferType != this->type()) {
- writeAccess |= GR_GL_MAP_INVALIDATE_BUFFER_BIT;
- }
- GL_CALL_RET(fMapPtr, MapBufferRange(fTarget, 0, fSizeInBytes,
- readOnly ? GR_GL_MAP_READ_BIT : writeAccess));
- break;
- }
- case GrGLCaps::kChromium_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- // Make sure the GL buffer size agrees with fDesc before mapping.
- if (fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
- }
- GL_CALL_RET(fMapPtr, MapBufferSubData(fTarget, 0, fSizeInBytes,
- readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
- break;
- }
- fGLSizeInBytes = fSizeInBytes;
- VALIDATE();
-}
-
-void GrGLBuffer::onUnmap() {
- if (this->wasDestroyed()) {
- return;
- }
-
- VALIDATE();
- SkASSERT(this->isMapped());
- if (0 == fBufferID) {
- fMapPtr = nullptr;
- return;
- }
- // bind buffer handles the dirty context
- switch (this->glCaps().mapBufferType()) {
- case GrGLCaps::kNone_MapBufferType:
- SkDEBUGFAIL("Shouldn't get here.");
- return;
- case GrGLCaps::kMapBuffer_MapBufferType: // fall through
- case GrGLCaps::kMapBufferRange_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- GL_CALL(UnmapBuffer(fTarget));
- break;
- case GrGLCaps::kChromium_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- GL_CALL(UnmapBufferSubData(fMapPtr));
- break;
- }
- fMapPtr = nullptr;
-}
-
-bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
- if (this->wasDestroyed()) {
- return false;
- }
-
- SkASSERT(!this->isMapped());
- SkASSERT(GR_GL_ARRAY_BUFFER == fTarget || GR_GL_ELEMENT_ARRAY_BUFFER == fTarget);
- VALIDATE();
- if (srcSizeInBytes > fSizeInBytes) {
- return false;
- }
- if (0 == fBufferID) {
- memcpy(fCPUData, src, srcSizeInBytes);
- return true;
- }
- SkASSERT(srcSizeInBytes <= fSizeInBytes);
- // bindbuffer handles dirty context
- this->glGpu()->bindBuffer(fBufferID, fTarget);
-
-#if GR_GL_USE_BUFFER_DATA_NULL_HINT
- if (fSizeInBytes == srcSizeInBytes) {
- GL_CALL(BufferData(fTarget, (GrGLsizeiptr) srcSizeInBytes, src, fUsage));
- } else {
- // Before we call glBufferSubData we give the driver a hint using
- // glBufferData with nullptr. This makes the old buffer contents
- // inaccessible to future draws. The GPU may still be processing
- // draws that reference the old contents. With this hint it can
- // assign a different allocation for the new contents to avoid
- // flushing the gpu past draws consuming the old contents.
- // TODO I think we actually want to try calling bufferData here
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
- GL_CALL(BufferSubData(fTarget, 0, (GrGLsizeiptr) srcSizeInBytes, src));
- }
- fGLSizeInBytes = fSizeInBytes;
-#else
- // Note that we're cheating on the size here. Currently no methods
- // allow a partial update that preserves contents of non-updated
- // portions of the buffer (map() does a glBufferData(..size, nullptr..))
- GL_CALL(BufferData(fTarget, srcSizeInBytes, src, fUsage));
- fGLSizeInBytes = srcSizeInBytes;
-#endif
- VALIDATE();
- return true;
-}
-
-void GrGLBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
- const SkString& dumpName) const {
- SkString buffer_id;
- buffer_id.appendU32(this->bufferID());
- traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_buffer",
- buffer_id.c_str());
-}
-
-#ifdef SK_DEBUG
-
-void GrGLBuffer::validate() const {
- SkASSERT(GR_GL_ARRAY_BUFFER == fTarget || GR_GL_ELEMENT_ARRAY_BUFFER == fTarget ||
- GR_GL_PIXEL_PACK_BUFFER == fTarget || GR_GL_PIXEL_UNPACK_BUFFER == fTarget ||
- GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fTarget ||
- GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fTarget);
- // The following assert isn't valid when the buffer has been abandoned:
- // SkASSERT((0 == fDesc.fID) == (fCPUData));
- SkASSERT(0 != fBufferID || 0 == fGLSizeInBytes);
- SkASSERT(nullptr == fMapPtr || fCPUData || fGLSizeInBytes <= fSizeInBytes);
- SkASSERT(nullptr == fCPUData || nullptr == fMapPtr || fCPUData == fMapPtr);
-}
-
-#endif
diff --git a/src/gpu/gl/GrGLBuffer.h b/src/gpu/gl/GrGLBuffer.h
deleted file mode 100644
index 90d2c43dfa..0000000000
--- a/src/gpu/gl/GrGLBuffer.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLBuffer_DEFINED
-#define GrGLBuffer_DEFINED
-
-#include "GrBuffer.h"
-#include "gl/GrGLTypes.h"
-
-class GrGLGpu;
-class GrGLCaps;
-
-class GrGLBuffer : public GrBuffer {
-public:
- static GrGLBuffer* Create(GrGLGpu*, GrBufferType, size_t size, GrAccessPattern);
-
- ~GrGLBuffer() {
- // either release or abandon should have been called by the owner of this object.
- SkASSERT(0 == fBufferID);
- }
-
- GrGLenum target() const { return fTarget; }
- GrGLuint bufferID() const { return fBufferID; }
- size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); }
-
-protected:
- GrGLBuffer(GrGLGpu*, GrBufferType, size_t size, GrAccessPattern, bool cpuBacked);
-
- void onAbandon() override;
- void onRelease() override;
- void setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
- const SkString& dumpName) const override;
-
-private:
- GrGLGpu* glGpu() const;
- const GrGLCaps& glCaps() const;
-
- void onMap() override;
- void onUnmap() override;
- bool onUpdateData(const void* src, size_t srcSizeInBytes) override;
-
-#ifdef SK_DEBUG
- void validate() const;
-#endif
-
- void* fCPUData;
- GrGLenum fTarget; // GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER, e.g.
- GrGLuint fBufferID;
- size_t fSizeInBytes;
- GrGLenum fUsage;
- size_t fGLSizeInBytes; // In certain cases we make the size of the GL buffer object
- // smaller or larger than the size in fDesc.
-
- typedef GrBuffer INHERITED;
-};
-
-#endif
diff --git a/src/gpu/gl/GrGLBufferImpl.cpp b/src/gpu/gl/GrGLBufferImpl.cpp
new file mode 100644
index 0000000000..2babce8028
--- /dev/null
+++ b/src/gpu/gl/GrGLBufferImpl.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLBufferImpl.h"
+#include "GrGLGpu.h"
+
+#define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X)
+
+#ifdef SK_DEBUG
+#define VALIDATE() this->validate()
+#else
+#define VALIDATE() do {} while(false)
+#endif
+
+GrGLBufferImpl::GrGLBufferImpl(GrGLGpu* gpu, const Desc& desc, GrGLenum bufferType)
+ : fDesc(desc)
+ , fBufferType(bufferType)
+ , fMapPtr(nullptr) {
+ if (0 == desc.fID) {
+ if (gpu->caps()->mustClearUploadedBufferData()) {
+ fCPUData = sk_calloc_throw(desc.fSizeInBytes);
+ } else {
+ fCPUData = sk_malloc_flags(desc.fSizeInBytes, SK_MALLOC_THROW);
+ }
+ fGLSizeInBytes = 0;
+ } else {
+ fCPUData = nullptr;
+ // We assume that the GL buffer was created at the desc's size initially.
+ fGLSizeInBytes = fDesc.fSizeInBytes;
+ }
+ VALIDATE();
+}
+
+void GrGLBufferImpl::release(GrGLGpu* gpu) {
+ VALIDATE();
+ // make sure we've not been abandoned or already released
+ if (fCPUData) {
+ sk_free(fCPUData);
+ fCPUData = nullptr;
+ } else if (fDesc.fID) {
+ gpu->releaseBuffer(fDesc.fID, fBufferType);
+ fDesc.fID = 0;
+ fGLSizeInBytes = 0;
+ }
+ fMapPtr = nullptr;
+ VALIDATE();
+}
+
+void GrGLBufferImpl::abandon() {
+ fDesc.fID = 0;
+ fGLSizeInBytes = 0;
+ fMapPtr = nullptr;
+ sk_free(fCPUData);
+ fCPUData = nullptr;
+ VALIDATE();
+}
+
+void* GrGLBufferImpl::map(GrGLGpu* gpu) {
+ VALIDATE();
+ SkASSERT(!this->isMapped());
+ if (0 == fDesc.fID) {
+ fMapPtr = fCPUData;
+ } else {
+ fMapPtr = gpu->mapBuffer(fDesc.fID, fBufferType, fDesc.fUsage, fGLSizeInBytes,
+ fDesc.fSizeInBytes);
+ fGLSizeInBytes = fDesc.fSizeInBytes;
+ }
+ VALIDATE();
+ return fMapPtr;
+}
+
+void GrGLBufferImpl::unmap(GrGLGpu* gpu) {
+ VALIDATE();
+ SkASSERT(this->isMapped());
+ if (0 != fDesc.fID) {
+ gpu->unmapBuffer(fDesc.fID, fBufferType, fMapPtr);
+ }
+ fMapPtr = nullptr;
+}
+
+bool GrGLBufferImpl::isMapped() const {
+ VALIDATE();
+ return SkToBool(fMapPtr);
+}
+
+bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInBytes) {
+ SkASSERT(!this->isMapped());
+ SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
+ VALIDATE();
+ if (srcSizeInBytes > fDesc.fSizeInBytes) {
+ return false;
+ }
+ if (0 == fDesc.fID) {
+ memcpy(fCPUData, src, srcSizeInBytes);
+ return true;
+ }
+ gpu->bufferData(fDesc.fID, fBufferType, fDesc.fUsage, fDesc.fSizeInBytes, src,
+ srcSizeInBytes);
+#if GR_GL_USE_BUFFER_DATA_NULL_HINT
+ fGLSizeInBytes = fDesc.fSizeInBytes;
+#else
+ fGLSizeInBytes = srcSizeInBytes;
+#endif
+ VALIDATE();
+ return true;
+}
+
+void GrGLBufferImpl::validate() const {
+ SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType ||
+ GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType ||
+ GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fBufferType ||
+ GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fBufferType);
+ // The following assert isn't valid when the buffer has been abandoned:
+ // SkASSERT((0 == fDesc.fID) == (fCPUData));
+ SkASSERT(nullptr == fCPUData || 0 == fGLSizeInBytes);
+ SkASSERT(nullptr == fMapPtr || fCPUData || fGLSizeInBytes <= fDesc.fSizeInBytes);
+ SkASSERT(nullptr == fCPUData || nullptr == fMapPtr || fCPUData == fMapPtr);
+}
diff --git a/src/gpu/gl/GrGLBufferImpl.h b/src/gpu/gl/GrGLBufferImpl.h
new file mode 100644
index 0000000000..a8f2cced37
--- /dev/null
+++ b/src/gpu/gl/GrGLBufferImpl.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLBufferImpl_DEFINED
+#define GrGLBufferImpl_DEFINED
+
+#include "SkTypes.h"
+#include "gl/GrGLTypes.h"
+
+class GrGLGpu;
+
+/**
+ * This class serves as the implementation of GrGL*Buffer classes. It was written to avoid code
+ * duplication in those classes.
+ */
+class GrGLBufferImpl : SkNoncopyable {
+public:
+ enum Usage {
+ kStaticDraw_Usage = 0,
+ kDynamicDraw_Usage,
+ kStreamDraw_Usage,
+ kStreamRead_Usage,
+
+ kLast_Usage = kStreamRead_Usage
+ };
+ static const int kUsageCount = kLast_Usage + 1;
+
+ struct Desc {
+ GrGLuint fID; // set to 0 to indicate buffer is CPU-backed and not a VBO.
+ size_t fSizeInBytes;
+ Usage fUsage;
+ };
+
+ GrGLBufferImpl(GrGLGpu*, const Desc&, GrGLenum bufferType);
+ ~GrGLBufferImpl() {
+ // either release or abandon should have been called by the owner of this object.
+ SkASSERT(0 == fDesc.fID);
+ }
+
+ void abandon();
+ void release(GrGLGpu* gpu);
+
+ GrGLuint bufferID() const { return fDesc.fID; }
+ size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); }
+ GrGLenum bufferType() const { return fBufferType; }
+
+ void* map(GrGLGpu* gpu);
+ void unmap(GrGLGpu* gpu);
+ bool isMapped() const;
+ bool updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInBytes);
+
+private:
+ void validate() const;
+
+ Desc fDesc;
+ GrGLenum fBufferType; // GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER, e.g.
+ void* fCPUData;
+ void* fMapPtr;
+ size_t fGLSizeInBytes; // In certain cases we make the size of the GL buffer object
+ // smaller or larger than the size in fDesc.
+
+ typedef SkNoncopyable INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 51974d4c02..50a74febe7 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -400,14 +400,14 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
// On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
// threshold to the maximum unless the client gives us a hint that map memory is cheap.
- if (fBufferMapThreshold < 0) {
+ if (fGeometryBufferMapThreshold < 0) {
// We think mapping on Chromium will be cheaper once we know ahead of time how much space
// we will use for all GrBatchs. Right now we might wind up mapping a large buffer and using
// a small subset.
#if 0
- fBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
+ fGeometryBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
#else
- fBufferMapThreshold = SK_MaxS32;
+ fGeometryBufferMapThreshold = SK_MaxS32;
#endif
}
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index c97e605ba8..ff4c457250 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -122,9 +122,7 @@
#define GR_GL_STREAM_DRAW 0x88E0
#define GR_GL_STREAM_READ 0x88E1
#define GR_GL_STATIC_DRAW 0x88E4
-#define GR_GL_STATIC_READ 0x88E5
#define GR_GL_DYNAMIC_DRAW 0x88E8
-#define GR_GL_DYNAMIC_READ 0x88E9
#define GR_GL_BUFFER_SIZE 0x8764
#define GR_GL_BUFFER_USAGE 0x8765
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 6b591494b9..3a293610f2 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -6,7 +6,6 @@
*/
#include "GrGLGpu.h"
-#include "GrGLBuffer.h"
#include "GrGLGLSL.h"
#include "GrGLStencilAttachment.h"
#include "GrGLTextureRenderTarget.h"
@@ -844,7 +843,7 @@ bool GrGLGpu::onWritePixels(GrSurface* surface,
bool GrGLGpu::onTransferPixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes) {
GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
@@ -860,14 +859,16 @@ bool GrGLGpu::onTransferPixels(GrSurface* surface,
this->setScratchTextureUnit();
GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
- SkASSERT(kXferCpuToGpu_GrBufferType == transferBuffer->type());
- SkASSERT(!transferBuffer->isMapped());
- const GrGLBuffer* glBuffer = reinterpret_cast<const GrGLBuffer*>(transferBuffer);
- this->bindBuffer(glBuffer->bufferID(), glBuffer->target());
+ SkASSERT(!buffer->isMapped());
+ GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer);
+ // bind the transfer buffer
+ SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() ||
+ GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType());
+ GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID()));
bool success = false;
GrMipLevel mipLevel;
- mipLevel.fPixels = transferBuffer;
+ mipLevel.fPixels = buffer;
mipLevel.fRowBytes = rowBytes;
SkSTArray<1, GrMipLevel> texels;
texels.push_back(mipLevel);
@@ -1932,8 +1933,111 @@ GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen
// objects are implemented as client-side-arrays on tile-deferred architectures.
#define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW
-GrBuffer* GrGLGpu::onCreateBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) {
- return GrGLBuffer::Create(this, type, size, accessPattern);
+GrVertexBuffer* GrGLGpu::onCreateVertexBuffer(size_t size, bool dynamic) {
+ GrGLVertexBuffer::Desc desc;
+ desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl::kStaticDraw_Usage;
+ desc.fSizeInBytes = size;
+
+ if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
+ desc.fID = 0;
+ GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc);
+ return vertexBuffer;
+ } else {
+ desc.fID = 0;
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ fHWGeometryState.setVertexBufferID(this, desc.fID);
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ // make sure driver can allocate memory for this buffer
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(GR_GL_ARRAY_BUFFER,
+ (GrGLsizeiptr) desc.fSizeInBytes,
+ nullptr, // data ptr
+ dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ this->notifyVertexBufferDelete(desc.fID);
+ return nullptr;
+ }
+ GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc);
+ return vertexBuffer;
+ }
+ return nullptr;
+ }
+}
+
+GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
+ GrGLIndexBuffer::Desc desc;
+ desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl::kStaticDraw_Usage;
+ desc.fSizeInBytes = size;
+
+ if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
+ desc.fID = 0;
+ GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc);
+ return indexBuffer;
+ } else {
+ desc.fID = 0;
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, desc.fID);
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ // make sure driver can allocate memory for this buffer
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
+ (GrGLsizeiptr) desc.fSizeInBytes,
+ nullptr, // data ptr
+ dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ this->notifyIndexBufferDelete(desc.fID);
+ return nullptr;
+ }
+ GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc);
+ return indexBuffer;
+ }
+ return nullptr;
+ }
+}
+
+GrTransferBuffer* GrGLGpu::onCreateTransferBuffer(size_t size, TransferType xferType) {
+ GrGLCaps::TransferBufferType xferBufferType = this->ctxInfo().caps()->transferBufferType();
+ if (GrGLCaps::kNone_TransferBufferType == xferBufferType) {
+ return nullptr;
+ }
+
+ GrGLTransferBuffer::Desc desc;
+ bool toGpu = (kCpuToGpu_TransferType == xferType);
+ desc.fUsage = toGpu ? GrGLBufferImpl::kStreamDraw_Usage : GrGLBufferImpl::kStreamRead_Usage;
+
+ desc.fSizeInBytes = size;
+ desc.fID = 0;
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ // make sure driver can allocate memory for this bmapuffer
+ GrGLenum target;
+ if (GrGLCaps::kChromium_TransferBufferType == xferBufferType) {
+ target = toGpu ? GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM
+ : GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
+ } else {
+ SkASSERT(GrGLCaps::kPBO_TransferBufferType == xferBufferType);
+ target = toGpu ? GR_GL_PIXEL_UNPACK_BUFFER : GR_GL_PIXEL_PACK_BUFFER;
+ }
+ GL_CALL(BindBuffer(target, desc.fID));
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(target,
+ (GrGLsizeiptr) desc.fSizeInBytes,
+ nullptr, // data ptr
+ (toGpu ? GR_GL_STREAM_DRAW : GR_GL_STREAM_READ)));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ return nullptr;
+ }
+ GrTransferBuffer* transferBuffer = new GrGLTransferBuffer(this, desc, target);
+ return transferBuffer;
+ }
+
+ return nullptr;
}
void GrGLGpu::flushScissor(const GrScissorState& scissorState,
@@ -2018,18 +2122,18 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
const GrNonInstancedMesh& mesh,
size_t* indexOffsetInBytes) {
- const GrGLBuffer* vbuf;
- vbuf = static_cast<const GrGLBuffer*>(mesh.vertexBuffer());
+ GrGLVertexBuffer* vbuf;
+ vbuf = (GrGLVertexBuffer*) mesh.vertexBuffer();
SkASSERT(vbuf);
SkASSERT(!vbuf->isMapped());
- const GrGLBuffer* ibuf = nullptr;
+ GrGLIndexBuffer* ibuf = nullptr;
if (mesh.isIndexed()) {
SkASSERT(indexOffsetInBytes);
*indexOffsetInBytes = 0;
- ibuf = static_cast<const GrGLBuffer*>(mesh.indexBuffer());
+ ibuf = (GrGLIndexBuffer*)mesh.indexBuffer();
SkASSERT(ibuf);
SkASSERT(!ibuf->isMapped());
@@ -2119,6 +2223,113 @@ void GrGLGpu::releaseBuffer(GrGLuint id, GrGLenum type) {
}
}
+static GrGLenum get_gl_usage(GrGLBufferImpl::Usage usage) {
+ static const GrGLenum grToGL[] = {
+ GR_GL_STATIC_DRAW, // GrGLBufferImpl::kStaticDraw_Usage
+ DYNAMIC_USAGE_PARAM, // GrGLBufferImpl::kDynamicDraw_Usage
+ GR_GL_STREAM_DRAW, // GrGLBufferImpl::kStreamDraw_Usage
+ GR_GL_STREAM_READ, // GrGLBufferImpl::kStreamRead_Usage
+ };
+ static_assert(SK_ARRAY_COUNT(grToGL) == GrGLBufferImpl::kUsageCount, "array_size_mismatch");
+
+ return grToGL[usage];
+}
+
+void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage,
+ size_t currentSize, size_t requestedSize) {
+ void* mapPtr = nullptr;
+ GrGLenum glUsage = get_gl_usage(usage);
+ bool readOnly = (GrGLBufferImpl::kStreamRead_Usage == usage);
+
+ // Handling dirty context is done in the bindBuffer call
+ switch (this->glCaps().mapBufferType()) {
+ case GrGLCaps::kNone_MapBufferType:
+ break;
+ case GrGLCaps::kMapBuffer_MapBufferType:
+ this->bindBuffer(id, type);
+ // Let driver know it can discard the old data
+ if (GR_GL_USE_BUFFER_DATA_NULL_HINT || currentSize != requestedSize) {
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
+ }
+ GL_CALL_RET(mapPtr, MapBuffer(type, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
+ break;
+ case GrGLCaps::kMapBufferRange_MapBufferType: {
+ this->bindBuffer(id, type);
+ // Make sure the GL buffer size agrees with fDesc before mapping.
+ if (currentSize != requestedSize) {
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
+ }
+ GrGLbitfield writeAccess = GR_GL_MAP_WRITE_BIT;
+ // TODO: allow the client to specify invalidation in the stream draw case
+ if (GrGLBufferImpl::kStreamDraw_Usage != usage) {
+ writeAccess |= GR_GL_MAP_INVALIDATE_BUFFER_BIT;
+ }
+ GL_CALL_RET(mapPtr, MapBufferRange(type, 0, requestedSize, readOnly ?
+ GR_GL_MAP_READ_BIT :
+ writeAccess));
+ break;
+ }
+ case GrGLCaps::kChromium_MapBufferType:
+ this->bindBuffer(id, type);
+ // Make sure the GL buffer size agrees with fDesc before mapping.
+ if (currentSize != requestedSize) {
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
+ }
+ GL_CALL_RET(mapPtr, MapBufferSubData(type, 0, requestedSize, readOnly ?
+ GR_GL_READ_ONLY :
+ GR_GL_WRITE_ONLY));
+ break;
+ }
+ return mapPtr;
+}
+
+void GrGLGpu::bufferData(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage,
+ size_t currentSize, const void* src, size_t srcSizeInBytes) {
+ SkASSERT(srcSizeInBytes <= currentSize);
+ // bindbuffer handles dirty context
+ this->bindBuffer(id, type);
+ GrGLenum glUsage = get_gl_usage(usage);
+
+#if GR_GL_USE_BUFFER_DATA_NULL_HINT
+ if (currentSize == srcSizeInBytes) {
+ GL_CALL(BufferData(type, (GrGLsizeiptr) srcSizeInBytes, src, glUsage));
+ } else {
+ // Before we call glBufferSubData we give the driver a hint using
+ // glBufferData with nullptr. This makes the old buffer contents
+ // inaccessible to future draws. The GPU may still be processing
+ // draws that reference the old contents. With this hint it can
+ // assign a different allocation for the new contents to avoid
+ // flushing the gpu past draws consuming the old contents.
+ // TODO I think we actually want to try calling bufferData here
+ GL_CALL(BufferData(type, currentSize, nullptr, glUsage));
+ GL_CALL(BufferSubData(type, 0, (GrGLsizeiptr) srcSizeInBytes, src));
+ }
+#else
+ // Note that we're cheating on the size here. Currently no methods
+ // allow a partial update that preserves contents of non-updated
+ // portions of the buffer (map() does a glBufferData(..size, nullptr..))
+ GL_CALL(BufferData(type, srcSizeInBytes, src, glUsage));
+#endif
+}
+
+void GrGLGpu::unmapBuffer(GrGLuint id, GrGLenum type, void* mapPtr) {
+ // bind buffer handles the dirty context
+ switch (this->glCaps().mapBufferType()) {
+ case GrGLCaps::kNone_MapBufferType:
+ SkDEBUGFAIL("Shouldn't get here.");
+ return;
+ case GrGLCaps::kMapBuffer_MapBufferType: // fall through
+ case GrGLCaps::kMapBufferRange_MapBufferType:
+ this->bindBuffer(id, type);
+ GL_CALL(UnmapBuffer(type));
+ break;
+ case GrGLCaps::kChromium_MapBufferType:
+ this->bindBuffer(id, type);
+ GL_CALL(UnmapBufferSubData(mapPtr));
+ break;
+ }
+}
+
void GrGLGpu::disableScissor() {
if (kNo_TriState != fHWScissorSettings.fEnabled) {
GL_CALL(Disable(GR_GL_SCISSOR_TEST));
@@ -4140,8 +4351,8 @@ void GrGLGpu::resetShaderCacheForTesting() const {
///////////////////////////////////////////////////////////////////////////////
GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(
GrGLGpu* gpu,
- const GrGLBuffer* vbuffer,
- const GrGLBuffer* ibuffer) {
+ const GrGLVertexBuffer* vbuffer,
+ const GrGLIndexBuffer* ibuffer) {
SkASSERT(vbuffer);
GrGLuint vbufferID = vbuffer->bufferID();
GrGLuint* ibufferIDPtr = nullptr;
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index bc79d2f427..bcb3c193dc 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -10,12 +10,15 @@
#include "GrGLContext.h"
#include "GrGLIRect.h"
+#include "GrGLIndexBuffer.h"
#include "GrGLPathRendering.h"
#include "GrGLProgram.h"
#include "GrGLRenderTarget.h"
#include "GrGLStencilAttachment.h"
#include "GrGLTexture.h"
+#include "GrGLTransferBuffer.h"
#include "GrGLVertexArray.h"
+#include "GrGLVertexBuffer.h"
#include "GrGpu.h"
#include "GrPipelineBuilder.h"
#include "GrTypes.h"
@@ -23,7 +26,6 @@
#include "SkTArray.h"
#include "SkTypes.h"
-class GrGLBuffer;
class GrPipeline;
class GrNonInstancedMesh;
class GrSwizzle;
@@ -99,6 +101,15 @@ public:
void releaseBuffer(GrGLuint id, GrGLenum type);
+ // sizes are in bytes
+ void* mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize,
+ size_t requestedSize);
+
+ void unmapBuffer(GrGLuint id, GrGLenum type, void* mapPtr);
+
+ void bufferData(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize,
+ const void* src, size_t srcSizeInBytes);
+
const GrGLContext* glContextForTesting() const override {
return &this->glContext();
}
@@ -138,7 +149,9 @@ private:
GrGpuResource::LifeCycle lifeCycle,
const SkTArray<GrMipLevel>& texels) override;
- GrBuffer* onCreateBuffer(GrBufferType, size_t size, GrAccessPattern) override;
+ GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override;
+ GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override;
+ GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) override;
GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
GrWrapOwnership) override;
@@ -195,7 +208,7 @@ private:
bool onTransferPixels(GrSurface*,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes) override;
void onResolveRenderTarget(GrRenderTarget* target) override;
@@ -498,8 +511,8 @@ private:
* returned GrGLAttribArrayState should be used to set vertex attribute arrays.
*/
GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
- const GrGLBuffer* vbuffer,
- const GrGLBuffer* ibuffer);
+ const GrGLVertexBuffer* vbuffer,
+ const GrGLIndexBuffer* ibuffer);
/** Variants of the above that takes GL buffer IDs. Note that 0 does not imply that a
buffer won't be bound. The "default buffer" will be bound, which is used for client-side
diff --git a/src/gpu/gl/GrGLIndexBuffer.cpp b/src/gpu/gl/GrGLIndexBuffer.cpp
new file mode 100644
index 0000000000..5a794ad824
--- /dev/null
+++ b/src/gpu/gl/GrGLIndexBuffer.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLIndexBuffer.h"
+#include "GrGLGpu.h"
+#include "SkTraceMemoryDump.h"
+
+GrGLIndexBuffer::GrGLIndexBuffer(GrGLGpu* gpu, const Desc& desc)
+ : INHERITED(gpu, desc.fSizeInBytes, GrGLBufferImpl::kDynamicDraw_Usage == desc.fUsage,
+ 0 == desc.fID)
+ , fImpl(gpu, desc, GR_GL_ELEMENT_ARRAY_BUFFER) {
+ this->registerWithCache();
+}
+
+void GrGLIndexBuffer::onRelease() {
+ if (!this->wasDestroyed()) {
+ fImpl.release(this->getGpuGL());
+ }
+
+ INHERITED::onRelease();
+}
+
+void GrGLIndexBuffer::onAbandon() {
+ fImpl.abandon();
+ INHERITED::onAbandon();
+}
+
+void* GrGLIndexBuffer::onMap() {
+ if (!this->wasDestroyed()) {
+ return fImpl.map(this->getGpuGL());
+ } else {
+ return nullptr;
+ }
+}
+
+void GrGLIndexBuffer::onUnmap() {
+ if (!this->wasDestroyed()) {
+ fImpl.unmap(this->getGpuGL());
+ }
+}
+
+bool GrGLIndexBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
+ if (!this->wasDestroyed()) {
+ return fImpl.updateData(this->getGpuGL(), src, srcSizeInBytes);
+ } else {
+ return false;
+ }
+}
+
+void GrGLIndexBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
+ const SkString& dumpName) const {
+ SkString buffer_id;
+ buffer_id.appendU32(this->bufferID());
+ traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_buffer",
+ buffer_id.c_str());
+}
diff --git a/src/gpu/gl/GrGLIndexBuffer.h b/src/gpu/gl/GrGLIndexBuffer.h
new file mode 100644
index 0000000000..628970a0fa
--- /dev/null
+++ b/src/gpu/gl/GrGLIndexBuffer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLIndexBuffer_DEFINED
+#define GrGLIndexBuffer_DEFINED
+
+#include "GrIndexBuffer.h"
+#include "GrGLBufferImpl.h"
+#include "gl/GrGLInterface.h"
+
+class GrGLGpu;
+
+class GrGLIndexBuffer : public GrIndexBuffer {
+
+public:
+ typedef GrGLBufferImpl::Desc Desc;
+
+ GrGLIndexBuffer(GrGLGpu* gpu, const Desc& desc);
+
+ GrGLuint bufferID() const { return fImpl.bufferID(); }
+ size_t baseOffset() const { return fImpl.baseOffset(); }
+
+protected:
+ void onAbandon() override;
+ void onRelease() override;
+ void setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
+ const SkString& dumpName) const override;
+
+private:
+ void* onMap() override;
+ void onUnmap() override;
+ bool onUpdateData(const void* src, size_t srcSizeInBytes) override;
+
+ GrGLGpu* getGpuGL() const {
+ SkASSERT(!this->wasDestroyed());
+ return (GrGLGpu*)(this->getGpu());
+ }
+
+ GrGLBufferImpl fImpl;
+
+ typedef GrIndexBuffer INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLTransferBuffer.cpp b/src/gpu/gl/GrGLTransferBuffer.cpp
new file mode 100755
index 0000000000..b7ee766d92
--- /dev/null
+++ b/src/gpu/gl/GrGLTransferBuffer.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLTransferBuffer.h"
+#include "GrGLGpu.h"
+#include "SkTraceMemoryDump.h"
+
+GrGLTransferBuffer::GrGLTransferBuffer(GrGLGpu* gpu, const Desc& desc, GrGLenum type)
+ : INHERITED(gpu, desc.fSizeInBytes)
+ , fImpl(gpu, desc, type) {
+ this->registerWithCache();
+}
+
+void GrGLTransferBuffer::onRelease() {
+ if (!this->wasDestroyed()) {
+ fImpl.release(this->getGpuGL());
+ }
+
+ INHERITED::onRelease();
+}
+
+void GrGLTransferBuffer::onAbandon() {
+ fImpl.abandon();
+ INHERITED::onAbandon();
+}
+
+void* GrGLTransferBuffer::onMap() {
+ if (!this->wasDestroyed()) {
+ return fImpl.map(this->getGpuGL());
+ } else {
+ return nullptr;
+ }
+}
+
+void GrGLTransferBuffer::onUnmap() {
+ if (!this->wasDestroyed()) {
+ fImpl.unmap(this->getGpuGL());
+ }
+}
+
+void GrGLTransferBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
+ const SkString& dumpName) const {
+ SkString buffer_id;
+ buffer_id.appendU32(this->bufferID());
+ traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_buffer",
+ buffer_id.c_str());
+}
diff --git a/src/gpu/gl/GrGLTransferBuffer.h b/src/gpu/gl/GrGLTransferBuffer.h
new file mode 100755
index 0000000000..e01d4447df
--- /dev/null
+++ b/src/gpu/gl/GrGLTransferBuffer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLTransferBuffer_DEFINED
+#define GrGLTransferBuffer_DEFINED
+
+#include "GrTransferBuffer.h"
+#include "GrGLBufferImpl.h"
+#include "gl/GrGLInterface.h"
+
+class GrGLGpu;
+
+class GrGLTransferBuffer : public GrTransferBuffer {
+
+public:
+ typedef GrGLBufferImpl::Desc Desc;
+
+ GrGLTransferBuffer(GrGLGpu* gpu, const Desc& desc, GrGLenum type);
+
+ GrGLuint bufferID() const { return fImpl.bufferID(); }
+ size_t baseOffset() const { return fImpl.baseOffset(); }
+ GrGLenum bufferType() const { return fImpl.bufferType(); }
+
+protected:
+ void onAbandon() override;
+ void onRelease() override;
+ void setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
+ const SkString& dumpName) const override;
+
+private:
+ void* onMap() override;
+ void onUnmap() override;
+
+ GrGLGpu* getGpuGL() const {
+ SkASSERT(!this->wasDestroyed());
+ return (GrGLGpu*)(this->getGpu());
+ }
+
+ GrGLBufferImpl fImpl;
+
+ typedef GrTransferBuffer INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h
index 4a99d59058..f5a97672f3 100644
--- a/src/gpu/gl/GrGLVertexArray.h
+++ b/src/gpu/gl/GrGLVertexArray.h
@@ -13,6 +13,8 @@
#include "gl/GrGLTypes.h"
#include "SkTArray.h"
+class GrGLVertexBuffer;
+class GrGLIndexBuffer;
class GrGLGpu;
/**
diff --git a/src/gpu/gl/GrGLVertexBuffer.cpp b/src/gpu/gl/GrGLVertexBuffer.cpp
new file mode 100644
index 0000000000..2294844fc4
--- /dev/null
+++ b/src/gpu/gl/GrGLVertexBuffer.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLVertexBuffer.h"
+#include "GrGLGpu.h"
+#include "SkTraceMemoryDump.h"
+
+GrGLVertexBuffer::GrGLVertexBuffer(GrGLGpu* gpu, const Desc& desc)
+ : INHERITED(gpu, desc.fSizeInBytes, GrGLBufferImpl::kDynamicDraw_Usage == desc.fUsage,
+ 0 == desc.fID)
+ , fImpl(gpu, desc, GR_GL_ARRAY_BUFFER) {
+ this->registerWithCache();
+}
+
+void GrGLVertexBuffer::onRelease() {
+ if (!this->wasDestroyed()) {
+ fImpl.release(this->getGpuGL());
+ }
+
+ INHERITED::onRelease();
+}
+
+void GrGLVertexBuffer::onAbandon() {
+ fImpl.abandon();
+ INHERITED::onAbandon();
+}
+
+void* GrGLVertexBuffer::onMap() {
+ if (!this->wasDestroyed()) {
+ return fImpl.map(this->getGpuGL());
+ } else {
+ return nullptr;
+ }
+}
+
+void GrGLVertexBuffer::onUnmap() {
+ if (!this->wasDestroyed()) {
+ fImpl.unmap(this->getGpuGL());
+ }
+}
+
+bool GrGLVertexBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
+ if (!this->wasDestroyed()) {
+ return fImpl.updateData(this->getGpuGL(), src, srcSizeInBytes);
+ } else {
+ return false;
+ }
+}
+
+void GrGLVertexBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
+ const SkString& dumpName) const {
+ SkString buffer_id;
+ buffer_id.appendU32(this->bufferID());
+ traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_buffer",
+ buffer_id.c_str());
+}
diff --git a/src/gpu/gl/GrGLVertexBuffer.h b/src/gpu/gl/GrGLVertexBuffer.h
new file mode 100644
index 0000000000..93c6b2badd
--- /dev/null
+++ b/src/gpu/gl/GrGLVertexBuffer.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLVertexBuffer_DEFINED
+#define GrGLVertexBuffer_DEFINED
+
+#include "GrVertexBuffer.h"
+#include "GrGLBufferImpl.h"
+#include "gl/GrGLInterface.h"
+
+class GrGLGpu;
+
+class GrGLVertexBuffer : public GrVertexBuffer {
+
+public:
+ typedef GrGLBufferImpl::Desc Desc;
+
+ GrGLVertexBuffer(GrGLGpu* gpu, const Desc& desc);
+
+ GrGLuint bufferID() const { return fImpl.bufferID(); }
+ size_t baseOffset() const { return fImpl.baseOffset(); }
+
+protected:
+ void onAbandon() override;
+ void onRelease() override;
+ void setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
+ const SkString& dumpName) const override;
+
+private:
+ void* onMap() override;
+ void onUnmap() override;
+ bool onUpdateData(const void* src, size_t srcSizeInBytes) override;
+
+ GrGLGpu* getGpuGL() const {
+ SkASSERT(!this->wasDestroyed());
+ return (GrGLGpu*)(this->getGpu());
+ }
+
+ GrGLBufferImpl fImpl;
+
+ typedef GrVertexBuffer INHERITED;
+};
+
+#endif
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 35aef7a29a..7cfddbab2a 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -29,7 +29,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
fUseDrawInsteadOfClear = false; //TODO: figure this out
fMapBufferFlags = kNone_MapFlags; //TODO: figure this out
- fBufferMapThreshold = SK_MaxS32; //TODO: figure this out
+ fGeometryBufferMapThreshold = SK_MaxS32; //TODO: figure this out
fMaxRenderTargetSize = 4096; // minimum required by spec
fMaxTextureSize = 4096; // minimum required by spec
@@ -112,7 +112,7 @@ void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties,
// Assuming since we will always map in the end to upload the data we might as well just map
// from the get go. There is no hard data to suggest this is faster or slower.
- fBufferMapThreshold = 0;
+ fGeometryBufferMapThreshold = 0;
fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag;
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 5796f11d51..21e4ee358d 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -171,26 +171,18 @@ void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
}
///////////////////////////////////////////////////////////////////////////////
-GrBuffer* GrVkGpu::onCreateBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) {
- switch (type) {
- case kVertex_GrBufferType:
- SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
- kStatic_GrAccessPattern == accessPattern);
- return GrVkVertexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
- case kIndex_GrBufferType:
- SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
- kStatic_GrAccessPattern == accessPattern);
- return GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
- case kXferCpuToGpu_GrBufferType:
- SkASSERT(kStream_GrAccessPattern == accessPattern);
- return GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type);
- case kXferGpuToCpu_GrBufferType:
- SkASSERT(kStream_GrAccessPattern == accessPattern);
- return GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type);
- default:
- SkFAIL("Unknown buffer type.");
- return nullptr;
- }
+GrVertexBuffer* GrVkGpu::onCreateVertexBuffer(size_t size, bool dynamic) {
+ return GrVkVertexBuffer::Create(this, size, dynamic);
+}
+
+GrIndexBuffer* GrVkGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
+ return GrVkIndexBuffer::Create(this, size, dynamic);
+}
+
+GrTransferBuffer* GrVkGpu::onCreateTransferBuffer(size_t size, TransferType type) {
+ GrVkBuffer::Type bufferType = kCpuToGpu_TransferType ? GrVkBuffer::kCopyRead_Type
+ : GrVkBuffer::kCopyWrite_Type;
+ return GrVkTransferBuffer::Create(this, size, bufferType);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1225,9 +1217,8 @@ bool GrVkGpu::onReadPixels(GrSurface* surface,
false);
GrVkTransferBuffer* transferBuffer =
- static_cast<GrVkTransferBuffer*>(this->createBuffer(kXferGpuToCpu_GrBufferType,
- rowBytes * height,
- kStream_GrAccessPattern));
+ reinterpret_cast<GrVkTransferBuffer*>(this->createTransferBuffer(rowBytes * height,
+ kGpuToCpu_TransferType));
bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
VkOffset3D offset = {
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index a9a8a41d97..a6911f773b 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -136,7 +136,9 @@ private:
GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&,
GrWrapOwnership) override { return NULL; }
- GrBuffer* onCreateBuffer(GrBufferType, size_t size, GrAccessPattern) override;
+ GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override;
+ GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override;
+ GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) override;
void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override;
@@ -159,7 +161,7 @@ private:
bool onTransferPixels(GrSurface*,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes) override { return false; }
void onResolveRenderTarget(GrRenderTarget* target) override {}
diff --git a/src/gpu/vk/GrVkIndexBuffer.cpp b/src/gpu/vk/GrVkIndexBuffer.cpp
index 6cec856cd4..52f7bd59b7 100644
--- a/src/gpu/vk/GrVkIndexBuffer.cpp
+++ b/src/gpu/vk/GrVkIndexBuffer.cpp
@@ -10,8 +10,7 @@
GrVkIndexBuffer::GrVkIndexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
const GrVkBuffer::Resource* bufferResource)
- : INHERITED(gpu, kIndex_GrBufferType, desc.fSizeInBytes,
- desc.fDynamic ? kDynamic_GrAccessPattern : kStatic_GrAccessPattern, false)
+ : INHERITED(gpu, desc.fSizeInBytes, desc.fDynamic, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
}
@@ -48,9 +47,11 @@ void GrVkIndexBuffer::onAbandon() {
INHERITED::onAbandon();
}
-void GrVkIndexBuffer::onMap() {
+void* GrVkIndexBuffer::onMap() {
if (!this->wasDestroyed()) {
- this->GrBuffer::fMapPtr = this->vkMap(this->getVkGpu());
+ return this->vkMap(this->getVkGpu());
+ } else {
+ return NULL;
}
}
diff --git a/src/gpu/vk/GrVkIndexBuffer.h b/src/gpu/vk/GrVkIndexBuffer.h
index 4bca5a6b5c..84bbbd3377 100644
--- a/src/gpu/vk/GrVkIndexBuffer.h
+++ b/src/gpu/vk/GrVkIndexBuffer.h
@@ -8,13 +8,13 @@
#ifndef GrVkIndexBuffer_DEFINED
#define GrVkIndexBuffer_DEFINED
-#include "GrBuffer.h"
+#include "GrIndexBuffer.h"
#include "GrVkBuffer.h"
#include "vk/GrVkInterface.h"
class GrVkGpu;
-class GrVkIndexBuffer : public GrBuffer, public GrVkBuffer {
+class GrVkIndexBuffer : public GrIndexBuffer, public GrVkBuffer {
public:
static GrVkIndexBuffer* Create(GrVkGpu* gpu, size_t size, bool dynamic);
@@ -27,13 +27,13 @@ private:
GrVkIndexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
const GrVkBuffer::Resource* resource);
- void onMap() override;
+ void* onMap() override;
void onUnmap() override;
bool onUpdateData(const void* src, size_t srcSizeInBytes) override;
GrVkGpu* getVkGpu() const;
- typedef GrBuffer INHERITED;
+ typedef GrIndexBuffer INHERITED;
};
#endif
diff --git a/src/gpu/vk/GrVkTransferBuffer.cpp b/src/gpu/vk/GrVkTransferBuffer.cpp
index 43fd3af9a9..3730627764 100644
--- a/src/gpu/vk/GrVkTransferBuffer.cpp
+++ b/src/gpu/vk/GrVkTransferBuffer.cpp
@@ -31,9 +31,7 @@ GrVkTransferBuffer* GrVkTransferBuffer::Create(GrVkGpu* gpu, size_t size, GrVkBu
GrVkTransferBuffer::GrVkTransferBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
const GrVkBuffer::Resource* bufferResource)
- : INHERITED(gpu, kCopyRead_Type == desc.fType ?
- kXferCpuToGpu_GrBufferType : kXferGpuToCpu_GrBufferType,
- desc.fSizeInBytes, kStream_GrAccessPattern, false)
+ : INHERITED(gpu, desc.fSizeInBytes)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
}
diff --git a/src/gpu/vk/GrVkTransferBuffer.h b/src/gpu/vk/GrVkTransferBuffer.h
index c6ca2147b3..f978df95fd 100644
--- a/src/gpu/vk/GrVkTransferBuffer.h
+++ b/src/gpu/vk/GrVkTransferBuffer.h
@@ -8,13 +8,13 @@
#ifndef GrVkTransferBuffer_DEFINED
#define GrVkTransferBuffer_DEFINED
-#include "GrBuffer.h"
+#include "GrTransferBuffer.h"
#include "GrVkBuffer.h"
#include "vk/GrVkInterface.h"
class GrVkGpu;
-class GrVkTransferBuffer : public GrBuffer, public GrVkBuffer {
+class GrVkTransferBuffer : public GrTransferBuffer, public GrVkBuffer {
public:
static GrVkTransferBuffer* Create(GrVkGpu* gpu, size_t size, GrVkBuffer::Type type);
@@ -29,9 +29,11 @@ private:
void setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
const SkString& dumpName) const override;
- void onMap() override {
+ void* onMap() override {
if (!this->wasDestroyed()) {
- this->GrBuffer::fMapPtr = this->vkMap(this->getVkGpu());
+ return this->vkMap(this->getVkGpu());
+ } else {
+ return nullptr;
}
}
@@ -41,17 +43,12 @@ private:
}
}
- bool onUpdateData(const void* src, size_t srcSizeInBytes) override {
- SkFAIL("Not implemented for transfer buffers.");
- return false;
- }
-
GrVkGpu* getVkGpu() const {
SkASSERT(!this->wasDestroyed());
return reinterpret_cast<GrVkGpu*>(this->getGpu());
}
- typedef GrBuffer INHERITED;
+ typedef GrTransferBuffer INHERITED;
};
#endif
diff --git a/src/gpu/vk/GrVkVertexBuffer.cpp b/src/gpu/vk/GrVkVertexBuffer.cpp
index 1d3eadb42c..46c6d28f23 100644
--- a/src/gpu/vk/GrVkVertexBuffer.cpp
+++ b/src/gpu/vk/GrVkVertexBuffer.cpp
@@ -10,8 +10,7 @@
GrVkVertexBuffer::GrVkVertexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
const GrVkBuffer::Resource* bufferResource)
- : INHERITED(gpu, kVertex_GrBufferType, desc.fSizeInBytes,
- desc.fDynamic ? kDynamic_GrAccessPattern : kStatic_GrAccessPattern, false)
+ : INHERITED(gpu, desc.fSizeInBytes, desc.fDynamic, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
}
@@ -47,9 +46,11 @@ void GrVkVertexBuffer::onAbandon() {
INHERITED::onAbandon();
}
-void GrVkVertexBuffer::onMap() {
+void* GrVkVertexBuffer::onMap() {
if (!this->wasDestroyed()) {
- this->GrBuffer::fMapPtr = this->vkMap(this->getVkGpu());
+ return this->vkMap(this->getVkGpu());
+ } else {
+ return NULL;
}
}
diff --git a/src/gpu/vk/GrVkVertexBuffer.h b/src/gpu/vk/GrVkVertexBuffer.h
index 7786f6275c..82f00597b7 100644
--- a/src/gpu/vk/GrVkVertexBuffer.h
+++ b/src/gpu/vk/GrVkVertexBuffer.h
@@ -8,13 +8,13 @@
#ifndef GrVkVertexBuffer_DEFINED
#define GrVkVertexBuffer_DEFINED
-#include "GrBuffer.h"
+#include "GrVertexBuffer.h"
#include "GrVkBuffer.h"
#include "vk/GrVkInterface.h"
class GrVkGpu;
-class GrVkVertexBuffer : public GrBuffer, public GrVkBuffer {
+class GrVkVertexBuffer : public GrVertexBuffer, public GrVkBuffer {
public:
static GrVkVertexBuffer* Create(GrVkGpu* gpu, size_t size, bool dynamic);
@@ -26,13 +26,13 @@ private:
GrVkVertexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
const GrVkBuffer::Resource* resource);
- void onMap() override;
+ void* onMap() override;
void onUnmap() override;
bool onUpdateData(const void* src, size_t srcSizeInBytes) override;
GrVkGpu* getVkGpu() const;
- typedef GrBuffer INHERITED;
+ typedef GrVertexBuffer INHERITED;
};
#endif