Bug 1042296 - Part 1. Implement ShouldCopyBackground. draft
authorcku <cku@mozilla.com>
Fri, 11 Nov 2016 01:23:16 +0800
changeset 437259 258d3657de7f3c2db3302401b2a051ad07510152
parent 435666 783356f1476eafd8e4d6fa5f3919cf6167e84f8d
child 536599 83ddec5ed8c20a1b3c6c6c0e1bac792af67205f2
push id35368
push userbmo:cku@mozilla.com
push dateThu, 10 Nov 2016 17:23:39 +0000
bugs1042296
milestone52.0a1
Bug 1042296 - Part 1. Implement ShouldCopyBackground. MozReview-Commit-ID: CdUncJw9pBL
gfx/layers/basic/BasicLayerManager.cpp
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -71,16 +71,38 @@ ClipToContain(gfxContext* aContext, cons
   aContext->NewPath();
   aContext->Rectangle(deviceRect);
   aContext->Clip();
   aContext->SetMatrix(currentMatrix);
 
   return aContext->DeviceToUser(deviceRect).IsEqualInterior(userRect);
 }
 
+static
+bool ShouldCopyBackground(Layer* aLayer)
+{
+  if (aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) {
+    return true;
+  }
+
+  ContainerLayer* container = aLayer->AsContainerLayer();
+  if (container) {
+    for (Layer* child = container->GetFirstChild(); child;
+         child = child->GetNextSibling()) {
+      if (ShouldCopyBackground(child)) {
+        return true;
+      }
+    }
+  }
+
+  // We should copy backgronud into pushed draw target if any child layer
+  // has blend mode not OP_OVER.
+  return (GetEffectiveOperator(aLayer) != CompositionOp::OP_OVER);
+}
+
 bool
 BasicLayerManager::PushGroupForLayer(gfxContext* aContext, Layer* aLayer, const nsIntRegion& aRegion,  PushedGroup& aGroupResult)
 {
   aGroupResult.mVisibleRegion = aRegion;
   aGroupResult.mFinalTarget = aContext;
   aGroupResult.mOperator = GetEffectiveOperator(aLayer);
   aGroupResult.mOpacity = aLayer->GetEffectiveOpacity();
 
@@ -147,17 +169,17 @@ BasicLayerManager::PushGroupForLayer(gfx
     aGroupResult.mNeedsClipToVisibleRegion = !didCompleteClip || aRegion.GetNumRects() > 1;
     if (aGroupResult.mNeedsClipToVisibleRegion) {
       aGroupResult.mFinalTarget->Save();
       gfxUtils::ClipToRegion(aGroupResult.mFinalTarget, aGroupResult.mVisibleRegion);
     }
 
     aContext->PushGroupForBlendBack(gfxContentType::COLOR, aGroupResult.mOpacity, maskSurf, maskTransform);
   } else {
-    if (aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) {
+    if (ShouldCopyBackground(aLayer)) {
       aContext->PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA, aGroupResult.mOpacity, maskSurf, maskTransform);
     } else {
       aContext->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, aGroupResult.mOpacity, maskSurf, maskTransform);
     }
   }
 
   aGroupResult.mGroupTarget = aGroupResult.mFinalTarget;