5#include "flutter/lib/gpu/shader_library.h"
10#include "flutter/assets/asset_manager.h"
11#include "flutter/lib/gpu/fixtures.h"
12#include "flutter/lib/gpu/shader.h"
13#include "flutter/lib/ui/ui_dart_state.h"
14#include "flutter/lib/ui/window/platform_configuration.h"
20#include "impeller/shader_bundle/shader_bundle_flatbuffers.h"
32 const std::string&
name,
33 std::string& out_error) {
34 if (override_shader_library_) {
35 return override_shader_library_;
39 std::shared_ptr<AssetManager> asset_manager =
40 dart_state->platform_configuration()->client()->GetAssetManager();
42 std::unique_ptr<fml::Mapping>
data = asset_manager->GetAsMapping(
name);
43 if (
data ==
nullptr) {
44 out_error = std::string(
"Asset '") +
name + std::string(
"' not found.");
52 return fml::MakeRefCounted<flutter::gpu::ShaderLibrary>(
nullptr,
59 case impeller::fb::shaderbundle::ShaderStage::kVertex:
61 case impeller::fb::shaderbundle::ShaderStage::kFragment:
63 case impeller::fb::shaderbundle::ShaderStage::kCompute:
70 impeller::fb::shaderbundle::InputDataType input_type) {
72 case impeller::fb::shaderbundle::InputDataType::kBoolean:
74 case impeller::fb::shaderbundle::InputDataType::kSignedByte:
78 case impeller::fb::shaderbundle::InputDataType::kSignedShort:
80 case impeller::fb::shaderbundle::InputDataType::kUnsignedShort:
82 case impeller::fb::shaderbundle::InputDataType::kSignedInt:
84 case impeller::fb::shaderbundle::InputDataType::kUnsignedInt:
86 case impeller::fb::shaderbundle::InputDataType::kSignedInt64:
88 case impeller::fb::shaderbundle::InputDataType::kUnsignedInt64:
98 impeller::fb::shaderbundle::UniformDataType uniform_type) {
99 switch (uniform_type) {
100 case impeller::fb::shaderbundle::UniformDataType::kBoolean:
102 case impeller::fb::shaderbundle::UniformDataType::kSignedByte:
106 case impeller::fb::shaderbundle::UniformDataType::kSignedShort:
108 case impeller::fb::shaderbundle::UniformDataType::kUnsignedShort:
110 case impeller::fb::shaderbundle::UniformDataType::kSignedInt:
112 case impeller::fb::shaderbundle::UniformDataType::kUnsignedInt:
114 case impeller::fb::shaderbundle::UniformDataType::kSignedInt64:
116 case impeller::fb::shaderbundle::UniformDataType::kUnsignedInt64:
122 case impeller::fb::shaderbundle::UniformDataType::kHalfFloat:
130 impeller::fb::shaderbundle::InputDataType input_type) {
131 switch (input_type) {
132 case impeller::fb::shaderbundle::InputDataType::kBoolean:
134 case impeller::fb::shaderbundle::InputDataType::kSignedByte:
138 case impeller::fb::shaderbundle::InputDataType::kSignedShort:
140 case impeller::fb::shaderbundle::InputDataType::kUnsignedShort:
142 case impeller::fb::shaderbundle::InputDataType::kSignedInt:
144 case impeller::fb::shaderbundle::InputDataType::kUnsignedInt:
146 case impeller::fb::shaderbundle::InputDataType::kSignedInt64:
148 case impeller::fb::shaderbundle::InputDataType::kUnsignedInt64:
159 const impeller::fb::shaderbundle::Shader* shader) {
160 switch (backend_type) {
163 return shader->metal_ios();
165 return shader->metal_desktop();
169 return shader->opengl_es();
171 return shader->opengl_desktop();
174 return shader->vulkan();
180 std::shared_ptr<fml::Mapping> payload) {
181 if (payload ==
nullptr || !payload->GetMapping()) {
184 if (!impeller::fb::shaderbundle::ShaderBundleBufferHasIdentifier(
185 payload->GetMapping())) {
189 impeller::fb::shaderbundle::GetShaderBundle(payload->GetMapping());
196 for (
const auto* bundled_shader : *bundle->shaders()) {
197 const impeller::fb::shaderbundle::BackendShader* backend_shader =
199 if (!backend_shader) {
201 << bundled_shader->name()->c_str() <<
"\" from bundle.";
205 auto code_mapping = std::make_shared<fml::NonOwnedMapping>(
206 backend_shader->shader()->data(),
207 backend_shader->shader()->size(),
208 [payload = payload](
auto,
auto) {}
211 std::vector<impeller::DescriptorSetLayout> descriptor_set_layouts;
213 std::unordered_map<std::string, Shader::UniformBinding> uniform_structs;
214 if (backend_shader->uniform_structs() !=
nullptr) {
215 for (
const auto& uniform : *backend_shader->uniform_structs()) {
216 std::vector<impeller::ShaderStructMemberMetadata> members;
217 if (uniform->fields() !=
nullptr) {
218 for (
const auto& struct_member : *uniform->fields()) {
221 .name = struct_member->name()->c_str(),
222 .offset =
static_cast<size_t>(struct_member->offset_in_bytes()),
224 static_cast<size_t>(struct_member->element_size_in_bytes()),
226 static_cast<size_t>(struct_member->total_size_in_bytes()),
228 struct_member->array_elements() != 0
229 ? std::optional<size_t>(std::nullopt)
230 :
static_cast<size_t>(struct_member->array_elements()),
238 .
name = uniform->name()->c_str(),
239 .ext_res_0 =
static_cast<size_t>(uniform->ext_res_0()),
240 .
set =
static_cast<size_t>(uniform->set()),
241 .binding =
static_cast<size_t>(uniform->binding()),
245 .
name = uniform->name()->c_str(),
248 .size_in_bytes =
static_cast<size_t>(uniform->size_in_bytes()),
252 static_cast<uint32_t
>(uniform->binding()),
259 std::unordered_map<std::string, impeller::SampledImageSlot>
261 if (backend_shader->uniform_textures() !=
nullptr) {
262 for (
const auto& uniform : *backend_shader->uniform_textures()) {
264 .
name = uniform->name()->c_str(),
265 .texture_index =
static_cast<size_t>(uniform->ext_res_0()),
266 .
set =
static_cast<size_t>(uniform->set()),
267 .binding =
static_cast<size_t>(uniform->binding()),
271 static_cast<uint32_t
>(uniform->binding()),
278 std::vector<impeller::ShaderStageIOSlot>
inputs;
279 std::vector<impeller::ShaderStageBufferLayout> layouts;
280 if (backend_shader->stage() ==
281 impeller::fb::shaderbundle::ShaderStage::kVertex) {
282 auto inputs_fb = backend_shader->inputs();
284 inputs.reserve(inputs_fb->size());
285 size_t default_stride = 0;
286 for (
const auto& input : *inputs_fb) {
288 slot.
name = input->name()->c_str();
290 slot.
set = input->set();
291 slot.
binding = input->binding();
295 slot.
columns = input->columns();
296 slot.
offset = input->offset();
297 inputs.emplace_back(slot);
309 backend_shader->entrypoint()->str(),
310 ToShaderStage(backend_shader->stage()), std::move(code_mapping),
311 std::move(
inputs), std::move(layouts), std::move(uniform_structs),
312 std::move(uniform_textures), std::move(descriptor_set_layouts));
313 shader_map[bundled_shader->name()->str()] = std::move(shader);
316 return fml::MakeRefCounted<flutter::gpu::ShaderLibrary>(
317 std::move(payload), std::move(shader_map));
322 override_shader_library_ = std::move(override_shader_library);
327 auto it = shaders_.find(shader_name);
328 if (it == shaders_.end()) {
331 auto shader = it->second;
333 if (shader->dart_wrapper() ==
nullptr) {
334 shader->AssociateWithDartWrapper(shader_wrapper);
339ShaderLibrary::ShaderLibrary(std::shared_ptr<fml::Mapping> payload,
341 : payload_(
std::move(payload)), shaders_(
std::move(shaders)) {}
359 std::optional<std::string> out_error;
361 if (out_error.has_value()) {
372 res->AssociateWithDartWrapper(wrapper);
static UIDartState * Current()
static std::shared_ptr< impeller::Context > GetDefaultContext(std::optional< std::string > &out_error)
An immutable collection of shaders loaded from a shader bundle asset.
static void SetOverride(fml::RefPtr< ShaderLibrary > override_shader_library)
Sets a return override for MakeFromAsset for testing purposes.
static fml::RefPtr< ShaderLibrary > MakeFromAsset(impeller::Context::BackendType backend_type, const std::string &name, std::string &out_error)
~ShaderLibrary() override
static fml::RefPtr< ShaderLibrary > MakeFromShaders(ShaderMap shaders)
static fml::RefPtr< ShaderLibrary > MakeFromFlatbuffer(impeller::Context::BackendType backend_type, std::shared_ptr< fml::Mapping > payload)
std::unordered_map< std::string, fml::RefPtr< Shader > > ShaderMap
fml::RefPtr< Shader > GetShader(const std::string &shader_name, Dart_Handle shader_wrapper) const
static fml::RefPtr< Shader > Make(std::string entrypoint, impeller::ShaderStage stage, std::shared_ptr< fml::Mapping > code_mapping, std::vector< impeller::ShaderStageIOSlot > inputs, std::vector< impeller::ShaderStageBufferLayout > layouts, std::unordered_map< std::string, UniformBinding > uniform_structs, std::unordered_map< std::string, impeller::SampledImageSlot > uniform_textures, std::vector< impeller::DescriptorSetLayout > descriptor_set_layouts)
struct _Dart_Handle * Dart_Handle
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT bool Dart_IsString(Dart_Handle object)
const uint8_t uint32_t uint32_t GError ** error
#define FML_UNREACHABLE()
#define FML_DCHECK(condition)
Dart_Handle InternalFlutterGpu_ShaderLibrary_InitializeWithAsset(Dart_Handle wrapper, Dart_Handle asset_name)
Dart_Handle InternalFlutterGpu_ShaderLibrary_GetShader(flutter::gpu::ShaderLibrary *wrapper, Dart_Handle shader_name, Dart_Handle shader_wrapper)
static const impeller::fb::shaderbundle::BackendShader * GetShaderBackend(impeller::Context::BackendType backend_type, const impeller::fb::shaderbundle::Shader *shader)
static impeller::ShaderType FromUniformType(impeller::fb::shaderbundle::UniformDataType uniform_type)
static impeller::ShaderType FromInputType(impeller::fb::shaderbundle::InputDataType input_type)
IMPLEMENT_WRAPPERTYPEINFO(flutter_gpu, CommandBuffer)
static impeller::ShaderStage ToShaderStage(impeller::fb::shaderbundle::ShaderStage stage)
static size_t SizeOfInputType(impeller::fb::shaderbundle::InputDataType input_type)
DEF_SWITCHES_START aot vmservice shared library name
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
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 set
Dart_Handle ToDart(const T &object)
std::string StdStringFromDart(Dart_Handle handle)
Metadata required to bind a combined texture and sampler.
const char * name
The name of the uniform slot.