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
This commit is contained in:
parent
46cdf890b1
commit
1cd677c1b0
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user