| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/lib/gpu/shader.h" |
| |
| #include <utility> |
| |
| #include "flutter/lib/gpu/formats.h" |
| #include "fml/make_copyable.h" |
| #include "impeller/core/runtime_types.h" |
| #include "impeller/renderer/shader_function.h" |
| #include "impeller/renderer/shader_library.h" |
| #include "tonic/converter/dart_converter.h" |
| |
| namespace flutter { |
| namespace gpu { |
| |
| const impeller::ShaderStructMemberMetadata* |
| Shader::UniformBinding::GetMemberMetadata(const std::string& name) const { |
| auto result = |
| std::find_if(metadata.members.begin(), metadata.members.end(), |
| [&name](const impeller::ShaderStructMemberMetadata& member) { |
| return member.name == name; |
| }); |
| if (result == metadata.members.end()) { |
| return nullptr; |
| } |
| return &(*result); |
| } |
| |
| IMPLEMENT_WRAPPERTYPEINFO(flutter_gpu, Shader); |
| |
| Shader::Shader() = default; |
| |
| Shader::~Shader() = default; |
| |
| fml::RefPtr<Shader> Shader::Make( |
| std::string entrypoint, |
| impeller::ShaderStage stage, |
| std::shared_ptr<fml::Mapping> code_mapping, |
| std::shared_ptr<impeller::VertexDescriptor> vertex_desc, |
| std::unordered_map<std::string, UniformBinding> uniform_structs, |
| std::unordered_map<std::string, impeller::SampledImageSlot> |
| uniform_textures) { |
| auto shader = fml::MakeRefCounted<Shader>(); |
| shader->entrypoint_ = std::move(entrypoint); |
| shader->stage_ = stage; |
| shader->code_mapping_ = std::move(code_mapping); |
| shader->vertex_desc_ = std::move(vertex_desc); |
| shader->uniform_structs_ = std::move(uniform_structs); |
| shader->uniform_textures_ = std::move(uniform_textures); |
| return shader; |
| } |
| |
| std::shared_ptr<const impeller::ShaderFunction> Shader::GetFunctionFromLibrary( |
| impeller::ShaderLibrary& library) { |
| return library.GetFunction(entrypoint_, stage_); |
| } |
| |
| bool Shader::IsRegistered(Context& context) { |
| auto& lib = *context.GetContext()->GetShaderLibrary(); |
| return GetFunctionFromLibrary(lib) != nullptr; |
| } |
| |
| bool Shader::RegisterSync(Context& context) { |
| if (IsRegistered(context)) { |
| return true; // Already registered. |
| } |
| |
| auto& lib = *context.GetContext()->GetShaderLibrary(); |
| |
| std::promise<bool> promise; |
| auto future = promise.get_future(); |
| lib.RegisterFunction( |
| entrypoint_, stage_, code_mapping_, |
| fml::MakeCopyable([promise = std::move(promise)](bool result) mutable { |
| promise.set_value(result); |
| })); |
| if (!future.get()) { |
| return false; // Registration failed. |
| } |
| return true; |
| } |
| |
| std::shared_ptr<impeller::VertexDescriptor> Shader::GetVertexDescriptor() |
| const { |
| return vertex_desc_; |
| } |
| |
| impeller::ShaderStage Shader::GetShaderStage() const { |
| return stage_; |
| } |
| |
| const Shader::UniformBinding* Shader::GetUniformStruct( |
| const std::string& name) const { |
| auto uniform = uniform_structs_.find(name); |
| if (uniform == uniform_structs_.end()) { |
| return nullptr; |
| } |
| return &uniform->second; |
| } |
| |
| const impeller::SampledImageSlot* Shader::GetUniformTexture( |
| const std::string& name) const { |
| auto uniform = uniform_textures_.find(name); |
| if (uniform == uniform_textures_.end()) { |
| return nullptr; |
| } |
| return &uniform->second; |
| } |
| |
| } // namespace gpu |
| } // namespace flutter |
| |
| //---------------------------------------------------------------------------- |
| /// Exports |
| /// |
| |
| int InternalFlutterGpu_Shader_GetUniformStructSize( |
| flutter::gpu::Shader* wrapper, |
| Dart_Handle struct_name_handle) { |
| auto name = tonic::StdStringFromDart(struct_name_handle); |
| const auto* uniform = wrapper->GetUniformStruct(name); |
| if (uniform == nullptr) { |
| return -1; |
| } |
| |
| return uniform->size_in_bytes; |
| } |
| |
| int InternalFlutterGpu_Shader_GetUniformMemberOffset( |
| flutter::gpu::Shader* wrapper, |
| Dart_Handle struct_name_handle, |
| Dart_Handle member_name_handle) { |
| auto struct_name = tonic::StdStringFromDart(struct_name_handle); |
| const auto* uniform = wrapper->GetUniformStruct(struct_name); |
| if (uniform == nullptr) { |
| return -1; |
| } |
| |
| auto member_name = tonic::StdStringFromDart(member_name_handle); |
| const auto* member = uniform->GetMemberMetadata(member_name); |
| if (member == nullptr) { |
| return -1; |
| } |
| |
| return member->offset; |
| } |