mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
synced 2026-04-18 06:33:43 -04:00
drm/amd/display: Optimize custom brightness curve interpolation
[Why] Custom brightness curve works by walking through all data points one by one. When the brightness value is at either extreme this is a lot of data points to walk. This is especially noticeable when moving a brightness slider around how it can lag. [How] Bisect the data points to find the closest for interpolation. Reviewed-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
002a612023
commit
de63b05593
@@ -4817,8 +4817,8 @@ static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *cap
|
||||
uint32_t *user_brightness)
|
||||
{
|
||||
u32 brightness = scale_input_to_fw(min, max, *user_brightness);
|
||||
u8 prev_signal = 0, prev_lum = 0;
|
||||
int i = 0;
|
||||
u8 lower_signal, upper_signal, upper_lum, lower_lum, lum;
|
||||
int left, right;
|
||||
|
||||
if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)
|
||||
return;
|
||||
@@ -4826,32 +4826,44 @@ static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *cap
|
||||
if (!caps->data_points)
|
||||
return;
|
||||
|
||||
/* choose start to run less interpolation steps */
|
||||
if (caps->luminance_data[caps->data_points/2].input_signal > brightness)
|
||||
i = caps->data_points/2;
|
||||
do {
|
||||
u8 signal = caps->luminance_data[i].input_signal;
|
||||
u8 lum = caps->luminance_data[i].luminance;
|
||||
left = 0;
|
||||
right = caps->data_points - 1;
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
u8 signal = caps->luminance_data[mid].input_signal;
|
||||
|
||||
/*
|
||||
* brightness == signal: luminance is percent numerator
|
||||
* brightness < signal: interpolate between previous and current luminance numerator
|
||||
* brightness > signal: find next data point
|
||||
*/
|
||||
if (brightness > signal) {
|
||||
prev_signal = signal;
|
||||
prev_lum = lum;
|
||||
i++;
|
||||
continue;
|
||||
/* Exact match found */
|
||||
if (signal == brightness) {
|
||||
lum = caps->luminance_data[mid].luminance;
|
||||
goto scale;
|
||||
}
|
||||
if (brightness < signal)
|
||||
lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) *
|
||||
(brightness - prev_signal),
|
||||
signal - prev_signal);
|
||||
*user_brightness = scale_fw_to_input(min, max,
|
||||
DIV_ROUND_CLOSEST(lum * brightness, 101));
|
||||
return;
|
||||
} while (i < caps->data_points);
|
||||
|
||||
if (signal < brightness)
|
||||
left = mid + 1;
|
||||
else
|
||||
right = mid - 1;
|
||||
}
|
||||
|
||||
/* verify bound */
|
||||
if (left >= caps->data_points)
|
||||
left = caps->data_points - 1;
|
||||
|
||||
/* At this point, left > right */
|
||||
lower_signal = caps->luminance_data[right].input_signal;
|
||||
upper_signal = caps->luminance_data[left].input_signal;
|
||||
lower_lum = caps->luminance_data[right].luminance;
|
||||
upper_lum = caps->luminance_data[left].luminance;
|
||||
|
||||
/* interpolate */
|
||||
if (right == left || !lower_lum)
|
||||
lum = upper_lum;
|
||||
else
|
||||
lum = lower_lum + DIV_ROUND_CLOSEST((upper_lum - lower_lum) *
|
||||
(brightness - lower_signal),
|
||||
upper_signal - lower_signal);
|
||||
scale:
|
||||
*user_brightness = scale_fw_to_input(min, max,
|
||||
DIV_ROUND_CLOSEST(lum * brightness, 101));
|
||||
}
|
||||
|
||||
static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
|
||||
|
||||
Reference in New Issue
Block a user