diff options
24 files changed, 409 insertions, 120 deletions
diff --git a/hwc3/Android.mk b/hwc3/Android.mk index f233aab..43538d3 100644 --- a/hwc3/Android.mk +++ b/hwc3/Android.mk @@ -35,7 +35,7 @@ LOCAL_SHARED_LIBRARIES := android.hardware.graphics.composer3-V1-ndk \ android.hardware.graphics.composer@2.1-resources \ android.hardware.graphics.composer@2.2-resources \ android.hardware.graphics.composer@2.4 \ - com.google.hardware.pixel.display-V6-ndk \ + com.google.hardware.pixel.display-V7-ndk \ libbase \ libbinder \ libbinder_ndk \ diff --git a/libhwc2.1/Android.mk b/libhwc2.1/Android.mk index 5b0d781..71391cd 100644 --- a/libhwc2.1/Android.mk +++ b/libhwc2.1/Android.mk @@ -68,7 +68,7 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware \ android.hardware.power-V2-ndk pixel-power-ext-V1-ndk LOCAL_SHARED_LIBRARIES += android.hardware.graphics.composer3-V1-ndk \ - com.google.hardware.pixel.display-V6-ndk \ + com.google.hardware.pixel.display-V7-ndk \ libbinder_ndk \ libbase \ libpng \ @@ -160,7 +160,7 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libbinder libexynosdisplay l android.hardware.graphics.allocator@2.0 \ android.hardware.graphics.mapper@2.0 -LOCAL_SHARED_LIBRARIES += com.google.hardware.pixel.display-V6-ndk \ +LOCAL_SHARED_LIBRARIES += com.google.hardware.pixel.display-V7-ndk \ libbinder_ndk \ libbase @@ -221,7 +221,7 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libexynosdisplay libacryl \ libui LOCAL_SHARED_LIBRARIES += android.hardware.graphics.composer3-V1-ndk \ - com.google.hardware.pixel.display-V6-ndk \ + com.google.hardware.pixel.display-V7-ndk \ libbinder_ndk \ libbase diff --git a/libhwc2.1/ExynosHWC.cpp b/libhwc2.1/ExynosHWC.cpp index 8b3d9a4..fee44ed 100644 --- a/libhwc2.1/ExynosHWC.cpp +++ b/libhwc2.1/ExynosHWC.cpp @@ -1149,15 +1149,34 @@ int32_t exynos_SetActiveConfigWithConstraints(hwc2_device_t* dev, hwc2_display_t { HDEBUGLOGD(eDebugDisplayConfig, "%s, %d", __func__, config); ExynosDevice *exynosDevice = checkDevice(dev); + if (!exynosDevice) { + return HWC2_ERROR_BAD_DISPLAY; + } - if (exynosDevice) { - ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display); - if (exynosDisplay) { - return exynosDisplay->setActiveConfigWithConstraints(config, vsyncPeriodChangeConstraints, outTimeline); + ExynosDisplay *exynosDisplay = checkDisplay(exynosDevice, display); + if (!exynosDisplay) { + return HWC2_ERROR_BAD_DISPLAY; + } + + const auto prevXres = exynosDisplay->mXres, prevYres = exynosDisplay->mYres; + auto ret = exynosDisplay->setActiveConfigWithConstraints(config, + vsyncPeriodChangeConstraints, + outTimeline); + if (ret != HWC2_ERROR_NONE) { + ALOGE("exynos_SetActiveConfigWithConstraints() failed config(%d)", config); + return ret; + } + + // when resolution is changed, HWC2 updates the property + if (prevXres != exynosDisplay->mDisplayConfigs[config].width || + prevYres != exynosDisplay->mDisplayConfigs[config].height) { + if ((ret = exynosDisplay->setBootDisplayConfig(config)) != HWC2_ERROR_NONE) { + ALOGE("setBootDisplayConfig() failed when setActiveConfigWithConstraints()"); + return ret; } } - return HWC2_ERROR_BAD_DISPLAY; + return HWC2_ERROR_NONE; } int32_t exynos_SetAutoLowLatencyMode(hwc2_device_t* dev, hwc2_display_t display, bool on) diff --git a/libhwc2.1/histogram_mediator.cpp b/libhwc2.1/histogram_mediator.cpp index c917783..991b972 100644 --- a/libhwc2.1/histogram_mediator.cpp +++ b/libhwc2.1/histogram_mediator.cpp @@ -19,8 +19,9 @@ histogram::HistogramMediator::HistogramMediator(ExynosDisplay *display) { mDisplay = display; ExynosDisplayDrmInterface *moduleDisplayInterface = static_cast<ExynosDisplayDrmInterface *>(display->mDisplayInterface.get()); + mIDLHistogram = std::make_shared<HistogramReceiver>(); - moduleDisplayInterface->registerHistogramInfo(static_cast<IDLHistogram *>(&mIDLHistogram)); + moduleDisplayInterface->registerHistogramInfo(mIDLHistogram); moduleDisplayInterface->getPanelResolution(); } uint32_t histogram::HistogramMediator::getFrameCount() { @@ -60,8 +61,8 @@ histogram::HistogramErrorCode histogram::HistogramMediator::requestHist() { return histogram::HistogramErrorCode::ENABLE_HIST_ERROR; } { - std::unique_lock<std::mutex> lk(mIDLHistogram.mDataCollectingMutex); - mIDLHistogram.mHistReq_pending = true; + std::unique_lock<std::mutex> lk(mIDLHistogram->mDataCollectingMutex); + mIDLHistogram->mHistReq_pending = true; } return histogram::HistogramErrorCode::NONE; } @@ -94,25 +95,25 @@ int histogram::HistogramMediator::calculateThreshold(const RoiRect &roi) { histogram::HistogramErrorCode histogram::HistogramMediator::setRoiWeightThreshold( const RoiRect roi, const Weight weight, const HistogramPos pos) { int threshold = calculateThreshold(roi); - mIDLHistogram.setHistogramROI((uint16_t)roi.left, (uint16_t)roi.top, - (uint16_t)(roi.right - roi.left), - (uint16_t)(roi.bottom - roi.top)); - mIDLHistogram.setHistogramWeights(weight.weightR, weight.weightG, weight.weightB); - mIDLHistogram.setHistogramThreshold(threshold); - mIDLHistogram.setHistogramPos(pos); + mIDLHistogram->setHistogramROI((uint16_t)roi.left, (uint16_t)roi.top, + (uint16_t)(roi.right - roi.left), + (uint16_t)(roi.bottom - roi.top)); + mIDLHistogram->setHistogramWeights(weight.weightR, weight.weightG, weight.weightB); + mIDLHistogram->setHistogramThreshold(threshold); + mIDLHistogram->setHistogramPos(pos); return histogram::HistogramErrorCode::NONE; } histogram::HistogramErrorCode histogram::HistogramMediator::collectRoiLuma( std::vector<char16_t> *buf) { - std::unique_lock<std::mutex> lk(mIDLHistogram.mDataCollectingMutex); + std::unique_lock<std::mutex> lk(mIDLHistogram->mDataCollectingMutex); - mIDLHistogram.mHistData_cv.wait_for(lk, std::chrono::milliseconds(50), [this]() { - return (!isDisplayPowerOff() && !mIDLHistogram.mHistReq_pending); + mIDLHistogram->mHistData_cv.wait_for(lk, std::chrono::milliseconds(50), [this]() { + return (!isDisplayPowerOff() && !mIDLHistogram->mHistReq_pending); }); - if (mIDLHistogram.mHistReq_pending == false) setSampleFrameCounter(getFrameCount()); - buf->assign(mIDLHistogram.mHistData, mIDLHistogram.mHistData + HISTOGRAM_BINS_SIZE); + if (mIDLHistogram->mHistReq_pending == false) setSampleFrameCounter(getFrameCount()); + buf->assign(mIDLHistogram->mHistData, mIDLHistogram->mHistData + HISTOGRAM_BINS_SIZE); return histogram::HistogramErrorCode::NONE; } diff --git a/libhwc2.1/histogram_mediator.h b/libhwc2.1/histogram_mediator.h index 84f77a2..eac4c98 100644 --- a/libhwc2.1/histogram_mediator.h +++ b/libhwc2.1/histogram_mediator.h @@ -66,7 +66,7 @@ public: const HistogramPos pos); RoiRect calRoi(RoiRect roi); struct HistogramReceiver : public IDLHistogram { - HistogramReceiver() : mHistData() {} + HistogramReceiver() : mHistData(){}; void callbackHistogram(char16_t *bin) override; uint16_t mHistData[HISTOGRAM_BINS_SIZE]; // luma buffer std::condition_variable mHistData_cv; // for pullback data sync ctrl @@ -76,11 +76,11 @@ public: uint32_t getFrameCount(); void setSampleFrameCounter(int32_t id) { mSampledFrameCounter = id; } uint32_t getSampleFrameCounter() { return mSampledFrameCounter; } - bool histRequested() { return mIDLHistogram.mHistReq_pending; } + bool histRequested() { return mIDLHistogram->mHistReq_pending; } private: int calculateThreshold(const RoiRect &roi); - HistogramReceiver mIDLHistogram; + std::shared_ptr<HistogramReceiver> mIDLHistogram; ExynosDisplay *mDisplay = nullptr; uint32_t mSampledFrameCounter = 0; }; diff --git a/libhwc2.1/libdevice/BrightnessController.cpp b/libhwc2.1/libdevice/BrightnessController.cpp index a18c499..1057629 100644 --- a/libhwc2.1/libdevice/BrightnessController.cpp +++ b/libhwc2.1/libdevice/BrightnessController.cpp @@ -34,6 +34,7 @@ BrightnessController::BrightnessController(int32_t panelIndex, std::function<voi mLhbm(false), mSdrDim(false), mPrevSdrDim(false), + mDimBrightnessReq(false), mFrameRefresh(refresh), mHdrLayerState(HdrLayerState::kHdrNone), mUpdateDcLhbm(updateDcLhbm) { @@ -106,11 +107,15 @@ void BrightnessController::initBrightnessSysfs() { } void BrightnessController::initCabcSysfs() { + mCabcSupport = property_get_bool("vendor.display.cabc.supported", false); + if (!mCabcSupport) return; + String8 nodeName; nodeName.appendFormat(kLocalCabcModeFileNode, mPanelIndex); + mCabcModeOfs.open(nodeName.string(), std::ofstream::out); if (mCabcModeOfs.fail()) { - ALOGW("%s %s fail to open", __func__, nodeName.string()); + ALOGE("%s %s fail to open", __func__, nodeName.string()); mCabcModeOfs.close(); return; } @@ -153,6 +158,21 @@ void BrightnessController::initBrightnessTable(const DrmDevice& drmDevice, mBrightnessIntfSupported = true; drmModeFreePropertyBlob(blob); + + String8 nodeName; + nodeName.appendFormat(kDimBrightnessFileNode, mPanelIndex); + + std::ifstream ifsDimBrightness(nodeName.string()); + if (ifsDimBrightness.fail()) { + ALOGW("%s fail to open %s", __func__, nodeName.string()); + } else { + ifsDimBrightness >> mDimBrightness; + ifsDimBrightness.close(); + if (mDimBrightness >= mBrightnessTable[toUnderlying(BrightnessRange::NORMAL)].mBklStart) + mDimBrightness = 0; + } + mDbmSupported = !!mDimBrightness; + ALOGI("%s mDimBrightness=%d, mDbmSupported=%d", __func__, mDimBrightness, mDbmSupported); } int BrightnessController::processEnhancedHbm(bool on) { @@ -202,20 +222,14 @@ int BrightnessController::processDisplayBrightness(float brightness, const nsecs // check if it will go drm path for below cases. // case 1: hbm state will change // case 2: for hwc3, brightness command could apply at next present if possible - if (mGhbmSupported || waitPresent) { + if (queryBrightness(brightness, &ghbm, &level) == NO_ERROR) { // ghbm on/off always go drm path - if (mGhbmSupported) { - if (queryBrightness(brightness, &ghbm, &level)) { - ALOGE("%s failed to convert brightness %f", __func__, brightness); - return -EINVAL; - } - // check if this will cause a hbm transition - if ((mGhbm.get() != HbmMode::OFF) != ghbm) { - // this brightness change will go drm path - updateStates(); - mFrameRefresh(); // force next frame to update brightness - return NO_ERROR; - } + // check if this will cause a hbm transition + if (mGhbmSupported && (mGhbm.get() != HbmMode::OFF) != ghbm) { + // this brightness change will go drm path + updateStates(); + mFrameRefresh(); // force next frame to update brightness + return NO_ERROR; } // there will be a Present to apply this brightness change if (waitPresent) { @@ -234,13 +248,13 @@ int BrightnessController::processDisplayBrightness(float brightness, const nsecs if (mUncheckedGbhmRequest) { ATRACE_NAME("check_ghbm_mode"); checkSysfsStatus(kGlobalHbmModeFileNode, - std::to_string(toUnderlying(mPendingGhbmStatus.load())), vsyncNs * 5); + {std::to_string(toUnderlying(mPendingGhbmStatus.load()))}, vsyncNs * 5); mUncheckedGbhmRequest = false; } if (mUncheckedLhbmRequest) { ATRACE_NAME("check_lhbm_mode"); - checkSysfsStatus(kLocalHbmModeFileNode, std::to_string(mPendingLhbmStatus), vsyncNs * 5); + checkSysfsStatus(kLocalHbmModeFileNode, {std::to_string(mPendingLhbmStatus)}, vsyncNs * 5); mUncheckedLhbmRequest = false; } @@ -279,7 +293,7 @@ int BrightnessController::applyPendingChangeViaSysfs(const nsecs_t vsyncNs) { if (mUncheckedBlRequest) { ATRACE_NAME("check_bl_value"); - checkSysfsStatus(BRIGHTNESS_SYSFS_NODE, std::to_string(mPendingBl), vsyncNs * 5); + checkSysfsStatus(BRIGHTNESS_SYSFS_NODE, {std::to_string(mPendingBl)}, vsyncNs * 5); mUncheckedBlRequest = false; } @@ -327,6 +341,16 @@ int BrightnessController::processInstantHbm(bool on) { return NO_ERROR; } +int BrightnessController::processDimBrightness(bool on) { + std::lock_guard<std::recursive_mutex> lock(mBrightnessMutex); + mDimBrightnessReq.store(on); + if (mDimBrightnessReq.is_dirty()) { + updateStates(); + ALOGI("%s request = %d", __func__, mDimBrightnessReq.get()); + } + return NO_ERROR; +} + float BrightnessController::getSdrDimRatioForInstantHbm() { if (!mBrightnessIntfSupported || !mGhbmSupported) { return 1.0f; @@ -358,9 +382,10 @@ float BrightnessController::getSdrDimRatioForInstantHbm() { } void BrightnessController::onClearDisplay() { + resetLhbmState(); + std::lock_guard<std::recursive_mutex> lock(mBrightnessMutex); mEnhanceHbmReq.reset(false); - mLhbmReq.reset(false); mBrightnessFloatReq.reset(-1); mInstantHbmReq.reset(false); @@ -373,9 +398,6 @@ void BrightnessController::onClearDisplay() { if (mBrightnessDimmingUsage == BrightnessDimmingUsage::NORMAL) { mDimming.store(true); } - mLhbm.reset(false); - - mLhbmBrightnessAdj = false; std::lock_guard<std::recursive_mutex> lock1(mCabcModeMutex); mCabcMode.reset(false); @@ -594,11 +616,11 @@ int BrightnessController::updateStates() { mInstantHbmReq.clear_dirty(); mSdrDim.clear_dirty(); mPrevSdrDim.clear_dirty(); + mDimBrightnessReq.clear_dirty(); if (mBrightnessLevel.is_dirty() || mDimming.is_dirty() || mGhbm.is_dirty() || mLhbm.is_dirty()) { - ALOGI("level=%d, DimmingOn=%d, Hbm=%d, LhbmOn=%d.", mBrightnessLevel.get(), mDimming.get(), - mGhbm.get(), mLhbm.get()); + printBrightnessStates("drm"); } return NO_ERROR; } @@ -609,6 +631,15 @@ int BrightnessController::queryBrightness(float brightness, bool *ghbm, uint32_t return HWC2_ERROR_UNSUPPORTED; } + if (mBrightnessTable[toUnderlying(BrightnessRange::NORMAL)].mBklStart == 0 && + mBrightnessTable[toUnderlying(BrightnessRange::NORMAL)].mBklEnd == 0 && + mBrightnessTable[toUnderlying(BrightnessRange::NORMAL)].mBriStart == 0 && + mBrightnessTable[toUnderlying(BrightnessRange::NORMAL)].mBriEnd == 0 && + mBrightnessTable[toUnderlying(BrightnessRange::NORMAL)].mNitsStart == 0 && + mBrightnessTable[toUnderlying(BrightnessRange::NORMAL)].mNitsEnd == 0) { + return HWC2_ERROR_UNSUPPORTED; + } + if (brightness < 0) { // screen off if (ghbm) { @@ -644,7 +675,10 @@ int BrightnessController::queryBrightness(float brightness, bool *ghbm, uint32_t *nits = norm * nSpan + mBrightnessTable[i].mNitsStart; } } - + if ((i == toUnderlying(BrightnessRange::NORMAL)) && mDbmSupported && + (mDimBrightnessReq.get() == true) && (*level == mBrightnessTable[i].mBklStart)) { + *level = mDimBrightness; + } return NO_ERROR; } } @@ -653,9 +687,13 @@ int BrightnessController::queryBrightness(float brightness, bool *ghbm, uint32_t } // Return immediately if it's already in the status. Otherwise poll the status -int BrightnessController::checkSysfsStatus(const char* file, const std::string& expectedValue, +int BrightnessController::checkSysfsStatus(const char* file, + const std::vector<std::string>& expectedValue, const nsecs_t timeoutNs) { ATRACE_CALL(); + + if (expectedValue.size() == 0) return false; + char buf[16]; String8 nodeName; nodeName.appendFormat(file, mPanelIndex); @@ -668,8 +706,11 @@ int BrightnessController::checkSysfsStatus(const char* file, const std::string& } // '- 1' to remove trailing '\n' - if (std::string_view(buf, size - 1) == expectedValue) { + std::string val = std::string(buf, size - 1); + if (std::find(expectedValue.begin(), expectedValue.end(), val) != expectedValue.end()) { return true; + } else if (timeoutNs == 0) { + return false; } struct pollfd pfd; @@ -699,12 +740,20 @@ int BrightnessController::checkSysfsStatus(const char* file, const std::string& lseek(fd.get(), 0, SEEK_SET); size = read(fd.get(), buf, sizeof(buf)); if (size > 0) { - if (std::string_view(buf, size - 1) == expectedValue) { + val = std::string(buf, size - 1); + if (std::find(expectedValue.begin(), expectedValue.end(), val) != + expectedValue.end()) { ret = 0; } else { - buf[size - 1] = 0; - ALOGE("%s read %s expected %s after notified", __func__, buf, - expectedValue.c_str()); + std::string values; + for (auto& s : expectedValue) { + values += s + std::string(" "); + } + if (values.size() > 0) { + values.resize(values.size() - 1); + } + ALOGE("%s read %s expected %s after notified", __func__, val.c_str(), + values.c_str()); ret = EINVAL; } } else { @@ -726,13 +775,20 @@ int BrightnessController::checkSysfsStatus(const char* file, const std::string& return ret == NO_ERROR; } +void BrightnessController::resetLhbmState() { + std::lock_guard<std::recursive_mutex> lock(mBrightnessMutex); + mLhbmReq.reset(false); + mLhbm.reset(false); + mLhbmBrightnessAdj = false; +} + void BrightnessController::setOutdoorVisibility(LbeState state) { std::lock_guard<std::recursive_mutex> lock(mCabcModeMutex); mOutdoorVisibility = (state != LbeState::OFF); } int BrightnessController::updateCabcMode() { - if (mCabcModeOfs.fail()) return HWC2_ERROR_UNSUPPORTED; + if (!mCabcSupport || mCabcModeOfs.fail()) return HWC2_ERROR_UNSUPPORTED; std::lock_guard<std::recursive_mutex> lock(mCabcModeMutex); bool mode = (!(isHdrLayerOn() || mOutdoorVisibility)); @@ -763,8 +819,7 @@ int BrightnessController::applyBrightnessViaSysfs(uint32_t level) { std::lock_guard<std::recursive_mutex> lock(mBrightnessMutex); mBrightnessLevel.reset(level); mPrevDisplayWhitePointNits = mDisplayWhitePointNits; - ALOGI("level=%d, DimmingOn=%d, Hbm=%d, LhbmOn=%d", level, - mDimming.get(), mGhbm.get(), mLhbm.get()); + printBrightnessStates("sysfs"); } return NO_ERROR; @@ -819,6 +874,15 @@ void BrightnessController::parseHbmModeEnums(const DrmProperty& property) { } } +/* + * WARNING: This print is parsed by Battery Historian. Consult with the Battery + * Historian team before modifying (b/239640926). + */ +void BrightnessController::printBrightnessStates(const char* path) { + ALOGI("path=%s, id=%d, level=%d, DimmingOn=%d, Hbm=%d, LhbmOn=%d", path ?: "unknown", + mPanelIndex, mBrightnessLevel.get(), mDimming.get(), mGhbm.get(), mLhbm.get()); +} + void BrightnessController::dump(String8& result) { std::lock_guard<std::recursive_mutex> lock(mBrightnessMutex); @@ -827,9 +891,9 @@ void BrightnessController::dump(String8& result) { "lhbm supported %d, ghbm supported %d\n", mBrightnessOfs.is_open(), mMaxBrightness, mBrightnessIntfSupported, mLhbmSupported, mGhbmSupported); result.appendFormat("\trequests: enhance hbm %d, lhbm %d, " - "brightness %f, instant hbm %d\n", + "brightness %f, instant hbm %d, DimBrightness %d\n", mEnhanceHbmReq.get(), mLhbmReq.get(), mBrightnessFloatReq.get(), - mInstantHbmReq.get()); + mInstantHbmReq.get(), mDimBrightnessReq.get()); result.appendFormat("\tstates: brighntess level %d, ghbm %d, dimming %d, lhbm %d", mBrightnessLevel.get(), mGhbm.get(), mDimming.get(), mLhbm.get()); result.appendFormat("\thdr layer state %d, unchecked lhbm request %d(%d), " diff --git a/libhwc2.1/libdevice/BrightnessController.h b/libhwc2.1/libdevice/BrightnessController.h index e1662d4..1a19758 100644 --- a/libhwc2.1/libdevice/BrightnessController.h +++ b/libhwc2.1/libdevice/BrightnessController.h @@ -65,6 +65,8 @@ public: int processEnhancedHbm(bool on); int processDisplayBrightness(float bl, const nsecs_t vsyncNs, bool waitPresent = false); int processLocalHbm(bool on); + int processDimBrightness(bool on); + bool isDbmSupported() { return mDbmSupported; } int applyPendingChangeViaSysfs(const nsecs_t vsyncNs); bool validateLayerBrightness(float brightness); @@ -112,8 +114,9 @@ public: std::lock_guard<std::recursive_mutex> lock(mBrightnessMutex); return mLhbm.get(); } - int checkSysfsStatus(const char *file, const std::string &expectedValue, + int checkSysfsStatus(const char *file, const std::vector<std::string>& expectedValue, const nsecs_t timeoutNs); + void resetLhbmState(); uint32_t getBrightnessLevel() { std::lock_guard<std::recursive_mutex> lock(mBrightnessMutex); @@ -159,16 +162,39 @@ public: const BrightnessTable *getBrightnessTable() { return mBrightnessTable; } + /* + * WARNING: This enum is parsed by Battery Historian. Add new values, but + * do not modify/remove existing ones. Alternatively, consult with the + * Battery Historian team (b/239640926). + */ enum class BrightnessRange : uint32_t { NORMAL = 0, - HBM, + HBM = 1, MAX, }; + /* + * WARNING: This enum is parsed by Battery Historian. Add new values, but + * do not modify/remove existing ones. Alternatively, consult with the + * Battery Historian team (b/239640926). + */ enum class HbmMode { OFF = 0, - ON_IRC_ON, - ON_IRC_OFF, + ON_IRC_ON = 1, + ON_IRC_OFF = 2, + }; + + /* + * LHBM command need take a couple of frames to become effective + * DISABLED - finish sending disabling command to panel + * ENABLED - panel finishes boosting brightness to the peak value + * ENABLING - finish sending enabling command to panel (panel begins boosting brightness) + * Note: the definition should be consistent with kernel driver + */ + enum class LhbmMode { + DISABLED = 0, + ENABLED = 1, + ENABLING = 2, }; /* @@ -176,15 +202,22 @@ public: * NORMAL- enable dimming * HBM- enable dimming only for hbm transition * NONE- disable dimming + * + * WARNING: This enum is parsed by Battery Historian. Add new values, but + * do not modify/remove existing ones. Alternatively, consult with the + * Battery Historian team (b/239640926). */ enum class BrightnessDimmingUsage { NORMAL = 0, - HBM, + HBM = 1, NONE, }; static constexpr const char *kLocalHbmModeFileNode = "/sys/class/backlight/panel%d-backlight/local_hbm_mode"; + static constexpr const char* kDimBrightnessFileNode = + "/sys/class/backlight/panel%d-backlight/dim_brightness"; + private: // sync brightness change for mixed composition when there is more than 50% luminance change. // The percentage is calculated as: @@ -216,8 +249,11 @@ private: void parseHbmModeEnums(const DrmProperty& property); + void printBrightnessStates(const char* path) REQUIRES(mBrightnessMutex); + bool mLhbmSupported = false; bool mGhbmSupported = false; + bool mDbmSupported = false; bool mBrightnessIntfSupported = false; BrightnessTable mBrightnessTable[toUnderlying(BrightnessRange::MAX)]; @@ -238,6 +274,7 @@ private: CtrlValue<bool> mLhbm GUARDED_BY(mBrightnessMutex); CtrlValue<bool> mSdrDim GUARDED_BY(mBrightnessMutex); CtrlValue<bool> mPrevSdrDim GUARDED_BY(mBrightnessMutex); + CtrlValue<bool> mDimBrightnessReq GUARDED_BY(mBrightnessMutex); // Indicating if the last LHBM on has changed the brightness level bool mLhbmBrightnessAdj = false; @@ -269,6 +306,8 @@ private: std::ofstream mBrightnessOfs; uint32_t mMaxBrightness = 0; // read from sysfs std::ofstream mCabcModeOfs; + bool mCabcSupport = false; + uint32_t mDimBrightness = 0; // Note IRC or dimming is not in consideration for now. float mDisplayWhitePointNits = 0; diff --git a/libhwc2.1/libdevice/ExynosDisplay.cpp b/libhwc2.1/libdevice/ExynosDisplay.cpp index 987ec7c..354d75c 100644 --- a/libhwc2.1/libdevice/ExynosDisplay.cpp +++ b/libhwc2.1/libdevice/ExynosDisplay.cpp @@ -3214,7 +3214,7 @@ int32_t ExynosDisplay::getDisplayRequests( for (int32_t i = mClientCompositionInfo.mFirstIndex; i < mClientCompositionInfo.mLastIndex; i++) { ExynosLayer *layer = mLayers[i]; - if (layer->mOverlayPriority >= ePriorityHigh) { + if (layer->needClearClientTarget()) { if ((outLayers != NULL) && (outLayerRequests != NULL)) { if (requestNum >= *outNumElements) return -1; @@ -4902,8 +4902,10 @@ int32_t ExynosDisplay::addClientCompositionLayer(uint32_t layerIndex) /* handle sandwiched layers */ for (uint32_t i = (uint32_t)mClientCompositionInfo.mFirstIndex + 1; i < (uint32_t)mClientCompositionInfo.mLastIndex; i++) { ExynosLayer *layer = mLayers[i]; - if (layer->mOverlayPriority >= ePriorityHigh) { - DISPLAY_LOGD(eDebugResourceManager, "\t[%d] layer has high or max priority (%d)", i, layer->mOverlayPriority); + if (layer->needClearClientTarget()) { + DISPLAY_LOGD(eDebugResourceManager, + "\t[%d] layer is opaque and has high or max priority (%d)", i, + layer->mOverlayPriority); continue; } if (layer->mValidateCompositionType != HWC2_COMPOSITION_CLIENT) @@ -6041,3 +6043,27 @@ bool ExynosDisplay::isMixedComposition() { } return false; } + +int ExynosDisplay::lookupDisplayConfigs(const int32_t &width, + const int32_t &height, + const int32_t &fps, + int32_t *outConfig) { + if (!fps) + return HWC2_ERROR_BAD_CONFIG; + + constexpr auto nsecsPerSec = std::chrono::nanoseconds(1s).count(); + constexpr auto nsecsPerMs = std::chrono::nanoseconds(1ms).count(); + + const auto vsyncPeriod = nsecsPerSec / fps; + + for (auto const& [config, mode] : mDisplayConfigs) { + long delta = abs(vsyncPeriod - mode.vsyncPeriod); + if ((width == mode.width) && (height == mode.height) && (delta < nsecsPerMs)) { + ALOGD("%s: found display config for mode: %dx%d@%d=%d", + __func__, width, height, fps, config); + *outConfig = config; + return HWC2_ERROR_NONE; + } + } + return HWC2_ERROR_BAD_CONFIG; +} diff --git a/libhwc2.1/libdevice/ExynosDisplay.h b/libhwc2.1/libdevice/ExynosDisplay.h index 0132415..ad7977b 100644 --- a/libhwc2.1/libdevice/ExynosDisplay.h +++ b/libhwc2.1/libdevice/ExynosDisplay.h @@ -1209,6 +1209,8 @@ class ExynosDisplay { virtual PanelCalibrationStatus getPanelCalibrationStatus() { return PanelCalibrationStatus::UNCALIBRATED; } + virtual bool isDbmSupported() { return false; } + virtual int32_t setDbmState(bool __unused enabled) { return NO_ERROR; } /* getDisplayPreAssignBit support mIndex up to 1. It supports only dual LCD and 2 external displays */ @@ -1260,6 +1262,10 @@ class ExynosDisplay { // check if there are any dimmed layers bool isMixedComposition(); bool isPriorFrameMixedCompostion() { return mPriorFrameMixedComposition; } + int lookupDisplayConfigs(const int32_t& width, + const int32_t& height, + const int32_t& fps, + int32_t* outConfig); private: bool skipStaticLayerChanged(ExynosCompositionInfo& compositionInfo); diff --git a/libhwc2.1/libdevice/ExynosLayer.h b/libhwc2.1/libdevice/ExynosLayer.h index ead41af..0838c0f 100644 --- a/libhwc2.1/libdevice/ExynosLayer.h +++ b/libhwc2.1/libdevice/ExynosLayer.h @@ -471,6 +471,18 @@ class ExynosLayer : public ExynosMPPSource { return ((mLayerBuffer != NULL) && isFormatYUV(VendorGraphicBufferMeta::get_internal_format(mLayerBuffer))); } + bool isLayerHasAlphaChannel() { + return ((mLayerBuffer != NULL) && + formatHasAlphaChannel( + VendorGraphicBufferMeta::get_internal_format(mLayerBuffer))); + } + bool isLayerOpaque() { + return (!isLayerHasAlphaChannel() && + std::fabs(mPlaneAlpha - 1.0f) <= std::numeric_limits<float>::epsilon()); + } + bool needClearClientTarget() { + return (mOverlayPriority >= ePriorityHigh && isLayerOpaque()); + } size_t getDisplayFrameArea() { return HEIGHT(mDisplayFrame) * WIDTH(mDisplayFrame); } void setGeometryChanged(uint64_t changedBit); void clearGeometryChanged() {mGeometryChanged = 0;}; diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp index 1984d7b..994027a 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.cpp @@ -832,23 +832,41 @@ int32_t ExynosDisplayDrmInterface::chosePreferredConfig() if (err != HWC2_ERROR_NONE || !num_configs) return err; - hwc2_config_t config; - int32_t bootConfig; - err = mExynosDisplay->getPreferredDisplayConfigInternal(&bootConfig); - if (err == HWC2_ERROR_NONE && property_get_bool("sys.boot_completed", false) == true) { - config = static_cast<hwc2_config_t>(bootConfig); + int32_t config = -1; + char modeStr[PROPERTY_VALUE_MAX] = "\0"; + int32_t width = 0, height = 0, fps = 0; + if (property_get("vendor.display.preferred_mode", modeStr, "") > 0 && + sscanf(modeStr, "%dx%d@%d", &width, &height, &fps) == 3) { + err = mExynosDisplay->lookupDisplayConfigs(width, height, fps, &config); } else { - config = mDrmConnector->get_preferred_mode_id(); + err = HWC2_ERROR_BAD_CONFIG; } - ALOGI("Preferred mode id: %d, state: %d", config, mDrmConnector->state()); - if ((err = setActiveConfig(config)) < 0) { - ALOGE("failed to set default config, err %d", err); - return err; + const int32_t drmPreferredConfig = mDrmConnector->get_preferred_mode_id(); + if (err != HWC2_ERROR_NONE) { + config = drmPreferredConfig; + } + ALOGI("Preferred mode id: %d(%s), state: %d", config, modeStr, mDrmConnector->state()); + + auto &configs = mExynosDisplay->mDisplayConfigs; + if (config != drmPreferredConfig && + (configs[config].width != configs[drmPreferredConfig].width || + configs[config].height != configs[drmPreferredConfig].height)) { + // HWC cannot send a resolution change commit here until 1st frame update because of + // some panels requirement. Therefore, it calls setActiveConfigWithConstraints() help + // set mDesiredModeState correctly, and then trigger modeset in the 1s frame update. + if ((err = setActiveConfigWithConstraints(config)) < 0) { + ALOGE("failed to setActiveConfigWithConstraints(), err %d", err); + return err; + } + } else { + if ((err = setActiveConfig(config)) < 0) { + ALOGE("failed to set default config, err %d", err); + return err; + } } - mExynosDisplay->updateInternalDisplayConfigVariables(config); - return err; + return mExynosDisplay->updateInternalDisplayConfigVariables(config); } int32_t ExynosDisplayDrmInterface::getDisplayConfigs( diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h index d795b72..c391b9f 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterface.h @@ -318,7 +318,7 @@ class ExynosDisplayDrmInterface : return NO_ERROR; } int32_t getFrameCount() { return mFrameCounter; } - virtual void registerHistogramInfo(IDLHistogram *info) { return; } + virtual void registerHistogramInfo(const std::shared_ptr<IDLHistogram> &info) { return; } virtual int32_t setHistogramControl(hidl_histogram_control_t enabled) { return NO_ERROR; } virtual int32_t setHistogramData(void *bin) { return NO_ERROR; } int32_t getActiveModeHDisplay() { return mActiveModeState.mode.h_display(); } diff --git a/libhwc2.1/libhwcService/ExynosHWCService.cpp b/libhwc2.1/libhwcService/ExynosHWCService.cpp index 5413f41..aac4916 100644 --- a/libhwc2.1/libhwcService/ExynosHWCService.cpp +++ b/libhwc2.1/libhwcService/ExynosHWCService.cpp @@ -502,4 +502,17 @@ int32_t ExynosHWCService::triggerDisplayIdleEnter(uint32_t displayIndex, return NO_ERROR; } +int32_t ExynosHWCService::setDisplayDbm(int32_t display_id, uint32_t on) { + if (on > 1) return -EINVAL; + + auto display = mHWCCtx->device->getDisplay(display_id); + + if (display == nullptr) return -EINVAL; + + ALOGD("ExynosHWCService::%s() display(%u) on=%d", __func__, display_id, on); + display->setDbmState(!!on); + mHWCCtx->device->onRefresh(); + return NO_ERROR; +} + } //namespace android diff --git a/libhwc2.1/libhwcService/ExynosHWCService.h b/libhwc2.1/libhwcService/ExynosHWCService.h index f4224fb..586e335 100644 --- a/libhwc2.1/libhwcService/ExynosHWCService.h +++ b/libhwc2.1/libhwcService/ExynosHWCService.h @@ -78,6 +78,8 @@ public: virtual int32_t setMinIdleRefreshRate(uint32_t display_id, int32_t fps); virtual int32_t setRefreshRateThrottle(uint32_t display_id, int32_t delayMs); + virtual int32_t setDisplayDbm(int32_t display_id, uint32_t on); + int32_t setDisplayRCDLayerEnabled(uint32_t displayIndex, bool enable) override; int32_t triggerDisplayIdleEnter(uint32_t displayIndex, uint32_t idleTeRefreshRate) override; diff --git a/libhwc2.1/libhwcService/IExynosHWC.cpp b/libhwc2.1/libhwcService/IExynosHWC.cpp index 181fdf2..9833e64 100644 --- a/libhwc2.1/libhwcService/IExynosHWC.cpp +++ b/libhwc2.1/libhwcService/IExynosHWC.cpp @@ -66,6 +66,7 @@ enum { SET_REFRESH_RATE_THROTTLE = 1006, SET_DISPLAY_RCDLAYER_ENABLED = 1007, TRIGGER_DISPLAY_IDLE_ENTER = 1008, + SET_DISPLAY_DBM = 1009, }; class BpExynosHWCService : public BpInterface<IExynosHWCService> { @@ -459,6 +460,16 @@ public: ALOGE_IF(result != NO_ERROR, "TRIGGER_DISPLAY_IDLE_ENTER transact error(%d)", result); return result; } + + virtual int32_t setDisplayDbm(int32_t display_id, uint32_t on) { + Parcel data, reply; + data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor()); + data.writeInt32(display_id); + data.writeInt32(on); + int result = remote()->transact(SET_DISPLAY_DBM, data, &reply); + if (result) ALOGE("SET_DISPLAY_DBM transact error(%d)", result); + return result; + } }; IMPLEMENT_META_INTERFACE(ExynosHWCService, "android.hal.ExynosHWCService"); @@ -741,6 +752,15 @@ status_t BnExynosHWCService::onTransact( return triggerDisplayIdleEnter(displayIndex, idleTeRefreshRate); } break; + case SET_DISPLAY_DBM: { + CHECK_INTERFACE(IExynosHWCService, data, reply); + int32_t display_id = data.readInt32(); + uint32_t on = data.readInt32(); + int32_t error = setDisplayDbm(display_id, on); + reply->writeInt32(error); + return NO_ERROR; + } break; + default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/libhwc2.1/libhwcService/IExynosHWC.h b/libhwc2.1/libhwcService/IExynosHWC.h index debf6fb..640ca7d 100644 --- a/libhwc2.1/libhwcService/IExynosHWC.h +++ b/libhwc2.1/libhwcService/IExynosHWC.h @@ -76,6 +76,7 @@ public: virtual int32_t setRefreshRateThrottle(uint32_t display_id, int32_t throttle) = 0; virtual int32_t setDisplayRCDLayerEnabled(uint32_t displayIndex, bool enable) = 0; virtual int32_t triggerDisplayIdleEnter(uint32_t displayIndex, uint32_t idleTeRefreshRate) = 0; + virtual int32_t setDisplayDbm(int32_t display_id, uint32_t on) = 0; }; /* Native Interface */ diff --git a/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp b/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp index d9d5b4b..1c10909 100644 --- a/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp +++ b/libhwc2.1/libhwchelper/ExynosHWCHelper.cpp @@ -1157,8 +1157,9 @@ int32_t load_png_image(const char* filepath, buffer_handle_t buffer) { return -EINVAL; } - uint32_t bufferHandleSize = gmeta.stride * gmeta.vstride * formatToBpp(gmeta.format) / 8; - if (bufferHandleSize > gmeta.size) { + size_t bufferHandleSize = gmeta.stride * gmeta.vstride * formatToBpp(gmeta.format) / 8; + size_t png_size = png_get_rowbytes(png_ptr, info_ptr) * height; + if (bufferHandleSize > gmeta.size || (bufferHandleSize < png_size)) { fclose(fp); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return -EINVAL; diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp index 6fc7ee9..594495b 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.cpp @@ -38,7 +38,6 @@ extern struct exynos_hwc_control exynosHWCControl; using namespace SOC_VERSION; constexpr auto nsecsPerSec = std::chrono::nanoseconds(1s).count(); -constexpr auto nsecsPerMs = std::chrono::nanoseconds(1ms).count(); static const std::map<const DisplayType, const std::string> panelSysfsPath = {{DisplayType::DISPLAY_PRIMARY, "/sys/devices/platform/exynos-drm/primary-panel/"}, @@ -259,25 +258,16 @@ int32_t ExynosPrimaryDisplay::getPreferredDisplayConfigInternal(int32_t *outConf return HWC2_ERROR_BAD_CONFIG; } - const auto vsyncPeriod = nsecsPerSec / fps; - - for (auto const& [config, mode] : mDisplayConfigs) { - long delta = abs(vsyncPeriod - mode.vsyncPeriod); - if ((width == mode.width) && (height == mode.height) && - (delta < nsecsPerMs)) { - ALOGD("%s: found preferred display config for mode: %s=%d", - __func__, modeStr, config); - *outConfig = config; - return HWC2_ERROR_NONE; - } - } - return HWC2_ERROR_BAD_CONFIG; + return lookupDisplayConfigs(width, height, fps, outConfig); } int32_t ExynosPrimaryDisplay::setPowerOn() { ATRACE_CALL(); updateAppliedActiveConfig(0, 0); - int ret = applyPendingConfig(); + int ret = NO_ERROR; + if (!mFirstPowerOn) { + ret = applyPendingConfig(); + } if (!mPowerModeState.has_value() || (*mPowerModeState == HWC2_POWER_MODE_OFF)) { // check the dynamic recomposition thread by following display @@ -353,6 +343,11 @@ int32_t ExynosPrimaryDisplay::setPowerDoze(hwc2_power_mode_t mode) { mPowerModeState = mode; } + // LHBM will be disabled in the kernel while entering AOD mode if it's + // already enabled. Reset the state to avoid the sync problem. + mBrightnessController->resetLhbmState(); + mLhbmOn = false; + ExynosDisplay::updateRefreshRateHint(); return HWC2_ERROR_NONE; @@ -564,13 +559,35 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) { setLHBMRefreshRateThrottle(kLhbmRefreshRateThrottleMs); } + bool wasDisabled = + mBrightnessController + ->checkSysfsStatus(BrightnessController::kLocalHbmModeFileNode, + {std::to_string(static_cast<int>( + BrightnessController::LhbmMode::DISABLED))}, + 0); + if (!enabled && wasDisabled) { + ALOGW("lhbm is at DISABLED state, skip disabling"); + return NO_ERROR; + } else if (enabled && !wasDisabled) { + requestLhbm(true); + ALOGI("lhbm is at ENABLING or ENABLED state, re-enable to reset timeout timer"); + return NO_ERROR; + } + + int64_t lhbmEnablingNanos; + std::vector<std::string> checkingValue = { + std::to_string(static_cast<int>(BrightnessController::LhbmMode::DISABLED))}; + if (enabled) { + checkingValue = {std::to_string(static_cast<int>(BrightnessController::LhbmMode::ENABLING)), + std::to_string(static_cast<int>(BrightnessController::LhbmMode::ENABLED))}; + lhbmEnablingNanos = systemTime(SYSTEM_TIME_MONOTONIC); + } requestLhbm(enabled); constexpr uint32_t kSysfsCheckTimeoutMs = 500; ALOGI("setLhbmState =%d", enabled); - bool succeed = mBrightnessController->checkSysfsStatus( - BrightnessController::kLocalHbmModeFileNode, - std::to_string(enabled ? 1 : 0), - ms2ns(kSysfsCheckTimeoutMs)); + bool succeed = + mBrightnessController->checkSysfsStatus(BrightnessController::kLocalHbmModeFileNode, + checkingValue, ms2ns(kSysfsCheckTimeoutMs)); if (!succeed) { ALOGE("failed to update lhbm mode"); if (enabled) { @@ -579,11 +596,40 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) { return -ENODEV; } - if (!enabled) { + if (enabled) { + int64_t lhbmEnablingDoneNanos = systemTime(SYSTEM_TIME_MONOTONIC); + bool enablingStateSupported = !mFramesToReachLhbmPeakBrightness; + if (enablingStateSupported) { + ATRACE_NAME("lhbm_wait_peak_brightness"); + if (!mBrightnessController + ->checkSysfsStatus(BrightnessController::kLocalHbmModeFileNode, + {std::to_string(static_cast<int>( + BrightnessController::LhbmMode::ENABLED))}, + ms2ns(kSysfsCheckTimeoutMs))) { + ALOGE("failed to wait for lhbm becoming effective"); + return -EIO; + } + } else { + // lhbm takes effect at next vblank + ATRACE_NAME("lhbm_wait_apply"); + if (mDisplayInterface->waitVBlank()) { + ALOGE("%s failed to wait vblank for taking effect", __func__); + return -ENODEV; + } + ATRACE_NAME("lhbm_wait_peak_brightness"); + for (int32_t i = mFramesToReachLhbmPeakBrightness; i > 0; i--) { + if (mDisplayInterface->waitVBlank()) { + ALOGE("%s failed to wait vblank for peak brightness, %d", __func__, i); + return -ENODEV; + } + } + } + ALOGI("lhbm delay mode: %s, latency(ms): total: %d cmd: %d\n", + enablingStateSupported ? "poll" : "fixed", + static_cast<int>((systemTime(SYSTEM_TIME_MONOTONIC) - lhbmEnablingNanos) / 1000000), + static_cast<int>((lhbmEnablingDoneNanos - lhbmEnablingNanos) / 1000000)); + } else { setLHBMRefreshRateThrottle(0); - } - - { // lhbm takes effect at next vblank ATRACE_NAME("lhbm_wait_apply"); if (mDisplayInterface->waitVBlank()) { @@ -592,16 +638,6 @@ int32_t ExynosPrimaryDisplay::setLhbmState(bool enabled) { } } - if (enabled) { - for (int32_t i = mFramesToReachLhbmPeakBrightness; i > 0; i--) { - ATRACE_NAME("lhbm_wait_peak_brightness"); - if (mDisplayInterface->waitVBlank()) { - ALOGE("%s failed to wait vblank for peak brightness, %d", __func__, i); - return -ENODEV; - } - } - } - mLhbmOn = enabled; if (!mPowerModeState.has_value() || (*mPowerModeState == HWC2_POWER_MODE_OFF && mLhbmOn)) { mLhbmOn = false; @@ -968,3 +1004,12 @@ void ExynosPrimaryDisplay::checkBtsReassignResource(const uint32_t vsyncPeriod, } } } + +bool ExynosPrimaryDisplay::isDbmSupported() { + return mBrightnessController->isDbmSupported(); +} + +int32_t ExynosPrimaryDisplay::setDbmState(bool enabled) { + mBrightnessController->processDimBrightness(enabled); + return NO_ERROR; +} diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h index bd9cda7..d9ec1ca 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplay.h @@ -52,6 +52,9 @@ class ExynosPrimaryDisplay : public ExynosDisplay { virtual int setMinIdleRefreshRate(const int fps) override; virtual int setRefreshRateThrottleNanos(const int64_t delayNs, const VrrThrottleRequester requester) override; + virtual bool isDbmSupported() override; + virtual int32_t setDbmState(bool enabled) override; + virtual void dump(String8& result) override; virtual void updateAppliedActiveConfig(const hwc2_config_t newConfig, const int64_t ts) override; diff --git a/libhwc2.1/libresource/ExynosResourceManager.cpp b/libhwc2.1/libresource/ExynosResourceManager.cpp index 85bcaa4..3c94c2f 100644 --- a/libhwc2.1/libresource/ExynosResourceManager.cpp +++ b/libhwc2.1/libresource/ExynosResourceManager.cpp @@ -2314,7 +2314,7 @@ void ExynosResourceManager::setScaleDownRatio(uint32_t physicalType, } } -int32_t ExynosResourceManager::prepareResources() +int32_t ExynosResourceManager::prepareResources() { int ret = NO_ERROR; HDEBUGLOGD(eDebugResourceManager, "This is first validate"); diff --git a/libhwc2.1/pixel-display-default.xml b/libhwc2.1/pixel-display-default.xml index fc10d6a..86c1b03 100644 --- a/libhwc2.1/pixel-display-default.xml +++ b/libhwc2.1/pixel-display-default.xml @@ -1,7 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>com.google.hardware.pixel.display</name> - <version>6</version> + <version>7</version> <fqname>IDisplay/default</fqname> </hal> </manifest> diff --git a/libhwc2.1/pixel-display-secondary.xml b/libhwc2.1/pixel-display-secondary.xml index f8bd77b..515bc21 100644 --- a/libhwc2.1/pixel-display-secondary.xml +++ b/libhwc2.1/pixel-display-secondary.xml @@ -1,7 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>com.google.hardware.pixel.display</name> - <version>6</version> + <version>7</version> <fqname>IDisplay/secondary</fqname> </hal> </manifest> diff --git a/libhwc2.1/pixel-display.cpp b/libhwc2.1/pixel-display.cpp index d12e328..c95c239 100644 --- a/libhwc2.1/pixel-display.cpp +++ b/libhwc2.1/pixel-display.cpp @@ -260,6 +260,23 @@ ndk::ScopedAStatus Display::getPanelCalibrationStatus(PanelCalibrationStatus *_a } return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } + +ndk::ScopedAStatus Display::isDbmSupported(bool *_aidl_return) { + if (!mDisplay) { + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } + *_aidl_return = mDisplay->isDbmSupported(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Display::setDbmState(bool enabled) { + if (!mDisplay) { + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } + mDisplay->setDbmState(enabled); + return ndk::ScopedAStatus::ok(); +} + } // namespace display } // namespace pixel } // namespace hardware diff --git a/libhwc2.1/pixel-display.h b/libhwc2.1/pixel-display.h index 0fd0a5b..b1696d5 100644 --- a/libhwc2.1/pixel-display.h +++ b/libhwc2.1/pixel-display.h @@ -59,6 +59,8 @@ public: Priority pri, std::vector<char16_t> *histogrambuffer, HistogramErrorCode *_aidl_return) override; ndk::ScopedAStatus getPanelCalibrationStatus(PanelCalibrationStatus *_aidl_return) override; + ndk::ScopedAStatus isDbmSupported(bool *_aidl_return) override; + ndk::ScopedAStatus setDbmState(bool enabled) override; private: bool runMediator(const RoiRect roi, const Weight weight, const HistogramPos pos, |