hwc: Set display as active only after unblanking it
* For HDMI and non-Hybrid WFD solution, on receiving
online event, display hal sends hotplug connect to SF.
* In case of such displays, set them as active only
after receiving an unblank call.
* For Hybrid WFD solution, since display hal will not
be receiving unblank call from SF, set it as active
as part of processing online event itself.
Change-Id: I319f1576cba954da2024680568c37fedb1eb5d43
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 113e916..0d6d17e 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -67,12 +67,12 @@
}
};
-/* In case of proprietary WFD session, we are fooling SF by piggybacking on
+/* In case of non-hybrid WFD session, we are fooling SF by piggybacking on
* HDMI display ID for virtual. This helper is needed to differentiate their
* paths in HAL.
* TODO: Not needed once we have WFD client working on top of Google API's */
-static int getHWCDpy(hwc_context_t *ctx, int dpy) {
+static int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) {
if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive)
return HWC_DISPLAY_VIRTUAL;
return dpy;
@@ -267,7 +267,7 @@
for (int32_t i = numDisplays; i >= 0; i--) {
hwc_display_contents_1_t *list = displays[i];
- int dpy = getHWCDpy(ctx, i);
+ int dpy = getDpyforExternalDisplay(ctx, i);
switch(dpy) {
case HWC_DISPLAY_PRIMARY:
ret = hwc_prepare_primary(dev, list);
@@ -329,6 +329,14 @@
Locker::Autolock _l(ctx->mDrawLock);
int ret = 0, value = 0;
+
+ /* In case of non-hybrid WFD session, we are fooling SF by
+ * piggybacking on HDMI display ID for virtual.
+ * TODO: Not needed once we have WFD client working on top
+ * of Google API's.
+ */
+ dpy = getDpyforExternalDisplay(ctx,dpy);
+
ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
blank==1 ? "Blanking":"Unblanking", dpy);
if(blank) {
@@ -355,13 +363,37 @@
ctx->mExtDisplay->setHPD(1);
}
- /* Since SF is not aware of VIRTUAL DISPLAY being handle by HWC,
- * it wont send blank / unblank events for it. We piggyback on
- * PRIMARY DISPLAY events to release mdp pips and
- * activate/deactive VIRTUAL DISPLAY */
+ ctx->dpyAttr[dpy].isActive = !blank;
+
+ if(ctx->mVirtualonExtActive) {
+ /* if mVirtualonExtActive is true, display hal will
+ * receive unblank calls for non-hybrid WFD solution
+ * since we piggyback on HDMI.
+ * TODO: Not needed once we have WFD client working on top
+ of Google API's */
+ break;
+ }
+ case HWC_DISPLAY_VIRTUAL:
+ /* There are two ways to reach this block of code.
+
+ * Display hal has received unblank call on HWC_DISPLAY_EXTERNAL
+ and ctx->mVirtualonExtActive is true. In this case, non-hybrid
+ WFD is active. If so, getDpyforExternalDisplay will return dpy
+ as HWC_DISPLAY_VIRTUAL.
+
+ * Display hal has received unblank call on HWC_DISPLAY_PRIMARY
+ and since SF is not aware of VIRTUAL DISPLAY being handle by HWC,
+ it wont send blank / unblank events for it. We piggyback on
+ PRIMARY DISPLAY events to release mdp pipes and
+ activate/deactivate VIRTUAL DISPLAY.
+
+ * TODO: This separate case statement is not needed once we have
+ WFD client working on top of Google API's.
+
+ */
if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
- if(blank) {
+ if(blank and (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause)) {
int dpy = HWC_DISPLAY_VIRTUAL;
if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
ALOGE("%s: display commit fail for virtual!", __FUNCTION__);
@@ -378,13 +410,12 @@
ret = -1;
}
}
+ ctx->dpyAttr[dpy].isActive = !blank;
break;
default:
return -EINVAL;
}
- ctx->dpyAttr[dpy].isActive = !blank;
-
ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
blank ? "blanking":"unblanking", dpy);
return ret;
@@ -596,7 +627,7 @@
hwc_context_t* ctx = (hwc_context_t*)(dev);
for (uint32_t i = 0; i <= numDisplays; i++) {
hwc_display_contents_1_t* list = displays[i];
- int dpy = getHWCDpy(ctx, i);
+ int dpy = getDpyforExternalDisplay(ctx, i);
switch(dpy) {
case HWC_DISPLAY_PRIMARY:
ret = hwc_set_primary(ctx, list);
@@ -625,7 +656,7 @@
uint32_t* configs, size_t* numConfigs) {
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
- disp = getHWCDpy(ctx, disp);
+ disp = getDpyforExternalDisplay(ctx, disp);
//in 1.1 there is no way to choose a config, report as config id # 0
//This config is passed to getDisplayAttributes. Ignore for now.
switch(disp) {
@@ -655,7 +686,7 @@
uint32_t config, const uint32_t* attributes, int32_t* values) {
hwc_context_t* ctx = (hwc_context_t*)(dev);
- disp = getHWCDpy(ctx, disp);
+ disp = getDpyforExternalDisplay(ctx, disp);
//If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
return -1;
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index 5590798..ecb2104 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -226,20 +226,20 @@
ctx->dpyAttr[dpy].connected = true;
ctx->dpyAttr[dpy].isConfiguring = true;
- if(dpy == HWC_DISPLAY_VIRTUAL) {
+ if(dpy == HWC_DISPLAY_EXTERNAL ||
+ ctx->mVirtualonExtActive) {
+ /* External display is HDMI or non-hybrid WFD solution */
+ ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL_OFFLINE ONLINE"
+ "hotplug event", __FUNCTION__);
+ ctx->proc->hotplug(ctx->proc,HWC_DISPLAY_EXTERNAL,
+ EXTERNAL_ONLINE);
+ } else {
/* We wont be getting unblank for VIRTUAL DISPLAY and its
* always guaranteed from WFD stack that CONNECT uevent for
* VIRTUAL DISPLAY will be triggered before creating
* surface for the same. */
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = true;
}
- if(dpy == HWC_DISPLAY_EXTERNAL ||
- ctx->mVirtualonExtActive) {
- ALOGE_IF(UEVENT_DEBUG, "%s: Sending EXTERNAL_OFFLINE ONLINE"
- "hotplug event", __FUNCTION__);
- ctx->proc->hotplug(ctx->proc,HWC_DISPLAY_EXTERNAL,
- EXTERNAL_ONLINE);
- }
break;
}
case EXTERNAL_PAUSE: