| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:typed_data'; |
| |
| import 'package:test/bootstrap/browser.dart'; |
| import 'package:test/test.dart'; |
| import 'package:ui/src/engine.dart'; |
| import 'package:ui/ui.dart' as ui; |
| |
| import 'common.dart'; |
| import 'test_data.dart'; |
| |
| void main() { |
| internalBootstrapBrowserTest(() => testMain); |
| } |
| |
| void testMain() { |
| group('CanvasKit shaders', () { |
| setUpCanvasKitTest(); |
| |
| test('Sweep gradient', () { |
| final CkGradientSweep gradient = ui.Gradient.sweep( |
| ui.Offset.zero, |
| testColors, |
| ) as CkGradientSweep; |
| expect(gradient.getSkShader(ui.FilterQuality.none), isNotNull); |
| }); |
| |
| test('Linear gradient', () { |
| final CkGradientLinear gradient = ui.Gradient.linear( |
| ui.Offset.zero, |
| const ui.Offset(0, 1), |
| testColors, |
| ) as CkGradientLinear; |
| expect(gradient.getSkShader(ui.FilterQuality.none), isNotNull); |
| }); |
| |
| test('Radial gradient', () { |
| final CkGradientRadial gradient = ui.Gradient.radial( |
| ui.Offset.zero, |
| 10, |
| testColors, |
| ) as CkGradientRadial; |
| expect(gradient.getSkShader(ui.FilterQuality.none), isNotNull); |
| }); |
| |
| test('Conical gradient', () { |
| final CkGradientConical gradient = ui.Gradient.radial( |
| ui.Offset.zero, |
| 10, |
| testColors, |
| null, |
| ui.TileMode.clamp, |
| null, |
| const ui.Offset(10, 10), |
| 40, |
| ) as CkGradientConical; |
| expect(gradient.getSkShader(ui.FilterQuality.none), isNotNull); |
| }); |
| |
| test('Image shader initialize/dispose cycle', () { |
| final SkImage skImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!.makeImageAtCurrentFrame(); |
| final CkImage image = CkImage(skImage); |
| final CkImageShader imageShader = ui.ImageShader( |
| image, |
| ui.TileMode.clamp, |
| ui.TileMode.repeated, |
| Float64List.fromList(Matrix4.diagonal3Values(1, 2, 3).storage), |
| ) as CkImageShader; |
| expect(imageShader, isA<CkImageShader>()); |
| |
| final UniqueRef<SkShader> ref = imageShader.ref!; |
| expect(imageShader.debugDisposed, false); |
| expect(imageShader.getSkShader(ui.FilterQuality.none), same(ref.nativeObject)); |
| expect(ref.isDisposed, false); |
| expect(image.debugDisposed, false); |
| imageShader.dispose(); |
| expect(imageShader.debugDisposed, true); |
| expect(ref.isDisposed, true); |
| expect(imageShader.ref, isNull); |
| expect(image.debugDisposed, true); |
| }); |
| |
| test('Image shader withQuality', () { |
| final SkImage skImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!.makeImageAtCurrentFrame(); |
| final CkImage image = CkImage(skImage); |
| final CkImageShader imageShader = ui.ImageShader( |
| image, |
| ui.TileMode.clamp, |
| ui.TileMode.repeated, |
| Float64List.fromList(Matrix4.diagonal3Values(1, 2, 3).storage), |
| ) as CkImageShader; |
| expect(imageShader, isA<CkImageShader>()); |
| |
| final UniqueRef<SkShader> ref1 = imageShader.ref!; |
| expect(imageShader.getSkShader(ui.FilterQuality.none), same(ref1.nativeObject)); |
| |
| // Request the same quality as the default quality (none). |
| expect(imageShader.getSkShader(ui.FilterQuality.none), isNotNull); |
| final UniqueRef<SkShader> ref2 = imageShader.ref!; |
| expect(ref1, same(ref2)); |
| expect(ref1.isDisposed, false); |
| expect(image.debugDisposed, false); |
| |
| // Change quality to medium. |
| expect(imageShader.getSkShader(ui.FilterQuality.medium), isNotNull); |
| final UniqueRef<SkShader> ref3 = imageShader.ref!; |
| expect(ref1, isNot(same(ref3))); |
| expect(ref1.isDisposed, true, reason: 'The previous reference must be released to avoid a memory leak'); |
| expect(image.debugDisposed, false); |
| expect(imageShader.ref!.nativeObject, same(ref3.nativeObject)); |
| |
| // Ask for medium again. |
| expect(imageShader.getSkShader(ui.FilterQuality.medium), isNotNull); |
| final UniqueRef<SkShader> ref4 = imageShader.ref!; |
| expect(ref4, same(ref3)); |
| expect(ref3.isDisposed, false); |
| expect(image.debugDisposed, false); |
| expect(imageShader.ref!.nativeObject, same(ref4.nativeObject)); |
| |
| // Done with the shader. |
| imageShader.dispose(); |
| expect(imageShader.debugDisposed, true); |
| expect(ref4.isDisposed, true); |
| expect(imageShader.ref, isNull); |
| expect(image.debugDisposed, true); |
| }); |
| }); |
| } |
| |
| const List<ui.Color> testColors = <ui.Color>[ui.Color(0xFFFFFF00), ui.Color(0xFFFFFFFF)]; |