Bug 1321412 - Allow ShouldPrerenderTransformedContent() to override the dirty rect. r=mattwoodrow
authorBotond Ballo <botond@mozilla.com>
Wed, 23 Nov 2016 16:50:47 -0500
changeset 325956 2f289f029b733c832833e487197d4fb426702e8f
parent 325955 f9b9c558f02a94f31e38efbf73d80ef37174599d
child 325957 925e1dc46a402bdfb7cda98461b49976393a2ff3
push id84847
push usercbook@mozilla.com
push dateThu, 15 Dec 2016 13:25:18 +0000
treeherdermozilla-inbound@85a362b51c44 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1321412
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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()