Use different classes for client side arrays and GPU buffer objects.
GrBuffer is a base class for GrGpuBuffer and GrCpuBuffer. GrGpuBuffer is a
GrGpuResource and the others are not. This allows GrCpuBuffers to exist
outside of the GrGpuResourceCache.
Also removes flags from GrResourceProvider buffer factory function. The
only flag still in use was kRequireGpuMemory. Now CPU buffers are made
without using GrResourceProvider.
Change-Id: I82670d1316e28fd6331ca36b26c8c4ead33846f9
Reviewed-on: https://skia-review.googlesource.com/c/188823
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp
index 6b12a3f..ab52b25 100644
--- a/src/gpu/gl/GrGLVertexArray.cpp
+++ b/src/gpu/gl/GrGLVertexArray.cpp
@@ -6,6 +6,7 @@
*/
#include "GrGLVertexArray.h"
+#include "GrCpuBuffer.h"
#include "GrGLBuffer.h"
#include "GrGLGpu.h"
@@ -89,14 +90,32 @@
SkASSERT(index >= 0 && index < fAttribArrayStates.count());
SkASSERT(0 == divisor || gpu->caps()->instanceAttribSupport());
AttribArrayState* array = &fAttribArrayStates[index];
- if (array->fVertexBufferUniqueID != vertexBuffer->uniqueID() ||
+ const char* offsetAsPtr;
+ bool bufferChanged = false;
+ if (vertexBuffer->isCpuBuffer()) {
+ if (!array->fUsingCpuBuffer) {
+ bufferChanged = true;
+ array->fUsingCpuBuffer = true;
+ }
+ offsetAsPtr = static_cast<const GrCpuBuffer*>(vertexBuffer)->data() + offsetInBytes;
+ } else {
+ auto gpuBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
+ if (array->fUsingCpuBuffer || array->fVertexBufferUniqueID != gpuBuffer->uniqueID()) {
+ bufferChanged = true;
+ array->fVertexBufferUniqueID = gpuBuffer->uniqueID();
+ }
+ offsetAsPtr = reinterpret_cast<const char*>(offsetInBytes);
+ }
+ if (bufferChanged ||
array->fCPUType != cpuType ||
array->fGPUType != gpuType ||
array->fStride != stride ||
- array->fOffset != offsetInBytes) {
+ array->fOffset != offsetAsPtr) {
+ // We always have to call this if we're going to change the array pointer. 'array' is
+ // tracking the last buffer used to setup attrib pointers, not the last buffer bound.
+ // GrGLGpu will avoid redundant binds.
gpu->bindBuffer(GrGpuBufferType::kVertex, vertexBuffer);
const AttribLayout& layout = attrib_layout(cpuType);
- const GrGLvoid* offsetAsPtr = reinterpret_cast<const GrGLvoid*>(offsetInBytes);
if (GrSLTypeIsFloatType(gpuType)) {
GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
layout.fCount,
@@ -113,11 +132,10 @@
stride,
offsetAsPtr));
}
- array->fVertexBufferUniqueID = vertexBuffer->uniqueID();
array->fCPUType = cpuType;
array->fGPUType = gpuType;
array->fStride = stride;
- array->fOffset = offsetInBytes;
+ array->fOffset = offsetAsPtr;
}
if (gpu->caps()->instanceAttribSupport() && array->fDivisor != divisor) {
SkASSERT(0 == divisor || 1 == divisor); // not necessarily a requirement but what we expect.
@@ -179,15 +197,19 @@
GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* ibuff) {
GrGLAttribArrayState* state = this->bind(gpu);
- if (state && fIndexBufferUniqueID != ibuff->uniqueID()) {
- if (ibuff->isCPUBacked()) {
- GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0));
- } else {
+ if (!state) {
+ return nullptr;
+ }
+ if (ibuff->isCpuBuffer()) {
+ GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0));
+ } else {
+ const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff);
+ if (fIndexBufferUniqueID != glBuffer->uniqueID()) {
const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff);
- GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
- glBuffer->bufferID()));
+ GR_GL_CALL(gpu->glInterface(),
+ BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, glBuffer->bufferID()));
+ fIndexBufferUniqueID = glBuffer->uniqueID();
}
- fIndexBufferUniqueID = ibuff->uniqueID();
}
return state;
}