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  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|
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 
73  switch (type) {
75  return GL_ARRAY_BUFFER;
77  return GL_ELEMENT_ARRAY_BUFFER;
78  }
79  FML_UNREACHABLE();
80 }
81 
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 
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