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
serviceDiedqcamera::PowerHalDeathRecipient62 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.
getPowerHalLocked()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 *==========================================================================*/
QCameraPerfLockMgr()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 *==========================================================================*/
~QCameraPerfLockMgr()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 *==========================================================================*/
acquirePerfLock(PerfLockEnum perfLockType,uint32_t timer)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 *==========================================================================*/
acquirePerfLockIfExpired(PerfLockEnum perfLockType,uint32_t timer)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 *==========================================================================*/
releasePerfLock(PerfLockEnum perfLockType)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 *==========================================================================*/
powerHintInternal(PerfLockEnum perfLockType,PowerHint powerHint,int32_t time_out)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 *==========================================================================*/
create(PerfLockEnum perfLockType)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 *==========================================================================*/
QCameraPerfLock(PerfLockEnum perfLockType,QCameraPerfLockIntf * perfLockIntf)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 *==========================================================================*/
~QCameraPerfLock()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 *==========================================================================*/
isTimedOut()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 *==========================================================================*/
restartTimer(uint32_t timer)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 *==========================================================================*/
acquirePerfLock(bool forceReaquirePerfLock,uint32_t timer)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::CAMERA_STREAMING, 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_SHOT, 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 *==========================================================================*/
releasePerfLock()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::CAMERA_STREAMING, 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_SHOT, 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 *==========================================================================*/
powerHintInternal(PowerHint powerHint,int32_t time_out)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 *==========================================================================*/
createSingleton()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 *==========================================================================*/
deleteInstance()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 *==========================================================================*/
~QCameraPerfLockIntf()721 QCameraPerfLockIntf::~QCameraPerfLockIntf()
722 {
723 if (mDlHandle) {
724 dlclose(mDlHandle);
725 }
726 }
727
powerHint(PowerHint hint,int32_t data)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