Fork me on GitHub

高通BoostFramework概要介绍

概要介绍

为了保证Android系统的顺滑体验,各个厂家都有针对性的对Android系统做了性能优化的方案。高通也基于AOSP开发了一套性能优化框架,本文叫做BoostFramework。本文将介绍下BoostFramework的基本框架。BoostFramework的结构框架

BoostFramework可以理解为高通开发的一个性能SDK,主要作用是给应用提供性能提升的相关能力。以应用启动场景为例。在应用启动时,系统识别到这个场景,会使用BoostFramework SDK提升CPU的频率,以此来达到提升应用启动性能的目的。

先看一张结构图:

BoostFramework Client端介绍========================Client端各个模块介绍

从上图可以看出BoostFramework分为client端和server端两大块。先介绍一下client端各个模块的情况:

BoostFramework:源码文件在路径frameworks/base/core/java/android/util/BoostFramework.java,该源文件被编译到framework.jar,作为一个工具类对外提供接口。各个应用模块就是通过这个接口使用BoostFramework SDK提供的能力。

QPerformance:是以QPerformance.jar的形式存在于/system/framework中,主要是提供调频接口给Java侧调用。源码路径在:vendor/qcom/proprietary/commonsys/android-perf/QPerformance

UxPerformance:是以UxPerformance.jar的形式存在于/system/framework中,主要提供的是io-prefetch的功能。源码路径在:vendor/qcom/proprietary/commonsys/android-perf/UxPerfomance

perfservice:是一个native service。以可执行程序的形式存在于/system/bin/perfservice,主要用于给三方应用提供perf sdk的调用接口。源码路径在vendor/qcom/proprietary/commonsys/android-perf/perfservice

libqti-at.so:一个共享库,主要是提供activity生命周期记录的功能。源码路径在vendor/qcom/proprietary/commonsys/android-perf/activity_trigger

libqti-perfd-client_system.so:作为一个client端,提供访问vendor.qti.hardware.perf@1.0-service这个hal service的接口。源码路径在:vendor/qcom/proprietary/commonsys-intf/android-perf/mp-ctllibqti-iopd-client_system.so:作为一个client端,提供访问vendor.qti.hardware.perf@1.0-service这个hal service的接口。源码路径在:vendor/qcom/proprietary/commonsys-intf/android-perf/io-plibqti-util_system.so:高通自研的事件池,用于保存和处理事件。源码路径在vendor/qcom/proprietary/commonsys-intf/android-perf/perf-utillibqti_performance:JNI接口,提供给系统签名应用使用。

BoostFramework的基本实现

BoostFramework提供的事件能力

    //perf hints
    public static final int VENDOR_HINT_SCROLL_BOOST = 0x00001080;
    public static final int VENDOR_HINT_FIRST_LAUNCH_BOOST = 0x00001081;
    public static final int VENDOR_HINT_SUBSEQ_LAUNCH_BOOST = 0x00001082;
    public static final int VENDOR_HINT_ANIM_BOOST = 0x00001083;
    public static final int VENDOR_HINT_ACTIVITY_BOOST = 0x00001084;
    public static final int VENDOR_HINT_TOUCH_BOOST = 0x00001085;
    public static final int VENDOR_HINT_MTP_BOOST = 0x00001086;
    public static final int VENDOR_HINT_DRAG_BOOST = 0x00001087;
    public static final int VENDOR_HINT_PACKAGE_INSTALL_BOOST = 0x00001088;
    public static final int VENDOR_HINT_ROTATION_LATENCY_BOOST = 0x00001089;
    public static final int VENDOR_HINT_ROTATION_ANIM_BOOST = 0x00001090;
    //perf events
    public static final int VENDOR_HINT_FIRST_DRAW = 0x00001042;
    public static final int VENDOR_HINT_TAP_EVENT = 0x00001043;
    //feedback hints
    public static final int VENDOR_FEEDBACK_WORKLOAD_TYPE = 0x00001601;
    public static final int VENDOR_FEEDBACK_LAUNCH_END_POINT = 0x00001602;

    //UXE Events and Triggers
    public static final int UXE_TRIGGER = 1;
    public static final int UXE_EVENT_BINDAPP = 2;
    public static final int UXE_EVENT_DISPLAYED_ACT = 3;
    public static final int UXE_EVENT_KILL = 4;
    public static final int UXE_EVENT_GAME  = 5;
    public static final int UXE_EVENT_SUB_LAUNCH = 6;
    public static final int UXE_EVENT_PKG_UNINSTALL = 7;
    public static final int UXE_EVENT_PKG_INSTALL = 8;

