| /* |
| * Copyright 2019 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrClientMappedBufferManager_DEFINED |
| #define GrClientMappedBufferManager_DEFINED |
| |
| #include "include/private/SkTArray.h" |
| #include "src/core/SkMessageBus.h" |
| #include "src/gpu/GrGpuBuffer.h" |
| #include <forward_list> |
| |
| /** |
| * We sometimes hand clients objects that contain mapped GrGpuBuffers. The client may consume |
| * the mapped buffer on another thread. This object manages receiving messages that buffers are |
| * ready to be unmapped (on the direct GrContext's thread). It also handles cleaning up mapped |
| * buffers if the GrContext is destroyed before the client has finished with the buffer. |
| * |
| * Buffers are first registered using insert() before being passed the client. process() should be |
| * called periodically on the direct GrContext thread to poll for messages and process them. |
| */ |
| class GrClientMappedBufferManager final { |
| public: |
| /** |
| * The message type that internal users of this should post to unmap the buffer. |
| * Set fInboxID to inboxID(). fBuffer must have been previously passed to insert(). |
| */ |
| struct BufferFinishedMessage { |
| sk_sp<GrGpuBuffer> fBuffer; |
| uint32_t fInboxID; |
| }; |
| using BufferFinishedMessageBus = SkMessageBus<BufferFinishedMessage>; |
| |
| GrClientMappedBufferManager(uint32_t contextID); |
| GrClientMappedBufferManager(const GrClientMappedBufferManager&) = delete; |
| GrClientMappedBufferManager(GrClientMappedBufferManager&&) = delete; |
| |
| ~GrClientMappedBufferManager(); |
| |
| GrClientMappedBufferManager& operator=(const GrClientMappedBufferManager&) = delete; |
| GrClientMappedBufferManager& operator=(GrClientMappedBufferManager&&) = delete; |
| |
| /** Initialize BufferFinishedMessage::fInboxID to this value. */ |
| uint32_t inboxID() const { return fFinishedBufferInbox.uniqueID(); } |
| |
| /** |
| * Let the manager know to expect a message with buffer 'b'. It's illegal for a buffer to be |
| * inserted again before it is unmapped by process(). |
| */ |
| void insert(sk_sp<GrGpuBuffer> b); |
| |
| /** Poll for messages and unmap any incoming buffers. */ |
| void process(); |
| |
| /** Notifies the manager that the context has been abandoned. No more unmaps() will occur.*/ |
| void abandon(); |
| |
| private: |
| BufferFinishedMessageBus::Inbox fFinishedBufferInbox; |
| std::forward_list<sk_sp<GrGpuBuffer>> fClientHeldBuffers; |
| bool fAbandoned = false; |
| |
| void remove(const sk_sp<GrGpuBuffer>& b); |
| }; |
| |
| bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage&, |
| uint32_t msgBusUniqueID); |
| |
| #endif |