Files
android_vendor_qcom_opensou…/libexternal/external.cpp
Jeykumar Sankaran c1f8682f7b display: Remove framebuffer HAL usage
This patch removes the usage of the framebuffer HAL which is
deprecated in JB MR1 onwards. The code is left for compatibility
such as conformance tests but it is unused for normal display
usage.

Change-Id: If98133bdaa759cdc41d4503ff695b225ee43cb6f

Conflicts:

	libhwcomposer/hwc_utils.cpp
2013-03-18 16:38:54 -04:00

766 lines
24 KiB
C++

/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define DEBUG 0
#include <ctype.h>
#include <fcntl.h>
#include <media/IAudioPolicyService.h>
#include <media/AudioSystem.h>
#include <utils/threads.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <linux/msm_mdp.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/resource.h>
#include <cutils/properties.h>
#include "hwc_utils.h"
#include "external.h"
#include "overlayUtils.h"
#include "overlay.h"
using namespace android;
namespace qhwc {
#define MAX_FRAME_BUFFER_NAME_SIZE (80)
#define MAX_DISPLAY_DEVICES (3)
const char* msmFbDevicePath[] = { "/dev/graphics/fb1",
"/dev/graphics/fb2"};
/*
* Updates extDeviceFbIndex Array with the correct frame buffer indices
* of avaiable external devices
*
*/
void ExternalDisplay::updateExtDispDevFbIndex()
{
FILE *displayDeviceFP = NULL;
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
for(int j = 1; j < MAX_DISPLAY_DEVICES; j++) {
sprintf (msmFbTypePath,"/sys/class/graphics/fb%d/msm_fb_type", j);
displayDeviceFP = fopen(msmFbTypePath, "r");
if(displayDeviceFP){
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
displayDeviceFP);
if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0){
ALOGD_IF(DEBUG,"hdmi framebuffer index is %d",j);
mHdmiFbNum = j;
} else if(strncmp(fbType, "writeback panel",
strlen("writeback panel")) == 0){
ALOGD_IF(DEBUG,"wfd framebuffer index is %d",j);
mWfdFbNum = j;
}
fclose(displayDeviceFP);
}
}
ALOGD_IF(DEBUG,"%s: mHdmiFbNum: %d mWfdFbNum: %d ",__FUNCTION__,
mHdmiFbNum, mWfdFbNum);
}
int ExternalDisplay::configureHDMIDisplay() {
openFrameBuffer(mHdmiFbNum);
if(mFd == -1)
return -1;
readCEUnderscanInfo();
readResolution();
// TODO: Move this to activate
/* Used for changing the resolution
* getUserMode will get the preferred
* mode set thru adb shell */
int mode = getUserMode();
if (mode == -1) {
//Get the best mode and set
mode = getBestMode();
}
setResolution(mode);
setDpyHdmiAttr();
setExternalDisplay(true, mHdmiFbNum);
return 0;
}
int ExternalDisplay::configureWFDDisplay() {
int ret = 0;
if(mConnectedFbNum == mHdmiFbNum) {
ALOGE("%s: Cannot process WFD connection while HDMI is active",
__FUNCTION__);
return -1;
}
openFrameBuffer(mWfdFbNum);
if(mFd == -1)
return -1;
ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
if(ret < 0) {
ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
strerror(errno));
}
setDpyWfdAttr();
setExternalDisplay(true, mWfdFbNum);
return 0;
}
int ExternalDisplay::teardownHDMIDisplay() {
if(mConnectedFbNum == mHdmiFbNum) {
// hdmi offline event..!
closeFrameBuffer();
resetInfo();
setExternalDisplay(false);
}
return 0;
}
int ExternalDisplay::teardownWFDDisplay() {
if(mConnectedFbNum == mWfdFbNum) {
// wfd offline event..!
closeFrameBuffer();
memset(&mVInfo, 0, sizeof(mVInfo));
setExternalDisplay(false);
}
return 0;
}
void ExternalDisplay::processUEventOnline(const char *str) {
const char *s1 = str + strlen("change@/devices/virtual/switch/");
if(!strncmp(s1,"hdmi",strlen(s1))) {
// hdmi online event..!
configureHDMIDisplay();
// set system property
property_set("hw.hdmiON", "1");
}else if(!strncmp(s1,"wfd",strlen(s1))) {
// wfd online event..!
configureWFDDisplay();
}
}
void ExternalDisplay::processUEventOffline(const char *str) {
const char *s1 = str + strlen("change@/devices/virtual/switch/");
if(!strncmp(s1,"hdmi",strlen(s1))) {
teardownHDMIDisplay();
// unset system property
property_set("hw.hdmiON", "0");
}else if(!strncmp(s1,"wfd",strlen(s1))) {
teardownWFDDisplay();
}
}
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
mUnderscanSupported(false), mHwcContext(ctx), mHdmiFbNum(-1),
mWfdFbNum(-1), mExtDpyNum(HWC_DISPLAY_EXTERNAL)
{
memset(&mVInfo, 0, sizeof(mVInfo));
//Determine the fb index for external display devices.
updateExtDispDevFbIndex();
}
void ExternalDisplay::setEDIDMode(int resMode) {
ALOGD_IF(DEBUG,"resMode=%d ", resMode);
{
Mutex::Autolock lock(mExtDispLock);
setExternalDisplay(false);
openFrameBuffer(mHdmiFbNum);
setResolution(resMode);
}
setExternalDisplay(true, mHdmiFbNum);
}
void ExternalDisplay::setHPD(uint32_t startEnd) {
ALOGD_IF(DEBUG,"HPD enabled=%d", startEnd);
writeHPDOption(startEnd);
}
void ExternalDisplay::setActionSafeDimension(int w, int h) {
ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
Mutex::Autolock lock(mExtDispLock);
char actionsafeWidth[PROPERTY_VALUE_MAX];
char actionsafeHeight[PROPERTY_VALUE_MAX];
sprintf(actionsafeWidth, "%d", w);
property_set("hw.actionsafe.width", actionsafeWidth);
sprintf(actionsafeHeight, "%d", h);
property_set("hw.actionsafe.height", actionsafeHeight);
setExternalDisplay(true, mHdmiFbNum);
}
int ExternalDisplay::getModeCount() const {
ALOGD_IF(DEBUG,"HPD mModeCount=%d", mModeCount);
Mutex::Autolock lock(mExtDispLock);
return mModeCount;
}
void ExternalDisplay::getEDIDModes(int *out) const {
Mutex::Autolock lock(mExtDispLock);
for(int i = 0;i < mModeCount;i++) {
out[i] = mEDIDModes[i];
}
}
void ExternalDisplay::readCEUnderscanInfo()
{
int hdmiScanInfoFile = -1;
int len = -1;
char scanInfo[17];
char *ce_info_str = NULL;
const char token[] = ", \n";
int ce_info = -1;
char sysFsScanInfoFilePath[128];
sprintf(sysFsScanInfoFilePath, "/sys/devices/virtual/graphics/fb%d/"
"scan_info", mHdmiFbNum);
memset(scanInfo, 0, sizeof(scanInfo));
hdmiScanInfoFile = open(sysFsScanInfoFilePath, O_RDONLY, 0);
if (hdmiScanInfoFile < 0) {
ALOGD_IF(DEBUG, "%s: scan_info file '%s' not found",
__FUNCTION__, sysFsScanInfoFilePath);
return;
} else {
len = read(hdmiScanInfoFile, scanInfo, sizeof(scanInfo)-1);
ALOGD("%s: Scan Info string: %s length = %d",
__FUNCTION__, scanInfo, len);
if (len <= 0) {
close(hdmiScanInfoFile);
ALOGE("%s: Scan Info file empty '%s'",
__FUNCTION__, sysFsScanInfoFilePath);
return;
}
scanInfo[len] = '\0'; /* null terminate the string */
}
close(hdmiScanInfoFile);
/*
* The scan_info contains the three fields
* PT - preferred video format
* IT - video format
* CE video format - containing the underscan support information
*/
/* PT */
ce_info_str = strtok(scanInfo, token);
if (ce_info_str) {
/* IT */
ce_info_str = strtok(NULL, token);
if (ce_info_str) {
/* CE */
ce_info_str = strtok(NULL, token);
if (ce_info_str)
ce_info = atoi(ce_info_str);
}
}
if (ce_info_str) {
// ce_info contains the underscan information
if (ce_info == EXT_SCAN_ALWAYS_UNDERSCANED ||
ce_info == EXT_SCAN_BOTH_SUPPORTED)
// if TV supported underscan, then driver will always underscan
// hence no need to apply action safe rectangle
mUnderscanSupported = true;
} else {
ALOGE("%s: scan_info string error", __FUNCTION__);
}
// Store underscan support info in a system property
const char* prop = (mUnderscanSupported) ? "1" : "0";
property_set("hw.underscan_supported", prop);
return;
}
ExternalDisplay::~ExternalDisplay()
{
closeFrameBuffer();
}
struct disp_mode_timing_type {
int video_format;
int active_h;
int active_v;
int front_porch_h;
int pulse_width_h;
int back_porch_h;
int front_porch_v;
int pulse_width_v;
int back_porch_v;
int pixel_freq;
bool interlaced;
void set_info(struct fb_var_screeninfo &info) const;
};
void disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const
{
info.reserved[0] = 0;
info.reserved[1] = 0;
info.reserved[2] = 0;
#ifndef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
info.reserved[3] = (info.reserved[3] & 0xFFFF) | (video_format << 16);
#endif
info.xoffset = 0;
info.yoffset = 0;
info.xres = active_h;
info.yres = active_v;
info.pixclock = pixel_freq*1000;
info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
info.right_margin = front_porch_h;
info.hsync_len = pulse_width_h;
info.left_margin = back_porch_h;
info.lower_margin = front_porch_v;
info.vsync_len = pulse_width_v;
info.upper_margin = back_porch_v;
}
/* Video formates supported by the HDMI Standard */
/* Indicates the resolution, pix clock and the aspect ratio */
#define m640x480p60_4_3 1
#define m720x480p60_4_3 2
#define m720x480p60_16_9 3
#define m1280x720p60_16_9 4
#define m1920x1080i60_16_9 5
#define m1440x480i60_4_3 6
#define m1440x480i60_16_9 7
#define m1920x1080p60_16_9 16
#define m720x576p50_4_3 17
#define m720x576p50_16_9 18
#define m1280x720p50_16_9 19
#define m1440x576i50_4_3 21
#define m1440x576i50_16_9 22
#define m1920x1080p50_16_9 31
#define m1920x1080p24_16_9 32
#define m1920x1080p25_16_9 33
#define m1920x1080p30_16_9 34
static struct disp_mode_timing_type supported_video_mode_lut[] = {
{m640x480p60_4_3, 640, 480, 16, 96, 48, 10, 2, 33, 25200, false},
{m720x480p60_4_3, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false},
{m720x480p60_16_9, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false},
{m1280x720p60_16_9, 1280, 720, 110, 40, 220, 5, 5, 20, 74250, false},
{m1920x1080i60_16_9, 1920, 540, 88, 44, 148, 2, 5, 5, 74250, false},
{m1440x480i60_4_3, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true},
{m1440x480i60_16_9, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true},
{m1920x1080p60_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 148500, false},
{m720x576p50_4_3, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false},
{m720x576p50_16_9, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false},
{m1280x720p50_16_9, 1280, 720, 440, 40, 220, 5, 5, 20, 74250, false},
{m1440x576i50_4_3, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true},
{m1440x576i50_16_9, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true},
{m1920x1080p50_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 148500, false},
{m1920x1080p24_16_9, 1920, 1080, 638, 44, 148, 4, 5, 36, 74250, false},
{m1920x1080p25_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 74250, false},
{m1920x1080p30_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 74250, false},
};
int ExternalDisplay::parseResolution(char* edidStr, int* edidModes)
{
char delim = ',';
int count = 0;
char *start, *end;
// EDIDs are string delimited by ','
// Ex: 16,4,5,3,32,34,1
// Parse this string to get mode(int)
start = (char*) edidStr;
end = &delim;
while(*end == delim) {
edidModes[count] = (int) strtol(start, &end, 10);
start = end+1;
count++;
}
ALOGD_IF(DEBUG, "In %s: count = %d", __FUNCTION__, count);
for (int i = 0; i < count; i++)
ALOGD_IF(DEBUG, "Mode[%d] = %d", i, edidModes[i]);
return count;
}
bool ExternalDisplay::readResolution()
{
char sysFsEDIDFilePath[255];
sprintf(sysFsEDIDFilePath , "/sys/devices/virtual/graphics/fb%d/edid_modes",
mHdmiFbNum);
int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0);
int len = -1;
if (hdmiEDIDFile < 0) {
ALOGE("%s: edid_modes file '%s' not found",
__FUNCTION__, sysFsEDIDFilePath);
return false;
} else {
len = read(hdmiEDIDFile, mEDIDs, sizeof(mEDIDs)-1);
ALOGD_IF(DEBUG, "%s: EDID string: %s length = %d",
__FUNCTION__, mEDIDs, len);
if ( len <= 0) {
ALOGE("%s: edid_modes file empty '%s'",
__FUNCTION__, sysFsEDIDFilePath);
}
else {
while (len > 1 && isspace(mEDIDs[len-1]))
--len;
mEDIDs[len] = 0;
}
}
close(hdmiEDIDFile);
if(len > 0) {
// Get EDID modes from the EDID strings
mModeCount = parseResolution(mEDIDs, mEDIDModes);
ALOGD_IF(DEBUG, "%s: mModeCount = %d", __FUNCTION__,
mModeCount);
}
return (strlen(mEDIDs) > 0);
}
bool ExternalDisplay::openFrameBuffer(int fbNum)
{
if (mFd == -1) {
mFd = open(msmFbDevicePath[fbNum-1], O_RDWR);
if (mFd < 0)
ALOGE("%s: %s is not available", __FUNCTION__,
msmFbDevicePath[fbNum-1]);
if(mHwcContext) {
mHwcContext->dpyAttr[mExtDpyNum].fd = mFd;
}
}
return (mFd > 0);
}
bool ExternalDisplay::closeFrameBuffer()
{
int ret = 0;
if(mFd >= 0) {
ret = close(mFd);
mFd = -1;
}
if(mHwcContext) {
mHwcContext->dpyAttr[mExtDpyNum].fd = mFd;
}
return (ret == 0);
}
// clears the vinfo, edid, best modes
void ExternalDisplay::resetInfo()
{
memset(&mVInfo, 0, sizeof(mVInfo));
memset(mEDIDs, 0, sizeof(mEDIDs));
memset(mEDIDModes, 0, sizeof(mEDIDModes));
mModeCount = 0;
mCurrentMode = -1;
mUnderscanSupported = false;
// Reset the underscan supported system property
const char* prop = "0";
property_set("hw.underscan_supported", prop);
}
int ExternalDisplay::getModeOrder(int mode)
{
// XXX: We dont support interlaced modes but having
// it here for for future
switch (mode) {
default:
case m1440x480i60_4_3:
return 1; // 480i 4:3
case m1440x480i60_16_9:
return 2; // 480i 16:9
case m1440x576i50_4_3:
return 3; // i576i 4:3
case m1440x576i50_16_9:
return 4; // 576i 16:9
case m640x480p60_4_3:
return 5; // 640x480 4:3
case m720x480p60_4_3:
return 6; // 480p 4:3
case m720x480p60_16_9:
return 7; // 480p 16:9
case m720x576p50_4_3:
return 8; // 576p 4:3
case m720x576p50_16_9:
return 9; // 576p 16:9
case m1920x1080i60_16_9:
return 10; // 1080i 16:9
case m1280x720p50_16_9:
return 11; // 720p@50Hz
case m1280x720p60_16_9:
return 12; // 720p@60Hz
case m1920x1080p24_16_9:
return 13; //1080p@24Hz
case m1920x1080p25_16_9:
return 14; //108-p@25Hz
case m1920x1080p30_16_9:
return 15; //1080p@30Hz
case m1920x1080p50_16_9:
return 16; //1080p@50Hz
case m1920x1080p60_16_9:
return 17; //1080p@60Hz
}
}
/// Returns the user mode set(if any) using adb shell
int ExternalDisplay::getUserMode() {
/* 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)) {
ALOGD_IF(DEBUG, "%s: setting the HDMI mode = %d", __FUNCTION__, mode);
return mode;
}
return -1;
}
// Get the best mode for the current HD TV
int ExternalDisplay::getBestMode() {
int bestOrder = 0;
int bestMode = m640x480p60_4_3;
Mutex::Autolock lock(mExtDispLock);
// 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;
}
}
return bestMode;
}
inline bool ExternalDisplay::isValidMode(int ID)
{
bool valid = false;
for (int i = 0; i < mModeCount; i++) {
if(ID == mEDIDModes[i]) {
valid = true;
break;
}
}
return valid;
}
// returns true if the mode(ID) is interlaced mode format
bool ExternalDisplay::isInterlacedMode(int ID) {
bool interlaced = false;
switch(ID) {
case m1440x480i60_4_3:
case m1440x480i60_16_9:
case m1440x576i50_4_3:
case m1440x576i50_16_9:
case m1920x1080i60_16_9:
interlaced = true;
default:
interlaced = false;
}
return interlaced;
}
void ExternalDisplay::setResolution(int ID)
{
struct fb_var_screeninfo info;
int ret = 0;
ret = ioctl(mFd, FBIOGET_VSCREENINFO, &mVInfo);
if(ret < 0) {
ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
strerror(errno));
}
ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
"(%d,%d,%d) %dMHz>", __FUNCTION__,
mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
mVInfo.pixclock/1000/1000);
//If its a new ID - update var_screeninfo
if ((isValidMode(ID)) && mCurrentMode != ID) {
const struct disp_mode_timing_type *mode =
&supported_video_mode_lut[0];
unsigned count = sizeof(supported_video_mode_lut)/sizeof
(*supported_video_mode_lut);
for (unsigned int i = 0; i < count; ++i) {
const struct disp_mode_timing_type *cur =
&supported_video_mode_lut[i];
if (cur->video_format == ID)
mode = cur;
}
mode->set_info(mVInfo);
ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
"(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
mode->video_format, mVInfo.xres, mVInfo.yres,
mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
mVInfo.pixclock/1000/1000);
#ifdef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
struct msmfb_metadata metadata;
memset(&metadata, 0 , sizeof(metadata));
metadata.op = metadata_op_vic;
metadata.data.video_info_code = mode->video_format;
if (ioctl(mFd, MSMFB_METADATA_SET, &metadata) == -1) {
ALOGD("In %s: MSMFB_METADATA_SET failed Err Str = %s",
__FUNCTION__, strerror(errno));
}
#endif
mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo);
if(ret < 0) {
ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s",
__FUNCTION__, strerror(errno));
}
mCurrentMode = ID;
}
}
void ExternalDisplay::setExternalDisplay(bool connected, int extFbNum)
{
hwc_context_t* ctx = mHwcContext;
if(ctx) {
ALOGD_IF(DEBUG, "%s: connected = %d", __FUNCTION__, connected);
// Store the external display
mConnected = connected;
mConnectedFbNum = extFbNum;
mHwcContext->dpyAttr[mExtDpyNum].connected = connected;
// Update external fb number in Overlay context
overlay::Overlay::getInstance()->setExtFbNum(extFbNum);
}
}
int ExternalDisplay::getExtFbNum(int &fbNum) {
int ret = -1;
if(mConnected) {
fbNum = mConnectedFbNum;
ret = 0;
}
return ret;
}
bool ExternalDisplay::writeHPDOption(int userOption) const
{
bool ret = true;
char sysFsHPDFilePath[255];
sprintf(sysFsHPDFilePath ,"/sys/devices/virtual/graphics/fb%d/hpd",
mHdmiFbNum);
int hdmiHPDFile = open(sysFsHPDFilePath,O_RDWR, 0);
if (hdmiHPDFile < 0) {
ALOGE("%s: state file '%s' not found : ret%d err str: %s", __FUNCTION__,
sysFsHPDFilePath, hdmiHPDFile, strerror(errno));
ret = false;
} else {
int err = -1;
ALOGD_IF(DEBUG, "%s: option = %d", __FUNCTION__, userOption);
if(userOption)
err = write(hdmiHPDFile, "1", 2);
else
err = write(hdmiHPDFile, "0" , 2);
if (err <= 0) {
ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath);
ret = false;
}
close(hdmiHPDFile);
}
return ret;
}
void ExternalDisplay::setDpyWfdAttr() {
if(mHwcContext) {
mHwcContext->dpyAttr[mExtDpyNum].xres = mVInfo.xres;
mHwcContext->dpyAttr[mExtDpyNum].yres = mVInfo.yres;
mHwcContext->dpyAttr[mExtDpyNum].vsync_period =
1000000000l /60;
ALOGD_IF(DEBUG,"%s: wfd...connected..!",__FUNCTION__);
}
}
void ExternalDisplay::setDpyHdmiAttr() {
int width = 0, height = 0, fps = 0;
getAttrForMode(width, height, fps);
if(mHwcContext) {
ALOGD("ExtDisplay setting xres = %d, yres = %d", width, height);
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width;
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height;
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
1000000000l / fps;
}
}
void ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
switch (mCurrentMode) {
case m640x480p60_4_3:
width = 640;
height = 480;
fps = 60;
break;
case m720x480p60_4_3:
case m720x480p60_16_9:
width = 720;
height = 480;
fps = 60;
break;
case m720x576p50_4_3:
case m720x576p50_16_9:
width = 720;
height = 576;
fps = 50;
break;
case m1280x720p50_16_9:
width = 1280;
height = 720;
fps = 50;
break;
case m1280x720p60_16_9:
width = 1280;
height = 720;
fps = 60;
break;
case m1920x1080p24_16_9:
width = 1920;
height = 1080;
fps = 24;
break;
case m1920x1080p25_16_9:
width = 1920;
height = 1080;
fps = 25;
break;
case m1920x1080p30_16_9:
width = 1920;
height = 1080;
fps = 30;
break;
case m1920x1080p50_16_9:
width = 1920;
height = 1080;
fps = 50;
break;
case m1920x1080p60_16_9:
width = 1920;
height = 1080;
fps = 60;
break;
}
}
};