drm_hwcomposer: Dynamic DrmDisplayPipeline to HwcDisplay bindings
The following use scenarios are now possible:
1. When no display connected, primary HwcDisplay is created in headless
mode.
2. When user connects first display, it binds to primary slot, replacing
headless HwcDisplay.
3. When user connects another display it binds to the new HwcDisplay
slot, creating new display for the framework.
4. When user disconnects first (Primary) display, drm_hwc detaches
second display and attaches it to the Primary slot. In this case
framework is notified as Primary display resolution updated
(Plugged->Plugged transition). And second display is disconnected
(Plugged->Unplugged transition).
DrmDisplayPipeline is now created on demand (after hotplug event).
HwcDisplay class is now destructed on connector unplug, which will give
us ability to destroy any resource caches (will be required for FB
caching logic).
Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
diff --git a/hwc2_device/DrmHwcTwo.h b/hwc2_device/DrmHwcTwo.h
index fa13170..83fbd79 100644
--- a/hwc2_device/DrmHwcTwo.h
+++ b/hwc2_device/DrmHwcTwo.h
@@ -24,11 +24,10 @@
namespace android {
-class DrmHwcTwo {
+class DrmHwcTwo : public PipelineToFrontendBindingInterface {
public:
DrmHwcTwo();
-
- HWC2::Error Init();
+ ~DrmHwcTwo() override = default;
std::pair<HWC2_PFN_HOTPLUG, hwc2_callback_data_t> hotplug_callback_{};
std::pair<HWC2_PFN_VSYNC, hwc2_callback_data_t> vsync_callback_{};
@@ -45,27 +44,38 @@
uint32_t GetMaxVirtualDisplayCount();
HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
hwc2_function_pointer_t function);
- HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type);
auto GetDisplay(hwc2_display_t display_handle) {
- return displays_.count(display_handle) != 0 ? &displays_.at(display_handle)
- : nullptr;
+ return displays_.count(display_handle) != 0
+ ? displays_[display_handle].get()
+ : nullptr;
}
auto &GetResMan() {
return resource_manager_;
}
- private:
- void HandleDisplayHotplug(hwc2_display_t displayid, int state);
- void HandleInitialHotplugState(DrmDevice *drmDevice);
+ void ScheduleHotplugEvent(hwc2_display_t displayid, bool connected) {
+ deferred_hotplug_events_[displayid] = connected;
+ }
- void HandleHotplugUEvent();
+ // PipelineToFrontendBindingInterface
+ bool BindDisplay(DrmDisplayPipeline *pipeline) override;
+ bool UnbindDisplay(DrmDisplayPipeline *pipeline) override;
+ void FinalizeDisplayBinding() override;
+
+ private:
+ void SendHotplugEventToClient(hwc2_display_t displayid, bool connected);
ResourceManager resource_manager_;
- std::map<hwc2_display_t, HwcDisplay> displays_;
+ std::map<hwc2_display_t, std::unique_ptr<HwcDisplay>> displays_;
+ std::map<DrmDisplayPipeline *, hwc2_display_t> display_handles_;
std::string mDumpString;
+
+ std::map<hwc2_display_t, bool> deferred_hotplug_events_;
+
+ uint32_t last_display_handle_ = kPrimaryDisplay;
};
} // namespace android