summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBeYkeRYkt <beykerykt@gmail.com>2018-12-13 06:42:35 +0900
committerMichael Bestas <mkbestas@lineageos.org>2019-10-23 01:12:57 +0300
commitef7a7ed7e04d113afdbe96ca07f55dd74111cc3c (patch)
tree7b2fac246a8614a6deda51eaacc7d5c8d77ee063
parent2c5b2b8afe66195d926adc0e4085b36625f2f4b0 (diff)
downloadvendor_qcom_opensource_power-ef7a7ed7e04d113afdbe96ca07f55dd74111cc3c.tar.gz
vendor_qcom_opensource_power-ef7a7ed7e04d113afdbe96ca07f55dd74111cc3c.tar.bz2
vendor_qcom_opensource_power-ef7a7ed7e04d113afdbe96ca07f55dd74111cc3c.zip
power: Handle launch and interaction hints for perf HAL platforms
Author: BeYkeRYkt <beykerykt@gmail.com> Date: Thu Dec 13 06:42:35 2018 +0900 power: Handle launch and interaction hints for perf HAL platforms * MP-CTL does not handle POWER_HINT_INTERACTION and POWER_HINT_LAUNCH directly. Requests for processing are sent by Qualcomm BoostFramework (QPerformance) at the framework service level. Since we do not have BoostFramework, process POWER_HINT_INTERACTION and POWER_HINT_LAUNCH in PowerHAL to ensure a sufficient level of performance. * For proper operation, perfboostsconfig.xml file is required. Change-Id: I4c67d886c9dd74ae07094d32bdffc8ef403e04e7 Author: tomascus <arbiter1000@gmail.com> Date: Wed Feb 13 14:42:27 2019 +1100 power: don't use SCROLL_PREFILING The current use of the SCROLL_PREFILING hint hurts scroll performance and results in a lot of dropped frames. The hint ID corresponding to SCROLL_PREFILING only takes into effect for a default timeout value of 80 ms (as found in perfboostsconfig.xml), while the duration value in the process_interaction_hint function runs for a much longer time, from 1500 ms up to 5000 ms (bounds of kMinFlingDuration and kMaxInteractiveDuration). During the period of time, when the timeout value has elapsed and current time is less than duration, another interaction hint cannot be processed. Therefore, if the user decides to scroll during this period, high frame drops can be experienced as the CPU freq isn't raised by processing another hint to account for this additional scrolling. By only using SCROLL_VERTICAL, fluidity can be maintained, improving user experience. Furthmore, kMinInteractiveDuration has been lowered to 400 ms for some platforms as it is more than sufficient to maintain fluidity (minimal frames dropped) while scrolling. Change-Id: I42edd07a67c7dca43a10ae2fa1b44b64b7794b43 commit e9063a6956974a2e33652e2df0ecac991ee84c80 Author: tomascus <arbiter1000@gmail.com> Date: Tue Feb 19 17:15:58 2019 +1100 power: Release launch boost perflock when launch is completed Currently, the launch boost perflock is held for a fixed duration, either specified in perfboostsconfig.xml for perf HAL platforms or hardcoded in the powerHAL for non-perf HAL platforms. Using a fixed duration for this perflock has two shortcomings: * perflock can be held for too long, causing the CPU freq and other resources to be boosted for too long even if the application has finished launching, resulting in excessive battery drainage * perflock can be held not long enough if it takes more than the timeout time to finish launch The framework sends out a powerhint for both when launch starts and when launch ends. The launch finish hint can be used to signal when to release the perflock. Reference: Wahoo power-libperfmgr Change-Id: I405cc453c5f58d9fb2583b9c6017f3964a0ce024 Change-Id: I8ef6a890bc191f9504980707107750a720b50da3
-rw-r--r--performance.h16
-rw-r--r--power-660.c67
-rw-r--r--power-845.c79
-rw-r--r--power-8937.c67
-rw-r--r--power-8953.c67
-rw-r--r--power-8996.c75
-rw-r--r--power-8998.c76
-rw-r--r--power-common.h1
-rw-r--r--utils.c14
-rw-r--r--utils.h1
10 files changed, 452 insertions, 11 deletions
diff --git a/performance.h b/performance.h
index 7b40331..1a8fad6 100644
--- a/performance.h
+++ b/performance.h
@@ -42,6 +42,22 @@ extern "C" {
#define VENDOR_HINT_DISPLAY_OFF 0x00001040
#define VENDOR_HINT_DISPLAY_ON 0x00001041
+#define VENDOR_HINT_SCROLL_BOOST 0x00001080
+#define VENDOR_HINT_FIRST_LAUNCH_BOOST 0x00001081
+
+enum SCROLL_BOOST_TYPE {
+ SCROLL_VERTICAL = 1,
+ SCROLL_HORIZONTAL = 2,
+ SCROLL_PANEL_VIEW = 3,
+ SCROLL_PREFILING = 4,
+};
+
+enum LAUNCH_BOOST_TYPE {
+ LAUNCH_BOOST_V1 = 1,
+ LAUNCH_BOOST_V2 = 2,
+ LAUNCH_BOOST_V3 = 3,
+};
+
enum SCREEN_DISPLAY_TYPE {
DISPLAY_OFF = 0x00FF,
};
diff --git a/power-660.c b/power-660.c
index e1b74de..5696718 100644
--- a/power-660.c
+++ b/power-660.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#define LOG_TAG "QTI PowerHAL"
@@ -51,6 +52,10 @@
static int video_encode_hint_sent;
+const int kMinInteractiveDuration = 400; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
/**
* Returns true if the target is SDM630/SDM455.
*/
@@ -140,12 +145,74 @@ static int process_video_encode_hint(void* metadata) {
return HINT_NONE;
}
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kMinInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (!launch_mode) {
+ launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST,
+ kMaxLaunchDuration, LAUNCH_BOOST_V1);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
case POWER_HINT_VIDEO_ENCODE:
ret_val = process_video_encode_hint(data);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-845.c b/power-845.c
index 2758bcf..e2b6892 100644
--- a/power-845.c
+++ b/power-845.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#define LOG_TAG "QTI PowerHAL"
@@ -52,9 +53,12 @@
static int display_fd;
#define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr"
-#define CHECK_HANDLE(x) ((x) > 0)
#define NUM_PERF_MODES 3
+const int kMinInteractiveDuration = 100; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
typedef enum {
NORMAL_MODE = 0,
SUSTAINED_MODE = 1,
@@ -178,6 +182,68 @@ static int process_video_encode_hint(void* metadata) {
}
}
return HINT_NONE;
+};
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kMinInteractiveDuration;
+
+ if (current_mode != NORMAL_MODE) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ return;
+ }
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (current_mode != NORMAL_MODE) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ } else if (!launch_mode) {
+ launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST,
+ kMaxLaunchDuration, LAUNCH_BOOST_V1);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
}
int power_hint_override(power_hint_t hint, void* data) {
@@ -192,12 +258,13 @@ int power_hint_override(power_hint_t hint, void* data) {
case POWER_HINT_VR_MODE:
ret_val = process_perf_hint(data, VR_MODE);
break;
- case POWER_HINT_INTERACTION: {
- int resources[] = {MIN_FREQ_LITTLE_CORE_0, 0x514};
- int duration = 100;
- interaction(duration, ARRAY_SIZE(resources), resources);
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
ret_val = HINT_HANDLED;
- } break;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-8937.c b/power-8937.c
index e3554f2..6887b78 100644
--- a/power-8937.c
+++ b/power-8937.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#define LOG_TAG "QTI PowerHAL"
@@ -54,6 +55,10 @@ static int video_encode_hint_sent;
static int display_fd;
#define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr"
+const int kMinInteractiveDuration = 500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
/**
* Returns true if the target is SDM439/SDM429.
*/
@@ -156,12 +161,74 @@ static int process_video_encode_hint(void* metadata) {
return HINT_NONE;
}
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kMinInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (!launch_mode) {
+ launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST,
+ kMaxLaunchDuration, LAUNCH_BOOST_V1);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
case POWER_HINT_VIDEO_ENCODE:
ret_val = process_video_encode_hint(data);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-8953.c b/power-8953.c
index 7c97b77..3d76c6b 100644
--- a/power-8953.c
+++ b/power-8953.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#define LOG_TAG "QTI PowerHAL"
@@ -54,6 +55,10 @@ static int video_encode_hint_sent;
static int display_fd;
#define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr"
+const int kMinInteractiveDuration = 500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
/**
* Returns true if the target is SDM632.
*/
@@ -153,12 +158,74 @@ static int process_video_encode_hint(void* metadata) {
return HINT_NONE;
}
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kMinInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (!launch_mode) {
+ launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST,
+ kMaxLaunchDuration, LAUNCH_BOOST_V1);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
case POWER_HINT_VIDEO_ENCODE:
ret_val = process_video_encode_hint(data);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-8996.c b/power-8996.c
index faee7a7..0ef4dfd 100644
--- a/power-8996.c
+++ b/power-8996.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -47,11 +48,14 @@
#include "power-common.h"
#include "utils.h"
-#define CHECK_HANDLE(x) ((x) > 0)
#define NUM_PERF_MODES 3
static int video_encode_hint_sent;
+const int kMinInteractiveDuration = 500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
typedef enum {
NORMAL_MODE = 0,
SUSTAINED_MODE = 1,
@@ -205,6 +209,68 @@ static int process_video_encode_hint(void* metadata) {
return HINT_NONE;
}
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kMinInteractiveDuration;
+
+ if (current_mode != NORMAL_MODE) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ return;
+ }
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (current_mode != NORMAL_MODE) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ } else if (!launch_mode) {
+ launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST,
+ kMaxLaunchDuration, LAUNCH_BOOST_V1);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -217,6 +283,13 @@ int power_hint_override(power_hint_t hint, void* data) {
case POWER_HINT_VR_MODE:
ret_val = process_perf_hint(data, VR_MODE);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-8998.c b/power-8998.c
index 7fcc347..4971640 100644
--- a/power-8998.c
+++ b/power-8998.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#define LOG_TAG "QTI PowerHAL"
@@ -48,9 +49,12 @@
#include "power-common.h"
#include "utils.h"
-#define CHECK_HANDLE(x) ((x) > 0)
#define NUM_PERF_MODES 3
+const int kMaxLaunchDuration = 5000; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMinInteractiveDuration = 400; /* ms */
+
typedef enum {
NORMAL_MODE = 0,
SUSTAINED_MODE = 1,
@@ -176,6 +180,68 @@ static int process_video_encode_hint(void* metadata) {
return HINT_NONE;
}
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kMinInteractiveDuration;
+
+ if (current_mode != NORMAL_MODE) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ return;
+ }
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (current_mode != NORMAL_MODE) {
+ ALOGV("%s: ignoring due to other active perf hints", __func__);
+ } else if (!launch_mode) {
+ launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST,
+ kMaxLaunchDuration, LAUNCH_BOOST_V1);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -189,9 +255,11 @@ int power_hint_override(power_hint_t hint, void* data) {
ret_val = process_perf_hint(data, VR_MODE);
break;
case POWER_HINT_INTERACTION:
- if (current_mode != NORMAL_MODE) {
- ret_val = HINT_HANDLED;
- }
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
break;
default:
break;
diff --git a/power-common.h b/power-common.h
index c989e97..9124aac 100644
--- a/power-common.h
+++ b/power-common.h
@@ -51,6 +51,7 @@ void power_hint(power_hint_t hint, void* data);
void set_interactive(int on);
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
+#define CHECK_HANDLE(x) ((x) > 0)
#define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#ifdef __cplusplus
diff --git a/utils.c b/utils.c
index 38b5803..2ad301f 100644
--- a/utils.c
+++ b/utils.c
@@ -256,6 +256,20 @@ int perf_hint_enable(int hint_id, int duration) {
return lock_handle;
}
+// Same as perf_hint_enable, but with the ability to
+// choose the type
+int perf_hint_enable_with_type(int hint_id, int duration, int type) {
+ int lock_handle = 0;
+
+ if (qcopt_handle) {
+ if (perf_hint) {
+ lock_handle = perf_hint(hint_id, NULL, duration, type);
+ if (lock_handle == -1) ALOGE("Failed to acquire lock.");
+ }
+ }
+ return lock_handle;
+}
+
void release_request(int lock_handle) {
if (qcopt_handle && perf_lock_rel) perf_lock_rel(lock_handle);
}
diff --git a/utils.h b/utils.h
index 2c46a20..3acb0f7 100644
--- a/utils.h
+++ b/utils.h
@@ -43,6 +43,7 @@ void release_request(int lock_handle);
void interaction(int duration, int num_args, int opt_list[]);
int interaction_with_handle(int lock_handle, int duration, int num_args, int opt_list[]);
int perf_hint_enable(int hint_id, int duration);
+int perf_hint_enable_with_type(int hint_id, int duration, int type);
long long calc_timespan_us(struct timespec start, struct timespec end);
int get_soc_id(void);