Bug 1247979. Optimize ScaleToOutsidePixels. r=kats

This does a union of all the rectangles at once, instead of one-by-one. It
also cuts down a lot on allocation churn.

It would be possible to avoid an additional allocation/copy if we change
the interface of this function to mutate the existing region instead of
returning a new one.
This commit is contained in:
Jeff Muizelaar 2016-02-12 13:36:24 -05:00
parent 0b32350888
commit b331c8c76d

View File

@ -738,13 +738,24 @@ nsIntRegion nsRegion::ScaleToNearestPixels (float aScaleX, float aScaleY,
nsIntRegion nsRegion::ScaleToOutsidePixels (float aScaleX, float aScaleY,
nscoord aAppUnitsPerPixel) const
{
nsIntRegion result;
for (auto iter = RectIter(); !iter.Done(); iter.Next()) {
mozilla::gfx::IntRect deviceRect =
iter.Get().ScaleToOutsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel);
result.Or(result, deviceRect);
// make a copy of the region so that we can mutate it inplace
nsRegion region = *this;
int n;
pixman_box32_t *boxes = pixman_region32_rectangles(&region.mImpl, &n);
boxes = pixman_region32_rectangles(&region.mImpl, &n);
for (int i=0; i<n; i++) {
nsRect rect = BoxToRect(boxes[i]);
mozilla::gfx::IntRect irect = rect.ScaleToOutsidePixels(aScaleX, aScaleY, aAppUnitsPerPixel);
boxes[i] = RectToBox(irect);
}
return result;
nsIntRegion iRegion;
// clear out the initial pixman_region so that we can replace it below
pixman_region32_fini(&iRegion.mImpl.mImpl);
// This will union all of the rectangles and runs in about O(n lg(n))
pixman_region32_init_rects(&iRegion.mImpl.mImpl, boxes, n);
return iRegion;
}
nsIntRegion nsRegion::ScaleToInsidePixels (float aScaleX, float aScaleY,