Bug 1023677 - Don't flatten active transform layers. r=roc
☠☠ backed out by 5f930157632c ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 18 Jul 2014 18:48:23 +1200
changeset 194877 d03cb12a166ebd3dc8a2bc79f752ad475dcb0696
parent 194876 84df2aaf5e2ac20449469a710f221da2d2470c21
child 194878 b049e0ae4d1d81f0da619970891109414d0cab2c
push id7810
push userryanvm@gmail.com
push dateFri, 18 Jul 2014 20:08:45 +0000
treeherderfx-team@85d5040f1ad2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1023677
milestone33.0a1
Bug 1023677 - Don't flatten active transform layers. r=roc
layout/base/FrameLayerBuilder.cpp
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -525,17 +525,17 @@ public:
   /**
    * This finalizes all the open ThebesLayers by popping every element off
    * mThebesLayerDataStack, then sets the children of the container layer
    * to be all the layers in mNewChildLayers in that order and removes any
    * layers as children of the container that aren't in mNewChildLayers.
    * @param aTextContentFlags if any child layer has CONTENT_COMPONENT_ALPHA,
    * set *aTextContentFlags to CONTENT_COMPONENT_ALPHA
    */
-  void Finish(uint32_t *aTextContentFlags, LayerManagerData* aData);
+  void Finish(uint32_t *aTextContentFlags, LayerManagerData* aData, bool& aHasComponentAlphaChildren);
 
   nsRect GetChildrenBounds() { return mBounds; }
 
   nscoord GetAppUnitsPerDevPixel() { return mAppUnitsPerDevPixel; }
 
   nsIntRect ScaleToNearestPixels(const nsRect& aRect)
   {
     return aRect.ScaleToNearestPixels(mParameters.mXScale, mParameters.mYScale,
@@ -3060,17 +3060,17 @@ ContainerState::CollectOldLayers()
       NS_ASSERTION(maskLayer->GetType() == Layer::TYPE_IMAGE,
                    "Could not recycle mask layer, unsupported layer type.");
       mRecycledMaskImageLayers.Put(layer, static_cast<ImageLayer*>(maskLayer));
     }
   }
 }
 
 void
-ContainerState::Finish(uint32_t* aTextContentFlags, LayerManagerData* aData)
+ContainerState::Finish(uint32_t* aTextContentFlags, LayerManagerData* aData, bool& aHasComponentAlphaChildren)
 {
   while (!mThebesLayerDataStack.IsEmpty()) {
     PopThebesLayerData();
   }
 
   uint32_t textContentFlags = 0;
 
   // Make sure that current/existing layers are added to the parent and are
@@ -3079,16 +3079,26 @@ ContainerState::Finish(uint32_t* aTextCo
   for (uint32_t i = 0; i < mNewChildLayers.Length(); ++i) {
     Layer* prevChild = i == 0 ? nullptr : mNewChildLayers[i - 1].get();
     layer = mNewChildLayers[i];
 
     if (!layer->GetVisibleRegion().IsEmpty()) {
       textContentFlags |=
         layer->GetContentFlags() & (Layer::CONTENT_COMPONENT_ALPHA |
                                     Layer::CONTENT_COMPONENT_ALPHA_DESCENDANT);
+
+      // Notify the parent of component alpha children unless it's coming from
+      // within a transformed child since we don't want flattening of component
+      // alpha layers to happen across transforms. Re-rendering the text during
+      // transform animations looks worse than losing subpixel-AA.
+      if ((layer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) &&
+          (layer->GetType() != Layer::TYPE_CONTAINER ||
+           layer->GetBaseTransform().IsIdentity())) {
+        aHasComponentAlphaChildren = true;
+      }
     }
 
     if (!layer->GetParent()) {
       // This is not currently a child of the container, so just add it
       // now.
       mContainerLayer->InsertAfter(layer, prevChild);
       continue;
     }
@@ -3418,22 +3428,23 @@ FrameLayerBuilder::BuildContainerLayerFo
                          aContainerFrame, aContainerItem,
                          containerLayer, scaleParameters);
 
     state.ProcessDisplayItems(aChildren, stateFlags);
 
     // Set CONTENT_COMPONENT_ALPHA if any of our children have it.
     // This is suboptimal ... a child could have text that's over transparent
     // pixels in its own layer, but over opaque parts of previous siblings.
-    state.Finish(&flags, data);
+    bool hasComponentAlphaChildren = false;
+    state.Finish(&flags, data, hasComponentAlphaChildren);
     bounds = state.GetChildrenBounds();
     pixBounds = state.ScaleToOutsidePixels(bounds, false);
     appUnitsPerDevPixel = state.GetAppUnitsPerDevPixel();
 
-    if ((flags & Layer::CONTENT_COMPONENT_ALPHA) &&
+    if (hasComponentAlphaChildren &&
         mRetainingManager &&
         !mRetainingManager->AreComponentAlphaLayersEnabled() &&
         containerLayer->HasMultipleChildren() &&
         !stateFlags) {
       // Since we don't want any component alpha layers on BasicLayers, we repeat
       // the layer building process with this explicitely forced off.
       // We restore the previous FrameLayerBuilder state since the first set
       // of layer building will have changed it.