Bug 779598 - Prerender descendant frames in prerendered preserve-3d frame. r?mattwoodrow
MozReview-Commit-ID: 819nIPeNIh4
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1643,16 +1643,39 @@ nsIFrame::In3DContextAndBackfaceIsHidden
// While both tests fail most of the time, test BackfaceIsHidden()
// first since it's likely to fail faster.
const nsStyleDisplay* disp = StyleDisplay();
return BackfaceIsHidden(disp) &&
Combines3DTransformWithAncestors(disp);
}
bool
+nsIFrame::IsInPrerendered3DContext(nsDisplayListBuilder* aBuilder) const
+{
+ if (!Combines3DTransformWithAncestors()) {
+ return false;
+ }
+
+ nsIFrame* parent = GetInFlowParent();
+ MOZ_ASSERT(parent && parent->Extend3DContext());
+
+ DisplayItemDataArray& array = parent->DisplayItemData();
+ for (auto data: array) {
+ DisplayItemData::AssertDisplayItemData(data);
+ if (data->GetItem() &&
+ data->GetItem()->CanUseAsyncAnimations(aBuilder) &&
+ data->GetDisplayItemKey() ==
+ static_cast<uint32_t>(DisplayItemType::TYPE_TRANSFORM)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
nsIFrame::HasPerspective(const nsStyleDisplay* aStyleDisplay) const
{
MOZ_ASSERT(aStyleDisplay == StyleDisplay());
if (!IsTransformed(aStyleDisplay)) {
return false;
}
nsIFrame* containingBlock = GetContainingBlock(SKIP_SCROLLED_FRAME, aStyleDisplay);
if (!containingBlock) {
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1854,16 +1854,21 @@ public:
mozilla::EffectSet* aEffectSet = nullptr) const {
return Combines3DTransformWithAncestors(aStyleDisplay) &&
!Extend3DContext(aStyleDisplay, aEffectSet);
}
bool IsPreserve3DLeaf(mozilla::EffectSet* aEffectSet = nullptr) const {
return IsPreserve3DLeaf(StyleDisplay(), aEffectSet);
}
+ /**
+ * Returns true if this frame is a child of prerendered preserve-3d frame.
+ */
+ bool IsInPrerendered3DContext(nsDisplayListBuilder* aBuilder) const;
+
bool HasPerspective(const nsStyleDisplay* aStyleDisplay) const;
bool HasPerspective() const {
return HasPerspective(StyleDisplay());
}
bool ChildrenHavePerspective(const nsStyleDisplay* aStyleDisplay) const;
bool ChildrenHavePerspective() const {
return ChildrenHavePerspective(StyleDisplay());
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8022,16 +8022,20 @@ nsDisplayTransform::CanUseAsyncAnimation
return mAllowAsyncAnimation;
}
/* static */ auto
nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsRect* aDirtyRect) -> PrerenderDecision
{
+ // Prerender if the frame is a child of prerendered preserve-3d context.
+ if (aFrame->IsInPrerendered3DContext(aBuilder)) {
+ return FullPrerender;
+ }
// Elements whose transform has been modified recently, or which
// have a compositor-animated transform, can be prerendered. An element
// might have only just had its transform animated in which case
// the ActiveLayerManager may not have been notified yet.
if (!ActiveLayerTracker::IsStyleMaybeAnimated(aFrame, eCSSProperty_transform) &&
!EffectCompositor::HasAnimationsForCompositor(aFrame,
eCSSProperty_transform)) {
EffectCompositor::SetPerformanceWarning(