summaryrefslogtreecommitdiff
authorYalong Liu <yalong.liu@amlogic.com>2017-02-08 01:56:46 (GMT)
committer Yalong Liu <yalong.liu@amlogic.com>2017-02-16 09:52:36 (GMT)
commit4ac6bdf1d1ae5e96e15605ab2851ab7a541f5159 (patch)
treedbdbc1dc6185344ccffaaed3e7a0b7281d91704e
parent93c8557bf598cc2ef87cf78dbedf7f68e0a3e1e0 (diff)
downloadhwcomposer-4ac6bdf1d1ae5e96e15605ab2851ab7a541f5159.zip
hwcomposer-4ac6bdf1d1ae5e96e15605ab2851ab7a541f5159.tar.gz
hwcomposer-4ac6bdf1d1ae5e96e15605ab2851ab7a541f5159.tar.bz2
PD#137813: upload initial active-mode code, patch 1
1. init active-mode code, but only support one config:1080p60hz 2. support NTS function in HWC layer Change-Id: I2cd3935c76571491cafaf282de292bc7f075d451
Diffstat
-rw-r--r--hwc2/common/devices/ExternalDevice.cpp20
-rw-r--r--hwc2/common/devices/PhysicalDevice.cpp148
-rw-r--r--hwc2/common/devices/PrimaryDevice.cpp22
-rw-r--r--hwc2/common/hdmi/DisplayHdmi.cpp499
-rw-r--r--hwc2/common/hdmi/DisplayHdmi.h122
-rw-r--r--hwc2/common/utils/Utils.cpp131
-rw-r--r--hwc2/common/utils/Utils.h24
-rw-r--r--hwc2/include/ExternalDevice.h4
-rw-r--r--hwc2/include/IDisplayDevice.h24
-rw-r--r--hwc2/include/PhysicalDevice.h9
-rw-r--r--hwc2/platforms/Android.mk14
11 files changed, 800 insertions, 217 deletions
diff --git a/hwc2/common/devices/ExternalDevice.cpp b/hwc2/common/devices/ExternalDevice.cpp
index 7d6dce3..a4c53d9 100644
--- a/hwc2/common/devices/ExternalDevice.cpp
+++ b/hwc2/common/devices/ExternalDevice.cpp
@@ -66,6 +66,10 @@ bool ExternalDevice::initialize()
} else {
ETRACE("Uevent observer is NULL");
}
+
+ mDisplayHdmi = new DisplayHdmi(mId);
+ mDisplayHdmi->initialize();
+
return true;
}
@@ -85,6 +89,7 @@ void ExternalDevice::deinitialize()
}
mHotplugEventPending = false;
+ DEINIT_AND_DELETE_OBJ(mDisplayHdmi);
PhysicalDevice::deinitialize();
}
@@ -324,16 +329,13 @@ bool ExternalDevice::setActiveConfig(int index)
return false;
}
- // for now we will only permit the frequency change. In the future
- // we may need to set mode as well.
- if (index >= 0 && index < static_cast<int>(mDisplayConfigs.size())) {
- DisplayConfig *config = mDisplayConfigs.itemAt(index);
- setRefreshRate(config->getRefreshRate());
- mActiveDisplayConfig = index;
- return true;
- } else {
+ int ret = mDisplayHdmi->setActiveConfig(index);
+ if (ret < 0)
return false;
- }
+
+ setRefreshRate(mDisplayHdmi->getActiveRefreshRate());
+ mActiveDisplayConfig = index;
+
return true;
}
diff --git a/hwc2/common/devices/PhysicalDevice.cpp b/hwc2/common/devices/PhysicalDevice.cpp
index 46a9c6f..de69655 100644
--- a/hwc2/common/devices/PhysicalDevice.cpp
+++ b/hwc2/common/devices/PhysicalDevice.cpp
@@ -37,7 +37,6 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControl
: mId(id),
mHwc(hwc),
mControlFactory(controlFactory),
- mActiveDisplayConfig(-1),
mVsyncObserver(NULL),
mIsConnected(false),
mFramebufferHnd(NULL),
@@ -77,9 +76,6 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc, DeviceControl
mHwcLayersChangeRequest.setCapacity(LAYER_MAX_NUM_CHANGE_REQUEST);
mHwcLayers.setCapacity(LAYER_MAX_NUM_SUPPORT);
- // set capacity of mDisplayConfigs
- mDisplayConfigs.setCapacity(DEVICE_COUNT);
-
mGE2DRenderSortedLayerIds.setCapacity(GE2D_COMPOSE_MAX_LAYERS);
mGE2DRenderSortedLayerIds.clear();
@@ -107,6 +103,9 @@ bool PhysicalDevice::initialize() {
DEINIT_AND_RETURN_FALSE("failed to create vsync observer");
}
+ mDisplayHdmi = new DisplayHdmi(mId);
+ mDisplayHdmi->initialize();
+
mInitialized = true;
return true;
}
@@ -115,6 +114,7 @@ void PhysicalDevice::deinitialize() {
Mutex::Autolock _l(mLock);
DEINIT_AND_DELETE_OBJ(mVsyncObserver);
+ DEINIT_AND_DELETE_OBJ(mDisplayHdmi);
DEINIT_AND_DELETE_OBJ(mComposer);
if (mFramebufferContext != NULL) {
@@ -206,8 +206,9 @@ bool PhysicalDevice::destroyLayer(hwc2_layer_t layerId) {
int32_t PhysicalDevice::getActiveConfig(
hwc2_config_t* outConfig) {
+ Mutex::Autolock _l(mLock);
- return HWC2_ERROR_NONE;
+ return mDisplayHdmi->getActiveConfig(outConfig);
}
int32_t PhysicalDevice::getChangedCompositionTypes(
@@ -302,47 +303,9 @@ int32_t PhysicalDevice::getDisplayAttribute(
ETRACE("display %d is not connected.", mId);
}
- // framebuffer_info_t* fbInfo = mFramebufferContext->getInfo();
- DisplayConfig *configChosen = mDisplayConfigs.itemAt(config);
- if (!configChosen) {
- ETRACE("failed to get display config: %ld", config);
+ int ret = mDisplayHdmi->getDisplayAttribute(config, attribute, outValue);
+ if (ret < 0)
return HWC2_ERROR_BAD_CONFIG;
- }
-
- // TODO: HWC2_ERROR_BAD_CONFIG?
- switch (attribute) {
- case HWC2_ATTRIBUTE_VSYNC_PERIOD:
- //*outValue = (int32_t)mVsyncObserver->getRefreshPeriod();
- if (configChosen->getRefreshRate()) {
- *outValue = 1e9 / configChosen->getRefreshRate();
- } else {
- ETRACE("refresh rate is 0, default to 60fps!!!");
- *outValue = 1e9 / 60;
- }
-
- ETRACE("refresh period: %d", *outValue);
- break;
- case HWC2_ATTRIBUTE_WIDTH:
- //*outValue = fbInfo->info.xres;
- *outValue = configChosen->getWidth();
- break;
- case HWC2_ATTRIBUTE_HEIGHT:
- //*outValue = fbInfo->info.yres;
- *outValue = configChosen->getHeight();
- break;
- case HWC2_ATTRIBUTE_DPI_X:
- //*outValue = fbInfo->xdpi*1000;
- *outValue = configChosen->getDpiX() * 1000.0f;
- break;
- case HWC2_ATTRIBUTE_DPI_Y:
- //*outValue = fbInfo->ydpi*1000;
- *outValue = configChosen->getDpiY() * 1000.0f;
- break;
- default:
- ETRACE("unknown display attribute %u", attribute);
- *outValue = -1;
- break;
- }
return HWC2_ERROR_NONE;
}
@@ -352,22 +315,7 @@ int32_t PhysicalDevice::getDisplayConfigs(
hwc2_config_t* outConfigs) {
Mutex::Autolock _l(mLock);
- if (!mIsConnected) {
- ETRACE("display %d is not connected.", mId);
- }
-
- /* if (NULL != outConfigs) outConfigs[0] = 0;
- *outNumConfigs = 1; */
-
- // fill in all config handles
- if (NULL != outConfigs) {
- for (int i = 0; i < static_cast<int>(*outNumConfigs); i++) {
- outConfigs[i] = i;
- }
- }
- *outNumConfigs = mDisplayConfigs.size();
-
- return HWC2_ERROR_NONE;
+ return mDisplayHdmi->getDisplayConfigs(outNumConfigs, outConfigs);
}
int32_t PhysicalDevice::getDisplayName(
@@ -788,7 +736,13 @@ int32_t PhysicalDevice::presentDisplay(
int32_t PhysicalDevice::setActiveConfig(
hwc2_config_t config) {
- return HWC2_ERROR_NONE;
+ Mutex::Autolock _l(mLock);
+
+ int32_t err = mDisplayHdmi->setActiveConfig(config);
+ if (err == HWC2_ERROR_NONE)
+ mVsyncObserver->setRefreshRate(mDisplayHdmi->getActiveRefreshRate());
+
+ return err;
}
int32_t PhysicalDevice::setClientTarget(
@@ -1269,56 +1223,27 @@ int32_t PhysicalDevice::initDisplay() {
return 0;
}
-void PhysicalDevice::removeDisplayConfigs()
-{
- for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
- DisplayConfig *config = mDisplayConfigs.itemAt(i);
- delete config;
- }
-
- mDisplayConfigs.clear();
- mActiveDisplayConfig = -1;
-}
-
-bool PhysicalDevice::updateDisplayConfigs()
-{
+bool PhysicalDevice::updateDisplayConfigs() {
Mutex::Autolock _l(mLock);
-
bool ret;
- int32_t rate;
if (!mIsConnected) {
ETRACE("disp: %llu is not connected", mId);
return false;
}
- ret = Utils::checkOutputMode(mDisplayMode, &rate);
- if (ret) {
- mVsyncObserver->setRefreshRate(rate);
- }
- ETRACE("output mode refresh rate: %d", rate);
-
framebuffer_info_t* fbinfo = mFramebufferContext->getInfo();
- ret |= Utils::checkVinfo(fbinfo);
-
- if (ret) {
- // reset display configs
- removeDisplayConfigs();
- // reset the number of display configs
- mDisplayConfigs.setCapacity(1);
-
- // use active fb dimension as config width/height
- DisplayConfig *config = new DisplayConfig(rate,
- fbinfo->info.xres,
- fbinfo->info.yres,
- fbinfo->xdpi,
- fbinfo->ydpi);
- // add it to the front of other configs
- mDisplayConfigs.push_front(config);
-
- // init the active display config
- mActiveDisplayConfig = 0;
+ ret = Utils::checkVinfo(fbinfo);
+ if (!ret) {
+ ETRACE("checkVinfo fail");
+ return false;
}
+
+ mDisplayHdmi->updateHotplug(mIsConnected, fbinfo, mFramebufferHnd);
+ if (mIsConnected)
+ mVsyncObserver->setRefreshRate(mDisplayHdmi->getActiveRefreshRate());
+ //ETRACE("updateDisplayConfigs rate:%d", mDisplayHdmi->getActiveRefreshRate());
+
return true;
}
@@ -1469,24 +1394,7 @@ void PhysicalDevice::dump(Dump& d) {
"----------------------------------------------------------------\n");
d.append("Device Name: %s (%s)\n", mName,
mIsConnected ? "connected" : "disconnected");
- d.append(" CONFIG | VSYNC_PERIOD | WIDTH | HEIGHT |"
- " DPI_X | DPI_Y \n");
- d.append("------------+------------------+-----------+------------+"
- "-----------+-----------\n");
- for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
- DisplayConfig *config = mDisplayConfigs.itemAt(i);
- if (config) {
- d.append("%s %2d | %4d | %5d | %4d |"
- " %3d | %3d \n",
- (i == (size_t)mActiveDisplayConfig) ? "* " : " ",
- i,
- config->getRefreshRate(),
- config->getWidth(),
- config->getHeight(),
- config->getDpiX(),
- config->getDpiY());
- }
- }
+ mDisplayHdmi->dump(d);
// dump layer list
d.append(" Layers state:\n");
diff --git a/hwc2/common/devices/PrimaryDevice.cpp b/hwc2/common/devices/PrimaryDevice.cpp
index 6a695fe..550876c 100644
--- a/hwc2/common/devices/PrimaryDevice.cpp
+++ b/hwc2/common/devices/PrimaryDevice.cpp
@@ -84,19 +84,17 @@ void PrimaryDevice::hotplugListener(bool connected)
{
CTRACE();
- if (getDisplayId() == HWC_DISPLAY_EXTERNAL) {
- ETRACE("hotpug event: %d", connected);
-
- updateHotplugState(connected);
- // update display configs
- if (connected && !updateDisplayConfigs()) {
- ETRACE("failed to update display config");
- return;
- }
-
- if (connected)
- getDevice().hotplug(getDisplayId(), connected);
+ ETRACE("hotpug event: %d", connected);
+
+ updateHotplugState(connected);
+ // update display configs
+ if (connected && !updateDisplayConfigs()) {
+ ETRACE("failed to update display config");
+ return;
}
+
+ if (connected)
+ getDevice().hotplug(getDisplayId(), connected);
}
} // namespace amlogic
diff --git a/hwc2/common/hdmi/DisplayHdmi.cpp b/hwc2/common/hdmi/DisplayHdmi.cpp
new file mode 100644
index 0000000..f49b826
--- a/dev/null
+++ b/hwc2/common/hdmi/DisplayHdmi.cpp
@@ -0,0 +1,499 @@
+//#define LOG_NDEBUG 0
+#include <HwcTrace.h>
+#include <binder/IServiceManager.h>
+#include <utils/Tokenizer.h>
+#include <thread>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
+#include "DisplayHdmi.h"
+
+namespace android {
+namespace amlogic {
+
+DisplayHdmi::DisplayHdmi(hwc2_display_t id) {
+ mDisplayId = id;
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (sm == NULL)
+ {
+ ETRACE("Couldn't get default ServiceManager\n");
+ return ;
+ }
+
+ mSystemControlService = interface_cast<ISystemControlService>(sm->getService(String16("system_control")));
+ if (mSystemControlService == NULL)
+ {
+ ETRACE("Couldn't get connection to SystemControlService\n");
+ return ;
+ }
+
+ initModes();
+}
+
+DisplayHdmi::~DisplayHdmi() {
+ mAllModes.clear();
+}
+
+void DisplayHdmi::initialize() {
+ reset();
+}
+
+void DisplayHdmi::deinitialize() {
+ reset();
+}
+
+void DisplayHdmi::reset() {
+ mConnected = false;
+ mActiveDisplayConfigItem = 0;
+ mActiveRefreshRate = 60;
+ memset(mActiveDisplaymode, 0, HWC_DISPLAY_MODE_LENGTH);
+ mSupportDispModes.clear();
+ for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
+ DisplayConfig *config = mDisplayConfigs[i];
+ if (config)
+ delete config;
+ }
+ mDisplayConfigs.clear();
+}
+
+bool DisplayHdmi::updateHotplug(bool connected,
+ framebuffer_info_t * framebufferInfo,
+ private_handle_t* framebufferHnd) {
+ bool ret = true;
+ int32_t rate;
+
+ mConnected = connected;
+
+ if (!isConnected()) {
+ ETRACE("disp: %d disconnect", (int32_t)mDisplayId);
+ return true;
+ }
+
+ mFramebufferInfo = framebufferInfo;
+ mFramebufferHnd = framebufferHnd;
+
+ if (-1 == updateDisplayModeList()) {
+ //hdmi plug out when system is starting up
+ std::string dispMode;
+ int width, height;
+ mSystemControlService->getActiveDispMode(&dispMode);
+ ret = calcMode2Config(dispMode.c_str(), &rate, &width, &height);
+ if (!ret) {
+ dispMode = std::string("1080p60hz");
+ rate = 60;
+ }
+ ETRACE("only init one display config: %s", dispMode.c_str());
+ strcpy(mActiveDisplaymode, dispMode.c_str());
+
+ // reset display configs
+ for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
+ DisplayConfig *config = mDisplayConfigs[i];
+ if (config)
+ delete config;
+ }
+ mDisplayConfigs.clear();
+
+ // use active fb dimension as config width/height
+ DisplayConfig *config = new DisplayConfig(mActiveDisplaymode,
+ rate,
+ mFramebufferInfo->info.xres,
+ mFramebufferInfo->info.yres,
+ mFramebufferInfo->xdpi,
+ mFramebufferInfo->ydpi);
+ // add it to the front of other configs
+ mDisplayConfigs.push_back(config);
+
+ // init the active display config
+ mActiveDisplayConfigItem = 0;
+ mActiveRefreshRate = rate;
+ //ETRACE("Active display mode %s, refresh rate: %d", mActiveDisplaymode, rate);
+ } else {
+ //hdmi plug in when system is starting up
+ updateActiveDisplayMode();
+ updateDisplayConfigures();
+ updateActiveDisplayConfigure();
+
+ ALOGD("updateHotplug setDisplayMode to %s", mActiveDisplaymode);
+ std::string strmode(mActiveDisplaymode);
+ mSystemControlService->setActiveDispMode(strmode);
+ }
+
+ std::thread t1(&DisplayHdmi::setSurfaceFlingerActiveMode, this);
+ t1.detach();
+
+ return true;
+}
+
+int DisplayHdmi::updateDisplayModeList() {
+ // clear display modes
+ mSupportDispModes.clear();
+
+ bool fullActiveMode = Utils::get_bool_prop("ro.sf.full_activemode");
+ bool isConfiged = readConfigFile("/system/etc/displayModeList.cfg", &mSupportDispModes);
+ if (isConfiged) {
+ return 0;
+ }
+
+ if (!fullActiveMode) {
+ ALOGD("Simple Active Mode!!!");
+ return -1;
+ }
+
+ std::vector<std::string> getSupportDispModes;
+ std::string::size_type pos;
+ mSystemControlService->getSupportDispModeList(&getSupportDispModes);
+ if (getSupportDispModes.size() == 0) {
+ ALOGD("SupportDispModeList null!!!");
+ return -1;
+ }
+
+ for (size_t i = 0; i < getSupportDispModes.size(); i++) {
+ //ALOGD("get support display mode:%s", getSupportDispModes[i].c_str());
+ while (!getSupportDispModes[i].empty()) {
+ pos = getSupportDispModes[i].find('*');
+ if (pos != std::string::npos) {
+ getSupportDispModes[i].erase(pos, 1);
+ //ALOGD("modify support display mode:%s", getSupportDispModes[i].c_str());
+ } else {
+ break;
+ }
+ }
+ }
+
+
+ for (size_t k = 0; k < mAllModes.size(); k++) {
+ for (size_t j = 0; j < getSupportDispModes.size(); j++) {
+ if (!getSupportDispModes[j].empty()) {
+ if (mAllModes[k] == getSupportDispModes[j]) {
+ mSupportDispModes.push_back(getSupportDispModes[j]);
+ ALOGD("support display mode:%s", getSupportDispModes[j].c_str());
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+int DisplayHdmi::updateActiveDisplayMode() {
+ std::string dispMode;
+ mSystemControlService->getActiveDispMode(&dispMode);
+ strcpy(mActiveDisplaymode, dispMode.c_str());
+
+ int refreshRate = 60;
+ if (strstr(mActiveDisplaymode, "60hz") != NULL) {
+ refreshRate = 60;
+ } else if (strstr(mActiveDisplaymode, "50hz") != NULL) {
+ refreshRate = 50;
+ } else if (strstr(mActiveDisplaymode, "30hz") != NULL) {
+ refreshRate = 30;
+ } else if (strstr(mActiveDisplaymode, "25hz") != NULL) {
+ refreshRate = 25;
+ } else if ((strstr(mActiveDisplaymode, "24hz") != NULL)
+ || (strstr(mActiveDisplaymode, "smpte") != NULL)) {
+ refreshRate = 24;
+ } else
+ ETRACE("displaymode (%s) doesn't specify HZ", mActiveDisplaymode);
+
+ ALOGD("Active display mode: (%s), refresh rate: (%d)", mActiveDisplaymode, refreshRate);
+
+ mActiveRefreshRate = refreshRate;
+
+ return 0;
+}
+
+int DisplayHdmi::setDisplayMode(const char* displaymode) {
+ ALOGD("setDisplayMode to %s", displaymode);
+
+ std::string strmode(displaymode);
+ mSystemControlService->setActiveDispMode(strmode);
+
+ updateActiveDisplayMode();
+
+ return 0;
+}
+
+int DisplayHdmi::updateDisplayConfigures() {
+ size_t i;
+
+ std::string dispMode;
+ int refreshRate, width, height;
+
+ // reset display configs
+ for (i = 0; i < mDisplayConfigs.size(); i++) {
+ DisplayConfig *config = mDisplayConfigs[i];
+ if (config)
+ delete config;
+ }
+ mDisplayConfigs.clear();
+
+ for (i =0; i < mSupportDispModes.size(); i ++) {
+ dispMode = mSupportDispModes[i];
+ calcMode2Config(dispMode.c_str(), &refreshRate, &width, &height);
+
+ // init dimension as config width/height, set xdpi/ydpi after
+ DisplayConfig *config = new DisplayConfig(dispMode.c_str(),
+ refreshRate, width, height,
+ mFramebufferInfo->xdpi,
+ mFramebufferInfo->ydpi);
+ // add it to the front of other configs
+ mDisplayConfigs.push_back(config);
+ }
+ return 0;
+}
+
+int DisplayHdmi::updateActiveDisplayConfigure() {
+ size_t i;
+
+ DisplayConfig *dispConfig = NULL;
+ for (i = 0; i < mDisplayConfigs.size(); i++) {
+ dispConfig = mDisplayConfigs[i];
+ if (!dispConfig) {
+ continue;
+ }
+ if (0 == strncmp(mActiveDisplaymode, dispConfig->getDisplayMode(),
+ HWC_DISPLAY_MODE_LENGTH-1)) {
+ mActiveDisplayConfigItem = i;
+ ALOGD("updateActiveDisplayConfigure to config(%d)", mActiveDisplayConfigItem);
+ dispConfig->setDpi(mFramebufferInfo->xdpi, mFramebufferInfo->ydpi);
+ break;
+ }
+ }
+ return 0;
+}
+
+int DisplayHdmi::getDisplayConfigs(uint32_t* outNumConfigs,
+ hwc2_config_t* outConfigs) {
+ size_t i;
+
+ if (!isConnected()) {
+ //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
+ }
+
+ for (i = 0; i < mDisplayConfigs.size(); i++) {
+ if (NULL != outConfigs)
+ outConfigs[i] = i;
+ }
+
+ *outNumConfigs = i;
+
+ return HWC2_ERROR_NONE;
+}
+
+int DisplayHdmi::getDisplayAttribute(hwc2_config_t config,
+ int32_t /*hwc2_attribute_t*/ attribute,
+ int32_t* outValue) {
+
+ if (!isConnected()) {
+ //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
+ }
+
+ DisplayConfig *configChosen = mDisplayConfigs[config];
+ if (!configChosen) {
+ ETRACE("failed to get display config: %d", config);
+ return HWC2_ERROR_NONE;
+ }
+
+ switch (attribute) {
+ case HWC2_ATTRIBUTE_VSYNC_PERIOD:
+ if (configChosen->getRefreshRate()) {
+ *outValue = 1e9 / configChosen->getRefreshRate();
+ }
+ break;
+ case HWC2_ATTRIBUTE_WIDTH:
+ *outValue = configChosen->getWidth();
+ break;
+ case HWC2_ATTRIBUTE_HEIGHT:
+ *outValue = configChosen->getHeight();
+ break;
+ case HWC2_ATTRIBUTE_DPI_X:
+ *outValue = configChosen->getDpiX() * 1000.0f;
+ break;
+ case HWC2_ATTRIBUTE_DPI_Y:
+ *outValue = configChosen->getDpiY() * 1000.0f;
+ break;
+ default:
+ ETRACE("unknown display attribute %u", attribute);
+ *outValue = -1;
+ break;
+ }
+
+ return HWC2_ERROR_NONE;
+}
+
+int DisplayHdmi::getActiveConfig(hwc2_config_t* outConfig) {
+ if (!isConnected()) {
+ //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
+ }
+ //ALOGD("getActiveConfig to config(%d).", mActiveDisplayConfigItem);
+ *outConfig = mActiveDisplayConfigItem;
+
+ return HWC2_ERROR_NONE;
+}
+
+int DisplayHdmi::setActiveConfig(int id) {
+ DisplayConfig *dispConfig = NULL;
+ char *dispMode = NULL;
+
+ if (!isConnected()) {
+ //ETRACE("display %d is not connected.", (int32_t)mDisplayId);
+ }
+
+ ALOGD("setActiveConfig to config(%d).", id);
+ mActiveDisplayConfigItem = id;
+ dispConfig = mDisplayConfigs[id];
+ if (!dispConfig) {
+ ETRACE("failed to get display config: %d", id);
+ return HWC2_ERROR_BAD_CONFIG;
+ }
+
+ dispConfig->setDpi(mFramebufferInfo->xdpi,
+ mFramebufferInfo->ydpi);
+
+ dispMode = dispConfig->getDisplayMode();
+ if (!dispMode) {
+ ETRACE("failed to get display mode by config: %d", id);
+ return HWC2_ERROR_BAD_CONFIG;
+ }
+
+ setDisplayMode(dispMode);
+
+ return HWC2_ERROR_NONE;
+}
+
+bool DisplayHdmi::calcMode2Config(const char *dispMode, int* refreshRate,
+ int* width, int* height) {
+
+ if (NULL == dispMode) {
+ ETRACE("dispMode is NULL");
+ return false;
+ }
+
+ if (strstr(dispMode, "60hz") != NULL) {
+ *refreshRate = 60;
+ } else if (strstr(dispMode, "50hz") != NULL) {
+ *refreshRate = 50;
+ } else if (strstr(dispMode, "30hz") != NULL) {
+ *refreshRate = 30;
+ } else if (strstr(dispMode, "25hz") != NULL) {
+ *refreshRate = 25;
+ } else if ((strstr(dispMode, "24hz") != NULL)
+ || (strstr(dispMode, "smpte") != NULL)) {
+ *refreshRate = 24;
+ } else {
+ ETRACE("displaymode (%s) doesn't specify HZ", dispMode);
+ return false;
+ }
+
+ if (strstr(dispMode, "2160") != NULL) {
+ *width = 3840;
+ *height = 2160;
+ } else if (strstr(dispMode, "1080") != NULL) {
+ *width = 1920;
+ *height = 1080;
+ } else if (strstr(dispMode, "720") != NULL) {
+ *width = 1280;
+ *height = 720;
+ } else if (strstr(dispMode, "576") != NULL) {
+ *width = 720;
+ *height = 576;
+ } else if (strstr(dispMode, "480") != NULL) {
+ *width = 640;
+ *height = 480;
+ } else {
+ // smpte and panle imcomplete!!!!!
+ ETRACE("calcMode2Config displaymode (%s) doesn't specify HZ", dispMode);
+ return false;
+ }
+
+ //DTRACE("calcMode2Config (%s) refreshRate(%d), (%dx%d)", dispMode, *refreshRate, *width, *height);
+ return true;
+}
+
+bool DisplayHdmi::readConfigFile(const char* configPath, std::vector<std::string>* supportDispModes) {
+ const char* WHITESPACE = " \t\r";
+
+ Tokenizer* tokenizer;
+ status_t status = Tokenizer::open(String8(configPath), &tokenizer);
+
+ if (status) {
+ DTRACE("Error %d opening display config file %s.", status, configPath);
+ return false;
+ } else {
+ while (!tokenizer->isEof()) {
+ tokenizer->skipDelimiters(WHITESPACE);
+ if (!tokenizer->isEol() && tokenizer->peekChar() != '#') {
+ String8 token = tokenizer->nextToken(WHITESPACE);
+ const char* dispMode = token.string();
+ if (strstr(dispMode, "hz")) {
+ ETRACE("dispMode %s.", dispMode);
+ (*supportDispModes).push_back(std::string(dispMode));
+ }
+ }
+
+ tokenizer->nextLine();
+ }
+ delete tokenizer;
+ }
+
+ size_t num = (*supportDispModes).size();
+
+ if (num <= 0) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+void DisplayHdmi::setSurfaceFlingerActiveMode() {
+ sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
+ ISurfaceComposer::eDisplayIdMain));
+
+ SurfaceComposerClient::setActiveConfig(dtoken, mDisplayConfigs.size()-mActiveDisplayConfigItem-1);
+
+ return;
+}
+
+void DisplayHdmi::initModes() {
+ //mAllModes.push_back("480p60hz");
+ //mAllModes.push_back("576p50hz");
+ //mAllModes.push_back("720p50hz");
+ //mAllModes.push_back("720p60hz");
+ mAllModes.push_back("1080p60hz");
+ mAllModes.push_back("1080p50hz");
+ mAllModes.push_back("1080p30hz");
+ mAllModes.push_back("1080p25hz");
+ mAllModes.push_back("1080p24hz");
+ //mAllModes.push_back("2160p24hz");
+ //mAllModes.push_back("2160p25hz");
+ //mAllModes.push_back("2160p30hz");
+ //mAllModes.push_back("2160p50hz");
+ //mAllModes.push_back("2160p60hz");
+}
+
+void DisplayHdmi::dump(Dump& d) {
+ d.append(" CONFIG | VSYNC_PERIOD | WIDTH | HEIGHT |"
+ " DPI_X | DPI_Y \n");
+ d.append("------------+------------------+-----------+------------+"
+ "-----------+-----------\n");
+ for (size_t i = 0; i < mDisplayConfigs.size(); i++) {
+ DisplayConfig *config = mDisplayConfigs[i];
+ if (config) {
+ d.append("%s %2d | %4d | %5d | %4d |"
+ " %3d | %3d \n",
+ (i == (size_t)mActiveDisplayConfigItem) ? "* " : " ",
+ i,
+ config->getRefreshRate(),
+ config->getWidth(),
+ config->getHeight(),
+ config->getDpiX(),
+ config->getDpiY());
+ }
+ }
+ }
+
+} // namespace amlogic
+} // namespace android
+
+
+
diff --git a/hwc2/common/hdmi/DisplayHdmi.h b/hwc2/common/hdmi/DisplayHdmi.h
new file mode 100644
index 0000000..2d27150
--- a/dev/null
+++ b/hwc2/common/hdmi/DisplayHdmi.h
@@ -0,0 +1,122 @@
+#ifndef AML_DISPLAY_HDMI_H
+#define AML_DISPLAY_HDMI_H
+
+#include <gralloc_priv.h>
+#include <utils/String8.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <linux/fb.h>
+#include <string>
+#include <vector>
+
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
+#include <Hwcomposer.h>
+#include <SoftVsyncObserver.h>
+#include <Utils.h>
+#include <ISystemControlService.h>
+#include <gui/SurfaceComposerClient.h>
+
+#define HWC_DISPLAY_MODE_LENGTH 32
+
+namespace android {
+namespace amlogic {
+
+// display config
+class DisplayConfig {
+public:
+ DisplayConfig(const char* dm,
+ int rr,
+ int w = 0,
+ int h = 0,
+ int dpix = 0,
+ int dpiy = 0)
+ : mRefreshRate(rr),
+ mWidth(w),
+ mHeight(h),
+ mDpiX(dpix),
+ mDpiY(dpiy)
+ {
+ memset(mDisplayMode, 0, HWC_DISPLAY_MODE_LENGTH);
+ int length = strlen(dm);
+ length = (length <= HWC_DISPLAY_MODE_LENGTH-1)?length:(HWC_DISPLAY_MODE_LENGTH-1);
+ memcpy(mDisplayMode, dm, length);
+ }
+public:
+ char* getDisplayMode() const { return (char*)(&mDisplayMode[0]); };
+ int getRefreshRate() const { return mRefreshRate; };
+ int getWidth() const { return mWidth; };
+ int getHeight() const { return mHeight; };
+ int getDpiX() const { return mDpiX; };
+ int getDpiY() const { return mDpiY; };
+ void setDpi(int dpix, int dpiy) {
+ mDpiX = dpix;
+ mDpiY = dpiy;
+ };
+
+private:
+ char mDisplayMode[HWC_DISPLAY_MODE_LENGTH];
+ int mRefreshRate;
+ int mWidth;
+ int mHeight;
+ int mDpiX;
+ int mDpiY;
+};
+
+class DisplayHdmi {
+public:
+ DisplayHdmi(hwc2_display_t id);
+ ~DisplayHdmi();
+
+ void initialize();
+ void deinitialize();
+ void reset();
+ bool updateHotplug(bool connected, framebuffer_info_t * framebufferInfo,
+ private_handle_t* framebufferHnd);
+ int updateDisplayModeList();
+ int updateActiveDisplayMode();
+ int setDisplayMode(const char* displaymode);
+ int updateDisplayConfigures();
+ int updateActiveDisplayConfigure();
+
+ int getDisplayConfigs(uint32_t* outNumConfigs, hwc2_config_t* outConfigs);
+ int getDisplayAttribute(hwc2_config_t config, int32_t attribute, int32_t* outValue);
+ int getActiveConfig(hwc2_config_t* outConfig);
+ int setActiveConfig(int id);
+ //int setPowerMode(int power) {return 0;};
+
+ inline bool isConnected() {return mConnected;};
+ int getActiveRefreshRate() {return mActiveRefreshRate;};
+ bool calcMode2Config(const char *dispMode, int* refreshRate, int* width, int* height);
+ bool readConfigFile(const char* configPath, std::vector<std::string>* supportDispModes);
+ void setSurfaceFlingerActiveMode();
+ void initModes();
+
+ void dump(Dump& d);
+
+private:
+ hwc2_display_t mDisplayId; //0-primary 1-external
+ bool mConnected;
+ sp<ISystemControlService> mSystemControlService;
+ sp<SurfaceComposerClient> mComposerClient;
+
+ //display outputmode as 4k20hz, 1080p60hz, panel. etc.
+ std::vector<std::string> mAllModes;
+ std::vector<std::string> mSupportDispModes;
+ char mActiveDisplaymode[HWC_DISPLAY_MODE_LENGTH];
+ int mActiveRefreshRate;
+
+ std::vector<DisplayConfig*> mDisplayConfigs;
+ hwc2_config_t mActiveDisplayConfigItem;
+
+ framebuffer_info_t *mFramebufferInfo;
+ private_handle_t *mFramebufferHnd;
+};
+
+} // namespace amlogic
+} // namespace android
+
+#endif
diff --git a/hwc2/common/utils/Utils.cpp b/hwc2/common/utils/Utils.cpp
index 80d5ed8..fa6cb84 100644
--- a/hwc2/common/utils/Utils.cpp
+++ b/hwc2/common/utils/Utils.cpp
@@ -26,6 +26,100 @@ Utils::~Utils()
}
+bool Utils::get_bool_prop(const char* prop) {
+ char val[PROPERTY_VALUE_MAX];
+ memset(val, 0, sizeof(val));
+ if (property_get(prop, val, "false") && strcmp(val, "true") == 0) {
+ //VTRACE("prop: %s is %s",prop, val);
+ return true;
+ }
+
+ return false;
+}
+
+int Utils::get_int_prop(const char* prop) {
+ char val[PROPERTY_VALUE_MAX];
+ memset(val, 0, sizeof(val));
+ if (property_get(prop, val, "2")) {
+ //VTRACE("prop: %s is %s",prop, val);
+ return atoi(val);
+ }
+ return 0;
+}
+
+int Utils::getSysfsInt(const char* syspath, int def) {
+ int val = def;
+ char valstr[64];
+ if (getSysfsStr(syspath, valstr, sizeof(valstr)) == 0) {
+ val = atoi(valstr);
+ //DTRACE("sysfs(%s) read int (%s)=(%d)", syspath, valstr, val);
+ }
+ return val;
+}
+
+int Utils::getSysfsStr(const char* syspath, char *valstr, int size,
+ bool needOriginalData) {
+
+ int fd, len;
+
+ if ( NULL == valstr ) {
+ ETRACE("buf is NULL");
+ return -1;
+ }
+
+ if ((fd = open(syspath, O_RDONLY)) < 0) {
+ ETRACE("readSysFs, open %s fail.", syspath);
+ return -1;
+ }
+
+ len = read(fd, valstr, size);
+ if (len < 0) {
+ ETRACE("read error: %s, %s\n", syspath, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if (!needOriginalData) {
+ int i , j;
+ for (i = 0, j = 0; i <= len -1; i++) {
+ /*change '\0' to 0x20(spacing), otherwise the string buffer will be cut off
+ * if the last char is '\0' should not replace it
+ */
+ if (0x0 == valstr[i] && i < len - 1) {
+ valstr[i] = 0x20;
+ }
+ //DTRACE("read buffer index:%d is a 0x0, replace to spacing \n", i);
+
+
+ /* delete all the character of '\n' */
+ if (0x0a != valstr[i]) {
+ valstr[j++] = valstr[i];
+ }
+ }
+
+ valstr[j] = 0x0;
+ }
+
+ //DTRACE("read %s, result length:%d, val:%s\n", syspath, len, valstr);
+
+ close(fd);
+ return 0;
+
+}
+
+int Utils::setSysfsStr(const char *path, const char *val) {
+ int bytes;
+ int fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0644);
+ if (fd >= 0) {
+ bytes = write(fd, val, strlen(val));
+ //DTRACE("setSysfsStr %s= %s\n", path,val);
+ close(fd);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
bool Utils::checkBoolProp(const char* prop) {
char val[PROPERTY_VALUE_MAX];
@@ -69,7 +163,7 @@ bool Utils::checkSysfsStatus(const char* sysfstr, char* lastr, int32_t size) {
char *p = lastr;
memset(val, 0, sizeof(val));
- if (amsysfs_get_sysfs_str(sysfstr, val, sizeof(val)) == 0) {
+ if (getSysfsStr(sysfstr, val, sizeof(val)) == 0) {
DTRACE("val: %s, lastr: %s",val, p);
if ((strcmp(val, p) != 0)) {
memset(p, 0, size);
@@ -82,41 +176,6 @@ bool Utils::checkSysfsStatus(const char* sysfstr, char* lastr, int32_t size) {
}
#endif
-bool Utils::checkOutputMode(char* curmode, int32_t* rate) {
- int32_t modefd = open(SYSFS_DISPLAY_MODE, O_RDONLY);
- if (modefd < 0) {
- ETRACE("open (%s) fail", SYSFS_DISPLAY_MODE);
- return -1;
- }
-
- char outputmode[32] = {0};
- read(modefd, outputmode, 31);
- close(modefd);
- modefd = -1;
-
- *rate = 60;
- if (strstr(outputmode, "50hz") != NULL) {
- *rate = 50;
- } else if (strstr(outputmode, "30hz") != NULL) {
- *rate = 30;
- } else if (strstr(outputmode, "25hz") != NULL) {
- *rate = 25;
- } else if ((strstr(outputmode, "24hz") != NULL) || (strstr(outputmode, "smpte") != NULL)) {
- *rate = 24;
- } else
- DTRACE("displaymode (%s) doesn't specify HZ", curmode);
-
- //check if need update vsync.
- if (strcmp(outputmode, curmode) == 0) {
- ETRACE("outputmode didn't change %s", curmode);
- return false;
- }
-
- strcpy(curmode, outputmode);
- DTRACE("get new outputmode (%s) new period (%d)", curmode, rate);
- return true;
-}
-
bool Utils::checkVinfo(framebuffer_info_t *fbInfo) {
if (fbInfo != NULL && fbInfo->fd >= 0) {
struct fb_var_screeninfo vinfo;
diff --git a/hwc2/common/utils/Utils.h b/hwc2/common/utils/Utils.h
index a580d19..956e331 100644
--- a/hwc2/common/utils/Utils.h
+++ b/hwc2/common/utils/Utils.h
@@ -10,12 +10,16 @@
#include <Amavutils.h>
#endif
+#define DISPLAY_HPD_STATE "/sys/class/amhdmitx/amhdmitx0/hpd_state"
+#define DISPLAY_HDMI_EDID "/sys/class/amhdmitx/amhdmitx0/disp_cap"
#define SYSFS_AMVIDEO_CURIDX "/sys/module/amvideo/parameters/cur_dev_idx"
-#define SYSFS_DISPLAY_MODE "/sys/class/display/mode"
-#define SYSFS_FB0_FREE_SCALE "/sys/class/graphics/fb0/free_scale"
-#define SYSFS_FB1_FREE_SCALE "/sys/class/graphics/fb0/free_scale"
-#define SYSFS_VIDEO_AXIS "/sys/class/video/axis"
-#define SYSFS_VIDEOBUFUSED "/sys/class/amstream/videobufused"
+#define SYSFS_DISPLAY_MODE "/sys/class/display/mode"
+#define SYSFS_DISPLAY1_MODE "/sys/class/display/mode"
+#define SYSFS_DISPLAY2_MODE "/sys/class/display2/mode"
+#define SYSFS_FB0_FREE_SCALE "/sys/class/graphics/fb0/free_scale"
+#define SYSFS_FB1_FREE_SCALE "/sys/class/graphics/fb1/free_scale"
+#define SYSFS_VIDEO_AXIS "/sys/class/video/axis"
+#define SYSFS_VIDEOBUFUSED "/sys/class/amstream/videobufused"
#define SYSFS_WINDOW_AXIS "/sys/class/graphics/fb0/window_axis"
namespace android {
@@ -25,6 +29,15 @@ class Utils {
public:
Utils();
~Utils();
+
+ static int get_int_prop(const char* prop);
+ static bool get_bool_prop(const char* prop);
+
+ static int getSysfsInt(const char* syspath, int def);
+ static int getSysfsStr(const char* syspath, char *valstr, int size,
+ bool needOriginalData = false);
+ static int setSysfsStr(const char *path, const char *val);
+
static bool checkBoolProp(const char* prop);
static int32_t checkIntProp(const char* prop);
static int32_t checkAndDupFd(int32_t fd);
@@ -34,7 +47,6 @@ public:
#if WITH_LIBPLAYER_MODULE
static bool checkSysfsStatus(const char* sysfstr, char* lastr, int32_t size);
#endif
- static bool checkOutputMode(char* curmode, int32_t* rate);
static bool checkVinfo(framebuffer_info_t *fbinfo);
diff --git a/hwc2/include/ExternalDevice.h b/hwc2/include/ExternalDevice.h
index 6817b75..b8f296c 100644
--- a/hwc2/include/ExternalDevice.h
+++ b/hwc2/include/ExternalDevice.h
@@ -23,6 +23,8 @@
#include <IHdcpControl.h>
#include <SimpleThread.h>
+#include <DisplayHdmi.h>
+
namespace android {
namespace amlogic {
@@ -40,6 +42,7 @@ public:
virtual int getActiveConfig();
virtual bool setActiveConfig(int index);
int getRefreshRate();
+ DisplayHdmi* getDisplayHdmi() const { return mDisplayHdmi; };
private:
static void HdcpLinkStatusListener(bool success, void *userData);
@@ -57,6 +60,7 @@ private:
drmModeModeInfo mPendingDrmMode;
bool mHotplugEventPending;
int mExpectedRefreshRate;
+ DisplayHdmi* mDisplayHdmi;
private:
DECLARE_THREAD(ModeSettingThread, ExternalDevice);
diff --git a/hwc2/include/IDisplayDevice.h b/hwc2/include/IDisplayDevice.h
index adb10a9..ada3534 100644
--- a/hwc2/include/IDisplayDevice.h
+++ b/hwc2/include/IDisplayDevice.h
@@ -42,30 +42,6 @@ enum {
GE2D_COMPOSE_MAX_LAYERS = GE2D_COMPOSE_THREE_LAYERS,
};
-// display config
-class DisplayConfig {
-public:
- DisplayConfig(int rr, int w, int h, int dpix, int dpiy)
- : mRefreshRate(rr),
- mWidth(w),
- mHeight(h),
- mDpiX(dpix),
- mDpiY(dpiy)
- {}
-public:
- int getRefreshRate() const { return mRefreshRate; }
- int getWidth() const { return mWidth; }
- int getHeight() const { return mHeight; }
- int getDpiX() const { return mDpiX; }
- int getDpiY() const { return mDpiY; }
-private:
- int mRefreshRate;
- int mWidth;
- int mHeight;
- int mDpiX;
- int mDpiY;
-};
-
// display device interface
class IDisplayDevice {
diff --git a/hwc2/include/PhysicalDevice.h b/hwc2/include/PhysicalDevice.h
index a643f43..a27f0a7 100644
--- a/hwc2/include/PhysicalDevice.h
+++ b/hwc2/include/PhysicalDevice.h
@@ -24,6 +24,7 @@
#include <IDisplayDevice.h>
#include <HwcLayer.h>
#include <IComposer.h>
+#include <DisplayHdmi.h>
namespace android {
namespace amlogic {
@@ -132,12 +133,12 @@ public:
virtual HwcLayer* getLayerById(hwc2_layer_t layerId);
// display config operations
- virtual void removeDisplayConfigs();
virtual bool updateDisplayConfigs();
//events
virtual void onVsync(int64_t timestamp);
virtual void dump(Dump& d);
+ DisplayHdmi* getDisplayHdmi() const { return mDisplayHdmi; };
private:
// For use by Device
@@ -176,12 +177,8 @@ private:
const char *mName;
bool mIsConnected;
Hwcomposer& mHwc;
+ DisplayHdmi* mDisplayHdmi;
DeviceControlFactory *mControlFactory;
- char mDisplayMode[32];
-
- // display configs
- Vector<DisplayConfig*> mDisplayConfigs;
- int mActiveDisplayConfig;
SoftVsyncObserver *mVsyncObserver;
IComposer *mComposer;
diff --git a/hwc2/platforms/Android.mk b/hwc2/platforms/Android.mk
index 5c2df1c..e1a62de 100644
--- a/hwc2/platforms/Android.mk
+++ b/hwc2/platforms/Android.mk
@@ -19,6 +19,7 @@ LOCAL_SRC_FILES := \
../common/devices/PhysicalDevice.cpp \
../common/devices/PrimaryDevice.cpp \
../common/devices/VirtualDevice.cpp \
+ ../common/hdmi/DisplayHdmi.cpp \
../common/observers/SoftVsyncObserver.cpp \
../common/observers/UeventObserver.cpp \
../common/composers/Composers.cpp \
@@ -39,7 +40,10 @@ LOCAL_SHARED_LIBRARIES := \
libsync \
libion \
libfbcnf \
- libge2d
+ libge2d \
+ libbinder \
+ libsystemcontrolservice\
+ libgui\
LOCAL_STATIC_LIBRARIES := \
libomxutil
@@ -54,14 +58,14 @@ LOCAL_C_INCLUDES := \
LOCAL_C_INCLUDES += $(LOCAL_PATH) \
$(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../common/base \
- $(LOCAL_PATH)/../common/buffers \
$(LOCAL_PATH)/../common/devices \
+ $(LOCAL_PATH)/../common/hdmi \
$(LOCAL_PATH)/../common/observers \
- $(LOCAL_PATH)/../common/planes \
$(LOCAL_PATH)/../common/utils \
$(LOCAL_PATH)/../common/composers \
$(LOCAL_PATH)/../.. \
- $(LOCAL_PATH)/
+ $(LOCAL_PATH)/ \
+ $(TOP)/vendor/amlogic/frameworks/services/systemcontrol \
LOCAL_KK=0
ifeq ($(GPU_TYPE),t83x)
@@ -76,6 +80,8 @@ else
LOCAL_CFLAGS += -DMALI_AFBC_GRALLOC=0
endif
+LOCAL_CPPFLAGS += -std=c++14
+
MESON_GRALLOC_DIR ?= hardware/amlogic/gralloc
LOCAL_C_INCLUDES += $(MESON_GRALLOC_DIR)