Flutter Impeller
shader_archive_writer.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 <array>
8 #include <filesystem>
9 #include <optional>
10 
11 #include "flutter/fml/build_config.h"
12 #include "impeller/shader_archive/shader_archive_flatbuffers.h"
13 
14 namespace impeller {
15 
17 
19 
20 std::optional<ArchiveShaderType> InferShaderTypefromFileExtension(
21  const std::filesystem::path& path) {
22 #if FML_OS_QNX
23  return std::nullopt;
24 #else // FML_OS_QNX
25  if (path == ".vert") {
27  } else if (path == ".frag") {
29  } else if (path == ".comp") {
31  }
32  return std::nullopt;
33 #endif // FML_OS_QNX
34 }
35 
36 bool ShaderArchiveWriter::AddShaderAtPath(const std::string& std_path) {
37 #if FML_OS_QNX
38  return false;
39 #else // FML_OS_QNX
40  std::filesystem::path path(std_path);
41 
42  if (path.stem().empty()) {
43  FML_LOG(ERROR) << "File path stem was empty for " << path;
44  return false;
45  }
46 
47  if (path.extension() != ".gles" && path.extension() != ".vkspv") {
48  FML_LOG(ERROR) << "File path doesn't have a known shader extension "
49  << path;
50  return false;
51  }
52 
53  // Get rid of .gles
54  path = path.replace_extension();
55 
56  auto shader_type = InferShaderTypefromFileExtension(path.extension());
57 
58  if (!shader_type.has_value()) {
59  FML_LOG(ERROR) << "Could not infer shader type from file extension: "
60  << path.extension().string();
61  return false;
62  }
63 
64  // Get rid of the shader type extension (.vert, .frag, etc..).
65  path = path.replace_extension();
66 
67  const auto shader_name = path.stem().string();
68  if (shader_name.empty()) {
69  FML_LOG(ERROR) << "Shader name was empty.";
70  return false;
71  }
72 
73  auto file_mapping = fml::FileMapping::CreateReadOnly(std_path);
74  if (!file_mapping) {
75  FML_LOG(ERROR) << "File doesn't exist at path: " << path;
76  return false;
77  }
78 
79  return AddShader(shader_type.value(), shader_name, std::move(file_mapping));
80 #endif // FML_OS_QNX
81 }
82 
84  std::string name,
85  std::shared_ptr<fml::Mapping> mapping) {
86  if (name.empty() || !mapping || mapping->GetMapping() == nullptr) {
87  return false;
88  }
89 
90  shader_descriptions_.emplace_back(
91  ShaderDescription{type, std::move(name), std::move(mapping)});
92  return true;
93 }
94 
95 constexpr fb::Stage ToStage(ArchiveShaderType type) {
96  switch (type) {
98  return fb::Stage::kVertex;
100  return fb::Stage::kFragment;
102  return fb::Stage::kCompute;
103  }
104  FML_UNREACHABLE();
105 }
106 
107 std::shared_ptr<fml::Mapping> ShaderArchiveWriter::CreateMapping() const {
108  fb::ShaderArchiveT shader_archive;
109  for (const auto& shader_description : shader_descriptions_) {
110  auto mapping = shader_description.mapping;
111  if (!mapping) {
112  return nullptr;
113  }
114  auto desc = std::make_unique<fb::ShaderBlobT>();
115  desc->name = shader_description.name;
116  desc->stage = ToStage(shader_description.type);
117  desc->mapping = {mapping->GetMapping(),
118  mapping->GetMapping() + mapping->GetSize()};
119  shader_archive.items.emplace_back(std::move(desc));
120  }
121  auto builder = std::make_shared<flatbuffers::FlatBufferBuilder>();
122  builder->Finish(fb::ShaderArchive::Pack(*builder.get(), &shader_archive),
123  fb::ShaderArchiveIdentifier());
124  return std::make_shared<fml::NonOwnedMapping>(builder->GetBufferPointer(),
125  builder->GetSize(),
126  [builder](auto, auto) {});
127 }
128 
129 } // namespace impeller
GLenum type
bool AddShaderAtPath(const std::string &path)
bool AddShader(ArchiveShaderType type, std::string name, std::shared_ptr< fml::Mapping > mapping)
std::shared_ptr< fml::Mapping > CreateMapping() const
std::optional< ArchiveShaderType > InferShaderTypefromFileExtension(const std::filesystem::path &path)
constexpr fb::Stage ToStage(ArchiveShaderType type)