/*
 * Copyright 2019 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/ganesh/GrClientMappedBufferManager.h"

#include <algorithm>

GrClientMappedBufferManager::GrClientMappedBufferManager(
            GrDirectContext::DirectContextID owningDirectContext)
        : fFinishedBufferInbox(owningDirectContext) {
}

GrClientMappedBufferManager::~GrClientMappedBufferManager() {
    this->process();
    if (!fAbandoned) {
        // If we're going down before we got the messages we go ahead and unmap all the buffers.
        // It's up to the client to ensure that they aren't being accessed on another thread while
        // this is happening (or afterwards on any thread).
        for (auto& b : fClientHeldBuffers) {
            b->unmap();
        }
    }
}

void GrClientMappedBufferManager::insert(sk_sp<GrGpuBuffer> b) {
    SkDEBUGCODE(auto end = fClientHeldBuffers.end());
    SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) == end);
    fClientHeldBuffers.emplace_front(std::move(b));
}

void GrClientMappedBufferManager::process() {
    SkSTArray<4, BufferFinishedMessage> messages;
    fFinishedBufferInbox.poll(&messages);
    if (!fAbandoned) {
        for (auto& m : messages) {
            this->remove(m.fBuffer);
            m.fBuffer->unmap();
        }
    }
}

void GrClientMappedBufferManager::abandon() {
    fAbandoned = true;
    fClientHeldBuffers.clear();
}

void GrClientMappedBufferManager::remove(const sk_sp<GrGpuBuffer>& b) {
    // There is no convenient remove only the first element that equals a value functionality in
    // std::forward_list.
    auto prev = fClientHeldBuffers.before_begin();
    auto end = fClientHeldBuffers.end();
    SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) != end);
    for (auto cur = fClientHeldBuffers.begin(); cur != end; prev = cur++) {
        if (*cur == b) {
            fClientHeldBuffers.erase_after(prev);
            break;
        }
    }
    SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) == end);
}

//////////////////////////////////////////////////////////////////////////////

DECLARE_SKMESSAGEBUS_MESSAGE(GrClientMappedBufferManager::BufferFinishedMessage,
                             GrDirectContext::DirectContextID,
                             false)

bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage& m,
                              GrDirectContext::DirectContextID potentialRecipient) {
    return m.fIntendedRecipient == potentialRecipient;
}
