Merge "Display and wfd synchronization during teardown"

This commit is contained in:
Linux Build Service Account
2014-04-17 03:52:54 -07:00
committed by Gerrit - the friendly Code Review server
9 changed files with 118 additions and 31 deletions

View File

@@ -74,6 +74,7 @@ void free_buffer(private_handle_t *hnd);
class Locker {
pthread_mutex_t mutex;
pthread_cond_t cond;
public:
class Autolock {
Locker& locker;
@@ -81,10 +82,18 @@ class Locker {
inline Autolock(Locker& locker) : locker(locker) { locker.lock(); }
inline ~Autolock() { locker.unlock(); }
};
inline Locker() { pthread_mutex_init(&mutex, 0); }
inline ~Locker() { pthread_mutex_destroy(&mutex); }
inline Locker() {
pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0);
}
inline ~Locker() {
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}
inline void lock() { pthread_mutex_lock(&mutex); }
inline void wait() { pthread_cond_wait(&cond, &mutex); }
inline void unlock() { pthread_mutex_unlock(&mutex); }
inline void signal() { pthread_cond_signal(&cond); }
};

View File

@@ -157,6 +157,9 @@ static status_t getDisplayVisibleRegion(hwc_context_t* ctx, int dpy,
}
static void pauseWFD(hwc_context_t *ctx, uint32_t pause) {
/* TODO: Will remove pauseWFD once all the clients start using
* setWfdStatus to indicate the status of WFD display
*/
int dpy = HWC_DISPLAY_VIRTUAL;
if(pause) {
//WFD Pause
@@ -167,6 +170,24 @@ static void pauseWFD(hwc_context_t *ctx, uint32_t pause) {
}
}
static void setWfdStatus(hwc_context_t *ctx, uint32_t wfdStatus) {
ALOGD_IF(HWC_WFDDISPSYNC_LOG,
"%s: Received a binder call that WFD state is %s",
__FUNCTION__,getExternalDisplayState(wfdStatus));
int dpy = HWC_DISPLAY_VIRTUAL;
if(wfdStatus == EXTERNAL_OFFLINE) {
ctx->mWfdSyncLock.lock();
ctx->mWfdSyncLock.signal();
ctx->mWfdSyncLock.unlock();
} else if(wfdStatus == EXTERNAL_PAUSE) {
handle_pause(ctx, dpy);
} else if(wfdStatus == EXTERNAL_RESUME) {
handle_resume(ctx, dpy);
}
}
status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
Parcel* outParcel) {
status_t ret = NO_ERROR;
@@ -199,15 +220,17 @@ status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
break;
case IQService::SET_HSIC_DATA:
setHSIC(inParcel);
break;
case IQService::PAUSE_WFD:
pauseWFD(mHwcContext, inParcel->readInt32());
break;
case IQService::SET_WFD_STATUS:
setWfdStatus(mHwcContext,inParcel->readInt32());
break;
default:
ret = NO_ERROR;
}
return ret;
}
}

View File

