Flutter Engine
The Flutter Engine
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
6#include "flutter/fml/paths.h"
7#include "flutter/fml/process.h"
8
9#include <algorithm>
10#include <filesystem>
11
12namespace impeller {
13namespace compiler {
14namespace testing {
15
16static 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());
23 {flutter::testing::GetFixturesPath(), dir_name.str()});
24}
25
27 intermediates_directory_ =
28 fml::OpenDirectory(intermediates_path_.c_str(),
29 true, // create if necessary
31 FML_CHECK(intermediates_directory_.is_valid());
32}
33
35 intermediates_directory_.reset();
36
37 std::filesystem::remove_all(std::filesystem::path(intermediates_path_));
38}
39
40static std::string ReflectionHeaderName(const char* fixture_name) {
41 std::stringstream stream;
42 stream << fixture_name << ".h";
43 return stream.str();
44}
45
46static std::string ReflectionCCName(const char* fixture_name) {
47 std::stringstream stream;
48 stream << fixture_name << ".cc";
49 return stream.str();
50}
51
52static std::string ReflectionJSONName(const char* fixture_name) {
53 std::stringstream stream;
54 stream << fixture_name << ".json";
55 return stream.str();
56}
57
58static std::string SPIRVFileName(const char* fixture_name) {
59 std::stringstream stream;
60 stream << fixture_name << ".spv";
61 return stream.str();
62}
63
64static std::string SLFileName(const char* fixture_name,
65 TargetPlatform platform) {
66 std::stringstream stream;
67 stream << fixture_name << "." << TargetPlatformSLExtension(platform);
68 return stream.str();
69}
70
71std::unique_ptr<fml::FileMapping> CompilerTest::GetReflectionJson(
72 const char* fixture_name) const {
73 auto filename = ReflectionJSONName(fixture_name);
74 auto fd = fml::OpenFileReadOnly(intermediates_directory_, filename.c_str());
76}
77
78std::unique_ptr<fml::FileMapping> CompilerTest::GetShaderFile(
79 const char* fixture_name,
80 TargetPlatform platform) const {
81 auto filename = SLFileName(fixture_name, platform);
82 auto fd = fml::OpenFileReadOnly(intermediates_directory_, filename.c_str());
84}
85
86bool CompilerTest::CanCompileAndReflect(const char* fixture_name,
87 SourceType source_type,
88 SourceLanguage source_language,
89 const char* entry_point_name) const {
90 std::shared_ptr<fml::Mapping> fixture =
92 if (!fixture || !fixture->GetMapping()) {
93 VALIDATION_LOG << "Could not find shader in fixtures: " << fixture_name;
94 return false;
95 }
96
97 SourceOptions source_options(fixture_name, source_type);
98 source_options.target_platform = GetParam();
99 source_options.source_language = source_language;
100 source_options.working_directory = std::make_shared<fml::UniqueFD>(
103 fixture_name, SourceTypeFromFileName(fixture_name), source_language,
104 entry_point_name);
105
106 Reflector::Options reflector_options;
107 reflector_options.header_file_name = ReflectionHeaderName(fixture_name);
108 reflector_options.shader_name = "shader_name";
109
110 Compiler compiler(fixture, source_options, reflector_options);
111 if (!compiler.IsValid()) {
112 VALIDATION_LOG << "Compilation failed: " << compiler.GetErrorMessages();
113 return false;
114 }
115
116 auto spirv_assembly = compiler.GetSPIRVAssembly();
117 if (!spirv_assembly) {
118 VALIDATION_LOG << "No spirv was generated.";
119 return false;
120 }
121
122 if (!fml::WriteAtomically(intermediates_directory_,
123 SPIRVFileName(fixture_name).c_str(),
124 *spirv_assembly)) {
125 VALIDATION_LOG << "Could not write SPIRV intermediates.";
126 return false;
127 }
128
129 auto sl_source = compiler.GetSLShaderSource();
130 if (!sl_source) {
131 VALIDATION_LOG << "No SL source was generated.";
132 return false;
133 }
134
135 if (!fml::WriteAtomically(intermediates_directory_,
136 SLFileName(fixture_name, GetParam()).c_str(),
137 *sl_source)) {
138 VALIDATION_LOG << "Could not write SL intermediates.";
139 return false;
140 }
141
142 if (TargetPlatformNeedsReflection(GetParam())) {
143 auto reflector = compiler.GetReflector();
144 if (!reflector) {
146 << "No reflector was found for target platform SL compiler.";
147 return false;
148 }
149
150 auto reflection_json = reflector->GetReflectionJSON();
151 auto reflection_header = reflector->GetReflectionHeader();
152 auto reflection_source = reflector->GetReflectionCC();
153
154 if (!reflection_json) {
155 VALIDATION_LOG << "Reflection JSON was not found.";
156 return false;
157 }
158
159 if (!reflection_header) {
160 VALIDATION_LOG << "Reflection header was not found.";
161 return false;
162 }
163
164 if (!reflection_source) {
165 VALIDATION_LOG << "Reflection source was not found.";
166 return false;
167 }
168
169 if (!fml::WriteAtomically(intermediates_directory_,
170 ReflectionHeaderName(fixture_name).c_str(),
171 *reflection_header)) {
172 VALIDATION_LOG << "Could not write reflection header intermediates.";
173 return false;
174 }
175
176 if (!fml::WriteAtomically(intermediates_directory_,
177 ReflectionCCName(fixture_name).c_str(),
178 *reflection_source)) {
179 VALIDATION_LOG << "Could not write reflection CC intermediates.";
180 return false;
181 }
182
183 if (!fml::WriteAtomically(intermediates_directory_,
184 ReflectionJSONName(fixture_name).c_str(),
185 *reflection_json)) {
186 VALIDATION_LOG << "Could not write reflection json intermediates.";
187 return false;
188 }
189 }
190 return true;
191}
192
193} // namespace testing
194} // namespace compiler
195} // namespace impeller
static std::unique_ptr< FileMapping > CreateReadOnly(const std::string &path)
Definition: mapping.cc:20
void reset(const T &value=Traits::InvalidValue())
Definition: unique_object.h:62
bool is_valid() const
Definition: unique_object.h:89
bool CanCompileAndReflect(const char *fixture_name, SourceType source_type=SourceType::kUnknown, SourceLanguage source_language=SourceLanguage::kGLSL, const char *entry_point_name="main") const
std::unique_ptr< fml::FileMapping > GetReflectionJson(const char *fixture_name) const
std::unique_ptr< fml::FileMapping > GetShaderFile(const char *fixture_name, TargetPlatform platform) const
#define FML_CHECK(condition)
Definition: logging.h:85
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
Definition: testing.cc:15
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
fml::UniqueFD OpenFixturesDirectory()
Opens the fixtures directory for the unit-test harness.
Definition: testing.cc:23
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
Definition: testing.cc:59
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
std::string JoinPaths(std::initializer_list< std::string > components)
Definition: paths.cc:14
fml::UniqueFD OpenFileReadOnly(const fml::UniqueFD &base_directory, const char *path)
Definition: file.cc:92
bool WriteAtomically(const fml::UniqueFD &base_directory, const char *file_name, const Mapping &mapping)
Definition: file_posix.cc:191
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
Definition: file_posix.cc:97
int GetCurrentProcId()
Definition: process_posix.cc:9
static std::string ReflectionCCName(const char *fixture_name)
static std::string ReflectionJSONName(const char *fixture_name)
static std::string GetIntermediatesPath()
static std::string ReflectionHeaderName(const char *fixture_name)
static std::string SLFileName(const char *fixture_name, TargetPlatform platform)
static std::string SPIRVFileName(const char *fixture_name)
std::string TargetPlatformSLExtension(TargetPlatform platform)
Definition: types.cc:246
SourceType SourceTypeFromFileName(const std::string &file_name)
Definition: types.cc:30
std::string EntryPointFunctionNameFromSourceName(const std::string &file_name, SourceType type, SourceLanguage source_language, const std::string &entry_point_name)
Definition: types.cc:111
bool TargetPlatformNeedsReflection(TargetPlatform platform)
Definition: types.cc:141
compiler
Definition: malisc.py:17
static SkString to_string(int n)
Definition: nanobench.cpp:119
std::shared_ptr< fml::UniqueFD > working_directory
#define VALIDATION_LOG
Definition: validation.h:73