BoostFramework中提供的API接口的实现

/** @hide */
    public int perfLockAcquire(int duration, int... list) {
        int ret = -1;
        try {
            if (sAcquireFunc != null) {
                Object retVal = sAcquireFunc.invoke(mPerf, duration, list);
                ret = (int)retVal;
            }
        } catch(Exception e) {
            Log.e(TAG,"Exception " + e);
        }
        return ret;
    }

/** @hide */
    public int perfLockRelease() {
        int ret = -1;
        try {
            if (sReleaseFunc != null) {
                Object retVal = sReleaseFunc.invoke(mPerf);
                ret = (int)retVal;
            }
        } catch(Exception e) {
            Log.e(TAG,"Exception " + e);
        }
        return ret;
    }

/** @hide */
    public int perfLockReleaseHandler(int handle) {
        int ret = -1;
        try {
            if (sReleaseHandlerFunc != null) {
                Object retVal = sReleaseHandlerFunc.invoke(mPerf, handle);
                ret = (int)retVal;
            }
        } catch(Exception e) {
            Log.e(TAG,"Exception " + e);
        }
        return ret;
    }

/** @hide */
    public int perfHint(int hint, String userDataStr) {
        return perfHint(hint, userDataStr, -1, -1);
    }

/** @hide */
    public int perfHint(int hint, String userDataStr, int userData) {
        return perfHint(hint, userDataStr, userData, -1);
    }

/** @hide */
    public int perfHint(int hint, String userDataStr, int userData1, int userData2) {
        int ret = -1;
        try {
            if (sPerfHintFunc != null) {
                Object retVal = sPerfHintFunc.invoke(mPerf, hint, userDataStr, userData1, userData2);
                ret = (int)retVal;
            }
        } catch(Exception e) {
            Log.e(TAG,"Exception " + e);
        }
        return ret;
    }

/** @hide */
    public int perfGetFeedback(int req, String userDataStr) {
        int ret = -1;
        try {
            if (sFeedbackFunc != null) {
                Object retVal = sFeedbackFunc.invoke(mPerf, req, userDataStr);
                ret = (int)retVal;
            }
        } catch(Exception e) {
            Log.e(TAG,"Exception " + e);
        }
        return ret;
    }

/** @hide */
    public int perfIOPrefetchStart(int pid, String pkgName, String codePath) {
        int ret = -1;
        try {
            Object retVal = sIOPStart.invoke(mPerf, pid, pkgName, codePath);
            ret = (int) retVal;
            Log.d(TAG, "ret1 = " + ret);
        } catch (Exception e) {
            Log.e(TAG, "Exception " + e);
        }
        try {
            Object retVal = sUxIOPStart.invoke(mUxPerf, pid, pkgName, codePath);
            ret = (int) retVal;
            Log.d(TAG, "ret2 = " + ret);
        } catch (Exception e) {
            Log.e(TAG, "Ux Perf Exception " + e);
        }

        return ret;
    }

/** @hide */
    public int perfIOPrefetchStop() {
        int ret = -1;
        try {
            Object retVal = sIOPStop.invoke(mPerf);
            ret = (int) retVal;
        } catch (Exception e) {
            Log.e(TAG, "Exception " + e);
        }
        return ret;
    }

/** @hide */
    public int perfUXEngine_events(int opcode, int pid, String pkgName, int lat) {
        int ret = -1;
        if (sIopv2 == -1) {
            sIopv2 = SystemProperties.getInt("vendor.iop.enable_uxe", 0);
        }
        try {
            if (sIopv2 == 0 || sUXEngineEvents == null) {
                return ret;
            }
            Object retVal = sUXEngineEvents.invoke(mPerf, opcode, pid, pkgName, lat);
            ret = (int) retVal;
        } catch (Exception e) {
            Log.e(TAG, "Exception " + e);
        }
        return ret;
    }


