diff options
author | linpeter <linpeter@google.com> | 2021-05-17 10:36:12 +0800 |
---|---|---|
committer | linpeter <linpeter@google.com> | 2021-06-10 11:34:35 +0800 |
commit | 20cf479ad1c0abb81878df3c0768717fce1643f8 (patch) | |
tree | d4cf540d7d12ab517863a925f5aaf4d33ac15420 /libhwc2.1/libmaindisplay | |
parent | b432911c6031bdf308cea77f389921d0365ec60c (diff) | |
download | gs101-20cf479ad1c0abb81878df3c0768717fce1643f8.tar.gz |
hwc/gs101: atc st dimming
Added the atc st dimming mechanism
Bug: 181286324
test: atc st change
Change-Id: I365c2d904f5f874fa2bf4d22d0eea0b3468aa3bf
Diffstat (limited to 'libhwc2.1/libmaindisplay')
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp | 165 | ||||
-rw-r--r-- | libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h | 27 |
2 files changed, 158 insertions, 34 deletions
diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp index 4a98768..0a4a6d0 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.cpp @@ -20,6 +20,8 @@ #include <json/reader.h> #include <json/value.h> +#include <cmath> + #include "ExynosDisplayDrmInterfaceModule.h" #include "ExynosHWCDebug.h" @@ -360,6 +362,7 @@ int ExynosPrimaryDisplayModule::deliverWinConfigData() ret = ExynosDisplay::deliverWinConfigData(); + checkAtcAnimation(); return ret; } @@ -751,6 +754,16 @@ bool ExynosPrimaryDisplayModule::parseAtcProfile() { nodes[i][kAtcProfileStMapStr][index].asUInt()}); } + if (!nodes[i][kAtcProfileStUpStepStr].empty()) + mode.st_up_step = nodes[i][kAtcProfileStUpStepStr].asUInt(); + else + mode.st_up_step = kAtcStStep; + + if (!nodes[i][kAtcProfileStDownStepStr].empty()) + mode.st_down_step = nodes[i][kAtcProfileStDownStepStr].asUInt(); + else + mode.st_down_step = kAtcStStep; + if (nodes[i][kAtcProfileSubSettingStr].size() != kAtcSubSetting.size()) return false; for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) { @@ -779,6 +792,10 @@ 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(); } uint32_t ExynosPrimaryDisplayModule::getAtcLuxMapIndex(std::vector<atc_lux_map> map, uint32_t lux) { @@ -793,16 +810,18 @@ uint32_t ExynosPrimaryDisplayModule::getAtcLuxMapIndex(std::vector<atc_lux_map> return index; } -int32_t ExynosPrimaryDisplayModule::setAtcAmbientLight(uint32_t ambient_light, uint32_t strength, - bool force_update) { +int32_t ExynosPrimaryDisplayModule::setAtcStrength(uint32_t strength) { mAtcStrength.store(strength); - if (mAtcStrength.is_dirty() || force_update) { + if (mAtcStrength.is_dirty()) { if (writeIntToFile(ATC_ST_FILE_NAME, mAtcStrength.get()) != NO_ERROR) return -EPERM; mAtcStrength.clear_dirty(); } + return NO_ERROR; +} +int32_t ExynosPrimaryDisplayModule::setAtcAmbientLight(uint32_t ambient_light) { mAtcAmbientLight.store(ambient_light); - if (mAtcAmbientLight.is_dirty() || force_update) { + if (mAtcAmbientLight.is_dirty()) { if (writeIntToFile(ATC_AMBIENT_LIGHT_FILE_NAME, mAtcAmbientLight.get()) != NO_ERROR) return -EPERM; mAtcAmbientLight.clear_dirty(); @@ -811,54 +830,69 @@ int32_t ExynosPrimaryDisplayModule::setAtcAmbientLight(uint32_t ambient_light, u return NO_ERROR; } -int32_t ExynosPrimaryDisplayModule::setAtcMode(std::string mode_name, bool force_update) { - auto it = mAtcModeSetting.find(mode_name); - if (it == mAtcModeSetting.end()) { - ALOGW("Atc %s mode not found", mode_name.c_str()); - return -EINVAL; - } - atc_mode mode = it->second; +int32_t ExynosPrimaryDisplayModule::setAtcMode(std::string mode_name) { + auto mode_data = mAtcModeSetting.find(mode_name); + uint32_t ambient_light = 0; + uint32_t strength = 0; + bool enable = (!mode_name.empty()) && (mode_data != mAtcModeSetting.end()); - 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() || force_update) { - if (writeIntToFile(it->second.c_str(), mAtcSubSetting[it->first.c_str()].get()) != - NO_ERROR) - return -EPERM; - mAtcSubSetting[it->first.c_str()].clear_dirty(); + 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) + return -EPERM; + mAtcSubSetting[it->first.c_str()].clear_dirty(); + } } + mAtcStUpStep = mode.st_up_step; + mAtcStDownStep = mode.st_down_step; + + uint32_t index = getAtcLuxMapIndex(mode.lux_map, mCurrentLux); + ambient_light = mode.lux_map[index].al; + strength = mode.lux_map[index].st; } - mAtcLuxMapIndex = getAtcLuxMapIndex(mode.lux_map, mCurrentLux); - if (setAtcAmbientLight(mode.lux_map[mAtcLuxMapIndex].al, mode.lux_map[mAtcLuxMapIndex].st, - force_update) != NO_ERROR) { + if (setAtcAmbientLight(ambient_light) != NO_ERROR) { ALOGE("Fail to set atc ambient light for %s mode", mode_name.c_str()); return -EPERM; } - mCurrentAtcModeName = mode_name; - ALOGI("mCurrentAtcModeName %s", mCurrentAtcModeName.c_str()); + if (setAtcStDimming(strength) != NO_ERROR) { + ALOGE("Fail to set atc st dimming for %s mode", mode_name.c_str()); + return -EPERM; + } + + if (!enable && isInAtcAnimation()) { + mPendingAtcOff = true; + } else { + if (setAtcEnable(enable) != NO_ERROR) { + ALOGE("Fail to set atc enable = %d", enable); + return -EPERM; + } + } + + mCurrentAtcModeName = enable ? mode_name : "NULL"; + ALOGI("atc enable=%d (mode=%s, pending off=%s)", enable, mCurrentAtcModeName.c_str(), + mPendingAtcOff ? "true" : "false"); return NO_ERROR; } void ExynosPrimaryDisplayModule::setLbeState(LbeState state) { if (!mAtcInit) return; std::string modeStr; - uint32_t atc_on = 0; switch (state) { case LbeState::OFF: - atc_on = 0; mCurrentLux = 0; break; case LbeState::NORMAL: - atc_on = 1; modeStr = kAtcModeNormalStr; break; case LbeState::HIGH_BRIGHTNESS: - atc_on = 1; modeStr = kAtcModeHbmStr; break; case LbeState::POWER_SAVE: - atc_on = 1; modeStr = kAtcModePowerSaveStr; break; default: @@ -866,11 +900,9 @@ void ExynosPrimaryDisplayModule::setLbeState(LbeState state) { return; } - if (!modeStr.empty()) - if (setAtcMode(modeStr, mCurrentAtcModeName.empty() ? true : false) != NO_ERROR) return; + if (setAtcMode(modeStr) != NO_ERROR) return; if (mCurrentLbeState != state) { - writeIntToFile(ATC_ENABLE_FILE_NAME, atc_on); mCurrentLbeState = state; mDevice->invalidate(); } @@ -888,11 +920,16 @@ void ExynosPrimaryDisplayModule::setLbeAmbientLight(int value) { atc_mode mode = it->second; uint32_t index = getAtcLuxMapIndex(mode.lux_map, value); - if (setAtcAmbientLight(mode.lux_map[index].al, mode.lux_map[index].st, false) != NO_ERROR) { + if (setAtcAmbientLight(mode.lux_map[index].al) != NO_ERROR) { ALOGE("Failed to set atc ambient light"); return; } + if (setAtcStDimming(mode.lux_map[index].st) != NO_ERROR) { + ALOGE("Failed to set atc st dimming"); + return; + } + if (mAtcLuxMapIndex != index) { mAtcLuxMapIndex = index; mDevice->invalidate(); @@ -903,3 +940,67 @@ void ExynosPrimaryDisplayModule::setLbeAmbientLight(int value) { LbeState ExynosPrimaryDisplayModule::getLbeState() { return mCurrentLbeState; } + +int32_t ExynosPrimaryDisplayModule::setAtcStDimming(uint32_t value) { + Mutex::Autolock lock(mAtcStMutex); + int32_t strength = mAtcStrength.get(); + if (mAtcStTarget != value) { + mAtcStTarget = value; + uint32_t step = mAtcStTarget > strength ? mAtcStUpStep : mAtcStDownStep; + + int diff = value - strength; + uint32_t steps = std::abs(diff) / step; + int remainder = std::abs(diff) % step; + if (remainder > 0) steps = steps + 1; + mAtcStStepLeft = steps; + ALOGI("setup atc st dimming=%d, steps=%d, step=%d", value, steps, step); + } + + if (mAtcStStepLeft == 0 && !mAtcStrength.is_dirty()) return NO_ERROR; + + if (strength < mAtcStTarget) { + strength = strength + mAtcStUpStep; + if (strength > mAtcStTarget) strength = mAtcStTarget; + } else if (strength > mAtcStTarget) { + strength = strength - mAtcStDownStep; + if (strength < mAtcStTarget) strength = mAtcStTarget; + } else + strength = mAtcStTarget; + + if (setAtcStrength(strength) != NO_ERROR) { + ALOGE("Failed to set atc st"); + return -EPERM; + } + + if (mAtcStStepLeft > 0) mAtcStStepLeft--; + return NO_ERROR; +} + +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(); + } + return NO_ERROR; +} + +void ExynosPrimaryDisplayModule::checkAtcAnimation() { + if (!isInAtcAnimation()) return; + + if (setAtcStDimming(mAtcStTarget) != NO_ERROR) { + ALOGE("Failed to set atc st dimming"); + return; + } + + if (mPendingAtcOff && mAtcStStepLeft == 0) { + if (setAtcEnable(false) != NO_ERROR) { + ALOGE("Failed to set atc enable to off"); + return; + } + mPendingAtcOff = false; + ALOGI("atc enable is off (pending off=false)"); + } + + mDevice->invalidate(); +} diff --git a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h index cb7056c..2e47355 100644 --- a/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h +++ b/libhwc2.1/libmaindisplay/ExynosPrimaryDisplayModule.h @@ -26,6 +26,7 @@ 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_" @@ -40,6 +41,9 @@ 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"; @@ -238,12 +242,24 @@ class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { struct atc_mode { std::vector<atc_lux_map> lux_map; std::unordered_map<std::string, int32_t> sub_setting; + uint32_t st_up_step; + uint32_t st_down_step; }; bool parseAtcProfile(); - int32_t setAtcMode(std::string mode_name, bool force_update); + int32_t setAtcMode(std::string mode_name); uint32_t getAtcLuxMapIndex(std::vector<atc_lux_map>, uint32_t lux); - int32_t setAtcAmbientLight(uint32_t ambient_light, uint32_t strenght, bool force_update); + 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 (mAtcStStepLeft > 0) + return true; + else + return false; + }; std::map<std::string, atc_mode> mAtcModeSetting; bool mAtcInit; @@ -253,7 +269,14 @@ class ExynosPrimaryDisplayModule : public ExynosPrimaryDisplay { 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; + uint32_t mAtcStStepLeft = 0; + uint32_t mAtcStTarget = 0; + uint32_t mAtcStUpStep; + uint32_t mAtcStDownStep; + Mutex mAtcStMutex; + bool mPendingAtcOff; }; #endif |