blob: a77e5982c040354dfc70cda56a389ac9088ea50f [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
Robert Phillips82ad7af2021-03-11 16:00:10 -050011#include "include/gpu/GrDirectContext.h"
Brian Salomon9241a6d2019-10-03 13:26:54 -040012#include "include/private/SkTArray.h"
13#include "src/core/SkMessageBus.h"
14#include "src/gpu/GrGpuBuffer.h"
15#include <forward_list>
16
17/**
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
Robert Phillips82ad7af2021-03-11 16:00:10 -050020 * 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.
Brian Salomon9241a6d2019-10-03 13:26:54 -040022 *
23 * Buffers are first registered using insert() before being passed the client. process() should be
Robert Phillips82ad7af2021-03-11 16:00:10 -050024 * called periodically on the GrDirectContext thread to poll for messages and process them.
Brian Salomon9241a6d2019-10-03 13:26:54 -040025 */
26class GrClientMappedBufferManager final {
27public:
28 /**
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().
31 */
32 struct BufferFinishedMessage {
Robert Phillips82ad7af2021-03-11 16:00:10 -050033 BufferFinishedMessage(sk_sp<GrGpuBuffer> buffer,
34 GrDirectContext::DirectContextID intendedRecipient)
35 : fBuffer(std::move(buffer)), fIntendedRecipient(intendedRecipient) {}
Peng Huang0408afc2021-03-06 21:16:15 -050036 BufferFinishedMessage(BufferFinishedMessage&& other) {
37 fBuffer = std::move(other.fBuffer);
Robert Phillips82ad7af2021-03-11 16:00:10 -050038 fIntendedRecipient = other.fIntendedRecipient;
39 other.fIntendedRecipient.makeInvalid();
Peng Huang0408afc2021-03-06 21:16:15 -050040 }
Robert Phillips82ad7af2021-03-11 16:00:10 -050041 sk_sp<GrGpuBuffer> fBuffer;
42 GrDirectContext::DirectContextID fIntendedRecipient;
Brian Salomon9241a6d2019-10-03 13:26:54 -040043 };
Robert Phillips82ad7af2021-03-11 16:00:10 -050044 using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage,
45 GrDirectContext::DirectContextID,
46 false>;
Brian Salomon9241a6d2019-10-03 13:26:54 -040047
Robert Phillips82ad7af2021-03-11 16:00:10 -050048 GrClientMappedBufferManager(GrDirectContext::DirectContextID owningDirectContext);
Brian Salomon9241a6d2019-10-03 13:26:54 -040049 GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete;
50 GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete;
51
52 ~GrClientMappedBufferManager();
53
54 GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete;
55 GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete;
56
Robert Phillips82ad7af2021-03-11 16:00:10 -050057 /** Initialize BufferFinishedMessage::fIntendedRecipient to this value. It is the
58 * unique ID of the GrDirectContext that owns this buffer manager.
59 */
60 GrDirectContext::DirectContextID owningDirectContext() const {
61 return fFinishedBufferInbox.uniqueID();
62 }
Brian Salomon9241a6d2019-10-03 13:26:54 -040063
64 /**
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().
67 */
68 void insert(sk_sp<GrGpuBuffer> b);
69
70 /** Poll for messages and unmap any incoming buffers. */
71 void process();
72
73 /** Notifies the manager that the context has been abandoned. No more unmaps() will occur.*/
74 void abandon();
75
76private:
77 BufferFinishedMessageBus::Inbox fFinishedBufferInbox;
78 std::forward_list<sk_sp<GrGpuBuffer>> fClientHeldBuffers;
79 bool fAbandoned = false;
80
81 void remove(const sk_sp<GrGpuBuffer>& b);
82};
83
84bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage&,
Robert Phillips82ad7af2021-03-11 16:00:10 -050085 GrDirectContext::DirectContextID potentialRecipient);
Brian Salomon9241a6d2019-10-03 13:26:54 -040086
87#endif