| /* |
| * Copyright 2026 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/graphite/StorageBufferManager.h" |
| |
| #include "src/gpu/graphite/BufferManager.h" |
| #include "src/shaders/gradients/SkGradientBaseShader.h" |
| |
| namespace skgpu::graphite { |
| |
| StorageBufferManager::~StorageBufferManager() { this->reset(); } |
| |
| void StorageBufferManager::GradientCache::reset() { |
| for (auto [k, _] : fOffsetCache) { |
| k->unref(); |
| } |
| fOffsetCache.reset(); |
| fStorage.clear(); |
| } |
| |
| void StorageBufferManager::reset() { |
| fGradientCache.reset(); |
| fBufferInfo.reset(); |
| } |
| |
| std::pair<float*, int> StorageBufferManager::allocateGradientData( |
| int numStops, const SkGradientBaseShader* shader) { |
| SkASSERT(!this->isFinalized()); |
| if (numStops > GradientCache::kMaxGradientStops) { |
| return {nullptr, -1}; |
| } |
| |
| int* existingOffset = fGradientCache.fOffsetCache.find(shader); |
| if (existingOffset) { |
| return {nullptr, *existingOffset}; |
| } |
| |
| int floatCount = numStops * 5; |
| int currentFloatCount = fGradientCache.fStorage.size(); |
| if (GradientCache::kMaxStorageFloats - floatCount < currentFloatCount) { |
| return {nullptr, -1}; |
| } |
| |
| float* startPtr = fGradientCache.fStorage.append(floatCount); |
| |
| // Since StorageBufferManager is single threaded, adding a ref and then storing in the |
| // map should be fine. |
| shader->ref(); |
| fGradientCache.fOffsetCache.set(shader, currentFloatCount); |
| |
| return {startPtr, currentFloatCount}; |
| } |
| |
| bool StorageBufferManager::finalize(DrawBufferManager* bufferMgr) { |
| SkASSERT(!this->isFinalized()); |
| size_t totalBytes = fGradientCache.fStorage.size_bytes(); |
| if (totalBytes > 0) { |
| auto [writer, bufferInfo, _] = |
| bufferMgr->getMappedStorageBuffer(totalBytes, sizeof(float)); |
| if (writer) { |
| if (!fGradientCache.fStorage.empty()) { |
| writer.write(fGradientCache.fStorage.data(), fGradientCache.fStorage.size_bytes()); |
| } |
| this->reset(); |
| fBufferInfo = bufferInfo; |
| return true; |
| } |
| return false; |
| } else { |
| fBufferInfo = BindBufferInfo(); |
| } |
| return true; |
| } |
| |
| } // namespace skgpu::graphite |