| Flutter Impeller |

compiler_test.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/compiler/compiler_test.h"
6 #include "flutter/fml/paths.h"
7 #include "flutter/fml/process.h"
8
9 #include <algorithm>
10 #include <filesystem>
11
12 namespace impeller {
13 namespace compiler {
14 namespace testing {
15
16 static std::string GetIntermediatesPath() {
17 auto test_name = flutter::testing::GetCurrentTestName();
18 std::replace(test_name.begin(), test_name.end(), '/', '_');
19 std::replace(test_name.begin(), test_name.end(), '.', '_');
20 std::stringstream dir_name;
21 dir_name << test_name << "_" << std::to_string(fml::GetCurrentProcId());
22 return fml::paths::JoinPaths(
23 {flutter::testing::GetFixturesPath(), dir_name.str()});
24 }
25
26 CompilerTestBase::CompilerTestBase()
27 : intermediates_path_(GetIntermediatesPath()) {
28 intermediates_directory_ =
29 fml::OpenDirectory(intermediates_path_.c_str(),
30 true, // create if necessary
31 fml::FilePermission::kReadWrite);
32 FML_CHECK(intermediates_directory_.is_valid());
33 }
34
35 CompilerTestBase::~CompilerTestBase() {
36 intermediates_directory_.reset();
37
38 std::filesystem::remove_all(std::filesystem::path(intermediates_path_));
39 }
40
41 static std::string ReflectionHeaderName(const char* fixture_name) {
42 std::stringstream stream;
43 stream << fixture_name << ".h";
44 return stream.str();
45 }
46
47 static std::string ReflectionCCName(const char* fixture_name) {
48 std::stringstream stream;
49 stream << fixture_name << ".cc";
50 return stream.str();
51 }
52
53 static std::string ReflectionJSONName(const char* fixture_name) {
54 std::stringstream stream;
55 stream << fixture_name << ".json";
56 return stream.str();
57 }
58
59 static std::string SPIRVFileName(const char* fixture_name) {
60 std::stringstream stream;
61 stream << fixture_name << ".spv";
62 return stream.str();
63 }
64
65 static std::string SLFileName(const char* fixture_name,
66 TargetPlatform platform) {
67 std::stringstream stream;
68 stream << fixture_name << "." << TargetPlatformSLExtension(platform);
69 return stream.str();
70 }
71
72 std::unique_ptr<fml::FileMapping> CompilerTestBase::GetReflectionJson(
73 const char* fixture_name) const {
74 auto filename = ReflectionJSONName(fixture_name);
75 auto fd = fml::OpenFileReadOnly(intermediates_directory_, filename.c_str());
76 return fml::FileMapping::CreateReadOnly(fd);
77 }
78
79 std::unique_ptr<fml::FileMapping> CompilerTestBase::GetShaderFile(
80 const char* fixture_name,
81 TargetPlatform platform) const {
82 auto filename = SLFileName(fixture_name, platform);
83 auto fd = fml::OpenFileReadOnly(intermediates_directory_, filename.c_str());
84 return fml::FileMapping::CreateReadOnly(fd);
85 }
86
87 bool CompilerTestBase::CanCompileAndReflect(
88 const char* fixture_name,
89 SourceType source_type,
90 SourceLanguage source_language,
91 const char* entry_point_name) const {
92 std::shared_ptr<fml::Mapping> fixture =
93 flutter::testing::OpenFixtureAsMapping(fixture_name);
94 if (!fixture || !fixture->GetMapping()) {
95 VALIDATION_LOG << "Could not find shader in fixtures: " << fixture_name;
96 return false;
97 }
98
99 SourceOptions source_options(fixture_name, source_type);
100 source_options.target_platform = GetParam();
101 source_options.source_language = source_language;
102 source_options.working_directory = std::make_shared<fml::UniqueFD>(
103 flutter::testing::OpenFixturesDirectory());
104 source_options.entry_point_name = EntryPointFunctionNameFromSourceName(
105 fixture_name, SourceTypeFromFileName(fixture_name), source_language,
106 entry_point_name);
107
108 Reflector::Options reflector_options;
109 reflector_options.target_platform = GetParam();
110 reflector_options.header_file_name = ReflectionHeaderName(fixture_name);
111 reflector_options.shader_name = "shader_name";
112
113 Compiler compiler(fixture, source_options, reflector_options);
114 if (!compiler.IsValid()) {
115 VALIDATION_LOG << "Compilation failed: " << compiler.GetErrorMessages();
116 return false;
117 }
118
119 auto spirv_assembly = compiler.GetSPIRVAssembly();
120 if (!spirv_assembly) {
121 VALIDATION_LOG << "No spirv was generated.";
122 return false;
123 }
124
125 if (!fml::WriteAtomically(intermediates_directory_,
126 SPIRVFileName(fixture_name).c_str(),
127 *spirv_assembly)) {
128 VALIDATION_LOG << "Could not write SPIRV intermediates.";
129 return false;
130 }
131
132 auto sl_source = compiler.GetSLShaderSource();
133 if (!sl_source) {
134 VALIDATION_LOG << "No SL source was generated.";
135 return false;
136 }
137
138 if (!fml::WriteAtomically(intermediates_directory_,
139 SLFileName(fixture_name, GetParam()).c_str(),
140 *sl_source)) {
141 VALIDATION_LOG << "Could not write SL intermediates.";
142 return false;
143 }
144
145 if (TargetPlatformNeedsReflection(GetParam())) {
146 auto reflector = compiler.GetReflector();
147 if (!reflector) {
148 VALIDATION_LOG
149 << "No reflector was found for target platform SL compiler.";
150 return false;
151 }
152
153 auto reflection_json = reflector->GetReflectionJSON();
154 auto reflection_header = reflector->GetReflectionHeader();
155 auto reflection_source = reflector->GetReflectionCC();
156
157 if (!reflection_json) {
158 VALIDATION_LOG << "Reflection JSON was not found.";
159 return false;
160 }
161
162 if (!reflection_header) {
163 VALIDATION_LOG << "Reflection header was not found.";
164 return false;
165 }
166
167 if (!reflection_source) {
168 VALIDATION_LOG << "Reflection source was not found.";
169 return false;
170 }
171
172 if (!fml::WriteAtomically(intermediates_directory_,
173 ReflectionHeaderName(fixture_name).c_str(),
174 *reflection_header)) {
175 VALIDATION_LOG << "Could not write reflection header intermediates.";
176 return false;
177 }
178
179 if (!fml::WriteAtomically(intermediates_directory_,
180 ReflectionCCName(fixture_name).c_str(),
181 *reflection_source)) {
182 VALIDATION_LOG << "Could not write reflection CC intermediates.";
183 return false;
184 }
185
186 if (!fml::WriteAtomically(intermediates_directory_,
187 ReflectionJSONName(fixture_name).c_str(),
188 *reflection_json)) {
189 VALIDATION_LOG << "Could not write reflection json intermediates.";
190 return false;
191 }
192 }
193 return true;
194 }
195
196 } // namespace testing
197 } // namespace compiler
198 } // namespace impeller
impeller::compiler::Compiler
Definition: compiler.h:24
impeller::compiler::Compiler::GetSPIRVAssembly
std::shared_ptr< fml::Mapping > GetSPIRVAssembly() const
Definition: compiler.cc:502
impeller::compiler::Compiler::GetReflector
const Reflector * GetReflector() const
Definition: compiler.cc:563
impeller::compiler::Compiler::IsValid
bool IsValid() const
Definition: compiler.cc:510
impeller::compiler::Compiler::GetSLShaderSource
std::shared_ptr< fml::Mapping > GetSLShaderSource() const
Definition: compiler.cc:506
impeller::compiler::Compiler::GetErrorMessages
std::string GetErrorMessages() const
Definition: compiler.cc:520
impeller::compiler::testing::CompilerTestBase::CanCompileAndReflect
bool CanCompileAndReflect(const char *fixture_name, SourceType source_type=SourceType::kUnknown, SourceLanguage source_language=SourceLanguage::kGLSL, const char *entry_point_name="main") const
Definition: compiler_test.cc:87
impeller::compiler::testing::CompilerTestBase::GetReflectionJson
std::unique_ptr< fml::FileMapping > GetReflectionJson(const char *fixture_name) const
Definition: compiler_test.cc:72
impeller::compiler::testing::CompilerTestBase::GetShaderFile
std::unique_ptr< fml::FileMapping > GetShaderFile(const char *fixture_name, TargetPlatform platform) const
Definition: compiler_test.cc:79
impeller::compiler::testing::CompilerTestBase::~CompilerTestBase
~CompilerTestBase()
Definition: compiler_test.cc:35
impeller::compiler::testing::CompilerTestBase::CompilerTestBase
CompilerTestBase()
Definition: compiler_test.cc:26
compiler_test.h
impeller::compiler::testing::ReflectionCCName
static std::string ReflectionCCName(const char *fixture_name)
Definition: compiler_test.cc:47
impeller::compiler::testing::ReflectionJSONName
static std::string ReflectionJSONName(const char *fixture_name)
Definition: compiler_test.cc:53
impeller::compiler::testing::GetIntermediatesPath
static std::string GetIntermediatesPath()
Definition: compiler_test.cc:16
impeller::compiler::testing::ReflectionHeaderName
static std::string ReflectionHeaderName(const char *fixture_name)
Definition: compiler_test.cc:41
impeller::compiler::testing::SLFileName
static std::string SLFileName(const char *fixture_name, TargetPlatform platform)
Definition: compiler_test.cc:65
impeller::compiler::testing::SPIRVFileName
static std::string SPIRVFileName(const char *fixture_name)
Definition: compiler_test.cc:59
impeller::compiler::SourceType
SourceType
Definition: types.h:23
impeller::compiler::TargetPlatformSLExtension
std::string TargetPlatformSLExtension(TargetPlatform platform)
Definition: types.cc:237
impeller::compiler::SourceTypeFromFileName
SourceType SourceTypeFromFileName(const std::filesystem::path &file_name)
Definition: types.cc:17
impeller::compiler::SourceLanguage
SourceLanguage
Definition: types.h:44
impeller::compiler::EntryPointFunctionNameFromSourceName
std::string EntryPointFunctionNameFromSourceName(const std::filesystem::path &file_name, SourceType type, SourceLanguage source_language, const std::string &entry_point_name)
Definition: types.cc:101
impeller::compiler::TargetPlatformNeedsReflection
bool TargetPlatformNeedsReflection(TargetPlatform platform)
Definition: types.cc:130
impeller::compiler::TargetPlatform
TargetPlatform
Definition: types.h:30
impeller
Definition: allocation.cc:12
impeller::compiler::Reflector::Options
Definition: reflector.h:162
impeller::compiler::Reflector::Options::target_platform
TargetPlatform target_platform
Definition: reflector.h:163
impeller::compiler::Reflector::Options::shader_name
std::string shader_name
Definition: reflector.h:165
impeller::compiler::Reflector::Options::header_file_name
std::string header_file_name
Definition: reflector.h:166
impeller::compiler::SourceOptions
Definition: source_options.h:20
impeller::compiler::SourceOptions::source_language
SourceLanguage source_language
Definition: source_options.h:23
impeller::compiler::SourceOptions::entry_point_name
std::string entry_point_name
Definition: source_options.h:27
impeller::compiler::SourceOptions::target_platform
TargetPlatform target_platform
Definition: source_options.h:22
impeller::compiler::SourceOptions::working_directory
std::shared_ptr< fml::UniqueFD > working_directory
Definition: source_options.h:24
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91