| /* | |
| * 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; | |
| } |