/* * 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(DisplayId displayId, bool expected) { if (expected) { mExpensiveDisplays.insert(displayId); } else { mExpensiveDisplays.erase(displayId); } const bool expectsExpensiveRendering = !mExpensiveDisplays.empty(); if (mNotifiedExpensiveRendering != expectsExpensiveRendering) { const sp<V1_3::IPower> powerHal = getPowerHal(); if (powerHal == nullptr) { return; } 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