diff options
Diffstat (limited to 'services/surfaceflinger/DisplayDevice.cpp')
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 126 |
1 files changed, 115 insertions, 11 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index bee0c8cfac..156e799b48 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -22,6 +22,8 @@ #undef LOG_TAG #define LOG_TAG "DisplayDevice" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + #include <android-base/stringprintf.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/Display.h> @@ -40,6 +42,7 @@ #include "DisplayDevice.h" #include "Layer.h" +#include "RefreshRateOverlay.h" #include "SurfaceFlinger.h" namespace android { @@ -65,10 +68,13 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mSequenceId(args.sequenceId), mConnectionType(args.connectionType), mCompositionDisplay{args.compositionDisplay}, + mActiveModeFPSTrace("ActiveModeFPS -" + to_string(getId())), + mActiveModeFPSHwcTrace("ActiveModeFPS_HWC -" + to_string(getId())), mPhysicalOrientation(args.physicalOrientation), mSupportedModes(std::move(args.supportedModes)), mIsPrimary(args.isPrimary), - mIsPowerModeOverride(false){ + mIsPowerModeOverride(false), + mRefreshRateConfigs(std::move(args.refreshRateConfigs)) { mCompositionDisplay->editState().isSecure = args.isSecure; mCompositionDisplay->createRenderSurface( compositionengine::RenderSurfaceCreationArgsBuilder() @@ -156,21 +162,30 @@ bool DisplayDevice::isPoweredOn() const { void DisplayDevice::setActiveMode(DisplayModeId id) { const auto mode = getMode(id); LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported."); + ATRACE_INT(mActiveModeFPSTrace.c_str(), mode->getFps().getIntValue()); mActiveMode = mode; resetVsyncPeriod(); + if (mRefreshRateConfigs) { + mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId()); + } + if (mRefreshRateOverlay) { + mRefreshRateOverlay->changeRefreshRate(mActiveMode->getFps()); + } } -status_t DisplayDevice::initiateModeChange(DisplayModeId modeId, +status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info, const hal::VsyncPeriodChangeConstraints& constraints, - hal::VsyncPeriodChangeTimeline* outTimeline) const { - const auto mode = getMode(modeId); - if (!mode) { + hal::VsyncPeriodChangeTimeline* outTimeline) { + if (!info.mode || info.mode->getPhysicalDisplayId() != getPhysicalId()) { ALOGE("Trying to initiate a mode change to invalid mode %s on display %s", - std::to_string(modeId.value()).c_str(), to_string(getId()).c_str()); + info.mode ? std::to_string(info.mode->getId().value()).c_str() : "null", + to_string(getId()).c_str()); return BAD_VALUE; } - return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), mode->getHwcId(), constraints, - outTimeline); + mUpcomingActiveMode = info; + ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue()); + return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(), + constraints, outTimeline); } const DisplayModePtr& DisplayDevice::getActiveMode() const { @@ -247,12 +262,23 @@ ui::Dataspace DisplayDevice::getCompositionDataSpace() const { } void DisplayDevice::setLayerStack(ui::LayerStack stack) { - mCompositionDisplay->setLayerStackFilter(stack, isPrimary()); + mCompositionDisplay->setLayerStackFilter(stack, isInternal()); + if (mRefreshRateOverlay) { + mRefreshRateOverlay->setLayerStack(stack); + } +} + +void DisplayDevice::setFlags(uint32_t flags) { + mFlags = flags; } void DisplayDevice::setDisplaySize(int width, int height) { LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays."); - mCompositionDisplay->setDisplaySize(ui::Size(width, height)); + const auto size = ui::Size(width, height); + mCompositionDisplay->setDisplaySize(size); + if (mRefreshRateOverlay) { + mRefreshRateOverlay->setViewport(size); + } } void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect, @@ -292,7 +318,7 @@ ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() { std::string DisplayDevice::getDebugName() const { const char* type = "virtual"; if (mConnectionType) { - type = *mConnectionType == ui::DisplayConnectionType::Internal ? "internal" : "external"; + type = isInternal() ? "internal" : "external"; } return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type, @@ -322,6 +348,10 @@ void DisplayDevice::dump(std::string& result) const { } result.append("\n"); getCompositionDisplay()->dump(result); + + if (mRefreshRateConfigs) { + mRefreshRateConfigs->dump(result); + } } bool DisplayDevice::hasRenderIntent(ui::RenderIntent intent) const { @@ -408,6 +438,80 @@ HdrCapabilities DisplayDevice::getHdrCapabilities() const { capabilities.getDesiredMinLuminance()); } +void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) { + if (!enable) { + mRefreshRateOverlay.reset(); + return; + } + + const auto [lowFps, highFps] = mRefreshRateConfigs->getSupportedRefreshRateRange(); + mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*mFlinger, lowFps.getIntValue(), + highFps.getIntValue(), showSpinnner); + mRefreshRateOverlay->setLayerStack(getLayerStack()); + mRefreshRateOverlay->setViewport(getSize()); + mRefreshRateOverlay->changeRefreshRate(getActiveMode()->getFps()); +} + +bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId, + bool timerExpired) { + if (mRefreshRateConfigs && mRefreshRateOverlay) { + const auto newRefreshRate = + mRefreshRateConfigs->onKernelTimerChanged(desiredModeId, timerExpired); + if (newRefreshRate) { + mRefreshRateOverlay->changeRefreshRate(*newRefreshRate); + return true; + } + } + + return false; +} + +void DisplayDevice::onInvalidate() { + if (mRefreshRateOverlay) { + mRefreshRateOverlay->onInvalidate(); + } +} + +bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) { + ATRACE_CALL(); + + LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided"); + LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch"); + + ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str()); + + std::scoped_lock lock(mActiveModeLock); + if (mDesiredActiveModeChanged) { + // If a mode change is pending, just cache the latest request in mDesiredActiveMode + const Scheduler::ModeEvent prevConfig = mDesiredActiveMode.event; + mDesiredActiveMode = info; + mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig; + return false; + } + + // Check if we are already at the desired mode + if (getActiveMode()->getId() == info.mode->getId()) { + return false; + } + + // Initiate a mode change. + mDesiredActiveModeChanged = true; + mDesiredActiveMode = info; + return true; +} + +std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const { + std::scoped_lock lock(mActiveModeLock); + if (mDesiredActiveModeChanged) return mDesiredActiveMode; + return std::nullopt; +} + +void DisplayDevice::clearDesiredActiveModeState() { + std::scoped_lock lock(mActiveModeLock); + mDesiredActiveMode.event = Scheduler::ModeEvent::None; + mDesiredActiveModeChanged = false; +} + std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1); } // namespace android |