/*
 * Copyright 2019 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrClientMappedBufferManager_DEFINED
#define GrClientMappedBufferManager_DEFINED

#include "include/gpu/GrDirectContext.h"
#include "include/private/SkTArray.h"
#include "src/core/SkMessageBus.h"
#include "src/gpu/ganesh/GrGpuBuffer.h"
#include <forward_list>

/**
 * We sometimes hand clients objects that contain mapped GrGpuBuffers. The client may consume
 * the mapped buffer on another thread. This object manages receiving messages that buffers are
 * ready to be unmapped (on the GrDirectContext's thread). It also handles cleaning up mapped
 * buffers if the GrDirectContext is destroyed before the client has finished with the buffer.
 *
 * Buffers are first registered using insert() before being passed the client. process() should be
 * called periodically on the GrDirectContext thread to poll for messages and process them.
 */
class GrClientMappedBufferManager final {
public:
    /**
     * The message type that internal users of this should post to unmap the buffer.
     * Set fInboxID to inboxID(). fBuffer must have been previously passed to insert().
     */
    struct BufferFinishedMessage {
        BufferFinishedMessage(sk_sp<GrGpuBuffer> buffer,
                              GrDirectContext::DirectContextID intendedRecipient)
                : fBuffer(std::move(buffer)), fIntendedRecipient(intendedRecipient) {}
        BufferFinishedMessage(BufferFinishedMessage&& other) {
            fBuffer = std::move(other.fBuffer);
            fIntendedRecipient = other.fIntendedRecipient;
            other.fIntendedRecipient.makeInvalid();
        }
        sk_sp<GrGpuBuffer>               fBuffer;
        GrDirectContext::DirectContextID fIntendedRecipient;
    };
    using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage,
                                                  GrDirectContext::DirectContextID,
                                                  false>;

    GrClientMappedBufferManager(GrDirectContext::DirectContextID owningDirectContext);
    GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete;
    GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete;

    ~GrClientMappedBufferManager();

    GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete;
    GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete;

    /** Initialize BufferFinishedMessage::fIntendedRecipient to this value. It is the
     *  unique ID of the GrDirectContext that owns this buffer manager.
     */
    GrDirectContext::DirectContextID owningDirectContext() const {
        return fFinishedBufferInbox.uniqueID();
    }

    /**
     * Let the manager know to expect a message with buffer 'b'. It's illegal for a buffer to be
     * inserted again before it is unmapped by process().
     */
    void insert(sk_sp<GrGpuBuffer> b);

    /** Poll for messages and unmap any incoming buffers. */
    void process();

    /** Notifies the manager that the context has been abandoned. No more unmaps() will occur.*/
    void abandon();

private:
    BufferFinishedMessageBus::Inbox fFinishedBufferInbox;
    std::forward_list<sk_sp<GrGpuBuffer>> fClientHeldBuffers;
    bool fAbandoned = false;

    void remove(const sk_sp<GrGpuBuffer>& b);
};

bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage&,
                              GrDirectContext::DirectContextID potentialRecipient);

#endif
