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 "DisplaySceneInfo.h"
17
18 #include "ExynosLayer.h"
19
getLayerColorDataInstance(uint32_t index)20 LayerColorData& DisplaySceneInfo::getLayerColorDataInstance(uint32_t index) {
21 size_t currentSize = displayScene.layer_data.size();
22 if (index >= currentSize) {
23 displayScene.layer_data.resize(currentSize + 1);
24 colorSettingChanged = true;
25 }
26 return displayScene.layer_data[index];
27 }
28
setLayerDataMappingInfo(ExynosMPPSource * layer,uint32_t index)29 int32_t DisplaySceneInfo::setLayerDataMappingInfo(ExynosMPPSource* layer, uint32_t index) {
30 if (layerDataMappingInfo.count(layer) != 0) {
31 ALOGE("layer mapping is already inserted (layer: %p, index:%d)", layer, index);
32 return -EINVAL;
33 }
34 // if assigned displaycolor dppIdx changes, do not reuse it (force plane color update).
35 uint32_t oldPlaneId = prev_layerDataMappingInfo.count(layer) != 0 &&
36 prev_layerDataMappingInfo[layer].dppIdx == index
37 ? prev_layerDataMappingInfo[layer].planeId
38 : LayerMappingInfo::kPlaneIdNone;
39 layerDataMappingInfo.insert(std::make_pair(layer, LayerMappingInfo{index, oldPlaneId}));
40
41 return NO_ERROR;
42 }
43
setLayerDataspace(LayerColorData & layerColorData,hwc::Dataspace dataspace)44 void DisplaySceneInfo::setLayerDataspace(LayerColorData& layerColorData, hwc::Dataspace dataspace) {
45 if (layerColorData.dataspace != dataspace) {
46 colorSettingChanged = true;
47 layerColorData.dataspace = dataspace;
48 }
49 }
50
disableLayerHdrStaticMetadata(LayerColorData & layerColorData)51 void DisplaySceneInfo::disableLayerHdrStaticMetadata(LayerColorData& layerColorData) {
52 if (layerColorData.static_metadata.is_valid) {
53 colorSettingChanged = true;
54 layerColorData.static_metadata.is_valid = false;
55 }
56 }
57
setLayerHdrStaticMetadata(LayerColorData & layerColorData,const ExynosHdrStaticInfo & exynosHdrStaticInfo)58 void DisplaySceneInfo::setLayerHdrStaticMetadata(LayerColorData& layerColorData,
59 const ExynosHdrStaticInfo& exynosHdrStaticInfo) {
60 if (layerColorData.static_metadata.is_valid == false) {
61 colorSettingChanged = true;
62 layerColorData.static_metadata.is_valid = true;
63 }
64
65 updateInfoSingleVal(layerColorData.static_metadata.display_red_primary_x,
66 exynosHdrStaticInfo.sType1.mR.x);
67 updateInfoSingleVal(layerColorData.static_metadata.display_red_primary_y,
68 exynosHdrStaticInfo.sType1.mR.y);
69 updateInfoSingleVal(layerColorData.static_metadata.display_green_primary_x,
70 exynosHdrStaticInfo.sType1.mG.x);
71 updateInfoSingleVal(layerColorData.static_metadata.display_green_primary_y,
72 exynosHdrStaticInfo.sType1.mG.y);
73 updateInfoSingleVal(layerColorData.static_metadata.display_blue_primary_x,
74 exynosHdrStaticInfo.sType1.mB.x);
75 updateInfoSingleVal(layerColorData.static_metadata.display_blue_primary_y,
76 exynosHdrStaticInfo.sType1.mB.y);
77 updateInfoSingleVal(layerColorData.static_metadata.white_point_x,
78 exynosHdrStaticInfo.sType1.mW.x);
79 updateInfoSingleVal(layerColorData.static_metadata.white_point_y,
80 exynosHdrStaticInfo.sType1.mW.y);
81 updateInfoSingleVal(layerColorData.static_metadata.max_luminance,
82 exynosHdrStaticInfo.sType1.mMaxDisplayLuminance);
83 updateInfoSingleVal(layerColorData.static_metadata.min_luminance,
84 exynosHdrStaticInfo.sType1.mMinDisplayLuminance);
85 updateInfoSingleVal(layerColorData.static_metadata.max_content_light_level,
86 exynosHdrStaticInfo.sType1.mMaxContentLightLevel);
87 updateInfoSingleVal(layerColorData.static_metadata.max_frame_average_light_level,
88 exynosHdrStaticInfo.sType1.mMaxFrameAverageLightLevel);
89 }
90
setLayerColorTransform(LayerColorData & layerColorData,std::array<float,TRANSFORM_MAT_SIZE> & matrix)91 void DisplaySceneInfo::setLayerColorTransform(LayerColorData& layerColorData,
92 std::array<float, TRANSFORM_MAT_SIZE>& matrix) {
93 updateInfoSingleVal(layerColorData.matrix, matrix);
94 }
95
disableLayerHdrDynamicMetadata(LayerColorData & layerColorData)96 void DisplaySceneInfo::disableLayerHdrDynamicMetadata(LayerColorData& layerColorData) {
97 if (layerColorData.dynamic_metadata.is_valid) {
98 colorSettingChanged = true;
99 layerColorData.dynamic_metadata.is_valid = false;
100 }
101 }
102
setLayerHdrDynamicMetadata(LayerColorData & layerColorData,const ExynosHdrDynamicInfo & exynosHdrDynamicInfo)103 void DisplaySceneInfo::setLayerHdrDynamicMetadata(
104 LayerColorData& layerColorData, const ExynosHdrDynamicInfo& exynosHdrDynamicInfo) {
105 if (layerColorData.dynamic_metadata.is_valid == false) {
106 colorSettingChanged = true;
107 layerColorData.dynamic_metadata.is_valid = true;
108 }
109 updateInfoSingleVal(layerColorData.dynamic_metadata.display_maximum_luminance,
110 exynosHdrDynamicInfo.data.targeted_system_display_maximum_luminance);
111
112 if (!std::equal(layerColorData.dynamic_metadata.maxscl.begin(),
113 layerColorData.dynamic_metadata.maxscl.end(),
114 exynosHdrDynamicInfo.data.maxscl[0])) {
115 colorSettingChanged = true;
116 for (uint32_t i = 0; i < layerColorData.dynamic_metadata.maxscl.size(); i++) {
117 layerColorData.dynamic_metadata.maxscl[i] = exynosHdrDynamicInfo.data.maxscl[0][i];
118 }
119 }
120 static constexpr uint32_t DYNAMIC_META_DAT_SIZE = 15;
121
122 updateInfoVectorVal(layerColorData.dynamic_metadata.maxrgb_percentages,
123 exynosHdrDynamicInfo.data.maxrgb_percentages[0], DYNAMIC_META_DAT_SIZE);
124 updateInfoVectorVal(layerColorData.dynamic_metadata.maxrgb_percentiles,
125 exynosHdrDynamicInfo.data.maxrgb_percentiles[0], DYNAMIC_META_DAT_SIZE);
126 updateInfoSingleVal(layerColorData.dynamic_metadata.tm_flag,
127 exynosHdrDynamicInfo.data.tone_mapping.tone_mapping_flag[0]);
128 updateInfoSingleVal(layerColorData.dynamic_metadata.tm_knee_x,
129 exynosHdrDynamicInfo.data.tone_mapping.knee_point_x[0]);
130 updateInfoSingleVal(layerColorData.dynamic_metadata.tm_knee_y,
131 exynosHdrDynamicInfo.data.tone_mapping.knee_point_y[0]);
132 updateInfoVectorVal(layerColorData.dynamic_metadata.bezier_curve_anchors,
133 exynosHdrDynamicInfo.data.tone_mapping.bezier_curve_anchors[0],
134 DYNAMIC_META_DAT_SIZE);
135 }
136
setClientCompositionColorData(const ExynosCompositionInfo & clientCompositionInfo,LayerColorData & layerData,float dimSdrRatio)137 int32_t DisplaySceneInfo::setClientCompositionColorData(
138 const ExynosCompositionInfo& clientCompositionInfo, LayerColorData& layerData,
139 float dimSdrRatio) {
140 layerData.dim_ratio = 1.0f;
141 setLayerDataspace(layerData, static_cast<hwc::Dataspace>(clientCompositionInfo.mDataSpace));
142 disableLayerHdrStaticMetadata(layerData);
143 disableLayerHdrDynamicMetadata(layerData);
144
145 if (dimSdrRatio != 1.0) {
146 std::array<float, TRANSFORM_MAT_SIZE> scaleMatrix = {
147 dimSdrRatio, 0.0, 0.0, 0.0,
148 0.0, dimSdrRatio, 0.0, 0.0,
149 0.0, 0.0, dimSdrRatio, 0.0,
150 0.0, 0.0, 0.0, 1.0
151 };
152 setLayerColorTransform(layerData, scaleMatrix);
153 } else {
154 static std::array<float, TRANSFORM_MAT_SIZE> defaultMatrix {
155 1.0, 0.0, 0.0, 0.0,
156 0.0, 1.0, 0.0, 0.0,
157 0.0, 0.0, 1.0, 0.0,
158 0.0, 0.0, 0.0, 1.0
159 };
160 setLayerColorTransform(layerData, defaultMatrix);
161 }
162
163 return NO_ERROR;
164 }
165
setLayerColorData(LayerColorData & layerData,ExynosLayer * layer,float dimSdrRatio)166 int32_t DisplaySceneInfo::setLayerColorData(LayerColorData& layerData, ExynosLayer* layer,
167 float dimSdrRatio) {
168 layerData.is_solid_color_layer = layer->isDimLayer();
169 layerData.solid_color.r = layer->mColor.r;
170 layerData.solid_color.g = layer->mColor.g;
171 layerData.solid_color.b = layer->mColor.b;
172 layerData.solid_color.a = layer->mColor.a;
173 layerData.dim_ratio = layer->mPreprocessedInfo.sdrDimRatio;
174 setLayerDataspace(layerData, static_cast<hwc::Dataspace>(layer->mDataSpace));
175 if (layer->mIsHdrLayer && layer->getMetaParcel() != nullptr) {
176 if (layer->getMetaParcel()->eType & VIDEO_INFO_TYPE_HDR_STATIC)
177 setLayerHdrStaticMetadata(layerData, layer->getMetaParcel()->sHdrStaticInfo);
178 else
179 disableLayerHdrStaticMetadata(layerData);
180
181 if (layer->getMetaParcel()->eType & VIDEO_INFO_TYPE_HDR_DYNAMIC)
182 setLayerHdrDynamicMetadata(layerData, layer->getMetaParcel()->sHdrDynamicInfo);
183 else
184 disableLayerHdrDynamicMetadata(layerData);
185 } else {
186 disableLayerHdrStaticMetadata(layerData);
187 disableLayerHdrDynamicMetadata(layerData);
188 }
189
190 static std::array<float, TRANSFORM_MAT_SIZE> defaultMatrix {
191 1.0, 0.0, 0.0, 0.0,
192 0.0, 1.0, 0.0, 0.0,
193 0.0, 0.0, 1.0, 0.0,
194 0.0, 0.0, 0.0, 1.0
195 };
196
197 if (dimSdrRatio == 1.0 || layer->mIsHdrLayer) {
198 if (layer->mLayerColorTransform.enable)
199 setLayerColorTransform(layerData, layer->mLayerColorTransform.mat);
200 else
201 setLayerColorTransform(layerData, defaultMatrix);
202 } else {
203 if (layer->mLayerColorTransform.enable) {
204 std::array<float, TRANSFORM_MAT_SIZE> scaleMatrix = layer->mLayerColorTransform.mat;
205
206 // scale coeffs
207 scaleMatrix[0] *= dimSdrRatio;
208 scaleMatrix[1] *= dimSdrRatio;
209 scaleMatrix[2] *= dimSdrRatio;
210 scaleMatrix[4] *= dimSdrRatio;
211 scaleMatrix[5] *= dimSdrRatio;
212 scaleMatrix[6] *= dimSdrRatio;
213 scaleMatrix[8] *= dimSdrRatio;
214 scaleMatrix[9] *= dimSdrRatio;
215 scaleMatrix[10] *= dimSdrRatio;
216
217 // scale offsets
218 scaleMatrix[12] *= dimSdrRatio;
219 scaleMatrix[13] *= dimSdrRatio;
220 scaleMatrix[14] *= dimSdrRatio;
221
222 setLayerColorTransform(layerData, scaleMatrix);
223 } else {
224 std::array<float, TRANSFORM_MAT_SIZE> scaleMatrix = {
225 dimSdrRatio, 0.0, 0.0, 0.0,
226 0.0, dimSdrRatio, 0.0, 0.0,
227 0.0, 0.0, dimSdrRatio, 0.0,
228 0.0, 0.0, 0.0, 1.0
229 };
230
231 setLayerColorTransform(layerData, scaleMatrix);
232 }
233 }
234
235 return NO_ERROR;
236 }
237
needDisplayColorSetting()238 bool DisplaySceneInfo::needDisplayColorSetting() {
239 /* TODO: Check if we can skip color setting */
240 /* For now, propage setting every frame */
241 return true;
242
243 if (colorSettingChanged) return true;
244 if (prev_layerDataMappingInfo != layerDataMappingInfo) return true;
245
246 return false;
247 }
248
printDisplayScene()249 void DisplaySceneInfo::printDisplayScene() {
250 ALOGD("======================= DisplayScene info ========================");
251 ALOGD("dpu_bit_depth: %d", static_cast<uint32_t>(displayScene.dpu_bit_depth));
252 ALOGD("color_mode: %d", static_cast<uint32_t>(displayScene.color_mode));
253 ALOGD("render_intent: %d", static_cast<uint32_t>(displayScene.render_intent));
254 ALOGD("matrix");
255 for (uint32_t i = 0; i < 16; (i += 4)) {
256 ALOGD("%f, %f, %f, %f", displayScene.matrix[i], displayScene.matrix[i + 1],
257 displayScene.matrix[i + 2], displayScene.matrix[i + 3]);
258 }
259 ALOGD("layer: %zu ++++++", displayScene.layer_data.size());
260 for (uint32_t i = 0; i < displayScene.layer_data.size(); i++) {
261 ALOGD("layer[%d] info", i);
262 printLayerColorData(displayScene.layer_data[i]);
263 }
264
265 ALOGD("layerDataMappingInfo: %zu ++++++", layerDataMappingInfo.size());
266 for (auto layer : layerDataMappingInfo) {
267 ALOGD("[layer: %p] [%d, %d]", layer.first, layer.second.dppIdx, layer.second.planeId);
268 }
269 }
270
printLayerColorData(const LayerColorData & layerData)271 void DisplaySceneInfo::printLayerColorData(const LayerColorData& layerData) {
272 ALOGD("dataspace: 0x%8x", static_cast<uint32_t>(layerData.dataspace));
273 ALOGD("matrix");
274 for (uint32_t i = 0; i < 16; (i += 4)) {
275 ALOGD("%f, %f, %f, %f", layerData.matrix[i], layerData.matrix[i + 1],
276 layerData.matrix[i + 2], layerData.matrix[i + 3]);
277 }
278 ALOGD("static_metadata.is_valid(%d)", layerData.static_metadata.is_valid);
279 if (layerData.static_metadata.is_valid) {
280 ALOGD("\tdisplay_red_primary(%d, %d)", layerData.static_metadata.display_red_primary_x,
281 layerData.static_metadata.display_red_primary_y);
282 ALOGD("\tdisplay_green_primary(%d, %d)", layerData.static_metadata.display_green_primary_x,
283 layerData.static_metadata.display_green_primary_y);
284 ALOGD("\tdisplay_blue_primary(%d, %d)", layerData.static_metadata.display_blue_primary_x,
285 layerData.static_metadata.display_blue_primary_y);
286 ALOGD("\twhite_point(%d, %d)", layerData.static_metadata.white_point_x,
287 layerData.static_metadata.white_point_y);
288 }
289 ALOGD("dynamic_metadata.is_valid(%d)", layerData.dynamic_metadata.is_valid);
290 if (layerData.dynamic_metadata.is_valid) {
291 ALOGD("\tdisplay_maximum_luminance: %d",
292 layerData.dynamic_metadata.display_maximum_luminance);
293 ALOGD("\tmaxscl(%d, %d, %d)", layerData.dynamic_metadata.maxscl[0],
294 layerData.dynamic_metadata.maxscl[1], layerData.dynamic_metadata.maxscl[2]);
295 ALOGD("\ttm_flag(%d)", layerData.dynamic_metadata.tm_flag);
296 ALOGD("\ttm_knee_x(%d)", layerData.dynamic_metadata.tm_knee_x);
297 ALOGD("\ttm_knee_y(%d)", layerData.dynamic_metadata.tm_knee_y);
298 }
299 }
300