Bug 1165185 - Try to avoid invalidations when scrolling transformed elements. r=roc

This commit is contained in:
Markus Stange 2015-06-15 19:20:59 -04:00
parent 6a928e0e83
commit 2e0f2286ad
9 changed files with 161 additions and 12 deletions

View File

@ -13,6 +13,7 @@
#include <math.h>
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/FloatingPoint.h"
namespace mozilla {
namespace gfx {
@ -857,6 +858,26 @@ public:
gfx::FuzzyEqual(_43, o._43) && gfx::FuzzyEqual(_44, o._44);
}
bool FuzzyEqualsMultiplicative(const Matrix4x4& o) const
{
return ::mozilla::FuzzyEqualsMultiplicative(_11, o._11) &&
::mozilla::FuzzyEqualsMultiplicative(_12, o._12) &&
::mozilla::FuzzyEqualsMultiplicative(_13, o._13) &&
::mozilla::FuzzyEqualsMultiplicative(_14, o._14) &&
::mozilla::FuzzyEqualsMultiplicative(_21, o._21) &&
::mozilla::FuzzyEqualsMultiplicative(_22, o._22) &&
::mozilla::FuzzyEqualsMultiplicative(_23, o._23) &&
::mozilla::FuzzyEqualsMultiplicative(_24, o._24) &&
::mozilla::FuzzyEqualsMultiplicative(_31, o._31) &&
::mozilla::FuzzyEqualsMultiplicative(_32, o._32) &&
::mozilla::FuzzyEqualsMultiplicative(_33, o._33) &&
::mozilla::FuzzyEqualsMultiplicative(_34, o._34) &&
::mozilla::FuzzyEqualsMultiplicative(_41, o._41) &&
::mozilla::FuzzyEqualsMultiplicative(_42, o._42) &&
::mozilla::FuzzyEqualsMultiplicative(_43, o._43) &&
::mozilla::FuzzyEqualsMultiplicative(_44, o._44);
}
bool IsBackfaceVisible() const
{
// Inverse()._33 < 0;
@ -889,6 +910,24 @@ public:
return *this;
}
// Nudge the 3D components to integer so that this matrix will become 2D if
// it's very close to already being 2D.
// This doesn't change the _41 and _42 components.
Matrix4x4 &NudgeTo2D()
{
NudgeToInteger(&_13);
NudgeToInteger(&_14);
NudgeToInteger(&_23);
NudgeToInteger(&_24);
NudgeToInteger(&_31);
NudgeToInteger(&_32);
NudgeToInteger(&_33);
NudgeToInteger(&_34);
NudgeToInteger(&_43);
NudgeToInteger(&_44);
return *this;
}
Point4D TransposedVector(int aIndex) const
{
MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");

View File

@ -136,7 +136,7 @@ struct LayerPropertiesBase : public LayerProperties
nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
bool transformChanged = !mTransform.FuzzyEqual(mLayer->GetLocalTransform()) ||
bool transformChanged = !mTransform.FuzzyEqualsMultiplicative(mLayer->GetLocalTransform()) ||
mLayer->GetPostXScale() != mPostXScale ||
mLayer->GetPostYScale() != mPostYScale;
Layer* otherMask = mLayer->GetMaskLayer();

View File

@ -4630,12 +4630,13 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
if (aTransform) {
// aTransform is applied first, then the scale is applied to the result
transform = (*aTransform)*transform;
// Set any matrix entries close to integers to be those exact integers.
// This protects against floating-point inaccuracies causing problems
// in the checks below.
// We use the fixed epsilon version here because we don't want the nudging
// to depend on the scroll position.
transform.NudgeToIntegersFixedEpsilon();
// Set relevant 3d matrix entries that are close to integers to be those
// exact integers. This protects against floating-point inaccuracies
// causing problems in the CanDraw2D / Is2D checks below.
// We don't nudge all matrix components here. In particular, we don't want to
// nudge the X/Y translation components, because those include the scroll
// offset, and we don't want scrolling to affect whether we nudge or not.
transform.NudgeTo2D();
}
Matrix transform2d;
if (aContainerFrame &&

View File

@ -3,11 +3,10 @@
== wide--contain--height.html ref-wide-empty.html
== wide--contain--width.html ref-wide-empty.html
# These tests fail because of integer overflow; see bug 894555.
fails == tall--cover--height.html ref-tall-lime.html
fails == tall--cover--width.html ref-tall-lime.html
fails == wide--cover--height.html ref-wide-lime.html
fails == wide--cover--width.html ref-wide-lime.html
== tall--cover--height.html ref-tall-lime.html
== tall--cover--width.html ref-tall-lime.html
== wide--cover--height.html ref-wide-lime.html
== wide--cover--width.html ref-wide-lime.html
== zero-height-ratio-contain.html ref-tall-empty.html
== zero-height-ratio-cover.html ref-tall-empty.html

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Scrolling shouldn't invalidate either rect.</title>
<style>
body {
margin: 0;
height: 5000px;
}
</style>
<body>
<svg width="768" height="1000">
<g transform="translate(0 -2000.3234)">
<rect x="100" y="2300" height="50" width="50" fill="grey" class="reftest-no-paint"/>
</g>
<g transform="translate(0 -4000.6468)">
<rect x="200" y="4300" height="50" width="50" fill="grey" class="reftest-no-paint"/>
</g>
</svg>
<script>
document.documentElement.scrollTop = 177;
window.addEventListener("MozReftestInvalidate", function (e) {
document.documentElement.scrollTop = 30;
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Scrolling shouldn't invalidate the square.</title>
<style>
body {
margin: 0;
height: 5000px;
}
</style>
<body>
<svg width="768" height="1000">
<g transform="translate(0 112.152992)">
<rect x="100" y="650" height="50" width="50" fill="grey" class="reftest-no-paint"/>
</g>
</svg>
<script>
document.documentElement.scrollTop = 709;
window.addEventListener("MozReftestInvalidate", function (e) {
document.documentElement.scrollTop = 617;
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Scrolling shouldn't invalidate the square.</title>
<style>
body {
margin: 0;
height: 5000px;
}
</style>
<body>
<svg width="768" height="1000">
<g transform="translate(0 0.999948799610138)">
<rect x="100" y="100" height="50" width="50" fill="grey" class="reftest-no-paint"/>
</g>
</svg>
<script>
document.documentElement.scrollTop = 11;
window.addEventListener("MozReftestInvalidate", function (e) {
document.documentElement.scrollTop = 51;
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -67,3 +67,6 @@ pref(layout.animated-image-layers.enabled,true) skip-if(Android||gtkWidget) == t
fuzzy-if(gtkWidget,2,4) == image-scrolling-zoom-1.html image-scrolling-zoom-1-ref.html
!= image-scrolling-zoom-1-ref.html image-scrolling-zoom-1-notref.html
!= fast-scrolling.html about:blank
!= fractional-transform-1.html about:blank
!= fractional-transform-2.html about:blank
!= fractional-transform-3.html about:blank

View File

@ -401,6 +401,13 @@ FuzzyEqualsMultiplicative(T aValue1, T aValue2,
T aEpsilon = detail::FuzzyEqualsEpsilon<T>::value())
{
static_assert(IsFloatingPoint<T>::value, "floating point type required");
// Short-circuit the common case in order to avoid the expensive operations
// below.
if (aValue1 == aValue2) {
return true;
}
// can't use std::min because of bug 965340
T smaller = Abs(aValue1) < Abs(aValue2) ? Abs(aValue1) : Abs(aValue2);
return Abs(aValue1 - aValue2) <= aEpsilon * smaller;