blob: 3f3b0678d936d2242242f633858952d7d89ccf0b [file] [log] [blame]
/*
* 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/private/SkTArray.h"
#include "src/core/SkMessageBus.h"
#include "src/gpu/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 direct GrContext's thread). It also handles cleaning up mapped
* buffers if the GrContext 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 direct GrContext 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 {
sk_sp<GrGpuBuffer> fBuffer;
uint32_t fInboxID;
};
using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage>;
GrClientMappedBufferManager(uint32_t contextID);
GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete;
GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete;
~GrClientMappedBufferManager();
GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete;
GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete;
/** Initialize BufferFinishedMessage::fInboxID to this value. */
uint32_t inboxID() 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&,
uint32_t msgBusUniqueID);
#endif