Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Simplify API for scheduling Skia object deletions #22409

Merged
merged 1 commit into from
Nov 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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>[];

// 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');
});
///
/// 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');
});
}

/// Any Skia object that has a `delete` method.
@JS()
Expand Down
3 changes: 1 addition & 2 deletions lib/web_ui/lib/src/engine/canvaskit/skia_object_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,7 @@ class SkiaObjectBox {
assert(removed);
_isDeleted = true;
if (_refs.isEmpty) {
_skObjectDeleteQueue.add(skObject);
_skObjectCollector ??= _scheduleSkObjectCollection();
_scheduleSkObjectCollection(skObject);
}
}
}
Expand Down