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 
6 
7 #include <cstring>
8 #include <memory>
9 
11 #include "impeller/base/config.h"
12 
13 namespace impeller {
14 
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|
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 
79  switch (type) {
81  return GL_ARRAY_BUFFER;
83  return GL_ELEMENT_ARRAY_BUFFER;
85  return GL_UNIFORM_BUFFER;
86  }
87  FML_UNREACHABLE();
88 }
89 
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 
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
GLenum type
void Flush(std::optional< Range > range=std::nullopt) const override
void UpdateBufferData(const std::function< void(uint8_t *, size_t length)> &update_buffer_data)
DeviceBufferGLES(DeviceBufferDescriptor desc, std::shared_ptr< ReactorGLES > reactor, std::shared_ptr< Allocation > backing_store)
bool BindAndUploadDataIfNecessary(BindingType type) const
const uint8_t * GetBufferData() const
std::optional< GLuint > GetHandle() const
static GLenum ToTarget(DeviceBufferGLES::BindingType type)
Definition: comparable.h:95
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:68