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 using android::hidl::base::V1_0::IBase; 53 using android::hardware::hidl_death_recipient; 54 55 static std::mutex gPowerHalMutex; 56 static sp<IPower> gPowerHal = nullptr; 57 static void getPowerHalLocked(); 58 59 // struct PowerHalDeathRecipient; 60 struct PowerHalDeathRecipient : virtual public hidl_death_recipient { 61 // hidl_death_recipient interface 62 virtual void serviceDied(uint64_t, const wp<IBase>&) override { 63 std::lock_guard<std::mutex> lock(gPowerHalMutex); 64 ALOGE("PowerHAL just died"); 65 gPowerHal = nullptr; 66 getPowerHalLocked(); 67 } 68 }; 69 70 sp<PowerHalDeathRecipient> gPowerHalDeathRecipient = nullptr; 71 72 // The caller must be holding gPowerHalMutex. 73 static void getPowerHalLocked() { 74 if (gPowerHal != nullptr) { 75 return; 76 } 77 78 gPowerHal = IPower::getService(); 79 80 if (gPowerHal == nullptr) { 81 ALOGE("Unable to get Power service."); 82 } else { 83 if (gPowerHalDeathRecipient == nullptr) { 84 gPowerHalDeathRecipient = new PowerHalDeathRecipient(); 85 } 86 hardware::Return<bool> linked = gPowerHal->linkToDeath( 87 gPowerHalDeathRecipient, 0x451F /* cookie */); 88 if (!linked.isOk()) { 89 ALOGE("Transaction error in linking to PowerHAL death: %s", 90 linked.description().c_str()); 91 gPowerHal = nullptr; 92 } else if (!linked) { 93 ALOGW("Unable to link to PowerHal death notifications"); 94 gPowerHal = nullptr; 95 } else { 96 ALOGD("Link to death notification successful"); 97 } 98 } 99 } 100 101 typedef enum { 102 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0 = 0x40800000, 103 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_1 = 0x40800010, 104 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_2 = 0x40800020, 105 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_3 = 0x40800030, 106 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40800100, 107 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40800110, 108 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40800120, 109 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40800130, 110 111 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0 = 0x40804000, 112 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_1 = 0x40804010, 113 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_2 = 0x40804020, 114 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_3 = 0x40804030, 115 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0 = 0x40804100, 116 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_1 = 0x40804110, 117 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_2 = 0x40804120, 118 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_3 = 0x40804130, 119 120 MPCTLV3_MIN_ONLINE_CPU_CLUSTER_BIG = 0x41000000, 121 MPCTLV3_MIN_ONLINE_CPU_CLUSTER_LITTLE = 0x41000100, 122 MPCTLV3_MAX_ONLINE_CPU_CLUSTER_BIG = 0x41004000, 123 MPCTLV3_MAX_ONLINE_CPU_CLUSTER_LITTLE = 0x41004100, 124 125 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS = 0x40400000, 126 MPCTLV3_CPUBW_HWMON_MIN_FREQ = 0x41800000, 127 MPCTLV3_CPUBW_HWMON_HYST_OPT = 0x4180C000 128 } perf_lock_params; 129 130 131 static int32_t perfLockParamsOpenCamera[] = { 132 // Disable power collapse and set CPU cloks to turbo 133 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 134 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 135 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 136 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 137 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF 138 }; 139 140 static int32_t perfLockParamsCloseCamera[] = { 141 // Disable power collapse and set CPU cloks to turbo 142 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 143 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 144 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 145 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 146 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF 147 }; 148 149 static int32_t perfLockParamsStartPreview[] = { 150 // Disable power collapse and set CPU cloks to turbo 151 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 152 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 153 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 154 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 155 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF 156 }; 157 158 static int32_t perfLockParamsTakeSnapshot[] = { 159 // Disable power collapse and set CPU cloks to turbo 160 MPCTLV3_ALL_CPUS_PWR_CLPS_DIS, 0x1, 161 MPCTLV3_MAX_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 162 MPCTLV3_MIN_FREQ_CLUSTER_BIG_CORE_0, 0xFFF, 163 MPCTLV3_MAX_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 164 MPCTLV3_MIN_FREQ_CLUSTER_LITTLE_CORE_0, 0xFFF, 165 MPCTLV3_CPUBW_HWMON_HYST_OPT, 0x0, 166 MPCTLV3_CPUBW_HWMON_MIN_FREQ, 0x8C 167 }; 168 169 PerfLockInfo QCameraPerfLock::mPerfLockInfo[] = { 170 { //PERF_LOCK_OPEN_CAMERA 171 perfLockParamsOpenCamera, 172 sizeof(perfLockParamsOpenCamera)/sizeof(int32_t) }, 173 { //PERF_LOCK_CLOSE_CAMERA 174 perfLockParamsCloseCamera, 175 sizeof(perfLockParamsCloseCamera)/sizeof(int32_t) }, 176 { //PERF_LOCK_START_PREVIEW 177 perfLockParamsStartPreview, 178 sizeof(perfLockParamsStartPreview)/sizeof(int32_t) }, 179 { //PERF_LOCK_TAKE_SNAPSHOT 180 perfLockParamsTakeSnapshot, 181 sizeof(perfLockParamsTakeSnapshot)/sizeof(int32_t) }, 182 { //PERF_LOCK_POWERHINT_PREVIEW 183 NULL, 0}, 184 { //PERF_LOCK_POWERHINT_ENCODE 185 NULL, 0} 186 }; 187 188 Mutex QCameraPerfLockIntf::mMutex; 189 QCameraPerfLockIntf* QCameraPerfLockIntf::mInstance = NULL; 190 191 192 /*=========================================================================== 193 * FUNCTION : QCameraPerfLockMgr constructor 194 * 195 * DESCRIPTION: Initialize the perf locks 196 * 197 * PARAMETERS : None 198 * 199 * RETURN : void 200 * 201 *==========================================================================*/ 202 QCameraPerfLockMgr::QCameraPerfLockMgr() : 203 mState(LOCK_MGR_STATE_UNINITIALIZED) 204 { 205 for (int i = 0; i < PERF_LOCK_COUNT; ++i) { 206 mPerfLock[i] = QCameraPerfLock::create((PerfLockEnum)i); 207 208 if (mPerfLock[i] == NULL) { 209 mState = LOCK_MGR_STATE_ERROR; 210 LOGE("Could not allocate perf locks"); 211 212 // Set the remaining perf locks to NULL 213 for (int j = i+1; j < PERF_LOCK_COUNT; ++j) { 214 mPerfLock[j] = NULL; 215 } 216 return; 217 } 218 } 219 mState = LOCK_MGR_STATE_READY; 220 } 221 222 223 /*=========================================================================== 224 * FUNCTION : QCameraPerfLockMgr destructor 225 * 226 * DESCRIPTION: class destructor 227 * 228 * PARAMETERS : None 229 * 230 * RETURN : void 231 * 232 *==========================================================================*/ 233 QCameraPerfLockMgr::~QCameraPerfLockMgr() 234 { 235 for (int i = 0; i < PERF_LOCK_COUNT; ++i) { 236 if (mPerfLock[i]) { 237 delete mPerfLock[i]; 238 } 239 } 240 } 241 242 243 /*=========================================================================== 244 * FUNCTION : acquirePerfLock 245 * 246 * DESCRIPTION: Call acquirePerfLock function for the requested perf lock 247 * 248 * PARAMETERS : 249 * @perfLockType: Perf lock enum 250 * @timer: Timer value in ms 251 * 252 * RETURN : true on success 253 * false on failure 254 *==========================================================================*/ 255 bool QCameraPerfLockMgr::acquirePerfLock( 256 PerfLockEnum perfLockType, 257 uint32_t timer) 258 { 259 bool ret = false; 260 if ((mState == LOCK_MGR_STATE_READY) && 261 isValidPerfLockEnum(perfLockType)) { 262 ret = mPerfLock[perfLockType]->acquirePerfLock(true, timer); 263 } 264 return ret; 265 } 266 267 268 /*=========================================================================== 269 * FUNCTION : acquirePerfLockIfExpired 270 * 271 * DESCRIPTION: Call acquirePerfLock function for the requested perf lock 272 * 273 * PARAMETERS : 274 * @perfLockType: Type of perf lock 275 * @timer: Timer value in ms 276 * 277 * RETURN : true on success 278 * false on failure 279 *==========================================================================*/ 280 bool QCameraPerfLockMgr::acquirePerfLockIfExpired( 281 PerfLockEnum perfLockType, 282 uint32_t timer) 283 { 284 bool ret = false; 285 if ((mState == LOCK_MGR_STATE_READY) && 286 isValidPerfLockEnum(perfLockType)) { 287 ret = mPerfLock[perfLockType]->acquirePerfLock(false, timer); 288 } 289 return ret; 290 291 } 292 293 294 /*=========================================================================== 295 * FUNCTION : releasePerfLock 296 * 297 * DESCRIPTION: Call releasePerfLock function for the requested perf lock 298 * 299 * PARAMETERS : 300 * @perfLockType: Enum of perf lock 301 * 302 * RETURN : true on success 303 * false on failure 304 *==========================================================================*/ 305 bool QCameraPerfLockMgr::releasePerfLock( 306 PerfLockEnum perfLockType) 307 { 308 bool ret = false; 309 if ((mState == LOCK_MGR_STATE_READY) && 310 isValidPerfLockEnum(perfLockType)) { 311 ret = mPerfLock[perfLockType]->releasePerfLock(); 312 } 313 return ret; 314 } 315 316 317 /*=========================================================================== 318 * FUNCTION : powerHintInternal 319 * 320 * DESCRIPTION: Calls the appropriate perf lock's powerHintInternal function 321 * 322 * PARAMETERS : 323 * @perfLockType: Type of perf lock 324 * @hint : Power hint 325 * @enable : Enable power hint if set to 1. Disable if set to 0. 326 * 327 * RETURN : void 328 * 329 *==========================================================================*/ 330 void QCameraPerfLockMgr::powerHintInternal( 331 PerfLockEnum perfLockType, 332 PowerHint powerHint, 333 int32_t time_out) 334 { 335 if ((mState == LOCK_MGR_STATE_READY) && 336 isValidPerfLockEnum(perfLockType)) { 337 mPerfLock[perfLockType]->powerHintInternal(powerHint, time_out); 338 } 339 } 340 341 342 /*=========================================================================== 343 * FUNCTION : create 344 * 345 * DESCRIPTION: This is a static method to create perf lock object. It calls 346 * protected constructor of the class and only returns a valid object 347 * if it can successfully initialize the perf lock. 348 * 349 * PARAMETERS : None 350 * 351 * RETURN : QCameraPerfLock object pointer on success 352 * NULL on failure 353 * 354 *==========================================================================*/ 355 QCameraPerfLock* QCameraPerfLock::create( 356 PerfLockEnum perfLockType) 357 { 358 QCameraPerfLock *perfLock = NULL; 359 360 if (perfLockType < PERF_LOCK_COUNT) { 361 QCameraPerfLockIntf *perfLockIntf = QCameraPerfLockIntf::createSingleton(); 362 if (perfLockIntf) { 363 perfLock = new QCameraPerfLock(perfLockType, perfLockIntf); 364 } 365 } 366 return perfLock; 367 } 368 369 370 /*=========================================================================== 371 * FUNCTION : QCameraPerfLock constructor 372 * 373 * DESCRIPTION: Initialize member variables 374 * 375 * PARAMETERS : None 376 * 377 * RETURN : void 378 * 379 *==========================================================================*/ 380 QCameraPerfLock::QCameraPerfLock( 381 PerfLockEnum perfLockType, 382 QCameraPerfLockIntf *perfLockIntf) : 383 mHandle(0), 384 mRefCount(0), 385 mTimeOut(0), 386 mPerfLockType(perfLockType), 387 mPerfLockIntf(perfLockIntf) 388 { 389 mIsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false); 390 } 391 392 393 /*=========================================================================== 394 * FUNCTION : QCameraPerfLock destructor 395 * 396 * DESCRIPTION: class destructor 397 * 398 * PARAMETERS : None 399 * 400 * RETURN : void 401 * 402 *==========================================================================*/ 403 QCameraPerfLock::~QCameraPerfLock() 404 { 405 if (mHandle > 0) { 406 (*mPerfLockIntf->perfLockRel())(mHandle); 407 } 408 QCameraPerfLockIntf::deleteInstance(); 409 } 410 411 412 /*=========================================================================== 413 * FUNCTION : isTimedOut 414 * 415 * DESCRIPTION: Check if the perf lock is timed out 416 * 417 * PARAMETERS : None 418 * 419 * RETURN : boolean indicating if the perf lock is timed out 420 * 421 *==========================================================================*/ 422 bool QCameraPerfLock::isTimedOut() 423 { 424 if (mTimeOut && (systemTime() > mTimeOut)) { 425 return true; 426 } 427 return false; 428 } 429 430 431 /*=========================================================================== 432 * FUNCTION : restartTimer 433 * 434 * DESCRIPTION: Restart the timer for the duration specified 435 * 436 * PARAMETERS : 437 * @timer : timer duration in milliseconds 438 * 439 * RETURN : void 440 * 441 *==========================================================================*/ 442 void inline QCameraPerfLock::restartTimer( 443 uint32_t timer) 444 { 445 if (timer > 0) { 446 mTimeOut = systemTime() + ms2ns(timer); 447 } 448 } 449 450 451 /*=========================================================================== 452 * FUNCTION : acquirePerfLock 453 * 454 * DESCRIPTION: Acquires the perf lock for the duration specified. Do not acquire 455 * the perf lock is reacquire flag is set to false provided the perf 456 * lock is already acquired. 457 * 458 * PARAMETERS : 459 * @forceReaquirePerfLock: Reacquire 460 * @timer : Duration of the perf lock 461 * 462 * RETURN : true on success 463 * false on failure 464 * 465 *==========================================================================*/ 466 bool QCameraPerfLock::acquirePerfLock( 467 bool forceReaquirePerfLock, 468 uint32_t timer) 469 { 470 bool ret = true; 471 Mutex::Autolock lock(mMutex); 472 473 switch (mPerfLockType) { 474 case PERF_LOCK_POWERHINT_PREVIEW: 475 case PERF_LOCK_POWERHINT_ENCODE: 476 powerHintInternal(PowerHint::VIDEO_ENCODE, true); 477 return true; 478 case PERF_LOCK_OPEN_CAMERA: 479 case PERF_LOCK_CLOSE_CAMERA: 480 powerHintInternal(PowerHint::CAMERA_LAUNCH, timer); 481 return true; 482 case PERF_LOCK_START_PREVIEW: 483 powerHintInternal(PowerHint::CAMERA_STREAMING, timer); 484 return true; 485 case PERF_LOCK_TAKE_SNAPSHOT: 486 powerHintInternal(PowerHint::CAMERA_SHOT, timer); 487 return true; 488 default: 489 LOGE("Unknown powerhint %d",(int)mPerfLockType); 490 return false; 491 } 492 493 if (!mIsPerfdEnabled) return ret; 494 495 if (isTimedOut()) { 496 mHandle = 0; 497 mRefCount = 0; 498 } 499 500 if ((mRefCount == 0) || forceReaquirePerfLock) { 501 mHandle = (*mPerfLockIntf->perfLockAcq())( 502 mHandle, timer, 503 mPerfLockInfo[mPerfLockType].perfLockParams, 504 mPerfLockInfo[mPerfLockType].perfLockParamsCount); 505 506 if (mHandle > 0) { 507 ++mRefCount; 508 restartTimer(timer); 509 LOGD("perfLockHandle %d, updated refCount: %d, perfLockType: %d", 510 mHandle, mRefCount, mPerfLockType); 511 } else { 512 LOGE("Failed to acquire the perf lock"); 513 ret = false; 514 } 515 } else { 516 LOGD("Perf lock already acquired, not re-aquiring"); 517 } 518 519 return ret; 520 } 521 522 523 /*=========================================================================== 524 * FUNCTION : releasePerfLock 525 * 526 * DESCRIPTION: Releases the perf lock 527 * 528 * PARAMETERS : None 529 * 530 * RETURN : true on success 531 * false on failure 532 * 533 *==========================================================================*/ 534 bool QCameraPerfLock::releasePerfLock() 535 { 536 bool ret = true; 537 Mutex::Autolock lock(mMutex); 538 539 switch (mPerfLockType) { 540 case PERF_LOCK_POWERHINT_PREVIEW: 541 case PERF_LOCK_POWERHINT_ENCODE: 542 powerHintInternal(PowerHint::VIDEO_ENCODE, false); 543 return true; 544 case PERF_LOCK_OPEN_CAMERA: 545 case PERF_LOCK_CLOSE_CAMERA: 546 powerHintInternal(PowerHint::CAMERA_LAUNCH, false); 547 return true; 548 case PERF_LOCK_START_PREVIEW: 549 powerHintInternal(PowerHint::CAMERA_STREAMING, false); 550 return true; 551 case PERF_LOCK_TAKE_SNAPSHOT: 552 powerHintInternal(PowerHint::CAMERA_SHOT, false); 553 return true; 554 default: 555 LOGE("Unknown powerhint %d",(int)mPerfLockType); 556 return false; 557 } 558 559 if (!mIsPerfdEnabled) return ret; 560 561 if (mHandle > 0) { 562 LOGD("perfLockHandle %d, refCount: %d, perfLockType: %d", 563 mHandle, mRefCount, mPerfLockType); 564 565 if (isTimedOut()) { 566 mHandle = 0; 567 mRefCount = 0; 568 } else if (--mRefCount == 0) { 569 int32_t rc = (*mPerfLockIntf->perfLockRel())(mHandle); 570 mHandle = 0; 571 mTimeOut = 0; 572 if (rc < 0) { 573 LOGE("Failed to release the perf lock"); 574 ret = false; 575 } 576 } 577 } else { 578 LOGW("Perf lock %d either not acquired or already released", mPerfLockType); 579 } 580 581 return ret; 582 } 583 584 585 /*=========================================================================== 586 * FUNCTION : powerHintInternal 587 * 588 * DESCRIPTION: Sets the requested power hint and state to power HAL. 589 * 590 * PARAMETERS : 591 * @hint : Power hint 592 * @enable : Enable power hint if set to 1. Disable if set to 0. 593 * 594 * RETURN : void 595 * 596 *==========================================================================*/ 597 void QCameraPerfLock::powerHintInternal( 598 PowerHint powerHint, 599 int32_t time_out) 600 { 601 #ifdef HAS_MULTIMEDIA_HINTS 602 if (!mPerfLockIntf->powerHint(powerHint, time_out)) { 603 LOGE("Send powerhint to PowerHal failed"); 604 } 605 #endif 606 } 607 608 609 610 /*=========================================================================== 611 * FUNCTION : createSingleton 612 * 613 * DESCRIPTION: Open the perf lock library, query the function pointers and 614 * create a singleton object upon success 615 * 616 * PARAMETERS : None 617 * 618 * RETURN : QCameraPerfLockIntf object pointer on success 619 * NULL on failure 620 * 621 *==========================================================================*/ 622 QCameraPerfLockIntf* QCameraPerfLockIntf::createSingleton() 623 { 624 bool error = true; 625 Mutex::Autolock lock(mMutex); 626 627 if (mInstance == NULL) { 628 // Open perflock library and query for the function pointers 629 uint32_t perfLockEnable = 0; 630 char value[PROPERTY_VALUE_MAX]; 631 632 property_get("persist.camera.perflock.enable", value, "1"); 633 perfLockEnable = atoi(value); 634 635 if (perfLockEnable) { 636 mInstance = new QCameraPerfLockIntf(); 637 if (mInstance) { 638 #ifdef HAS_MULTIMEDIA_HINTS 639 std::lock_guard<std::mutex> lock(gPowerHalMutex); 640 getPowerHalLocked(); 641 if (gPowerHal == nullptr) { 642 ALOGE("Couldn't load PowerHAL module"); 643 } 644 else 645 #endif 646 { 647 /* Retrieve the name of the vendor extension library */ 648 void *dlHandle = NULL; 649 if ((property_get("ro.vendor.extension_library", value, NULL) > 0) && 650 (dlHandle = dlopen(value, RTLD_NOW | RTLD_LOCAL))) { 651 652 perfLockAcquire pLockAcq = (perfLockAcquire)dlsym(dlHandle, "perf_lock_acq"); 653 perfLockRelease pLockRel = (perfLockRelease)dlsym(dlHandle, "perf_lock_rel"); 654 655 if (pLockAcq && pLockRel) { 656 mInstance->mDlHandle = dlHandle; 657 mInstance->mPerfLockAcq = pLockAcq; 658 mInstance->mPerfLockRel = pLockRel; 659 error = false; 660 } else { 661 LOGE("Failed to link the symbols- perf_lock_acq, perf_lock_rel"); 662 bool IsPerfdEnabled = android::base::GetBoolProperty("persist.camera.perfd.enable", false); 663 if (!IsPerfdEnabled) { 664 mInstance->mDlHandle = nullptr; 665 mInstance->mPerfLockAcq = nullptr; 666 mInstance->mPerfLockRel = nullptr; 667 error = false; 668 } 669 } 670 } else { 671 LOGE("Unable to load lib: %s", value); 672 } 673 } 674 if (error && mInstance) { 675 delete mInstance; 676 mInstance = NULL; 677 } 678 } 679 } 680 } 681 682 if (mInstance) { 683 ++(mInstance->mRefCount); 684 } 685 686 return mInstance; 687 } 688 689 690 /*=========================================================================== 691 * FUNCTION : deleteInstance 692 * 693 * DESCRIPTION: Delete the object if refCount is 0 694 * 695 * PARAMETERS : None 696 * 697 * RETURN : void 698 * 699 *==========================================================================*/ 700 void QCameraPerfLockIntf::deleteInstance() 701 { 702 Mutex::Autolock lock(mMutex); 703 704 if (mInstance && (--(mInstance->mRefCount) == 0)) { 705 delete mInstance; 706 mInstance = NULL; 707 } 708 } 709 710 711 /*=========================================================================== 712 * FUNCTION : QCameraPerfLockIntf destructor 713 * 714 * DESCRIPTION: class destructor 715 * 716 * PARAMETERS : None 717 * 718 * RETURN : void 719 * 720 *==========================================================================*/ 721 QCameraPerfLockIntf::~QCameraPerfLockIntf() 722 { 723 if (mDlHandle) { 724 dlclose(mDlHandle); 725 } 726 } 727 728 bool QCameraPerfLockIntf::powerHint(PowerHint hint, int32_t data) { 729 std::lock_guard<std::mutex> lock(gPowerHalMutex); 730 getPowerHalLocked(); 731 if (gPowerHal == nullptr) { 732 ALOGE("Couldn't do powerHint because of HAL error."); 733 return false; 734 } 735 auto ret = gPowerHal->powerHintAsync_1_2(hint, data); 736 if (!ret.isOk()) { 737 ALOGE("powerHint failed error: %s", ret.description().c_str()); 738 } 739 return ret.isOk(); 740 } 741 742 }; // namespace qcamera 743