aboutsummaryrefslogtreecommitdiff
path: root/camera/QCamera2/util/QCameraPerf.cpp
diff options
context:
space:
mode:
authorPrateek Chaubey <chaubeyprateek@gmail.com>2018-01-07 20:55:14 +0530
committerDavide Garberi <dade.garberi@gmail.com>2018-01-19 14:09:15 +0100
commit6616278131edd80a12545085e06ee6b0e0a0a788 (patch)
tree0aef88ed11809a9d67f6abe4dc2ff782a14737e2 /camera/QCamera2/util/QCameraPerf.cpp
parentcc4ccf34871da343111bf68d16ba4e4c67cac1dc (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.cpp545
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