You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
784 lines
24 KiB
784 lines
24 KiB
/* 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>
|
|
|
|
#include <aidl/android/hardware/power/Boost.h>
|
|
#include <aidl/android/hardware/power/IPower.h>
|
|
#include <aidl/android/hardware/power/Mode.h>
|
|
#include <android/binder_manager.h>
|
|
#include <android-base/properties.h>
|
|
|
|
// Camera dependencies
|
|
#include "QCameraPerf.h"
|
|
#include "QCameraTrace.h"
|
|
|
|
extern "C" {
|
|
#include "mm_camera_dbg.h"
|
|
}
|
|
|
|
namespace qcamera {
|
|
|
|
using aidl::android::hardware::power::Boost;
|
|
using aidl::android::hardware::power::Mode;
|
|
|
|
// Protect gPowerHal_1_2_ and gPowerHal_Aidl_
|
|
static android::sp<android::hardware::power::V1_2::IPower> gPowerHal_1_2_ = nullptr;
|
|
static std::shared_ptr<aidl::android::hardware::power::IPower> gPowerHal_Aidl_ = nullptr;
|
|
static std::mutex gPowerHalMutex;
|
|
static const std::string kInstance =
|
|
std::string() + aidl::android::hardware::power::IPower::descriptor + "/default";
|
|
|
|
namespace {
|
|
constexpr int kDefaultBoostDurationMs = 1000;
|
|
constexpr int kDisableBoostDurationMs = -1;
|
|
}
|
|
|
|
enum hal_version {
|
|
NONE,
|
|
HIDL_1_2,
|
|
AIDL,
|
|
};
|
|
|
|
// Connnect PowerHAL
|
|
static hal_version connectPowerHalLocked() {
|
|
static bool gPowerHalHidlExists = true;
|
|
static bool gPowerHalAidlExists = true;
|
|
|
|
if (!gPowerHalHidlExists && !gPowerHalAidlExists) {
|
|
return NONE;
|
|
}
|
|
|
|
if (gPowerHalHidlExists) {
|
|
if (!gPowerHal_1_2_) {
|
|
gPowerHal_1_2_ =
|
|
android::hardware::power::V1_2::IPower::getService();
|
|
}
|
|
if (gPowerHal_1_2_) {
|
|
ALOGV("Successfully connected to Power Hal Hidl service.");
|
|
return HIDL_1_2;
|
|
} else {
|
|
gPowerHalHidlExists = false;
|
|
}
|
|
}
|
|
|
|
if (gPowerHalAidlExists) {
|
|
if (!gPowerHal_Aidl_) {
|
|
ndk::SpAIBinder pwBinder = ndk::SpAIBinder(AServiceManager_getService(kInstance.c_str()));
|
|
gPowerHal_Aidl_ = aidl::android::hardware::power::IPower::fromBinder(pwBinder);
|
|
}
|
|
if (gPowerHal_Aidl_) {
|
|
ALOGV("Successfully connected to Power Hal Aidl service.");
|
|
return AIDL;
|
|
} else {
|
|
gPowerHalAidlExists = false;
|
|
}
|
|
}
|
|
|
|
return NONE;
|
|
}
|
|
|
|
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::CAMERA_STREAMING, 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_SHOT, 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::CAMERA_STREAMING, 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_SHOT, 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);
|
|
if (connectPowerHalLocked() == NONE) {
|
|
ALOGE("Couldn't load PowerHAL module");
|
|
} else {
|
|
error = false;
|
|
}
|
|
#else
|
|
{
|
|
/* 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);
|
|
}
|
|
}
|
|
#endif
|
|
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);
|
|
switch(connectPowerHalLocked()) {
|
|
case NONE:
|
|
return false;
|
|
case HIDL_1_2:
|
|
{
|
|
auto ret = gPowerHal_1_2_->powerHintAsync_1_2(hint, data);
|
|
if (!ret.isOk()) {
|
|
ALOGE("powerHint failed, error: %s",
|
|
ret.description().c_str());
|
|
gPowerHal_1_2_ = nullptr;
|
|
}
|
|
return ret.isOk();
|
|
}
|
|
case AIDL:
|
|
{
|
|
bool ret = false;
|
|
if (hint == PowerHint::CAMERA_LAUNCH) {
|
|
int32_t durationMs = data ? kDefaultBoostDurationMs : kDisableBoostDurationMs;
|
|
ret = gPowerHal_Aidl_->setBoost(Boost::CAMERA_LAUNCH, durationMs).isOk();
|
|
} else if (hint == PowerHint::CAMERA_SHOT) {
|
|
ret = gPowerHal_Aidl_->setBoost(Boost::CAMERA_SHOT, data).isOk();
|
|
} else if (hint == PowerHint::CAMERA_STREAMING) {
|
|
// Only CAMERA_STREAMING_MID is used
|
|
ret = gPowerHal_Aidl_->setMode(Mode::CAMERA_STREAMING_MID, static_cast<bool>(data)).isOk();
|
|
}
|
|
if (!ret) {
|
|
ALOGE("Failed to set power hint: %s.", toString(hint).c_str());
|
|
gPowerHal_Aidl_ = nullptr;
|
|
}
|
|
return ret;
|
|
}
|
|
default:
|
|
ALOGE("Unknown HAL state");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}; // namespace qcamera
|