diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk old mode 100755 new mode 100644 index 1ed1396..df25be9 --- a/libhwcomposer/Android.mk +++ b/libhwcomposer/Android.mk @@ -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) diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp old mode 100755 new mode 100644 index 1b55fdb..f55dba8 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -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; inumHwLayers; 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; diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk index d271fb5..a257de2 100644 --- a/liboverlay/Android.mk +++ b/liboverlay/Android.mk @@ -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) diff --git a/liboverlay/overlayLib.cpp b/liboverlay/overlayLib.cpp old mode 100755 new mode 100644 index 7d098f0..b111c86 --- a/liboverlay/overlayLib.cpp +++ b/liboverlay/overlayLib.cpp @@ -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