@@ -39,14 +39,6 @@ namespace qhwc {
#define HWC_UEVENT_SWITCH_STR "change@/devices/virtual/switch/"
#define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
/* External Display states */
enum {
EXTERNAL_OFFLINE = 0,
EXTERNAL_ONLINE,
EXTERNAL_PAUSE,
EXTERNAL_RESUME
};
static void setup(hwc_context_t* ctx, int dpy)
{
ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
@@ -145,9 +137,24 @@ static void teardownWfd(hwc_context_t* ctx) {
ctx->mVirtualonExtActive = false;
}
}
/* Wait for few frames for SF to tear down the WFD session. */
if(ctx->mVDSEnabled) {
ctx->mWfdSyncLock.lock();
ALOGD_IF(HWC_WFDDISPSYNC_LOG,
"%s: Waiting for wfd-teardown to be signalled",__FUNCTION__);
ctx->mWfdSyncLock.wait();
ALOGD_IF(HWC_WFDDISPSYNC_LOG,
"%s: Teardown signalled. Completed waiting in uevent thread",
__FUNCTION__);
ctx->mWfdSyncLock.unlock();
} else {
/*TODO: Remove this else block and have wait rather than usleep
once wfd module issues binder call on teardown.*/
/* For now, Wait for few frames for SF to tear down the WFD session.*/
usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
* 2 / 1000);
}
}
static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
@@ -166,7 +173,7 @@ static void handle_uevent(hwc_context_t* ctx, const char* udata, int len)
int switch_state = getConnectedState(udata, len);
ALOGE_IF(UEVENT_DEBUG,"%s: uevent recieved: %s switch state: %d",
ALOGE_IF(UEVENT_DEBUG,"%s: uevent received: %s switch state: %d",
__FUNCTION__,udata, switch_state);
switch(switch_state) {

View File

@@ -184,6 +184,7 @@ static int openFramebufferDevice(hwc_context_t *ctx)
void initContext(hwc_context_t *ctx)
{
openFramebufferDevice(ctx);
char value[PROPERTY_VALUE_MAX];
ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
@@ -225,7 +226,14 @@ void initContext(hwc_context_t *ctx)
ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
MDPComp::getObject(ctx, HWC_DISPLAY_PRIMARY);
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
ctx->mHWCVirtual = HWCVirtualBase::getObject();
ctx->mVDSEnabled = false;
if((property_get("persist.hwc.enable_vds", value, NULL) > 0)) {
if(atoi(value) != 0) {
ctx->mVDSEnabled = true;
}
}
ctx->mHWCVirtual = HWCVirtualBase::getObject(ctx->mVDSEnabled);
for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
ctx->mHwcDebug[i] = new HwcDebug(i);
@@ -262,7 +270,6 @@ void initContext(hwc_context_t *ctx)
// Read the system property to determine if downscale feature is enabled.
ctx->mMDPDownscaleEnabled = false;
char value[PROPERTY_VALUE_MAX];
if(property_get("sys.hwc.mdp_downscale_enabled", value, "false")
&& !strcmp(value, "true")) {
ctx->mMDPDownscaleEnabled = true;
@@ -642,6 +649,21 @@ int getMirrorModeOrientation(hwc_context_t *ctx) {
return extOrientation;
}
/* Get External State names */
const char* getExternalDisplayState(uint32_t external_state) {
static const char* externalStates[EXTERNAL_MAXSTATES] = {0};
externalStates[EXTERNAL_OFFLINE] = STR(EXTERNAL_OFFLINE);
externalStates[EXTERNAL_ONLINE] = STR(EXTERNAL_ONLINE);
externalStates[EXTERNAL_PAUSE] = STR(EXTERNAL_PAUSE);
externalStates[EXTERNAL_RESUME] = STR(EXTERNAL_RESUME);
if(external_state >= EXTERNAL_MAXSTATES) {
return "EXTERNAL_INVALID";
}
return externalStates[external_state];
}
bool isDownscaleRequired(hwc_layer_1_t const* layer) {
hwc_rect_t displayFrame = layer->displayFrame;
hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);

View File

@@ -39,6 +39,8 @@
#define MAX_NUM_APP_LAYERS 32
#define MIN_DISPLAY_XRES 200
#define MIN_DISPLAY_YRES 200
#define HWC_WFDDISPSYNC_LOG 0
#define STR(f) #f;
//Fwrd decls
struct hwc_context_t;
@@ -154,6 +156,15 @@ enum {
HWC_FORMAT_RB_SWAP = 0x00000040,
};
/* External Display states */
enum {
EXTERNAL_OFFLINE = 0,
EXTERNAL_ONLINE,
EXTERNAL_PAUSE,
EXTERNAL_RESUME,
EXTERNAL_MAXSTATES
};
class LayerRotMap {
public:
LayerRotMap() { reset(); }
@@ -280,6 +291,9 @@ void calcExtDisplayPosition(hwc_context_t *ctx,
// BufferMirrirMode(Sidesync)
int getMirrorModeOrientation(hwc_context_t *ctx);
/* Get External State names */
const char* getExternalDisplayState(uint32_t external_state);
// Handles wfd Pause and resume events
void handle_pause(hwc_context_t *ctx, int dpy);
void handle_resume(hwc_context_t *ctx, int dpy);
@@ -516,14 +530,21 @@ struct hwc_context_t {
//Used for SideSync feature
//which overrides the mExtOrientation
bool mBufferMirrorMode;
// Used to synchronize between WFD and Display modules
mutable Locker mWfdSyncLock;
qhwc::LayerRotMap *mLayerRotMap[HWC_NUM_DISPLAY_TYPES];
// Panel reset flag will be set if BTA check fails
bool mPanelResetStatus;
// number of active Displays
int numActiveDisplays;
// Downscale feature switch, set via system the property
// Downscale feature switch, set via system property
// sys.hwc.mdp_downscale_enabled
bool mMDPDownscaleEnabled;
// Is WFD enabled through VDS solution ?
// This can be set via system property
// persist.hwc.enable_vds
bool mVDSEnabled;
struct gpu_hint_info mGPUHintInfo;
};

View File

@@ -35,19 +35,17 @@
using namespace qhwc;
using namespace overlay;
HWCVirtualBase* HWCVirtualBase::getObject() {
char property[PROPERTY_VALUE_MAX];
HWCVirtualBase* HWCVirtualBase::getObject(bool isVDSEnabled) {
if((property_get("persist.hwc.enable_vds", property, NULL) > 0)) {
if(atoi(property) != 0) {
if(isVDSEnabled) {
ALOGD_IF(HWCVIRTUAL_LOG, "%s: VDS is enabled for Virtual display",
__FUNCTION__);
return new HWCVirtualVDS();
}
}
} else {
ALOGD_IF(HWCVIRTUAL_LOG, "%s: V4L2 is enabled for Virtual display",
__FUNCTION__);
return new HWCVirtualV4L2();
}
}
void HWCVirtualVDS::init(hwc_context_t *ctx) {
@@ -84,6 +82,9 @@ void HWCVirtualVDS::destroy(hwc_context_t *ctx, size_t /*numDisplays*/,
if(!Writeback::getInstance()->setSecure(false)) {
ALOGE("Failure while attempting to reset WB session.");
}
ctx->mWfdSyncLock.lock();
ctx->mWfdSyncLock.signal();
ctx->mWfdSyncLock.unlock();
}
}

View File

@@ -33,7 +33,7 @@ public:
explicit HWCVirtualBase(){};
virtual ~HWCVirtualBase(){};
// instantiates and returns the pointer to VDS or V4L2 object.
static HWCVirtualBase* getObject();
static HWCVirtualBase* getObject(bool isVDSEnabled);
virtual int prepare(hwc_composer_device_1 *dev,
hwc_display_contents_1_t* list) = 0;
virtual int set(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;

View File

@@ -50,6 +50,7 @@ public:
SET_HSIC_DATA, // Set HSIC on dspp
GET_DISPLAY_VISIBLE_REGION, // Get the visibleRegion for dpy
PAUSE_WFD, // Pause/Resume WFD
SET_WFD_STATUS, // Set if wfd connection is on/off
COMMAND_LIST_END = 400,
};

View File

@@ -87,4 +87,7 @@ inline android::status_t pauseWFD(uint32_t pause) {
return sendSingleParam(qService::IQService::PAUSE_WFD, pause);
}
inline android::status_t setWfdStatus(uint32_t wfdStatus) {
return sendSingleParam(qService::IQService::SET_WFD_STATUS, wfdStatus);
}
#endif /* end of include guard: QSERVICEUTILS_H */