/** @hide */
    public String perfUXEngine_trigger(int opcode) {
        String ret = null;
        if (sIopv2 == -1) {
            sIopv2 = SystemProperties.getInt("vendor.iop.enable_uxe", 0);
        }
        try {
            if (sIopv2 == 0 || sUXEngineTrigger == null) {
                return ret;
            }
            Object retVal = sUXEngineTrigger.invoke(mPerf, opcode);
            ret = (String) retVal;
        } catch (Exception e) {
            Log.e(TAG, "Exception " + e);
        }
        return ret;
    }

BoostFramework的基本使用方法

=========================================================================================
  PerfLock API usage in framework
=========================================================================================

1. Add "import android.util.BoostFramework;" in your Java source file

2. Create the BoostFramework class object

3. Use "perfLockAcquire" to request the optmizations required
   and store the returned handle into an int variable.

4. Use "perfLockRelease" to toggle the optimizations off
   NOTE: perfLockRelease is optional but required if the duration
         of acquisition is unknown (ie. 0).
______________________________________________________________________
Example: Request PerfLock for minimum of two cores and set the
         minimum frequency for CPU0 and CPU1 to 1026 Mhz for three seconds.

   BoostFramework mPerf = new BoostFramework();

   mPerf.perfLockAcquire(3000, Performance.CPUS_ON_2, \
                       Performance.CPU0_FREQ_LVL_NONTURBO_MAX, Performance.CPU1_FREQ_LVL_NONTURBO_MAX);

   // Critical section requiring PerfLock

NOTE: perfLockRelease is not required since PerfLock will automatically
      release after three seconds.

______________________________________________________________________
Example: Request PerfLock for minimum of three cores in one section.
         Set duration for five seconds and release before that if possible.

         Request PerfLock for minimum of two cores in another section.
         Set duration for three seconds and release before that if possible.

   BoostFramework mPerf = new BoostFramework();
   BoostFramework sPerf = new BoostFramework();

   mPerf.perfLockAcquire(5000, Performance.CPUS_ON_3);

   // Critical section requiring PerfLock

   mPerf.perfLockRelease();

   // other code in between

   sPerf.perfLockAcquire(3000, Performance.CPUS_ON_2);

   // Critical section requiring PerfLock

   sPerf.perfLockRelease();

NOTE: perfLockRelease is recommended to ensure PerfLock is not held for longer
      than it needs to be.

QPerformance

QPerformance对外提供的接口

从软件的最上层QPerformance开始看,提供的接口在vendor/qcom/proprietary/commonsys/android-perf/QPerformance/src/com/qualcomm/qti/IPerfManager.aidl文件中定义:

interface IPerfManager {
    //关闭之前所有请求的性能优化策略
    int perfLockRelease();
    //关闭handle对应的之前请求过的性能优化策略
    int perfLockReleaseHandler(int handle);
    int perfHint(int hint, String userDataStr, int userData1, int userData2, int tid);
    //使能某一种请求的性能优化策略
    int perfLockAcquire(int duration, in int[] list);
    int perfUXEngine_events(int opcode, int pid, String pkg_name, int lat);
    int setClientBinder(IBinder client);
    int perfGetFeedback(int req, String userDataStr);
}

QPerformance中给出了aidl接口的具体实现。对于系统应用走JNI调用流程到server端,对于三方应用则通过perfservice调用到server端。

PerfLock APIs介绍

=========================================================================================
  Description
=========================================================================================

The PerfLock APIs can be used in either the framework or in packaged applications.
The APIs toggle system performance optimizations based upon level requested.
PerfLock will always run the highest level of optimization requested.

NOTE: Each instance of the Performance class object will serve one unique PerfLock request.
      Therefore, a new Performance class object will need to be created for every
      unique request for PerfLock.

Please read through the following carefully to understand the proper usage of this API.

=========================================================================================
  PerfLock APIs
=========================================================================================

The following two methods are the PerfLock APIs

1. perfLockAcquire(int duration, int... args)

    Description:

        Toggle on all optimizations requested.

    Arguments:

        duration: The maximum amount of time required to hold the lock.
                  Only a positive integer value in milliseconds will be accepted.
                  You may explicitly call perfLockRelease before the timer expires.

        args: Enter all optimizations required. Only the optimizations in the
              table below are supported. You can only choose one optimization
              from each of the numbered sections in the table. Incorrect or
              unsupported optimizations will be ignored.

              NOTE: Enter the optimizations required in the order they appear in the table.

    Returns: REQUEST_SUCCEEDED or REQUEST_FAILED.

