Skip to content

Commit 42d8664

Browse files
yjbanovchaselatta
authored andcommitted
Simplify API for scheduling Skia object deletions (flutter#22409)
1 parent f5ed4af commit 42d8664

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

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

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,13 +1692,12 @@ List<SkDeletable> _skObjectDeleteQueue = <SkDeletable>[];
16921692

16931693
final SkObjectFinalizationRegistry skObjectFinalizationRegistry =
16941694
SkObjectFinalizationRegistry(js.allowInterop((SkDeletable deletable) {
1695-
_skObjectDeleteQueue.add(deletable);
1696-
_skObjectCollector ??= _scheduleSkObjectCollection();
1695+
_scheduleSkObjectCollection(deletable);
16971696
}));
16981697

1699-
/// Schedules an asap timer to delete garbage-collected Skia objects.
1698+
/// Schedules a Skia object for deletion in an asap timer.
17001699
///
1701-
/// We use a timer for the following reasons:
1700+
/// A timer is used for the following reasons:
17021701
///
17031702
/// - Deleting the object immediately may lead to dangling pointer as the Skia
17041703
/// object may still be used by a function in the current frame. For example,
@@ -1709,21 +1708,28 @@ final SkObjectFinalizationRegistry skObjectFinalizationRegistry =
17091708
/// - A microtask, while solves the problem above, would prevent the event from
17101709
/// yielding to the graphics system to render the frame on the screen if there
17111710
/// is a large number of objects to delete, causing jank.
1712-
Timer _scheduleSkObjectCollection() => Timer(Duration.zero, () {
1713-
html.window.performance.mark('SkObject collection-start');
1714-
final int length = _skObjectDeleteQueue.length;
1715-
for (int i = 0; i < length; i++) {
1716-
_skObjectDeleteQueue[i].delete();
1717-
}
1718-
_skObjectDeleteQueue = <SkDeletable>[];
1719-
1720-
// Null out the timer so we can schedule a new one next time objects are
1721-
// scheduled for deletion.
1722-
_skObjectCollector = null;
1723-
html.window.performance.mark('SkObject collection-end');
1724-
html.window.performance.measure('SkObject collection',
1725-
'SkObject collection-start', 'SkObject collection-end');
1726-
});
1711+
///
1712+
/// Because scheduling a timer is expensive, the timer is shared by all objects
1713+
/// deleted this frame. No timer is created if no objects were scheduled for
1714+
/// deletion.
1715+
void _scheduleSkObjectCollection(SkDeletable deletable) {
1716+
_skObjectDeleteQueue.add(deletable);
1717+
_skObjectCollector ??= Timer(Duration.zero, () {
1718+
html.window.performance.mark('SkObject collection-start');
1719+
final int length = _skObjectDeleteQueue.length;
1720+
for (int i = 0; i < length; i++) {
1721+
_skObjectDeleteQueue[i].delete();
1722+
}
1723+
_skObjectDeleteQueue = <SkDeletable>[];
1724+
1725+
// Null out the timer so we can schedule a new one next time objects are
1726+
// scheduled for deletion.
1727+
_skObjectCollector = null;
1728+
html.window.performance.mark('SkObject collection-end');
1729+
html.window.performance.measure('SkObject collection',
1730+
'SkObject collection-start', 'SkObject collection-end');
1731+
});
1732+
}
17271733

17281734
/// Any Skia object that has a `delete` method.
17291735
@JS()

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,7 @@ class SkiaObjectBox {
316316
assert(removed);
317317
_isDeleted = true;
318318
if (_refs.isEmpty) {
319-
_skObjectDeleteQueue.add(skObject);
320-
_skObjectCollector ??= _scheduleSkObjectCollection();
319+
_scheduleSkObjectCollection(skObject);
321320
}
322321
}
323322
}

0 commit comments

Comments
 (0)