display: Add support for overscan compensation for ext display
- Read scan_info sys file node to check if TV underscans
- Apply action safe parameters to avoid overscan on ext display
- Store action safe width and height ratio using system property
- Use these to calculate the destination position on the ext display
- Remove unsed ActionSafe Class
Change-Id: Id27e6fa20966fb13fc16aa7e237cacce8caeb642
CRs-fixed: 447367
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index b721195..2660c97 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -85,6 +85,7 @@
openFrameBuffer(mHdmiFbNum);
if(mFd == -1)
return -1;
+ readCEUnderscanInfo();
readResolution();
// TODO: Move this to activate
/* Used for changing the resolution
@@ -167,7 +168,7 @@
ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
- mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
+ mUnderscanSupported(false), mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
{
memset(&mVInfo, 0, sizeof(mVInfo));
//Determine the fb index for external display devices.
@@ -193,7 +194,12 @@
void ExternalDisplay::setActionSafeDimension(int w, int h) {
ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
Mutex::Autolock lock(mExtDispLock);
- overlay::utils::ActionSafe::getInstance()->setDimension(w, h);
+ 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);
}
@@ -210,6 +216,75 @@
}
}
+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();
@@ -393,6 +468,10 @@
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)
diff --git a/libexternal/external.h b/libexternal/external.h
index d85ce44..baf3598 100644
--- a/libexternal/external.h
+++ b/libexternal/external.h
@@ -28,6 +28,13 @@
namespace qhwc {
+//Type of scanning of EDID(Video Capability Data Block)
+enum external_scansupport_type {
+ EXT_SCAN_NOT_SUPPORTED = 0,
+ EXT_SCAN_ALWAYS_OVERSCANED = 1,
+ EXT_SCAN_ALWAYS_UNDERSCANED = 2,
+ EXT_SCAN_BOTH_SUPPORTED = 3
+};
class ExternalDisplay
{
@@ -36,6 +43,7 @@
~ExternalDisplay();
int getModeCount() const;
void getEDIDModes(int *out) const;
+ bool isCEUnderscanSupported() { return mUnderscanSupported; }
void setExternalDisplay(bool connected, int extFbNum = 0);
bool isExternalConnected() { return mConnected;};
bool post();
@@ -46,6 +54,7 @@
void processUEventOffline(const char *str);
private:
+ void readCEUnderscanInfo();
bool readResolution();
int parseResolution(char* edidStr, int* edidModes);
void setResolution(int ID);
@@ -78,6 +87,7 @@
char mEDIDs[128];
int mEDIDModes[64];
int mModeCount;
+ bool mUnderscanSupported;
hwc_context_t *mHwcContext;
fb_var_screeninfo mVInfo;
int mHdmiFbNum;