Home | History | Annotate | Download | only in util
      1 /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are
      5 * met:
      6 *     * Redistributions of source code must retain the above copyright
      7 *       notice, this list of conditions and the following disclaimer.
      8 *     * Redistributions in binary form must reproduce the above
      9 *       copyright notice, this list of conditions and the following
     10 *       disclaimer in the documentation and/or other materials provided
     11 *       with the distribution.
     12 *     * Neither the name of The Linux Foundation nor the names of its
     13 *       contributors may be used to endorse or promote products derived
     14 *       from this software without specific prior written permission.
     15 *
     16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 *
     28 */
     29 
     30 #define LOG_TAG "QCameraPerf"
     31 
     32 // To remove
     33 #include <cutils/properties.h>
     34 #include <utils/Errors.h>
     35 
     36 // System dependencies
     37 #include <stdlib.h>
     38 #include <dlfcn.h>
     39 #include <utils/Timers.h>
     40 // Camera dependencies
     41 #include "QCameraPerf.h"
     42 #include "QCameraTrace.h"
     43 
     44 #include <android-base/properties.h>
     45 
     46 extern "C" {
     47 #include "mm_camera_dbg.h"
     48 }
     49 
     50 namespace qcamera {
     51 
     52 typedef enum {
     53     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0     = 0x40800000,
     54     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_1     = 0x40800010,
     55     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_2     = 0x40800020,
     56     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_3     = 0x40800030,
     57     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0  = 0x40800100,
     58     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_1  = 0x40800110,
     59     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_2  = 0x40800120,
     60     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_3  = 0x40800130,
     61 
     62     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0     = 0x40804000,
     63     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_1     = 0x40804010,
     64     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_2     = 0x40804020,
     65     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_3     = 0x40804030,
     66     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0  = 0x40804100,
     67     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_1  = 0x40804110,
     68     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_2  = 0x40804120,
     69     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_3  = 0x40804130,
     70 
     71     MPCTLV3_MIN_ONLINE_CPU_CLUSTER_BIG      = 0x41000000,
     72     MPCTLV3_MIN_ONLINE_CPU_CLUSTER_LITTLE   = 0x41000100,
     73     MPCTLV3_MAX_ONLINE_CPU_CLUSTER_BIG      = 0x41004000,
     74     MPCTLV3_MAX_ONLINE_CPU_CLUSTER_LITTLE   = 0x41004100,
     75 
     76     MPCTLV3_ALL_CPUS_PWR_CLPS_DIS           = 0x40400000,
     77     MPCTLV3_CPUBW_HWMON_MIN_FREQ            = 0x41800000,
     78     MPCTLV3_CPUBW_HWMON_HYST_OPT            = 0x4180C000
     79 } perf_lock_params;
     80 
     81 
     82 static int32_t perfLockParamsOpenCamera[] = {
     83     // Disable power collapse and set CPU cloks to turbo
     84     MPCTLV3_ALL_CPUS_PWR_CLPS_DIS,          0x1,
     85     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
     86     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
     87     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
     88     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF
     89 };
     90 
     91 static int32_t perfLockParamsCloseCamera[] = {
     92     // Disable power collapse and set CPU cloks to turbo
     93     MPCTLV3_ALL_CPUS_PWR_CLPS_DIS,          0x1,
     94     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
     95     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
     96     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
     97     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF
     98 };
     99 
    100 static int32_t perfLockParamsStartPreview[] = {
    101     // Disable power collapse and set CPU cloks to turbo
    102     MPCTLV3_ALL_CPUS_PWR_CLPS_DIS,          0x1,
    103     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
    104     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
    105     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
    106     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF
    107 };
    108 
    109 static int32_t perfLockParamsTakeSnapshot[] = {
    110     // Disable power collapse and set CPU cloks to turbo
    111     MPCTLV3_ALL_CPUS_PWR_CLPS_DIS,          0x1,
    112     MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
    113     MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0,    0xFFF,
    114     MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
    115     MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF,
    116     MPCTLV3_CPUBW_HWMON_HYST_OPT,           0x0,
    117     MPCTLV3_CPUBW_HWMON_MIN_FREQ,           0x8C
    118 };
    119 
    120 PerfLockInfo QCameraPerfLock::mPerfLockInfo[] = {
    121     { //PERF_LOCK_OPEN_CAMERA
    122       perfLockParamsOpenCamera,
    123       sizeof(perfLockParamsOpenCamera)/sizeof(int32_t) },
    124     { //PERF_LOCK_CLOSE_CAMERA
    125       perfLockParamsCloseCamera,
    126       sizeof(perfLockParamsCloseCamera)/sizeof(int32_t) },
    127     { //PERF_LOCK_START_PREVIEW
    128       perfLockParamsStartPreview,
    129       sizeof(perfLockParamsStartPreview)/sizeof(int32_t) },
    130     { //PERF_LOCK_TAKE_SNAPSHOT
    131       perfLockParamsTakeSnapshot,
    132       sizeof(perfLockParamsTakeSnapshot)/sizeof(int32_t) },
    133     { //PERF_LOCK_POWERHINT_PREVIEW
    134       NULL, 0},
    135     { //PERF_LOCK_POWERHINT_ENCODE
    136       NULL, 0}
    137     };
    138 
    139 Mutex                QCameraPerfLockIntf::mMutex;
    140 QCameraPerfLockIntf* QCameraPerfLockIntf::mInstance = NULL;
    141 
    142 
    143 /*===========================================================================
    144  * FUNCTION   : QCameraPerfLockMgr constructor
    145  *
    146  * DESCRIPTION: Initialize the perf locks
    147  *
    148  * PARAMETERS : None
    149  *
    150  * RETURN     : void
    151  *
    152  *==========================================================================*/
    153 QCameraPerfLockMgr::QCameraPerfLockMgr() :
    154     mState(LOCK_MGR_STATE_UNINITIALIZED)
    155 {
    156     for (int i = 0; i < PERF_LOCK_COUNT; ++i) {
    157         mPerfLock[i] = QCameraPerfLock::create((PerfLockEnum)i);
    158 
    159         if (mPerfLock[i] == NULL) {
    160             mState = LOCK_MGR_STATE_ERROR;
    161             LOGE("Could not allocate perf locks");
    162 
    163             // Set the remaining perf locks to NULL
    164             for (int j = i+1; j < PERF_LOCK_COUNT; ++j) {
    165                 mPerfLock[j] = NULL;
    166             }
    167             return;
    168         }
    169     }
    170     mState = LOCK_MGR_STATE_READY;
    171 }
    172 
    173 
    174 /*===========================================================================
    175  * FUNCTION   : QCameraPerfLockMgr destructor
    176  *
    177  * DESCRIPTION: class destructor
    178  *
    179  * PARAMETERS : None
    180  *
    181  * RETURN     : void
    182  *
    183  *==========================================================================*/
    184 QCameraPerfLockMgr::~QCameraPerfLockMgr()
    185 {
    186     for (int i = 0; i < PERF_LOCK_COUNT; ++i) {
    187         if (mPerfLock[i]) {
    188             delete mPerfLock[i];
    189         }
    190     }
    191 }
    192 
    193 
    194 /*===========================================================================
    195  * FUNCTION   : acquirePerfLock
    196  *
    197  * DESCRIPTION: Call acquirePerfLock function for the requested perf lock
    198  *
    199  * PARAMETERS :
    200  * @perfLockType: Perf lock enum
    201  * @timer:        Timer value in ms
    202  *
    203  * RETURN     : true  on success
    204  *              false on failure
    205  *==========================================================================*/
    206 bool QCameraPerfLockMgr::acquirePerfLock(
    207         PerfLockEnum perfLockType,
    208         uint32_t     timer)
    209 {
    210     bool ret = false;
    211     if ((mState == LOCK_MGR_STATE_READY) &&
    212         isValidPerfLockEnum(perfLockType)) {
    213         ret = mPerfLock[perfLockType]->acquirePerfLock(true, timer);
    214     }
    215     return ret;
    216 }
    217 
    218 
    219 /*===========================================================================
    220  * FUNCTION   : acquirePerfLockIfExpired
    221  *
    222  * DESCRIPTION: Call acquirePerfLock function for the requested perf lock
    223  *
    224  * PARAMETERS :
    225  * @perfLockType: Type of perf lock
    226  * @timer:        Timer value in ms
    227  *
    228  * RETURN     : true  on success
    229  *              false on failure
    230  *==========================================================================*/
    231 bool QCameraPerfLockMgr::acquirePerfLockIfExpired(
    232         PerfLockEnum perfLockType,
    233         uint32_t     timer)
    234 {
    235     bool ret = false;
    236     if ((mState == LOCK_MGR_STATE_READY) &&
    237         isValidPerfLockEnum(perfLockType)) {
    238         ret = mPerfLock[perfLockType]->acquirePerfLock(false, timer);
    239     }
    240     return ret;
    241 
    242 }
    243 
    244 
    245 /*===========================================================================
    246  * FUNCTION   : releasePerfLock
    247  *
    248  * DESCRIPTION: Call releasePerfLock function for the requested perf lock
    249  *
    250  * PARAMETERS :
    251  * @perfLockType: Enum of perf lock
    252  *
    253  * RETURN     : true  on success
    254  *              false on failure
    255  *==========================================================================*/
    256 bool QCameraPerfLockMgr::releasePerfLock(
    257         PerfLockEnum perfLockType)
    258 {
    259     bool ret = false;
    260     if ((mState == LOCK_MGR_STATE_READY) &&
    261         isValidPerfLockEnum(perfLockType)) {
    262         ret = mPerfLock[perfLockType]->releasePerfLock();
    263     }
    264     return ret;
    265 }
    266 
    267 
    268 /*===========================================================================
    269  * FUNCTION   : powerHintInternal
    270  *
    271  * DESCRIPTION: Calls the appropriate perf lock's powerHintInternal function
    272  *
    273  * PARAMETERS :
    274  * @perfLockType: Type of perf lock
    275  * @hint        : Power hint
    276  * @enable      : Enable power hint if set to 1. Disable if set to 0.
    277  *
    278  * RETURN     : void
    279  *
    280  *==========================================================================*/
    281 void QCameraPerfLockMgr::powerHintInternal(
    282         PerfLockEnum perfLockType,
    283         PowerHint    powerHint,
    284         bool         enable)
    285 {
    286     if ((mState == LOCK_MGR_STATE_READY) &&
    287         isValidPerfLockEnum(perfLockType)) {
    288         mPerfLock[perfLockType]->powerHintInternal(powerHint, enable);
    289     }
    290 }
    291 
    292 
    293 /*===========================================================================
    294  * FUNCTION   : create
    295  *
    296  * DESCRIPTION: This is a static method to create perf lock object. It calls
    297  *              protected constructor of the class and only returns a valid object
    298  *              if it can successfully initialize the perf lock.
    299  *
    300  * PARAMETERS : None
    301  *
    302  * RETURN     : QCameraPerfLock object pointer on success
    303  *              NULL on failure
    304  *
    305  *==========================================================================*/
    306 QCameraPerfLock* QCameraPerfLock::create(
    307         PerfLockEnum perfLockType)
    308 {
    309     QCameraPerfLock *perfLock = NULL;
    310 
    311     if (perfLockType < PERF_LOCK_COUNT) {
    312         QCameraPerfLockIntf *perfLockIntf = QCameraPerfLockIntf::createSingleton();
    313         if (perfLockIntf) {
    314             perfLock = new QCameraPerfLock(perfLockType, perfLockIntf);
    315         }
    316     }
    317     return perfLock;
    318 }
    319 
    320 
    321 /*===========================================================================
    322  * FUNCTION   : QCameraPerfLock constructor
    323  *
    324  * DESCRIPTION: Initialize member variables
    325  *
    326  * PARAMETERS : None
    327  *
    328  * RETURN     : void
    329  *
    330  *==========================================================================*/
    331 QCameraPerfLock::QCameraPerfLock(
    332         PerfLockEnum         perfLockType,
    333         QCameraPerfLockIntf *perfLockIntf) :
    334         mHandle(0),
    335         mRefCount(0),
    336         mTimeOut(0),
    337         mPerfLockType(perfLockType),
    338         mPerfLockIntf(perfLockIntf)
    339 {
    340     mIsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false);
    341 }
    342 
    343 
    344 /*===========================================================================
    345  * FUNCTION   : QCameraPerfLock destructor
    346  *
    347  * DESCRIPTION: class destructor
    348  *
    349  * PARAMETERS : None
    350  *
    351  * RETURN     : void
    352  *
    353  *==========================================================================*/
    354 QCameraPerfLock::~QCameraPerfLock()
    355 {
    356     if (mHandle > 0) {
    357         (*mPerfLockIntf->perfLockRel())(mHandle);
    358     }
    359     QCameraPerfLockIntf::deleteInstance();
    360 }
    361 
    362 
    363 /*===========================================================================
    364  * FUNCTION   : isTimedOut
    365  *
    366  * DESCRIPTION: Check if the perf lock is timed out
    367  *
    368  * PARAMETERS : None
    369  *
    370  * RETURN     : boolean indicating if the perf lock is timed out
    371  *
    372  *==========================================================================*/
    373 bool QCameraPerfLock::isTimedOut()
    374 {
    375     if (mTimeOut && (systemTime() > mTimeOut)) {
    376         return true;
    377     }
    378     return false;
    379 }
    380 
    381 
    382 /*===========================================================================
    383  * FUNCTION   : restartTimer
    384  *
    385  * DESCRIPTION: Restart the timer for the duration specified
    386  *
    387  * PARAMETERS :
    388  *  @timer    : timer duration in milliseconds
    389  *
    390  * RETURN     : void
    391  *
    392  *==========================================================================*/
    393 void inline QCameraPerfLock::restartTimer(
    394         uint32_t timer)
    395 {
    396     if (timer > 0) {
    397         mTimeOut = systemTime() + ms2ns(timer);
    398     }
    399 }
    400 
    401 
    402 /*===========================================================================
    403  * FUNCTION   : acquirePerfLock
    404  *
    405  * DESCRIPTION: Acquires the perf lock for the duration specified. Do not acquire
    406  *              the perf lock is reacquire flag is set to false provided the perf
    407  *              lock is already acquired.
    408  *
    409  * PARAMETERS :
    410  * @forceReaquirePerfLock: Reacquire
    411  * @timer     : Duration of the perf lock
    412  *
    413  * RETURN     : true  on success
    414  *              false on failure
    415  *
    416  *==========================================================================*/
    417 bool QCameraPerfLock::acquirePerfLock(
    418         bool     forceReaquirePerfLock,
    419         uint32_t timer)
    420 {
    421     bool ret = true;
    422     Mutex::Autolock lock(mMutex);
    423 
    424     if ((mPerfLockType == PERF_LOCK_POWERHINT_PREVIEW) ||
    425         (mPerfLockType == PERF_LOCK_POWERHINT_ENCODE)) {
    426         powerHintInternal(PowerHint::VIDEO_ENCODE, true);
    427         return true;
    428     }
    429 
    430     if (!mIsPerfdEnabled) return ret;
    431 
    432     if (isTimedOut()) {
    433         mHandle   = 0;
    434         mRefCount = 0;
    435     }
    436 
    437     if ((mRefCount == 0) || forceReaquirePerfLock) {
    438         mHandle = (*mPerfLockIntf->perfLockAcq())(
    439             mHandle, timer,
    440             mPerfLockInfo[mPerfLockType].perfLockParams,
    441             mPerfLockInfo[mPerfLockType].perfLockParamsCount);
    442 
    443         if (mHandle > 0) {
    444             ++mRefCount;
    445             restartTimer(timer);
    446             LOGD("perfLockHandle %d, updated refCount: %d, perfLockType: %d",
    447                 mHandle, mRefCount, mPerfLockType);
    448         } else {
    449             LOGE("Failed to acquire the perf lock");
    450             ret = false;
    451         }
    452     } else {
    453         LOGD("Perf lock already acquired, not re-aquiring");
    454     }
    455 
    456     return ret;
    457 }
    458 
    459 
    460 /*===========================================================================
    461  * FUNCTION   : releasePerfLock
    462  *
    463  * DESCRIPTION: Releases the perf lock
    464  *
    465  * PARAMETERS : None
    466  *
    467  * RETURN     : true  on success
    468  *              false on failure
    469  *
    470  *==========================================================================*/
    471 bool QCameraPerfLock::releasePerfLock()
    472 {
    473     bool ret = true;
    474     Mutex::Autolock lock(mMutex);
    475 
    476     if ((mPerfLockType == PERF_LOCK_POWERHINT_PREVIEW) ||
    477         (mPerfLockType == PERF_LOCK_POWERHINT_ENCODE)) {
    478         powerHintInternal(PowerHint::VIDEO_ENCODE, false);
    479         return true;
    480     }
    481 
    482     if (!mIsPerfdEnabled) return ret;
    483 
    484     if (mHandle > 0) {
    485         LOGD("perfLockHandle %d, refCount: %d, perfLockType: %d",
    486                     mHandle, mRefCount, mPerfLockType);
    487 
    488         if (isTimedOut()) {
    489             mHandle   = 0;
    490             mRefCount = 0;
    491         } else if (--mRefCount == 0) {
    492             int32_t rc = (*mPerfLockIntf->perfLockRel())(mHandle);
    493             mHandle = 0;
    494             mTimeOut = 0;
    495             if (rc < 0) {
    496                 LOGE("Failed to release the perf lock");
    497                 ret = false;
    498             }
    499         }
    500     } else {
    501         LOGW("Perf lock %d either not acquired or already released", mPerfLockType);
    502     }
    503 
    504     return ret;
    505 }
    506 
    507 
    508 /*===========================================================================
    509  * FUNCTION   : powerHintInternal
    510  *
    511  * DESCRIPTION: Sets the requested power hint and state to power HAL.
    512  *
    513  * PARAMETERS :
    514  * @hint      : Power hint
    515  * @enable    : Enable power hint if set to 1. Disable if set to 0.
    516  *
    517  * RETURN     : void
    518  *
    519  *==========================================================================*/
    520 void QCameraPerfLock::powerHintInternal(
    521         PowerHint    powerHint,
    522         bool         enable)
    523 {
    524 #ifdef HAS_MULTIMEDIA_HINTS
    525     if (!mPerfLockIntf->powerHint(powerHint, enable)) {
    526         LOGE("Send powerhint to PowerHal failed");
    527     }
    528 #endif
    529 }
    530 
    531 
    532 
    533 /*===========================================================================
    534  * FUNCTION   : createSingleton
    535  *
    536  * DESCRIPTION: Open the perf lock library, query the function pointers and
    537  *              create a singleton object upon success
    538  *
    539  * PARAMETERS : None
    540  *
    541  * RETURN     : QCameraPerfLockIntf object pointer on success
    542  *              NULL on failure
    543  *
    544  *==========================================================================*/
    545 QCameraPerfLockIntf* QCameraPerfLockIntf::createSingleton()
    546 {
    547     bool error = true;
    548     Mutex::Autolock lock(mMutex);
    549 
    550     if (mInstance == NULL) {
    551         // Open perflock library and query for the function pointers
    552         uint32_t perfLockEnable = 0;
    553         char value[PROPERTY_VALUE_MAX];
    554 
    555         property_get("persist.camera.perflock.enable", value, "1");
    556         perfLockEnable = atoi(value);
    557 
    558         if (perfLockEnable) {
    559             mInstance = new QCameraPerfLockIntf();
    560             if (mInstance) {
    561                 #ifdef HAS_MULTIMEDIA_HINTS
    562                 mInstance->mPowerHal = IPower::getService();
    563                 if (mInstance->mPowerHal == nullptr) {
    564                     ALOGE("Couldn't load PowerHAL module");
    565                 }
    566                 else
    567                 #endif
    568                 {
    569                     /* Retrieve the name of the vendor extension library */
    570                     void *dlHandle = NULL;
    571                     if ((property_get("ro.vendor.extension_library", value, NULL) > 0) &&
    572                         (dlHandle = dlopen(value, RTLD_NOW | RTLD_LOCAL))) {
    573 
    574                         perfLockAcquire pLockAcq = (perfLockAcquire)dlsym(dlHandle, "perf_lock_acq");
    575                         perfLockRelease pLockRel = (perfLockRelease)dlsym(dlHandle, "perf_lock_rel");
    576 
    577                         if (pLockAcq && pLockRel) {
    578                             mInstance->mDlHandle    = dlHandle;
    579                             mInstance->mPerfLockAcq = pLockAcq;
    580                             mInstance->mPerfLockRel = pLockRel;
    581                             error = false;
    582                         } else {
    583                             LOGE("Failed to link the symbols- perf_lock_acq, perf_lock_rel");
    584                         }
    585                     } else {
    586                         LOGE("Unable to load lib: %s", value);
    587                     }
    588                 }
    589                 if (error && mInstance) {
    590                     delete mInstance;
    591                     mInstance = NULL;
    592                 }
    593             }
    594         }
    595     }
    596 
    597     if (mInstance) {
    598         ++(mInstance->mRefCount);
    599     }
    600 
    601     return mInstance;
    602 }
    603 
    604 
    605 /*===========================================================================
    606  * FUNCTION   : deleteInstance
    607  *
    608  * DESCRIPTION: Delete the object if refCount is 0
    609  *
    610  * PARAMETERS : None
    611  *
    612  * RETURN     : void
    613  *
    614  *==========================================================================*/
    615 void QCameraPerfLockIntf::deleteInstance()
    616 {
    617     Mutex::Autolock lock(mMutex);
    618 
    619     if (mInstance && (--(mInstance->mRefCount) == 0)) {
    620         delete mInstance;
    621         mInstance = NULL;
    622     }
    623 }
    624 
    625 
    626 /*===========================================================================
    627  * FUNCTION   : QCameraPerfLockIntf destructor
    628  *
    629  * DESCRIPTION: class destructor
    630  *
    631  * PARAMETERS : None
    632  *
    633  * RETURN     : void
    634  *
    635  *==========================================================================*/
    636 QCameraPerfLockIntf::~QCameraPerfLockIntf()
    637 {
    638     if (mDlHandle) {
    639         dlclose(mDlHandle);
    640     }
    641 }
    642 
    643 }; // namespace qcamera
    644