hwc: Bump up version to 1.4
Add support for setPowerMode HWC_POWER_MODE_DOZE and
HWC_POWER_MODE_DOZE_SUSPEND are treated equally.
getActiveConfig and setActiveConfig only support the default 0th
config for now.
Change-Id: I0303ed077409a66d9666c840cad8d917d7aad600
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 6f4f9c6..60d575d 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -44,7 +44,7 @@
using namespace overlay;
#define VSYNC_DEBUG 0
-#define BLANK_DEBUG 1
+#define POWER_MODE_DEBUG 1
static int hwc_device_open(const struct hw_module_t* module,
const char* name,
@@ -395,80 +395,86 @@
return ret;
}
-static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
+static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy,
+ int mode)
{
ATRACE_CALL();
hwc_context_t* ctx = (hwc_context_t*)(dev);
-
- Locker::Autolock _l(ctx->mDrawLock);
int ret = 0, value = 0;
- ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
- blank==1 ? "Blanking":"Unblanking", dpy);
- if(blank) {
- // free up all the overlay pipes in use
- // when we get a blank for either display
- // makes sure that all pipes are freed
- ctx->mOverlay->configBegin();
- ctx->mOverlay->configDone();
- ctx->mRotMgr->clear();
- // If VDS is connected, do not clear WB object as it
- // will end up detaching IOMMU. This is required
- // to send black frame to WFD sink on power suspend.
- // Note: With this change, we keep the WriteBack object
- // alive on power suspend for AD use case.
+ Locker::Autolock _l(ctx->mDrawLock);
+ ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d",
+ __FUNCTION__, mode, dpy);
+
+ switch(mode) {
+ case HWC_POWER_MODE_OFF:
+ // free up all the overlay pipes in use
+ // when we get a blank for either display
+ // makes sure that all pipes are freed
+ ctx->mOverlay->configBegin();
+ ctx->mOverlay->configDone();
+ ctx->mRotMgr->clear();
+ // If VDS is connected, do not clear WB object as it
+ // will end up detaching IOMMU. This is required
+ // to send black frame to WFD sink on power suspend.
+ // Note: With this change, we keep the WriteBack object
+ // alive on power suspend for AD use case.
+ value = FB_BLANK_POWERDOWN;
+ break;
+ case HWC_POWER_MODE_DOZE:
+ case HWC_POWER_MODE_DOZE_SUSPEND:
+ value = FB_BLANK_VSYNC_SUSPEND;
+ break;
+ case HWC_POWER_MODE_NORMAL:
+ value = FB_BLANK_UNBLANK;
+ break;
}
+
switch(dpy) {
case HWC_DISPLAY_PRIMARY:
- value = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK;
if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
- ALOGE("%s: Failed to handle blank event(%d) for Primary!!",
- __FUNCTION__, blank );
- return -1;
+ ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s"
+ " value %d", __FUNCTION__, strerror(errno), value);
+ return -errno;
}
- if(!blank) {
- // Enable HPD here, as during bootup unblank is called
+ if(mode == HWC_POWER_MODE_NORMAL) {
+ // Enable HPD here, as during bootup POWER_MODE_NORMAL is set
// when SF is completely initialized
ctx->mExtDisplay->setHPD(1);
}
- ctx->dpyAttr[dpy].isActive = !blank;
-
+ ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
+ //Deliberate fall through since there is no explicit power mode for
+ //virtual displays.
case 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.
- */
-
if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
- if(blank and (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause)) {
- int dpy = HWC_DISPLAY_VIRTUAL;
+ const int dpy = HWC_DISPLAY_VIRTUAL;
+ if(mode == HWC_POWER_MODE_OFF and
+ (not ctx->dpyAttr[dpy].isPause)) {
if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: display commit fail for virtual!", __FUNCTION__);
+ ALOGE("%s: displayCommit failed for virtual", __FUNCTION__);
ret = -1;
}
}
- ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
+ ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
}
break;
case HWC_DISPLAY_EXTERNAL:
- if(blank) {
+ if(mode == HWC_POWER_MODE_OFF) {
if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
- ALOGE("%s: display commit fail for external!", __FUNCTION__);
+ ALOGE("%s: displayCommit failed for external", __FUNCTION__);
ret = -1;
}
}
- ctx->dpyAttr[dpy].isActive = !blank;
+ ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
break;
default:
return -EINVAL;
}
- ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
- blank ? "blanking":"unblanking", dpy);
+ ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d",
+ __FUNCTION__, mode, dpy);
return ret;
}
@@ -483,18 +489,18 @@
return;
}
- ALOGD("%s: calling BLANK DISPLAY", __FUNCTION__);
- ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 1);
+ ALOGD("%s: setting power mode off", __FUNCTION__);
+ ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_OFF);
if (ret < 0) {
ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__,
- strerror(errno));
+ strerror(errno));
}
- ALOGD("%s: calling UNBLANK DISPLAY and enabling vsync", __FUNCTION__);
- ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 0);
+ ALOGD("%s: setting power mode normal and enabling vsync", __FUNCTION__);
+ ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL);
if (ret < 0) {
ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__,
- strerror(errno));
+ strerror(errno));
}
hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
@@ -700,8 +706,8 @@
uint32_t* configs, size_t* numConfigs) {
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
- //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.
+ //Currently we allow only 1 config, reported as config id # 0
+ //This config is passed in to getDisplayAttributes. Ignored for now.
switch(disp) {
case HWC_DISPLAY_PRIMARY:
if(*numConfigs > 0) {
@@ -810,6 +816,17 @@
strlcpy(buff, aBuf.string(), buff_len);
}
+int hwc_getActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/) {
+ //Supports only the default config (0th index) for now
+ return 0;
+}
+
+int hwc_setActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/,
+ int index) {
+ //Supports only the default config (0th index) for now
+ return (index == 0) ? index : -EINVAL;
+}
+
static int hwc_device_close(struct hw_device_t *dev)
{
if(!dev) {
@@ -839,18 +856,20 @@
//Setup HWC methods
dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = HWC_DEVICE_API_VERSION_1_3;
+ dev->device.common.version = HWC_DEVICE_API_VERSION_1_4;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = hwc_device_close;
dev->device.prepare = hwc_prepare;
dev->device.set = hwc_set;
dev->device.eventControl = hwc_eventControl;
- dev->device.blank = hwc_blank;
+ dev->device.setPowerMode = hwc_setPowerMode;
dev->device.query = hwc_query;
dev->device.registerProcs = hwc_registerProcs;
dev->device.dump = hwc_dump;
dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
+ dev->device.getActiveConfig = hwc_getActiveConfig;
+ dev->device.setActiveConfig = hwc_setActiveConfig;
*device = &dev->device.common;
status = 0;
}