[Pixman] [PATCH 1/2] Implement floating point gradient computation
Adam Jackson
ajax at redhat.com
Fri Jan 11 21:11:58 UTC 2019
On Thu, 2019-01-03 at 12:18 +0100, Maarten Lankhorst wrote:
> From: Basile Clement <basile-pixman at clement.pm>
>
> This patch modifies the gradient walker to be able to generate floating
> point values directly in addition to a8r8g8b8 32 bit values. This is
> then used by the various gradient implementations to render in floating
> point when asked to do so, instead of rendering to a8r8g8b8 and then
> expanding to floating point as they were doing previously.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
This series seems to be a pretty severe performance regression.
test/radial-perf-test on my machine goes from ~0.003 to ~0.006, which
is not great. At -O2 gcc doesn't seem to be smart enough to inline
radial_get_scanline (etc) into its callers or to specialize it for the
two possible pixel widths, but it does at -O3 and it doesn't fix the
performance. Likewise LTO doesn't help any.
What _does_ help is pasting in the old implementation of
_pixman_gradient_walker_pixel as the body of
pixman_gradient_walker_pixel_32. Apparently the out-of-line call to
pixman_contract_from_float is pretty punishing.
Cosmetic comments inline below...
> diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c
> index 822f8e62bae7..9f11cf450e25 100644
> --- a/pixman/pixman-gradient-walker.c
> +++ b/pixman/pixman-gradient-walker.c
> @@ -122,10 +122,10 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
> left_c = right_c;
> }
>
> - /* The alpha channel is scaled to be in the [0, 255] interval,
> + /* The alpha channel is scaled to be in the [0, 1] interval,
> * and the red/green/blue channels are scaled to be in [0, 1].
> * This ensures that after premultiplication all channels will
> - * be in the [0, 255] interval.
> + * be in the [0, 1] interval.
> */
This comment reads a bit funny now.
> @@ -103,10 +106,10 @@ linear_get_scanline_narrow (pixman_iter_t *iter,
> pixman_fixed_48_16_t dx, dy;
> gradient_t *gradient = (gradient_t *)image;
> linear_gradient_t *linear = (linear_gradient_t *)image;
> - uint32_t *end = buffer + width;
> + uint32_t *end = buffer + width * (Bpp / 4);
> pixman_gradient_walker_t walker;
>
> - _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
> + _pixman_gradient_walker_init (&walker,gradient, image->common.repeat);
Whitespace error.
> diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
> index 73a54146ddb1..0a07467c6593 100644
> --- a/pixman/pixman-private.h
> +++ b/pixman/pixman-private.h
> @@ -340,18 +340,18 @@ _pixman_image_validate (pixman_image_t *image);
> */
> typedef struct
> {
> - float a_s, a_b;
> - float r_s, r_b;
> - float g_s, g_b;
> - float b_s, b_b;
> - pixman_fixed_48_16_t left_x;
> - pixman_fixed_48_16_t right_x;
> -
> - pixman_gradient_stop_t *stops;
> - int num_stops;
> - pixman_repeat_t repeat;
> -
> - pixman_bool_t need_reset;
> + float a_s, a_b;
> + float r_s, r_b;
> + float g_s, g_b;
> + float b_s, b_b;
> + pixman_fixed_48_16_t left_x;
> + pixman_fixed_48_16_t right_x;
> +
> + pixman_gradient_stop_t *stops;
> + int num_stops;
> + pixman_repeat_t repeat;
> +
> + pixman_bool_t need_reset;
> } pixman_gradient_walker_t;
This appears to just be adding another space between the type and slot
names? Seems unnecessary.
- ajax
More information about the Pixman
mailing list