未验证 提交 b9520248 编写于 作者: D Dan Field 提交者: GitHub

Add debugDisposed to Image (#21547)

上级 0b26570e
...@@ -1632,6 +1632,19 @@ class Image { ...@@ -1632,6 +1632,19 @@ class Image {
} }
} }
/// Whether this reference to the underlying image is [dispose]d.
///
/// This only returns a valid value if asserts are enabled, and must not be
/// used otherwise.
bool get debugDisposed {
bool? disposed;
assert(() {
disposed = _disposed;
return true;
}());
return disposed ?? (throw StateError('Image.debugDisposed is only available when asserts are enabled.'));
}
/// Converts the [Image] object into a byte array. /// Converts the [Image] object into a byte array.
/// ///
/// The [format] argument specifies the format in which the bytes will be /// The [format] argument specifies the format in which the bytes will be
......
...@@ -54,12 +54,21 @@ class CkAnimatedImage implements ui.Image { ...@@ -54,12 +54,21 @@ class CkAnimatedImage implements ui.Image {
} }
} }
bool _disposed = false;
@override @override
void dispose() { void dispose() {
box.delete(); box.delete();
_disposed = true;
} }
@override @override
bool get debugDisposed {
if (assertionsEnabled) {
return _disposed;
}
throw StateError('Image.debugDisposed is only available when asserts are enabled.');
}
ui.Image clone() => CkAnimatedImage._(_skAnimatedImage, box); ui.Image clone() => CkAnimatedImage._(_skAnimatedImage, box);
@override @override
...@@ -138,9 +147,22 @@ class CkImage implements ui.Image { ...@@ -138,9 +147,22 @@ class CkImage implements ui.Image {
} }
} }
bool _disposed = false;
@override @override
void dispose() { void dispose() {
box.delete(); box.delete();
assert(() {
_disposed = true;
return true;
}());
}
@override
bool get debugDisposed {
if (assertionsEnabled) {
return _disposed;
}
throw StateError('Image.debugDisposed is only available when asserts are enabled.');
} }
@override @override
......
...@@ -116,12 +116,25 @@ class HtmlImage implements ui.Image { ...@@ -116,12 +116,25 @@ class HtmlImage implements ui.Image {
bool _requiresClone = false; bool _requiresClone = false;
HtmlImage(this.imgElement, this.width, this.height); HtmlImage(this.imgElement, this.width, this.height);
bool _disposed = false;
@override @override
void dispose() { void dispose() {
// Do nothing. The codec that owns this image should take care of // Do nothing. The codec that owns this image should take care of
// releasing the object url. // releasing the object url.
if (assertionsEnabled) {
_disposed = true;
}
}
@override
bool get debugDisposed {
if (assertionsEnabled) {
return _disposed;
}
return throw StateError('Image.debugDisposed is only available when asserts are enabled.');
} }
@override @override
ui.Image clone() => this; ui.Image clone() => this;
......
...@@ -329,6 +329,7 @@ abstract class Image { ...@@ -329,6 +329,7 @@ abstract class Image {
int get height; int get height;
Future<ByteData?> toByteData({ImageByteFormat format = ImageByteFormat.rawRgba}); Future<ByteData?> toByteData({ImageByteFormat format = ImageByteFormat.rawRgba});
void dispose(); void dispose();
bool get debugDisposed;
Image clone() => this; Image clone() => this;
......
...@@ -32,10 +32,13 @@ void testMain() { ...@@ -32,10 +32,13 @@ void testMain() {
final SkAnimatedImage skAnimatedImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage); final SkAnimatedImage skAnimatedImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage);
final CkAnimatedImage image = CkAnimatedImage(skAnimatedImage); final CkAnimatedImage image = CkAnimatedImage(skAnimatedImage);
expect(image.box.isDeleted, false); expect(image.box.isDeleted, false);
expect(image.debugDisposed, false);
image.dispose(); image.dispose();
expect(image.box.isDeleted, true); expect(image.box.isDeleted, true);
expect(image.debugDisposed, true);
image.dispose(); image.dispose();
expect(image.box.isDeleted, true); expect(image.box.isDeleted, true);
expect(image.debugDisposed, true);
}); });
test('CkAnimatedImage can be cloned and explicitly disposed of', () async { test('CkAnimatedImage can be cloned and explicitly disposed of', () async {
...@@ -69,10 +72,13 @@ void testMain() { ...@@ -69,10 +72,13 @@ void testMain() {
test('CkImage can be explicitly disposed of', () { test('CkImage can be explicitly disposed of', () {
final SkImage skImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage).getCurrentFrame(); final SkImage skImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage).getCurrentFrame();
final CkImage image = CkImage(skImage); final CkImage image = CkImage(skImage);
expect(image.debugDisposed, false);
expect(image.box.isDeleted, false); expect(image.box.isDeleted, false);
image.dispose(); image.dispose();
expect(image.debugDisposed, true);
expect(image.box.isDeleted, true); expect(image.box.isDeleted, true);
image.dispose(); image.dispose();
expect(image.debugDisposed, true);
expect(image.box.isDeleted, true); expect(image.box.isDeleted, true);
}); });
......
...@@ -63,6 +63,14 @@ void testMain() async { ...@@ -63,6 +63,14 @@ void testMain() async {
expect(frameInfo.image.width, 100); expect(frameInfo.image.width, 100);
expect(frameInfo.image.toString(), '[100×100]'); expect(frameInfo.image.toString(), '[100×100]');
}); });
test('dispose image image', () async {
final HtmlCodec codec = HtmlCodec('sample_image1.png');
final ui.FrameInfo frameInfo = await codec.getNextFrame();
expect(frameInfo.image, isNotNull);
expect(frameInfo.image.debugDisposed, false);
frameInfo.image.dispose();
expect(frameInfo.image.debugDisposed, true);
});
test('provides image loading progress', () async { test('provides image loading progress', () async {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
final HtmlCodec codec = HtmlCodec('sample_image1.png', final HtmlCodec codec = HtmlCodec('sample_image1.png',
......
...@@ -723,6 +723,9 @@ class TestImage implements Image { ...@@ -723,6 +723,9 @@ class TestImage implements Image {
@override @override
void dispose() {} void dispose() {}
@override
bool get debugDisposed => false;
@override @override
Image clone() => this; Image clone() => this;
......
...@@ -126,6 +126,25 @@ void main() { ...@@ -126,6 +126,25 @@ void main() {
expect(frame2.image.clone()..dispose(), isNotNull); expect(frame2.image.clone()..dispose(), isNotNull);
frame2.image.dispose(); frame2.image.dispose();
}); });
test('debugDisposed works', () async {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
if (assertsEnabled) {
expect(frame.image.debugDisposed, false);
} else {
expect(() => frame.image.debugDisposed, throwsStateError);
}
frame.image.dispose();
if (assertsEnabled) {
expect(frame.image.debugDisposed, true);
} else {
expect(() => frame.image.debugDisposed, throwsStateError);
}
});
} }
Future<Uint8List> readFile(String fileName) async { Future<Uint8List> readFile(String fileName) async {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册