unplugged-system/frameworks/native/services/surfaceflinger/mediatek/SfCpuPolicyAdapter/SfLegacyCpuPolicyAdapter.cpp

753 lines
26 KiB
C++
Raw Normal View History

/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein is
* confidential and proprietary to MediaTek Inc. and/or its licensors. Without
* the prior written permission of MediaTek inc. and/or its licensors, any
* reproduction, modification, use or disclosure of MediaTek Software, and
* information contained herein, in whole or in part, shall be strictly
* prohibited.
*
* MediaTek Inc. (C) 2022. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
* ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
* INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
* TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
* RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
* OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
* SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
* RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
* MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
* CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek
* Software") have been modified by MediaTek Inc. All revisions are subject to
* any receiver's applicable license agreements with MediaTek Inc.
*/
#ifdef MTK_SF_CPU_POLICY_FOR_LEGACY
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include "SfCpuPolicyAdapter.h"
#include <android-base/properties.h>
#include <cutils/properties.h>
#include <processgroup/sched_policy.h>
#include <processgroup/processgroup.h>
#include <sched.h>
#include <sys/utsname.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#ifdef MTK_COMPOSER_EXT
#include <composer_ext_intf/client_interface.h>
#endif
#ifdef MTK_SF_PERF_API
#include "SFPerfAPILoader.h"
#endif
namespace android {
const SfCpuPolicy::Config SfLegacyCpuPolicyAdapter::AnimationCong = {8000000, 200, 8000000, 100};
static int CONFIG_BL_CPU_MASK = 0xc0; // CPU mask for BL
static int CONFIG_FORCE_SUSPEND_CPU_POLICY = 0; // suspend CPU policy
static int CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT = 0; // default low bound uclamp min, 0 ~ 1024
static int CONFIG_LOWBOUND_UCLAMP_MIN_BL = 300; // default low bound uclamp min for BL, 0 ~ 1024
static int CONFIG_UPBOUND_UCLAMP_MIN_LL = 800; // default up bound uclamp min for LL, 0 ~ 1024
static int CONFIG_UPBOUND_UCLAMP_MIN_BL = 1000; // default up bound uclamp min for BL, 0 ~ 1024
static int CONFIG_MAX_UCLAMP_CORRECTION_OFFSET = 800; // max uclamp correction offset, 0 ~ 1024
static int CONFIG_MIN_UCLAMP_CORRECTION_OFFSET = 0; // min uclamp correction offset, 0 ~ 1024
static int CONFIG_POWER_DOWN_TARGET_TIME_FACTOR = (-3); //range -9 ~10, more large more easily power down
static int CONFIG_POWER_UP_TARGET_TIME_FACTOR = (-1); //range -9 ~ 10, more large more easily power up
static int CONFIG_POWER_UP_THRESHOLD = 3; // start to power up after up cnt threshold
static int CONFIG_POWER_DOWN_THRESHOLD = 3; // start to power down after down cnt threshold
static int CONFIG_EARLY_SCHEDULE_HEAVY = 1; // take early schedule as heavy load, for animation
static int CONFIG_FOREGROUND_LONG_FRAME_THRESHOLD = 3; // change to foreground after long frames cnt threshold
static int CONFIG_BACKGROUND_LONG_FRAME_THRESHOLD = 3; // change to background after long frames cnt threshold
#ifndef SFLOG
static int mEnableLog = 0;
#define SFLOG(...) \
{ \
if (mEnableLog>=2) { \
__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__); \
} \
}
#endif
#ifndef SF_ATRACE_BUFFER
#define SF_ATRACE_BUFFER(x, ...) \
if (ATRACE_ENABLED() && mEnableLog) { \
char ___traceBuf[256]; \
if (snprintf(___traceBuf, sizeof(___traceBuf), x, ##__VA_ARGS__) > 0) { \
android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); } \
}
#endif
#ifndef SF_ATRACE_INT
#define SF_ATRACE_INT(x,y) \
if(ATRACE_ENABLED() && mEnableLog) { \
ATRACE_INT(x,y); \
}
#endif
#ifndef SF_ATRACE_NAME
#define SF_ATRACE_NAME(x) \
if(ATRACE_ENABLED() && mEnableLog) { \
ATRACE_NAME(x); \
}
#endif
static int sched_setaffinity_task(int32_t pid, int cpuMask) {
cpu_set_t mask;
CPU_ZERO(&mask);
for (int i=0; i<8; i++) {
if (cpuMask & (1<<i)) {
CPU_SET(i, &mask);
}
}
int ret = sched_setaffinity(pid, sizeof(mask), &mask);
if(ret < 0){
ALOGE(" sched_setaffinity return fail %d", pid);
}
return ret;
}
SfLegacyCpuPolicyAdapter& SfLegacyCpuPolicyAdapter::getInstance(frametimeline::FrameTimeline & frameTimeline) {
static SfLegacyCpuPolicyAdapter gInstance(frameTimeline);
return gInstance;
}
bool SfLegacyCpuPolicyAdapter::isEnabled() {
static bool checked = false;
static bool enabled = false;
if (!checked){
char value[PROPERTY_VALUE_MAX] = {};
struct utsname u;
property_get("debug.sf.cpupolicy.legacy", value, "0");
enabled = (atoi(value) != 0);
if (uname (&u) < 0){
checked = true;
return enabled;
}
if (enabled) {
std::string const delims{ ".-"};
std::string str_big_version;
std::string str_middle_version;
std::string str = u.release;
int big_version;
int middle_version;
size_t beg = 0;
size_t pos = 0;
beg = str.find_first_not_of(delims, pos);
if ( beg != std::string::npos) {
pos = str.find_first_of(delims, beg + 1);
str_big_version = str.substr(beg, pos - beg);
}
beg = str.find_first_not_of(delims, pos);
if ( beg != std::string::npos) {
pos = str.find_first_of(delims, beg + 1);
str_middle_version = str.substr(beg, pos - beg);
}
big_version = std::stoi(str_big_version);
middle_version = std::stoi(str_middle_version);
if ((big_version != 4) || (big_version == 4 && middle_version != 19)) {
enabled = false;
}
}
ALOGI("legacy cpu policy enabled %d", enabled);
checked = true;
}
return enabled;
}
SfLegacyCpuPolicyAdapter::SfLegacyCpuPolicyAdapter(frametimeline::FrameTimeline & frameTimeline)
: mFrameTimeline(frameTimeline) {
mReadyTid.push_back((int)getpid());
memset(frameList, 0, sizeof(frameList));
mThreadStarted = true;
mCpuPolicyThread = std::thread(&SfLegacyCpuPolicyAdapter::cpuPolicyThread, this);
int value = base::GetIntProperty<int>("ro.surface_flinger.uclamp.min", 0U);
if (value)
CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT = value;
mBaseUclampMin = CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT;
initProp();
}
SfLegacyCpuPolicyAdapter::~SfLegacyCpuPolicyAdapter() {
{
std::lock_guard lock(mCpuPolicyThreadMutex);
mThreadStarted = false;
mCondition.notify_one();
}
if (mCpuPolicyThread.joinable()) {
mCpuPolicyThread.join();
}
}
void SfLegacyCpuPolicyAdapter::cpuPolicyThread() NO_THREAD_SAFETY_ANALYSIS{
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
ALOGE("Couldn't set SCHED_FIFO");
}
pthread_setname_np(pthread_self(), "SfCpu");
mReadyTid.push_back((int)gettid());
std::unique_lock<std::mutex> lock(mCpuPolicyThreadMutex);
while (mThreadStarted) {
if (!mTasks.empty()) {
auto task = mTasks.front();
mTasks.pop();
task();
}
mCondition.wait(lock, [this]() REQUIRES(mCpuPolicyThreadMutex) {
return !mThreadStarted || !mTasks.empty();
});
}
}
void SfLegacyCpuPolicyAdapter::initProp(){
char value[PROPERTY_VALUE_MAX] = {};
int iValue = 0;
property_get("vendor.debug.sf.cpupolicy.legacy.enable_log", value, "1");
mEnableLog = atoi(value);
property_get("vendor.debug.sf.cpupolicy.legacy.force_suspend", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_FORCE_SUSPEND_CPU_POLICY = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.lowbound_uclamp_min_default", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.lowbound_uclamp_min_bl", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_LOWBOUND_UCLAMP_MIN_BL = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.upbound_uclamp_min_ll", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_UPBOUND_UCLAMP_MIN_LL = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.upbound_uclamp_min_bl", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_UPBOUND_UCLAMP_MIN_BL = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.power_down_time_factor", value, "0");
iValue = (atoi(value));
if (iValue != 0) {
CONFIG_POWER_DOWN_TARGET_TIME_FACTOR = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.power_up_time_factor", value, "0");
iValue = (atoi(value));
if (iValue != 0) {
CONFIG_POWER_UP_TARGET_TIME_FACTOR = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.power_up_threshold", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_POWER_UP_THRESHOLD = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.power_down_threshold", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_POWER_DOWN_THRESHOLD = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.foreground_frame_threshold", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_FOREGROUND_LONG_FRAME_THRESHOLD = iValue;
}
property_get("vendor.debug.sf.cpupolicy.legacy.background_frame_threshold", value, "-1");
iValue = (atoi(value));
if (iValue >= 0) {
CONFIG_BACKGROUND_LONG_FRAME_THRESHOLD = iValue;
}
}
void SfLegacyCpuPolicyAdapter::setupConfig(SfCpuPolicy::Config & conf) {
if (conf.ForceMode) {
if (conf.SystemOrForground) {
mConf.SystemOnly = false;
mConf.ForgroundOnly= true;
} else {
mConf.SystemOnly = true;
mConf.ForgroundOnly= false;
}
} else {
mConf.SystemOnly = false;
mConf.ForgroundOnly= false;
}
if (mIsLastFrameFinished && mPolicySuspend) {
if (conf.targetTime) {
mConf.targetTime = conf.targetTime;
}
mConf.reason = conf.reason;
mConf.suspendMid = conf.suspendMid;
SFLOG("setupConfig powerUpMeasOffset %d powerUpMeasTime %" PRId64 " target %" PRId64
" %d reason %d suspendMid %d", conf.powerUpMeasOffset, conf.powerDownMeasTime,
conf.targetTime, (int)mConf.renderEngingTid, mConf.reason, mConf.suspendMid);
return;
}
{
std::lock_guard lock(mCpuPolicyThreadMutex);
mTasks.push([conf, this]() {
if (conf.powerUpMeasOffset) {
mConf.powerUpMeasTime = conf.powerUpMeasTime;
mConf.powerUpMeasOffset = conf.powerUpMeasOffset;
}
if (conf.powerDownMeasOffset) {
mConf.powerDownMeasTime = conf.powerDownMeasTime;
mConf.powerDownMeasOffset = conf.powerDownMeasOffset;
}
if (conf.targetTime) {
mConf.targetTime = conf.targetTime;
}
if (conf.renderEngingTid) {
std::lock_guard lock(mHwcMutex);
if (std::find(mReadyTid.begin(), mReadyTid.end(),
conf.renderEngingTid) == mReadyTid.end())
mReadyTid.push_back((int)conf.renderEngingTid);
mConf.renderEngingTid = conf.renderEngingTid;
}
mConf.reason = conf.reason;
SFLOG("setupConfig powerUpMeasOffset %d powerUpMeasTime %" PRId64 " target %"
PRId64 " %d reason %d", conf.powerUpMeasOffset, conf.powerDownMeasTime,
conf.targetTime, (int)mConf.renderEngingTid, mConf.reason);
});
}
mCondition.notify_one();
}
SfLegacyCpuPolicyAdapter::FrameInfo * SfLegacyCpuPolicyAdapter::getFrameById(int64_t vsyncId) {
std::scoped_lock lock(mMutex);
int len = sizeof(frameList)/sizeof(FrameInfo);
for (int i = 0 ; i < len; i++) {
if (frameList[i].vsyncId == vsyncId){
return & frameList[i];
}
}
return nullptr;
}
void SfLegacyCpuPolicyAdapter::frameInfoClear(FrameInfo * info) {
std::scoped_lock lock(mMutex);
info->vsyncId = 0;
info->startTime = 0;
info->endTime = 0;
info->clearCorrection = false;
info->heavyLoading = false;
}
void SfLegacyCpuPolicyAdapter::notifyFrameStart(nsecs_t startTime, int64_t vsyncId) {
if (!vsyncId)
return;
if (!mIsLastFrameFinished) {
FrameInfo * info = getFrameById(mLastVsyncId);
if (info != nullptr)
frameInfoClear(info);
mIsLastFrameFinished = true;
}
FrameInfo * info = getFrameById(0);
if (info == nullptr)
return;
info->startTime = startTime;
info->vsyncId = vsyncId;
mLastVsyncId = vsyncId;
mIsLastFrameFinished = false;
}
void SfLegacyCpuPolicyAdapter::notifyFrameEnd(nsecs_t endTime) {
if (!mLastVsyncId)
return;
FrameInfo * info = getFrameById(mLastVsyncId);
if (info == nullptr)
return;
info->endTime = endTime;
mIsLastFrameFinished = true;
{
std::lock_guard lock(mCpuPolicyThreadMutex);
mTasks.push([info,this]() {
if (!info->vsyncId)
return;
if (mPolicySuspend) {
resetUclamp();
frameInfoClear(info);
return;
}
calcCorrection(info);
calcAndUpdateUclamp(info);
frameInfoClear(info);
});
}
mCondition.notify_one();
SF_ATRACE_INT("sf_cpu_LL", mCpuSystemOnly ? 1 : 0);
SF_ATRACE_INT("sf_cpu_uclamp", mTargetUclampMin);
}
void SfLegacyCpuPolicyAdapter::calcCorrection(FrameInfo * info) {
nsecs_t startTime = info->startTime;
nsecs_t endTime = info->endTime;
nsecs_t targetTime = mConf.targetTime;
nsecs_t workTime = endTime - startTime;
bool needCheckPowerUp = false;
bool needCheckPowerDown = false;
if (info->heavyLoading) {
mConf.powerUpMeasTime = AnimationCong.powerUpMeasTime;
mConf.powerUpMeasOffset = AnimationCong.powerUpMeasOffset;
mConf.powerDownMeasTime = AnimationCong.powerDownMeasTime;
mConf.powerDownMeasOffset = AnimationCong.powerDownMeasOffset;
}
if ((endTime - mPowerUpStartTime) > mConf.powerUpMeasTime) {
mPowerUpStartTime = endTime - mConf.powerUpMeasTime;
needCheckPowerUp = true;
}
if ((endTime - mPowerDownStartTime) > mConf.powerDownMeasTime) {
mPowerDownStartTime = endTime - mConf.powerDownMeasTime;
needCheckPowerDown = true;
}
if (!(needCheckPowerUp || needCheckPowerDown))
return;
if (needCheckPowerUp && needIncreasePerf(startTime, endTime,
targetTime + targetTime * CONFIG_POWER_UP_TARGET_TIME_FACTOR / 10)) {
mNeedBoost = true;
mUpCount++;
mDownCount = 0;
if (mUpCount < CONFIG_POWER_UP_THRESHOLD)
return;
mUpCount = CONFIG_POWER_UP_THRESHOLD;
mPowerUpStartTime = endTime;
mCorrectionOffset += mConf.powerUpMeasOffset *
(workTime - (targetTime + targetTime *
CONFIG_POWER_UP_TARGET_TIME_FACTOR / 10)) / 1000000;
if (mCorrectionOffset > CONFIG_MAX_UCLAMP_CORRECTION_OFFSET)
mCorrectionOffset = CONFIG_MAX_UCLAMP_CORRECTION_OFFSET;
SFLOG("calcCorrection up %d endtime %" PRId64 " target %" PRId64 " ",
mCorrectionOffset, endTime, targetTime);
} else if (needCheckPowerDown && needReducePerf(startTime,endTime,
targetTime + targetTime * CONFIG_POWER_DOWN_TARGET_TIME_FACTOR / 10)) {
mNeedBoost = false;
mDownCount++;
mUpCount = 0;
if (mDownCount < CONFIG_POWER_DOWN_THRESHOLD)
return;
mDownCount = CONFIG_POWER_DOWN_THRESHOLD;
mPowerDownStartTime = endTime;
mCorrectionOffset -= mConf.powerDownMeasOffset *
((targetTime + targetTime *
CONFIG_POWER_DOWN_TARGET_TIME_FACTOR / 10) - workTime) / 1000000;
if (mCorrectionOffset < CONFIG_MIN_UCLAMP_CORRECTION_OFFSET)
mCorrectionOffset = CONFIG_MIN_UCLAMP_CORRECTION_OFFSET;
SFLOG("calcCorrection down %d endtime %" PRId64 " target %" PRId64 " ",
mCorrectionOffset, endTime, targetTime);
} else {
mNeedBoost = false;
SFLOG("calcCorrection keep %d endtime %" PRId64 " target %" PRId64 " ",
mCorrectionOffset, endTime, targetTime);
}
}
void SfLegacyCpuPolicyAdapter::calcAndUpdateUclamp(FrameInfo * info) {
bool cpuBackToSystem = false;
static nsecs_t oldConfTargetTime = 0;
static int creditFG = CONFIG_FOREGROUND_LONG_FRAME_THRESHOLD;
static int creditBG = CONFIG_BACKGROUND_LONG_FRAME_THRESHOLD;
if (info->clearCorrection && !info->heavyLoading) {
SFLOG("clear perf correction notified");
mCorrectionOffset = 0;
}
mTargetUclampMin = mBaseUclampMin + mCorrectionOffset;
if (oldConfTargetTime && oldConfTargetTime != mConf.targetTime) {
if (!mCpuSystemOnly && (oldConfTargetTime < mConf.targetTime)) {
cpuBackToSystem = true;
mCorrectionOffset = 0;
}
oldConfTargetTime = mConf.targetTime;
}
if (mCpuSystemOnly) {
if (mTargetUclampMin >= CONFIG_UPBOUND_UCLAMP_MIN_LL) {
mTargetUclampMin = CONFIG_UPBOUND_UCLAMP_MIN_LL;
creditFG --;
if (creditFG < 0)
creditFG = 0;
} else {
creditFG ++;
if (creditFG > CONFIG_FOREGROUND_LONG_FRAME_THRESHOLD)
creditFG = CONFIG_FOREGROUND_LONG_FRAME_THRESHOLD;
}
} else {
if (mTargetUclampMin >= CONFIG_UPBOUND_UCLAMP_MIN_BL)
mTargetUclampMin = CONFIG_UPBOUND_UCLAMP_MIN_BL;
if (mTargetUclampMin <= CONFIG_LOWBOUND_UCLAMP_MIN_BL) {
mTargetUclampMin = CONFIG_LOWBOUND_UCLAMP_MIN_BL;
creditBG --;
if (creditBG < 0)
creditBG = 0;
} else {
creditBG++;
if (creditBG > CONFIG_BACKGROUND_LONG_FRAME_THRESHOLD)
creditBG = CONFIG_BACKGROUND_LONG_FRAME_THRESHOLD;
}
}
if (mConf.ForgroundOnly) {
changeToForeground();
} else if (mConf.SystemOnly) {
changeToSystem();
} else if (!mCpuSystemOnly && (!mNeedBoost) && (cpuBackToSystem || !creditBG)) {
creditFG = CONFIG_FOREGROUND_LONG_FRAME_THRESHOLD;
mCorrectionOffset = CONFIG_UPBOUND_UCLAMP_MIN_LL;
mTargetUclampMin = mBaseUclampMin + mCorrectionOffset;
changeToSystem();
} else if (mCpuSystemOnly && mNeedBoost && (!creditFG)) {
creditBG = CONFIG_BACKGROUND_LONG_FRAME_THRESHOLD;
mCorrectionOffset = CONFIG_LOWBOUND_UCLAMP_MIN_BL;
mTargetUclampMin = mBaseUclampMin + mCorrectionOffset;
changeToForeground();
}
setUclamp();
}
void SfLegacyCpuPolicyAdapter::notifyClearCorrection(bool clear, bool heavyLoading) {
if ((mIsLastFrameFinished && mPolicySuspend) || (!mLastVsyncId))
return;
FrameInfo * info = getFrameById(mLastVsyncId);
if (info == nullptr)
return;
info->clearCorrection = clear;
info->heavyLoading = heavyLoading;
}
void SfLegacyCpuPolicyAdapter::notifyPowerSuspend(bool enable) {
mPowerSuspend = enable;
}
void SfLegacyCpuPolicyAdapter::notifyHwcHwbinderTid(int tid) {
std::lock_guard lock(mHwcMutex);
if (std::find(mReadyTid.begin(), mReadyTid.end(), tid) == mReadyTid.end())
mReadyTid.push_back(tid);
}
void SfLegacyCpuPolicyAdapter::changeToForeground() {
if (mCpuSystemOnly) {
std::lock_guard lock(mHwcMutex);
size_t size = mReadyTid.size();
for (size_t i = 0; i < size; i++) {
if (!SetTaskProfiles(mReadyTid[i], {"ProcessCapacityHigh"})) {
ALOGE("SetTaskProfiles error happened : ProcessCapacityHigh, pid %d", mReadyTid[i]);
}
sched_setaffinity_task(mReadyTid[i], CONFIG_BL_CPU_MASK);
}
mCpuSystemOnly = false;
SF_ATRACE_INT("sf_cpu_LL", mCpuSystemOnly ? 1 : 0);
}
}
void SfLegacyCpuPolicyAdapter::changeToSystem() {
if (!mCpuSystemOnly) {
std::lock_guard lock(mHwcMutex);
size_t size = mReadyTid.size();
for (size_t i = 0; i < size; i++) {
if (!SetTaskProfiles(mReadyTid[i], {"SFMainPolicy"})) {
ALOGE("SetTaskProfiles error happened : SFMainPolicy, pid %d", mReadyTid[i]);
}
}
mCpuSystemOnly = true;
SF_ATRACE_INT("sf_cpu_LL", mCpuSystemOnly ? 1 : 0);
}
}
bool SfLegacyCpuPolicyAdapter::checkIfHeavy (bool earlySchedule, bool /*dp*/,
bool userHeavy, bool gpu) {
if (CONFIG_EARLY_SCHEDULE_HEAVY && earlySchedule && gpu) {
mIsEarly = true;
return true;
}
mIsEarly = false;
return userHeavy;
}
SfCpuPolicy::EnableReason SfLegacyCpuPolicyAdapter::checkIfNeedSuspend(int rate, bool gpu_comp,
bool * /*sus_mid*/, nsecs_t */*targetTime*/, nsecs_t /*sfDuration*/) {
SfCpuPolicy::EnableReason ret = SfCpuPolicy::EnableReason::NONE;
if (!(mIsEarly && gpu_comp) || mPowerSuspend || CONFIG_FORCE_SUSPEND_CPU_POLICY) {
mPolicySuspend = true;
} else {
mPolicySuspend = false;
if (rate > MinFps::FPS_120 ) {
ret = SfCpuPolicy::EnableReason::MIN_SPEED_120;
} else if (rate > MinFps::FPS_90 ) {
ret = SfCpuPolicy::EnableReason::MIN_SPEED_90;
} else {
ret = SfCpuPolicy::EnableReason::MIN_SPEED_60;
}
}
SF_ATRACE_INT("sf_cpu_suspend", mPolicySuspend ? 1 : 0);
return ret;
}
nsecs_t SfLegacyCpuPolicyAdapter::calcTargetTime (int fps, nsecs_t sfDuration) {
nsecs_t targetTime = 16* 1000000;
if (fps > MinFps::FPS_120) { // 120 fps
targetTime = 8 * 1000000; // 8ms
} else if (fps > MinFps::FPS_90) { // 90 fps
targetTime = 11 * 1000000; // 11ms
} else if (fps > MinFps::FPS_60){ // 60 fps
targetTime = 16 * 1000000; // 16ms
} else {
targetTime = 25 * 1000000; // 25ms
}
if (targetTime > sfDuration)
targetTime = sfDuration;
return targetTime;
}
bool SfLegacyCpuPolicyAdapter::needIncreasePerf(nsecs_t startTime,
nsecs_t endTime, nsecs_t targetTime) {
return (endTime - startTime) > targetTime;
}
bool SfLegacyCpuPolicyAdapter::needReducePerf(nsecs_t startTime,
nsecs_t endTime, nsecs_t targetTime) {
return (endTime - startTime) < targetTime;
}
void SfLegacyCpuPolicyAdapter::resetUclamp() {
if (mResetUclamp)
return;
mTargetUclampMin = CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT;
mUpCount = 0;
mDownCount = 0;
mNeedBoost = 0;
mCorrectionOffset = 0;
if (!mCpuSystemOnly)
changeToSystem();
setUclamp();
mResetUclamp = true;
}
void SfLegacyCpuPolicyAdapter::setUclamp() {
static int lastUclampMin = 0;
mResetUclamp = false;
if (mTargetUclampMin < CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT)
mTargetUclampMin = CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT;
if (lastUclampMin == mTargetUclampMin)
return;
lastUclampMin = mTargetUclampMin;
#ifdef MTK_SF_PERF_API
int returnVal = 0;
{
std::lock_guard lock(mHwcMutex);
size_t size = mReadyTid.size();
for (size_t i = 0; i < size; i++) {
if (std::find(mCgroup.begin(), mCgroup.end(), mReadyTid[i]) == mCgroup.end()) {
returnVal = SFPerfAPILoader::getInstance().perfAddThreadRequest(mReadyTid[i]);
if (returnVal != 0)
ALOGE("add pid failed: %d", mReadyTid[i]);
else
mCgroup.push_back(mReadyTid[i]);
}
}
}
returnVal = SFPerfAPILoader::getInstance().perfTaskUclampRequest(mTargetUclampMin, 0);
if (returnVal != 0) {
ALOGE("setUclamp failed !!!");
mCorrectionOffset = 0;
mTargetUclampMin = CONFIG_LOWBOUND_UCLAMP_MIN_DEFAULT;
}
#endif //MTK_SF_PERF_API
}
void SfLegacyCpuPolicyAdapter::notifySpeedUpRE(int /*resource*/) {
// do nothing
}
void SfLegacyCpuPolicyAdapter::notifyResetCalculation() {
// do nothing
}
void SfLegacyCpuPolicyAdapter::notifyVpLpEnable(bool /*enable*/) {
// do nothing
}
void SfLegacyCpuPolicyAdapter::notifyLayerConnect(const void * /*token*/, const std::string& /*name*/) {
// do nothing
}
void SfLegacyCpuPolicyAdapter::notifyLayerDisconnect(const void * /*token*/) {
// do nothing
}
void SfLegacyCpuPolicyAdapter::notifyLayerSetBuffer(const void * /*token*/, const sp<GraphicBuffer>& /*buffer*/) {
// do nothing
}
#ifdef MTK_COMPOSER_EXT
void SfLegacyCpuPolicyAdapter::setComposerExtIntf(ComposerExt::ClientInterface* /*intf*/) {
// do nothing
}
#endif //MTK_COMPOSER_EXT
}// namespace android
#endif //MTK_SF_CPU_POLICY_FOR_LEGACY