Index: src/gpu/gl/GrGLBufferImpl.cpp |
diff --git a/src/gpu/gl/GrGLBufferImpl.cpp b/src/gpu/gl/GrGLBufferImpl.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2babce80285cc1f2bb61e34e657db58b727a7142 |
--- /dev/null |
+++ b/src/gpu/gl/GrGLBufferImpl.cpp |
@@ -0,0 +1,122 @@ |
+/* |
+ * Copyright 2013 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "GrGLBufferImpl.h" |
+#include "GrGLGpu.h" |
+ |
+#define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X) |
+ |
+#ifdef SK_DEBUG |
+#define VALIDATE() this->validate() |
+#else |
+#define VALIDATE() do {} while(false) |
+#endif |
+ |
+GrGLBufferImpl::GrGLBufferImpl(GrGLGpu* gpu, const Desc& desc, GrGLenum bufferType) |
+ : fDesc(desc) |
+ , fBufferType(bufferType) |
+ , fMapPtr(nullptr) { |
+ if (0 == desc.fID) { |
+ if (gpu->caps()->mustClearUploadedBufferData()) { |
+ fCPUData = sk_calloc_throw(desc.fSizeInBytes); |
+ } else { |
+ fCPUData = sk_malloc_flags(desc.fSizeInBytes, SK_MALLOC_THROW); |
+ } |
+ fGLSizeInBytes = 0; |
+ } else { |
+ fCPUData = nullptr; |
+ // We assume that the GL buffer was created at the desc's size initially. |
+ fGLSizeInBytes = fDesc.fSizeInBytes; |
+ } |
+ VALIDATE(); |
+} |
+ |
+void GrGLBufferImpl::release(GrGLGpu* gpu) { |
+ VALIDATE(); |
+ // make sure we've not been abandoned or already released |
+ if (fCPUData) { |
+ sk_free(fCPUData); |
+ fCPUData = nullptr; |
+ } else if (fDesc.fID) { |
+ gpu->releaseBuffer(fDesc.fID, fBufferType); |
+ fDesc.fID = 0; |
+ fGLSizeInBytes = 0; |
+ } |
+ fMapPtr = nullptr; |
+ VALIDATE(); |
+} |
+ |
+void GrGLBufferImpl::abandon() { |
+ fDesc.fID = 0; |
+ fGLSizeInBytes = 0; |
+ fMapPtr = nullptr; |
+ sk_free(fCPUData); |
+ fCPUData = nullptr; |
+ VALIDATE(); |
+} |
+ |
+void* GrGLBufferImpl::map(GrGLGpu* gpu) { |
+ VALIDATE(); |
+ SkASSERT(!this->isMapped()); |
+ if (0 == fDesc.fID) { |
+ fMapPtr = fCPUData; |
+ } else { |
+ fMapPtr = gpu->mapBuffer(fDesc.fID, fBufferType, fDesc.fUsage, fGLSizeInBytes, |
+ fDesc.fSizeInBytes); |
+ fGLSizeInBytes = fDesc.fSizeInBytes; |
+ } |
+ VALIDATE(); |
+ return fMapPtr; |
+} |
+ |
+void GrGLBufferImpl::unmap(GrGLGpu* gpu) { |
+ VALIDATE(); |
+ SkASSERT(this->isMapped()); |
+ if (0 != fDesc.fID) { |
+ gpu->unmapBuffer(fDesc.fID, fBufferType, fMapPtr); |
+ } |
+ fMapPtr = nullptr; |
+} |
+ |
+bool GrGLBufferImpl::isMapped() const { |
+ VALIDATE(); |
+ return SkToBool(fMapPtr); |
+} |
+ |
+bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInBytes) { |
+ SkASSERT(!this->isMapped()); |
+ SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType); |
+ VALIDATE(); |
+ if (srcSizeInBytes > fDesc.fSizeInBytes) { |
+ return false; |
+ } |
+ if (0 == fDesc.fID) { |
+ memcpy(fCPUData, src, srcSizeInBytes); |
+ return true; |
+ } |
+ gpu->bufferData(fDesc.fID, fBufferType, fDesc.fUsage, fDesc.fSizeInBytes, src, |
+ srcSizeInBytes); |
+#if GR_GL_USE_BUFFER_DATA_NULL_HINT |
+ fGLSizeInBytes = fDesc.fSizeInBytes; |
+#else |
+ fGLSizeInBytes = srcSizeInBytes; |
+#endif |
+ VALIDATE(); |
+ return true; |
+} |
+ |
+void GrGLBufferImpl::validate() const { |
+ SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType || |
+ GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType || |
+ GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fBufferType || |
+ GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fBufferType); |
+ // The following assert isn't valid when the buffer has been abandoned: |
+ // SkASSERT((0 == fDesc.fID) == (fCPUData)); |
+ SkASSERT(nullptr == fCPUData || 0 == fGLSizeInBytes); |
+ SkASSERT(nullptr == fMapPtr || fCPUData || fGLSizeInBytes <= fDesc.fSizeInBytes); |
+ SkASSERT(nullptr == fCPUData || nullptr == fMapPtr || fCPUData == fMapPtr); |
+} |