Merge "sdm: Handle idle fall back and idle power collapse with same event"
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index b8e2a9e..142d2c6 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -137,8 +137,9 @@
/*! @brief This enum represents the events received by Display HAL. */
enum DisplayEvent {
- kIdleTimeout, // Event triggered by Idle Timer.
- kThermalEvent, // Event triggered by Thermal.
+ kIdleTimeout, // Event triggered by Idle Timer.
+ kThermalEvent, // Event triggered by Thermal.
+ kIdlePowerCollapse, // Event triggered by Idle Power Collapse.
};
/*! @brief This structure defines configuration for fixed properties of a display device.
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index 64a0bcc..8f3d6f0 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -280,10 +280,15 @@
}
void DisplayPrimary::IdleTimeout() {
- handle_idle_timeout_ = true;
- event_handler_->Refresh();
- comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
- event_handler_->HandleEvent(kIdleTimeout);
+ if (hw_panel_info_.mode == kModeCommand) {
+ IdlePowerCollapse();
+ } else {
+ event_handler_->HandleEvent(kIdleTimeout);
+ handle_idle_timeout_ = true;
+ event_handler_->Refresh();
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
+ }
}
void DisplayPrimary::PingPongTimeout() {
@@ -292,12 +297,13 @@
}
void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
+ event_handler_->HandleEvent(kThermalEvent);
lock_guard<recursive_mutex> obj(recursive_mutex_);
comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
- event_handler_->HandleEvent(kThermalEvent);
}
void DisplayPrimary::IdlePowerCollapse() {
+ event_handler_->HandleEvent(kIdlePowerCollapse);
lock_guard<recursive_mutex> obj(recursive_mutex_);
comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
}
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index d112b67..380d162 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -40,6 +40,7 @@
#include "hwc_display.h"
#include "hwc_debugger.h"
#include "hwc_tonemapper.h"
+#include "hwc_session.h"
#ifndef USE_GRALLOC1
#include <gr.h>
@@ -952,6 +953,8 @@
switch (event) {
case kIdleTimeout:
case kThermalEvent:
+ case kIdlePowerCollapse:
+ HWCSession::WaitForSequence(id_);
validated_.reset();
break;
default:
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 2039a46..89de074 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -70,7 +70,7 @@
namespace sdm {
static HWCUEvent g_hwc_uevent_;
-Locker HWCSession::locker_;
+Locker HWCSession::locker_[HWC_NUM_DISPLAY_TYPES];
void HWCUEvent::UEventThread(HWCUEvent *hwc_uevent) {
const char *uevent_thread_name = "HWC_UeventThread";
@@ -135,6 +135,8 @@
}
int HWCSession::Init() {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+
int status = -EINVAL;
const char *qservice_name = "display.qservice";
@@ -224,6 +226,10 @@
}
int HWCSession::Deinit() {
+ Locker::SequenceCancelScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
+ Locker::SequenceCancelScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
+ Locker::SequenceCancelScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
+
HWCDisplay *primary_display = hwc_display_[HWC_DISPLAY_PRIMARY];
if (primary_display) {
if (hdmi_is_primary_) {
@@ -249,8 +255,6 @@
}
int HWCSession::Open(const hw_module_t *module, const char *name, hw_device_t **device) {
- SCOPE_LOCK(locker_);
-
if (!module || !name || !device) {
DLOGE("Invalid parameters.");
return -EINVAL;
@@ -275,8 +279,6 @@
}
int HWCSession::Close(hw_device_t *device) {
- SCOPE_LOCK(locker_);
-
if (!device) {
return -EINVAL;
}
@@ -317,20 +319,20 @@
// Defined in the same order as in the HWC2 header
int32_t HWCSession::AcceptDisplayChanges(hwc2_device_t *device, hwc2_display_t display) {
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[display]);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::AcceptDisplayChanges);
}
int32_t HWCSession::CreateLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t *out_layer_id) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
return CallDisplayFunction(device, display, &HWCDisplay::CreateLayer, out_layer_id);
}
int32_t HWCSession::CreateVirtualDisplay(hwc2_device_t *device, uint32_t width, uint32_t height,
int32_t *format, hwc2_display_t *out_display_id) {
// TODO(user): Handle concurrency with HDMI
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
@@ -349,16 +351,16 @@
int32_t HWCSession::DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t layer) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
return CallDisplayFunction(device, display, &HWCDisplay::DestroyLayer, layer);
}
int32_t HWCSession::DestroyVirtualDisplay(hwc2_device_t *device, hwc2_display_t display) {
- SCOPE_LOCK(locker_);
if (!device || display != HWC_DISPLAY_VIRTUAL) {
return HWC2_ERROR_BAD_DISPLAY;
}
+ SCOPE_LOCK(locker_[display]);
DLOGI("Destroying virtual display id:%" PRIu64, display);
auto *hwc_session = static_cast<HWCSession *>(device);
@@ -372,8 +374,6 @@
}
void HWCSession::Dump(hwc2_device_t *device, uint32_t *out_size, char *out_buffer) {
- SCOPE_LOCK(locker_);
-
if (!device) {
return;
}
@@ -387,6 +387,7 @@
DumpInterface::GetDump(sdm_dump, 4096); // TODO(user): Fix this workaround
std::string s("");
for (int id = HWC_DISPLAY_PRIMARY; id <= HWC_DISPLAY_VIRTUAL; id++) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[id]);
if (hwc_session->hwc_display_[id]) {
s += hwc_session->hwc_display_[id]->Dump();
}
@@ -490,6 +491,7 @@
int32_t *out_retire_fence) {
HWCSession *hwc_session = static_cast<HWCSession *>(device);
DTRACE_SCOPED();
+ SEQUENCE_EXIT_SCOPE_LOCK(locker_[display]);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
}
@@ -541,14 +543,14 @@
int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
int32_t /*android_color_mode_t*/ int_mode) {
auto mode = static_cast<android_color_mode_t>(int_mode);
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[display]);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
}
int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
const float *matrix,
int32_t /*android_color_transform_t*/ hint) {
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[display]);
android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
transform_hint);
@@ -634,7 +636,7 @@
int32_t HWCSession::SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
hwc2_layer_t layer, uint32_t z) {
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[display]);
return CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
}
@@ -648,6 +650,7 @@
return HWC2_ERROR_UNSUPPORTED;
}
+ SCOPE_LOCK(locker_[display]);
auto *hwc_session = static_cast<HWCSession *>(device);
if (hwc_session->hwc_display_[display]) {
auto vds = reinterpret_cast<HWCDisplayVirtual *>(hwc_session->hwc_display_[display]);
@@ -660,7 +663,7 @@
int32_t HWCSession::SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode) {
auto mode = static_cast<HWC2::PowerMode>(int_mode);
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
return CallDisplayFunction(device, display, &HWCDisplay::SetPowerMode, mode);
}
@@ -672,7 +675,6 @@
int32_t HWCSession::ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_types, uint32_t *out_num_requests) {
DTRACE_SCOPED();
- SCOPE_LOCK(locker_);
HWCSession *hwc_session = static_cast<HWCSession *>(device);
if (!device) {
return HWC2_ERROR_BAD_DISPLAY;
@@ -681,25 +683,35 @@
// TODO(user): Handle secure session, handle QDCM solid fill
// Handle external_pending_connect_ in CreateVirtualDisplay
auto status = HWC2::Error::BadDisplay;
- if (hwc_session->hwc_display_[display]) {
- if (display == HWC_DISPLAY_PRIMARY) {
- // TODO(user): This can be moved to HWCDisplayPrimary
- if (hwc_session->reset_panel_) {
- DLOGW("panel is in bad state, resetting the panel");
- hwc_session->ResetPanel();
+ {
+ SEQUENCE_ENTRY_SCOPE_LOCK(locker_[display]);
+ if (hwc_session->hwc_display_[display]) {
+ if (display == HWC_DISPLAY_PRIMARY) {
+ // TODO(user): This can be moved to HWCDisplayPrimary
+ if (hwc_session->reset_panel_) {
+ DLOGW("panel is in bad state, resetting the panel");
+ hwc_session->ResetPanel();
+ }
+
+ if (hwc_session->need_invalidate_) {
+ hwc_session->Refresh(display);
+ }
+
+ if (hwc_session->color_mgr_) {
+ hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
+ }
}
- if (hwc_session->need_invalidate_) {
- hwc_session->Refresh(display);
- }
-
- if (hwc_session->color_mgr_) {
- hwc_session->color_mgr_->SetColorModeDetailEnhancer(hwc_session->hwc_display_[display]);
- }
+ status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
}
-
- status = hwc_session->hwc_display_[display]->Validate(out_num_types, out_num_requests);
}
+
+ // If validate fails, cancel the sequence lock so that other operations
+ // (such as Dump or SetPowerMode) may succeed without blocking on the condition
+ if (status == HWC2::Error::BadDisplay) {
+ SEQUENCE_CANCEL_SCOPE_LOCK(locker_[display]);
+ }
+
return INT32(status);
}
@@ -1013,8 +1025,6 @@
android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
*input_parcel,
android::Parcel *output_parcel) {
- SCOPE_LOCK(locker_);
-
int config = input_parcel->readInt32();
int dpy = input_parcel->readInt32();
int error = android::BAD_VALUE;
@@ -1024,6 +1034,7 @@
return android::BAD_VALUE;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
if (hwc_display_[dpy]) {
error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
if (error == 0) {
@@ -1040,7 +1051,7 @@
}
android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
uint32_t operation = UINT32(input_parcel->readInt32());
HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
@@ -1066,20 +1077,19 @@
}
android::status_t HWCSession::SetDisplayMode(const android::Parcel *input_parcel) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
uint32_t mode = UINT32(input_parcel->readInt32());
return hwc_display_[HWC_DISPLAY_PRIMARY]->Perform(HWCDisplayPrimary::SET_DISPLAY_MODE, mode);
}
android::status_t HWCSession::SetMaxMixerStages(const android::Parcel *input_parcel) {
- SCOPE_LOCK(locker_);
-
DisplayError error = kErrorNone;
std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
uint32_t max_mixer_stages = UINT32(input_parcel->readInt32());
if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetMaxMixerStages(max_mixer_stages);
if (error != kErrorNone) {
@@ -1089,6 +1099,7 @@
}
if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
error = hwc_display_[HWC_DISPLAY_EXTERNAL]->SetMaxMixerStages(max_mixer_stages);
if (error != kErrorNone) {
@@ -1098,6 +1109,7 @@
}
if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
error = hwc_display_[HWC_DISPLAY_VIRTUAL]->SetMaxMixerStages(max_mixer_stages);
if (error != kErrorNone) {
@@ -1110,25 +1122,26 @@
}
void HWCSession::SetFrameDumpConfig(const android::Parcel *input_parcel) {
- SCOPE_LOCK(locker_);
-
uint32_t frame_dump_count = UINT32(input_parcel->readInt32());
std::bitset<32> bit_mask_display_type = UINT32(input_parcel->readInt32());
uint32_t bit_mask_layer_type = UINT32(input_parcel->readInt32());
if (bit_mask_display_type[HWC_DISPLAY_PRIMARY]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
hwc_display_[HWC_DISPLAY_PRIMARY]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
if (bit_mask_display_type[HWC_DISPLAY_EXTERNAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
hwc_display_[HWC_DISPLAY_EXTERNAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
}
if (bit_mask_display_type[HWC_DISPLAY_VIRTUAL]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_VIRTUAL]);
if (hwc_display_[HWC_DISPLAY_VIRTUAL]) {
hwc_display_[HWC_DISPLAY_VIRTUAL]->SetFrameDumpConfig(frame_dump_count, bit_mask_layer_type);
}
@@ -1136,8 +1149,6 @@
}
android::status_t HWCSession::SetMixerResolution(const android::Parcel *input_parcel) {
- SCOPE_LOCK(locker_);
-
DisplayError error = kErrorNone;
uint32_t dpy = UINT32(input_parcel->readInt32());
@@ -1146,6 +1157,7 @@
return -EINVAL;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
DLOGI("Primary display is not initialized");
return -EINVAL;
@@ -1166,6 +1178,8 @@
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
auto device = static_cast<hwc2_device_t *>(this);
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1181,6 +1195,7 @@
return -EINVAL;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorModeById, mode);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
@@ -1188,7 +1203,7 @@
}
void HWCSession::DynamicDebug(const android::Parcel *input_parcel) {
- SCOPE_LOCK(locker_);
+ // TODO(user): Do we really need a lock here?
int type = input_parcel->readInt32();
bool enable = (input_parcel->readInt32() > 0);
@@ -1427,13 +1442,12 @@
// To prevent sending events to client while a lock is held, acquire scope locks only within
// below scope so that those get automatically unlocked after the scope ends.
do {
- SCOPE_LOCK(locker_);
-
// If HDMI is primary but not created yet (first time), create it and notify surfaceflinger.
// if it is already created, but got disconnected/connected again,
// just toggle display status and do not notify surfaceflinger.
// If HDMI is not primary, create/destroy external display normally.
if (hdmi_is_primary_) {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetState(connected);
} else {
@@ -1445,13 +1459,18 @@
break;
}
- // Primary display must be connected for HDMI as secondary cases.
- if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
- DLOGE("Primary display is not connected.");
- return -1;
+ {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
+ // Primary display must be connected for HDMI as secondary cases.
+ if (!hwc_display_[HWC_DISPLAY_PRIMARY]) {
+ DLOGE("Primary display is not connected.");
+ return -1;
+ }
}
if (connected) {
+ SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
+ Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
// Connect external display if virtual display is not connected.
// Else, defer external display connection and process it when virtual display
// tears down; Do not notify SurfaceFlinger since connection is deferred now.
@@ -1466,6 +1485,7 @@
external_pending_connect_ = true;
}
} else {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_EXTERNAL]);
// Do not return error if external display is not in connected status.
// Due to virtual display concurrency, external display connection might be still pending
// but hdmi got disconnected before pending connection could be processed.
@@ -1500,7 +1520,7 @@
}
int HWCSession::GetVsyncPeriod(int disp) {
- SCOPE_LOCK(locker_);
+ SCOPE_LOCK(locker_[disp]);
// default value
int32_t vsync_period = 1000000000l / 60;
auto attribute = HWC2::Attribute::VsyncPeriod;
@@ -1514,14 +1534,12 @@
android::status_t HWCSession::GetVisibleDisplayRect(const android::Parcel *input_parcel,
android::Parcel *output_parcel) {
- SCOPE_LOCK(locker_);
-
int dpy = input_parcel->readInt32();
-
if (dpy < HWC_DISPLAY_PRIMARY || dpy > HWC_DISPLAY_VIRTUAL) {
return android::BAD_VALUE;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]);
if (!hwc_display_[dpy]) {
return android::NO_INIT;
}
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index f09ed0e..4dbcf9b 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -140,6 +140,12 @@
static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
const float *matrix, int32_t /*android_color_transform_t*/ hint);
+ // Meant to be called by HWCDisplay to preserve sequence of validate/present during events from
+ // polling thread
+ static void WaitForSequence(hwc2_display_t display) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
+ }
+
private:
static const int kExternalConnectionTimeoutMs = 500;
static const int kPartialUpdateControlTimeoutMs = 100;
@@ -221,7 +227,7 @@
void Refresh(hwc2_display_t display);
void HotPlug(hwc2_display_t display, HWC2::Connection state);
- static Locker locker_;
+ static Locker locker_[HWC_NUM_DISPLAY_TYPES];
CoreInterface *core_intf_ = nullptr;
HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
HWCCallbacks callbacks_;
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 425ffbe..a5cf66a 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -92,12 +92,12 @@
// Methods from ::vendor::hardware::display::config::V1_0::IDisplayConfig follow.
Return<void> HWCSession::isDisplayConnected(IDisplayConfig::DisplayType dpy,
isDisplayConnected_cb _hidl_cb) {
- SCOPE_LOCK(locker_);
-
int32_t error = -EINVAL;
bool connected = false;
int disp_id = MapDisplayType(dpy);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+
if (disp_id >= 0) {
connected = hwc_display_[disp_id];
error = 0;
@@ -109,12 +109,11 @@
}
int32_t HWCSession::SetSecondaryDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) {
- SCOPE_LOCK(locker_);
-
if (disp_id < 0) {
return -EINVAL;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
DLOGI("Display = %d, Status = %d", disp_id, status);
if (disp_id == HWC_DISPLAY_PRIMARY) {
@@ -135,8 +134,7 @@
Return<int32_t> HWCSession::configureDynRefeshRate(IDisplayConfig::DisplayDynRefreshRateOp op,
uint32_t refreshRate) {
- SCOPE_LOCK(locker_);
-
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
switch (op) {
@@ -158,9 +156,13 @@
}
int32_t HWCSession::GetConfigCount(int disp_id, uint32_t *count) {
- SCOPE_LOCK(locker_);
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
- if (disp_id >= 0 && hwc_display_[disp_id]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+
+ if (hwc_display_[disp_id]) {
return hwc_display_[disp_id]->GetDisplayConfigCount(count);
}
@@ -178,9 +180,13 @@
}
int32_t HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) {
- SCOPE_LOCK(locker_);
+ if (disp_id < 0) {
+ return -EINVAL;
+ }
- if (disp_id >= 0 && hwc_display_[disp_id]) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
+
+ if (hwc_display_[disp_id]) {
return hwc_display_[disp_id]->GetActiveDisplayConfig(config);
}
@@ -198,12 +204,11 @@
}
int32_t HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) {
- SCOPE_LOCK(locker_);
-
if (disp_id < 0) {
return -EINVAL;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
int32_t error = -EINVAL;
if (hwc_display_[disp_id]) {
error = hwc_display_[disp_id]->SetActiveDisplayConfig(config);
@@ -222,12 +227,11 @@
Return<void> HWCSession::getDisplayAttributes(uint32_t configIndex,
IDisplayConfig::DisplayType dpy,
getDisplayAttributes_cb _hidl_cb) {
- SCOPE_LOCK(locker_);
-
int32_t error = -EINVAL;
IDisplayConfig::DisplayAttributes display_attributes = {};
-
int disp_id = MapDisplayType(dpy);
+
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
if (disp_id >= 0 && hwc_display_[disp_id]) {
DisplayConfigVariableInfo hwc_display_attributes;
error = hwc_display_[disp_id]->GetDisplayAttributesForConfig(static_cast<int>(configIndex),
@@ -247,9 +251,9 @@
}
Return<int32_t> HWCSession::setPanelBrightness(uint32_t level) {
- SCOPE_LOCK(locker_);
-
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
int32_t error = -EINVAL;
+
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
error = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPanelBrightness(static_cast<int>(level));
if (error) {
@@ -261,8 +265,7 @@
}
int32_t HWCSession::GetPanelBrightness(int *level) {
- SCOPE_LOCK(locker_);
-
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
int32_t error = -EINVAL;
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
@@ -285,14 +288,13 @@
}
int32_t HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) {
- SCOPE_LOCK(locker_);
-
DLOGI("Display %d", disp_id);
if (disp_id < 0) {
return -EINVAL;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
if (disp_id != HWC_DISPLAY_EXTERNAL) {
DLOGE("Not supported for display");
} else if (!hwc_display_[disp_id]) {
@@ -310,16 +312,13 @@
}
Return<int32_t> HWCSession::refreshScreen() {
- SCOPE_LOCK(locker_);
-
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
Refresh(HWC_DISPLAY_PRIMARY);
return 0;
}
int32_t HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
- SCOPE_LOCK(locker_);
-
if (disp_id < 0) {
return -EINVAL;
}
@@ -329,6 +328,7 @@
return -EINVAL;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
if (!hwc_display) {
DLOGE("primary display object is not instantiated");
@@ -352,7 +352,7 @@
Refresh(HWC_DISPLAY_PRIMARY);
// Wait until partial update control is complete
- int32_t error = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
+ int32_t error = locker_[disp_id].WaitFinite(kPartialUpdateControlTimeoutMs);
return error;
}
@@ -362,7 +362,7 @@
}
Return<int32_t> HWCSession::toggleScreenUpdate(bool on) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
int32_t error = -EINVAL;
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
@@ -376,7 +376,7 @@
}
Return<int32_t> HWCSession::setIdleTimeout(uint32_t value) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(value);
@@ -388,8 +388,6 @@
Return<void> HWCSession::getHDRCapabilities(IDisplayConfig::DisplayType dpy,
getHDRCapabilities_cb _hidl_cb) {
- SCOPE_LOCK(locker_);
-
int32_t error = -EINVAL;
IDisplayConfig::DisplayHDRCapabilities hdr_caps = {};
@@ -400,6 +398,7 @@
break;
}
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_id]);
HWCDisplay *hwc_display = hwc_display_[disp_id];
if (!hwc_display) {
DLOGE("Display = %d is not connected.", disp_id);
@@ -438,7 +437,7 @@
}
Return<int32_t> HWCSession::setCameraLaunchStatus(uint32_t on) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
@@ -457,7 +456,7 @@
}
int32_t HWCSession::DisplayBWTransactionPending(bool *status) {
- SCOPE_LOCK(locker_);
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);
if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
if (sync_wait(bw_mode_release_fd_, 0) < 0) {