Unverified Commit 1cd677c1 authored by Seven's avatar Seven Committed by GitHub

Fix single frame image is decoded even cached (#82533)

* Fix single frame image is decoded even cached

* Add MultiFrameImageStreamCompleter decode test for one frame image
parent 46cdf890
......@@ -974,7 +974,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
@override
void addListener(ImageStreamListener listener) {
if (!hasListeners && _codec != null)
if (!hasListeners && _codec != null && (_currentImage == null || _codec!.frameCount > 1))
_decodeNextFrameAndSchedule();
super.addListener(listener);
}
......
......@@ -19,6 +19,7 @@ class FakeCodec implements ui.Codec {
final int _repetitionCount;
final List<ui.FrameInfo> _frameInfos;
int _nextFrame = 0;
int _numFramesAsked = 0;
/// Creates a FakeCodec from encoded image data.
///
......@@ -38,8 +39,11 @@ class FakeCodec implements ui.Codec {
@override
int get repetitionCount => _repetitionCount;
int get numFramesAsked => _numFramesAsked;
@override
Future<ui.FrameInfo> getNextFrame() {
_numFramesAsked += 1;
final SynchronousFuture<ui.FrameInfo> result =
SynchronousFuture<ui.FrameInfo>(_frameInfos[_nextFrame]);
_nextFrame = (_nextFrame + 1) % _frameCount;
......
......@@ -3,12 +3,16 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/painting.dart';
import 'package:flutter/scheduler.dart' show timeDilation, SchedulerBinding;
import 'package:flutter_test/flutter_test.dart';
import '../image_data.dart';
import 'fake_codec.dart';
class FakeFrameInfo implements FrameInfo {
const FakeFrameInfo(this._duration, this._image);
......@@ -780,6 +784,32 @@ void main() {
handle.dispose();
});
test('MultiFrameImageStreamCompleter - one frame image should only be decoded once', () async {
final FakeCodec oneFrameCodec = await FakeCodec.fromData(Uint8List.fromList(kTransparentImage));
final Completer<Codec> codecCompleter = Completer<Codec>();
final Completer<void> decodeCompleter = Completer<void>();
final ImageStreamCompleter imageStream = MultiFrameImageStreamCompleter(
codec: codecCompleter.future,
scale: 1.0,
);
final ImageStreamListener imageListener = ImageStreamListener((ImageInfo info, bool syncCall) {
decodeCompleter.complete();
});
imageStream.keepAlive(); // do not dispose
imageStream.addListener(imageListener);
codecCompleter.complete(oneFrameCodec);
await decodeCompleter.future;
imageStream.removeListener(imageListener);
expect(oneFrameCodec.numFramesAsked, 1);
// Adding a new listener for decoded imageSteam, the one frame image should
// not be decoded again.
imageStream.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {}));
expect(oneFrameCodec.numFramesAsked, 1);
}); // https://github.com/flutter/flutter/issues/82532
// TODO(amirh): enable this once WidgetTester supports flushTimers.
// https://github.com/flutter/flutter/issues/30344
// testWidgets('remove and add listener before a delayed frame is scheduled', (WidgetTester tester) async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment