aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-21 14:33:46 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-21 14:33:46 +0000
commitee3bc3b26771a58a78075f11cde8801e0e79f723 (patch)
tree118d722cc2a318a20e6b778842887f4ac3961941 /src/gpu/gl
parentd454ec135eeef48edea7ebc47a61ff39bd654576 (diff)
Add support for vertex data rendered from CPU arrays.
Review URL: https://codereview.appspot.com/7380044 git-svn-id: http://skia.googlecode.com/svn/trunk@7807 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLBufferImpl.cpp60
-rw-r--r--src/gpu/gl/GrGLBufferImpl.h7
-rw-r--r--src/gpu/gl/GrGLIndexBuffer.cpp2
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.cpp2
-rw-r--r--src/gpu/gl/GrGpuGL.cpp85
5 files changed, 101 insertions, 55 deletions
diff --git a/src/gpu/gl/GrGLBufferImpl.cpp b/src/gpu/gl/GrGLBufferImpl.cpp
index 0ab83fb77a..d9a8a8eca8 100644
--- a/src/gpu/gl/GrGLBufferImpl.cpp
+++ b/src/gpu/gl/GrGLBufferImpl.cpp
@@ -10,16 +10,32 @@
#define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X)
+#if GR_DEBUG
+#define VALIDATE() this->validate()
+#else
+#define VALIDATE() do {} while(false)
+#endif
+
GrGLBufferImpl::GrGLBufferImpl(GrGpuGL* gpu, const Desc& desc, GrGLenum bufferType)
: fDesc(desc)
, fBufferType(bufferType)
, fLockPtr(NULL) {
- GrAssert(GR_GL_ARRAY_BUFFER == bufferType || GR_GL_ELEMENT_ARRAY_BUFFER == bufferType);
+ if (0 == desc.fID) {
+ fCPUData = sk_malloc_flags(desc.fSizeInBytes, SK_MALLOC_THROW);
+ } else {
+ fCPUData = NULL;
+ }
+ VALIDATE();
}
void GrGLBufferImpl::release(GrGpuGL* gpu) {
- // make sure we've not been abandoned
- if (fDesc.fID && !fDesc.fIsWrapped) {
+ // make sure we've not been abandoned or already released
+ if (NULL != fCPUData) {
+ VALIDATE();
+ sk_free(fCPUData);
+ fCPUData = NULL;
+ } else if (fDesc.fID && !fDesc.fIsWrapped) {
+ VALIDATE();
GL_CALL(gpu, DeleteBuffers(1, &fDesc.fID));
if (GR_GL_ARRAY_BUFFER == fBufferType) {
gpu->notifyVertexBufferDelete(fDesc.fID);
@@ -29,14 +45,18 @@ void GrGLBufferImpl::release(GrGpuGL* gpu) {
}
fDesc.fID = 0;
}
+ fLockPtr = NULL;
}
void GrGLBufferImpl::abandon() {
fDesc.fID = 0;
fLockPtr = NULL;
+ sk_free(fCPUData);
+ fCPUData = NULL;
}
void GrGLBufferImpl::bind(GrGpuGL* gpu) const {
+ VALIDATE();
GL_CALL(gpu, BindBuffer(fBufferType, fDesc.fID));
if (GR_GL_ARRAY_BUFFER == fBufferType) {
gpu->notifyVertexBufferBind(fDesc.fID);
@@ -47,9 +67,11 @@ void GrGLBufferImpl::bind(GrGpuGL* gpu) const {
}
void* GrGLBufferImpl::lock(GrGpuGL* gpu) {
- GrAssert(0 != fDesc.fID);
+ VALIDATE();
GrAssert(!this->isLocked());
- if (gpu->getCaps().bufferLockSupport()) {
+ if (0 == fDesc.fID) {
+ fLockPtr = fCPUData;
+ } else if (gpu->getCaps().bufferLockSupport()) {
this->bind(gpu);
// Let driver know it can discard the old data
GL_CALL(gpu, BufferData(fBufferType,
@@ -59,34 +81,35 @@ void* GrGLBufferImpl::lock(GrGpuGL* gpu) {
GR_GL_CALL_RET(gpu->glInterface(),
fLockPtr,
MapBuffer(fBufferType, GR_GL_WRITE_ONLY));
- return fLockPtr;
}
- return NULL;
+ return fLockPtr;
}
void GrGLBufferImpl::unlock(GrGpuGL* gpu) {
-
- GrAssert(0 != fDesc.fID);
+ VALIDATE();
GrAssert(this->isLocked());
- GrAssert(gpu->getCaps().bufferLockSupport());
-
- this->bind(gpu);
- GL_CALL(gpu, UnmapBuffer(fBufferType));
+ if (0 != fDesc.fID) {
+ GrAssert(gpu->getCaps().bufferLockSupport());
+ this->bind(gpu);
+ GL_CALL(gpu, UnmapBuffer(fBufferType));
+ }
fLockPtr = NULL;
}
bool GrGLBufferImpl::isLocked() const {
- GrAssert(0 != fDesc.fID);
+ VALIDATE();
return NULL != fLockPtr;
}
bool GrGLBufferImpl::updateData(GrGpuGL* gpu, const void* src, size_t srcSizeInBytes) {
GrAssert(!this->isLocked());
+ VALIDATE();
if (srcSizeInBytes > fDesc.fSizeInBytes) {
return false;
}
if (0 == fDesc.fID) {
- return false;
+ memcpy(fCPUData, src, srcSizeInBytes);
+ return true;
}
this->bind(gpu);
GrGLenum usage = fDesc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
@@ -129,3 +152,10 @@ bool GrGLBufferImpl::updateData(GrGpuGL* gpu, const void* src, size_t srcSizeInB
#endif
return true;
}
+
+void GrGLBufferImpl::validate() const {
+ GrAssert(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
+ GrAssert((0 == fDesc.fID) == (NULL != fCPUData));
+ GrAssert(0 != fDesc.fID || !fDesc.fIsWrapped);
+ GrAssert(NULL == fCPUData || NULL == fLockPtr || fCPUData == fLockPtr);
+}
diff --git a/src/gpu/gl/GrGLBufferImpl.h b/src/gpu/gl/GrGLBufferImpl.h
index 7b44f14dc1..1fd8ce074f 100644
--- a/src/gpu/gl/GrGLBufferImpl.h
+++ b/src/gpu/gl/GrGLBufferImpl.h
@@ -21,7 +21,7 @@ class GrGLBufferImpl : public GrNoncopyable {
public:
struct Desc {
bool fIsWrapped;
- GrGLuint fID;
+ GrGLuint fID; // set to 0 to indicate buffer is CPU-backed and not a VBO.
size_t fSizeInBytes;
bool fDynamic;
};
@@ -36,7 +36,7 @@ public:
void release(GrGpuGL* gpu);
GrGLuint bufferID() const { return fDesc.fID; }
- size_t baseOffset() const { return 0; }
+ size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); }
void bind(GrGpuGL* gpu) const;
@@ -47,8 +47,11 @@ public:
bool updateData(GrGpuGL* gpu, const void* src, size_t srcSizeInBytes);
private:
+ void validate() const;
+
Desc fDesc;
GrGLenum fBufferType; // GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER
+ void* fCPUData;
void* fLockPtr;
typedef GrNoncopyable INHERITED;
diff --git a/src/gpu/gl/GrGLIndexBuffer.cpp b/src/gpu/gl/GrGLIndexBuffer.cpp
index ff167347f9..b6290b1826 100644
--- a/src/gpu/gl/GrGLIndexBuffer.cpp
+++ b/src/gpu/gl/GrGLIndexBuffer.cpp
@@ -9,7 +9,7 @@
#include "GrGpuGL.h"
GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu, const Desc& desc)
- : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic)
+ : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic, 0 == desc.fID)
, fImpl(gpu, desc, GR_GL_ELEMENT_ARRAY_BUFFER) {
}
diff --git a/src/gpu/gl/GrGLVertexBuffer.cpp b/src/gpu/gl/GrGLVertexBuffer.cpp
index 4152251433..685166c90b 100644
--- a/src/gpu/gl/GrGLVertexBuffer.cpp
+++ b/src/gpu/gl/GrGLVertexBuffer.cpp
@@ -9,7 +9,7 @@
#include "GrGpuGL.h"
GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu, const Desc& desc)
- : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic)
+ : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic, 0 == desc.fID)
, fImpl(gpu, desc, GR_GL_ARRAY_BUFFER) {
}
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 785b500899..235811c3fb 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1231,27 +1231,33 @@ GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) {
desc.fSizeInBytes = size;
desc.fIsWrapped = false;
- GL_CALL(GenBuffers(1, &desc.fID));
- if (desc.fID) {
- GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, 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,
- desc.fSizeInBytes,
- NULL, // data ptr
- desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
- if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
- GL_CALL(DeleteBuffers(1, &desc.fID));
- // deleting bound buffer does implicit bind to 0
- fHWGeometryState.setVertexBufferID(0);
- return NULL;
- }
+ if (false && desc.fDynamic) {
+ desc.fID = 0;
GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc));
- fHWGeometryState.setVertexBufferID(desc.fID);
return vertexBuffer;
+ } else {
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, desc.fID));
+ fHWGeometryState.setVertexBufferID(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,
+ desc.fSizeInBytes,
+ NULL, // data ptr
+ desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ // deleting bound buffer does implicit bind to 0
+ fHWGeometryState.setVertexBufferID(0);
+ return NULL;
+ }
+ GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc));
+ return vertexBuffer;
+ }
+ return NULL;
}
- return NULL;
}
GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
@@ -1260,27 +1266,33 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
desc.fSizeInBytes = size;
desc.fIsWrapped = false;
- GL_CALL(GenBuffers(1, &desc.fID));
- if (desc.fID) {
- GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 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,
- desc.fSizeInBytes,
- NULL, // data ptr
- desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
- if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
- GL_CALL(DeleteBuffers(1, &desc.fID));
- // deleting bound buffer does implicit bind to 0
- fHWGeometryState.setIndexBufferID(0);
- return NULL;
- }
+ if (false && desc.fDynamic) {
+ desc.fID = 0;
GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc));
- fHWGeometryState.setIndexBufferID(desc.fID);
return indexBuffer;
+ } else {
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, desc.fID));
+ fHWGeometryState.setIndexBufferID(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,
+ desc.fSizeInBytes,
+ NULL, // data ptr
+ desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ // deleting bound buffer does implicit bind to 0
+ fHWGeometryState.setIndexBufferID(0);
+ return NULL;
+ }
+ GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc));
+ return indexBuffer;
+ }
+ return NULL;
}
- return NULL;
}
GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) {
@@ -2354,6 +2366,7 @@ GrGLVertexBuffer* GrGpuGL::setBuffers(bool indexed,
GrAssert(NULL != ibuf);
GrAssert(!ibuf->isLocked());
+ *indexOffsetInBytes += ibuf->baseOffset();
if (!fHWGeometryState.isIndexBufferIDBound(ibuf->bufferID())) {
ibuf->bind();
fHWGeometryState.setIndexBufferID(ibuf->bufferID());