Bug 1321412 - Add support for partial prerendering to ShouldPrerenderTransformedContent(). r=mattwoodrow

This is behind a pref and not enabled by default yet.

MozReview-Commit-ID: HKbP02PkdI9

--HG--
extra : rebase_source : 3f724f12d467dfb6e3ac1c44841e8e452a7d4b7e
This commit is contained in:
Botond Ballo 2016-12-14 14:31:20 -05:00
Родитель d806f521fb
Коммит 2e3caa982c
5 изменённых файлов: 29 добавлений и 2 удалений

Просмотреть файл

@ -529,6 +529,7 @@ private:
DECL_GFX_PREF(Live, "layers.draw-mask-debug", DrawMaskLayer, bool, false);
DECL_GFX_PREF(Live, "layers.geometry.opengl.enabled", OGLLayerGeometry, bool, false);
DECL_GFX_PREF(Live, "layout.animation.prerender.partial", PartiallyPrerenderAnimatedContent, bool, false);
DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-x", AnimationPrerenderViewportRatioLimitX, float, 1.125f);
DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-y", AnimationPrerenderViewportRatioLimitY, float, 1.125f);
DECL_GFX_PREF(Live, "layout.animation.prerender.absolute-limit-x", AnimationPrerenderAbsoluteLimitX, uint32_t, 4096);

Просмотреть файл

@ -2214,6 +2214,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
case nsDisplayTransform::FullPrerender:
allowAsyncAnimation = true;
break;
case nsDisplayTransform::PartialPrerender:
allowAsyncAnimation = true;
MOZ_FALLTHROUGH;
// fall through to the NoPrerender case
case nsDisplayTransform::NoPrerender:
if (overflow.IsEmpty() && !extend3DContext) {
return;

Просмотреть файл

@ -6226,6 +6226,20 @@ nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
return mAllowAsyncAnimation;
}
static nsRect ComputePartialPrerenderArea(const nsRect& aDirtyRect,
const nsRect& aOverflow,
const nsSize& aPrerenderSize)
{
// Simple calculation for now: center the pre-render area on the dirty rect,
// and clamp to the overflow area. Later we can do more advanced things like
// redistributing from one axis to another, or from one side to another.
nscoord xExcess = aPrerenderSize.width - aDirtyRect.width;
nscoord yExcess = aPrerenderSize.height - aDirtyRect.height;
nsRect result = aDirtyRect;
result.Inflate(xExcess / 2, yExcess / 2);
return result.MoveInsideAndClamp(aOverflow);
}
/* static */ auto
nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
@ -6266,6 +6280,9 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui
if (frameSize <= maxSize) {
*aDirtyRect = overflow;
return FullPrerender;
} else if (gfxPrefs::PartiallyPrerenderAnimatedContent()) {
*aDirtyRect = ComputePartialPrerenderArea(*aDirtyRect, overflow, maxSize);
return PartialPrerender;
}
EffectCompositor::SetPerformanceWarning(

Просмотреть файл

@ -4065,7 +4065,8 @@ class nsDisplayTransform: public nsDisplayItem
public:
enum PrerenderDecision {
NoPrerender,
FullPrerender
FullPrerender,
PartialPrerender
};
/**
@ -4281,8 +4282,11 @@ public:
uint32_t aFlags,
const nsRect* aBoundsOverride = nullptr);
/**
* Return FullPrerender when we should try to prerender the entire contents of the
* Decide whether we should prerender some or all of the contents of the
* transformed frame even when it's not completely visible (yet).
* Return FullPrerender if the entire contents should be prerendered,
* PartialPrerender if some but not all of the contents should be prerendered,
* or NoPrerender if only the visible area should be rendered.
* |aDirtyRect| is updated to the area that should be prerendered.
*/
static PrerenderDecision ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,

Просмотреть файл

@ -2738,6 +2738,7 @@ pref("dom.animations.offscreen-throttling", true);
// Prefs to control the maximum area to pre-render when animating a large
// element on the compositor.
pref("layout.animation.prerender.partial", false);
pref("layout.animation.prerender.viewport-ratio-limit-x", "1.125");
pref("layout.animation.prerender.viewport-ratio-limit-y", "1.125");
pref("layout.animation.prerender.absolute-limit-x", 4096);