2. perfLockRelease()

    Description:

        Toggle off all optimizations requested.
        Use this function if you want to release before the time duration ends.

    Arguments: None.

    Returns: REQUEST_SUCCEEDED or REQUEST_FAILED.

=========================================================================================
  Optimizations Supported
=========================================================================================

The following resource optimizations are supported:

 ===============================================================================================
|         |                                        |                                            |
| Section | Optimization                           | Description                                |
|         |                                        |                                            |
 ===============================================================================================
|    1    | ALL_CPUS_PWR_CLPS_DIS                  | Disables power collapse on all CPUs        |
|         |                                        |                                            |
 ===============================================================================================
|    2    | CPUS_ON_MAX                            | Minimum of all cores on                    |
|         |________________________________________|____________________________________________|
|         | CPUS_ON_3                              | Minimum of three cores on                  |
|         |________________________________________|____________________________________________|
|         | CPUS_ON_2                              | Minimum of two cores on                    |
|         |________________________________________|____________________________________________|
|         | CPUS_ON_LIMIT_1                        | Maximum of one core on                     |
|         |________________________________________|____________________________________________|
|         | CPUS_ON_LIMIT_2                        | Maximum of two cores on                    |
|         |________________________________________|____________________________________________|
|         | CPUS_ON_LIMIT_3                        | Maximum of three cores on                  |
|         |                                        |                                            |
 ===============================================================================================
| For the following CPU FREQ resources, please read carefully on the usage.                     |
| All frequencies available on the device are supported. In order to use an intermediate        |
| frequency not specified with an enum, you will need to pass in a valid hex value.             |
| The leftmost byte represents the CPU and the rightmost byte represents the frequency.         |
| The hex value used will be multiplied by 10^5 to calculate the minimum frequency requested.   |
| This calculated frequency or the next highest frequency available will be set.                |
|                                                                                               |
| Example: Set CPU0 frequency to a minimum of 700 Mhz                                           |
|          Use 0x207.                                                                           |
|                                                                                               |
| Example: Set CPU1 frequency to a maximum of 2.0 Ghz                                           |
|          Use 0x1614.                                                                          |
|                                                                                               |
 ===============================================================================================
|    3    | CPU0_FREQ_LVL_TURBO_MAX = 0x2FE        | Set CPU0 minimum frequency to device max   |
|         |________________________________________|____________________________________________|
|         | CPU0_FREQ_LVL_NONTURBO_MAX = 0x20A     | Set CPU0 minimum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
|    4    | CPU1_FREQ_LVL_TURBO_MAX = 0x3FE        | Set CPU1 minimum frequency to device max   |
|         |________________________________________|____________________________________________|
|         | CPU1_FREQ_LVL_NONTURBO_MAX = 0x30A     | Set CPU1 minimum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
|    5    | CPU2_FREQ_LVL_TURBO_MAX = 0x4FE        | Set CPU2 minimum frequency to device max   |
|         |________________________________________|____________________________________________|
|         | CPU2_FREQ_LVL_NONTURBO_MAX = 0x40A     | Set CPU2 minimum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
|    6    | CPU3_FREQ_LVL_TURBO_MAX = 0x5FE        | Set CPU3 minimum frequency to device max   |
|         |________________________________________|____________________________________________|
|         | CPU3_FREQ_LVL_NONTURBO_MAX = 0x50A     | Set CPU3 minimum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
|    7    | CPU0_MAX_FREQ_LVL_NONTURBO_MAX = 0x150A| Set CPU0 maximum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
|    8    | CPU1_MAX_FREQ_LVL_NONTURBO_MAX = 0x160A| Set CPU1 maximum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
|    9    | CPU2_MAX_FREQ_LVL_NONTURBO_MAX = 0x170A| Set CPU2 maximum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
|   10    | CPU3_MAX_FREQ_LVL_NONTURBO_MAX = 0x180A| Set CPU3 maximum frequency to 1026 Mhz     |
|         |                                        |                                            |
 ===============================================================================================
posted @ 2024-07-17 16:24  yooooooo  阅读(2)  评论(0编辑  收藏  举报