hwc2: enable the vsync on the display requested by SF
-- Avoid calculating the next vsync source based on the
active display list in hwc2.
-- Enable/disable the vsync on the HWC display as requested
by SurfaceFlinger.
Change-Id: I901be3d06ad1102d30232e6fb8dbb0d1709b5a68
CRs-fixed: 2429625
diff --git a/sdm/libs/hwc2/hwc_callbacks.cpp b/sdm/libs/hwc2/hwc_callbacks.cpp
index b26d633..d1345ee 100644
--- a/sdm/libs/hwc2/hwc_callbacks.cpp
+++ b/sdm/libs/hwc2/hwc_callbacks.cpp
@@ -56,9 +56,6 @@
return HWC2::Error::NoResources;
}
DTRACE_SCOPED();
- if (IsVsyncSwapped() && display == vsync_from_) {
- display = vsync_to_;
- }
vsync_(vsync_data_, display, timestamp);
return HWC2::Error::None;
}
diff --git a/sdm/libs/hwc2/hwc_callbacks.h b/sdm/libs/hwc2/hwc_callbacks.h
index 6b39963..c3a760f 100644
--- a/sdm/libs/hwc2/hwc_callbacks.h
+++ b/sdm/libs/hwc2/hwc_callbacks.h
@@ -51,12 +51,10 @@
HWC2::Error Vsync(hwc2_display_t display, int64_t timestamp);
HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer);
- void SetSwapVsync(hwc2_display_t from, hwc2_display_t to) {
- vsync_from_ = from;
- vsync_to_ = to;
+ void UpdateVsyncSource(hwc2_display_t from) {
+ vsync_source_ = from;
}
- bool IsVsyncSwapped() { return (vsync_from_ != vsync_to_); }
- hwc2_display_t GetVsyncSource() { return vsync_from_; }
+ hwc2_display_t GetVsyncSource() { return vsync_source_; }
bool VsyncCallbackRegistered() { return (vsync_ != nullptr && vsync_data_ != nullptr); }
bool NeedsRefresh(hwc2_display_t display) { return pending_refresh_.test(UINT32(display)); }
@@ -70,8 +68,7 @@
HWC2_PFN_HOTPLUG hotplug_ = nullptr;
HWC2_PFN_REFRESH refresh_ = nullptr;
HWC2_PFN_VSYNC vsync_ = nullptr;
- hwc2_display_t vsync_from_ = HWC_DISPLAY_PRIMARY; // hw vsync is active on this display
- hwc2_display_t vsync_to_ = HWC_DISPLAY_PRIMARY; // vsync will be reported as this display
+ hwc2_display_t vsync_source_ = HWC_DISPLAY_PRIMARY; // hw vsync is active on this display
std::bitset<kNumDisplays> pending_refresh_; // Displays waiting to get refreshed
};
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 81d69e4..c50c81f 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -896,8 +896,6 @@
return HWC2::Error::BadDisplay;
}
- last_vsync_mode_ = enabled;
-
return HWC2::Error::None;
}
@@ -1215,10 +1213,6 @@
return current_power_mode_;
}
-HWC2::Vsync HWCDisplay::GetLastVsyncMode() {
- return last_vsync_mode_;
-}
-
DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
callbacks_->Vsync(id_, vsync.timestamp);
return kErrorNone;
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index d8c0140..53eccae 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -144,7 +144,6 @@
return kErrorNotSupported;
}
virtual HWC2::PowerMode GetCurrentPowerMode();
- virtual HWC2::Vsync GetLastVsyncMode();
virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
virtual int SetDisplayStatus(DisplayStatus display_status);
@@ -322,7 +321,6 @@
}
virtual HWC2::Error GetDisplayIdentificationData(uint8_t *out_port, uint32_t *out_data_size,
uint8_t *out_data);
- virtual void SetVsyncSource(bool enable) { vsync_source_ = enable; }
protected:
static uint32_t throttling_refresh_rate_;
@@ -383,7 +381,6 @@
uint32_t dump_frame_index_ = 0;
bool dump_input_layers_ = false;
HWC2::PowerMode current_power_mode_ = HWC2::PowerMode::Off;
- HWC2::Vsync last_vsync_mode_ = HWC2::Vsync::Invalid;
bool swap_interval_zero_ = false;
bool display_paused_ = false;
uint32_t min_refresh_rate_ = 0;
@@ -409,7 +406,6 @@
bool pending_commit_ = false;
bool is_cmd_mode_ = false;
bool partial_update_enabled_ = false;
- bool vsync_source_ = false;
bool skip_commit_ = false;
std::map<uint32_t, DisplayConfigVariableInfo> variable_config_map_;
std::vector<uint32_t> hwc_config_map_;
diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp
index d968602..cacbc7a 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.cpp
+++ b/sdm/libs/hwc2/hwc_display_builtin.cpp
@@ -220,8 +220,9 @@
hwc_layer->ResetBufferFlip();
}
+ bool vsync_source = (callbacks_->GetVsyncSource() == id_);
bool skip_commit = enable_drop_refresh_ && !pending_commit_ && !buffers_latched &&
- !pending_refresh_ && !vsync_source_;
+ !pending_refresh_ && !vsync_source;
pending_refresh_ = false;
return skip_commit;
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 7965914..83afed5 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1010,7 +1010,6 @@
hwc_session->idle_pc_ref_cnt_ = 0;
}
- hwc_session->UpdateVsyncSource();
hwc_session->UpdateThrottlingRate();
// Trigger refresh for doze mode to take effect.
@@ -1029,15 +1028,14 @@
if (int_enabled < HWC2_VSYNC_INVALID || int_enabled > HWC2_VSYNC_DISABLE) {
return HWC2_ERROR_BAD_PARAMETER;
}
- // already mapping taken care by HAL and SF. No need to react for other display.
- if (display != HWC_DISPLAY_PRIMARY) {
- return HWC2_ERROR_NONE;
- }
auto enabled = static_cast<HWC2::Vsync>(int_enabled);
HWCSession *hwc_session = static_cast<HWCSession *>(device);
- display = hwc_session->callbacks_.GetVsyncSource();
+
+ if (int_enabled == HWC2_VSYNC_ENABLE) {
+ hwc_session->callbacks_.UpdateVsyncSource(display);
+ }
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetVsyncEnabled, enabled);
}
@@ -2429,8 +2427,6 @@
if (!color_mgr_) {
DLOGW("Failed to load HWCColorManager.");
}
- // This display is the source of vsync events.
- (*hwc_display)->SetVsyncSource(true);
} else {
DLOGE("Primary display creation failed.");
}
@@ -2672,7 +2668,6 @@
for (auto client_id : pending_hotplugs) {
DLOGI("Notify hotplug display connected: client id = %d", client_id);
callbacks_.Hotplug(client_id, HWC2::Connection::Connected);
- UpdateVsyncSource();
}
return status;
@@ -2743,7 +2738,6 @@
hwc_display = nullptr;
map_info->Reset();
- UpdateVsyncSource();
}
}
@@ -2853,7 +2847,7 @@
}
}
- hwc2_display_t vsync_source = GetNextVsyncSource();
+ hwc2_display_t vsync_source = callbacks_.GetVsyncSource();
status = hwc_display_[vsync_source]->SetVsyncEnabled(HWC2::Vsync::Enable);
if (status != HWC2::Error::None) {
DLOGE("Enabling vsync failed for disp: %" PRIu64 " with error = %d", vsync_source, status);
@@ -3090,67 +3084,6 @@
return CallDisplayFunction(device, HWC_DISPLAY_PRIMARY, &HWCDisplay::SetQSyncMode, qsync_mode);
}
-void HWCSession::UpdateVsyncSource() {
- hwc2_display_t active_source = callbacks_.GetVsyncSource();
- hwc2_display_t next_vsync_source = GetNextVsyncSource();
- if (active_source == next_vsync_source) {
- return;
- }
-
- callbacks_.SetSwapVsync(next_vsync_source, HWC_DISPLAY_PRIMARY);
- hwc_display_[next_vsync_source]->SetVsyncSource(true);
- if (hwc_display_[active_source]) {
- hwc_display_[active_source]->SetVsyncSource(false);
- }
-
- HWC2::PowerMode power_mode = hwc_display_[next_vsync_source]->GetCurrentPowerMode();
- // Skip enabling vsync if display is Off, happens only for default source ie; primary.
- if (power_mode == HWC2::PowerMode::Off) {
- return;
- }
-
- HWC2::Vsync vsync_mode = hwc_display_[active_source] ?
- hwc_display_[active_source]->GetLastVsyncMode() : HWC2::Vsync::Enable;
- hwc_display_[next_vsync_source]->SetVsyncEnabled(vsync_mode);
- // Disable Vsync on previous display.
- if (hwc_display_[active_source]) {
- hwc_display_[active_source]->SetVsyncEnabled(HWC2::Vsync::Disable);
- }
-
- DLOGI("active_source %d next_vsync_source %d", active_source, next_vsync_source);
-}
-
-hwc2_display_t HWCSession::GetNextVsyncSource() {
- // If primary display is powered off, change vsync source to next builtin display.
- // If primary display is powerd on, change vsync source back to primary display.
- // First check for active builtins. If not found switch to pluggable displays.
-
- std::vector<DisplayMapInfo> map_info = {map_info_primary_};
- std::copy(map_info_builtin_.begin(), map_info_builtin_.end(), std::back_inserter(map_info));
- std::copy(map_info_pluggable_.begin(), map_info_pluggable_.end(), std::back_inserter(map_info));
-
- for (auto &info : map_info) {
- auto &hwc_display = hwc_display_[info.client_id];
- if (!hwc_display) {
- continue;
- }
-
- HWC2::PowerMode current_mode = hwc_display->GetCurrentPowerMode();
- if (update_vsync_on_doze_) {
- if (current_mode == HWC2::PowerMode::On) {
- return info.client_id;
- }
- } else if (update_vsync_on_power_off_) {
- if (current_mode != HWC2::PowerMode::Off) {
- return info.client_id;
- }
- }
- }
-
- // No Vsync source found. Default to main display.
- return HWC_DISPLAY_PRIMARY;
-}
-
void HWCSession::UpdateThrottlingRate() {
uint32_t new_min = 0;
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index d97840c..c82cc12 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -390,8 +390,6 @@
void HandleSecureSession();
void HandlePowerOnPending(hwc2_display_t display, int retire_fence);
void HandleHotplugPending(hwc2_display_t disp_id, int retire_fence);
- void UpdateVsyncSource();
- hwc2_display_t GetNextVsyncSource();
bool IsPluggableDisplayConnected();
hwc2_display_t GetActiveBuiltinDisplay();
void HandlePendingRefresh();
@@ -406,8 +404,6 @@
std::vector<DisplayMapInfo> map_info_builtin_; // Builtin displays excluding primary
std::vector<DisplayMapInfo> map_info_pluggable_; // Pluggable displays excluding primary
std::vector<DisplayMapInfo> map_info_virtual_; // Virtual displays
- bool update_vsync_on_power_off_ = false;
- bool update_vsync_on_doze_ = false;
bool reset_panel_ = false;
bool client_connected_ = false;
bool new_bw_mode_ = false;
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index acd2da8..a1eec83 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -657,14 +657,10 @@
#ifdef DISPLAY_CONFIG_1_6
Return<int32_t> HWCSession::updateVSyncSourceOnPowerModeOff() {
- update_vsync_on_power_off_ = true;
-
return 0;
}
Return<int32_t> HWCSession::updateVSyncSourceOnPowerModeDoze() {
- update_vsync_on_doze_ = true;
-
return 0;
}
#endif