1 /* 2 * Copyright 2016 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 "GrBuffer.h" 9 #include "GrGpu.h" 10 #include "GrCaps.h" 11 12 GrBuffer* GrBuffer::CreateCPUBacked(GrGpu* gpu, size_t sizeInBytes, GrBufferType intendedType, 13 const void* data) { 14 SkASSERT(GrBufferTypeIsVertexOrIndex(intendedType)); 15 void* cpuData; 16 if (gpu->caps()->mustClearUploadedBufferData()) { 17 cpuData = sk_calloc_throw(sizeInBytes); 18 } else { 19 cpuData = sk_malloc_flags(sizeInBytes, SK_MALLOC_THROW); 20 } 21 if (data) { 22 memcpy(cpuData, data, sizeInBytes); 23 } 24 return new GrBuffer(gpu, sizeInBytes, intendedType, cpuData); 25 } 26 27 GrBuffer::GrBuffer(GrGpu* gpu, size_t sizeInBytes, GrBufferType type, void* cpuData) 28 : INHERITED(gpu) 29 , fMapPtr(nullptr) 30 , fSizeInBytes(sizeInBytes) 31 , fAccessPattern(kDynamic_GrAccessPattern) 32 , fCPUData(cpuData) 33 , fIntendedType(type) { 34 this->registerWithCache(SkBudgeted::kNo); 35 } 36 37 GrBuffer::GrBuffer(GrGpu* gpu, size_t sizeInBytes, GrBufferType type, GrAccessPattern pattern) 38 : INHERITED(gpu) 39 , fMapPtr(nullptr) 40 , fSizeInBytes(sizeInBytes) 41 , fAccessPattern(pattern) 42 , fCPUData(nullptr) 43 , fIntendedType(type) { 44 // Subclass registers with cache. 45 } 46 47 void GrBuffer::ComputeScratchKeyForDynamicVBO(size_t size, GrBufferType intendedType, 48 GrScratchKey* key) { 49 static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType(); 50 GrScratchKey::Builder builder(key, kType, 1 + (sizeof(size_t) + 3) / 4); 51 // TODO: There's not always reason to cache a buffer by type. In some (all?) APIs it's just 52 // a chunk of memory we can use/reuse for any type of data. We really only need to 53 // differentiate between the "read" types (e.g. kGpuToCpu_BufferType) and "draw" types. 54 builder[0] = intendedType; 55 builder[1] = (uint32_t)size; 56 if (sizeof(size_t) > 4) { 57 builder[2] = (uint32_t)((uint64_t)size >> 32); 58 } 59 } 60 61 bool GrBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) { 62 SkASSERT(this->isCPUBacked()); 63 memcpy(fCPUData, src, srcSizeInBytes); 64 return true; 65 } 66 67 void GrBuffer::computeScratchKey(GrScratchKey* key) const { 68 if (!this->isCPUBacked() && SkIsPow2(fSizeInBytes) && 69 kDynamic_GrAccessPattern == fAccessPattern) { 70 ComputeScratchKeyForDynamicVBO(fSizeInBytes, fIntendedType, key); 71 } 72 } 73