/* * 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 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); } }