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 { ...@@ -974,7 +974,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
@override @override
void addListener(ImageStreamListener listener) { void addListener(ImageStreamListener listener) {
if (!hasListeners && _codec != null) if (!hasListeners && _codec != null && (_currentImage == null || _codec!.frameCount > 1))
_decodeNextFrameAndSchedule(); _decodeNextFrameAndSchedule();
super.addListener(listener); super.addListener(listener);
} }
......
...@@ -19,6 +19,7 @@ class FakeCodec implements ui.Codec { ...@@ -19,6 +19,7 @@ class FakeCodec implements ui.Codec {
final int _repetitionCount; final int _repetitionCount;
final List<ui.FrameInfo> _frameInfos; final List<ui.FrameInfo> _frameInfos;
int _nextFrame = 0; int _nextFrame = 0;
int _numFramesAsked = 0;
/// Creates a FakeCodec from encoded image data. /// Creates a FakeCodec from encoded image data.
/// ///
...@@ -38,8 +39,11 @@ class FakeCodec implements ui.Codec { ...@@ -38,8 +39,11 @@ class FakeCodec implements ui.Codec {
@override @override
int get repetitionCount => _repetitionCount; int get repetitionCount => _repetitionCount;
int get numFramesAsked => _numFramesAsked;
@override @override
Future<ui.FrameInfo> getNextFrame() { Future<ui.FrameInfo> getNextFrame() {
_numFramesAsked += 1;
final SynchronousFuture<ui.FrameInfo> result = final SynchronousFuture<ui.FrameInfo> result =
SynchronousFuture<ui.FrameInfo>(_frameInfos[_nextFrame]); SynchronousFuture<ui.FrameInfo>(_frameInfos[_nextFrame]);
_nextFrame = (_nextFrame + 1) % _frameCount; _nextFrame = (_nextFrame + 1) % _frameCount;
......
...@@ -3,12 +3,16 @@ ...@@ -3,12 +3,16 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter/scheduler.dart' show timeDilation, SchedulerBinding; import 'package:flutter/scheduler.dart' show timeDilation, SchedulerBinding;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../image_data.dart';
import 'fake_codec.dart';
class FakeFrameInfo implements FrameInfo { class FakeFrameInfo implements FrameInfo {
const FakeFrameInfo(this._duration, this._image); const FakeFrameInfo(this._duration, this._image);
...@@ -780,6 +784,32 @@ void main() { ...@@ -780,6 +784,32 @@ void main() {
handle.dispose(); 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. // TODO(amirh): enable this once WidgetTester supports flushTimers.
// https://github.com/flutter/flutter/issues/30344 // https://github.com/flutter/flutter/issues/30344
// testWidgets('remove and add listener before a delayed frame is scheduled', (WidgetTester tester) async { // 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