xref: /aosp_15_r20/external/mesa3d/src/amd/vpelib/src/core/color_cs.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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