/* * Copyright (C) 2019 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 EXYNOS_DISPLAY_MODULE_H #define EXYNOS_DISPLAY_MODULE_H #include #include "ExynosDeviceModule.h" #include "ExynosDisplay.h" #include "ExynosLayer.h" #include "ExynosPrimaryDisplay.h" constexpr char kAtcJsonRaw[] = "{\"version\":\"0.0\",\"modes\":[{\"name\":\"normal\",\"lux_map\":[0,5000,10000," "50000,70000],\"ambient_light_map\":[0,0,12,32,63],\"strength_map\":[0,0,128,128,200]," "\"st_up_step\":2, \"st_down_step\":2," "\"sub_setting\":{\"local_tone_gain\":128,\"noise_suppression_gain\":128,\"dither\":0," "\"plain_weight_1\":10,\"plain_weight_2\":14,\"color_transform_mode\":2,\"preprocessing_" "enable\":1,\"upgrade_on\":0,\"TDR_max\":900,\"TDR_min\":256,\"backlight\":255,\"dimming_" "step\":4,\"scale_mode\":1,\"threshold_1\":1,\"threshold_2\":1,\"threshold_3\":1,\"gain_" "limit\":511,\"lt_calc_ab_shift\":1}}]}"; constexpr char kAtcProfilePath[] = "vendor/etc/atc_profile.json"; constexpr char kAtcProfileVersionStr[] = "version"; constexpr char kAtcProfileModesStr[] = "modes"; constexpr char kAtcProfileModeNameStr[] = "name"; constexpr char kAtcProfileLuxMapStr[] = "lux_map"; constexpr char kAtcProfileAlMapStr[] = "ambient_light_map"; constexpr char kAtcProfileStMapStr[] = "strength_map"; constexpr char kAtcProfileSubSettingStr[] = "sub_setting"; constexpr char kAtcProfileStUpStepStr[] = "st_up_step"; constexpr char kAtcProfileStDownStepStr[] = "st_down_step"; constexpr uint32_t kAtcStStep = 2; 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" const std::unordered_map kAtcSubSetting = {{"local_tone_gain", ATC_LT_FILE_NAME}, {"noise_suppression_gain", ATC_NS_FILE_NAME}, {"dither", ATC_DITHER_FILE_NAME}, {"plain_weight_1", ATC_PL_W1_FILE_NAME}, {"plain_weight_2", ATC_PL_W2_FILE_NAME}, {"color_transform_mode", ATC_CTMODE_FILE_NAME}, {"preprocessing_enable", ATC_PP_EN_FILE_NAME}, {"upgrade_on", ATC_UPGRADE_ON_FILE_NAME}, {"TDR_max", ATC_TDR_MAX_FILE_NAME}, {"TDR_min", ATC_TDR_MIN_FILE_NAME}, {"backlight", ATC_BACKLIGHT_FILE_NAME}, {"dimming_step", ATC_DSTEP_FILE_NAME}, {"scale_mode", ATC_SCALE_MODE_FILE_NAME}, {"threshold_1", ATC_THRESHOLD_1_FILE_NAME}, {"threshold_2", ATC_THRESHOLD_2_FILE_NAME}, {"threshold_3", ATC_THRESHOLD_3_FILE_NAME}, {"gain_limit", ATC_GAIN_LIMIT_FILE_NAME}, {"lt_calc_ab_shift", ATC_LT_CALC_AB_SHIFT_FILE_NAME}}; namespace gs101 { using namespace displaycolor; class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { public: ExynosPrimaryDisplayModule(uint32_t index, ExynosDevice *device); ~ExynosPrimaryDisplayModule(); void usePreDefinedWindow(bool use); virtual int32_t validateWinConfigData(); void doPreProcessing(); virtual int32_t getColorModes( uint32_t* outNumModes, int32_t* outModes); virtual int32_t setColorMode(int32_t mode); virtual int32_t getRenderIntents(int32_t mode, uint32_t* outNumIntents, int32_t* outIntents); virtual int32_t setColorModeWithRenderIntent(int32_t mode, int32_t intent); virtual int32_t setColorTransform(const float* matrix, int32_t hint); 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); } virtual bool isColorCalibratedByDevice(); virtual int32_t getColorAdjustedDbv(uint32_t &dbv_adj); virtual void initLbe(); virtual void setLbeState(LbeState state); virtual void setLbeAmbientLight(int value); virtual LbeState getLbeState(); class DisplaySceneInfo { public: struct LayerMappingInfo { bool operator==(const LayerMappingInfo &rhs) const { return ((dppIdx == rhs.dppIdx) && (planeId == rhs.planeId)); } // index in DisplayScene::layer_data uint32_t dppIdx; // assigned drm plane id in last color setting update uint32_t planeId; }; bool colorSettingChanged = false; bool displaySettingDelivered = false; DisplayScene displayScene; /* * Index of LayerColorData in DisplayScene::layer_data * and assigned plane id in last color setting update. * for each layer, including client composition * key: ExynosMPPSource* * data: LayerMappingInfo */ std::map layerDataMappingInfo; std::map prev_layerDataMappingInfo; void reset() { colorSettingChanged = false; prev_layerDataMappingInfo = layerDataMappingInfo; layerDataMappingInfo.clear(); }; template void updateInfoSingleVal(T &dst, M &src) { if (src != dst) { colorSettingChanged = true; dst = src; } }; template void updateInfoVectorVal(std::vector &dst, M *src, uint32_t size) { if ((dst.size() != size) || !std::equal(dst.begin(), dst.end(), src)) { colorSettingChanged = true; dst.resize(size); for (uint32_t i = 0; i < size; i++) { dst[i] = src[i]; } } }; void setColorMode(hwc::ColorMode mode) { updateInfoSingleVal(displayScene.color_mode, mode); }; void setRenderIntent(hwc::RenderIntent intent) { updateInfoSingleVal(displayScene.render_intent, intent); }; void setColorTransform(const float* matrix) { for (uint32_t i = 0; i < displayScene.matrix.size(); i++) { if (displayScene.matrix[i] != matrix[i]) { colorSettingChanged = true; displayScene.matrix[i] = matrix[i]; } } } LayerColorData& getLayerColorDataInstance(uint32_t index); int32_t setLayerDataMappingInfo(ExynosMPPSource* layer, uint32_t index); void setLayerDataspace(LayerColorData& layerColorData, hwc::Dataspace dataspace); void disableLayerHdrStaticMetadata(LayerColorData& layerColorData); void setLayerHdrStaticMetadata(LayerColorData& layerColorData, const ExynosHdrStaticInfo& exynosHdrStaticInfo); void setLayerColorTransform(LayerColorData& layerColorData, std::array &matrix); void disableLayerHdrDynamicMetadata(LayerColorData& layerColorData); void setLayerHdrDynamicMetadata(LayerColorData& layerColorData, const ExynosHdrDynamicInfo& exynosHdrDynamicInfo); int32_t setLayerColorData(LayerColorData& layerData, ExynosLayer* layer, float dimSdrRatio); int32_t setClientCompositionColorData( const ExynosCompositionInfo& clientCompositionInfo, LayerColorData& layerData, float dimSdrRatio); bool needDisplayColorSetting(); void printDisplayScene(); void printLayerColorData(const LayerColorData& layerData); }; bool hasDisplayColor() { IDisplayColorGS101* displayColorInterface = getDisplayColorInterface(); return displayColorInterface != nullptr; } /* Call getDppForLayer() only if hasDppForLayer() is true */ bool hasDppForLayer(ExynosMPPSource* layer); const IDisplayColorGS101::IDpp& getDppForLayer(ExynosMPPSource* layer); int32_t getDppIndexForLayer(ExynosMPPSource* layer); /* Check if layer's assigned plane id has changed, save the new planeId. * call only if hasDppForLayer is true */ bool checkAndSaveLayerPlaneId(ExynosMPPSource* layer, uint32_t planeId) { auto &info = mDisplaySceneInfo.layerDataMappingInfo[layer]; bool change = info.planeId != planeId; info.planeId = planeId; return change; } size_t getNumOfDpp() { const DisplayType display = getDisplayTypeFromIndex(mIndex); IDisplayColorGS101* displayColorInterface = getDisplayColorInterface(); return displayColorInterface->GetPipelineData(display)->Dpp().size(); }; const IDisplayColorGS101::IDqe& getDqe() { const DisplayType display = getDisplayTypeFromIndex(mIndex); IDisplayColorGS101* displayColorInterface = getDisplayColorInterface(); return displayColorInterface->GetPipelineData(display)->Dqe(); }; private: int32_t setLayersColorData(); DisplaySceneInfo mDisplaySceneInfo; struct atc_lux_map { uint32_t lux; uint32_t al; uint32_t st; }; struct atc_mode { std::vector lux_map; std::unordered_map sub_setting; uint32_t st_up_step; uint32_t st_down_step; }; bool parseAtcProfile(); int32_t setAtcMode(std::string mode_name); uint32_t getAtcLuxMapIndex(std::vector, uint32_t lux); int32_t setAtcAmbientLight(uint32_t ambient_light); int32_t setAtcStrength(uint32_t strenght); int32_t setAtcStDimming(uint32_t target); int32_t setAtcEnable(bool enable); void checkAtcAnimation(); bool isInAtcAnimation() { if (mAtcStStepCount > 0) return true; else return false; }; DisplayType getDisplayTypeFromIndex(uint32_t index) { return (index >= DisplayType::DISPLAY_MAX) ? DisplayType::DISPLAY_PRIMARY : DisplayType(mIndex); }; IDisplayColorGS101* getDisplayColorInterface() { ExynosDeviceModule* device = (ExynosDeviceModule*)mDevice; return device->getDisplayColorInterface(); } bool isForceColorUpdate() const { return mForceColorUpdate; } void setForceColorUpdate(bool force) { mForceColorUpdate = force; } bool isDisplaySwitched(int32_t mode, int32_t prevMode); std::map mAtcModeSetting; bool mAtcInit; LbeState mCurrentLbeState = LbeState::OFF; std::string mCurrentAtcModeName; uint32_t mCurrentLux = 0; uint32_t mAtcLuxMapIndex = 0; CtrlValue mAtcAmbientLight; CtrlValue mAtcStrength; CtrlValue mAtcEnable; std::unordered_map> mAtcSubSetting; uint32_t mAtcStStepCount = 0; uint32_t mAtcStTarget = 0; uint32_t mAtcStUpStep; uint32_t mAtcStDownStep; Mutex mAtcStMutex; bool mPendingAtcOff; bool mForceColorUpdate = false; protected: virtual int32_t setPowerMode(int32_t mode) override; }; } // namespace gs101 #endif