Bug 1321412 - Allow ShouldPrerenderTransformedContent() to override the dirty rect. r=mattwoodrow
☠☠ backed out by 2391b4ab6f37 ☠ ☠
authorBotond Ballo <botond@mozilla.com>
Wed, 23 Nov 2016 16:50:47 -0500
changeset 325546 94302209286e4102d8e1bea82102970d36fbbbad
parent 325545 964ff414c5607ed43a884fddba06694fac2a04a6
child 325547 9587048cd2ee1f0f0a424995b789ddb05ccbcd32
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersmattwoodrow
bugs1321412
milestone53.0a1
Bug 1321412 - Allow ShouldPrerenderTransformedContent() to override the dirty rect. r=mattwoodrow MozReview-Commit-ID: 5EpiANOynwP
layout/generic/nsFrame.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2204,20 +2204,19 @@ nsIFrame::BuildDisplayListForStackingCon
   AutoSaveRestoreContainsBlendMode autoRestoreBlendMode(*aBuilder);
   aBuilder->SetContainsBlendMode(false);
  
   nsRect dirtyRectOutsideTransform = dirtyRect;
   bool allowAsyncAnimation = false;
   if (isTransformed) {
     const nsRect overflow = GetVisualOverflowRectRelativeToSelf();
     nsDisplayTransform::PrerenderDecision decision =
-        nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, this);
+        nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, this, &dirtyRect);
     switch (decision) {
     case nsDisplayTransform::FullPrerender:
-      dirtyRect = overflow;
       allowAsyncAnimation = true;
       break;
     case nsDisplayTransform::NoPrerender:
       if (overflow.IsEmpty() && !extend3DContext) {
         return;
       }
 
       // If we're in preserve-3d then grab the dirty rect that was given to the root
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6223,17 +6223,18 @@ nsDisplayOpacity::CanUseAsyncAnimations(
 bool
 nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
 {
   return mAllowAsyncAnimation;
 }
 
 /* static */ auto
 nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
-                                                      nsIFrame* aFrame) -> PrerenderDecision
+                                                      nsIFrame* aFrame,
+                                                      nsRect* aDirtyRect) -> PrerenderDecision
 {
   // 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)) {
@@ -6246,23 +6247,24 @@ nsDisplayTransform::ShouldPrerenderTrans
   }
 
   nsSize refSize = aBuilder->RootReferenceFrame()->GetSize();
   // Only prerender if the transformed frame's size is <= the
   // reference frame size (~viewport), allowing a 1/8th fuzz factor
   // for shadows, borders, etc.
   refSize += nsSize(refSize.width / 8, refSize.height / 8);
   gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(aFrame);
-  nsSize frameSize = nsSize(
-    aFrame->GetVisualOverflowRectRelativeToSelf().Size().width * scale.width,
-    aFrame->GetVisualOverflowRectRelativeToSelf().Size().height * scale.height);
+  nsRect overflow = aFrame->GetVisualOverflowRectRelativeToSelf();
+  nsSize frameSize = nsSize(overflow.Size().width * scale.width,
+                            overflow.Size().height * scale.height);
   nscoord maxInAppUnits = nscoord_MAX;
   if (frameSize <= refSize) {
     maxInAppUnits = aFrame->PresContext()->DevPixelsToAppUnits(4096);
     if (frameSize <= nsSize(maxInAppUnits, maxInAppUnits)) {
+      *aDirtyRect = overflow;
       return FullPrerender;
     }
   }
 
   nsRect visual = aFrame->GetVisualOverflowRect();
 
 
   EffectCompositor::SetPerformanceWarning(
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -4278,19 +4278,21 @@ public:
   static Matrix4x4 GetResultingTransformMatrix(const FrameTransformProperties& aProperties,
                                                const nsPoint& aOrigin,
                                                float aAppUnitsPerPixel,
                                                uint32_t aFlags,
                                                const nsRect* aBoundsOverride = nullptr);
   /**
    * Return FullPrerender when we should try to prerender the entire contents of the
    * transformed frame even when it's not completely visible (yet).
+   * |aDirtyRect| is updated to the area that should be prerendered.
    */
   static PrerenderDecision ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
-                                                             nsIFrame* aFrame);
+                                                             nsIFrame* aFrame,
+                                                             nsRect* aDirtyRect);
   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
 
   bool MayBeAnimated(nsDisplayListBuilder* aBuilder);
 
   virtual void WriteDebugInfo(std::stringstream& aStream) override;
 
   // Force the layer created for this item not to extend 3D context.
   // See nsIFrame::BuildDisplayListForStackingContext()