Bug 671302 - Avoid passing large offsets into pixman when drawing repeated background images. r=roc

This commit is contained in:
Markus Stange 2014-07-18 11:48:38 +02:00
parent bda3068dd1
commit df4a87e861
6 changed files with 78 additions and 15 deletions

View File

@ -607,17 +607,7 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
// On Mobile, we don't ever want to do this; it has the potential for
// allocating very large temporary surfaces, especially since we'll
// do full-page snapshots often (see bug 749426).
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
// If the pattern translation is large we can get into trouble with pixman's
// 16 bit coordinate limits. For now, we only do this on platforms where
// we know we have the pixman limits. 16384.0 is a somewhat arbitrary
// large number to make sure we avoid the expensive fmod when we can, but
// still maintain a safe margin from the actual limit
if (doTile && (userSpaceToImageSpace._32 > 16384.0 || userSpaceToImageSpace._31 > 16384.0)) {
userSpaceToImageSpace._31 = fmod(userSpaceToImageSpace._31, aImageRect.width);
userSpaceToImageSpace._32 = fmod(userSpaceToImageSpace._32, aImageRect.height);
}
#else
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
// OK now, the hard part left is to account for the subimage sampling
// restriction. If all the transforms involved are just integer
// translations, then we assume no resampling will occur so there's

View File

@ -4909,6 +4909,14 @@ struct SnappedImageDrawingParameters {
{}
};
static nsRect
TileNearRect(const nsRect& aAnyTile, const nsRect& aTargetRect)
{
nsPoint distance = aTargetRect.TopLeft() - aAnyTile.TopLeft();
return aAnyTile + nsPoint(distance.x / aAnyTile.width * aAnyTile.width,
distance.y / aAnyTile.height * aAnyTile.height);
}
/**
* Given a set of input parameters, compute certain output parameters
* for drawing an image with the image snapping algorithm.
@ -4929,8 +4937,13 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx,
if (aDest.IsEmpty() || aFill.IsEmpty() || !aImageSize.width || !aImageSize.height)
return SnappedImageDrawingParameters();
// Avoid unnecessarily large offsets.
bool doTile = !aDest.Contains(aFill);
nsRect dest = doTile ? TileNearRect(aDest, aFill.Intersect(aDirty)) : aDest;
nsPoint anchor = aAnchor + (dest.TopLeft() - aDest.TopLeft());
gfxRect devPixelDest =
nsLayoutUtils::RectToGfxRect(aDest, aAppUnitsPerDevPixel);
nsLayoutUtils::RectToGfxRect(dest, aAppUnitsPerDevPixel);
gfxRect devPixelFill =
nsLayoutUtils::RectToGfxRect(aFill, aAppUnitsPerDevPixel);
gfxRect devPixelDirty =
@ -4970,8 +4983,8 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx,
// Compute the anchor point and compute final fill rect.
// This code assumes that pixel-based devices have one pixel per
// device unit!
gfxPoint anchorPoint(gfxFloat(aAnchor.x)/aAppUnitsPerDevPixel,
gfxFloat(aAnchor.y)/aAppUnitsPerDevPixel);
gfxPoint anchorPoint(gfxFloat(anchor.x)/aAppUnitsPerDevPixel,
gfxFloat(anchor.y)/aAppUnitsPerDevPixel);
gfxPoint imageSpaceAnchorPoint =
MapToFloatImagePixels(imageSize, devPixelDest, anchorPoint);

View File

@ -0,0 +1,17 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<title>Make sure that repeated background images are painted even at extreme scroll positions</title>
<style>
html {
background-image: url(green-8x20-blue-8x20-vertical.png);
overflow: hidden;
}
</style>

View File

@ -0,0 +1,42 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Make sure that repeated background images are painted even at extreme scroll positions</title>
<!-- See https://bugzilla.mozilla.org/show_bug.cgi?id=671302 -->
<style>
html {
background-image: url(green-8x20-blue-8x20-vertical.png);
overflow: hidden;
}
html, body {
margin: 0;
}
body {
height: 100000px;
}
div {
height: 1000px;
background-color: red;
}
</style>
<div></div>
<script>
window.addEventListener("MozReftestInvalidate", function () {
document.documentElement.scrollTop = 16 * 3000; // = 48000 > 32768
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -160,3 +160,4 @@ fails-if(Android&&AndroidVersion==15) == attachment-local-clipping-image-5.html
fails-if(Android&&AndroidVersion==15) fuzzy-if(!Android||(Android&&AndroidVersion!=15),80,500) == attachment-local-clipping-image-6.html attachment-local-clipping-image-6-ref.html #Bug 959165
== background-multiple-with-border-radius.html background-multiple-with-border-radius-ref.html
== background-repeat-large-area.html background-repeat-large-area-ref.html

View File

@ -24,7 +24,7 @@ fuzzy-if(B2G,1,5) fuzzy-if(gtk2Widget,1,32) fuzzy-if(cocoaWidget,1,106) == eleme
== element-paint-sharpness-01b.html element-paint-sharpness-01c.html
== element-paint-sharpness-01c.html element-paint-sharpness-01d.html
== element-paint-sharpness-02a.html element-paint-sharpness-02b.html
== element-paint-sharpness-02b.html element-paint-sharpness-02c.html
fuzzy-if(B2G,11,4) == element-paint-sharpness-02b.html element-paint-sharpness-02c.html
== element-paint-paintserversize-rounding-01.html element-paint-paintserversize-rounding-01-ref.html
== element-paint-paintserversize-rounding-02.html element-paint-paintserversize-rounding-02-ref.html
== element-paint-multiple-backgrounds-01a.html element-paint-multiple-backgrounds-01-ref.html