plymouth performance

Ray Strode halfline at gmail.com
Wed Jun 17 19:59:37 PDT 2009


Hi,

>> The gradient using rand uses quite a lot which could be
>> replaced with a dither. I'll take a look.
>
> Attached is a patch to make the gradient faster by using our own pseudo
> random number generator and a new call graph. including the previous patch
> this drops the cycle count for 20 secs of animation from 1,000mil cycles to
> 185mil cycles.

Thanks for looking into this.  Looks like you got a pretty big win.
I think committing it makes a lot of sense.

I haven't had a chance to try it yet.

Comments below...

> diff --git a/src/libply/ply-frame-buffer.c b/src/libply/ply-frame-buffer.c
> index 74eafee..6b5eb04 100644
> --- a/src/libply/ply-frame-buffer.c
> +++ b/src/libply/ply-frame-buffer.c
> @@ -1093,6 +1093,10 @@ ply_frame_buffer_fill_with_gradient (ply_frame_buffer_t      *buffer,
>
>    uint32_t red, green, blue, red_step, green_step, blue_step, t, pixel;
>    uint32_t x, y;
> +  /* we use a fixed seed so that the dithering doesn't change on repaints
> +   * of the same area.
> +   */
> +  uint32_t p_rand = 0x76543210;
Minor nit: I'd call this variable noise instead of p_rand.

[...]
> +
> +#define RANDOMIZE(num) (num = ((num << 1) + (num >>1)) & NOISE_MASK)
I wonder if this is good enough.  The noise is changing in regular linear way.
Does the noise look random? As long as it looks okay, seems fine.

> +#define UNROLLED_PIXEL_COUNT 8
>
>    for (y = buffer->area.y; y < buffer->area.y + buffer->area.height; y++)
>      {
>        if (cropped_area.y <= y && y < cropped_area.y + cropped_area.height)
>          {
> -          for (x = cropped_area.x; x < cropped_area.x + cropped_area.width; x++)
> +          if (cropped_area.width < UNROLLED_PIXEL_COUNT)
>              {
[ snip noise dithering code ]
> +            }
> +          else
> +            {
> +              uint32_t shaded_set[UNROLLED_PIXEL_COUNT];
> +              uint32_t *ptr = &buffer->shadow_buffer[y * buffer->area.width + cropped_area.x];
> +              for (x = 0; x < UNROLLED_PIXEL_COUNT; x++)
> +                {
> +                  shaded_set[x] = 0xff000000;
> +                  RANDOMIZE(p_rand);
> +                  shaded_set[x] |= (((red   + p_rand) & COLOR_MASK) >> RED_SHIFT);
> +                  RANDOMIZE(p_rand);
> +                  shaded_set[x] |= (((green + p_rand) & COLOR_MASK) >> GREEN_SHIFT);
> +                  RANDOMIZE(p_rand);
> +                  shaded_set[x] |= (((blue  + p_rand) & COLOR_MASK) >> BLUE_SHIFT);
> +                }
> +              for (x = cropped_area.width; x >=UNROLLED_PIXEL_COUNT; x-=UNROLLED_PIXEL_COUNT)
> +                {
> +                    memcpy((void*)ptr, (void*)shaded_set, UNROLLED_PIXEL_COUNT * sizeof(uint32_t));
> +                    ptr += UNROLLED_PIXEL_COUNT;
> +                }
> +              memcpy((void*)ptr, (void*)shaded_set, x * sizeof(uint32_t));

So the idea here is to do 8 pixels worth of noise per line and then
tile that noise along the line?
I'm a little worried having a recurring color pattern on each line
will make the noise prominent
instead of just being a quiet way of down playing the banding.  Again
though, all that matters is
that it looks good.  As long as it does, we should do it.

Would be good if the two separate optimizations were separate commits though.

--Ray


More information about the plymouth mailing list