summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/DisplayDevice.cpp
diff options
context:
space:
mode:
author Dominik Laskowski <domlaskowski@google.com> 2023-12-08 15:26:04 -0500
committer Dominik Laskowski <domlaskowski@google.com> 2024-02-09 14:14:08 -0500
commit88096877a23168aaacdda5c8b3b1354d3db371f4 (patch)
tree74a7aad9678d026d7040de8b1b91fcaad0bad84d /services/surfaceflinger/DisplayDevice.cpp
parent203b22aa060460cd25067fd002c8f046a8b0b116 (diff)
Reland^2 "SF: Set an initial mode [...] for external displays"
Rebased and modified from Iec154c488ef7af9b8e1d6386509e97c9ce85103b, patch set 3. Does not include I688b0c922747a80e881965a1dc243d11ba2c7438, which was reverted. DM currently always picks 1080p@60 for an external display. More work (tracked in b/318534874) needs to be done in SF in order to use that mode initially. In the meantime, have SF pick the same mode on hotplug so that it avoids extra mode switches. Move "force" into DisplayModeRequest. If a request is already pending this allows forcing the final request if a pending request forced it, even if the new request does not. This matches how emitEvent is handled. If a DisplayModeRequest is forced, don't early exit in initiateDisplayModeChanges, which does not honor "force". When loading display modes for an external display, look for 1080p@60 and treat it as the active mode. If the display does not have 1080p@60, pick the mode closest to (but not exceeding) 1080p@60. DM will pick an appropriate mode later. When adding that display, apply that active mode so it will be used by SF. Fixes: 305813445 Test: libsurfaceflinger_unittest Test: YouTube is not frozen or choppy on external display hotplug. Test: Remove the option of 1080p@60 and connect. Change-Id: Ibb15df1c2c0ab162c11895219d8f4bb749c474a1
Diffstat (limited to 'services/surfaceflinger/DisplayDevice.cpp')
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 5f20cd9c87..45f08a4521 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -24,6 +24,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <common/FlagManager.h>
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/Display.h>
#include <compositionengine/DisplayColorProfile.h>
@@ -214,6 +215,17 @@ void DisplayDevice::setActiveMode(DisplayModeId modeId, Fps vsyncRate, Fps rende
bool DisplayDevice::initiateModeChange(display::DisplayModeRequest&& desiredMode,
const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline& outTimeline) {
+ // TODO(b/255635711): Flow the DisplayModeRequest through the desired/pending/active states. For
+ // now, `desiredMode` and `mDesiredModeOpt` are one and the same, but the latter is not cleared
+ // until the next `SF::initiateDisplayModeChanges`. However, the desired mode has been consumed
+ // at this point, so clear the `force` flag to prevent an endless loop of `initiateModeChange`.
+ if (FlagManager::getInstance().connected_display()) {
+ std::scoped_lock lock(mDesiredModeLock);
+ if (mDesiredModeOpt) {
+ mDesiredModeOpt->force = false;
+ }
+ }
+
mPendingModeOpt = std::move(desiredMode);
mIsModeSetPending = true;
@@ -517,8 +529,7 @@ void DisplayDevice::animateOverlay() {
}
}
-auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode, bool force)
- -> DesiredModeAction {
+auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode) -> DesiredModeAction {
ATRACE_CALL();
const auto& desiredModePtr = desiredMode.mode.modePtr;
@@ -526,20 +537,26 @@ auto DisplayDevice::setDesiredMode(display::DisplayModeRequest&& desiredMode, bo
LOG_ALWAYS_FATAL_IF(getPhysicalId() != desiredModePtr->getPhysicalDisplayId(),
"DisplayId mismatch");
- ALOGV("%s(%s)", __func__, to_string(*desiredModePtr).c_str());
+ // TODO (b/318533819): Stringize DisplayModeRequest.
+ ALOGD("%s(%s, force=%s)", __func__, to_string(*desiredModePtr).c_str(),
+ desiredMode.force ? "true" : "false");
std::scoped_lock lock(mDesiredModeLock);
if (mDesiredModeOpt) {
// A mode transition was already scheduled, so just override the desired mode.
const bool emitEvent = mDesiredModeOpt->emitEvent;
+ const bool force = mDesiredModeOpt->force;
mDesiredModeOpt = std::move(desiredMode);
mDesiredModeOpt->emitEvent |= emitEvent;
+ if (FlagManager::getInstance().connected_display()) {
+ mDesiredModeOpt->force |= force;
+ }
return DesiredModeAction::None;
}
// If the desired mode is already active...
const auto activeMode = refreshRateSelector().getActiveMode();
- if (!force && activeMode.modePtr->getId() == desiredModePtr->getId()) {
+ if (!desiredMode.force && activeMode.modePtr->getId() == desiredModePtr->getId()) {
if (activeMode == desiredMode.mode) {
return DesiredModeAction::None;
}