1/*
2 * Copyright 2019 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrClientMappedBufferManager_DEFINED
9#define GrClientMappedBufferManager_DEFINED
10
11#include "include/private/SkTArray.h"
12#include "src/core/SkMessageBus.h"
13#include "src/gpu/GrGpuBuffer.h"
14#include <forward_list>
15
16/**
17 * We sometimes hand clients objects that contain mapped GrGpuBuffers. The client may consume
18 * the mapped buffer on another thread. This object manages receiving messages that buffers are
19 * ready to be unmapped (on the direct GrContext's thread). It also handles cleaning up mapped
20 * buffers if the GrContext is destroyed before the client has finished with the buffer.
21 *
22 * Buffers are first registered using insert() before being passed the client. process() should be
23 * called periodically on the direct GrContext thread to poll for messages and process them.
24 */
25class GrClientMappedBufferManager final {
26public:
27 /**
28 * The message type that internal users of this should post to unmap the buffer.
29 * Set fInboxID to inboxID(). fBuffer must have been previously passed to insert().
30 */
31 struct BufferFinishedMessage {
32 sk_sp<GrGpuBuffer> fBuffer;
33 uint32_t fInboxID;
34 };
35 using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage>;
36
37 GrClientMappedBufferManager(uint32_t contextID);
38 GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete;
39 GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete;
40
41 ~GrClientMappedBufferManager();
42
43 GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete;
44 GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete;
45
46 /** Initialize BufferFinishedMessage::fInboxID to this value. */
47 uint32_t inboxID() const { return fFinishedBufferInbox.uniqueID(); }
48
49 /**
50 * Let the manager know to expect a message with buffer 'b'. It's illegal for a buffer to be
51 * inserted again before it is unmapped by process().
52 */
53 void insert(sk_sp<GrGpuBuffer> b);
54
55 /** Poll for messages and unmap any incoming buffers. */
56 void process();
57
58 /** Notifies the manager that the context has been abandoned. No more unmaps() will occur.*/
59 void abandon();
60
61private:
62 BufferFinishedMessageBus::Inbox fFinishedBufferInbox;
63 std::forward_list<sk_sp<GrGpuBuffer>> fClientHeldBuffers;
64 bool fAbandoned = false;
65
66 void remove(const sk_sp<GrGpuBuffer>& b);
67};
68
69bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage&,
70 uint32_t msgBusUniqueID);
71
72#endif
73