diff options
17 files changed, 120 insertions, 37 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 59311a012a..74be7cedc7 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -342,8 +342,7 @@ static int restorecon_app_data_lazy(const std::string& path, const std::string& // If the initial top-level restorecon above changed the label, then go // back and restorecon everything recursively - // TODO(b/190567190, b/188141923) Remove recursive fixup of com.google.android.gsf. - if (strcmp(before, after) || (path.find("com.google.android.gsf") != std::string::npos)) { + if (strcmp(before, after)) { if (existing) { LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at " << path << "; running recursive restorecon"; diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index c64371b84a..6b6d43425d 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -125,11 +125,16 @@ bool BufferQueueLayer::isBufferDue(nsecs_t expectedPresentTime) const { // ----------------------------------------------------------------------- bool BufferQueueLayer::fenceHasSignaled() const { + Mutex::Autolock lock(mQueueItemLock); + + if (SurfaceFlinger::enableLatchUnsignaled) { + return true; + } + if (!hasFrameUpdate()) { return true; } - Mutex::Autolock lock(mQueueItemLock); if (mQueueItems[0].item.mIsDroppable) { // Even though this buffer's fence may not have signaled yet, it could // be replaced by another buffer before it has a chance to, which means diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 2a49a0a340..645e883364 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -635,6 +635,10 @@ FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) c // Interface implementation for BufferLayer // ----------------------------------------------------------------------- bool BufferStateLayer::fenceHasSignaled() const { + if (SurfaceFlinger::enableLatchUnsignaled) { + return true; + } + const bool fenceSignaled = getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled; if (!fenceSignaled) { diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h index 29937fb089..554e2f4868 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h @@ -24,6 +24,7 @@ #include <compositionengine/LayerFE.h> #include <compositionengine/OutputColorSetting.h> #include <math/mat4.h> +#include <ui/FenceTime.h> #include <ui/Transform.h> namespace android::compositionengine { @@ -83,6 +84,10 @@ struct CompositionRefreshArgs { // The earliest time to send the present command to the HAL std::chrono::steady_clock::time_point earliestPresentTime; + // The previous present fence. Used together with earliestPresentTime + // to prevent an early presentation of a frame. + std::shared_ptr<FenceTime> previousPresentFence; + // The predicted next invalidation time std::optional<std::chrono::steady_clock::time_point> nextInvalidateTime; }; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h index d41c2dd527..f34cb94079 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h @@ -19,6 +19,7 @@ #include <cstdint> #include <math/mat4.h> +#include <ui/FenceTime.h> // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic push @@ -118,6 +119,10 @@ struct OutputCompositionState { // The earliest time to send the present command to the HAL std::chrono::steady_clock::time_point earliestPresentTime; + // The previous present fence. Used together with earliestPresentTime + // to prevent an early presentation of a frame. + std::shared_ptr<FenceTime> previousPresentFence; + // Current display brightness float displayBrightnessNits{-1.f}; diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index ae1336ec9d..2f2c686805 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -229,7 +229,8 @@ void Display::chooseCompositionStrategy() { auto& hwc = getCompositionEngine().getHwComposer(); if (status_t result = hwc.getDeviceCompositionChanges(*halDisplayId, anyLayersRequireClientComposition(), - getState().earliestPresentTime, &changes); + getState().earliestPresentTime, + getState().previousPresentFence, &changes); result != NO_ERROR) { ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result, strerror(-result)); @@ -330,7 +331,8 @@ compositionengine::Output::FrameFences Display::presentAndGetFrameFences() { } auto& hwc = getCompositionEngine().getHwComposer(); - hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime); + hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime, + getState().previousPresentFence); fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt); diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 67bb1496e5..cafcb40e80 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -729,6 +729,7 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr } editState().earliestPresentTime = refreshArgs.earliestPresentTime; + editState().previousPresentFence = refreshArgs.previousPresentFence; compositionengine::OutputLayer* peekThroughLayer = nullptr; sp<GraphicBuffer> previousOverride = nullptr; diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index db9437b9a8..c037cc6173 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -579,7 +579,7 @@ TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfGpuDisplay) { TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) { EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false)); EXPECT_CALL(mHwComposer, - getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), false, _, _)) + getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), false, _, _, _)) .WillOnce(Return(INVALID_OPERATION)); mDisplay->chooseCompositionStrategy(); @@ -602,7 +602,7 @@ TEST_F(DisplayChooseCompositionStrategyTest, normalOperation) { .WillOnce(Return(false)); EXPECT_CALL(mHwComposer, - getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _)) + getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _, _)) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false)); @@ -633,8 +633,8 @@ TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) { .WillOnce(Return(false)); EXPECT_CALL(mHwComposer, - getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _)) - .WillOnce(DoAll(SetArgPointee<3>(changes), Return(NO_ERROR))); + getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _, _, _)) + .WillOnce(DoAll(SetArgPointee<4>(changes), Return(NO_ERROR))); EXPECT_CALL(*mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1); EXPECT_CALL(*mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1); EXPECT_CALL(*mDisplay, applyLayerRequestsToLayers(changes.layerRequests)).Times(1); @@ -844,7 +844,7 @@ TEST_F(DisplayPresentAndGetFrameFencesTest, returnsPresentAndLayerFences) { sp<Fence> layer1Fence = new Fence(); sp<Fence> layer2Fence = new Fence(); - EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID), _)) + EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID), _, _)) .Times(1); EXPECT_CALL(mHwComposer, getPresentFence(HalDisplayId(DEFAULT_DISPLAY_ID))) .WillOnce(Return(presentFence)); @@ -1020,7 +1020,7 @@ TEST_F(DisplayFunctionalTest, postFramebufferCriticalCallsAreOrdered) { mDisplay->editState().isEnabled = true; - EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(_, _)); + EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(_, _, _)); EXPECT_CALL(*mDisplaySurface, onFrameCommitted()); mDisplay->postFramebuffer(); diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h index 64cbea91a3..a195e5808a 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h @@ -52,14 +52,16 @@ public: std::optional<PhysicalDisplayId>)); MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId)); MOCK_METHOD1(createLayer, std::shared_ptr<HWC2::Layer>(HalDisplayId)); - MOCK_METHOD4(getDeviceCompositionChanges, + MOCK_METHOD5(getDeviceCompositionChanges, status_t(HalDisplayId, bool, std::chrono::steady_clock::time_point, + const std::shared_ptr<FenceTime>&, std::optional<android::HWComposer::DeviceRequestedChanges>*)); MOCK_METHOD5(setClientTarget, status_t(HalDisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&, ui::Dataspace)); - MOCK_METHOD2(presentAndGetReleaseFences, - status_t(HalDisplayId, std::chrono::steady_clock::time_point)); + MOCK_METHOD3(presentAndGetReleaseFences, + status_t(HalDisplayId, std::chrono::steady_clock::time_point, + const std::shared_ptr<FenceTime>&)); MOCK_METHOD2(setPowerMode, status_t(PhysicalDisplayId, hal::PowerMode)); MOCK_METHOD2(setActiveConfig, status_t(HalDisplayId, size_t)); MOCK_METHOD2(setColorTransform, status_t(HalDisplayId, const mat4&)); diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h index b738096479..fc8cb507c4 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h @@ -29,8 +29,10 @@ public: PowerAdvisor(); ~PowerAdvisor() override; + MOCK_METHOD0(init, void()); MOCK_METHOD0(onBootFinished, void()); MOCK_METHOD2(setExpensiveRenderingExpected, void(DisplayId displayId, bool expected)); + MOCK_METHOD0(isUsingExpensiveRendering, bool()); MOCK_METHOD0(notifyDisplayUpdateImminent, void()); }; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 32f04e56bc..7e45dabdea 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -471,6 +471,7 @@ status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot, status_t HWComposer::getDeviceCompositionChanges( HalDisplayId displayId, bool frameUsesClientComposition, std::chrono::steady_clock::time_point earliestPresentTime, + const std::shared_ptr<FenceTime>& previousPresentFence, std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) { ATRACE_CALL(); @@ -487,12 +488,16 @@ status_t HWComposer::getDeviceCompositionChanges( hal::Error error = hal::Error::NONE; - // First try to skip validate altogether when we passed the earliest time - // to present and there is no client. Otherwise, we may present a frame too - // early or in case of client composition we first need to render the + // First try to skip validate altogether. We can do that when + // 1. The previous frame has not been presented yet or already passed the + // earliest time to present. Otherwise, we may present a frame too early. + // 2. There is no client composition. Otherwise, we first need to render the // client target buffer. - const bool canSkipValidate = - std::chrono::steady_clock::now() >= earliestPresentTime && !frameUsesClientComposition; + const bool prevFencePending = + previousPresentFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING; + const bool canPresentEarly = + !prevFencePending && std::chrono::steady_clock::now() < earliestPresentTime; + const bool canSkipValidate = !canPresentEarly && !frameUsesClientComposition; displayData.validateWasSkipped = false; if (canSkipValidate) { sp<Fence> outPresentFence; @@ -559,7 +564,8 @@ sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* } status_t HWComposer::presentAndGetReleaseFences( - HalDisplayId displayId, std::chrono::steady_clock::time_point earliestPresentTime) { + HalDisplayId displayId, std::chrono::steady_clock::time_point earliestPresentTime, + const std::shared_ptr<FenceTime>& previousPresentFence) { ATRACE_CALL(); RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); @@ -575,7 +581,9 @@ status_t HWComposer::presentAndGetReleaseFences( return NO_ERROR; } - { + const bool previousFramePending = + previousPresentFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING; + if (!previousFramePending) { ATRACE_NAME("wait for earliest present time"); std::this_thread::sleep_until(earliestPresentTime); } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index cd6f9f516f..b1849e8c11 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -27,7 +27,7 @@ #include <vector> #include <android-base/thread_annotations.h> -#include <ui/Fence.h> +#include <ui/FenceTime.h> // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic push @@ -134,6 +134,7 @@ public: virtual status_t getDeviceCompositionChanges( HalDisplayId, bool frameUsesClientComposition, std::chrono::steady_clock::time_point earliestPresentTime, + const std::shared_ptr<FenceTime>& previousPresentFence, std::optional<DeviceRequestedChanges>* outChanges) = 0; virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence, @@ -141,7 +142,8 @@ public: // Present layers to the display and read releaseFences. virtual status_t presentAndGetReleaseFences( - HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime) = 0; + HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime, + const std::shared_ptr<FenceTime>& previousPresentFence) = 0; // set power mode virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0; @@ -275,6 +277,7 @@ public: status_t getDeviceCompositionChanges( HalDisplayId, bool frameUsesClientComposition, std::chrono::steady_clock::time_point earliestPresentTime, + const std::shared_ptr<FenceTime>& previousPresentFence, std::optional<DeviceRequestedChanges>* outChanges) override; status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence, @@ -282,7 +285,8 @@ public: // Present layers to the display and read releaseFences. status_t presentAndGetReleaseFences( - HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime) override; + HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime, + const std::shared_ptr<FenceTime>& previousPresentFence) override; // set power mode status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override; diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp index 901e19a6a2..1765caf847 100644 --- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp +++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp @@ -32,6 +32,7 @@ #include "../SurfaceFlingerProperties.h" #include "PowerAdvisor.h" +#include "SurfaceFlinger.h" namespace android { namespace Hwc2 { @@ -61,14 +62,22 @@ int32_t getUpdateTimeout() { } // namespace -PowerAdvisor::PowerAdvisor() - : mUseUpdateImminentTimer(getUpdateTimeout() > 0), - mUpdateImminentTimer( +PowerAdvisor::PowerAdvisor(SurfaceFlinger& flinger) + : mFlinger(flinger), + mUseScreenUpdateTimer(getUpdateTimeout() > 0), + mScreenUpdateTimer( "UpdateImminentTimer", OneShotTimer::Interval(getUpdateTimeout()), /* resetCallback */ [this] { mSendUpdateImminent.store(false); }, - /* timeoutCallback */ [this] { mSendUpdateImminent.store(true); }) { - if (mUseUpdateImminentTimer) { - mUpdateImminentTimer.start(); + /* timeoutCallback */ + [this] { + mSendUpdateImminent.store(true); + mFlinger.disableExpensiveRendering(); + }) {} + +void PowerAdvisor::init() { + // Defer starting the screen update timer until SurfaceFlinger finishes construction. + if (mUseScreenUpdateTimer) { + mScreenUpdateTimer.start(); } } @@ -122,8 +131,8 @@ void PowerAdvisor::notifyDisplayUpdateImminent() { } } - if (mUseUpdateImminentTimer) { - mUpdateImminentTimer.reset(); + if (mUseScreenUpdateTimer) { + mScreenUpdateTimer.reset(); } } diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h index 95eb0e2bb7..f2d076691a 100644 --- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h +++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h @@ -25,14 +25,20 @@ #include "DisplayIdentification.h" namespace android { + +class SurfaceFlinger; + namespace Hwc2 { class PowerAdvisor { public: virtual ~PowerAdvisor(); + // Initializes resources that cannot be initialized on construction + virtual void init() = 0; virtual void onBootFinished() = 0; virtual void setExpensiveRenderingExpected(DisplayId displayId, bool expected) = 0; + virtual bool isUsingExpensiveRendering() = 0; virtual void notifyDisplayUpdateImminent() = 0; }; @@ -50,11 +56,13 @@ public: virtual bool notifyDisplayUpdateImminent() = 0; }; - PowerAdvisor(); + PowerAdvisor(SurfaceFlinger& flinger); ~PowerAdvisor() override; + void init() override; void onBootFinished() override; void setExpensiveRenderingExpected(DisplayId displayId, bool expected) override; + bool isUsingExpensiveRendering() override { return mNotifiedExpensiveRendering; } void notifyDisplayUpdateImminent() override; private: @@ -67,9 +75,10 @@ private: std::unordered_set<DisplayId> mExpensiveDisplays; bool mNotifiedExpensiveRendering = false; - const bool mUseUpdateImminentTimer; + SurfaceFlinger& mFlinger; + const bool mUseScreenUpdateTimer; std::atomic_bool mSendUpdateImminent = true; - scheduler::OneShotTimer mUpdateImminentTimer; + scheduler::OneShotTimer mScreenUpdateTimer; }; } // namespace impl diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e2f3ebb5a5..9c04fbf804 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -310,6 +310,7 @@ Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRG ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888; bool SurfaceFlinger::useFrameRateApi; bool SurfaceFlinger::enableSdrDimming; +bool SurfaceFlinger::enableLatchUnsignaled; std::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) { switch(displayColorSetting) { @@ -344,7 +345,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)), mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), - mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) { + mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), + mPowerAdvisor(*this) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); }); @@ -479,6 +481,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI // Debug property overrides ro. property enableSdrDimming = property_get_bool("debug.sf.enable_sdr_dimming", enable_sdr_dimming(false)); + + enableLatchUnsignaled = base::GetBoolProperty("debug.sf.latch_unsignaled"s, false); } SurfaceFlinger::~SurfaceFlinger() = default; @@ -816,6 +820,8 @@ void SurfaceFlinger::init() { // set initial conditions (e.g. unblank default device) initializeDisplays(); + mPowerAdvisor.init(); + char primeShaderCache[PROPERTY_VALUE_MAX]; property_get("service.sf.prime_shader_cache", primeShaderCache, "1"); if (atoi(primeShaderCache)) { @@ -1273,6 +1279,19 @@ void SurfaceFlinger::performSetActiveMode() { mSetActiveModePending = true; } +void SurfaceFlinger::disableExpensiveRendering() { + schedule([=]() MAIN_THREAD { + ATRACE_CALL(); + if (mPowerAdvisor.isUsingExpensiveRendering()) { + const auto& displays = ON_MAIN_THREAD(mDisplays); + for (const auto& [_, display] : displays) { + const static constexpr auto kDisable = false; + mPowerAdvisor.setExpensiveRenderingExpected(display->getId(), kDisable); + } + } + }).wait(); +} + std::vector<ColorMode> SurfaceFlinger::getDisplayColorModes(PhysicalDisplayId displayId) { auto modes = getHwComposer().getColorModes(displayId); bool isInternalDisplay = displayId == getInternalDisplayIdLocked(); @@ -2070,6 +2089,7 @@ void SurfaceFlinger::onMessageRefresh() { const auto prevVsyncTime = mScheduler->getPreviousVsyncFrom(mExpectedPresentTime); const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration; refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration; + refreshArgs.previousPresentFence = mPreviousPresentFences[0].fenceTime; refreshArgs.nextInvalidateTime = mEventQueue->nextExpectedInvalidate(); mGeometryInvalid = false; @@ -3571,7 +3591,7 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied( for (const ComposerState& state : states) { const layer_state_t& s = state.state; const bool acquireFenceChanged = (s.what & layer_state_t::eAcquireFenceChanged); - if (acquireFenceChanged && s.acquireFence && + if (acquireFenceChanged && s.acquireFence && !enableLatchUnsignaled && s.acquireFence->getStatus() == Fence::Status::Unsignaled) { ATRACE_NAME("fence unsignaled"); return false; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index f33df86494..644f76f65a 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -270,6 +270,8 @@ public: // being treated as native display brightness static bool enableSdrDimming; + static bool enableLatchUnsignaled; + // must be called before clients can connect void init() ANDROID_API; @@ -329,6 +331,10 @@ public: bool mDisableClientCompositionCache = false; void setInputWindowsFinished(); + // Disables expensive rendering for all displays + // This is scheduled on the main thread + void disableExpensiveRendering(); + protected: // We're reference counted, never destroy SurfaceFlinger directly virtual ~SurfaceFlinger(); diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h index 7450b5dfa4..159bdf1c01 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h @@ -27,8 +27,10 @@ public: PowerAdvisor(); ~PowerAdvisor() override; + MOCK_METHOD0(init, void()); MOCK_METHOD0(onBootFinished, void()); MOCK_METHOD2(setExpensiveRenderingExpected, void(DisplayId displayId, bool expected)); + MOCK_METHOD0(isUsingExpensiveRendering, bool()); MOCK_METHOD0(notifyDisplayUpdateImminent, void()); }; |