Bug 1462497 - Part 3: Don't condition useOpacity on values that might change silently between paints (HasAnimationsForCompositor, and the will-change budget). r?hiro draft
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 23 May 2018 11:03:42 +1200
changeset 798506 7a87b6abea456fbe857c9ca32079738e7497eb47
parent 798505 cdf1414bc42159f134b9d38b84fbf1830b5d0bb0
child 798507 f5612c87518b07ded05859db2a07e4f6e6921db2
push id110767
push usermwoodrow@mozilla.com
push dateTue, 22 May 2018 23:04:45 +0000
reviewershiro
bugs1462497
milestone62.0a1
Bug 1462497 - Part 3: Don't condition useOpacity on values that might change silently between paints (HasAnimationsForCompositor, and the will-change budget). r?hiro MozReview-Commit-ID: Kry5YIAIAHt
layout/generic/nsFrame.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2949,19 +2949,22 @@ nsIFrame::BuildDisplayListForStackingCon
     aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage);
   }
 
   // We build an opacity item if it's not going to be drawn by SVG content, or
   // SVG effects. SVG effects won't handle the opacity if we want an active
   // layer (for async animations), see
   // nsSVGIntegrationsUtils::PaintMaskAndClipPath or
   // nsSVGIntegrationsUtils::PaintFilter.
+  // Use MayNeedActiveLayer to decide, since we don't want to condition the wrapping
+  // display item on values that might change silently between paints (opacity activity
+  // can depend on the will-change budget).
   bool useOpacity = HasVisualOpacity(effectSet) &&
                     !nsSVGUtils::CanOptimizeOpacity(this) &&
-                    (!usingSVGEffects || nsDisplayOpacity::NeedsActiveLayer(aBuilder, this));
+                    (!usingSVGEffects || nsDisplayOpacity::MayNeedActiveLayer(this));
   bool useBlendMode = effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL;
   bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY &&
     IsScrollFrameActive(aBuilder,
                         nsLayoutUtils::GetNearestScrollableFrame(GetParent(),
                         nsLayoutUtils::SCROLLABLE_SAME_DOC |
                         nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN));
   bool useFixedPosition = disp->mPosition == NS_STYLE_POSITION_FIXED &&
     (nsLayoutUtils::IsFixedPosFrameInDisplayPort(this) || BuilderHasScrolledClip(aBuilder));
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6521,16 +6521,22 @@ nsDisplayOpacity::NeedsActiveLayer(nsDis
       (ActiveLayerTracker::IsStyleAnimated(aBuilder, aFrame,
                                            eCSSProperty_opacity) &&
        !IsItemTooSmallForActiveLayer(aFrame))) {
     return true;
   }
   return false;
 }
 
+/* static */ bool
+nsDisplayOpacity::MayNeedActiveLayer(nsIFrame* aFrame)
+{
+  return ActiveLayerTracker::IsStyleMaybeAnimated(aFrame, eCSSProperty_opacity);
+}
+
 void
 nsDisplayOpacity::ApplyOpacity(nsDisplayListBuilder* aBuilder,
                              float aOpacity,
                              const DisplayItemClipChain* aClip)
 {
   NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
   mOpacity = mOpacity * aOpacity;
   IntersectClip(aBuilder, aClip, false);
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -5381,16 +5381,17 @@ public:
   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
 
   /**
    * Returns true if ShouldFlattenAway() applied opacity to children.
    */
   bool OpacityAppliedToChildren() const { return mOpacityAppliedToChildren; }
 
   static bool NeedsActiveLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
+  static bool MayNeedActiveLayer(nsIFrame* aFrame);
   NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
   virtual void WriteDebugInfo(std::stringstream& aStream) override;
 
   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
 
   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
                                        const StackingContextHelper& aSc,