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_throw(sizeInBytes);
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