blob: 316e47e2c6674821be3e766d99890d716b84e3ae [file] [log] [blame]
Brian Salomon9241a6d2019-10-03 13:26:54 -04001/*
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#include "src/gpu/GrClientMappedBufferManager.h"
9
10#include <algorithm>
11
Robert Phillips82ad7af2021-03-11 16:00:10 -050012GrClientMappedBufferManager::GrClientMappedBufferManager(
13 GrDirectContext::DirectContextID owningDirectContext)
14 : fFinishedBufferInbox(owningDirectContext) {
15}
Brian Salomon9241a6d2019-10-03 13:26:54 -040016
17GrClientMappedBufferManager::~GrClientMappedBufferManager() {
18 this->process();
19 if (!fAbandoned) {
20 // If we're going down before we got the messages we go ahead and unmap all the buffers.
21 // It's up to the client to ensure that they aren't being accessed on another thread while
22 // this is happening (or afterwards on any thread).
23 for (auto& b : fClientHeldBuffers) {
24 b->unmap();
25 }
26 }
27}
28
29void GrClientMappedBufferManager::insert(sk_sp<GrGpuBuffer> b) {
30 SkDEBUGCODE(auto end = fClientHeldBuffers.end());
31 SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) == end);
32 fClientHeldBuffers.emplace_front(std::move(b));
33}
34
35void GrClientMappedBufferManager::process() {
36 SkSTArray<4, BufferFinishedMessage> messages;
37 fFinishedBufferInbox.poll(&messages);
38 if (!fAbandoned) {
39 for (auto& m : messages) {
40 this->remove(m.fBuffer);
41 m.fBuffer->unmap();
42 }
43 }
44}
45
46void GrClientMappedBufferManager::abandon() {
47 fAbandoned = true;
48 fClientHeldBuffers.clear();
49}
50
51void GrClientMappedBufferManager::remove(const sk_sp<GrGpuBuffer>& b) {
52 // There is no convenient remove only the first element that equals a value functionality in
53 // std::forward_list.
54 auto prev = fClientHeldBuffers.before_begin();
55 auto end = fClientHeldBuffers.end();
56 SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) != end);
57 for (auto cur = fClientHeldBuffers.begin(); cur != end; prev = cur++) {
58 if (*cur == b) {
59 fClientHeldBuffers.erase_after(prev);
60 break;
61 }
62 }
63 SkASSERT(std::find(fClientHeldBuffers.begin(), end, b) == end);
64}
65
66//////////////////////////////////////////////////////////////////////////////
67
Robert Phillips82ad7af2021-03-11 16:00:10 -050068DECLARE_SKMESSAGEBUS_MESSAGE(GrClientMappedBufferManager::BufferFinishedMessage,
69 GrDirectContext::DirectContextID,
70 false)
Brian Salomon9241a6d2019-10-03 13:26:54 -040071
72bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage& m,
Robert Phillips82ad7af2021-03-11 16:00:10 -050073 GrDirectContext::DirectContextID potentialRecipient) {
74 return m.fIntendedRecipient == potentialRecipient;
Brian Salomon9241a6d2019-10-03 13:26:54 -040075}