1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
18 
19 #include "ExynosPrimaryDisplayModule.h"
20 
21 #include <android-base/file.h>
22 #include <json/reader.h>
23 #include <json/value.h>
24 
25 #include <cmath>
26 
27 #include "BrightnessController.h"
28 #include "ExynosDisplayDrmInterfaceModule.h"
29 #include "ExynosHWCDebug.h"
30 
31 #ifdef FORCE_GPU_COMPOSITION
32 extern exynos_hwc_control exynosHWCControl;
33 #endif
34 
35 using namespace gs101;
36 
getMPPTypeFromDPPChannel(uint32_t channel)37 mpp_phycal_type_t getMPPTypeFromDPPChannel(uint32_t channel) {
38 
39     for (int i=0; i < MAX_DECON_DMA_TYPE; i++){
40         if(idma_channel_map[i].channel == channel)
41             return idma_channel_map[i].type;
42     }
43 
44     return MPP_P_TYPE_MAX;
45 }
46 
ExynosPrimaryDisplayModule(uint32_t index,ExynosDevice * device,const std::string & displayName)47 ExynosPrimaryDisplayModule::ExynosPrimaryDisplayModule(uint32_t index, ExynosDevice* device,
48                                                        const std::string& displayName)
49       : ExynosPrimaryDisplay(index, device, displayName), mAtcInit(false) {
50 #ifdef FORCE_GPU_COMPOSITION
51     exynosHWCControl.forceGpu = true;
52 #endif
53     mColorManager = std::make_unique<ColorManager>(this, static_cast<ExynosDeviceModule*>(device));
54 }
55 
~ExynosPrimaryDisplayModule()56 ExynosPrimaryDisplayModule::~ExynosPrimaryDisplayModule () {
57 }
58 
usePreDefinedWindow(bool use)59 void ExynosPrimaryDisplayModule::usePreDefinedWindow(bool use)
60 {
61 #ifdef FIX_BASE_WINDOW_INDEX
62     /* Use fixed base window index */
63     mBaseWindowIndex = FIX_BASE_WINDOW_INDEX;
64     return;
65 #endif
66 
67     if (use) {
68         mBaseWindowIndex = PRIMARY_DISP_BASE_WIN[mDevice->mDisplayMode];
69         mMaxWindowNum = mDisplayInterface->getMaxWindowNum() - PRIMARY_DISP_BASE_WIN[mDevice->mDisplayMode];
70     } else {
71         mBaseWindowIndex = 0;
72         mMaxWindowNum = mDisplayInterface->getMaxWindowNum();
73     }
74 }
75 
validateWinConfigData()76 int32_t ExynosPrimaryDisplayModule::validateWinConfigData()
77 {
78     bool flagValidConfig = true;
79 
80     if (ExynosDisplay::validateWinConfigData() != NO_ERROR)
81         flagValidConfig = false;
82 
83     for (size_t i = 0; i < mDpuData.configs.size(); i++) {
84         struct exynos_win_config_data &config = mDpuData.configs[i];
85         if (config.state == config.WIN_STATE_BUFFER) {
86             bool configInvalid = false;
87             uint32_t mppType = config.assignedMPP->mPhysicalType;
88             if ((config.src.w != config.dst.w) ||
89                 (config.src.h != config.dst.h)) {
90                 if ((mppType == MPP_DPP_GF) ||
91                     (mppType == MPP_DPP_VG) ||
92                     (mppType == MPP_DPP_VGF)) {
93                     DISPLAY_LOGE("WIN_CONFIG error: invalid assign id : "
94                             "%zu,  s_w : %d, d_w : %d, s_h : %d, d_h : %d, mppType : %d",
95                             i, config.src.w, config.dst.w, config.src.h, config.dst.h, mppType);
96                     configInvalid = true;
97                 }
98             }
99             if (configInvalid) {
100                 config.state = config.WIN_STATE_DISABLED;
101                 flagValidConfig = false;
102             }
103         }
104     }
105     if (flagValidConfig)
106         return NO_ERROR;
107     else
108         return -EINVAL;
109 }
110 
doPreProcessing()111 void ExynosPrimaryDisplayModule::doPreProcessing() {
112     ExynosDisplay::doPreProcessing();
113 
114     if (mDevice->checkNonInternalConnection()) {
115         mDisplayControl.adjustDisplayFrame = true;
116     } else {
117         mDisplayControl.adjustDisplayFrame = false;
118     }
119 }
120 
getColorModes(uint32_t * outNumModes,int32_t * outModes)121 int32_t ExynosPrimaryDisplayModule::getColorModes(
122         uint32_t* outNumModes, int32_t* outModes)
123 {
124     return mColorManager->getColorModes(outNumModes, outModes);
125 }
126 
setColorMode(int32_t mode)127 int32_t ExynosPrimaryDisplayModule::setColorMode(int32_t mode)
128 {
129     return mColorManager->setColorMode(mode);
130 }
131 
getRenderIntents(int32_t mode,uint32_t * outNumIntents,int32_t * outIntents)132 int32_t ExynosPrimaryDisplayModule::getRenderIntents(int32_t mode,
133         uint32_t* outNumIntents, int32_t* outIntents)
134 {
135     return mColorManager->getRenderIntents(mode, outNumIntents, outIntents);
136 }
137 
setColorModeWithRenderIntent(int32_t mode,int32_t intent)138 int32_t ExynosPrimaryDisplayModule::setColorModeWithRenderIntent(int32_t mode,
139         int32_t intent)
140 {
141     return mColorManager->setColorModeWithRenderIntent(mode, intent);
142 }
143 
setColorTransform(const float * matrix,int32_t hint)144 int32_t ExynosPrimaryDisplayModule::setColorTransform(
145         const float* matrix, int32_t hint)
146 {
147     return mColorManager->setColorTransform(matrix, hint);
148 }
149 
getClientTargetProperty(hwc_client_target_property_t * outClientTargetProperty,HwcDimmingStage * outDimmingStage)150 int32_t ExynosPrimaryDisplayModule::getClientTargetProperty(
151         hwc_client_target_property_t* outClientTargetProperty,
152         HwcDimmingStage *outDimmingStage) {
153     GsInterfaceType* displayColorInterface = getDisplayColorInterface();
154     if (displayColorInterface == nullptr) {
155         ALOGI("%s dc interface not created", __func__);
156         return ExynosDisplay::getClientTargetProperty(outClientTargetProperty);
157     }
158 
159     const DisplayType display = getDcDisplayType();
160     hwc::PixelFormat pixelFormat;
161     hwc::Dataspace dataspace;
162     bool dimming_linear;
163     if (!displayColorInterface->GetBlendingProperty(display, pixelFormat, dataspace,
164                                                     dimming_linear)) {
165         outClientTargetProperty->pixelFormat = toUnderlying(pixelFormat);
166         outClientTargetProperty->dataspace = toUnderlying(dataspace);
167         if (outDimmingStage != nullptr)
168             *outDimmingStage = dimming_linear
169                               ? HwcDimmingStage::DIMMING_LINEAR
170                               : HwcDimmingStage::DIMMING_OETF;
171 
172         return HWC2_ERROR_NONE;
173     }
174 
175     ALOGW("%s failed to get property of blending stage", __func__);
176     return ExynosDisplay::getClientTargetProperty(outClientTargetProperty);
177 }
178 
updateBrightnessTable()179 int32_t ExynosPrimaryDisplayModule::updateBrightnessTable() {
180     std::unique_ptr<const IBrightnessTable> table;
181     auto displayColorInterface = getDisplayColorInterface();
182     if (displayColorInterface == nullptr) {
183         ALOGE("%s displaycolor interface not available!", __func__);
184         return HWC2_ERROR_NO_RESOURCES;
185     }
186 
187     auto displayType = getDcDisplayType();
188     auto ret = displayColorInterface->GetBrightnessTable(displayType, table);
189     if (ret != android::OK) {
190         ALOGE("%s brightness table not available!", __func__);
191         return HWC2_ERROR_NO_RESOURCES;
192     }
193     // BrightnessController is not ready until this step
194     mBrightnessController->updateBrightnessTable(table);
195 
196     return HWC2_ERROR_NONE;
197 }
198 
deliverWinConfigData()199 int ExynosPrimaryDisplayModule::deliverWinConfigData()
200 {
201     int ret = 0;
202     ExynosDisplayDrmInterfaceModule *moduleDisplayInterface =
203         (ExynosDisplayDrmInterfaceModule*)(mDisplayInterface.get());
204     GsInterfaceType* displayColorInterface = getDisplayColorInterface();
205 
206     bool forceDisplayColorSetting = false;
207     if (!getDisplaySceneInfo().displaySettingDelivered || isForceColorUpdate())
208         forceDisplayColorSetting = true;
209 
210     setForceColorUpdate(false);
211 
212     if (displayColorInterface != nullptr) {
213         moduleDisplayInterface
214                 ->setColorSettingChanged(getDisplaySceneInfo().needDisplayColorSetting(),
215                                          forceDisplayColorSetting);
216     }
217 
218     checkAtcHdrMode();
219 
220     ret = ExynosDisplay::deliverWinConfigData();
221 
222     checkAtcAnimation();
223 
224     if (mDpuData.enable_readback &&
225        !mDpuData.readback_info.requested_from_service)
226         getDisplaySceneInfo().displaySettingDelivered = false;
227     else
228         getDisplaySceneInfo().displaySettingDelivered = true;
229 
230     return ret;
231 }
232 
updateColorConversionInfo()233 int32_t ExynosPrimaryDisplayModule::updateColorConversionInfo()
234 {
235     return mColorManager->updateColorConversionInfo();
236 }
237 
resetColorMappingInfo(ExynosMPPSource * mppSrc)238 int32_t ExynosPrimaryDisplayModule::resetColorMappingInfo(ExynosMPPSource* mppSrc) {
239     return mColorManager->resetColorMappingInfo(mppSrc);
240 }
241 
updatePresentColorConversionInfo()242 int32_t ExynosPrimaryDisplayModule::updatePresentColorConversionInfo()
243 {
244     int ret = NO_ERROR;
245     GsInterfaceType* displayColorInterface = getDisplayColorInterface();
246     if (displayColorInterface == nullptr) {
247         return ret;
248     }
249 
250     ExynosDisplayDrmInterfaceModule *moduleDisplayInterface =
251         (ExynosDisplayDrmInterfaceModule*)(mDisplayInterface.get());
252     auto refresh_rate = moduleDisplayInterface->getDesiredRefreshRate();
253     if (refresh_rate > 0) {
254         getDisplaySceneInfo().displayScene.refresh_rate = refresh_rate;
255     }
256     auto operation_rate = moduleDisplayInterface->getOperationRate();
257     if (operation_rate > 0) {
258         getDisplaySceneInfo().displayScene.operation_rate = static_cast<uint32_t>(operation_rate);
259     }
260 
261     getDisplaySceneInfo().displayScene.lhbm_on = mBrightnessController->isLhbmOn();
262     getDisplaySceneInfo().displayScene.dbv = mBrightnessController->getBrightnessLevel();
263     getDisplaySceneInfo().displayScene.temperature = getDisplayTemperatue();
264     const DisplayType display = getDcDisplayType();
265     if ((ret = displayColorInterface->UpdatePresent(display, getDisplaySceneInfo().displayScene)) !=
266         0) {
267         DISPLAY_LOGE("Display Scene update error (%d)", ret);
268         return ret;
269     }
270 
271     return ret;
272 }
273 
getColorAdjustedDbv(uint32_t & dbv_adj)274 int32_t ExynosPrimaryDisplayModule::getColorAdjustedDbv(uint32_t &dbv_adj) {
275     GsInterfaceType* displayColorInterface = getDisplayColorInterface();
276     if (displayColorInterface == nullptr) {
277         return NO_ERROR;
278     }
279 
280     const DisplayType display = getDcDisplayType();
281     dbv_adj = displayColorInterface->GetPipelineData(display)->Panel().GetAdjustedBrightnessLevel();
282     return NO_ERROR;
283 }
284 
parseAtcProfile()285 bool ExynosPrimaryDisplayModule::parseAtcProfile() {
286     Json::Value root;
287     Json::CharReaderBuilder reader_builder;
288     std::unique_ptr<Json::CharReader> reader(reader_builder.newCharReader());
289     std::string atc_profile;
290 
291     if (!android::base::ReadFileToString(kAtcProfilePath, &atc_profile)) {
292         atc_profile = kAtcJsonRaw;
293         ALOGI("Use default atc profile file");
294     }
295 
296     if (!reader->parse(atc_profile.c_str(), atc_profile.c_str() + atc_profile.size(), &root,
297                        nullptr)) {
298         ALOGE("Failed to parse atc profile file");
299         return false;
300     }
301 
302     ALOGI("Atc Profile version = %s", root[kAtcProfileVersionStr].asString().c_str());
303     Json::Value nodes = root[kAtcProfileModesStr];
304     atc_mode mode;
305 
306     for (Json::Value::ArrayIndex i = 0; i < nodes.size(); ++i) {
307         std::string name = nodes[i][kAtcProfileModeNameStr].asString();
308 
309         if (nodes[i][kAtcProfileLuxMapStr].size() != nodes[i][kAtcProfileAlMapStr].size() &&
310             nodes[i][kAtcProfileAlMapStr].size() != nodes[i][kAtcProfileStMapStr].size()) {
311             ALOGE("Atc profile is unavailable !");
312             return false;
313         }
314 
315         uint32_t map_cnt = nodes[i][kAtcProfileLuxMapStr].size();
316 
317         mode.lux_map.clear();
318         for (uint32_t index = 0; index < map_cnt; ++index) {
319             mode.lux_map.emplace_back(atc_lux_map{nodes[i][kAtcProfileLuxMapStr][index].asUInt(),
320                                                   nodes[i][kAtcProfileAlMapStr][index].asUInt(),
321                                                   nodes[i][kAtcProfileStMapStr][index].asUInt()});
322         }
323 
324         if (!nodes[i][kAtcProfileStUpStepStr].empty())
325             mode.st_up_step = nodes[i][kAtcProfileStUpStepStr].asUInt();
326         else
327             mode.st_up_step = kAtcStStep;
328 
329         if (!nodes[i][kAtcProfileStDownStepStr].empty())
330             mode.st_down_step = nodes[i][kAtcProfileStDownStepStr].asUInt();
331         else
332             mode.st_down_step = kAtcStStep;
333 
334         if (nodes[i][kAtcProfileSubSettingStr].size() != kAtcSubSetting.size()) return false;
335 
336         for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
337             mode.sub_setting[it->first.c_str()] =
338                     nodes[i][kAtcProfileSubSettingStr][it->first.c_str()].asUInt();
339         }
340         auto ret = mAtcModeSetting.insert(std::make_pair(name.c_str(), mode));
341         if (ret.second == false) {
342             ALOGE("Atc mode %s is already existed!", ret.first->first.c_str());
343             return false;
344         }
345     }
346 
347     if (mAtcModeSetting.find(kAtcModeNormalStr) == mAtcModeSetting.end()) {
348         ALOGW("Failed to find atc normal mode");
349         return false;
350     }
351     return true;
352 }
353 
isLbeSupported()354 bool ExynosPrimaryDisplayModule::isLbeSupported() {
355     return mLbeSupported;
356 }
357 
initLbe()358 void ExynosPrimaryDisplayModule::initLbe() {
359     if (!parseAtcProfile()) {
360         ALOGD("Failed to parseAtcMode");
361         mAtcInit = false;
362         return;
363     }
364 
365     mAtcInit = true;
366     mAtcAmbientLight.node = String8::format(ATC_AMBIENT_LIGHT_FILE_NAME, mIndex);
367     mAtcAmbientLight.value.set_dirty();
368     mAtcStrength.node = String8::format(ATC_ST_FILE_NAME, mIndex);
369     mAtcStrength.value.set_dirty();
370     mAtcEnable.node = String8::format(ATC_ENABLE_FILE_NAME, mIndex);
371     mAtcEnable.value.set_dirty();
372 
373     for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
374         mAtcSubSetting[it->first.c_str()].node = String8::format(it->second.c_str(), mIndex);
375         mAtcSubSetting[it->first.c_str()].value.set_dirty();
376     }
377     mLbeSupported = true;
378 }
379 
getAtcLuxMapIndex(std::vector<atc_lux_map> map,uint32_t lux)380 uint32_t ExynosPrimaryDisplayModule::getAtcLuxMapIndex(std::vector<atc_lux_map> map, uint32_t lux) {
381     uint32_t index = 0;
382     for (uint32_t i = 0; i < map.size(); i++) {
383         if (lux < map[i].lux) {
384             break;
385         }
386         index = i;
387     }
388 
389     return index;
390 }
391 
setAtcStrength(uint32_t strength)392 int32_t ExynosPrimaryDisplayModule::setAtcStrength(uint32_t strength) {
393     mAtcStrength.value.store(strength);
394     if (mAtcStrength.value.is_dirty()) {
395         if (writeIntToFile(mAtcStrength.node.c_str(), mAtcStrength.value.get()) != NO_ERROR) {
396             return -EPERM;
397         }
398         mAtcStrength.value.clear_dirty();
399     }
400     return NO_ERROR;
401 }
402 
setAtcAmbientLight(uint32_t ambient_light)403 int32_t ExynosPrimaryDisplayModule::setAtcAmbientLight(uint32_t ambient_light) {
404     mAtcAmbientLight.value.store(ambient_light);
405     if (mAtcAmbientLight.value.is_dirty()) {
406         if (writeIntToFile(mAtcAmbientLight.node.c_str(), mAtcAmbientLight.value.get()) != NO_ERROR)
407             return -EPERM;
408         mAtcAmbientLight.value.clear_dirty();
409     }
410 
411     return NO_ERROR;
412 }
413 
setAtcMode(std::string mode_name)414 int32_t ExynosPrimaryDisplayModule::setAtcMode(std::string mode_name) {
415     ATRACE_CALL();
416     auto mode_data = mAtcModeSetting.find(mode_name);
417     uint32_t ambient_light = 0;
418     uint32_t strength = 0;
419     bool enable = (!mode_name.empty()) && (mode_data != mAtcModeSetting.end());
420 
421     if (enable) {
422         atc_mode mode = mode_data->second;
423         for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
424             mAtcSubSetting[it->first.c_str()].value.store(mode.sub_setting[it->first.c_str()]);
425             if (mAtcSubSetting[it->first.c_str()].value.is_dirty()) {
426                 if (writeIntToFile(mAtcSubSetting[it->first.c_str()].node.c_str(),
427                                    mAtcSubSetting[it->first.c_str()].value.get()) != NO_ERROR)
428                     return -EPERM;
429                 mAtcSubSetting[it->first.c_str()].value.clear_dirty();
430             }
431         }
432         mAtcStUpStep = mode.st_up_step;
433         mAtcStDownStep = mode.st_down_step;
434 
435         uint32_t index = getAtcLuxMapIndex(mode.lux_map, mCurrentLux);
436         ambient_light = mode.lux_map[index].al;
437         strength = mode.lux_map[index].st;
438     }
439 
440     if (setAtcAmbientLight(ambient_light) != NO_ERROR) {
441         ALOGE("Fail to set atc ambient light for %s mode", mode_name.c_str());
442         return -EPERM;
443     }
444 
445     if (setAtcStDimming(strength) != NO_ERROR) {
446         ALOGE("Fail to set atc st dimming for %s mode", mode_name.c_str());
447         return -EPERM;
448     }
449 
450     if (!enable && isInAtcAnimation()) {
451         mPendingAtcOff = true;
452     } else {
453         if (setAtcEnable(enable) != NO_ERROR) {
454             ALOGE("Fail to set atc enable = %d", enable);
455             return -EPERM;
456         }
457         mPendingAtcOff = false;
458     }
459 
460     mCurrentAtcModeName = enable ? mode_name : "NULL";
461     ALOGI("atc enable=%d (mode=%s, pending off=%s)", enable, mCurrentAtcModeName.c_str(),
462           mPendingAtcOff ? "true" : "false");
463     return NO_ERROR;
464 }
setLbeState(LbeState state)465 void ExynosPrimaryDisplayModule::setLbeState(LbeState state) {
466     if (!mAtcInit) return;
467 
468     std::string modeStr;
469     bool enhanced_hbm = false;
470     bool fullHdrLayer = isFullScreenHdrLayer();
471 
472     switch (state) {
473         case LbeState::OFF:
474             mCurrentLux = 0;
475             break;
476         case LbeState::NORMAL:
477             modeStr = kAtcModeNormalStr;
478             break;
479         case LbeState::HIGH_BRIGHTNESS:
480             modeStr = kAtcModeHbmStr;
481             break;
482         case LbeState::POWER_SAVE:
483             modeStr = kAtcModePowerSaveStr;
484             break;
485         case LbeState::HIGH_BRIGHTNESS_ENHANCE:
486             modeStr = kAtcModeHbmStr;
487             enhanced_hbm = true;
488             break;
489         default:
490             ALOGE("Lbe state not support");
491             return;
492     }
493 
494     if (fullHdrLayer && state != LbeState::OFF) checkAtcHdrMode();
495     else if (setAtcMode(modeStr) != NO_ERROR) return;
496 
497     mBrightnessController->processEnhancedHbm(enhanced_hbm);
498     mBrightnessController->setOutdoorVisibility(state);
499 
500     if (mCurrentLbeState != state) {
501         mCurrentLbeState = state;
502         mDevice->onRefresh(mDisplayId);
503     }
504     ALOGI("Lbe state %hhd", mCurrentLbeState);
505 }
506 
setLbeAmbientLight(int value)507 void ExynosPrimaryDisplayModule::setLbeAmbientLight(int value) {
508     if (!mAtcInit) return;
509 
510     auto it = mAtcModeSetting.find(mCurrentAtcModeName);
511     if (it == mAtcModeSetting.end()) {
512         ALOGE("Atc mode not found");
513         return;
514     }
515     atc_mode mode = it->second;
516 
517     uint32_t index = getAtcLuxMapIndex(mode.lux_map, value);
518     if (setAtcAmbientLight(mode.lux_map[index].al) != NO_ERROR) {
519         ALOGE("Failed to set atc ambient light");
520         return;
521     }
522 
523     if (setAtcStDimming(mode.lux_map[index].st) != NO_ERROR) {
524         ALOGE("Failed to set atc st dimming");
525         return;
526     }
527 
528     if (mAtcLuxMapIndex != index) {
529         mAtcLuxMapIndex = index;
530         mDevice->onRefresh(mDisplayId);
531     }
532     mCurrentLux = value;
533 }
534 
getLbeState()535 LbeState ExynosPrimaryDisplayModule::getLbeState() {
536     return mCurrentLbeState;
537 }
538 
getPanelCalibrationStatus()539 PanelCalibrationStatus ExynosPrimaryDisplayModule::getPanelCalibrationStatus() {
540     auto displayColorInterface = getDisplayColorInterface();
541     if (displayColorInterface == nullptr) {
542         return PanelCalibrationStatus::UNCALIBRATED;
543     }
544 
545     auto displayType = getDcDisplayType();
546     auto calibrationInfo = displayColorInterface->GetCalibrationInfo(displayType);
547 
548     if (calibrationInfo.factory_cal_loaded) {
549         return PanelCalibrationStatus::ORIGINAL;
550     } else if (calibrationInfo.golden_cal_loaded) {
551         return PanelCalibrationStatus::GOLDEN;
552     } else {
553         return PanelCalibrationStatus::UNCALIBRATED;
554     }
555 }
556 
setAtcStDimming(uint32_t value)557 int32_t ExynosPrimaryDisplayModule::setAtcStDimming(uint32_t value) {
558     Mutex::Autolock lock(mAtcStMutex);
559     int32_t strength = mAtcStrength.value.get();
560     if (mAtcStTarget != value) {
561         mAtcStTarget = value;
562         uint32_t step = mAtcStTarget > strength ? mAtcStUpStep : mAtcStDownStep;
563 
564         int diff = value - strength;
565         uint32_t count = (std::abs(diff) + step - 1) / step;
566         mAtcStStepCount = count;
567         ALOGI("setup atc st dimming=%d, count=%d, step=%d", value, count, step);
568     }
569 
570     if (mAtcStStepCount == 0 && !mAtcStrength.value.is_dirty()) return NO_ERROR;
571 
572     if ((strength + mAtcStUpStep) < mAtcStTarget) {
573         strength = strength + mAtcStUpStep;
574     } else if (strength > (mAtcStTarget + mAtcStDownStep)) {
575         strength = strength - mAtcStDownStep;
576     } else {
577         strength = mAtcStTarget;
578     }
579 
580     if (setAtcStrength(strength) != NO_ERROR) {
581         ALOGE("Failed to set atc st");
582         return -EPERM;
583     }
584 
585     if (mAtcStStepCount > 0) mAtcStStepCount--;
586     return NO_ERROR;
587 }
588 
setAtcEnable(bool enable)589 int32_t ExynosPrimaryDisplayModule::setAtcEnable(bool enable) {
590     mAtcEnable.value.store(enable);
591     if (mAtcEnable.value.is_dirty()) {
592         if (writeIntToFile(mAtcEnable.node.c_str(), enable) != NO_ERROR) return -EPERM;
593         mAtcEnable.value.clear_dirty();
594     }
595     return NO_ERROR;
596 }
597 
checkAtcAnimation()598 void ExynosPrimaryDisplayModule::checkAtcAnimation() {
599     if (!isInAtcAnimation()) return;
600 
601     if (setAtcStDimming(mAtcStTarget) != NO_ERROR) {
602         ALOGE("Failed to set atc st dimming");
603         return;
604     }
605 
606     if (mPendingAtcOff && mAtcStStepCount == 0) {
607         if (setAtcEnable(false) != NO_ERROR) {
608             ALOGE("Failed to set atc enable to off");
609             return;
610         }
611         mPendingAtcOff = false;
612         ALOGI("atc enable is off (pending off=false)");
613     }
614 
615     mDevice->onRefresh(mDisplayId);
616 }
617 
setPowerMode(int32_t mode)618 int32_t ExynosPrimaryDisplayModule::setPowerMode(int32_t mode) {
619     hwc2_power_mode_t prevPowerModeState = mPowerModeState.value_or(HWC2_POWER_MODE_OFF);
620     int32_t ret;
621 
622     ret = ExynosPrimaryDisplay::setPowerMode(mode);
623 
624     if ((ret == HWC2_ERROR_NONE) && isDisplaySwitched(mode, prevPowerModeState)) {
625         ExynosDeviceModule* device = static_cast<ExynosDeviceModule*>(mDevice);
626 
627         device->setActiveDisplay(mIndex);
628         setForceColorUpdate(true);
629     }
630     return ret;
631 }
632 
isDisplaySwitched(int32_t mode,int32_t prevMode)633 bool ExynosPrimaryDisplayModule::isDisplaySwitched(int32_t mode, int32_t prevMode) {
634     ExynosDeviceModule* device = static_cast<ExynosDeviceModule*>(mDevice);
635 
636     return (device->getActiveDisplay() != mIndex) && (prevMode == HWC_POWER_MODE_OFF) &&
637             (mode != HWC_POWER_MODE_OFF);
638 }
639 
checkAtcHdrMode()640 void ExynosPrimaryDisplayModule::checkAtcHdrMode() {
641     ATRACE_CALL();
642     if (!mAtcInit) return;
643 
644     auto it = mAtcModeSetting.find(kAtcModeHdrStr);
645     if (it == mAtcModeSetting.end()) {
646         return;
647     }
648 
649     bool hdrModeActive = (mCurrentAtcModeName == kAtcModeHdrStr);
650     bool fullHdrLayer = isFullScreenHdrLayer();
651 
652     if (fullHdrLayer) {
653         if (!hdrModeActive && (mCurrentLbeState != LbeState::OFF)) {
654             setAtcMode(kAtcModeHdrStr);
655             ALOGI("HdrLayer on to set atc hdr mode");
656         }
657     } else {
658         if (hdrModeActive) {
659             setLbeState(mCurrentLbeState);
660             ALOGI("HdrLayer off to restore Lbe State");
661         }
662     }
663 }
664 
isFullScreenHdrLayer()665 bool ExynosPrimaryDisplayModule::isFullScreenHdrLayer() {
666     return mBrightnessController->getHdrLayerState() == HdrLayerState::kHdrLarge;
667 }
668