summaryrefslogtreecommitdiff
path: root/sdm/libs/hwc2/hwc_session.cpp
diff options
context:
space:
mode:
authorPullakavi Srinivas <spullaka@codeaurora.org>2019-03-25 16:24:22 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2019-05-02 23:41:09 -0700
commit51d863db03e1901843cfd757c21f54370cf21c44 (patch)
tree06909294cb803801e6dda163d8ede9bd45d6ffed /sdm/libs/hwc2/hwc_session.cpp
parent281b157a6989ba70d0ff01c434c9051b473792b0 (diff)
hwc2: Clean up display slot handling.
-- Deprecate SetDisplayIndex api. -- Query for max display supported displays per type. -- Create display_map corresponding to capabilities. -- Fail creation of any display if free slot isn't available. Change-Id: Ic22f5695e7425a68ca7d4c85f0b85703055abe63 CRs-fixed: 2429625
Diffstat (limited to 'sdm/libs/hwc2/hwc_session.cpp')
-rw-r--r--sdm/libs/hwc2/hwc_session.cpp308
1 files changed, 142 insertions, 166 deletions
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 3e161c8f..79659148 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -167,7 +167,6 @@ int HWCSession::Init() {
return status;
}
- InitDisplaySlots();
#if defined(DISPLAY_CONFIG_1_2) && defined(CONFIG_BASEID_FROM_PROP)
char indices[kPropertyMax];
@@ -209,51 +208,12 @@ int HWCSession::Init() {
HWCDebugHandler::Get()->GetProperty(ENABLE_NULL_DISPLAY_PROP, &null_display_mode_);
HWCDebugHandler::Get()->GetProperty(DISABLE_HOTPLUG_BWCHECK, &disable_hotplug_bwcheck_);
HWCDebugHandler::Get()->GetProperty(DISABLE_MASK_LAYER_HINT, &disable_mask_layer_hint_);
- DisplayError error = kErrorNone;
-
- HWDisplayInterfaceInfo hw_disp_info = {};
- if (null_display_mode_) {
- hw_disp_info.type = kPrimary;
- hw_disp_info.is_connected = true;
- } else {
- error = CoreInterface::CreateCore(&buffer_allocator_, &buffer_sync_handler_, &socket_handler_,
- &core_intf_);
- if (error != kErrorNone) {
- DLOGE("Failed to create CoreInterface");
- return -EOWNERDEAD;
- }
-
- error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
- if (error != kErrorNone) {
- CoreInterface::DestroyCore();
- DLOGE("Primary display type not recognized. Error = %d", error);
- return -EINVAL;
- }
-
- error = core_intf_->GetMaxDisplaysSupported(kPluggable, &max_sde_pluggable_displays_);
- if (kErrorNone == error) {
- if (max_sde_pluggable_displays_ && (kPluggable == hw_disp_info.type)) {
- // If primary is a pluggable display, we have already used one pluggable display interface.
- max_sde_pluggable_displays_--;
- }
- } else {
- DLOGE("Could not find maximum pluggable displays supported. Error = %d", error);
- }
-
- error = core_intf_->GetMaxDisplaysSupported(kBuiltIn, &max_sde_builtin_displays_);
- if (kErrorNone == error) {
- if (max_sde_builtin_displays_ && (kBuiltIn == hw_disp_info.type)) {
- // If primary is not a pluggable display, we have already used one built-in display
- // interface.
- max_sde_builtin_displays_--;
- }
- } else {
- DLOGE("Could not find maximum built-in displays supported. Error = %d", error);
- }
+ if (!null_display_mode_) {
g_hwc_uevent_.Register(this);
}
+ InitSupportedDisplaySlots();
// Create primary display here. Remaining builtin displays will be created after client has set
// display indexes which may happen sometime before callback is registered.
status = CreatePrimaryDisplay();
@@ -299,33 +259,87 @@ int HWCSession::Deinit() {
return 0;
}
-void HWCSession::InitDisplaySlots() {
+void HWCSession::InitSupportedDisplaySlots() {
// Default slots:
- // Primary = 0, External = 1, Virtual = 2 (legacy IDs)
- // Additional builtin displays 3, 4 ... x
- // Additional external displays x+1, x+2 ... y
- // Additional virtual displays y+1, y+2 ... z
- // If client does not support additional displays, hotplug for such displays
- // will be disregarded by the client.
- // If client supports different range of ids for additional displays, those
- // will be set and overridden by an explicit call to set display indexes.
- hwc2_display_t additional_base_id = qdutils::DISPLAY_VIRTUAL + 1;
+ // Primary = 0, External = 1
+ // Additional external displays 2,3,...max_pluggable_count.
+ // Additional builtin displays max_pluggable_count + 1, max_pluggable_count + 2,...
+ // Last slots for virtual displays.
+ // Virtual display id is only for SF <--> HWC communication.
+ // It need not align with hwccomposer_defs
map_info_primary_.client_id = qdutils::DISPLAY_PRIMARY;
- map_info_builtin_.resize(HWCCallbacks::kNumBuiltIn);
- for (size_t i = 0; i < HWCCallbacks::kNumBuiltIn; i++) {
- map_info_builtin_[i].client_id = additional_base_id++;
+ if (null_display_mode_) {
+ // Skip display slot initialization.
+ return;
}
- map_info_pluggable_.resize(HWCCallbacks::kNumPluggable);
- for (size_t i = 0; i < HWCCallbacks::kNumPluggable; i++) {
- map_info_pluggable_[i].client_id = i ? additional_base_id++ : qdutils::DISPLAY_EXTERNAL;
+ DisplayError error = CoreInterface::CreateCore(&buffer_allocator_, &buffer_sync_handler_,
+ &socket_handler_, &core_intf_);
+ if (error != kErrorNone) {
+ DLOGE("Failed to create CoreInterface");
+ return;
}
- map_info_virtual_.resize(HWCCallbacks::kNumVirtual);
- for (size_t i = 0; i < HWCCallbacks::kNumVirtual; i++) {
- map_info_virtual_[i].client_id = i ? additional_base_id++ : qdutils::DISPLAY_VIRTUAL;
+ HWDisplayInterfaceInfo hw_disp_info = {};
+ error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
+ if (error != kErrorNone) {
+ CoreInterface::DestroyCore();
+ DLOGE("Primary display type not recognized. Error = %d", error);
+ return;
+ }
+
+ int max_builtin = 0;
+ int max_pluggable = 0;
+ int max_virtual = 0;
+
+ error = core_intf_->GetMaxDisplaysSupported(kBuiltIn, &max_builtin);
+ if (error != kErrorNone) {
+ CoreInterface::DestroyCore();
+ DLOGE("Could not find maximum built-in displays supported. Error = %d", error);
+ return;
+ }
+
+ error = core_intf_->GetMaxDisplaysSupported(kPluggable, &max_pluggable);
+ if (error != kErrorNone) {
+ CoreInterface::DestroyCore();
+ DLOGE("Could not find maximum pluggable displays supported. Error = %d", error);
+ return;
+ }
+
+ error = core_intf_->GetMaxDisplaysSupported(kVirtual, &max_virtual);
+ if (error != kErrorNone) {
+ CoreInterface::DestroyCore();
+ DLOGE("Could not find maximum virtual displays supported. Error = %d", error);
+ return;
+ }
+
+ if (kPluggable == hw_disp_info.type) {
+ // If primary is a pluggable display, we have already used one pluggable display interface.
+ max_pluggable--;
+ } else {
+ max_builtin--;
+ }
+
+ // Init slots in accordance to h/w capability.
+ uint32_t disp_count = UINT32(std::min(max_pluggable, HWCCallbacks::kNumPluggable));
+ hwc2_display_t base_id = qdutils::DISPLAY_EXTERNAL;
+ map_info_pluggable_.resize(disp_count);
+ for (auto &map_info : map_info_pluggable_) {
+ map_info.client_id = base_id++;
+ }
+
+ disp_count = UINT32(std::min(max_builtin, HWCCallbacks::kNumBuiltIn));
+ map_info_builtin_.resize(disp_count);
+ for (auto &map_info : map_info_builtin_) {
+ map_info.client_id = base_id++;
+ }
+
+ disp_count = UINT32(std::min(max_virtual, HWCCallbacks::kNumVirtual));
+ map_info_virtual_.resize(disp_count);
+ for (auto &map_info : map_info_virtual_) {
+ map_info.client_id = base_id++;
}
}
@@ -527,7 +541,7 @@ uint32_t HWCSession::GetMaxVirtualDisplayCount(hwc2_device_t *device) {
return HWC2_ERROR_BAD_PARAMETER;
}
- return null_display_mode_ ? 0 : 1;
+ return 1;
}
static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
@@ -1035,14 +1049,15 @@ int32_t HWCSession::GetDozeSupport(hwc2_device_t *device, hwc2_display_t display
}
HWCSession *hwc_session = static_cast<HWCSession *>(device);
- if (display >= HWCCallbacks::kNumDisplays || (hwc_session->hwc_display_[display] == nullptr)) {
- DLOGE("Invalid Display %d Handle %s ", display, hwc_session->hwc_display_[display] ?
+ HWCDisplay *hwc_display = hwc_session->hwc_display_[display];;
+ if (display >= HWCCallbacks::kNumDisplays || (hwc_display == nullptr)) {
+ DLOGE("Invalid Display %d Handle %s ", display, hwc_display ?
"Valid" : "NULL");
return HWC2_ERROR_BAD_DISPLAY;
}
*out_support = 0;
- if (hwc_session->GetDisplayClass(display) == DISPLAY_CLASS_BUILTIN) {
+ if (hwc_display->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) {
*out_support = 1;
}
@@ -1203,23 +1218,11 @@ hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,
HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, int32_t *format,
hwc2_display_t *out_display_id) {
- if (null_display_mode_) {
- DLOGW("Virtual display creation attempted. Not supported in null-display mode."
- " display_id is not set, and no real display object was created");
- return HWC2::Error::None;
- }
-
if (!client_connected_) {
DLOGE("Client is not ready yet.");
return HWC2::Error::BadDisplay;
}
- // Use first virtual display only for now.
- if (!map_info_virtual_.size()) {
- DLOGE("Virtual display is not supported");
- return HWC2::Error::NoResources;
- }
-
hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
if (active_builtin_disp_id < HWCCallbacks::kNumDisplays) {
SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
@@ -1236,6 +1239,13 @@ HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height,
}
}
+ if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DisplayError error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
+ if (error) {
+ return HWC2::Error::NoResources;
+ }
+ }
+
HWDisplaysInfo hw_displays_info = {};
DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
if (error != kErrorNone) {
@@ -1243,47 +1253,37 @@ HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height,
return HWC2::Error::BadDisplay;
}
- auto &map_info = map_info_virtual_[0];
- hwc2_display_t client_id = map_info.client_id;
-
// Lock confined to this scope
int status = -EINVAL;
- {
- SCOPE_LOCK(locker_[client_id]);
- auto &hwc_display = hwc_display_[client_id];
- if (hwc_display) {
- DLOGE("Virtual display is already created.");
- return HWC2::Error::NoResources;
+ for (auto &iter : hw_displays_info) {
+ auto &info = iter.second;
+ if (info.display_type != kVirtual) {
+ continue;
}
- for (auto &iter : hw_displays_info) {
- auto &info = iter.second;
- if (info.display_type != kVirtual) {
- continue;
- }
+ for (auto &map_info : map_info_virtual_) {
+ hwc2_display_t client_id = map_info.client_id;
+ {
+ SCOPE_LOCK(locker_[client_id]);
+ auto &hwc_display = hwc_display_[client_id];
+ if (hwc_display) {
+ continue;
+ }
- if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
- error = hwc_display_[HWC_DISPLAY_PRIMARY]->TeardownConcurrentWriteback();
- if (error) {
- return HWC2::Error::NoResources;
- }
- }
+ status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, client_id,
+ info.display_id, width, height, format, &hwc_display);
+ // TODO(user): validate width and height support
+ if (status) {
+ return HWC2::Error::NoResources;
+ }
- status = HWCDisplayVirtual::Create(core_intf_, &buffer_allocator_, &callbacks_, client_id,
- info.display_id, width, height, format, &hwc_display);
- // TODO(user): validate width and height support
- if (!status) {
DLOGI("Created virtual display id:% " PRIu64 " with res: %dx%d", client_id, width, height);
*out_display_id = client_id;
map_info.disp_type = info.display_type;
map_info.sdm_id = info.display_id;
+ break;
}
- break;
- }
-
- if (status) {
- return HWC2::Error::NoResources;
}
}
@@ -1295,18 +1295,6 @@ HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height,
return HWC2::Error::None;
}
-DisplayClass HWCSession::GetDisplayClass(hwc2_display_t display) {
- if (display >= HWCCallbacks::kNumDisplays) {
- DLOGE("display = %d beyond max supported display slots = %d",
- display, HWCCallbacks::kNumDisplays);
- return DISPLAY_CLASS_NULL;
- } else if (!hwc_display_[display]) {
- DLOGE("display = %d slot empty.", display);
- return DISPLAY_CLASS_NULL;
- }
- return hwc_display_[display]->GetDisplayClass();
-}
-
bool HWCSession::IsPluggableDisplayConnected() {
for (auto &map_info : map_info_pluggable_) {
if (hwc_display_[map_info.client_id]) {
@@ -2476,41 +2464,33 @@ int HWCSession::HandleBuiltInDisplays() {
continue;
}
- if (registered_builtin_displays_ >= max_sde_builtin_displays_) {
- DLOGI("Maximum supported built-in displays (= %d) created.", max_sde_builtin_displays_);
- break;
- }
-
- if (registered_builtin_displays_ >= INT32(map_info_builtin_.size())) {
- DLOGW("Insufficient builtin display slots. All displays could not be created.");
- return 0;
- }
-
- DisplayMapInfo &map_info = map_info_builtin_[UINT32(registered_builtin_displays_)];
- hwc2_display_t client_id = map_info.client_id;
+ for (auto &map_info : map_info_builtin_) {
+ hwc2_display_t client_id = map_info.client_id;
- // Lock confined to this scope
- {
- SCOPE_LOCK(locker_[client_id]);
+ {
+ SCOPE_LOCK(locker_[client_id]);
+ // Lock confined to this scope
+ if (hwc_display_[client_id]) {
+ continue;
+ }
- DLOGI("Create builtin display, sdm id = %d, client id = %d", info.display_id, client_id);
- status = HWCDisplayBuiltIn::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
- qservice_, client_id, info.display_id,
- &hwc_display_[client_id]);
- if (!status) {
+ DLOGI("Create builtin display, sdm id = %d, client id = %d", info.display_id, client_id);
+ status = HWCDisplayBuiltIn::Create(core_intf_, &buffer_allocator_, &callbacks_, this,
+ qservice_, client_id, info.display_id,
+ &hwc_display_[client_id]);
+ if (status) {
+ DLOGE("Builtin display creation failed.");
+ break;
+ }
DLOGI("Builtin display created: 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;
- registered_builtin_displays_++;
- } else {
- DLOGE("Builtin display creation failed.");
- // Attempt creating remaining builtin displays.
- continue;
}
- }
- DLOGI("Hotplugging builtin display, sdm id = %d, client id = %d", info.display_id, client_id);
- callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
+ DLOGI("Hotplugging builtin display, sdm id = %d, client id = %d", info.display_id, client_id);
+ callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
+ break;
+ }
}
return status;
@@ -2585,13 +2565,11 @@ int HWCSession::HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool d
}
// Count active pluggable display slots and slots with no commits.
- int32_t display_slots_used = 0;
bool first_commit_pending = false;
std::for_each(map_info_pluggable_.begin(), map_info_pluggable_.end(),
[&](auto &p) {
SCOPE_LOCK(locker_[p.client_id]);
if (hwc_display_[p.client_id]) {
- display_slots_used++;
if (!hwc_display_[p.client_id]->IsFirstCommitDone()) {
DLOGI("Display commit pending on display %d-1", p.sdm_id);
first_commit_pending = true;
@@ -2599,11 +2577,6 @@ int HWCSession::HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool d
}
});
- if (display_slots_used >= max_sde_pluggable_displays_) {
- DLOGW("Pluggable display instance limit reached. %d pluggable displays connected.",
- display_slots_used);
- break;
- }
if (!disable_hotplug_bwcheck_ && first_commit_pending) {
// Hotplug bandwidth check is accomplished by creating and hotplugging a new display after
// a display commit has happened on previous hotplugged displays. This allows the driver to
@@ -2787,9 +2760,6 @@ void HWCSession::DestroyNonPluggableDisplay(DisplayMapInfo *map_info) {
switch (map_info->disp_type) {
case kBuiltIn:
HWCDisplayBuiltIn::Destroy(hwc_display);
- if (registered_builtin_displays_) {
- registered_builtin_displays_--;
- }
break;
default:
HWCDisplayVirtual::Destroy(hwc_display);
@@ -2845,10 +2815,6 @@ HWC2::Error HWCSession::PresentDisplayInternal(hwc2_display_t display, int32_t *
}
void HWCSession::DisplayPowerReset() {
- hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
- if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
- active_builtin_disp_id = HWC_DISPLAY_PRIMARY;
- }
// Acquire lock on all displays.
for (hwc2_display_t display = HWC_DISPLAY_PRIMARY;
display < HWCCallbacks::kNumDisplays; display++) {
@@ -2887,10 +2853,10 @@ void HWCSession::DisplayPowerReset() {
}
}
- status = hwc_display_[active_builtin_disp_id]->SetVsyncEnabled(HWC2::Vsync::Enable);
+ hwc2_display_t vsync_source = GetNextVsyncSource();
+ status = hwc_display_[vsync_source]->SetVsyncEnabled(HWC2::Vsync::Enable);
if (status != HWC2::Error::None) {
- DLOGE("Enabling vsync failed for built-in %" PRIu64 " with error = %d", active_builtin_disp_id,
- status);
+ DLOGE("Enabling vsync failed for disp: %" PRIu64 " with error = %d", vsync_source, status);
}
// Release lock on all displays.
@@ -2898,7 +2864,8 @@ void HWCSession::DisplayPowerReset() {
display < HWCCallbacks::kNumDisplays; display++) {
locker_[display].Unlock();
}
- Refresh(active_builtin_disp_id);
+
+ Refresh(vsync_source);
}
void HWCSession::HandleSecureSession() {
@@ -3055,8 +3022,17 @@ int32_t HWCSession::SetReadbackBuffer(hwc2_device_t *device, hwc2_display_t disp
}
HWCSession *hwc_session = static_cast<HWCSession *>(device);
- if (hwc_session->hwc_display_[HWC_DISPLAY_EXTERNAL] ||
- hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
+ hwc2_display_t external_display_index =
+ (hwc2_display_t)hwc_session->GetDisplayIndex(qdutils::DISPLAY_EXTERNAL);
+ hwc2_display_t virtual_display_index =
+ (hwc2_display_t)hwc_session->GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
+
+ if ((external_display_index == -1) || (virtual_display_index == -1)) {
+ return HWC2_ERROR_UNSUPPORTED;
+ }
+
+ if (hwc_session->hwc_display_[external_display_index] ||
+ hwc_session->hwc_display_[virtual_display_index]) {
return HWC2_ERROR_UNSUPPORTED;
}