blob: cd7862a226bc74c9473fa1bff015a8601519a40c [file] [log] [blame]
csmartdalton485a1202016-07-13 10:16:32 -07001/*
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
12GrBuffer* 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 {
Mike Reed8dc8dbc2018-01-05 11:20:10 -050019 cpuData = sk_malloc_throw(sizeInBytes);
csmartdalton485a1202016-07-13 10:16:32 -070020 }
21 if (data) {
22 memcpy(cpuData, data, sizeInBytes);
23 }
24 return new GrBuffer(gpu, sizeInBytes, intendedType, cpuData);
25}
26
27GrBuffer::GrBuffer(GrGpu* gpu, size_t sizeInBytes, GrBufferType type, void* cpuData)
Robert Phillipsa5b39fa2017-06-08 15:34:16 -040028 : INHERITED(gpu)
29 , fMapPtr(nullptr)
30 , fSizeInBytes(sizeInBytes)
31 , fAccessPattern(kDynamic_GrAccessPattern)
32 , fCPUData(cpuData)
33 , fIntendedType(type) {
csmartdalton485a1202016-07-13 10:16:32 -070034 this->registerWithCache(SkBudgeted::kNo);
35}
36
37GrBuffer::GrBuffer(GrGpu* gpu, size_t sizeInBytes, GrBufferType type, GrAccessPattern pattern)
Robert Phillipsa5b39fa2017-06-08 15:34:16 -040038 : INHERITED(gpu)
39 , fMapPtr(nullptr)
40 , fSizeInBytes(sizeInBytes)
41 , fAccessPattern(pattern)
42 , fCPUData(nullptr)
43 , fIntendedType(type) {
csmartdalton485a1202016-07-13 10:16:32 -070044 // Subclass registers with cache.
45}
46
47void 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
61bool GrBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
62 SkASSERT(this->isCPUBacked());
63 memcpy(fCPUData, src, srcSizeInBytes);
64 return true;
65}
66
67void GrBuffer::computeScratchKey(GrScratchKey* key) const {
68 if (!this->isCPUBacked() && SkIsPow2(fSizeInBytes) &&
69 kDynamic_GrAccessPattern == fAccessPattern) {
70 ComputeScratchKeyForDynamicVBO(fSizeInBytes, fIntendedType, key);
71 }
72}