| 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
5 #include "impeller/shader_archive/shader_archive_writer.h"
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
15 ShaderArchiveWriter::ShaderArchiveWriter() = default;
16
17 ShaderArchiveWriter::~ShaderArchiveWriter() = default;
18
19 std::optional<ArchiveShaderType> InferShaderTypefromFileExtension(
20 const std::filesystem::path& path) {
21 if (path == ".vert") {
22 return ArchiveShaderType::kVertex;
23 } else if (path == ".frag") {
24 return ArchiveShaderType::kFragment;
25 } else if (path == ".comp") {
26 return ArchiveShaderType::kCompute;
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
74 bool ShaderArchiveWriter::AddShader(ArchiveShaderType type,
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) {
88 case ArchiveShaderType::kVertex:
89 return fb::Stage::kVertex;
90 case ArchiveShaderType::kFragment:
91 return fb::Stage::kFragment;
92 case ArchiveShaderType::kCompute:
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
type
GLenum type
Definition: blit_command_gles.cc:127
impeller::ArchiveShaderType::kFragment
@ kFragment
impeller::ArchiveShaderType::kCompute
@ kCompute
impeller
Definition: allocation.cc:12