summaryrefslogtreecommitdiff
path: root/sdm/libs/hwc2/hwc_session.cpp
diff options
context:
space:
mode:
authorVarun Arora <varuaror@codeaurora.org>2019-02-07 14:25:28 -0800
committerVarun Arora <varuaror@codeaurora.org>2019-02-07 14:25:28 -0800
commitfa90e204a7f95300e1b50a2949b13c7748a62a88 (patch)
tree6f3c71c42917adcb8d68e4d1e75a3d7be2fcf9e2 /sdm/libs/hwc2/hwc_session.cpp
parentb18d78f17059dd961c8f70403d9eb519360c6034 (diff)
parent467f45c2ca4e5fb076729adb310a352dc1f15928 (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.cpp238
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