summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPritama Biswas <pritbisw@codeaurora.org>2021-09-18 21:12:47 +0530
committerPritama Biswas <pritbisw@codeaurora.org>2021-09-27 15:11:36 +0530
commitb83651dc7a690a13eccb0757dd5d10787670bc4f (patch)
tree6ca5c772fe66ea6c1ce8d6ff6b1e8e20bf74cd48
parentc346a211b1f38ccb3ea492a6a0dd81ca286a1dde (diff)
hwc2: Add support for pluggable as primary
Change-Id: I25f45d1583fbf79146dd5d6323a2ca51b42c65ab
-rw-r--r--sdm/libs/hwc2/hwc_display.h3
-rw-r--r--sdm/libs/hwc2/hwc_display_dummy.cpp10
-rw-r--r--sdm/libs/hwc2/hwc_display_dummy.h5
-rw-r--r--sdm/libs/hwc2/hwc_display_pluggable.h4
-rw-r--r--sdm/libs/hwc2/hwc_session.cpp82
-rw-r--r--sdm/libs/hwc2/hwc_session.h1
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_;