msm7k: Detect display type and mark layers

Mark layers for convert to S3D when playing S3D content on a 3DTV.

Change-Id: I355a73753682134b8ec5544a03d55ae40793e897
This commit is contained in:
Kinjal Bhavsar 2011-10-14 18:03:04 -07:00
parent 802829be05
commit 6eb041de80
5 changed files with 106 additions and 15 deletions

3
libhwcomposer/Android.mk Executable file → Normal file
View File

@ -22,4 +22,7 @@ endif
ifeq ($(TARGET_HAVE_BYPASS),true)
LOCAL_CFLAGS += -DCOMPOSITION_BYPASS
endif
ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
endif
include $(BUILD_SHARED_LIBRARY)

51
libhwcomposer/hwcomposer.cpp Executable file → Normal file
View File

@ -605,6 +605,46 @@ static int getYUVBufferCount (const hwc_layer_list_t* list) {
return yuvBufferCount;
}
static int getS3DVideoFormat (const hwc_layer_list_t* list) {
int s3dFormat = 0;
if (list) {
for (size_t i=0; i<list->numHwLayers; i++) {
private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO))
s3dFormat = FORMAT_3D_INPUT(hnd->format);
if (s3dFormat)
break;
}
}
return s3dFormat;
}
static bool isS3DCompositionRequired() {
#ifdef HDMI_AS_PRIMARY
return overlay::is3DTV();
#endif
return false;
}
static void markUILayerForS3DComposition (hwc_layer_t &layer, int s3dVideoFormat) {
#ifdef HDMI_AS_PRIMARY
layer.compositionType = HWC_FRAMEBUFFER;
switch(s3dVideoFormat) {
case HAL_3D_IN_SIDE_BY_SIDE_L_R:
case HAL_3D_IN_SIDE_BY_SIDE_R_L:
layer.hints |= HWC_HINT_DRAW_S3D_SIDE_BY_SIDE;
break;
case HAL_3D_IN_TOP_BOTTOM:
layer.hints |= HWC_HINT_DRAW_S3D_TOP_BOTTOM;
break;
default:
LOGE("%s: Unknown S3D input format 0x%x", __FUNCTION__, s3dVideoFormat);
break;
}
#endif
return;
}
static int getLayersNotUpdatingCount(const hwc_layer_list_t* list) {
int numLayersNotUpdating = 0;
if (list) {
@ -636,6 +676,8 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
int yuvBufferCount = 0;
int layerType = 0;
bool isS3DCompositionNeeded = false;
int s3dVideoFormat = 0;
int numLayersNotUpdating = 0;
bool fullscreen = false;
@ -648,6 +690,9 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
numLayersNotUpdating = getLayersNotUpdatingCount(list);
skipComposition = canSkipComposition(ctx, yuvBufferCount,
list->numHwLayers, numLayersNotUpdating);
s3dVideoFormat = getS3DVideoFormat(list);
if (s3dVideoFormat)
isS3DCompositionNeeded = isS3DCompositionRequired();
}
if (list->flags & HWC_GEOMETRY_CHANGED) {
@ -662,6 +707,10 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
// If there is a single Fullscreen layer, we can bypass it - TBD
// If there is only one video/camera buffer, we can bypass itn
if (list->hwLayers[i].flags & HWC_SKIP_LAYER) {
// During the animaton UI layers are marked as SKIP
// need to still mark the layer for S3D composition
if (isS3DCompositionNeeded)
markUILayerForS3DComposition(list->hwLayers[i], s3dVideoFormat);
continue;
}
if (hnd && (hnd->bufferType == BUFFER_TYPE_VIDEO) && (yuvBufferCount == 1)) {
@ -685,6 +734,8 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) {
list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
skipComposition = false;
}
} else if (isS3DCompositionNeeded) {
markUILayerForS3DComposition(list->hwLayers[i], s3dVideoFormat);
} else if (list->hwLayers[i].flags == HWC_USE_ORIGINAL_RESOLUTION) {
list->hwLayers[i].compositionType = HWC_USE_OVERLAY;
list->hwLayers[i].hints |= HWC_HINT_CLEAR_FB;

View File

@ -27,6 +27,9 @@ LOCAL_SRC_FILES := \
overlayLib.cpp \
overlayLibUI.cpp \
LOCAL_CFLAGS:= -DLOG_TAG=\"OverlayLib\"
ifeq ($(TARGET_USE_HDMI_AS_PRIMARY),true)
LOCAL_CFLAGS += -DHDMI_AS_PRIMARY
endif
LOCAL_MODULE := liboverlay
include $(BUILD_SHARED_LIBRARY)

58
liboverlay/overlayLib.cpp Executable file → Normal file
View File

@ -25,6 +25,14 @@ static inline size_t ALIGN(size_t x, size_t align) {
return (x + align-1) & ~(align-1);
}
using namespace overlay;
#ifdef HDMI_AS_PRIMARY
bool Overlay::sHDMIAsPrimary = true;
#else
bool Overlay::sHDMIAsPrimary = false;
#endif
int overlay::get_mdp_format(int format) {
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888 :
@ -167,8 +175,6 @@ const char* overlay::getFormatString(int format){
return formats[format];
}
using namespace overlay;
bool overlay::isHDMIConnected () {
char value[PROPERTY_VALUE_MAX];
property_get("hw.hdmiON", value, "0");
@ -183,7 +189,7 @@ bool overlay::is3DTV() {
fread(&is3DTV, 1, 1, fp);
fclose(fp);
}
LOGI("3DTV EDID flag: %d", is3DTV);
LOGI("3DTV EDID flag: %c", is3DTV);
return (is3DTV == '0') ? false : true;
}
@ -205,6 +211,9 @@ bool overlay::isPanel3D() {
}
bool overlay::usePanel3D() {
if (Overlay::sHDMIAsPrimary)
return is3DTV();
if(!isPanel3D())
return false;
char value[PROPERTY_VALUE_MAX];
@ -325,8 +334,12 @@ bool Overlay::closeChannel() {
if(mS3DFormat) {
if (mHDMIConnected)
overlay::send3DInfoPacket(0);
else if (mState == OV_3D_VIDEO_3D_PANEL)
enableBarrier(0);
else if (mState == OV_3D_VIDEO_3D_PANEL) {
if (sHDMIAsPrimary)
overlay::send3DInfoPacket(0);
else
enableBarrier(0);
}
}
for (int i = 0; i < NUM_CHANNELS; i++) {
objOvCtrlChannel[i].closeControlChannel();
@ -367,11 +380,15 @@ bool Overlay::setPosition(int x, int y, uint32_t w, uint32_t h) {
break;
case OV_3D_VIDEO_3D_PANEL:
for (int i = 0; i < NUM_CHANNELS; i++) {
if (!objOvCtrlChannel[i].useVirtualFB()) {
LOGE("%s: failed virtual fb for channel %d", __FUNCTION__, i);
return false;
if (sHDMIAsPrimary)
objOvCtrlChannel[i].getPositionS3D(i, mS3DFormat, &rect);
else {
if (!objOvCtrlChannel[i].useVirtualFB()) {
LOGE("%s: failed virtual fb for channel %d", __FUNCTION__, i);
return false;
}
objOvCtrlChannel[i].getPositionS3D(i, 0x1, &rect);
}
objOvCtrlChannel[i].getPositionS3D(i, 0x1, &rect);
if(!setChannelPosition(rect.x, rect.y, rect.w, rect.h, i)) {
LOGE("%s: failed for channel %d", __FUNCTION__, i);
return false;
@ -429,6 +446,9 @@ bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientati
geometryChanged = false;
}
if (sHDMIAsPrimary)
needUpdateFlags = false;
if ((false == needUpdateFlags) && (false == geometryChanged)) {
objOvDataChannel[0].updateDataChannel(0, 0);
return true;
@ -436,14 +456,16 @@ bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientati
// Disable rotation for the HDMI channels
int orientHdmi = 0;
int orient[2] = {true, orientHdmi};
int orientPrimary = sHDMIAsPrimary ? 0 : orientation;
int orient[2] = {orientPrimary, orientHdmi};
// enable waitForVsync on HDMI
bool waitForHDMI = true;
bool wait[2] = {waitForVsync, waitForHDMI};
bool waitForPrimary = sHDMIAsPrimary ? true : waitForVsync;
bool waitCond[2] = {waitForPrimary, waitForHDMI};
switch(mState) {
case OV_3D_VIDEO_3D_PANEL:
orient[1] = orientation;
orient[1] = sHDMIAsPrimary ? 0 : orientation;
break;
case OV_3D_VIDEO_3D_TV:
orient[0] = 0;
@ -464,7 +486,7 @@ bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientati
// Set the overlay source info
for (int i = 0; i < NUM_CHANNELS; i++) {
if (objOvCtrlChannel[i].isChannelUP()) {
ret = objOvCtrlChannel[i].updateOverlaySource(info, orient[i], wait[i]);
ret = objOvCtrlChannel[i].updateOverlaySource(info, orient[i], waitCond[i]);
if (!ret) {
LOGE("objOvCtrlChannel[%d].updateOverlaySource failed", i);
return false;
@ -525,6 +547,7 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
}
// We always enable the rotator for the primary.
bool noRot = false;
bool uiChannel = false;
switch(mState) {
case OV_2D_VIDEO_ON_PANEL:
case OV_3D_VIDEO_2D_PANEL:
@ -532,8 +555,13 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
mS3DFormat, VG0_PIPE, waitForVsync, num_buffers);
break;
case OV_3D_VIDEO_3D_PANEL:
if (sHDMIAsPrimary) {
noRot = true;
waitForVsync = true;
send3DInfoPacket(mS3DFormat & OUTPUT_MASK_3D);
}
for (int i=0; i<NUM_CHANNELS; i++) {
if(!startChannel(info, FRAMEBUFFER_0, noRot,
if(!startChannel(info, FRAMEBUFFER_0, noRot, uiChannel,
mS3DFormat, i, waitForVsync, num_buffers)) {
LOGE("%s:failed to open channel %d", __FUNCTION__, i);
return false;
@ -648,7 +676,7 @@ bool Overlay::setParameter(int param, int value) {
}
break;
case OV_3D_VIDEO_3D_PANEL:
if (param == OVERLAY_TRANSFORM) {
if (!sHDMIAsPrimary && param == OVERLAY_TRANSFORM) {
int barrier = 0;
switch (value) {
case HAL_TRANSFORM_ROT_90:

6
liboverlay/overlayLib.h Executable file → Normal file
View File

@ -90,8 +90,13 @@ enum {
#define BARRIER_LANDSCAPE 1
#define BARRIER_PORTRAIT 2
#ifdef HDMI_AS_PRIMARY
#define FORMAT_3D_FILE "/sys/class/graphics/fb0/format_3d"
#define EDID_3D_INFO_FILE "/sys/class/graphics/fb0/3d_present"
#else
#define FORMAT_3D_FILE "/sys/class/graphics/fb1/format_3d"
#define EDID_3D_INFO_FILE "/sys/class/graphics/fb1/3d_present"
#endif
#define BARRIER_FILE "/sys/devices/platform/mipi_novatek.0/enable_3d_barrier"
/* -------------------------- end 3D defines ----------------------------------------*/
@ -254,6 +259,7 @@ public:
Overlay();
~Overlay();
static bool sHDMIAsPrimary;
bool startChannel(const overlay_buffer_info& info, int fbnum, bool norot = false,
bool uichannel = false, unsigned int format3D = 0,
int channel = 0, bool ignoreFB = false,