| Flutter Impeller |

device_buffer_gles.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 "impeller/renderer/backend/gles/device_buffer_gles.h"
6
7 #include <cstring>
8 #include <memory>
9
10 #include "impeller/base/allocation.h"
11 #include "impeller/base/config.h"
12
13 namespace impeller {
14
15 DeviceBufferGLES::DeviceBufferGLES(DeviceBufferDescriptor desc,
16 std::shared_ptr<ReactorGLES> reactor,
17 std::shared_ptr<Allocation> backing_store)
18 : DeviceBuffer(desc),
19 reactor_(std::move(reactor)),
20 backing_store_(std::move(backing_store)) {}
21
22 // |DeviceBuffer|
23 DeviceBufferGLES::~DeviceBufferGLES() {
24 if (handle_.has_value() && !handle_->IsDead()) {
25 reactor_->CollectHandle(*handle_);
26 }
27 }
28
29 // |DeviceBuffer|
30 uint8_t* DeviceBufferGLES::OnGetContents() const {
31 if (!reactor_) {
32 return nullptr;
33 }
34 return backing_store_->GetBuffer();
35 }
36
37 // |DeviceBuffer|
38 bool DeviceBufferGLES::OnCopyHostBuffer(const uint8_t* source,
39 Range source_range,
40 size_t offset) {
41 if (!reactor_) {
42 return false;
43 }
44
45 if (offset + source_range.length >
46 backing_store_->GetLength().GetByteSize()) {
47 return false;
48 }
49
50 std::memmove(backing_store_->GetBuffer() + offset,
51 source + source_range.offset, source_range.length);
52 Flush(Range{offset, source_range.length});
53
54 return true;
55 }
56
57 std::optional<GLuint> DeviceBufferGLES::GetHandle() const {
58 if (handle_.has_value()) {
59 return reactor_->GetGLHandle(*handle_);
60 } else {
61 return std::nullopt;
62 }
63 }
64
65 void DeviceBufferGLES::Flush(std::optional<Range> range) const {
66 if (!range.has_value()) {
67 dirty_range_ = Range{
68 0, static_cast<size_t>(backing_store_->GetLength().GetByteSize())};
69 } else {
70 if (dirty_range_.has_value()) {
71 dirty_range_ = dirty_range_->Merge(range.value());
72 } else {
73 dirty_range_ = range.value();
74 }
75 }
76 }
77
78 static GLenum ToTarget(DeviceBufferGLES::BindingType type) {
79 switch (type) {
80 case DeviceBufferGLES::BindingType::kArrayBuffer:
81 return GL_ARRAY_BUFFER;
82 case DeviceBufferGLES::BindingType::kElementArrayBuffer:
83 return GL_ELEMENT_ARRAY_BUFFER;
84 case DeviceBufferGLES::BindingType::kUniformBuffer:
85 return GL_UNIFORM_BUFFER;
86 }
87 FML_UNREACHABLE();
88 }
89
90 bool DeviceBufferGLES::BindAndUploadDataIfNecessary(BindingType type) const {
91 if (!reactor_) {
92 return false;
93 }
94
95 if (!handle_.has_value()) {
96 handle_ = reactor_->CreateUntrackedHandle(HandleType::kBuffer);
97 #ifdef IMPELLER_DEBUG
98 if (handle_.has_value() && label_.has_value()) {
99 reactor_->SetDebugLabel(*handle_, *label_);
100 }
101 #endif
102 }
103
104 auto buffer = reactor_->GetGLHandle(*handle_);
105 if (!buffer.has_value()) {
106 return false;
107 }
108
109 const auto target_type = ToTarget(type);
110 const auto& gl = reactor_->GetProcTable();
111
112 gl.BindBuffer(target_type, buffer.value());
113 if (!initialized_) {
114 gl.BufferData(target_type, backing_store_->GetLength().GetByteSize(),
115 nullptr, GL_DYNAMIC_DRAW);
116 initialized_ = true;
117 }
118
119 if (dirty_range_.has_value()) {
120 auto range = dirty_range_.value();
121 gl.BufferSubData(target_type, range.offset, range.length,
122 backing_store_->GetBuffer() + range.offset);
123 dirty_range_ = std::nullopt;
124 }
125
126 return true;
127 }
128
129 // |DeviceBuffer|
130 bool DeviceBufferGLES::SetLabel(std::string_view label) {
131 #ifdef IMPELLER_DEBUG
132 label_ = label;
133 if (handle_.has_value()) {
134 reactor_->SetDebugLabel(*handle_, label);
135 }
136 #endif // IMPELLER_DEBUG
137 return true;
138 }
139
140 // |DeviceBuffer|
141 bool DeviceBufferGLES::SetLabel(std::string_view label, Range range) {
142 // Cannot support debug label on the range. Set the label for the entire
143 // range.
144 return SetLabel(label);
145 }
146
147 const uint8_t* DeviceBufferGLES::GetBufferData() const {
148 return backing_store_->GetBuffer();
149 }
150
151 void DeviceBufferGLES::UpdateBufferData(
152 const std::function<void(uint8_t* data, size_t length)>&
153 update_buffer_data) {
154 if (update_buffer_data) {
155 update_buffer_data(backing_store_->GetBuffer(),
156 backing_store_->GetLength().GetByteSize());
157 Flush(Range{
158 0, static_cast<size_t>(backing_store_->GetLength().GetByteSize())});
159 }
160 }
161
162 } // namespace impeller
allocation.h
config.h
type
GLenum type
Definition: blit_command_gles.cc:151
impeller::DeviceBufferGLES::Flush
void Flush(std::optional< Range > range=std::nullopt) const override
Definition: device_buffer_gles.cc:65
impeller::DeviceBufferGLES::UpdateBufferData
void UpdateBufferData(const std::function< void(uint8_t *, size_t length)> &update_buffer_data)
Definition: device_buffer_gles.cc:151
impeller::DeviceBufferGLES::DeviceBufferGLES
DeviceBufferGLES(DeviceBufferDescriptor desc, std::shared_ptr< ReactorGLES > reactor, std::shared_ptr< Allocation > backing_store)
Definition: device_buffer_gles.cc:15
impeller::DeviceBufferGLES::BindAndUploadDataIfNecessary
bool BindAndUploadDataIfNecessary(BindingType type) const
Definition: device_buffer_gles.cc:90
impeller::DeviceBufferGLES::~DeviceBufferGLES
~DeviceBufferGLES() override
Definition: device_buffer_gles.cc:23
impeller::DeviceBufferGLES::GetBufferData
const uint8_t * GetBufferData() const
Definition: device_buffer_gles.cc:147
impeller::DeviceBufferGLES::GetHandle
std::optional< GLuint > GetHandle() const
Definition: device_buffer_gles.cc:57
impeller::DeviceBufferGLES::BindingType
BindingType
Definition: device_buffer_gles.h:34
impeller::DeviceBufferGLES::BindingType::kArrayBuffer
@ kArrayBuffer
impeller::DeviceBufferGLES::BindingType::kElementArrayBuffer
@ kElementArrayBuffer
impeller::DeviceBufferGLES::BindingType::kUniformBuffer
@ kUniformBuffer
impeller::DeviceBuffer
Definition: device_buffer.h:18
device_buffer_gles.h
impeller
Definition: allocation.cc:12
impeller::ToTarget
static GLenum ToTarget(DeviceBufferGLES::BindingType type)
Definition: device_buffer_gles.cc:78
impeller::HandleType::kBuffer
@ kBuffer
std
Definition: comparable.h:95
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:322
impeller::DeviceBufferDescriptor
Definition: device_buffer_descriptor.h:14
impeller::Range
Definition: range.h:13
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:67