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>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <utils/Errors.h>
|
||||
#include <sys/types.h>
|
||||
#include <cutils/log.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <media/IMediaDeathNotifier.h>
|
||||
#include <IQClient.h>
|
||||
@@ -51,6 +52,13 @@ public:
|
||||
const android::Parcel* inParcel,
|
||||
android::Parcel* outParcel);
|
||||
|
||||
//Notifies camera service death
|
||||
class CamDeathNotifier : public IBinder::DeathRecipient {
|
||||
public:
|
||||
CamDeathNotifier(){}
|
||||
virtual void binderDied(const android::wp<IBinder>& who);
|
||||
};
|
||||
|
||||
private:
|
||||
//Notifies of Media Player death
|
||||
class MPDeathNotifier : public android::IMediaDeathNotifier {
|
||||
@@ -62,6 +70,7 @@ private:
|
||||
|
||||
hwc_context_t *mHwcContext;
|
||||
const android::sp<android::IMediaDeathNotifier> mMPDeathNotifier;
|
||||
const android::sp<QClient::CamDeathNotifier> mCamDeathNotifier;
|
||||
};
|
||||
}; // namespace qClient
|
||||
#endif // ANDROID_QCLIENT_H
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
GET_CONFIG_COUNT = 27, //Get the number of supported display configs
|
||||
GET_DISPLAY_ATTRIBUTES_FOR_CONFIG = 28, //Get attr for specified config
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
@@ -91,4 +91,8 @@ inline android::status_t setBufferMirrorMode(uint32_t 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 */
|
||||
|
||||
Reference in New Issue
Block a user