Commit 03b979e1 authored by Mario Limonciello's avatar Mario Limonciello Committed by Alex Deucher
Browse files

drm/amd/display: Optimize custom brightness curve



[Why]
When BIOS includes a lot of custom brightness data points, walking
the entire list can be time consuming.  This is most noticed when
dragging a power slider.  The "higher" values are "slower" to drag
around.

[How]
Move custom brightness calculation loop into a static function. Before
starting the loop check the "half way" data point to see how it compares
to the input.  If greater than the half way data point use that as the
starting point instead.

Reviewed-by: default avatarAlex Hung <alex.hung@amd.com>
Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarRoman Li <roman.li@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f9fbc338
Loading
Loading
Loading
Loading
+33 −20
Original line number Diff line number Diff line
@@ -4826,42 +4826,55 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps,
	return 1;
}

static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
					uint32_t brightness)
static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps,
				      uint32_t *brightness)
{
	unsigned int min, max;
	u8 prev_signal = 0, prev_lum = 0;

	if (!get_brightness_range(caps, &min, &max))
		return brightness;

	for (int i = 0; i < caps->data_points; i++) {
		u8 signal, lum;
	int i = 0;

	if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)
			break;
		return;

		signal = caps->luminance_data[i].input_signal;
		lum = caps->luminance_data[i].luminance;
	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;

		/*
		 * brightness == signal: luminance is percent numerator
		 * brightness < signal: interpolate between previous and current luminance numerator
		 * brightness > signal: find next data point
		 */
		if (brightness < signal)
			lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) *
							   (brightness - prev_signal),
							   signal - prev_signal);
		else if (brightness > signal) {
		if (*brightness > signal) {
			prev_signal = signal;
			prev_lum = lum;
			i++;
			continue;
		}
		brightness = DIV_ROUND_CLOSEST(lum * brightness, 101);
		break;
		if (*brightness < signal)
			lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) *
							   (*brightness - prev_signal),
							   signal - prev_signal);
		*brightness = DIV_ROUND_CLOSEST(lum * *brightness, 101);
		return;
	} while (i < caps->data_points);
}

static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps,
					uint32_t brightness)
{
	unsigned int min, max;

	if (!get_brightness_range(caps, &min, &max))
		return brightness;

	convert_custom_brightness(caps, &brightness);

	// Rescale 0..255 to min..max
	return min + DIV_ROUND_CLOSEST((max - min) * brightness,
				       AMDGPU_MAX_BL_LEVEL);