Loading services/surfaceflinger/SurfaceFlinger.cpp +16 −14 Original line number Original line Diff line number Diff line Loading @@ -95,6 +95,7 @@ #include <cmath> #include <cmath> #include <cstdint> #include <cstdint> #include <functional> #include <functional> #include <memory> #include <mutex> #include <mutex> #include <optional> #include <optional> #include <type_traits> #include <type_traits> Loading @@ -113,6 +114,7 @@ #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/PowerAdvisor.h" #include "DisplayHardware/VirtualDisplaySurface.h" #include "DisplayHardware/VirtualDisplaySurface.h" #include "DisplayRenderArea.h" #include "DisplayRenderArea.h" #include "EffectLayer.h" #include "EffectLayer.h" Loading Loading @@ -327,7 +329,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), mPowerAdvisor(*this), mPowerAdvisor(std::make_unique<Hwc2::impl::PowerAdvisor>(*this)), mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) { mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); } } Loading Loading @@ -677,16 +679,16 @@ void SurfaceFlinger::bootFinished() { } } readPersistentProperties(); readPersistentProperties(); mPowerAdvisor.onBootFinished(); mPowerAdvisor->onBootFinished(); mPowerAdvisor.enablePowerHint(mFlagManager.use_adpf_cpu_hint()); mPowerAdvisor->enablePowerHint(mFlagManager.use_adpf_cpu_hint()); if (mPowerAdvisor.usePowerHintSession()) { if (mPowerAdvisor->usePowerHintSession()) { std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid(); std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid(); std::vector<int32_t> tidList; std::vector<int32_t> tidList; tidList.emplace_back(gettid()); tidList.emplace_back(gettid()); if (renderEngineTid.has_value()) { if (renderEngineTid.has_value()) { tidList.emplace_back(*renderEngineTid); tidList.emplace_back(*renderEngineTid); } } if (!mPowerAdvisor.startPowerHintSession(tidList)) { if (!mPowerAdvisor->startPowerHintSession(tidList)) { ALOGW("Cannot start power hint session"); ALOGW("Cannot start power hint session"); } } } } Loading Loading @@ -812,7 +814,7 @@ void SurfaceFlinger::init() { // set initial conditions (e.g. unblank default device) // set initial conditions (e.g. unblank default device) initializeDisplays(); initializeDisplays(); mPowerAdvisor.init(); mPowerAdvisor->init(); char primeShaderCache[PROPERTY_VALUE_MAX]; char primeShaderCache[PROPERTY_VALUE_MAX]; property_get("service.sf.prime_shader_cache", primeShaderCache, "1"); property_get("service.sf.prime_shader_cache", primeShaderCache, "1"); Loading Loading @@ -1284,10 +1286,10 @@ void SurfaceFlinger::disableExpensiveRendering() { const char* const whence = __func__; const char* const whence = __func__; auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) { auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) { ATRACE_NAME(whence); ATRACE_NAME(whence); if (mPowerAdvisor.isUsingExpensiveRendering()) { if (mPowerAdvisor->isUsingExpensiveRendering()) { for (const auto& [_, display] : mDisplays) { for (const auto& [_, display] : mDisplays) { constexpr bool kDisable = false; constexpr bool kDisable = false; mPowerAdvisor.setExpensiveRenderingExpected(display->getId(), kDisable); mPowerAdvisor->setExpensiveRenderingExpected(display->getId(), kDisable); } } } } }); }); Loading Loading @@ -1809,7 +1811,7 @@ void SurfaceFlinger::scheduleCommit(FrameHint hint) { if (hint == FrameHint::kActive) { if (hint == FrameHint::kActive) { mScheduler->resetIdleTimer(); mScheduler->resetIdleTimer(); } } mPowerAdvisor.notifyDisplayUpdateImminent(); mPowerAdvisor->notifyDisplayUpdateImminent(); mScheduler->scheduleFrame(); mScheduler->scheduleFrame(); } } Loading Loading @@ -1979,7 +1981,7 @@ nsecs_t SurfaceFlinger::calculateExpectedPresentTime(DisplayStatInfo stats) cons bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) FTL_FAKE_GUARD(kMainThreadContext) { FTL_FAKE_GUARD(kMainThreadContext) { // we set this once at the beginning of commit to ensure consistency throughout the whole frame // we set this once at the beginning of commit to ensure consistency throughout the whole frame mPowerHintSessionData.sessionEnabled = mPowerAdvisor.usePowerHintSession(); mPowerHintSessionData.sessionEnabled = mPowerAdvisor->usePowerHintSession(); if (mPowerHintSessionData.sessionEnabled) { if (mPowerHintSessionData.sessionEnabled) { mPowerHintSessionData.commitStart = systemTime(); mPowerHintSessionData.commitStart = systemTime(); } } Loading @@ -1998,7 +2000,7 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected mScheduledPresentTime = expectedVsyncTime; mScheduledPresentTime = expectedVsyncTime; if (mPowerHintSessionData.sessionEnabled) { if (mPowerHintSessionData.sessionEnabled) { mPowerAdvisor.setTargetWorkDuration(mExpectedPresentTime - mPowerAdvisor->setTargetWorkDuration(mExpectedPresentTime - mPowerHintSessionData.commitStart); mPowerHintSessionData.commitStart); } } const auto vsyncIn = [&] { const auto vsyncIn = [&] { Loading Loading @@ -2263,7 +2265,7 @@ void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId) if (mPowerHintSessionData.sessionEnabled) { if (mPowerHintSessionData.sessionEnabled) { const nsecs_t flingerDuration = const nsecs_t flingerDuration = (mPowerHintSessionData.presentEnd - mPowerHintSessionData.commitStart); (mPowerHintSessionData.presentEnd - mPowerHintSessionData.commitStart); mPowerAdvisor.sendActualWorkDuration(flingerDuration, mPowerHintSessionData.presentEnd); mPowerAdvisor->sendActualWorkDuration(flingerDuration, mPowerHintSessionData.presentEnd); } } } } Loading Loading @@ -2918,7 +2920,7 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, builder.setPixels(resolution); builder.setPixels(resolution); builder.setIsSecure(state.isSecure); builder.setIsSecure(state.isSecure); builder.setPowerAdvisor(&mPowerAdvisor); builder.setPowerAdvisor(mPowerAdvisor.get()); builder.setName(state.displayName); builder.setName(state.displayName); auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled); compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled); Loading services/surfaceflinger/SurfaceFlinger.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1383,7 +1383,7 @@ private: sp<os::IInputFlinger> mInputFlinger; sp<os::IInputFlinger> mInputFlinger; InputWindowCommands mInputWindowCommands; InputWindowCommands mInputWindowCommands; Hwc2::impl::PowerAdvisor mPowerAdvisor; std::unique_ptr<Hwc2::PowerAdvisor> mPowerAdvisor; void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock); void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock); Loading services/surfaceflinger/tests/unittests/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -103,6 +103,7 @@ cc_test { "SurfaceFlinger_HotplugTest.cpp", "SurfaceFlinger_HotplugTest.cpp", "SurfaceFlinger_NotifyPowerBoostTest.cpp", "SurfaceFlinger_NotifyPowerBoostTest.cpp", "SurfaceFlinger_OnInitializeDisplaysTest.cpp", "SurfaceFlinger_OnInitializeDisplaysTest.cpp", "SurfaceFlinger_PowerHintTest.cpp", "SurfaceFlinger_SetDisplayStateTest.cpp", "SurfaceFlinger_SetDisplayStateTest.cpp", "SurfaceFlinger_SetPowerModeInternalTest.cpp", "SurfaceFlinger_SetPowerModeInternalTest.cpp", "SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp", "SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp", Loading services/surfaceflinger/tests/unittests/CompositionTest.cpp +4 −3 Original line number Original line Diff line number Diff line Loading @@ -113,8 +113,9 @@ public: mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats)); mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats)); mComposer = new Hwc2::mock::Composer(); mComposer = new Hwc2::mock::Composer(); mPowerAdvisor = new Hwc2::mock::PowerAdvisor(); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor>(mPowerAdvisor)); mFlinger.mutableMaxRenderTargetSize() = 16384; mFlinger.mutableMaxRenderTargetSize() = 16384; } } Loading Loading @@ -188,7 +189,7 @@ public: Hwc2::mock::Composer* mComposer = nullptr; Hwc2::mock::Composer* mComposer = nullptr; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); mock::TimeStats* mTimeStats = new mock::TimeStats(); mock::TimeStats* mTimeStats = new mock::TimeStats(); Hwc2::mock::PowerAdvisor mPowerAdvisor; Hwc2::mock::PowerAdvisor* mPowerAdvisor = nullptr; sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE; sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE; Loading Loading @@ -300,7 +301,7 @@ struct BaseDisplayVariant { .setId(DEFAULT_DISPLAY_ID) .setId(DEFAULT_DISPLAY_ID) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setIsSecure(Derived::IS_SECURE) .setIsSecure(Derived::IS_SECURE) .setPowerAdvisor(&test->mPowerAdvisor) .setPowerAdvisor(test->mPowerAdvisor) .setName(std::string("Injected display for ") + .setName(std::string("Injected display for ") + test_info->test_case_name() + "." + test_info->name()) test_info->test_case_name() + "." + test_info->name()) .build(); .build(); Loading services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp 0 → 100644 +155 −0 Original line number Original line Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef LOG_TAG #define LOG_TAG "SurfaceFlingerPowerHintTest" #include <compositionengine/Display.h> #include <compositionengine/mock/DisplaySurface.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <renderengine/mock/RenderEngine.h> #include <algorithm> #include <chrono> #include <memory> #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/DisplayHardware/MockPowerAdvisor.h" #include "mock/MockEventThread.h" #include "mock/MockTimeStats.h" #include "mock/MockVsyncController.h" #include "mock/system/window/MockNativeWindow.h" using namespace android; using namespace android::Hwc2::mock; using namespace android::hardware::power; using namespace std::chrono_literals; using namespace testing; namespace android { namespace { using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector; using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector; constexpr hal::HWDisplayId HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DISPLAY_ID; constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u); constexpr int DEFAULT_DISPLAY_WIDTH = 1920; constexpr int DEFAULT_DISPLAY_HEIGHT = 1024; class SurfaceFlingerPowerHintTest : public Test { public: void SetUp() override; void setupScheduler(); protected: TestableSurfaceFlinger mFlinger; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); sp<DisplayDevice> mDisplay; sp<compositionengine::mock::DisplaySurface> mDisplaySurface = new compositionengine::mock::DisplaySurface(); mock::NativeWindow* mNativeWindow = new mock::NativeWindow(); mock::TimeStats* mTimeStats = new mock::TimeStats(); Hwc2::mock::PowerAdvisor* mPowerAdvisor = nullptr; Hwc2::mock::Composer* mComposer = nullptr; }; void SurfaceFlingerPowerHintTest::SetUp() { setupScheduler(); mComposer = new Hwc2::mock::Composer(); mPowerAdvisor = new Hwc2::mock::PowerAdvisor(); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats)); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor>(mPowerAdvisor)); static constexpr bool kIsPrimary = true; FakeHwcDisplayInjector(DEFAULT_DISPLAY_ID, hal::DisplayType::PHYSICAL, kIsPrimary) .setPowerMode(hal::PowerMode::ON) .inject(&mFlinger, mComposer); auto compostionEngineDisplayArgs = compositionengine::DisplayCreationArgsBuilder() .setId(DEFAULT_DISPLAY_ID) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setPowerAdvisor(mPowerAdvisor) .setName("injected display") .build(); auto compositionDisplay = compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(), std::move(compostionEngineDisplayArgs)); mDisplay = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, ui::DisplayConnectionType::Internal, HWC_DISPLAY, kIsPrimary) .setDisplaySurface(mDisplaySurface) .setNativeWindow(mNativeWindow) .setPowerMode(hal::PowerMode::ON) .inject(); } void SurfaceFlingerPowerHintTest::setupScheduler() { auto eventThread = std::make_unique<mock::EventThread>(); auto sfEventThread = std::make_unique<mock::EventThread>(); EXPECT_CALL(*eventThread, registerDisplayEventConnection(_)); EXPECT_CALL(*eventThread, createEventConnection(_, _)) .WillOnce(Return(new EventThreadConnection(eventThread.get(), /*callingUid=*/0, ResyncCallback()))); EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_)); EXPECT_CALL(*sfEventThread, createEventConnection(_, _)) .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), /*callingUid=*/0, ResyncCallback()))); auto vsyncController = std::make_unique<mock::VsyncController>(); auto vsyncTracker = std::make_unique<mock::VSyncTracker>(); EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0)); EXPECT_CALL(*vsyncTracker, currentPeriod()) .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)); EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0)); mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker), std::move(eventThread), std::move(sfEventThread), TestableSurfaceFlinger::SchedulerCallbackImpl::kNoOp, TestableSurfaceFlinger::kTwoDisplayModes); } TEST_F(SurfaceFlingerPowerHintTest, sendDurationsIncludingHwcWaitTime) { ON_CALL(*mPowerAdvisor, usePowerHintSession()).WillByDefault(Return(true)); const std::chrono::nanoseconds mockVsyncPeriod = 15ms; const std::chrono::nanoseconds expectedTargetTime = 14ms; EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(Gt(expectedTargetTime.count()))).Times(1); const nsecs_t now = systemTime(); const std::chrono::nanoseconds mockHwcRunTime = 20ms; EXPECT_CALL(*mDisplaySurface, prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc)) .Times(1); EXPECT_CALL(*mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _, _)) .WillOnce([mockHwcRunTime] { std::this_thread::sleep_for(mockHwcRunTime); return hardware::graphics::composer::V2_1::Error::NONE; }); EXPECT_CALL(*mPowerAdvisor, sendActualWorkDuration(Gt(mockHwcRunTime.count()), Gt(now + mockHwcRunTime.count()))) .Times(1); static constexpr bool kVsyncId = 123; // arbitrary mFlinger.commitAndComposite(now, kVsyncId, now + mockVsyncPeriod.count()); } } // namespace } // namespace android Loading
services/surfaceflinger/SurfaceFlinger.cpp +16 −14 Original line number Original line Diff line number Diff line Loading @@ -95,6 +95,7 @@ #include <cmath> #include <cmath> #include <cstdint> #include <cstdint> #include <functional> #include <functional> #include <memory> #include <mutex> #include <mutex> #include <optional> #include <optional> #include <type_traits> #include <type_traits> Loading @@ -113,6 +114,7 @@ #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/PowerAdvisor.h" #include "DisplayHardware/VirtualDisplaySurface.h" #include "DisplayHardware/VirtualDisplaySurface.h" #include "DisplayRenderArea.h" #include "DisplayRenderArea.h" #include "EffectLayer.h" #include "EffectLayer.h" Loading Loading @@ -327,7 +329,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), mPowerAdvisor(*this), mPowerAdvisor(std::make_unique<Hwc2::impl::PowerAdvisor>(*this)), mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) { mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); } } Loading Loading @@ -677,16 +679,16 @@ void SurfaceFlinger::bootFinished() { } } readPersistentProperties(); readPersistentProperties(); mPowerAdvisor.onBootFinished(); mPowerAdvisor->onBootFinished(); mPowerAdvisor.enablePowerHint(mFlagManager.use_adpf_cpu_hint()); mPowerAdvisor->enablePowerHint(mFlagManager.use_adpf_cpu_hint()); if (mPowerAdvisor.usePowerHintSession()) { if (mPowerAdvisor->usePowerHintSession()) { std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid(); std::optional<pid_t> renderEngineTid = getRenderEngine().getRenderEngineTid(); std::vector<int32_t> tidList; std::vector<int32_t> tidList; tidList.emplace_back(gettid()); tidList.emplace_back(gettid()); if (renderEngineTid.has_value()) { if (renderEngineTid.has_value()) { tidList.emplace_back(*renderEngineTid); tidList.emplace_back(*renderEngineTid); } } if (!mPowerAdvisor.startPowerHintSession(tidList)) { if (!mPowerAdvisor->startPowerHintSession(tidList)) { ALOGW("Cannot start power hint session"); ALOGW("Cannot start power hint session"); } } } } Loading Loading @@ -812,7 +814,7 @@ void SurfaceFlinger::init() { // set initial conditions (e.g. unblank default device) // set initial conditions (e.g. unblank default device) initializeDisplays(); initializeDisplays(); mPowerAdvisor.init(); mPowerAdvisor->init(); char primeShaderCache[PROPERTY_VALUE_MAX]; char primeShaderCache[PROPERTY_VALUE_MAX]; property_get("service.sf.prime_shader_cache", primeShaderCache, "1"); property_get("service.sf.prime_shader_cache", primeShaderCache, "1"); Loading Loading @@ -1284,10 +1286,10 @@ void SurfaceFlinger::disableExpensiveRendering() { const char* const whence = __func__; const char* const whence = __func__; auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) { auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) { ATRACE_NAME(whence); ATRACE_NAME(whence); if (mPowerAdvisor.isUsingExpensiveRendering()) { if (mPowerAdvisor->isUsingExpensiveRendering()) { for (const auto& [_, display] : mDisplays) { for (const auto& [_, display] : mDisplays) { constexpr bool kDisable = false; constexpr bool kDisable = false; mPowerAdvisor.setExpensiveRenderingExpected(display->getId(), kDisable); mPowerAdvisor->setExpensiveRenderingExpected(display->getId(), kDisable); } } } } }); }); Loading Loading @@ -1809,7 +1811,7 @@ void SurfaceFlinger::scheduleCommit(FrameHint hint) { if (hint == FrameHint::kActive) { if (hint == FrameHint::kActive) { mScheduler->resetIdleTimer(); mScheduler->resetIdleTimer(); } } mPowerAdvisor.notifyDisplayUpdateImminent(); mPowerAdvisor->notifyDisplayUpdateImminent(); mScheduler->scheduleFrame(); mScheduler->scheduleFrame(); } } Loading Loading @@ -1979,7 +1981,7 @@ nsecs_t SurfaceFlinger::calculateExpectedPresentTime(DisplayStatInfo stats) cons bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) FTL_FAKE_GUARD(kMainThreadContext) { FTL_FAKE_GUARD(kMainThreadContext) { // we set this once at the beginning of commit to ensure consistency throughout the whole frame // we set this once at the beginning of commit to ensure consistency throughout the whole frame mPowerHintSessionData.sessionEnabled = mPowerAdvisor.usePowerHintSession(); mPowerHintSessionData.sessionEnabled = mPowerAdvisor->usePowerHintSession(); if (mPowerHintSessionData.sessionEnabled) { if (mPowerHintSessionData.sessionEnabled) { mPowerHintSessionData.commitStart = systemTime(); mPowerHintSessionData.commitStart = systemTime(); } } Loading @@ -1998,7 +2000,7 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected mScheduledPresentTime = expectedVsyncTime; mScheduledPresentTime = expectedVsyncTime; if (mPowerHintSessionData.sessionEnabled) { if (mPowerHintSessionData.sessionEnabled) { mPowerAdvisor.setTargetWorkDuration(mExpectedPresentTime - mPowerAdvisor->setTargetWorkDuration(mExpectedPresentTime - mPowerHintSessionData.commitStart); mPowerHintSessionData.commitStart); } } const auto vsyncIn = [&] { const auto vsyncIn = [&] { Loading Loading @@ -2263,7 +2265,7 @@ void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId) if (mPowerHintSessionData.sessionEnabled) { if (mPowerHintSessionData.sessionEnabled) { const nsecs_t flingerDuration = const nsecs_t flingerDuration = (mPowerHintSessionData.presentEnd - mPowerHintSessionData.commitStart); (mPowerHintSessionData.presentEnd - mPowerHintSessionData.commitStart); mPowerAdvisor.sendActualWorkDuration(flingerDuration, mPowerHintSessionData.presentEnd); mPowerAdvisor->sendActualWorkDuration(flingerDuration, mPowerHintSessionData.presentEnd); } } } } Loading Loading @@ -2918,7 +2920,7 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, builder.setPixels(resolution); builder.setPixels(resolution); builder.setIsSecure(state.isSecure); builder.setIsSecure(state.isSecure); builder.setPowerAdvisor(&mPowerAdvisor); builder.setPowerAdvisor(mPowerAdvisor.get()); builder.setName(state.displayName); builder.setName(state.displayName); auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); auto compositionDisplay = getCompositionEngine().createDisplay(builder.build()); compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled); compositionDisplay->setLayerCachingEnabled(mLayerCachingEnabled); Loading
services/surfaceflinger/SurfaceFlinger.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1383,7 +1383,7 @@ private: sp<os::IInputFlinger> mInputFlinger; sp<os::IInputFlinger> mInputFlinger; InputWindowCommands mInputWindowCommands; InputWindowCommands mInputWindowCommands; Hwc2::impl::PowerAdvisor mPowerAdvisor; std::unique_ptr<Hwc2::PowerAdvisor> mPowerAdvisor; void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock); void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock); Loading
services/surfaceflinger/tests/unittests/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -103,6 +103,7 @@ cc_test { "SurfaceFlinger_HotplugTest.cpp", "SurfaceFlinger_HotplugTest.cpp", "SurfaceFlinger_NotifyPowerBoostTest.cpp", "SurfaceFlinger_NotifyPowerBoostTest.cpp", "SurfaceFlinger_OnInitializeDisplaysTest.cpp", "SurfaceFlinger_OnInitializeDisplaysTest.cpp", "SurfaceFlinger_PowerHintTest.cpp", "SurfaceFlinger_SetDisplayStateTest.cpp", "SurfaceFlinger_SetDisplayStateTest.cpp", "SurfaceFlinger_SetPowerModeInternalTest.cpp", "SurfaceFlinger_SetPowerModeInternalTest.cpp", "SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp", "SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp", Loading
services/surfaceflinger/tests/unittests/CompositionTest.cpp +4 −3 Original line number Original line Diff line number Diff line Loading @@ -113,8 +113,9 @@ public: mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats)); mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats)); mComposer = new Hwc2::mock::Composer(); mComposer = new Hwc2::mock::Composer(); mPowerAdvisor = new Hwc2::mock::PowerAdvisor(); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor>(mPowerAdvisor)); mFlinger.mutableMaxRenderTargetSize() = 16384; mFlinger.mutableMaxRenderTargetSize() = 16384; } } Loading Loading @@ -188,7 +189,7 @@ public: Hwc2::mock::Composer* mComposer = nullptr; Hwc2::mock::Composer* mComposer = nullptr; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); mock::TimeStats* mTimeStats = new mock::TimeStats(); mock::TimeStats* mTimeStats = new mock::TimeStats(); Hwc2::mock::PowerAdvisor mPowerAdvisor; Hwc2::mock::PowerAdvisor* mPowerAdvisor = nullptr; sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE; sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE; Loading Loading @@ -300,7 +301,7 @@ struct BaseDisplayVariant { .setId(DEFAULT_DISPLAY_ID) .setId(DEFAULT_DISPLAY_ID) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setIsSecure(Derived::IS_SECURE) .setIsSecure(Derived::IS_SECURE) .setPowerAdvisor(&test->mPowerAdvisor) .setPowerAdvisor(test->mPowerAdvisor) .setName(std::string("Injected display for ") + .setName(std::string("Injected display for ") + test_info->test_case_name() + "." + test_info->name()) test_info->test_case_name() + "." + test_info->name()) .build(); .build(); Loading
services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp 0 → 100644 +155 −0 Original line number Original line Diff line number Diff line /* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef LOG_TAG #define LOG_TAG "SurfaceFlingerPowerHintTest" #include <compositionengine/Display.h> #include <compositionengine/mock/DisplaySurface.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <renderengine/mock/RenderEngine.h> #include <algorithm> #include <chrono> #include <memory> #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/DisplayHardware/MockPowerAdvisor.h" #include "mock/MockEventThread.h" #include "mock/MockTimeStats.h" #include "mock/MockVsyncController.h" #include "mock/system/window/MockNativeWindow.h" using namespace android; using namespace android::Hwc2::mock; using namespace android::hardware::power; using namespace std::chrono_literals; using namespace testing; namespace android { namespace { using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector; using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector; constexpr hal::HWDisplayId HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DISPLAY_ID; constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u); constexpr int DEFAULT_DISPLAY_WIDTH = 1920; constexpr int DEFAULT_DISPLAY_HEIGHT = 1024; class SurfaceFlingerPowerHintTest : public Test { public: void SetUp() override; void setupScheduler(); protected: TestableSurfaceFlinger mFlinger; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); sp<DisplayDevice> mDisplay; sp<compositionengine::mock::DisplaySurface> mDisplaySurface = new compositionengine::mock::DisplaySurface(); mock::NativeWindow* mNativeWindow = new mock::NativeWindow(); mock::TimeStats* mTimeStats = new mock::TimeStats(); Hwc2::mock::PowerAdvisor* mPowerAdvisor = nullptr; Hwc2::mock::Composer* mComposer = nullptr; }; void SurfaceFlingerPowerHintTest::SetUp() { setupScheduler(); mComposer = new Hwc2::mock::Composer(); mPowerAdvisor = new Hwc2::mock::PowerAdvisor(); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); mFlinger.setupTimeStats(std::shared_ptr<TimeStats>(mTimeStats)); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.setupPowerAdvisor(std::unique_ptr<Hwc2::PowerAdvisor>(mPowerAdvisor)); static constexpr bool kIsPrimary = true; FakeHwcDisplayInjector(DEFAULT_DISPLAY_ID, hal::DisplayType::PHYSICAL, kIsPrimary) .setPowerMode(hal::PowerMode::ON) .inject(&mFlinger, mComposer); auto compostionEngineDisplayArgs = compositionengine::DisplayCreationArgsBuilder() .setId(DEFAULT_DISPLAY_ID) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setPowerAdvisor(mPowerAdvisor) .setName("injected display") .build(); auto compositionDisplay = compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(), std::move(compostionEngineDisplayArgs)); mDisplay = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, ui::DisplayConnectionType::Internal, HWC_DISPLAY, kIsPrimary) .setDisplaySurface(mDisplaySurface) .setNativeWindow(mNativeWindow) .setPowerMode(hal::PowerMode::ON) .inject(); } void SurfaceFlingerPowerHintTest::setupScheduler() { auto eventThread = std::make_unique<mock::EventThread>(); auto sfEventThread = std::make_unique<mock::EventThread>(); EXPECT_CALL(*eventThread, registerDisplayEventConnection(_)); EXPECT_CALL(*eventThread, createEventConnection(_, _)) .WillOnce(Return(new EventThreadConnection(eventThread.get(), /*callingUid=*/0, ResyncCallback()))); EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_)); EXPECT_CALL(*sfEventThread, createEventConnection(_, _)) .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), /*callingUid=*/0, ResyncCallback()))); auto vsyncController = std::make_unique<mock::VsyncController>(); auto vsyncTracker = std::make_unique<mock::VSyncTracker>(); EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0)); EXPECT_CALL(*vsyncTracker, currentPeriod()) .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)); EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0)); mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker), std::move(eventThread), std::move(sfEventThread), TestableSurfaceFlinger::SchedulerCallbackImpl::kNoOp, TestableSurfaceFlinger::kTwoDisplayModes); } TEST_F(SurfaceFlingerPowerHintTest, sendDurationsIncludingHwcWaitTime) { ON_CALL(*mPowerAdvisor, usePowerHintSession()).WillByDefault(Return(true)); const std::chrono::nanoseconds mockVsyncPeriod = 15ms; const std::chrono::nanoseconds expectedTargetTime = 14ms; EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(Gt(expectedTargetTime.count()))).Times(1); const nsecs_t now = systemTime(); const std::chrono::nanoseconds mockHwcRunTime = 20ms; EXPECT_CALL(*mDisplaySurface, prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc)) .Times(1); EXPECT_CALL(*mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _, _)) .WillOnce([mockHwcRunTime] { std::this_thread::sleep_for(mockHwcRunTime); return hardware::graphics::composer::V2_1::Error::NONE; }); EXPECT_CALL(*mPowerAdvisor, sendActualWorkDuration(Gt(mockHwcRunTime.count()), Gt(now + mockHwcRunTime.count()))) .Times(1); static constexpr bool kVsyncId = 123; // arbitrary mFlinger.commitAndComposite(now, kVsyncId, now + mockVsyncPeriod.count()); } } // namespace } // namespace android