1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gpu/command_buffer/client/readback_buffer_shadow_tracker.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "build/build_config.h"
9 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
10 #include "gpu/command_buffer/client/mapped_memory.h"
11
12 namespace gpu {
13 namespace gles2 {
14
15 // ReadbackBufferShadowTracker::Buffer
16
Buffer(GLuint buffer_id,ReadbackBufferShadowTracker * tracker)17 ReadbackBufferShadowTracker::Buffer::Buffer(
18 GLuint buffer_id,
19 ReadbackBufferShadowTracker* tracker)
20 : buffer_id_(buffer_id), tracker_(tracker) {}
21
~Buffer()22 ReadbackBufferShadowTracker::Buffer::~Buffer() {
23 Free();
24 }
25
Alloc(int32_t * shm_id,uint32_t * shm_offset,bool * already_allocated)26 uint32_t ReadbackBufferShadowTracker::Buffer::Alloc(int32_t* shm_id,
27 uint32_t* shm_offset,
28 bool* already_allocated) {
29 *already_allocated = readback_shm_address_ != nullptr;
30 if (!readback_shm_address_) {
31 readback_shm_address_ =
32 tracker_->mapped_memory_->Alloc(size_, &shm_id_, &shm_offset_);
33 }
34 *shm_id = shm_id_;
35 *shm_offset = shm_offset_;
36 return size_;
37 }
38
Free()39 void ReadbackBufferShadowTracker::Buffer::Free() {
40 if (readback_shm_address_) {
41 tracker_->mapped_memory_->FreePendingToken(
42 readback_shm_address_, tracker_->helper_->InsertToken());
43 }
44 readback_shm_address_ = nullptr;
45 }
46
MapReadbackShm(uint32_t offset,uint32_t map_size)47 void* ReadbackBufferShadowTracker::Buffer::MapReadbackShm(uint32_t offset,
48 uint32_t map_size) {
49 DCHECK(!is_mapped_);
50 if (serial_of_readback_data_ != serial_of_last_write_) {
51 return nullptr;
52 }
53 if (!readback_shm_address_) {
54 return nullptr;
55 }
56 if (map_size > size_) {
57 return nullptr;
58 }
59 DCHECK_GE(size_, map_size);
60 if (offset > size_ - map_size) {
61 return nullptr;
62 }
63 is_mapped_ = true;
64 return &static_cast<uint8_t*>(readback_shm_address_)[offset];
65 }
66
UnmapReadbackShm()67 bool ReadbackBufferShadowTracker::Buffer::UnmapReadbackShm() {
68 Free();
69
70 bool was_mapped = is_mapped_;
71 is_mapped_ = false;
72 return was_mapped;
73 }
74
UpdateSerialTo(uint64_t serial)75 void ReadbackBufferShadowTracker::Buffer::UpdateSerialTo(uint64_t serial) {
76 DCHECK_LT(serial_of_readback_data_, serial);
77 serial_of_readback_data_ = serial;
78 }
79
80 // ReadbackBufferShadowTracker
81
ReadbackBufferShadowTracker(MappedMemoryManager * mapped_memory,GLES2CmdHelper * helper)82 ReadbackBufferShadowTracker::ReadbackBufferShadowTracker(
83 MappedMemoryManager* mapped_memory,
84 GLES2CmdHelper* helper)
85 : mapped_memory_(mapped_memory), helper_(helper) {}
86
~ReadbackBufferShadowTracker()87 ReadbackBufferShadowTracker::~ReadbackBufferShadowTracker() {}
88
89 ReadbackBufferShadowTracker::Buffer*
GetOrCreateBuffer(GLuint id,GLuint size)90 ReadbackBufferShadowTracker::GetOrCreateBuffer(GLuint id, GLuint size) {
91 Buffer* buffer = GetBuffer(id);
92 if (buffer) {
93 buffer->Free();
94 } else {
95 buffer = new Buffer(id, this);
96 buffers_.emplace(id, base::WrapUnique(buffer));
97 }
98 buffer->size_ = size;
99 OnBufferWrite(id);
100
101 return buffer;
102 }
103
OnBufferWrite(GLuint id)104 void ReadbackBufferShadowTracker::OnBufferWrite(GLuint id) {
105 Buffer* buffer = GetBuffer(id);
106 if (!buffer) {
107 // Buffer is not tracked by the ReadbackBufferShadowTracker.
108 return;
109 }
110
111 DCHECK(buffer->serial_of_last_write_ <= buffer_shadow_serial_);
112 buffer->serial_of_last_write_ = buffer_shadow_serial_;
113
114 for (const auto& b : buffers_written_but_not_fenced_) {
115 if (b.get() == buffer) {
116 return;
117 }
118 }
119 buffers_written_but_not_fenced_.push_back(buffer->AsWeakPtr());
120 }
121
122 ReadbackBufferShadowTracker::BufferList
TakeUnfencedBufferList()123 ReadbackBufferShadowTracker::TakeUnfencedBufferList() {
124 BufferList buffers;
125 std::swap(buffers, buffers_written_but_not_fenced_);
126 return buffers;
127 }
128
129 } // namespace gles2
130 } // namespace gpu
131