aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-20 19:33:20 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-20 19:33:20 +0000
commite49ad45404adf43c585bdf625ce05e2d61c28e9f (patch)
tree6ebd67157258054c465ad0dd35eda1ff9dfef209 /src/gpu
parentd98df1a3c468a2a7a5fff5efbf6dbdaf077d1abe (diff)
Add GrGLBufferImpl to unify implementation of GrGLVertexBuffer and GrGLIndexBuffer.
Review URL: https://codereview.appspot.com/7346055 git-svn-id: http://skia.googlecode.com/svn/trunk@7798 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gl/GrGLBufferImpl.cpp131
-rw-r--r--src/gpu/gl/GrGLBufferImpl.h57
-rw-r--r--src/gpu/gl/GrGLIndexBuffer.cpp112
-rw-r--r--src/gpu/gl/GrGLIndexBuffer.h29
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.cpp125
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.h28
-rw-r--r--src/gpu/gl/GrGpuGL.cpp68
-rw-r--r--src/gpu/gl/GrGpuGL.h14
8 files changed, 296 insertions, 268 deletions
diff --git a/src/gpu/gl/GrGLBufferImpl.cpp b/src/gpu/gl/GrGLBufferImpl.cpp
new file mode 100644
index 0000000000..0ab83fb77a
--- /dev/null
+++ b/src/gpu/gl/GrGLBufferImpl.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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 "GrGpuGL.h"
+
+#define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X)
+
+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);
+}
+
+void GrGLBufferImpl::release(GrGpuGL* gpu) {
+ // make sure we've not been abandoned
+ if (fDesc.fID && !fDesc.fIsWrapped) {
+ GL_CALL(gpu, DeleteBuffers(1, &fDesc.fID));
+ if (GR_GL_ARRAY_BUFFER == fBufferType) {
+ gpu->notifyVertexBufferDelete(fDesc.fID);
+ } else {
+ GrAssert(GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
+ gpu->notifyIndexBufferDelete(fDesc.fID);
+ }
+ fDesc.fID = 0;
+ }
+}
+
+void GrGLBufferImpl::abandon() {
+ fDesc.fID = 0;
+ fLockPtr = NULL;
+}
+
+void GrGLBufferImpl::bind(GrGpuGL* gpu) const {
+ GL_CALL(gpu, BindBuffer(fBufferType, fDesc.fID));
+ if (GR_GL_ARRAY_BUFFER == fBufferType) {
+ gpu->notifyVertexBufferBind(fDesc.fID);
+ } else {
+ GrAssert(GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
+ gpu->notifyIndexBufferBind(fDesc.fID);
+ }
+}
+
+void* GrGLBufferImpl::lock(GrGpuGL* gpu) {
+ GrAssert(0 != fDesc.fID);
+ GrAssert(!this->isLocked());
+ if (gpu->getCaps().bufferLockSupport()) {
+ this->bind(gpu);
+ // Let driver know it can discard the old data
+ GL_CALL(gpu, BufferData(fBufferType,
+ fDesc.fSizeInBytes,
+ NULL,
+ fDesc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
+ GR_GL_CALL_RET(gpu->glInterface(),
+ fLockPtr,
+ MapBuffer(fBufferType, GR_GL_WRITE_ONLY));
+ return fLockPtr;
+ }
+ return NULL;
+}
+
+void GrGLBufferImpl::unlock(GrGpuGL* gpu) {
+
+ GrAssert(0 != fDesc.fID);
+ GrAssert(this->isLocked());
+ GrAssert(gpu->getCaps().bufferLockSupport());
+
+ this->bind(gpu);
+ GL_CALL(gpu, UnmapBuffer(fBufferType));
+ fLockPtr = NULL;
+}
+
+bool GrGLBufferImpl::isLocked() const {
+ GrAssert(0 != fDesc.fID);
+ return NULL != fLockPtr;
+}
+
+bool GrGLBufferImpl::updateData(GrGpuGL* gpu, const void* src, size_t srcSizeInBytes) {
+ GrAssert(!this->isLocked());
+ if (srcSizeInBytes > fDesc.fSizeInBytes) {
+ return false;
+ }
+ if (0 == fDesc.fID) {
+ return false;
+ }
+ this->bind(gpu);
+ GrGLenum usage = fDesc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
+
+#if GR_GL_USE_BUFFER_DATA_NULL_HINT
+ if (fDesc.fSizeInBytes == srcSizeInBytes) {
+ GL_CALL(gpu, BufferData(fBufferType, srcSizeInBytes, src, usage));
+ } else {
+ // Before we call glBufferSubData we give the driver a hint using
+ // glBufferData with NULL. 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.
+ GL_CALL(gpu, BufferData(fBufferType, fDesc.fSizeInBytes, NULL, usage));
+ GL_CALL(gpu, BufferSubData(fBufferType, 0, 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 (lock() does a glBufferData(..size, NULL..))
+ bool doSubData = false;
+#if GR_GL_MAC_BUFFER_OBJECT_PERFOMANCE_WORKAROUND
+ static int N = 0;
+ // 128 was chosen experimentally. At 256 a slight hitchiness was noticed
+ // when dragging a Chromium window around with a canvas tab backgrounded.
+ doSubData = 0 == (N % 128);
+ ++N;
+#endif
+ if (doSubData) {
+ // The workaround is to do a glBufferData followed by glBufferSubData.
+ // Chromium's command buffer may turn a glBufferSubData where the size
+ // exactly matches the buffer size into a glBufferData. So we tack 1
+ // extra byte onto the glBufferData.
+ GL_CALL(gpu, BufferData(fBufferType, srcSizeInBytes + 1, NULL, usage));
+ GL_CALL(gpu, BufferSubData(fBufferType, 0, srcSizeInBytes, src));
+ } else {
+ GL_CALL(gpu, BufferData(fBufferType, srcSizeInBytes, src, usage));
+ }
+#endif
+ return true;
+}
diff --git a/src/gpu/gl/GrGLBufferImpl.h b/src/gpu/gl/GrGLBufferImpl.h
new file mode 100644
index 0000000000..7b44f14dc1
--- /dev/null
+++ b/src/gpu/gl/GrGLBufferImpl.h
@@ -0,0 +1,57 @@
+/*
+ * 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 "GrNoncopyable.h"
+#include "gl/GrGLFunctions.h"
+
+class GrGpuGL;
+
+/**
+ * This class serves as the implementation of GrGL*Buffer classes. It was written to avoid code
+ * duplication in those classes.
+ */
+class GrGLBufferImpl : public GrNoncopyable {
+public:
+ struct Desc {
+ bool fIsWrapped;
+ GrGLuint fID;
+ size_t fSizeInBytes;
+ bool fDynamic;
+ };
+
+ GrGLBufferImpl(GrGpuGL*, const Desc&, GrGLenum bufferType);
+ ~GrGLBufferImpl() {
+ // either release or abandon should have been called by the owner of this object.
+ GrAssert(0 == fDesc.fID);
+ }
+
+ void abandon();
+ void release(GrGpuGL* gpu);
+
+ GrGLuint bufferID() const { return fDesc.fID; }
+ size_t baseOffset() const { return 0; }
+
+ void bind(GrGpuGL* gpu) const;
+
+ void* lock(GrGpuGL* gpu);
+ void* lockPtr() const { return fLockPtr; }
+ void unlock(GrGpuGL* gpu);
+ bool isLocked() const;
+ bool updateData(GrGpuGL* gpu, const void* src, size_t srcSizeInBytes);
+
+private:
+ Desc fDesc;
+ GrGLenum fBufferType; // GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER
+ void* fLockPtr;
+
+ typedef GrNoncopyable INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLIndexBuffer.cpp b/src/gpu/gl/GrGLIndexBuffer.cpp
index 035bfaccce..ff167347f9 100644
--- a/src/gpu/gl/GrGLIndexBuffer.cpp
+++ b/src/gpu/gl/GrGLIndexBuffer.cpp
@@ -5,129 +5,53 @@
* found in the LICENSE file.
*/
-
-
#include "GrGLIndexBuffer.h"
#include "GrGpuGL.h"
-#define GPUGL static_cast<GrGpuGL*>(getGpu())
-
-#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
-
-GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu,
- bool isWrapped,
- GrGLuint id,
- size_t sizeInBytes,
- bool dynamic)
- : INHERITED(gpu, isWrapped, sizeInBytes, dynamic)
- , fBufferID(id)
- , fLockPtr(NULL) {
-
+GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu, const Desc& desc)
+ : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic)
+ , fImpl(gpu, desc, GR_GL_ELEMENT_ARRAY_BUFFER) {
}
void GrGLIndexBuffer::onRelease() {
- // make sure we've not been abandoned
- if (fBufferID && !this->isWrapped()) {
- GPUGL->notifyIndexBufferDelete(this);
- GL_CALL(DeleteBuffers(1, &fBufferID));
- fBufferID = 0;
+ if (this->isValid()) {
+ fImpl.release(this->getGpuGL());
}
INHERITED::onRelease();
}
void GrGLIndexBuffer::onAbandon() {
- fBufferID = 0;
- fLockPtr = NULL;
-
+ fImpl.abandon();
INHERITED::onAbandon();
}
-void GrGLIndexBuffer::bind() const {
- GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, fBufferID));
- GPUGL->notifyIndexBufferBind(this);
-}
-
void* GrGLIndexBuffer::lock() {
- GrAssert(fBufferID);
- GrAssert(!isLocked());
- if (this->getGpu()->getCaps().bufferLockSupport()) {
- this->bind();
- // Let driver know it can discard the old data
- GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
- this->sizeInBytes(),
- NULL,
- this->dynamic() ? GR_GL_DYNAMIC_DRAW :
- GR_GL_STATIC_DRAW));
- GR_GL_CALL_RET(GPUGL->glInterface(),
- fLockPtr,
- MapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
- GR_GL_WRITE_ONLY));
-
- return fLockPtr;
+ if (this->isValid()) {
+ return fImpl.lock(this->getGpuGL());
+ } else {
+ return NULL;
}
- return NULL;
}
void* GrGLIndexBuffer::lockPtr() const {
- return fLockPtr;
+ return fImpl.lockPtr();
}
void GrGLIndexBuffer::unlock() {
- GrAssert(fBufferID);
- GrAssert(isLocked());
- GrAssert(this->getGpu()->getCaps().bufferLockSupport());
-
- this->bind();
- GL_CALL(UnmapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER));
- fLockPtr = NULL;
+ if (this->isValid()) {
+ fImpl.unlock(this->getGpuGL());
+ }
}
bool GrGLIndexBuffer::isLocked() const {
- // this check causes a lot of noise in the gl log
-#if 0
- if (this->isValid() && this->getGpu()->getCaps().fBufferLockSupport) {
- this->bind();
- GrGLint mapped;
- GL_CALL(GetBufferParameteriv(GR_GL_ELEMENT_ARRAY_BUFFER,
- GR_GL_BUFFER_MAPPED, &mapped));
- GrAssert(!!mapped == !!fLockPtr);
- }
-#endif
- return NULL != fLockPtr;
+ return fImpl.isLocked();
}
bool GrGLIndexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
- GrAssert(fBufferID);
- GrAssert(!isLocked());
- if (srcSizeInBytes > this->sizeInBytes()) {
- return false;
- }
- this->bind();
- GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
-
-#if GR_GL_USE_BUFFER_DATA_NULL_HINT
- if (this->sizeInBytes() == srcSizeInBytes) {
- GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
- srcSizeInBytes, src, usage));
+ if (this->isValid()) {
+ return fImpl.updateData(this->getGpuGL(), src, srcSizeInBytes);
} else {
- // Before we call glBufferSubData we give the driver a hint using
- // glBufferData with NULL. 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.
- GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
- this->sizeInBytes(), NULL, usage));
- GL_CALL(BufferSubData(GR_GL_ELEMENT_ARRAY_BUFFER,
- 0, srcSizeInBytes, src));
+ return false;
}
-#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 (lock() does a glBufferData(..size, NULL..))
- GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
- srcSizeInBytes, src, usage));
-#endif
- return true;
}
diff --git a/src/gpu/gl/GrGLIndexBuffer.h b/src/gpu/gl/GrGLIndexBuffer.h
index 5182573abf..5c8588b211 100644
--- a/src/gpu/gl/GrGLIndexBuffer.h
+++ b/src/gpu/gl/GrGLIndexBuffer.h
@@ -5,12 +5,11 @@
* found in the LICENSE file.
*/
-
-
#ifndef GrGLIndexBuffer_DEFINED
#define GrGLIndexBuffer_DEFINED
#include "GrIndexBuffer.h"
+#include "GrGLBufferImpl.h"
#include "gl/GrGLInterface.h"
class GrGpuGL;
@@ -18,19 +17,19 @@ class GrGpuGL;
class GrGLIndexBuffer : public GrIndexBuffer {
public:
+ typedef GrGLBufferImpl::Desc Desc;
- GrGLIndexBuffer(GrGpuGL* gpu,
- bool isWrapped,
- GrGLuint id,
- size_t sizeInBytes,
- bool dynamic);
-
+ GrGLIndexBuffer(GrGpuGL* gpu, const Desc& desc);
virtual ~GrGLIndexBuffer() { this->release(); }
- GrGLuint bufferID() const { return fBufferID; }
- size_t baseOffset() const { return 0; }
+ GrGLuint bufferID() const { return fImpl.bufferID(); }
+ size_t baseOffset() const { return fImpl.baseOffset(); }
- void bind() const;
+ void bind() const {
+ if (this->isValid()) {
+ fImpl.bind(this->getGpuGL());
+ }
+ }
// overrides of GrIndexBuffer
virtual void* lock();
@@ -40,15 +39,17 @@ public:
virtual bool updateData(const void* src, size_t srcSizeInBytes);
protected:
-
// overrides of GrResource
virtual void onAbandon() SK_OVERRIDE;
virtual void onRelease() SK_OVERRIDE;
private:
+ GrGpuGL* getGpuGL() const {
+ GrAssert(this->isValid());
+ return (GrGpuGL*)(this->getGpu());
+ }
- GrGLuint fBufferID;
- void* fLockPtr;
+ GrGLBufferImpl fImpl;
typedef GrIndexBuffer INHERITED;
};
diff --git a/src/gpu/gl/GrGLVertexBuffer.cpp b/src/gpu/gl/GrGLVertexBuffer.cpp
index 42b76ea4a8..4152251433 100644
--- a/src/gpu/gl/GrGLVertexBuffer.cpp
+++ b/src/gpu/gl/GrGLVertexBuffer.cpp
@@ -5,141 +5,54 @@
* found in the LICENSE file.
*/
-
-
#include "GrGLVertexBuffer.h"
#include "GrGpuGL.h"
-#define GPUGL static_cast<GrGpuGL*>(getGpu())
-
-#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
-
-GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu,
- bool isWrapped,
- GrGLuint id,
- size_t sizeInBytes,
- bool dynamic)
- : INHERITED(gpu, isWrapped, sizeInBytes, dynamic)
- , fBufferID(id)
- , fLockPtr(NULL) {
+GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu, const Desc& desc)
+ : INHERITED(gpu, desc.fIsWrapped, desc.fSizeInBytes, desc.fDynamic)
+ , fImpl(gpu, desc, GR_GL_ARRAY_BUFFER) {
}
void GrGLVertexBuffer::onRelease() {
- // make sure we've not been abandoned
- if (fBufferID && !this->isWrapped()) {
- GPUGL->notifyVertexBufferDelete(this);
- GL_CALL(DeleteBuffers(1, &fBufferID));
- fBufferID = 0;
+ if (this->isValid()) {
+ fImpl.release(this->getGpuGL());
}
INHERITED::onRelease();
}
-void GrGLVertexBuffer::onAbandon() {
- fBufferID = 0;
- fLockPtr = NULL;
+void GrGLVertexBuffer::onAbandon() {
+ fImpl.abandon();
INHERITED::onAbandon();
}
-void GrGLVertexBuffer::bind() const {
- GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, fBufferID));
- GPUGL->notifyVertexBufferBind(this);
-}
-
void* GrGLVertexBuffer::lock() {
- GrAssert(fBufferID);
- GrAssert(!isLocked());
- if (this->getGpu()->getCaps().bufferLockSupport()) {
- this->bind();
- // Let driver know it can discard the old data
- GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, this->sizeInBytes(), NULL,
- this->dynamic() ? GR_GL_DYNAMIC_DRAW :
- GR_GL_STATIC_DRAW));
- GR_GL_CALL_RET(GPUGL->glInterface(),
- fLockPtr,
- MapBuffer(GR_GL_ARRAY_BUFFER, GR_GL_WRITE_ONLY));
- return fLockPtr;
+ if (this->isValid()) {
+ return fImpl.lock(this->getGpuGL());
+ } else {
+ return NULL;
}
- return NULL;
}
void* GrGLVertexBuffer::lockPtr() const {
- return fLockPtr;
+ return fImpl.lockPtr();
}
void GrGLVertexBuffer::unlock() {
-
- GrAssert(fBufferID);
- GrAssert(isLocked());
- GrAssert(this->getGpu()->getCaps().bufferLockSupport());
-
- this->bind();
- GL_CALL(UnmapBuffer(GR_GL_ARRAY_BUFFER));
- fLockPtr = NULL;
+ if (this->isValid()) {
+ fImpl.unlock(this->getGpuGL());
+ }
}
bool GrGLVertexBuffer::isLocked() const {
- GrAssert(!this->isValid() || fBufferID);
- // this check causes a lot of noise in the gl log
-#if 0
- if (this->isValid() && this->getGpu()->getCaps().fBufferLockSupport) {
- GrGLint mapped;
- this->bind();
- GL_CALL(GetBufferParameteriv(GR_GL_ARRAY_BUFFER,
- GR_GL_BUFFER_MAPPED, &mapped));
- GrAssert(!!mapped == !!fLockPtr);
- }
-#endif
- return NULL != fLockPtr;
+ return fImpl.isLocked();
}
bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
- GrAssert(fBufferID);
- GrAssert(!isLocked());
- if (srcSizeInBytes > this->sizeInBytes()) {
- return false;
- }
- this->bind();
- GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
-
-#if GR_GL_USE_BUFFER_DATA_NULL_HINT
- if (this->sizeInBytes() == srcSizeInBytes) {
- GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
- } else {
- // Before we call glBufferSubData we give the driver a hint using
- // glBufferData with NULL. 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.
- GL_CALL(BufferData(GR_GL_ARRAY_BUFFER,
- this->sizeInBytes(), NULL, usage));
- GL_CALL(BufferSubData(GR_GL_ARRAY_BUFFER, 0, 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 (lock() does a glBufferData(..size, NULL..))
- bool doSubData = false;
-#if GR_GL_MAC_BUFFER_OBJECT_PERFOMANCE_WORKAROUND
- static int N = 0;
- // 128 was chosen experimentally. At 256 a slight hitchiness was noticed
- // when dragging a Chromium window around with a canvas tab backgrounded.
- doSubData = 0 == (N % 128);
- ++N;
-#endif
- if (doSubData) {
- // The workaround is to do a glBufferData followed by glBufferSubData.
- // Chromium's command buffer may turn a glBufferSubData where the size
- // exactly matches the buffer size into a glBufferData. So we tack 1
- // extra byte onto the glBufferData.
- GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes + 1,
- NULL, usage));
- GL_CALL(BufferSubData(GR_GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
+ if (this->isValid()) {
+ return fImpl.updateData(this->getGpuGL(), src, srcSizeInBytes);
} else {
- GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
+ return false;
}
-#endif
- return true;
}
diff --git a/src/gpu/gl/GrGLVertexBuffer.h b/src/gpu/gl/GrGLVertexBuffer.h
index 61b5020404..f15a5dab63 100644
--- a/src/gpu/gl/GrGLVertexBuffer.h
+++ b/src/gpu/gl/GrGLVertexBuffer.h
@@ -5,12 +5,11 @@
* found in the LICENSE file.
*/
-
-
#ifndef GrGLVertexBuffer_DEFINED
#define GrGLVertexBuffer_DEFINED
#include "GrVertexBuffer.h"
+#include "GrGLBufferImpl.h"
#include "gl/GrGLInterface.h"
class GrGpuGL;
@@ -18,17 +17,19 @@ class GrGpuGL;
class GrGLVertexBuffer : public GrVertexBuffer {
public:
- GrGLVertexBuffer(GrGpuGL* gpu,
- bool isWrapped,
- GrGLuint id,
- size_t sizeInBytes,
- bool dynamic);
+ typedef GrGLBufferImpl::Desc Desc;
+
+ GrGLVertexBuffer(GrGpuGL* gpu, const Desc& desc);
virtual ~GrGLVertexBuffer() { this->release(); }
- GrGLuint bufferID() const { return fBufferID; }
- size_t baseOffset() const { return 0; }
+ GrGLuint bufferID() const { return fImpl.bufferID(); }
+ size_t baseOffset() const { return fImpl.baseOffset(); }
- void bind() const;
+ void bind() const {
+ if (this->isValid()) {
+ fImpl.bind(this->getGpuGL());
+ }
+ }
// overrides of GrVertexBuffer
virtual void* lock();
@@ -43,9 +44,12 @@ protected:
virtual void onRelease() SK_OVERRIDE;
private:
+ GrGpuGL* getGpuGL() const {
+ GrAssert(this->isValid());
+ return (GrGpuGL*)(this->getGpu());
+ }
- GrGLuint fBufferID;
- void* fLockPtr;
+ GrGLBufferImpl fImpl;
typedef GrVertexBuffer INHERITED;
};
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index abf5ac937b..785b500899 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1226,58 +1226,58 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
////////////////////////////////////////////////////////////////////////////////
GrVertexBuffer* GrGpuGL::onCreateVertexBuffer(uint32_t size, bool dynamic) {
- GrGLuint id;
- GL_CALL(GenBuffers(1, &id));
- if (id) {
- GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, id));
+ GrGLVertexBuffer::Desc desc;
+ desc.fDynamic = 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,
- size,
+ desc.fSizeInBytes,
NULL, // data ptr
- dynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
+ desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
- GL_CALL(DeleteBuffers(1, &id));
+ GL_CALL(DeleteBuffers(1, &desc.fID));
// deleting bound buffer does implicit bind to 0
fHWGeometryState.setVertexBufferID(0);
return NULL;
}
- static const bool kIsWrapped = false;
- GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this,
- kIsWrapped,
- id,
- size,
- dynamic));
- fHWGeometryState.setVertexBufferID(id);
+ GrGLVertexBuffer* vertexBuffer = SkNEW_ARGS(GrGLVertexBuffer, (this, desc));
+ fHWGeometryState.setVertexBufferID(desc.fID);
return vertexBuffer;
}
return NULL;
}
GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
- GrGLuint id;
- GL_CALL(GenBuffers(1, &id));
- if (id) {
- GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id));
+ GrGLIndexBuffer::Desc desc;
+ desc.fDynamic = 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,
- size,
+ desc.fSizeInBytes,
NULL, // data ptr
- dynamic ? GR_GL_DYNAMIC_DRAW :
- GR_GL_STATIC_DRAW));
+ desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
- GL_CALL(DeleteBuffers(1, &id));
+ GL_CALL(DeleteBuffers(1, &desc.fID));
// deleting bound buffer does implicit bind to 0
fHWGeometryState.setIndexBufferID(0);
return NULL;
}
- static const bool kIsWrapped = false;
- GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer,
- (this, kIsWrapped, id, size, dynamic));
- fHWGeometryState.setIndexBufferID(id);
+ GrIndexBuffer* indexBuffer = SkNEW_ARGS(GrGLIndexBuffer, (this, desc));
+ fHWGeometryState.setIndexBufferID(desc.fID);
return indexBuffer;
}
return NULL;
@@ -2145,20 +2145,20 @@ void GrGpuGL::flushMiscFixedFunctionState() {
}
}
-void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) {
- fHWGeometryState.setVertexBufferID(buffer->bufferID());
+void GrGpuGL::notifyVertexBufferBind(GrGLuint id) {
+ fHWGeometryState.setVertexBufferID(id);
}
-void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) {
- fHWGeometryState.notifyVertexBufferDelete(buffer);
+void GrGpuGL::notifyVertexBufferDelete(GrGLuint id) {
+ fHWGeometryState.notifyVertexBufferDelete(id);
}
-void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
- fHWGeometryState.setIndexBufferID(buffer->bufferID());
+void GrGpuGL::notifyIndexBufferBind(GrGLuint id) {
+ fHWGeometryState.setIndexBufferID(id);
}
-void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
- fHWGeometryState.notifyIndexBufferDelete(buffer);
+void GrGpuGL::notifyIndexBufferDelete(GrGLuint id) {
+ fHWGeometryState.notifyIndexBufferDelete(id);
}
void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index fae4a93c6c..8d1e7dda45 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -58,10 +58,10 @@ public:
const GrGLCaps& glCaps() const { return fGLContextInfo.caps(); }
// Callbacks to update state tracking when related GL objects are bound or deleted
- void notifyVertexBufferBind(const GrGLVertexBuffer* buffer);
- void notifyVertexBufferDelete(const GrGLVertexBuffer* buffer);
- void notifyIndexBufferBind(const GrGLIndexBuffer* buffer);
- void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer);
+ void notifyVertexBufferBind(GrGLuint id);
+ void notifyVertexBufferDelete(GrGLuint id);
+ void notifyIndexBufferBind(GrGLuint id);
+ void notifyIndexBufferDelete(GrGLuint id);
void notifyTextureDelete(GrGLTexture* texture);
void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
@@ -291,8 +291,7 @@ private:
}
}
- void notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) {
- GrGLuint id = buffer->bufferID();
+ void notifyVertexBufferDelete(GrGLuint id) {
if (0 != id) {
if (this->isVertexBufferIDBound(id)) {
// deleting bound buffer does implied bind to 0
@@ -306,8 +305,7 @@ private:
}
}
- void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
- GrGLuint id = buffer->bufferID();
+ void notifyIndexBufferDelete(GrGLuint id) {
if (0 != id) {
if (this->isIndexBufferIDBound(id)) {
// deleting bound buffer does implied bind to 0