| 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 ReactorGLES::Ref reactor,
17 std::shared_ptr<Allocation> backing_store)
18 : DeviceBuffer(desc),
19 reactor_(std::move(reactor)),
20 handle_(reactor_ ? reactor_->CreateHandle(HandleType::kBuffer)
21 : HandleGLES::DeadHandle()),
22 backing_store_(std::move(backing_store)) {}
23
24 // |DeviceBuffer|
25 DeviceBufferGLES::~DeviceBufferGLES() {
26 if (!handle_.IsDead()) {
27 reactor_->CollectHandle(handle_);
28 }
29 }
30
31 // |DeviceBuffer|
32 uint8_t* DeviceBufferGLES::OnGetContents() const {
33 if (!reactor_) {
34 return nullptr;
35 }
36 return backing_store_->GetBuffer();
37 }
38
39 // |DeviceBuffer|
40 bool DeviceBufferGLES::OnCopyHostBuffer(const uint8_t* source,
41 Range source_range,
42 size_t offset) {
43 if (!reactor_) {
44 return false;
45 }
46
47 if (offset + source_range.length >
48 backing_store_->GetLength().GetByteSize()) {
49 return false;
50 }
51
52 std::memmove(backing_store_->GetBuffer() + offset,
53 source + source_range.offset, source_range.length);
54 Flush(Range{offset, source_range.length});
55
56 return true;
57 }
58
59 void DeviceBufferGLES::Flush(std::optional<Range> range) const {
60 if (!range.has_value()) {
61 dirty_range_ = Range{
62 0, static_cast<size_t>(backing_store_->GetLength().GetByteSize())};
63 } else {
64 if (dirty_range_.has_value()) {
65 dirty_range_ = dirty_range_->Merge(range.value());
66 } else {
67 dirty_range_ = range.value();
68 }
69 }
70 }
71
72 static GLenum ToTarget(DeviceBufferGLES::BindingType type) {
73 switch (type) {
74 case DeviceBufferGLES::BindingType::kArrayBuffer:
75 return GL_ARRAY_BUFFER;
76 case DeviceBufferGLES::BindingType::kElementArrayBuffer:
77 return GL_ELEMENT_ARRAY_BUFFER;
78 }
79 FML_UNREACHABLE();
80 }
81
82 bool DeviceBufferGLES::BindAndUploadDataIfNecessary(BindingType type) const {
83 if (!reactor_) {
84 return false;
85 }
86
87 auto buffer = reactor_->GetGLHandle(handle_);
88 if (!buffer.has_value()) {
89 return false;
90 }
91
92 const auto target_type = ToTarget(type);
93 const auto& gl = reactor_->GetProcTable();
94
95 gl.BindBuffer(target_type, buffer.value());
96 if (!initialized_) {
97 gl.BufferData(target_type, backing_store_->GetLength().GetByteSize(),
98 nullptr, GL_DYNAMIC_DRAW);
99 initialized_ = true;
100 }
101
102 if (dirty_range_.has_value()) {
103 auto range = dirty_range_.value();
104 gl.BufferSubData(target_type, range.offset, range.length,
105 backing_store_->GetBuffer() + range.offset);
106 dirty_range_ = std::nullopt;
107 }
108
109 return true;
110 }
111
112 // |DeviceBuffer|
113 bool DeviceBufferGLES::SetLabel(const std::string& label) {
114 reactor_->SetDebugLabel(handle_, label);
115 return true;
116 }
117
118 // |DeviceBuffer|
119 bool DeviceBufferGLES::SetLabel(const std::string& label, Range range) {
120 // Cannot support debug label on the range. Set the label for the entire
121 // range.
122 return SetLabel(label);
123 }
124
125 const uint8_t* DeviceBufferGLES::GetBufferData() const {
126 return backing_store_->GetBuffer();
127 }
128
129 void DeviceBufferGLES::UpdateBufferData(
130 const std::function<void(uint8_t* data, size_t length)>&
131 update_buffer_data) {
132 if (update_buffer_data) {
133 update_buffer_data(backing_store_->GetBuffer(),
134 backing_store_->GetLength().GetByteSize());
135 Flush(Range{
136 0, static_cast<size_t>(backing_store_->GetLength().GetByteSize())});
137 }
138 }
139
140 } // namespace impeller
impeller::DeviceBufferGLES::BindingType::kArrayBuffer
@ kArrayBuffer
impeller::DeviceBuffer
Definition: device_buffer.h:18
allocation.h
impeller::DeviceBufferDescriptor
Definition: device_buffer_descriptor.h:14
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
impeller::ReactorGLES::Ref
std::shared_ptr< ReactorGLES > Ref
Definition: reactor_gles.h:86
impeller::HandleType
HandleType
Definition: handle_gles.h:18
impeller::HandleGLES::IsDead
constexpr bool IsDead() const
Determines if the handle is dead.
Definition: handle_gles.h:54
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:304
impeller::DeviceBufferGLES::GetBufferData
const uint8_t * GetBufferData() const
Definition: device_buffer_gles.cc:125
device_buffer_gles.h
impeller::DeviceBufferGLES::BindingType::kElementArrayBuffer
@ kElementArrayBuffer
impeller::DeviceBufferGLES::BindAndUploadDataIfNecessary
bool BindAndUploadDataIfNecessary(BindingType type) const
Definition: device_buffer_gles.cc:82
type
GLenum type
Definition: blit_command_gles.cc:127
impeller::HandleGLES
Represents a handle to an underlying OpenGL object. Unlike OpenGL object handles, these handles can b...
Definition: handle_gles.h:36
impeller::DeviceBufferGLES::~DeviceBufferGLES
~DeviceBufferGLES() override
Definition: device_buffer_gles.cc:25
impeller::DeviceBufferGLES::UpdateBufferData
void UpdateBufferData(const std::function< void(uint8_t *, size_t length)> &update_buffer_data)
Definition: device_buffer_gles.cc:129
impeller::DeviceBufferGLES::DeviceBufferGLES
DeviceBufferGLES(DeviceBufferDescriptor desc, ReactorGLES::Ref reactor, std::shared_ptr< Allocation > backing_store)
Definition: device_buffer_gles.cc:15
impeller::DeviceBufferGLES::BindingType
BindingType
Definition: device_buffer_gles.h:34
impeller::ToTarget
static GLenum ToTarget(DeviceBufferGLES::BindingType type)
Definition: device_buffer_gles.cc:72
impeller::Range
Definition: range.h:13
std
Definition: comparable.h:95
impeller::HandleType::kBuffer
@ kBuffer
config.h
impeller
Definition: allocation.cc:12
impeller::DeviceBufferGLES::Flush
void Flush(std::optional< Range > range=std::nullopt) const override
Definition: device_buffer_gles.cc:59