# [Pixman] [PATCH/RFC 1/2] New FAST_PATH_SIMPLE_ROTATE_TRANSFORM flag

Soeren Sandmann sandmann at daimi.au.dk
Mon Aug 2 07:08:58 PDT 2010

```Siarhei Siamashka <siarhei.siamashka at gmail.com> writes:

> +static pixman_bool_t
> +has_suitable_filter_for_simple_rotate (pixman_image_t *image)
> +{
> +    if (image->common.filter == PIXMAN_FILTER_NEAREST)
> +	return TRUE;
> +
> +    if (image->common.filter == PIXMAN_FILTER_BILINEAR &&
> +	pixman_fixed_frac (image->common.transform->matrix) == 0 &&
> +	pixman_fixed_frac (image->common.transform->matrix) == 0)
> +    {
> +	return TRUE;
> +    }
> +
> +    return FALSE;
> +}

This seems to basically compute whether the filter is effectively
NEAREST. If so, would it be possible to just set the
HAS_NEAREST_FILTER flag in that case, and then rely on that instead?

Doing it this way would make it possible to hit the NEAREST scaling
fast paths in more cases too.

The transformation check could be generalized too I think. Suppose the
transform is t00..t22, and the input coordinates are (n + 0.5, m + 0.5).
Then the transformed x coordinate would be:

tx = t00 * (n + 0.5) + t01 * (m + 0.5) + t02
= t00 * n + t01 * m + t02 + (t00 + t01) * 0.5

which implies that if t00, t01 and t02 are all integers and (t00 + t01)
is odd, then tx will be an integer plus 0.5, which means the bilinear
filter will reduce to NEAREST. Something similar applies in
the Y direction. (And the transform would have to be affine).

>  static void
>  compute_image_info (pixman_image_t *image)
>  {
> @@ -299,18 +315,35 @@ compute_image_info (pixman_image_t *image)
>      {
>  	flags |= (FAST_PATH_ID_TRANSFORM | FAST_PATH_X_UNIT_POSITIVE);
>      }
> -    else
> +    else if (image->common.transform->matrix == 0 &&
> +	     image->common.transform->matrix == 0 &&
> +	     image->common.transform->matrix == pixman_fixed_1)
>      {
> -	if (image->common.transform->matrix == 0 &&
> -	    image->common.transform->matrix == 0 &&
> -	    image->common.transform->matrix == 0 &&
> -	    image->common.transform->matrix == 0 &&
> -	    image->common.transform->matrix == pixman_fixed_1)
> +	/* affine transform */
> +	const pixman_transform_t *t = image->common.transform;

It would make sense to move this shorthand to the top of the function
and use it in other places too.

> +	if (t->matrix == 0 && t->matrix == 0)
>  	{
> +	    if (t->matrix == -pixman_fixed_1 &&
> +		t->matrix == -pixman_fixed_1 &&
> +		has_suitable_filter_for_simple_rotate (image))
> +	    {
> +		/* 180 degrees rotation */
> +		flags |= FAST_PATH_SIMPLE_ROTATE_TRANSFORM;
> +	    }
>  	    flags |= FAST_PATH_SCALE_TRANSFORM;
>  	}

Isn't this case already covered by the existing NEAREST scalers?

Soren
```