drm_hwcomposer: Rework HwcDisplay disposal to avoid races
The code prior to this commit has a flaw:
HwcDisplay::~HwcDisplay() {
...
auto &main_lock = hwc2_->GetResMan().GetMainLock();
/* Unlock to allow pending vsync callbacks to finish */
main_lock.unlock();
At this point display is no longer in displays_[] list. After
lock is released, hwc2 API thread starts to process transactions
which may fail with BAD_SIAPLAY responce and cause SF to crash.
vsync_worker_.VSyncControl(false);
vsync_worker_.Exit();
main_lock.lock();
}
1. Rework the logic in order to avoid such scenariuos:
1.a. Temporary switch non-primary unplugged displays to headless state
allowing remaining transactions to succeed without impacting the
pipeline.
1.b. Give 100mSec delay before destroying / removing display from the
displays_[] list to allow all pending hwc2 transactions to complete.
2. Support hotswap of the DrmDisplayPipeline, which makes primary display
reattaching process smoother.
Now SF should be able to gracefully remove all layers.
Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
diff --git a/hwc2_device/DrmHwcTwo.h b/hwc2_device/DrmHwcTwo.h
index 0e72251..2b8a74f 100644
--- a/hwc2_device/DrmHwcTwo.h
+++ b/hwc2_device/DrmHwcTwo.h
@@ -81,6 +81,7 @@
std::string mDumpString;
std::map<hwc2_display_t, bool> deferred_hotplug_events_;
+ std::vector<hwc2_display_t> displays_for_removal_list_;
uint32_t last_display_handle_ = kPrimaryDisplay;
};