1 /*
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
GrClientMappedBufferManager(GrDirectContext::DirectContextID owningDirectContext)12 GrClientMappedBufferManager::GrClientMappedBufferManager(
13 GrDirectContext::DirectContextID owningDirectContext)
14 : fFinishedBufferInbox(owningDirectContext) {
15 }
16
~GrClientMappedBufferManager()17 GrClientMappedBufferManager::~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
insert(sk_sp<GrGpuBuffer> b)29 void 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
process()35 void 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
abandon()46 void GrClientMappedBufferManager::abandon() {
47 fAbandoned = true;
48 fClientHeldBuffers.clear();
49 }
50
remove(const sk_sp<GrGpuBuffer> & b)51 void 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
DECLARE_SKMESSAGEBUS_MESSAGE(GrClientMappedBufferManager::BufferFinishedMessage,GrDirectContext::DirectContextID,false)68 DECLARE_SKMESSAGEBUS_MESSAGE(GrClientMappedBufferManager::BufferFinishedMessage,
69 GrDirectContext::DirectContextID,
70 false)
71
72 bool SkShouldPostMessageToBus(const GrClientMappedBufferManager::BufferFinishedMessage& m,
73 GrDirectContext::DirectContextID potentialRecipient) {
74 return m.fIntendedRecipient == potentialRecipient;
75 }
76