5#include "gtest/gtest.h"
8#include "flutter/testing/testing.h"
11#include "impeller/shader_bundle/shader_bundle_flatbuffers.h"
18 "\"UnlitFragment\": {\"type\": \"fragment\", \"file\": "
19 "\"shaders/flutter_gpu_unlit.frag\"}";
21 "\"UnlitVertex\": {\"type\": \"vertex\", \"file\": "
22 "\"shaders/flutter_gpu_unlit.vert\"}";
24TEST(ShaderBundleTest, ParseShaderBundleConfigFailsForInvalidJSON) {
25 std::string bundle =
"";
26 std::stringstream
error;
28 ASSERT_FALSE(
result.has_value());
29 ASSERT_STREQ(
error.str().c_str(),
30 "The shader bundle is not a valid JSON object.\n");
33TEST(ShaderBundleTest, ParseShaderBundleConfigFailsWhenEntryNotObject) {
34 std::string bundle =
"{\"UnlitVertex\": []}";
35 std::stringstream
error;
37 ASSERT_FALSE(
result.has_value());
40 "Invalid shader entry \"UnlitVertex\": Entry is not a JSON object.\n");
43TEST(ShaderBundleTest, ParseShaderBundleConfigFailsWhenMissingFile) {
44 std::string bundle =
"{\"UnlitVertex\": {\"type\": \"vertex\"}}";
45 std::stringstream
error;
47 ASSERT_FALSE(
result.has_value());
48 ASSERT_STREQ(
error.str().c_str(),
49 "Invalid shader entry \"UnlitVertex\": Missing required "
53TEST(ShaderBundleTest, ParseShaderBundleConfigFailsWhenMissingType) {
55 "{\"UnlitVertex\": {\"file\": \"shaders/flutter_gpu_unlit.vert\"}}";
56 std::stringstream
error;
58 ASSERT_FALSE(
result.has_value());
59 ASSERT_STREQ(
error.str().c_str(),
60 "Invalid shader entry \"UnlitVertex\": Missing required "
64TEST(ShaderBundleTest, ParseShaderBundleConfigFailsForInvalidType) {
66 "{\"UnlitVertex\": {\"type\": \"invalid\", \"file\": "
67 "\"shaders/flutter_gpu_unlit.vert\"}}";
68 std::stringstream
error;
70 ASSERT_FALSE(
result.has_value());
71 ASSERT_STREQ(
error.str().c_str(),
72 "Invalid shader entry \"UnlitVertex\": Shader type "
73 "\"invalid\" is unknown.\n");
76TEST(ShaderBundleTest, ParseShaderBundleConfigFailsForInvalidLanguage) {
78 "{\"UnlitVertex\": {\"type\": \"vertex\", \"language\": \"invalid\", "
79 "\"file\": \"shaders/flutter_gpu_unlit.vert\"}}";
80 std::stringstream
error;
82 ASSERT_FALSE(
result.has_value());
83 ASSERT_STREQ(
error.str().c_str(),
84 "Invalid shader entry \"UnlitVertex\": Unknown language type "
88TEST(ShaderBundleTest, ParseShaderBundleConfigReturnsExpectedConfig) {
91 std::stringstream
error;
93 ASSERT_TRUE(
result.has_value());
94 ASSERT_STREQ(
error.str().c_str(),
"");
97 auto maybe_vertex =
result->find(
"UnlitVertex");
98 auto maybe_fragment =
result->find(
"UnlitFragment");
99 ASSERT_TRUE(maybe_vertex !=
result->end());
100 ASSERT_TRUE(maybe_fragment !=
result->end());
101 auto vertex = maybe_vertex->second;
102 auto fragment = maybe_fragment->second;
107 EXPECT_STREQ(vertex.entry_point.c_str(),
"main");
108 EXPECT_STREQ(vertex.source_file_name.c_str(),
109 "shaders/flutter_gpu_unlit.vert");
113 EXPECT_STREQ(fragment.entry_point.c_str(),
"main");
114 EXPECT_STREQ(fragment.source_file_name.c_str(),
115 "shaders/flutter_gpu_unlit.frag");
119const T*
FindByName(
const std::vector<std::unique_ptr<T>>& collection,
120 const std::string&
name) {
121 const auto maybe = std::find_if(
122 collection.begin(), collection.end(),
123 [&
name](
const std::unique_ptr<T>&
value) { return value->name == name; });
124 if (maybe == collection.end()) {
130TEST(ShaderBundleTest, GenerateShaderBundleFlatbufferProducesCorrectResult) {
133 "{\"UnlitFragment\": {\"type\": \"fragment\", \"file\": \"" +
135 "/flutter_gpu_unlit.frag\"}, \"UnlitVertex\": {\"type\": "
136 "\"vertex\", \"file\": \"" +
137 fixtures_path +
"/flutter_gpu_unlit.vert\"}}";
143 std::optional<fb::shaderbundle::ShaderBundleT> bundle =
145 ASSERT_TRUE(bundle.has_value());
148 const auto& shaders = bundle->shaders;
149 const auto* vertex =
FindByName(shaders,
"UnlitVertex");
150 const auto* fragment =
FindByName(shaders,
"UnlitFragment");
151 ASSERT_NE(vertex,
nullptr);
152 ASSERT_NE(fragment,
nullptr);
158 EXPECT_STREQ(vertex->metal_desktop->entrypoint.c_str(),
159 "flutter_gpu_unlit_vertex_main");
160 EXPECT_EQ(vertex->metal_desktop->stage,
161 fb::shaderbundle::ShaderStage::kVertex);
164 ASSERT_EQ(vertex->metal_desktop->inputs.size(), 1u);
165 const auto& v_in_position = vertex->metal_desktop->inputs[0];
166 EXPECT_STREQ(v_in_position->name.c_str(),
"position");
167 EXPECT_EQ(v_in_position->location, 0u);
168 EXPECT_EQ(v_in_position->set, 0u);
169 EXPECT_EQ(v_in_position->binding, 0u);
171 EXPECT_EQ(v_in_position->bit_width, 32u);
172 EXPECT_EQ(v_in_position->vec_size, 2u);
173 EXPECT_EQ(v_in_position->columns, 1u);
174 EXPECT_EQ(v_in_position->offset, 0u);
177 ASSERT_EQ(vertex->metal_desktop->uniform_structs.size(), 1u);
178 const auto* vert_info =
179 FindByName(vertex->metal_desktop->uniform_structs,
"VertInfo");
180 ASSERT_NE(vert_info,
nullptr);
181 EXPECT_EQ(vert_info->ext_res_0, 0u);
182 EXPECT_EQ(vert_info->set, 0u);
183 EXPECT_EQ(vert_info->binding, 0u);
184 ASSERT_EQ(vert_info->fields.size(), 2u);
185 const auto& mvp = vert_info->fields[0];
186 EXPECT_STREQ(mvp->name.c_str(),
"mvp");
188 EXPECT_EQ(mvp->offset_in_bytes, 0u);
189 EXPECT_EQ(mvp->element_size_in_bytes, 64u);
190 EXPECT_EQ(mvp->total_size_in_bytes, 64u);
191 EXPECT_EQ(mvp->array_elements, 0u);
192 const auto&
color = vert_info->fields[1];
193 EXPECT_STREQ(
color->name.c_str(),
"color");
195 EXPECT_EQ(
color->offset_in_bytes, 64u);
196 EXPECT_EQ(
color->element_size_in_bytes, 16u);
197 EXPECT_EQ(
color->total_size_in_bytes, 16u);
198 EXPECT_EQ(
color->array_elements, 0u);
204 EXPECT_STREQ(fragment->metal_desktop->entrypoint.c_str(),
205 "flutter_gpu_unlit_fragment_main");
206 EXPECT_EQ(fragment->metal_desktop->stage,
207 fb::shaderbundle::ShaderStage::kFragment);
210 ASSERT_EQ(fragment->metal_desktop->inputs.size(), 0u);
213 ASSERT_EQ(fragment->metal_desktop->inputs.size(), 0u);
const uint8_t uint32_t uint32_t GError ** error
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
DEF_SWITCHES_START aot vmservice shared library name
TEST(CompilerTest, ShaderKindMatchingIsSuccessful)
const std::string kUnlitFragmentBundleConfig
const std::string kUnlitVertexBundleConfig
const T * FindByName(const std::vector< std::unique_ptr< T > > &collection, const std::string &name)
std::optional< fb::shaderbundle::ShaderBundleT > GenerateShaderBundleFlatbuffer(const std::string &bundle_config_json, const SourceOptions &options)
Parses the JSON shader bundle configuration and invokes the compiler multiple times to produce a shad...
std::optional< ShaderBundleConfig > ParseShaderBundleConfig(const std::string &bundle_config_json, std::ostream &error_stream)
Parse a shader bundle configuration from a given JSON string.