Loading services/surfaceflinger/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ cc_defaults { "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", "android.hardware.power@1.0", "android.hardware.power@1.3", "libbase", "libbinder", "libbufferhubqueue", Loading Loading @@ -71,6 +72,7 @@ cc_defaults { "android.hardware.graphics.composer@2.1", "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", "android.hardware.power@1.3", "libhidlbase", "libhidltransport", "libhwbinder", Loading Loading @@ -99,6 +101,7 @@ filegroup { "DisplayHardware/HWC2.cpp", "DisplayHardware/HWComposer.cpp", "DisplayHardware/HWComposerBufferCache.cpp", "DisplayHardware/PowerAdvisor.cpp", "DisplayHardware/VirtualDisplaySurface.cpp", "DispSync.cpp", "Effects/Daltonizer.cpp", Loading services/surfaceflinger/DisplayHardware/HWC2.cpp +10 −3 Original line number Diff line number Diff line Loading @@ -144,7 +144,7 @@ Error Device::createVirtualDisplay(uint32_t width, uint32_t height, } auto display = std::make_unique<Display>( *mComposer.get(), mCapabilities, displayId, DisplayType::Virtual); *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, DisplayType::Virtual); display->setConnected(true); *outDisplay = display.get(); mDisplays.emplace(displayId, std::move(display)); Loading Loading @@ -183,7 +183,7 @@ void Device::onHotplug(hwc2_display_t displayId, Connection connection) { } auto newDisplay = std::make_unique<Display>( *mComposer.get(), mCapabilities, displayId, displayType); *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType); newDisplay->setConnected(true); mDisplays.emplace(displayId, std::move(newDisplay)); } else if (connection == Connection::Disconnected) { Loading Loading @@ -225,10 +225,11 @@ Error Device::flushCommands() // Display methods Display::Display(android::Hwc2::Composer& composer, Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type) : mComposer(composer), mPowerAdvisor(advisor), mCapabilities(capabilities), mId(id), mIsConnected(false), Loading Loading @@ -611,6 +612,12 @@ 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); } Loading services/surfaceflinger/DisplayHardware/HWC2.h +6 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ #include <unordered_set> #include <vector> #include "PowerAdvisor.h" namespace android { class Fence; class FloatRect; Loading Loading @@ -122,6 +124,7 @@ 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; }; Loading @@ -129,7 +132,8 @@ private: class Display { public: Display(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities, Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type); ~Display(); Loading Loading @@ -285,6 +289,7 @@ 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; Loading services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 "PowerAdvisor" #include <cinttypes> #include <utils/Log.h> #include <utils/Mutex.h> #include "PowerAdvisor.h" namespace android { namespace Hwc2 { PowerAdvisor::~PowerAdvisor() = default; namespace impl { namespace V1_0 = android::hardware::power::V1_0; using V1_3::PowerHint; PowerAdvisor::~PowerAdvisor() = default; PowerAdvisor::PowerAdvisor() = default; void PowerAdvisor::setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) { if (expected) { mExpensiveDisplays.insert(displayId); } else { mExpensiveDisplays.erase(displayId); } const sp<V1_3::IPower> powerHal = getPowerHal(); if (powerHal == nullptr) { return; } const bool expectsExpensiveRendering = !mExpensiveDisplays.empty(); if (mNotifiedExpensiveRendering != expectsExpensiveRendering) { auto ret = powerHal->powerHintAsync_1_3(PowerHint::EXPENSIVE_RENDERING, expectsExpensiveRendering); // If Power HAL 1.3 was available previously but now fails, // it may restart, so attempt to reconnect next time if (!ret.isOk()) { mReconnectPowerHal = true; return; } mNotifiedExpensiveRendering = expectsExpensiveRendering; } } sp<V1_3::IPower> PowerAdvisor::getPowerHal() { static sp<V1_3::IPower> sPowerHal_1_3 = nullptr; static bool sHasPowerHal_1_3 = true; if (mReconnectPowerHal) { sPowerHal_1_3 = nullptr; mReconnectPowerHal = false; } // Power HAL 1.3 is not guaranteed to be available, thus we need to query // Power HAL 1.0 first and try to cast it to Power HAL 1.3. // Power HAL 1.0 is always available, thus if we fail to query it, it means // Power HAL is not available temporarily and we should retry later. However, // if Power HAL 1.0 is available and we can't cast it to Power HAL 1.3, // it means Power HAL 1.3 is not available at all, so we should stop trying. if (sHasPowerHal_1_3 && sPowerHal_1_3 == nullptr) { sp<V1_0::IPower> powerHal_1_0 = V1_0::IPower::getService(); if (powerHal_1_0 != nullptr) { // Try to cast to Power HAL 1.3 sPowerHal_1_3 = V1_3::IPower::castFrom(powerHal_1_0); if (sPowerHal_1_3 == nullptr) { ALOGW("No Power HAL 1.3 service in system"); sHasPowerHal_1_3 = false; } else { ALOGI("Loaded Power HAL 1.3 service"); } } } return sPowerHal_1_3; } } // namespace impl } // namespace Hwc2 } // namespace android services/surfaceflinger/DisplayHardware/PowerAdvisor.h 0 → 100644 +63 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 #define HWC2_INCLUDE_STRINGIFICATION #define HWC2_USE_CPP11 #include <hardware/hwcomposer2.h> #undef HWC2_INCLUDE_STRINGIFICATION #undef HWC2_USE_CPP11 #include <android/hardware/power/1.3/IPower.h> #include <utils/StrongPointer.h> #include <unordered_set> namespace android { namespace Hwc2 { class PowerAdvisor { public: virtual ~PowerAdvisor(); virtual void setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) = 0; }; namespace impl { namespace V1_3 = android::hardware::power::V1_3; // PowerAdvisor is a wrapper around IPower HAL which takes into account the // full state of the system when sending out power hints to things like the GPU. class PowerAdvisor final : public Hwc2::PowerAdvisor { public: PowerAdvisor(); ~PowerAdvisor() override; void setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) override; private: sp<V1_3::IPower> getPowerHal(); std::unordered_set<hwc2_display_t> mExpensiveDisplays; bool mNotifiedExpensiveRendering = false; bool mReconnectPowerHal = false; }; } // namespace impl } // namespace Hwc2 } // namespace android Loading
services/surfaceflinger/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ cc_defaults { "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", "android.hardware.power@1.0", "android.hardware.power@1.3", "libbase", "libbinder", "libbufferhubqueue", Loading Loading @@ -71,6 +72,7 @@ cc_defaults { "android.hardware.graphics.composer@2.1", "android.hardware.graphics.composer@2.2", "android.hardware.graphics.composer@2.3", "android.hardware.power@1.3", "libhidlbase", "libhidltransport", "libhwbinder", Loading Loading @@ -99,6 +101,7 @@ filegroup { "DisplayHardware/HWC2.cpp", "DisplayHardware/HWComposer.cpp", "DisplayHardware/HWComposerBufferCache.cpp", "DisplayHardware/PowerAdvisor.cpp", "DisplayHardware/VirtualDisplaySurface.cpp", "DispSync.cpp", "Effects/Daltonizer.cpp", Loading
services/surfaceflinger/DisplayHardware/HWC2.cpp +10 −3 Original line number Diff line number Diff line Loading @@ -144,7 +144,7 @@ Error Device::createVirtualDisplay(uint32_t width, uint32_t height, } auto display = std::make_unique<Display>( *mComposer.get(), mCapabilities, displayId, DisplayType::Virtual); *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, DisplayType::Virtual); display->setConnected(true); *outDisplay = display.get(); mDisplays.emplace(displayId, std::move(display)); Loading Loading @@ -183,7 +183,7 @@ void Device::onHotplug(hwc2_display_t displayId, Connection connection) { } auto newDisplay = std::make_unique<Display>( *mComposer.get(), mCapabilities, displayId, displayType); *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType); newDisplay->setConnected(true); mDisplays.emplace(displayId, std::move(newDisplay)); } else if (connection == Connection::Disconnected) { Loading Loading @@ -225,10 +225,11 @@ Error Device::flushCommands() // Display methods Display::Display(android::Hwc2::Composer& composer, Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type) : mComposer(composer), mPowerAdvisor(advisor), mCapabilities(capabilities), mId(id), mIsConnected(false), Loading Loading @@ -611,6 +612,12 @@ 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); } Loading
services/surfaceflinger/DisplayHardware/HWC2.h +6 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ #include <unordered_set> #include <vector> #include "PowerAdvisor.h" namespace android { class Fence; class FloatRect; Loading Loading @@ -122,6 +124,7 @@ 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; }; Loading @@ -129,7 +132,8 @@ private: class Display { public: Display(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities, Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, const std::unordered_set<Capability>& capabilities, hwc2_display_t id, DisplayType type); ~Display(); Loading Loading @@ -285,6 +289,7 @@ 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; Loading
services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 "PowerAdvisor" #include <cinttypes> #include <utils/Log.h> #include <utils/Mutex.h> #include "PowerAdvisor.h" namespace android { namespace Hwc2 { PowerAdvisor::~PowerAdvisor() = default; namespace impl { namespace V1_0 = android::hardware::power::V1_0; using V1_3::PowerHint; PowerAdvisor::~PowerAdvisor() = default; PowerAdvisor::PowerAdvisor() = default; void PowerAdvisor::setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) { if (expected) { mExpensiveDisplays.insert(displayId); } else { mExpensiveDisplays.erase(displayId); } const sp<V1_3::IPower> powerHal = getPowerHal(); if (powerHal == nullptr) { return; } const bool expectsExpensiveRendering = !mExpensiveDisplays.empty(); if (mNotifiedExpensiveRendering != expectsExpensiveRendering) { auto ret = powerHal->powerHintAsync_1_3(PowerHint::EXPENSIVE_RENDERING, expectsExpensiveRendering); // If Power HAL 1.3 was available previously but now fails, // it may restart, so attempt to reconnect next time if (!ret.isOk()) { mReconnectPowerHal = true; return; } mNotifiedExpensiveRendering = expectsExpensiveRendering; } } sp<V1_3::IPower> PowerAdvisor::getPowerHal() { static sp<V1_3::IPower> sPowerHal_1_3 = nullptr; static bool sHasPowerHal_1_3 = true; if (mReconnectPowerHal) { sPowerHal_1_3 = nullptr; mReconnectPowerHal = false; } // Power HAL 1.3 is not guaranteed to be available, thus we need to query // Power HAL 1.0 first and try to cast it to Power HAL 1.3. // Power HAL 1.0 is always available, thus if we fail to query it, it means // Power HAL is not available temporarily and we should retry later. However, // if Power HAL 1.0 is available and we can't cast it to Power HAL 1.3, // it means Power HAL 1.3 is not available at all, so we should stop trying. if (sHasPowerHal_1_3 && sPowerHal_1_3 == nullptr) { sp<V1_0::IPower> powerHal_1_0 = V1_0::IPower::getService(); if (powerHal_1_0 != nullptr) { // Try to cast to Power HAL 1.3 sPowerHal_1_3 = V1_3::IPower::castFrom(powerHal_1_0); if (sPowerHal_1_3 == nullptr) { ALOGW("No Power HAL 1.3 service in system"); sHasPowerHal_1_3 = false; } else { ALOGI("Loaded Power HAL 1.3 service"); } } } return sPowerHal_1_3; } } // namespace impl } // namespace Hwc2 } // namespace android
services/surfaceflinger/DisplayHardware/PowerAdvisor.h 0 → 100644 +63 −0 Original line number Diff line number Diff line /* * Copyright 2018 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 #define HWC2_INCLUDE_STRINGIFICATION #define HWC2_USE_CPP11 #include <hardware/hwcomposer2.h> #undef HWC2_INCLUDE_STRINGIFICATION #undef HWC2_USE_CPP11 #include <android/hardware/power/1.3/IPower.h> #include <utils/StrongPointer.h> #include <unordered_set> namespace android { namespace Hwc2 { class PowerAdvisor { public: virtual ~PowerAdvisor(); virtual void setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) = 0; }; namespace impl { namespace V1_3 = android::hardware::power::V1_3; // PowerAdvisor is a wrapper around IPower HAL which takes into account the // full state of the system when sending out power hints to things like the GPU. class PowerAdvisor final : public Hwc2::PowerAdvisor { public: PowerAdvisor(); ~PowerAdvisor() override; void setExpensiveRenderingExpected(hwc2_display_t displayId, bool expected) override; private: sp<V1_3::IPower> getPowerHal(); std::unordered_set<hwc2_display_t> mExpensiveDisplays; bool mNotifiedExpensiveRendering = false; bool mReconnectPowerHal = false; }; } // namespace impl } // namespace Hwc2 } // namespace android