1 /* Copyright 2022 Advanced Micro Devices, Inc.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Authors: AMD
22 *
23 */
24
25 #include <string.h>
26 #include "common.h"
27 #include "vpe_priv.h"
28 #include "color.h"
29 #include "color_cs.h"
30 #include "hw_shared.h"
31 #include "conversion.h"
32
33 #define DIVIDER 10000
34 /* S2D13 value in [-3.999...3.999] */
35 #define S2D13_MIN (-39990)
36 #define S2D13_MAX (39990)
37
38 static void translate_blt_to_internal_adjustments(
39 const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust);
40
41 /* these values are defaults: 0 brightness, 1 contrast, 0 hue, 1 saturation*/
42 static struct vpe_color_adjust defaultClrAdjust = {0.0f, 1.0f, 0.0f, 1.0f};
43
vpe_color_set_adjustments_to_default(struct vpe_color_adjust * crt_vpe_adjusts)44 void vpe_color_set_adjustments_to_default(struct vpe_color_adjust *crt_vpe_adjusts)
45 {
46 *crt_vpe_adjusts = defaultClrAdjust;
47 }
48
vpe_color_different_color_adjusts(const struct vpe_color_adjust * new_vpe_adjusts,struct vpe_color_adjust * crt_vpe_adjsuts)49 bool vpe_color_different_color_adjusts(
50 const struct vpe_color_adjust *new_vpe_adjusts, struct vpe_color_adjust *crt_vpe_adjsuts)
51 {
52 if ((crt_vpe_adjsuts->brightness != new_vpe_adjusts->brightness) ||
53 (crt_vpe_adjsuts->saturation != new_vpe_adjusts->saturation) ||
54 (crt_vpe_adjsuts->hue != new_vpe_adjusts->hue) ||
55 (crt_vpe_adjsuts->contrast != new_vpe_adjusts->contrast)) {
56 return true;
57 }
58 return false;
59 }
60
61 /**
62 * Adjustment Min Max default step
63 *
64 * Input range
65 * Brightness -100.0f, 100.0f, 0.0f, 0.1f
66 * Contrast 0.0f, 2.0f, 1.0f, 0.01f
67 * Hue -180.0f, 180.0f, 0.0f, 1.0f
68 * Saturation 0.0f, 3.0f, 1.0f, 0.01f
69 *
70 * DAL range
71 * Brightness -100, 100, 0, 1
72 * Contrast 0, 200, 100, 1
73 * Hue -30, 30, 0, 1
74 * Saturation 0, 200, 100, 1
75 */
76
translate_blt_to_internal_adjustments(const struct vpe_color_adjust * blt_adjust,struct vpe_color_adjustments * dal_adjust)77 static void translate_blt_to_internal_adjustments(
78 const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust)
79 {
80 dal_adjust->brightness.current = (int)(10 * blt_adjust->brightness);
81 dal_adjust->brightness.min = -1000;
82 dal_adjust->brightness.max = 1000;
83
84 dal_adjust->contrast.current = (int)(100 * blt_adjust->contrast);
85 dal_adjust->contrast.min = 0;
86 dal_adjust->contrast.max = 200;
87
88 dal_adjust->saturation.current = (int)(100 * blt_adjust->saturation);
89 dal_adjust->saturation.min = 0;
90 dal_adjust->saturation.max = 300; // assuming input bigger range
91
92 dal_adjust->hue.current = (int)(blt_adjust->hue);
93 dal_adjust->hue.min = -180;
94 dal_adjust->hue.max = 180; // assuming input bigger range
95 }
96
get_hw_value_from_sw_value(int swVal,int swMin,int swMax,int hwMin,int hwMax)97 static int get_hw_value_from_sw_value(int swVal, int swMin, int swMax, int hwMin, int hwMax)
98 {
99 int dSW = swMax - swMin; /*software adjustment range size*/
100 int dHW = hwMax - hwMin; /*hardware adjustment range size*/
101 int hwVal; /*HW adjustment value*/
102
103 /* error case, I preserve the behavior from the predecessor
104 *getHwStepFromSwHwMinMaxValue (removed in Feb 2013)
105 *which was the FP version that only computed SCLF (i.e. dHW/dSW).
106 *it would return 0 in this case so
107 *hwVal = hwMin from the formula given in @brief
108 */
109 if (dSW == 0)
110 return hwMin;
111
112 /*it's quite often that ranges match,
113 *e.g. for overlay colors currently (Feb 2013)
114 *only brightness has a different
115 *HW range, and in this case no multiplication or division is needed,
116 *and if minimums match, no calculation at all
117 */
118
119 if (dSW != dHW) {
120 hwVal = (swVal - swMin) * dHW / dSW + hwMin;
121 } else {
122 hwVal = swVal;
123 if (swMin != hwMin)
124 hwVal += (hwMin - swMin);
125 }
126
127 return hwVal;
128 }
129
color_adjustments_to_fixed_point(const struct vpe_color_adjustments * vpe_adjust,bool icsc,struct fixed31_32 * grph_cont,struct fixed31_32 * grph_sat,struct fixed31_32 * grph_bright,struct fixed31_32 * sin_grph_hue,struct fixed31_32 * cos_grph_hue)130 static void color_adjustments_to_fixed_point(const struct vpe_color_adjustments *vpe_adjust,
131 bool icsc, // input csc or output csc
132 struct fixed31_32 *grph_cont, struct fixed31_32 *grph_sat, struct fixed31_32 *grph_bright,
133 struct fixed31_32 *sin_grph_hue, struct fixed31_32 *cos_grph_hue)
134 {
135 /* Hue adjustment could be negative. -45 ~ +45 */
136 struct fixed31_32 hue;
137 const int hw_hue_min = -30;
138 const int hw_hue_max = 30;
139 const int hw_sat_min = 0;
140 const int hw_sat_max = 300;
141 const int hw_contrast_min = 0;
142 const int hw_contrast_max = 200;
143 const int hw_bright_min = -1000;
144 const int hw_bright_max = 1000;
145 const int hw_bright_cap = 460;
146 int hw_val = 0;
147
148 if (icsc) {
149 hue = vpe_fixpt_mul(
150 vpe_fixpt_from_fraction(
151 get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
152 vpe_adjust->hue.max, hw_hue_min, hw_hue_max),
153 180),
154 vpe_fixpt_pi);
155
156 hw_val = get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
157 vpe_adjust->brightness.max, hw_bright_min, hw_bright_max);
158 if (hw_val > hw_bright_cap) { // to avoid image saturation, cap the brigthness to 0.5
159 hw_val = hw_bright_cap;
160 }
161
162 if (hw_val < -hw_bright_cap) {
163 hw_val = -hw_bright_cap;
164 }
165
166 *grph_bright = vpe_fixpt_from_fraction(hw_val, 1000);
167
168 *grph_cont = vpe_fixpt_from_fraction(
169 get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
170 vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
171 100);
172
173 *grph_sat = vpe_fixpt_from_fraction(
174 get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
175 vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
176 100);
177 } else {
178 hue = vpe_fixpt_mul(
179 vpe_fixpt_from_fraction(
180 get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
181 vpe_adjust->hue.max, hw_hue_min, hw_hue_max),
182 180),
183 vpe_fixpt_pi);
184
185 *grph_bright = vpe_fixpt_from_fraction(
186 get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
187 vpe_adjust->brightness.max, hw_bright_min, hw_bright_max),
188 100);
189
190 *grph_cont = vpe_fixpt_from_fraction(
191 get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
192 vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
193 100);
194
195 *grph_sat = vpe_fixpt_from_fraction(
196 get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
197 vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
198 100);
199 }
200
201 *sin_grph_hue = vpe_fixpt_sin(hue);
202 *cos_grph_hue = vpe_fixpt_cos(hue);
203 }
204
calculate_rgb_matrix_legacy(struct vpe_color_adjustments * vpe_adjust,struct fixed31_32 * rgb_matrix)205 static void calculate_rgb_matrix_legacy(
206 struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
207 {
208 const struct fixed31_32 k1 = vpe_fixpt_from_fraction(787400, 1000000);
209 const struct fixed31_32 k2 = vpe_fixpt_from_fraction(180428, 1000000);
210 const struct fixed31_32 k3 = vpe_fixpt_from_fraction(-715200, 1000000);
211 const struct fixed31_32 k4 = vpe_fixpt_from_fraction(606972, 1000000);
212 const struct fixed31_32 k5 = vpe_fixpt_from_fraction(-72200, 1000000);
213 const struct fixed31_32 k6 = vpe_fixpt_from_fraction(-787400, 1000000);
214 const struct fixed31_32 k7 = vpe_fixpt_from_fraction(-212600, 1000000);
215 const struct fixed31_32 k8 = vpe_fixpt_from_fraction(-147296, 1000000);
216 const struct fixed31_32 k9 = vpe_fixpt_from_fraction(284800, 1000000);
217 const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-95354, 1000000);
218 const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-72200, 1000000);
219 const struct fixed31_32 k12 = vpe_fixpt_from_fraction(242650, 1000000);
220 const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-212600, 1000000);
221 const struct fixed31_32 k14 = vpe_fixpt_from_fraction(927800, 1000000);
222 const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-715200, 1000000);
223 const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-842726, 1000000);
224 const struct fixed31_32 k17 = vpe_fixpt_from_fraction(927800, 1000000);
225 const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-85074, 1000000);
226
227 const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(2126, 10000);
228 const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(7152, 10000);
229 const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(722, 10000);
230
231 struct fixed31_32 grph_cont;
232 struct fixed31_32 grph_sat;
233 struct fixed31_32 grph_bright;
234 struct fixed31_32 sin_grph_hue;
235 struct fixed31_32 cos_grph_hue;
236
237 color_adjustments_to_fixed_point(
238 vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
239
240 /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
241 /* Sin(GrphHue) * K2))*/
242 /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
243 rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
244 /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
245 rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
246 /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
247 rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
248 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
249 /* K2))*/
250 rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
251
252 /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
253 /* Sin(GrphHue) * K4))*/
254 /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
255 rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
256 /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
257 rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
258 /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
259 rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
260 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
261 /* K4))*/
262 rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
263
264 /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
265 /* Sin(GrphHue) * K6))*/
266 /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
267 rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
268 /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
269 rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
270 /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
271 rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
272 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
273 /* K6))*/
274 rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
275
276 /* COEF_1_4 = GrphBright*/
277 rgb_matrix[3] = grph_bright;
278
279 /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
280 /* Sin(GrphHue) * K8))*/
281 /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
282 rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
283 /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
284 rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
285 /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
286 rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
287 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
288 /* K8))*/
289 rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
290
291 /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
292 /* Sin(GrphHue) * K10))*/
293 /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
294 rgb_matrix[5] =
295 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
296 /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
297 rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
298 /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
299 rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
300 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
301 /* K10))*/
302 rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
303
304 /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
305 /* Sin(GrphHue) * K12))*/
306 /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
307 rgb_matrix[6] =
308 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
309 /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
310 rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
311 /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
312 rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
313 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
314 /* K12))*/
315 rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
316
317 /* COEF_2_4 = GrphBright*/
318 rgb_matrix[7] = grph_bright;
319
320 /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
321 /* Sin(GrphHue) * K14))*/
322 /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
323 rgb_matrix[8] =
324 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
325 /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
326 rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
327 /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
328 rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
329 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
330 /* K14)) */
331 rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
332
333 /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
334 /* Sin(GrphHue) * K16)) */
335 /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
336 rgb_matrix[9] =
337 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
338 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
339 rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
340 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
341 rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
342 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
343 /* K16)) */
344 rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
345
346 /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
347 /* Sin(GrphHue) * K18)) */
348 /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
349 rgb_matrix[10] =
350 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
351 /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
352 rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
353 /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
354 rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
355 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
356 /* K18)) */
357 rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
358
359 /* COEF_3_4 = GrphBright */
360 rgb_matrix[11] = grph_bright;
361 }
362
calculate_rgb_limited_range_matrix_legacy(struct vpe_color_adjustments * vpe_adjust,struct fixed31_32 * rgb_matrix)363 static void calculate_rgb_limited_range_matrix_legacy(
364 struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
365 {
366 const struct fixed31_32 k1 = vpe_fixpt_from_fraction(701000, 1000000);
367 const struct fixed31_32 k2 = vpe_fixpt_from_fraction(236568, 1000000);
368 const struct fixed31_32 k3 = vpe_fixpt_from_fraction(-587000, 1000000);
369 const struct fixed31_32 k4 = vpe_fixpt_from_fraction(464432, 1000000);
370 const struct fixed31_32 k5 = vpe_fixpt_from_fraction(-114000, 1000000);
371 const struct fixed31_32 k6 = vpe_fixpt_from_fraction(-701000, 1000000);
372 const struct fixed31_32 k7 = vpe_fixpt_from_fraction(-299000, 1000000);
373 const struct fixed31_32 k8 = vpe_fixpt_from_fraction(-292569, 1000000);
374 const struct fixed31_32 k9 = vpe_fixpt_from_fraction(413000, 1000000);
375 const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-92482, 1000000);
376 const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-114000, 1000000);
377 const struct fixed31_32 k12 = vpe_fixpt_from_fraction(385051, 1000000);
378 const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-299000, 1000000);
379 const struct fixed31_32 k14 = vpe_fixpt_from_fraction(886000, 1000000);
380 const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-587000, 1000000);
381 const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-741914, 1000000);
382 const struct fixed31_32 k17 = vpe_fixpt_from_fraction(886000, 1000000);
383 const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-144086, 1000000);
384
385 const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(299, 1000);
386 const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(587, 1000);
387 const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(114, 1000);
388 /*onst struct fixed31_32 luma_scale =
389 vpe_fixpt_from_fraction(875855, 1000000);*/
390
391 const struct fixed31_32 rgb_scale = vpe_fixpt_from_fraction(85546875, 100000000);
392 const struct fixed31_32 rgb_bias = vpe_fixpt_from_fraction(625, 10000);
393
394 struct fixed31_32 grph_cont;
395 struct fixed31_32 grph_sat;
396 struct fixed31_32 grph_bright;
397 struct fixed31_32 sin_grph_hue;
398 struct fixed31_32 cos_grph_hue;
399
400 color_adjustments_to_fixed_point(
401 vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
402
403 /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
404 /* Sin(GrphHue) * K2))*/
405 /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
406 rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
407 /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
408 rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
409 /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
410 rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
411 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
412 /* K2))*/
413 rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
414 /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + */
415 /* Sin(GrphHue) * K2))*/
416 rgb_matrix[0] = vpe_fixpt_mul(rgb_scale, rgb_matrix[0]);
417
418 /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
419 /* Sin(GrphHue) * K4))*/
420 /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
421 rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
422 /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
423 rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
424 /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
425 rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
426 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
427 /* K4))*/
428 rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
429 /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K3 + */
430 /* Sin(GrphHue) * K4))*/
431 rgb_matrix[1] = vpe_fixpt_mul(rgb_scale, rgb_matrix[1]);
432
433 /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
434 /* Sin(GrphHue) * K6))*/
435 /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
436 rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
437 /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
438 rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
439 /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
440 rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
441 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
442 /* K6))*/
443 rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
444 /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K5 + */
445 /* Sin(GrphHue) * K6))*/
446 rgb_matrix[2] = vpe_fixpt_mul(rgb_scale, rgb_matrix[2]);
447
448 /* COEF_1_4 = RGBBias + RGBScale * GrphBright*/
449 rgb_matrix[3] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
450
451 /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
452 /* Sin(GrphHue) * K8))*/
453 /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
454 rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
455 /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
456 rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
457 /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
458 rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
459 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
460 /* K8))*/
461 rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
462 /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + */
463 /* Sin(GrphHue) * K8))*/
464 rgb_matrix[4] = vpe_fixpt_mul(rgb_scale, rgb_matrix[4]);
465
466 /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
467 /* Sin(GrphHue) * K10))*/
468 /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
469 rgb_matrix[5] =
470 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
471 /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
472 rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
473 /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
474 rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
475 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
476 /* K10))*/
477 rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
478 /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K9 + */
479 /* Sin(GrphHue) * K10))*/
480 rgb_matrix[5] = vpe_fixpt_mul(rgb_scale, rgb_matrix[5]);
481
482 /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
483 /* Sin(GrphHue) * K12))*/
484 /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
485 rgb_matrix[6] =
486 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
487 /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
488 rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
489 /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
490 rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
491 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
492 /* K12))*/
493 rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
494 /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K11 +*/
495 /* Sin(GrphHue) * K12)) */
496 rgb_matrix[6] = vpe_fixpt_mul(rgb_scale, rgb_matrix[6]);
497
498 /* COEF_2_4 = RGBBias + RGBScale * GrphBright*/
499 rgb_matrix[7] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
500
501 /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
502 /* Sin(GrphHue) * K14))*/
503 /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
504 rgb_matrix[8] =
505 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
506 /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
507 rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
508 /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
509 rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
510 /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
511 /* K14)) */
512 rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
513 /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
514 /* Sin(GrphHue) * K14))*/
515 rgb_matrix[8] = vpe_fixpt_mul(rgb_scale, rgb_matrix[8]);
516
517 /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
518 /* Sin(GrphHue) * K16)) */
519 /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
520 rgb_matrix[9] =
521 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
522 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
523 rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
524 /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
525 rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
526 /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
527 /* K16)) */
528 rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
529 /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K15 + */
530 /* Sin(GrphHue) * K16))*/
531 rgb_matrix[9] = vpe_fixpt_mul(rgb_scale, rgb_matrix[9]);
532
533 /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
534 /* Sin(GrphHue) * K18)) */
535 /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
536 rgb_matrix[10] =
537 vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
538 /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
539 rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
540 /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
541 rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
542 /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
543 /* K18)) */
544 rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
545 /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * */
546 /* K17 + Sin(GrphHue) * K18))*/
547 rgb_matrix[10] = vpe_fixpt_mul(rgb_scale, rgb_matrix[10]);
548
549 /* COEF_3_4 = RGBBias + RGBScale * GrphBright */
550 rgb_matrix[11] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
551 }
552
553 /* this function scales the matrix coefficients to fit a maximum integer bit range*/
vpe_scale_csc_matrix(struct fixed31_32 * matrix,unsigned int matrixLength,unsigned int maxIntegerBits,struct fixed31_32 * scalingFactor)554 static bool vpe_scale_csc_matrix(struct fixed31_32 *matrix, unsigned int matrixLength,
555 unsigned int maxIntegerBits, struct fixed31_32 *scalingFactor)
556 {
557 bool ret = false;
558 unsigned int index = 0;
559 long long maxIntegerVal = ((long long)1 << maxIntegerBits);
560 long long maxMatrixVal = 0;
561 unsigned int crtIntPart = 0;
562 struct fixed31_32 divisionFactor = vpe_fixpt_one;
563 long long crtValue = 0;
564 unsigned int posLargestBit = 0;
565 (*scalingFactor) = vpe_fixpt_one; // by default this is initialized to one
566 for (index = 0; index < matrixLength; index++) {
567 crtValue = matrix[index].value;
568 if (crtValue < 0) {
569 crtValue = -crtValue;
570 }
571 crtIntPart = (crtValue >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
572 if (maxMatrixVal < crtIntPart) {
573 maxMatrixVal = crtIntPart;
574 }
575 }
576 if ((maxMatrixVal >= maxIntegerVal) && (maxIntegerVal > 0)) {
577 for (index = 0; index < (FIXED31_32_BITS_PER_FRACTIONAL_PART - 1); index++) {
578 if (maxMatrixVal & ((long long)1 << index)) { // scan all the bits
579 posLargestBit = index;
580 }
581 }
582 divisionFactor.value = (long long)1 << (posLargestBit - maxIntegerBits + 1);
583 divisionFactor.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
584 (*scalingFactor) = divisionFactor;
585 for (index = 0; index < matrixLength; index++) {
586 matrix[index] = vpe_fixpt_div(matrix[index], divisionFactor);
587 }
588 ret = true;
589 }
590 return ret;
591 }
592
calculate_yuv_matrix(struct vpe_color_adjustments * vpe_adjust,enum color_space color_space,struct vpe_csc_matrix * input_cs,struct fixed31_32 * yuv_matrix)593 static void calculate_yuv_matrix(struct vpe_color_adjustments *vpe_adjust,
594 enum color_space color_space, struct vpe_csc_matrix *input_cs, struct fixed31_32 *yuv_matrix)
595 {
596 struct fixed31_32 initialMatrix[12];
597 uint32_t i = 0;
598 bool ovl = true; // if we ever have Output CSC case, we can reuse this function with ovl passed
599 // in as param
600 struct fixed31_32 grph_cont;
601 struct fixed31_32 grph_sat;
602 struct fixed31_32 grph_bright;
603 struct fixed31_32 sin_grph_hue;
604 struct fixed31_32 cos_grph_hue;
605 struct fixed31_32 multiplier;
606 struct fixed31_32 chromaOffset = vpe_fixpt_sub(vpe_fixpt_half, vpe_fixpt_one); // = -0.5
607 struct fixed31_32 lumaOffset = {
608 0x10101010LL}; //=16/255.0 This is an offset applied in the shader, not clear why
609 // to maintain compatibility this offset is still applied in VPE
610
611 /* The input YCbCr to RGB matrix is modified to embed the color adjustments as follows:
612 A = initial YCbCr to RGB conversion matrix
613 s = saturation , h = hue, c = contrast, b = brightness
614
615 | c*s*(a11*cos(h)+a13*sin(h)) a12*c c*s(a13*cos(h)-a11*sin(h)) |
616 |R| | | |Y+b |
617 |G|= | c*s*(a21*cos(h)+a23*sin(h)) a22*c c*s(a23*cos(h)-a21*sin(h)) | * |Cb-0.5|
618 |B| | | |Cr-0.5|
619 | c*s*(a31*cos(h)+a33*sin(h)) a32*c c*s(a33*cos(h)-a31*sin(h)) |
620 */
621
622 for (i = 0; i < 12; i++) {
623 initialMatrix[i] = vpe_convfix31_32(input_cs->regval[i]); // convert from s.2.13 to s.31.32
624 }
625 color_adjustments_to_fixed_point(
626 vpe_adjust, ovl, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
627 grph_bright = vpe_fixpt_sub(grph_bright, lumaOffset);
628
629 multiplier = vpe_fixpt_mul(grph_cont, grph_sat); // contSat
630
631 yuv_matrix[0] =
632 vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[0], cos_grph_hue),
633 vpe_fixpt_mul(initialMatrix[2], sin_grph_hue)));
634
635 yuv_matrix[1] = vpe_fixpt_mul(initialMatrix[1], grph_cont);
636
637 yuv_matrix[2] =
638 vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[2], cos_grph_hue),
639 vpe_fixpt_mul(initialMatrix[0], sin_grph_hue)));
640
641 yuv_matrix[3] = initialMatrix[3];
642
643 yuv_matrix[4] =
644 vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[4], cos_grph_hue),
645 vpe_fixpt_mul(initialMatrix[6], sin_grph_hue)));
646
647 yuv_matrix[5] = vpe_fixpt_mul(initialMatrix[5], grph_cont);
648
649 yuv_matrix[6] =
650 vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[6], cos_grph_hue),
651 vpe_fixpt_mul(initialMatrix[4], sin_grph_hue)));
652
653 yuv_matrix[7] = initialMatrix[7];
654
655 yuv_matrix[8] =
656 vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[8], cos_grph_hue),
657 vpe_fixpt_mul(initialMatrix[10], sin_grph_hue)));
658
659 yuv_matrix[9] = vpe_fixpt_mul(initialMatrix[9], grph_cont);
660
661 yuv_matrix[10] =
662 vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[10], cos_grph_hue),
663 vpe_fixpt_mul(initialMatrix[8], sin_grph_hue)));
664
665 yuv_matrix[3] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[1]),
666 vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[0]),
667 vpe_fixpt_mul(chromaOffset, yuv_matrix[2])));
668 yuv_matrix[7] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[5]),
669 vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[4]),
670 vpe_fixpt_mul(chromaOffset, yuv_matrix[6])));
671 yuv_matrix[11] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[9]),
672 vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[8]),
673 vpe_fixpt_mul(chromaOffset, yuv_matrix[10])));
674 }
675
convert_float_matrix(uint16_t * matrix,struct fixed31_32 * flt,uint32_t buffer_size)676 static void convert_float_matrix(uint16_t *matrix, struct fixed31_32 *flt, uint32_t buffer_size)
677 {
678 const struct fixed31_32 min_2_13 = vpe_fixpt_from_fraction(S2D13_MIN, DIVIDER);
679 const struct fixed31_32 max_2_13 = vpe_fixpt_from_fraction(S2D13_MAX, DIVIDER);
680 uint32_t i;
681 uint16_t temp_matrix[12];
682
683 for (i = 0; i < 12; i++)
684 temp_matrix[i] = 0;
685
686 for (i = 0; i < buffer_size; ++i) {
687 uint32_t reg_value =
688 conv_fixed_point_to_int_frac(vpe_fixpt_clamp(flt[i], min_2_13, max_2_13), 2, 13);
689
690 temp_matrix[i] = (uint16_t)reg_value;
691 }
692
693 matrix[4] = temp_matrix[0];
694 matrix[5] = temp_matrix[1];
695 matrix[6] = temp_matrix[2];
696 matrix[7] = temp_matrix[3];
697
698 matrix[8] = temp_matrix[4];
699 matrix[9] = temp_matrix[5];
700 matrix[10] = temp_matrix[6];
701 matrix[11] = temp_matrix[7];
702
703 matrix[0] = temp_matrix[8];
704 matrix[1] = temp_matrix[9];
705 matrix[2] = temp_matrix[10];
706 matrix[3] = temp_matrix[11];
707 }
708
vpe_color_calculate_input_cs(struct vpe_priv * vpe_priv,enum color_space in_cs,const struct vpe_color_adjust * vpe_blt_adjust,struct vpe_csc_matrix * input_cs,struct fixed31_32 * matrix_scaling_factor)709 bool vpe_color_calculate_input_cs(struct vpe_priv *vpe_priv, enum color_space in_cs,
710 const struct vpe_color_adjust *vpe_blt_adjust, struct vpe_csc_matrix *input_cs,
711 struct fixed31_32 *matrix_scaling_factor)
712 {
713 struct fixed31_32 fixed_csc_matrix[12];
714
715 struct vpe_color_adjustments vpe_adjust = {0};
716
717 if (vpe_blt_adjust) {
718 translate_blt_to_internal_adjustments(vpe_blt_adjust, &vpe_adjust);
719 }
720
721 switch (in_cs) {
722 case COLOR_SPACE_SRGB:
723 case COLOR_SPACE_2020_RGB_FULLRANGE:
724 case COLOR_SPACE_MSREF_SCRGB:
725 case COLOR_SPACE_SRGB_LIMITED:
726 case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
727 calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
728 break;
729
730 case COLOR_SPACE_YCBCR601:
731 case COLOR_SPACE_YCBCR709:
732 case COLOR_SPACE_YCBCR601_LIMITED:
733 case COLOR_SPACE_YCBCR709_LIMITED:
734 case COLOR_SPACE_2020_YCBCR:
735 calculate_yuv_matrix(&vpe_adjust, in_cs, input_cs, fixed_csc_matrix);
736 if (vpe_priv->scale_yuv_matrix) { // in case the coefficitents are too large
737 // they are scaled down to fit the n integer bits, m
738 // fractional bits (for now 2.19)
739 vpe_log("Scale down YUV -> RGB matrix");
740 vpe_scale_csc_matrix(fixed_csc_matrix, 12, 2, matrix_scaling_factor);
741 } else {
742 vpe_log("No scaling on the yuv -> rgb matrix");
743 }
744 break;
745
746 default:
747 calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
748 break;
749 }
750 conv_convert_float_matrix(&input_cs->regval[0], fixed_csc_matrix, 12);
751
752 return true;
753 }
754