Skip to content

Commit

Permalink
Fix getNextFrame (flutter#21422)
Browse files Browse the repository at this point in the history
  • Loading branch information
dnfield committed Sep 26, 2020
1 parent f1961e5 commit 08cf725
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 18 deletions.
30 changes: 12 additions & 18 deletions lib/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1905,8 +1905,6 @@ class Codec extends NativeFieldWrapperClass2 {
int get repetitionCount => _cachedRepetitionCount ??= _repetitionCount;
int get _repetitionCount native 'Codec_repetitionCount';

FrameInfo? _cachedFrame;

/// Fetches the next animation frame.
///
/// Wraps back to the first frame after returning the last frame.
Expand All @@ -1916,24 +1914,20 @@ class Codec extends NativeFieldWrapperClass2 {
/// The caller of this method is responsible for disposing the
/// [FrameInfo.image] on the returned object.
Future<FrameInfo> getNextFrame() async {
if (_cachedFrame == null || frameCount != 1) {
final Completer<void> completer = Completer<void>.sync();
final String? error = _getNextFrame((_Image? image, int durationMilliseconds) {
if (image == null) {
throw Exception('Codec failed to produce an image, possibly due to invalid image data.');
}
_cachedFrame = FrameInfo._(
image: Image._(image),
duration: Duration(milliseconds: durationMilliseconds),
);
completer.complete();
});
if (error != null) {
throw Exception(error);
final Completer<FrameInfo> completer = Completer<FrameInfo>.sync();
final String? error = _getNextFrame((_Image? image, int durationMilliseconds) {
if (image == null) {
throw Exception('Codec failed to produce an image, possibly due to invalid image data.');
}
await completer.future;
completer.complete(FrameInfo._(
image: Image._(image),
duration: Duration(milliseconds: durationMilliseconds),
));
});
if (error != null) {
throw Exception(error);
}
return _cachedFrame!;
return await completer.future;
}

/// Returns an error message on failure, null on success.
Expand Down
12 changes: 12 additions & 0 deletions testing/dart/image_dispose_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ void main() {

expect(frame2.image.isCloneOf(frame.image), false);
});

test('getNextFrame does not return a disposed image', () async {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();

frame.image.dispose();

final FrameInfo frame2 = await codec.getNextFrame();
expect(frame2.image.clone()..dispose(), isNotNull);
frame2.image.dispose();
});
}

Future<Uint8List> readFile(String fileName) async {
Expand Down

0 comments on commit 08cf725

Please sign in to comment.