| /* |
| * Copyright 2019 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/GrClientMappedBufferManager.h" |
| |
| #include <algorithm> |
| |
| GrClientMappedBufferManager::GrClientMappedBufferManager( |
| GrDirectContext::DirectContextID owningDirectContext) |
| : fFinishedBufferInbox(owningDirectContext) { |
| } |
| |
| GrClientMappedBufferManager::~GrClientMappedBufferManager() { |
| this->process(); |
| if (!fAbandoned) { |
| // If we're going down before we got the messages we go ahead and unmap all the buffers. |
| // It's up to the client to ensure that they aren't being accessed on another thread while |
| // this is happening (or afterwards on any thread). |
| for (auto& b : fClientHeldBuffers) { |
| b->unmap(); |
| } |
| } |
| } |
| |
| void GrClientMappedBufferManager::insert(sk_sp<GrGpuBuffer> b) { |
| SkDEBUGCODE(auto end = fClientHeldBuffers.end()); |
| SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) == end); |
| fClientHeldBuffers.emplace_front(std::move(b)); |
| } |
| |
| void GrClientMappedBufferManager::process() { |
| SkSTArray<4, BufferFinishedMessage> messages; |
| fFinishedBufferInbox.poll(&messages); |
| if (!fAbandoned) { |
| for (auto& m : messages) { |
| this->remove(m.fBuffer); |
| m.fBuffer->unmap(); |
| } |
| } |
| } |
| |
| void GrClientMappedBufferManager::abandon() { |
| fAbandoned = true; |
| fClientHeldBuffers.clear(); |
| } |
| |
| void GrClientMappedBufferManager::remove(const sk_sp<GrGpuBuffer>& b) { |
| // There is no convenient remove only the first element that equals a value functionality in |
| // std::forward_list. |
| auto prev = fClientHeldBuffers.before_begin(); |
| auto end = fClientHeldBuffers.end(); |
| SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) != end); |
| for (auto cur = fClientHeldBuffers.begin(); cur != end; prev = cur++) { |
| if (*cur == b) { |
| fClientHeldBuffers.erase_after(prev); |
| break; |
| } |
| } |
| SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) == end); |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| DECLARE_SKMESSAGEBUS_MESSAGE(GrClientMappedBufferManager::BufferFinishedMessage, |
| GrDirectContext::DirectContextID, |
| false) |
| |
| bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage& m, |
| GrDirectContext::DirectContextID potentialRecipient) { |
| return m.fIntendedRecipient == potentialRecipient; |
| } |