diff options
author | Matt Wagantall <mwagantall@cyngn.com> | 2016-02-26 17:09:09 -0800 |
---|---|---|
committer | Matt Wagantall <mwagantall@cyngn.com> | 2016-02-26 17:12:19 -0800 |
commit | c9cd4af3fdfcda5ed12f090699446c8537d7218a (patch) | |
tree | 4662d3b465da654c09a940fe7aa9d15b12767ce2 | |
parent | 9fa4c99a9644ee2678c20812f576a76baad57872 (diff) | |
parent | 99c272be15cf4d3b97fcb7db6e8a4375c1d64327 (diff) | |
download | android_hardware_qcom_display-stable/cm-13.0-caf-8994-ZNH2K.tar.gz android_hardware_qcom_display-stable/cm-13.0-caf-8994-ZNH2K.tar.bz2 android_hardware_qcom_display-stable/cm-13.0-caf-8994-ZNH2K.zip |
Merge tag 'LA.BF64.1.2.2-03340-8x94.0' into HEADstable/cm-13.0-caf-8994-ZNH2KBstable/cm-13.0-caf-8994-ZNH2K
"LA.BF64.1.2.2-03340-8x94.0"
Issue-Id: SAMBAR-1290
Change-Id: Ia4989241a9c10d6f8b37ea6f17c27ad5e0a9cfd0
-rw-r--r-- | libhdmi/hdmi.cpp | 84 | ||||
-rw-r--r-- | libhdmi/hdmi.h | 7 |
2 files changed, 86 insertions, 5 deletions
diff --git a/libhdmi/hdmi.cpp b/libhdmi/hdmi.cpp index b2cde7af0..dac085774 100644 --- a/libhdmi/hdmi.cpp +++ b/libhdmi/hdmi.cpp @@ -38,6 +38,8 @@ namespace qhwc { #define SPD_NAME_LENGTH 16 int HDMIDisplay::configure() { + char value[PROPERTY_VALUE_MAX]; + if(!openFrameBuffer()) { ALOGE("%s: Failed to open FB: %d", __FUNCTION__, mFbNum); return -1; @@ -50,11 +52,18 @@ int HDMIDisplay::configure() { mActiveConfig = getUserConfig(); if (mActiveConfig == -1) { //Get the best mode and set - mActiveConfig = getBestConfig(); + property_get("hw.hdmi.s3d_enable", value, "0"); + if (atoi(value) != 0) { + mActiveConfig = getBestConfig(HDMI_S3D_SIDE_BY_SIDE); + if (mActiveConfig == -1) { + mActiveConfig = getBestConfig(HDMI_S3D_NONE); + } + } else { + mActiveConfig = getBestConfig(HDMI_S3D_NONE); + } } // Read the system property to determine if downscale feature is enabled. - char value[PROPERTY_VALUE_MAX]; mMDPDownscaleEnabled = false; if(property_get("sys.hwc.mdp_downscale_enabled", value, "false") && !strcmp(value, "true")) { @@ -407,10 +416,63 @@ int HDMIDisplay::getUserConfig() { return -1; } +void HDMIDisplay::getS3DConfigs(uint32_t* s3d_configs) { + char *saveptr_l1, *saveptr_l2, *saveptr_l3; + char *l1, *l2, *l3; + int edid_s3d_node; + ssize_t length = -1; + char edid_s3d_str[PAGE_SIZE] = {'\0'}; + + for (int i = 0; i < mModeCount; i++) { + s3d_configs[i] = 0; + SET_BIT(s3d_configs[i], HDMI_S3D_NONE); + } + + edid_s3d_node = openDeviceNode("edid_3d_modes", O_RDONLY); + if (edid_s3d_node < 0) { + ALOGE_IF(DEBUG, "%s: open device node edid_3d_modes failed", __FUNCTION__); + return; + } + + length = read(edid_s3d_node, edid_s3d_str, sizeof(edid_s3d_str)-1); + if (length <= 0) { + ALOGE_IF(DEBUG, "%s: read device node edid_3d_modes failed", __FUNCTION__); + close(edid_s3d_node); + return; + } + + // Three level inception! + // The string looks like 16=SSH,4=FP:TAB:SSH,5=FP:SSH,31=FP:TAB:SSH + l1 = strtok_r(edid_s3d_str, ",", &saveptr_l1); + while (l1 != NULL) { + l2 = strtok_r(l1, "=", &saveptr_l2); + if (l2 != NULL) { + for (int index = 0; index < mModeCount; index++) { + if (mEDIDModes[index] == (int)atoi(l2)) { + l3 = strtok_r(saveptr_l2, ":", &saveptr_l3); + while (l3 != NULL) { + if (strncmp("SSH", l3, strlen("SSH")) == 0) { + SET_BIT(s3d_configs[index], HDMI_S3D_SIDE_BY_SIDE); + } else if (strncmp("TAB", l3, strlen("TAB")) == 0) { + SET_BIT(s3d_configs[index], HDMI_S3D_TOP_AND_BOTTOM); + } else if (strncmp("FP", l3, strlen("FP")) == 0) { + SET_BIT(s3d_configs[index], HDMI_S3D_FRAME_PACKING); + } + l3 = strtok_r(NULL, ":", &saveptr_l3); + } + } + } + l1 = strtok_r(NULL, ",", &saveptr_l1); + } + } + close(edid_s3d_node); +} + // Get the index of the best mode for the current HD TV -int HDMIDisplay::getBestConfig() { - int bestConfigIndex = 0; +int HDMIDisplay::getBestConfig(int s3d_mode) { + int bestConfigIndex = -1; int edidMode = -1; + uint32_t* s3d_configs = NULL; struct msm_hdmi_mode_timing_info currentModeInfo = {0}; struct msm_hdmi_mode_timing_info bestModeInfo = {0}; bestModeInfo.video_format = 0; @@ -419,6 +481,10 @@ int HDMIDisplay::getBestConfig() { bestModeInfo.refresh_rate = 0; bestModeInfo.ar = HDMI_RES_AR_INVALID; + // get S3D configs for all the modes + s3d_configs = new uint32_t[mModeCount]; + getS3DConfigs(s3d_configs); + // for all the timing info read, get the best config for (int configIndex = 0; configIndex < mModeCount; configIndex++) { currentModeInfo = mDisplayConfigs[configIndex]; @@ -429,6 +495,12 @@ int HDMIDisplay::getBestConfig() { continue; } + if (!IS_BIT_SET(s3d_configs[configIndex], s3d_mode)) { + ALOGD("%s EDID Mode %d cannot support s3d mode %d", __FUNCTION__, + edidMode, s3d_mode); + continue; + } + ALOGD_IF(DEBUG, "%s Best (%d) : (%dx%d) @ %d;" " Current (%d) (%dx%d) @ %d", __FUNCTION__, bestConfigIndex, bestModeInfo.active_h, @@ -458,6 +530,10 @@ int HDMIDisplay::getBestConfig() { bestModeInfo = mDisplayConfigs[bestConfigIndex]; } } + if (s3d_configs) { + delete [] s3d_configs; + s3d_configs = NULL; + } return bestConfigIndex; } diff --git a/libhdmi/hdmi.h b/libhdmi/hdmi.h index 274472a4d..57f18b2d9 100644 --- a/libhdmi/hdmi.h +++ b/libhdmi/hdmi.h @@ -24,6 +24,10 @@ #include <linux/fb.h> #include <video/msm_hdmi_modes.h> +#define SET_BIT(value, bit) (value |= (1 << (bit))) +#define CLEAR_BIT(value, bit) (value &= (~(1 << (bit)))) +#define IS_BIT_SET(value, bit) (value & (1 << (bit))) + struct msm_hdmi_mode_timing_info; namespace qhwc { @@ -79,7 +83,7 @@ private: bool isValidMode(int mode); int getModeOrder(int mode); int getUserConfig(); - int getBestConfig(); + int getBestConfig(int s3d_mode); bool isInterlacedMode(int mode); void resetInfo(); void setAttributes(); @@ -90,6 +94,7 @@ private: void readConfigs(); bool readResFile(char* configBuffer); bool writeS3DMode(int s3dMode); + void getS3DConfigs(uint32_t* s3d_configs); int mFd; int mFbNum; |