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