author | Tellen Yu <tellen.yu@amlogic.com> | 2016-12-15 11:25:57 (GMT) |
---|---|---|
committer | Tellen Yu <tellen.yu@amlogic.com> | 2016-12-23 07:24:34 (GMT) |
commit | fe1516110c7dd8dc576449bfeda6d2d23dd073c0 (patch) | |
tree | 2aa47553d0b0a80556b8f18d676d65d899de00ab | |
parent | 8008a01e2d66da19a94a8d186f375e3064adeeff (diff) | |
download | hwcomposer-fe1516110c7dd8dc576449bfeda6d2d23dd073c0.zip hwcomposer-fe1516110c7dd8dc576449bfeda6d2d23dd073c0.tar.gz hwcomposer-fe1516110c7dd8dc576449bfeda6d2d23dd073c0.tar.bz2 |
PD #137033 hwc add hdr capabilities detect and HDMI hotplug
Change-Id: Ie97a7ea2b3e8f8307e3c0c163cc2664095adf2ce
-rw-r--r-- | hwc2/common/devices/PhysicalDevice.cpp | 148 | ||||
-rw-r--r-- | hwc2/common/devices/PrimaryDevice.cpp | 34 | ||||
-rw-r--r-- | hwc2/common/utils/Utils.cpp | 9 | ||||
-rw-r--r-- | hwc2/common/utils/Utils.h | 3 | ||||
-rw-r--r-- | hwc2/include/PhysicalDevice.h | 15 | ||||
-rw-r--r-- | hwc2/include/PrimaryDevice.h | 5 |
6 files changed, 197 insertions, 17 deletions
diff --git a/hwc2/common/devices/PhysicalDevice.cpp b/hwc2/common/devices/PhysicalDevice.cpp index b7015e8..d9095c2 100644 --- a/hwc2/common/devices/PhysicalDevice.cpp +++ b/hwc2/common/devices/PhysicalDevice.cpp @@ -1,6 +1,7 @@ /* // Copyright(c) 2016 Amlogic Corporation */ +#include <fcntl.h> #include <HwcTrace.h> #include <PhysicalDevice.h> #include <Hwcomposer.h> @@ -41,6 +42,7 @@ PhysicalDevice::PhysicalDevice(hwc2_display_t id, Hwcomposer& hwc) mName = "Unknown"; } + mHdrCapabilities.init = false; // init Display here. initDisplay(); @@ -357,6 +359,8 @@ int32_t PhysicalDevice::getDisplayRequests( int32_t PhysicalDevice::getDisplayType( int32_t* /*hwc2_display_type_t*/ outType) { + + *outType = HWC2_DISPLAY_TYPE_PHYSICAL; return HWC2_ERROR_NONE; } @@ -371,6 +375,33 @@ int32_t PhysicalDevice::getHdrCapabilities( float* outMaxLuminance, float* outMaxAverageLuminance, float* outMinLuminance) { + + Mutex::Autolock _l(mLock); + if (!mIsConnected) { + ETRACE("disp: %llu is not connected", mId); + return HWC2_ERROR_BAD_DISPLAY; + } + + if (!mHdrCapabilities.init) { + parseHdrCapabilities(); + mHdrCapabilities.init = true; + } + + if (NULL == outTypes) { + int num = 0; + if (mHdrCapabilities.dvSupport) num++; + if (mHdrCapabilities.hdrSupport) num++; + + *outNumTypes = num; + } else { + if (mHdrCapabilities.dvSupport) *outTypes++ = HAL_HDR_DOLBY_VISION; + if (mHdrCapabilities.hdrSupport) *outTypes++ = HAL_HDR_HDR10; + + *outMaxLuminance = mHdrCapabilities.maxLuminance; + *outMaxAverageLuminance = mHdrCapabilities.avgLuminance; + *outMinLuminance = mHdrCapabilities.minLuminance; + } + return HWC2_ERROR_NONE; } @@ -766,7 +797,7 @@ bool PhysicalDevice::updateDisplayConfigs() if (!mIsConnected) { ETRACE("disp: %llu is not connected", mId); - return true; + return false; } ret = Utils::checkOutputMode(mDisplayMode, &rate); @@ -830,6 +861,115 @@ int32_t PhysicalDevice::setOutputBuffer( return HWC2_ERROR_NONE; } +void PhysicalDevice::updateHotplugState(bool connected) { + Mutex::Autolock _l(mLock); + + mIsConnected = connected; + //if plug out, need reinit + if (!connected) + mHdrCapabilities.init = false; +} + +int32_t PhysicalDevice::getLineValue(const char *lineStr, const char *magicStr) { + int len = 0; + char value[100] = {0}; + char *pos = NULL; + + if ((NULL == lineStr) || (NULL == magicStr)) { + ETRACE("line string: %s, magic string: %s\n", lineStr, magicStr); + return 0; + } + + if (NULL != (pos = strstr(lineStr, magicStr))) { + pos = pos + strlen(magicStr); + char* start = pos; + while (*start != '\n' && (strlen(start) > 0)) + start++; + + len = start - pos; + strncpy(value, pos, len); + value[len] = '\0'; + return atoi(value); + } + + return 0; +} + +/* +cat /sys/class/amhdmitx/amhdmitx0/hdr_cap +Supported EOTF: + Traditional SDR: 1 + Traditional HDR: 0 + SMPTE ST 2084: 1 + Future EOTF: 0 +Supported SMD type1: 1 +Luminance Data + Max: 0 + Avg: 0 + Min: 0 +cat /sys/class/amhdmitx/amhdmitx0/dv_cap +DolbyVision1 RX support list: + 2160p30hz: 1 + global dimming + colorimetry + IEEEOUI: 0x00d046 + DM Ver: 1 +*/ +int32_t PhysicalDevice::parseHdrCapabilities() { + //DolbyVision1 + const char *DV_PATH = "/sys/class/amhdmitx/amhdmitx0/dv_cap"; + //HDR + const char *HDR_PATH = "/sys/class/amhdmitx/amhdmitx0/hdr_cap"; + + char buf[1024+1] = {0}; + char* pos = buf; + int fd, len; + + memset(&mHdrCapabilities, 0, sizeof(hdr_capabilities_t)); + if ((fd = open(DV_PATH, O_RDONLY)) < 0) { + ETRACE("open %s fail.", DV_PATH); + goto exit; + } + + len = read(fd, buf, 1024); + if (len < 0) { + ETRACE("read error: %s, %s\n", DV_PATH, strerror(errno)); + goto exit; + } + close(fd); + + if ((NULL != strstr(pos, "2160p30hz")) || (NULL != strstr(pos, "2160p60hz"))) + mHdrCapabilities.dvSupport = true; + //dobly version parse end + + memset(buf, 0, 1024); + if ((fd = open(HDR_PATH, O_RDONLY)) < 0) { + ETRACE("open %s fail.", HDR_PATH); + goto exit; + } + + len = read(fd, buf, 1024); + if (len < 0) { + ETRACE("read error: %s, %s\n", HDR_PATH, strerror(errno)); + goto exit; + } + + pos = strstr(pos, "SMPTE ST 2084: "); + if ((NULL != pos) && ('1' == *(pos + strlen("SMPTE ST 2084: ")))) { + mHdrCapabilities.hdrSupport = true; + + mHdrCapabilities.maxLuminance = getLineValue(pos, "Max: "); + mHdrCapabilities.avgLuminance = getLineValue(pos, "Avg: "); + mHdrCapabilities.minLuminance = getLineValue(pos, "Min: "); + } + + ITRACE("dolby version support:%d, hdr support:%d max:%d, avg:%d, min:%d\n", + mHdrCapabilities.dvSupport?1:0, mHdrCapabilities.hdrSupport?1:0, mHdrCapabilities.maxLuminance, mHdrCapabilities.avgLuminance, mHdrCapabilities.minLuminance); +exit: + close(fd); + return HWC2_ERROR_NONE; +} + void PhysicalDevice::dump(Dump& d) { Mutex::Autolock _l(mLock); d.append("-------------------------------------------------------------" @@ -873,6 +1013,12 @@ void PhysicalDevice::dump(Dump& d) { if (layer) layer->dump(d); } } + + // HDR info + d.append(" HDR Capabilities:\n"); + d.append(" DolbyVision1=%zu\n", mHdrCapabilities.dvSupport?1:0); + d.append(" HDR10=%zu, maxLuminance=%zu, avgLuminance=%zu, minLuminance=%zu\n", + mHdrCapabilities.hdrSupport?1:0, mHdrCapabilities.maxLuminance, mHdrCapabilities.avgLuminance, mHdrCapabilities.minLuminance); } } // namespace amlogic diff --git a/hwc2/common/devices/PrimaryDevice.cpp b/hwc2/common/devices/PrimaryDevice.cpp index d932f5f..8f5b434 100644 --- a/hwc2/common/devices/PrimaryDevice.cpp +++ b/hwc2/common/devices/PrimaryDevice.cpp @@ -30,8 +30,13 @@ bool PrimaryDevice::initialize() UeventObserver *observer = Hwcomposer::getInstance().getUeventObserver(); if (observer) { observer->registerListener( - Utils::getHotplugString(), - hotplugEventListener, + Utils::getHotplugInString(), + hotplugInEventListener, + this); + + observer->registerListener( + Utils::getHotplugOutString(), + hotplugOutEventListener, this); } else { ETRACE("Uevent observer is NULL"); @@ -45,30 +50,37 @@ void PrimaryDevice::deinitialize() PhysicalDevice::deinitialize(); } -void PrimaryDevice::hotplugEventListener(void *data) +void PrimaryDevice::hotplugInEventListener(void *data) { PrimaryDevice *pThis = (PrimaryDevice*)data; if (pThis) { - pThis->hotplugListener(); + pThis->hotplugListener(true); } } -void PrimaryDevice::hotplugListener() +void PrimaryDevice::hotplugOutEventListener(void *data) { - bool ret; + PrimaryDevice *pThis = (PrimaryDevice*)data; + if (pThis) { + pThis->hotplugListener(false); + } +} +void PrimaryDevice::hotplugListener(bool connected) +{ CTRACE(); + ETRACE("hotpug event: %d", connected); + + updateHotplugState(connected); // update display configs - ret = updateDisplayConfigs(); - if (ret == false) { + if (connected && !updateDisplayConfigs()) { ETRACE("failed to update display config"); return; } - DTRACE("hotpug event: %d", isConnected()); - - getDevice().hotplug(getDisplayId(), isConnected()); + if (connected) + getDevice().hotplug(getDisplayId(), connected); } } // namespace amlogic diff --git a/hwc2/common/utils/Utils.cpp b/hwc2/common/utils/Utils.cpp index b2eed85..9af81fc 100644 --- a/hwc2/common/utils/Utils.cpp +++ b/hwc2/common/utils/Utils.cpp @@ -108,7 +108,7 @@ bool Utils::checkOutputMode(char* curmode, int32_t* rate) { //check if need update vsync. if (strcmp(outputmode, curmode) == 0) { - DTRACE("outputmode didn't change %s", curmode); + ETRACE("outputmode didn't change %s", curmode); return false; } @@ -156,7 +156,12 @@ const char* Utils::getUeventEnvelope() return "change@/devices/virtual/switch/hdmi_audio"; } -const char* Utils::getHotplugString() +const char* Utils::getHotplugOutString() +{ + return "SWITCH_STATE=0"; +} + +const char* Utils::getHotplugInString() { return "SWITCH_STATE=1"; } diff --git a/hwc2/common/utils/Utils.h b/hwc2/common/utils/Utils.h index fc993a6..a6783a6 100644 --- a/hwc2/common/utils/Utils.h +++ b/hwc2/common/utils/Utils.h @@ -36,7 +36,8 @@ public: static bool checkVinfo(framebuffer_info_t *fbinfo); static const char* getUeventEnvelope(); - static const char* getHotplugString(); + static const char* getHotplugInString(); + static const char* getHotplugOutString(); }; diff --git a/hwc2/include/PhysicalDevice.h b/hwc2/include/PhysicalDevice.h index a59bde9..85419f6 100644 --- a/hwc2/include/PhysicalDevice.h +++ b/hwc2/include/PhysicalDevice.h @@ -14,6 +14,15 @@ namespace amlogic { class IHdcpControl; +typedef struct hdr_capabilities { + bool init; + bool dvSupport; + bool hdrSupport; + int maxLuminance; + int avgLuminance; + int minLuminance; +} hdr_capabilities_t; + class DeviceControlFactory { public: virtual ~DeviceControlFactory(){} @@ -100,6 +109,7 @@ public: virtual Hwcomposer& getDevice() const { return mHwc; } virtual hwc2_display_t getId() const { return mId; } virtual bool isConnected() const { return mIsConnected; } + virtual void updateHotplugState(bool connected); // device related operations virtual bool initCheck() const { return mInitialized; } @@ -121,6 +131,8 @@ private: // For use by Device int32_t initDisplay(); int32_t postFramebuffer(int32_t* outRetireFence); + int32_t getLineValue(const char *lineStr, const char *magicStr); + int32_t parseHdrCapabilities(); // Member variables hwc2_display_t mId; @@ -161,6 +173,9 @@ private: KeyedVector<hwc2_layer_t, HwcLayer*> mHwcLayersChangeRequest; KeyedVector<hwc2_layer_t, HwcLayer*> mHwcLayers; + //HDR Capabilities + hdr_capabilities_t mHdrCapabilities; + // lock Mutex mLock; bool mInitialized; diff --git a/hwc2/include/PrimaryDevice.h b/hwc2/include/PrimaryDevice.h index b812086..136f6e6 100644 --- a/hwc2/include/PrimaryDevice.h +++ b/hwc2/include/PrimaryDevice.h @@ -20,8 +20,9 @@ public: virtual void deinitialize(); private: - static void hotplugEventListener(void *data); - void hotplugListener(); + static void hotplugInEventListener(void *data); + static void hotplugOutEventListener(void *data); + void hotplugListener(bool connected); }; } |