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