display: External display refactor
- cleans up external library
- add separate library for virtual display
- process virtual updates in its separate path
in hwc.
- Acquire blank mutex lock for one complete drawing
cycle
Change-Id: Ib984c578464a131ecdb27ee48960f58d68b7a5a7
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index 97f031d..b247dfb 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -21,8 +21,6 @@
#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>
@@ -31,8 +29,6 @@
#include <video/msm_hdmi_modes.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"
@@ -42,53 +38,15 @@
using namespace android;
namespace qhwc {
-
-#define MAX_FRAME_BUFFER_NAME_SIZE (80)
-#define MAX_DISPLAY_DEVICES (3)
#define MAX_SYSFS_FILE_PATH 255
#define UNKNOWN_STRING "unknown"
#define SPD_NAME_LENGTH 16
-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++) {
- snprintf (msmFbTypePath, sizeof(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)
+int ExternalDisplay::configure() {
+ if(!openFrameBuffer()) {
+ ALOGE("%s: Failed to open FB: %d", __FUNCTION__, mFbNum);
return -1;
+ }
readCEUnderscanInfo();
readResolution();
// TODO: Move this to activate
@@ -101,82 +59,33 @@
mode = getBestMode();
}
setResolution(mode);
- setDpyHdmiAttr();
- setExternalDisplay(true, mHdmiFbNum);
+ setAttributes();
// set system property
property_set("hw.hdmiON", "1");
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);
+int ExternalDisplay::teardown() {
+ closeFrameBuffer();
+ resetInfo();
+ // unset system property
+ property_set("hw.hdmiON", "0");
return 0;
}
-int ExternalDisplay::teardownHDMIDisplay() {
- if(mConnectedFbNum == mHdmiFbNum) {
- // hdmi offline event..!
- closeFrameBuffer();
- resetInfo();
- setExternalDisplay(false);
- // unset system property
- property_set("hw.hdmiON", "0");
- }
- return 0;
-}
-
-int ExternalDisplay::teardownWFDDisplay() {
- if(mConnectedFbNum == mWfdFbNum) {
- // wfd offline event..!
- closeFrameBuffer();
- memset(&mVInfo, 0, sizeof(mVInfo));
- setExternalDisplay(false);
- }
- return 0;
-}
-
-int ExternalDisplay::ignoreRequest(const char *str) {
- const char *s1 = str + strlen("change@/devices/virtual/switch/");
- if(!strncmp(s1,"wfd",strlen(s1))) {
- if(mConnectedFbNum == mHdmiFbNum) {
- ALOGE("Ignore wfd event when HDMI is active");
- return true;
- }
- }
- return false;
-}
-
-
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)
+ mCurrentMode(-1), mModeCount(0),
+ mUnderscanSupported(false), mHwcContext(ctx)
{
memset(&mVInfo, 0, sizeof(mVInfo));
- //Determine the fb index for external display devices.
- updateExtDispDevFbIndex();
+ mFbNum = overlay::Overlay::getInstance()->getFbForDpy(HWC_DISPLAY_EXTERNAL);
// disable HPD at start, it will be enabled later
// when the display powers on
// This helps for framework reboot or adb shell stop/start
writeHPDOption(0);
// for HDMI - retreive all the modes supported by the driver
- if(mHdmiFbNum != -1) {
+ if(mFbNum != -1) {
supported_video_mode_lut =
new msm_hdmi_mode_timing_info[HDMI_VFRMT_MAX];
// Populate the mode table for supported modes
@@ -201,7 +110,7 @@
memset(sysFsSPDFilePath, 0, sizeof(sysFsSPDFilePath));
snprintf(sysFsSPDFilePath , sizeof(sysFsSPDFilePath),
"/sys/devices/virtual/graphics/fb%d/%s",
- mHdmiFbNum, node);
+ mFbNum, node);
int spdFile = open(sysFsSPDFilePath, O_RDWR, 0);
if (spdFile < 0) {
ALOGE("%s: file '%s' not found : ret = %d"
@@ -225,17 +134,6 @@
}
}
-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);
@@ -243,24 +141,20 @@
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];
snprintf(actionsafeWidth, sizeof(actionsafeWidth), "%d", w);
property_set("persist.sys.actionsafe.width", actionsafeWidth);
snprintf(actionsafeHeight, sizeof(actionsafeHeight), "%d", h);
property_set("persist.sys.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];
}
@@ -277,7 +171,7 @@
char sysFsScanInfoFilePath[MAX_SYSFS_FILE_PATH];
snprintf(sysFsScanInfoFilePath, sizeof(sysFsScanInfoFilePath),
"/sys/devices/virtual/graphics/fb%d/"
- "scan_info", mHdmiFbNum);
+ "scan_info", mFbNum);
memset(scanInfo, 0, sizeof(scanInfo));
hdmiScanInfoFile = open(sysFsScanInfoFilePath, O_RDONLY, 0);
@@ -397,7 +291,7 @@
{
char sysFsEDIDFilePath[MAX_SYSFS_FILE_PATH];
snprintf(sysFsEDIDFilePath , sizeof(sysFsEDIDFilePath),
- "/sys/devices/virtual/graphics/fb%d/edid_modes", mHdmiFbNum);
+ "/sys/devices/virtual/graphics/fb%d/edid_modes", mFbNum);
int hdmiEDIDFile = open(sysFsEDIDFilePath, O_RDONLY, 0);
int len = -1;
@@ -431,16 +325,15 @@
return (strlen(mEDIDs) > 0);
}
-bool ExternalDisplay::openFrameBuffer(int fbNum)
+bool ExternalDisplay::openFrameBuffer()
{
if (mFd == -1) {
- mFd = open(msmFbDevicePath[fbNum-1], O_RDWR);
+ char strDevPath[MAX_SYSFS_FILE_PATH];
+ snprintf(strDevPath, MAX_SYSFS_FILE_PATH, "/dev/graphics/fb%d", mFbNum);
+ mFd = open(strDevPath, O_RDWR);
if (mFd < 0)
- ALOGE("%s: %s is not available", __FUNCTION__,
- msmFbDevicePath[fbNum-1]);
- if(mHwcContext) {
- mHwcContext->dpyAttr[mExtDpyNum].fd = mFd;
- }
+ ALOGE("%s: %s is not available", __FUNCTION__, strDevPath);
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
}
return (mFd > 0);
}
@@ -452,9 +345,7 @@
ret = close(mFd);
mFd = -1;
}
- if(mHwcContext) {
- mHwcContext->dpyAttr[mExtDpyNum].fd = mFd;
- }
+ mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].fd = mFd;
return (ret == 0);
}
@@ -547,7 +438,6 @@
int ExternalDisplay::getBestMode() {
int bestOrder = 0;
int bestMode = HDMI_VFRMT_640x480p60_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];
@@ -644,40 +534,17 @@
}
}
-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;
- if(mHdmiFbNum != -1) {
+ if(mFbNum != -1) {
char sysFsHPDFilePath[MAX_SYSFS_FILE_PATH];
snprintf(sysFsHPDFilePath ,sizeof(sysFsHPDFilePath),
- "/sys/devices/virtual/graphics/fb%d/hpd", mHdmiFbNum);
+ "/sys/devices/virtual/graphics/fb%d/hpd", mFbNum);
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));
+ ALOGE("%s: state file '%s' not found : ret%d err str: %s",
+ __FUNCTION__, sysFsHPDFilePath, hdmiHPDFile, strerror(errno));
ret = false;
} else {
int err = -1;
@@ -687,7 +554,8 @@
else
err = write(hdmiHPDFile, "0" , 2);
if (err <= 0) {
- ALOGE("%s: file write failed '%s'", __FUNCTION__, sysFsHPDFilePath);
+ ALOGE("%s: file write failed '%s'", __FUNCTION__,
+ sysFsHPDFilePath);
ret = false;
}
close(hdmiHPDFile);
@@ -696,26 +564,15 @@
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() {
+void ExternalDisplay::setAttributes() {
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;
- }
+
+ 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) {