/*
 * 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/dawn/GrDawnStagingManager.h"

#include "src/core/SkMathPriv.h"

GrDawnStagingManager::GrDawnStagingManager(dawn::Device device) : fDevice(device) {
}

GrDawnStagingManager::~GrDawnStagingManager() {
    // Clean up any pending callbacks before destroying the StagingBuffers.
    while (fWaitingCount > 0) {
        fDevice.Tick();
    }
}

GrDawnStagingBuffer* GrDawnStagingManager::findOrCreateStagingBuffer(size_t size) {
    size_t sizePow2 = GrNextPow2(size);
    GrDawnStagingBuffer* stagingBuffer;
    auto i = fReadyPool.find(sizePow2);
    if (i != fReadyPool.end()) {
        stagingBuffer = i->second;
        fReadyPool.erase(i);
    } else {
        dawn::BufferDescriptor desc;
        desc.usage = dawn::BufferUsage::MapWrite | dawn::BufferUsage::CopySrc;
        desc.size = sizePow2;
        dawn::CreateBufferMappedResult result = fDevice.CreateBufferMapped(&desc);
        std::unique_ptr<GrDawnStagingBuffer> b(new GrDawnStagingBuffer(
            this, result.buffer, sizePow2, result.data));
        stagingBuffer = b.get();
        fBuffers.push_back(std::move(b));
    }
    fBusyList.push_back(stagingBuffer);
    return stagingBuffer;
}

static void callback(DawnBufferMapAsyncStatus status, void* data, uint64_t dataLength,
                     void* userData) {
    GrDawnStagingBuffer* buffer = static_cast<GrDawnStagingBuffer*>(userData);
    buffer->fData = data;
    if (buffer->fManager) {
        buffer->fManager->addToReadyPool(buffer);
    }
}

void GrDawnStagingManager::mapBusyList() {
    // Map all buffers on the busy list for writing. When they're no longer in flight on the GPU,
    // their callback will be called and they'll be moved to the ready pool.
    for (GrDawnStagingBuffer* buffer : fBusyList) {
        buffer->fBuffer.MapWriteAsync(callback, buffer);
        fWaitingCount++;
    }
    fBusyList.clear();
}

void GrDawnStagingManager::addToReadyPool(GrDawnStagingBuffer* buffer) {
    fWaitingCount--;
    fReadyPool.insert(std::pair<size_t, GrDawnStagingBuffer*>(buffer->fSize, buffer));
}
