Snap for 7364021 from 9bc4795125a764b4bc60c5eae13b6820ded2e637 to sc-release
Change-Id: If064094f7e24ad78b90e81c4a9d9381a8ecc300e
diff --git a/composer/cpuhint.cpp b/composer/cpuhint.cpp
index ca88ead..e63149f 100644
--- a/composer/cpuhint.cpp
+++ b/composer/cpuhint.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015, 2021, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -49,7 +49,6 @@
debug_handler->GetProperty(PERF_HINT_WINDOW_PROP, &pre_enable_window);
if (pre_enable_window <= 0) {
DLOGI("Invalid CPU Hint Pre-enable Window %d", pre_enable_window);
- return kErrorNotSupported;
}
DLOGI("CPU Hint Pre-enable Window %d", pre_enable_window);
@@ -57,7 +56,10 @@
if (vendor_ext_lib_.Open(path)) {
if (!vendor_ext_lib_.Sym("perf_lock_acq", reinterpret_cast<void **>(&fn_lock_acquire_)) ||
- !vendor_ext_lib_.Sym("perf_lock_rel", reinterpret_cast<void **>(&fn_lock_release_))) {
+ !vendor_ext_lib_.Sym("perf_lock_rel", reinterpret_cast<void **>(&fn_lock_release_)) ||
+ !vendor_ext_lib_.Sym("perf_hint", reinterpret_cast<void **>(&fn_perf_hint_)) ||
+ !vendor_ext_lib_.Sym("perf_hint_offload", reinterpret_cast<void **> \
+ (&fn_perf_hint_offload_))) {
DLOGW("Failed to load symbols for Vendor Extension Library");
return kErrorNotSupported;
}
@@ -67,7 +69,7 @@
DLOGW("Failed to open %s : %s", path, vendor_ext_lib_.Error());
}
- return kErrorNone;
+ return enabled_ ? kErrorNone : kErrorNotSupported;
}
void CPUHint::Set() {
@@ -105,4 +107,15 @@
lock_acquired_ = false;
}
+void CPUHint::ReqHints(int hint) {
+ if(enabled_ && hint > 0) {
+ fn_perf_hint_(hint, NULL, 0, 0);
+ }
+}
+
+void CPUHint::ReqHintsOffload(int hint, int duration) {
+ if(enabled_ && hint > 0) {
+ fn_perf_hint_offload_(hint, NULL, duration, 0, 0, NULL);
+ }
+}
} // namespace sdm
diff --git a/composer/cpuhint.h b/composer/cpuhint.h
index e758763..e080f75 100644
--- a/composer/cpuhint.h
+++ b/composer/cpuhint.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015, 2021, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -42,6 +42,8 @@
DisplayError Init(HWCDebugHandler *debug_handler);
void Set();
void Reset();
+ void ReqHints(int hint);
+ void ReqHintsOffload(int hint, int duration);
private:
enum { HINT = 0x4501 /* 45-display layer hint, 01-Enable */ };
@@ -54,6 +56,9 @@
DynLib vendor_ext_lib_;
int (*fn_lock_acquire_)(int handle, int duration, int *hints, int num_args) = NULL;
int (*fn_lock_release_)(int value) = NULL;
+ int (*fn_perf_hint_)(int hint, const char *pkg, int duration, int type) = NULL;
+ int (*fn_perf_hint_offload_)(int hint, const char *pkg, int duration, int type,
+ int numArgs, int *) = NULL;
};
} // namespace sdm
diff --git a/composer/hwc_display.cpp b/composer/hwc_display.cpp
index fb24944..affc189 100644
--- a/composer/hwc_display.cpp
+++ b/composer/hwc_display.cpp
@@ -53,7 +53,6 @@
namespace sdm {
uint32_t HWCDisplay::throttling_refresh_rate_ = 60;
-constexpr uint32_t kVsyncTimeDriftNs = 1000000;
bool NeedsToneMap(const LayerStack &layer_stack) {
for (Layer *layer : layer_stack.layers) {
@@ -65,7 +64,7 @@
}
bool IsTimeAfterOrEqualVsyncTime(int64_t time, int64_t vsync_time) {
- return ((vsync_time != INT64_MAX) && ((time - (vsync_time - kVsyncTimeDriftNs)) >= 0));
+ return ((vsync_time != INT64_MAX) && ((time - vsync_time) >= 0));
}
HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
@@ -748,8 +747,14 @@
hdr_largest_layer_px_ = std::max(hdr_largest_layer_px_, hdr_layer_area);
}
+ if (game_supported_ && (hwc_layer->GetType() == kLayerGame)) {
+ layer->flags.is_game = true;
+ layer->input_buffer.flags.game = true;
+ }
+
if (hwc_layer->IsNonIntegralSourceCrop() && !is_secure && !hdr_layer &&
- !layer->flags.single_buffer && !layer->flags.solid_fill && !is_video) {
+ !layer->flags.single_buffer && !layer->flags.solid_fill && !is_video &&
+ !layer->flags.is_game) {
layer->flags.skip = true;
}
@@ -811,11 +816,6 @@
layer->update_mask.set(kClientCompRequest);
}
- if (game_supported_ && (hwc_layer->GetType() == kLayerGame)) {
- layer->flags.is_game = true;
- layer->input_buffer.flags.game = true;
- }
-
layer_stack_.layers.push_back(layer);
}
@@ -1238,6 +1238,20 @@
return HWC2::Error::BadParameter;
}
client_target_->SetLayerBuffer(target, acquire_fence);
+ client_target_handle_ = target;
+ client_acquire_fence_ = acquire_fence;
+ client_dataspace_ = dataspace;
+ client_damage_region_ = damage;
+
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::GetClientTarget(buffer_handle_t target, shared_ptr<Fence> acquire_fence,
+ int32_t dataspace, hwc_region_t damage) {
+ target = client_target_handle_;
+ acquire_fence = client_acquire_fence_;
+ dataspace = client_dataspace_;
+ damage = client_damage_region_;
return HWC2::Error::None;
}
@@ -1377,6 +1391,9 @@
case kInvalidateDisplay:
validated_ = false;
break;
+ case kPostIdleTimeout:
+ display_idle_ = true;
+ break;
default:
DLOGW("Unknown event: %d", event);
break;
@@ -1393,6 +1410,7 @@
layer_changes_.clear();
layer_requests_.clear();
has_client_composition_ = false;
+ display_idle_ = false;
DTRACE_SCOPED();
if (shutdown_pending_) {
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index b396b2e..a156b8f 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -250,6 +250,10 @@
return false;
}
+ virtual bool VsyncEnablePending() {
+ return false;
+ }
+
// Display Configurations
static uint32_t GetThrottlingRefreshRate() { return HWCDisplay::throttling_refresh_rate_; }
static void SetThrottlingRefreshRate(uint32_t newRefreshRate)
@@ -305,6 +309,8 @@
}
virtual HWC2::Error SetClientTarget(buffer_handle_t target, shared_ptr<Fence> acquire_fence,
int32_t dataspace, hwc_region_t damage);
+ virtual HWC2::Error GetClientTarget(buffer_handle_t target, shared_ptr<Fence> acquire_fence,
+ int32_t dataspace, hwc_region_t damage);
virtual HWC2::Error SetColorMode(ColorMode mode) { return HWC2::Error::Unsupported; }
virtual HWC2::Error SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
return HWC2::Error::Unsupported;
@@ -429,6 +435,11 @@
uint64_t *samples[NUM_HISTOGRAM_COLOR_COMPONENTS]);
virtual HWC2::Error GetDisplayVsyncPeriod(VsyncPeriodNanos *vsync_period);
+ virtual HWC2::Error SetDisplayVsyncPeriod(VsyncPeriodNanos vsync_period) {
+ return HWC2::Error::None;
+ }
+
+
virtual HWC2::Error SetActiveConfigWithConstraints(
hwc2_config_t config, const VsyncPeriodChangeConstraints *vsync_period_change_constraints,
VsyncPeriodChangeTimeline *out_timeline);
@@ -438,6 +449,7 @@
HWC2::Error SetDisplayElapseTime(uint64_t time);
virtual bool HasReadBackBufferSupport() { return false; }
+ virtual bool IsDisplayIdle() { return false; };
virtual bool IsHbmSupported() { return false; }
virtual HWC2::Error SetHbm(HbmState state, HbmClient client) { return HWC2::Error::None; }
@@ -562,6 +574,11 @@
bool windowed_display_ = false;
uint32_t active_refresh_rate_ = 0;
bool animating_ = false;
+ buffer_handle_t client_target_handle_ = 0;
+ shared_ptr<Fence> client_acquire_fence_ = nullptr;
+ int32_t client_dataspace_ = 0;
+ hwc_region_t client_damage_region_ = {};
+ bool display_idle_ = false;
private:
void DumpInputBuffers(void);
diff --git a/composer/hwc_display_builtin.cpp b/composer/hwc_display_builtin.cpp
index 1c1e37d..6123e82 100644
--- a/composer/hwc_display_builtin.cpp
+++ b/composer/hwc_display_builtin.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-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
@@ -254,6 +254,10 @@
enhance_idle_time_ = (value == 1);
DLOGI("enhance_idle_time: %d", enhance_idle_time_);
+ HWCDebugHandler::Get()->GetProperty(PERF_HINT_WINDOW_PROP, &perf_hint_window_);
+ HWCDebugHandler::Get()->GetProperty(ENABLE_PERF_HINT_LARGE_COMP_CYCLE,
+ &perf_hint_large_comp_cycle_);
+
return status;
}
@@ -262,23 +266,20 @@
*os << histogram.Dump();
}
-void HWCDisplayBuiltIn::ValidateScalingForDozeMode() {
- if (current_power_mode_ == HWC2::PowerMode::Doze) {
- bool scaling_present = false;
- for (auto &hwc_layer : layer_set_) {
- if (hwc_layer->IsScalingPresent()) {
- scaling_present = true;
- break;
- }
- }
- if (scaling_present) {
- scaling_in_doze_ = true;
- } else {
- scaling_in_doze_ = false;
- }
- } else {
- scaling_in_doze_ = false;
+void HWCDisplayBuiltIn::ValidateUiScaling() {
+ if (is_primary_ || !is_cmd_mode_) {
+ force_reset_validate_ = false;
+ return;
}
+
+ for (auto &hwc_layer : layer_set_) {
+ Layer *layer = hwc_layer->GetSDMLayer();
+ if (hwc_layer->IsScalingPresent() && !layer->input_buffer.flags.video) {
+ force_reset_validate_ = true;
+ return;
+ }
+ }
+ force_reset_validate_ = false;
}
HWC2::Error HWCDisplayBuiltIn::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) {
@@ -301,7 +302,7 @@
BuildLayerStack();
// Check for scaling layers during Doze mode
- ValidateScalingForDozeMode();
+ ValidateUiScaling();
// Add stitch layer to layer stack.
AppendStitchLayer();
@@ -366,6 +367,7 @@
}
status = PrepareLayerStack(out_num_types, out_num_requests);
+ SetCpuPerfHintLargeCompCycle();
pending_commit_ = true;
return status;
}
@@ -620,8 +622,8 @@
pending_commit_ = false;
- // In case of scaling layer in Doze, reset validate
- if (scaling_in_doze_) {
+ // In case of scaling UI layer for command mode, reset validate
+ if (force_reset_validate_) {
validated_ = false;
display_intf_->ClearLUTs();
}
@@ -949,7 +951,7 @@
}
void HWCDisplayBuiltIn::ToggleCPUHint(bool set) {
- if (!cpu_hint_) {
+ if (!cpu_hint_ || !perf_hint_window_) {
return;
}
@@ -1622,6 +1624,29 @@
return updating_count;
}
+bool HWCDisplayBuiltIn::IsDisplayIdle() {
+ // Notify only if this display is source of vsync.
+ bool vsync_source = (callbacks_->GetVsyncSource() == id_);
+ return vsync_source && display_idle_;
+}
+
+void HWCDisplayBuiltIn::SetCpuPerfHintLargeCompCycle() {
+ if (!cpu_hint_ || !perf_hint_large_comp_cycle_) {
+ DLOGV_IF(kTagResources, "cpu_hint_ not initialized or property not set");
+ return;
+ }
+
+ for (auto hwc_layer : layer_set_) {
+ Layer *layer = hwc_layer->GetSDMLayer();
+ if (layer->composition == kCompositionGPU) {
+ DLOGV_IF(kTagResources, "Set perf hint for large comp cycle");
+ int hwc_tid = gettid();
+ cpu_hint_->ReqHintsOffload(kPerfHintLargeCompCycle, hwc_tid);
+ break;
+ }
+ }
+}
+
HWC2::Error HWCDisplayBuiltIn::ApplyHbmLocked() {
if (!mHasHbmNode)
return HWC2::Error::Unsupported;
diff --git a/composer/hwc_display_builtin.h b/composer/hwc_display_builtin.h
index b310d3e..f608e7e 100644
--- a/composer/hwc_display_builtin.h
+++ b/composer/hwc_display_builtin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-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
@@ -148,6 +148,7 @@
void Dump(std::ostringstream *os) override;
virtual HWC2::Error SetPowerMode(HWC2::PowerMode mode, bool teardown);
virtual bool HasReadBackBufferSupport();
+ virtual bool IsDisplayIdle();
virtual bool IsHbmSupported() override;
virtual HWC2::Error SetHbm(HbmState state, HbmClient client) override;
@@ -178,11 +179,12 @@
bool AllocateStitchBuffer();
void CacheAvrStatus();
void PostCommitStitchLayers();
+ void SetCpuPerfHintLargeCompCycle();
int GetBwCode(const DisplayConfigVariableInfo &attr);
void SetBwLimitHint(bool enable);
void SetPartialUpdate(DisplayConfigFixedInfo fixed_info);
uint32_t GetUpdatingAppLayersCount();
- void ValidateScalingForDozeMode();
+ void ValidateUiScaling();
HWC2::Error ApplyHbmLocked() REQUIRES(hbm_mutex);
// SyncTask methods.
@@ -192,7 +194,7 @@
constexpr static int kBwLow = 2;
constexpr static int kBwMedium = 3;
constexpr static int kBwHigh = 4;
-
+ const int kPerfHintLargeCompCycle = 0x00001097;
BufferAllocator *buffer_allocator_ = nullptr;
CPUHint *cpu_hint_ = nullptr;
CWBClient cwb_client_ = kCWBClientNone;
@@ -232,13 +234,15 @@
std::mutex sampling_mutex;
bool api_sampling_vote = false;
bool vndservice_sampling_vote = false;
+ int perf_hint_window_ = 0;
+ int perf_hint_large_comp_cycle_ = 0;
int curr_refresh_rate_ = 0;
bool is_smart_panel_ = false;
const char *kDisplayBwName = "display_bw";
bool enable_bw_limits_ = false;
bool disable_dyn_fps_ = false;
bool enhance_idle_time_ = false;
- bool scaling_in_doze_ = false;
+ bool force_reset_validate_ = false;
// Members for HBM feature
static constexpr const char kHighBrightnessModeNode[] =
diff --git a/composer/hwc_display_dummy.cpp b/composer/hwc_display_dummy.cpp
index 83a5df9..0413ab7 100644
--- a/composer/hwc_display_dummy.cpp
+++ b/composer/hwc_display_dummy.cpp
@@ -91,4 +91,35 @@
return HWC2::Error::None;
}
+HWC2::Error HWCDisplayDummy::SetVsyncEnabled(HWC2::Vsync enabled) {
+ bool state = false;
+ if (enabled == HWC2::Vsync::Enable) {
+ state = true;
+ }
+ vsync_enable_ = state;
+ return HWC2::Error::None;
+}
+
+bool HWCDisplayDummy::VsyncEnablePending() {
+ return vsync_enable_;
+}
+HWC2::Error HWCDisplayDummy::GetDisplayVsyncPeriod(VsyncPeriodNanos *vsync_period) {
+ *vsync_period = vsync_period_;
+ return HWC2::Error::None;
+}
+HWC2::Error HWCDisplayDummy::SetDisplayVsyncPeriod(VsyncPeriodNanos vsync_period) {
+ vsync_period_ = vsync_period;
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplayDummy::SetClientTarget(buffer_handle_t target,
+ shared_ptr<Fence> acquire_fence,
+ int32_t dataspace, hwc_region_t damage) {
+ client_target_handle_ = target;
+ client_acquire_fence_ = acquire_fence;
+ client_dataspace_ = dataspace;
+ client_damage_region_ = damage;
+ return HWC2::Error::None;
+}
+
} // namespace sdm
diff --git a/composer/hwc_display_dummy.h b/composer/hwc_display_dummy.h
index 03ad65a..efd8a4b 100644
--- a/composer/hwc_display_dummy.h
+++ b/composer/hwc_display_dummy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2020, 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
@@ -47,12 +47,19 @@
virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config);
virtual HWC2::Error UpdatePowerMode(HWC2::PowerMode mode);
virtual HWC2::Error SetColorMode(ColorMode mode);
-
+ virtual HWC2::Error SetVsyncEnabled(HWC2::Vsync enabled);
+ virtual bool VsyncEnablePending();
+ virtual HWC2::Error SetClientTarget(buffer_handle_t target, shared_ptr<Fence> acquire_fence,
+ int32_t dataspace, hwc_region_t damage);
+ virtual HWC2::Error GetDisplayVsyncPeriod(VsyncPeriodNanos *vsync_period);
+ virtual HWC2::Error SetDisplayVsyncPeriod(VsyncPeriodNanos vsync_period);
private:
HWCDisplayDummy(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
qService::QService *qservice, hwc2_display_t id, int32_t sdm_id);
DisplayNull display_null_;
+ bool vsync_enable_ = false;
+ VsyncPeriodNanos vsync_period_ = 16600000;
};
} // namespace sdm
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index 9753166..fe52a52 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -743,6 +743,18 @@
}
}
+void HWCSession::PerformIdleStatusCallback(hwc2_display_t display) {
+ std::shared_ptr<DisplayConfig::ConfigCallback> callback = idle_callback_.lock();
+ if (!callback) {
+ return;
+ }
+
+ if (hwc_display_[display]->IsDisplayIdle()) {
+ DTRACE_SCOPED();
+ callback->NotifyIdleStatus(true);
+ }
+}
+
int32_t HWCSession::PresentDisplay(hwc2_display_t display, shared_ptr<Fence> *out_retire_fence) {
auto status = HWC2::Error::BadDisplay;
DTRACE_SCOPED();
@@ -791,6 +803,7 @@
status = hwc_display_[target_display]->Present(out_retire_fence);
if (status == HWC2::Error::None) {
PerformQsyncCallback(target_display);
+ PerformIdleStatusCallback(target_display);
}
}
}
@@ -1098,7 +1111,20 @@
return HWC2_ERROR_UNSUPPORTED;
}
- bool override_mode = async_powermode_ && display_ready_.test(UINT32(display));
+ // async_powermode supported for power on and off
+ bool override_mode = async_powermode_ && display_ready_.test(UINT32(display)) &&
+ async_power_mode_triggered_;
+ HWC2::PowerMode last_power_mode = hwc_display_[display]->GetCurrentPowerMode();
+
+ if (last_power_mode == mode) {
+ return HWC2_ERROR_NONE;
+ }
+
+ if (!((last_power_mode == HWC2::PowerMode::Off && mode == HWC2::PowerMode::On) ||
+ (last_power_mode == HWC2::PowerMode::On && mode == HWC2::PowerMode::Off))) {
+ override_mode = false;
+ }
+
if (!override_mode) {
auto error = CallDisplayFunction(display, &HWCDisplay::SetPowerMode, mode,
false /* teardown */);
@@ -3165,6 +3191,8 @@
Locker::ScopeLock lock_d(locker_[active_builtin_disp_id]);
bool pending_power_mode = false;
+ std::bitset<kSecureMax> secure_sessions = 0;
+ hwc_display_[active_builtin_disp_id]->GetActiveSecureSession(&secure_sessions);
for (hwc2_display_t display = HWC_DISPLAY_PRIMARY + 1;
display < HWCCallbacks::kNumDisplays; display++) {
if (display != active_builtin_disp_id) {
@@ -3177,6 +3205,9 @@
}
if (!pending_power_mode) {
+ if (!secure_sessions.any()) {
+ secure_session_active_ = false;
+ }
return;
}
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index 105d592..7f198ac 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -399,6 +399,7 @@
virtual int IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id, bool *is_smart);
virtual int IsRotatorSupportedFormat(int hal_format, bool ubwc, bool *supported);
virtual int ControlQsyncCallback(bool enable);
+ virtual int ControlIdleStatusCallback(bool enable);
std::weak_ptr<DisplayConfig::ConfigCallback> callback_;
HWCSession *hwc_session_ = nullptr;
@@ -519,6 +520,7 @@
int32_t GetVirtualDisplayId();
void PerformQsyncCallback(hwc2_display_t display);
bool isSmartPanelConfig(uint32_t disp_id, uint32_t config_id);
+ void PerformIdleStatusCallback(hwc2_display_t display);
int SendLTMCommand(const char *cmd);
@@ -562,7 +564,9 @@
std::bitset<HWCCallbacks::kNumDisplays> pending_refresh_;
CWB cwb_;
std::weak_ptr<DisplayConfig::ConfigCallback> qsync_callback_;
+ std::weak_ptr<DisplayConfig::ConfigCallback> idle_callback_;
bool async_powermode_ = false;
+ bool async_power_mode_triggered_ = false;
bool async_vds_creation_ = false;
bool power_state_transition_[HWCCallbacks::kNumDisplays] = {};
std::bitset<HWCCallbacks::kNumDisplays> display_ready_;
diff --git a/composer/hwc_session_services.cpp b/composer/hwc_session_services.cpp
index 0a7f8ca..ceff82b 100644
--- a/composer/hwc_session_services.cpp
+++ b/composer/hwc_session_services.cpp
@@ -502,32 +502,9 @@
return -EINVAL;
}
- hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
- if (active_builtin_disp_id < HWCCallbacks::kNumRealDisplays) {
- std::vector<DisplayMapInfo> map_info = {map_info_primary_};
- std::copy(map_info_builtin_.begin(), map_info_builtin_.end(), std::back_inserter(map_info));
+ // trigger invalidate to apply new bw caps.
+ callbacks_.Refresh(0);
- for (auto &info : map_info) {
- hwc2_display_t target_display = info.client_id;
- {
- SCOPE_LOCK(power_state_[target_display]);
- if (power_state_transition_[target_display]) {
- // Route all interactions with client to dummy display.
- target_display = map_hwc_display_.find(target_display)->second;
- }
- }
- {
- SEQUENCE_WAIT_SCOPE_LOCK(locker_[target_display]);
- auto &hwc_display = hwc_display_[target_display];
- if (hwc_display && hwc_display->GetCurrentPowerMode() != HWC2::PowerMode::Off) {
- hwc_display->ResetValidation();
- }
- }
- }
-
- // trigger invalidate to apply new bw caps.
- callbacks_.Refresh(active_builtin_disp_id);
- }
return 0;
}
@@ -718,12 +695,15 @@
if (!supported) {
return 0;
}
-
+ // Added this flag for pixel
+ hwc_session_->async_power_mode_triggered_ = true;
// Active builtin display needs revalidation
hwc2_display_t active_builtin_disp_id = hwc_session_->GetActiveBuiltinDisplay();
HWC2::PowerMode previous_mode = hwc_session_->hwc_display_[disp_id]->GetCurrentPowerMode();
DLOGI("disp_id: %d power_mode: %d", disp_id, power_mode);
+ auto mode = static_cast<HWC2::PowerMode>(power_mode);
+
HWCDisplay::HWCLayerStack stack = {};
hwc2_display_t dummy_disp_id = hwc_session_->map_hwc_display_.at(disp_id);
@@ -740,6 +720,21 @@
hwc_session_->hwc_display_[dummy_disp_id]->UpdatePowerMode(
hwc_session_->hwc_display_[disp_id]->GetCurrentPowerMode());
+ buffer_handle_t target = 0;
+ shared_ptr<Fence> acquire_fence = nullptr;
+ int32_t dataspace = 0;
+ hwc_region_t damage = {};
+ VsyncPeriodNanos vsync_period = 16600000;
+ hwc_session_->hwc_display_[disp_id]->GetClientTarget(
+ target, acquire_fence, dataspace, damage);
+ hwc_session_->hwc_display_[dummy_disp_id]->SetClientTarget(
+ target, acquire_fence, dataspace, damage);
+
+
+
+ hwc_session_->hwc_display_[disp_id]->GetDisplayVsyncPeriod(&vsync_period);
+ hwc_session_->hwc_display_[dummy_disp_id]->SetDisplayVsyncPeriod(vsync_period);
+
hwc_session_->locker_[dummy_disp_id].Unlock(); // Release the dummy display.
// Release the display's power-state transition var read lock.
hwc_session_->power_state_[disp_id].Unlock();
@@ -748,8 +743,7 @@
// those operations on the dummy display.
// Perform the actual [synchronous] power-state change.
- hwc_session_->hwc_display_[disp_id]->SetPowerMode(static_cast<HWC2::PowerMode>(power_mode),
- false /* teardown */);
+ hwc_session_->hwc_display_[disp_id]->SetPowerMode(mode, false /* teardown */);
// Power state transition end.
// Acquire the display's power-state transition var read lock.
@@ -760,6 +754,15 @@
// Retrieve the real display's layer-stack from the dummy display.
hwc_session_->hwc_display_[dummy_disp_id]->GetLayerStack(&stack);
hwc_session_->hwc_display_[disp_id]->SetLayerStack(&stack);
+ bool vsync_pending = hwc_session_->hwc_display_[dummy_disp_id]->VsyncEnablePending();
+ if (vsync_pending) {
+ hwc_session_->hwc_display_[disp_id]->SetVsyncEnabled(HWC2::Vsync::Enable);
+ }
+ hwc_session_->hwc_display_[dummy_disp_id]->GetClientTarget(
+ target, acquire_fence, dataspace, damage);
+ hwc_session_->hwc_display_[disp_id]->SetClientTarget(
+ target, acquire_fence, dataspace, damage);
+
// Read display has got layerstack. Update the fences.
hwc_session_->hwc_display_[disp_id]->PostPowerMode();
@@ -1206,4 +1209,14 @@
return 0;
}
+int HWCSession::DisplayConfigImpl::ControlIdleStatusCallback(bool enable) {
+ if (enable) {
+ hwc_session_->idle_callback_ = callback_;
+ } else {
+ hwc_session_->idle_callback_.reset();
+ }
+
+ return 0;
+}
+
} // namespace sdm
diff --git a/config/display-product.mk b/config/display-product.mk
index 2922b97..f349a1d 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -53,10 +53,6 @@
debug.sf.enable_gl_backpressure=1
endif
-ifneq ($(PLATFORM_VERSION), 10)
- PRODUCT_PROPERTY_OVERRIDES += vendor.display.enable_async_powermode=0
-endif
-
#Set WCG properties
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.has_wide_color_display=true
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.has_HDR_display=true
@@ -75,6 +71,9 @@
vendor.display.disable_hw_recovery_dump=1
endif
+# Enable power async mode
+#PRODUCT_PROPERTY_OVERRIDES += vendor.display.enable_async_powermode=1
+
QMAA_ENABLED_HAL_MODULES += display
ifeq ($(TARGET_USES_QMAA),true)
ifeq ($(TARGET_USES_QMAA_OVERRIDE_DISPLAY),true)
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
index a29dceb..5044213 100644
--- a/gralloc/gr_utils.h
+++ b/gralloc/gr_utils.h
@@ -31,6 +31,9 @@
#define __GR_UTILS_H__
#include <android/hardware/graphics/common/1.2/types.h>
+
+#include <limits>
+
#include "gralloc_priv.h"
#include "qdMetaData.h"
@@ -71,6 +74,11 @@
template <class Type1, class Type2>
inline Type1 ALIGN(Type1 x, Type2 align) {
+ Type1 max_val = std::numeric_limits<Type1>::max();
+ if (x > (max_val - (Type1)align)) {
+ return x;
+ }
+
return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
}
diff --git a/include/display_properties.h b/include/display_properties.h
index 9f004f8..1c0e8a4 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
+* Copyright (c) 2018-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
@@ -123,6 +123,10 @@
#define ENABLE_POMS_DURING_DOZE DISPLAY_PROP("enable_poms_during_doze")
#define DISABLE_DYNAMIC_FPS DISPLAY_PROP("disable_dynamic_fps")
#define ENHANCE_IDLE_TIME DISPLAY_PROP("enhance_idle_time")
+#define ENABLE_QSYNC_IDLE DISPLAY_PROP("enable_qsync_idle")
+
+// PERF hint properties
+#define ENABLE_PERF_HINT_LARGE_COMP_CYCLE DISPLAY_PROP("enable_perf_hint_large_comp_cycle")
// Add all vendor.display properties above
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 51df12d..a13266b 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -150,6 +150,7 @@
kDisplayPowerResetEvent, // Event triggered by Hardware Recovery.
kInvalidateDisplay, // Event triggered by DrawCycle thread to Invalidate display.
kSyncInvalidateDisplay, // Event triggered by Non-DrawCycle threads to Invalidate display.
+ kPostIdleTimeout, // Event triggered after entering idle.
};
/*! @brief This enum represents the secure events received by Display HAL. */
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 990facf..6f81788 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -501,11 +501,8 @@
hdr_supported = (hdr_supported && hw_panel_info_.hdr_enabled);
}
- // Built-in displays not support HDR10+ even the target supports HDR to comply with spec. For non-builtins, check
- // panel capability.
- if (kBuiltIn == display_type_) {
- hdr_plus_supported = false;
- } else if (hdr_supported && hw_panel_info_.hdr_plus_enabled) {
+ // For non-builtin displays, check panel capability for HDR10+
+ if (hdr_supported && hw_panel_info_.hdr_plus_enabled) {
hdr_plus_supported = true;
}
@@ -749,6 +746,7 @@
os << " h_total: " << display_attributes_.h_total;
os << " clk: " << display_attributes_.clock_khz;
os << " Topology: " << display_attributes_.topology;
+ os << " Qsync mode: " << active_qsync_mode_;
os << std::noboolalpha;
os << "\nCurrent Color Mode: " << current_color_mode_.c_str();
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index c924bb8..509c025 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -61,7 +61,7 @@
virtual DisplayError GetDisplayState(DisplayState *state);
virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info);
- virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info);
+ virtual DisplayError GetConfig(DisplayConfigFixedInfo *fixed_info);
virtual DisplayError GetActiveConfig(uint32_t *index);
virtual DisplayError GetVSyncState(bool *enabled);
virtual DisplayError SetDisplayState(DisplayState state, bool teardown,
@@ -164,6 +164,7 @@
virtual DisplayError ClearLUTs() {
return kErrorNotSupported;
}
+ QSyncMode active_qsync_mode_ = kQSyncModeNone;
protected:
const char *kBt2020Pq = "bt2020_pq";
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index f2d69f3..6a869de 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -129,6 +129,13 @@
DebugHandler::Get()->GetProperty(ENHANCE_IDLE_TIME, &value);
enhance_idle_time_ = (value == 1);
+ value = 0;
+ DebugHandler::Get()->GetProperty(ENABLE_QSYNC_IDLE, &value);
+ enable_qsync_idle_ = hw_panel_info_.qsync_support && (value == 1);
+ if (enable_qsync_idle_) {
+ DLOGI("Enabling qsync on idling");
+ }
+
return error;
}
@@ -155,8 +162,7 @@
}
} else {
if (CanSkipDisplayPrepare(layer_stack)) {
- hw_layers_.hw_avr_info.update = needs_avr_update_;
- hw_layers_.hw_avr_info.mode = GetAvrMode(qsync_mode_);
+ UpdateQsyncMode();
return kErrorNone;
}
}
@@ -164,8 +170,7 @@
// Clean hw layers for reuse.
hw_layers_ = HWLayers();
- hw_layers_.hw_avr_info.update = needs_avr_update_;
- hw_layers_.hw_avr_info.mode = GetAvrMode(qsync_mode_);
+ UpdateQsyncMode();
left_frame_roi_ = {};
right_frame_roi_ = {};
@@ -183,6 +188,31 @@
return error;
}
+void DisplayBuiltIn::UpdateQsyncMode() {
+ if (!hw_panel_info_.qsync_support || (hw_panel_info_.mode == kModeCommand)) {
+ return;
+ }
+
+ QSyncMode mode = kQSyncModeNone;
+ if (handle_idle_timeout_ && enable_qsync_idle_) {
+ // Override to continuous mode upon idling.
+ mode = kQSyncModeContinuous;
+ DLOGV_IF(kTagDisplay, "Qsync entering continuous mode");
+ } else {
+ // Set Qsync mode requested by client.
+ mode = qsync_mode_;
+ DLOGV_IF(kTagDisplay, "Restoring client's qsync mode: %d", mode);
+ }
+
+ hw_layers_.hw_avr_info.update = (mode != active_qsync_mode_) || needs_avr_update_;
+ hw_layers_.hw_avr_info.mode = GetAvrMode(mode);
+
+ DLOGV_IF(kTagDisplay, "update: %d mode: %d", hw_layers_.hw_avr_info.update, mode);
+
+ // Store active mode.
+ active_qsync_mode_ = mode;
+}
+
HWAVRModes DisplayBuiltIn::GetAvrMode(QSyncMode mode) {
switch (mode) {
case kQSyncModeNone:
@@ -326,6 +356,18 @@
}
dpps_info_.Init(this, hw_panel_info_.panel_name);
+ HandleQsyncPostCommit(layer_stack);
+
+ first_cycle_ = false;
+
+ previous_retire_fence_ = layer_stack->retire_fence;
+
+ handle_idle_timeout_ = false;
+
+ return error;
+}
+
+void DisplayBuiltIn::HandleQsyncPostCommit(LayerStack *layer_stack) {
if (qsync_mode_ == kQsyncModeOneShot) {
// Reset qsync mode.
SetQSyncMode(kQSyncModeNone);
@@ -337,11 +379,13 @@
needs_avr_update_ = false;
}
- first_cycle_ = false;
+ SetVsyncStatus(true /*Re-enable vsync.*/);
- previous_retire_fence_ = layer_stack->retire_fence;
-
- return error;
+ bool notify_idle = enable_qsync_idle_ && (active_qsync_mode_ != kQSyncModeNone) &&
+ handle_idle_timeout_;
+ if (notify_idle) {
+ event_handler_->HandleEvent(kPostIdleTimeout);
+ }
}
void DisplayBuiltIn::UpdateDisplayModeParams() {
@@ -549,7 +593,7 @@
return kErrorParameters;
}
- if (CanLowerFps(idle_screen) && !final_rate) {
+ if (CanLowerFps(idle_screen) && !final_rate && !enable_qsync_idle_) {
refresh_rate = hw_panel_info_.min_fps;
}
@@ -575,7 +619,6 @@
// On success, set current refresh rate to new refresh rate
current_refresh_rate_ = refresh_rate;
- handle_idle_timeout_ = false;
deferred_config_.MarkDirty();
return ReconfigureDisplay();
@@ -600,15 +643,38 @@
}
DisplayError DisplayBuiltIn::VSync(int64_t timestamp) {
- if (vsync_enable_ && !drop_hw_vsync_) {
- DisplayEventVSync vsync;
- vsync.timestamp = timestamp;
- event_handler_->VSync(vsync);
+ DTRACE_SCOPED();
+ bool qsync_enabled = enable_qsync_idle_ && (active_qsync_mode_ != kQSyncModeNone);
+ // Client isn't aware of underlying qsync mode.
+ // Disable vsync propagation as long as qsync is enabled.
+ bool propagate_vsync = vsync_enable_ && !drop_hw_vsync_ && !qsync_enabled;
+ if (!propagate_vsync) {
+ // Re enable when display updates.
+ SetVsyncStatus(false /*Disable vsync events.*/);
+ return kErrorNone;
}
+ DisplayEventVSync vsync;
+ vsync.timestamp = timestamp;
+ event_handler_->VSync(vsync);
+
return kErrorNone;
}
+void DisplayBuiltIn::SetVsyncStatus(bool enable) {
+ string trace_name = enable ? "enable" : "disable";
+ DTRACE_BEGIN(trace_name.c_str());
+ if (enable) {
+ // Enable if vsync is still enabled.
+ hw_events_intf_->SetEventState(HWEvent::VSYNC, vsync_enable_);
+ pending_vsync_enable_ = false;
+ } else {
+ hw_events_intf_->SetEventState(HWEvent::VSYNC, false);
+ pending_vsync_enable_ = true;
+ }
+ DTRACE_END();
+}
+
void DisplayBuiltIn::IdleTimeout() {
if (hw_panel_info_.mode == kModeVideo) {
if (event_handler_->HandleEvent(kIdleTimeout) != kErrorNone) {
@@ -940,7 +1006,7 @@
}
DisplayError DisplayBuiltIn::GetQSyncMode(QSyncMode *qsync_mode) {
- *qsync_mode = qsync_mode_;
+ *qsync_mode = active_qsync_mode_;
return kErrorNone;
}
@@ -1262,4 +1328,26 @@
panel_info->transfer_time_us = hw_panel_info_.transfer_time_us;
}
+DisplayError DisplayBuiltIn::GetConfig(DisplayConfigFixedInfo *fixed_info) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ fixed_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand);
+
+ HWResourceInfo hw_resource_info = HWResourceInfo();
+ hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
+
+ fixed_info->hdr_supported = hw_resource_info.has_hdr;
+ // Built-in displays not support HDR10+ even the target supports HDR to comply with spec
+ fixed_info->hdr_plus_supported = false;
+ // Populate luminance values only if hdr will be supported on that display
+ fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
+ fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
+ fixed_info->min_luminance = fixed_info->hdr_supported ? hw_panel_info_.blackness_level: 0;
+ fixed_info->hdr_eotf = hw_panel_info_.hdr_eotf;
+ fixed_info->hdr_metadata_type_one = hw_panel_info_.hdr_metadata_type_one;
+ fixed_info->partial_update = hw_panel_info_.partial_update;
+ fixed_info->readback_supported = hw_resource_info.has_concurrent_writeback;
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index 7ec4dec..8e43f0b 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -132,6 +132,7 @@
virtual DisplayError GetQSyncMode(QSyncMode *qsync_mode);
virtual DisplayError colorSamplingOn();
virtual DisplayError colorSamplingOff();
+ virtual DisplayError GetConfig(DisplayConfigFixedInfo *fixed_info);
// Implement the HWEventHandlers
virtual DisplayError VSync(int64_t timestamp);
@@ -161,6 +162,9 @@
void GetFpsConfig(HWDisplayAttributes *display_attributes, HWPanelInfo *panel_info);
void UpdateDisplayModeParams();
bool CanLowerFps(bool idle_screen);
+ void HandleQsyncPostCommit(LayerStack *layer_stack);
+ void UpdateQsyncMode();
+ void SetVsyncStatus(bool enable);
const uint32_t kPuTimeOutMs = 1000;
std::vector<HWEvent> event_list_;
@@ -195,6 +199,8 @@
bool enhance_idle_time_ = false;
int idle_time_ms_ = 0;
struct timespec idle_timer_start_;
+ bool enable_qsync_idle_ = false;
+ bool pending_vsync_enable_ = false;
};
} // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 0da6303..e0cf2d7 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -163,6 +163,9 @@
case kFormatRGB888:
*drm_format = DRM_FORMAT_BGR888;
break;
+ case kFormatBGR888:
+ *drm_format = DRM_FORMAT_RGB888;
+ break;
case kFormatRGB565:
*drm_format = DRM_FORMAT_BGR565;
break;