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