Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
impeller::BufferBindingsGLES Class Reference

Sets up stage bindings for single draw call in the OpenGLES backend. More...

#include <buffer_bindings_gles.h>

Public Member Functions

 BufferBindingsGLES ()
 
 ~BufferBindingsGLES ()
 
bool RegisterVertexStageInput (const ProcTableGLES &gl, const std::vector< ShaderStageIOSlot > &inputs, const std::vector< ShaderStageBufferLayout > &layouts)
 
bool ReadUniformsBindings (const ProcTableGLES &gl, GLuint program)
 
bool BindVertexAttributes (const ProcTableGLES &gl, size_t binding, size_t vertex_offset, size_t instance=0)
 
bool BindUniformData (const ProcTableGLES &gl, const std::vector< TextureAndSampler > &bound_textures, const std::vector< BufferResource > &bound_buffers, Range texture_range, Range buffer_range)
 
bool UnbindVertexAttributes (const ProcTableGLES &gl)
 

Detailed Description

Sets up stage bindings for single draw call in the OpenGLES backend.

Definition at line 30 of file buffer_bindings_gles.h.

Constructor & Destructor Documentation

◆ BufferBindingsGLES()

impeller::BufferBindingsGLES::BufferBindingsGLES ( )
default

◆ ~BufferBindingsGLES()

impeller::BufferBindingsGLES::~BufferBindingsGLES ( )
default

References type.

Member Function Documentation

◆ BindUniformData()

bool impeller::BufferBindingsGLES::BindUniformData ( const ProcTableGLES gl,
const std::vector< TextureAndSampler > &  bound_textures,
const std::vector< BufferResource > &  bound_buffers,
Range  texture_range,
Range  buffer_range 
)

Definition at line 261 of file buffer_bindings_gles.cc.

266 {
267 for (auto i = 0u; i < buffer_range.length; i++) {
268 if (!BindUniformBuffer(gl, bound_buffers[buffer_range.offset + i])) {
269 return false;
270 }
271 }
272 std::optional<size_t> next_unit_index =
273 BindTextures(gl, bound_textures, texture_range, ShaderStage::kVertex);
274 if (!next_unit_index.has_value()) {
275 return false;
276 }
277 if (!BindTextures(gl, bound_textures, texture_range, ShaderStage::kFragment,
278 *next_unit_index)
279 .has_value()) {
280 return false;
281 }
282
283 return true;
284}

References i, impeller::kFragment, impeller::kVertex, impeller::Range::length, and impeller::Range::offset.

Referenced by impeller::EncodeCommandsInReactor(), impeller::testing::TEST(), impeller::testing::TEST(), impeller::testing::TEST(), and impeller::testing::TEST().

◆ BindVertexAttributes()

bool impeller::BufferBindingsGLES::BindVertexAttributes ( const ProcTableGLES gl,
size_t  binding,
size_t  vertex_offset,
size_t  instance = 0 
)

Bind the vertex attributes for buffer slot [binding].

[instance] re-points instance-rate attributes at the given instance, used to emulate an instanced draw on drivers without hardware instancing support. It is 0 for a non-instanced or hardware-instanced draw.

Definition at line 197 of file buffer_bindings_gles.cc.

200 {
201 if (binding >= vertex_attrib_arrays_.size()) {
202 return false;
203 }
204
205 // For an emulated instanced draw (instance > 0), a binding whose attributes
206 // are all vertex-rate (divisor 0) does not change across instances, so the
207 // state bound for instance 0 still applies. Skip the redundant re-binding.
208 if (instance > 0u) {
209 bool has_instance_rate = false;
210 for (const auto& array : vertex_attrib_arrays_[binding]) {
211 if (array.vertex_attrib_divisor != 0u) {
212 has_instance_rate = true;
213 break;
214 }
215 }
216 if (!has_instance_rate) {
217 return true;
218 }
219 }
220
221 if (!gl.GetCapabilities()->IsES()) {
222 FML_DCHECK(vertex_array_object_ == 0);
223 gl.GenVertexArrays(1, &vertex_array_object_);
224 gl.BindVertexArray(vertex_array_object_);
225 }
226
227 for (const auto& array : vertex_attrib_arrays_[binding]) {
228 gl.EnableVertexAttribArray(array.index);
229 // For an emulated instanced draw, an instance-rate attribute is
230 // re-pointed at instance `instance`, since there is no hardware divisor
231 // to advance it. A non-instanced or hardware-instanced draw passes
232 // instance 0 and lets the divisor (if any) do the stepping.
233 size_t attribute_offset = vertex_offset + array.offset;
234 if (array.vertex_attrib_divisor != 0u) {
235 attribute_offset += instance * static_cast<size_t>(array.stride);
236 }
237 gl.VertexAttribPointer(array.index, // index
238 array.size, // size (must be 1, 2, 3, or 4)
239 array.type, // type
240 array.normalized, // normalized
241 array.stride, // stride
242 reinterpret_cast<const GLvoid*>(
243 static_cast<uintptr_t>(attribute_offset)) // ptr
244 );
245 // Set the instancing divisor when the driver supports it. It is core
246 // on ES 3.0+ and comes from GL_EXT_instanced_arrays on ES 2.0. When
247 // unavailable, only per-vertex (divisor 0) bindings are possible,
248 // which is the default. Setting it for every attribute (including
249 // divisor 0) also clears any stale divisor left by a prior pipeline,
250 // which matters on ES, where there is no vertex array object.
251 if (gl.VertexAttribDivisor.IsAvailable()) {
252 gl.VertexAttribDivisor(array.index, array.vertex_attrib_divisor);
253 } else if (gl.VertexAttribDivisorEXT.IsAvailable()) {
254 gl.VertexAttribDivisorEXT(array.index, array.vertex_attrib_divisor);
255 }
256 }
257
258 return true;
259}
VkInstance instance
Definition main.cc:64
#define FML_DCHECK(condition)
Definition logging.h:122

