diff options
-rw-r--r-- | include/gs101/histogram/histogram.h | 91 | ||||
-rw-r--r-- | libhwc2.1/ExynosHWCModule.h | 9 | ||||
-rw-r--r-- | libhwc2.1/libdevice/ExynosDeviceModule.cpp | 4 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp | 186 | ||||
-rw-r--r-- | libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h | 46 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp | 155 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h | 66 |
7 files changed, 466 insertions, 91 deletions
diff --git a/include/gs101/histogram/histogram.h b/include/gs101/histogram/histogram.h new file mode 100644 index 0000000..07a1de1 --- /dev/null +++ b/include/gs101/histogram/histogram.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2022 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. + */ + +#ifndef HISTOGRAM_H_ +#define HISTOGRAM_H_ + +typedef enum { + HISTOGRAM_CONTROL_INVALID = 0, + HISTOGRAM_CONTROL_REQUEST = 1, + HISTOGRAM_CONTROL_CANCEL = 2, +} hidl_histogram_control_t; + +namespace gs101 { + +class HistogramInfo { +public: + enum Histogram_Type { HISTOGRAM_SAMPLING, HISTOGRAM_HIDL, HISTOGRAM_TYPE_NUM }; + /// Histogram ROI information, same definition as in uapi + struct HistogramROI { + uint16_t start_x; + uint16_t start_y; + uint16_t hsize; + uint16_t vsize; + }; + /// Histogram Weights information, same definition as in uapi + struct HistogramWeights { + uint16_t weight_r; + uint16_t weight_g; + uint16_t weight_b; + }; + + void setHistogramROI(uint16_t x, uint16_t y, uint16_t h, uint16_t v) { + mHistogramROI.start_x = x; + mHistogramROI.start_y = y; + mHistogramROI.hsize = h; + mHistogramROI.vsize = v; + }; + const struct HistogramROI& getHistogramROI() { return mHistogramROI; } + + void setHistogramWeights(uint16_t r, uint16_t g, uint16_t b) { + mHistogramWeights.weight_r = r; + mHistogramWeights.weight_g = g; + mHistogramWeights.weight_b = b; + }; + const struct HistogramWeights& getHistogramWeights() { return mHistogramWeights; } + + void setHistogramThreshold(uint32_t t) { mHistogramThreshold = t; } + uint32_t getHistogramThreshold() { return mHistogramThreshold; } + + Histogram_Type getHistogramType() { return mHistogramType; } + + HistogramInfo(Histogram_Type type) { mHistogramType = type; } + virtual ~HistogramInfo() {} + +private: + Histogram_Type mHistogramType = HISTOGRAM_TYPE_NUM; + struct HistogramROI mHistogramROI; + struct HistogramWeights mHistogramWeights; + uint32_t mHistogramThreshold = 0; +}; + +class SamplingHistogram : public HistogramInfo { +public: + SamplingHistogram() : HistogramInfo(HISTOGRAM_SAMPLING) {} + virtual ~SamplingHistogram() {} +}; + +class HIDLHistogram : public HistogramInfo { +public: + HIDLHistogram() : HistogramInfo(HISTOGRAM_HIDL) {} + virtual ~HIDLHistogram() {} + + virtual void CallbackHistogram(void* bin) = 0; +}; + +} // namespace gs101 + +#endif // HISTOGRAM_H_ diff --git a/libhwc2.1/ExynosHWCModule.h b/libhwc2.1/ExynosHWCModule.h index 0b71845..d879edb 100644 --- a/libhwc2.1/ExynosHWCModule.h +++ b/libhwc2.1/ExynosHWCModule.h @@ -30,11 +30,10 @@ #define DP_LINK_NAME "130b0000.displayport" #define DP_UEVENT_NAME "change@/devices/platform/%s/extcon/extcon0" #define DP_CABLE_STATE_NAME "/sys/devices/platform/%s/extcon/extcon0/cable.0/state" -#define BRIGHTNESS_NODE_0_BASE "/sys/class/backlight/panel0-backlight/brightness" -#define MAX_BRIGHTNESS_NODE_0_BASE "/sys/class/backlight/panel0-backlight/max_brightness" -#define BRIGHTNESS_NODE_1_BASE "/sys/class/backlight/panel1-backlight/brightness" -#define MAX_BRIGHTNESS_NODE_1_BASE "/sys/class/backlight/panel1-backlight/max_brightness" -#define EARLY_WAKUP_NODE_BASE "/sys/devices/platform/1c300000.drmdecon/early_wakeup" +#define BRIGHTNESS_SYSFS_NODE "/sys/class/backlight/panel%d-backlight/brightness" +#define MAX_BRIGHTNESS_SYSFS_NODE "/sys/class/backlight/panel%d-backlight/max_brightness" + +#define EARLY_WAKUP_NODE_0_BASE "/sys/devices/platform/1c300000.drmdecon/early_wakeup" #define IDMA(x) static_cast<decon_idma_type>(x) diff --git a/libhwc2.1/libdevice/ExynosDeviceModule.cpp b/libhwc2.1/libdevice/ExynosDeviceModule.cpp index b8d31da..678c474 100644 --- a/libhwc2.1/libdevice/ExynosDeviceModule.cpp +++ b/libhwc2.1/libdevice/ExynosDeviceModule.cpp @@ -31,7 +31,9 @@ ExynosDeviceModule::ExynosDeviceModule() : ExynosDevice(), mDisplayColorLoader(D ExynosDisplayDrmInterfaceModule* moduleDisplayInterface = (ExynosDisplayDrmInterfaceModule*)(display->mDisplayInterface.get()); - moduleDisplayInterface->getDisplayInfo(display_info); + if (display->mType == HWC_DISPLAY_PRIMARY) { + moduleDisplayInterface->getDisplayInfo(display_info); + } } initDisplayColor(display_info); } diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp index dcf7cc3..bfe8eaa 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.cpp @@ -14,10 +14,13 @@ * limitations under the License. */ +#include "BrightnessController.h" #include "ExynosDisplayDrmInterfaceModule.h" #include "ExynosPrimaryDisplayModule.h" #include <drm/samsung_drm.h> +using BrightnessRange = BrightnessController::BrightnessRange; + template <typename T, typename M> int32_t convertDqeMatrixDataToMatrix(T &colorMatrix, M &mat, uint32_t dimension) { @@ -62,7 +65,7 @@ void ExynosDisplayDrmInterfaceModule::parseBpcEnums(const DrmProperty& property) }; ALOGD("Init bpc enums"); - parseEnums(property, bpcEnums, mBpcEnums); + DrmEnumParser::parseEnums(property, bpcEnums, mBpcEnums); for (auto &e : mBpcEnums) { ALOGD("bpc [bpc: %d, drm: %" PRId64 "]", e.first, e.second); } @@ -82,6 +85,9 @@ int32_t ExynosDisplayDrmInterfaceModule::initDrmDevice(DrmDevice *drmDevice) initOldDppBlobs(drmDevice); if (mDrmCrtc->force_bpc_property().id()) parseBpcEnums(mDrmCrtc->force_bpc_property()); + + mOldHistoBlobs.init(drmDevice); + return ret; } @@ -535,8 +541,7 @@ int32_t ExynosDisplayDrmInterfaceModule::setDisplayColorSetting( if (dqe.DqeControl().config->force_10bpc) bpc = static_cast<uint32_t>(BPC_10); } - uint64_t bpcEnum = 0; - std::tie(bpcEnum, ret) = halToDrmEnum(bpc, mBpcEnums); + auto [bpcEnum, ret] = DrmEnumParser::halToDrmEnum(bpc, mBpcEnums); if (ret < 0) { HWC_LOGE(mExynosDisplay, "Fail to convert bpc(%d)", bpc); } else { @@ -747,20 +752,179 @@ void ExynosDisplayDrmInterfaceModule::getDisplayInfo( std::vector<displaycolor::DisplayInfo> &display_info) { displaycolor::DisplayInfo primary_display; auto &tb = primary_display.brightness_table; + auto *brightnessTable = mExynosDisplay->mBrightnessController->getBrightnessTable(); - tb.nbm_nits_min = mBrightnessTable[BrightnessRange::NORMAL].mNitsStart; - tb.nbm_nits_max = mBrightnessTable[BrightnessRange::NORMAL].mNitsEnd; - tb.nbm_dbv_min = mBrightnessTable[BrightnessRange::NORMAL].mBklStart; - tb.nbm_dbv_max = mBrightnessTable[BrightnessRange::NORMAL].mBklEnd; + tb.nbm_nits_min = brightnessTable[toUnderlying(BrightnessRange::NORMAL)].mNitsStart; + tb.nbm_nits_max = brightnessTable[toUnderlying(BrightnessRange::NORMAL)].mNitsEnd; + tb.nbm_dbv_min = brightnessTable[toUnderlying(BrightnessRange::NORMAL)].mBklStart; + tb.nbm_dbv_max = brightnessTable[toUnderlying(BrightnessRange::NORMAL)].mBklEnd; - tb.hbm_nits_min = mBrightnessTable[BrightnessRange::HBM].mNitsStart; - tb.hbm_nits_max = mBrightnessTable[BrightnessRange::HBM].mNitsEnd; - tb.hbm_dbv_min = mBrightnessTable[BrightnessRange::HBM].mBklStart; - tb.hbm_dbv_max = mBrightnessTable[BrightnessRange::HBM].mBklEnd; + tb.hbm_nits_min = brightnessTable[toUnderlying(BrightnessRange::HBM)].mNitsStart; + tb.hbm_nits_max = brightnessTable[toUnderlying(BrightnessRange::HBM)].mNitsEnd; + tb.hbm_dbv_min = brightnessTable[toUnderlying(BrightnessRange::HBM)].mBklStart; + tb.hbm_dbv_max = brightnessTable[toUnderlying(BrightnessRange::HBM)].mBklEnd; + + primary_display.panel_name = GetPanelName(); + primary_display.panel_serial = GetPanelSerial(); display_info.push_back(primary_display); } +const std::string ExynosDisplayDrmInterfaceModule::GetPanelInfo(const std::string &sysfs_rel, + char delim) { + ExynosPrimaryDisplayModule* display = (ExynosPrimaryDisplayModule*)mExynosDisplay; + const DisplayType type = display->getBuiltInDisplayType(); + const std::string &sysfs = display->getPanelSysfsPath(type); + + if (sysfs.empty()) { + return ""; + } + + std::string info; + if (readLineFromFile(sysfs + "/" + sysfs_rel, info, delim) != OK) { + ALOGE("failed reading %s/%s", sysfs.c_str(), sysfs_rel.c_str()); + return ""; + } + + return info; +} + +/* For Histogram */ +int32_t ExynosDisplayDrmInterfaceModule::createHistoRoiBlob(uint32_t &blobId) { + struct histogram_roi histo_roi; + + histo_roi.start_x = mHistogramInfo->getHistogramROI().start_x; + histo_roi.start_y = mHistogramInfo->getHistogramROI().start_y; + histo_roi.hsize = mHistogramInfo->getHistogramROI().hsize; + histo_roi.vsize = mHistogramInfo->getHistogramROI().vsize; + + int ret = mDrmDevice->CreatePropertyBlob(&histo_roi, sizeof(histo_roi), &blobId); + if (ret) { + HWC_LOGE(mExynosDisplay, "Failed to create histogram roi blob %d", ret); + return ret; + } + + return NO_ERROR; +} + +int32_t ExynosDisplayDrmInterfaceModule::createHistoWeightsBlob(uint32_t &blobId) { + struct histogram_weights histo_weights; + + histo_weights.weight_r = mHistogramInfo->getHistogramWeights().weight_r; + histo_weights.weight_g = mHistogramInfo->getHistogramWeights().weight_g; + histo_weights.weight_b = mHistogramInfo->getHistogramWeights().weight_b; + + int ret = mDrmDevice->CreatePropertyBlob(&histo_weights, sizeof(histo_weights), &blobId); + if (ret) { + HWC_LOGE(mExynosDisplay, "Failed to create histogram weights blob %d", ret); + return ret; + } + + return NO_ERROR; +} + +int32_t ExynosDisplayDrmInterfaceModule::setDisplayHistoBlob( + const DrmProperty &prop, const uint32_t type, + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) { + if (!prop.id()) return NO_ERROR; + + int32_t ret = NO_ERROR; + uint32_t blobId = 0; + + switch (type) { + case HistoBlobs::ROI: + ret = createHistoRoiBlob(blobId); + break; + case HistoBlobs::WEIGHTS: + ret = createHistoWeightsBlob(blobId); + break; + default: + ret = -EINVAL; + } + if (ret != NO_ERROR) { + HWC_LOGE(mExynosDisplay, "%s: Failed to create blob", __func__); + return ret; + } + + /* Skip setting when previous and current setting is same with 0 */ + if ((blobId == 0) && (mOldHistoBlobs.getBlob(type) == 0)) return ret; + + if ((ret = drmReq.atomicAddProperty(mDrmCrtc->id(), prop, blobId)) < 0) { + HWC_LOGE(mExynosDisplay, "%s: Failed to add property", __func__); + return ret; + } + mOldHistoBlobs.addBlob(type, blobId); + + return ret; +} + +int32_t ExynosDisplayDrmInterfaceModule::setDisplayHistogramSetting( + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq) { + if ((mHistogramInfoRegistered == false) || (isPrimary() == false)) return NO_ERROR; + + int ret = NO_ERROR; + + if ((ret = setDisplayHistoBlob(mDrmCrtc->histogram_roi_property(), + static_cast<uint32_t>(HistoBlobs::ROI), drmReq) != NO_ERROR)) { + HWC_LOGE(mExynosDisplay, "%s: Failed to set Histo_ROI blob", __func__); + return ret; + } + if ((ret = setDisplayHistoBlob(mDrmCrtc->histogram_weights_property(), + static_cast<uint32_t>(HistoBlobs::WEIGHTS), + drmReq) != NO_ERROR)) { + HWC_LOGE(mExynosDisplay, "%s: Failed to set Histo_Weights blob", __func__); + return ret; + } + + const DrmProperty &prop_histo_threshold = mDrmCrtc->histogram_threshold_property(); + if (prop_histo_threshold.id()) { + if ((ret = drmReq.atomicAddProperty(mDrmCrtc->id(), prop_histo_threshold, + (uint64_t)(mHistogramInfo->getHistogramThreshold()), + true)) < 0) { + HWC_LOGE(mExynosDisplay, "%s: Failed to set histogram thereshold property", __func__); + return ret; + } + } + + return NO_ERROR; +} + +int32_t ExynosDisplayDrmInterfaceModule::setHistogramControl(int32_t control) { + if ((mHistogramInfoRegistered == false) || (isPrimary() == false)) return NO_ERROR; + + int ret = NO_ERROR; + uint32_t crtc_id = mDrmCrtc->id(); + + if (control == HISTOGRAM_CONTROL_REQUEST) { + ret = mDrmDevice->CallVendorIoctl(DRM_IOCTL_EXYNOS_HISTOGRAM_REQUEST, (void *)&crtc_id); + ALOGD("Histogram Requested"); + } else if (control == HISTOGRAM_CONTROL_CANCEL) { + ret = mDrmDevice->CallVendorIoctl(DRM_IOCTL_EXYNOS_HISTOGRAM_CANCEL, (void *)&crtc_id); + ALOGD("Histogram Canceled"); + } + + return ret; +} + +int32_t ExynosDisplayDrmInterfaceModule::setHistogramData(void *bin) { + if (!bin) return -EINVAL; + + /* + * There are two handling methods. + * For ContentSampling in HWC_2.3 API, histogram bin needs to be accumulated. + * For Histogram HIDL, histogram bin need to be sent to HIDL block. + */ + if (mHistogramInfo->getHistogramType() == HistogramInfo::Histogram_Type::HISTOGRAM_HIDL) { + static_cast<HIDLHistogram *>(mHistogramInfo.get())->CallbackHistogram(bin); + } else { + /* + * ContentSampling in HWC2.3 API is not supported + */ + } + + return NO_ERROR; +} + //////////////////////////////////////////////////// ExynosPrimaryDisplayDrmInterfaceModule ////////////////////////////////////////////////////////////////// ExynosPrimaryDisplayDrmInterfaceModule::ExynosPrimaryDisplayDrmInterfaceModule(ExynosDisplay *exynosDisplay) : ExynosDisplayDrmInterfaceModule(exynosDisplay) diff --git a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h index 0ba995a..b72f2a7 100644 --- a/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h +++ b/libhwc2.1/libdisplayinterface/ExynosDisplayDrmInterfaceModule.h @@ -18,6 +18,7 @@ #define EXYNOS_DISPLAY_DRM_INTERFACE_MODULE_H #include <gs101/displaycolor/displaycolor_gs101.h> +#include <gs101/histogram/histogram.h> #include "ExynosDisplayDrmInterface.h" @@ -69,6 +70,27 @@ class ExynosDisplayDrmInterfaceModule : public ExynosDisplayDrmInterface { void getDisplayInfo(std::vector<displaycolor::DisplayInfo> &display_info); + /* For Histogram */ + int32_t createHistoRoiBlob(uint32_t &blobId); + int32_t createHistoWeightsBlob(uint32_t &blobId); + + virtual int32_t setDisplayHistogramSetting( + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq); + + void registerHistogramInfo(HistogramInfo *info) { + if (info) + mHistogramInfo.reset(info); + else + mHistogramInfo.reset(); + + if (mHistogramInfo.get()) + mHistogramInfoRegistered = true; + else + mHistogramInfoRegistered = false; + } + int32_t setHistogramControl(int32_t enabled); + virtual int32_t setHistogramData(void *bin); + protected: class SaveBlob { public: @@ -145,7 +167,29 @@ class ExynosDisplayDrmInterfaceModule : public ExynosDisplayDrmInterface { BPC_8, BPC_10, }; - DrmPropertyMap mBpcEnums; + DrmEnumParser::MapHal2DrmEnum mBpcEnums; + + /* For Histogram */ + class HistoBlobs : public SaveBlob { + public: + enum Histo_Blob_Type { + ROI, + WEIGHTS, + HISTO_BLOB_NUM // number of Histogram blobs + }; + void init(DrmDevice *drmDevice) { SaveBlob::init(drmDevice, HISTO_BLOB_NUM); } + }; + int32_t setDisplayHistoBlob(const DrmProperty &prop, const uint32_t type, + ExynosDisplayDrmInterface::DrmModeAtomicReq &drmReq); + HistoBlobs mOldHistoBlobs; + + std::shared_ptr<HistogramInfo> mHistogramInfo; + bool mHistogramInfoRegistered = false; + + private: + const std::string GetPanelInfo(const std::string &sysfs_rel, char delim); + const std::string GetPanelSerial() { return GetPanelInfo("serial_number", '\n'); } + const std::string GetPanelName() { return GetPanelInfo("panel_name", '\n'); } }; class ExynosPrimaryDisplayDrmInterfaceModule : public ExynosDisplayDrmInterfaceModule { diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp index 117dd25..a6ec3c1 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp @@ -22,6 +22,7 @@ #include <cmath> +#include "BrightnessController.h" #include "ExynosDisplayDrmInterfaceModule.h" #include "ExynosHWCDebug.h" @@ -213,7 +214,6 @@ int32_t ExynosPrimaryDisplayModule::getRenderIntents(int32_t mode, int32_t ExynosPrimaryDisplayModule::setColorModeWithRenderIntent(int32_t mode, int32_t intent) { - ALOGD("%s: mode(%d), intent(%d)", __func__, mode, intent); IDisplayColorGS101* displayColorInterface = getDisplayColorInterface(); const DisplayType display = getDisplayTypeFromIndex(mIndex); const ColorModesMap colorModeMap = displayColorInterface == nullptr @@ -241,8 +241,10 @@ int32_t ExynosPrimaryDisplayModule::setColorModeWithRenderIntent(int32_t mode, mDisplaySceneInfo.setColorMode(colorMode); mDisplaySceneInfo.setRenderIntent(renderIntent); - if (mColorMode != mode) + if (mColorMode != mode) { + ALOGD("%s: mode(%d), intent(%d)", __func__, mode, intent); setGeometryChanged(GEOMETRY_DISPLAY_COLOR_MODE_CHANGED); + } mColorMode = (android_color_mode_t)mode; return HWC2_ERROR_NONE; @@ -265,11 +267,42 @@ int32_t ExynosPrimaryDisplayModule::setColorTransform( } +int32_t ExynosPrimaryDisplayModule::getClientTargetProperty( + hwc_client_target_property_t* outClientTargetProperty, + HwcDimmingStage *outDimmingStage) { + IDisplayColorGS101* displayColorInterface = getDisplayColorInterface(); + if (displayColorInterface == nullptr) { + ALOGI("%s dc interface not created", __func__); + return ExynosDisplay::getClientTargetProperty(outClientTargetProperty); + } + + const DisplayType display = getDisplayTypeFromIndex(mIndex); + hwc::PixelFormat pixelFormat; + hwc::Dataspace dataspace; + bool dimming_linear; + if (!displayColorInterface->GetBlendingProperty(display, pixelFormat, dataspace, + dimming_linear)) { + outClientTargetProperty->pixelFormat = toUnderlying(pixelFormat); + outClientTargetProperty->dataspace = toUnderlying(dataspace); + if (outDimmingStage != nullptr) + *outDimmingStage = dimming_linear + ? HwcDimmingStage::DIMMING_LINEAR + : HwcDimmingStage::DIMMING_OETF; + + return HWC2_ERROR_NONE; + } + + ALOGW("%s failed to get property of blending stage", __func__); + return ExynosDisplay::getClientTargetProperty(outClientTargetProperty); +} + int32_t ExynosPrimaryDisplayModule::setLayersColorData() { int32_t ret = 0; uint32_t layerNum = 0; + // TODO: b/212616164 remove dimSdrRatio + float dimSdrRatio = mBrightnessController->getSdrDimRatioForInstantHbm(); for (uint32_t i = 0; i < mLayers.size(); i++) { ExynosLayer* layer = mLayers[i]; @@ -288,9 +321,9 @@ int32_t ExynosPrimaryDisplayModule::setLayersColorData() return ret; } + if ((ret = mDisplaySceneInfo.setLayerColorData(layerColorData, layer, - getBrightnessState().dim_sdr_ratio)) - != NO_ERROR) { + dimSdrRatio)) != NO_ERROR) { DISPLAY_LOGE("%s: layer[%d] setLayerColorData fail, layerNum(%d)", __func__, i, layerNum); return ret; @@ -311,8 +344,7 @@ int32_t ExynosPrimaryDisplayModule::setLayersColorData() } if ((ret = mDisplaySceneInfo.setClientCompositionColorData( - mClientCompositionInfo, layerColorData, - getBrightnessState().dim_sdr_ratio)) != NO_ERROR) { + mClientCompositionInfo, layerColorData, dimSdrRatio)) != NO_ERROR) { DISPLAY_LOGE("%s: setClientCompositionColorData fail", __func__); return ret; } @@ -540,6 +572,7 @@ int32_t ExynosPrimaryDisplayModule::DisplaySceneInfo::setClientCompositionColorD const ExynosCompositionInfo &clientCompositionInfo, LayerColorData& layerData, float dimSdrRatio) { + layerData.dim_ratio = 1.0f; setLayerDataspace(layerData, static_cast<hwc::Dataspace>(clientCompositionInfo.mDataSpace)); disableLayerHdrStaticMetadata(layerData); @@ -553,6 +586,14 @@ int32_t ExynosPrimaryDisplayModule::DisplaySceneInfo::setClientCompositionColorD 0.0, 0.0, 0.0, 1.0 }; setLayerColorTransform(layerData, scaleMatrix); + } else { + static std::array<float, TRANSFORM_MAT_SIZE> defaultMatrix { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + setLayerColorTransform(layerData, defaultMatrix); } return NO_ERROR; @@ -561,13 +602,10 @@ int32_t ExynosPrimaryDisplayModule::DisplaySceneInfo::setClientCompositionColorD int32_t ExynosPrimaryDisplayModule::DisplaySceneInfo::setLayerColorData( LayerColorData& layerData, ExynosLayer* layer, float dimSdrRatio) { + layerData.dim_ratio = layer->mPreprocessedInfo.sdrDimRatio; setLayerDataspace(layerData, static_cast<hwc::Dataspace>(layer->mDataSpace)); - if (layer->mIsHdrLayer) { - if (layer->getMetaParcel() == nullptr) { - HDEBUGLOGE("%s:: meta data parcel is null", __func__); - return -EINVAL; - } + if (layer->mIsHdrLayer && layer->getMetaParcel() != nullptr) { if (layer->getMetaParcel()->eType & VIDEO_INFO_TYPE_HDR_STATIC) setLayerHdrStaticMetadata(layerData, layer->getMetaParcel()->sHdrStaticInfo); else @@ -647,16 +685,14 @@ int32_t ExynosPrimaryDisplayModule::updateColorConversionInfo() if ((ret = setLayersColorData()) != NO_ERROR) return ret; - ExynosDisplayDrmInterfaceModule *moduleDisplayInterface = - (ExynosDisplayDrmInterfaceModule*)(mDisplayInterface.get()); - mDisplaySceneInfo.displayScene.bm = moduleDisplayInterface->isHbmOn() + mDisplaySceneInfo.displayScene.bm = mBrightnessController->isGhbmOn() ? displaycolor::BrightnessMode::BM_HBM : displaycolor::BrightnessMode::BM_NOMINAL; - mDisplaySceneInfo.displayScene.force_hdr = getBrightnessState().dim_sdr_ratio != 1.0; - mDisplaySceneInfo.displayScene.lhbm_on = getBrightnessState().local_hbm; - mDisplaySceneInfo.displayScene.hdr_full_screen = getBrightnessState().hdr_full_screen; - mDisplaySceneInfo.displayScene.dbv = moduleDisplayInterface->getDbv(); + mDisplaySceneInfo.displayScene.force_hdr = mBrightnessController->isDimSdr(); + mDisplaySceneInfo.displayScene.lhbm_on = mBrightnessController->isLhbmOn(); + mDisplaySceneInfo.displayScene.hdr_layer_state = mBrightnessController->getHdrLayerState(); + mDisplaySceneInfo.displayScene.dbv = mBrightnessController->getBrightnessLevel(); if (hwcCheckDebugMessages(eDebugColorManagement)) mDisplaySceneInfo.printDisplayScene(); @@ -685,6 +721,8 @@ int32_t ExynosPrimaryDisplayModule::updatePresentColorConversionInfo() mDisplaySceneInfo.displayScene.refresh_rate = refresh_rate; } + mDisplaySceneInfo.displayScene.lhbm_on = mBrightnessController->isLhbmOn(); + mDisplaySceneInfo.displayScene.dbv = mBrightnessController->getBrightnessLevel(); const DisplayType display = getDisplayTypeFromIndex(mIndex); if ((ret = displayColorInterface->UpdatePresent(display, mDisplaySceneInfo.displayScene)) != 0) { @@ -861,10 +899,17 @@ void ExynosPrimaryDisplayModule::initLbe() { } mAtcInit = true; - mAtcAmbientLight.set_dirty(); - mAtcStrength.set_dirty(); - for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) - mAtcSubSetting[it->first.c_str()].set_dirty(); + mAtcAmbientLight.node = String8::format(ATC_AMBIENT_LIGHT_FILE_NAME, mIndex); + mAtcAmbientLight.value.set_dirty(); + mAtcStrength.node = String8::format(ATC_ST_FILE_NAME, mIndex); + mAtcStrength.value.set_dirty(); + mAtcEnable.node = String8::format(ATC_ENABLE_FILE_NAME, mIndex); + mAtcEnable.value.set_dirty(); + + for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) { + mAtcSubSetting[it->first.c_str()].node = String8::format(it->second.c_str(), mIndex); + mAtcSubSetting[it->first.c_str()].value.set_dirty(); + } } uint32_t ExynosPrimaryDisplayModule::getAtcLuxMapIndex(std::vector<atc_lux_map> map, uint32_t lux) { @@ -880,20 +925,20 @@ uint32_t ExynosPrimaryDisplayModule::getAtcLuxMapIndex(std::vector<atc_lux_map> } int32_t ExynosPrimaryDisplayModule::setAtcStrength(uint32_t strength) { - mAtcStrength.store(strength); - if (mAtcStrength.is_dirty()) { - if (writeIntToFile(ATC_ST_FILE_NAME, mAtcStrength.get()) != NO_ERROR) return -EPERM; - mAtcStrength.clear_dirty(); + mAtcStrength.value.store(strength); + if (mAtcStrength.value.is_dirty()) { + if (writeIntToFile(mAtcStrength.node, mAtcStrength.value.get()) != NO_ERROR) return -EPERM; + mAtcStrength.value.clear_dirty(); } return NO_ERROR; } int32_t ExynosPrimaryDisplayModule::setAtcAmbientLight(uint32_t ambient_light) { - mAtcAmbientLight.store(ambient_light); - if (mAtcAmbientLight.is_dirty()) { - if (writeIntToFile(ATC_AMBIENT_LIGHT_FILE_NAME, mAtcAmbientLight.get()) != NO_ERROR) + mAtcAmbientLight.value.store(ambient_light); + if (mAtcAmbientLight.value.is_dirty()) { + if (writeIntToFile(mAtcAmbientLight.node, mAtcAmbientLight.value.get()) != NO_ERROR) return -EPERM; - mAtcAmbientLight.clear_dirty(); + mAtcAmbientLight.value.clear_dirty(); } return NO_ERROR; @@ -908,12 +953,12 @@ int32_t ExynosPrimaryDisplayModule::setAtcMode(std::string mode_name) { if (enable) { atc_mode mode = mode_data->second; for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) { - mAtcSubSetting[it->first.c_str()].store(mode.sub_setting[it->first.c_str()]); - if (mAtcSubSetting[it->first.c_str()].is_dirty()) { - if (writeIntToFile(it->second.c_str(), mAtcSubSetting[it->first.c_str()].get()) != - NO_ERROR) + mAtcSubSetting[it->first.c_str()].value.store(mode.sub_setting[it->first.c_str()]); + if (mAtcSubSetting[it->first.c_str()].value.is_dirty()) { + if (writeIntToFile(mAtcSubSetting[it->first.c_str()].node, + mAtcSubSetting[it->first.c_str()].value.get()) != NO_ERROR) return -EPERM; - mAtcSubSetting[it->first.c_str()].clear_dirty(); + mAtcSubSetting[it->first.c_str()].value.clear_dirty(); } } mAtcStUpStep = mode.st_up_step; @@ -973,12 +1018,10 @@ void ExynosPrimaryDisplayModule::setLbeState(LbeState state) { if (setAtcMode(modeStr) != NO_ERROR) return; - requestEnhancedHbm(enhanced_hbm); - mDisplayInterface->updateBrightness(false); - + mBrightnessController->processEnhancedHbm(enhanced_hbm); if (mCurrentLbeState != state) { mCurrentLbeState = state; - mDevice->invalidate(); + mDevice->onRefresh(); } ALOGI("Lbe state %hhd", mCurrentLbeState); } @@ -1006,7 +1049,7 @@ void ExynosPrimaryDisplayModule::setLbeAmbientLight(int value) { if (mAtcLuxMapIndex != index) { mAtcLuxMapIndex = index; - mDevice->invalidate(); + mDevice->onRefresh(); } mCurrentLux = value; } @@ -1015,9 +1058,27 @@ LbeState ExynosPrimaryDisplayModule::getLbeState() { return mCurrentLbeState; } +PanelCalibrationStatus ExynosPrimaryDisplayModule::getPanelCalibrationStatus() { + auto displayColorInterface = getDisplayColorInterface(); + if (displayColorInterface == nullptr) { + return PanelCalibrationStatus::UNCALIBRATED; + } + + auto displayType = getBuiltInDisplayType(); + auto calibrationInfo = displayColorInterface->GetCalibrationInfo(displayType); + + if (calibrationInfo.factory_cal_loaded) { + return PanelCalibrationStatus::ORIGINAL; + } else if (calibrationInfo.golden_cal_loaded) { + return PanelCalibrationStatus::GOLDEN; + } else { + return PanelCalibrationStatus::UNCALIBRATED; + } +} + int32_t ExynosPrimaryDisplayModule::setAtcStDimming(uint32_t value) { Mutex::Autolock lock(mAtcStMutex); - int32_t strength = mAtcStrength.get(); + int32_t strength = mAtcStrength.value.get(); if (mAtcStTarget != value) { mAtcStTarget = value; uint32_t step = mAtcStTarget > strength ? mAtcStUpStep : mAtcStDownStep; @@ -1028,7 +1089,7 @@ int32_t ExynosPrimaryDisplayModule::setAtcStDimming(uint32_t value) { ALOGI("setup atc st dimming=%d, count=%d, step=%d", value, count, step); } - if (mAtcStStepCount == 0 && !mAtcStrength.is_dirty()) return NO_ERROR; + if (mAtcStStepCount == 0 && !mAtcStrength.value.is_dirty()) return NO_ERROR; if ((strength + mAtcStUpStep) < mAtcStTarget) { strength = strength + mAtcStUpStep; @@ -1048,10 +1109,10 @@ int32_t ExynosPrimaryDisplayModule::setAtcStDimming(uint32_t value) { } int32_t ExynosPrimaryDisplayModule::setAtcEnable(bool enable) { - mAtcEnable.store(enable); - if (mAtcEnable.is_dirty()) { - if (writeIntToFile(ATC_ENABLE_FILE_NAME, enable) != NO_ERROR) return -EPERM; - mAtcEnable.clear_dirty(); + mAtcEnable.value.store(enable); + if (mAtcEnable.value.is_dirty()) { + if (writeIntToFile(mAtcEnable.node, enable) != NO_ERROR) return -EPERM; + mAtcEnable.value.clear_dirty(); } return NO_ERROR; } @@ -1073,7 +1134,7 @@ void ExynosPrimaryDisplayModule::checkAtcAnimation() { ALOGI("atc enable is off (pending off=false)"); } - mDevice->invalidate(); + mDevice->onRefresh(); } int32_t ExynosPrimaryDisplayModule::setPowerMode(int32_t mode) { diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h index 0339526..ada69f6 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h @@ -49,27 +49,27 @@ constexpr char kAtcModeNormalStr[] = "normal"; constexpr char kAtcModeHbmStr[] = "hbm"; constexpr char kAtcModePowerSaveStr[] = "power_save"; -#define ATC_AMBIENT_LIGHT_FILE_NAME "/sys/class/dqe/atc/ambient_light" -#define ATC_ST_FILE_NAME "/sys/class/dqe/atc/st" -#define ATC_ENABLE_FILE_NAME "/sys/class/dqe/atc/en" -#define ATC_LT_FILE_NAME "/sys/class/dqe/atc/lt" -#define ATC_NS_FILE_NAME "/sys/class/dqe/atc/ns" -#define ATC_DITHER_FILE_NAME "/sys/class/dqe/atc/dither" -#define ATC_PL_W1_FILE_NAME "/sys/class/dqe/atc/pl_w1" -#define ATC_PL_W2_FILE_NAME "/sys/class/dqe/atc/pl_w2" -#define ATC_CTMODE_FILE_NAME "/sys/class/dqe/atc/ctmode" -#define ATC_PP_EN_FILE_NAME "/sys/class/dqe/atc/pp_en" -#define ATC_UPGRADE_ON_FILE_NAME "/sys/class/dqe/atc/upgrade_on" -#define ATC_TDR_MAX_FILE_NAME "/sys/class/dqe/atc/tdr_max" -#define ATC_TDR_MIN_FILE_NAME "/sys/class/dqe/atc/tdr_min" -#define ATC_BACKLIGHT_FILE_NAME "/sys/class/dqe/atc/back_light" -#define ATC_DSTEP_FILE_NAME "/sys/class/dqe/atc/dstep" -#define ATC_SCALE_MODE_FILE_NAME "/sys/class/dqe/atc/scale_mode" -#define ATC_THRESHOLD_1_FILE_NAME "/sys/class/dqe/atc/threshold_1" -#define ATC_THRESHOLD_2_FILE_NAME "/sys/class/dqe/atc/threshold_2" -#define ATC_THRESHOLD_3_FILE_NAME "/sys/class/dqe/atc/threshold_3" -#define ATC_GAIN_LIMIT_FILE_NAME "/sys/class/dqe/atc/gain_limit" -#define ATC_LT_CALC_AB_SHIFT_FILE_NAME "/sys/class/dqe/atc/lt_calc_ab_shift" +#define ATC_AMBIENT_LIGHT_FILE_NAME "/sys/class/dqe%d/atc/ambient_light" +#define ATC_ST_FILE_NAME "/sys/class/dqe%d/atc/st" +#define ATC_ENABLE_FILE_NAME "/sys/class/dqe%d/atc/en" +#define ATC_LT_FILE_NAME "/sys/class/dqe%d/atc/lt" +#define ATC_NS_FILE_NAME "/sys/class/dqe%d/atc/ns" +#define ATC_DITHER_FILE_NAME "/sys/class/dqe%d/atc/dither" +#define ATC_PL_W1_FILE_NAME "/sys/class/dqe%d/atc/pl_w1" +#define ATC_PL_W2_FILE_NAME "/sys/class/dqe%d/atc/pl_w2" +#define ATC_CTMODE_FILE_NAME "/sys/class/dqe%d/atc/ctmode" +#define ATC_PP_EN_FILE_NAME "/sys/class/dqe%d/atc/pp_en" +#define ATC_UPGRADE_ON_FILE_NAME "/sys/class/dqe%d/atc/upgrade_on" +#define ATC_TDR_MAX_FILE_NAME "/sys/class/dqe%d/atc/tdr_max" +#define ATC_TDR_MIN_FILE_NAME "/sys/class/dqe%d/atc/tdr_min" +#define ATC_BACKLIGHT_FILE_NAME "/sys/class/dqe%d/atc/back_light" +#define ATC_DSTEP_FILE_NAME "/sys/class/dqe%d/atc/dstep" +#define ATC_SCALE_MODE_FILE_NAME "/sys/class/dqe%d/atc/scale_mode" +#define ATC_THRESHOLD_1_FILE_NAME "/sys/class/dqe%d/atc/threshold_1" +#define ATC_THRESHOLD_2_FILE_NAME "/sys/class/dqe%d/atc/threshold_2" +#define ATC_THRESHOLD_3_FILE_NAME "/sys/class/dqe%d/atc/threshold_3" +#define ATC_GAIN_LIMIT_FILE_NAME "/sys/class/dqe%d/atc/gain_limit" +#define ATC_LT_CALC_AB_SHIFT_FILE_NAME "/sys/class/dqe%d/atc/lt_calc_ab_shift" const std::unordered_map<std::string, std::string> kAtcSubSetting = {{"local_tone_gain", ATC_LT_FILE_NAME}, @@ -111,13 +111,18 @@ class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { virtual int32_t setColorModeWithRenderIntent(int32_t mode, int32_t intent); virtual int32_t setColorTransform(const float* matrix, int32_t hint); + virtual int32_t getClientTargetProperty( + hwc_client_target_property_t* outClientTargetProperty, + HwcDimmingStage *outDimmingStage = nullptr) override; virtual int deliverWinConfigData(); virtual int32_t updateColorConversionInfo(); virtual int32_t updatePresentColorConversionInfo(); virtual bool checkRrCompensationEnabled() { const DisplayType display = getDisplayTypeFromIndex(mIndex); IDisplayColorGS101* displayColorInterface = getDisplayColorInterface(); - return displayColorInterface->IsRrCompensationEnabled(display); + return displayColorInterface + ? displayColorInterface->IsRrCompensationEnabled(display) + : false; } virtual bool isColorCalibratedByDevice(); @@ -129,6 +134,8 @@ class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { virtual void setLbeAmbientLight(int value); virtual LbeState getLbeState(); + virtual PanelCalibrationStatus getPanelCalibrationStatus(); + class DisplaySceneInfo { public: struct LayerMappingInfo { @@ -251,6 +258,9 @@ class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { return displayColorInterface->GetPipelineData(display)->Dqe(); }; + // primary or secondary + DisplayType getBuiltInDisplayType() { return getDisplayTypeFromIndex(mIndex); } + private: int32_t setLayersColorData(); DisplaySceneInfo mDisplaySceneInfo; @@ -267,6 +277,10 @@ class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { uint32_t st_up_step; uint32_t st_down_step; }; + struct atc_sysfs { + String8 node; + CtrlValue<int32_t> value; + }; bool parseAtcProfile(); int32_t setAtcMode(std::string mode_name); @@ -303,10 +317,10 @@ class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { std::string mCurrentAtcModeName; uint32_t mCurrentLux = 0; uint32_t mAtcLuxMapIndex = 0; - CtrlValue<uint32_t> mAtcAmbientLight; - CtrlValue<uint32_t> mAtcStrength; - CtrlValue<uint32_t> mAtcEnable; - std::unordered_map<std::string, CtrlValue<int32_t>> mAtcSubSetting; + struct atc_sysfs mAtcAmbientLight; + struct atc_sysfs mAtcStrength; + struct atc_sysfs mAtcEnable; + std::unordered_map<std::string, struct atc_sysfs> mAtcSubSetting; uint32_t mAtcStStepCount = 0; uint32_t mAtcStTarget = 0; uint32_t mAtcStUpStep; |