forked from FernetMenta/xbmc
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[IMX] probe & push all resolutions we can use
beside standard(S), try also DVI(U), VESA(V) - try in order S -> U -> V - don't add modes with resolution & refresh we alredy have - S are preferred (over other types with same XxYxR) because they come from EDID(CEA) and do pass requirements for proper hdmi audio out (this superseeds sam's PR and was rediscussed with fritsch on IRC.)
- Loading branch information
Showing
2 changed files
with
99 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ | |
CEGLNativeTypeIMX::CEGLNativeTypeIMX() | ||
: m_display(NULL) | ||
, m_window(NULL) | ||
, m_sar(0) | ||
{ | ||
} | ||
|
||
|
@@ -126,6 +127,7 @@ void CEGLNativeTypeIMX::Initialize() | |
|
||
close(fd); | ||
|
||
m_sar = GetMonitorSAR(); | ||
return; | ||
} | ||
|
||
|
@@ -262,24 +264,47 @@ bool CEGLNativeTypeIMX::SetNativeResolution(const RESOLUTION_INFO &res) | |
return true; | ||
} | ||
|
||
bool CEGLNativeTypeIMX::FindMatchingResolution(const RESOLUTION_INFO &res, const std::vector<RESOLUTION_INFO> &resolutions) | ||
{ | ||
for (int i = 0; i < (int)resolutions.size(); i++) | ||
{ | ||
if(resolutions[i].iScreenWidth == res.iScreenWidth && | ||
resolutions[i].iScreenHeight == res.iScreenHeight && | ||
resolutions[i].fRefreshRate == res.fRefreshRate && | ||
(resolutions[i].dwFlags & D3DPRESENTFLAG_MODEMASK) == (res.dwFlags & D3DPRESENTFLAG_MODEMASK)) | ||
{ | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
bool CEGLNativeTypeIMX::ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions) | ||
{ | ||
if (m_readonly) | ||
return false; | ||
|
||
std::string valstr; | ||
SysfsUtils::GetString("/sys/class/graphics/fb0/modes", valstr); | ||
std::vector<std::string> probe_str; | ||
probe_str = StringUtils::Split(valstr, "\n"); | ||
std::vector<std::string> probe_str = StringUtils::Split(valstr, "\n"); | ||
|
||
// lexical order puts the modes list into our preferred | ||
// order and by later filtering through FindMatchingResolution() | ||
// we make sure we read _all_ S modes, following U and V modes | ||
// while list will hold unique resolutions only | ||
std::sort(probe_str.begin(), probe_str.end()); | ||
|
||
resolutions.clear(); | ||
RESOLUTION_INFO res; | ||
for (size_t i = 0; i < probe_str.size(); i++) | ||
{ | ||
if(!StringUtils::StartsWith(probe_str[i], "S:")) | ||
if(!StringUtils::StartsWith(probe_str[i], "S:") && !StringUtils::StartsWith(probe_str[i], "U:") && | ||
!StringUtils::StartsWith(probe_str[i], "V:")) | ||
continue; | ||
|
||
if(ModeToResolution(probe_str[i], &res)) | ||
resolutions.push_back(res); | ||
if(!FindMatchingResolution(res, resolutions)) | ||
resolutions.push_back(res); | ||
} | ||
return resolutions.size() > 0; | ||
} | ||
|
@@ -300,6 +325,68 @@ bool CEGLNativeTypeIMX::ShowWindow(bool show) | |
return false; | ||
} | ||
|
||
float CEGLNativeTypeIMX::GetMonitorSAR() | ||
{ | ||
FILE *f_edid; | ||
char *str = NULL; | ||
unsigned char p; | ||
size_t n; | ||
int done = 0; | ||
|
||
// kernels <= 3.18 use ./soc0/soc.0 | ||
// kernels > 3.18 use ./soc0/soc | ||
f_edid = fopen("/sys/devices/soc0/soc/20e0000.hdmi_video/edid", "r"); | ||
if(!f_edid) | ||
f_edid = fopen("/sys/devices/soc0/soc.0/20e0000.hdmi_video/edid", "r"); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
fritsch
Owner
|
||
|
||
if(!f_edid) | ||
return 0; | ||
|
||
// we need to convert mxc_hdmi output format to binary array | ||
// mxc_hdmi provides the EDID as space delimited 1bytes blocks | ||
// exported as text with format specifier %x eg: | ||
// 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x4C 0x2D 0x7A 0x0A 0x00 0x00 0x00 0x00 | ||
// | ||
// this translates into the inner cycle where we move pointer first | ||
// with +2 to skip '0x', | ||
// we sscanf actual data (eg FF) into a byte, | ||
// we move over the FF and delimiting space with +3 | ||
// | ||
// this parses whole 512 byte long info into internal binary array for future | ||
// reference and use. current use is only to grab screen's physical params | ||
// at EGL init. | ||
while(getline(&str, &n, f_edid) > 0) | ||
{ | ||
char *c = str; | ||
while(*c != '\n' && done < 512) | ||
{ | ||
c += 2; | ||
sscanf(c, "%hhx", &p); | ||
m_edid[done++] = p; | ||
c += 3; | ||
} | ||
if (str) | ||
free(str); | ||
str = NULL; | ||
} | ||
fclose(f_edid); | ||
|
||
// info related to 'Basic display parameters.' is at offset 0x14-0x18. | ||
// where W is 2nd byte, H 3rd. | ||
int cmWidth = (int)*(m_edid +EDID_STRUCT_DISPLAY +1); | ||
int cmHeight = (int)*(m_edid +EDID_STRUCT_DISPLAY +2); | ||
if (cmHeight > 0) | ||
{ | ||
float t_sar = (float) cmWidth / cmHeight; | ||
if (t_sar >= 0.33 && t_sar <= 3.0) | ||
return t_sar; | ||
} | ||
|
||
// if we end up here, H/W values or final SAR are useless | ||
// return 0 and use 1.0f as PR for all resolutions | ||
return 0; | ||
} | ||
|
||
bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) const | ||
{ | ||
if (!res) | ||
|
@@ -334,7 +421,8 @@ bool CEGLNativeTypeIMX::ModeToResolution(std::string mode, RESOLUTION_INFO *res) | |
res->iScreen = 0; | ||
res->bFullScreen = true; | ||
res->iSubtitles = (int)(0.965 * res->iHeight); | ||
res->fPixelRatio = 1.0f; | ||
|
||
res->fPixelRatio = !m_sar ? 1.0f : (float)m_sar / res->iScreenWidth * res->iScreenHeight; | ||
res->strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", res->iScreenWidth, res->iScreenHeight, res->fRefreshRate, | ||
res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : ""); | ||
res->strId = mode; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
On Vero, this is osmc@vero:/sys/devices/soc0/soc.1/20e0000.hdmi_video on LK 3.14