glamor: Simplify fill acceleration for spans/polyfillrect by only clipping once.
This commit was borrowed from uxa driver contributed by Eric.
    commit number is e0066e77e026b0dd0daa0c3765473c7d63aa6753. commit log paste as
    below:
    We were clipping each span against the bounds of the clip, throwing
    out the span early if it was all clipped, and then walked the clip box
    clipping against each of the cliprects.  We would expect spans to
    typically be clipped against one box, and not thrown out, so we were
    not saving any work there.  For multiple cliprects, we were adding
    work.  Only for many spans clipped entirely out of a complicated clip
    region would it have saved work, and it clearly didn't save bugs as
    evidenced by the many fix attempts here.
Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
			
			
This commit is contained in:
		
							parent
							
								
									a0a52be739
								
							
						
					
					
						commit
						ba6dd8aa49
					
				| 
						 | 
					@ -38,68 +38,48 @@ glamor_fill_spans(DrawablePtr drawable,
 | 
				
			||||||
		  int *widths,
 | 
							  int *widths,
 | 
				
			||||||
		  int sorted)
 | 
							  int sorted)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    RegionPtr clip = gc->pCompositeClip;
 | 
					    DDXPointPtr ppt;
 | 
				
			||||||
    BoxPtr extents, boxes;
 | 
					 | 
				
			||||||
    int nbox;
 | 
					    int nbox;
 | 
				
			||||||
    int extentX1, extentX2, extentY1, extentY2;
 | 
					    BoxPtr pbox;
 | 
				
			||||||
    int fullX1, fullX2, fullY1;
 | 
					    int x1, x2, y;
 | 
				
			||||||
    int partX1, partX2;
 | 
					    int off_x, off_y;
 | 
				
			||||||
 | 
					    RegionPtr pClip = fbGetCompositeClip(gc);
 | 
				
			||||||
 | 
					    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 | 
					    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 | 
				
			||||||
	goto fail;
 | 
						goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    extents = REGION_EXTENTS(gc->pScreen, clip);
 | 
					 | 
				
			||||||
    extentX1 = extents->x1;
 | 
					 | 
				
			||||||
    extentY1 = extents->y1;
 | 
					 | 
				
			||||||
    extentX2 = extents->x2;
 | 
					 | 
				
			||||||
    extentY2 = extents->y2;
 | 
					 | 
				
			||||||
    while (n--) {
 | 
					 | 
				
			||||||
	fullX1 = points->x;
 | 
					 | 
				
			||||||
	fullY1 = points->y;
 | 
					 | 
				
			||||||
	fullX2 = fullX1 + *widths;
 | 
					 | 
				
			||||||
	points++;
 | 
					 | 
				
			||||||
	widths++;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullY1 < extentY1 || extentY2 <= fullY1)
 | 
					    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
 | 
				
			||||||
	    continue;
 | 
						ppt = points;
 | 
				
			||||||
 | 
					        while (n--) {
 | 
				
			||||||
 | 
					                x1 = ppt->x;
 | 
				
			||||||
 | 
					                y = ppt->y;
 | 
				
			||||||
 | 
					                x2 = x1 + (int)*widths;
 | 
				
			||||||
 | 
					                ppt++;
 | 
				
			||||||
 | 
					                widths++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullX1 < extentX1)
 | 
					                nbox = REGION_NUM_RECTS(pClip);
 | 
				
			||||||
	    fullX1 = extentX1;
 | 
					                pbox = REGION_RECTS(pClip);
 | 
				
			||||||
 | 
					                while (nbox--) {
 | 
				
			||||||
 | 
					                        if (pbox->y1 > y || pbox->y2 <= y)
 | 
				
			||||||
 | 
					                                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullX2 > extentX2)
 | 
					                        if (x1 < pbox->x1)
 | 
				
			||||||
	    fullX2 = extentX2;
 | 
					                                x1 = pbox->x1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullX1 >= fullX2)
 | 
					                        if (x2 > pbox->x2)
 | 
				
			||||||
	    continue;
 | 
					                                x2 = pbox->x2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nbox = REGION_NUM_RECTS (clip);
 | 
					                        if (x2 <= x1)
 | 
				
			||||||
	if (nbox == 1) {
 | 
					                                continue;
 | 
				
			||||||
	    glamor_fill(drawable,
 | 
					                        glamor_fill (drawable,gc,
 | 
				
			||||||
			gc,
 | 
					                                     x1 + off_x, y + off_y,
 | 
				
			||||||
			fullX1, fullY1, fullX2-fullX1, 1);
 | 
					                                     x2 - x1 ,  1);
 | 
				
			||||||
	} else {
 | 
					                        pbox++;
 | 
				
			||||||
	    boxes = REGION_RECTS(clip);
 | 
					                }
 | 
				
			||||||
	    while(nbox--)
 | 
					        }
 | 
				
			||||||
	    {
 | 
					 | 
				
			||||||
		if (boxes->y1 <= fullY1 && fullY1 < boxes->y2)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
		    partX1 = boxes->x1;
 | 
					 | 
				
			||||||
		    if (partX1 < fullX1)
 | 
					 | 
				
			||||||
			partX1 = fullX1;
 | 
					 | 
				
			||||||
		    partX2 = boxes->x2;
 | 
					 | 
				
			||||||
		    if (partX2 > fullX2)
 | 
					 | 
				
			||||||
			partX2 = fullX2;
 | 
					 | 
				
			||||||
		    if (partX2 > partX1)
 | 
					 | 
				
			||||||
		    {
 | 
					 | 
				
			||||||
			glamor_fill(drawable, gc,
 | 
					 | 
				
			||||||
				    partX1, fullY1,
 | 
					 | 
				
			||||||
				    partX2 - partX1, 1);
 | 
					 | 
				
			||||||
		    }
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		boxes++;
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
    glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable,
 | 
					    glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,80 +43,60 @@ glamor_poly_fill_rect(DrawablePtr drawable,
 | 
				
			||||||
		      int nrect,
 | 
							      int nrect,
 | 
				
			||||||
		      xRectangle *prect)
 | 
							      xRectangle *prect)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    RegionPtr	    clip = fbGetCompositeClip(gc);
 | 
					 | 
				
			||||||
    register BoxPtr box;
 | 
					 | 
				
			||||||
    BoxPtr	    pextent;
 | 
					 | 
				
			||||||
    int		    extentX1, extentX2, extentY1, extentY2;
 | 
					 | 
				
			||||||
    int		    fullX1, fullX2, fullY1, fullY2;
 | 
					    int		    fullX1, fullX2, fullY1, fullY2;
 | 
				
			||||||
    int		    partX1, partX2, partY1, partY2;
 | 
					 | 
				
			||||||
    int		    xorg, yorg;
 | 
					    int		    xorg, yorg;
 | 
				
			||||||
    int		    n;
 | 
					    int		    n;
 | 
				
			||||||
 | 
					    register BoxPtr pbox;
 | 
				
			||||||
 | 
					    int off_x, off_y;
 | 
				
			||||||
 | 
					    RegionPtr pClip = fbGetCompositeClip(gc);
 | 
				
			||||||
 | 
					    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 | 
					    if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
 | 
				
			||||||
	goto fail;
 | 
						goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    xorg = drawable->x;
 | 
					    xorg = drawable->x;
 | 
				
			||||||
    yorg = drawable->y;
 | 
					    yorg = drawable->y;
 | 
				
			||||||
 | 
					    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pextent = REGION_EXTENTS(gc->pScreen, clip);
 | 
					        while (nrect--) {
 | 
				
			||||||
    extentX1 = pextent->x1;
 | 
					                fullX1 = prect->x + xorg;
 | 
				
			||||||
    extentY1 = pextent->y1;
 | 
					                fullY1 = prect->y + yorg;
 | 
				
			||||||
    extentX2 = pextent->x2;
 | 
					                fullX2 = fullX1 + (int)prect->width;
 | 
				
			||||||
    extentY2 = pextent->y2;
 | 
					                fullY2 = fullY1 + (int)prect->height;
 | 
				
			||||||
    while (nrect--)
 | 
					                prect++;
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
	fullX1 = prect->x + xorg;
 | 
					 | 
				
			||||||
	fullY1 = prect->y + yorg;
 | 
					 | 
				
			||||||
	fullX2 = fullX1 + (int)prect->width;
 | 
					 | 
				
			||||||
	fullY2 = fullY1 + (int)prect->height;
 | 
					 | 
				
			||||||
	prect++;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullX1 < extentX1)
 | 
					                n = REGION_NUM_RECTS(pClip);
 | 
				
			||||||
	    fullX1 = extentX1;
 | 
					                pbox = REGION_RECTS(pClip);
 | 
				
			||||||
 | 
					                /*
 | 
				
			||||||
 | 
					                 * clip the rectangle to each box in the clip region
 | 
				
			||||||
 | 
					                 * this is logically equivalent to calling Intersect(),
 | 
				
			||||||
 | 
					                 * but rectangles may overlap each other here.
 | 
				
			||||||
 | 
					                 */
 | 
				
			||||||
 | 
					                while (n--) {
 | 
				
			||||||
 | 
					                        int x1 = fullX1;
 | 
				
			||||||
 | 
					                        int x2 = fullX2;
 | 
				
			||||||
 | 
					                        int y1 = fullY1;
 | 
				
			||||||
 | 
					                        int y2 = fullY2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullY1 < extentY1)
 | 
					                        if (pbox->x1 > x1)
 | 
				
			||||||
	    fullY1 = extentY1;
 | 
					                                x1 = pbox->x1;
 | 
				
			||||||
 | 
					                        if (pbox->x2 < x2)
 | 
				
			||||||
 | 
					                                x2 = pbox->x2;
 | 
				
			||||||
 | 
					                        if (pbox->y1 > y1)
 | 
				
			||||||
 | 
					                                y1 = pbox->y1;
 | 
				
			||||||
 | 
					                        if (pbox->y2 < y2)
 | 
				
			||||||
 | 
					                                y2 = pbox->y2;
 | 
				
			||||||
 | 
					                        pbox++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fullX2 > extentX2)
 | 
					                        if (x1 >= x2 || y1 >= y2)
 | 
				
			||||||
	    fullX2 = extentX2;
 | 
					                                continue;
 | 
				
			||||||
 | 
						                glamor_fill(drawable,
 | 
				
			||||||
	if (fullY2 > extentY2)
 | 
								            gc,
 | 
				
			||||||
	    fullY2 = extentY2;
 | 
									    x1 + off_x,
 | 
				
			||||||
 | 
									    y1 + off_y,
 | 
				
			||||||
	if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
 | 
									    x2 - x1,
 | 
				
			||||||
	    continue;
 | 
					                                    y2 - y1);
 | 
				
			||||||
	n = REGION_NUM_RECTS(clip);
 | 
					                }
 | 
				
			||||||
	if (n == 1) {
 | 
					 | 
				
			||||||
	    glamor_fill(drawable,
 | 
					 | 
				
			||||||
			gc,
 | 
					 | 
				
			||||||
			fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	    box = REGION_RECTS(clip);
 | 
					 | 
				
			||||||
	    /* clip the rectangle to each box in the clip region
 | 
					 | 
				
			||||||
	     * this is logically equivalent to calling Intersect()
 | 
					 | 
				
			||||||
	     */
 | 
					 | 
				
			||||||
	    while (n--) {
 | 
					 | 
				
			||||||
		partX1 = box->x1;
 | 
					 | 
				
			||||||
		if (partX1 < fullX1)
 | 
					 | 
				
			||||||
		    partX1 = fullX1;
 | 
					 | 
				
			||||||
		partY1 = box->y1;
 | 
					 | 
				
			||||||
		if (partY1 < fullY1)
 | 
					 | 
				
			||||||
		    partY1 = fullY1;
 | 
					 | 
				
			||||||
		partX2 = box->x2;
 | 
					 | 
				
			||||||
		if (partX2 > fullX2)
 | 
					 | 
				
			||||||
		    partX2 = fullX2;
 | 
					 | 
				
			||||||
		partY2 = box->y2;
 | 
					 | 
				
			||||||
		if (partY2 > fullY2)
 | 
					 | 
				
			||||||
		    partY2 = fullY2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		box++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (partX1 < partX2 && partY1 < partY2)
 | 
					 | 
				
			||||||
		    glamor_fill(drawable, gc,
 | 
					 | 
				
			||||||
				partX1, partY1,
 | 
					 | 
				
			||||||
				partX2 - partX1, partY2 - partY1);
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue