summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/DisplayDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/DisplayDevice.cpp')
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp126
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