Commit ba6dd8aa authored by Zhigang Gong's avatar Zhigang Gong

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: 's avatarZhigang Gong <zhigang.gong@linux.intel.com>
parent a0a52be7
......@@ -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,
......
......@@ -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;
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++;
if (fullX1 < extentX1)
fullX1 = extentX1;
if (fullY1 < extentY1)
fullY1 = extentY1;
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);
}
}
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
while (nrect--) {
fullX1 = prect->x + xorg;
fullY1 = prect->y + yorg;
fullX2 = fullX1 + (int)prect->width;
fullY2 = fullY1 + (int)prect->height;
prect++;
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 (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 (x1 >= x2 || y1 >= y2)
continue;
glamor_fill(drawable,
gc,
x1 + off_x,
y1 + off_y,
x2 - x1,
y2 - y1);
}
}
return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment