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:
Zhigang Gong 2011-06-10 18:32:15 +08:00
parent a0a52be739
commit ba6dd8aa49
2 changed files with 73 additions and 113 deletions

View File

@ -38,68 +38,48 @@ glamor_fill_spans(DrawablePtr drawable,
int *widths,
int sorted)
{
RegionPtr clip = gc->pCompositeClip;
BoxPtr extents, boxes;
DDXPointPtr ppt;
int nbox;
int extentX1, extentX2, extentY1, extentY2;
int fullX1, fullX2, fullY1;
int partX1, partX2;
BoxPtr pbox;
int x1, x2, y;
int off_x, off_y;
RegionPtr pClip = fbGetCompositeClip(gc);
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
if (gc->fillStyle != FillSolid && gc->fillStyle != FillTiled)
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)
continue;
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
ppt = points;
while (n--) {
x1 = ppt->x;
y = ppt->y;
x2 = x1 + (int)*widths;
ppt++;
widths++;
if (fullX1 < extentX1)
fullX1 = extentX1;
nbox = REGION_NUM_RECTS(pClip);
pbox = REGION_RECTS(pClip);
while (nbox--) {
if (pbox->y1 > y || pbox->y2 <= y)
continue;
if (fullX2 > extentX2)
fullX2 = extentX2;
if (x1 < pbox->x1)
x1 = pbox->x1;
if (fullX1 >= fullX2)
continue;
if (x2 > pbox->x2)
x2 = pbox->x2;
nbox = REGION_NUM_RECTS (clip);
if (nbox == 1) {
glamor_fill(drawable,
gc,
fullX1, fullY1, fullX2-fullX1, 1);
} else {
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++;
}
}
}
if (x2 <= x1)
continue;
glamor_fill (drawable,gc,
x1 + off_x, y + off_y,
x2 - x1 , 1);
pbox++;
}
}
return;
fail:
glamor_fallback("glamor_fillspans(): to %p (%c)\n", drawable,

View File

@ -43,80 +43,60 @@ glamor_poly_fill_rect(DrawablePtr drawable,
int nrect,
xRectangle *prect)
{
RegionPtr clip = fbGetCompositeClip(gc);
register BoxPtr box;
BoxPtr pextent;
int extentX1, extentX2, extentY1, extentY2;
int fullX1, fullX2, fullY1, fullY2;
int partX1, partX2, partY1, partY2;
int xorg, yorg;
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)
goto fail;
xorg = drawable->x;
yorg = drawable->y;
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
pextent = REGION_EXTENTS(gc->pScreen, clip);
extentX1 = pextent->x1;
extentY1 = pextent->y1;
extentX2 = pextent->x2;
extentY2 = pextent->y2;
while (nrect--)
{
fullX1 = prect->x + xorg;
fullY1 = prect->y + yorg;
fullX2 = fullX1 + (int)prect->width;
fullY2 = fullY1 + (int)prect->height;
prect++;
while (nrect--) {
fullX1 = prect->x + xorg;
fullY1 = prect->y + yorg;
fullX2 = fullX1 + (int)prect->width;
fullY2 = fullY1 + (int)prect->height;
prect++;
if (fullX1 < extentX1)
fullX1 = extentX1;
n = REGION_NUM_RECTS(pClip);
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)
fullY1 = extentY1;
if (pbox->x1 > x1)
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)
fullX2 = extentX2;
if (fullY2 > extentY2)
fullY2 = extentY2;
if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
continue;
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);
}
}
if (x1 >= x2 || y1 >= y2)
continue;
glamor_fill(drawable,
gc,
x1 + off_x,
y1 + off_y,
x2 - x1,
y2 - y1);
}
}
return;