753 lines
26 KiB
C++
753 lines
26 KiB
C++
/* 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, ¶m) != 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
|