aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrTypesPriv.h11
-rw-r--r--src/gpu/GrBuffer.h14
-rw-r--r--src/gpu/GrBufferAllocPool.cpp2
-rw-r--r--src/gpu/GrGpu.cpp5
-rw-r--r--src/gpu/GrGpu.h8
-rw-r--r--src/gpu/GrResourceProvider.cpp8
-rw-r--r--src/gpu/GrResourceProvider.h12
-rw-r--r--src/gpu/batches/GrTessellatingPathRenderer.cpp2
-rw-r--r--src/gpu/gl/GrGLBuffer.cpp170
-rw-r--r--src/gpu/gl/GrGLBuffer.h21
-rw-r--r--src/gpu/gl/GrGLCaps.cpp1
-rw-r--r--src/gpu/gl/GrGLGpu.cpp639
-rw-r--r--src/gpu/gl/GrGLGpu.h159
-rw-r--r--src/gpu/gl/GrGLVertexArray.cpp33
-rw-r--r--src/gpu/gl/GrGLVertexArray.h29
-rw-r--r--src/gpu/vk/GrVkGpu.cpp6
-rw-r--r--src/gpu/vk/GrVkGpu.h2
-rw-r--r--src/gpu/vk/GrVkIndexBuffer.cpp2
-rw-r--r--src/gpu/vk/GrVkTransferBuffer.cpp7
-rw-r--r--src/gpu/vk/GrVkVertexBuffer.cpp2
-rw-r--r--tools/gpu/GrTest.cpp2
21 files changed, 512 insertions, 623 deletions
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
index bf8ea49063..39386f0140 100644
--- a/include/gpu/GrTypesPriv.h
+++ b/include/gpu/GrTypesPriv.h
@@ -406,11 +406,22 @@ private:
enum GrBufferType {
kVertex_GrBufferType,
kIndex_GrBufferType,
+ kTexel_GrBufferType,
+ kDrawIndirect_GrBufferType,
kXferCpuToGpu_GrBufferType,
kXferGpuToCpu_GrBufferType,
kLast_GrBufferType = kXferGpuToCpu_GrBufferType
};
+static const int kGrBufferTypeCount = kLast_GrBufferType + 1;
+
+static inline bool GrBufferTypeIsVertexOrIndex(GrBufferType type) {
+ SkASSERT(type >= 0 && type < kGrBufferTypeCount);
+ return type <= kIndex_GrBufferType;
+
+ GR_STATIC_ASSERT(0 == kVertex_GrBufferType);
+ GR_STATIC_ASSERT(1 == kIndex_GrBufferType);
+}
/**
* Provides a performance hint regarding the frequency at which a data store will be accessed.
diff --git a/src/gpu/GrBuffer.h b/src/gpu/GrBuffer.h
index 4fadba6aa7..7e04577543 100644
--- a/src/gpu/GrBuffer.h
+++ b/src/gpu/GrBuffer.h
@@ -18,22 +18,20 @@ 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,
+ static void ComputeScratchKeyForDynamicBuffer(size_t size, GrBufferType intendedType,
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[0] = intendedType;
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; }
/**
@@ -110,17 +108,16 @@ public:
}
protected:
- GrBuffer(GrGpu* gpu, GrBufferType type, size_t gpuMemorySize, GrAccessPattern accessPattern,
- bool cpuBacked)
+ GrBuffer(GrGpu* gpu, size_t gpuMemorySize, GrBufferType intendedType,
+ 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);
+ ComputeScratchKeyForDynamicBuffer(fGpuMemorySize, intendedType, &key);
this->setScratchKey(key);
}
}
@@ -134,7 +131,6 @@ private:
virtual void onUnmap() = 0;
virtual bool onUpdateData(const void* src, size_t srcSizeInBytes) = 0;
- GrBufferType fType;
size_t fGpuMemorySize;
GrAccessPattern fAccessPattern;
bool fCPUBacked;
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index 278cf86bfd..d19604c718 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -319,7 +319,7 @@ GrBuffer* GrBufferAllocPool::getBuffer(size_t size) {
// 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);
+ return rp->createBuffer(size, fBufferType, kDynamic_GrAccessPattern, kFlags);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index bc11b4b9c6..6b815b6971 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -235,9 +235,10 @@ GrRenderTarget* GrGpu::wrapBackendTextureAsRenderTarget(const GrBackendTextureDe
return this->onWrapBackendTextureAsRenderTarget(desc);
}
-GrBuffer* GrGpu::createBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) {
+GrBuffer* GrGpu::createBuffer(size_t size, GrBufferType intendedType,
+ GrAccessPattern accessPattern) {
this->handleDirtyContext();
- GrBuffer* buffer = this->onCreateBuffer(type, size, accessPattern);
+ GrBuffer* buffer = this->onCreateBuffer(size, intendedType, accessPattern);
if (!this->caps()->reuseScratchBuffers()) {
buffer->resourcePriv().removeScratchKey();
}
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index b3251dc14f..d0a290fd22 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -135,9 +135,13 @@ public:
/**
* Creates a buffer.
*
+ * @param size size of buffer to create.
+ * @param intendedType hint to the graphics subsystem about what the buffer will be used for.
+ * @param accessPattern hint to the graphics subsystem about how the data will be accessed.
+ *
* @return the buffer if successful, otherwise nullptr.
*/
- GrBuffer* createBuffer(GrBufferType, size_t size, GrAccessPattern);
+ GrBuffer* createBuffer(size_t size, GrBufferType intendedType, GrAccessPattern accessPattern);
/**
* Resolves MSAA.
@@ -533,7 +537,7 @@ private:
virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
GrWrapOwnership) = 0;
virtual GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&) = 0;
- virtual GrBuffer* onCreateBuffer(GrBufferType, size_t size, GrAccessPattern) = 0;
+ virtual GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern) = 0;
// overridden by backend-specific derived class to perform the clear.
virtual void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) = 0;
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 238276d799..4c60f079a7 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -32,7 +32,7 @@ const GrBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* p
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,
+ GrBuffer* buffer = this->createBuffer(bufferSize, kIndex_GrBufferType, kStatic_GrAccessPattern,
kNoPendingIO_Flag);
if (!buffer) {
return nullptr;
@@ -88,7 +88,7 @@ GrPathRange* GrResourceProvider::createGlyphs(const SkTypeface* tf, const SkDesc
return this->gpu()->pathRendering()->createGlyphs(tf, desc, stroke);
}
-GrBuffer* GrResourceProvider::createBuffer(GrBufferType type, size_t size,
+GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
GrAccessPattern accessPattern, uint32_t flags) {
if (this->isAbandoned()) {
return nullptr;
@@ -100,7 +100,7 @@ GrBuffer* GrResourceProvider::createBuffer(GrBufferType type, size_t size,
size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size)));
GrScratchKey key;
- GrBuffer::ComputeScratchKeyForDynamicBuffer(type, size, &key);
+ GrBuffer::ComputeScratchKeyForDynamicBuffer(size, intendedType, &key);
uint32_t scratchFlags = 0;
if (flags & kNoPendingIO_Flag) {
scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
@@ -112,7 +112,7 @@ GrBuffer* GrResourceProvider::createBuffer(GrBufferType type, size_t size,
return static_cast<GrBuffer*>(resource);
}
}
- return this->gpu()->createBuffer(type, size, accessPattern);
+ return this->gpu()->createBuffer(size, intendedType, accessPattern);
}
GrBatchAtlas* GrResourceProvider::createAtlas(GrPixelConfig config,
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index fe0b5defa5..d8e595a47b 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -102,7 +102,17 @@ public:
kNoPendingIO_Flag = kNoPendingIO_ScratchTextureFlag,
};
- GrBuffer* createBuffer(GrBufferType, size_t size, GrAccessPattern, uint32_t flags);
+ /**
+ * Returns a buffer.
+ *
+ * @param size minimum size of buffer to return.
+ * @param intendedType hint to the graphics subsystem about what the buffer will be used for.
+ * @param GrAccessPattern hint to the graphics subsystem about how the data will be accessed.
+ * @param flags see Flags enum.
+ *
+ * @return the buffer if successful, otherwise nullptr.
+ */
+ GrBuffer* createBuffer(size_t size, GrBufferType intendedType, GrAccessPattern, uint32_t flags);
GrTexture* createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) {
SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index 1c17134867..39aa50c597 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -69,7 +69,7 @@ public:
SkPoint* lock(int vertexCount) override {
size_t size = vertexCount * sizeof(SkPoint);
fVertexBuffer.reset(fResourceProvider->createBuffer(
- kVertex_GrBufferType, size, kStatic_GrAccessPattern, 0));
+ size, kVertex_GrBufferType, kStatic_GrAccessPattern, 0));
if (!fVertexBuffer.get()) {
return nullptr;
}
diff --git a/src/gpu/gl/GrGLBuffer.cpp b/src/gpu/gl/GrGLBuffer.cpp
index 5d2d72bf35..c5bbb0a9dd 100644
--- a/src/gpu/gl/GrGLBuffer.cpp
+++ b/src/gpu/gl/GrGLBuffer.cpp
@@ -28,14 +28,14 @@
#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);
+GrGLBuffer* GrGLBuffer::Create(GrGLGpu* gpu, size_t size, GrBufferType intendedType,
+ GrAccessPattern accessPattern, const void* data) {
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) {
+ GrBufferTypeIsVertexOrIndex(intendedType) &&
+ kDynamic_GrAccessPattern == accessPattern;
+ SkAutoTUnref<GrGLBuffer> buffer(new GrGLBuffer(gpu, size, intendedType, accessPattern,
+ cpuBacked, data));
+ if (!cpuBacked && 0 == buffer->bufferID()) {
return nullptr;
}
return buffer.release();
@@ -45,94 +45,81 @@ GrGLBuffer* GrGLBuffer::Create(GrGLGpu* gpu, GrBufferType type, size_t size,
// 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);
-
+inline static GrGLenum gr_to_gl_access_pattern(GrBufferType bufferType,
+ GrAccessPattern accessPattern) {
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
+ DYNAMIC_DRAW_PARAM, // TODO: Do we really want to use STREAM_DRAW here on non-Chromium?
+ GR_GL_STATIC_DRAW, // kStatic_GrAccessPattern
+ GR_GL_STREAM_DRAW // kStream_GrAccessPattern
};
+
static const GrGLenum readUsages[] = {
- GR_GL_DYNAMIC_READ,
- GR_GL_STATIC_READ,
- GR_GL_STREAM_READ
+ GR_GL_DYNAMIC_READ, // kDynamic_GrAccessPattern
+ GR_GL_STATIC_READ, // kStatic_GrAccessPattern
+ GR_GL_STREAM_READ // kStream_GrAccessPattern
};
+
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);
+ static GrGLenum const* const usageTypes[] = {
+ drawUsages, // kVertex_GrBufferType,
+ drawUsages, // kIndex_GrBufferType,
+ drawUsages, // kTexel_GrBufferType,
+ drawUsages, // kDrawIndirect_GrBufferType,
+ drawUsages, // kXferCpuToGpu_GrBufferType,
+ readUsages // kXferGpuToCpu_GrBufferType,
+ };
+
+ GR_STATIC_ASSERT(0 == kVertex_GrBufferType);
+ GR_STATIC_ASSERT(1 == kIndex_GrBufferType);
+ GR_STATIC_ASSERT(2 == kTexel_GrBufferType);
+ GR_STATIC_ASSERT(3 == kDrawIndirect_GrBufferType);
+ GR_STATIC_ASSERT(4 == kXferCpuToGpu_GrBufferType);
+ GR_STATIC_ASSERT(5 == kXferGpuToCpu_GrBufferType);
+ GR_STATIC_ASSERT(SK_ARRAY_COUNT(usageTypes) == kGrBufferTypeCount);
+
+ SkASSERT(bufferType >= 0 && bufferType <= kLast_GrBufferType);
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;
- }
+ return usageTypes[bufferType][accessPattern];
}
-GrGLBuffer::GrGLBuffer(GrGLGpu* gpu, GrBufferType type, size_t size, GrAccessPattern accessPattern,
- bool cpuBacked)
- : INHERITED(gpu, type, size, accessPattern, cpuBacked),
+GrGLBuffer::GrGLBuffer(GrGLGpu* gpu, size_t size, GrBufferType intendedType,
+ GrAccessPattern accessPattern, bool cpuBacked, const void* data)
+ : INHERITED(gpu, size, intendedType, accessPattern, cpuBacked),
fCPUData(nullptr),
- fTarget(0),
+ fIntendedType(intendedType),
fBufferID(0),
fSizeInBytes(size),
- fUsage(0),
+ fUsage(gr_to_gl_access_pattern(intendedType, accessPattern)),
fGLSizeInBytes(0) {
- if (cpuBacked) {
+ if (this->isCPUBacked()) {
+ // Core profile uses vertex array objects, which disallow client side arrays.
+ SkASSERT(!gpu->glCaps().isCoreProfile());
if (gpu->caps()->mustClearUploadedBufferData()) {
fCPUData = sk_calloc_throw(fSizeInBytes);
} else {
fCPUData = sk_malloc_flags(fSizeInBytes, SK_MALLOC_THROW);
}
- SkASSERT(kVertex_GrBufferType == type || kIndex_GrBufferType == type);
- fTarget = kVertex_GrBufferType == type ? GR_GL_ARRAY_BUFFER : GR_GL_ELEMENT_ARRAY_BUFFER;
+ if (data) {
+ memcpy(fCPUData, data, fSizeInBytes);
+ }
} else {
GL_CALL(GenBuffers(1, &fBufferID));
- fSizeInBytes = size;
- get_target_and_usage(type, accessPattern, gpu->glCaps(), &fTarget, &fUsage);
if (fBufferID) {
- gpu->bindBuffer(fBufferID, fTarget);
+ GrGLenum target = gpu->bindBuffer(fIntendedType, this);
CLEAR_ERROR_BEFORE_ALLOC(gpu->glInterface());
// make sure driver can allocate memory for this buffer
- GL_ALLOC_CALL(gpu->glInterface(), BufferData(fTarget,
+ GL_ALLOC_CALL(gpu->glInterface(), BufferData(target,
(GrGLsizeiptr) fSizeInBytes,
- nullptr, // data ptr
+ data,
fUsage));
if (CHECK_ALLOC_ERROR(gpu->glInterface()) != GR_GL_NO_ERROR) {
- gpu->releaseBuffer(fBufferID, fTarget);
+ GL_CALL(DeleteBuffers(1, &fBufferID));
fBufferID = 0;
} else {
fGLSizeInBytes = fSizeInBytes;
@@ -161,7 +148,7 @@ void GrGLBuffer::onRelease() {
sk_free(fCPUData);
fCPUData = nullptr;
} else if (fBufferID) {
- this->glGpu()->releaseBuffer(fBufferID, fTarget);
+ GL_CALL(DeleteBuffers(1, &fBufferID));
fBufferID = 0;
fGLSizeInBytes = 0;
}
@@ -196,44 +183,47 @@ void GrGLBuffer::onMap() {
return;
}
- bool readOnly = (kXferGpuToCpu_GrBufferType == this->type());
+ // TODO: Make this a function parameter.
+ bool readOnly = (kXferGpuToCpu_GrBufferType == fIntendedType);
// 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);
+ case GrGLCaps::kMapBuffer_MapBufferType: {
+ GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
// 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(BufferData(target, fSizeInBytes, nullptr, fUsage));
}
- GL_CALL_RET(fMapPtr, MapBuffer(fTarget, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
+ GL_CALL_RET(fMapPtr, MapBuffer(target, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
break;
+ }
case GrGLCaps::kMapBufferRange_MapBufferType: {
- this->glGpu()->bindBuffer(fBufferID, fTarget);
+ GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
// Make sure the GL buffer size agrees with fDesc before mapping.
if (fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
+ GL_CALL(BufferData(target, 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()) {
+ if (kXferCpuToGpu_GrBufferType != fIntendedType) {
+ // TODO: Make this a function parameter.
writeAccess |= GR_GL_MAP_INVALIDATE_BUFFER_BIT;
}
- GL_CALL_RET(fMapPtr, MapBufferRange(fTarget, 0, fSizeInBytes,
+ GL_CALL_RET(fMapPtr, MapBufferRange(target, 0, fSizeInBytes,
readOnly ? GR_GL_MAP_READ_BIT : writeAccess));
break;
}
- case GrGLCaps::kChromium_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
+ case GrGLCaps::kChromium_MapBufferType: {
+ GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
// Make sure the GL buffer size agrees with fDesc before mapping.
if (fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
+ GL_CALL(BufferData(target, fSizeInBytes, nullptr, fUsage));
}
- GL_CALL_RET(fMapPtr, MapBufferSubData(fTarget, 0, fSizeInBytes,
+ GL_CALL_RET(fMapPtr, MapBufferSubData(target, 0, fSizeInBytes,
readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
break;
+ }
}
fGLSizeInBytes = fSizeInBytes;
VALIDATE();
@@ -256,12 +246,13 @@ void GrGLBuffer::onUnmap() {
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));
+ case GrGLCaps::kMapBufferRange_MapBufferType: {
+ GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
+ GL_CALL(UnmapBuffer(target));
break;
+ }
case GrGLCaps::kChromium_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
+ this->glGpu()->bindBuffer(fIntendedType, this); // TODO: Is this needed?
GL_CALL(UnmapBufferSubData(fMapPtr));
break;
}
@@ -274,7 +265,6 @@ bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
}
SkASSERT(!this->isMapped());
- SkASSERT(GR_GL_ARRAY_BUFFER == fTarget || GR_GL_ELEMENT_ARRAY_BUFFER == fTarget);
VALIDATE();
if (srcSizeInBytes > fSizeInBytes) {
return false;
@@ -285,11 +275,11 @@ bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
}
SkASSERT(srcSizeInBytes <= fSizeInBytes);
// bindbuffer handles dirty context
- this->glGpu()->bindBuffer(fBufferID, fTarget);
+ GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
#if GR_GL_USE_BUFFER_DATA_NULL_HINT
if (fSizeInBytes == srcSizeInBytes) {
- GL_CALL(BufferData(fTarget, (GrGLsizeiptr) srcSizeInBytes, src, fUsage));
+ GL_CALL(BufferData(target, (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
@@ -298,8 +288,8 @@ bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
// 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));
+ GL_CALL(BufferData(target, fSizeInBytes, nullptr, fUsage));
+ GL_CALL(BufferSubData(target, 0, (GrGLsizeiptr) srcSizeInBytes, src));
}
fGLSizeInBytes = fSizeInBytes;
#else
@@ -324,10 +314,6 @@ void GrGLBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
#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);
diff --git a/src/gpu/gl/GrGLBuffer.h b/src/gpu/gl/GrGLBuffer.h
index 90d2c43dfa..b3b4feb002 100644
--- a/src/gpu/gl/GrGLBuffer.h
+++ b/src/gpu/gl/GrGLBuffer.h
@@ -16,19 +16,20 @@ class GrGLCaps;
class GrGLBuffer : public GrBuffer {
public:
- static GrGLBuffer* Create(GrGLGpu*, GrBufferType, size_t size, GrAccessPattern);
+ static GrGLBuffer* Create(GrGLGpu*, size_t size, GrBufferType intendedType, GrAccessPattern,
+ const void* data = nullptr);
~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);
+ GrGLBuffer(GrGLGpu*, size_t size, GrBufferType intendedType, GrAccessPattern, bool cpuBacked,
+ const void* data);
void onAbandon() override;
void onRelease() override;
@@ -47,13 +48,13 @@ private:
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.
+ void* fCPUData;
+ GrBufferType fIntendedType;
+ 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;
};
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 7319164913..e850dcabaf 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -136,6 +136,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
// data for dynamic content on these GPUs. Perhaps we should read the renderer string and
// limit this decision to specific GPU families rather than basing it on the vendor alone.
if (!GR_GL_MUST_USE_VBO &&
+ !fIsCoreProfile &&
(kARM_GrGLVendor == ctxInfo.vendor() ||
kImagination_GrGLVendor == ctxInfo.vendor() ||
kQualcomm_GrGLVendor == ctxInfo.vendor())) {
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 0063b3d16c..e8b5755849 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -188,12 +188,45 @@ static bool gPrintStartupSpew;
GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
: GrGpu(context)
- , fGLContext(ctx) {
+ , fGLContext(ctx)
+ , fProgramCache(new ProgramCache(this))
+ , fHWProgramID(0)
+ , fTempSrcFBOID(0)
+ , fTempDstFBOID(0)
+ , fStencilClearFBOID(0)
+ , fHWPLSEnabled(false)
+ , fPLSHasBeenUsed(false)
+ , fHWMinSampleShading(0.0) {
+ for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
+ fCopyPrograms[i].fProgram = 0;
+ }
+ fWireRectProgram.fProgram = 0;
+ fPLSSetupProgram.fProgram = 0;
+
SkASSERT(ctx);
fCaps.reset(SkRef(ctx->caps()));
fHWBoundTextureUniqueIDs.reset(this->glCaps().glslCaps()->maxCombinedSamplers());
+ fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER;
+ fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER;
+ fHWBufferState[kTexel_GrBufferType].fGLTarget = GR_GL_TEXTURE_BUFFER;
+ fHWBufferState[kDrawIndirect_GrBufferType].fGLTarget = GR_GL_DRAW_INDIRECT_BUFFER;
+ if (GrGLCaps::kChromium_TransferBufferType == this->glCaps().transferBufferType()) {
+ fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget =
+ GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM;
+ fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget =
+ GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
+ } else {
+ fHWBufferState[kXferCpuToGpu_GrBufferType].fGLTarget = GR_GL_PIXEL_UNPACK_BUFFER;
+ fHWBufferState[kXferGpuToCpu_GrBufferType].fGLTarget = GR_GL_PIXEL_PACK_BUFFER;
+ }
+ GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState));
+
+ if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
+ fPathRendering.reset(new GrGLPathRendering(this));
+ }
+
GrGLClearErr(this->glInterface());
if (gPrintStartupSpew) {
const GrGLubyte* vendor;
@@ -212,35 +245,15 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
SkDebugf("\n");
SkDebugf("%s", this->glCaps().dump().c_str());
}
-
- fProgramCache = new ProgramCache(this);
-
- fHWProgramID = 0;
- fTempSrcFBOID = 0;
- fTempDstFBOID = 0;
- fStencilClearFBOID = 0;
-
- if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
- fPathRendering.reset(new GrGLPathRendering(this));
- }
- this->createCopyPrograms();
- fWireRectProgram.fProgram = 0;
- fWireRectArrayBuffer = 0;
- if (this->glCaps().shaderCaps()->plsPathRenderingSupport()) {
- this->createPLSSetupProgram();
- }
- else {
- memset(&fPLSSetupProgram, 0, sizeof(fPLSSetupProgram));
- }
- fHWPLSEnabled = false;
- fPLSHasBeenUsed = false;
- fHWMinSampleShading = 0.0;
}
GrGLGpu::~GrGLGpu() {
- // Delete the path rendering explicitly, since it will need working gpu object to release the
- // resources the object itself holds.
+ // Ensure any GrGpuResource objects get deleted first, since they may require a working GrGLGpu
+ // to release the resources held by the objects themselves.
fPathRendering.reset();
+ fCopyProgramArrayBuffer.reset();
+ fWireRectArrayBuffer.reset();
+ fPLSSetupProgram.fArrayBuffer.reset();
if (0 != fHWProgramID) {
// detach the current program so there is no confusion on OpenGL's part
@@ -264,22 +277,10 @@ GrGLGpu::~GrGLGpu() {
}
}
- if (0 != fCopyProgramArrayBuffer) {
- GL_CALL(DeleteBuffers(1, &fCopyProgramArrayBuffer));
- }
-
if (0 != fWireRectProgram.fProgram) {
GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
}
- if (0 != fWireRectArrayBuffer) {
- GL_CALL(DeleteBuffers(1, &fWireRectArrayBuffer));
- }
-
- if (0 != fPLSSetupProgram.fArrayBuffer) {
- GL_CALL(DeleteBuffers(1, &fPLSSetupProgram.fArrayBuffer));
- }
-
if (0 != fPLSSetupProgram.fProgram) {
GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram));
}
@@ -287,7 +288,28 @@ GrGLGpu::~GrGLGpu() {
delete fProgramCache;
}
-void GrGLGpu::createPLSSetupProgram() {
+bool GrGLGpu::createPLSSetupProgram() {
+ if (!fPLSSetupProgram.fArrayBuffer) {
+ static const GrGLfloat vdata[] = {
+ 0, 0,
+ 0, 1,
+ 1, 0,
+ 1, 1
+ };
+ fPLSSetupProgram.fArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata),
+ kVertex_GrBufferType,
+ kStatic_GrAccessPattern, vdata));
+ if (!fPLSSetupProgram.fArrayBuffer) {
+ return false;
+ }
+ }
+
+ SkASSERT(!fPLSSetupProgram.fProgram);
+ GL_CALL_RET(fPLSSetupProgram.fProgram, CreateProgram());
+ if (!fPLSSetupProgram.fProgram) {
+ return false;
+ }
+
const GrGLSLCaps* glslCaps = this->glCaps().glslCaps();
const char* version = glslCaps->versionDeclString();
@@ -347,7 +369,7 @@ void GrGLGpu::createPLSSetupProgram() {
" pls.windings = ivec4(0, 0, 0, 0);\n"
"}"
);
- GL_CALL_RET(fPLSSetupProgram.fProgram, CreateProgram());
+
const char* str;
GrGLint length;
@@ -371,19 +393,7 @@ void GrGLGpu::createPLSSetupProgram() {
GL_CALL(DeleteShader(vshader));
GL_CALL(DeleteShader(fshader));
- GL_CALL(GenBuffers(1, &fPLSSetupProgram.fArrayBuffer));
- fHWGeometryState.setVertexBufferID(this, fPLSSetupProgram.fArrayBuffer);
- static const GrGLfloat vdata[] = {
- 0, 0,
- 0, 1,
- 1, 0,
- 1, 1
- };
- GL_ALLOC_CALL(this->glInterface(),
- BufferData(GR_GL_ARRAY_BUFFER,
- (GrGLsizeiptr) sizeof(vdata),
- vdata, // data ptr
- GR_GL_STATIC_DRAW));
+ return true;
}
void GrGLGpu::disconnect(DisconnectType type) {
@@ -401,9 +411,6 @@ void GrGLGpu::disconnect(DisconnectType type) {
if (fStencilClearFBOID) {
GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID));
}
- if (fCopyProgramArrayBuffer) {
- GL_CALL(DeleteBuffers(1, &fCopyProgramArrayBuffer));
- }
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
if (fCopyPrograms[i].fProgram) {
GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram));
@@ -412,16 +419,9 @@ void GrGLGpu::disconnect(DisconnectType type) {
if (fWireRectProgram.fProgram) {
GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
}
- if (fWireRectArrayBuffer) {
- GL_CALL(DeleteBuffers(1, &fWireRectArrayBuffer));
- }
-
if (fPLSSetupProgram.fProgram) {
GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram));
}
- if (fPLSSetupProgram.fArrayBuffer) {
- GL_CALL(DeleteBuffers(1, &fPLSSetupProgram.fArrayBuffer));
- }
} else {
if (fProgramCache) {
fProgramCache->abandon();
@@ -435,14 +435,14 @@ void GrGLGpu::disconnect(DisconnectType type) {
fTempSrcFBOID = 0;
fTempDstFBOID = 0;
fStencilClearFBOID = 0;
- fCopyProgramArrayBuffer = 0;
+ fCopyProgramArrayBuffer.reset();
for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
fCopyPrograms[i].fProgram = 0;
}
fWireRectProgram.fProgram = 0;
- fWireRectArrayBuffer = 0;
+ fWireRectArrayBuffer.reset();
fPLSSetupProgram.fProgram = 0;
- fPLSSetupProgram.fArrayBuffer = 0;
+ fPLSSetupProgram.fArrayBuffer.reset();
if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
this->glPathRendering()->disconnect(type);
}
@@ -456,8 +456,10 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
GL_CALL(Disable(GR_GL_DEPTH_TEST));
GL_CALL(DepthMask(GR_GL_FALSE));
- fHWBoundTextureBufferIDIsValid = false;
- fHWBoundDrawIndirectBufferIDIsValid = false;
+ fHWBufferState[kTexel_GrBufferType].invalidate();
+ fHWBufferState[kDrawIndirect_GrBufferType].invalidate();
+ fHWBufferState[kXferCpuToGpu_GrBufferType].invalidate();
+ fHWBufferState[kXferGpuToCpu_GrBufferType].invalidate();
fHWDrawFace = GrPipelineBuilder::kInvalid_DrawFace;
@@ -538,7 +540,9 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
// Vertex
if (resetBits & kVertex_GrGLBackendState) {
- fHWGeometryState.invalidate();
+ fHWVertexArrayState.invalidate();
+ fHWBufferState[kVertex_GrBufferType].invalidate();
+ fHWBufferState[kIndex_GrBufferType].invalidate();
}
if (resetBits & kRenderTarget_GrGLBackendState) {
@@ -900,11 +904,10 @@ bool GrGLGpu::onTransferPixels(GrSurface* surface,
this->setScratchTextureUnit();
GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
- SkASSERT(kXferCpuToGpu_GrBufferType == transferBuffer->type());
SkASSERT(!transferBuffer->isMapped());
SkASSERT(!transferBuffer->isCPUBacked());
const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer);
- this->bindBuffer(glBuffer->bufferID(), glBuffer->target());
+ this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer);
bool success = false;
GrMipLevel mipLevel;
@@ -1974,8 +1977,9 @@ 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);
+GrBuffer* GrGLGpu::onCreateBuffer(size_t size, GrBufferType intendedType,
+ GrAccessPattern accessPattern) {
+ return GrGLBuffer::Create(this, size, intendedType, accessPattern);
}
void GrGLGpu::flushScissor(const GrScissorState& scissorState,
@@ -2077,22 +2081,21 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
SkASSERT(vbuf);
SkASSERT(!vbuf->isMapped());
- SkASSERT(kVertex_GrBufferType == vbuf->type());
- const GrGLBuffer* ibuf = nullptr;
+ GrGLAttribArrayState* attribState;
if (mesh.isIndexed()) {
SkASSERT(indexOffsetInBytes);
*indexOffsetInBytes = 0;
- ibuf = static_cast<const GrGLBuffer*>(mesh.indexBuffer());
+ const GrGLBuffer* ibuf = static_cast<const GrGLBuffer*>(mesh.indexBuffer());
SkASSERT(ibuf);
SkASSERT(!ibuf->isMapped());
- SkASSERT(kIndex_GrBufferType == ibuf->type());
*indexOffsetInBytes += ibuf->baseOffset();
+ attribState = fHWVertexArrayState.bindInternalVertexArray(this, ibuf);
+ } else {
+ attribState = fHWVertexArrayState.bindInternalVertexArray(this);
}
- GrGLAttribArrayState* attribState =
- fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
int vaCount = primProc.numAttribs();
if (vaCount > 0) {
@@ -2112,7 +2115,7 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
GrVertexAttribType attribType = attrib.fType;
attribState->set(this,
attribIndex,
- vbuf->bufferID(),
+ vbuf,
attribType,
stride,
reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + offset));
@@ -2122,57 +2125,26 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
}
}
-void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) {
+GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrGLBuffer* buffer) {
this->handleDirtyContext();
- switch (type) {
- case GR_GL_ARRAY_BUFFER:
- this->bindVertexBuffer(id);
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- this->bindIndexBufferAndDefaultVertexArray(id);
- break;
- case GR_GL_TEXTURE_BUFFER:
- if (!fHWBoundTextureBufferIDIsValid || id != fHWBoundTextureBufferID) {
- GR_GL_CALL(this->glInterface(), BindBuffer(type, id));
- fHWBoundTextureBufferID = id;
- fHWBoundTextureBufferIDIsValid = true;
- }
- break;
- case GR_GL_DRAW_INDIRECT_BUFFER:
- if (!fHWBoundDrawIndirectBufferIDIsValid || id != fHWBoundDrawIndirectBufferID) {
- GR_GL_CALL(this->glInterface(), BindBuffer(type, id));
- fHWBoundDrawIndirectBufferID = id;
- fHWBoundDrawIndirectBufferIDIsValid = true;
- }
- break;
- default:
- SkDebugf("WARNING: buffer target 0x%x is not tracked by GrGLGpu.\n", type);
- GR_GL_CALL(this->glInterface(), BindBuffer(type, id));
- break;
+
+ // Index buffer state is tied to the vertex array.
+ if (kIndex_GrBufferType == type) {
+ this->bindVertexArray(0);
}
-}
-void GrGLGpu::releaseBuffer(GrGLuint id, GrGLenum type) {
- this->handleDirtyContext();
- GL_CALL(DeleteBuffers(1, &id));
- switch (type) {
- case GR_GL_ARRAY_BUFFER:
- this->notifyVertexBufferDelete(id);
- break;
- case GR_GL_ELEMENT_ARRAY_BUFFER:
- this->notifyIndexBufferDelete(id);
- break;
- case GR_GL_TEXTURE_BUFFER:
- if (fHWBoundTextureBufferIDIsValid && id == fHWBoundTextureBufferID) {
- fHWBoundTextureBufferID = 0;
- }
- break;
- case GR_GL_DRAW_INDIRECT_BUFFER:
- if (fHWBoundDrawIndirectBufferIDIsValid && id == fHWBoundDrawIndirectBufferID) {
- fHWBoundDrawIndirectBufferID = 0;
- }
- break;
+ SkASSERT(type >= 0 && type <= kLast_GrBufferType);
+ auto& bufferState = fHWBufferState[type];
+
+ if (buffer->getUniqueID() != bufferState.fBoundBufferUniqueID) {
+ if (!buffer->isCPUBacked() || !bufferState.fBufferZeroKnownBound) {
+ GL_CALL(BindBuffer(bufferState.fGLTarget, buffer->bufferID()));
+ bufferState.fBufferZeroKnownBound = buffer->isCPUBacked();
+ }
+ bufferState.fBoundBufferUniqueID = buffer->getUniqueID();
}
+
+ return bufferState.fGLTarget;
}
void GrGLGpu::disableScissor() {
@@ -2670,10 +2642,7 @@ void GrGLGpu::finishDrawTarget() {
SkASSERT(!fHWPLSEnabled);
SkASSERT(fMSAAEnabled != kYes_TriState);
GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
- this->stampRectUsingProgram(fPLSSetupProgram.fProgram,
- SkRect::MakeXYWH(-100.0f, -100.0f, 0.01f, 0.01f),
- fPLSSetupProgram.fPosXformUniform,
- fPLSSetupProgram.fArrayBuffer);
+ this->stampPLSSetupRect(SkRect::MakeXYWH(-100.0f, -100.0f, 0.01f, 0.01f));
GL_CALL(Disable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
}
}
@@ -2841,18 +2810,26 @@ void GrGLGpu::onDraw(const GrPipeline& pipeline,
#endif
}
-void GrGLGpu::stampRectUsingProgram(GrGLuint program, const SkRect& bounds, GrGLint posXformUniform,
- GrGLuint arrayBuffer) {
- GL_CALL(UseProgram(program));
- this->fHWGeometryState.setVertexArrayID(this, 0);
+void GrGLGpu::stampPLSSetupRect(const SkRect& bounds) {
+ SkASSERT(this->glCaps().glslCaps()->plsPathRenderingSupport())
- GrGLAttribArrayState* attribs =
- this->fHWGeometryState.bindArrayAndBufferToDraw(this, arrayBuffer);
- attribs->set(this, 0, arrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), 0);
+ if (!fPLSSetupProgram.fProgram) {
+ if (!this->createPLSSetupProgram()) {
+ SkDebugf("Failed to create PLS setup program.\n");
+ return;
+ }
+ }
+
+ GL_CALL(UseProgram(fPLSSetupProgram.fProgram));
+ this->fHWVertexArrayState.setVertexArrayID(this, 0);
+
+ GrGLAttribArrayState* attribs = this->fHWVertexArrayState.bindInternalVertexArray(this);
+ attribs->set(this, 0, fPLSSetupProgram.fArrayBuffer, kVec2f_GrVertexAttribType,
+ 2 * sizeof(GrGLfloat), 0);
attribs->disableUnusedArrays(this, 0x1);
- GL_CALL(Uniform4f(posXformUniform, bounds.width(), bounds.height(), bounds.left(),
- bounds.top()));
+ GL_CALL(Uniform4f(fPLSSetupProgram.fPosXformUniform, bounds.width(), bounds.height(),
+ bounds.left(), bounds.top()));
GrXferProcessor::BlendInfo blendInfo;
blendInfo.reset();
@@ -2889,8 +2866,7 @@ void GrGLGpu::setupPixelLocalStorage(const GrPipeline& pipeline,
SkRect deviceBounds = SkRect::MakeXYWH(dx0, dy0, dx1 - dx0, dy1 - dy0);
GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
- this->stampRectUsingProgram(fPLSSetupProgram.fProgram, deviceBounds,
- fPLSSetupProgram.fPosXformUniform, fPLSSetupProgram.fArrayBuffer);
+ this->stampPLSSetupRect(deviceBounds);
}
void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
@@ -3562,8 +3538,9 @@ bool GrGLGpu::onCopySurface(GrSurface* dst,
// Don't prefer copying as a draw if the dst doesn't already have a FBO object.
bool preferCopy = SkToBool(dst->asRenderTarget());
if (preferCopy && src->asTexture()) {
- this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
- return true;
+ if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
+ return true;
+ }
}
if (can_copy_texsubimage(dst, src, this)) {
@@ -3576,151 +3553,173 @@ bool GrGLGpu::onCopySurface(GrSurface* dst,
}
if (!preferCopy && src->asTexture()) {
- this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
- return true;
+ if (this->copySurfaceAsDraw(dst, src, srcRect, dstPoint)) {
+ return true;
+ }
}
return false;
}
-void GrGLGpu::createCopyPrograms() {
- for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) {
- fCopyPrograms[i].fProgram = 0;
- }
+bool GrGLGpu::createCopyProgram(int progIdx) {
const GrGLSLCaps* glslCaps = this->glCaps().glslCaps();
- const char* version = glslCaps->versionDeclString();
static const GrSLType kSamplerTypes[3] = { kSampler2D_GrSLType, kSamplerExternal_GrSLType,
kSampler2DRect_GrSLType };
- SkASSERT(3 == SK_ARRAY_COUNT(fCopyPrograms));
- for (int i = 0; i < 3; ++i) {
- if (kSamplerExternal_GrSLType == kSamplerTypes[i] &&
- !this->glCaps().glslCaps()->externalTextureSupport()) {
- continue;
- }
- if (kSampler2DRect_GrSLType == kSamplerTypes[i] &&
- !this->glCaps().rectangleTextureSupport()) {
- continue;
- }
- GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
- GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
- GrShaderVar::kUniform_TypeModifier);
- GrGLSLShaderVar uPosXform("u_posXform", kVec4f_GrSLType,
- GrShaderVar::kUniform_TypeModifier);
- GrGLSLShaderVar uTexture("u_texture", kSamplerTypes[i],
+ if (kSamplerExternal_GrSLType == kSamplerTypes[progIdx] &&
+ !this->glCaps().glslCaps()->externalTextureSupport()) {
+ return false;
+ }
+ if (kSampler2DRect_GrSLType == kSamplerTypes[progIdx] &&
+ !this->glCaps().rectangleTextureSupport()) {
+ return false;
+ }
+
+ if (!fCopyProgramArrayBuffer) {
+ static const GrGLfloat vdata[] = {
+ 0, 0,
+ 0, 1,
+ 1, 0,
+ 1, 1
+ };
+ fCopyProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType,
+ kStatic_GrAccessPattern, vdata));
+ }
+ if (!fCopyProgramArrayBuffer) {
+ return false;
+ }
+
+ SkASSERT(!fCopyPrograms[progIdx].fProgram);
+ GL_CALL_RET(fCopyPrograms[progIdx].fProgram, CreateProgram());
+ if (!fCopyPrograms[progIdx].fProgram) {
+ return false;
+ }
+
+ const char* version = glslCaps->versionDeclString();
+ GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
+ GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
GrShaderVar::kUniform_TypeModifier);
- GrGLSLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType,
- GrShaderVar::kVaryingOut_TypeModifier);
- GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType,
- GrShaderVar::kOut_TypeModifier);
-
- SkString vshaderTxt(version);
- if (glslCaps->noperspectiveInterpolationSupport()) {
- if (const char* extension = glslCaps->noperspectiveInterpolationExtensionString()) {
- vshaderTxt.appendf("#extension %s : require\n", extension);
- }
- vTexCoord.addModifier("noperspective");
- }
+ GrGLSLShaderVar uPosXform("u_posXform", kVec4f_GrSLType,
+ GrShaderVar::kUniform_TypeModifier);
+ GrGLSLShaderVar uTexture("u_texture", kSamplerTypes[progIdx],
+ GrShaderVar::kUniform_TypeModifier);
+ GrGLSLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType,
+ GrShaderVar::kVaryingOut_TypeModifier);
+ GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType,
+ GrShaderVar::kOut_TypeModifier);
- aVertex.appendDecl(glslCaps, &vshaderTxt);
- vshaderTxt.append(";");
- uTexCoordXform.appendDecl(glslCaps, &vshaderTxt);
- vshaderTxt.append(";");
- uPosXform.appendDecl(glslCaps, &vshaderTxt);
- vshaderTxt.append(";");
- vTexCoord.appendDecl(glslCaps, &vshaderTxt);
- vshaderTxt.append(";");
-
- vshaderTxt.append(
- "// Copy Program VS\n"
- "void main() {"
- " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
- " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
- " gl_Position.zw = vec2(0, 1);"
- "}"
- );
-
- SkString fshaderTxt(version);
- if (glslCaps->noperspectiveInterpolationSupport()) {
- if (const char* extension = glslCaps->noperspectiveInterpolationExtensionString()) {
- fshaderTxt.appendf("#extension %s : require\n", extension);
- }
+ SkString vshaderTxt(version);
+ if (glslCaps->noperspectiveInterpolationSupport()) {
+ if (const char* extension = glslCaps->noperspectiveInterpolationExtensionString()) {
+ vshaderTxt.appendf("#extension %s : require\n", extension);
}
- if (kSamplerTypes[i] == kSamplerExternal_GrSLType) {
- fshaderTxt.appendf("#extension %s : require\n",
- glslCaps->externalTextureExtensionString());
+ vTexCoord.addModifier("noperspective");
+ }
+
+ aVertex.appendDecl(glslCaps, &vshaderTxt);
+ vshaderTxt.append(";");
+ uTexCoordXform.appendDecl(glslCaps, &vshaderTxt);
+ vshaderTxt.append(";");
+ uPosXform.appendDecl(glslCaps, &vshaderTxt);
+ vshaderTxt.append(";");
+ vTexCoord.appendDecl(glslCaps, &vshaderTxt);
+ vshaderTxt.append(";");
+
+ vshaderTxt.append(
+ "// Copy Program VS\n"
+ "void main() {"
+ " v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
+ " gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
+ " gl_Position.zw = vec2(0, 1);"
+ "}"
+ );
+
+ SkString fshaderTxt(version);
+ if (glslCaps->noperspectiveInterpolationSupport()) {
+ if (const char* extension = glslCaps->noperspectiveInterpolationExtensionString()) {
+ fshaderTxt.appendf("#extension %s : require\n", extension);
}
- GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *glslCaps,
- &fshaderTxt);
- vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
- vTexCoord.appendDecl(glslCaps, &fshaderTxt);
- fshaderTxt.append(";");
- uTexture.appendDecl(glslCaps, &fshaderTxt);
+ }
+ if (kSamplerTypes[progIdx] == kSamplerExternal_GrSLType) {
+ fshaderTxt.appendf("#extension %s : require\n",
+ glslCaps->externalTextureExtensionString());
+ }
+ GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *glslCaps,
+ &fshaderTxt);
+ vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
+ vTexCoord.appendDecl(glslCaps, &fshaderTxt);
+ fshaderTxt.append(";");
+ uTexture.appendDecl(glslCaps, &fshaderTxt);
+ fshaderTxt.append(";");
+ const char* fsOutName;
+ if (glslCaps->mustDeclareFragmentShaderOutput()) {
+ oFragColor.appendDecl(glslCaps, &fshaderTxt);
fshaderTxt.append(";");
- const char* fsOutName;
- if (glslCaps->mustDeclareFragmentShaderOutput()) {
- oFragColor.appendDecl(glslCaps, &fshaderTxt);
- fshaderTxt.append(";");
- fsOutName = oFragColor.c_str();
- } else {
- fsOutName = "gl_FragColor";
- }
- fshaderTxt.appendf(
- "// Copy Program FS\n"
- "void main() {"
- " %s = %s(u_texture, v_texCoord);"
- "}",
- fsOutName,
- GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[i], this->glslGeneration())
- );
-
- GL_CALL_RET(fCopyPrograms[i].fProgram, CreateProgram());
- const char* str;
- GrGLint length;
-
- str = vshaderTxt.c_str();
- length = SkToInt(vshaderTxt.size());
- GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[i].fProgram,
- GR_GL_VERTEX_SHADER, &str, &length, 1,
- &fStats);
-
- str = fshaderTxt.c_str();
- length = SkToInt(fshaderTxt.size());
- GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[i].fProgram,
- GR_GL_FRAGMENT_SHADER, &str, &length, 1,
- &fStats);
-
- GL_CALL(LinkProgram(fCopyPrograms[i].fProgram));
-
- GL_CALL_RET(fCopyPrograms[i].fTextureUniform,
- GetUniformLocation(fCopyPrograms[i].fProgram, "u_texture"));
- GL_CALL_RET(fCopyPrograms[i].fPosXformUniform,
- GetUniformLocation(fCopyPrograms[i].fProgram, "u_posXform"));
- GL_CALL_RET(fCopyPrograms[i].fTexCoordXformUniform,
- GetUniformLocation(fCopyPrograms[i].fProgram, "u_texCoordXform"));
-
- GL_CALL(BindAttribLocation(fCopyPrograms[i].fProgram, 0, "a_vertex"));
-
- GL_CALL(DeleteShader(vshader));
- GL_CALL(DeleteShader(fshader));
- }
- fCopyProgramArrayBuffer = 0;
- GL_CALL(GenBuffers(1, &fCopyProgramArrayBuffer));
- fHWGeometryState.setVertexBufferID(this, fCopyProgramArrayBuffer);
- static const GrGLfloat vdata[] = {
- 0, 0,
- 0, 1,
- 1, 0,
- 1, 1
- };
- GL_ALLOC_CALL(this->glInterface(),
- BufferData(GR_GL_ARRAY_BUFFER,
- (GrGLsizeiptr) sizeof(vdata),
- vdata, // data ptr
- GR_GL_STATIC_DRAW));
+ fsOutName = oFragColor.c_str();
+ } else {
+ fsOutName = "gl_FragColor";
+ }
+ fshaderTxt.appendf(
+ "// Copy Program FS\n"
+ "void main() {"
+ " %s = %s(u_texture, v_texCoord);"
+ "}",
+ fsOutName,
+ GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[progIdx], this->glslGeneration())
+ );
+
+ const char* str;
+ GrGLint length;
+
+ str = vshaderTxt.c_str();
+ length = SkToInt(vshaderTxt.size());
+ GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
+ GR_GL_VERTEX_SHADER, &str, &length, 1,
+ &fStats);
+
+ str = fshaderTxt.c_str();
+ length = SkToInt(fshaderTxt.size());
+ GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fCopyPrograms[progIdx].fProgram,
+ GR_GL_FRAGMENT_SHADER, &str, &length, 1,
+ &fStats);
+
+ GL_CALL(LinkProgram(fCopyPrograms[progIdx].fProgram));
+
+ GL_CALL_RET(fCopyPrograms[progIdx].fTextureUniform,
+ GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texture"));
+ GL_CALL_RET(fCopyPrograms[progIdx].fPosXformUniform,
+ GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_posXform"));
+ GL_CALL_RET(fCopyPrograms[progIdx].fTexCoordXformUniform,
+ GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordXform"));
+
+ GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex"));
+
+ GL_CALL(DeleteShader(vshader));
+ GL_CALL(DeleteShader(fshader));
+
+ return true;
}
-void GrGLGpu::createWireRectProgram() {
+bool GrGLGpu::createWireRectProgram() {
+ if (!fWireRectArrayBuffer) {
+ static const GrGLfloat vdata[] = {
+ 0, 0,
+ 0, 1,
+ 1, 1,
+ 1, 0
+ };
+ fWireRectArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType,
+ kStatic_GrAccessPattern, vdata));
+ if (!fWireRectArrayBuffer) {
+ return false;
+ }
+ }
+
SkASSERT(!fWireRectProgram.fProgram);
+ GL_CALL_RET(fWireRectProgram.fProgram, CreateProgram());
+ if (!fWireRectProgram.fProgram) {
+ return false;
+ }
+
GrGLSLShaderVar uColor("u_color", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
GrGLSLShaderVar uRect("u_rect", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
@@ -3768,7 +3767,6 @@ void GrGLGpu::createWireRectProgram() {
uColor.c_str()
);
- GL_CALL_RET(fWireRectProgram.fProgram, CreateProgram());
const char* str;
GrGLint length;
@@ -3794,19 +3792,8 @@ void GrGLGpu::createWireRectProgram() {
GL_CALL(DeleteShader(vshader));
GL_CALL(DeleteShader(fshader));
- GL_CALL(GenBuffers(1, &fWireRectArrayBuffer));
- fHWGeometryState.setVertexBufferID(this, fWireRectArrayBuffer);
- static const GrGLfloat vdata[] = {
- 0, 0,
- 0, 1,
- 1, 1,
- 1, 0,
- };
- GL_ALLOC_CALL(this->glInterface(),
- BufferData(GR_GL_ARRAY_BUFFER,
- (GrGLsizeiptr) sizeof(vdata),
- vdata, // data ptr
- GR_GL_STATIC_DRAW));
+
+ return true;
}
void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) {
@@ -3815,7 +3802,10 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor
this->handleDirtyContext();
if (!fWireRectProgram.fProgram) {
- this->createWireRectProgram();
+ if (!this->createWireRectProgram()) {
+ SkDebugf("Failed to create wire rect program.\n");
+ return;
+ }
}
int w = rt->width();
@@ -3851,10 +3841,9 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor
GL_CALL(UseProgram(fWireRectProgram.fProgram));
fHWProgramID = fWireRectProgram.fProgram;
- fHWGeometryState.setVertexArrayID(this, 0);
+ fHWVertexArrayState.setVertexArrayID(this, 0);
- GrGLAttribArrayState* attribs =
- fHWGeometryState.bindArrayAndBufferToDraw(this, fWireRectArrayBuffer);
+ GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
attribs->set(this, 0, fWireRectArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat),
0);
attribs->disableUnusedArrays(this, 0x1);
@@ -3877,14 +3866,23 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor
}
-void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
+bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
+ GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
+ int progIdx = TextureTargetToCopyProgramIdx(srcTex->target());
+
+ if (!fCopyPrograms[progIdx].fProgram) {
+ if (!this->createCopyProgram(progIdx)) {
+ SkDebugf("Failed to create copy program.\n");
+ return false;
+ }
+ }
+
int w = srcRect.width();
int h = srcRect.height();
- GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
this->bindTexture(0, params, true, srcTex);
@@ -3895,15 +3893,12 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
- int progIdx = TextureTargetToCopyProgramIdx(srcTex->target());
-
GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram));
fHWProgramID = fCopyPrograms[progIdx].fProgram;
- fHWGeometryState.setVertexArrayID(this, 0);
+ fHWVertexArrayState.setVertexArrayID(this, 0);
- GrGLAttribArrayState* attribs =
- fHWGeometryState.bindArrayAndBufferToDraw(this, fCopyProgramArrayBuffer);
+ GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
attribs->set(this, 0, fCopyProgramArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat),
0);
attribs->disableUnusedArrays(this, 0x1);
@@ -3959,6 +3954,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
this->unbindTextureFBOForCopy(GR_GL_FRAMEBUFFER, dst);
this->didWriteToSurface(dst, &dstRect);
+ return true;
}
void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst,
@@ -4196,52 +4192,27 @@ void GrGLGpu::resetShaderCacheForTesting() const {
}
///////////////////////////////////////////////////////////////////////////////
-GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(
- GrGLGpu* gpu,
- const GrGLBuffer* vbuffer,
- const GrGLBuffer* ibuffer) {
- SkASSERT(vbuffer);
- GrGLuint vbufferID = vbuffer->bufferID();
- GrGLuint* ibufferIDPtr = nullptr;
- GrGLuint ibufferID;
- if (ibuffer) {
- ibufferID = ibuffer->bufferID();
- ibufferIDPtr = &ibufferID;
- }
- return this->internalBind(gpu, vbufferID, ibufferIDPtr);
-}
-
-GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBufferToDraw(GrGLGpu* gpu,
- GrGLuint vbufferID) {
- return this->internalBind(gpu, vbufferID, nullptr);
-}
-
-GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(GrGLGpu* gpu,
- GrGLuint vbufferID,
- GrGLuint ibufferID) {
- return this->internalBind(gpu, vbufferID, &ibufferID);
-}
-GrGLAttribArrayState* GrGLGpu::HWGeometryState::internalBind(GrGLGpu* gpu,
- GrGLuint vbufferID,
- GrGLuint* ibufferID) {
+GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu,
+ const GrGLBuffer* ibuf) {
GrGLAttribArrayState* attribState;
- if (gpu->glCaps().isCoreProfile() && 0 != vbufferID) {
- if (!fVBOVertexArray) {
+ if (gpu->glCaps().isCoreProfile()) {
+ if (!fCoreProfileVertexArray) {
GrGLuint arrayID;
GR_GL_CALL(gpu->glInterface(), GenVertexArrays(1, &arrayID));
int attrCount = gpu->glCaps().maxVertexAttributes();
- fVBOVertexArray = new GrGLVertexArray(arrayID, attrCount);
+ fCoreProfileVertexArray = new GrGLVertexArray(arrayID, attrCount);
}
- if (ibufferID) {
- attribState = fVBOVertexArray->bindWithIndexBuffer(gpu, *ibufferID);
+ if (ibuf) {
+ attribState = fCoreProfileVertexArray->bindWithIndexBuffer(gpu, ibuf);
} else {
- attribState = fVBOVertexArray->bind(gpu);
+ attribState = fCoreProfileVertexArray->bind(gpu);
}
} else {
- if (ibufferID) {
- this->setIndexBufferIDOnDefaultVertexArray(gpu, *ibufferID);
+ if (ibuf) {
+ // bindBuffer implicitly binds VAO 0 when binding an index buffer.
+ gpu->bindBuffer(kIndex_GrBufferType, ibuf);
} else {
this->setVertexArrayID(gpu, 0);
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index c77076fc51..c2dda0a222 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -32,7 +32,7 @@ class GrSwizzle;
#define PROGRAM_CACHE_STATS
#endif
-class GrGLGpu : public GrGpu {
+class GrGLGpu final : public GrGpu {
public:
static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options,
GrContext* context);
@@ -73,31 +73,20 @@ public:
// These functions should be used to bind GL objects. They track the GL state and skip redundant
// bindings. Making the equivalent glBind calls directly will confuse the state tracking.
void bindVertexArray(GrGLuint id) {
- fHWGeometryState.setVertexArrayID(this, id);
- }
- void bindIndexBufferAndDefaultVertexArray(GrGLuint id) {
- fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id);
- }
- void bindVertexBuffer(GrGLuint id) {
- fHWGeometryState.setVertexBufferID(this, id);
+ fHWVertexArrayState.setVertexArrayID(this, id);
}
// These callbacks update state tracking when GL objects are deleted. They are called from
// GrGLResource onRelease functions.
void notifyVertexArrayDelete(GrGLuint id) {
- fHWGeometryState.notifyVertexArrayDelete(id);
- }
- void notifyVertexBufferDelete(GrGLuint id) {
- fHWGeometryState.notifyVertexBufferDelete(id);
- }
- void notifyIndexBufferDelete(GrGLuint id) {
- fHWGeometryState.notifyIndexBufferDelete(id);
+ fHWVertexArrayState.notifyVertexArrayDelete(id);
}
- // id and type (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, etc.) of buffer to bind
- void bindBuffer(GrGLuint id, GrGLenum type);
-
- void releaseBuffer(GrGLuint id, GrGLenum type);
+ // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
+ // returns the GL target the buffer was bound to.
+ // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
+ // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
+ GrGLenum bindBuffer(GrBufferType type, const GrGLBuffer*);
const GrGLContext* glContextForTesting() const override {
return &this->glContext();
@@ -138,7 +127,7 @@ private:
GrGpuResource::LifeCycle lifeCycle,
const SkTArray<GrMipLevel>& texels) override;
- GrBuffer* onCreateBuffer(GrBufferType, size_t size, GrAccessPattern) override;
+ GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern) override;
GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
GrWrapOwnership) override;
@@ -231,7 +220,7 @@ private:
bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
- void copySurfaceAsDraw(GrSurface* dst,
+ bool copySurfaceAsDraw(GrSurface* dst,
GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint);
@@ -244,8 +233,7 @@ private:
const SkIRect& srcRect,
const SkIPoint& dstPoint);
- void stampRectUsingProgram(GrGLuint program, const SkRect& bounds, GrGLint posXformUniform,
- GrGLuint arrayBuffer);
+ void stampPLSSetupRect(const SkRect& bounds);
void setupPixelLocalStorage(const GrPipeline&, const GrPrimitiveProcessor&);
@@ -373,11 +361,9 @@ private:
SkAutoTUnref<GrGLContext> fGLContext;
- void createCopyPrograms();
- void createWireRectProgram();
- void createUnitRectBuffer();
-
- void createPLSSetupProgram();
+ bool createCopyProgram(int progIdx);
+ bool createWireRectProgram();
+ bool createPLSSetupProgram();
// GL program-related state
ProgramCache* fProgramCache;
@@ -412,22 +398,19 @@ private:
GrGLIRect fHWViewport;
/**
- * Tracks bound vertex and index buffers and vertex attrib array state.
+ * Tracks vertex attrib array state.
*/
- class HWGeometryState {
+ class HWVertexArrayState {
public:
- HWGeometryState() { fVBOVertexArray = nullptr; this->invalidate(); }
+ HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
- ~HWGeometryState() { delete fVBOVertexArray; }
+ ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
void invalidate() {
fBoundVertexArrayIDIsValid = false;
- fBoundVertexBufferIDIsValid = false;
- fDefaultVertexArrayBoundIndexBufferID = false;
- fDefaultVertexArrayBoundIndexBufferIDIsValid = false;
fDefaultVertexArrayAttribState.invalidate();
- if (fVBOVertexArray) {
- fVBOVertexArray->invalidateCachedState();
+ if (fCoreProfileVertexArray) {
+ fCoreProfileVertexArray->invalidateCachedState();
}
}
@@ -450,89 +433,41 @@ private:
}
}
- void notifyVertexBufferDelete(GrGLuint id) {
- if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) {
- fBoundVertexBufferID = 0;
- }
- if (fVBOVertexArray) {
- fVBOVertexArray->notifyVertexBufferDelete(id);
- }
- fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id);
- }
-
- void notifyIndexBufferDelete(GrGLuint id) {
- if (fDefaultVertexArrayBoundIndexBufferIDIsValid &&
- id == fDefaultVertexArrayBoundIndexBufferID) {
- fDefaultVertexArrayBoundIndexBufferID = 0;
- }
- if (fVBOVertexArray) {
- fVBOVertexArray->notifyIndexBufferDelete(id);
- }
- }
-
- void setVertexBufferID(GrGLGpu* gpu, GrGLuint id) {
- if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) {
- GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id));
- fBoundVertexBufferIDIsValid = true;
- fBoundVertexBufferID = id;
- }
- }
-
- /**
- * Binds the default vertex array and binds the index buffer. This is used when binding
- * an index buffer in order to update it.
- */
- void setIndexBufferIDOnDefaultVertexArray(GrGLGpu* gpu, GrGLuint id) {
- this->setVertexArrayID(gpu, 0);
- if (!fDefaultVertexArrayBoundIndexBufferIDIsValid ||
- id != fDefaultVertexArrayBoundIndexBufferID) {
- GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
- fDefaultVertexArrayBoundIndexBufferIDIsValid = true;
- fDefaultVertexArrayBoundIndexBufferID = id;
- }
- }
-
/**
- * Binds the vertex array object that should be used to render from the vertex buffer.
- * The vertex array is bound and its attrib array state object is returned. The vertex
- * buffer is bound. The index buffer (if non-nullptr) is bound to the vertex array. The
- * returned GrGLAttribArrayState should be used to set vertex attribute arrays.
+ * Binds the vertex array that should be used for internal draws, and returns its attrib
+ * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
+ * case we use a dummy array instead.
+ *
+ * If an index buffer is privided, it will be bound to the vertex array. Otherwise the
+ * index buffer binding will be left unchanged.
+ *
+ * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
*/
- GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
- const GrGLBuffer* vbuffer,
- const GrGLBuffer* 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
- array rendering. */
- GrGLAttribArrayState* bindArrayAndBufferToDraw(GrGLGpu* gpu, GrGLuint vbufferID);
- GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu,
- GrGLuint vbufferID,
- GrGLuint ibufferID);
+ GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrGLBuffer* ibuff = nullptr);
private:
- GrGLAttribArrayState* internalBind(GrGLGpu* gpu, GrGLuint vbufferID, GrGLuint* ibufferID);
-
GrGLuint fBoundVertexArrayID;
- GrGLuint fBoundVertexBufferID;
bool fBoundVertexArrayIDIsValid;
- bool fBoundVertexBufferIDIsValid;
- GrGLuint fDefaultVertexArrayBoundIndexBufferID;
- bool fDefaultVertexArrayBoundIndexBufferIDIsValid;
// We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
// is bound. However, this class is internal to GrGLGpu and this object never leaks out of
// GrGLGpu.
GrGLAttribArrayState fDefaultVertexArrayAttribState;
- // This is used when we're using a core profile and the vertices are in a VBO.
- GrGLVertexArray* fVBOVertexArray;
- } fHWGeometryState;
+ // This is used when we're using a core profile.
+ GrGLVertexArray* fCoreProfileVertexArray;
+ } fHWVertexArrayState;
- GrGLuint fHWBoundTextureBufferID;
- GrGLuint fHWBoundDrawIndirectBufferID;
- bool fHWBoundTextureBufferIDIsValid;
- bool fHWBoundDrawIndirectBufferIDIsValid;
+ struct {
+ GrGLenum fGLTarget;
+ uint32_t fBoundBufferUniqueID;
+ bool fBufferZeroKnownBound;
+
+ void invalidate() {
+ fBoundBufferUniqueID = SK_InvalidUniqueID;
+ fBufferZeroKnownBound = false;
+ }
+ } fHWBufferState[kGrBufferTypeCount];
struct {
GrBlendEquation fEquation;
@@ -575,14 +510,14 @@ private:
GrGLint fTexCoordXformUniform;
GrGLint fPosXformUniform;
} fCopyPrograms[3];
- GrGLuint fCopyProgramArrayBuffer;
+ SkAutoTUnref<GrGLBuffer> fCopyProgramArrayBuffer;
struct {
GrGLuint fProgram;
GrGLint fColorUniform;
GrGLint fRectUniform;
} fWireRectProgram;
- GrGLuint fWireRectArrayBuffer;
+ SkAutoTUnref<GrGLBuffer> fWireRectArrayBuffer;
static int TextureTargetToCopyProgramIdx(GrGLenum target) {
switch (target) {
@@ -599,9 +534,9 @@ private:
}
struct {
- GrGLuint fProgram;
- GrGLint fPosXformUniform;
- GrGLuint fArrayBuffer;
+ GrGLuint fProgram;
+ GrGLint fPosXformUniform;
+ SkAutoTUnref<GrGLBuffer> fArrayBuffer;
} fPLSSetupProgram;
bool fHWPLSEnabled;
diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp
index 564a91a1b6..d131ff2186 100644
--- a/src/gpu/gl/GrGLVertexArray.cpp
+++ b/src/gpu/gl/GrGLVertexArray.cpp
@@ -6,6 +6,7 @@
*/
#include "GrGLVertexArray.h"
+#include "GrGLBuffer.h"
#include "GrGLGpu.h"
struct AttribLayout {
@@ -38,7 +39,7 @@ GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType);
void GrGLAttribArrayState::set(GrGLGpu* gpu,
int index,
- GrGLuint vertexBufferID,
+ const GrGLBuffer* vertexBuffer,
GrVertexAttribType type,
GrGLsizei stride,
GrGLvoid* offset) {
@@ -49,13 +50,11 @@ void GrGLAttribArrayState::set(GrGLGpu* gpu,
array->fEnableIsValid = true;
array->fEnabled = true;
}
- if (!array->fAttribPointerIsValid ||
- array->fVertexBufferID != vertexBufferID ||
+ if (array->fVertexBufferUniqueID != vertexBuffer->getUniqueID() ||
array->fType != type ||
array->fStride != stride ||
array->fOffset != offset) {
-
- gpu->bindVertexBuffer(vertexBufferID);
+ gpu->bindBuffer(kVertex_GrBufferType, vertexBuffer);
const AttribLayout& layout = gLayouts[type];
if (!GrVertexAttribTypeIsIntType(type)) {
GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
@@ -73,8 +72,7 @@ void GrGLAttribArrayState::set(GrGLGpu* gpu,
stride,
offset));
}
- array->fAttribPointerIsValid = true;
- array->fVertexBufferID = vertexBufferID;
+ array->fVertexBufferUniqueID = vertexBuffer->getUniqueID();
array->fType = type;
array->fStride = stride;
array->fOffset = offset;
@@ -103,7 +101,7 @@ void GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t used
GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount)
: fID(id)
, fAttribArrays(attribCount)
- , fIndexBufferIDIsValid(false) {
+ , fIndexBufferUniqueID(SK_InvalidUniqueID) {
}
GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
@@ -114,25 +112,16 @@ GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
return &fAttribArrays;
}
-GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, GrGLuint ibufferID) {
+GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrGLBuffer* ibuff) {
GrGLAttribArrayState* state = this->bind(gpu);
- if (state) {
- if (!fIndexBufferIDIsValid || ibufferID != fIndexBufferID) {
- GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibufferID));
- fIndexBufferIDIsValid = true;
- fIndexBufferID = ibufferID;
- }
+ if (state && fIndexBufferUniqueID != ibuff->getUniqueID()) {
+ GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibuff->bufferID()));
+ fIndexBufferUniqueID = ibuff->getUniqueID();
}
return state;
}
-void GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) {
- if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) {
- fIndexBufferID = 0;
- }
- }
-
void GrGLVertexArray::invalidateCachedState() {
fAttribArrays.invalidate();
- fIndexBufferIDIsValid = false;
+ fIndexBufferUniqueID = SK_InvalidUniqueID;
}
diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h
index 4a99d59058..6b865bd621 100644
--- a/src/gpu/gl/GrGLVertexArray.h
+++ b/src/gpu/gl/GrGLVertexArray.h
@@ -13,6 +13,7 @@
#include "gl/GrGLTypes.h"
#include "SkTArray.h"
+class GrGLBuffer;
class GrGLGpu;
/**
@@ -39,7 +40,7 @@ public:
*/
void set(GrGLGpu*,
int attribIndex,
- GrGLuint vertexBufferID,
+ const GrGLBuffer* vertexBuffer,
GrVertexAttribType type,
GrGLsizei stride,
GrGLvoid* offset);
@@ -57,16 +58,6 @@ public:
}
}
- void notifyVertexBufferDelete(GrGLuint id) {
- int count = fAttribArrayStates.count();
- for (int i = 0; i < count; ++i) {
- if (fAttribArrayStates[i].fAttribPointerIsValid &&
- id == fAttribArrayStates[i].fVertexBufferID) {
- fAttribArrayStates[i].invalidate();
- }
- }
- }
-
/**
* The number of attrib arrays that this object is configured to track.
*/
@@ -79,13 +70,12 @@ private:
struct AttribArrayState {
void invalidate() {
fEnableIsValid = false;
- fAttribPointerIsValid = false;
+ fVertexBufferUniqueID = SK_InvalidUniqueID;
}
bool fEnableIsValid;
- bool fAttribPointerIsValid;
bool fEnabled;
- GrGLuint fVertexBufferID;
+ uint32_t fVertexBufferUniqueID;
GrVertexAttribType fType;
GrGLsizei fStride;
GrGLvoid* fOffset;
@@ -113,13 +103,7 @@ public:
* This is a version of the above function that also binds an index buffer to the vertex
* array object.
*/
- GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, GrGLuint indexBufferID);
-
- void notifyIndexBufferDelete(GrGLuint bufferID);
-
- void notifyVertexBufferDelete(GrGLuint id) {
- fAttribArrays.notifyVertexBufferDelete(id);
- }
+ GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrGLBuffer* indexBuffer);
GrGLuint arrayID() const { return fID; }
@@ -128,8 +112,7 @@ public:
private:
GrGLuint fID;
GrGLAttribArrayState fAttribArrays;
- GrGLuint fIndexBufferID;
- bool fIndexBufferIDIsValid;
+ uint32_t fIndexBufferUniqueID;
};
#endif
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index e35a814b03..c82ec56e4a 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -172,7 +172,7 @@ void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
}
///////////////////////////////////////////////////////////////////////////////
-GrBuffer* GrVkGpu::onCreateBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) {
+GrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern accessPattern) {
switch (type) {
case kVertex_GrBufferType:
SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
@@ -1356,8 +1356,8 @@ bool GrVkGpu::onReadPixels(GrSurface* surface,
false);
GrVkTransferBuffer* transferBuffer =
- static_cast<GrVkTransferBuffer*>(this->createBuffer(kXferGpuToCpu_GrBufferType,
- rowBytes * height,
+ static_cast<GrVkTransferBuffer*>(this->createBuffer(rowBytes * height,
+ kXferGpuToCpu_GrBufferType,
kStream_GrAccessPattern));
bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 87fea90e32..91f9d4d379 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -131,7 +131,7 @@ private:
GrWrapOwnership) override;
GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&) override { return NULL; }
- GrBuffer* onCreateBuffer(GrBufferType, size_t size, GrAccessPattern) override;
+ GrBuffer* onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern) override;
void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override;
diff --git a/src/gpu/vk/GrVkIndexBuffer.cpp b/src/gpu/vk/GrVkIndexBuffer.cpp
index 7342e939e1..02e100d28a 100644
--- a/src/gpu/vk/GrVkIndexBuffer.cpp
+++ b/src/gpu/vk/GrVkIndexBuffer.cpp
@@ -10,7 +10,7 @@
GrVkIndexBuffer::GrVkIndexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
const GrVkBuffer::Resource* bufferResource)
- : INHERITED(gpu, kIndex_GrBufferType, desc.fSizeInBytes,
+ : INHERITED(gpu, desc.fSizeInBytes, kIndex_GrBufferType,
desc.fDynamic ? kDynamic_GrAccessPattern : kStatic_GrAccessPattern, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
diff --git a/src/gpu/vk/GrVkTransferBuffer.cpp b/src/gpu/vk/GrVkTransferBuffer.cpp
index 43fd3af9a9..0556111935 100644
--- a/src/gpu/vk/GrVkTransferBuffer.cpp
+++ b/src/gpu/vk/GrVkTransferBuffer.cpp
@@ -31,9 +31,10 @@ 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,
+ kCopyRead_Type == desc.fType ?
+ kXferCpuToGpu_GrBufferType : kXferGpuToCpu_GrBufferType,
+ kStream_GrAccessPattern, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
}
diff --git a/src/gpu/vk/GrVkVertexBuffer.cpp b/src/gpu/vk/GrVkVertexBuffer.cpp
index c2c2df0d8f..32fb0370d0 100644
--- a/src/gpu/vk/GrVkVertexBuffer.cpp
+++ b/src/gpu/vk/GrVkVertexBuffer.cpp
@@ -10,7 +10,7 @@
GrVkVertexBuffer::GrVkVertexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
const GrVkBuffer::Resource* bufferResource)
- : INHERITED(gpu, kVertex_GrBufferType, desc.fSizeInBytes,
+ : INHERITED(gpu, desc.fSizeInBytes, kVertex_GrBufferType,
desc.fDynamic ? kDynamic_GrAccessPattern : kStatic_GrAccessPattern, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 1fec1a694b..95b7802a4d 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -345,7 +345,7 @@ private:
return nullptr;
}
- GrBuffer* onCreateBuffer(GrBufferType, size_t, GrAccessPattern) override { return nullptr; }
+ GrBuffer* onCreateBuffer(size_t, GrBufferType, GrAccessPattern) override { return nullptr; }
void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override {}