Bug 1024126 - Fix rounding errors and add a danger zone to the B2G AboutToCheckerboard heuristic function. r=Cwiiis

This commit is contained in:
Kartikaya Gupta 2014-06-23 20:54:32 -04:00
parent 6251dc1051
commit 1ad2e6330b
3 changed files with 39 additions and 7 deletions

View File

@ -160,6 +160,20 @@ typedef GeckoContentController::APZStateChange APZStateChange;
* "apz.cross_slide_enabled"
* Pref that enables integration with the Metro "cross-slide" gesture.
*
* "apz.danger_zone_x"
* "apz.danger_zone_y"
* When drawing high-res tiles, we drop down to drawing low-res tiles
* when we know we can't keep up with the scrolling. The way we determine
* this is by checking if we are entering the "danger zone", which is the
* boundary of the painted content. For example, if the painted content
* goes from y=0...1000 and the visible portion is y=250...750 then
* we're far from checkerboarding. If we get to y=490...990 though then we're
* only 10 pixels away from showing checkerboarding so we are probably in
* a state where we can't keep up with scrolling. The danger zone prefs specify
* how wide this margin is; in the above example a y-axis danger zone of 10
* pixels would make us drop to low-res at y=490...990.
* This value is in layer pixels.
*
* "apz.enlarge_displayport_when_clipped"
* Pref that enables enlarging of the displayport along one axis when the
* generated displayport's size is beyond that of the scrollable rect on the

View File

@ -249,13 +249,29 @@ bool
SharedFrameMetricsHelper::AboutToCheckerboard(const FrameMetrics& aContentMetrics,
const FrameMetrics& aCompositorMetrics)
{
CSSRect painted =
(aContentMetrics.mCriticalDisplayPort.IsEmpty() ? aContentMetrics.mDisplayPort : aContentMetrics.mCriticalDisplayPort)
+ aContentMetrics.GetScrollOffset();
// Inflate painted by some small epsilon to deal with rounding
// error. We should replace this with a FuzzyContains function.
painted.Inflate(0.01f);
CSSRect showing = CSSRect(aCompositorMetrics.GetScrollOffset(), aCompositorMetrics.CalculateBoundedCompositedSizeInCssPixels());
// The size of the painted area is originally computed in layer pixels in layout, but then
// converted to app units and then back to CSS pixels before being put in the FrameMetrics.
// This process can introduce some rounding error, so we inflate the rect by one app unit
// to account for that.
CSSRect painted = (aContentMetrics.mCriticalDisplayPort.IsEmpty()
? aContentMetrics.mDisplayPort
: aContentMetrics.mCriticalDisplayPort)
+ aContentMetrics.GetScrollOffset();
painted.Inflate(CSSMargin::FromAppUnits(nsMargin(1, 1, 1, 1)));
// Inflate the rect by the danger zone. See the description of the danger zone prefs
// in AsyncPanZoomController.cpp for an explanation of this.
CSSRect showing = CSSRect(aCompositorMetrics.GetScrollOffset(),
aCompositorMetrics.CalculateBoundedCompositedSizeInCssPixels());
showing.Inflate(LayerSize(gfxPrefs::APZDangerZoneX(), gfxPrefs::APZDangerZoneY())
/ aCompositorMetrics.LayersPixelsPerCSSPixel());
// Clamp both rects to the scrollable rect, because having either of those
// exceed the scrollable rect doesn't make sense, and could lead to false
// positives.
painted = painted.Intersect(aContentMetrics.mScrollableRect);
showing = showing.Intersect(aContentMetrics.mScrollableRect);
return !painted.Contains(showing);
}

View File

@ -110,6 +110,8 @@ private:
DECL_GFX_PREF(Live, "apz.axis_lock_mode", APZAxisLockMode, int32_t, 0);
DECL_GFX_PREF(Live, "apz.content_response_timeout", APZContentResponseTimeout, int32_t, 300);
DECL_GFX_PREF(Live, "apz.cross_slide.enabled", APZCrossSlideEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.danger_zone_x", APZDangerZoneX, int32_t, 50);
DECL_GFX_PREF(Live, "apz.danger_zone_y", APZDangerZoneY, int32_t, 100);
DECL_GFX_PREF(Live, "apz.enlarge_displayport_when_clipped", APZEnlargeDisplayPortWhenClipped, bool, false);
DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms", APZFlingAccelInterval, int32_t, 500);
DECL_GFX_PREF(Live, "apz.fling_accel_base_mult", APZFlingAccelBaseMultiplier, float, 1.0f);