Bug 1343057 - Part 1: Recycle painted layers with AA in mind. r=mattwoodrow
authorThinker K.F. Li <thinker@codemud.net>
Wed, 29 Mar 2017 09:37:00 -0400
changeset 553333 b895979d4e6d89d70b357465e0eb86d56b5e0c91
parent 553332 d13e65fc7379efbd3313e432442f8c13a8b6f659
child 553334 3793b906e1e79d0f3a0bd07c0b666321ddb0768d
push id51596
push usermozilla@kaply.com
push dateWed, 29 Mar 2017 20:39:42 +0000
reviewersmattwoodrow
bugs1343057
milestone55.0a1
Bug 1343057 - Part 1: Recycle painted layers with AA in mind. r=mattwoodrow
layout/painting/FrameLayerBuilder.cpp
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -1540,16 +1540,21 @@ public:
   RefPtr<ImageLayer> mImageLayer;
 
   // The region for which display item visibility for this layer has already
   // been calculated. Used to reduce the number of calls to
   // RecomputeVisibilityForItems if it is known in advance that a larger
   // region will be painted during a transaction than in a single call to
   // DrawPaintedLayer, for example when progressive paint is enabled.
   nsIntRegion mVisibilityComputedRegion;
+
+  /**
+   * This is set when the painted layer has no component alpha.
+   */
+  bool mDisabledAlpha;
 };
 
 /*
  * User data for layers which will be used as masks.
  */
 struct MaskLayerUserData : public LayerUserData
 {
   MaskLayerUserData()
@@ -2390,16 +2395,18 @@ ContainerState::CreatePaintedLayer(Paint
   // Create a new painted layer
   RefPtr<PaintedLayer> layer = mManager->CreatePaintedLayerWithHint(creationHint);
   if (!layer) {
     return nullptr;
   }
 
   // Mark this layer as being used for painting display items
   PaintedDisplayItemLayerUserData* userData = new PaintedDisplayItemLayerUserData();
+  userData->mDisabledAlpha =
+    mParameters.mDisableSubpixelAntialiasingInDescendants;
   layer->SetUserData(&gPaintedDisplayItemLayerUserData, userData);
   ResetScrollPositionForLayerPixelAlignment(aData->mAnimatedGeometryRoot);
 
   PreparePaintedLayerForUse(layer, userData, aData->mAnimatedGeometryRoot,
                             aData->mReferenceFrame,
                             aData->mAnimatedGeometryRootOffset, true);
 
   return layer.forget();
@@ -2488,21 +2495,30 @@ ContainerState::PreparePaintedLayerForUs
                        RoundToMatchResidual(scaledOffset.y, aData->mAnimatedGeometryRootPosition.y));
   aData->mTranslation = pixOffset;
   pixOffset += mParameters.mOffset;
   Matrix matrix = Matrix::Translation(pixOffset.x, pixOffset.y);
   aLayer->SetBaseTransform(Matrix4x4::From2D(matrix));
 
   aData->mVisibilityComputedRegion.SetEmpty();
 
-  // FIXME: Temporary workaround for bug 681192 and bug 724786.
-#ifndef MOZ_WIDGET_ANDROID
   // Calculate exact position of the top-left of the active scrolled root.
   // This might not be 0,0 due to the snapping in ScaleToNearestPixels.
   gfxPoint animatedGeometryRootTopLeft = scaledOffset - ThebesPoint(matrix.GetTranslation()) + mParameters.mOffset;
+  const bool disableAlpha =
+    mParameters.mDisableSubpixelAntialiasingInDescendants;
+  if (aData->mDisabledAlpha != disableAlpha) {
+    aData->mAnimatedGeometryRootPosition = animatedGeometryRootTopLeft;
+    InvalidateEntirePaintedLayer(aLayer, aAnimatedGeometryRoot, "change of subpixel-AA");
+    aData->mDisabledAlpha = disableAlpha;
+    return;
+  }
+
+  // FIXME: Temporary workaround for bug 681192 and bug 724786.
+#ifndef MOZ_WIDGET_ANDROID
   // If it has changed, then we need to invalidate the entire layer since the
   // pixels in the layer buffer have the content at a (subpixel) offset
   // from what we need.
   if (!animatedGeometryRootTopLeft.WithinEpsilonOf(aData->mAnimatedGeometryRootPosition, SUBPIXEL_OFFSET_EPSILON)) {
     aData->mAnimatedGeometryRootPosition = animatedGeometryRootTopLeft;
     InvalidateEntirePaintedLayer(aLayer, aAnimatedGeometryRoot, "subpixel offset");
   } else if (didResetScrollPositionForLayerPixelAlignment) {
     aData->mAnimatedGeometryRootPosition = animatedGeometryRootTopLeft;