• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gpu/GrDirectContext.h"
12 #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
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.
22  *
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.
25  */
26 class GrClientMappedBufferManager final {
27 public:
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 {
BufferFinishedMessageBufferFinishedMessage33         BufferFinishedMessage(sk_sp<GrGpuBuffer> buffer,
34                               GrDirectContext::DirectContextID intendedRecipient)
35                 : fBuffer(std::move(buffer)), fIntendedRecipient(intendedRecipient) {}
BufferFinishedMessageBufferFinishedMessage36         BufferFinishedMessage(BufferFinishedMessage&& other) {
37             fBuffer = std::move(other.fBuffer);
38             fIntendedRecipient = other.fIntendedRecipient;
39             other.fIntendedRecipient.makeInvalid();
40         }
41         sk_sp<GrGpuBuffer>               fBuffer;
42         GrDirectContext::DirectContextID fIntendedRecipient;
43     };
44     using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage,
45                                                   GrDirectContext::DirectContextID,
46                                                   false>;
47 
48     GrClientMappedBufferManager(GrDirectContext::DirectContextID owningDirectContext);
49     GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete;
50     GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete;
51 
52     ~GrClientMappedBufferManager();
53 
54     GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete;
55     GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete;
56 
57     /** Initialize BufferFinishedMessage::fIntendedRecipient to this value. It is the
58      *  unique ID of the GrDirectContext that owns this buffer manager.
59      */
owningDirectContext()60     GrDirectContext::DirectContextID owningDirectContext() const {
61         return fFinishedBufferInbox.uniqueID();
62     }
63 
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 
76 private:
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 
84 bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage&,
85                               GrDirectContext::DirectContextID potentialRecipient);
86 
87 #endif
88