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