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