diff options
14 files changed, 75 insertions, 18 deletions
diff --git a/services/sensorservice/AidlSensorHalWrapper.cpp b/services/sensorservice/AidlSensorHalWrapper.cpp index f5b360f3b6..e60db93431 100644 --- a/services/sensorservice/AidlSensorHalWrapper.cpp +++ b/services/sensorservice/AidlSensorHalWrapper.cpp @@ -308,8 +308,12 @@ status_t AidlSensorHalWrapper::configureDirectChannel(int32_t sensorHandle, int3 } int32_t token; - mSensors->configDirectReport(sensorHandle, channelHandle, rate, &token); - return token; + status_t status = convertToStatus( + mSensors->configDirectReport(sensorHandle, channelHandle, rate, &token)); + if (status == OK && rate != ISensors::RateLevel::STOP) { + status = static_cast<status_t>(token); + } + return status; } void AidlSensorHalWrapper::writeWakeLockHandled(uint32_t count) { diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h index d93e25e4ca..09bc46747a 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h @@ -37,6 +37,15 @@ struct BorderRenderInfo { half4 color; std::vector<int32_t> layerIds; }; + +// Interface of composition engine power hint callback. +struct ICEPowerCallback { + virtual void notifyCpuLoadUp() = 0; + +protected: + ~ICEPowerCallback() = default; +}; + /** * A parameter object for refreshing a set of outputs */ @@ -96,6 +105,8 @@ struct CompositionRefreshArgs { std::vector<BorderRenderInfo> borderInfoList; bool hasTrustedPresentationListener = false; + + ICEPowerCallback* powerCallback = nullptr; }; } // namespace android::compositionengine diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h index a3fda61ecb..28c6e92b06 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h @@ -32,6 +32,7 @@ // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" +#include <compositionengine/CompositionRefreshArgs.h> #include <compositionengine/ProjectionSpace.h> #include <renderengine/BorderRenderInfo.h> #include <ui/LayerStack.h> @@ -167,6 +168,8 @@ struct OutputCompositionState { uint64_t lastOutputLayerHash = 0; uint64_t outputLayerHash = 0; + ICEPowerCallback* powerCallback = nullptr; + // Debugging void dump(std::string& result) const; }; diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 793959cea6..1205a2ce71 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -843,6 +843,7 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr editState().earliestPresentTime = refreshArgs.earliestPresentTime; editState().expectedPresentTime = refreshArgs.expectedPresentTime; + editState().powerCallback = refreshArgs.powerCallback; compositionengine::OutputLayer* peekThroughLayer = nullptr; sp<GraphicBuffer> previousOverride = nullptr; diff --git a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp index c512a1e97f..9713e79fe3 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp @@ -67,7 +67,7 @@ void OutputCompositionState::dump(std::string& out) const { out.append("\n "); out.append("\n "); - dumpVal(out, "treate170mAsSrgb", treat170mAsSrgb); + dumpVal(out, "treat170mAsSrgb", treat170mAsSrgb); out.append("\n"); for (const auto& borderRenderInfo : borderInfoList) { diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp index 8ced0aca36..7547be94e3 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -162,6 +162,9 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te const OutputCompositionState& outputState, bool deviceHandlesColorTransform) { ATRACE_CALL(); + if (outputState.powerCallback) { + outputState.powerCallback->notifyCpuLoadUp(); + } const Rect& viewport = outputState.layerStackSpace.getContent(); const ui::Dataspace& outputDataspace = outputState.dataspace; const ui::Transform::RotationFlags orientation = @@ -177,18 +180,19 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& te .targetLuminanceNits = outputState.displayBrightnessNits, }; - LayerFE::ClientCompositionTargetSettings targetSettings{ - .clip = Region(viewport), - .needsFiltering = false, - .isSecure = outputState.isSecure, - .supportsProtectedContent = false, - .viewport = viewport, - .dataspace = outputDataspace, - .realContentIsVisible = true, - .clearContent = false, - .blurSetting = LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, - .whitePointNits = outputState.displayBrightnessNits, - }; + LayerFE::ClientCompositionTargetSettings + targetSettings{.clip = Region(viewport), + .needsFiltering = false, + .isSecure = outputState.isSecure, + .supportsProtectedContent = false, + .viewport = viewport, + .dataspace = outputDataspace, + .realContentIsVisible = true, + .clearContent = false, + .blurSetting = + LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled, + .whitePointNits = outputState.displayBrightnessNits, + .treat170mAsSrgb = outputState.treat170mAsSrgb}; std::vector<renderengine::LayerSettings> layerSettings; renderengine::LayerSettings highlight; diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h index 961ec808e8..f74ef4c60e 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h @@ -34,6 +34,7 @@ public: MOCK_METHOD(void, setExpensiveRenderingExpected, (DisplayId displayId, bool expected), (override)); MOCK_METHOD(bool, isUsingExpensiveRendering, (), (override)); + MOCK_METHOD(void, notifyCpuLoadUp, (), (override)); MOCK_METHOD(void, notifyDisplayUpdateImminentAndCpuReset, (), (override)); MOCK_METHOD(bool, usePowerHintSession, (), (override)); MOCK_METHOD(bool, supportsPowerHintSession, (), (override)); diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp index f8b466c93c..9c7576e76d 100644 --- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp +++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp @@ -138,6 +138,21 @@ void PowerAdvisor::setExpensiveRenderingExpected(DisplayId displayId, bool expec } } +void PowerAdvisor::notifyCpuLoadUp() { + // Only start sending this notification once the system has booted so we don't introduce an + // early-boot dependency on Power HAL + if (!mBootFinished.load()) { + return; + } + if (usePowerHintSession() && ensurePowerHintSessionRunning()) { + std::lock_guard lock(mHintSessionMutex); + auto ret = mHintSession->sendHint(SessionHint::CPU_LOAD_UP); + if (!ret.isOk()) { + mHintSessionRunning = false; + } + } +} + void PowerAdvisor::notifyDisplayUpdateImminentAndCpuReset() { // Only start sending this notification once the system has booted so we don't introduce an // early-boot dependency on Power HAL diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h index f0d3fd8518..cfaa135299 100644 --- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h +++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h @@ -49,6 +49,7 @@ public: virtual void onBootFinished() = 0; virtual void setExpensiveRenderingExpected(DisplayId displayId, bool expected) = 0; virtual bool isUsingExpensiveRendering() = 0; + virtual void notifyCpuLoadUp() = 0; virtual void notifyDisplayUpdateImminentAndCpuReset() = 0; // Checks both if it supports and if it's enabled virtual bool usePowerHintSession() = 0; @@ -108,6 +109,7 @@ public: void onBootFinished() override; void setExpensiveRenderingExpected(DisplayId displayId, bool expected) override; bool isUsingExpensiveRendering() override { return mNotifiedExpensiveRendering; }; + void notifyCpuLoadUp() override; void notifyDisplayUpdateImminentAndCpuReset() override; bool usePowerHintSession() override; bool supportsPowerHintSession() override; diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp index 09dac23410..ee87687eea 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -37,6 +37,7 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp output->setRenderSurface(std::make_unique<ScreenCaptureRenderSurface>(std::move(args.buffer))); output->setDisplayBrightness(args.sdrWhitePointNits, args.displayBrightnessNits); output->editState().clientTargetBrightness = args.targetBrightness; + output->editState().treat170mAsSrgb = args.treat170mAsSrgb; output->setDisplayColorProfile(std::make_unique<compositionengine::impl::DisplayColorProfile>( compositionengine::DisplayColorProfileCreationArgsBuilder() diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h index 3c307b0733..159c2bf903 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.h +++ b/services/surfaceflinger/ScreenCaptureOutput.h @@ -36,6 +36,7 @@ struct ScreenCaptureOutputArgs { // Counterintuitively, when targetBrightness > 1.0 then dim the scene. float targetBrightness; bool regionSampling; + bool treat170mAsSrgb; }; // ScreenCaptureOutput is used to compose a set of layers into a preallocated buffer. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index fe2db940f7..f4f4bccc7e 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2568,6 +2568,7 @@ void SurfaceFlinger::composite(TimePoint frameTime, VsyncId vsyncId) ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId.value); compositionengine::CompositionRefreshArgs refreshArgs; + refreshArgs.powerCallback = this; const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays); refreshArgs.outputs.reserve(displays.size()); std::vector<DisplayId> displayIds; @@ -3926,6 +3927,10 @@ void SurfaceFlinger::triggerOnFrameRateOverridesChanged() { mScheduler->onFrameRateOverridesChanged(mAppConnectionHandle, displayId); } +void SurfaceFlinger::notifyCpuLoadUp() { + mPowerAdvisor->notifyCpuLoadUp(); +} + void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) { using namespace scheduler; @@ -7419,7 +7424,10 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( renderArea->getHintForSeamlessTransition()); sdrWhitePointNits = state.sdrWhitePointNits; displayBrightnessNits = state.displayBrightnessNits; - if (sdrWhitePointNits > 1.0f) { + // Only clamp the display brightness if this is not a seamless transition. Otherwise + // for seamless transitions it's important to match the current display state as the + // buffer will be shown under these same conditions, and we want to avoid any flickers + if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) { // Restrict the amount of HDR "headroom" in the screenshot to avoid over-dimming // the SDR portion. 2.0 chosen by experimentation constexpr float kMaxScreenshotHeadroom = 2.0f; @@ -7480,7 +7488,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( .sdrWhitePointNits = sdrWhitePointNits, .displayBrightnessNits = displayBrightnessNits, .targetBrightness = targetBrightness, - .regionSampling = regionSampling}); + .regionSampling = regionSampling, + .treat170mAsSrgb = mTreat170mAsSrgb}); const float colorSaturation = grayscale ? 0 : 1; compositionengine::CompositionRefreshArgs refreshArgs{ diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 0bc506f1fe..4b29be86b1 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -194,7 +194,8 @@ class SurfaceFlinger : public BnSurfaceComposer, private IBinder::DeathRecipient, private HWC2::ComposerCallback, private ICompositor, - private scheduler::ISchedulerCallback { + private scheduler::ISchedulerCallback, + private compositionengine::ICEPowerCallback { public: struct SkipInitializationTag {}; @@ -645,6 +646,9 @@ private: void kernelTimerChanged(bool expired) override; void triggerOnFrameRateOverridesChanged() override; + // ICEPowerCallback overrides: + void notifyCpuLoadUp() override; + // Toggles the kernel idle timer on or off depending the policy decisions around refresh rates. void toggleKernelIdleTimer() REQUIRES(mStateLock); diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h index 3caa2b9847..d635508b5e 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h @@ -32,6 +32,7 @@ public: MOCK_METHOD(void, setExpensiveRenderingExpected, (DisplayId displayId, bool expected), (override)); MOCK_METHOD(bool, isUsingExpensiveRendering, (), (override)); + MOCK_METHOD(void, notifyCpuLoadUp, (), (override)); MOCK_METHOD(void, notifyDisplayUpdateImminentAndCpuReset, (), (override)); MOCK_METHOD(bool, usePowerHintSession, (), (override)); MOCK_METHOD(bool, supportsPowerHintSession, (), (override)); |