blob: 20ef457f44482de944e770963cf8dc8a2a1fed21 [file] [log] [blame]
Brian Salomon9241a6d2019-10-03 13:26:54 -04001/*
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 {
Peng Huang0408afc2021-03-06 21:16:15 -050032 BufferFinishedMessage(sk_sp<GrGpuBuffer> buffer, uint32_t indexId)
33 : fBuffer(std::move(buffer)), fInboxID(indexId) {}
34 BufferFinishedMessage(BufferFinishedMessage&& other) {
35 fBuffer = std::move(other.fBuffer);
36 fInboxID = other.fInboxID;
37 other.fInboxID = 0;
38 }
Brian Salomon9241a6d2019-10-03 13:26:54 -040039 sk_sp<GrGpuBuffer> fBuffer;
40 uint32_t fInboxID;
41 };
Peng Huang0408afc2021-03-06 21:16:15 -050042 using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage, false>;
Brian Salomon9241a6d2019-10-03 13:26:54 -040043
44 GrClientMappedBufferManager(uint32_t contextID);
45 GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete;
46 GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete;
47
48 ~GrClientMappedBufferManager();
49
50 GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete;
51 GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete;
52
53 /** Initialize BufferFinishedMessage::fInboxID to this value. */
54 uint32_t inboxID() const { return fFinishedBufferInbox.uniqueID(); }
55
56 /**
57 * Let the manager know to expect a message with buffer 'b'. It's illegal for a buffer to be
58 * inserted again before it is unmapped by process().
59 */
60 void insert(sk_sp<GrGpuBuffer> b);
61
62 /** Poll for messages and unmap any incoming buffers. */
63 void process();
64
65 /** Notifies the manager that the context has been abandoned. No more unmaps() will occur.*/
66 void abandon();
67
68private:
69 BufferFinishedMessageBus::Inbox fFinishedBufferInbox;
70 std::forward_list<sk_sp<GrGpuBuffer>> fClientHeldBuffers;
71 bool fAbandoned = false;
72
73 void remove(const sk_sp<GrGpuBuffer>& b);
74};
75
76bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage&,
77 uint32_t msgBusUniqueID);
78
79#endif