1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrGLBufferImpl.h" 9 #include "GrGLGpu.h" 10 11 #define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X) 12 13 #ifdef SK_DEBUG 14 #define VALIDATE() this->validate() 15 #else 16 #define VALIDATE() do {} while(false) 17 #endif 18 19 GrGLBufferImpl::GrGLBufferImpl(GrGLGpu* gpu, const Desc& desc, GrGLenum bufferType) 20 : fDesc(desc) 21 , fBufferType(bufferType) 22 , fMapPtr(nullptr) { 23 if (0 == desc.fID) { 24 if (gpu->caps()->mustClearUploadedBufferData()) { 25 fCPUData = sk_calloc_throw(desc.fSizeInBytes); 26 } else { 27 fCPUData = sk_malloc_flags(desc.fSizeInBytes, SK_MALLOC_THROW); 28 } 29 fGLSizeInBytes = 0; 30 } else { 31 fCPUData = nullptr; 32 // We assume that the GL buffer was created at the desc's size initially. 33 fGLSizeInBytes = fDesc.fSizeInBytes; 34 } 35 VALIDATE(); 36 } 37 38 void GrGLBufferImpl::release(GrGLGpu* gpu) { 39 VALIDATE(); 40 // make sure we've not been abandoned or already released 41 if (fCPUData) { 42 sk_free(fCPUData); 43 fCPUData = nullptr; 44 } else if (fDesc.fID) { 45 gpu->releaseBuffer(fDesc.fID, fBufferType); 46 fDesc.fID = 0; 47 fGLSizeInBytes = 0; 48 } 49 fMapPtr = nullptr; 50 VALIDATE(); 51 } 52 53 void GrGLBufferImpl::abandon() { 54 fDesc.fID = 0; 55 fGLSizeInBytes = 0; 56 fMapPtr = nullptr; 57 sk_free(fCPUData); 58 fCPUData = nullptr; 59 VALIDATE(); 60 } 61 62 void* GrGLBufferImpl::map(GrGLGpu* gpu) { 63 VALIDATE(); 64 SkASSERT(!this->isMapped()); 65 if (0 == fDesc.fID) { 66 fMapPtr = fCPUData; 67 } else { 68 fMapPtr = gpu->mapBuffer(fDesc.fID, fBufferType, fDesc.fUsage, fGLSizeInBytes, 69 fDesc.fSizeInBytes); 70 fGLSizeInBytes = fDesc.fSizeInBytes; 71 } 72 VALIDATE(); 73 return fMapPtr; 74 } 75 76 void GrGLBufferImpl::unmap(GrGLGpu* gpu) { 77 VALIDATE(); 78 SkASSERT(this->isMapped()); 79 if (0 != fDesc.fID) { 80 gpu->unmapBuffer(fDesc.fID, fBufferType, fMapPtr); 81 } 82 fMapPtr = nullptr; 83 } 84 85 bool GrGLBufferImpl::isMapped() const { 86 VALIDATE(); 87 return SkToBool(fMapPtr); 88 } 89 90 bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInBytes) { 91 SkASSERT(!this->isMapped()); 92 SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType); 93 VALIDATE(); 94 if (srcSizeInBytes > fDesc.fSizeInBytes) { 95 return false; 96 } 97 if (0 == fDesc.fID) { 98 memcpy(fCPUData, src, srcSizeInBytes); 99 return true; 100 } 101 gpu->bufferData(fDesc.fID, fBufferType, fDesc.fUsage, fDesc.fSizeInBytes, src, 102 srcSizeInBytes); 103 #if GR_GL_USE_BUFFER_DATA_NULL_HINT 104 fGLSizeInBytes = fDesc.fSizeInBytes; 105 #else 106 fGLSizeInBytes = srcSizeInBytes; 107 #endif 108 VALIDATE(); 109 return true; 110 } 111 112 void GrGLBufferImpl::validate() const { 113 SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType || 114 GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType || 115 GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fBufferType || 116 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fBufferType); 117 // The following assert isn't valid when the buffer has been abandoned: 118 // SkASSERT((0 == fDesc.fID) == (fCPUData)); 119 SkASSERT(nullptr == fCPUData || 0 == fGLSizeInBytes); 120 SkASSERT(nullptr == fMapPtr || fCPUData || fGLSizeInBytes <= fDesc.fSizeInBytes); 121 SkASSERT(nullptr == fCPUData || nullptr == fMapPtr || fCPUData == fMapPtr); 122 } 123