| /* 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> |
| #include <utils/Errors.h> |
| |
| // System dependencies |
| #include <stdlib.h> |
| #include <dlfcn.h> |
| #include <utils/Timers.h> |
| // Camera dependencies |
| #include "QCameraPerf.h" |
| #include "QCameraTrace.h" |
| |
| #include <android-base/properties.h> |
| |
| extern "C" { |
| #include "mm_camera_dbg.h" |
| } |
| |
| namespace qcamera { |
| |
| using android::hidl::base::V1_0::IBase; |
| using android::hardware::hidl_death_recipient; |
| |
| static std::mutex gPowerHalMutex; |
| static sp<IPower> gPowerHal = nullptr; |
| static void getPowerHalLocked(); |
| |
| // struct PowerHalDeathRecipient; |
| struct PowerHalDeathRecipient : virtual public hidl_death_recipient { |
| // hidl_death_recipient interface |
| virtual void serviceDied(uint64_t, const wp<IBase>&) override { |
| std::lock_guard<std::mutex> lock(gPowerHalMutex); |
| ALOGE("PowerHAL just died"); |
| gPowerHal = nullptr; |
| getPowerHalLocked(); |
| } |
| }; |
| |
| sp<PowerHalDeathRecipient> gPowerHalDeathRecipient = nullptr; |
| |
| // The caller must be holding gPowerHalMutex. |
| static void getPowerHalLocked() { |
| if (gPowerHal != nullptr) { |
| return; |
| } |
| |
| gPowerHal = IPower::getService(); |
| |
| if (gPowerHal == nullptr) { |
| ALOGE("Unable to get Power service."); |
| } else { |
| if (gPowerHalDeathRecipient == nullptr) { |
| gPowerHalDeathRecipient = new PowerHalDeathRecipient(); |
| } |
| hardware::Return<bool> linked = gPowerHal->linkToDeath( |
| gPowerHalDeathRecipient, 0x451F /* cookie */); |
| if (!linked.isOk()) { |
| ALOGE("Transaction error in linking to PowerHAL death: %s", |
| linked.description().c_str()); |
| gPowerHal = nullptr; |
| } else if (!linked) { |
| ALOGW("Unable to link to PowerHal death notifications"); |
| gPowerHal = nullptr; |
| } else { |
| ALOGD("Link to death notification successful"); |
| } |
| } |
| } |
| |
| typedef enum { |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0 = 0x40800000, |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_1 = 0x40800010, |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_2 = 0x40800020, |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_3 = 0x40800030, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40800100, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40800110, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40800120, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40800130, |
| |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0 = 0x40804000, |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_1 = 0x40804010, |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_2 = 0x40804020, |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_3 = 0x40804030, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40804100, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40804110, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40804120, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40804130, |
| |
| MPCTLV3_MIN_ONLINE_CPU_CLUSTER_BIG = 0x41000000, |
| MPCTLV3_MIN_ONLINE_CPU_CLUSTER_LITTLE = 0x41000100, |
| MPCTLV3_MAX_ONLINE_CPU_CLUSTER_BIG = 0x41004000, |
| MPCTLV3_MAX_ONLINE_CPU_CLUSTER_LITTLE = 0x41004100, |
| |
| MPCTLV3_ALL_CPUS_PWR_CLPS_DIS = 0x40400000, |
| MPCTLV3_CPUBW_HWMON_MIN_FREQ = 0x41800000, |
| MPCTLV3_CPUBW_HWMON_HYST_OPT = 0x4180C000 |
| } perf_lock_params; |
| |
| |
| static int32_t perfLockParamsOpenCamera[] = { |
| // Disable power collapse and set CPU cloks to turbo |
| MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF |
| }; |
| |
| static int32_t perfLockParamsCloseCamera[] = { |
| // Disable power collapse and set CPU cloks to turbo |
| MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF |
| }; |
| |
| static int32_t perfLockParamsStartPreview[] = { |
| // Disable power collapse and set CPU cloks to turbo |
| MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF |
| }; |
| |
| static int32_t perfLockParamsTakeSnapshot[] = { |
| // Disable power collapse and set CPU cloks to turbo |
| MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, |
| MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, |
| MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, |
| MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, |
| MPCTLV3_CPUBW_HWMON_HYST_OPT, 0x0, |
| MPCTLV3_CPUBW_HWMON_MIN_FREQ, 0x8C |
| }; |
| |
| PerfLockInfo QCameraPerfLock::mPerfLockInfo[] = { |
| { //PERF_LOCK_OPEN_CAMERA |
| perfLockParamsOpenCamera, |
| sizeof(perfLockParamsOpenCamera)/sizeof(int32_t) }, |
| { //PERF_LOCK_CLOSE_CAMERA |
| perfLockParamsCloseCamera, |
| sizeof(perfLockParamsCloseCamera)/sizeof(int32_t) }, |
| { //PERF_LOCK_START_PREVIEW |
| perfLockParamsStartPreview, |
| sizeof(perfLockParamsStartPreview)/sizeof(int32_t) }, |
| { //PERF_LOCK_TAKE_SNAPSHOT |
| perfLockParamsTakeSnapshot, |
| sizeof(perfLockParamsTakeSnapshot)/sizeof(int32_t) }, |
| { //PERF_LOCK_POWERHINT_PREVIEW |
| NULL, 0}, |
| { //PERF_LOCK_POWERHINT_ENCODE |
| NULL, 0} |
| }; |
| |
| Mutex QCameraPerfLockIntf::mMutex; |
| QCameraPerfLockIntf* QCameraPerfLockIntf::mInstance = NULL; |
| |
| |
| /*=========================================================================== |
| * FUNCTION : QCameraPerfLockMgr constructor |
| * |
| * DESCRIPTION: Initialize the perf locks |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| QCameraPerfLockMgr::QCameraPerfLockMgr() : |
| mState(LOCK_MGR_STATE_UNINITIALIZED) |
| { |
| for (int i = 0; i < PERF_LOCK_COUNT; ++i) { |
| mPerfLock[i] = QCameraPerfLock::create((PerfLockEnum)i); |
| |
| if (mPerfLock[i] == NULL) { |
| mState = LOCK_MGR_STATE_ERROR; |
| LOGE("Could not allocate perf locks"); |
| |
| // Set the remaining perf locks to NULL |
| for (int j = i+1; j < PERF_LOCK_COUNT; ++j) { |
| mPerfLock[j] = NULL; |
| } |
| return; |
| } |
| } |
| mState = LOCK_MGR_STATE_READY; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : QCameraPerfLockMgr destructor |
| * |
| * DESCRIPTION: class destructor |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| QCameraPerfLockMgr::~QCameraPerfLockMgr() |
| { |
| for (int i = 0; i < PERF_LOCK_COUNT; ++i) { |
| if (mPerfLock[i]) { |
| delete mPerfLock[i]; |
| } |
| } |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : acquirePerfLock |
| * |
| * DESCRIPTION: Call acquirePerfLock function for the requested perf lock |
| * |
| * PARAMETERS : |
| * @perfLockType: Perf lock enum |
| * @timer: Timer value in ms |
| * |
| * RETURN : true on success |
| * false on failure |
| *==========================================================================*/ |
| bool QCameraPerfLockMgr::acquirePerfLock( |
| PerfLockEnum perfLockType, |
| uint32_t timer) |
| { |
| bool ret = false; |
| if ((mState == LOCK_MGR_STATE_READY) && |
| isValidPerfLockEnum(perfLockType)) { |
| ret = mPerfLock[perfLockType]->acquirePerfLock(true, timer); |
| } |
| return ret; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : acquirePerfLockIfExpired |
| * |
| * DESCRIPTION: Call acquirePerfLock function for the requested perf lock |
| * |
| * PARAMETERS : |
| * @perfLockType: Type of perf lock |
| * @timer: Timer value in ms |
| * |
| * RETURN : true on success |
| * false on failure |
| *==========================================================================*/ |
| bool QCameraPerfLockMgr::acquirePerfLockIfExpired( |
| PerfLockEnum perfLockType, |
| uint32_t timer) |
| { |
| bool ret = false; |
| if ((mState == LOCK_MGR_STATE_READY) && |
| isValidPerfLockEnum(perfLockType)) { |
| ret = mPerfLock[perfLockType]->acquirePerfLock(false, timer); |
| } |
| return ret; |
| |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : releasePerfLock |
| * |
| * DESCRIPTION: Call releasePerfLock function for the requested perf lock |
| * |
| * PARAMETERS : |
| * @perfLockType: Enum of perf lock |
| * |
| * RETURN : true on success |
| * false on failure |
| *==========================================================================*/ |
| bool QCameraPerfLockMgr::releasePerfLock( |
| PerfLockEnum perfLockType) |
| { |
| bool ret = false; |
| if ((mState == LOCK_MGR_STATE_READY) && |
| isValidPerfLockEnum(perfLockType)) { |
| ret = mPerfLock[perfLockType]->releasePerfLock(); |
| } |
| return ret; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : powerHintInternal |
| * |
| * DESCRIPTION: Calls the appropriate perf lock's powerHintInternal function |
| * |
| * PARAMETERS : |
| * @perfLockType: Type of perf lock |
| * @hint : Power hint |
| * @enable : Enable power hint if set to 1. Disable if set to 0. |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| void QCameraPerfLockMgr::powerHintInternal( |
| PerfLockEnum perfLockType, |
| PowerHint powerHint, |
| int32_t time_out) |
| { |
| if ((mState == LOCK_MGR_STATE_READY) && |
| isValidPerfLockEnum(perfLockType)) { |
| mPerfLock[perfLockType]->powerHintInternal(powerHint, time_out); |
| } |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : create |
| * |
| * DESCRIPTION: This is a static method to create perf lock object. It calls |
| * protected constructor of the class and only returns a valid object |
| * if it can successfully initialize the perf lock. |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : QCameraPerfLock object pointer on success |
| * NULL on failure |
| * |
| *==========================================================================*/ |
| QCameraPerfLock* QCameraPerfLock::create( |
| PerfLockEnum perfLockType) |
| { |
| QCameraPerfLock *perfLock = NULL; |
| |
| if (perfLockType < PERF_LOCK_COUNT) { |
| QCameraPerfLockIntf *perfLockIntf = QCameraPerfLockIntf::createSingleton(); |
| if (perfLockIntf) { |
| perfLock = new QCameraPerfLock(perfLockType, perfLockIntf); |
| } |
| } |
| return perfLock; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : QCameraPerfLock constructor |
| * |
| * DESCRIPTION: Initialize member variables |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| QCameraPerfLock::QCameraPerfLock( |
| PerfLockEnum perfLockType, |
| QCameraPerfLockIntf *perfLockIntf) : |
| mHandle(0), |
| mRefCount(0), |
| mTimeOut(0), |
| mPerfLockType(perfLockType), |
| mPerfLockIntf(perfLockIntf) |
| { |
| mIsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false); |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : QCameraPerfLock destructor |
| * |
| * DESCRIPTION: class destructor |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| QCameraPerfLock::~QCameraPerfLock() |
| { |
| if (mHandle > 0) { |
| (*mPerfLockIntf->perfLockRel())(mHandle); |
| } |
| QCameraPerfLockIntf::deleteInstance(); |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : isTimedOut |
| * |
| * DESCRIPTION: Check if the perf lock is timed out |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : boolean indicating if the perf lock is timed out |
| * |
| *==========================================================================*/ |
| bool QCameraPerfLock::isTimedOut() |
| { |
| if (mTimeOut && (systemTime() > mTimeOut)) { |
| return true; |
| } |
| return false; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : restartTimer |
| * |
| * DESCRIPTION: Restart the timer for the duration specified |
| * |
| * PARAMETERS : |
| * @timer : timer duration in milliseconds |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| void inline QCameraPerfLock::restartTimer( |
| uint32_t timer) |
| { |
| if (timer > 0) { |
| mTimeOut = systemTime() + ms2ns(timer); |
| } |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : acquirePerfLock |
| * |
| * DESCRIPTION: Acquires the perf lock for the duration specified. Do not acquire |
| * the perf lock is reacquire flag is set to false provided the perf |
| * lock is already acquired. |
| * |
| * PARAMETERS : |
| * @forceReaquirePerfLock: Reacquire |
| * @timer : Duration of the perf lock |
| * |
| * RETURN : true on success |
| * false on failure |
| * |
| *==========================================================================*/ |
| bool QCameraPerfLock::acquirePerfLock( |
| bool forceReaquirePerfLock, |
| uint32_t timer) |
| { |
| bool ret = true; |
| Mutex::Autolock lock(mMutex); |
| |
| switch (mPerfLockType) { |
| case PERF_LOCK_POWERHINT_PREVIEW: |
| case PERF_LOCK_POWERHINT_ENCODE: |
| powerHintInternal(PowerHint::VIDEO_ENCODE, true); |
| return true; |
| case PERF_LOCK_OPEN_CAMERA: |
| case PERF_LOCK_CLOSE_CAMERA: |
| powerHintInternal(PowerHint::CAMERA_LAUNCH, timer); |
| return true; |
| case PERF_LOCK_START_PREVIEW: |
| powerHintInternal(PowerHint::CAMERA_STREAMING, timer); |
| return true; |
| case PERF_LOCK_TAKE_SNAPSHOT: |
| powerHintInternal(PowerHint::CAMERA_SHOT, timer); |
| return true; |
| default: |
| LOGE("Unknown powerhint %d",(int)mPerfLockType); |
| return false; |
| } |
| |
| if (!mIsPerfdEnabled) return ret; |
| |
| if (isTimedOut()) { |
| mHandle = 0; |
| mRefCount = 0; |
| } |
| |
| if ((mRefCount == 0) || forceReaquirePerfLock) { |
| mHandle = (*mPerfLockIntf->perfLockAcq())( |
| mHandle, timer, |
| mPerfLockInfo[mPerfLockType].perfLockParams, |
| mPerfLockInfo[mPerfLockType].perfLockParamsCount); |
| |
| if (mHandle > 0) { |
| ++mRefCount; |
| restartTimer(timer); |
| LOGD("perfLockHandle %d, updated refCount: %d, perfLockType: %d", |
| mHandle, mRefCount, mPerfLockType); |
| } else { |
| LOGE("Failed to acquire the perf lock"); |
| ret = false; |
| } |
| } else { |
| LOGD("Perf lock already acquired, not re-aquiring"); |
| } |
| |
| return ret; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : releasePerfLock |
| * |
| * DESCRIPTION: Releases the perf lock |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : true on success |
| * false on failure |
| * |
| *==========================================================================*/ |
| bool QCameraPerfLock::releasePerfLock() |
| { |
| bool ret = true; |
| Mutex::Autolock lock(mMutex); |
| |
| switch (mPerfLockType) { |
| case PERF_LOCK_POWERHINT_PREVIEW: |
| case PERF_LOCK_POWERHINT_ENCODE: |
| powerHintInternal(PowerHint::VIDEO_ENCODE, false); |
| return true; |
| case PERF_LOCK_OPEN_CAMERA: |
| case PERF_LOCK_CLOSE_CAMERA: |
| powerHintInternal(PowerHint::CAMERA_LAUNCH, false); |
| return true; |
| case PERF_LOCK_START_PREVIEW: |
| powerHintInternal(PowerHint::CAMERA_STREAMING, false); |
| return true; |
| case PERF_LOCK_TAKE_SNAPSHOT: |
| powerHintInternal(PowerHint::CAMERA_SHOT, false); |
| return true; |
| default: |
| LOGE("Unknown powerhint %d",(int)mPerfLockType); |
| return false; |
| } |
| |
| if (!mIsPerfdEnabled) return ret; |
| |
| if (mHandle > 0) { |
| LOGD("perfLockHandle %d, refCount: %d, perfLockType: %d", |
| mHandle, mRefCount, mPerfLockType); |
| |
| if (isTimedOut()) { |
| mHandle = 0; |
| mRefCount = 0; |
| } else if (--mRefCount == 0) { |
| int32_t rc = (*mPerfLockIntf->perfLockRel())(mHandle); |
| mHandle = 0; |
| mTimeOut = 0; |
| if (rc < 0) { |
| LOGE("Failed to release the perf lock"); |
| ret = false; |
| } |
| } |
| } else { |
| LOGW("Perf lock %d either not acquired or already released", mPerfLockType); |
| } |
| |
| 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( |
| PowerHint powerHint, |
| int32_t time_out) |
| { |
| #ifdef HAS_MULTIMEDIA_HINTS |
| if (!mPerfLockIntf->powerHint(powerHint, time_out)) { |
| LOGE("Send powerhint to PowerHal failed"); |
| } |
| #endif |
| } |
| |
| |
| |
| /*=========================================================================== |
| * FUNCTION : createSingleton |
| * |
| * DESCRIPTION: Open the perf lock library, query the function pointers and |
| * create a singleton object upon success |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : QCameraPerfLockIntf object pointer on success |
| * NULL on failure |
| * |
| *==========================================================================*/ |
| QCameraPerfLockIntf* QCameraPerfLockIntf::createSingleton() |
| { |
| bool error = true; |
| Mutex::Autolock lock(mMutex); |
| |
| if (mInstance == NULL) { |
| // Open perflock library and query for the function pointers |
| uint32_t perfLockEnable = 0; |
| char value[PROPERTY_VALUE_MAX]; |
| |
| property_get("persist.camera.perflock.enable", value, "1"); |
| perfLockEnable = atoi(value); |
| |
| if (perfLockEnable) { |
| mInstance = new QCameraPerfLockIntf(); |
| if (mInstance) { |
| #ifdef HAS_MULTIMEDIA_HINTS |
| std::lock_guard<std::mutex> lock(gPowerHalMutex); |
| getPowerHalLocked(); |
| if (gPowerHal == nullptr) { |
| ALOGE("Couldn't load PowerHAL module"); |
| } |
| else |
| #endif |
| { |
| /* Retrieve the name of the vendor extension library */ |
| void *dlHandle = NULL; |
| if ((property_get("ro.vendor.extension_library", value, NULL) > 0) && |
| (dlHandle = dlopen(value, RTLD_NOW | RTLD_LOCAL))) { |
| |
| perfLockAcquire pLockAcq = (perfLockAcquire)dlsym(dlHandle, "perf_lock_acq"); |
| perfLockRelease pLockRel = (perfLockRelease)dlsym(dlHandle, "perf_lock_rel"); |
| |
| if (pLockAcq && pLockRel) { |
| mInstance->mDlHandle = dlHandle; |
| mInstance->mPerfLockAcq = pLockAcq; |
| mInstance->mPerfLockRel = pLockRel; |
| error = false; |
| } else { |
| LOGE("Failed to link the symbols- perf_lock_acq, perf_lock_rel"); |
| bool IsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false); |
| if (!IsPerfdEnabled) { |
| mInstance->mDlHandle = nullptr; |
| mInstance->mPerfLockAcq = nullptr; |
| mInstance->mPerfLockRel = nullptr; |
| error = false; |
| } |
| } |
| } else { |
| LOGE("Unable to load lib: %s", value); |
| } |
| } |
| if (error && mInstance) { |
| delete mInstance; |
| mInstance = NULL; |
| } |
| } |
| } |
| } |
| |
| if (mInstance) { |
| ++(mInstance->mRefCount); |
| } |
| |
| return mInstance; |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : deleteInstance |
| * |
| * DESCRIPTION: Delete the object if refCount is 0 |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| void QCameraPerfLockIntf::deleteInstance() |
| { |
| Mutex::Autolock lock(mMutex); |
| |
| if (mInstance && (--(mInstance->mRefCount) == 0)) { |
| delete mInstance; |
| mInstance = NULL; |
| } |
| } |
| |
| |
| /*=========================================================================== |
| * FUNCTION : QCameraPerfLockIntf destructor |
| * |
| * DESCRIPTION: class destructor |
| * |
| * PARAMETERS : None |
| * |
| * RETURN : void |
| * |
| *==========================================================================*/ |
| QCameraPerfLockIntf::~QCameraPerfLockIntf() |
| { |
| if (mDlHandle) { |
| dlclose(mDlHandle); |
| } |
| } |
| |
| bool QCameraPerfLockIntf::powerHint(PowerHint hint, int32_t data) { |
| std::lock_guard<std::mutex> lock(gPowerHalMutex); |
| getPowerHalLocked(); |
| if (gPowerHal == nullptr) { |
| ALOGE("Couldn't do powerHint because of HAL error."); |
| return false; |
| } |
| auto ret = gPowerHal->powerHintAsync_1_2(hint, data); |
| if (!ret.isOk()) { |
| ALOGE("powerHint failed error: %s", ret.description().c_str()); |
| } |
| return ret.isOk(); |
| } |
| |
| }; // namespace qcamera |