diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/BUILD.gn b/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/BUILD.gn index 744a4ba8e0a..0873f835115 100644 --- a/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/BUILD.gn +++ b/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/BUILD.gn @@ -10,6 +10,7 @@ if (enable_unittests) { test_shaders = [ "blue_green_sampler.frag", "children_and_uniforms.frag", + "circle_sdf.frag", "double_sampler_swapped.frag", "double_sampler.frag", "filter_shader.frag", @@ -18,15 +19,16 @@ if (enable_unittests) { "missing_texture.frag", "no_builtin_redefinition.frag", "no_uniforms.frag", + "sdf.frag", "simple.frag", "texture.frag", "uniform_arrays.frag", "uniform_ordering.frag", "uniforms_inserted.frag", + "uniforms_renamed.frag", "uniforms_reordered.frag", "uniforms_sorted.frag", "uniforms.frag", - "uniforms_renamed.frag", "vec3_uniform.frag", ] @@ -38,18 +40,6 @@ if (enable_unittests) { impellerc("compile_general_shaders") { mnemonic = "IMPELLERC_SKSL" shaders = test_shaders - shader_target_flags = [ "--sksl" ] - intermediates_subdir = "iplr" - sl_file_extension = "iplr" - iplr = true - } - - impellerc("compile_sdf_shaders") { - mnemonic = "IMPELLERC_SDF" - shaders = [ - "circle_sdf.frag", - "sdf.frag", - ] shader_target_flags = [ "--sksl", "--runtime-stage-metal", @@ -62,12 +52,8 @@ if (enable_unittests) { } test_fixtures("fixtures") { - deps = [ - ":compile_general_shaders", - ":compile_sdf_shaders", - ] - fixtures = get_target_outputs(":compile_general_shaders") + - get_target_outputs(":compile_sdf_shaders") + deps = [ ":compile_general_shaders" ] + fixtures = get_target_outputs(":compile_general_shaders") dest = "$root_gen_dir/flutter/lib/ui" } } diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/blue_green_sampler.frag b/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/blue_green_sampler.frag index 8cff5d531da..224e9754886 100644 --- a/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/blue_green_sampler.frag +++ b/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/blue_green_sampler.frag @@ -6,9 +6,9 @@ precision highp float; -layout(location = 0) out vec4 oColor; +out vec4 oColor; -layout(location = 0) uniform sampler2D iChild; +uniform sampler2D iChild; void main() { // iChild1 is an image that is half blue, half green, diff --git a/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/children_and_uniforms.frag b/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/children_and_uniforms.frag index 41bb1556535..9dafb0cbc54 100644 --- a/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/children_and_uniforms.frag +++ b/engine/src/flutter/lib/ui/fixtures/shaders/general_shaders/children_and_uniforms.frag @@ -8,10 +8,10 @@ precision highp float; layout(location = 0) out vec4 color; -layout(location = 0) uniform sampler2D child1; -layout(location = 1) uniform float a; -layout(location = 2) uniform sampler2D child2; -layout(location = 3) uniform float b; +uniform sampler2D child1; +uniform float a; +uniform sampler2D child2; +uniform float b; void main() { // child1 is a 10x10 image where the left half is blue and the right diff --git a/engine/src/flutter/testing/dart/fragment_shader_test.dart b/engine/src/flutter/testing/dart/fragment_shader_test.dart index 8d44ce8a465..684ac08ab8a 100644 --- a/engine/src/flutter/testing/dart/fragment_shader_test.dart +++ b/engine/src/flutter/testing/dart/fragment_shader_test.dart @@ -17,8 +17,6 @@ import 'impeller_enabled.dart'; import 'shader_test_file_utils.dart'; void main() async { - final ImageComparer comparer = await ImageComparer.create(); - test('impellerc produces reasonable JSON encoded IPLR files', () async { final Directory directory = shaderDirectory('iplr-json'); final Object? rawData = convert.json.decode( @@ -43,11 +41,6 @@ void main() async { expect(uniformData['location'] is int, true); }); - if (impellerEnabled) { - // https://github.com/flutter/flutter/issues/122823 - return; - } - test('FragmentProgram objects are cached.', () async { final FragmentProgram programA = await FragmentProgram.fromAsset( 'blue_green_sampler.frag.iplr', @@ -59,109 +52,6 @@ void main() async { expect(identical(programA, programB), true); }); - group('FragmentProgram getUniform*', () { - late FragmentShader shader; - - setUpAll(() async { - final FragmentProgram program = await FragmentProgram.fromAsset('uniforms.frag.iplr'); - shader = program.fragmentShader(); - }); - - test('FragmentProgram uniform info', () async { - final List slots = [ - shader.getUniformFloat('iFloatUniform'), - shader.getUniformFloat('iVec2Uniform', 0), - shader.getUniformFloat('iVec2Uniform', 1), - shader.getUniformFloat('iMat2Uniform', 0), - shader.getUniformFloat('iMat2Uniform', 1), - shader.getUniformFloat('iMat2Uniform', 2), - shader.getUniformFloat('iMat2Uniform', 3), - ]; - for (var i = 0; i < slots.length; ++i) { - expect(slots[i].shaderIndex, equals(i)); - } - }); - - test('FragmentProgram getUniformFloat unknown', () async { - try { - shader.getUniformFloat('unknown'); - fail('Unreachable'); - } catch (e) { - expect(e.toString(), contains('No uniform named "unknown".')); - } - }); - - test('FragmentProgram getUniformFloat offset overflow', () async { - try { - shader.getUniformFloat('iVec2Uniform', 2); - fail('Unreachable'); - } catch (e) { - expect(e.toString(), contains('Index `2` out of bounds for `iVec2Uniform`.')); - } - }); - - test('FragmentProgram getUniformFloat offset underflow', () async { - try { - shader.getUniformFloat('iVec2Uniform', -1); - fail('Unreachable'); - } catch (e) { - expect(e.toString(), contains('Index `-1` out of bounds for `iVec2Uniform`.')); - } - }); - - test('FragmentProgram getUniformVec2', () async { - final UniformVec2Slot slot = shader.getUniformVec2('iVec2Uniform'); - slot.set(6.0, 7.0); - }); - - test('FragmentProgram getUniformVec2 wrong size', () async { - try { - shader.getUniformVec2('iVec3Uniform'); - fail('Unreachable'); - } catch (e) { - expect(e.toString(), contains('`iVec3Uniform` has size 3, not size 2.')); - } - try { - shader.getUniformVec2('iFloatUniform'); - } catch (e) { - expect(e.toString(), contains('`iFloatUniform` has size 1, not size 2.')); - } - }); - - test('FragmentProgram getUniformVec3', () async { - final UniformVec3Slot slot = shader.getUniformVec3('iVec3Uniform'); - slot.set(0.8, 0.1, 0.3); - }); - - test('FragmentProgram getUniformVec3 wrong size', () async { - try { - shader.getUniformVec3('iVec2Uniform'); - fail('Unreachable'); - } catch (e) { - expect(e.toString(), contains('`iVec2Uniform` has size 2, not size 3.')); - } - try { - shader.getUniformVec3('iVec4Uniform'); - } catch (e) { - expect(e.toString(), contains('`iVec4Uniform` has size 4, not size 3.')); - } - }); - - test('FragmentProgram getUniformVec4', () async { - final UniformVec4Slot slot = shader.getUniformVec4('iVec4Uniform'); - slot.set(11.0, 22.0, 19.0, 96.0); - }); - - test('FragmentProgram getUniformVec4 wrong size', () async { - try { - shader.getUniformVec4('iVec3Uniform'); - fail('Unreachable'); - } catch (e) { - expect(e.toString(), contains('`iVec3Uniform` has size 3, not size 4.')); - } - }); - }); - test('FragmentProgram getImageSampler', () async { final FragmentProgram program = await FragmentProgram.fromAsset('uniform_ordering.frag.iplr'); final FragmentShader shader = program.fragmentShader(); @@ -182,17 +72,6 @@ void main() async { } }); - test('FragmentProgram getImageSampler wrong type', () async { - final FragmentProgram program = await FragmentProgram.fromAsset('uniform_ordering.frag.iplr'); - final FragmentShader shader = program.fragmentShader(); - try { - shader.getImageSampler('b'); - fail('Unreachable'); - } catch (e) { - expect(e.toString(), contains('Uniform "b" is not an image sampler.')); - } - }); - test('FragmentShader setSampler throws with out-of-bounds index', () async { final FragmentProgram program = await FragmentProgram.fromAsset('blue_green_sampler.frag.iplr'); final Image blueGreenImage = await _createBlueGreenImage(); @@ -331,13 +210,6 @@ void main() async { ); }); - test('FragmentShader simple shader renders correctly', () async { - final FragmentProgram program = await FragmentProgram.fromAsset('functions.frag.iplr'); - final FragmentShader shader = program.fragmentShader()..setFloat(0, 1.0); - await _expectShaderRendersGreen(shader); - shader.dispose(); - }); - test('Reused FragmentShader simple shader renders correctly', () async { final FragmentProgram program = await FragmentProgram.fromAsset('functions.frag.iplr'); final FragmentShader shader = program.fragmentShader()..setFloat(0, 1.0); @@ -367,77 +239,6 @@ void main() async { blueGreenImage.dispose(); }); - for (final (filterQuality, goldenFilename) in [ - (FilterQuality.none, 'fragment_shader_texture_with_quality_none.png'), - (FilterQuality.low, 'fragment_shader_texture_with_quality_low.png'), - (FilterQuality.medium, 'fragment_shader_texture_with_quality_medium.png'), - (FilterQuality.high, 'fragment_shader_texture_with_quality_high.png'), - ]) { - test('FragmentShader renders sampler with filter quality ${filterQuality.name}', () async { - final FragmentProgram program = await FragmentProgram.fromAsset('texture.frag.iplr'); - final Image image = _createOvalGradientImage(imageDimension: 16); - final FragmentShader shader = program.fragmentShader() - ..setImageSampler(0, image, filterQuality: filterQuality); - shader.getUniformFloat('u_size', 0).set(300); - shader.getUniformFloat('u_size', 1).set(300); - - final Image shaderImage = await _imageFromShader(shader: shader, imageDimension: 300); - - await comparer.addGoldenImage(shaderImage, goldenFilename); - shader.dispose(); - image.dispose(); - }); - } - - test('FragmentShader with uniforms renders correctly', () async { - final FragmentProgram program = await FragmentProgram.fromAsset('uniforms.frag.iplr'); - - final FragmentShader shader = program.fragmentShader() - ..setFloat(0, 0.0) - ..setFloat(1, 0.25) - ..setFloat(2, 0.75) - ..setFloat(3, 0.0) - ..setFloat(4, 0.0) - ..setFloat(5, 0.0) - ..setFloat(6, 1.0); - - final ByteData renderedBytes = (await _imageByteDataFromShader(shader: shader))!; - - expect(toFloat(renderedBytes.getUint8(0)), closeTo(0.0, epsilon)); - expect(toFloat(renderedBytes.getUint8(1)), closeTo(0.25, epsilon)); - expect(toFloat(renderedBytes.getUint8(2)), closeTo(0.75, epsilon)); - expect(toFloat(renderedBytes.getUint8(3)), closeTo(1.0, epsilon)); - - shader.dispose(); - }); - - test('FragmentShader shader with array uniforms renders correctly', () async { - final FragmentProgram program = await FragmentProgram.fromAsset('uniform_arrays.frag.iplr'); - - final FragmentShader shader = program.fragmentShader(); - for (var i = 0; i < 20; i++) { - shader.setFloat(i, i.toDouble()); - } - - await _expectShaderRendersGreen(shader); - shader.dispose(); - }); - - test('FragmentShader The ink_sparkle shader is accepted', () async { - if (impellerEnabled) { - print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); - return; - } - final FragmentProgram program = await FragmentProgram.fromAsset('ink_sparkle.frag.iplr'); - final FragmentShader shader = program.fragmentShader(); - - await _imageByteDataFromShader(shader: shader); - - // Testing that no exceptions are thrown. Tests that the ink_sparkle shader - // produces the correct pixels are in the framework. - shader.dispose(); - }); - test('FragmentShader Uniforms are sorted correctly', () async { final FragmentProgram program = await FragmentProgram.fromAsset('uniforms_sorted.frag.iplr'); @@ -492,10 +293,6 @@ void main() async { }); test('FragmentShader user defined functions do not redefine builtins', () async { - if (impellerEnabled) { - print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); - return; - } final FragmentProgram program = await FragmentProgram.fromAsset( 'no_builtin_redefinition.frag.iplr', ); @@ -505,21 +302,199 @@ void main() async { }); test('FragmentShader fromAsset accepts a shader with no uniforms', () async { - if (impellerEnabled) { - print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); - return; - } final FragmentProgram program = await FragmentProgram.fromAsset('no_uniforms.frag.iplr'); final FragmentShader shader = program.fragmentShader(); await _expectShaderRendersGreen(shader); shader.dispose(); }); - test('ImageFilter.shader errors if shader does not have correct uniform layout', () async { - if (!impellerEnabled) { - print('Skipped for Skia'); - return; + group('FragmentProgram getUniform*', () { + late FragmentShader shader; + + setUpAll(() async { + final FragmentProgram program = await FragmentProgram.fromAsset('uniforms.frag.iplr'); + shader = program.fragmentShader(); + }); + + _runSkiaTest('FragmentProgram uniform info', () async { + final List slots = [ + shader.getUniformFloat('iFloatUniform'), + shader.getUniformFloat('iVec2Uniform', 0), + shader.getUniformFloat('iVec2Uniform', 1), + shader.getUniformFloat('iMat2Uniform', 0), + shader.getUniformFloat('iMat2Uniform', 1), + shader.getUniformFloat('iMat2Uniform', 2), + shader.getUniformFloat('iMat2Uniform', 3), + ]; + for (var i = 0; i < slots.length; ++i) { + expect(slots[i].shaderIndex, equals(i)); + } + }); + + _runSkiaTest('FragmentProgram getUniformFloat unknown', () async { + try { + shader.getUniformFloat('unknown'); + fail('Unreachable'); + } catch (e) { + expect(e.toString(), contains('No uniform named "unknown".')); + } + }); + + _runSkiaTest('FragmentProgram getUniformFloat offset overflow', () async { + try { + shader.getUniformFloat('iVec2Uniform', 2); + fail('Unreachable'); + } catch (e) { + expect(e.toString(), contains('Index `2` out of bounds for `iVec2Uniform`.')); + } + }); + + _runSkiaTest('FragmentProgram getUniformFloat offset underflow', () async { + try { + shader.getUniformFloat('iVec2Uniform', -1); + fail('Unreachable'); + } catch (e) { + expect(e.toString(), contains('Index `-1` out of bounds for `iVec2Uniform`.')); + } + }); + + _runSkiaTest('FragmentProgram getUniformVec2', () async { + final UniformVec2Slot slot = shader.getUniformVec2('iVec2Uniform'); + slot.set(6.0, 7.0); + }); + + _runSkiaTest('FragmentProgram getUniformVec2 wrong size', () async { + try { + shader.getUniformVec2('iVec3Uniform'); + fail('Unreachable'); + } catch (e) { + expect(e.toString(), contains('`iVec3Uniform` has size 3, not size 2.')); + } + try { + shader.getUniformVec2('iFloatUniform'); + } catch (e) { + expect(e.toString(), contains('`iFloatUniform` has size 1, not size 2.')); + } + }); + + _runSkiaTest('FragmentProgram getUniformVec3', () async { + final UniformVec3Slot slot = shader.getUniformVec3('iVec3Uniform'); + slot.set(0.8, 0.1, 0.3); + }); + + _runSkiaTest('FragmentProgram getUniformVec3 wrong size', () async { + try { + shader.getUniformVec3('iVec2Uniform'); + fail('Unreachable'); + } catch (e) { + expect(e.toString(), contains('`iVec2Uniform` has size 2, not size 3.')); + } + try { + shader.getUniformVec3('iVec4Uniform'); + } catch (e) { + expect(e.toString(), contains('`iVec4Uniform` has size 4, not size 3.')); + } + }); + + _runSkiaTest('FragmentProgram getUniformVec4', () async { + final UniformVec4Slot slot = shader.getUniformVec4('iVec4Uniform'); + slot.set(11.0, 22.0, 19.0, 96.0); + }); + + _runSkiaTest('FragmentProgram getUniformVec4 wrong size', () async { + try { + shader.getUniformVec4('iVec3Uniform'); + fail('Unreachable'); + } catch (e) { + expect(e.toString(), contains('`iVec3Uniform` has size 3, not size 4.')); + } + }); + }); + + _runSkiaTest('FragmentProgram getImageSampler wrong type', () async { + final FragmentProgram program = await FragmentProgram.fromAsset('uniform_ordering.frag.iplr'); + final FragmentShader shader = program.fragmentShader(); + try { + shader.getImageSampler('b'); + fail('Unreachable'); + } catch (e) { + expect(e.toString(), contains('Uniform "b" is not an image sampler.')); } + }); + + final ImageComparer comparer = await ImageComparer.create(); + for (final (filterQuality, goldenFilename) in [ + (FilterQuality.none, 'fragment_shader_texture_with_quality_none.png'), + (FilterQuality.low, 'fragment_shader_texture_with_quality_low.png'), + (FilterQuality.medium, 'fragment_shader_texture_with_quality_medium.png'), + (FilterQuality.high, 'fragment_shader_texture_with_quality_high.png'), + ]) { + _runSkiaTest( + 'FragmentShader renders sampler with filter quality ${filterQuality.name}', + () async { + final FragmentProgram program = await FragmentProgram.fromAsset('texture.frag.iplr'); + final Image image = _createOvalGradientImage(imageDimension: 16); + final FragmentShader shader = program.fragmentShader() + ..setImageSampler(0, image, filterQuality: filterQuality); + shader.getUniformFloat('u_size', 0).set(300); + shader.getUniformFloat('u_size', 1).set(300); + + final Image shaderImage = await _imageFromShader(shader: shader, imageDimension: 300); + + await comparer.addGoldenImage(shaderImage, goldenFilename); + shader.dispose(); + image.dispose(); + }, + ); + } + + _runSkiaTest('FragmentShader simple shader renders correctly', () async { + final FragmentProgram program = await FragmentProgram.fromAsset('functions.frag.iplr'); + final FragmentShader shader = program.fragmentShader()..setFloat(0, 1.0); + await _expectShaderRendersGreen(shader); + shader.dispose(); + }); + + _runSkiaTest('FragmentShader with uniforms renders correctly', () async { + final FragmentProgram program = await FragmentProgram.fromAsset('uniforms.frag.iplr'); + + final FragmentShader shader = program.fragmentShader() + ..setFloat(0, 0.0) + ..setFloat(1, 0.25) + ..setFloat(2, 0.75) + ..setFloat(3, 0.0) + ..setFloat(4, 0.0) + ..setFloat(5, 0.0) + ..setFloat(6, 1.0); + + final ByteData renderedBytes = (await _imageByteDataFromShader(shader: shader))!; + + expect(toFloat(renderedBytes.getUint8(0)), closeTo(0.0, epsilon)); + expect(toFloat(renderedBytes.getUint8(1)), closeTo(0.25, epsilon)); + expect(toFloat(renderedBytes.getUint8(2)), closeTo(0.75, epsilon)); + expect(toFloat(renderedBytes.getUint8(3)), closeTo(1.0, epsilon)); + + shader.dispose(); + }); + + _runSkiaTest('FragmentShader shader with array uniforms renders correctly', () async { + final FragmentProgram program = await FragmentProgram.fromAsset('uniform_arrays.frag.iplr'); + + final FragmentShader shader = program.fragmentShader(); + for (var i = 0; i < 20; i++) { + shader.setFloat(i, i.toDouble()); + } + + await _expectShaderRendersGreen(shader); + shader.dispose(); + }); + + test('ImageFilter.shader errors if shader does not have correct uniform layout', () async { + // TODO(gaaclarke): This test was disabled for a long time and has been + // atrophied. Fix it or remove it. + print('Atrophied test is disabled.'); + return; + // ignore: dead_code const shaders = [ 'no_uniforms.frag.iplr', 'missing_size.frag.iplr', @@ -548,12 +523,13 @@ void main() async { } }); - test('Shader Compiler appropriately pads vec3 uniform arrays', () async { - if (!impellerEnabled) { - print('Skipped for Skia'); - return; - } + _runImpellerTest('Shader Compiler appropriately pads vec3 uniform arrays', () async { + // TODO(gaaclarke): This test was disabled for a long time and has been + // atrophied. Fix it or remove it. + print('Atrophied test is disabled.'); + return; + // ignore: dead_code final FragmentProgram program = await FragmentProgram.fromAsset('vec3_uniform.frag.iplr'); final FragmentShader shader = program.fragmentShader(); @@ -566,11 +542,12 @@ void main() async { await _expectShaderRendersGreen(shader); }); - test('ImageFilter.shader can be applied to canvas operations', () async { - if (!impellerEnabled) { - print('Skipped for Skia'); - return; - } + _runImpellerTest('ImageFilter.shader can be applied to canvas operations', () async { + // TODO(gaaclarke): This test was disabled for a long time and has been + // atrophied. Fix it or remove it. + print('Atrophied test is disabled.'); + return; + // ignore: dead_code final FragmentProgram program = await FragmentProgram.fromAsset('filter_shader.frag.iplr'); final FragmentShader shader = program.fragmentShader(); final recorder = PictureRecorder(); @@ -589,10 +566,11 @@ void main() async { // For an explaination of the problem see https://github.com/flutter/flutter/issues/163302 . test('ImageFilter.shader equality checks consider uniform values', () async { - if (!impellerEnabled) { - print('Skipped for Skia'); - return; - } + // TODO(gaaclarke): This test was disabled for a long time and has been + // atrophied. Fix it or remove it. + print('Atrophied test is disabled.'); + return; + // ignore: dead_code final FragmentProgram program = await FragmentProgram.fromAsset('filter_shader.frag.iplr'); final FragmentShader shader = program.fragmentShader(); final filter = ImageFilter.shader(shader); @@ -615,24 +593,56 @@ void main() async { expect(identical(filter, filter_3), false); }); - if (impellerEnabled) { - print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); - return; + _runSkiaTest('FragmentShader The ink_sparkle shader is accepted', () async { + final FragmentProgram program = await FragmentProgram.fromAsset('ink_sparkle.frag.iplr'); + final FragmentShader shader = program.fragmentShader(); + + await _imageByteDataFromShader(shader: shader); + + // Testing that no exceptions are thrown. Tests that the ink_sparkle shader + // produces the correct pixels are in the framework. + shader.dispose(); + }); + + if (!impellerEnabled) { + // Test all supported GLSL ops. See lib/spirv/lib/src/constants.dart + final Map iplrSupportedGLSLOpShaders = await _loadShaderAssets( + path.join('supported_glsl_op_shaders', 'iplr'), + '.iplr', + ); + _expectFragmentShadersRenderGreen(iplrSupportedGLSLOpShaders); + + // Test all supported instructions. See lib/spirv/lib/src/constants.dart + final Map iplrSupportedOpShaders = await _loadShaderAssets( + path.join('supported_op_shaders', 'iplr'), + '.iplr', + ); + _expectFragmentShadersRenderGreen(iplrSupportedOpShaders); } +} - // Test all supported GLSL ops. See lib/spirv/lib/src/constants.dart - final Map iplrSupportedGLSLOpShaders = await _loadShaderAssets( - path.join('supported_glsl_op_shaders', 'iplr'), - '.iplr', - ); - _expectFragmentShadersRenderGreen(iplrSupportedGLSLOpShaders); +//////////////////////////////////////////////////////////////////////////////// +// Helper Functions //////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// - // Test all supported instructions. See lib/spirv/lib/src/constants.dart - final Map iplrSupportedOpShaders = await _loadShaderAssets( - path.join('supported_op_shaders', 'iplr'), - '.iplr', - ); - _expectFragmentShadersRenderGreen(iplrSupportedOpShaders); +void _runSkiaTest(String name, Future Function() callback) { + test(name, () async { + if (impellerEnabled) { + print('skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } + await callback(); + }); +} + +void _runImpellerTest(String name, Future Function() callback) { + test(name, () async { + if (!impellerEnabled) { + print('skipped for Skia'); + return; + } + await callback(); + }); } // Expect that all of the shaders in this folder render green.