From 15d3ee5eadd38849de483660656bdcbc3c8e163c Mon Sep 17 00:00:00 2001 From: shuze.ma Date: Sat, 30 Sep 2017 08:19:39 +0000 Subject: hwc2: add framebuffer info [1/2] PD# 150777 read display mode from config file support 720p mode, but need set density 160. Change-Id: I50446da77f84d21aae7fce174c7cb3f40b5ae0b1 --- diff --git a/hwc2/common/devices/PhysicalDevice.cpp b/hwc2/common/devices/PhysicalDevice.cpp index 3c9d462..175cfa8 100644 --- a/hwc2/common/devices/PhysicalDevice.cpp +++ b/hwc2/common/devices/PhysicalDevice.cpp @@ -124,12 +124,28 @@ bool PhysicalDevice::initialize() { } mDisplayHdmi = new DisplayHdmi(); - mDisplayHdmi->initialize(*(mFramebufferContext->getInfo())); + framebuffer_info_t framebufferInfo = *(mFramebufferContext->getInfo()); + framebufferInfo.info.xres = mDisplayWidth; + framebufferInfo.info.yres = mDisplayHeight; + mDisplayHdmi->initialize(framebufferInfo); mInitialized = true; return true; } +void PhysicalDevice::updateDisplayInfo(char defaultMode[64]) { + if (!strncmp(defaultMode, "720", 3)) { + mDisplayWidth= FULL_WIDTH_720; + mDisplayHeight = FULL_HEIGHT_720; + } else if (!strncmp(defaultMode, "1080", 4)) { + mDisplayWidth = FULL_WIDTH_1080; + mDisplayHeight = FULL_HEIGHT_1080; + } else if (!strncmp(defaultMode, "4k2k", 4)) { + mDisplayWidth = FULL_WIDTH_4K2K; + mDisplayHeight = FULL_HEIGHT_4K2K; + } +} + void PhysicalDevice::hdcpEventListener(void *data, bool status) { PhysicalDevice *pThis = (PhysicalDevice*)data; if (pThis) { diff --git a/hwc2/common/devices/PrimaryDevice.cpp b/hwc2/common/devices/PrimaryDevice.cpp index c6a82e2..da28b8e 100644 --- a/hwc2/common/devices/PrimaryDevice.cpp +++ b/hwc2/common/devices/PrimaryDevice.cpp @@ -20,13 +20,19 @@ #include #include #include +#include + namespace android { namespace amlogic { PrimaryDevice::PrimaryDevice(Hwcomposer& hwc, IComposeDeviceFactory * controlFactory) - : PhysicalDevice(DEVICE_PRIMARY, hwc, controlFactory) + : PhysicalDevice(DEVICE_PRIMARY, hwc, controlFactory), + pConfigPath(DISPLAY_CFG_FILE), + mDisplayType(DISPLAY_TYPE_MBOX) { + DTRACE("display mode config path: %s", pConfigPath); + CTRACE(); } @@ -37,6 +43,9 @@ PrimaryDevice::~PrimaryDevice() bool PrimaryDevice::initialize() { + parseConfigFile(); + updateDisplayInfo(mDefaultMode); + if (!PhysicalDevice::initialize()) { DEINIT_AND_RETURN_FALSE("failed to initialize physical device"); } @@ -78,5 +87,42 @@ void PrimaryDevice::hotplugListener(bool connected) onHotplug(getDisplayId(), connected); } +int PrimaryDevice::parseConfigFile() +{ + const char* WHITESPACE = " \t\r"; + + SysTokenizer* tokenizer; + int status = SysTokenizer::open(pConfigPath, &tokenizer); + if (status) { + ETRACE("Error %d opening display config file %s.", status, pConfigPath); + } else { + while (!tokenizer->isEof()) { + ITRACE("Parsing %s: %s", tokenizer->getLocation(), tokenizer->peekRemainderOfLine()); + + tokenizer->skipDelimiters(WHITESPACE); + if (!tokenizer->isEol() && tokenizer->peekChar() != '#') { + + char *token = tokenizer->nextToken(WHITESPACE); + if (!strcmp(token, DEVICE_STR_MBOX)) { + mDisplayType = DISPLAY_TYPE_MBOX; + } else if (!strcmp(token, DEVICE_STR_TV)) { + mDisplayType = DISPLAY_TYPE_TV; + } else { + DTRACE("%s: Expected keyword, got '%s'.", tokenizer->getLocation(), token); + break; + } + tokenizer->skipDelimiters(WHITESPACE); + tokenizer->nextToken(WHITESPACE); + tokenizer->skipDelimiters(WHITESPACE); + strcpy(mDefaultMode, tokenizer->nextToken(WHITESPACE)); + } + + tokenizer->nextLine(); + } + delete tokenizer; + } + return status; +} + } // namespace amlogic } // namespace android diff --git a/hwc2/common/hdmi/DisplayHdmi.cpp b/hwc2/common/hdmi/DisplayHdmi.cpp index 76b9e3d..7992d6e 100644 --- a/hwc2/common/hdmi/DisplayHdmi.cpp +++ b/hwc2/common/hdmi/DisplayHdmi.cpp @@ -29,7 +29,8 @@ namespace amlogic { #define DEFAULT_DISPLAY_DPI 160 DisplayHdmi::DisplayHdmi() - : mFirstBootup(true) + : mFirstBootup(true), + mDispMode(DEFAULT_DISPMODE) { if (Utils::get_bool_prop("ro.sf.full_activemode")) { mWorkMode = REAL_ACTIVEMODE; @@ -84,10 +85,9 @@ auto DisplayHdmi::getSystemControlService() { void DisplayHdmi::initialize(framebuffer_info_t& framebufferInfo) { reset(); - std::string dispMode; - calcDefaultMode(framebufferInfo, dispMode); - buildSingleConfigList(dispMode); - updateActiveConfig(dispMode); + calcDefaultMode(framebufferInfo, mDispMode); + buildSingleConfigList(mDispMode); + updateActiveConfig(mDispMode); mFbWidth = framebufferInfo.info.xres; mFbHeight = framebufferInfo.info.yres; @@ -126,7 +126,7 @@ bool DisplayHdmi::updateHotplug(bool connected, if (updateSupportedConfigs() != HWC2_ERROR_NONE) { ETRACE("updateHotplug: No supported display list, set default configs."); - std::string dM (DEFAULT_DISPMODE); + std::string dM (mDispMode); buildSingleConfigList(dM); } updateActiveConfig(activemode); @@ -141,7 +141,7 @@ int DisplayHdmi::updateSupportedConfigs() { std::vector supportDispModes; std::string::size_type pos; - std::string dM (DEFAULT_DISPMODE); + std::string dM (mDispMode); bool isConfiged = readConfigFile("/system/etc/displayModeList.cfg", &supportDispModes); if (isConfiged) { @@ -196,8 +196,6 @@ int DisplayHdmi::calcDefaultMode(framebuffer_info_t& framebufferInfo, defaultMode = mode->name; } - defaultMode = DEFAULT_DISPMODE; - DTRACE("calcDefaultMode %s", defaultMode.c_str()); return NO_ERROR; } diff --git a/hwc2/common/hdmi/DisplayHdmi.h b/hwc2/common/hdmi/DisplayHdmi.h index 4ddca40..322a83e 100644 --- a/hwc2/common/hdmi/DisplayHdmi.h +++ b/hwc2/common/hdmi/DisplayHdmi.h @@ -206,6 +206,7 @@ private: int mWorkMode; // first boot up flag. bool mFirstBootup; + std::string mDispMode; }; } // namespace amlogic } // namespace android diff --git a/hwc2/common/utils/SysTokenizer.cpp b/hwc2/common/utils/SysTokenizer.cpp new file mode 100644 index 0000000..2855e27 --- a/dev/null +++ b/hwc2/common/utils/SysTokenizer.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @author Tellen Yu + * @version 1.0 + * @date 2014/11/04 + * @par function description: + * - 1 parse file use tokenizer + */ + +#define LOG_TAG "hwcomposer" +//#define LOG_NDEBUG 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SysTokenizer.h" + +// Enables debug output for the tokenizer. +#define DEBUG_TOKENIZER 1 + +static inline bool isDelimiter(char ch, const char* delimiters) { + return strchr(delimiters, ch) != NULL; +} + +SysTokenizer::SysTokenizer(const char*filename, char* buffer, + bool ownBuffer, size_t length) : + mFilename(filename), + mBuffer(buffer), mOwnBuffer(ownBuffer), mLength(length), + mCurrent(buffer), mLineNumber(1) { +} + +SysTokenizer::~SysTokenizer() { + if (mOwnBuffer) { + delete[] mBuffer; + } +} + +int SysTokenizer::open(const char*filename, SysTokenizer** outTokenizer) { + *outTokenizer = NULL; + + int result = 0; + int fd = ::open(filename, O_RDONLY); + if (fd < 0) { + result = -errno; + ETRACE("Error opening file '%s', %s.", filename, strerror(errno)); + } else { + struct stat stat; + if (fstat(fd, &stat)) { + result = -errno; + ETRACE("Error getting size of file '%s', %s.", filename, strerror(errno)); + } else { + size_t length = size_t(stat.st_size); + bool ownBuffer = false; + char* buffer; + + // Fall back to reading into a buffer since we can't mmap files in sysfs. + // The length we obtained from stat is wrong too (it will always be 4096) + // so we must trust that read will read the entire file. + buffer = new char[length]; + ownBuffer = true; + ssize_t nrd = read(fd, buffer, length); + if (nrd < 0) { + result = -errno; + ETRACE("Error reading file '%s', %s.", filename, strerror(errno)); + delete[] buffer; + buffer = NULL; + } else { + length = size_t(nrd); + } + + if (!result) { + *outTokenizer = new SysTokenizer(filename, buffer, ownBuffer, length); + } + } + close(fd); + } + return result; +} + +int SysTokenizer::fromContents(const char*filename, + const char* contents, SysTokenizer** outTokenizer) { + *outTokenizer = new SysTokenizer(filename, + const_cast(contents), false, strlen(contents)); + return 0; +} + +char* SysTokenizer::getLocation() const { + memset((void*)mStrs, 0 , MAX_STR_LEN); + sprintf((char *)mStrs, "%s:%d", mFilename, mLineNumber); + return (char *)mStrs; +} + +char* SysTokenizer::peekRemainderOfLine() const { + const char* end = getEnd(); + const char* eol = mCurrent; + while (eol != end) { + char ch = *eol; + if (ch == '\n') { + break; + } + eol += 1; + } + + memset((void*)mLine, 0 , MAX_STR_LEN); + strncpy((char *)mLine, mCurrent, eol - mCurrent); + return (char *)mLine; +} + +char* SysTokenizer::nextToken(const char* delimiters) { + const char* end = getEnd(); + const char* tokenStart = mCurrent; + +#if DEBUG_TOKENIZER + ITRACE("nextToken mCurrent:%s, delimiters:%s\n", mCurrent, delimiters); +#endif + + while (mCurrent != end) { + char ch = *mCurrent; + if (ch == '\n' || isDelimiter(ch, delimiters)) { + break; + } + mCurrent += 1; + } + + memset((void*)mStrs, 0 , MAX_STR_LEN); + strncpy((char *)mStrs, tokenStart, mCurrent - tokenStart); + +#if DEBUG_TOKENIZER + ITRACE("nextToken parse end str:%s, num:%d \n", mStrs, mCurrent - tokenStart); +#endif + return (char *)mStrs; +} + +void SysTokenizer::nextLine() { +#if DEBUG_TOKENIZER + VTRACE("nextLine"); +#endif + const char* end = getEnd(); + while (mCurrent != end) { + char ch = *(mCurrent++); + if (ch == '\n') { + mLineNumber += 1; + break; + } + } +} + +void SysTokenizer::skipDelimiters(const char* delimiters) { +#if DEBUG_TOKENIZER + VTRACE("skipDelimiters"); +#endif + const char* end = getEnd(); + while (mCurrent != end) { + char ch = *mCurrent; + if (ch == '\n' || !isDelimiter(ch, delimiters)) { + break; + } + mCurrent += 1; + } +} + diff --git a/hwc2/common/utils/SysTokenizer.h b/hwc2/common/utils/SysTokenizer.h new file mode 100644 index 0000000..af16f34 --- a/dev/null +++ b/hwc2/common/utils/SysTokenizer.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * @author Tellen Yu + * @version 1.0 + * @date 2014/11/04 + * @par function description: + * - 1 parse file use tokenizer + */ + +#ifndef _SYS_TOKENIZER_H +#define _SYS_TOKENIZER_H + +#include + +#define MAX_STR_LEN 4096 + +/** + * A simple tokenizer for loading and parsing ASCII text files line by line. + */ +class SysTokenizer { +public: + SysTokenizer(const char*filename, char* buffer, + bool ownBuffer, size_t length); + + ~SysTokenizer(); + + /** + * Opens a file and maps it into memory. + * + * Returns NO_ERROR and a tokenizer for the file, if successful. + * Otherwise returns an error and sets outTokenizer to NULL. + */ + static int open(const char*filename, SysTokenizer** outTokenizer); + + /** + * Prepares to tokenize the contents of a string. + * + * Returns NO_ERROR and a tokenizer for the string, if successful. + * Otherwise returns an error and sets outTokenizer to NULL. + */ + static int fromContents(const char*filename, + const char* contents, SysTokenizer** outTokenizer); + + /** + * Returns true if at the end of the file. + */ + inline bool isEof() const { return mCurrent == getEnd(); } + + /** + * Returns true if at the end of the line or end of the file. + */ + inline bool isEol() const { return isEof() || *mCurrent == '\n'; } + + /** + * Gets the name of the file. + */ + inline char* getFilename() const { return const_cast(mFilename); } + + /** + * Gets a 1-based line number index for the current position. + */ + inline int32_t getLineNumber() const { return mLineNumber; } + + /** + * Formats a location string consisting of the filename and current line number. + * Returns a string like "MyFile.txt:33". + */ + char* getLocation() const; + + /** + * Gets the character at the current position. + * Returns null at end of file. + */ + inline char peekChar() const { return isEof() ? '\0' : *mCurrent; } + + /** + * Gets the remainder of the current line as a string, excluding the newline character. + */ + char* peekRemainderOfLine() const; + + /** + * Gets the character at the current position and advances past it. + * Returns null at end of file. + */ + inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); } + + /** + * Gets the next token on this line stopping at the specified delimiters + * or the end of the line whichever comes first and advances past it. + * Also stops at embedded nulls. + * Returns the token or an empty string if the current character is a delimiter + * or is at the end of the line. + */ + char* nextToken(const char* delimiters); + + /** + * Advances to the next line. + * Does nothing if already at the end of the file. + */ + void nextLine(); + + /** + * Skips over the specified delimiters in the line. + * Also skips embedded nulls. + */ + void skipDelimiters(const char* delimiters); + +private: + const char* mFilename; + char* mBuffer; + bool mOwnBuffer; + size_t mLength; + + const char* mCurrent; + int32_t mLineNumber; + + char mStrs[MAX_STR_LEN]; + char mLine[MAX_STR_LEN]; + inline const char* getEnd() const { return mBuffer + mLength; } + +}; + +#endif // _SYS_TOKENIZER_H diff --git a/hwc2/include/PhysicalDevice.h b/hwc2/include/PhysicalDevice.h index 708b6ee..66f925c 100644 --- a/hwc2/include/PhysicalDevice.h +++ b/hwc2/include/PhysicalDevice.h @@ -133,6 +133,7 @@ public: // display config operations virtual bool updateDisplayConfigs(); virtual void updateActiveDisplayAttribute(); + void updateDisplayInfo(char defaultMode[64]); // events virtual void onVsync(int64_t timestamp); @@ -258,6 +259,9 @@ private: float mReverseScaleX; float mReverseScaleY; + int mDisplayWidth; + int mDisplayHeight; + //omx handle for set omx pts int32_t mOmxVideoHandle; }; diff --git a/hwc2/include/PrimaryDevice.h b/hwc2/include/PrimaryDevice.h index 6d88617..d003133 100644 --- a/hwc2/include/PrimaryDevice.h +++ b/hwc2/include/PrimaryDevice.h @@ -23,6 +23,15 @@ #include #include +#define DEVICE_STR_MBOX "MBOX" +#define DEVICE_STR_TV "TV" + +#if PLATFORM_SDK_VERSION >= 26 //8.0 +#define DISPLAY_CFG_FILE "/vendor/etc/mesondisplay.cfg" +#else +#define DISPLAY_CFG_FILE "/system/etc/mesondisplay.cfg" +#endif + namespace android { namespace amlogic { @@ -41,6 +50,11 @@ public: private: static void hotplugEventListener(void *data, bool status); void hotplugListener(bool connected); + int parseConfigFile(); + + const char* pConfigPath; + int mDisplayType; + char mDefaultMode[64];//this used for mbox }; } diff --git a/hwc2/platforms/Android.mk b/hwc2/platforms/Android.mk index a5896d4..e57368e 100644 --- a/hwc2/platforms/Android.mk +++ b/hwc2/platforms/Android.mk @@ -31,7 +31,8 @@ LOCAL_SRC_FILES := \ ../common/utils/Utils.cpp \ ../common/utils/Dump.cpp \ ../common/utils/AmVinfo.cpp \ - ../common/utils/AmVideo.cpp + ../common/utils/AmVideo.cpp \ + ../common/utils/SysTokenizer.cpp \ LOCAL_SRC_FILES += \ PlatFactory.cpp -- cgit