Bug 755078 - Disable mask layers on Android. r=roc
authorNicholas Cameron <ncameron@mozilla.com>
Thu, 17 May 2012 10:30:10 +1200
changeset 94162 9a5020492b65fd47a55b6e56c328eca9ef797159
parent 94161 c5e203fd9ff973e404f6c345194b58e6274af7c7
child 94163 5e3bd5a8cb3ba49ab67f30d5a39aa3316a754994
push id9502
push userryanvm@gmail.com
push dateThu, 17 May 2012 00:17:21 +0000
treeherdermozilla-inbound@9a5020492b65 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs755078
milestone15.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 755078 - Disable mask layers on Android. r=roc
gfx/layers/Layers.h
layout/base/FrameLayerBuilder.cpp
layout/generic/nsGfxScrollFrame.cpp
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -60,16 +60,18 @@
 #  define MOZ_LAYERS_HAVE_LOG
 #  define MOZ_LAYERS_LOG(_args)                             \
   PR_LOG(LayerManager::GetLog(), PR_LOG_DEBUG, _args)
 #else
 struct PRLogModuleInfo;
 #  define MOZ_LAYERS_LOG(_args)
 #endif  // if defined(DEBUG) || defined(PR_LOGGING)
 
+#define MOZ_ENABLE_MASK_LAYERS
+
 class gfxContext;
 class nsPaintEvent;
 
 namespace mozilla {
 namespace gl {
 class GLContext;
 }
 
@@ -714,27 +716,29 @@ public:
    * Currently, only 2D translations are supported for the mask layer transform.
    *
    * Ownership of aMaskLayer passes to this.
    * Typical use would be an ImageLayer with an alpha image used for masking.
    * See also ContainerState::BuildMaskLayer in FrameLayerBuilder.cpp.
    */
   void SetMaskLayer(Layer* aMaskLayer)
   {
+#ifdef MOZ_ENABLE_MASK_LAYERS
 #ifdef DEBUG
     if (aMaskLayer) {
       gfxMatrix maskTransform;
       bool maskIs2D = aMaskLayer->GetTransform().CanDraw2D(&maskTransform);
       NS_ASSERTION(maskIs2D && maskTransform.HasOnlyIntegerTranslation(),
                    "Mask layer has invalid transform.");
     }
 #endif
 
     mMaskLayer = aMaskLayer;
     Mutated();
+#endif
   }
 
   /**
    * CONSTRUCTION PHASE ONLY
    * Tell this layer what its transform should be. The transformation
    * is applied when compositing the layer into its parent container.
    * XXX Currently only transformations corresponding to 2D affine transforms
    * are supported.
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -1157,17 +1157,21 @@ ContainerState::ThebesLayerData::UpdateC
     // first item in the layer
     mCommonClipCount = aCurrentClip.mRoundedClipRects.Length();
   } 
 }
 
 already_AddRefed<ImageContainer>
 ContainerState::ThebesLayerData::CanOptimizeImageLayer()
 {
+#ifdef MOZ_ENABLE_MASK_LAYERS
   if (!mImage) {
+#else
+  if (!mImage || !mItemClip.mRoundedClipRects.IsEmpty()) {
+#endif
     return nsnull;
   }
 
   return mImage->GetContainer();
 }
 
 void
 ContainerState::PopThebesLayerData()
@@ -1187,16 +1191,20 @@ ContainerState::PopThebesLayerData()
     if (imageContainer) {
       nsRefPtr<ImageLayer> imageLayer = CreateOrRecycleImageLayer();
       imageLayer->SetContainer(imageContainer);
       data->mImage->ConfigureLayer(imageLayer);
       // The layer's current transform is applied first, then the result is scaled.
       gfx3DMatrix transform = imageLayer->GetTransform()*
         gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f);
       imageLayer->SetTransform(transform);
+#ifndef MOZ_ENABLE_MASK_LAYERS
+      NS_ASSERTION(data->mItemClip.mRoundedClipRects.IsEmpty(),
+                   "How did we get rounded clip rects here?");
+#endif
       if (data->mItemClip.mHaveClipRect) {
         nsIntRect clip = ScaleToNearestPixels(data->mItemClip.mClipRect);
         imageLayer->IntersectClipRect(clip);
       }
       layer = imageLayer;
     } else {
       nsRefPtr<ColorLayer> colorLayer = CreateOrRecycleColorLayer();
       colorLayer->SetIsFixedPosition(data->mLayer->GetIsFixedPosition());
@@ -1268,27 +1276,29 @@ ContainerState::PopThebesLayerData()
     NS_ASSERTION(userData, "where did our user data go?");
     if (userData->mForcedBackgroundColor != backgroundColor) {
       // Invalidate the entire target ThebesLayer since we're changing
       // the background color
       data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion());
     }
     userData->mForcedBackgroundColor = backgroundColor;
 
+#ifdef MOZ_ENABLE_MASK_LAYERS
     // use a mask layer for rounded rect clipping
     PRInt32 commonClipCount = data->mCommonClipCount;
     NS_ASSERTION(commonClipCount >= 0, "Inconsistent clip count.");
     SetupMaskLayer(layer, data->mItemClip, commonClipCount);
     // copy commonClipCount to the entry
     FrameLayerBuilder::ThebesLayerItemsEntry* entry = mBuilder->LayerBuilder()->
       GetThebesLayerItemsEntry(static_cast<ThebesLayer*>(layer.get()));
     entry->mCommonClipCount = commonClipCount;
   } else {
     // mask layer for image and color layers
     SetupMaskLayer(layer, data->mItemClip);
+#endif
   }
   PRUint32 flags;
   if (isOpaque && !data->mForceTransparentSurface) {
     flags = Layer::CONTENT_OPAQUE;
   } else if (data->mNeedComponentAlpha) {
     flags = Layer::CONTENT_COMPONENT_ALPHA;
   } else {
     flags = 0;
@@ -1641,17 +1651,23 @@ ContainerState::ProcessDisplayItems(cons
     LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
 
     nsIFrame* activeScrolledRoot =
       nsLayoutUtils::GetActiveScrolledRootFor(item, mBuilder);
 
     // Assign the item to a layer
     if (layerState == LAYER_ACTIVE_FORCE ||
         layerState == LAYER_ACTIVE_EMPTY ||
+#ifdef MOZ_ENABLE_MASK_LAYERS
         layerState == LAYER_ACTIVE) {
+#else
+        (layerState == LAYER_ACTIVE &&
+         (aClip.mRoundedClipRects.IsEmpty() ||
+          !aClip.IsRectClippedByRoundedCorner(item->GetVisibleRect())))) {
+#endif
 
       // LAYER_ACTIVE_EMPTY means the layer is created just for its metadata.
       // We should never see an empty layer with any visible content!
       NS_ASSERTION(layerState != LAYER_ACTIVE_EMPTY ||
                    itemVisibleRect.IsEmpty(),
                    "State is LAYER_ACTIVE_EMPTY but visible rect is not.");
 
       // If the item would have its own layer but is invisible, just hide it.
@@ -1702,21 +1718,23 @@ ContainerState::ProcessDisplayItems(cons
         // The visible region may be excluding opaque content above the
         // item, and we need to ensure that that content is not placed
         // in a ThebesLayer below the item!
         data->mDrawAboveRegion.Or(data->mDrawAboveRegion, itemDrawRect);
         data->mDrawAboveRegion.SimplifyOutward(4);
       }
       RestrictVisibleRegionForLayer(ownLayer, itemVisibleRect);
 
+#ifdef MOZ_ENABLE_MASK_LAYERS
       // rounded rectangle clipping using mask layers
       // (must be done after visible rect is set on layer)
       if (aClip.IsRectClippedByRoundedCorner(itemContent)) {
           SetupMaskLayer(ownLayer, aClip);
       }
+#endif
 
       ContainerLayer* oldContainer = ownLayer->GetParent();
       if (oldContainer && oldContainer != mContainerLayer) {
         oldContainer->RemoveChild(ownLayer);
       }
       NS_ASSERTION(!mNewChildLayers.Contains(ownLayer),
                    "Layer already in list???");
 
@@ -2797,16 +2815,17 @@ ArrayRangeEquals(const nsTArray<T>& a1, 
 
   return true;
 }
 
 void
 ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip,
                                PRUint32 aRoundedRectClipCount) 
 {
+#ifdef MOZ_ENABLE_MASK_LAYERS
   // don't build an unnecessary mask
   if (aClip.mRoundedClipRects.IsEmpty() ||
       aRoundedRectClipCount <= 0) {
     return;
   }
 
   const gfx3DMatrix& layerTransform = aLayer->GetTransform();
   NS_ASSERTION(layerTransform.CanDraw2D() || aLayer->AsContainerLayer(),
@@ -2885,12 +2904,13 @@ ContainerState::SetupMaskLayer(Layer *aL
   userData->mRoundedClipRects = aClip.mRoundedClipRects;
   if (aRoundedRectClipCount < userData->mRoundedClipRects.Length()) {
     userData->mRoundedClipRects.TruncateLength(aRoundedRectClipCount);
   }
   userData->mTransform = aLayer->GetTransform();
   userData->mBounds = aLayer->GetEffectiveVisibleRegion().GetBounds();
 
   aLayer->SetMaskLayer(maskLayer);
+#endif
   return;
 }
 
 } // namespace mozilla
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1842,16 +1842,22 @@ CanScrollWithBlitting(nsIFrame* aFrame)
     return false;
 
   for (nsIFrame* f = aFrame; f;
        f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
     if (nsSVGIntegrationUtils::UsingEffectsForFrame(f) ||
         f->IsFrameOfType(nsIFrame::eSVG)) {
       return false;
     }
+#ifndef MOZ_ENABLE_MASK_LAYERS
+    nsIScrollableFrame* sf = do_QueryFrame(f);
+    if ((sf || f->IsFrameOfType(nsIFrame::eReplaced)) &&
+        nsLayoutUtils::HasNonZeroCorner(f->GetStyleBorder()->mBorderRadius))
+      return false;
+#endif
     if (nsLayoutUtils::IsPopup(f))
       break;
   }
   return true;
 }
 
 static void
 InvalidateFixedBackgroundFramesFromList(nsDisplayListBuilder* aBuilder,