2 * Copyright 2019 Google LLC
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrClientMappedBufferManager_DEFINED
9 #define GrClientMappedBufferManager_DEFINED
11 #include "include/gpu/GrDirectContext.h"
12 #include "include/private/SkTArray.h"
13 #include "src/core/SkMessageBus.h"
14 #include "src/gpu/ganesh/GrGpuBuffer.h"
15 #include <forward_list>
18 * We sometimes hand clients objects that contain mapped GrGpuBuffers. The client may consume
19 * the mapped buffer on another thread. This object manages receiving messages that buffers are
20 * ready to be unmapped (on the GrDirectContext's thread). It also handles cleaning up mapped
21 * buffers if the GrDirectContext is destroyed before the client has finished with the buffer.
23 * Buffers are first registered using insert() before being passed the client. process() should be
24 * called periodically on the GrDirectContext thread to poll for messages and process them.
26 class GrClientMappedBufferManager final {
29 * The message type that internal users of this should post to unmap the buffer.
30 * Set fInboxID to inboxID(). fBuffer must have been previously passed to insert().
32 struct BufferFinishedMessage {
33 BufferFinishedMessage(sk_sp<GrGpuBuffer> buffer,
34 GrDirectContext::DirectContextID intendedRecipient)
35 : fBuffer(std::move(buffer)), fIntendedRecipient(intendedRecipient) {}
36 BufferFinishedMessage(BufferFinishedMessage&& other) {
37 fBuffer = std::move(other.fBuffer);
38 fIntendedRecipient = other.fIntendedRecipient;
39 other.fIntendedRecipient.makeInvalid();
41 sk_sp<GrGpuBuffer> fBuffer;
42 GrDirectContext::DirectContextID fIntendedRecipient;
44 using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage,
45 GrDirectContext::DirectContextID,
48 GrClientMappedBufferManager(GrDirectContext::DirectContextID owningDirectContext);
49 GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete;
50 GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete;
52 ~GrClientMappedBufferManager();
54 GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete;
55 GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete;
57 /** Initialize BufferFinishedMessage::fIntendedRecipient to this value. It is the
58 * unique ID of the GrDirectContext that owns this buffer manager.
60 GrDirectContext::DirectContextID owningDirectContext() const {
61 return fFinishedBufferInbox.uniqueID();
65 * Let the manager know to expect a message with buffer 'b'. It's illegal for a buffer to be
66 * inserted again before it is unmapped by process().
68 void insert(sk_sp<GrGpuBuffer> b);
70 /** Poll for messages and unmap any incoming buffers. */
73 /** Notifies the manager that the context has been abandoned. No more unmaps() will occur.*/
77 BufferFinishedMessageBus::Inbox fFinishedBufferInbox;
78 std::forward_list<sk_sp<GrGpuBuffer>> fClientHeldBuffers;
79 bool fAbandoned = false;
81 void remove(const sk_sp<GrGpuBuffer>& b);
84 bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage&,
85 GrDirectContext::DirectContextID potentialRecipient);