[Mesa-dev] [PATCH] draw: fix alpha value for very short aa lines

Brian Paul brianp at vmware.com
Fri Mar 9 14:59:25 UTC 2018


Reviewed-by: Brian Paul <brianp at vmware.com>

On 03/08/2018 09:30 PM, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
> 
> The logic would not work correctly for line lengths smaller than 1.0,
> even a degenerated line with length 0 would still produce a fragment
> with anyhwere between alpha 0.0 and 0.5.
> ---
>   src/gallium/auxiliary/draw/draw_pipe_aaline.c  | 25 ++++++++++++++++++++++++-
>   src/gallium/auxiliary/draw/draw_pipe_stipple.c |  1 -
>   2 files changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
> index 14a4b2f..66a943a 100644
> --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
> +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
> @@ -370,7 +370,30 @@ aaline_line(struct draw_stage *stage, struct prim_header *header)
>      float t_l, t_w;
>      uint i;
>   
> -   half_length = 0.5f * sqrtf(dx * dx + dy * dy) + 0.5f;
> +   half_length = 0.5f * sqrtf(dx * dx + dy * dy);
> +
> +   if (half_length < 0.5f) {
> +      /*
> +       * The logic we use for "normal" sized segments is incorrect
> +       * for very short segments (basically because we only have
> +       * one value to interpolate, not a distance to each endpoint).
> +       * Therefore, we calculate half_length differently, so that for
> +       * original line length (near) 0, we get alpha 0 - otherwise
> +       * max alpha would still be 0.5. This also prevents us from
> +       * artifacts due to degenerated lines (the endpoints being
> +       * identical, which would still receive anywhere from alpha
> +       * 0-0.5 otherwise) (at least the pstipple stage may generate
> +       * such lines due to float inaccuracies if line length is very
> +       * close to a integer).
> +       * Might not be fully accurate neither (because the "strength" of
> +       * the line is going to be determined by how close to the pixel
> +       * center those 1 or 2 fragments are) but it's probably the best
> +       * we can do.
> +       */
> +      half_length = 2.0f * half_length;
> +   } else {
> +      half_length = half_length + 0.5f;
> +   }
>   
>      t_w = half_width;
>      t_l = 0.5f;
> diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
> index 3a44e96..d30572c 100644
> --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c
> +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
> @@ -150,7 +150,6 @@ stipple_line(struct draw_stage *stage, struct prim_header *header)
>      if (header->flags & DRAW_PIPE_RESET_STIPPLE)
>         stipple->counter = 0;
>   
> -
>      /* XXX ToDo: instead of iterating pixel-by-pixel, use a look-up table.
>       */
>      for (i = 0; i < length; i++) {
> 



More information about the mesa-dev mailing list