From f81d2c8206d793716b6cedd28c514727120c6bbf Mon Sep 17 00:00:00 2001 From: Roman Stratiienko Date: Tue, 11 Jan 2022 19:47:24 +0200 Subject: [PATCH] drm_hwcomposer: Send crtc.active and crtc.mode together with the frame On HiKey/HiKey960 boards, enabling the crtc before the first composition is set can cause trouble, as part of the display engine is configured in the atomic plane update method. So when commit 36a7f28516a4 ("drm_hwcomposer: Rework display Mode Setting and DPMS handling"), which reworked the dpms and modeset logic to commit the modeset immediately, landed it caused bootup regressions on those boards. Talking with others it seems other drivers likely may have issues trying to enable the crtc without a plane. Thus this patch changes the logic to queue modesets so they are submitted with the initial composition. Similarly it removes the crtc activation, as the initial composition will implicitly activate the crtc. Fixes: 36a7f28516a4 ("drm_hwcomposer: Rework display Mode Setting and DPMS handling") Signed-off-by: Roman Stratiienko [jstultz: Added commit message, reworked a comment] Signed-off-by: John Stultz Change-Id: Ie4d1f967da052b0b3ef73257c2ca76b30504a6c2 --- DrmHwcTwo.cpp | 27 ++++++++++++++++----------- DrmHwcTwo.h | 3 +++ compositor/DrmDisplayCompositor.h | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/DrmHwcTwo.cpp b/DrmHwcTwo.cpp index 8142e6c..291bbdd 100644 --- a/DrmHwcTwo.cpp +++ b/DrmHwcTwo.cpp @@ -757,6 +757,9 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) { } a_args.composition = composition; + if (staged_mode) { + a_args.display_mode = *staged_mode; + } ret = compositor_.ExecuteAtomicCommit(a_args); if (ret) { @@ -764,6 +767,11 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) { ALOGE("Failed to apply the frame composition ret=%d", ret); return HWC2::Error::BadParameter; } + + if (!a_args.test_only) { + staged_mode.reset(); + } + return HWC2::Error::None; } @@ -805,16 +813,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) { auto &mode = hwc_configs_[conf].mode; - AtomicCommitArgs a_args = { - .display_mode = mode, - .clear_active_composition = true, - }; - - int err = compositor_.ExecuteAtomicCommit(a_args); - if (err != 0) { - ALOGE("Failed to queue mode changing commit %d", err); - return HWC2::Error::BadConfig; - } + staged_mode = mode; active_config_id_ = conf; @@ -895,7 +894,13 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) { a_args.active = false; break; case HWC2::PowerMode::On: - a_args.active = true; + /* + * Setting the display to active before we have a composition + * can break some drivers, so skip setting a_args.active to + * true, as the next composition frame will implicitly activate + * the display + */ + return HWC2::Error::None; break; case HWC2::PowerMode::Doze: case HWC2::PowerMode::DozeSuspend: diff --git a/DrmHwcTwo.h b/DrmHwcTwo.h index 7fd4fbd..eb74f32 100644 --- a/DrmHwcTwo.h +++ b/DrmHwcTwo.h @@ -22,6 +22,7 @@ #include #include +#include #include "compositor/DrmDisplayCompositor.h" #include "compositor/Planner.h" @@ -347,6 +348,8 @@ class DrmHwcTwo : public hwc2_device_t { DrmHwcTwo *hwc2_; + std::optional staged_mode; + ResourceManager *resource_manager_; DrmDevice *drm_; DrmDisplayCompositor compositor_; diff --git a/compositor/DrmDisplayCompositor.h b/compositor/DrmDisplayCompositor.h index 6d2c421..f6333eb 100644 --- a/compositor/DrmDisplayCompositor.h +++ b/compositor/DrmDisplayCompositor.h @@ -23,6 +23,7 @@ #include #include +#include #include #include -- GitLab