hwc : Set bw limit on mdss when camera is on.
-Expose qservice API to get notified when Camera is on or off. -Set bandwidth hint to mdss based on camera launch status by writing into fb0/mdp/bw_mode_bitmap. -Implement camera service death notifier to recover display bw. Change-Id: I532f44281b5d7de1d638f1cef250114a3cc952ae
This commit is contained in:
@@ -40,6 +40,8 @@
|
|||||||
#include <hwc_qdcm.h>
|
#include <hwc_qdcm.h>
|
||||||
|
|
||||||
#define QCLIENT_DEBUG 0
|
#define QCLIENT_DEBUG 0
|
||||||
|
#define FILE_MAX_MDSSBW_FLAG \
|
||||||
|
"/sys/devices/virtual/graphics/fb0/mdp/bw_mode_bitmap"
|
||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
using namespace qService;
|
using namespace qService;
|
||||||
@@ -52,7 +54,8 @@ namespace qClient {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
QClient::QClient(hwc_context_t *ctx) : mHwcContext(ctx),
|
QClient::QClient(hwc_context_t *ctx) : mHwcContext(ctx),
|
||||||
mMPDeathNotifier(new MPDeathNotifier(ctx))
|
mMPDeathNotifier(new MPDeathNotifier(ctx)),
|
||||||
|
mCamDeathNotifier(new CamDeathNotifier())
|
||||||
{
|
{
|
||||||
ALOGD_IF(QCLIENT_DEBUG, "QClient Constructor invoked");
|
ALOGD_IF(QCLIENT_DEBUG, "QClient Constructor invoked");
|
||||||
}
|
}
|
||||||
@@ -481,6 +484,84 @@ static status_t getDisplayAttributesForConfig(hwc_context_t* ctx,
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* register/unregister camera service */
|
||||||
|
static bool setCameraDeathNotifier(
|
||||||
|
android::sp<QClient::CamDeathNotifier> camDeathNotifier, bool on) {
|
||||||
|
sp<IServiceManager> sm = defaultServiceManager();
|
||||||
|
sp<IBinder> binder = sm->getService(String16("media.camera"));
|
||||||
|
if (binder == 0) {
|
||||||
|
ALOGW("%s: CameraService not published or dead...", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(on) {
|
||||||
|
binder->linkToDeath(camDeathNotifier);
|
||||||
|
} else {
|
||||||
|
binder->unlinkToDeath(camDeathNotifier);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool updateDisplayBWCapForCam(bool on) {
|
||||||
|
char sysfsPath[255];
|
||||||
|
char bw[64];
|
||||||
|
int bw_flag = 0; // to reset to default.
|
||||||
|
|
||||||
|
memset(sysfsPath, 0, sizeof(sysfsPath));
|
||||||
|
snprintf(sysfsPath , sizeof(sysfsPath), FILE_MAX_MDSSBW_FLAG);
|
||||||
|
int sysfsFd = open(sysfsPath, O_RDWR);
|
||||||
|
if(sysfsFd < 0 ) {
|
||||||
|
ALOGE("%s: Status: %d Error in opening %s: %s",
|
||||||
|
__FUNCTION__, on, sysfsPath, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(on) {
|
||||||
|
bw_flag = MDSS_MAX_BW_LIMIT_CAMERA;
|
||||||
|
}
|
||||||
|
snprintf(bw, sizeof(bw), "%d", bw_flag);
|
||||||
|
ssize_t bytes = pwrite(sysfsFd, bw, strlen(bw), 0);
|
||||||
|
if(bytes < 0) {
|
||||||
|
ALOGE ("%s: Unable to write into %s node %s",
|
||||||
|
__FUNCTION__, sysfsPath, strerror(errno));
|
||||||
|
close(sysfsFd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
close(sysfsFd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setCameraStatus(hwc_context_t* ctx,
|
||||||
|
android::sp<QClient::CamDeathNotifier> camDeathNotifier, uint32_t on) {
|
||||||
|
|
||||||
|
//Currently we need this only for 8952.
|
||||||
|
if(!MDPVersion::getInstance().is8x52()) {
|
||||||
|
ALOGI("%s Not 8952?? return", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!setCameraDeathNotifier(camDeathNotifier, on)) {
|
||||||
|
ALOGE("%s failed in updateCameraStatus", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!updateDisplayBWCapForCam(on)) {
|
||||||
|
ALOGE("%s failed in updateDisplayBWCap", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger a screen update so that our BW setting will reflect
|
||||||
|
// atleast by next vsync.
|
||||||
|
screenRefresh(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QClient::CamDeathNotifier::binderDied(const wp<IBinder>& who) {
|
||||||
|
//If Cameraservice abruptly gone, reset mdss bw caps
|
||||||
|
//This new cap will be applicable from next frame onwards
|
||||||
|
if(!updateDisplayBWCapForCam(false)) {
|
||||||
|
ALOGE("%s failed in updateDisplayBWCap", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
|
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
|
||||||
Parcel* outParcel) {
|
Parcel* outParcel) {
|
||||||
status_t ret = NO_ERROR;
|
status_t ret = NO_ERROR;
|
||||||
@@ -559,6 +640,10 @@ status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
|
|||||||
case IQService::QDCM_SVC_CMDS:
|
case IQService::QDCM_SVC_CMDS:
|
||||||
qdcmCmdsHandler(mHwcContext, inParcel, outParcel);
|
qdcmCmdsHandler(mHwcContext, inParcel, outParcel);
|
||||||
break;
|
break;
|
||||||
|
case IQService::SET_CAMERA_STATUS:
|
||||||
|
setCameraStatus(mHwcContext,
|
||||||
|
mCamDeathNotifier, inParcel->readInt32());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ret = NO_ERROR;
|
ret = NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <utils/Errors.h>
|
#include <utils/Errors.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <cutils/log.h>
|
#include <cutils/log.h>
|
||||||
|
#include <utils/RefBase.h>
|
||||||
#include <binder/IServiceManager.h>
|
#include <binder/IServiceManager.h>
|
||||||
#include <media/IMediaDeathNotifier.h>
|
#include <media/IMediaDeathNotifier.h>
|
||||||
#include <IQClient.h>
|
#include <IQClient.h>
|
||||||
@@ -51,6 +52,13 @@ public:
|
|||||||
const android::Parcel* inParcel,
|
const android::Parcel* inParcel,
|
||||||
android::Parcel* outParcel);
|
android::Parcel* outParcel);
|
||||||
|
|
||||||
|
//Notifies camera service death
|
||||||
|
class CamDeathNotifier : public IBinder::DeathRecipient {
|
||||||
|
public:
|
||||||
|
CamDeathNotifier(){}
|
||||||
|
virtual void binderDied(const android::wp<IBinder>& who);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//Notifies of Media Player death
|
//Notifies of Media Player death
|
||||||
class MPDeathNotifier : public android::IMediaDeathNotifier {
|
class MPDeathNotifier : public android::IMediaDeathNotifier {
|
||||||
@@ -62,6 +70,7 @@ private:
|
|||||||
|
|
||||||
hwc_context_t *mHwcContext;
|
hwc_context_t *mHwcContext;
|
||||||
const android::sp<android::IMediaDeathNotifier> mMPDeathNotifier;
|
const android::sp<android::IMediaDeathNotifier> mMPDeathNotifier;
|
||||||
|
const android::sp<QClient::CamDeathNotifier> mCamDeathNotifier;
|
||||||
};
|
};
|
||||||
}; // namespace qClient
|
}; // namespace qClient
|
||||||
#endif // ANDROID_QCLIENT_H
|
#endif // ANDROID_QCLIENT_H
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public:
|
|||||||
GET_CONFIG_COUNT = 27, //Get the number of supported display configs
|
GET_CONFIG_COUNT = 27, //Get the number of supported display configs
|
||||||
GET_DISPLAY_ATTRIBUTES_FOR_CONFIG = 28, //Get attr for specified config
|
GET_DISPLAY_ATTRIBUTES_FOR_CONFIG = 28, //Get attr for specified config
|
||||||
SET_DISPLAY_MODE = 29, // Set display mode to command or video mode
|
SET_DISPLAY_MODE = 29, // Set display mode to command or video mode
|
||||||
|
SET_CAMERA_STATUS = 30, // To notify display when camera is on and off
|
||||||
COMMAND_LIST_END = 400,
|
COMMAND_LIST_END = 400,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -91,4 +91,8 @@ inline android::status_t setBufferMirrorMode(uint32_t enable) {
|
|||||||
return sendSingleParam(qService::IQService::BUFFER_MIRRORMODE, enable);
|
return sendSingleParam(qService::IQService::BUFFER_MIRRORMODE, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline android::status_t setCameraLaunchStatus(uint32_t on) {
|
||||||
|
return sendSingleParam(qService::IQService::SET_CAMERA_STATUS, on);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* end of include guard: QSERVICEUTILS_H */
|
#endif /* end of include guard: QSERVICEUTILS_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user