hwc: hdmi: Use res_info sysfs node to get HDMI timing info
This change removes the use of static declarations in the HDMI library
that were used to configure the HDMI class with the best mode.
We now rely on the res_info sysfs node to provide timing information
on request for supported modes. Furthermore, we now dynamically compare
HDMI modes in order of height, width, refresh rate and aspect ratio, when
we want to determine the best configuration.
Note: SurfaceFlinger currently has a limit of 128 modes but HDMI can
potentially provide more that 128 modes. In use cases when HDMI provides
more than 128 modes, the HAL needs to sort and provide the best 128 modes.
Change-Id: If4ed8845fb77024771dde15fe23dfcee515d93d2
diff --git a/libhdmi/hdmi.cpp b/libhdmi/hdmi.cpp
index 7d709cb..bca7a0b 100644
--- a/libhdmi/hdmi.cpp
+++ b/libhdmi/hdmi.cpp
@@ -21,7 +21,6 @@
#define DEBUG 0
#include <fcntl.h>
#include <linux/msm_mdp.h>
-#include <video/msm_hdmi_modes.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <cutils/properties.h>
@@ -38,62 +37,6 @@
#define UNKNOWN_STRING "unknown"
#define SPD_NAME_LENGTH 16
-/* The array gEDIDData contains a list of modes currently
- * supported by HDMI and display, and modes that are not
- * supported i.e. interlaced modes.
-
- * In order to add support for a new mode, the mode must be
- * appended to the end of the array.
- *
- * Each new entry must contain the following:
- * -Mode: a video format defined in msm_hdmi_modes.h
- * -Width: x resolution for the mode
- * -Height: y resolution for the mode
- * -FPS: the frame rate for the mode
- * -Mode Order: the priority for the new mode that is used when determining
- * the best mode when the HDMI display is connected.
- */
-EDIDData gEDIDData [] = {
- EDIDData(HDMI_VFRMT_1440x480i60_4_3, 1440, 480, 60, 1),
- EDIDData(HDMI_VFRMT_1440x480i60_16_9, 1440, 480, 60, 2),
- EDIDData(HDMI_VFRMT_1440x576i50_4_3, 1440, 576, 50, 3),
- EDIDData(HDMI_VFRMT_1440x576i50_16_9, 1440, 576, 50, 4),
- EDIDData(HDMI_VFRMT_1920x1080i60_16_9, 1920, 1080, 60, 5),
- EDIDData(HDMI_VFRMT_640x480p60_4_3, 640, 480, 60, 6),
- EDIDData(HDMI_VFRMT_720x480p60_4_3, 720, 480, 60, 7),
- EDIDData(HDMI_VFRMT_720x480p60_16_9, 720, 480, 60, 8),
- EDIDData(HDMI_VFRMT_720x576p50_4_3, 720, 576, 50, 9),
- EDIDData(HDMI_VFRMT_720x576p50_16_9, 720, 576, 50, 10),
- EDIDData(HDMI_VFRMT_800x600p60_4_3, 800, 600, 60, 11),
- EDIDData(HDMI_VFRMT_848x480p60_16_9, 848, 480, 60, 12),
- EDIDData(HDMI_VFRMT_1024x768p60_4_3, 1024, 768, 60, 13),
- EDIDData(HDMI_VFRMT_1280x1024p60_5_4, 1280, 1024, 60, 14),
- EDIDData(HDMI_VFRMT_1280x720p50_16_9, 1280, 720, 50, 15),
- EDIDData(HDMI_VFRMT_1280x720p60_16_9, 1280, 720, 60, 16),
- EDIDData(HDMI_VFRMT_1280x800p60_16_10, 1280, 800, 60, 17),
- EDIDData(HDMI_VFRMT_1280x960p60_4_3, 1280, 960, 60, 18),
- EDIDData(HDMI_VFRMT_1360x768p60_16_9, 1360, 768, 60, 19),
- EDIDData(HDMI_VFRMT_1366x768p60_16_10, 1366, 768, 60, 20),
- EDIDData(HDMI_VFRMT_1440x900p60_16_10, 1440, 900, 60, 21),
- EDIDData(HDMI_VFRMT_1400x1050p60_4_3, 1400, 1050, 60, 22),
- EDIDData(HDMI_VFRMT_1680x1050p60_16_10, 1680, 1050, 60, 23),
- EDIDData(HDMI_VFRMT_1600x1200p60_4_3, 1600, 1200, 60, 24),
- EDIDData(HDMI_VFRMT_1920x1080p24_16_9, 1920, 1080, 24, 25),
- EDIDData(HDMI_VFRMT_1920x1080p25_16_9, 1920, 1080, 25, 26),
- EDIDData(HDMI_VFRMT_1920x1080p30_16_9, 1920, 1080, 30, 27),
- EDIDData(HDMI_VFRMT_1920x1080p50_16_9, 1920, 1080, 50, 28),
- EDIDData(HDMI_VFRMT_1920x1080p60_16_9, 1920, 1080, 60, 29),
- EDIDData(HDMI_VFRMT_1920x1200p60_16_10, 1920, 1200, 60, 30),
- EDIDData(HDMI_VFRMT_2560x1600p60_16_9, 2560, 1600, 60, 31),
- EDIDData(HDMI_VFRMT_3840x2160p24_16_9, 3840, 2160, 24, 32),
- EDIDData(HDMI_VFRMT_3840x2160p25_16_9, 3840, 2160, 25, 33),
- EDIDData(HDMI_VFRMT_3840x2160p30_16_9, 3840, 2160, 30, 34),
- EDIDData(HDMI_VFRMT_4096x2160p24_16_9, 4096, 2160, 24, 35),
-};
-
-// Number of modes in gEDIDData
-const int gEDIDCount = (sizeof(gEDIDData)/sizeof(gEDIDData)[0]);
-
int HDMIDisplay::configure() {
if(!openFrameBuffer()) {
ALOGE("%s: Failed to open FB: %d", __FUNCTION__, mFbNum);
@@ -135,8 +78,8 @@
}
void HDMIDisplay::getAttributes(uint32_t& width, uint32_t& height) {
- uint32_t fps = 0;
- getAttrForMode(width, height, fps);
+ uint32_t refresh = 0, fps = 0;
+ getAttrForConfig(mActiveConfig, width, height, refresh, fps);
}
int HDMIDisplay::teardown() {
@@ -167,14 +110,7 @@
writeHPDOption(0);
}
- // for HDMI - retreive all the modes supported by the driver
if(mFbNum != -1) {
- supported_video_mode_lut =
- new msm_hdmi_mode_timing_info[HDMI_VFRMT_MAX];
- // Populate the mode table for supported modes
- MSM_HDMI_MODES_INIT_TIMINGS(supported_video_mode_lut);
- MSM_HDMI_MODES_SET_SUPP_TIMINGS(supported_video_mode_lut,
- MSM_HDMI_MODES_ALL);
// Update the Source Product Information
// Vendor Name
setSPDInfo("vendor_name", "ro.product.manufacturer");
@@ -298,7 +234,6 @@
HDMIDisplay::~HDMIDisplay()
{
- delete [] supported_video_mode_lut;
closeFrameBuffer();
}
@@ -356,7 +291,7 @@
bool HDMIDisplay::readResolution()
{
ssize_t len = -1;
- char edidStr[128] = {'\0'};
+ char edidStr[PAGE_SIZE] = {'\0'};
int hdmiEDIDFile = openDeviceNode("edid_modes", O_RDONLY);
if (hdmiEDIDFile < 0) {
@@ -383,6 +318,25 @@
ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
mModeCount);
}
+ // Populate the internal data structure with the timing information
+ // for each edid mode read from the driver
+ if (mModeCount > 0) {
+ mDisplayConfigs = new msm_hdmi_mode_timing_info[mModeCount];
+ readConfigs();
+ } else {
+ // If we fail to read from EDID when HDMI is connected, then
+ // mModeCount will be 0 and bestConfigIndex will be invalid.
+ // In this case, we populate the mEDIDModes structure with
+ // a default mode at config index 0.
+ uint32_t defaultConfigIndex = 0;
+ mModeCount = 1;
+ mEDIDModes[defaultConfigIndex] = HDMI_VFRMT_640x480p60_4_3;
+ struct msm_hdmi_mode_timing_info defaultMode =
+ HDMI_VFRMT_640x480p60_4_3_TIMING;
+ mDisplayConfigs = new msm_hdmi_mode_timing_info[mModeCount];
+ mDisplayConfigs[defaultConfigIndex] = defaultMode;
+ ALOGD("%s Defaulting to HDMI_VFRMT_640x480p60_4_3", __FUNCTION__);
+ }
return (len > 0);
}
@@ -421,30 +375,22 @@
mYres = 0;
mVsyncPeriod = 0;
mMDPScalingMode = false;
+ if (mDisplayConfigs) {
+ delete [] mDisplayConfigs;
+ mDisplayConfigs = 0;
+ }
// Reset the underscan supported system property
const char* prop = "0";
property_set("hw.underscan_supported", prop);
}
-int HDMIDisplay::getModeOrder(int mode)
-{
- for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
- if (gEDIDData[dataIndex].mMode == mode) {
- return gEDIDData[dataIndex].mModeOrder;
- }
- }
- ALOGE("%s Mode not found: %d", __FUNCTION__, mode);
- return -1;
-}
-
/// Returns the index of the user mode set(if any) using adb shell
int HDMIDisplay::getUserConfig() {
/* Based on the property set the resolution */
char property_value[PROPERTY_VALUE_MAX];
property_get("hw.hdmi.resolution", property_value, "-1");
int mode = atoi(property_value);
- // We dont support interlaced modes
- if(isValidMode(mode) && !isInterlacedMode(mode)) {
+ if(isValidMode(mode)) {
ALOGD_IF(DEBUG, "%s: setting the HDMI mode = %d", __FUNCTION__, mode);
return getModeIndex(mode);
}
@@ -453,61 +399,137 @@
// Get the index of the best mode for the current HD TV
int HDMIDisplay::getBestConfig() {
- int bestOrder = 0;
- int bestMode = HDMI_VFRMT_640x480p60_4_3;
- int bestModeIndex = -1;
- // for all the edid read, get the best mode
- for(int i = 0; i < mModeCount; i++) {
- int mode = mEDIDModes[i];
- int order = getModeOrder(mode);
- if (order > bestOrder) {
- bestOrder = order;
- bestMode = mode;
- bestModeIndex = i;
+ int bestConfigIndex = 0;
+ int edidMode = -1;
+ struct msm_hdmi_mode_timing_info currentModeInfo = {0};
+ struct msm_hdmi_mode_timing_info bestModeInfo = {0};
+ bestModeInfo.video_format = 0;
+ bestModeInfo.active_v = 0;
+ bestModeInfo.active_h = 0;
+ bestModeInfo.refresh_rate = 0;
+ bestModeInfo.ar = HDMI_RES_AR_INVALID;
+
+ // for all the timing info read, get the best config
+ for (int configIndex = 0; configIndex < mModeCount; configIndex++) {
+ currentModeInfo = mDisplayConfigs[configIndex];
+
+ if (!currentModeInfo.supported) {
+ ALOGD("%s EDID Mode %d is not supported", __FUNCTION__, edidMode);
+ continue;
+ }
+
+ ALOGD_IF(DEBUG, "%s Best (%d) : (%dx%d) @ %d;"
+ " Current (%d) (%dx%d) @ %d",
+ __FUNCTION__, bestConfigIndex, bestModeInfo.active_h,
+ bestModeInfo.active_v, bestModeInfo.refresh_rate, configIndex,
+ currentModeInfo.active_h, currentModeInfo.active_v,
+ currentModeInfo.refresh_rate);
+
+ // Compare two HDMI modes in order of height, width, refresh rate and
+ // aspect ratio.
+ if (currentModeInfo.active_v > bestModeInfo.active_v) {
+ bestConfigIndex = configIndex;
+ } else if (currentModeInfo.active_v == bestModeInfo.active_v) {
+ if (currentModeInfo.active_h > bestModeInfo.active_h) {
+ bestConfigIndex = configIndex;
+ } else if (currentModeInfo.active_h == bestModeInfo.active_h) {
+ if (currentModeInfo.refresh_rate > bestModeInfo.refresh_rate) {
+ bestConfigIndex = configIndex;
+ } else if (currentModeInfo.refresh_rate ==
+ bestModeInfo.refresh_rate) {
+ if (currentModeInfo.ar > bestModeInfo.ar) {
+ bestConfigIndex = configIndex;
+ }
+ }
+ }
+ }
+ if (bestConfigIndex == configIndex) {
+ bestModeInfo = mDisplayConfigs[bestConfigIndex];
}
}
- // If we fail to read from EDID when HDMI is connected, then
- // mModeCount will be 0 and bestModeIndex will be invalid.
- // In this case, we populate the mEDIDModes structure with
- // a default mode at index 0.
- if (bestModeIndex == -1) {
- bestModeIndex = 0;
- mModeCount = 1;
- mEDIDModes[bestModeIndex] = bestMode;
+ return bestConfigIndex;
+}
+
+// Utility function used to request HDMI driver to write a new page of timing
+// info into res_info node
+void HDMIDisplay::requestNewPage(int pageNumber) {
+ char pageString[PAGE_SIZE];
+ int fd = openDeviceNode("res_info", O_WRONLY);
+ if (fd >= 0) {
+ snprintf(pageString, sizeof(pageString), "%d", pageNumber);
+ ALOGD_IF(DEBUG, "%s: page=%s", __FUNCTION__, pageString);
+ ssize_t err = write(fd, pageString, sizeof(pageString));
+ if (err <= 0) {
+ ALOGE("%s: Write to res_info failed (%d)", __FUNCTION__, errno);
+ }
+ close(fd);
}
- return bestModeIndex;
+}
+
+// Reads the contents of res_info node into a buffer if the file is not empty
+bool HDMIDisplay::readResFile(char * configBuffer) {
+ bool fileRead = false;
+ size_t bytesRead = 0;
+ int fd = openDeviceNode("res_info", O_RDONLY);
+ if (fd >= 0 && (bytesRead = read(fd, configBuffer, PAGE_SIZE)) != 0) {
+ fileRead = true;
+ }
+ close(fd);
+ ALOGD_IF(DEBUG, "%s: bytesRead=%d fileRead=%d",
+ __FUNCTION__, bytesRead, fileRead);
+ return fileRead;
+}
+
+// Populates the internal timing info structure with the timing info obtained
+// from the HDMI driver
+void HDMIDisplay::readConfigs() {
+ int configIndex = 0;
+ int pageNumber = MSM_HDMI_INIT_RES_PAGE;
+ long unsigned int size = sizeof(msm_hdmi_mode_timing_info);
+
+ while (true) {
+ char configBuffer[PAGE_SIZE] = {0};
+ msm_hdmi_mode_timing_info *info =
+ (msm_hdmi_mode_timing_info*) configBuffer;
+
+ if (!readResFile(configBuffer))
+ break;
+
+ while (info->video_format && size < PAGE_SIZE) {
+ mDisplayConfigs[configIndex] = *info;
+ size += sizeof(msm_hdmi_mode_timing_info);
+ info++;
+ ALOGD_IF(DEBUG, "%s: Config=%d Mode %d: (%dx%d) @ %d",
+ __FUNCTION__, configIndex,
+ mDisplayConfigs[configIndex].video_format,
+ mDisplayConfigs[configIndex].active_h,
+ mDisplayConfigs[configIndex].active_v,
+ mDisplayConfigs[configIndex].refresh_rate);
+ configIndex++;
+ }
+ size = sizeof(msm_hdmi_mode_timing_info);
+ // Request HDMI driver to populate res_info with more
+ // timing information
+ pageNumber++;
+ requestNewPage(pageNumber);
+ }
}
inline bool HDMIDisplay::isValidMode(int ID)
{
bool valid = false;
- for (int i = 0; i < mModeCount; i++) {
- if(ID == mEDIDModes[i]) {
- valid = true;
- break;
- }
+ int modeIndex = getModeIndex(ID);
+ if (ID <= 0 || modeIndex < 0 || modeIndex > mModeCount) {
+ return false;
+ }
+ struct msm_hdmi_mode_timing_info* mode = &mDisplayConfigs[modeIndex];
+ // We dont support interlaced modes
+ if (mode->supported && !mode->interlaced) {
+ valid = true;
}
return valid;
}
-// returns true if the mode(ID) is interlaced mode format
-bool HDMIDisplay::isInterlacedMode(int ID) {
- bool interlaced = false;
- switch(ID) {
- case HDMI_VFRMT_1440x480i60_4_3:
- case HDMI_VFRMT_1440x480i60_16_9:
- case HDMI_VFRMT_1440x576i50_4_3:
- case HDMI_VFRMT_1440x576i50_16_9:
- case HDMI_VFRMT_1920x1080i60_16_9:
- interlaced = true;
- break;
- default:
- interlaced = false;
- break;
- }
- return interlaced;
-}
-
// Does a put_vscreen info on the HDMI interface which will update
// the configuration (resolution, timing info) to match mCurrentMode
void HDMIDisplay::activateDisplay()
@@ -525,16 +547,7 @@
mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
mVInfo.pixclock/1000/1000);
- const struct msm_hdmi_mode_timing_info *mode =
- &supported_video_mode_lut[0];
- for (unsigned int i = 0; i < HDMI_VFRMT_MAX; ++i) {
- const struct msm_hdmi_mode_timing_info *cur =
- &supported_video_mode_lut[i];
- if (cur->video_format == (uint32_t)mCurrentMode) {
- mode = cur;
- break;
- }
- }
+ struct msm_hdmi_mode_timing_info *mode = &mDisplayConfigs[mActiveConfig];
setDisplayTiming(mVInfo, mode);
ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
"(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, mCurrentMode,
@@ -585,9 +598,9 @@
void HDMIDisplay::setAttributes() {
- uint32_t fps = 0;
+ uint32_t refresh = 0, fps = 0;
// Always set dpyAttr res to mVInfo res
- getAttrForMode(mXres, mYres, fps);
+ getAttrForConfig(mActiveConfig, mXres, mYres, refresh, fps);
mMDPScalingMode = false;
if(overlay::Overlay::getInstance()->isUIScalingOnExternalSupported()
@@ -653,19 +666,6 @@
ALOGD_IF(DEBUG, "%s xres=%d, yres=%d", __FUNCTION__, mXres, mYres);
}
-void HDMIDisplay::getAttrForMode(uint32_t& width, uint32_t& height,
- uint32_t& fps) {
- for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
- if (gEDIDData[dataIndex].mMode == mCurrentMode) {
- width = gEDIDData[dataIndex].mWidth;
- height = gEDIDData[dataIndex].mHeight;
- fps = gEDIDData[dataIndex].mFps;
- return;
- }
- }
- ALOGE("%s Unable to get attributes for %d", __FUNCTION__, mCurrentMode);
-}
-
/* returns the fd related to the node specified*/
int HDMIDisplay::openDeviceNode(const char* node, int fileMode) const {
char sysFsFilePath[MAX_SYSFS_FILE_PATH];
@@ -743,8 +743,8 @@
// not match the current config
bool HDMIDisplay::isValidConfigChange(int newConfig) {
int newMode = mEDIDModes[newConfig];
- uint32_t width = 0, height = 0, refresh = 0;
- getAttrForConfig(newConfig, width, height, refresh);
+ uint32_t width = 0, height = 0, refresh = 0, fps = 0;
+ getAttrForConfig(newConfig, width, height, refresh, fps);
return ((mXres == width) && (mYres == height)) || mEnableResolutionChange;
}
@@ -760,21 +760,16 @@
}
int HDMIDisplay::getAttrForConfig(int config, uint32_t& xres,
- uint32_t& yres, uint32_t& refresh) const {
+ uint32_t& yres, uint32_t& refresh, uint32_t& fps) const {
if(config < 0 || config > mModeCount) {
ALOGE("%s Invalid configuration %d", __FUNCTION__, config);
return -EINVAL;
}
- int mode = mEDIDModes[config];
- uint32_t fps = 0;
- // Retrieve the mode attributes from gEDIDData
- for (int dataIndex = 0; dataIndex < gEDIDCount; dataIndex++) {
- if (gEDIDData[dataIndex].mMode == mode) {
- xres = gEDIDData[dataIndex].mWidth;
- yres = gEDIDData[dataIndex].mHeight;
- fps = gEDIDData[dataIndex].mFps;
- }
- }
+
+ xres = mDisplayConfigs[config].active_h;
+ yres = mDisplayConfigs[config].active_v;
+ fps = (mDisplayConfigs[config].refresh_rate / 1000);
+
refresh = (uint32_t) 1000000000l / fps;
ALOGD_IF(DEBUG, "%s xres(%d) yres(%d) fps(%d) refresh(%d)", __FUNCTION__,
xres, yres, fps, refresh);
diff --git a/libhdmi/hdmi.h b/libhdmi/hdmi.h
index d262a63..32c48ff 100644
--- a/libhdmi/hdmi.h
+++ b/libhdmi/hdmi.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -22,6 +22,7 @@
#define HWC_HDMI_DISPLAY_H
#include <linux/fb.h>
+#include <video/msm_hdmi_modes.h>
struct msm_hdmi_mode_timing_info;
@@ -35,16 +36,6 @@
HDMI_SCAN_BOTH_SUPPORTED = 3
};
-// Structure to store EDID related data
-struct EDIDData {
- int mMode, mWidth, mHeight, mFps;
- // Predetermined ordering for each mode
- int mModeOrder;
- EDIDData(int mode, int width, int height, int fps, int order)
- : mMode(mode), mWidth(width), mHeight(height), mFps(fps), mModeOrder(order)
- { }
-};
-
class HDMIDisplay
{
public:
@@ -71,7 +62,7 @@
int getActiveConfig() const { return mActiveConfig; };
int setActiveConfig(int newConfig);
int getAttrForConfig(int config, uint32_t& xres,
- uint32_t& yres, uint32_t& refresh) const;
+ uint32_t& yres, uint32_t& refresh, uint32_t& fps) const;
int getDisplayConfigs(uint32_t* configs, size_t* numConfigs) const;
private:
@@ -90,10 +81,12 @@
bool isInterlacedMode(int mode);
void resetInfo();
void setAttributes();
- void getAttrForMode(uint32_t& width, uint32_t& height, uint32_t& fps);
int openDeviceNode(const char* node, int fileMode) const;
int getModeIndex(int mode);
bool isValidConfigChange(int newConfig);
+ void requestNewPage(int pageNumber);
+ void readConfigs();
+ bool readResFile(char* configBuffer);
int mFd;
int mFbNum;
@@ -105,11 +98,11 @@
int mActiveConfig;
// mEDIDModes contains a list of HDMI video formats (modes) supported by the
// HDMI display
- int mEDIDModes[64];
+ int mEDIDModes[HDMI_VFRMT_MAX];
int mModeCount;
fb_var_screeninfo mVInfo;
// Holds all the HDMI modes and timing info supported by driver
- msm_hdmi_mode_timing_info* supported_video_mode_lut;
+ msm_hdmi_mode_timing_info *mDisplayConfigs;
uint32_t mXres, mYres, mVsyncPeriod, mPrimaryWidth, mPrimaryHeight;
bool mMDPScalingMode;
bool mUnderscanSupported;
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index fd3bb69..32e8474 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -809,10 +809,11 @@
const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
sizeof(DISPLAY_ATTRIBUTES)[0]);
- uint32_t xres = 0, yres = 0, refresh = 0;
+ uint32_t xres = 0, yres = 0, refresh = 0, fps = 0;
int ret = 0;
if (hotPluggable) {
- ret = ctx->mHDMIDisplay->getAttrForConfig(config, xres, yres, refresh);
+ ret = ctx->mHDMIDisplay->getAttrForConfig(config, xres,
+ yres, refresh, fps);
if(ret < 0) {
ALOGE("%s Error getting attributes for config %d",
__FUNCTION__, config);