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