Loading services/surfaceflinger/SurfaceFlinger.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -4888,7 +4888,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode)); } const auto refreshRate = display->refreshRateConfigs().getActiveMode()->getFps(); if (*currentMode == hal::PowerMode::OFF) { if (!currentMode || *currentMode == hal::PowerMode::OFF) { // Turn on the display if (display->isInternal() && (!activeDisplay || !activeDisplay->isPoweredOn())) { onActiveDisplayChangedLocked(display); Loading Loading @@ -6942,9 +6942,12 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal( return NO_ERROR; } scheduler::RefreshRateConfigs::Policy currentPolicy = display->refreshRateConfigs().getCurrentPolicy(); return applyRefreshRateConfigsPolicy(display); } status_t SurfaceFlinger::applyRefreshRateConfigsPolicy(const sp<DisplayDevice>& display) { const scheduler::RefreshRateConfigs::Policy currentPolicy = display->refreshRateConfigs().getCurrentPolicy(); ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str()); // TODO(b/140204874): Leave the event in until we do proper testing with all apps that might Loading Loading @@ -7317,9 +7320,11 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activ onActiveDisplaySizeChanged(activeDisplay); mActiveDisplayTransformHint = activeDisplay->getTransformHint(); // Update the kernel timer for the current active display, since the policy // for this display might have changed when it was not the active display. toggleKernelIdleTimer(); // The policy of the new active/leader display may have changed while it was inactive. In that // case, its preferred mode has not been propagated to HWC (via setDesiredActiveMode). In either // case, the Scheduler's cachedModeChangedParams must be initialized to the newly active mode, // and the kernel idle timer of the newly active display must be toggled. applyRefreshRateConfigsPolicy(activeDisplay); } status_t SurfaceFlinger::addWindowInfosListener( Loading services/surfaceflinger/SurfaceFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -735,6 +735,8 @@ private: const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) EXCLUDES(mStateLock); status_t applyRefreshRateConfigsPolicy(const sp<DisplayDevice>&) REQUIRES(mStateLock); void commitTransactions() EXCLUDES(mStateLock); void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock); void doCommitTransactions() REQUIRES(mStateLock); Loading services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +0 −45 Original line number Diff line number Diff line Loading @@ -120,51 +120,6 @@ void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() { }); } sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay( std::function<void(FakeDisplayDeviceInjector&)> injectExtra) { constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(255u); constexpr int DEFAULT_DISPLAY_WIDTH = 1080; constexpr int DEFAULT_DISPLAY_HEIGHT = 1920; constexpr HWDisplayId DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0; // The DisplayDevice is required to have a framebuffer (behind the // ANativeWindow interface) which uses the actual hardware display // size. EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0))); EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0))); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber()); auto compositionDisplay = compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(), compositionengine::DisplayCreationArgsBuilder() .setId(DEFAULT_DISPLAY_ID) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setPowerAdvisor(&mPowerAdvisor) .build()); constexpr bool kIsPrimary = true; auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, ui::DisplayConnectionType::Internal, DEFAULT_DISPLAY_HWC_DISPLAY_ID, kIsPrimary); injector.setNativeWindow(mNativeWindow); if (injectExtra) { injectExtra(injector); } auto displayDevice = injector.inject(); Mock::VerifyAndClear(mNativeWindow.get()); return displayDevice; } bool DisplayTransactionTest::hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId) const { return mFlinger.hwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1; } Loading services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h +6 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <renderengine/mock/RenderEngine.h> #include <ui/DebugUtils.h> #include "FakeDisplayInjector.h" #include "TestableScheduler.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" Loading Loading @@ -90,7 +91,9 @@ public: void injectFakeBufferQueueFactory(); void injectFakeNativeWindowSurfaceFactory(); sp<DisplayDevice> injectDefaultInternalDisplay( std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)>); std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)> injectExtra) { return mFakeDisplayInjector.injectInternalDisplay(injectExtra); } // -------------------------------------------------------------------- // Postcondition helpers Loading @@ -115,6 +118,8 @@ public: sp<GraphicBuffer> mBuffer = new GraphicBuffer(); Hwc2::mock::PowerAdvisor mPowerAdvisor; FakeDisplayInjector mFakeDisplayInjector{mFlinger, mPowerAdvisor, mNativeWindow}; // These mocks are created by the test, but are destroyed by SurfaceFlinger // by virtue of being stored into a std::unique_ptr. However we still need // to keep a reference to them for use in setting up call expectations. Loading services/surfaceflinger/tests/unittests/FakeDisplayInjector.h 0 → 100644 +96 −0 Original line number 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. */ #pragma once #include <gmock/gmock.h> #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockPowerAdvisor.h" #include "mock/system/window/MockNativeWindow.h" namespace android { using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector; using android::hardware::graphics::composer::hal::HWDisplayId; using android::Hwc2::mock::PowerAdvisor; struct FakeDisplayInjectorArgs { PhysicalDisplayId displayId = PhysicalDisplayId::fromPort(255u); HWDisplayId hwcDisplayId = 0; bool isPrimary = true; }; class FakeDisplayInjector { public: FakeDisplayInjector(TestableSurfaceFlinger& flinger, Hwc2::mock::PowerAdvisor& powerAdvisor, sp<mock::NativeWindow> nativeWindow) : mFlinger(flinger), mPowerAdvisor(powerAdvisor), mNativeWindow(nativeWindow) {} sp<DisplayDevice> injectInternalDisplay( const std::function<void(FakeDisplayDeviceInjector&)>& injectExtra, FakeDisplayInjectorArgs args = {}) { using testing::_; using testing::AnyNumber; using testing::DoAll; using testing::Mock; using testing::Return; using testing::SetArgPointee; constexpr ui::Size kResolution = {1080, 1920}; // The DisplayDevice is required to have a framebuffer (behind the // ANativeWindow interface) which uses the actual hardware display // size. EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(kResolution.getWidth()), Return(0))); EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(kResolution.getHeight()), Return(0))); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber()); auto compositionDisplay = compositionengine::impl:: createDisplay(mFlinger.getCompositionEngine(), compositionengine::DisplayCreationArgsBuilder() .setId(args.displayId) .setPixels(kResolution) .setPowerAdvisor(&mPowerAdvisor) .build()); auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, ui::DisplayConnectionType::Internal, args.hwcDisplayId, args.isPrimary); injector.setNativeWindow(mNativeWindow); if (injectExtra) { injectExtra(injector); } auto displayDevice = injector.inject(); Mock::VerifyAndClear(mNativeWindow.get()); return displayDevice; } TestableSurfaceFlinger& mFlinger; Hwc2::mock::PowerAdvisor& mPowerAdvisor; sp<mock::NativeWindow> mNativeWindow; }; } // namespace android Loading
services/surfaceflinger/SurfaceFlinger.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -4888,7 +4888,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode)); } const auto refreshRate = display->refreshRateConfigs().getActiveMode()->getFps(); if (*currentMode == hal::PowerMode::OFF) { if (!currentMode || *currentMode == hal::PowerMode::OFF) { // Turn on the display if (display->isInternal() && (!activeDisplay || !activeDisplay->isPoweredOn())) { onActiveDisplayChangedLocked(display); Loading Loading @@ -6942,9 +6942,12 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal( return NO_ERROR; } scheduler::RefreshRateConfigs::Policy currentPolicy = display->refreshRateConfigs().getCurrentPolicy(); return applyRefreshRateConfigsPolicy(display); } status_t SurfaceFlinger::applyRefreshRateConfigsPolicy(const sp<DisplayDevice>& display) { const scheduler::RefreshRateConfigs::Policy currentPolicy = display->refreshRateConfigs().getCurrentPolicy(); ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str()); // TODO(b/140204874): Leave the event in until we do proper testing with all apps that might Loading Loading @@ -7317,9 +7320,11 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activ onActiveDisplaySizeChanged(activeDisplay); mActiveDisplayTransformHint = activeDisplay->getTransformHint(); // Update the kernel timer for the current active display, since the policy // for this display might have changed when it was not the active display. toggleKernelIdleTimer(); // The policy of the new active/leader display may have changed while it was inactive. In that // case, its preferred mode has not been propagated to HWC (via setDesiredActiveMode). In either // case, the Scheduler's cachedModeChangedParams must be initialized to the newly active mode, // and the kernel idle timer of the newly active display must be toggled. applyRefreshRateConfigsPolicy(activeDisplay); } status_t SurfaceFlinger::addWindowInfosListener( Loading
services/surfaceflinger/SurfaceFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -735,6 +735,8 @@ private: const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) EXCLUDES(mStateLock); status_t applyRefreshRateConfigsPolicy(const sp<DisplayDevice>&) REQUIRES(mStateLock); void commitTransactions() EXCLUDES(mStateLock); void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock); void doCommitTransactions() REQUIRES(mStateLock); Loading
services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +0 −45 Original line number Diff line number Diff line Loading @@ -120,51 +120,6 @@ void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() { }); } sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay( std::function<void(FakeDisplayDeviceInjector&)> injectExtra) { constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(255u); constexpr int DEFAULT_DISPLAY_WIDTH = 1080; constexpr int DEFAULT_DISPLAY_HEIGHT = 1920; constexpr HWDisplayId DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0; // The DisplayDevice is required to have a framebuffer (behind the // ANativeWindow interface) which uses the actual hardware display // size. EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0))); EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0))); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber()); auto compositionDisplay = compositionengine::impl::createDisplay(mFlinger.getCompositionEngine(), compositionengine::DisplayCreationArgsBuilder() .setId(DEFAULT_DISPLAY_ID) .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT}) .setPowerAdvisor(&mPowerAdvisor) .build()); constexpr bool kIsPrimary = true; auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, ui::DisplayConnectionType::Internal, DEFAULT_DISPLAY_HWC_DISPLAY_ID, kIsPrimary); injector.setNativeWindow(mNativeWindow); if (injectExtra) { injectExtra(injector); } auto displayDevice = injector.inject(); Mock::VerifyAndClear(mNativeWindow.get()); return displayDevice; } bool DisplayTransactionTest::hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId) const { return mFlinger.hwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1; } Loading
services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h +6 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include <renderengine/mock/RenderEngine.h> #include <ui/DebugUtils.h> #include "FakeDisplayInjector.h" #include "TestableScheduler.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" Loading Loading @@ -90,7 +91,9 @@ public: void injectFakeBufferQueueFactory(); void injectFakeNativeWindowSurfaceFactory(); sp<DisplayDevice> injectDefaultInternalDisplay( std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)>); std::function<void(TestableSurfaceFlinger::FakeDisplayDeviceInjector&)> injectExtra) { return mFakeDisplayInjector.injectInternalDisplay(injectExtra); } // -------------------------------------------------------------------- // Postcondition helpers Loading @@ -115,6 +118,8 @@ public: sp<GraphicBuffer> mBuffer = new GraphicBuffer(); Hwc2::mock::PowerAdvisor mPowerAdvisor; FakeDisplayInjector mFakeDisplayInjector{mFlinger, mPowerAdvisor, mNativeWindow}; // These mocks are created by the test, but are destroyed by SurfaceFlinger // by virtue of being stored into a std::unique_ptr. However we still need // to keep a reference to them for use in setting up call expectations. Loading
services/surfaceflinger/tests/unittests/FakeDisplayInjector.h 0 → 100644 +96 −0 Original line number 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. */ #pragma once #include <gmock/gmock.h> #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockPowerAdvisor.h" #include "mock/system/window/MockNativeWindow.h" namespace android { using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector; using android::hardware::graphics::composer::hal::HWDisplayId; using android::Hwc2::mock::PowerAdvisor; struct FakeDisplayInjectorArgs { PhysicalDisplayId displayId = PhysicalDisplayId::fromPort(255u); HWDisplayId hwcDisplayId = 0; bool isPrimary = true; }; class FakeDisplayInjector { public: FakeDisplayInjector(TestableSurfaceFlinger& flinger, Hwc2::mock::PowerAdvisor& powerAdvisor, sp<mock::NativeWindow> nativeWindow) : mFlinger(flinger), mPowerAdvisor(powerAdvisor), mNativeWindow(nativeWindow) {} sp<DisplayDevice> injectInternalDisplay( const std::function<void(FakeDisplayDeviceInjector&)>& injectExtra, FakeDisplayInjectorArgs args = {}) { using testing::_; using testing::AnyNumber; using testing::DoAll; using testing::Mock; using testing::Return; using testing::SetArgPointee; constexpr ui::Size kResolution = {1080, 1920}; // The DisplayDevice is required to have a framebuffer (behind the // ANativeWindow interface) which uses the actual hardware display // size. EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(kResolution.getWidth()), Return(0))); EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(kResolution.getHeight()), Return(0))); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)); EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber()); auto compositionDisplay = compositionengine::impl:: createDisplay(mFlinger.getCompositionEngine(), compositionengine::DisplayCreationArgsBuilder() .setId(args.displayId) .setPixels(kResolution) .setPowerAdvisor(&mPowerAdvisor) .build()); auto injector = FakeDisplayDeviceInjector(mFlinger, compositionDisplay, ui::DisplayConnectionType::Internal, args.hwcDisplayId, args.isPrimary); injector.setNativeWindow(mNativeWindow); if (injectExtra) { injectExtra(injector); } auto displayDevice = injector.inject(); Mock::VerifyAndClear(mNativeWindow.get()); return displayDevice; } TestableSurfaceFlinger& mFlinger; Hwc2::mock::PowerAdvisor& mPowerAdvisor; sp<mock::NativeWindow> mNativeWindow; }; } // namespace android