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:
Prabhanjan Kandula
2015-03-30 22:35:09 +05:30
parent 2d34a3bbfa
commit db274fa42a
4 changed files with 100 additions and 1 deletions

View File

@@ -40,6 +40,8 @@
#include <hwc_qdcm.h>
#define QCLIENT_DEBUG 0
#define FILE_MAX_MDSSBW_FLAG \
"/sys/devices/virtual/graphics/fb0/mdp/bw_mode_bitmap"
using namespace android;
using namespace qService;
@@ -52,7 +54,8 @@ namespace qClient {
// ----------------------------------------------------------------------------
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");
}
@@ -481,6 +484,84 @@ static status_t getDisplayAttributesForConfig(hwc_context_t* ctx,
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,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -559,6 +640,10 @@ status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
case IQService::QDCM_SVC_CMDS:
qdcmCmdsHandler(mHwcContext, inParcel, outParcel);
break;
case IQService::SET_CAMERA_STATUS:
setCameraStatus(mHwcContext,
mCamDeathNotifier, inParcel->readInt32());
break;
default:
ret = NO_ERROR;
}