summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--common/display/include/HwDisplayConnector.h8
-rw-r--r--common/hwc/ActiveModeMgr.cpp (renamed from hwc2/ActiveModeMgr.cpp)0
-rw-r--r--common/hwc/Android.mk5
-rw-r--r--common/hwc/FixedSizeModeMgr.cpp (renamed from hwc2/FixedSizeModeMgr.cpp)0
-rw-r--r--common/hwc/HwcModeMgr.cpp (renamed from hwc2/HwcModeMgr.cpp)0
-rw-r--r--common/hwc/RealModeMgr.cpp (renamed from hwc2/RealModeMgr.cpp)0
-rw-r--r--common/hwc/VariableModeMgr.cpp (renamed from hwc2/VariableModeMgr.cpp)0
-rw-r--r--common/hwc/include/ActiveModeMgr.h (renamed from hwc2/ActiveModeMgr.h)0
-rw-r--r--common/hwc/include/FixedSizeModeMgr.h (renamed from hwc2/FixedSizeModeMgr.h)0
-rw-r--r--common/hwc/include/RealModeMgr.h (renamed from hwc2/RealModeMgr.h)0
-rw-r--r--common/hwc/include/VariableModeMgr.h (renamed from hwc2/VariableModeMgr.h)0
-rw-r--r--hwc2/Android.mk62
-rwxr-xr-xhwc2/Hwc2Display.cpp18
-rw-r--r--hwc2/Hwc2Display.h4
-rw-r--r--hwc2/Hwc2Module.cpp9
-rw-r--r--hwc2/MesonHwc2.cpp8
-rw-r--r--hwc2/MesonHwc2.h9
-rw-r--r--postprocessor/Android.mk3
-rw-r--r--postprocessor/fbprocessor/CopyProcessor.cpp16
-rw-r--r--service/2.3/default/android.hardware.graphics.composer@2.3-service.droidlogic.xml9
-rw-r--r--service/2.4/default/android.hardware.graphics.composer@2.4-service.droidlogic.xml9
21 files changed, 138 insertions, 22 deletions
diff --git a/common/hwc/VariableModeMgr.cpp b/common/hwc/VariableModeMgr.cpp
new file mode 100644
index 0000000..da4017d
--- a/dev/null
+++ b/common/hwc/VariableModeMgr.cpp
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
+ *
+ * This source code is subject to the terms and conditions defined in the
+ * file 'LICENSE' which is part of this source code package.
+ *
+ * Description:
+ */
+
+#include "VariableModeMgr.h"
+
+#include <HwcConfig.h>
+#include <MesonLog.h>
+#include <systemcontrol.h>
+#include <hardware/hwcomposer2.h>
+
+#include <string>
+
+#define DEFUALT_DPI (160)
+#define DEFAULT_REFRESH_RATE_60 (60.0f)
+#define DEFAULT_REFRESH_RATE_50 (50.0f)
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/* used for init default configs */
+static const drm_mode_info_t mode_info[] = {
+ { /* VMODE_720P */
+ .name = "720p60hz",
+ .dpiX = DEFUALT_DPI,
+ .dpiY = DEFUALT_DPI,
+ .pixelW = 1280,
+ .pixelH = 720,
+ .refreshRate = DEFAULT_REFRESH_RATE_60,
+ },
+ { /* VMODE_1080P */
+ .name = "1080p60hz",
+ .dpiX = DEFUALT_DPI,
+ .dpiY = DEFUALT_DPI,
+ .pixelW = 1920,
+ .pixelH = 1080,
+ .refreshRate = DEFAULT_REFRESH_RATE_60,
+ },
+ { /* VMODE_720P_50hz */
+ .name = "720p50hz",
+ .dpiX = DEFUALT_DPI,
+ .dpiY = DEFUALT_DPI,
+ .pixelW = 1280,
+ .pixelH = 720,
+ .refreshRate = DEFAULT_REFRESH_RATE_50,
+ },
+ { /* VMODE_1080P_50HZ */
+ .name = "1080p50hz",
+ .dpiX = DEFUALT_DPI,
+ .dpiY = DEFUALT_DPI,
+ .pixelW = 1920,
+ .pixelH = 1080,
+ .refreshRate = DEFAULT_REFRESH_RATE_50,
+ },
+ { /* DefaultMode */
+ .name = "DefaultMode",
+ .dpiX = DEFUALT_DPI,
+ .dpiY = DEFUALT_DPI,
+ .pixelW = 1920,
+ .pixelH = 1080,
+ .refreshRate = DEFAULT_REFRESH_RATE_60,
+ },
+};
+
+VariableModeMgr::VariableModeMgr()
+ : mIsInit(true) {
+}
+
+VariableModeMgr::~VariableModeMgr() {
+
+}
+
+hwc_modes_policy_t VariableModeMgr::getPolicyType() {
+ return FULL_ACTIVE_POLICY;
+}
+
+const char * VariableModeMgr::getName() {
+ return "VariableMode";
+}
+
+void VariableModeMgr::setFramebufferSize(uint32_t w, uint32_t h) {
+ mFbWidth = w;
+ mFbHeight = h;
+}
+
+void VariableModeMgr::setDisplayResources(
+ std::shared_ptr<HwDisplayCrtc> & crtc,
+ std::shared_ptr<HwDisplayConnector> & connector) {
+ mConnector = connector;
+ mCrtc = crtc;
+
+ /*
+ * Only when it is first boot will come here,
+ * initialize a default display mode according to the given FB size,
+ * and will return this default mode to SF before it calls setActiveConfig().
+ */
+ if (mIsInit) {
+ mIsInit = false;
+ reset();
+ initDefaultDispResources();
+ }
+
+ update();
+}
+
+int32_t VariableModeMgr::initDefaultDispResources() {
+ mDefaultMode =
+ findMatchedMode(mFbWidth, mFbHeight, DEFAULT_REFRESH_RATE_60);
+ mHwcActiveModes.emplace(mHwcActiveModes.size(), mDefaultMode);
+ updateHwcActiveConfig(mDefaultMode.name);
+ MESON_LOGV("initDefaultDispResources (%s)", mDefaultMode.name);
+ return 0;
+}
+
+int32_t VariableModeMgr::update() {
+ MESON_LOG_FUN_ENTER();
+ bool useFakeMode = false;
+
+ if (mConnector->isConnected()) {
+ updateHwcDispConfigs();
+ drm_mode_info_t dispmode;
+ if (getDisplayMode(dispmode) == 0) {
+ updateHwcActiveConfig(dispmode.name);
+ } else {
+ useFakeMode = true;
+ MESON_LOGD("Get invalid display mode.");
+ }
+ } else
+ useFakeMode = true;
+
+ if (useFakeMode)
+ updateHwcActiveConfig(mDefaultMode.name);
+
+ MESON_LOG_FUN_LEAVE();
+ return 0;
+}
+
+int32_t VariableModeMgr::getDisplayMode(drm_mode_info_t & mode) {
+ return mCrtc->getMode(mode);
+}
+
+int32_t VariableModeMgr::getDisplayConfigs(
+ uint32_t * outNumConfigs, uint32_t * outConfigs) {
+ *outNumConfigs = mHwcActiveModes.size();
+
+ if (outConfigs) {
+ updateSfDispConfigs();
+ std::map<uint32_t, drm_mode_info_t>::iterator it =
+ mSfActiveModes.begin();
+ for (uint32_t index = 0; it != mSfActiveModes.end(); ++it, ++index) {
+ outConfigs[index] = it->first;
+ MESON_LOGV("outConfig[%d]: %d.", index, outConfigs[index]);
+ }
+ }
+ return HWC2_ERROR_NONE;
+}
+
+int32_t VariableModeMgr::updateHwcDispConfigs() {
+ std::map<uint32_t, drm_mode_info_t> activeModes;
+ mHwcActiveModes.clear();
+
+ mConnector->getModes(activeModes);
+ for (auto it = activeModes.begin(); it != activeModes.end(); ++it) {
+ // skip default / fake active mode as we add it to the end
+ if (!strncmp(mDefaultMode.name, it->second.name, DRM_DISPLAY_MODE_LEN)
+ && mDefaultMode.refreshRate == it->second.refreshRate) {
+ mDefaultModeSupport = true;
+ mDefaultMode.dpiX = it->second.dpiX;
+ mDefaultMode.dpiY = it->second.dpiY;
+ } else {
+ MESON_LOGV("[%s]: Hwc modes %d.", __func__, mHwcActiveModes.size());
+ mHwcActiveModes.emplace(mHwcActiveModes.size(), it->second);
+ }
+ }
+
+ // Add default mode as last, unconditionally in all cases. This is to ensure
+ // availability of 1080p mode always.
+ MESON_LOGV("[%s]: Hwc modes %d.", __func__, mHwcActiveModes.size());
+ mHwcActiveModes.emplace(mHwcActiveModes.size(), mDefaultMode);
+ return HWC2_ERROR_NONE;
+}
+
+int32_t VariableModeMgr::updateSfDispConfigs() {
+ // clear display modes
+ mSfActiveModes.clear();
+
+ mSfActiveModes = mHwcActiveModes;
+
+ // Set active config id used by SF.
+ mSfActiveConfigId = mHwcActiveConfigId;
+
+ return HWC2_ERROR_NONE;
+}
+
+int32_t VariableModeMgr::getDisplayAttribute(
+ uint32_t config, int32_t attribute, int32_t * outValue, int32_t caller) {
+ MESON_LOGV("getDisplayAttribute: config %d, fakeConfig %d,"
+ "HwcActiveConfig %d, SfActiveConfig %d, mExtModeSet %d, caller (%s)",
+ config, mFakeConfigId, mHwcActiveConfigId, mSfActiveConfigId, mExtModeSet,
+ caller == CALL_FROM_SF ? "SF" : "HWC");
+
+ std::map<uint32_t, drm_mode_info_t>::iterator it;
+ if (CALL_FROM_SF == caller) {
+ it = mSfActiveModes.find(config);
+ } else if (CALL_FROM_HWC == caller) {
+ it = mHwcActiveModes.find(config);
+ }
+
+ if (it != mHwcActiveModes.end() || it != mSfActiveModes.end()) {
+ drm_mode_info_t curMode = it->second;
+
+ switch (attribute) {
+ case HWC2_ATTRIBUTE_WIDTH:
+ *outValue = curMode.pixelW;
+ break;
+ case HWC2_ATTRIBUTE_HEIGHT:
+ *outValue = curMode.pixelH;
+ break;
+ case HWC2_ATTRIBUTE_VSYNC_PERIOD:
+ #ifdef HWC_HEADLESS
+ *outValue = 1e9 / (HWC_HEADLESS_REFRESHRATE);
+ #else
+ *outValue = 1e9 / curMode.refreshRate;
+ #endif
+ break;
+ case HWC2_ATTRIBUTE_DPI_X:
+ *outValue = curMode.dpiX * 1000.0f;
+ break;
+ case HWC2_ATTRIBUTE_DPI_Y:
+ *outValue = curMode.dpiY * 1000.0f;
+ break;
+ default:
+ MESON_LOGE("Unkown display attribute(%d)", attribute);
+ break;
+ }
+
+ return HWC2_ERROR_NONE;
+ } else {
+ MESON_LOGE("[%s]: no support display config: %d", __func__, config);
+ return HWC2_ERROR_UNSUPPORTED;
+ }
+}
+
+int32_t VariableModeMgr::updateHwcActiveConfig(
+ const char * activeMode) {
+ mActiveConfigStr = activeMode;
+
+ for (auto it = mHwcActiveModes.begin(); it != mHwcActiveModes.end(); ++it) {
+ if (strncmp(activeMode, it->second.name, DRM_DISPLAY_MODE_LEN) == 0) {
+ mHwcActiveConfigId = it->first;
+ mFakeConfigId = mHwcActiveModes.size()-1;
+ MESON_LOGD("updateActiveConfig to (%s, %d)", activeMode, mHwcActiveConfigId);
+ return HWC2_ERROR_NONE;
+ }
+ }
+
+ // If we reach here we are trying to set an unsupported mode. This can happen as
+ // SystemControl does not guarantee to keep the EDID mode list and the active
+ // mode id synchronised. We therefore handle the case where the active mode is
+ // not supported by ensuring something sane is set instead.
+ // NOTE: this is only really a workaround - HWC should instead guarantee that
+ // the display mode list and active mode reported to SF are kept in sync with
+ // hot plug events.
+ mHwcActiveConfigId = mHwcActiveModes.size()-1;
+ mFakeConfigId = mHwcActiveConfigId;
+ MESON_LOGD("updateActiveConfig something error to (%s, %d)", activeMode, mHwcActiveConfigId);
+
+ return HWC2_ERROR_NONE;
+}
+
+int32_t VariableModeMgr::getActiveConfig(
+ uint32_t * outConfig, int32_t caller) {
+ if (CALL_FROM_SF == caller) {
+ *outConfig = mExtModeSet ? mSfActiveConfigId : mFakeConfigId;
+ } else if (CALL_FROM_HWC == caller) {
+ *outConfig = mExtModeSet ? mHwcActiveConfigId : mFakeConfigId;
+ }
+ MESON_LOGV("[%s]: ret %d, Sf id %d, Hwc id %d, fake id %d, mExtModeSet %d, caller (%s)",
+ __func__ ,*outConfig, mSfActiveConfigId, mHwcActiveConfigId, mFakeConfigId,
+ mExtModeSet, caller == CALL_FROM_SF ? "SF" : "HWC");
+ return HWC2_ERROR_NONE;
+}
+
+int32_t VariableModeMgr::setActiveConfig(
+ uint32_t config) {
+ std::map<uint32_t, drm_mode_info_t>::iterator it =
+ mSfActiveModes.find(config);
+ if (it != mSfActiveModes.end()) {
+ drm_mode_info_t cfg = it->second;
+
+ // update real active config.
+ updateHwcActiveConfig(cfg.name);
+
+ // since SF is asking to set the mode, we should update mSFActiveConfigId
+ // as well here so that when SF calls getActiveConfig, we return correct
+ // mode. Without it, mSFActiveConfigId is getting updated only when
+ // updateSfDispConfigs is called by getDisplayConfigs. But getDisplayConfigs
+ // does not get called when user manually selects a mode and mSFActiveConfigId
+ // stays stale.
+ mSfActiveConfigId = mHwcActiveConfigId;
+
+ // It is possible that default mode is not supported by the sink
+ // and it was only advertised to the FWK to force 1080p UI.
+ // Trap this case and do nothing. FWK will keep thinking
+ // 1080p is supported and set.
+ if (!mDefaultModeSupport
+ && strncmp(cfg.name, mDefaultMode.name, DRM_DISPLAY_MODE_LEN) == 0) {
+ MESON_LOGD("setActiveConfig default mode not supported");
+ return HWC2_ERROR_NONE;
+ }
+
+ mCrtc->setMode(cfg);
+ mExtModeSet = true;
+ MESON_LOGD("setActiveConfig %d, mExtModeSet %d",
+ config, mExtModeSet);
+ return HWC2_ERROR_NONE;
+ } else {
+ MESON_LOGE("set invalild active config (%d)", config);
+ return HWC2_ERROR_NOT_VALIDATED;
+ }
+}
+
+void VariableModeMgr::reset() {
+ mHwcActiveModes.clear();
+ mSfActiveModes.clear();
+ mDefaultModeSupport = false;
+ mSfActiveConfigId = mHwcActiveConfigId = mFakeConfigId = -1;
+ mExtModeSet = false;
+}
+
+const drm_mode_info_t VariableModeMgr::findMatchedMode(
+ uint32_t width, uint32_t height, float refreshrate) {
+ uint32_t i = 0;
+ uint32_t size = ARRAY_SIZE(mode_info);
+ for (i = 0; i < size; i++) {
+ if (mode_info[i].pixelW == width &&
+ mode_info[i].pixelH == height &&
+ mode_info[i].refreshRate == refreshrate) {
+ return mode_info[i];
+ }
+ }
+ return mode_info[size-1];
+}
+
+void VariableModeMgr::dump(String8 & dumpstr) {
+ dumpstr.appendFormat("VariableModeMgr: %s\n", mActiveConfigStr.c_str());
+ dumpstr.append("---------------------------------------------------------"
+ "-------------------------\n");
+ dumpstr.append("| CONFIG | VSYNC_PERIOD | WIDTH | HEIGHT |"
+ " DPI_X | DPI_Y |\n");
+ dumpstr.append("+------------+------------------+-----------+------------+"
+ "-----------+-----------+\n");
+ std::map<uint32_t, drm_mode_info_t>::iterator it =
+ mHwcActiveModes.begin();
+ for (; it != mHwcActiveModes.end(); ++it) {
+ int mode = it->first;
+ drm_mode_info_t config = it->second;
+ dumpstr.appendFormat("%s %2d | %.3f | %5d | %5d |"
+ " %3d | %3d \n",
+ (mode == (int)mHwcActiveConfigId) ? "* " : " ",
+ mode,
+ config.refreshRate,
+ config.pixelW,
+ config.pixelH,
+ config.dpiX,
+ config.dpiY);
+ }
+ dumpstr.append("---------------------------------------------------------"
+ "-------------------------\n");
+}
+