1 | // Copyright 2014 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 | import 'package:flutter_tools/src/base/file_system.dart'; |
6 | import 'package:flutter_tools/src/base/logger.dart'; |
7 | import 'package:flutter_tools/src/build_info.dart'; |
8 | import 'package:flutter_tools/src/build_system/tools/shader_compiler.dart'; |
9 | import 'package:flutter_tools/src/globals.dart' as globals; |
10 | |
11 | import '../src/common.dart'; |
12 | import '../src/context.dart'; |
13 | |
14 | void main() { |
15 | late BufferLogger logger; |
16 | |
17 | setUp(() { |
18 | logger = BufferLogger.test(); |
19 | }); |
20 | |
21 | Future<void> testCompileShader(String source) async { |
22 | final Directory tmpDir = globals.fs.systemTempDirectory.createTempSync('shader_compiler_test.' ); |
23 | final File file = tmpDir.childFile('test_shader.frag' )..writeAsStringSync(source); |
24 | final shaderCompiler = ShaderCompiler( |
25 | processManager: globals.processManager, |
26 | logger: logger, |
27 | fileSystem: globals.fs, |
28 | artifacts: globals.artifacts!, |
29 | ); |
30 | await shaderCompiler.compileShader( |
31 | input: file, |
32 | outputPath: tmpDir.childFile('test_shader.frag.out' ).path, |
33 | targetPlatform: TargetPlatform.tester, |
34 | ); |
35 | } |
36 | |
37 | testUsingContext('impellerc .iplr output has correct permissions' , () async { |
38 | if (globals.platform.isWindows) { |
39 | return; |
40 | } |
41 | |
42 | final String flutterRoot = getFlutterRoot(); |
43 | final String inkSparklePath = globals.fs.path.join( |
44 | flutterRoot, |
45 | 'packages' , |
46 | 'flutter' , |
47 | 'lib' , |
48 | 'src' , |
49 | 'material' , |
50 | 'shaders' , |
51 | 'ink_sparkle.frag' , |
52 | ); |
53 | final Directory tmpDir = globals.fs.systemTempDirectory.createTempSync('shader_compiler_test.' ); |
54 | final String inkSparkleOutputPath = globals.fs.path.join(tmpDir.path, 'ink_sparkle.frag' ); |
55 | |
56 | final shaderCompiler = ShaderCompiler( |
57 | processManager: globals.processManager, |
58 | logger: logger, |
59 | fileSystem: globals.fs, |
60 | artifacts: globals.artifacts!, |
61 | ); |
62 | final bool compileResult = await shaderCompiler.compileShader( |
63 | input: globals.fs.file(inkSparklePath), |
64 | outputPath: inkSparkleOutputPath, |
65 | targetPlatform: TargetPlatform.tester, |
66 | ); |
67 | final File resultFile = globals.fs.file(inkSparkleOutputPath); |
68 | |
69 | expect(compileResult, true); |
70 | expect(resultFile.existsSync(), true); |
71 | |
72 | final int expectedMode = int.parse('644' , radix: 8); |
73 | expect(resultFile.statSync().mode & expectedMode, equals(expectedMode)); |
74 | }); |
75 | |
76 | testUsingContext('Compilation error with in storage' , () async { |
77 | const kShaderWithInput = ''' |
78 | in float foo; |
79 | |
80 | out vec4 fragColor; |
81 | |
82 | void main() { |
83 | fragColor = vec4(1.0, 0.0, 0.0, 1.0); |
84 | } |
85 | ''' ; |
86 | |
87 | expect( |
88 | () => testCompileShader(kShaderWithInput), |
89 | throwsA( |
90 | isA<ShaderCompilerException>().having( |
91 | (ShaderCompilerException exception) => exception.message, |
92 | 'message' , |
93 | contains('SkSL does not support inputs' ), |
94 | ), |
95 | ), |
96 | ); |
97 | }); |
98 | |
99 | testUsingContext('Compilation error with UBO' , () async { |
100 | const kShaderWithInput = ''' |
101 | uniform Data { |
102 | vec4 foo; |
103 | } data; |
104 | |
105 | out vec4 fragColor; |
106 | |
107 | void main() { |
108 | fragColor = data.foo; |
109 | } |
110 | ''' ; |
111 | |
112 | expect( |
113 | () => testCompileShader(kShaderWithInput), |
114 | throwsA( |
115 | isA<ShaderCompilerException>().having( |
116 | (ShaderCompilerException exception) => exception.message, |
117 | 'message' , |
118 | contains('SkSL does not support UBOs or SSBOs' ), |
119 | ), |
120 | ), |
121 | ); |
122 | }); |
123 | |
124 | testUsingContext( |
125 | 'Compilation error with texture arguments besides position or sampler' , |
126 | () async { |
127 | const kShaderWithInput = ''' |
128 | uniform sampler2D tex; |
129 | |
130 | out vec4 fragColor; |
131 | |
132 | void main() { |
133 | fragColor = texture(tex, vec2(0.5, 0.3), 0.5); |
134 | } |
135 | ''' ; |
136 | |
137 | expect( |
138 | () => testCompileShader(kShaderWithInput), |
139 | throwsA( |
140 | isA<ShaderCompilerException>().having( |
141 | (ShaderCompilerException exception) => exception.message, |
142 | 'message' , |
143 | contains('Only sampler and position arguments are supported in texture() calls' ), |
144 | ), |
145 | ), |
146 | ); |
147 | }, |
148 | ); |
149 | |
150 | testUsingContext('Compilation error with uint8 uniforms' , () async { |
151 | const kShaderWithInput = ''' |
152 | #version 310 es |
153 | |
154 | layout(location = 0) uniform uint foo; |
155 | layout(location = 0) out vec4 fragColor; |
156 | |
157 | void main() {} |
158 | ''' ; |
159 | |
160 | expect( |
161 | () => testCompileShader(kShaderWithInput), |
162 | throwsA( |
163 | isA<ShaderCompilerException>().having( |
164 | (ShaderCompilerException exception) => exception.message, |
165 | 'message' , |
166 | contains('SkSL does not support unsigned integers' ), |
167 | ), |
168 | ), |
169 | ); |
170 | }); |
171 | } |
172 | |