diff options
author | Prateek Chaubey <chaubeyprateek@gmail.com> | 2018-01-07 20:55:14 +0530 |
---|---|---|
committer | Davide Garberi <dade.garberi@gmail.com> | 2018-01-19 14:09:15 +0100 |
commit | 6616278131edd80a12545085e06ee6b0e0a0a788 (patch) | |
tree | 0aef88ed11809a9d67f6abe4dc2ff782a14737e2 /camera/QCamera2/util/QCameraPerf.cpp | |
parent | cc4ccf34871da343111bf68d16ba4e4c67cac1dc (diff) |
msm8996-common: zuk: Import OSS Camera HAL
Tag: LA.HB.1.3.2-32600-8x96.0
Signed-off-by: Davide Garberi <dade.garberi@gmail.com>
Diffstat (limited to 'camera/QCamera2/util/QCameraPerf.cpp')
-rw-r--r-- | camera/QCamera2/util/QCameraPerf.cpp | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/camera/QCamera2/util/QCameraPerf.cpp b/camera/QCamera2/util/QCameraPerf.cpp new file mode 100644 index 0000000..83ba4cc --- /dev/null +++ b/camera/QCamera2/util/QCameraPerf.cpp @@ -0,0 +1,545 @@ +/* Copyright (c) 2015-2016, 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_TAG "QCameraPerf" + +// To remove +#include <cutils/properties.h> + +// System dependencies +#include <stdlib.h> +#include <dlfcn.h> + +// Camera dependencies +#include "QCameraPerf.h" +#include "QCameraTrace.h" + +extern "C" { +#include "mm_camera_dbg.h" +} + +namespace qcamera { + +/*=========================================================================== + * FUNCTION : QCameraPerfLock constructor + * + * DESCRIPTION: initialize member variables + * + * PARAMETERS : + * None + * + * RETURN : void + * + *==========================================================================*/ +QCameraPerfLock::QCameraPerfLock() : + perf_lock_acq(NULL), + perf_lock_rel(NULL), + mDlHandle(NULL), + mPerfLockEnable(0), + mPerfLockHandle(-1), + mPerfLockHandleTimed(-1), + mTimerSet(0), + mPerfLockTimeout(0), + mStartTimeofLock(0) +{ +} + +/*=========================================================================== + * FUNCTION : QCameraPerfLock destructor + * + * DESCRIPTION: class desctructor + * + * PARAMETERS : + * None + * + * RETURN : void + * + *==========================================================================*/ +QCameraPerfLock::~QCameraPerfLock() +{ + lock_deinit(); +} + + +/*=========================================================================== + * FUNCTION : lock_init + * + * DESCRIPTION: opens the performance lib and initilizes the perf lock functions + * + * PARAMETERS : + * None + * + * RETURN : void + * + *==========================================================================*/ +void QCameraPerfLock::lock_init() +{ + const char *rc; + char value[PROPERTY_VALUE_MAX]; + + LOGD("E"); + Mutex::Autolock lock(mLock); + + // Clear the list of active power hints + mActivePowerHints.clear(); + mCurrentPowerHint = static_cast<power_hint_t>(0); + mCurrentPowerHintEnable = false; + + property_get("persist.camera.perflock.enable", value, "1"); + mPerfLockEnable = atoi(value); +#ifdef HAS_MULTIMEDIA_HINTS + if (hw_get_module(POWER_HARDWARE_MODULE_ID, (const hw_module_t **)&m_pPowerModule)) { + LOGE("%s module not found", POWER_HARDWARE_MODULE_ID); + } +#endif + + if (mPerfLockEnable) { + perf_lock_acq = NULL; + perf_lock_rel = NULL; + mPerfLockHandle = -1; + /* Retrieve name of vendor extension library */ + if (property_get("ro.vendor.extension_library", value, NULL) <= 0) { + goto cleanup; + } + + mDlHandle = dlopen(value, RTLD_NOW | RTLD_LOCAL); + if (mDlHandle == NULL) { + goto cleanup; + } + + dlerror(); + + perf_lock_acq = (int (*) (int, int, int[], int))dlsym(mDlHandle, "perf_lock_acq"); + if ((rc = dlerror()) != NULL) { + LOGE("failed to perf_lock_acq function handle"); + goto cleanup; + } + + perf_lock_rel = (int (*) (int))dlsym(mDlHandle, "perf_lock_rel"); + if ((rc = dlerror()) != NULL) { + LOGE("failed to perf_lock_rel function handle"); + goto cleanup; + } + LOGD("X"); + return; + +cleanup: + perf_lock_acq = NULL; + perf_lock_rel = NULL; + mPerfLockEnable = 0; + if (mDlHandle) { + dlclose(mDlHandle); + mDlHandle = NULL; + } + } + LOGD("X"); +} + +/*=========================================================================== + * FUNCTION : lock_deinit + * + * DESCRIPTION: deinitialize the perf lock parameters + * + * PARAMETERS : + * None + * + * RETURN : void + * + *==========================================================================*/ +void QCameraPerfLock::lock_deinit() +{ + Mutex::Autolock lock(mLock); + if (mPerfLockEnable) { + LOGD("E"); + + if (mActivePowerHints.empty() == false) { + // Disable the active power hint + mCurrentPowerHint = *mActivePowerHints.begin(); + powerHintInternal(mCurrentPowerHint, false); + mActivePowerHints.clear(); + } + + if ((NULL != perf_lock_rel) && (mPerfLockHandleTimed >= 0)) { + (*perf_lock_rel)(mPerfLockHandleTimed); + } + + if ((NULL != perf_lock_rel) && (mPerfLockHandle >= 0)) { + (*perf_lock_rel)(mPerfLockHandle); + } + + if (mDlHandle) { + perf_lock_acq = NULL; + perf_lock_rel = NULL; + + dlclose(mDlHandle); + mDlHandle = NULL; + } + mPerfLockEnable = 0; + LOGD("X"); + } +} + +/*=========================================================================== + * FUNCTION : isTimerReset + * + * DESCRIPTION: Check if timout duration is reached + * + * PARAMETERS : None + * + * RETURN : true if timeout reached + * false if timeout not reached + * + *==========================================================================*/ +bool QCameraPerfLock::isTimerReset() +{ + Mutex::Autolock lock(mLock); + if (mPerfLockEnable && mTimerSet) { + nsecs_t timeDiff = systemTime() - mStartTimeofLock; + if (ns2ms(timeDiff) > (uint32_t)mPerfLockTimeout) { + resetTimer(); + return true; + } + } + return false; +} + +/*=========================================================================== + * FUNCTION : resetTimer + * + * DESCRIPTION: Reset the timer used in timed perf lock + * + * PARAMETERS : None + * + * RETURN : void + * + *==========================================================================*/ +void QCameraPerfLock::resetTimer() +{ + mPerfLockTimeout = 0; + mTimerSet = 0; +} + +/*=========================================================================== + * FUNCTION : start_timer + * + * DESCRIPTION: get the start of the timer + * + * PARAMETERS : + * @timer_val: timer duration in milliseconds + * + * RETURN : int32_t type of status + * NO_ERROR -- success + * none-zero failure code + * + *==========================================================================*/ +void QCameraPerfLock::startTimer(uint32_t timer_val) +{ + mStartTimeofLock = systemTime(); + mTimerSet = 1; + mPerfLockTimeout = timer_val; +} + +/*=========================================================================== + * FUNCTION : lock_acq_timed + * + * DESCRIPTION: Acquire the performance lock for the specified duration. + * If an existing lock timeout has not elapsed, extend the + * lock further for the specified duration + * + * PARAMETERS : + * @timer_val: lock duration + * + * RETURN : int32_t type of status + * NO_ERROR -- success + * none-zero failure code + * + *==========================================================================*/ +int32_t QCameraPerfLock::lock_acq_timed(int32_t timer_val) +{ + int32_t ret = -1; + + LOGD("E"); + Mutex::Autolock lock(mLock); + + if (mPerfLockEnable) { + int32_t perf_lock_params[] = { + ALL_CPUS_PWR_CLPS_DIS, + CPU0_MIN_FREQ_TURBO_MAX, + CPU4_MIN_FREQ_TURBO_MAX + }; + if (mTimerSet) { + nsecs_t curElapsedTime = systemTime() - mStartTimeofLock; + int32_t pendingTimeout = mPerfLockTimeout - ns2ms(curElapsedTime); + timer_val += pendingTimeout; + } + startTimer(timer_val); + + // Disable power hint when acquiring the perf lock + if (mCurrentPowerHintEnable) { + LOGD("mCurrentPowerHintEnable %d" ,mCurrentPowerHintEnable); + powerHintInternal(mCurrentPowerHint, false); + } + + if ((NULL != perf_lock_acq) && (mPerfLockHandleTimed < 0)) { + ret = (*perf_lock_acq)(mPerfLockHandleTimed, timer_val, perf_lock_params, + sizeof(perf_lock_params) / sizeof(int32_t)); + LOGD("ret %d", ret); + if (ret < 0) { + LOGE("failed to acquire lock"); + } else { + mPerfLockHandleTimed = ret; + } + } + LOGD("perf_handle_acq %d ", mPerfLockHandleTimed); + } + + LOGD("X"); + return ret; +} + +/*=========================================================================== + * FUNCTION : lock_acq + * + * DESCRIPTION: acquire the performance lock + * + * PARAMETERS : + * None + * + * RETURN : int32_t type of status + * NO_ERROR -- success + * none-zero failure code + * + *==========================================================================*/ +int32_t QCameraPerfLock::lock_acq() +{ + int32_t ret = -1; + + LOGD("E"); + Mutex::Autolock lock(mLock); + + if (mPerfLockEnable) { + int32_t perf_lock_params[] = { + ALL_CPUS_PWR_CLPS_DIS, + CPU0_MIN_FREQ_TURBO_MAX, + CPU4_MIN_FREQ_TURBO_MAX + }; + + // Disable power hint when acquiring the perf lock + if (mCurrentPowerHintEnable) { + powerHintInternal(mCurrentPowerHint, false); + } + + if ((NULL != perf_lock_acq) && (mPerfLockHandle < 0)) { + ret = (*perf_lock_acq)(mPerfLockHandle, ONE_SEC, perf_lock_params, + sizeof(perf_lock_params) / sizeof(int32_t)); + LOGD("ret %d", ret); + if (ret < 0) { + LOGE("failed to acquire lock"); + } else { + mPerfLockHandle = ret; + } + } + LOGD("perf_handle_acq %d ", mPerfLockHandle); + } + + LOGD("X"); + return ret; +} + +/*=========================================================================== + * FUNCTION : lock_rel_timed + * + * DESCRIPTION: release the performance lock + * + * PARAMETERS : + * None + * + * RETURN : int32_t type of status + * NO_ERROR -- success + * none-zero failure code + * + *==========================================================================*/ +int32_t QCameraPerfLock::lock_rel_timed() +{ + int ret = -1; + Mutex::Autolock lock(mLock); + if (mPerfLockEnable) { + LOGD("E"); + if (mPerfLockHandleTimed < 0) { + LOGW("mPerfLockHandle < 0,check if lock is acquired"); + return ret; + } + LOGD("perf_handle_rel %d ", mPerfLockHandleTimed); + + if ((NULL != perf_lock_rel) && (0 <= mPerfLockHandleTimed)) { + ret = (*perf_lock_rel)(mPerfLockHandleTimed); + if (ret < 0) { + LOGE("failed to release lock"); + } + mPerfLockHandleTimed = -1; + resetTimer(); + } + + if ((mCurrentPowerHintEnable == 1) && (mTimerSet == 0)) { + powerHintInternal(mCurrentPowerHint, mCurrentPowerHintEnable); + } + LOGD("X"); + } + return ret; +} + +/*=========================================================================== + * FUNCTION : lock_rel + * + * DESCRIPTION: release the performance lock + * + * PARAMETERS : + * None + * + * RETURN : int32_t type of status + * NO_ERROR -- success + * none-zero failure code + * + *==========================================================================*/ +int32_t QCameraPerfLock::lock_rel() +{ + int ret = -1; + Mutex::Autolock lock(mLock); + if (mPerfLockEnable) { + LOGD("E"); + if (mPerfLockHandle < 0) { + LOGW("mPerfLockHandle < 0,check if lock is acquired"); + return ret; + } + LOGD("perf_handle_rel %d ", mPerfLockHandle); + + if ((NULL != perf_lock_rel) && (0 <= mPerfLockHandle)) { + ret = (*perf_lock_rel)(mPerfLockHandle); + if (ret < 0) { + LOGE("failed to release lock"); + } + mPerfLockHandle = -1; + } + + if (mCurrentPowerHintEnable == 1) { + powerHintInternal(mCurrentPowerHint, mCurrentPowerHintEnable); + } + LOGD("X"); + } + return ret; +} + +/*=========================================================================== + * FUNCTION : powerHintInternal + * + * DESCRIPTION: Sets the requested power hint and state to power HAL. + * + * PARAMETERS : + * hint : Power hint + * enable : Enable power hint if set to 1. Disable if set to 0. + * RETURN : void + * + *==========================================================================*/ +void QCameraPerfLock::powerHintInternal(power_hint_t hint, bool enable) +{ +#ifdef HAS_MULTIMEDIA_HINTS + if (m_pPowerModule != NULL) { + if (enable == true) { + m_pPowerModule->powerHint(m_pPowerModule, hint, (void *)"state=1"); + } else { + m_pPowerModule->powerHint(m_pPowerModule, hint, (void *)"state=0"); + } + } +#endif +} + +/*=========================================================================== + * FUNCTION : powerHint + * + * DESCRIPTION: Updates the list containing active/enabled power hints. + * If needed, calls the internal powerHint function with + * requested power hint and state. + * PARAMETERS : + * hint : Power hint + * enable : Enable power hint if set to 1. Disable if set to 0. + * RETURN : void + * + *==========================================================================*/ +void QCameraPerfLock::powerHint(power_hint_t hint, bool enable) +{ +#ifdef HAS_MULTIMEDIA_HINTS + if (enable == true) { + if ((hint != mCurrentPowerHint) || (enable != mCurrentPowerHintEnable)) { + // Disable the current active power hint + if (mCurrentPowerHintEnable == true) { + powerHintInternal(mCurrentPowerHint, false); + } + // Push the new power hint at the head of the active power hint list + mActivePowerHints.push_front(hint); + + // Set the new power hint + mCurrentPowerHint = hint; + mCurrentPowerHintEnable = enable; + powerHintInternal(hint, enable); + } + } else { + // Remove the power hint from the list + for (List<power_hint_t>::iterator it = mActivePowerHints.begin(); + it != mActivePowerHints.end(); ++it) { + if (*it == hint) { + if (it != mActivePowerHints.begin()) { + LOGW("Request to remove the previous power hint: %d instead of " + "currently active power hint: %d", static_cast<int>(hint), + static_cast<int>(mCurrentPowerHint)); + } + mActivePowerHints.erase(it); + break; + } + } + + if (hint == mCurrentPowerHint) { + // Disable the power hint + powerHintInternal(hint, false); + + // If the active power hint list is not empty, + // restore the previous power hint from the head of the list + if (mActivePowerHints.empty() == false) { + mCurrentPowerHint = *mActivePowerHints.begin(); + mCurrentPowerHintEnable = true; + powerHintInternal(mCurrentPowerHint, true); + } else { + mCurrentPowerHint = static_cast<power_hint_t>(0); + mCurrentPowerHintEnable = false; + } + } + } +#endif +} + +}; // namespace qcamera |