mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Simplify API for scheduling Skia object deletions (#22409)
This commit is contained in:
parent
af185be87c
commit
1a13dac529
@ -1692,13 +1692,12 @@ List<SkDeletable> _skObjectDeleteQueue = <SkDeletable>[];
|
||||
|
||||
final SkObjectFinalizationRegistry skObjectFinalizationRegistry =
|
||||
SkObjectFinalizationRegistry(js.allowInterop((SkDeletable deletable) {
|
||||
_skObjectDeleteQueue.add(deletable);
|
||||
_skObjectCollector ??= _scheduleSkObjectCollection();
|
||||
_scheduleSkObjectCollection(deletable);
|
||||
}));
|
||||
|
||||
/// Schedules an asap timer to delete garbage-collected Skia objects.
|
||||
/// Schedules a Skia object for deletion in an asap timer.
|
||||
///
|
||||
/// We use a timer for the following reasons:
|
||||
/// A timer is used for the following reasons:
|
||||
///
|
||||
/// - Deleting the object immediately may lead to dangling pointer as the Skia
|
||||
/// object may still be used by a function in the current frame. For example,
|
||||
@ -1709,21 +1708,28 @@ final SkObjectFinalizationRegistry skObjectFinalizationRegistry =
|
||||
/// - A microtask, while solves the problem above, would prevent the event from
|
||||
/// yielding to the graphics system to render the frame on the screen if there
|
||||
/// is a large number of objects to delete, causing jank.
|
||||
Timer _scheduleSkObjectCollection() => Timer(Duration.zero, () {
|
||||
html.window.performance.mark('SkObject collection-start');
|
||||
final int length = _skObjectDeleteQueue.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
_skObjectDeleteQueue[i].delete();
|
||||
}
|
||||
_skObjectDeleteQueue = <SkDeletable>[];
|
||||
///
|
||||
/// Because scheduling a timer is expensive, the timer is shared by all objects
|
||||
/// deleted this frame. No timer is created if no objects were scheduled for
|
||||
/// deletion.
|
||||
void _scheduleSkObjectCollection(SkDeletable deletable) {
|
||||
_skObjectDeleteQueue.add(deletable);
|
||||
_skObjectCollector ??= Timer(Duration.zero, () {
|
||||
html.window.performance.mark('SkObject collection-start');
|
||||
final int length = _skObjectDeleteQueue.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
_skObjectDeleteQueue[i].delete();
|
||||
}
|
||||
_skObjectDeleteQueue = <SkDeletable>[];
|
||||
|
||||
// Null out the timer so we can schedule a new one next time objects are
|
||||
// scheduled for deletion.
|
||||
_skObjectCollector = null;
|
||||
html.window.performance.mark('SkObject collection-end');
|
||||
html.window.performance.measure('SkObject collection',
|
||||
'SkObject collection-start', 'SkObject collection-end');
|
||||
});
|
||||
// Null out the timer so we can schedule a new one next time objects are
|
||||
// scheduled for deletion.
|
||||
_skObjectCollector = null;
|
||||
html.window.performance.mark('SkObject collection-end');
|
||||
html.window.performance.measure('SkObject collection',
|
||||
'SkObject collection-start', 'SkObject collection-end');
|
||||
});
|
||||
}
|
||||
|
||||
/// Any Skia object that has a `delete` method.
|
||||
@JS()
|
||||
|
||||
@ -316,8 +316,7 @@ class SkiaObjectBox {
|
||||
assert(removed);
|
||||
_isDeleted = true;
|
||||
if (_refs.isEmpty) {
|
||||
_skObjectDeleteQueue.add(skObject);
|
||||
_skObjectCollector ??= _scheduleSkObjectCollection();
|
||||
_scheduleSkObjectCollection(skObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user