1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #undef LOG_TAG 18 #define LOG_TAG "PowerAdvisor" 19 20 #include <cinttypes> 21 22 #include <utils/Log.h> 23 #include <utils/Mutex.h> 24 25 #include "PowerAdvisor.h" 26 27 namespace android { 28 namespace Hwc2 { 29 30 PowerAdvisor::~PowerAdvisor() = default; 31 32 namespace impl { 33 34 namespace V1_0 = android::hardware::power::V1_0; 35 using V1_3::PowerHint; 36 37 PowerAdvisor::~PowerAdvisor() = default; 38 39 PowerAdvisor::PowerAdvisor() = default; 40 41 void PowerAdvisor::setExpensiveRenderingExpected(DisplayId displayId, bool expected) { 42 if (expected) { 43 mExpensiveDisplays.insert(displayId); 44 } else { 45 mExpensiveDisplays.erase(displayId); 46 } 47 48 const bool expectsExpensiveRendering = !mExpensiveDisplays.empty(); 49 if (mNotifiedExpensiveRendering != expectsExpensiveRendering) { 50 const sp<V1_3::IPower> powerHal = getPowerHal(); 51 if (powerHal == nullptr) { 52 return; 53 } 54 auto ret = powerHal->powerHintAsync_1_3(PowerHint::EXPENSIVE_RENDERING, 55 expectsExpensiveRendering); 56 // If Power HAL 1.3 was available previously but now fails, 57 // it may restart, so attempt to reconnect next time 58 if (!ret.isOk()) { 59 mReconnectPowerHal = true; 60 return; 61 } 62 mNotifiedExpensiveRendering = expectsExpensiveRendering; 63 } 64 } 65 66 sp<V1_3::IPower> PowerAdvisor::getPowerHal() { 67 static sp<V1_3::IPower> sPowerHal_1_3 = nullptr; 68 static bool sHasPowerHal_1_3 = true; 69 70 if (mReconnectPowerHal) { 71 sPowerHal_1_3 = nullptr; 72 mReconnectPowerHal = false; 73 } 74 75 // Power HAL 1.3 is not guaranteed to be available, thus we need to query 76 // Power HAL 1.0 first and try to cast it to Power HAL 1.3. 77 // Power HAL 1.0 is always available, thus if we fail to query it, it means 78 // Power HAL is not available temporarily and we should retry later. However, 79 // if Power HAL 1.0 is available and we can't cast it to Power HAL 1.3, 80 // it means Power HAL 1.3 is not available at all, so we should stop trying. 81 if (sHasPowerHal_1_3 && sPowerHal_1_3 == nullptr) { 82 sp<V1_0::IPower> powerHal_1_0 = V1_0::IPower::getService(); 83 if (powerHal_1_0 != nullptr) { 84 // Try to cast to Power HAL 1.3 85 sPowerHal_1_3 = V1_3::IPower::castFrom(powerHal_1_0); 86 if (sPowerHal_1_3 == nullptr) { 87 ALOGW("No Power HAL 1.3 service in system"); 88 sHasPowerHal_1_3 = false; 89 } else { 90 ALOGI("Loaded Power HAL 1.3 service"); 91 } 92 } 93 } 94 return sPowerHal_1_3; 95 } 96 97 } // namespace impl 98 } // namespace Hwc2 99 } // namespace android 100