fix: Call codec.dispose in tests of engine/src/flutter (#161115)

PR derived from https://github.com/flutter/flutter/pull/159945.

Added `codec.dispose()` for directories under `engine/src/flutter`.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Koji Wakamiya 2025-01-24 00:13:57 +09:00 committed by GitHub
parent d59995bac3
commit 2919003513
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 54 additions and 11 deletions

View File

@ -14,8 +14,6 @@ import 'package:ui/ui.dart' as ui;
import 'common.dart';
import 'test_data.dart';
List<TestCodec>? testCodecs;
void main() {
internalBootstrapBrowserTest(() => testMain);
}
@ -29,6 +27,11 @@ abstract class TestCodec {
Future<ui.Codec> getCodec() async => _cachedCodec ??= await createCodec();
Future<ui.Codec> createCodec();
void dispose() {
_cachedCodec?.dispose();
_cachedCodec = null;
}
}
abstract class TestFileCodec extends TestCodec {
@ -134,13 +137,10 @@ class BitmapSingleFrameCodec implements ui.Codec {
}
Future<void> testMain() async {
Future<List<TestCodec>> createTestCodecs({
int testTargetWidth = 300,
int testTargetHeight = 300,
}) async {
final HttpFetchResponse listingResponse = await httpFetch('/test_images/');
final List<String> testFiles = (await listingResponse.json() as List<dynamic>).cast<String>();
final HttpFetchResponse listingResponse = await httpFetch('/test_images/');
final List<String> testFiles = (await listingResponse.json() as List<dynamic>).cast<String>();
List<TestCodec> createTestCodecs({int testTargetWidth = 300, int testTargetHeight = 300}) {
// Sanity-check the test file list. If suddenly test files are moved or
// deleted, and the test server returns an empty list, or is missing some
// important test files, we want to know.
@ -192,8 +192,6 @@ Future<void> testMain() async {
return testCodecs;
}
testCodecs = await createTestCodecs();
group('CanvasKit Images', () {
setUpCanvasKitTest(withImplicitView: true);
@ -202,7 +200,8 @@ Future<void> testMain() async {
});
group('Codecs', () {
for (final TestCodec testCodec in testCodecs!) {
final List<TestCodec> testCodecs = createTestCodecs();
for (final TestCodec testCodec in testCodecs) {
test('${testCodec.description} can create an image', () async {
try {
final ui.Codec codec = await testCodec.getCodec();
@ -247,6 +246,9 @@ Future<void> testMain() async {
);
});
}
for (final testCodec in testCodecs) {
testCodec.dispose();
}
});
test('crossOrigin requests cause an error', () async {

View File

@ -39,6 +39,7 @@ Future<void> testMain() async {
final Uint8List imageData = base64Decode(base64PngData);
final Codec codec = await instantiateImageCodec(imageData);
final FrameInfo frameInfo = await codec.getNextFrame();
codec.dispose();
const Rect bounds = Rect.fromLTRB(0, 0, 400, 300);
final EnginePictureRecorder recorder = EnginePictureRecorder();

View File

@ -30,6 +30,7 @@ Future<void> testMain() async {
expect(codec.frameCount, 1);
final ui.FrameInfo info = await codec.getNextFrame();
codec.dispose();
final ui.Image image = info.image;
expect(image.width, 128);
expect(image.height, 128);

View File

@ -381,6 +381,7 @@ Future<void> testMain() async {
expect(codec.frameCount, 1);
final ui.FrameInfo info = await codec.getNextFrame();
codec.dispose();
return info.image;
});
@ -393,6 +394,7 @@ Future<void> testMain() async {
expect(codec.frameCount, 1);
final ui.FrameInfo info = await codec.getNextFrame();
codec.dispose();
expect(info.image.width, 3024);
expect(info.image.height, 4032);
});
@ -424,6 +426,7 @@ Future<void> testMain() async {
await completer.future;
final DomImageBitmap bitmap = await createImageBitmap(image as JSObject);
domWindow.URL.revokeObjectURL(url);
expect(bitmap.width.toDartInt, 150);
expect(bitmap.height.toDartInt, 150);
@ -471,6 +474,7 @@ Future<void> testMain() async {
height: 150,
transferOwnership: false,
);
domWindow.URL.revokeObjectURL(url);
return uiImage;
});
}
@ -485,6 +489,7 @@ Future<void> testMain() async {
expect(codec.frameCount, 1);
final ui.FrameInfo info = await codec.getNextFrame();
codec.dispose();
return info.image;
});
}

View File

@ -49,6 +49,8 @@ void main() {
} else {
expect(e.toString(), contains('Codec failed'));
}
} finally {
codec.dispose();
}
});
@ -64,6 +66,7 @@ void main() {
frameInfo.image.height,
]);
}
codec.dispose();
expect(
decodedFrameInfos,
equals(<List<int>>[
@ -88,6 +91,7 @@ void main() {
frameInfo.image.height,
]);
}
codec.dispose();
expect(
decodedFrameInfos,
equals(<List<int>>[
@ -115,6 +119,7 @@ void main() {
frameInfo.image.height,
]);
}
codec.dispose();
expect(
decodedFrameInfos,
equals(<List<int>>[
@ -136,6 +141,7 @@ void main() {
} on Exception catch (e) {
expect(e.toString(), contains('Decoded image has been disposed'));
}
codec.dispose();
});
test('Animated gif can reuse across multiple frames', () async {
@ -153,6 +159,7 @@ void main() {
for (int i = 0; i < 4; i++) {
frameInfo = await codec.getNextFrame();
}
codec.dispose();
final ui.Image image = frameInfo.image;
final ByteData imageData = (await image.toByteData(format: ui.ImageByteFormat.png))!;
@ -180,6 +187,7 @@ void main() {
for (int i = 0; i < 69; i++) {
frameInfo = await codec.getNextFrame();
}
codec.dispose();
final ui.Image image = frameInfo.image;
final ByteData imageData = (await image.toByteData(format: ui.ImageByteFormat.png))!;
@ -220,6 +228,7 @@ void main() {
expect(imageData.buffer.asUint8List(), goldenData);
}
}
codec.dispose();
});
test('Animated apng alpha type handling', () async {
@ -237,6 +246,7 @@ void main() {
image = (await codec.getNextFrame()).image;
imageData = (await image.toByteData())!;
expect(imageData.getUint32(0), 0x99000099);
codec.dispose();
});
test('Animated apng background color restore', () async {
@ -261,6 +271,7 @@ void main() {
image = (await codec.getNextFrame()).image;
imageData = (await image.toByteData())!;
expect(imageData.getUint32(imageData.lengthInBytes - 4), 0x00000000);
codec.dispose();
});
test('Animated apng frame decode does not crash with invalid destination region', () async {
@ -277,6 +288,8 @@ void main() {
} else {
expect(e.toString(), contains('Codec failed'));
}
} finally {
codec.dispose();
}
});
@ -298,6 +311,8 @@ void main() {
} else {
expect(e.toString(), contains('Codec failed'));
}
} finally {
codec.dispose();
}
},
);

View File

@ -544,6 +544,7 @@ Future<Image> _createBlueGreenImage() async {
);
final Codec codec = await descriptor.instantiateCodec();
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
return frame.image;
}

View File

@ -22,6 +22,7 @@ void main() {
final Codec codec = await descriptor.instantiateCodec();
expect(codec.frameCount, 1);
codec.dispose();
});
test('basic image descriptor - encoded - square', () async {
@ -35,6 +36,7 @@ void main() {
final Codec codec = await descriptor.instantiateCodec();
expect(codec.frameCount, 1);
codec.dispose();
});
test('basic image descriptor - encoded - animated', () async {
@ -49,6 +51,7 @@ void main() {
final Codec codec = await descriptor.instantiateCodec();
expect(codec.frameCount, 4);
expect(codec.repetitionCount, -1);
codec.dispose();
});
test('basic image descriptor - raw', () async {
@ -68,6 +71,7 @@ void main() {
final Codec codec = await descriptor.instantiateCodec();
expect(codec.frameCount, 1);
codec.dispose();
});
test('HEIC image', () async {
@ -81,6 +85,7 @@ void main() {
final Codec codec = await descriptor.instantiateCodec();
expect(codec.frameCount, 1);
codec.dispose();
}, skip: !(Platform.isAndroid || Platform.isIOS || Platform.isMacOS || Platform.isWindows));
}

View File

@ -14,6 +14,7 @@ void main() {
final Uint8List bytes = await _readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
expect(frame.image.width, 2);
expect(frame.image.height, 2);
@ -33,6 +34,7 @@ void main() {
final Uint8List bytes = await _readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
expect(frame.image.width, 2);
expect(frame.image.height, 2);
@ -71,6 +73,7 @@ void main() {
final Uint8List bytes = await _readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final Image handle1 = frame.image.clone();
final Image handle2 = handle1.clone();
@ -97,6 +100,7 @@ void main() {
final Uint8List bytes = await _readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final Image handle1 = frame.image.clone();
final Image handle2 = handle1.clone();
@ -112,6 +116,7 @@ void main() {
final Codec codec2 = await instantiateImageCodec(bytes);
final FrameInfo frame2 = await codec2.getNextFrame();
codec2.dispose();
expect(frame2.image.isCloneOf(frame.image), false);
});
@ -120,6 +125,7 @@ void main() {
final Uint8List bytes = await _readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
expect(frame.image.debugDisposed, false);

View File

@ -15,6 +15,7 @@ void main() {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final int codecHeight = frame.image.height;
final int codecWidth = frame.image.width;
expect(codecHeight, 2);
@ -25,6 +26,7 @@ void main() {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes, targetHeight: 1);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final int codecHeight = frame.image.height;
final int codecWidth = frame.image.width;
expect(codecHeight, 1);
@ -35,6 +37,7 @@ void main() {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes, targetWidth: 1);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final int codecHeight = frame.image.height;
final int codecWidth = frame.image.width;
expect(codecHeight, 1);
@ -45,6 +48,7 @@ void main() {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes, targetWidth: 10);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final int codecHeight = frame.image.height;
final int codecWidth = frame.image.width;
expect(codecHeight, 10);
@ -55,6 +59,7 @@ void main() {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes, targetWidth: 10, allowUpscaling: false);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final int codecHeight = frame.image.height;
final int codecWidth = frame.image.width;
expect(codecHeight, 2);
@ -65,6 +70,7 @@ void main() {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes, targetWidth: 10, targetHeight: 1);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final int codecHeight = frame.image.height;
final int codecWidth = frame.image.width;
expect(codecHeight, 1);
@ -80,6 +86,7 @@ void main() {
allowUpscaling: false,
);
final FrameInfo frame = await codec.getNextFrame();
codec.dispose();
final int codecHeight = frame.image.height;
final int codecWidth = frame.image.width;
expect(codecHeight, 1);