ozone/drm: Release PageFlipRequest reference in tests
If a pageflip is committed to FakeDrmDevice, and the pageflip callback
is not cleared, this results in a reference cycle preventing the
FakeDrmDevice from being deleted.
- DrmOverlayPlane holds a scoped_refptr<DrmFramebuffer>
- DrmFramebuffer holds a scoped_refptr<DrmDevice>
- in HardwareDisplayController::SchedulePageFlip the
vector<DrmOverlayPlane> is bound to a base::OnceCallback
- PageFlipRequest takes ownership of the callback through TakeCallback
- In FakeDrmDevice::CommitProperties, the FakeDrmDevice adds the
PageFlipRequest to its internal queue, causing a reference cycle.
For tests that run the callbacks via FakeDrmDevice::RunCallbacks, the
PageFlipRequest reference will be dropped and the reference cycle
broken.
FakeDrmDevice::ClearCallbacks provides a mechanism to break the
reference cycle while avoiding any unintended side effects of executing
the callbacks.
Bug: chromium:40263665
TEST: ozone_unittests with detect_leaks=1
Change-Id: I4404b6c339d6fa76da116e070cace36469a8cbbb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5410833
Reviewed-by: Gil Dekel <gildekel@chromium.org>
Commit-Queue: Drew Davenport <ddavenport@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1282221}
diff --git a/ui/ozone/platform/drm/gpu/fake_drm_device.cc b/ui/ozone/platform/drm/gpu/fake_drm_device.cc
index a0a3343..824aaa4 100644
--- a/ui/ozone/platform/drm/gpu/fake_drm_device.cc
+++ b/ui/ozone/platform/drm/gpu/fake_drm_device.cc
@@ -986,4 +986,9 @@
plane_manager_.reset();
}
+void FakeDrmDevice::ClearCallbacks() {
+ base::queue<PageFlipCallback> empty;
+ callbacks_.swap(empty);
+}
+
} // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/fake_drm_device.h b/ui/ozone/platform/drm/gpu/fake_drm_device.h
index 48d165e9..e602816 100644
--- a/ui/ozone/platform/drm/gpu/fake_drm_device.h
+++ b/ui/ozone/platform/drm/gpu/fake_drm_device.h
@@ -374,6 +374,12 @@
// This function can be used to break the cycle in unittests.
void ResetPlaneManagerForTesting();
+ // When CommitProperties has been called with a PageFlipRequest, FakeDrmDevice
+ // holds a reference to the PageFlipRequest, resulting in a reference cycle.
+ // This reference os released as a part of RunCallbacks. ClearCallbacks breaks
+ // the cycle without running the callbacks.
+ void ClearCallbacks();
+
protected:
~FakeDrmDevice() override;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
index 764f1e07..11df12ea 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -173,6 +173,7 @@
void MAYBE_HardwareDisplayControllerTest::TearDown() {
controller_.reset();
drm_->ResetPlaneManagerForTesting();
+ drm_->ClearCallbacks();
drm_ = nullptr;
}