-
Notifications
You must be signed in to change notification settings - Fork 6k
Remove tech debt related to image disposal and layer GC #26870
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,23 +30,11 @@ class ImageDisposeTest : public ShellTest { | |
// Used to wait on Dart callbacks or Shell task runner flushing | ||
fml::AutoResetWaitableEvent message_latch_; | ||
|
||
fml::AutoResetWaitableEvent picture_finalizer_latch_; | ||
static void picture_finalizer(void* isolate_callback_data, void* peer) { | ||
auto latch = reinterpret_cast<fml::AutoResetWaitableEvent*>(peer); | ||
latch->Signal(); | ||
} | ||
|
||
sk_sp<SkPicture> current_picture_; | ||
sk_sp<SkImage> current_image_; | ||
}; | ||
|
||
TEST_F(ImageDisposeTest, | ||
#if defined(OS_FUCHSIA) | ||
DISABLED_ImageReleasedAfterFrame | ||
#else | ||
ImageReleasedAfterFrame | ||
#endif // defined(OS_FUCHSIA) | ||
) { | ||
TEST_F(ImageDisposeTest, ImageReleasedAfterFrameAndDisposePictureAndLayer) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reviewers take note: this re-enables a test that was flaking on Fuchsia. However, this test no longer relies on GC behavior and should be fully deterministic now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It also no longer relies on decoding a massive image, and is much faster now too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. flutter/flutter#84116 can be closed when this lands. |
||
auto native_capture_image_and_picture = [&](Dart_NativeArguments args) { | ||
auto image_handle = Dart_GetNativeArgument(args, 0); | ||
auto native_image_handle = | ||
|
@@ -60,12 +48,9 @@ TEST_F(ImageDisposeTest, | |
ASSERT_FALSE(picture->picture()->unique()); | ||
current_image_ = image->image(); | ||
current_picture_ = picture->picture(); | ||
|
||
Dart_NewFinalizableHandle(Dart_GetNativeArgument(args, 1), | ||
&picture_finalizer_latch_, 0, &picture_finalizer); | ||
}; | ||
|
||
auto native_on_begin_frame_done = [&](Dart_NativeArguments args) { | ||
auto native_finish = [&](Dart_NativeArguments args) { | ||
message_latch_.Signal(); | ||
}; | ||
|
||
|
@@ -80,8 +65,7 @@ TEST_F(ImageDisposeTest, | |
|
||
AddNativeCallback("CaptureImageAndPicture", | ||
CREATE_NATIVE_ENTRY(native_capture_image_and_picture)); | ||
AddNativeCallback("OnBeginFrameDone", | ||
CREATE_NATIVE_ENTRY(native_on_begin_frame_done)); | ||
AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(native_finish)); | ||
|
||
std::unique_ptr<Shell> shell = CreateShell(std::move(settings), task_runners); | ||
|
||
|
@@ -103,15 +87,8 @@ TEST_F(ImageDisposeTest, | |
ASSERT_TRUE(current_picture_); | ||
ASSERT_TRUE(current_image_); | ||
|
||
// Simulate a large notify idle, as the animator would do | ||
// when it has no frames left. | ||
// On slower machines, this is especially important - we capture that | ||
// this happens normally in devicelab bnechmarks like large_image_changer. | ||
NotifyIdle(shell.get(), Dart_TimelineGetMicros() + 100000); | ||
|
||
picture_finalizer_latch_.Wait(); | ||
|
||
// Force a drain the SkiaUnrefQueue. | ||
// Force a drain the SkiaUnrefQueue. The engine does this normally as frames | ||
// pump, but we force it here to make the test more deterministic. | ||
message_latch_.Reset(); | ||
task_runner->PostTask([&, io_manager = shell->GetIOManager()]() { | ||
io_manager->GetSkiaUnrefQueue()->Drain(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -195,17 +195,14 @@ bool RuntimeController::ReportTimings(std::vector<int64_t> timings) { | |
return false; | ||
} | ||
|
||
bool RuntimeController::NotifyIdle(int64_t deadline, size_t freed_hint) { | ||
bool RuntimeController::NotifyIdle(int64_t deadline) { | ||
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock(); | ||
if (!root_isolate) { | ||
return false; | ||
} | ||
|
||
tonic::DartState::Scope scope(root_isolate); | ||
|
||
// Dart will use the freed hint at the next idle notification. Make sure to | ||
// Update it with our latest value before calling NotifyIdle. | ||
Dart_HintFreed(freed_hint); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you let me know if my understanding is correct here? Not tracking/providing this hint for freed images won't cause the GC policy to behave poorly for us because:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. Running the GC for this is expensive and no longer needed |
||
Dart_NotifyIdle(deadline); | ||
|
||
// Idle notifications being in isolate scope are part of the contract. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the shallow size of the C++ object still tracked as an external allocation for Dart GC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's handled automatically here: https://github.com/flutter/engine/blob/master/third_party/tonic/dart_wrappable.h#L89