diff options
8 files changed, 35 insertions, 45 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index bca0abc44f..910a5275e9 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -143,8 +143,8 @@ Error Device::createVirtualDisplay(uint32_t width, uint32_t height, return error; } - auto display = std::make_unique<impl::Display>(*mComposer.get(), mPowerAdvisor, mCapabilities, - displayId, DisplayType::Virtual); + auto display = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId, + DisplayType::Virtual); display->setConnected(true); *outDisplay = display.get(); mDisplays.emplace(displayId, std::move(display)); @@ -182,8 +182,8 @@ void Device::onHotplug(hwc2_display_t displayId, Connection connection) { return; } - auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mPowerAdvisor, - mCapabilities, displayId, displayType); + auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, + displayId, displayType); newDisplay->setConnected(true); mDisplays.emplace(displayId, std::move(newDisplay)); } else if (connection == Connection::Disconnected) { @@ -254,11 +254,10 @@ float Display::Config::Builder::getDefaultDensity() { } namespace impl { -Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, +Display::Display(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type) : mComposer(composer), - mPowerAdvisor(advisor), mCapabilities(capabilities), mId(id), mIsConnected(false), @@ -636,12 +635,6 @@ Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, Error Display::setColorMode(ColorMode mode, RenderIntent renderIntent) { - // When the color mode is switched to DISPLAY_P3, we want to boost the GPU frequency - // so that GPU composition can finish in time. When color mode is switched from - // DISPLAY_P3, we want to reset GPU frequency. - const bool expensiveRenderingExpected = (mode == ColorMode::DISPLAY_P3); - mPowerAdvisor.setExpensiveRenderingExpected(mId, expensiveRenderingExpected); - auto intError = mComposer.setColorMode(mId, mode, renderIntent); return static_cast<Error>(intError); } diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 70358a0e0f..f96614fc96 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -37,8 +37,6 @@ #include <unordered_set> #include <vector> -#include "PowerAdvisor.h" - namespace android { struct DisplayedFrameStats; class Fence; @@ -125,7 +123,6 @@ private: std::unique_ptr<android::Hwc2::Composer> mComposer; std::unordered_set<Capability> mCapabilities; std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays; - android::Hwc2::impl::PowerAdvisor mPowerAdvisor; bool mRegisteredCallback = false; }; @@ -273,9 +270,8 @@ namespace impl { class Display : public HWC2::Display { public: - Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, - const std::unordered_set<Capability>& capabilities, hwc2_display_t id, - DisplayType type); + Display(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities, + hwc2_display_t id, DisplayType type); ~Display() override; // Required by HWC2 @@ -352,7 +348,6 @@ private: // this HWC2::Display, so these references are guaranteed to be valid for // the lifetime of this object. android::Hwc2::Composer& mComposer; - android::Hwc2::PowerAdvisor& mPowerAdvisor; const std::unordered_set<Capability>& mCapabilities; hwc2_display_t mId; diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp index 12bbae207b..039db73928 100644 --- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp +++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp @@ -38,7 +38,7 @@ PowerAdvisor::~PowerAdvisor() = default; PowerAdvisor::PowerAdvisor() = default; -void PowerAdvisor::setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) { +void PowerAdvisor::setExpensiveRenderingExpected(DisplayId displayId, bool expected) { if (expected) { mExpensiveDisplays.insert(displayId); } else { diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h index 573a1a9ad3..5aa1f22b9e 100644 --- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h +++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h @@ -22,10 +22,12 @@ #undef HWC2_INCLUDE_STRINGIFICATION #undef HWC2_USE_CPP11 +#include <unordered_set> + #include <android/hardware/power/1.3/IPower.h> #include <utils/StrongPointer.h> -#include <unordered_set> +#include "DisplayIdentification.h" namespace android { namespace Hwc2 { @@ -34,7 +36,7 @@ class PowerAdvisor { public: virtual ~PowerAdvisor(); - virtual void setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) = 0; + virtual void setExpensiveRenderingExpected(DisplayId displayId, bool expected) = 0; }; namespace impl { @@ -48,12 +50,12 @@ public: PowerAdvisor(); ~PowerAdvisor() override; - void setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) override; + void setExpensiveRenderingExpected(DisplayId displayId, bool expected) override; private: sp<V1_3::IPower> getPowerHal(); - std::unordered_set<hwc2_display_t> mExpensiveDisplays; + std::unordered_set<DisplayId> mExpensiveDisplays; bool mNotifiedExpensiveRendering = false; bool mReconnectPowerHal = false; }; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e50dd08738..128ebf92ef 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3364,6 +3364,16 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice, // Perform some cleanup steps if we used client composition. if (hasClientComposition) { clientCompositionDisplay.clearRegion = clearRegion; + + // We boost GPU frequency here because there will be color spaces conversion + // and it's expensive. We boost the GPU frequency so that GPU composition can + // finish in time. We must reset GPU frequency afterwards, because high frequency + // consumes extra battery. + const bool expensiveRenderingExpected = + clientCompositionDisplay.outputDataspace == Dataspace::DISPLAY_P3; + if (expensiveRenderingExpected && displayId) { + mPowerAdvisor.setExpensiveRenderingExpected(*displayId, true); + } if (!debugRegion.isEmpty()) { Region::const_iterator it = debugRegion.begin(); Region::const_iterator end = debugRegion.end(); @@ -3379,6 +3389,9 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice, } renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayers, buf->getNativeBuffer(), std::move(fd), readyFence); + if (expensiveRenderingExpected && displayId) { + mPowerAdvisor.setExpensiveRenderingExpected(*displayId, false); + } } return true; } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 3eaaaea54d..57dab7fbbb 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -53,6 +53,7 @@ #include "DisplayDevice.h" #include "DisplayHardware/HWC2.h" #include "DisplayHardware/HWComposer.h" +#include "DisplayHardware/PowerAdvisor.h" #include "Effects/Daltonizer.h" #include "FrameTracker.h" #include "LayerStats.h" @@ -1150,11 +1151,11 @@ private: InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock); // Should only be accessed by the main thread. InputWindowCommands mInputWindowCommands; - ui::DisplayPrimaries mInternalDisplayPrimaries; sp<SetInputWindowsListener> mSetInputWindowsListener; bool mPendingSyncInputWindows GUARDED_BY(mStateLock); + Hwc2::impl::PowerAdvisor mPowerAdvisor; }; }; // namespace android diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index d61973e897..79b5ca0025 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -324,6 +324,7 @@ public: auto& mutableTexturePool() { return mFlinger->mTexturePool; } auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; } auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; } + auto& mutablePowerAdvisor() { return mFlinger->mPowerAdvisor; } auto& mutableComposerSequenceId() { return mFlinger->getBE().mComposerSequenceId; } auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; } @@ -352,18 +353,11 @@ public: * Wrapper classes for Read-write access to private data to set up * preconditions and assert post-conditions. */ - class FakePowerAdvisor : public Hwc2::PowerAdvisor { - public: - FakePowerAdvisor() = default; - ~FakePowerAdvisor() override = default; - void setExpensiveRenderingExpected(hwc2_display_t, bool) override {} - }; - struct HWC2Display : public HWC2::impl::Display { - HWC2Display(Hwc2::Composer& composer, Hwc2::PowerAdvisor& advisor, + HWC2Display(Hwc2::Composer& composer, const std::unordered_set<HWC2::Capability>& capabilities, hwc2_display_t id, HWC2::DisplayType type) - : HWC2::impl::Display(composer, advisor, capabilities, id, type) {} + : HWC2::impl::Display(composer, capabilities, id, type) {} ~HWC2Display() { // Prevents a call to disable vsyncs. mType = HWC2::DisplayType::Invalid; @@ -427,14 +421,7 @@ public: return *this; } - auto& setPowerAdvisor(Hwc2::PowerAdvisor* powerAdvisor) { - mPowerAdvisor = powerAdvisor; - return *this; - } - void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) { - static FakePowerAdvisor defaultPowerAdvisor; - if (mPowerAdvisor == nullptr) mPowerAdvisor = &defaultPowerAdvisor; static const std::unordered_set<HWC2::Capability> defaultCapabilities; if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities; @@ -442,8 +429,8 @@ public: // not refer to an instance owned by FakeHwcDisplayInjector. This // class has temporary lifetime, while the constructed HWC2::Display // is much longer lived. - auto display = std::make_unique<HWC2Display>(*composer, *mPowerAdvisor, *mCapabilities, - mHwcDisplayId, mHwcDisplayType); + auto display = std::make_unique<HWC2Display>(*composer, *mCapabilities, mHwcDisplayId, + mHwcDisplayType); auto config = HWC2::Display::Config::Builder(*display, mActiveConfig); config.setWidth(mWidth); @@ -478,7 +465,6 @@ public: int32_t mDpiY = DEFAULT_DPI; int32_t mActiveConfig = DEFAULT_ACTIVE_CONFIG; const std::unordered_set<HWC2::Capability>* mCapabilities = nullptr; - Hwc2::PowerAdvisor* mPowerAdvisor = nullptr; }; class FakeDisplayDeviceInjector { diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h index dc6d83b0fd..7c65f95cb7 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h @@ -29,7 +29,7 @@ public: PowerAdvisor(); ~PowerAdvisor() override; - MOCK_METHOD2(setExpensiveRenderingExpected, void(hwc2_display_t displayId, bool expected)); + MOCK_METHOD2(setExpensiveRenderingExpected, void(DisplayId displayId, bool expected)); }; } // namespace mock |