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

Add debugDisposed to Image (#21547)

上级 0b26570e
......@@ -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.
///
/// The [format] argument specifies the format in which the bytes will be
......
......@@ -54,12 +54,21 @@ class CkAnimatedImage implements ui.Image {
}
}
bool _disposed = false;
@override
void dispose() {
box.delete();
_disposed = true;
}
@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);
@override
......@@ -138,9 +147,22 @@ class CkImage implements ui.Image {
}
}
bool _disposed = false;
@override
void dispose() {
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
......
......@@ -116,11 +116,24 @@ class HtmlImage implements ui.Image {
bool _requiresClone = false;
HtmlImage(this.imgElement, this.width, this.height);
bool _disposed = false;
@override
void dispose() {
// Do nothing. The codec that owns this image should take care of
// 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
ui.Image clone() => this;
......
......@@ -329,6 +329,7 @@ abstract class Image {
int get height;
Future<ByteData?> toByteData({ImageByteFormat format = ImageByteFormat.rawRgba});
void dispose();
bool get debugDisposed;
Image clone() => this;
......
......@@ -32,10 +32,13 @@ void testMain() {
final SkAnimatedImage skAnimatedImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage);
final CkAnimatedImage image = CkAnimatedImage(skAnimatedImage);
expect(image.box.isDeleted, false);
expect(image.debugDisposed, false);
image.dispose();
expect(image.box.isDeleted, true);
expect(image.debugDisposed, true);
image.dispose();
expect(image.box.isDeleted, true);
expect(image.debugDisposed, true);
});
test('CkAnimatedImage can be cloned and explicitly disposed of', () async {
......@@ -69,10 +72,13 @@ void testMain() {
test('CkImage can be explicitly disposed of', () {
final SkImage skImage = canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage).getCurrentFrame();
final CkImage image = CkImage(skImage);
expect(image.debugDisposed, false);
expect(image.box.isDeleted, false);
image.dispose();
expect(image.debugDisposed, true);
expect(image.box.isDeleted, true);
image.dispose();
expect(image.debugDisposed, true);
expect(image.box.isDeleted, true);
});
......
......@@ -63,6 +63,14 @@ void testMain() async {
expect(frameInfo.image.width, 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 {
StringBuffer buffer = new StringBuffer();
final HtmlCodec codec = HtmlCodec('sample_image1.png',
......
......@@ -723,6 +723,9 @@ class TestImage implements Image {
@override
void dispose() {}
@override
bool get debugDisposed => false;
@override
Image clone() => this;
......
......@@ -126,6 +126,25 @@ void main() {
expect(frame2.image.clone()..dispose(), isNotNull);
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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册