power: Handle launch and interaction hints
Co-authored-by: dianlujitao <dianlujitao@lineageos.org> Co-authored-by: Michael Bestas <mkbestas@lineageos.org> Co-authored-by: Quallenauge <Hamsi2k@freenet.de> Co-authored-by: tomascus <arbiter1000@gmail.com> Co-authored-by: Wei Wang <wvw@google.com> Change-Id: I472a177e0a13b0c4201cf0b1e5ddee18a785b683
This commit is contained in:
committed by
Michael Bestas
parent
b5dbefb18a
commit
7c575afade
@@ -59,10 +59,6 @@ ifeq ($(call is-board-platform-in-list,sdm845), true)
|
||||
LOCAL_SRC_FILES += power-845.c
|
||||
endif
|
||||
|
||||
ifeq ($(call is-board-platform-in-list,msmnile), true)
|
||||
LOCAL_SRC_FILES += power-msmnile.c
|
||||
endif
|
||||
|
||||
endif # End of board specific list
|
||||
|
||||
ifneq ($(TARGET_POWERHAL_MODE_EXT),)
|
||||
|
||||
24
Power.cpp
24
Power.cpp
@@ -84,7 +84,6 @@ ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||
#endif
|
||||
case Mode::LOW_POWER:
|
||||
case Mode::LAUNCH:
|
||||
case Mode::DEVICE_IDLE:
|
||||
case Mode::DISPLAY_INACTIVE:
|
||||
case Mode::AUDIO_STREAMING_LOW_LATENCY:
|
||||
@@ -98,9 +97,11 @@ ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
||||
case Mode::EXPENSIVE_RENDERING:
|
||||
set_expensive_rendering(enabled);
|
||||
break;
|
||||
case Mode::LAUNCH:
|
||||
power_hint(POWER_HINT_LAUNCH, enabled ? &enabled : NULL);
|
||||
break;
|
||||
case Mode::INTERACTIVE:
|
||||
setInteractive(enabled);
|
||||
power_hint(POWER_HINT_INTERACTION, NULL);
|
||||
break;
|
||||
case Mode::SUSTAINED_PERFORMANCE:
|
||||
case Mode::FIXED_PERFORMANCE:
|
||||
@@ -131,6 +132,7 @@ ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
|
||||
#ifdef TAP_TO_WAKE_NODE
|
||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||
#endif
|
||||
case Mode::LAUNCH:
|
||||
case Mode::INTERACTIVE:
|
||||
case Mode::SUSTAINED_PERFORMANCE:
|
||||
case Mode::FIXED_PERFORMANCE:
|
||||
@@ -146,14 +148,30 @@ ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
|
||||
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
||||
LOG(VERBOSE) << "Power setBoost: " << static_cast<int32_t>(type)
|
||||
<< ", duration: " << durationMs;
|
||||
switch (type) {
|
||||
case Boost::INTERACTION:
|
||||
power_hint(POWER_HINT_INTERACTION, &durationMs);
|
||||
break;
|
||||
default:
|
||||
LOG(INFO) << "Boost " << static_cast<int32_t>(type) << "Not Supported";
|
||||
break;
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) {
|
||||
LOG(INFO) << "Power isBoostSupported: " << static_cast<int32_t>(type);
|
||||
*_aidl_return = false;
|
||||
switch (type) {
|
||||
case Boost::INTERACTION:
|
||||
*_aidl_return = true;
|
||||
break;
|
||||
default:
|
||||
*_aidl_return = false;
|
||||
break;
|
||||
}
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::createHintSession(int32_t tgid, int32_t uid,
|
||||
const std::vector<int32_t>& threadIds,
|
||||
int64_t durationNanos,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
#include "power-common.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define CHECK_HANDLE(x) ((x) > 0)
|
||||
#define NUM_PERF_MODES 3
|
||||
|
||||
typedef enum {
|
||||
@@ -189,12 +188,6 @@ 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);
|
||||
ret_val = HINT_HANDLED;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#include "power-common.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define CHECK_HANDLE(x) ((x) > 0)
|
||||
#define NUM_PERF_MODES 3
|
||||
|
||||
static int video_encode_hint_sent;
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#include "power-common.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define CHECK_HANDLE(x) ((x) > 0)
|
||||
#define NUM_PERF_MODES 3
|
||||
|
||||
typedef enum {
|
||||
@@ -188,11 +187,6 @@ 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:
|
||||
if (current_mode != NORMAL_MODE) {
|
||||
ret_val = HINT_HANDLED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@
|
||||
static struct hint_handles handles[NUM_HINTS];
|
||||
static int handleER = 0;
|
||||
|
||||
const int kMaxLaunchDuration = 5000; /* ms */
|
||||
const int kMaxInteractiveDuration = 5000; /* ms */
|
||||
const int kMinInteractiveDuration = 500; /* ms */
|
||||
|
||||
void power_init() {
|
||||
ALOGI("Initing");
|
||||
|
||||
@@ -60,6 +64,69 @@ void power_init() {
|
||||
}
|
||||
}
|
||||
|
||||
void process_interaction_hint(void* data) {
|
||||
static struct timespec s_previous_boost_timespec;
|
||||
static int s_previous_duration = 0;
|
||||
static int prev_interaction_handle = -1;
|
||||
|
||||
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 it's been less than 250ms since last boost
|
||||
// also detect if we're doing anything resembling a fling
|
||||
// support additional boosting in case of flings
|
||||
if (elapsed_time < 250000 && duration <= 750) {
|
||||
return;
|
||||
}
|
||||
s_previous_boost_timespec = cur_boost_timespec;
|
||||
s_previous_duration = duration;
|
||||
|
||||
int interaction_handle =
|
||||
perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
|
||||
|
||||
if (CHECK_HANDLE(prev_interaction_handle)) {
|
||||
release_request(prev_interaction_handle);
|
||||
}
|
||||
prev_interaction_handle = interaction_handle;
|
||||
}
|
||||
|
||||
void 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
launch_mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int __attribute__((weak)) power_hint_override(power_hint_t hint, void* data) {
|
||||
return HINT_NONE;
|
||||
}
|
||||
@@ -74,12 +141,6 @@ void power_hint(power_hint_t hint, void* data) {
|
||||
case POWER_HINT_VR_MODE:
|
||||
ALOGI("VR mode power hint not handled in power_hint_override");
|
||||
break;
|
||||
case POWER_HINT_INTERACTION: {
|
||||
int resources[] = {0x702, 0x20F, 0x30F};
|
||||
int duration = 3000;
|
||||
|
||||
interaction(duration, sizeof(resources) / sizeof(resources[0]), resources);
|
||||
} break;
|
||||
// fall through below, hints will fail if not defined in powerhint.xml
|
||||
case POWER_HINT_SUSTAINED_PERFORMANCE:
|
||||
case POWER_HINT_VIDEO_ENCODE:
|
||||
@@ -99,6 +160,12 @@ void power_hint(power_hint_t hint, void* data) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case POWER_HINT_INTERACTION:
|
||||
process_interaction_hint(data);
|
||||
break;
|
||||
case POWER_HINT_LAUNCH:
|
||||
process_activity_launch_hint(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ void set_expensive_rendering(bool enabled);
|
||||
void set_interactive(int on);
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
|
||||
#define CHECK_HANDLE(x) ((x) > 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LOG_NIDEBUG 0
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LOG_TAG "QTI PowerHAL"
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/power.h>
|
||||
#include <log/log.h>
|
||||
|
||||
#include "performance.h"
|
||||
#include "power-common.h"
|
||||
#include "utils.h"
|
||||
|
||||
int power_hint_override(power_hint_t hint, void* data) {
|
||||
int ret_val = HINT_NONE;
|
||||
switch (hint) {
|
||||
case POWER_HINT_INTERACTION: {
|
||||
int resources[] = {MIN_FREQ_LITTLE_CORE_0, 0x514};
|
||||
int duration = 100;
|
||||
interaction(duration, ARRAY_SIZE(resources), resources);
|
||||
ret_val = HINT_HANDLED;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
24
utils.c
24
utils.c
@@ -43,6 +43,9 @@
|
||||
#define LOG_TAG "QTI PowerHAL"
|
||||
#include <log/log.h>
|
||||
|
||||
#define USINSEC 1000000L
|
||||
#define NSINUS 1000L
|
||||
|
||||
#define SOC_ID_0 "/sys/devices/soc0/soc_id"
|
||||
#define SOC_ID_1 "/sys/devices/system/soc/soc0/id"
|
||||
|
||||
@@ -258,6 +261,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);
|
||||
}
|
||||
@@ -364,3 +381,10 @@ int get_soc_id(void) {
|
||||
close(fd);
|
||||
return soc_id;
|
||||
}
|
||||
|
||||
long long calc_timespan_us(struct timespec start, struct timespec end) {
|
||||
long long diff_in_us = 0;
|
||||
diff_in_us += (end.tv_sec - start.tv_sec) * USINSEC;
|
||||
diff_in_us += (end.tv_nsec - start.tv_nsec) / NSINUS;
|
||||
return diff_in_us;
|
||||
}
|
||||
|
||||
2
utils.h
2
utils.h
@@ -47,7 +47,9 @@ 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);
|
||||
|
||||
PropVal perf_get_property(const char* prop, const char* def_val);
|
||||
|
||||
Reference in New Issue
Block a user