diff options
author | Pritama Biswas <pritbisw@codeaurora.org> | 2021-09-18 21:12:47 +0530 |
---|---|---|
committer | Pritama Biswas <pritbisw@codeaurora.org> | 2021-09-27 15:11:36 +0530 |
commit | b83651dc7a690a13eccb0757dd5d10787670bc4f (patch) | |
tree | 6ca5c772fe66ea6c1ce8d6ff6b1e8e20bf74cd48 | |
parent | c346a211b1f38ccb3ea492a6a0dd81ca286a1dde (diff) |
hwc2: Add support for pluggable as primary
Change-Id: I25f45d1583fbf79146dd5d6323a2ca51b42c65ab
-rw-r--r-- | sdm/libs/hwc2/hwc_display.h | 3 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_display_dummy.cpp | 10 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_display_dummy.h | 5 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_display_pluggable.h | 4 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_session.cpp | 82 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_session.h | 1 |
6 files changed, 74 insertions, 31 deletions
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h index 5c6bce9e..056ab6ec 100644 --- a/sdm/libs/hwc2/hwc_display.h +++ b/sdm/libs/hwc2/hwc_display.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2020, 2021, The Linux Foundation. All rights reserved. * Not a Contribution. * * Copyright 2015 The Android Open Source Project @@ -475,6 +475,7 @@ class HWCDisplay : public DisplayEventHandler { int64_t pending_refresh_rate_applied_time_ = INT64_MAX; std::deque<TransientRefreshRateInfo> transient_refresh_rate_info_; std::mutex transient_refresh_rate_lock_; + DisplayNullExternal display_null_; private: void DumpInputBuffers(void); diff --git a/sdm/libs/hwc2/hwc_display_dummy.cpp b/sdm/libs/hwc2/hwc_display_dummy.cpp index ace26ac6..0f48916f 100644 --- a/sdm/libs/hwc2/hwc_display_dummy.cpp +++ b/sdm/libs/hwc2/hwc_display_dummy.cpp @@ -46,13 +46,17 @@ int HWCDisplayDummy::Create(CoreInterface *core_intf, BufferAllocator *buffer_al void HWCDisplayDummy::Destroy(HWCDisplay *hwc_display) { delete hwc_display; + hwc_display = NULL; } HWC2::Error HWCDisplayDummy::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) { + validated_ = true; + PrepareLayerStack(out_num_types, out_num_requests); return HWC2::Error::None; } HWC2::Error HWCDisplayDummy::Present(int32_t *out_retire_fence) { + PostCommitLayerStack(out_retire_fence); for (auto hwc_layer : layer_set_) { hwc_layer->PushBackReleaseFence(-1); } @@ -82,6 +86,12 @@ HWCDisplayDummy::HWCDisplayDummy(CoreInterface *core_intf, BufferAllocator *buff hwc_config_map_.at(0) = 0; } +HWC2::Error HWCDisplayDummy::GetDisplayRequests(int32_t *out_display_requests, + uint32_t *out_num_elements, hwc2_layer_t *out_layers, + int32_t *out_layer_requests) { + return HWC2::Error::None; +} + HWC2::Error HWCDisplayDummy::GetActiveConfig(hwc2_config_t *out_config) { *out_config = 0; return HWC2::Error::None; diff --git a/sdm/libs/hwc2/hwc_display_dummy.h b/sdm/libs/hwc2/hwc_display_dummy.h index 29e04f47..1ce0996a 100644 --- a/sdm/libs/hwc2/hwc_display_dummy.h +++ b/sdm/libs/hwc2/hwc_display_dummy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019, 2021, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -44,6 +44,9 @@ class HWCDisplayDummy : public HWCDisplay { static void Destroy(HWCDisplay *hwc_display); virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests); virtual HWC2::Error Present(int32_t *out_retire_fence); + virtual HWC2::Error GetDisplayRequests(int32_t *out_display_requests, + uint32_t *out_num_elements, hwc2_layer_t *out_layers, + int32_t *out_layer_requests); virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config); private: diff --git a/sdm/libs/hwc2/hwc_display_pluggable.h b/sdm/libs/hwc2/hwc_display_pluggable.h index 7c24c1d7..0d6f60a6 100644 --- a/sdm/libs/hwc2/hwc_display_pluggable.h +++ b/sdm/libs/hwc2/hwc_display_pluggable.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2019, 2021, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,7 +31,6 @@ #define __HWC_DISPLAY_PLUGGABLE_H__ #include "hwc_display.h" -#include "display_null.h" #include "hwc_display_event_handler.h" namespace sdm { @@ -65,7 +64,6 @@ class HWCDisplayPluggable : public HWCDisplay { static void GetDownscaleResolution(uint32_t primary_width, uint32_t primary_height, uint32_t *virtual_width, uint32_t *virtual_height); - DisplayNullExternal display_null_; int underscan_width_ = 0; int underscan_height_ = 0; }; diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp index 281a0755..794ebc33 100644 --- a/sdm/libs/hwc2/hwc_session.cpp +++ b/sdm/libs/hwc2/hwc_session.cpp @@ -2592,23 +2592,21 @@ int HWCSession::CreatePrimaryDisplay() { auto hwc_display = &hwc_display_[HWC_DISPLAY_PRIMARY]; hwc2_display_t client_id = map_info_primary_.client_id; - if (!info.is_connected) { - // primary display is not connected, create a dummy display. - HWCDisplayDummy::Create(core_intf_, &buffer_allocator_, &callbacks_, this, qservice_, - 0, 0, hwc_display); - null_display_active_ = true; - map_info_primary_.disp_type = info.display_type; - map_info_primary_.sdm_id = info.display_id; - status = kErrorNone; - break; - } DLOGI("Create primary display type = %d, sdm id = %d, client id = %d", info.display_type, info.display_id, client_id); - if (info.display_type == kBuiltIn) { + if (!info.is_connected && info.display_type == kPluggable) { + pluggable_is_primary_ = true; + null_display_active_ = true; + status = HWCDisplayDummy::Create(core_intf_, &buffer_allocator_, &callbacks_, this, qservice_, + client_id, info.display_id, hwc_display); + DLOGI("Pluggable display is primary but not connected!"); + } else if (info.display_type == kBuiltIn) { status = HWCDisplayBuiltIn::Create(core_intf_, &buffer_allocator_, &callbacks_, this, qservice_, client_id, info.display_id, hwc_display); - } else if (info.display_type == kPluggable) { + } else if (info.is_connected && info.display_type == kPluggable) { + pluggable_is_primary_ = true; + DLOGI("Pluggable display is primary and is connected!"); status = HWCDisplayPluggable::Create(core_intf_, &buffer_allocator_, &callbacks_, this, qservice_, client_id, info.display_id, 0, 0, false, hwc_display); @@ -2711,9 +2709,13 @@ int HWCSession::HandleBuiltInDisplays() { int HWCSession::HandlePluggableDisplays(bool delay_hotplug) { SCOPE_LOCK(pluggable_handler_lock_); - if (null_display_mode_) { - DLOGW("Skipped pluggable display handling in null-display mode"); - return 0; + if (null_display_active_) { + SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); + auto &hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY]; + HWCDisplayDummy::Destroy(hwc_display); + CoreInterface::DestroyCore(); + DLOGI("Primary pluggable display is connected. Exit!"); + _exit(1); } DLOGI("Handling hotplug..."); @@ -2762,16 +2764,38 @@ int HWCSession::HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool d for (auto &iter : *hw_displays_info) { auto &info = iter.second; - if (info.is_primary && info.is_connected && null_display_active_) { - DLOGI("Pluggable display is connected. Exit!"); - auto hwc_display_dummy = hwc_display_[HWC_DISPLAY_PRIMARY]; - HWCDisplayDummy::Destroy(hwc_display_dummy); - CoreInterface::DestroyCore(); - _exit(1); - } - // Do not recreate primary display or if display is not connected. - if (info.is_primary || info.display_type != kPluggable || !info.is_connected) { + if (pluggable_is_primary_) { + DisplayMapInfo map_info = map_info_primary_; + hwc2_display_t client_id = map_info.client_id; + { + SCOPE_LOCK(locker_[client_id]); + auto &hwc_display = hwc_display_[client_id]; + if (hwc_display && info.is_primary && info.display_type == kPluggable + && info.is_connected) { + DLOGI("Create primary pluggable display, sdm id = %d, client id = %d", + info.display_id, client_id); + status = hwc_display->SetState(true); + if (status) { + DLOGE("Pluggable display creation failed."); + return status; + } + is_hdr_display_[UINT32(client_id)] = HasHDRSupport(hwc_display); + DLOGI("Created primary pluggable display successfully: sdm id = %d," + "client id = %d", info.display_id, client_id); + map_info.disp_type = info.display_type; + map_info.sdm_id = info.display_id; + + } + } + { + SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); + hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation(); + } + Refresh(0); + } + if (!pluggable_is_primary_ && (info.is_primary || info.display_type != kPluggable + || !info.is_connected)) { continue; } @@ -2954,7 +2978,10 @@ void HWCSession::DestroyPluggableDisplay(DisplayMapInfo *map_info) { hwc2_display_t client_id = map_info->client_id; DLOGI("Notify hotplug display disconnected: client id = %d", client_id); - callbacks_.Hotplug(client_id, HWC2::Connection::Disconnected); + if (!pluggable_is_primary_) { + // Notify SurfaceFlinger. + callbacks_.Hotplug(client_id, HWC2::Connection::Disconnected); + } // Trigger refresh to make sure disconnect event received/updated properly by SurfaceFlinger. Refresh(HWC_DISPLAY_PRIMARY); @@ -2971,7 +2998,10 @@ void HWCSession::DestroyPluggableDisplay(DisplayMapInfo *map_info) { } DLOGI("Destroy display %d-%d, client id = %d", map_info->sdm_id, map_info->disp_type, client_id); - + if (pluggable_is_primary_){ + hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(false); + return; + } is_hdr_display_[UINT32(client_id)] = false; if (!map_info->test_pattern) { HWCDisplayPluggable::Destroy(hwc_display); diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h index 2ad0f037..fed39c98 100644 --- a/sdm/libs/hwc2/hwc_session.h +++ b/sdm/libs/hwc2/hwc_session.h @@ -430,6 +430,7 @@ class HWCSession : hwc2_device_t, HWCUEventListener, public qClient::BnQClient, int bw_mode_release_fd_ = -1; qService::QService *qservice_ = nullptr; HWCSocketHandler socket_handler_; + bool pluggable_is_primary_ = false; bool null_display_active_ = false; bool is_composer_up_ = false; Locker callbacks_lock_; |