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> #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;
} }

View File

@@ -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

View File

@@ -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,
}; };

View File

@@ -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 */