Bug 1234485 - Part 2. Determine nsDisplayMask layer state. draft
authorcku <cku@mozilla.com>
Tue, 18 Oct 2016 17:46:25 +0800
changeset 426556 3d7b935fa0a7626c3fae933dc407a676b09be342
parent 426555 43550c353a02324af12852664dba6de1bb4ca295
child 426557 cadab115d570137eccf5cc4314bc74a7f88e87d2
push id32740
push userbmo:cku@mozilla.com
push dateTue, 18 Oct 2016 18:13:24 +0000
bugs1234485
milestone52.0a1
Bug 1234485 - Part 2. Determine nsDisplayMask layer state. MozReview-Commit-ID: Fu2DWreaNYO
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2843,67 +2843,68 @@ nsDisplayBackgroundImage::GetDestRect()
 
 already_AddRefed<imgIContainer>
 nsDisplayBackgroundImage::GetImage()
 {
   nsCOMPtr<imgIContainer> image = mImage;
   return image.forget();
 }
 
-nsDisplayBackgroundImage::ImageLayerization
+ImageLayerization
 nsDisplayBackgroundImage::ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
                                                LayerManager* aManager)
 {
   nsIFrame* backgroundStyleFrame = nsCSSRendering::FindBackgroundStyleFrame(mFrame);
   if (ActiveLayerTracker::IsBackgroundPositionAnimated(aBuilder,
                                                        backgroundStyleFrame)) {
-    return WHENEVER_POSSIBLE;
+    return ImageLayerization::WHENEVER_POSSIBLE;
   }
 
   if (nsLayoutUtils::AnimatedImageLayersEnabled() && mBackgroundStyle) {
     const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mImage.mLayers[mLayer];
     const nsStyleImage* image = &layer.mImage;
     if (image->GetType() == eStyleImageType_Image) {
       imgIRequest* imgreq = image->GetImageData();
       nsCOMPtr<imgIContainer> image;
       if (NS_SUCCEEDED(imgreq->GetImage(getter_AddRefs(image))) && image) {
         bool animated = false;
         if (NS_SUCCEEDED(image->GetAnimated(&animated)) && animated) {
-          return WHENEVER_POSSIBLE;
+          return ImageLayerization::WHENEVER_POSSIBLE;
         }
       }
     }
   }
 
   if (nsLayoutUtils::GPUImageScalingEnabled() &&
       aManager->IsCompositingCheap()) {
-    return ONLY_FOR_SCALING;
-  }
-
-  return NO_LAYER_NEEDED;
+    return ImageLayerization::ONLY_FOR_SCALING;
+  }
+
+  return ImageLayerization::NO_LAYER_NEEDED;
 }
 
 LayerState
 nsDisplayBackgroundImage::GetLayerState(nsDisplayListBuilder* aBuilder,
                                         LayerManager* aManager,
                                         const ContainerLayerParameters& aParameters)
 {
   ImageLayerization shouldLayerize = ShouldCreateOwnLayer(aBuilder, aManager);
-  if (shouldLayerize == NO_LAYER_NEEDED) {
+  if (shouldLayerize == ImageLayerization::NO_LAYER_NEEDED) {
     // We can skip the call to CanOptimizeToImageLayer if we don't want a
     // layer anyway.
     return LAYER_NONE;
   }
 
   if (CanOptimizeToImageLayer(aManager, aBuilder)) {
-    if (shouldLayerize == WHENEVER_POSSIBLE) {
+    if (shouldLayerize == ImageLayerization::WHENEVER_POSSIBLE) {
       return LAYER_ACTIVE;
     }
 
-    MOZ_ASSERT(shouldLayerize == ONLY_FOR_SCALING, "unhandled ImageLayerization value?");
+    MOZ_ASSERT(shouldLayerize == ImageLayerization::ONLY_FOR_SCALING,
+               "unhandled ImageLayerization value?");
 
     MOZ_ASSERT(mImage);
     int32_t imageWidth;
     int32_t imageHeight;
     mImage->GetWidth(&imageWidth);
     mImage->GetHeight(&imageHeight);
     NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
   
@@ -7038,22 +7039,37 @@ nsDisplayMask::BuildLayer(nsDisplayListB
 
   RefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
                            aContainerParameters, nullptr);
 
   return container.forget();
 }
 
+ImageLayerization
+nsDisplayMask::ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
+                                               LayerManager* aManager)
+{
+  nsIFrame* firstFrame =
+    nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
+  if (ActiveLayerTracker::IsMaskPositionAnimated(aBuilder, firstFrame)) {
+    return ImageLayerization::WHENEVER_POSSIBLE;
+  }
+
+  return ImageLayerization::NO_LAYER_NEEDED;
+}
+
 LayerState
 nsDisplayMask::GetLayerState(nsDisplayListBuilder* aBuilder,
                              LayerManager* aManager,
                              const ContainerLayerParameters& aParameters)
 {
-  return LAYER_SVG_EFFECTS;
+  ImageLayerization shouldLayerize = ShouldCreateOwnLayer(aBuilder, aManager);
+  return (shouldLayerize == ImageLayerization::WHENEVER_POSSIBLE)
+         ? LAYER_ACTIVE : LAYER_SVG_EFFECTS;
 }
 
 bool nsDisplayMask::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                       nsRegion* aVisibleRegion)
 {
   // Our children may be made translucent or arbitrarily deformed so we should
   // not allow them to subtract area from aVisibleRegion.
   nsRegion childrenVisible(mVisibleRect);
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2702,16 +2702,23 @@ protected:
 
   NS_DISPLAY_DECL_NAME("SolidColorRegion", TYPE_SOLID_COLOR_REGION)
 
 private:
   nsRegion mRegion;
   Color mColor;
 };
 
+// Determine whether we want to be separated into our own layer, independent
+// of whether this item can actually be layerized.
+enum class ImageLayerization : uint32_t {
+  WHENEVER_POSSIBLE,
+  ONLY_FOR_SCALING,
+  NO_LAYER_NEEDED
+};
 /**
  * A display item to paint one background-image for a frame. Each background
  * image layer gets its own nsDisplayBackgroundImage.
  */
 class nsDisplayBackgroundImage : public nsDisplayImageContainer {
 public:
   /**
    * aLayer signifies which background layer this item represents.
@@ -2802,23 +2809,16 @@ protected:
   bool IsNonEmptyFixedImage() const;
   nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder);
   bool ShouldTreatAsFixed() const;
   bool ComputeShouldTreatAsFixed(bool isTransformedFixed) const;
 
   void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
                      const nsRect& aBounds, nsRect* aClipRect);
 
-  // Determine whether we want to be separated into our own layer, independent
-  // of whether this item can actually be layerized.
-  enum ImageLayerization {
-    WHENEVER_POSSIBLE,
-    ONLY_FOR_SCALING,
-    NO_LAYER_NEEDED
-  };
   ImageLayerization ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
                                          LayerManager* aManager);
 
   // Cache the result of nsCSSRendering::FindBackground. Always null if
   // mIsThemed is true or if FindBackground returned false.
   const nsStyleBackground* mBackgroundStyle;
   nsCOMPtr<imgIContainer> mImage;
   nsRect mBackgroundRect; // relative to the reference frame
@@ -3912,16 +3912,18 @@ public:
                     nsRenderingContext* aCtx,
                     LayerManager* aManager);
 
   const nsTArray<nsRect>& GetDestRects()
   {
     return mDestRects;
   }
 private:
+  ImageLayerization ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
+                                         LayerManager* aManager);
   nsTArray<nsRect> mDestRects;
 };
 
 /**
  * A display item to paint a stacking context with filter effects set by the
  * stacking context root frame's style.
  */
 class nsDisplayFilter : public nsDisplaySVGEffects {