#include "src/gpu/graphite/dawn/DawnBuffer.h"
#include "include/core/SkTraceMemoryDump.h"
#include "include/private/base/SkAlign.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/dawn/DawnAsyncWait.h"
#include "src/gpu/graphite/dawn/DawnSharedContext.h"
namespace skgpu::graphite {
namespace {
[[maybe_unused]]
bool is_map_succeeded(WGPUBufferMapAsyncStatus status) { … }
[[maybe_unused]]
void log_map_error(WGPUBufferMapAsyncStatus status, const char*) { … }
#if !defined(__EMSCRIPTEN__)
bool is_map_succeeded(wgpu::MapAsyncStatus status) { … }
void log_map_error(wgpu::MapAsyncStatus status, const char* message) { … }
#endif
}
sk_sp<DawnBuffer> DawnBuffer::Make(const DawnSharedContext* sharedContext,
size_t size,
BufferType type,
AccessPattern accessPattern) { … }
DawnBuffer::DawnBuffer(const DawnSharedContext* sharedContext,
size_t size,
wgpu::Buffer buffer,
void* mappedAtCreationPtr)
: … { … }
#if defined(__EMSCRIPTEN__)
void DawnBuffer::prepareForReturnToCache(const std::function<void()>& takeRef) {
SkASSERT(this->sharedContext()->caps()->bufferMapsAreAsync());
if (!(fBuffer.GetUsage() & wgpu::BufferUsage::MapWrite)) {
return;
}
SkASSERT(!this->debugHasCommandBufferRef());
if (this->isMapped()) {
return;
}
takeRef();
this->asyncMap([](void* ctx, skgpu::CallbackResult result) {
sk_sp<DawnBuffer> buffer(static_cast<DawnBuffer*>(ctx));
if (result != skgpu::CallbackResult::kSuccess) {
buffer->setDeleteASAP();
}
},
this);
}
void DawnBuffer::onAsyncMap(GpuFinishedProc proc, GpuFinishedContext ctx) {
SkASSERT(this->sharedContext()->caps()->bufferMapsAreAsync());
if (proc) {
SkAutoMutexExclusive ex(fAsyncMutex);
if (this->isMapped()) {
proc(ctx, CallbackResult::kSuccess);
return;
}
fAsyncMapCallbacks.push_back(RefCntedCallback::Make(proc, ctx));
}
if (this->isUnmappable()) {
return;
}
SkASSERT(fBuffer);
SkASSERT((fBuffer.GetUsage() & wgpu::BufferUsage::MapRead) ||
(fBuffer.GetUsage() & wgpu::BufferUsage::MapWrite));
SkASSERT(fBuffer.GetMapState() == wgpu::BufferMapState::Unmapped);
bool isWrite = fBuffer.GetUsage() & wgpu::BufferUsage::MapWrite;
auto buffer = sk_ref_sp(this);
fBuffer.MapAsync(
isWrite ? wgpu::MapMode::Write : wgpu::MapMode::Read,
0,
fBuffer.GetSize(),
[](WGPUBufferMapAsyncStatus s, void* userData) {
sk_sp<DawnBuffer> buffer(static_cast<DawnBuffer*>(userData));
buffer->mapCallback(s, nullptr);
},
buffer.release());
}
#endif
void DawnBuffer::onMap() { … }
void DawnBuffer::onUnmap() { … }
template <typename StatusT>
void DawnBuffer::mapCallback(StatusT status, const char* message) { … }
bool DawnBuffer::isUnmappable() const { … }
void DawnBuffer::freeGpuData() { … }
void DawnBuffer::setBackendLabel(char const* label) { … }
}