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 const DisplayType display = getDcDisplayType();
264 if ((ret = displayColorInterface->UpdatePresent(display, getDisplaySceneInfo().displayScene)) !=
265 0) {
266 DISPLAY_LOGE("Display Scene update error (%d)", ret);
267 return ret;
268 }
269
270 return ret;
271 }
272
getColorAdjustedDbv(uint32_t & dbv_adj)273 int32_t ExynosPrimaryDisplayModule::getColorAdjustedDbv(uint32_t &dbv_adj) {
274 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
275 if (displayColorInterface == nullptr) {
276 return NO_ERROR;
277 }
278
279 const DisplayType display = getDcDisplayType();
280 dbv_adj = displayColorInterface->GetPipelineData(display)->Panel().GetAdjustedBrightnessLevel();
281 return NO_ERROR;
282 }
283
parseAtcProfile()284 bool ExynosPrimaryDisplayModule::parseAtcProfile() {
285 Json::Value root;
286 Json::CharReaderBuilder reader_builder;
287 std::unique_ptr<Json::CharReader> reader(reader_builder.newCharReader());
288 std::string atc_profile;
289
290 if (!android::base::ReadFileToString(kAtcProfilePath, &atc_profile)) {
291 atc_profile = kAtcJsonRaw;
292 ALOGI("Use default atc profile file");
293 }
294
295 if (!reader->parse(atc_profile.c_str(), atc_profile.c_str() + atc_profile.size(), &root,
296 nullptr)) {
297 ALOGE("Failed to parse atc profile file");
298 return false;
299 }
300
301 ALOGI("Atc Profile version = %s", root[kAtcProfileVersionStr].asString().c_str());
302 Json::Value nodes = root[kAtcProfileModesStr];
303 atc_mode mode;
304
305 for (Json::Value::ArrayIndex i = 0; i < nodes.size(); ++i) {
306 std::string name = nodes[i][kAtcProfileModeNameStr].asString();
307
308 if (nodes[i][kAtcProfileLuxMapStr].size() != nodes[i][kAtcProfileAlMapStr].size() &&
309 nodes[i][kAtcProfileAlMapStr].size() != nodes[i][kAtcProfileStMapStr].size()) {
310 ALOGE("Atc profile is unavailable !");
311 return false;
312 }
313
314 uint32_t map_cnt = nodes[i][kAtcProfileLuxMapStr].size();
315
316 mode.lux_map.clear();
317 for (uint32_t index = 0; index < map_cnt; ++index) {
318 mode.lux_map.emplace_back(atc_lux_map{nodes[i][kAtcProfileLuxMapStr][index].asUInt(),
319 nodes[i][kAtcProfileAlMapStr][index].asUInt(),
320 nodes[i][kAtcProfileStMapStr][index].asUInt()});
321 }
322
323 if (!nodes[i][kAtcProfileStUpStepStr].empty())
324 mode.st_up_step = nodes[i][kAtcProfileStUpStepStr].asUInt();
325 else
326 mode.st_up_step = kAtcStStep;
327
328 if (!nodes[i][kAtcProfileStDownStepStr].empty())
329 mode.st_down_step = nodes[i][kAtcProfileStDownStepStr].asUInt();
330 else
331 mode.st_down_step = kAtcStStep;
332
333 if (nodes[i][kAtcProfileSubSettingStr].size() != kAtcSubSetting.size()) return false;
334
335 for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
336 mode.sub_setting[it->first.c_str()] =
337 nodes[i][kAtcProfileSubSettingStr][it->first.c_str()].asUInt();
338 }
339 auto ret = mAtcModeSetting.insert(std::make_pair(name.c_str(), mode));
340 if (ret.second == false) {
341 ALOGE("Atc mode %s is already existed!", ret.first->first.c_str());
342 return false;
343 }
344 }
345
346 if (mAtcModeSetting.find(kAtcModeNormalStr) == mAtcModeSetting.end()) {
347 ALOGW("Failed to find atc normal mode");
348 return false;
349 }
350 return true;
351 }
352
isLbeSupported()353 bool ExynosPrimaryDisplayModule::isLbeSupported() {
354 return mLbeSupported;
355 }
356
initLbe()357 void ExynosPrimaryDisplayModule::initLbe() {
358 if (!parseAtcProfile()) {
359 ALOGD("Failed to parseAtcMode");
360 mAtcInit = false;
361 return;
362 }
363
364 mAtcInit = true;
365 mAtcAmbientLight.node = String8::format(ATC_AMBIENT_LIGHT_FILE_NAME, mIndex);
366 mAtcAmbientLight.value.set_dirty();
367 mAtcStrength.node = String8::format(ATC_ST_FILE_NAME, mIndex);
368 mAtcStrength.value.set_dirty();
369 mAtcEnable.node = String8::format(ATC_ENABLE_FILE_NAME, mIndex);
370 mAtcEnable.value.set_dirty();
371
372 for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
373 mAtcSubSetting[it->first.c_str()].node = String8::format(it->second.c_str(), mIndex);
374 mAtcSubSetting[it->first.c_str()].value.set_dirty();
375 }
376 mLbeSupported = true;
377 }
378
getAtcLuxMapIndex(std::vector<atc_lux_map> map,uint32_t lux)379 uint32_t ExynosPrimaryDisplayModule::getAtcLuxMapIndex(std::vector<atc_lux_map> map, uint32_t lux) {
380 uint32_t index = 0;
381 for (uint32_t i = 0; i < map.size(); i++) {
382 if (lux < map[i].lux) {
383 break;
384 }
385 index = i;
386 }
387
388 return index;
389 }
390
setAtcStrength(uint32_t strength)391 int32_t ExynosPrimaryDisplayModule::setAtcStrength(uint32_t strength) {
392 mAtcStrength.value.store(strength);
393 if (mAtcStrength.value.is_dirty()) {
394 if (writeIntToFile(mAtcStrength.node.c_str(), mAtcStrength.value.get()) != NO_ERROR) {
395 return -EPERM;
396 }
397 mAtcStrength.value.clear_dirty();
398 }
399 return NO_ERROR;
400 }
401
setAtcAmbientLight(uint32_t ambient_light)402 int32_t ExynosPrimaryDisplayModule::setAtcAmbientLight(uint32_t ambient_light) {
403 mAtcAmbientLight.value.store(ambient_light);
404 if (mAtcAmbientLight.value.is_dirty()) {
405 if (writeIntToFile(mAtcAmbientLight.node.c_str(), mAtcAmbientLight.value.get()) != NO_ERROR)
406 return -EPERM;
407 mAtcAmbientLight.value.clear_dirty();
408 }
409
410 return NO_ERROR;
411 }
412
setAtcMode(std::string mode_name)413 int32_t ExynosPrimaryDisplayModule::setAtcMode(std::string mode_name) {
414 ATRACE_CALL();
415 auto mode_data = mAtcModeSetting.find(mode_name);
416 uint32_t ambient_light = 0;
417 uint32_t strength = 0;
418 bool enable = (!mode_name.empty()) && (mode_data != mAtcModeSetting.end());
419
420 if (enable) {
421 atc_mode mode = mode_data->second;
422 for (auto it = kAtcSubSetting.begin(); it != kAtcSubSetting.end(); it++) {
423 mAtcSubSetting[it->first.c_str()].value.store(mode.sub_setting[it->first.c_str()]);
424 if (mAtcSubSetting[it->first.c_str()].value.is_dirty()) {
425 if (writeIntToFile(mAtcSubSetting[it->first.c_str()].node.c_str(),
426 mAtcSubSetting[it->first.c_str()].value.get()) != NO_ERROR)
427 return -EPERM;
428 mAtcSubSetting[it->first.c_str()].value.clear_dirty();
429 }
430 }
431 mAtcStUpStep = mode.st_up_step;
432 mAtcStDownStep = mode.st_down_step;
433
434 uint32_t index = getAtcLuxMapIndex(mode.lux_map, mCurrentLux);
435 ambient_light = mode.lux_map[index].al;
436 strength = mode.lux_map[index].st;
437 }
438
439 if (setAtcAmbientLight(ambient_light) != NO_ERROR) {
440 ALOGE("Fail to set atc ambient light for %s mode", mode_name.c_str());
441 return -EPERM;
442 }
443
444 if (setAtcStDimming(strength) != NO_ERROR) {
445 ALOGE("Fail to set atc st dimming for %s mode", mode_name.c_str());
446 return -EPERM;
447 }
448
449 if (!enable && isInAtcAnimation()) {
450 mPendingAtcOff = true;
451 } else {
452 if (setAtcEnable(enable) != NO_ERROR) {
453 ALOGE("Fail to set atc enable = %d", enable);
454 return -EPERM;
455 }
456 mPendingAtcOff = false;
457 }
458
459 mCurrentAtcModeName = enable ? mode_name : "NULL";
460 ALOGI("atc enable=%d (mode=%s, pending off=%s)", enable, mCurrentAtcModeName.c_str(),
461 mPendingAtcOff ? "true" : "false");
462 return NO_ERROR;
463 }
setLbeState(LbeState state)464 void ExynosPrimaryDisplayModule::setLbeState(LbeState state) {
465 if (!mAtcInit) return;
466
467 std::string modeStr;
468 bool enhanced_hbm = false;
469 bool fullHdrLayer = isFullScreenHdrLayer();
470
471 switch (state) {
472 case LbeState::OFF:
473 mCurrentLux = 0;
474 break;
475 case LbeState::NORMAL:
476 modeStr = kAtcModeNormalStr;
477 break;
478 case LbeState::HIGH_BRIGHTNESS:
479 modeStr = kAtcModeHbmStr;
480 break;
481 case LbeState::POWER_SAVE:
482 modeStr = kAtcModePowerSaveStr;
483 break;
484 case LbeState::HIGH_BRIGHTNESS_ENHANCE:
485 modeStr = kAtcModeHbmStr;
486 enhanced_hbm = true;
487 break;
488 default:
489 ALOGE("Lbe state not support");
490 return;
491 }
492
493 if (fullHdrLayer && state != LbeState::OFF) checkAtcHdrMode();
494 else if (setAtcMode(modeStr) != NO_ERROR) return;
495
496 mBrightnessController->processEnhancedHbm(enhanced_hbm);
497 mBrightnessController->setOutdoorVisibility(state);
498
499 if (mCurrentLbeState != state) {
500 mCurrentLbeState = state;
501 mDevice->onRefresh(mDisplayId);
502 }
503 ALOGI("Lbe state %hhd", mCurrentLbeState);
504 }
505
setLbeAmbientLight(int value)506 void ExynosPrimaryDisplayModule::setLbeAmbientLight(int value) {
507 if (!mAtcInit) return;
508
509 auto it = mAtcModeSetting.find(mCurrentAtcModeName);
510 if (it == mAtcModeSetting.end()) {
511 ALOGE("Atc mode not found");
512 return;
513 }
514 atc_mode mode = it->second;
515
516 uint32_t index = getAtcLuxMapIndex(mode.lux_map, value);
517 if (setAtcAmbientLight(mode.lux_map[index].al) != NO_ERROR) {
518 ALOGE("Failed to set atc ambient light");
519 return;
520 }
521
522 if (setAtcStDimming(mode.lux_map[index].st) != NO_ERROR) {
523 ALOGE("Failed to set atc st dimming");
524 return;
525 }
526
527 if (mAtcLuxMapIndex != index) {
528 mAtcLuxMapIndex = index;
529 mDevice->onRefresh(mDisplayId);
530 }
531 mCurrentLux = value;
532 }
533
getLbeState()534 LbeState ExynosPrimaryDisplayModule::getLbeState() {
535 return mCurrentLbeState;
536 }
537
getPanelCalibrationStatus()538 PanelCalibrationStatus ExynosPrimaryDisplayModule::getPanelCalibrationStatus() {
539 auto displayColorInterface = getDisplayColorInterface();
540 if (displayColorInterface == nullptr) {
541 return PanelCalibrationStatus::UNCALIBRATED;
542 }
543
544 auto displayType = getDcDisplayType();
545 auto calibrationInfo = displayColorInterface->GetCalibrationInfo(displayType);
546
547 if (calibrationInfo.factory_cal_loaded) {
548 return PanelCalibrationStatus::ORIGINAL;
549 } else if (calibrationInfo.golden_cal_loaded) {
550 return PanelCalibrationStatus::GOLDEN;
551 } else {
552 return PanelCalibrationStatus::UNCALIBRATED;
553 }
554 }
555
setAtcStDimming(uint32_t value)556 int32_t ExynosPrimaryDisplayModule::setAtcStDimming(uint32_t value) {
557 Mutex::Autolock lock(mAtcStMutex);
558 int32_t strength = mAtcStrength.value.get();
559 if (mAtcStTarget != value) {
560 mAtcStTarget = value;
561 uint32_t step = mAtcStTarget > strength ? mAtcStUpStep : mAtcStDownStep;
562
563 int diff = value - strength;
564 uint32_t count = (std::abs(diff) + step - 1) / step;
565 mAtcStStepCount = count;
566 ALOGI("setup atc st dimming=%d, count=%d, step=%d", value, count, step);
567 }
568
569 if (mAtcStStepCount == 0 && !mAtcStrength.value.is_dirty()) return NO_ERROR;
570
571 if ((strength + mAtcStUpStep) < mAtcStTarget) {
572 strength = strength + mAtcStUpStep;
573 } else if (strength > (mAtcStTarget + mAtcStDownStep)) {
574 strength = strength - mAtcStDownStep;
575 } else {
576 strength = mAtcStTarget;
577 }
578
579 if (setAtcStrength(strength) != NO_ERROR) {
580 ALOGE("Failed to set atc st");
581 return -EPERM;
582 }
583
584 if (mAtcStStepCount > 0) mAtcStStepCount--;
585 return NO_ERROR;
586 }
587
setAtcEnable(bool enable)588 int32_t ExynosPrimaryDisplayModule::setAtcEnable(bool enable) {
589 mAtcEnable.value.store(enable);
590 if (mAtcEnable.value.is_dirty()) {
591 if (writeIntToFile(mAtcEnable.node.c_str(), enable) != NO_ERROR) return -EPERM;
592 mAtcEnable.value.clear_dirty();
593 }
594 return NO_ERROR;
595 }
596
checkAtcAnimation()597 void ExynosPrimaryDisplayModule::checkAtcAnimation() {
598 if (!isInAtcAnimation()) return;
599
600 if (setAtcStDimming(mAtcStTarget) != NO_ERROR) {
601 ALOGE("Failed to set atc st dimming");
602 return;
603 }
604
605 if (mPendingAtcOff && mAtcStStepCount == 0) {
606 if (setAtcEnable(false) != NO_ERROR) {
607 ALOGE("Failed to set atc enable to off");
608 return;
609 }
610 mPendingAtcOff = false;
611 ALOGI("atc enable is off (pending off=false)");
612 }
613
614 mDevice->onRefresh(mDisplayId);
615 }
616
setPowerMode(int32_t mode)617 int32_t ExynosPrimaryDisplayModule::setPowerMode(int32_t mode) {
618 hwc2_power_mode_t prevPowerModeState = mPowerModeState.value_or(HWC2_POWER_MODE_OFF);
619 int32_t ret;
620
621 ret = ExynosPrimaryDisplay::setPowerMode(mode);
622
623 if ((ret == HWC2_ERROR_NONE) && isDisplaySwitched(mode, prevPowerModeState)) {
624 ExynosDeviceModule* device = static_cast<ExynosDeviceModule*>(mDevice);
625
626 device->setActiveDisplay(mIndex);
627 setForceColorUpdate(true);
628 }
629 return ret;
630 }
631
isDisplaySwitched(int32_t mode,int32_t prevMode)632 bool ExynosPrimaryDisplayModule::isDisplaySwitched(int32_t mode, int32_t prevMode) {
633 ExynosDeviceModule* device = static_cast<ExynosDeviceModule*>(mDevice);
634
635 return (device->getActiveDisplay() != mIndex) && (prevMode == HWC_POWER_MODE_OFF) &&
636 (mode != HWC_POWER_MODE_OFF);
637 }
638
checkAtcHdrMode()639 void ExynosPrimaryDisplayModule::checkAtcHdrMode() {
640 ATRACE_CALL();
641 if (!mAtcInit) return;
642
643 auto it = mAtcModeSetting.find(kAtcModeHdrStr);
644 if (it == mAtcModeSetting.end()) {
645 return;
646 }
647
648 bool hdrModeActive = (mCurrentAtcModeName == kAtcModeHdrStr);
649 bool fullHdrLayer = isFullScreenHdrLayer();
650
651 if (fullHdrLayer) {
652 if (!hdrModeActive && (mCurrentLbeState != LbeState::OFF)) {
653 setAtcMode(kAtcModeHdrStr);
654 ALOGI("HdrLayer on to set atc hdr mode");
655 }
656 } else {
657 if (hdrModeActive) {
658 setLbeState(mCurrentLbeState);
659 ALOGI("HdrLayer off to restore Lbe State");
660 }
661 }
662 }
663
isFullScreenHdrLayer()664 bool ExynosPrimaryDisplayModule::isFullScreenHdrLayer() {
665 return mBrightnessController->getHdrLayerState() == HdrLayerState::kHdrLarge;
666 }
667