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