References FML_DCHECK, impeller::ProcTableGLES::GetCapabilities(), and instance.

Referenced by impeller::BindVertexBuffer(), and impeller::testing::TEST().

◆ ReadUniformsBindings()

bool impeller::BufferBindingsGLES::ReadUniformsBindings ( const ProcTableGLES gl,
GLuint  program 
)

Definition at line 104 of file buffer_bindings_gles.cc.

105 {
106 if (!gl.IsProgram(program)) {
107 return false;
108 }
109 program_handle_ = program;
110 if (gl.GetDescription()->GetGlVersion().IsAtLeast(Version{3, 0, 0})) {
111 return ReadUniformsBindingsV3(gl, program);
112 }
113 return ReadUniformsBindingsV2(gl, program);
114}

References impeller::ProcTableGLES::GetDescription(), impeller::DescriptionGLES::GetGlVersion(), and impeller::Version::IsAtLeast().

◆ RegisterVertexStageInput()

bool impeller::BufferBindingsGLES::RegisterVertexStageInput ( const ProcTableGLES gl,
const std::vector< ShaderStageIOSlot > &  inputs,
const std::vector< ShaderStageBufferLayout > &  layouts 
)

Definition at line 32 of file buffer_bindings_gles.cc.

35 {
36 std::vector<std::vector<VertexAttribPointer>> vertex_attrib_arrays(
37 layouts.size());
38 // Every layout corresponds to a vertex binding.
39 // As we record, separate the attributes into buckets for each layout in
40 // ascending order. We do this because later on, we'll need to associate each
41 // of the attributes with bound buffers corresponding to the binding.
42 for (auto layout_i = 0u; layout_i < layouts.size(); layout_i++) {
43 const auto& layout = layouts[layout_i];
44 for (const auto& input : p_inputs) {
45 if (input.binding != layout_i) {
46 continue;
47 }
48 VertexAttribPointer attrib;
49 attrib.index = input.location;
50 // Component counts must be 1, 2, 3 or 4. Do that validation now.
51 if (input.vec_size < 1u || input.vec_size > 4u) {
52 return false;
53 }
54 attrib.size = input.vec_size;
55 auto type = ToVertexAttribType(input.type);
56 if (!type.has_value()) {
57 return false;
58 }
59 attrib.type = type.value();
60 attrib.normalized = GL_FALSE;
61 attrib.offset = input.offset;
62 attrib.stride = layout.stride;
63 attrib.vertex_attrib_divisor =
64 layout.input_rate == VertexInputRate::kInstance ? 1u : 0u;
65 vertex_attrib_arrays[layout_i].push_back(attrib);
66 }
67 }
68 vertex_attrib_arrays_ = std::move(vertex_attrib_arrays);
69 return true;
70}
static int input(yyscan_t yyscanner)
@ kInstance
The binding is read once per instance.
constexpr std::optional< GLenum > ToVertexAttribType(ShaderType type)
impeller::ShaderType type

References input(), impeller::kInstance, impeller::ToVertexAttribType(), and type.

Referenced by impeller::testing::TEST().

◆ UnbindVertexAttributes()

bool impeller::BufferBindingsGLES::UnbindVertexAttributes ( const ProcTableGLES gl)

Definition at line 286 of file buffer_bindings_gles.cc.

286 {
287 for (const auto& array : vertex_attrib_arrays_) {
288 for (const auto& attribute : array) {
289 gl.DisableVertexAttribArray(attribute.index);
290 }
291 }
292 if (!gl.GetCapabilities()->IsES()) {
293 gl.DeleteVertexArrays(1, &vertex_array_object_);
294 vertex_array_object_ = 0;
295 }
296
297 return true;
298}

References impeller::ProcTableGLES::GetCapabilities().

Referenced by impeller::EncodeCommandsInReactor().


The documentation for this class was generated from the following files: