Skip to content

Commit

Permalink
hwc: msm8226: Bump up version to 1.4
Browse files Browse the repository at this point in the history
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: I010d1dae470c2b111d4ef2937b94d8c5e519e385
Acked-by: Saurabh Shah <[email protected]>
  • Loading branch information
naseer authored and Prashant Malani committed Jan 13, 2015
1 parent 66528d1 commit adc3f59
Showing 1 changed file with 71 additions and 78 deletions.
149 changes: 71 additions & 78 deletions msm8226/libhwcomposer/hwc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ using namespace qhwc;
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,
Expand Down Expand Up @@ -401,106 +401,86 @@ static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
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;

/* 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) {
// 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;

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;
}
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:
/* 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 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;
}

Expand All @@ -515,18 +495,18 @@ static void reset_panel(struct hwc_composer_device_1* dev)
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);

Expand Down Expand Up @@ -740,8 +720,8 @@ int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
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.
//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) {
Expand Down Expand Up @@ -853,6 +833,17 @@ void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
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) {
Expand Down Expand Up @@ -882,18 +873,20 @@ static int hwc_device_open(const struct hw_module_t* module, const char* name,

//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;
}
Expand Down

0 comments on commit adc3f59

Please sign in to comment.