diff options
author | Varun Arora <varuaror@codeaurora.org> | 2019-02-07 14:25:28 -0800 |
---|---|---|
committer | Varun Arora <varuaror@codeaurora.org> | 2019-02-07 14:25:28 -0800 |
commit | fa90e204a7f95300e1b50a2949b13c7748a62a88 (patch) | |
tree | 6f3c71c42917adcb8d68e4d1e75a3d7be2fcf9e2 /sdm/libs/hwc2/hwc_session.cpp | |
parent | b18d78f17059dd961c8f70403d9eb519360c6034 (diff) | |
parent | 467f45c2ca4e5fb076729adb310a352dc1f15928 (diff) |
Merge remote-tracking branch 'quic/display.lnx.5.0' into tip
2/7/2019 FF
Change-Id: I78cdd49ab0f4da7ec24e9009ee5dd2cf0cb94ada
CRs-Fixed: 2395201
Diffstat (limited to 'sdm/libs/hwc2/hwc_session.cpp')
-rw-r--r-- | sdm/libs/hwc2/hwc_session.cpp | 238 |
1 files changed, 155 insertions, 83 deletions
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp index 6c6e56f9..cf52eec7 100644 --- a/sdm/libs/hwc2/hwc_session.cpp +++ b/sdm/libs/hwc2/hwc_session.cpp @@ -77,7 +77,7 @@ static const int kSolidFillDelay = 100 * 1000; int HWCSession::null_display_mode_ = 0; // Map the known color modes to dataspace. -static int32_t GetDataspace(ColorMode mode) { +int32_t GetDataspaceFromColorMode(ColorMode mode) { switch (mode) { case ColorMode::SRGB: case ColorMode::NATIVE: @@ -449,15 +449,15 @@ int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t return HWC2_ERROR_BAD_DISPLAY; } - Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]); auto *hwc_session = static_cast<HWCSession *>(device); + hwc2_display_t active_builtin_disp_id = hwc_session->GetActiveBuiltinDisplay(); - if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) { + if (active_builtin_disp_id < kNumDisplays) { + Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]); std::bitset<kSecureMax> secure_sessions = 0; - hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions); + hwc_session->hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions); if (secure_sessions.any()) { - DLOGI("Destroying virtual display id:%" PRIu64, display); - DLOGW("Secure session is active, deferring destruction of virtual display"); + DLOGW("Secure session is active, defer destruction of virtual display id:%" PRIu64, display); hwc_session->destroy_virtual_disp_pending_ = true; return HWC2_ERROR_NONE; } @@ -682,7 +682,7 @@ int32_t HWCSession::PresentDisplay(hwc2_device_t *device, hwc2_display_t display return HWC2_ERROR_BAD_DISPLAY; } - hwc_session->HandleSecureSession(display); + hwc_session->HandleSecureSession(); { SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]); if (!hwc_session->hwc_display_[display]) { @@ -1003,7 +1003,7 @@ int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t displa HWCSession *hwc_session = static_cast<HWCSession *>(device); // TODO(user): Handle secure session, handle QDCM solid fill auto status = HWC2::Error::BadDisplay; - hwc_session->HandleSecureSession(display); + hwc_session->HandleSecureSession(); { SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]); if (power_on_pending_[display]) { @@ -1157,10 +1157,13 @@ HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, return HWC2::Error::NoResources; } - if (hwc_display_[HWC_DISPLAY_PRIMARY]) { - SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); + hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); + if (active_builtin_disp_id < kNumDisplays) { + SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]); std::bitset<kSecureMax> secure_sessions = 0; - hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions); + if (hwc_display_[active_builtin_disp_id]) { + hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions); + } if (secure_sessions.any()) { DLOGE("Secure session is active, cannot create virtual display."); return HWC2::Error::Unsupported; @@ -1196,6 +1199,13 @@ HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, 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 @@ -1210,12 +1220,14 @@ HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, } if (status) { - return HWC2::Error::BadDisplay; + return HWC2::Error::NoResources; } } - SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); - hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation(); + if (active_builtin_disp_id < kNumDisplays) { + SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]); + hwc_display_[active_builtin_disp_id]->ResetValidation(); + } return HWC2::Error::None; } @@ -1546,6 +1558,14 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa status = GetSupportedDsiClk(input_parcel, output_parcel); break; + case qService::IQService::SET_COLOR_MODE_FROM_CLIENT: + if (!input_parcel) { + DLOGE("QService command = %d: input_parcel needed.", command); + break; + } + status = SetColorModeFromClient(input_parcel); + break; + default: DLOGW("QService command = %d is not supported.", command); break; @@ -1818,6 +1838,27 @@ android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parc return 0; } +android::status_t HWCSession::SetColorModeFromClient(const android::Parcel *input_parcel) { + int display = input_parcel->readInt32(); + auto mode = input_parcel->readInt32(); + auto device = static_cast<hwc2_device_t *>(this); + + int disp_idx = GetDisplayIndex(display); + if (disp_idx == -1) { + DLOGE("Invalid display = %d", display); + return -EINVAL; + } + + auto err = CallDisplayFunction(device, static_cast<hwc2_display_t>(disp_idx), + &HWCDisplay::SetColorModeFromClientApi, mode); + if (err != HWC2_ERROR_NONE) + return -EINVAL; + + Refresh(static_cast<hwc2_display_t>(disp_idx)); + + return 0; +} + android::status_t HWCSession::RefreshScreen(const android::Parcel *input_parcel) { int display = input_parcel->readInt32(); @@ -2185,9 +2226,10 @@ void HWCSession::UEventHandler(const char *uevent_data, int length) { (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL); std::bitset<kSecureMax> secure_sessions = 0; - { - Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]); - hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions); + hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); + if (active_builtin_disp_id < kNumDisplays) { + Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]); + hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions); } if (secure_sessions[kSecureDisplay] || hwc_display_[virtual_display_index]) { // Defer hotplug events. @@ -2518,20 +2560,23 @@ int HWCSession::HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool d return status; } - // Primary display needs revalidation - { - SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); - hwc_display_[HWC_DISPLAY_PRIMARY]->ResetValidation(); - } + // Active builtin display needs revalidation + hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); + if (active_builtin_disp_id < kNumDisplays) { + { + SCOPE_LOCK(locker_[active_builtin_disp_id]); + hwc_display_[active_builtin_disp_id]->ResetValidation(); + } - if (client_connected_) { - Refresh(HWC_DISPLAY_PRIMARY); - } + if (client_connected_) { + Refresh(active_builtin_disp_id); + } - // Do not sleep if this method is called from client thread. - if (delay_hotplug) { - // wait sufficient time to ensure resources are available for new display connection. - usleep(UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY)) * 2 / 1000); + // Do not sleep if this method is called from client thread. + if (delay_hotplug) { + // wait sufficient time to ensure resources are available for new display connection. + usleep(UINT32(GetVsyncPeriod(INT32(active_builtin_disp_id))) * 2 / 1000); + } } for (auto client_id : pending_hotplugs) { @@ -2723,16 +2768,18 @@ void HWCSession::DisplayPowerReset() { Refresh(HWC_DISPLAY_PRIMARY); } -void HWCSession::HandleSecureSession(hwc2_display_t disp_id) { +void HWCSession::HandleSecureSession() { std::bitset<kSecureMax> secure_sessions = 0; { - Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]); - if (hwc_display_[HWC_DISPLAY_PRIMARY]) { - hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions); + hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); + if (active_builtin_disp_id >= kNumDisplays) { + return; } + Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]); + hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions); } - // If it is called during primary prepare/commit, we need to pause any onging commit on + // If it is called during primary prepare/commit, we need to pause any ongoing commit on // external/virtual display. for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < kNumDisplays; display++) { Locker::ScopeLock lock_d(locker_[display]); @@ -2743,17 +2790,20 @@ void HWCSession::HandleSecureSession(hwc2_display_t disp_id) { } void HWCSession::HandlePowerOnPending(hwc2_display_t disp_id, int retire_fence) { - if (disp_id != HWC_DISPLAY_PRIMARY) { + hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); + if (disp_id != active_builtin_disp_id) { return; } - Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]); + Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]); bool power_on_pending = false; - for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1; display < kNumDisplays; display++) { - Locker::ScopeLock lock_d(locker_[display]); - if (power_on_pending_[display]) { - power_on_pending = true; - break; + for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < kNumDisplays; display++) { + if (display != active_builtin_disp_id) { + Locker::ScopeLock lock_d(locker_[display]); + if (power_on_pending_[display]) { + power_on_pending = true; + break; + } } } if (power_on_pending) { @@ -2771,56 +2821,59 @@ void HWCSession::HandlePowerOnPending(hwc2_display_t disp_id, int retire_fence) return; } - for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1; display < kNumDisplays; display++) { - Locker::ScopeLock lock_d(locker_[display]); - if (power_on_pending_[display] && hwc_display_[display]) { - HWC2::Error status = + for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < kNumDisplays; display++) { + if (display != active_builtin_disp_id) { + Locker::ScopeLock lock_d(locker_[display]); + if (power_on_pending_[display] && hwc_display_[display]) { + HWC2::Error status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::On, false /* teardown */); - if (status == HWC2::Error::None) { - power_on_pending_[display] = false; + if (status == HWC2::Error::None) { + power_on_pending_[display] = false; + } } } } } void HWCSession::HandleHotplugPending(hwc2_display_t disp_id, int retire_fence) { - if (disp_id != HWC_DISPLAY_PRIMARY || + hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); + if (disp_id != active_builtin_disp_id || (kHotPlugNone == hotplug_pending_event_ && !destroy_virtual_disp_pending_)) { return; } std :: bitset < kSecureMax > secure_sessions = 0; - { - Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]); - if (hwc_display_[HWC_DISPLAY_PRIMARY]) { - if (!hwc_display_[HWC_DISPLAY_PRIMARY]->IsDisplayCommandMode()) { - if (destroy_virtual_disp_pending_ || kHotPlugEvent == hotplug_pending_event_) { - if (retire_fence >= 0) { - int error = sync_wait(retire_fence, 1000); - if (error < 0) { - DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); - } - } - } + if (active_builtin_disp_id < kNumDisplays) { + Locker::ScopeLock lock_a(locker_[active_builtin_disp_id]); + hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions); + } + + if (secure_sessions.any() || active_builtin_disp_id == kNumDisplays) { + return; + } + + if (destroy_virtual_disp_pending_ || kHotPlugEvent == hotplug_pending_event_) { + if (retire_fence >= 0) { + int error = sync_wait(retire_fence, 1000); + if (error < 0) { + DLOGE("sync_wait error errno = %d, desc = %s", errno, strerror(errno)); } - hwc_display_[HWC_DISPLAY_PRIMARY]->GetActiveSecureSession(&secure_sessions); } - } - // Destroy the pending virtual display if secure session not present. - if (!secure_sessions.any() && destroy_virtual_disp_pending_) { - for (auto &map_info : map_info_virtual_) { - DestroyDisplay(&map_info); - destroy_virtual_disp_pending_ = false; + // Destroy the pending virtual display if secure session not present. + if (destroy_virtual_disp_pending_) { + for (auto &map_info : map_info_virtual_) { + DestroyDisplay(&map_info); + destroy_virtual_disp_pending_ = false; + } } - } - // Handle connect/disconnect hotplugs if secure session is not present. - hwc2_display_t virtual_display_index = (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL); - if (!secure_sessions.any() && !hwc_display_[virtual_display_index] && - kHotPlugEvent == hotplug_pending_event_) { - if (HandlePluggableDisplays(true)) { - DLOGE("Could not handle hotplug. Event dropped."); + // Handle connect/disconnect hotplugs if secure session is not present. + hwc2_display_t virtual_display_idx = (hwc2_display_t)GetDisplayIndex(qdutils::DISPLAY_VIRTUAL); + if (!hwc_display_[virtual_display_idx] && kHotPlugEvent == hotplug_pending_event_) { + if (HandlePluggableDisplays(true)) { + DLOGE("Could not handle hotplug. Event dropped."); + } + hotplug_pending_event_ = kHotPlugNone; } - hotplug_pending_event_ = kHotPlugNone; } } @@ -2839,7 +2892,7 @@ int32_t HWCSession::GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_disp if (hwc_display) { *format = HAL_PIXEL_FORMAT_RGB_888; - *dataspace = GetDataspace(hwc_display->GetCurrentColorMode()); + *dataspace = GetDataspaceFromColorMode(hwc_display->GetCurrentColorMode()); return HWC2_ERROR_NONE; } @@ -2976,18 +3029,23 @@ android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) { return static_cast<android::status_t>(controlIdlePowerCollapse(enable, synchronous)); #else { - SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); - if (hwc_display_[HWC_DISPLAY_PRIMARY]) { + hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay(); + if (active_builtin_disp_id >= kNumDisplays) { + DLOGE("No active displays"); + return -EINVAL; + } + SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]); + if (hwc_display_[active_builtin_disp_id]) { DLOGE("Primary display is not ready"); return -EINVAL; } - auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous); - if (error != kErrorNone) { - return (error == kErrorNotSupported) ? 0 : -EINVAL; + auto err = hwc_display_[active_builtin_disp_id]->ControlIdlePowerCollapse(enable, synchronous); + if (err != kErrorNone) { + return (err == kErrorNotSupported) ? 0 : -EINVAL; } if (!enable) { - Refresh(HWC_DISPLAY_PRIMARY); - int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs); + Refresh(active_builtin_disp_id); + int32_t error = locker_[active_builtin_disp_id].WaitFinite(kCommitDoneTimeoutMs); if (error == ETIMEDOUT) { DLOGE("Timed out!! Next frame commit done event not received!!"); return error; @@ -2999,4 +3057,18 @@ android::status_t HWCSession::SetIdlePC(const android::Parcel *input_parcel) { #endif } +hwc2_display_t HWCSession::GetActiveBuiltinDisplay() { + hwc2_display_t disp_id = kNumDisplays; + Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]); + Locker::ScopeLock lock_b2(locker_[HWC_DISPLAY_BUILTIN_2]); + if (hwc_display_[HWC_DISPLAY_PRIMARY] && + hwc_display_[HWC_DISPLAY_PRIMARY]->GetCurrentPowerMode() == HWC2::PowerMode::On) { + disp_id = HWC_DISPLAY_PRIMARY; + } else if (hwc_display_[HWC_DISPLAY_BUILTIN_2] && + hwc_display_[HWC_DISPLAY_BUILTIN_2]->GetCurrentPowerMode() == HWC2::PowerMode::On) { + disp_id = HWC_DISPLAY_BUILTIN_2; + } + return disp_id; +} + } // namespace sdm |