未验证 提交 cdb5b2af 编写于 作者: Y Yegor 提交者: GitHub

Remove double-referencing from CkImage to SkImage (#22415)

上级 5419f70f
......@@ -46,22 +46,18 @@ Future<ui.Codec> skiaInstantiateWebImageCodec(
/// A wrapper for `SkAnimatedImage`.
class CkAnimatedImage implements ui.Image {
final SkAnimatedImage _skAnimatedImage;
// Use a box because `SkImage` may be deleted either due to this object
// being garbage-collected, or by an explicit call to [delete].
late final SkiaObjectBox box;
late final SkiaObjectBox<SkAnimatedImage> box;
CkAnimatedImage(SkAnimatedImage skAnimatedImage)
: this._(skAnimatedImage, null);
SkAnimatedImage get _skAnimatedImage => box.skObject;
CkAnimatedImage._(this._skAnimatedImage, SkiaObjectBox? boxToClone) {
if (boxToClone != null) {
assert(boxToClone.skObject == _skAnimatedImage);
box = boxToClone.clone(this);
} else {
box = SkiaObjectBox(this, _skAnimatedImage as SkDeletable);
}
CkAnimatedImage(SkAnimatedImage skAnimatedImage) {
box = SkiaObjectBox<SkAnimatedImage>(this, skAnimatedImage);
}
CkAnimatedImage.cloneOf(SkiaObjectBox<SkAnimatedImage> boxToClone) {
box = boxToClone.clone(this);
}
bool _disposed = false;
......@@ -80,7 +76,7 @@ class CkAnimatedImage implements ui.Image {
'Image.debugDisposed is only available when asserts are enabled.');
}
ui.Image clone() => CkAnimatedImage._(_skAnimatedImage, box);
ui.Image clone() => CkAnimatedImage.cloneOf(box);
@override
bool isCloneOf(ui.Image other) {
......@@ -143,21 +139,18 @@ class CkAnimatedImage implements ui.Image {
/// A [ui.Image] backed by an `SkImage` from Skia.
class CkImage implements ui.Image {
final SkImage skImage;
// Use a box because `SkImage` may be deleted either due to this object
// being garbage-collected, or by an explicit call to [delete].
late final SkiaObjectBox box;
late final SkiaObjectBox<SkImage> box;
CkImage(SkImage skImage) : this._(skImage, null);
SkImage get skImage => box.skObject;
CkImage._(this.skImage, SkiaObjectBox? boxToClone) {
if (boxToClone != null) {
assert(boxToClone.skObject == skImage);
box = boxToClone.clone(this);
} else {
box = SkiaObjectBox(this, skImage as SkDeletable);
}
CkImage(SkImage skImage) {
box = SkiaObjectBox<SkImage>(this, skImage);
}
CkImage.cloneOf(SkiaObjectBox<SkImage> boxToClone) {
box = boxToClone.clone(this);
}
bool _disposed = false;
......@@ -180,7 +173,7 @@ class CkImage implements ui.Image {
}
@override
ui.Image clone() => CkImage._(skImage, box);
ui.Image clone() => CkImage.cloneOf(box);
@override
bool isCloneOf(ui.Image other) {
......
......@@ -162,15 +162,15 @@ class CkGradientConical extends CkShader implements ui.Gradient {
class CkImageShader extends CkShader implements ui.ImageShader {
CkImageShader(
ui.Image image, this.tileModeX, this.tileModeY, this.matrix4)
: _skImage = image as CkImage;
: _image = image as CkImage;
final ui.TileMode tileModeX;
final ui.TileMode tileModeY;
final Float64List matrix4;
final CkImage _skImage;
final CkImage _image;
@override
SkShader createDefault() => _skImage.skImage.makeShader(
SkShader createDefault() => _image.skImage.makeShader(
toSkTileMode(tileModeX),
toSkTileMode(tileModeY),
toSkMatrixFromFloat64(matrix4),
......
......@@ -250,11 +250,11 @@ abstract class OneShotSkiaObject<T extends Object> extends SkiaObject<T> {
///
/// The [delete] method may be called any number of times. The box
/// will only delete the object once.
class SkiaObjectBox {
SkiaObjectBox(Object wrapper, SkDeletable skObject)
: this._(wrapper, skObject, <SkiaObjectBox>{});
class SkiaObjectBox<T> {
SkiaObjectBox(Object wrapper, T skObject)
: this._(wrapper, skObject, skObject as SkDeletable, <SkiaObjectBox>{});
SkiaObjectBox._(Object wrapper, this.skObject, this._refs) {
SkiaObjectBox._(Object wrapper, this.skObject, this._skDeletable, this._refs) {
if (assertionsEnabled) {
_debugStackTrace = StackTrace.current;
}
......@@ -280,7 +280,8 @@ class SkiaObjectBox {
}
/// The Skia object whose lifecycle is being managed.
final SkDeletable skObject;
final T skObject;
final SkDeletable _skDeletable;
/// Whether this object has been deleted.
bool get isDeleted => _isDeleted;
......@@ -295,10 +296,10 @@ class SkiaObjectBox {
/// Returns a clone of this object, which increases its reference count.
///
/// Clones must be [dispose]d when finished.
SkiaObjectBox clone(Object wrapper) {
SkiaObjectBox<T> clone(Object wrapper) {
assert(!_isDeleted, 'Cannot clone from a deleted handle.');
assert(_refs.isNotEmpty);
return SkiaObjectBox._(wrapper, skObject, _refs);
return SkiaObjectBox<T>._(wrapper, skObject, _skDeletable, _refs);
}
/// Decrements the reference count for the [skObject].
......@@ -316,7 +317,7 @@ class SkiaObjectBox {
assert(removed);
_isDeleted = true;
if (_refs.isEmpty) {
_scheduleSkObjectCollection(skObject);
_scheduleSkObjectCollection(_skDeletable);
}
}
}
......
......@@ -155,13 +155,11 @@ void _tests() {
});
});
group(SkiaObjectBox, () {
test('Records stack traces and respects refcounts', () async {
TestOneShotSkiaObject.deleteCount = 0;
final TestOneShotSkiaObject skObject = TestOneShotSkiaObject();
TestSkDeletable.deleteCount = 0;
final Object wrapper = Object();
final SkiaObjectBox box = SkiaObjectBox(wrapper, skObject);
final SkiaObjectBox<TestSkDeletable> box = SkiaObjectBox<TestSkDeletable>(wrapper, TestSkDeletable());
expect(box.debugGetStackTraces().length, 1);
......@@ -178,7 +176,7 @@ void _tests() {
// Let any timers elapse.
await Future<void>.delayed(Duration.zero);
expect(TestOneShotSkiaObject.deleteCount, 0);
expect(TestSkDeletable.deleteCount, 0);
expect(clone.debugGetStackTraces().length, 1);
expect(box.debugGetStackTraces().length, 1);
......@@ -188,7 +186,7 @@ void _tests() {
// Let any timers elapse.
await Future<void>.delayed(Duration.zero);
expect(TestOneShotSkiaObject.deleteCount, 1);
expect(TestSkDeletable.deleteCount, 1);
expect(clone.debugGetStackTraces().length, 0);
expect(box.debugGetStackTraces().length, 0);
......@@ -196,6 +194,15 @@ void _tests() {
});
}
class TestSkDeletable implements SkDeletable {
static int deleteCount = 0;
@override
void delete() {
deleteCount++;
}
}
class TestOneShotSkiaObject extends OneShotSkiaObject<SkPaint> implements SkDeletable {
static int deleteCount = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册