blob: 9f09d0d3f8b233671584050d1c12192749e184c3 [file]
/*
* 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