author | Yalong 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) |
commit | 4ac6bdf1d1ae5e96e15605ab2851ab7a541f5159 (patch) | |
tree | dbdbc1dc6185344ccffaaed3e7a0b7281d91704e | |
parent | 93c8557bf598cc2ef87cf78dbedf7f68e0a3e1e0 (diff) | |
download | hwcomposer-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
-rw-r--r-- | hwc2/common/devices/ExternalDevice.cpp | 20 | ||||
-rw-r--r-- | hwc2/common/devices/PhysicalDevice.cpp | 148 | ||||
-rw-r--r-- | hwc2/common/devices/PrimaryDevice.cpp | 22 | ||||
-rw-r--r-- | hwc2/common/hdmi/DisplayHdmi.cpp | 499 | ||||
-rw-r--r-- | hwc2/common/hdmi/DisplayHdmi.h | 122 | ||||
-rw-r--r-- | hwc2/common/utils/Utils.cpp | 131 | ||||
-rw-r--r-- | hwc2/common/utils/Utils.h | 24 | ||||
-rw-r--r-- | hwc2/include/ExternalDevice.h | 4 | ||||
-rw-r--r-- | hwc2/include/IDisplayDevice.h | 24 | ||||
-rw-r--r-- | hwc2/include/PhysicalDevice.h | 9 | ||||
-rw-r--r-- | hwc2/platforms/Android.mk | 14 |
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) |