25 "ANGLEInputAttachment";
33 const std::vector<ShaderStageIOSlot>& p_inputs,
34 const std::vector<ShaderStageBufferLayout>& layouts) {
35 std::vector<std::vector<VertexAttribPointer>> vertex_attrib_arrays(
41 for (
auto layout_i = 0u; layout_i < layouts.size(); layout_i++) {
42 const auto& layout = layouts[layout_i];
43 for (
const auto&
input : p_inputs) {
44 if (
input.binding != layout_i) {
47 VertexAttribPointer attrib;
48 attrib.index =
input.location;
50 if (
input.vec_size < 1u ||
input.vec_size > 4u) {
53 attrib.size =
input.vec_size;
55 if (!
type.has_value()) {
58 attrib.type =
type.value();
59 attrib.normalized = GL_FALSE;
60 attrib.offset =
input.offset;
61 attrib.stride = layout.stride;
62 vertex_attrib_arrays[layout_i].push_back(attrib);
65 vertex_attrib_arrays_ = std::move(vertex_attrib_arrays);
71 result.reserve(
key.length());
74 result.push_back(toupper(ch));
81 const std::string& member,
84 result.reserve(struct_name.length() + member.length() + (is_array ? 4 : 1));
85 result += struct_name;
86 if (!member.empty()) {
97 const std::string& non_struct_member) {
103 if (!gl.IsProgram(program)) {
106 program_handle_ = program;
108 return ReadUniformsBindingsV3(gl, program);
110 return ReadUniformsBindingsV2(gl, program);
113bool BufferBindingsGLES::ReadUniformsBindingsV3(
const ProcTableGLES& gl,
115 program_handle_ = program;
116 GLint uniform_blocks = 0;
117 gl.GetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &uniform_blocks);
118 for (GLint
i = 0;
i < uniform_blocks;
i++) {
119 GLint name_length = 0;
120 gl.GetActiveUniformBlockiv(program,
i, GL_UNIFORM_BLOCK_NAME_LENGTH,
123 std::vector<GLchar>
name;
124 name.resize(name_length);
126 gl.GetActiveUniformBlockName(program,
i, name_length, &
length,
name.data());
128 GLuint block_index = gl.GetUniformBlockIndex(program,
name.data());
129 gl.UniformBlockBinding(program_handle_, block_index,
i);
131 ubo_locations_[std::string{
name.data(),
static_cast<size_t>(
length)}] =
132 std::make_pair(block_index,
i);
135 return ReadUniformsBindingsV2(gl, program);
138bool BufferBindingsGLES::ReadUniformsBindingsV2(
const ProcTableGLES& gl,
140 GLint max_name_size = 0;
141 gl.GetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_size);
143 GLint uniform_count = 0;
144 gl.GetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniform_count);
148 for (GLint
i = 0;
i < uniform_count;
i++) {
149 std::vector<GLchar>
name;
150 name.resize(max_name_size);
151 GLsizei written_count = 0u;
152 GLint uniform_var_size = 0u;
153 GLenum uniform_type = GL_FLOAT;
157 gl.GetActiveUniform(program,
167 if (gl.GetCapabilities()->IsANGLE()) {
176 auto location = gl.GetUniformLocation(program,
name.data());
181 VALIDATION_LOG <<
"Could not query the location of an active uniform.";
184 if (written_count <= 0) {
185 VALIDATION_LOG <<
"Uniform name could not be read for active uniform.";
189 name.data(),
static_cast<size_t>(written_count)})] =
location;
196 size_t vertex_offset) {
197 if (binding >= vertex_attrib_arrays_.size()) {
203 gl.GenVertexArrays(1, &vertex_array_object_);
204 gl.BindVertexArray(vertex_array_object_);
207 for (
const auto& array : vertex_attrib_arrays_[binding]) {
208 gl.EnableVertexAttribArray(array.index);
209 gl.VertexAttribPointer(array.index,
214 reinterpret_cast<const GLvoid*
>(
static_cast<GLsizei
>(
215 vertex_offset + array.offset))
224 const std::vector<TextureAndSampler>& bound_textures,
225 const std::vector<BufferResource>& bound_buffers,
227 Range buffer_range) {
228 for (
auto i = 0u;
i < buffer_range.
length;
i++) {
229 if (!BindUniformBuffer(gl, bound_buffers[buffer_range.
offset +
i])) {
233 std::optional<size_t> next_unit_index =
235 if (!next_unit_index.has_value()) {
248 for (
const auto& array : vertex_attrib_arrays_) {
249 for (
const auto& attribute : array) {
250 gl.DisableVertexAttribArray(attribute.index);
254 gl.DeleteVertexArrays(1, &vertex_array_object_);
255 vertex_array_object_ = 0;
261GLint BufferBindingsGLES::ComputeTextureLocation(
264 if (
location != binding_map_.end()) {
267 auto& locations = binding_map_[metadata->
name] = {};
268 auto computed_location =
270 if (computed_location == uniform_locations_.end()) {
271 locations.push_back(-1);
273 locations.push_back(computed_location->second);
278const std::vector<GLint>& BufferBindingsGLES::ComputeUniformLocations(
279 const ShaderMetadata* metadata) {
280 BindingMap::iterator
location = binding_map_.find(metadata->name);
281 if (
location != binding_map_.end()) {
287 std::vector<GLint>& locations = binding_map_[metadata->name] = {};
288 locations.reserve(metadata->members.size());
289 for (
const ShaderStructMemberMetadata& member : metadata->members) {
293 locations.push_back(-1);
298 metadata->name, member.name, member.array_elements.has_value());
299 const absl::flat_hash_map<std::string, GLint>::iterator computed_location =
300 uniform_locations_.find(member_key);
301 if (computed_location == uniform_locations_.end()) {
303 locations.push_back(-1);
306 locations.push_back(computed_location->second);
311bool BufferBindingsGLES::BindUniformBuffer(
const ProcTableGLES& gl,
313 const ShaderMetadata* metadata =
buffer.GetMetadata();
314 const DeviceBuffer* device_buffer =
buffer.resource.GetBuffer();
315 if (!device_buffer) {
319 const DeviceBufferGLES& device_buffer_gles =
323 return BindUniformBufferV3(gl,
buffer.resource, metadata,
326 return BindUniformBufferV2(gl,
buffer.resource, metadata, device_buffer_gles);
329bool BufferBindingsGLES::BindUniformBufferV3(
330 const ProcTableGLES& gl,
331 const BufferView& buffer,
332 const ShaderMetadata* metadata,
333 const DeviceBufferGLES& device_buffer_gles) {
334 absl::flat_hash_map<std::string, std::pair<GLint, GLuint>>::iterator it =
335 ubo_locations_.find(metadata->name);
336 if (it == ubo_locations_.end()) {
337 return BindUniformBufferV2(gl, buffer, metadata, device_buffer_gles);
339 const auto& [block_index, binding_point] = it->second;
340 if (!device_buffer_gles.BindAndUploadDataIfNecessary(
344 auto handle = device_buffer_gles.GetHandle();
345 if (!handle.has_value()) {
348 gl.BindBufferRange(GL_UNIFORM_BUFFER, binding_point, handle.value(),
353bool BufferBindingsGLES::BindUniformBufferV2(
354 const ProcTableGLES& gl,
355 const BufferView& buffer,
356 const ShaderMetadata* metadata,
357 const DeviceBufferGLES& device_buffer_gles) {
358 const uint8_t* buffer_ptr =
359 device_buffer_gles.GetBufferData() +
buffer.GetRange().offset;
361 if (metadata->members.empty()) {
362 VALIDATION_LOG <<
"Uniform buffer had no members. This is currently "
363 "unsupported in the OpenGL ES backend. Use a uniform "
368 const std::vector<GLint>& locations = ComputeUniformLocations(metadata);
369 for (
size_t i = 0u;
i < metadata->members.size();
i++) {
370 const ShaderStructMemberMetadata& member = metadata->members[
i];
377 size_t element_count = member.array_elements.value_or(1);
378 size_t element_stride = member.byte_length / element_count;
380 reinterpret_cast<const GLfloat*
>(buffer_ptr + member.offset);
385 std::vector<uint8_t> array_element_buffer;
386 if (element_count > 1 && element_stride != member.size) {
387 array_element_buffer.resize(member.size * element_count);
388 for (
size_t element_i = 0; element_i < element_count; element_i++) {
389 std::memcpy(array_element_buffer.data() + element_i * member.size,
390 reinterpret_cast<const char*
>(buffer_data) +
391 element_i * element_stride,
395 reinterpret_cast<const GLfloat*
>(array_element_buffer.data());
399 VALIDATION_LOG <<
"Unsupported uniform data type for key: " << member.name
400 <<
", has type " <<
static_cast<int>(member.type)
401 <<
". Only float uniforms are supported.";
405 switch (member.size) {
413 case sizeof(Vector4):
419 case sizeof(Vector3):
445std::optional<size_t> BufferBindingsGLES::BindTextures(
446 const ProcTableGLES& gl,
447 const std::vector<TextureAndSampler>& bound_textures,
450 size_t unit_start_index) {
451 size_t active_index = unit_start_index;
452 for (
auto i = 0u;
i < texture_range.length;
i++) {
453 const TextureAndSampler&
data = bound_textures[texture_range.offset +
i];
454 if (
data.stage != stage) {
458 if (
data.texture.GetMetadata() ==
nullptr) {
463 auto location = ComputeTextureLocation(
data.texture.GetMetadata());
472 if (active_index >= gl.GetCapabilities()->GetMaxTextureUnits(stage)) {
473 VALIDATION_LOG <<
"Texture units specified exceed the capabilities for "
474 "this shader stage.";
477 gl.ActiveTexture(GL_TEXTURE0 + active_index);
482 if (!texture_gles.Bind()) {
491 if (!sampler_gles.ConfigureBoundTexture(texture_gles, gl)) {
498 gl.Uniform1i(
location, active_index);
static DeviceBufferGLES & Cast(DeviceBuffer &base)
bool BindVertexAttributes(const ProcTableGLES &gl, size_t binding, size_t vertex_offset)
bool ReadUniformsBindings(const ProcTableGLES &gl, GLuint program)
bool UnbindVertexAttributes(const ProcTableGLES &gl)
bool RegisterVertexStageInput(const ProcTableGLES &gl, const std::vector< ShaderStageIOSlot > &inputs, const std::vector< ShaderStageBufferLayout > &layouts)
bool BindUniformData(const ProcTableGLES &gl, const std::vector< TextureAndSampler > &bound_textures, const std::vector< BufferResource > &bound_buffers, Range texture_range, Range buffer_range)
Version GetGlVersion() const
const std::shared_ptr< const CapabilitiesGLES > & GetCapabilities() const
const DescriptionGLES * GetDescription() const
#define FML_DCHECK(condition)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
static std::string CreateUniformMemberKey(const std::string &struct_name, const std::string &member, bool is_array)
static constexpr std::string_view kAngleInputAttachmentPrefix
Resource< BufferView > BufferResource
static std::string NormalizeUniformKey(const std::string &key)
constexpr std::optional< GLenum > ToVertexAttribType(ShaderType type)
constexpr bool IsAtLeast(const Version &other) const
std::shared_ptr< const fml::Mapping > data