2018-02-05 12:29:57 -07:00
|
|
|
|
/*
|
|
|
|
|
* Copyright 2016 Advanced Micro Devices, Inc.
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
|
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
|
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*
|
|
|
|
|
* Authors: AMD
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "dc.h"
|
|
|
|
|
#include "opp.h"
|
|
|
|
|
#include "color_gamma.h"
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
#define NUM_PTS_IN_REGION 16
|
|
|
|
|
#define NUM_REGIONS 32
|
2018-02-06 14:06:23 -07:00
|
|
|
|
#define MAX_HW_POINTS (NUM_PTS_IN_REGION*NUM_REGIONS)
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2];
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
static struct fixed31_32 pq_table[MAX_HW_POINTS + 2];
|
2018-02-13 12:18:43 -07:00
|
|
|
|
static struct fixed31_32 de_pq_table[MAX_HW_POINTS + 2];
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
static bool pq_initialized; /* = false; */
|
2018-02-06 14:06:23 -07:00
|
|
|
|
static bool de_pq_initialized; /* = false; */
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
/* one-time setup of X points */
|
|
|
|
|
void setup_x_points_distribution(void)
|
|
|
|
|
{
|
2018-04-18 09:37:53 -06:00
|
|
|
|
struct fixed31_32 region_size = dc_fixpt_from_int(128);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
int32_t segment;
|
|
|
|
|
uint32_t seg_offset;
|
|
|
|
|
uint32_t index;
|
|
|
|
|
struct fixed31_32 increment;
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
coordinates_x[MAX_HW_POINTS].x = region_size;
|
|
|
|
|
coordinates_x[MAX_HW_POINTS + 1].x = region_size;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
for (segment = 6; segment > (6 - NUM_REGIONS); segment--) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
region_size = dc_fixpt_div_int(region_size, 2);
|
|
|
|
|
increment = dc_fixpt_div_int(region_size,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
NUM_PTS_IN_REGION);
|
|
|
|
|
seg_offset = (segment + (NUM_REGIONS - 7)) * NUM_PTS_IN_REGION;
|
|
|
|
|
coordinates_x[seg_offset].x = region_size;
|
|
|
|
|
|
|
|
|
|
for (index = seg_offset + 1;
|
|
|
|
|
index < seg_offset + NUM_PTS_IN_REGION;
|
|
|
|
|
index++) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coordinates_x[index].x = dc_fixpt_add
|
2018-02-05 12:29:57 -07:00
|
|
|
|
(coordinates_x[index-1].x, increment);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
|
|
|
|
|
{
|
|
|
|
|
/* consts for PQ gamma formula. */
|
|
|
|
|
const struct fixed31_32 m1 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(159301758, 1000000000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
const struct fixed31_32 m2 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(7884375, 100000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
const struct fixed31_32 c1 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(8359375, 10000000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
const struct fixed31_32 c2 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(188515625, 10000000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
const struct fixed31_32 c3 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(186875, 10000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
struct fixed31_32 l_pow_m1;
|
|
|
|
|
struct fixed31_32 base;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(in_x, dc_fixpt_zero))
|
|
|
|
|
in_x = dc_fixpt_zero;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
l_pow_m1 = dc_fixpt_pow(in_x, m1);
|
|
|
|
|
base = dc_fixpt_div(
|
|
|
|
|
dc_fixpt_add(c1,
|
|
|
|
|
(dc_fixpt_mul(c2, l_pow_m1))),
|
|
|
|
|
dc_fixpt_add(dc_fixpt_one,
|
|
|
|
|
(dc_fixpt_mul(c3, l_pow_m1))));
|
|
|
|
|
*out_y = dc_fixpt_pow(base, m2);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
static void compute_de_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
|
|
|
|
|
{
|
|
|
|
|
/* consts for dePQ gamma formula. */
|
|
|
|
|
const struct fixed31_32 m1 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(159301758, 1000000000);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
const struct fixed31_32 m2 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(7884375, 100000);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
const struct fixed31_32 c1 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(8359375, 10000000);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
const struct fixed31_32 c2 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(188515625, 10000000);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
const struct fixed31_32 c3 =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(186875, 10000);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
struct fixed31_32 l_pow_m1;
|
|
|
|
|
struct fixed31_32 base, div;
|
|
|
|
|
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(in_x, dc_fixpt_zero))
|
|
|
|
|
in_x = dc_fixpt_zero;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
l_pow_m1 = dc_fixpt_pow(in_x,
|
|
|
|
|
dc_fixpt_div(dc_fixpt_one, m2));
|
|
|
|
|
base = dc_fixpt_sub(l_pow_m1, c1);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(base, dc_fixpt_zero))
|
|
|
|
|
base = dc_fixpt_zero;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
div = dc_fixpt_sub(c2, dc_fixpt_mul(c3, l_pow_m1));
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
*out_y = dc_fixpt_pow(dc_fixpt_div(base, div),
|
|
|
|
|
dc_fixpt_div(dc_fixpt_one, m1));
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
}
|
2018-05-10 11:37:35 -06:00
|
|
|
|
|
|
|
|
|
/*de gamma, none linear to linear*/
|
|
|
|
|
static void compute_hlg_oetf(struct fixed31_32 in_x, bool is_light0_12, struct fixed31_32 *out_y)
|
|
|
|
|
{
|
|
|
|
|
struct fixed31_32 a;
|
|
|
|
|
struct fixed31_32 b;
|
|
|
|
|
struct fixed31_32 c;
|
|
|
|
|
struct fixed31_32 threshold;
|
|
|
|
|
struct fixed31_32 reference_white_level;
|
|
|
|
|
|
|
|
|
|
a = dc_fixpt_from_fraction(17883277, 100000000);
|
|
|
|
|
if (is_light0_12) {
|
|
|
|
|
/*light 0-12*/
|
|
|
|
|
b = dc_fixpt_from_fraction(28466892, 100000000);
|
|
|
|
|
c = dc_fixpt_from_fraction(55991073, 100000000);
|
|
|
|
|
threshold = dc_fixpt_one;
|
|
|
|
|
reference_white_level = dc_fixpt_half;
|
|
|
|
|
} else {
|
|
|
|
|
/*light 0-1*/
|
|
|
|
|
b = dc_fixpt_from_fraction(2372241, 100000000);
|
|
|
|
|
c = dc_fixpt_add(dc_fixpt_one, dc_fixpt_from_fraction(429347, 100000000));
|
|
|
|
|
threshold = dc_fixpt_from_fraction(1, 12);
|
|
|
|
|
reference_white_level = dc_fixpt_pow(dc_fixpt_from_fraction(3, 1), dc_fixpt_half);
|
|
|
|
|
}
|
|
|
|
|
if (dc_fixpt_lt(threshold, in_x))
|
|
|
|
|
*out_y = dc_fixpt_add(c, dc_fixpt_mul(a, dc_fixpt_log(dc_fixpt_sub(in_x, b))));
|
|
|
|
|
else
|
|
|
|
|
*out_y = dc_fixpt_mul(dc_fixpt_pow(in_x, dc_fixpt_half), reference_white_level);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*re gamma, linear to none linear*/
|
|
|
|
|
static void compute_hlg_eotf(struct fixed31_32 in_x, bool is_light0_12, struct fixed31_32 *out_y)
|
|
|
|
|
{
|
|
|
|
|
struct fixed31_32 a;
|
|
|
|
|
struct fixed31_32 b;
|
|
|
|
|
struct fixed31_32 c;
|
|
|
|
|
struct fixed31_32 reference_white_level;
|
|
|
|
|
|
|
|
|
|
a = dc_fixpt_from_fraction(17883277, 100000000);
|
|
|
|
|
if (is_light0_12) {
|
|
|
|
|
/*light 0-12*/
|
|
|
|
|
b = dc_fixpt_from_fraction(28466892, 100000000);
|
|
|
|
|
c = dc_fixpt_from_fraction(55991073, 100000000);
|
|
|
|
|
reference_white_level = dc_fixpt_from_fraction(4, 1);
|
|
|
|
|
} else {
|
|
|
|
|
/*light 0-1*/
|
|
|
|
|
b = dc_fixpt_from_fraction(2372241, 100000000);
|
|
|
|
|
c = dc_fixpt_add(dc_fixpt_one, dc_fixpt_from_fraction(429347, 100000000));
|
|
|
|
|
reference_white_level = dc_fixpt_from_fraction(1, 3);
|
|
|
|
|
}
|
|
|
|
|
if (dc_fixpt_lt(dc_fixpt_half, in_x))
|
|
|
|
|
*out_y = dc_fixpt_add(dc_fixpt_exp(dc_fixpt_div(dc_fixpt_sub(in_x, c), a)), b);
|
|
|
|
|
else
|
|
|
|
|
*out_y = dc_fixpt_mul(dc_fixpt_pow(in_x, dc_fixpt_from_fraction(2, 1)), reference_white_level);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
/* one-time pre-compute PQ values - only for sdr_white_level 80 */
|
|
|
|
|
void precompute_pq(void)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
struct fixed31_32 x;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinates_x + 32;
|
|
|
|
|
struct fixed31_32 scaling_factor =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(80, 10000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
/* pow function has problems with arguments too small */
|
|
|
|
|
for (i = 0; i < 32; i++)
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pq_table[i] = dc_fixpt_zero;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
for (i = 32; i <= MAX_HW_POINTS; i++) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
x = dc_fixpt_mul(coord_x->x, scaling_factor);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
compute_pq(x, &pq_table[i]);
|
|
|
|
|
++coord_x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
/* one-time pre-compute dePQ values - only for max pixel value 125 FP16 */
|
|
|
|
|
void precompute_de_pq(void)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
struct fixed31_32 y;
|
2018-02-13 12:18:43 -07:00
|
|
|
|
uint32_t begin_index, end_index;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
struct fixed31_32 scaling_factor = dc_fixpt_from_int(125);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-02-13 12:18:43 -07:00
|
|
|
|
/* X points is 2^-25 to 2^7
|
|
|
|
|
* De-gamma X is 2^-12 to 2^0 – we are skipping first -12-(-25) = 13 regions
|
|
|
|
|
*/
|
|
|
|
|
begin_index = 13 * NUM_PTS_IN_REGION;
|
|
|
|
|
end_index = begin_index + 12 * NUM_PTS_IN_REGION;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-02-13 12:18:43 -07:00
|
|
|
|
for (i = 0; i <= begin_index; i++)
|
2018-04-18 09:37:53 -06:00
|
|
|
|
de_pq_table[i] = dc_fixpt_zero;
|
2018-02-13 12:18:43 -07:00
|
|
|
|
|
|
|
|
|
for (; i <= end_index; i++) {
|
|
|
|
|
compute_de_pq(coordinates_x[i].x, &y);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
de_pq_table[i] = dc_fixpt_mul(y, scaling_factor);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
}
|
2018-02-13 12:18:43 -07:00
|
|
|
|
|
|
|
|
|
for (; i <= MAX_HW_POINTS; i++)
|
|
|
|
|
de_pq_table[i] = de_pq_table[i-1];
|
2018-02-06 14:06:23 -07:00
|
|
|
|
}
|
2018-02-05 12:29:57 -07:00
|
|
|
|
struct dividers {
|
|
|
|
|
struct fixed31_32 divider1;
|
|
|
|
|
struct fixed31_32 divider2;
|
|
|
|
|
struct fixed31_32 divider3;
|
|
|
|
|
};
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
static void build_coefficients(struct gamma_coefficients *coefficients, bool is_2_4)
|
2018-02-05 12:29:57 -07:00
|
|
|
|
{
|
2018-04-13 14:06:24 -06:00
|
|
|
|
static const int32_t numerator01[] = { 31308, 180000};
|
|
|
|
|
static const int32_t numerator02[] = { 12920, 4500};
|
|
|
|
|
static const int32_t numerator03[] = { 55, 99};
|
|
|
|
|
static const int32_t numerator04[] = { 55, 99};
|
|
|
|
|
static const int32_t numerator05[] = { 2400, 2200};
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
uint32_t index = is_2_4 == true ? 0:1;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
do {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coefficients->a0[i] = dc_fixpt_from_fraction(
|
2018-02-06 14:06:23 -07:00
|
|
|
|
numerator01[index], 10000000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coefficients->a1[i] = dc_fixpt_from_fraction(
|
2018-02-06 14:06:23 -07:00
|
|
|
|
numerator02[index], 1000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coefficients->a2[i] = dc_fixpt_from_fraction(
|
2018-02-06 14:06:23 -07:00
|
|
|
|
numerator03[index], 1000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coefficients->a3[i] = dc_fixpt_from_fraction(
|
2018-02-06 14:06:23 -07:00
|
|
|
|
numerator04[index], 1000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coefficients->user_gamma[i] = dc_fixpt_from_fraction(
|
2018-02-06 14:06:23 -07:00
|
|
|
|
numerator05[index], 1000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
} while (i != ARRAY_SIZE(coefficients->a0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct fixed31_32 translate_from_linear_space(
|
|
|
|
|
struct fixed31_32 arg,
|
|
|
|
|
struct fixed31_32 a0,
|
|
|
|
|
struct fixed31_32 a1,
|
|
|
|
|
struct fixed31_32 a2,
|
|
|
|
|
struct fixed31_32 a3,
|
|
|
|
|
struct fixed31_32 gamma)
|
|
|
|
|
{
|
2018-04-18 09:37:53 -06:00
|
|
|
|
const struct fixed31_32 one = dc_fixpt_from_int(1);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(one, arg))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
return one;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_le(arg, dc_fixpt_neg(a0)))
|
|
|
|
|
return dc_fixpt_sub(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
a2,
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_mul(
|
|
|
|
|
dc_fixpt_add(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
one,
|
|
|
|
|
a3),
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_pow(
|
|
|
|
|
dc_fixpt_neg(arg),
|
|
|
|
|
dc_fixpt_recip(gamma))));
|
|
|
|
|
else if (dc_fixpt_le(a0, arg))
|
|
|
|
|
return dc_fixpt_sub(
|
|
|
|
|
dc_fixpt_mul(
|
|
|
|
|
dc_fixpt_add(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
one,
|
|
|
|
|
a3),
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_pow(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
arg,
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_recip(gamma))),
|
2018-02-05 12:29:57 -07:00
|
|
|
|
a2);
|
|
|
|
|
else
|
2018-04-18 09:37:53 -06:00
|
|
|
|
return dc_fixpt_mul(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
arg,
|
|
|
|
|
a1);
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-11 15:48:07 -06:00
|
|
|
|
static struct fixed31_32 calculate_gamma22(struct fixed31_32 arg)
|
|
|
|
|
{
|
|
|
|
|
struct fixed31_32 gamma = dc_fixpt_from_fraction(22, 10);
|
|
|
|
|
|
|
|
|
|
return translate_from_linear_space(arg,
|
|
|
|
|
dc_fixpt_zero,
|
|
|
|
|
dc_fixpt_zero,
|
|
|
|
|
dc_fixpt_zero,
|
|
|
|
|
dc_fixpt_zero,
|
|
|
|
|
gamma);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
static struct fixed31_32 translate_to_linear_space(
|
|
|
|
|
struct fixed31_32 arg,
|
|
|
|
|
struct fixed31_32 a0,
|
|
|
|
|
struct fixed31_32 a1,
|
|
|
|
|
struct fixed31_32 a2,
|
|
|
|
|
struct fixed31_32 a3,
|
|
|
|
|
struct fixed31_32 gamma)
|
|
|
|
|
{
|
|
|
|
|
struct fixed31_32 linear;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
a0 = dc_fixpt_mul(a0, a1);
|
|
|
|
|
if (dc_fixpt_le(arg, dc_fixpt_neg(a0)))
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
linear = dc_fixpt_neg(
|
|
|
|
|
dc_fixpt_pow(
|
|
|
|
|
dc_fixpt_div(
|
|
|
|
|
dc_fixpt_sub(a2, arg),
|
|
|
|
|
dc_fixpt_add(
|
|
|
|
|
dc_fixpt_one, a3)), gamma));
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
else if (dc_fixpt_le(dc_fixpt_neg(a0), arg) &&
|
|
|
|
|
dc_fixpt_le(arg, a0))
|
|
|
|
|
linear = dc_fixpt_div(arg, a1);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
else
|
2018-04-18 09:37:53 -06:00
|
|
|
|
linear = dc_fixpt_pow(
|
|
|
|
|
dc_fixpt_div(
|
|
|
|
|
dc_fixpt_add(a2, arg),
|
|
|
|
|
dc_fixpt_add(
|
|
|
|
|
dc_fixpt_one, a3)), gamma);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
return linear;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
static inline struct fixed31_32 translate_from_linear_space_ex(
|
|
|
|
|
struct fixed31_32 arg,
|
|
|
|
|
struct gamma_coefficients *coeff,
|
|
|
|
|
uint32_t color_index)
|
|
|
|
|
{
|
|
|
|
|
return translate_from_linear_space(
|
|
|
|
|
arg,
|
|
|
|
|
coeff->a0[color_index],
|
|
|
|
|
coeff->a1[color_index],
|
|
|
|
|
coeff->a2[color_index],
|
|
|
|
|
coeff->a3[color_index],
|
|
|
|
|
coeff->user_gamma[color_index]);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
static inline struct fixed31_32 translate_to_linear_space_ex(
|
|
|
|
|
struct fixed31_32 arg,
|
|
|
|
|
struct gamma_coefficients *coeff,
|
|
|
|
|
uint32_t color_index)
|
|
|
|
|
{
|
|
|
|
|
return translate_to_linear_space(
|
|
|
|
|
arg,
|
|
|
|
|
coeff->a0[color_index],
|
|
|
|
|
coeff->a1[color_index],
|
|
|
|
|
coeff->a2[color_index],
|
|
|
|
|
coeff->a3[color_index],
|
|
|
|
|
coeff->user_gamma[color_index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
static bool find_software_points(
|
|
|
|
|
const struct dc_gamma *ramp,
|
|
|
|
|
const struct gamma_pixel *axis_x,
|
|
|
|
|
struct fixed31_32 hw_point,
|
|
|
|
|
enum channel_name channel,
|
|
|
|
|
uint32_t *index_to_start,
|
|
|
|
|
uint32_t *index_left,
|
|
|
|
|
uint32_t *index_right,
|
|
|
|
|
enum hw_point_position *pos)
|
|
|
|
|
{
|
|
|
|
|
const uint32_t max_number = ramp->num_entries + 3;
|
|
|
|
|
|
|
|
|
|
struct fixed31_32 left, right;
|
|
|
|
|
|
|
|
|
|
uint32_t i = *index_to_start;
|
|
|
|
|
|
|
|
|
|
while (i < max_number) {
|
|
|
|
|
if (channel == CHANNEL_NAME_RED) {
|
|
|
|
|
left = axis_x[i].r;
|
|
|
|
|
|
|
|
|
|
if (i < max_number - 1)
|
|
|
|
|
right = axis_x[i + 1].r;
|
|
|
|
|
else
|
|
|
|
|
right = axis_x[max_number - 1].r;
|
|
|
|
|
} else if (channel == CHANNEL_NAME_GREEN) {
|
|
|
|
|
left = axis_x[i].g;
|
|
|
|
|
|
|
|
|
|
if (i < max_number - 1)
|
|
|
|
|
right = axis_x[i + 1].g;
|
|
|
|
|
else
|
|
|
|
|
right = axis_x[max_number - 1].g;
|
|
|
|
|
} else {
|
|
|
|
|
left = axis_x[i].b;
|
|
|
|
|
|
|
|
|
|
if (i < max_number - 1)
|
|
|
|
|
right = axis_x[i + 1].b;
|
|
|
|
|
else
|
|
|
|
|
right = axis_x[max_number - 1].b;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_le(left, hw_point) &&
|
|
|
|
|
dc_fixpt_le(hw_point, right)) {
|
2018-02-05 12:29:57 -07:00
|
|
|
|
*index_to_start = i;
|
|
|
|
|
*index_left = i;
|
|
|
|
|
|
|
|
|
|
if (i < max_number - 1)
|
|
|
|
|
*index_right = i + 1;
|
|
|
|
|
else
|
|
|
|
|
*index_right = max_number - 1;
|
|
|
|
|
|
|
|
|
|
*pos = HW_POINT_POSITION_MIDDLE;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} else if ((i == *index_to_start) &&
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_le(hw_point, left)) {
|
2018-02-05 12:29:57 -07:00
|
|
|
|
*index_to_start = i;
|
|
|
|
|
*index_left = i;
|
|
|
|
|
*index_right = i;
|
|
|
|
|
|
|
|
|
|
*pos = HW_POINT_POSITION_LEFT;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} else if ((i == max_number - 1) &&
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_le(right, hw_point)) {
|
2018-02-05 12:29:57 -07:00
|
|
|
|
*index_to_start = i;
|
|
|
|
|
*index_left = i;
|
|
|
|
|
*index_right = i;
|
|
|
|
|
|
|
|
|
|
*pos = HW_POINT_POSITION_RIGHT;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool build_custom_gamma_mapping_coefficients_worker(
|
|
|
|
|
const struct dc_gamma *ramp,
|
|
|
|
|
struct pixel_gamma_point *coeff,
|
|
|
|
|
const struct hw_x_point *coordinates_x,
|
|
|
|
|
const struct gamma_pixel *axis_x,
|
|
|
|
|
enum channel_name channel,
|
|
|
|
|
uint32_t number_of_points)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
|
|
|
|
|
while (i <= number_of_points) {
|
|
|
|
|
struct fixed31_32 coord_x;
|
|
|
|
|
|
|
|
|
|
uint32_t index_to_start = 0;
|
|
|
|
|
uint32_t index_left = 0;
|
|
|
|
|
uint32_t index_right = 0;
|
|
|
|
|
|
|
|
|
|
enum hw_point_position hw_pos;
|
|
|
|
|
|
|
|
|
|
struct gamma_point *point;
|
|
|
|
|
|
|
|
|
|
struct fixed31_32 left_pos;
|
|
|
|
|
struct fixed31_32 right_pos;
|
|
|
|
|
|
|
|
|
|
if (channel == CHANNEL_NAME_RED)
|
|
|
|
|
coord_x = coordinates_x[i].regamma_y_red;
|
|
|
|
|
else if (channel == CHANNEL_NAME_GREEN)
|
|
|
|
|
coord_x = coordinates_x[i].regamma_y_green;
|
|
|
|
|
else
|
|
|
|
|
coord_x = coordinates_x[i].regamma_y_blue;
|
|
|
|
|
|
|
|
|
|
if (!find_software_points(
|
|
|
|
|
ramp, axis_x, coord_x, channel,
|
|
|
|
|
&index_to_start, &index_left, &index_right, &hw_pos)) {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (index_left >= ramp->num_entries + 3) {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (index_right >= ramp->num_entries + 3) {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (channel == CHANNEL_NAME_RED) {
|
|
|
|
|
point = &coeff[i].r;
|
|
|
|
|
|
|
|
|
|
left_pos = axis_x[index_left].r;
|
|
|
|
|
right_pos = axis_x[index_right].r;
|
|
|
|
|
} else if (channel == CHANNEL_NAME_GREEN) {
|
|
|
|
|
point = &coeff[i].g;
|
|
|
|
|
|
|
|
|
|
left_pos = axis_x[index_left].g;
|
|
|
|
|
right_pos = axis_x[index_right].g;
|
|
|
|
|
} else {
|
|
|
|
|
point = &coeff[i].b;
|
|
|
|
|
|
|
|
|
|
left_pos = axis_x[index_left].b;
|
|
|
|
|
right_pos = axis_x[index_right].b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hw_pos == HW_POINT_POSITION_MIDDLE)
|
2018-04-18 09:37:53 -06:00
|
|
|
|
point->coeff = dc_fixpt_div(
|
|
|
|
|
dc_fixpt_sub(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
coord_x,
|
|
|
|
|
left_pos),
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_sub(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
right_pos,
|
|
|
|
|
left_pos));
|
|
|
|
|
else if (hw_pos == HW_POINT_POSITION_LEFT)
|
2018-04-18 09:37:53 -06:00
|
|
|
|
point->coeff = dc_fixpt_zero;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
else if (hw_pos == HW_POINT_POSITION_RIGHT)
|
2018-04-18 09:37:53 -06:00
|
|
|
|
point->coeff = dc_fixpt_from_int(2);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
else {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
point->left_index = index_left;
|
|
|
|
|
point->right_index = index_right;
|
|
|
|
|
point->pos = hw_pos;
|
|
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct fixed31_32 calculate_mapped_value(
|
|
|
|
|
struct pwl_float_data *rgb,
|
|
|
|
|
const struct pixel_gamma_point *coeff,
|
|
|
|
|
enum channel_name channel,
|
|
|
|
|
uint32_t max_index)
|
|
|
|
|
{
|
|
|
|
|
const struct gamma_point *point;
|
|
|
|
|
|
|
|
|
|
struct fixed31_32 result;
|
|
|
|
|
|
|
|
|
|
if (channel == CHANNEL_NAME_RED)
|
|
|
|
|
point = &coeff->r;
|
|
|
|
|
else if (channel == CHANNEL_NAME_GREEN)
|
|
|
|
|
point = &coeff->g;
|
|
|
|
|
else
|
|
|
|
|
point = &coeff->b;
|
|
|
|
|
|
|
|
|
|
if ((point->left_index < 0) || (point->left_index > max_index)) {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
2018-04-18 09:37:53 -06:00
|
|
|
|
return dc_fixpt_zero;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((point->right_index < 0) || (point->right_index > max_index)) {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
2018-04-18 09:37:53 -06:00
|
|
|
|
return dc_fixpt_zero;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (point->pos == HW_POINT_POSITION_MIDDLE)
|
|
|
|
|
if (channel == CHANNEL_NAME_RED)
|
2018-04-18 09:37:53 -06:00
|
|
|
|
result = dc_fixpt_add(
|
|
|
|
|
dc_fixpt_mul(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
point->coeff,
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_sub(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
rgb[point->right_index].r,
|
|
|
|
|
rgb[point->left_index].r)),
|
|
|
|
|
rgb[point->left_index].r);
|
|
|
|
|
else if (channel == CHANNEL_NAME_GREEN)
|
2018-04-18 09:37:53 -06:00
|
|
|
|
result = dc_fixpt_add(
|
|
|
|
|
dc_fixpt_mul(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
point->coeff,
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_sub(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
rgb[point->right_index].g,
|
|
|
|
|
rgb[point->left_index].g)),
|
|
|
|
|
rgb[point->left_index].g);
|
|
|
|
|
else
|
2018-04-18 09:37:53 -06:00
|
|
|
|
result = dc_fixpt_add(
|
|
|
|
|
dc_fixpt_mul(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
point->coeff,
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_sub(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
rgb[point->right_index].b,
|
|
|
|
|
rgb[point->left_index].b)),
|
|
|
|
|
rgb[point->left_index].b);
|
|
|
|
|
else if (point->pos == HW_POINT_POSITION_LEFT) {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
2018-04-18 09:37:53 -06:00
|
|
|
|
result = dc_fixpt_zero;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
} else {
|
|
|
|
|
BREAK_TO_DEBUGGER();
|
2018-04-18 09:37:53 -06:00
|
|
|
|
result = dc_fixpt_one;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
static void build_pq(struct pwl_float_data_ex *rgb_regamma,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct hw_x_point *coordinate_x,
|
|
|
|
|
uint32_t sdr_white_level)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i, start_index;
|
|
|
|
|
|
|
|
|
|
struct pwl_float_data_ex *rgb = rgb_regamma;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinate_x;
|
|
|
|
|
struct fixed31_32 x;
|
|
|
|
|
struct fixed31_32 output;
|
|
|
|
|
struct fixed31_32 scaling_factor =
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dc_fixpt_from_fraction(sdr_white_level, 10000);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
if (!pq_initialized && sdr_white_level == 80) {
|
|
|
|
|
precompute_pq();
|
|
|
|
|
pq_initialized = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO: start index is from segment 2^-24, skipping first segment
|
|
|
|
|
* due to x values too small for power calculations
|
|
|
|
|
*/
|
|
|
|
|
start_index = 32;
|
|
|
|
|
rgb += start_index;
|
|
|
|
|
coord_x += start_index;
|
|
|
|
|
|
|
|
|
|
for (i = start_index; i <= hw_points_num; i++) {
|
|
|
|
|
/* Multiply 0.008 as regamma is 0-1 and FP16 input is 0-125.
|
|
|
|
|
* FP 1.0 = 80nits
|
|
|
|
|
*/
|
|
|
|
|
if (sdr_white_level == 80) {
|
|
|
|
|
output = pq_table[i];
|
|
|
|
|
} else {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
x = dc_fixpt_mul(coord_x->x, scaling_factor);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
compute_pq(x, &output);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* should really not happen? */
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(output, dc_fixpt_zero))
|
|
|
|
|
output = dc_fixpt_zero;
|
|
|
|
|
else if (dc_fixpt_lt(dc_fixpt_one, output))
|
|
|
|
|
output = dc_fixpt_one;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
rgb->r = output;
|
|
|
|
|
rgb->g = output;
|
|
|
|
|
rgb->b = output;
|
|
|
|
|
|
|
|
|
|
++coord_x;
|
|
|
|
|
++rgb;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
static void build_de_pq(struct pwl_float_data_ex *de_pq,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct hw_x_point *coordinate_x)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
struct fixed31_32 output;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
struct fixed31_32 scaling_factor = dc_fixpt_from_int(125);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
if (!de_pq_initialized) {
|
|
|
|
|
precompute_de_pq();
|
|
|
|
|
de_pq_initialized = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i <= hw_points_num; i++) {
|
|
|
|
|
output = de_pq_table[i];
|
|
|
|
|
/* should really not happen? */
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(output, dc_fixpt_zero))
|
|
|
|
|
output = dc_fixpt_zero;
|
|
|
|
|
else if (dc_fixpt_lt(scaling_factor, output))
|
2018-02-06 14:06:23 -07:00
|
|
|
|
output = scaling_factor;
|
2018-02-13 12:18:43 -07:00
|
|
|
|
de_pq[i].r = output;
|
|
|
|
|
de_pq[i].g = output;
|
|
|
|
|
de_pq[i].b = output;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void build_regamma(struct pwl_float_data_ex *rgb_regamma,
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct hw_x_point *coordinate_x, bool is_2_4)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
struct gamma_coefficients coeff;
|
|
|
|
|
struct pwl_float_data_ex *rgb = rgb_regamma;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinate_x;
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
build_coefficients(&coeff, is_2_4);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
while (i != hw_points_num + 1) {
|
2018-02-06 14:06:23 -07:00
|
|
|
|
/*TODO use y vs r,g,b*/
|
2018-02-05 12:29:57 -07:00
|
|
|
|
rgb->r = translate_from_linear_space_ex(
|
|
|
|
|
coord_x->x, &coeff, 0);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
rgb->g = rgb->r;
|
|
|
|
|
rgb->b = rgb->r;
|
|
|
|
|
++coord_x;
|
|
|
|
|
++rgb;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-11 15:48:07 -06:00
|
|
|
|
static void hermite_spline_eetf(struct fixed31_32 input_x,
|
|
|
|
|
struct fixed31_32 max_display,
|
|
|
|
|
struct fixed31_32 min_display,
|
|
|
|
|
struct fixed31_32 max_content,
|
|
|
|
|
struct fixed31_32 *out_x)
|
|
|
|
|
{
|
|
|
|
|
struct fixed31_32 min_lum_pq;
|
|
|
|
|
struct fixed31_32 max_lum_pq;
|
|
|
|
|
struct fixed31_32 max_content_pq;
|
|
|
|
|
struct fixed31_32 ks;
|
|
|
|
|
struct fixed31_32 E1;
|
|
|
|
|
struct fixed31_32 E2;
|
|
|
|
|
struct fixed31_32 E3;
|
|
|
|
|
struct fixed31_32 t;
|
|
|
|
|
struct fixed31_32 t2;
|
|
|
|
|
struct fixed31_32 t3;
|
|
|
|
|
struct fixed31_32 two;
|
|
|
|
|
struct fixed31_32 three;
|
|
|
|
|
struct fixed31_32 temp1;
|
|
|
|
|
struct fixed31_32 temp2;
|
|
|
|
|
struct fixed31_32 a = dc_fixpt_from_fraction(15, 10);
|
|
|
|
|
struct fixed31_32 b = dc_fixpt_from_fraction(5, 10);
|
|
|
|
|
struct fixed31_32 epsilon = dc_fixpt_from_fraction(1, 1000000); // dc_fixpt_epsilon is a bit too small
|
|
|
|
|
|
|
|
|
|
if (dc_fixpt_eq(max_content, dc_fixpt_zero)) {
|
|
|
|
|
*out_x = dc_fixpt_zero;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
compute_pq(input_x, &E1);
|
|
|
|
|
compute_pq(dc_fixpt_div(min_display, max_content), &min_lum_pq);
|
|
|
|
|
compute_pq(dc_fixpt_div(max_display, max_content), &max_lum_pq);
|
|
|
|
|
compute_pq(dc_fixpt_one, &max_content_pq); // always 1? DAL2 code is weird
|
|
|
|
|
a = dc_fixpt_div(dc_fixpt_add(dc_fixpt_one, b), max_content_pq); // (1+b)/maxContent
|
|
|
|
|
ks = dc_fixpt_sub(dc_fixpt_mul(a, max_lum_pq), b); // a * max_lum_pq - b
|
|
|
|
|
|
|
|
|
|
if (dc_fixpt_lt(E1, ks))
|
|
|
|
|
E2 = E1;
|
|
|
|
|
else if (dc_fixpt_le(ks, E1) && dc_fixpt_le(E1, dc_fixpt_one)) {
|
|
|
|
|
if (dc_fixpt_lt(epsilon, dc_fixpt_sub(dc_fixpt_one, ks)))
|
|
|
|
|
// t = (E1 - ks) / (1 - ks)
|
|
|
|
|
t = dc_fixpt_div(dc_fixpt_sub(E1, ks),
|
|
|
|
|
dc_fixpt_sub(dc_fixpt_one, ks));
|
|
|
|
|
else
|
|
|
|
|
t = dc_fixpt_zero;
|
|
|
|
|
|
|
|
|
|
two = dc_fixpt_from_int(2);
|
|
|
|
|
three = dc_fixpt_from_int(3);
|
|
|
|
|
|
|
|
|
|
t2 = dc_fixpt_mul(t, t);
|
|
|
|
|
t3 = dc_fixpt_mul(t2, t);
|
|
|
|
|
temp1 = dc_fixpt_mul(two, t3);
|
|
|
|
|
temp2 = dc_fixpt_mul(three, t2);
|
|
|
|
|
|
|
|
|
|
// (2t^3 - 3t^2 + 1) * ks
|
|
|
|
|
E2 = dc_fixpt_mul(ks, dc_fixpt_add(dc_fixpt_one,
|
|
|
|
|
dc_fixpt_sub(temp1, temp2)));
|
|
|
|
|
|
|
|
|
|
// (-2t^3 + 3t^2) * max_lum_pq
|
|
|
|
|
E2 = dc_fixpt_add(E2, dc_fixpt_mul(max_lum_pq,
|
|
|
|
|
dc_fixpt_sub(temp2, temp1)));
|
|
|
|
|
|
|
|
|
|
temp1 = dc_fixpt_mul(two, t2);
|
|
|
|
|
temp2 = dc_fixpt_sub(dc_fixpt_one, ks);
|
|
|
|
|
|
|
|
|
|
// (t^3 - 2t^2 + t) * (1-ks)
|
|
|
|
|
E2 = dc_fixpt_add(E2, dc_fixpt_mul(temp2,
|
|
|
|
|
dc_fixpt_add(t, dc_fixpt_sub(t3, temp1))));
|
2018-10-02 06:44:04 -06:00
|
|
|
|
} else
|
|
|
|
|
E2 = dc_fixpt_one;
|
2018-09-11 15:48:07 -06:00
|
|
|
|
|
|
|
|
|
temp1 = dc_fixpt_sub(dc_fixpt_one, E2);
|
|
|
|
|
temp2 = dc_fixpt_mul(temp1, temp1);
|
|
|
|
|
temp2 = dc_fixpt_mul(temp2, temp2);
|
|
|
|
|
// temp2 = (1-E2)^4
|
|
|
|
|
|
|
|
|
|
E3 = dc_fixpt_add(E2, dc_fixpt_mul(min_lum_pq, temp2));
|
|
|
|
|
compute_de_pq(E3, out_x);
|
|
|
|
|
|
|
|
|
|
*out_x = dc_fixpt_div(*out_x, dc_fixpt_div(max_display, max_content));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool build_freesync_hdr(struct pwl_float_data_ex *rgb_regamma,
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct hw_x_point *coordinate_x,
|
|
|
|
|
const struct freesync_hdr_tf_params *fs_params)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
struct pwl_float_data_ex *rgb = rgb_regamma;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinate_x;
|
|
|
|
|
struct fixed31_32 scaledX = dc_fixpt_zero;
|
|
|
|
|
struct fixed31_32 scaledX1 = dc_fixpt_zero;
|
2018-11-20 10:17:45 -07:00
|
|
|
|
struct fixed31_32 max_display;
|
|
|
|
|
struct fixed31_32 min_display;
|
|
|
|
|
struct fixed31_32 max_content;
|
|
|
|
|
struct fixed31_32 min_content;
|
2018-09-11 15:48:07 -06:00
|
|
|
|
struct fixed31_32 clip = dc_fixpt_one;
|
|
|
|
|
struct fixed31_32 output;
|
|
|
|
|
bool use_eetf = false;
|
2018-10-09 10:59:46 -06:00
|
|
|
|
bool is_clipped = false;
|
2018-11-20 10:17:45 -07:00
|
|
|
|
struct fixed31_32 sdr_white_level;
|
2018-09-11 15:48:07 -06:00
|
|
|
|
|
|
|
|
|
if (fs_params == NULL || fs_params->max_content == 0 ||
|
|
|
|
|
fs_params->max_display == 0)
|
|
|
|
|
return false;
|
|
|
|
|
|
2018-11-20 10:17:45 -07:00
|
|
|
|
max_display = dc_fixpt_from_int(fs_params->max_display);
|
|
|
|
|
min_display = dc_fixpt_from_fraction(fs_params->min_display, 10000);
|
|
|
|
|
max_content = dc_fixpt_from_int(fs_params->max_content);
|
|
|
|
|
min_content = dc_fixpt_from_fraction(fs_params->min_content, 10000);
|
|
|
|
|
sdr_white_level = dc_fixpt_from_int(fs_params->sdr_white_level);
|
|
|
|
|
|
2018-09-11 15:48:07 -06:00
|
|
|
|
if (fs_params->min_display > 1000) // cap at 0.1 at the bottom
|
|
|
|
|
min_display = dc_fixpt_from_fraction(1, 10);
|
|
|
|
|
if (fs_params->max_display < 100) // cap at 100 at the top
|
|
|
|
|
max_display = dc_fixpt_from_int(100);
|
|
|
|
|
|
|
|
|
|
if (fs_params->min_content < fs_params->min_display)
|
|
|
|
|
use_eetf = true;
|
|
|
|
|
else
|
|
|
|
|
min_content = min_display;
|
|
|
|
|
|
|
|
|
|
if (fs_params->max_content > fs_params->max_display)
|
|
|
|
|
use_eetf = true;
|
|
|
|
|
else
|
|
|
|
|
max_content = max_display;
|
|
|
|
|
|
|
|
|
|
rgb += 32; // first 32 points have problems with fixed point, too small
|
|
|
|
|
coord_x += 32;
|
|
|
|
|
for (i = 32; i <= hw_points_num; i++) {
|
2018-10-09 10:59:46 -06:00
|
|
|
|
if (!is_clipped) {
|
|
|
|
|
if (use_eetf) {
|
|
|
|
|
/*max content is equal 1 */
|
|
|
|
|
scaledX1 = dc_fixpt_div(coord_x->x,
|
|
|
|
|
dc_fixpt_div(max_content, sdr_white_level));
|
|
|
|
|
hermite_spline_eetf(scaledX1, max_display, min_display,
|
|
|
|
|
max_content, &scaledX);
|
|
|
|
|
} else
|
|
|
|
|
scaledX = dc_fixpt_div(coord_x->x,
|
|
|
|
|
dc_fixpt_div(max_display, sdr_white_level));
|
|
|
|
|
|
|
|
|
|
if (dc_fixpt_lt(scaledX, clip)) {
|
|
|
|
|
if (dc_fixpt_lt(scaledX, dc_fixpt_zero))
|
|
|
|
|
output = dc_fixpt_zero;
|
|
|
|
|
else
|
|
|
|
|
output = calculate_gamma22(scaledX);
|
|
|
|
|
|
|
|
|
|
rgb->r = output;
|
|
|
|
|
rgb->g = output;
|
|
|
|
|
rgb->b = output;
|
|
|
|
|
} else {
|
|
|
|
|
is_clipped = true;
|
|
|
|
|
rgb->r = clip;
|
|
|
|
|
rgb->g = clip;
|
|
|
|
|
rgb->b = clip;
|
|
|
|
|
}
|
2018-09-11 15:48:07 -06:00
|
|
|
|
} else {
|
|
|
|
|
rgb->r = clip;
|
|
|
|
|
rgb->g = clip;
|
|
|
|
|
rgb->b = clip;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++coord_x;
|
|
|
|
|
++rgb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
static void build_degamma(struct pwl_float_data_ex *curve,
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct hw_x_point *coordinate_x, bool is_2_4)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
struct gamma_coefficients coeff;
|
2018-02-13 12:18:43 -07:00
|
|
|
|
uint32_t begin_index, end_index;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
build_coefficients(&coeff, is_2_4);
|
|
|
|
|
i = 0;
|
|
|
|
|
|
2018-02-13 12:18:43 -07:00
|
|
|
|
/* X points is 2^-25 to 2^7
|
|
|
|
|
* De-gamma X is 2^-12 to 2^0 – we are skipping first -12-(-25) = 13 regions
|
|
|
|
|
*/
|
|
|
|
|
begin_index = 13 * NUM_PTS_IN_REGION;
|
|
|
|
|
end_index = begin_index + 12 * NUM_PTS_IN_REGION;
|
|
|
|
|
|
|
|
|
|
while (i != begin_index) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
curve[i].r = dc_fixpt_zero;
|
|
|
|
|
curve[i].g = dc_fixpt_zero;
|
|
|
|
|
curve[i].b = dc_fixpt_zero;
|
2018-02-13 12:18:43 -07:00
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (i != end_index) {
|
|
|
|
|
curve[i].r = translate_to_linear_space_ex(
|
|
|
|
|
coordinate_x[i].x, &coeff, 0);
|
|
|
|
|
curve[i].g = curve[i].r;
|
|
|
|
|
curve[i].b = curve[i].r;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
2018-02-06 14:06:23 -07:00
|
|
|
|
while (i != hw_points_num + 1) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
curve[i].r = dc_fixpt_one;
|
|
|
|
|
curve[i].g = dc_fixpt_one;
|
|
|
|
|
curve[i].b = dc_fixpt_one;
|
2018-02-13 12:18:43 -07:00
|
|
|
|
i++;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-10 11:37:35 -06:00
|
|
|
|
static void build_hlg_degamma(struct pwl_float_data_ex *degamma,
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct hw_x_point *coordinate_x, bool is_light0_12)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
|
|
struct pwl_float_data_ex *rgb = degamma;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinate_x;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
while (i != hw_points_num + 1) {
|
|
|
|
|
compute_hlg_oetf(coord_x->x, is_light0_12, &rgb->r);
|
|
|
|
|
rgb->g = rgb->r;
|
|
|
|
|
rgb->b = rgb->r;
|
|
|
|
|
++coord_x;
|
|
|
|
|
++rgb;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void build_hlg_regamma(struct pwl_float_data_ex *regamma,
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct hw_x_point *coordinate_x, bool is_light0_12)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
|
|
struct pwl_float_data_ex *rgb = regamma;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinate_x;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
while (i != hw_points_num + 1) {
|
|
|
|
|
compute_hlg_eotf(coord_x->x, is_light0_12, &rgb->r);
|
|
|
|
|
rgb->g = rgb->r;
|
|
|
|
|
rgb->b = rgb->r;
|
|
|
|
|
++coord_x;
|
|
|
|
|
++rgb;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
static void scale_gamma(struct pwl_float_data *pwl_rgb,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
const struct dc_gamma *ramp,
|
|
|
|
|
struct dividers dividers)
|
|
|
|
|
{
|
2018-04-18 09:37:53 -06:00
|
|
|
|
const struct fixed31_32 max_driver = dc_fixpt_from_int(0xFFFF);
|
|
|
|
|
const struct fixed31_32 max_os = dc_fixpt_from_int(0xFF00);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
struct fixed31_32 scaler = max_os;
|
|
|
|
|
uint32_t i;
|
|
|
|
|
struct pwl_float_data *rgb = pwl_rgb;
|
|
|
|
|
struct pwl_float_data *rgb_last = rgb + ramp->num_entries - 1;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(max_os, ramp->entries.red[i]) ||
|
|
|
|
|
dc_fixpt_lt(max_os, ramp->entries.green[i]) ||
|
|
|
|
|
dc_fixpt_lt(max_os, ramp->entries.blue[i])) {
|
2018-02-05 12:29:57 -07:00
|
|
|
|
scaler = max_driver;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
} while (i != ramp->num_entries);
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_div(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
ramp->entries.red[i], scaler);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_div(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
ramp->entries.green[i], scaler);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_div(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
ramp->entries.blue[i], scaler);
|
|
|
|
|
|
|
|
|
|
++rgb;
|
|
|
|
|
++i;
|
|
|
|
|
} while (i != ramp->num_entries);
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_mul(rgb_last->r,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider1);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_mul(rgb_last->g,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider1);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_mul(rgb_last->b,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider1);
|
|
|
|
|
|
|
|
|
|
++rgb;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_mul(rgb_last->r,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider2);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_mul(rgb_last->g,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider2);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_mul(rgb_last->b,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider2);
|
|
|
|
|
|
|
|
|
|
++rgb;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_mul(rgb_last->r,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider3);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_mul(rgb_last->g,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider3);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_mul(rgb_last->b,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
dividers.divider3);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
static void scale_gamma_dx(struct pwl_float_data *pwl_rgb,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
const struct dc_gamma *ramp,
|
|
|
|
|
struct dividers dividers)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
2018-04-18 09:37:53 -06:00
|
|
|
|
struct fixed31_32 min = dc_fixpt_zero;
|
|
|
|
|
struct fixed31_32 max = dc_fixpt_one;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
struct fixed31_32 delta = dc_fixpt_zero;
|
|
|
|
|
struct fixed31_32 offset = dc_fixpt_zero;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
for (i = 0 ; i < ramp->num_entries; i++) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(ramp->entries.red[i], min))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
min = ramp->entries.red[i];
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(ramp->entries.green[i], min))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
min = ramp->entries.green[i];
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(ramp->entries.blue[i], min))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
min = ramp->entries.blue[i];
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(max, ramp->entries.red[i]))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
max = ramp->entries.red[i];
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(max, ramp->entries.green[i]))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
max = ramp->entries.green[i];
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(max, ramp->entries.blue[i]))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
max = ramp->entries.blue[i];
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
if (dc_fixpt_lt(min, dc_fixpt_zero))
|
|
|
|
|
delta = dc_fixpt_neg(min);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
offset = dc_fixpt_add(min, max);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
for (i = 0 ; i < ramp->num_entries; i++) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].r = dc_fixpt_div(
|
|
|
|
|
dc_fixpt_add(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
ramp->entries.red[i], delta), offset);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].g = dc_fixpt_div(
|
|
|
|
|
dc_fixpt_add(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
ramp->entries.green[i], delta), offset);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].b = dc_fixpt_div(
|
|
|
|
|
dc_fixpt_add(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
ramp->entries.blue[i], delta), offset);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].r = dc_fixpt_sub(dc_fixpt_mul_int(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].g = dc_fixpt_sub(dc_fixpt_mul_int(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].b = dc_fixpt_sub(dc_fixpt_mul_int(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b);
|
|
|
|
|
++i;
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].r = dc_fixpt_sub(dc_fixpt_mul_int(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
pwl_rgb[i-1].r, 2), pwl_rgb[i-2].r);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].g = dc_fixpt_sub(dc_fixpt_mul_int(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
pwl_rgb[i-1].g, 2), pwl_rgb[i-2].g);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
pwl_rgb[i].b = dc_fixpt_sub(dc_fixpt_mul_int(
|
2018-02-05 12:29:57 -07:00
|
|
|
|
pwl_rgb[i-1].b, 2), pwl_rgb[i-2].b);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
}
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
/* todo: all these scale_gamma functions are inherently the same but
|
|
|
|
|
* take different structures as params or different format for ramp
|
|
|
|
|
* values. We could probably implement it in a more generic fashion
|
|
|
|
|
*/
|
|
|
|
|
static void scale_user_regamma_ramp(struct pwl_float_data *pwl_rgb,
|
|
|
|
|
const struct regamma_ramp *ramp,
|
|
|
|
|
struct dividers dividers)
|
|
|
|
|
{
|
|
|
|
|
unsigned short max_driver = 0xFFFF;
|
|
|
|
|
unsigned short max_os = 0xFF00;
|
|
|
|
|
unsigned short scaler = max_os;
|
|
|
|
|
uint32_t i;
|
|
|
|
|
struct pwl_float_data *rgb = pwl_rgb;
|
|
|
|
|
struct pwl_float_data *rgb_last = rgb + GAMMA_RGB_256_ENTRIES - 1;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
do {
|
|
|
|
|
if (ramp->gamma[i] > max_os ||
|
|
|
|
|
ramp->gamma[i + 256] > max_os ||
|
|
|
|
|
ramp->gamma[i + 512] > max_os) {
|
|
|
|
|
scaler = max_driver;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
} while (i != GAMMA_RGB_256_ENTRIES);
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
do {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
ramp->gamma[i], scaler);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
ramp->gamma[i + 256], scaler);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
ramp->gamma[i + 512], scaler);
|
|
|
|
|
|
|
|
|
|
++rgb;
|
|
|
|
|
++i;
|
|
|
|
|
} while (i != GAMMA_RGB_256_ENTRIES);
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_mul(rgb_last->r,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider1);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_mul(rgb_last->g,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider1);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_mul(rgb_last->b,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider1);
|
|
|
|
|
|
|
|
|
|
++rgb;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_mul(rgb_last->r,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider2);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_mul(rgb_last->g,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider2);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_mul(rgb_last->b,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider2);
|
|
|
|
|
|
|
|
|
|
++rgb;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->r = dc_fixpt_mul(rgb_last->r,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider3);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->g = dc_fixpt_mul(rgb_last->g,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider3);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
rgb->b = dc_fixpt_mul(rgb_last->b,
|
2018-04-13 14:06:24 -06:00
|
|
|
|
dividers.divider3);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* RS3+ color transform DDI - 1D LUT adjustment is composed with regamma here
|
|
|
|
|
* Input is evenly distributed in the output color space as specified in
|
|
|
|
|
* SetTimings
|
|
|
|
|
*
|
|
|
|
|
* Interpolation details:
|
|
|
|
|
* 1D LUT has 4096 values which give curve correction in 0-1 float range
|
|
|
|
|
* for evenly spaced points in 0-1 range. lut1D[index] gives correction
|
|
|
|
|
* for index/4095.
|
|
|
|
|
* First we find index for which:
|
|
|
|
|
* index/4095 < regamma_y < (index+1)/4095 =>
|
|
|
|
|
* index < 4095*regamma_y < index + 1
|
|
|
|
|
* norm_y = 4095*regamma_y, and index is just truncating to nearest integer
|
|
|
|
|
* lut1 = lut1D[index], lut2 = lut1D[index+1]
|
|
|
|
|
*
|
2018-07-12 13:46:41 -06:00
|
|
|
|
* adjustedY is then linearly interpolating regamma Y between lut1 and lut2
|
|
|
|
|
*
|
|
|
|
|
* Custom degamma on Linux uses the same interpolation math, so is handled here
|
2018-02-05 12:29:57 -07:00
|
|
|
|
*/
|
|
|
|
|
static void apply_lut_1d(
|
|
|
|
|
const struct dc_gamma *ramp,
|
|
|
|
|
uint32_t num_hw_points,
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
int color = 0;
|
|
|
|
|
struct fixed31_32 *regamma_y;
|
|
|
|
|
struct fixed31_32 norm_y;
|
|
|
|
|
struct fixed31_32 lut1;
|
|
|
|
|
struct fixed31_32 lut2;
|
|
|
|
|
const int max_lut_index = 4095;
|
|
|
|
|
const struct fixed31_32 max_lut_index_f =
|
2018-04-18 11:54:24 -06:00
|
|
|
|
dc_fixpt_from_int(max_lut_index);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
int32_t index = 0, index_next = 0;
|
|
|
|
|
struct fixed31_32 index_f;
|
|
|
|
|
struct fixed31_32 delta_lut;
|
|
|
|
|
struct fixed31_32 delta_index;
|
|
|
|
|
|
2018-07-12 13:46:41 -06:00
|
|
|
|
if (ramp->type != GAMMA_CS_TFM_1D && ramp->type != GAMMA_CUSTOM)
|
2018-02-05 12:29:57 -07:00
|
|
|
|
return; // this is not expected
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < num_hw_points; i++) {
|
|
|
|
|
for (color = 0; color < 3; color++) {
|
|
|
|
|
if (color == 0)
|
|
|
|
|
regamma_y = &tf_pts->red[i];
|
|
|
|
|
else if (color == 1)
|
|
|
|
|
regamma_y = &tf_pts->green[i];
|
|
|
|
|
else
|
|
|
|
|
regamma_y = &tf_pts->blue[i];
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
norm_y = dc_fixpt_mul(max_lut_index_f,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
*regamma_y);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
index = dc_fixpt_floor(norm_y);
|
2018-04-18 11:54:24 -06:00
|
|
|
|
index_f = dc_fixpt_from_int(index);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
if (index < 0 || index > max_lut_index)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
index_next = (index == max_lut_index) ? index : index+1;
|
|
|
|
|
|
|
|
|
|
if (color == 0) {
|
|
|
|
|
lut1 = ramp->entries.red[index];
|
|
|
|
|
lut2 = ramp->entries.red[index_next];
|
|
|
|
|
} else if (color == 1) {
|
|
|
|
|
lut1 = ramp->entries.green[index];
|
|
|
|
|
lut2 = ramp->entries.green[index_next];
|
|
|
|
|
} else {
|
|
|
|
|
lut1 = ramp->entries.blue[index];
|
|
|
|
|
lut2 = ramp->entries.blue[index_next];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// we have everything now, so interpolate
|
2018-04-18 09:37:53 -06:00
|
|
|
|
delta_lut = dc_fixpt_sub(lut2, lut1);
|
|
|
|
|
delta_index = dc_fixpt_sub(norm_y, index_f);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
*regamma_y = dc_fixpt_add(lut1,
|
|
|
|
|
dc_fixpt_mul(delta_index, delta_lut));
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void build_evenly_distributed_points(
|
|
|
|
|
struct gamma_pixel *points,
|
|
|
|
|
uint32_t numberof_points,
|
|
|
|
|
struct dividers dividers)
|
|
|
|
|
{
|
|
|
|
|
struct gamma_pixel *p = points;
|
2018-09-20 13:03:27 -06:00
|
|
|
|
struct gamma_pixel *p_last;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
|
2018-09-20 13:03:27 -06:00
|
|
|
|
// This function should not gets called with 0 as a parameter
|
|
|
|
|
ASSERT(numberof_points > 0);
|
|
|
|
|
p_last = p + numberof_points - 1;
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
do {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
struct fixed31_32 value = dc_fixpt_from_fraction(i,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
numberof_points - 1);
|
|
|
|
|
|
|
|
|
|
p->r = value;
|
|
|
|
|
p->g = value;
|
|
|
|
|
p->b = value;
|
|
|
|
|
|
|
|
|
|
++p;
|
|
|
|
|
++i;
|
2018-09-20 13:03:27 -06:00
|
|
|
|
} while (i < numberof_points);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
p->r = dc_fixpt_div(p_last->r, dividers.divider1);
|
|
|
|
|
p->g = dc_fixpt_div(p_last->g, dividers.divider1);
|
|
|
|
|
p->b = dc_fixpt_div(p_last->b, dividers.divider1);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
++p;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
p->r = dc_fixpt_div(p_last->r, dividers.divider2);
|
|
|
|
|
p->g = dc_fixpt_div(p_last->g, dividers.divider2);
|
|
|
|
|
p->b = dc_fixpt_div(p_last->b, dividers.divider2);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
++p;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
p->r = dc_fixpt_div(p_last->r, dividers.divider3);
|
|
|
|
|
p->g = dc_fixpt_div(p_last->g, dividers.divider3);
|
|
|
|
|
p->b = dc_fixpt_div(p_last->b, dividers.divider3);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void copy_rgb_regamma_to_coordinates_x(
|
|
|
|
|
struct hw_x_point *coordinates_x,
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
const struct pwl_float_data_ex *rgb_ex)
|
|
|
|
|
{
|
|
|
|
|
struct hw_x_point *coords = coordinates_x;
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
const struct pwl_float_data_ex *rgb_regamma = rgb_ex;
|
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
while (i <= hw_points_num + 1) {
|
2018-02-05 12:29:57 -07:00
|
|
|
|
coords->regamma_y_red = rgb_regamma->r;
|
|
|
|
|
coords->regamma_y_green = rgb_regamma->g;
|
|
|
|
|
coords->regamma_y_blue = rgb_regamma->b;
|
|
|
|
|
|
|
|
|
|
++coords;
|
|
|
|
|
++rgb_regamma;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool calculate_interpolated_hardware_curve(
|
|
|
|
|
const struct dc_gamma *ramp,
|
|
|
|
|
struct pixel_gamma_point *coeff128,
|
|
|
|
|
struct pwl_float_data *rgb_user,
|
|
|
|
|
const struct hw_x_point *coordinates_x,
|
|
|
|
|
const struct gamma_pixel *axis_x,
|
|
|
|
|
uint32_t number_of_points,
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
const struct pixel_gamma_point *coeff = coeff128;
|
|
|
|
|
uint32_t max_entries = 3 - 1;
|
|
|
|
|
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
|
if (!build_custom_gamma_mapping_coefficients_worker(
|
|
|
|
|
ramp, coeff128, coordinates_x, axis_x, i,
|
|
|
|
|
number_of_points))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
max_entries += ramp->num_entries;
|
|
|
|
|
|
|
|
|
|
/* TODO: float point case */
|
|
|
|
|
|
|
|
|
|
while (i <= number_of_points) {
|
|
|
|
|
tf_pts->red[i] = calculate_mapped_value(
|
|
|
|
|
rgb_user, coeff, CHANNEL_NAME_RED, max_entries);
|
|
|
|
|
tf_pts->green[i] = calculate_mapped_value(
|
|
|
|
|
rgb_user, coeff, CHANNEL_NAME_GREEN, max_entries);
|
|
|
|
|
tf_pts->blue[i] = calculate_mapped_value(
|
|
|
|
|
rgb_user, coeff, CHANNEL_NAME_BLUE, max_entries);
|
|
|
|
|
|
|
|
|
|
++coeff;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
/* The "old" interpolation uses a complicated scheme to build an array of
|
|
|
|
|
* coefficients while also using an array of 0-255 normalized to 0-1
|
|
|
|
|
* Then there's another loop using both of the above + new scaled user ramp
|
|
|
|
|
* and we concatenate them. It also searches for points of interpolation and
|
|
|
|
|
* uses enums for positions.
|
|
|
|
|
*
|
|
|
|
|
* This function uses a different approach:
|
|
|
|
|
* user ramp is always applied on X with 0/255, 1/255, 2/255, ..., 255/255
|
|
|
|
|
* To find index for hwX , we notice the following:
|
|
|
|
|
* i/255 <= hwX < (i+1)/255 <=> i <= 255*hwX < i+1
|
|
|
|
|
* See apply_lut_1d which is the same principle, but on 4K entry 1D LUT
|
|
|
|
|
*
|
|
|
|
|
* Once the index is known, combined Y is simply:
|
|
|
|
|
* user_ramp(index) + (hwX-index/255)*(user_ramp(index+1) - user_ramp(index)
|
|
|
|
|
*
|
|
|
|
|
* We should switch to this method in all cases, it's simpler and faster
|
|
|
|
|
* ToDo one day - for now this only applies to ADL regamma to avoid regression
|
|
|
|
|
* for regular use cases (sRGB and PQ)
|
|
|
|
|
*/
|
|
|
|
|
static void interpolate_user_regamma(uint32_t hw_points_num,
|
|
|
|
|
struct pwl_float_data *rgb_user,
|
|
|
|
|
bool apply_degamma,
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
uint32_t color = 0;
|
|
|
|
|
int32_t index;
|
|
|
|
|
int32_t index_next;
|
|
|
|
|
struct fixed31_32 *tf_point;
|
|
|
|
|
struct fixed31_32 hw_x;
|
|
|
|
|
struct fixed31_32 norm_factor =
|
2018-04-18 11:54:24 -06:00
|
|
|
|
dc_fixpt_from_int(255);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
struct fixed31_32 norm_x;
|
|
|
|
|
struct fixed31_32 index_f;
|
|
|
|
|
struct fixed31_32 lut1;
|
|
|
|
|
struct fixed31_32 lut2;
|
|
|
|
|
struct fixed31_32 delta_lut;
|
|
|
|
|
struct fixed31_32 delta_index;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
/* fixed_pt library has problems handling too small values */
|
|
|
|
|
while (i != 32) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
tf_pts->red[i] = dc_fixpt_zero;
|
|
|
|
|
tf_pts->green[i] = dc_fixpt_zero;
|
|
|
|
|
tf_pts->blue[i] = dc_fixpt_zero;
|
2018-04-13 14:06:24 -06:00
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
while (i <= hw_points_num + 1) {
|
|
|
|
|
for (color = 0; color < 3; color++) {
|
|
|
|
|
if (color == 0)
|
|
|
|
|
tf_point = &tf_pts->red[i];
|
|
|
|
|
else if (color == 1)
|
|
|
|
|
tf_point = &tf_pts->green[i];
|
|
|
|
|
else
|
|
|
|
|
tf_point = &tf_pts->blue[i];
|
|
|
|
|
|
|
|
|
|
if (apply_degamma) {
|
|
|
|
|
if (color == 0)
|
|
|
|
|
hw_x = coordinates_x[i].regamma_y_red;
|
|
|
|
|
else if (color == 1)
|
|
|
|
|
hw_x = coordinates_x[i].regamma_y_green;
|
|
|
|
|
else
|
|
|
|
|
hw_x = coordinates_x[i].regamma_y_blue;
|
|
|
|
|
} else
|
|
|
|
|
hw_x = coordinates_x[i].x;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
norm_x = dc_fixpt_mul(norm_factor, hw_x);
|
|
|
|
|
index = dc_fixpt_floor(norm_x);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
if (index < 0 || index > 255)
|
|
|
|
|
continue;
|
|
|
|
|
|
2018-04-18 11:54:24 -06:00
|
|
|
|
index_f = dc_fixpt_from_int(index);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
index_next = (index == 255) ? index : index + 1;
|
|
|
|
|
|
|
|
|
|
if (color == 0) {
|
|
|
|
|
lut1 = rgb_user[index].r;
|
|
|
|
|
lut2 = rgb_user[index_next].r;
|
|
|
|
|
} else if (color == 1) {
|
|
|
|
|
lut1 = rgb_user[index].g;
|
|
|
|
|
lut2 = rgb_user[index_next].g;
|
|
|
|
|
} else {
|
|
|
|
|
lut1 = rgb_user[index].b;
|
|
|
|
|
lut2 = rgb_user[index_next].b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// we have everything now, so interpolate
|
2018-04-18 09:37:53 -06:00
|
|
|
|
delta_lut = dc_fixpt_sub(lut2, lut1);
|
|
|
|
|
delta_index = dc_fixpt_sub(norm_x, index_f);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
*tf_point = dc_fixpt_add(lut1,
|
|
|
|
|
dc_fixpt_mul(delta_index, delta_lut));
|
2018-04-13 14:06:24 -06:00
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
static void build_new_custom_resulted_curve(
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
|
|
while (i != hw_points_num + 1) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
tf_pts->red[i] = dc_fixpt_clamp(
|
|
|
|
|
tf_pts->red[i], dc_fixpt_zero,
|
|
|
|
|
dc_fixpt_one);
|
|
|
|
|
tf_pts->green[i] = dc_fixpt_clamp(
|
|
|
|
|
tf_pts->green[i], dc_fixpt_zero,
|
|
|
|
|
dc_fixpt_one);
|
|
|
|
|
tf_pts->blue[i] = dc_fixpt_clamp(
|
|
|
|
|
tf_pts->blue[i], dc_fixpt_zero,
|
|
|
|
|
dc_fixpt_one);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
static void apply_degamma_for_user_regamma(struct pwl_float_data_ex *rgb_regamma,
|
|
|
|
|
uint32_t hw_points_num)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
|
|
struct gamma_coefficients coeff;
|
|
|
|
|
struct pwl_float_data_ex *rgb = rgb_regamma;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinates_x;
|
|
|
|
|
|
|
|
|
|
build_coefficients(&coeff, true);
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
while (i != hw_points_num + 1) {
|
|
|
|
|
rgb->r = translate_from_linear_space_ex(
|
|
|
|
|
coord_x->x, &coeff, 0);
|
|
|
|
|
rgb->g = rgb->r;
|
|
|
|
|
rgb->b = rgb->r;
|
|
|
|
|
++coord_x;
|
|
|
|
|
++rgb;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
static bool map_regamma_hw_to_x_user(
|
|
|
|
|
const struct dc_gamma *ramp,
|
|
|
|
|
struct pixel_gamma_point *coeff128,
|
|
|
|
|
struct pwl_float_data *rgb_user,
|
|
|
|
|
struct hw_x_point *coords_x,
|
|
|
|
|
const struct gamma_pixel *axis_x,
|
|
|
|
|
const struct pwl_float_data_ex *rgb_regamma,
|
|
|
|
|
uint32_t hw_points_num,
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts,
|
|
|
|
|
bool mapUserRamp)
|
|
|
|
|
{
|
|
|
|
|
/* setup to spare calculated ideal regamma values */
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
struct hw_x_point *coords = coords_x;
|
|
|
|
|
const struct pwl_float_data_ex *regamma = rgb_regamma;
|
|
|
|
|
|
|
|
|
|
if (mapUserRamp) {
|
|
|
|
|
copy_rgb_regamma_to_coordinates_x(coords,
|
|
|
|
|
hw_points_num,
|
|
|
|
|
rgb_regamma);
|
|
|
|
|
|
|
|
|
|
calculate_interpolated_hardware_curve(
|
|
|
|
|
ramp, coeff128, rgb_user, coords, axis_x,
|
|
|
|
|
hw_points_num, tf_pts);
|
|
|
|
|
} else {
|
|
|
|
|
/* just copy current rgb_regamma into tf_pts */
|
|
|
|
|
while (i <= hw_points_num) {
|
|
|
|
|
tf_pts->red[i] = regamma->r;
|
|
|
|
|
tf_pts->green[i] = regamma->g;
|
|
|
|
|
tf_pts->blue[i] = regamma->b;
|
|
|
|
|
|
|
|
|
|
++regamma;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
/* this should be named differently, all it does is clamp to 0-1 */
|
2018-02-05 12:29:57 -07:00
|
|
|
|
build_new_custom_resulted_curve(hw_points_num, tf_pts);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
#define _EXTRA_POINTS 3
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
|
2018-09-11 15:48:07 -06:00
|
|
|
|
const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed,
|
|
|
|
|
const struct freesync_hdr_tf_params *fs_params)
|
2018-02-05 12:29:57 -07:00
|
|
|
|
{
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
|
|
|
|
|
struct dividers dividers;
|
|
|
|
|
|
|
|
|
|
struct pwl_float_data *rgb_user = NULL;
|
|
|
|
|
struct pwl_float_data_ex *rgb_regamma = NULL;
|
|
|
|
|
struct gamma_pixel *axix_x = NULL;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
struct pixel_gamma_point *coeff = NULL;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (output_tf->type == TF_TYPE_BYPASS)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/* we can use hardcoded curve for plain SRGB TF */
|
2018-07-18 14:10:10 -06:00
|
|
|
|
if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true &&
|
2018-02-05 12:29:57 -07:00
|
|
|
|
output_tf->tf == TRANSFER_FUNCTION_SRGB &&
|
2018-09-24 14:30:20 -06:00
|
|
|
|
(ramp->is_identity || (!mapUserRamp && ramp->type == GAMMA_RGB_256)))
|
2018-02-05 12:29:57 -07:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
|
|
|
|
|
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_user),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
if (!rgb_user)
|
|
|
|
|
goto rgb_user_alloc_fail;
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_regamma),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
if (!rgb_regamma)
|
|
|
|
|
goto rgb_regamma_alloc_fail;
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
axix_x = kvcalloc(ramp->num_entries + 3, sizeof(*axix_x),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
if (!axix_x)
|
|
|
|
|
goto axix_x_alloc_fail;
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
|
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!coeff)
|
|
|
|
|
goto coeff_alloc_fail;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dividers.divider1 = dc_fixpt_from_fraction(3, 2);
|
|
|
|
|
dividers.divider2 = dc_fixpt_from_int(2);
|
|
|
|
|
dividers.divider3 = dc_fixpt_from_fraction(5, 2);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
|
|
|
|
|
tf = output_tf->tf;
|
|
|
|
|
|
|
|
|
|
build_evenly_distributed_points(
|
|
|
|
|
axix_x,
|
|
|
|
|
ramp->num_entries,
|
|
|
|
|
dividers);
|
|
|
|
|
|
|
|
|
|
if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
|
|
|
|
|
scale_gamma(rgb_user, ramp, dividers);
|
|
|
|
|
else if (ramp->type == GAMMA_RGB_FLOAT_1024)
|
|
|
|
|
scale_gamma_dx(rgb_user, ramp, dividers);
|
|
|
|
|
|
|
|
|
|
if (tf == TRANSFER_FUNCTION_PQ) {
|
|
|
|
|
tf_pts->end_exponent = 7;
|
|
|
|
|
tf_pts->x_point_at_y1_red = 125;
|
|
|
|
|
tf_pts->x_point_at_y1_green = 125;
|
|
|
|
|
tf_pts->x_point_at_y1_blue = 125;
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
build_pq(rgb_regamma,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x,
|
|
|
|
|
output_tf->sdr_ref_white_level);
|
2018-09-11 15:48:07 -06:00
|
|
|
|
} else if (tf == TRANSFER_FUNCTION_GAMMA22 &&
|
|
|
|
|
fs_params != NULL) {
|
|
|
|
|
build_freesync_hdr(rgb_regamma,
|
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x,
|
|
|
|
|
fs_params);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
} else {
|
|
|
|
|
tf_pts->end_exponent = 0;
|
|
|
|
|
tf_pts->x_point_at_y1_red = 1;
|
|
|
|
|
tf_pts->x_point_at_y1_green = 1;
|
|
|
|
|
tf_pts->x_point_at_y1_blue = 1;
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
build_regamma(rgb_regamma,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
MAX_HW_POINTS,
|
2018-02-06 14:06:23 -07:00
|
|
|
|
coordinates_x, tf == TRANSFER_FUNCTION_SRGB ? true:false);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
2018-02-06 14:06:23 -07:00
|
|
|
|
map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
coordinates_x, axix_x, rgb_regamma,
|
|
|
|
|
MAX_HW_POINTS, tf_pts,
|
|
|
|
|
(mapUserRamp || ramp->type != GAMMA_RGB_256) &&
|
|
|
|
|
ramp->type != GAMMA_CS_TFM_1D);
|
|
|
|
|
|
|
|
|
|
if (ramp->type == GAMMA_CS_TFM_1D)
|
|
|
|
|
apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
|
|
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(coeff);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
coeff_alloc_fail:
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(axix_x);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
axix_x_alloc_fail:
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(rgb_regamma);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
rgb_regamma_alloc_fail:
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(rgb_user);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
rgb_user_alloc_fail:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 14:06:24 -06:00
|
|
|
|
bool calculate_user_regamma_coeff(struct dc_transfer_func *output_tf,
|
|
|
|
|
const struct regamma_lut *regamma)
|
|
|
|
|
{
|
|
|
|
|
struct gamma_coefficients coeff;
|
|
|
|
|
const struct hw_x_point *coord_x = coordinates_x;
|
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
|
|
|
|
|
do {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coeff.a0[i] = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
regamma->coeff.A0[i], 10000000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coeff.a1[i] = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
regamma->coeff.A1[i], 1000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coeff.a2[i] = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
regamma->coeff.A2[i], 1000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coeff.a3[i] = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
regamma->coeff.A3[i], 1000);
|
2018-04-18 09:37:53 -06:00
|
|
|
|
coeff.user_gamma[i] = dc_fixpt_from_fraction(
|
2018-04-13 14:06:24 -06:00
|
|
|
|
regamma->coeff.gamma[i], 1000);
|
|
|
|
|
|
|
|
|
|
++i;
|
|
|
|
|
} while (i != 3);
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
/* fixed_pt library has problems handling too small values */
|
|
|
|
|
while (i != 32) {
|
2018-04-18 09:37:53 -06:00
|
|
|
|
output_tf->tf_pts.red[i] = dc_fixpt_zero;
|
|
|
|
|
output_tf->tf_pts.green[i] = dc_fixpt_zero;
|
|
|
|
|
output_tf->tf_pts.blue[i] = dc_fixpt_zero;
|
2018-04-13 14:06:24 -06:00
|
|
|
|
++coord_x;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
while (i != MAX_HW_POINTS + 1) {
|
|
|
|
|
output_tf->tf_pts.red[i] = translate_from_linear_space_ex(
|
|
|
|
|
coord_x->x, &coeff, 0);
|
|
|
|
|
output_tf->tf_pts.green[i] = translate_from_linear_space_ex(
|
|
|
|
|
coord_x->x, &coeff, 1);
|
|
|
|
|
output_tf->tf_pts.blue[i] = translate_from_linear_space_ex(
|
|
|
|
|
coord_x->x, &coeff, 2);
|
|
|
|
|
++coord_x;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// this function just clamps output to 0-1
|
|
|
|
|
build_new_custom_resulted_curve(MAX_HW_POINTS, &output_tf->tf_pts);
|
|
|
|
|
output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool calculate_user_regamma_ramp(struct dc_transfer_func *output_tf,
|
|
|
|
|
const struct regamma_lut *regamma)
|
|
|
|
|
{
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
|
|
|
|
|
struct dividers dividers;
|
|
|
|
|
|
|
|
|
|
struct pwl_float_data *rgb_user = NULL;
|
|
|
|
|
struct pwl_float_data_ex *rgb_regamma = NULL;
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (regamma == NULL)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
|
|
|
|
|
|
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:03:40 -06:00
|
|
|
|
rgb_user = kcalloc(GAMMA_RGB_256_ENTRIES + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_user),
|
|
|
|
|
GFP_KERNEL);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
if (!rgb_user)
|
|
|
|
|
goto rgb_user_alloc_fail;
|
|
|
|
|
|
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:03:40 -06:00
|
|
|
|
rgb_regamma = kcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_regamma),
|
|
|
|
|
GFP_KERNEL);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
if (!rgb_regamma)
|
|
|
|
|
goto rgb_regamma_alloc_fail;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dividers.divider1 = dc_fixpt_from_fraction(3, 2);
|
|
|
|
|
dividers.divider2 = dc_fixpt_from_int(2);
|
|
|
|
|
dividers.divider3 = dc_fixpt_from_fraction(5, 2);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
|
|
|
|
|
scale_user_regamma_ramp(rgb_user, ®amma->ramp, dividers);
|
|
|
|
|
|
|
|
|
|
if (regamma->flags.bits.applyDegamma == 1) {
|
|
|
|
|
apply_degamma_for_user_regamma(rgb_regamma, MAX_HW_POINTS);
|
|
|
|
|
copy_rgb_regamma_to_coordinates_x(coordinates_x,
|
|
|
|
|
MAX_HW_POINTS, rgb_regamma);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interpolate_user_regamma(MAX_HW_POINTS, rgb_user,
|
|
|
|
|
regamma->flags.bits.applyDegamma, tf_pts);
|
|
|
|
|
|
|
|
|
|
// no custom HDR curves!
|
|
|
|
|
tf_pts->end_exponent = 0;
|
|
|
|
|
tf_pts->x_point_at_y1_red = 1;
|
|
|
|
|
tf_pts->x_point_at_y1_green = 1;
|
|
|
|
|
tf_pts->x_point_at_y1_blue = 1;
|
|
|
|
|
|
|
|
|
|
// this function just clamps output to 0-1
|
|
|
|
|
build_new_custom_resulted_curve(MAX_HW_POINTS, tf_pts);
|
|
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
|
|
|
|
|
kfree(rgb_regamma);
|
|
|
|
|
rgb_regamma_alloc_fail:
|
2018-05-17 22:08:53 -06:00
|
|
|
|
kvfree(rgb_user);
|
2018-04-13 14:06:24 -06:00
|
|
|
|
rgb_user_alloc_fail:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
|
|
|
|
|
const struct dc_gamma *ramp, bool mapUserRamp)
|
|
|
|
|
{
|
|
|
|
|
struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
|
|
|
|
|
struct dividers dividers;
|
|
|
|
|
|
|
|
|
|
struct pwl_float_data *rgb_user = NULL;
|
|
|
|
|
struct pwl_float_data_ex *curve = NULL;
|
|
|
|
|
struct gamma_pixel *axix_x = NULL;
|
|
|
|
|
struct pixel_gamma_point *coeff = NULL;
|
|
|
|
|
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (input_tf->type == TF_TYPE_BYPASS)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/* we can use hardcoded curve for plain SRGB TF */
|
|
|
|
|
if (input_tf->type == TF_TYPE_PREDEFINED &&
|
|
|
|
|
input_tf->tf == TRANSFER_FUNCTION_SRGB &&
|
2018-07-12 13:26:47 -06:00
|
|
|
|
(!mapUserRamp &&
|
|
|
|
|
(ramp->type == GAMMA_RGB_256 || ramp->num_entries == 0)))
|
2018-02-06 14:06:23 -07:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
|
|
|
|
|
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_user),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!rgb_user)
|
|
|
|
|
goto rgb_user_alloc_fail;
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!curve)
|
|
|
|
|
goto curve_alloc_fail;
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
axix_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axix_x),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!axix_x)
|
|
|
|
|
goto axix_x_alloc_fail;
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
|
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!coeff)
|
|
|
|
|
goto coeff_alloc_fail;
|
|
|
|
|
|
2018-04-18 09:37:53 -06:00
|
|
|
|
dividers.divider1 = dc_fixpt_from_fraction(3, 2);
|
|
|
|
|
dividers.divider2 = dc_fixpt_from_int(2);
|
|
|
|
|
dividers.divider3 = dc_fixpt_from_fraction(5, 2);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
tf = input_tf->tf;
|
|
|
|
|
|
|
|
|
|
build_evenly_distributed_points(
|
|
|
|
|
axix_x,
|
|
|
|
|
ramp->num_entries,
|
|
|
|
|
dividers);
|
|
|
|
|
|
|
|
|
|
if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
|
|
|
|
|
scale_gamma(rgb_user, ramp, dividers);
|
|
|
|
|
else if (ramp->type == GAMMA_RGB_FLOAT_1024)
|
|
|
|
|
scale_gamma_dx(rgb_user, ramp, dividers);
|
|
|
|
|
|
|
|
|
|
if (tf == TRANSFER_FUNCTION_PQ)
|
|
|
|
|
build_de_pq(curve,
|
2018-02-13 12:18:43 -07:00
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
else
|
|
|
|
|
build_degamma(curve,
|
2018-02-13 12:18:43 -07:00
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x,
|
2018-02-06 14:06:23 -07:00
|
|
|
|
tf == TRANSFER_FUNCTION_SRGB ? true:false);
|
|
|
|
|
|
|
|
|
|
tf_pts->end_exponent = 0;
|
|
|
|
|
tf_pts->x_point_at_y1_red = 1;
|
|
|
|
|
tf_pts->x_point_at_y1_green = 1;
|
|
|
|
|
tf_pts->x_point_at_y1_blue = 1;
|
|
|
|
|
|
|
|
|
|
map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
|
2018-02-13 12:18:43 -07:00
|
|
|
|
coordinates_x, axix_x, curve,
|
|
|
|
|
MAX_HW_POINTS, tf_pts,
|
2018-07-12 13:46:41 -06:00
|
|
|
|
mapUserRamp && ramp->type != GAMMA_CUSTOM);
|
|
|
|
|
if (ramp->type == GAMMA_CUSTOM)
|
|
|
|
|
apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
|
|
|
|
ret = true;
|
|
|
|
|
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(coeff);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
coeff_alloc_fail:
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(axix_x);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
axix_x_alloc_fail:
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(curve);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
curve_alloc_fail:
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(rgb_user);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
rgb_user_alloc_fail:
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-02-05 12:29:57 -07:00
|
|
|
|
bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
|
2018-07-18 14:10:10 -06:00
|
|
|
|
struct dc_transfer_func_distributed_points *points,
|
|
|
|
|
uint32_t sdr_ref_white_level)
|
2018-02-05 12:29:57 -07:00
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
bool ret = false;
|
|
|
|
|
struct pwl_float_data_ex *rgb_regamma = NULL;
|
|
|
|
|
|
2018-02-28 09:44:54 -07:00
|
|
|
|
if (trans == TRANSFER_FUNCTION_UNITY ||
|
|
|
|
|
trans == TRANSFER_FUNCTION_LINEAR) {
|
2018-02-06 14:06:23 -07:00
|
|
|
|
points->end_exponent = 0;
|
|
|
|
|
points->x_point_at_y1_red = 1;
|
|
|
|
|
points->x_point_at_y1_green = 1;
|
|
|
|
|
points->x_point_at_y1_blue = 1;
|
|
|
|
|
|
2018-02-13 12:18:43 -07:00
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
2018-02-05 12:29:57 -07:00
|
|
|
|
points->red[i] = coordinates_x[i].x;
|
|
|
|
|
points->green[i] = coordinates_x[i].x;
|
|
|
|
|
points->blue[i] = coordinates_x[i].x;
|
|
|
|
|
}
|
|
|
|
|
ret = true;
|
|
|
|
|
} else if (trans == TRANSFER_FUNCTION_PQ) {
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_regamma),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
if (!rgb_regamma)
|
|
|
|
|
goto rgb_regamma_alloc_fail;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
points->end_exponent = 7;
|
|
|
|
|
points->x_point_at_y1_red = 125;
|
|
|
|
|
points->x_point_at_y1_green = 125;
|
|
|
|
|
points->x_point_at_y1_blue = 125;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
build_pq(rgb_regamma,
|
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x,
|
2018-07-18 14:10:10 -06:00
|
|
|
|
sdr_ref_white_level);
|
2018-02-13 12:18:43 -07:00
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
2018-02-06 14:06:23 -07:00
|
|
|
|
points->red[i] = rgb_regamma[i].r;
|
|
|
|
|
points->green[i] = rgb_regamma[i].g;
|
|
|
|
|
points->blue[i] = rgb_regamma[i].b;
|
|
|
|
|
}
|
|
|
|
|
ret = true;
|
|
|
|
|
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(rgb_regamma);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
} else if (trans == TRANSFER_FUNCTION_SRGB ||
|
|
|
|
|
trans == TRANSFER_FUNCTION_BT709) {
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_regamma),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!rgb_regamma)
|
|
|
|
|
goto rgb_regamma_alloc_fail;
|
2018-02-05 12:29:57 -07:00
|
|
|
|
points->end_exponent = 0;
|
|
|
|
|
points->x_point_at_y1_red = 1;
|
|
|
|
|
points->x_point_at_y1_green = 1;
|
|
|
|
|
points->x_point_at_y1_blue = 1;
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
build_regamma(rgb_regamma,
|
2018-02-05 12:29:57 -07:00
|
|
|
|
MAX_HW_POINTS,
|
2018-02-06 14:06:23 -07:00
|
|
|
|
coordinates_x, trans == TRANSFER_FUNCTION_SRGB ? true:false);
|
2018-02-13 12:18:43 -07:00
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
2018-02-05 12:29:57 -07:00
|
|
|
|
points->red[i] = rgb_regamma[i].r;
|
|
|
|
|
points->green[i] = rgb_regamma[i].g;
|
|
|
|
|
points->blue[i] = rgb_regamma[i].b;
|
|
|
|
|
}
|
|
|
|
|
ret = true;
|
|
|
|
|
|
2018-05-10 11:37:35 -06:00
|
|
|
|
kvfree(rgb_regamma);
|
|
|
|
|
} else if (trans == TRANSFER_FUNCTION_HLG ||
|
|
|
|
|
trans == TRANSFER_FUNCTION_HLG12) {
|
2018-07-04 11:27:30 -06:00
|
|
|
|
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_regamma),
|
2018-05-10 11:37:35 -06:00
|
|
|
|
GFP_KERNEL);
|
|
|
|
|
if (!rgb_regamma)
|
|
|
|
|
goto rgb_regamma_alloc_fail;
|
|
|
|
|
|
|
|
|
|
build_hlg_regamma(rgb_regamma,
|
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x,
|
|
|
|
|
trans == TRANSFER_FUNCTION_HLG12 ? true:false);
|
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
|
|
|
|
points->red[i] = rgb_regamma[i].r;
|
|
|
|
|
points->green[i] = rgb_regamma[i].g;
|
|
|
|
|
points->blue[i] = rgb_regamma[i].b;
|
|
|
|
|
}
|
|
|
|
|
ret = true;
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(rgb_regamma);
|
2018-02-05 12:29:57 -07:00
|
|
|
|
}
|
|
|
|
|
rgb_regamma_alloc_fail:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-02-06 14:06:23 -07:00
|
|
|
|
bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
|
|
|
|
|
struct dc_transfer_func_distributed_points *points)
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
bool ret = false;
|
|
|
|
|
struct pwl_float_data_ex *rgb_degamma = NULL;
|
|
|
|
|
|
2018-02-28 09:44:54 -07:00
|
|
|
|
if (trans == TRANSFER_FUNCTION_UNITY ||
|
|
|
|
|
trans == TRANSFER_FUNCTION_LINEAR) {
|
2018-02-06 14:06:23 -07:00
|
|
|
|
|
2018-02-13 12:18:43 -07:00
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
|
|
|
|
points->red[i] = coordinates_x[i].x;
|
|
|
|
|
points->green[i] = coordinates_x[i].x;
|
|
|
|
|
points->blue[i] = coordinates_x[i].x;
|
2018-02-06 14:06:23 -07:00
|
|
|
|
}
|
|
|
|
|
ret = true;
|
|
|
|
|
} else if (trans == TRANSFER_FUNCTION_PQ) {
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_degamma),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!rgb_degamma)
|
|
|
|
|
goto rgb_degamma_alloc_fail;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
build_de_pq(rgb_degamma,
|
2018-02-13 12:18:43 -07:00
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x);
|
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
2018-02-06 14:06:23 -07:00
|
|
|
|
points->red[i] = rgb_degamma[i].r;
|
|
|
|
|
points->green[i] = rgb_degamma[i].g;
|
|
|
|
|
points->blue[i] = rgb_degamma[i].b;
|
|
|
|
|
}
|
|
|
|
|
ret = true;
|
|
|
|
|
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(rgb_degamma);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
} else if (trans == TRANSFER_FUNCTION_SRGB ||
|
|
|
|
|
trans == TRANSFER_FUNCTION_BT709) {
|
treewide: kvzalloc() -> kvcalloc()
The kvzalloc() function has a 2-factor argument form, kvcalloc(). This
patch replaces cases of:
kvzalloc(a * b, gfp)
with:
kvcalloc(a * b, gfp)
as well as handling cases of:
kvzalloc(a * b * c, gfp)
with:
kvzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kvcalloc(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kvzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kvzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kvzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kvzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kvzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kvzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kvzalloc
+ kvcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kvzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kvzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kvzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kvzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kvzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kvzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kvzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kvzalloc(sizeof(THING) * C2, ...)
|
kvzalloc(sizeof(TYPE) * C2, ...)
|
kvzalloc(C1 * C2 * C3, ...)
|
kvzalloc(C1 * C2, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kvzalloc
+ kvcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 15:04:48 -06:00
|
|
|
|
rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_degamma),
|
2018-04-17 04:25:22 -06:00
|
|
|
|
GFP_KERNEL);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
if (!rgb_degamma)
|
|
|
|
|
goto rgb_degamma_alloc_fail;
|
|
|
|
|
|
|
|
|
|
build_degamma(rgb_degamma,
|
2018-02-13 12:18:43 -07:00
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x, trans == TRANSFER_FUNCTION_SRGB ? true:false);
|
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
2018-02-06 14:06:23 -07:00
|
|
|
|
points->red[i] = rgb_degamma[i].r;
|
|
|
|
|
points->green[i] = rgb_degamma[i].g;
|
|
|
|
|
points->blue[i] = rgb_degamma[i].b;
|
|
|
|
|
}
|
|
|
|
|
ret = true;
|
|
|
|
|
|
2018-05-10 11:37:35 -06:00
|
|
|
|
kvfree(rgb_degamma);
|
|
|
|
|
} else if (trans == TRANSFER_FUNCTION_HLG ||
|
|
|
|
|
trans == TRANSFER_FUNCTION_HLG12) {
|
2018-07-04 11:27:30 -06:00
|
|
|
|
rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
|
|
|
|
|
sizeof(*rgb_degamma),
|
2018-05-10 11:37:35 -06:00
|
|
|
|
GFP_KERNEL);
|
|
|
|
|
if (!rgb_degamma)
|
|
|
|
|
goto rgb_degamma_alloc_fail;
|
|
|
|
|
|
|
|
|
|
build_hlg_degamma(rgb_degamma,
|
|
|
|
|
MAX_HW_POINTS,
|
|
|
|
|
coordinates_x,
|
|
|
|
|
trans == TRANSFER_FUNCTION_HLG12 ? true:false);
|
|
|
|
|
for (i = 0; i <= MAX_HW_POINTS ; i++) {
|
|
|
|
|
points->red[i] = rgb_degamma[i].r;
|
|
|
|
|
points->green[i] = rgb_degamma[i].g;
|
|
|
|
|
points->blue[i] = rgb_degamma[i].b;
|
|
|
|
|
}
|
|
|
|
|
ret = true;
|
2018-04-17 04:25:22 -06:00
|
|
|
|
kvfree(rgb_degamma);
|
2018-02-06 14:06:23 -07:00
|
|
|
|
}
|
|
|
|
|
points->end_exponent = 0;
|
|
|
|
|
points->x_point_at_y1_red = 1;
|
|
|
|
|
points->x_point_at_y1_green = 1;
|
|
|
|
|
points->x_point_at_y1_blue = 1;
|
|
|
|
|
|
|
|
|
|
rgb_degamma_alloc_fail:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|