[PATCH 1/3] Move miTrapezoids() into fb as fbTrapezoids().

Aaron Plattner aplattner at nvidia.com
Tue Oct 4 15:52:44 PDT 2011


This caused a performance regression because previously, miTrapezoids 
would render its mask image into a scratch pixmap and then perform the 
final composite using a possibly-accelerated RENDER Composite call. 
Now, fbTrapezoids does the final composite in software, leading to, for 
example, http://www.nvnews.net/vbulletin/showthread.php?t=166698

Of course, I could simply copy the old miTrapezoids implementation into 
our driver, but it seems hard to believe that our driver is the only one 
that benefited from the "rasterize in software, composite in hardware" 
behavior of the old code.  Should I re-add miTrapezoids as a helper that 
drivers can plug in when they want the old behavior, just revert this 
change, or go the "only nvidia gets to go fast" copy & paste route?

On 02/11/2011 06:54 AM, "Søren Sandmann Pedersen" <sandmann at cs.au.dk>" 
wrote:
> From: Søren Sandmann Pedersen<ssp at redhat.com>
>
> The main consumer of trapezoids, cairo, is using the Trapezoids
> request, which is currently implemented in the miTrapezoids()
> function. That function splits the request into smaller bits and calls
> lower level functions such as AddTrap.
>
> By moving the implementation of the whole request into fb, we can
> instead call pixman_composite_trapezoids() to do the whole request in
> one step.
>
> There are no callers of miTrapezoids in any of the open source
> drivers, although exa and uxa have their own copies of the function.
>
> Signed-off-by: Søren Sandmann<ssp at redhat.com>
> ---
>   fb/fbpict.c     |    1 +
>   fb/fbpict.h     |   10 ++++++
>   fb/fbtrap.c     |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
>   render/mipict.c |    2 +-
>   render/mipict.h |   10 ------
>   render/mitrap.c |   61 ----------------------------------------
>   6 files changed, 92 insertions(+), 75 deletions(-)
>
> diff --git a/fb/fbpict.c b/fb/fbpict.c
> index 7636040..6e66db8 100644
> --- a/fb/fbpict.c
> +++ b/fb/fbpict.c
> @@ -364,6 +364,7 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
>       ps->Glyphs = miGlyphs;
>       ps->CompositeRects = miCompositeRects;
>       ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
> +    ps->Trapezoids = fbTrapezoids;
>       ps->AddTraps = fbAddTraps;
>       ps->AddTriangles = fbAddTriangles;
>
> diff --git a/fb/fbpict.h b/fb/fbpict.h
> index 9abced1..03d2665 100644
> --- a/fb/fbpict.h
> +++ b/fb/fbpict.h
> @@ -65,4 +65,14 @@ fbAddTriangles (PicturePtr  pPicture,
>   		int	    ntri,
>   		xTriangle   *tris);
>
> +extern _X_EXPORT void
> +fbTrapezoids (CARD8	    op,
> +	      PicturePtr    pSrc,
> +	      PicturePtr    pDst,
> +	      PictFormatPtr maskFormat,
> +	      INT16	    xSrc,
> +	      INT16	    ySrc,
> +	      int	    ntrap,
> +	      xTrapezoid    *traps);
> +
>   #endif /* _FBPICT_H_ */
> diff --git a/fb/fbtrap.c b/fb/fbtrap.c
> index c309ceb..687de55 100644
> --- a/fb/fbtrap.c
> +++ b/fb/fbtrap.c
> @@ -123,9 +123,9 @@ fbAddTriangles (PicturePtr  pPicture,
>   	 *	       / \             / \
>   	 *	      /   \           /   \
>   	 *	     /     +         +     \
> -	 *      /    --           --    \
> -	 *     /   --               --   \
> -	 *    / ---                   --- \
> +	 *          /    --           --    \
> +	 *         /   --               --   \
> +	 *        / ---                   --- \
>   	 *	 +--                         --+
>   	 */
>   	
> @@ -157,3 +157,80 @@ fbAddTriangles (PicturePtr  pPicture,
>       }
>   }
>
> +
> +void
> +fbTrapezoids (CARD8	    op,
> +	      PicturePtr    pSrc,
> +	      PicturePtr    pDst,
> +	      PictFormatPtr maskFormat,
> +	      INT16	    xSrc,
> +	      INT16	    ySrc,
> +	      int	    ntrap,
> +	      xTrapezoid    *traps)
> +{
> +    pixman_image_t *src, *dst;
> +    int src_xoff, src_yoff;
> +    int dst_xoff, dst_yoff;
> +
> +    if (ntrap == 0)
> +	return;
> +
> +    src = image_from_pict (pSrc, FALSE,&src_xoff,&src_yoff);
> +    dst = image_from_pict (pDst, TRUE,&dst_xoff,&dst_yoff);
> +
> +    if (src&&  dst)
> +    {
> +	pixman_format_code_t format;
> +	int x_dst, y_dst;
> +	int i;
> +
> +	x_dst = traps[0].left.p1.x>>  16;
> +	y_dst = traps[0].left.p1.y>>  16;
> +	
> +	if (!maskFormat)
> +	{
> +	    if (pDst->polyEdge == PolyEdgeSharp)
> +		format = PIXMAN_a1;
> +	    else
> +		format = PIXMAN_a8;
> +
> +	    for (i = 0; i<  ntrap; ++i)
> +	    {
> +		pixman_composite_trapezoids (op, src, dst, format,
> +					     xSrc + src_xoff,
> +					     ySrc + src_yoff,
> +					     x_dst + dst_xoff,
> +					     y_dst + dst_yoff,
> +					     1, (pixman_trapezoid_t *)traps++);
> +	    }
> +	}
> +	else
> +	{
> +	    switch (PICT_FORMAT_A (maskFormat->format))
> +	    {
> +	    case 1:
> +		format = PIXMAN_a1;
> +		break;
> +
> +	    case 4:
> +		format = PIXMAN_a4;
> +		break;
> +
> +	    default:
> +	    case 8:
> +		format = PIXMAN_a8;
> +		break;
> +	    }
> +
> +	    pixman_composite_trapezoids (op, src, dst, format,
> +					 xSrc + src_xoff,
> +					 ySrc + src_yoff,
> +					 x_dst + dst_xoff,
> +					 y_dst + dst_yoff,
> +					 ntrap, (pixman_trapezoid_t *)traps);
> +	}
> +    }
> +
> +    free_pixman_pict (pSrc, src);
> +    free_pixman_pict (pDst, dst);
> +}
> diff --git a/render/mipict.c b/render/mipict.c
> index de5eea6..46b45b5 100644
> --- a/render/mipict.c
> +++ b/render/mipict.c
> @@ -631,7 +631,7 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
>       ps->Composite	= 0;			/* requires DDX support */
>       ps->Glyphs		= miGlyphs;
>       ps->CompositeRects	= miCompositeRects;
> -    ps->Trapezoids	= miTrapezoids;
> +    ps->Trapezoids	= 0;
>       ps->Triangles	= miTriangles;
>       ps->TriStrip	= miTriStrip;
>       ps->TriFan		= miTriFan;
> diff --git a/render/mipict.h b/render/mipict.h
> index eb6b664..be7b20b 100644
> --- a/render/mipict.h
> +++ b/render/mipict.h
> @@ -146,16 +146,6 @@ extern _X_EXPORT void
>   miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
>
>   extern _X_EXPORT void
> -miTrapezoids (CARD8	    op,
> -	      PicturePtr    pSrc,
> -	      PicturePtr    pDst,
> -	      PictFormatPtr maskFormat,
> -	      INT16	    xSrc,
> -	      INT16	    ySrc,
> -	      int	    ntrap,
> -	      xTrapezoid    *traps);
> -
> -extern _X_EXPORT void
>   miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
>
>   extern _X_EXPORT void
> diff --git a/render/mitrap.c b/render/mitrap.c
> index 8bdc8a8..1f09a1e 100644
> --- a/render/mitrap.c
> +++ b/render/mitrap.c
> @@ -126,64 +126,3 @@ miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
>   	    box->x2 = x2;
>       }
>   }
> -
> -void
> -miTrapezoids (CARD8	    op,
> -	      PicturePtr    pSrc,
> -	      PicturePtr    pDst,
> -	      PictFormatPtr maskFormat,
> -	      INT16	    xSrc,
> -	      INT16	    ySrc,
> -	      int	    ntrap,
> -	      xTrapezoid    *traps)
> -{
> -    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
> -    PictureScreenPtr    ps = GetPictureScreen(pScreen);
> -
> -    /*
> -     * Check for solid alpha add
> -     */
> -    if (op == PictOpAdd&&  miIsSolidAlpha (pSrc))
> -    {
> -	for (; ntrap; ntrap--, traps++)
> -	    (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
> -    }
> -    else if (maskFormat)
> -    {
> -	PicturePtr	pPicture;
> -	BoxRec		bounds;
> -	INT16		xDst, yDst;
> -	INT16		xRel, yRel;
> -	
> -	xDst = traps[0].left.p1.x>>  16;
> -	yDst = traps[0].left.p1.y>>  16;
> -
> -	miTrapezoidBounds (ntrap, traps,&bounds);
> -	if (bounds.y1>= bounds.y2 || bounds.x1>= bounds.x2)
> -	    return;
> -	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
> -					 bounds.x2 - bounds.x1,
> -					 bounds.y2 - bounds.y1);
> -	if (!pPicture)
> -	    return;
> -	for (; ntrap; ntrap--, traps++)
> -	    (*ps->RasterizeTrapezoid) (pPicture, traps,
> -				       -bounds.x1, -bounds.y1);
> -	xRel = bounds.x1 + xSrc - xDst;
> -	yRel = bounds.y1 + ySrc - yDst;
> -	CompositePicture (op, pSrc, pPicture, pDst,
> -			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
> -			  bounds.x2 - bounds.x1,
> -			  bounds.y2 - bounds.y1);
> -	FreePicture (pPicture, 0);
> -    }
> -    else
> -    {
> -	if (pDst->polyEdge == PolyEdgeSharp)
> -	    maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
> -	else
> -	    maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
> -	for (; ntrap; ntrap--, traps++)
> -	    miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
> -    }
> -}



More information about the xorg-devel mailing list