1 /*
2 * Copyright (C) 2023 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 #include "ColorManager.h"
17
18 #include "BrightnessController.h"
19 #include "ExynosDisplay.h"
20 #include "ExynosHWCDebug.h"
21 #include "ExynosLayer.h"
22
23 namespace gs101 {
24
25 #define CLR_LOGD(msg, ...) \
26 ALOGD("[%s] %s: " msg, mExynosDisplay->mDisplayName.c_str(), __func__, ##__VA_ARGS__);
27
getColorModes(uint32_t * outNumModes,int32_t * outModes)28 int32_t ColorManager::getColorModes(uint32_t* outNumModes, int32_t* outModes) {
29 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
30 const DisplayType display = mExynosDisplay->getDcDisplayType();
31 const ColorModesMap colorModeMap = displayColorInterface == nullptr
32 ? ColorModesMap()
33 : displayColorInterface->ColorModesAndRenderIntents(display);
34 CLR_LOGD("size(%zu)", colorModeMap.size());
35 if (outNumModes == nullptr) {
36 DISPLAY_DRM_LOGE("%s: outNumModes is null", __func__);
37 return HWC2_ERROR_BAD_PARAMETER;
38 }
39 if (outModes == nullptr) {
40 *outNumModes = colorModeMap.size();
41 return HWC2_ERROR_NONE;
42 }
43 if (*outNumModes != colorModeMap.size()) {
44 DISPLAY_DRM_LOGE("%s: Invalid color mode size(%d), It should be(%zu)", __func__,
45 *outNumModes, colorModeMap.size());
46 return HWC2_ERROR_BAD_PARAMETER;
47 }
48
49 uint32_t index = 0;
50 for (const auto& it : colorModeMap) {
51 outModes[index] = static_cast<int32_t>(it.first);
52 CLR_LOGD("\tmode[%d] %d", index, outModes[index]);
53 index++;
54 }
55
56 return HWC2_ERROR_NONE;
57 }
58
setColorMode(int32_t mode)59 int32_t ColorManager::setColorMode(int32_t mode) {
60 CLR_LOGD("mode(%d)", mode);
61 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
62 const DisplayType display = mExynosDisplay->getDcDisplayType();
63 const ColorModesMap colorModeMap = displayColorInterface == nullptr
64 ? ColorModesMap()
65 : displayColorInterface->ColorModesAndRenderIntents(display);
66 hwc::ColorMode colorMode = static_cast<hwc::ColorMode>(mode);
67 const auto it = colorModeMap.find(colorMode);
68 if (it == colorModeMap.end()) {
69 DISPLAY_DRM_LOGE("%s: Invalid color mode(%d)", __func__, mode);
70 return HWC2_ERROR_BAD_PARAMETER;
71 }
72 mDisplaySceneInfo.setColorMode(colorMode);
73
74 if (mExynosDisplay->mColorMode != mode)
75 mExynosDisplay->setGeometryChanged(GEOMETRY_DISPLAY_COLOR_MODE_CHANGED);
76 mExynosDisplay->mColorMode = (android_color_mode_t)mode;
77
78 return HWC2_ERROR_NONE;
79 }
80
getRenderIntents(int32_t mode,uint32_t * outNumIntents,int32_t * outIntents)81 int32_t ColorManager::getRenderIntents(int32_t mode, uint32_t* outNumIntents, int32_t* outIntents) {
82 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
83 const DisplayType display = mExynosDisplay->getDcDisplayType();
84 const ColorModesMap colorModeMap = displayColorInterface == nullptr
85 ? ColorModesMap()
86 : displayColorInterface->ColorModesAndRenderIntents(display);
87 CLR_LOGD("size(%zu)", colorModeMap.size());
88 hwc::ColorMode colorMode = static_cast<hwc::ColorMode>(mode);
89 const auto it = colorModeMap.find(colorMode);
90 if (it == colorModeMap.end()) {
91 DISPLAY_DRM_LOGE("%s: Invalid color mode(%d)", __func__, mode);
92 return HWC2_ERROR_BAD_PARAMETER;
93 }
94 auto& renderIntents = it->second;
95 if (outIntents == NULL) {
96 *outNumIntents = renderIntents.size();
97 CLR_LOGD("\tintent num(%zu)", renderIntents.size());
98 return HWC2_ERROR_NONE;
99 }
100 if (*outNumIntents != renderIntents.size()) {
101 DISPLAY_DRM_LOGE("%s: Invalid intent size(%d), It should be(%zu)", __func__, *outNumIntents,
102 renderIntents.size());
103 return HWC2_ERROR_BAD_PARAMETER;
104 }
105
106 for (uint32_t i = 0; i < renderIntents.size(); i++) {
107 outIntents[i] = static_cast<uint32_t>(renderIntents[i]);
108 CLR_LOGD("\tintent[%d] %d", i, outIntents[i]);
109 }
110
111 return HWC2_ERROR_NONE;
112 }
113
setColorModeWithRenderIntent(int32_t mode,int32_t intent)114 int32_t ColorManager::setColorModeWithRenderIntent(int32_t mode, int32_t intent) {
115 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
116 const DisplayType display = mExynosDisplay->getDcDisplayType();
117 const ColorModesMap colorModeMap = displayColorInterface == nullptr
118 ? ColorModesMap()
119 : displayColorInterface->ColorModesAndRenderIntents(display);
120 hwc::ColorMode colorMode = static_cast<hwc::ColorMode>(mode);
121 hwc::RenderIntent renderIntent = static_cast<hwc::RenderIntent>(intent);
122
123 const auto mode_it = colorModeMap.find(colorMode);
124 if (mode_it == colorModeMap.end()) {
125 DISPLAY_DRM_LOGE("%s: Invalid color mode(%d)", __func__, mode);
126 return HWC2_ERROR_BAD_PARAMETER;
127 }
128
129 auto& renderIntents = mode_it->second;
130 auto intent_it = std::find(renderIntents.begin(), renderIntents.end(), renderIntent);
131 if (intent_it == renderIntents.end()) {
132 DISPLAY_DRM_LOGE("%s: Invalid render intent(%d)", __func__, intent);
133 return HWC2_ERROR_BAD_PARAMETER;
134 }
135
136 mDisplaySceneInfo.setColorMode(colorMode);
137 mDisplaySceneInfo.setRenderIntent(renderIntent);
138
139 if (mExynosDisplay->mColorMode != mode) {
140 CLR_LOGD("mode(%d), intent(%d)", mode, intent);
141 mExynosDisplay->setGeometryChanged(GEOMETRY_DISPLAY_COLOR_MODE_CHANGED);
142 }
143 mExynosDisplay->mColorMode = (android_color_mode_t)mode;
144
145 if (mExynosDisplay->mBrightnessController)
146 mExynosDisplay->mBrightnessController->updateColorRenderIntent(intent);
147
148 return HWC2_ERROR_NONE;
149 }
150
setColorTransform(const float * matrix,int32_t hint)151 int32_t ColorManager::setColorTransform(const float* matrix, int32_t hint) {
152 if ((hint < HAL_COLOR_TRANSFORM_IDENTITY) || (hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA))
153 return HWC2_ERROR_BAD_PARAMETER;
154 if (mExynosDisplay->mColorTransformHint != hint) {
155 ALOGI("[%s] %s:: %d -> %d", mExynosDisplay->mDisplayName.c_str(), __func__,
156 mExynosDisplay->mColorTransformHint, hint);
157 mExynosDisplay->setGeometryChanged(GEOMETRY_DISPLAY_COLOR_TRANSFORM_CHANGED);
158 }
159 mExynosDisplay->mColorTransformHint = hint;
160 #ifdef HWC_SUPPORT_COLOR_TRANSFORM
161 mDisplaySceneInfo.setColorTransform(matrix);
162 #endif
163 return HWC2_ERROR_NONE;
164 }
165
hasDppForLayer(ExynosMPPSource * layer)166 bool ColorManager::hasDppForLayer(ExynosMPPSource* layer) {
167 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
168 if (displayColorInterface == nullptr) {
169 return false;
170 }
171
172 if (getDisplaySceneInfo().layerDataMappingInfo.count(layer) == 0) return false;
173
174 uint32_t index = getDisplaySceneInfo().layerDataMappingInfo[layer].dppIdx;
175 const DisplayType display = mExynosDisplay->getDcDisplayType();
176 auto size = displayColorInterface->GetPipelineData(display)->Dpp().size();
177 if (index >= size) {
178 DISPLAY_DRM_LOGE("%s: invalid dpp index(%d) dpp size(%zu)", __func__, index, size);
179 return false;
180 }
181
182 return true;
183 }
184
getDppForLayer(ExynosMPPSource * layer)185 const ColorManager::GsInterfaceType::IDpp& ColorManager::getDppForLayer(ExynosMPPSource* layer) {
186 uint32_t index = getDisplaySceneInfo().layerDataMappingInfo[layer].dppIdx;
187 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
188 const DisplayType display = mExynosDisplay->getDcDisplayType();
189 return displayColorInterface->GetPipelineData(display)->Dpp()[index].get();
190 }
191
getDppIndexForLayer(ExynosMPPSource * layer)192 int32_t ColorManager::getDppIndexForLayer(ExynosMPPSource* layer) {
193 if (getDisplaySceneInfo().layerDataMappingInfo.count(layer) == 0) return -1;
194 uint32_t index = getDisplaySceneInfo().layerDataMappingInfo[layer].dppIdx;
195
196 return static_cast<int32_t>(index);
197 }
198
getDqe()199 const ColorManager::GsInterfaceType::IDqe& ColorManager::getDqe() {
200 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
201 return displayColorInterface->GetPipelineData(mExynosDisplay->getDcDisplayType())->Dqe();
202 }
203
setLayersColorData()204 int32_t ColorManager::setLayersColorData() {
205 int32_t ret = 0;
206 uint32_t layerNum = 0;
207
208 // TODO: b/212616164 remove dimSdrRatio
209 float dimSdrRatio = 1;
210 if (mExynosDisplay->mBrightnessController)
211 dimSdrRatio = mExynosDisplay->mBrightnessController->getSdrDimRatioForInstantHbm();
212
213 // for client target
214 {
215 LayerColorData& layerColorData = getDisplaySceneInfo().getLayerColorDataInstance(layerNum);
216
217 /* set layer data mapping info */
218 if ((ret = getDisplaySceneInfo()
219 .setLayerDataMappingInfo(&mExynosDisplay->mClientCompositionInfo,
220 layerNum)) != NO_ERROR) {
221 DISPLAY_DRM_LOGE("%s: setLayerDataMappingInfo fail for client composition", __func__);
222 return ret;
223 }
224
225 if ((ret = getDisplaySceneInfo()
226 .setClientCompositionColorData(mExynosDisplay->mClientCompositionInfo,
227 layerColorData, dimSdrRatio)) !=
228 NO_ERROR) {
229 DISPLAY_DRM_LOGE("%s: setClientCompositionColorData fail", __func__);
230 return ret;
231 }
232
233 layerColorData.is_client_target = true;
234 layerNum++;
235 }
236
237 for (uint32_t i = 0; i < mExynosDisplay->mLayers.size(); i++) {
238 ExynosLayer* layer = mExynosDisplay->mLayers[i];
239
240 if (layer->mCompositionType == HWC2_COMPOSITION_CLIENT) continue;
241
242 LayerColorData& layerColorData = getDisplaySceneInfo().getLayerColorDataInstance(layerNum);
243
244 /* set layer data mapping info */
245 if ((ret = getDisplaySceneInfo().setLayerDataMappingInfo(layer, layerNum)) != NO_ERROR) {
246 DISPLAY_DRM_LOGE("%s: layer[%d] setLayerDataMappingInfo fail, layerNum(%d)", __func__,
247 i, layerNum);
248 return ret;
249 }
250
251 if ((ret = getDisplaySceneInfo().setLayerColorData(layerColorData, layer, dimSdrRatio)) !=
252 NO_ERROR) {
253 DISPLAY_DRM_LOGE("%s: layer[%d] setLayerColorData fail, layerNum(%d)", __func__, i,
254 layerNum);
255 return ret;
256 }
257
258 layerColorData.is_client_target = false;
259 layerNum++;
260 }
261
262 /* Resize layer_data when layers were destroyed */
263 if (layerNum < getDisplaySceneInfo().displayScene.layer_data.size())
264 getDisplaySceneInfo().displayScene.layer_data.resize(layerNum);
265
266 return NO_ERROR;
267 }
268
updateColorConversionInfo()269 int32_t ColorManager::updateColorConversionInfo() {
270 int ret = 0;
271 GsInterfaceType* displayColorInterface = getDisplayColorInterface();
272 if (displayColorInterface == nullptr) {
273 return ret;
274 }
275
276 mExynosDisplay->updateBrightnessState();
277 /* clear flag and layer mapping info before setting */
278 getDisplaySceneInfo().reset();
279
280 if ((ret = setLayersColorData()) != NO_ERROR) return ret;
281
282 DisplayScene& displayScene = getDisplaySceneInfo().displayScene;
283 auto& brightnessController = mExynosDisplay->mBrightnessController;
284
285 displayScene.bm = displaycolor::BrightnessMode::BM_NOMINAL;
286 if (brightnessController && brightnessController->isGhbmOn())
287 displayScene.bm = displaycolor::BrightnessMode::BM_HBM;
288
289 displayScene.force_hdr = false;
290 displayScene.lhbm_on = false;
291 displayScene.hdr_layer_state = displaycolor::HdrLayerState::kHdrNone;
292 displayScene.dbv = 1000;
293
294 if (brightnessController) {
295 displayScene.force_hdr = brightnessController->isDimSdr();
296 displayScene.lhbm_on = brightnessController->isLhbmOn();
297 displayScene.hdr_layer_state = brightnessController->getHdrLayerState();
298 displayScene.dbv = brightnessController->getBrightnessLevel();
299 }
300
301 if (hwcCheckDebugMessages(eDebugColorManagement)) getDisplaySceneInfo().printDisplayScene();
302
303 const DisplayType display = mExynosDisplay->getDcDisplayType();
304 if ((ret = displayColorInterface->Update(display, getDisplaySceneInfo().displayScene)) != 0) {
305 DISPLAY_DRM_LOGE("Display Scene update error (%d)", ret);
306 return ret;
307 }
308
309 return ret;
310 }
311
resetColorMappingInfo(ExynosMPPSource * mppSrc)312 int32_t ColorManager::resetColorMappingInfo(ExynosMPPSource* mppSrc) {
313 if (getDisplaySceneInfo().layerDataMappingInfo.count(mppSrc) == 0) {
314 return -EINVAL;
315 }
316
317 getDisplaySceneInfo().layerDataMappingInfo[mppSrc].planeId =
318 DisplaySceneInfo::LayerMappingInfo::kPlaneIdNone;
319
320 return NO_ERROR;
321 }
322
323 } // namespace gs101
324