| /* |
| * Copyright 2019 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/ganesh/GrGpuBuffer.h" |
| |
| #include "include/private/base/SkAlign.h" |
| #include "include/private/base/SkAssert.h" |
| #include "include/private/base/SkTo.h" |
| #include "src/gpu/ResourceKey.h" |
| #include "src/gpu/ganesh/GrCaps.h" |
| #include "src/gpu/ganesh/GrGpu.h" |
| |
| #include <cstdint> |
| |
| GrGpuBuffer::GrGpuBuffer(GrGpu* gpu, size_t sizeInBytes, GrGpuBufferType type, |
| GrAccessPattern pattern, |
| std::string_view label) |
| : GrGpuResource(gpu, label) |
| , fMapPtr(nullptr) |
| , fSizeInBytes(sizeInBytes) |
| , fAccessPattern(pattern) |
| , fIntendedType(type) {} |
| |
| void* GrGpuBuffer::map() { |
| if (this->wasDestroyed()) { |
| return nullptr; |
| } |
| if (!fMapPtr) { |
| this->onMap(this->mapType()); |
| } |
| return fMapPtr; |
| } |
| |
| void GrGpuBuffer::unmap() { |
| if (this->wasDestroyed()) { |
| return; |
| } |
| SkASSERT(fMapPtr); |
| this->onUnmap(this->mapType()); |
| fMapPtr = nullptr; |
| } |
| |
| bool GrGpuBuffer::isMapped() const { return SkToBool(fMapPtr); } |
| |
| bool GrGpuBuffer::clearToZero() { |
| SkASSERT(!this->isMapped()); |
| |
| if (this->wasDestroyed()) { |
| return false; |
| } |
| |
| if (this->intendedType() == GrGpuBufferType::kXferGpuToCpu) { |
| return false; |
| } |
| |
| return this->onClearToZero(); |
| } |
| |
| bool GrGpuBuffer::updateData(const void* src, size_t offset, size_t size, bool preserve) { |
| SkASSERT(!this->isMapped()); |
| SkASSERT(size > 0 && offset + size <= fSizeInBytes); |
| SkASSERT(src); |
| |
| if (this->wasDestroyed()) { |
| return false; |
| } |
| |
| if (preserve) { |
| size_t a = this->getGpu()->caps()->bufferUpdateDataPreserveAlignment(); |
| if (SkAlignTo(offset, a) != offset || SkAlignTo(size, a) != size) { |
| return false; |
| } |
| } |
| |
| if (this->intendedType() == GrGpuBufferType::kXferGpuToCpu) { |
| return false; |
| } |
| |
| return this->onUpdateData(src, offset, size, preserve); |
| } |
| |
| void GrGpuBuffer::ComputeScratchKeyForDynamicBuffer(size_t size, |
| GrGpuBufferType intendedType, |
| skgpu::ScratchKey* key) { |
| static const skgpu::ScratchKey::ResourceType kType = skgpu::ScratchKey::GenerateResourceType(); |
| skgpu::ScratchKey::Builder builder(key, kType, 1 + (sizeof(size_t) + 3) / 4); |
| builder[0] = SkToU32(intendedType); |
| builder[1] = (uint32_t)size; |
| if (sizeof(size_t) > 4) { |
| builder[2] = (uint32_t)((uint64_t)size >> 32); |
| } |
| } |
| |
| void GrGpuBuffer::computeScratchKey(skgpu::ScratchKey* key) const { |
| if (kDynamic_GrAccessPattern == fAccessPattern) { |
| ComputeScratchKeyForDynamicBuffer(fSizeInBytes, fIntendedType, key); |
| } |
| } |