Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ca27c58

Browse files
committed
make CkAnimatedImage a Codec
1 parent f772e7d commit ca27c58

File tree

2 files changed

+22
-55
lines changed

2 files changed

+22
-55
lines changed

lib/web_ui/lib/src/engine/canvaskit/image.dart

Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ part of engine;
88
/// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia.
99
void skiaInstantiateImageCodec(Uint8List list, Callback<ui.Codec> callback,
1010
[int? width, int? height, int? format, int? rowBytes]) {
11-
final SkAnimatedImage skAnimatedImage =
12-
canvasKit.MakeAnimatedImageFromEncoded(list);
13-
final CkAnimatedImage animatedImage = CkAnimatedImage(skAnimatedImage);
14-
final CkAnimatedImageCodec codec = CkAnimatedImageCodec(animatedImage);
11+
final CkAnimatedImage codec = CkAnimatedImage.decodeFromBytes(list);
1512
callback(codec);
1613
}
1714

@@ -33,27 +30,25 @@ Future<ui.Codec> skiaInstantiateWebImageCodec(
3330
}
3431
final Uint8List list =
3532
new Uint8List.view((response.response as ByteBuffer));
36-
final SkAnimatedImage skAnimatedImage =
37-
canvasKit.MakeAnimatedImageFromEncoded(list);
38-
final CkAnimatedImage animatedImage = CkAnimatedImage(skAnimatedImage);
39-
final CkAnimatedImageCodec codec = CkAnimatedImageCodec(animatedImage);
33+
final CkAnimatedImage codec = CkAnimatedImage.decodeFromBytes(list);
4034
completer.complete(codec);
4135
}, onError: (dynamic error) {
4236
completer.completeError(error);
4337
});
4438
return completer.future;
4539
}
4640

47-
/// A wrapper for `SkAnimatedImage`.
48-
class CkAnimatedImage implements StackTraceDebugger {
49-
/// Wraps an existing [SkAnimatedImage] and takes ownership of it.
50-
///
51-
/// Do not store references to [skAnimatedImage] outside this class due to
52-
/// the risk of use-after-free bugs.
53-
CkAnimatedImage(SkAnimatedImage skAnimatedImage) {
41+
/// The CanvasKit implementation of [ui.Codec].
42+
///
43+
/// Wraps `SkAnimatedImage`.
44+
class CkAnimatedImage implements ui.Codec, StackTraceDebugger {
45+
/// Decodes an image from a list of encoded bytes.
46+
CkAnimatedImage.decodeFromBytes(Uint8List bytes) {
5447
if (assertionsEnabled) {
5548
_debugStackTrace = StackTrace.current;
5649
}
50+
final SkAnimatedImage skAnimatedImage =
51+
canvasKit.MakeAnimatedImageFromEncoded(bytes);
5752
box = SkiaObjectBox<CkAnimatedImage, SkAnimatedImage>(this, skAnimatedImage);
5853
}
5954

@@ -73,6 +68,7 @@ class CkAnimatedImage implements StackTraceDebugger {
7368
return true;
7469
}
7570

71+
@override
7672
void dispose() {
7773
if (_disposed) {
7874
// This method is idempotent.
@@ -84,26 +80,25 @@ class CkAnimatedImage implements StackTraceDebugger {
8480
box.unref(this);
8581
}
8682

83+
@override
8784
int get frameCount {
8885
assert(_debugCheckIsNotDisposed());
8986
return box.skiaObject.getFrameCount();
9087
}
9188

92-
/// Decodes the next frame and returns the frame duration.
93-
Duration decodeNextFrame() {
94-
assert(_debugCheckIsNotDisposed());
95-
final int durationMillis = box.skiaObject.decodeNextFrame();
96-
return Duration(milliseconds: durationMillis);
97-
}
98-
89+
@override
9990
int get repetitionCount {
10091
assert(_debugCheckIsNotDisposed());
10192
return box.skiaObject.getRepetitionCount();
10293
}
10394

104-
CkImage get currentFrameAsImage {
95+
@override
96+
Future<ui.FrameInfo> getNextFrame() {
10597
assert(_debugCheckIsNotDisposed());
106-
return CkImage(box.skiaObject.getCurrentFrame());
98+
final int durationMillis = box.skiaObject.decodeNextFrame();
99+
final Duration duration = Duration(milliseconds: durationMillis);
100+
final CkImage image = CkImage(box.skiaObject.getCurrentFrame());
101+
return Future<ui.FrameInfo>.value(AnimatedImageFrameInfo(duration, image));
107102
}
108103
}
109104

@@ -223,31 +218,6 @@ class CkImage implements ui.Image, StackTraceDebugger {
223218
}
224219
}
225220

226-
/// A [Codec] that wraps an `SkAnimatedImage`.
227-
class CkAnimatedImageCodec implements ui.Codec {
228-
CkAnimatedImage animatedImage;
229-
230-
CkAnimatedImageCodec(this.animatedImage);
231-
232-
@override
233-
void dispose() {
234-
animatedImage.dispose();
235-
}
236-
237-
@override
238-
int get frameCount => animatedImage.frameCount;
239-
240-
@override
241-
int get repetitionCount => animatedImage.repetitionCount;
242-
243-
@override
244-
Future<ui.FrameInfo> getNextFrame() {
245-
final Duration duration = animatedImage.decodeNextFrame();
246-
final CkImage image = animatedImage.currentFrameAsImage;
247-
return Future<ui.FrameInfo>.value(AnimatedImageFrameInfo(duration, image));
248-
}
249-
}
250-
251221
/// Data for a single frame of an animated image.
252222
class AnimatedImageFrameInfo implements ui.FrameInfo {
253223
final Duration _duration;

lib/web_ui/test/canvaskit/image_test.dart

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ void testMain() {
2424
});
2525

2626
test('CkAnimatedImage can be explicitly disposed of', () {
27-
final SkAnimatedImage skAnimatedImage =
28-
canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage);
29-
final CkAnimatedImage image = CkAnimatedImage(skAnimatedImage);
27+
final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kTransparentImage);
3028
expect(image.box.isDeleted, false);
3129
expect(image.debugDisposed, false);
3230
image.dispose();
@@ -38,9 +36,8 @@ void testMain() {
3836
});
3937

4038
test('CkAnimatedImage can be cloned and explicitly disposed of', () async {
41-
final SkAnimatedImage skAnimatedImage =
42-
canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage);
43-
final CkAnimatedImage image = CkAnimatedImage(skAnimatedImage);
39+
final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kTransparentImage);
40+
final SkAnimatedImage skAnimatedImage = image.box.skiaObject;
4441
final SkiaObjectBox<CkAnimatedImage, SkAnimatedImage> box = image.box;
4542
expect(box.refCount, 1);
4643
expect(box.debugGetStackTraces().length, 1);

0 commit comments

Comments
 (0)