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 //#define LOG_NDEBUG 0
17 #include "ExynosExternalDisplayModule.h"
18 #include "ExynosPrimaryDisplayModule.h"
19
20 #ifdef USES_VIRTUAL_DISPLAY
21 #include "ExynosVirtualDisplayModule.h"
22 #endif
23
24 #include "ExynosDisplayDrmInterfaceModule.h"
25 #include "ExynosHWCDebug.h"
26 #include "ExynosHWCHelper.h"
27
28 #define SKIP_FRAME_COUNT 3
29
30 using namespace gs101;
31
ExynosExternalDisplayModule(uint32_t index,ExynosDevice * device,const std::string & displayName)32 ExynosExternalDisplayModule::ExynosExternalDisplayModule(uint32_t index, ExynosDevice* device,
33 const std::string& displayName)
34 : ExynosExternalDisplay(index, device, displayName) {
35 mColorManager = std::make_unique<ColorManager>(this, static_cast<ExynosDeviceModule*>(device));
36 }
37
~ExynosExternalDisplayModule()38 ExynosExternalDisplayModule::~ExynosExternalDisplayModule ()
39 {
40
41 }
42
validateWinConfigData()43 int32_t ExynosExternalDisplayModule::validateWinConfigData()
44 {
45 bool flagValidConfig = true;
46
47 if (ExynosDisplay::validateWinConfigData() != NO_ERROR)
48 flagValidConfig = false;
49
50 for (size_t i = 0; i < mDpuData.configs.size(); i++) {
51 struct exynos_win_config_data &config = mDpuData.configs[i];
52 if (config.state == config.WIN_STATE_BUFFER) {
53 bool configInvalid = false;
54 uint32_t mppType = config.assignedMPP->mPhysicalType;
55 if ((config.src.w != config.dst.w) ||
56 (config.src.h != config.dst.h)) {
57 if ((mppType == MPP_DPP_GF) ||
58 (mppType == MPP_DPP_VG) ||
59 (mppType == MPP_DPP_VGF)) {
60 DISPLAY_LOGE("WIN_CONFIG error: invalid assign id : %zu, s_w : %d, d_w : %d, s_h : %d, d_h : %d, mppType : %d",
61 i, config.src.w, config.dst.w, config.src.h, config.dst.h, mppType);
62 configInvalid = true;
63 }
64 }
65 if (configInvalid) {
66 config.state = config.WIN_STATE_DISABLED;
67 flagValidConfig = false;
68 }
69 }
70 }
71 if (flagValidConfig)
72 return NO_ERROR;
73 else
74 return -EINVAL;
75 }
76
getColorModes(uint32_t * outNumModes,int32_t * outModes)77 int32_t ExynosExternalDisplayModule::getColorModes(uint32_t* outNumModes, int32_t* outModes) {
78 return mColorManager->getColorModes(outNumModes, outModes);
79 }
80
setColorMode(int32_t mode)81 int32_t ExynosExternalDisplayModule::setColorMode(int32_t mode) {
82 return mColorManager->setColorMode(mode);
83 }
84
getRenderIntents(int32_t mode,uint32_t * outNumIntents,int32_t * outIntents)85 int32_t ExynosExternalDisplayModule::getRenderIntents(int32_t mode, uint32_t* outNumIntents,
86 int32_t* outIntents) {
87 return mColorManager->getRenderIntents(mode, outNumIntents, outIntents);
88 }
89
setColorModeWithRenderIntent(int32_t mode,int32_t intent)90 int32_t ExynosExternalDisplayModule::setColorModeWithRenderIntent(int32_t mode, int32_t intent) {
91 return mColorManager->setColorModeWithRenderIntent(mode, intent);
92 }
93
setColorTransform(const float * matrix,int32_t hint)94 int32_t ExynosExternalDisplayModule::setColorTransform(const float* matrix, int32_t hint) {
95 return mColorManager->setColorTransform(matrix, hint);
96 }
97
updateColorConversionInfo()98 int32_t ExynosExternalDisplayModule::updateColorConversionInfo() {
99 return mColorManager->updateColorConversionInfo();
100 }
101
resetColorMappingInfo(ExynosMPPSource * mppSrc)102 int32_t ExynosExternalDisplayModule::resetColorMappingInfo(ExynosMPPSource* mppSrc) {
103 return mColorManager->resetColorMappingInfo(mppSrc);
104 }
105
deliverWinConfigData()106 int ExynosExternalDisplayModule::deliverWinConfigData() {
107 int ret = 0;
108 ExynosDisplayDrmInterfaceModule* moduleDisplayInterface =
109 (ExynosDisplayDrmInterfaceModule*)(mDisplayInterface.get());
110 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
111
112 bool forceDisplayColorSetting = false;
113 if (!getDisplaySceneInfo().displaySettingDelivered || isForceColorUpdate())
114 forceDisplayColorSetting = true;
115
116 setForceColorUpdate(false);
117
118 if (displayColorInterface != nullptr) {
119 moduleDisplayInterface
120 ->setColorSettingChanged(getDisplaySceneInfo().needDisplayColorSetting(),
121 forceDisplayColorSetting);
122 }
123
124 ret = ExynosDisplay::deliverWinConfigData();
125
126 if (mDpuData.enable_readback && !mDpuData.readback_info.requested_from_service)
127 getDisplaySceneInfo().displaySettingDelivered = false;
128 else
129 getDisplaySceneInfo().displaySettingDelivered = true;
130
131 return ret;
132 }
133
invalidate()134 void ExynosExternalDisplayModule::invalidate() {
135 ExynosExternalDisplay::invalidate();
136
137 // invalidate() is invoked when we handle hotplug event for the external display.
138 // we need to call clear() here to ensure both layerDataMappingInfo and
139 // prev_layerDataMappingInfo are clearead in DisplaySceneInfo, otherwise old
140 // mappings preserved in prev_layerDataMappingInfo will be re-used after the
141 // next hotplug, causing color issues (see b/325549729).
142 getDisplaySceneInfo().clear();
143 }
144