Merge "Display and wfd synchronization during teardown"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
38ef977bad
@@ -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); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user