LCOV - code coverage report
Current view: top level - gfx/layers/basic - BasicContainerLayer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 44 87 50.6 %
Date: 2017-07-14 16:53:18 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "BasicContainerLayer.h"
       7             : #include <sys/types.h>                  // for int32_t
       8             : #include "BasicLayersImpl.h"            // for ToData
       9             : #include "basic/BasicImplData.h"        // for BasicImplData
      10             : #include "basic/BasicLayers.h"          // for BasicLayerManager
      11             : #include "mozilla/gfx/BaseRect.h"       // for BaseRect
      12             : #include "mozilla/mozalloc.h"           // for operator new
      13             : #include "nsCOMPtr.h"                   // for already_AddRefed
      14             : #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
      15             : #include "nsPoint.h"                    // for nsIntPoint
      16             : #include "nsRegion.h"                   // for nsIntRegion
      17             : #include "ReadbackProcessor.h"
      18             : 
      19             : using namespace mozilla::gfx;
      20             : 
      21             : namespace mozilla {
      22             : namespace layers {
      23             : 
      24         144 : BasicContainerLayer::~BasicContainerLayer()
      25             : {
      26          48 :   ContainerLayer::RemoveAllChildren();
      27          48 :   MOZ_COUNT_DTOR(BasicContainerLayer);
      28         144 : }
      29             : 
      30             : void
      31         217 : BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSurface)
      32             : {
      33             :   // We push groups for container layers if we need to, which always
      34             :   // are aligned in device space, so it doesn't really matter how we snap
      35             :   // containers.
      36         217 :   Matrix residual;
      37         217 :   Matrix4x4 transformToSurface = aTransformToSurface;
      38         217 :   bool participate3DCtx = Extend3DContext() || Is3DContextLeaf();
      39         434 :   if (!participate3DCtx &&
      40         217 :       GetContentFlags() & CONTENT_BACKFACE_HIDDEN) {
      41             :     // For backface-hidden layers
      42           0 :     transformToSurface.ProjectTo2D();
      43             :   }
      44         217 :   Matrix4x4 idealTransform = GetLocalTransform() * transformToSurface;
      45         434 :   if (!participate3DCtx &&
      46         217 :       !(GetContentFlags() & CONTENT_BACKFACE_HIDDEN)) {
      47             :     // For non-backface-hidden layers,
      48             :     // 3D components are required to handle CONTENT_BACKFACE_HIDDEN.
      49         217 :     idealTransform.ProjectTo2D();
      50             :   }
      51             : 
      52         217 :   if (!idealTransform.CanDraw2D()) {
      53           0 :     if (!Extend3DContext()) {
      54           0 :       mEffectiveTransform = idealTransform;
      55           0 :       ComputeEffectiveTransformsForChildren(Matrix4x4());
      56           0 :       ComputeEffectiveTransformForMaskLayers(Matrix4x4());
      57           0 :       mUseIntermediateSurface = true;
      58           0 :       return;
      59             :     }
      60             : 
      61           0 :     mEffectiveTransform = idealTransform;
      62           0 :     ComputeEffectiveTransformsForChildren(idealTransform);
      63           0 :     ComputeEffectiveTransformForMaskLayers(idealTransform);
      64           0 :     mUseIntermediateSurface = false;
      65           0 :     return;
      66             :   }
      67             : 
      68             :   // With 2D transform or extended 3D context.
      69             : 
      70         217 :   Layer* child = GetFirstChild();
      71         217 :   bool hasSingleBlendingChild = false;
      72         217 :   if (!HasMultipleChildren() && child) {
      73         214 :     hasSingleBlendingChild = child->GetMixBlendMode() != CompositionOp::OP_OVER;
      74             :   }
      75             : 
      76             :   /* If we have a single childand it is not blending,, it can just inherit our opacity,
      77             :    * otherwise we need a PushGroup and we need to mark ourselves as using
      78             :    * an intermediate surface so our children don't inherit our opacity
      79             :    * via GetEffectiveOpacity.
      80             :    * Having a mask layer always forces our own push group
      81             :    * Having a blend mode also always forces our own push group
      82             :    */
      83         217 :   mUseIntermediateSurface =
      84         434 :     GetMaskLayer() ||
      85         434 :     GetForceIsolatedGroup() ||
      86         651 :     (GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) ||
      87         378 :     (GetEffectiveOpacity() != 1.0 && ((HasMultipleChildren() && !Extend3DContext()) || hasSingleBlendingChild));
      88             : 
      89             :   mEffectiveTransform =
      90         217 :     !mUseIntermediateSurface ?
      91             :     idealTransform :
      92           0 :     (!(GetContentFlags() & CONTENT_BACKFACE_HIDDEN) ?
      93         217 :      SnapTransformTranslation(idealTransform, &residual) :
      94         434 :      SnapTransformTranslation3D(idealTransform, &residual));
      95             :   Matrix4x4 childTransformToSurface =
      96         217 :     (!mUseIntermediateSurface ||
      97         217 :      (mUseIntermediateSurface && !Extend3DContext() /* 2D */)) ?
      98         217 :     idealTransform : Matrix4x4::From2D(residual);
      99         217 :   ComputeEffectiveTransformsForChildren(childTransformToSurface);
     100             : 
     101         217 :   ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
     102             : }
     103             : 
     104             : bool
     105           0 : BasicContainerLayer::ChildrenPartitionVisibleRegion(const gfx::IntRect& aInRect)
     106             : {
     107           0 :   Matrix transform;
     108           0 :   if (!GetEffectiveTransform().CanDraw2D(&transform) ||
     109           0 :       ThebesMatrix(transform).HasNonIntegerTranslation())
     110           0 :     return false;
     111             : 
     112           0 :   nsIntPoint offset(int32_t(transform._31), int32_t(transform._32));
     113           0 :   gfx::IntRect rect = aInRect.Intersect(GetLocalVisibleRegion().ToUnknownRegion().GetBounds() + offset);
     114           0 :   nsIntRegion covered;
     115             : 
     116           0 :   for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
     117           0 :     if (ToData(l)->IsHidden())
     118           0 :       continue;
     119             : 
     120           0 :     Matrix childTransform;
     121           0 :     if (!l->GetEffectiveTransform().CanDraw2D(&childTransform) ||
     122           0 :         ThebesMatrix(childTransform).HasNonIntegerTranslation() ||
     123           0 :         l->GetEffectiveOpacity() != 1.0)
     124           0 :       return false;
     125           0 :     nsIntRegion childRegion = l->GetLocalVisibleRegion().ToUnknownRegion();
     126           0 :     childRegion.MoveBy(int32_t(childTransform._31), int32_t(childTransform._32));
     127           0 :     childRegion.And(childRegion, rect);
     128           0 :     if (l->GetClipRect()) {
     129           0 :       childRegion.And(childRegion, l->GetClipRect()->ToUnknownRect() + offset);
     130             :     }
     131           0 :     nsIntRegion intersection;
     132           0 :     intersection.And(covered, childRegion);
     133           0 :     if (!intersection.IsEmpty())
     134           0 :       return false;
     135           0 :     covered.Or(covered, childRegion);
     136             :   }
     137             : 
     138           0 :   return covered.Contains(rect);
     139             : }
     140             : 
     141             : void
     142          72 : BasicContainerLayer::Validate(LayerManager::DrawPaintedLayerCallback aCallback,
     143             :                               void* aCallbackData,
     144             :                               ReadbackProcessor* aReadback)
     145             : {
     146         144 :   ReadbackProcessor readback;
     147          72 :   if (BasicManager()->IsRetained()) {
     148           0 :     readback.BuildUpdates(this);
     149             :   }
     150         168 :   for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
     151          96 :     BasicImplData* data = ToData(l);
     152          96 :     data->Validate(aCallback, aCallbackData, &readback);
     153          96 :     if (l->GetMaskLayer()) {
     154           0 :       data = ToData(l->GetMaskLayer());
     155           0 :       data->Validate(aCallback, aCallbackData, nullptr);
     156             :     }
     157             :   }
     158          72 : }
     159             : 
     160             : already_AddRefed<ContainerLayer>
     161          54 : BasicLayerManager::CreateContainerLayer()
     162             : {
     163          54 :   NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
     164         108 :   RefPtr<ContainerLayer> layer = new BasicContainerLayer(this);
     165         108 :   return layer.forget();
     166             : }
     167             : 
     168             : } // namespace layers
     169             : } // namespace mozilla

Generated by: LCOV version 1.13