LCOV - code coverage report
Current view: top level - gfx/layers/mlgpu - ContainerLayerMLGPU.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 95 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; 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 "ContainerLayerMLGPU.h"
       7             : #include "gfxPrefs.h"
       8             : #include "LayersLogging.h"
       9             : #include "LayerManagerMLGPU.h"
      10             : #include "MLGDevice.h"
      11             : #include "mozilla/gfx/Rect.h"
      12             : #include "mozilla/gfx/Types.h"
      13             : #include "UnitTransforms.h"
      14             : #include "UtilityMLGPU.h"
      15             : 
      16             : namespace mozilla {
      17             : namespace layers {
      18             : 
      19             : using namespace gfx;
      20             : 
      21           0 : ContainerLayerMLGPU::ContainerLayerMLGPU(LayerManagerMLGPU* aManager)
      22             :   : ContainerLayer(aManager, nullptr)
      23           0 :   , LayerMLGPU(aManager)
      24             : {
      25           0 : }
      26             : 
      27           0 : ContainerLayerMLGPU::~ContainerLayerMLGPU()
      28             : {
      29           0 :   while (mFirstChild) {
      30           0 :     RemoveChild(mFirstChild);
      31             :   }
      32           0 : }
      33             : 
      34             : bool
      35           0 : ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
      36             : {
      37           0 :   if (!UseIntermediateSurface()) {
      38           0 :     return true;
      39             :   }
      40             : 
      41           0 :   if ((!mRenderTarget || mChildrenChanged) &&
      42           0 :       gfxPrefs::AdvancedLayersEnableContainerResizing())
      43             :   {
      44             :     // Try to compute a more accurate visible region.
      45             :     AL_LOG("Computing new surface size for container %p:\n", GetLayer());
      46             : 
      47           0 :     Maybe<IntRect> bounds = ComputeIntermediateSurfaceBounds();
      48           0 :     if (bounds) {
      49           0 :       LayerIntRegion region = Move(GetShadowVisibleRegion());
      50           0 :       region.AndWith(LayerIntRect::FromUnknownRect(bounds.value()));
      51             :       AL_LOG("  computed bounds: %s\n", Stringify(bounds.value()).c_str());
      52             :       AL_LOG("  new visible: %s\n", Stringify(region).c_str());
      53             : 
      54           0 :       SetShadowVisibleRegion(Move(region));
      55             :     }
      56             :   }
      57           0 :   mChildrenChanged = false;
      58             : 
      59           0 :   mTargetOffset = GetIntermediateSurfaceRect().TopLeft().ToUnknownPoint();
      60           0 :   mTargetSize = GetIntermediateSurfaceRect().Size().ToUnknownSize();
      61             : 
      62           0 :   if (mRenderTarget && mRenderTarget->GetSize() != mTargetSize) {
      63           0 :     mRenderTarget = nullptr;
      64             :   }
      65             : 
      66           0 :   gfx::IntRect viewport(gfx::IntPoint(0, 0), mTargetSize);
      67           0 :   if (!mRenderTarget || !gfxPrefs::AdvancedLayersUseInvalidation()) {
      68             :     // Fine-grained invalidation is disabled, invalidate everything.
      69           0 :     mInvalidRect = viewport;
      70             :   } else {
      71             :     // Clamp the invalid rect to the viewport.
      72           0 :     mInvalidRect = mInvalidRect.Intersect(viewport);
      73             :   }
      74           0 :   return true;
      75             : }
      76             : 
      77             : static IntRect
      78           0 : GetTransformedBounds(Layer* aLayer)
      79             : {
      80           0 :   IntRect bounds = aLayer->GetLocalVisibleRegion().GetBounds().ToUnknownRect();
      81           0 :   if (bounds.IsEmpty()) {
      82           0 :     return bounds;
      83             :   }
      84             : 
      85           0 :   const Matrix4x4& transform = aLayer->GetEffectiveTransform();
      86           0 :   Rect rect = transform.TransformAndClipBounds(Rect(bounds), Rect::MaxIntRect());
      87           0 :   rect.RoundOut();
      88           0 :   rect.ToIntRect(&bounds);
      89           0 :   return bounds;
      90             : }
      91             : 
      92             : static Maybe<IntRect>
      93           0 : FindVisibleBounds(Layer* aLayer, const Maybe<RenderTargetIntRect>& aClip)
      94             : {
      95             :   AL_LOG("  visiting child %p\n", aLayer);
      96             :   AL_LOG_IF(aClip, "  parent clip: %s\n", Stringify(aClip.value()).c_str());
      97             : 
      98           0 :   ContainerLayer* container = aLayer->AsContainerLayer();
      99           0 :   if (container && !container->UseIntermediateSurface()) {
     100           0 :     Maybe<IntRect> accumulated = Some(IntRect());
     101             : 
     102             :     // Traverse children.
     103           0 :     for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
     104           0 :       Maybe<RenderTargetIntRect> clip = aClip;
     105           0 :       if (const Maybe<ParentLayerIntRect>& childClip = child->AsHostLayer()->GetShadowClipRect()) {
     106             :         RenderTargetIntRect rtChildClip =
     107           0 :           TransformBy(ViewAs<ParentLayerToRenderTargetMatrix4x4>(
     108           0 :                         aLayer->GetEffectiveTransform(),
     109             :                         PixelCastJustification::RenderTargetIsParentLayerForRoot),
     110           0 :                       childClip.value());
     111           0 :         clip = IntersectMaybeRects(clip, Some(rtChildClip));
     112             :         AL_LOG("    target clip: %s\n", Stringify(rtChildClip).c_str());
     113             :         AL_LOG_IF(clip, "    full clip: %s\n", Stringify(clip.value()).c_str());
     114             :       }
     115             : 
     116           0 :       Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
     117           0 :       if (!childBounds) {
     118           0 :         return Nothing();
     119             :       }
     120             : 
     121           0 :       accumulated = accumulated->SafeUnion(childBounds.value());
     122           0 :       if (!accumulated) {
     123           0 :         return Nothing();
     124             :       }
     125             :     }
     126           0 :     return accumulated;
     127             :   }
     128             : 
     129           0 :   IntRect bounds = GetTransformedBounds(aLayer);
     130             :   AL_LOG("    layer bounds: %s\n", Stringify(bounds).c_str());
     131             : 
     132           0 :   if (aClip) {
     133           0 :     bounds = bounds.Intersect(aClip.value().ToUnknownRect());
     134             :     AL_LOG("    clipped bounds: %s\n", Stringify(bounds).c_str());
     135             :   }
     136           0 :   return Some(bounds);
     137             : }
     138             : 
     139             : Maybe<IntRect>
     140           0 : ContainerLayerMLGPU::ComputeIntermediateSurfaceBounds()
     141             : {
     142           0 :   Maybe<IntRect> bounds = Some(IntRect());
     143           0 :   for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
     144             :     Maybe<RenderTargetIntRect> clip =
     145           0 :        ViewAs<RenderTargetPixel>(child->AsHostLayer()->GetShadowClipRect(),
     146           0 :                                  PixelCastJustification::RenderTargetIsParentLayerForRoot);
     147           0 :     Maybe<IntRect> childBounds = FindVisibleBounds(child, clip);
     148           0 :     if (!childBounds) {
     149           0 :       return Nothing();
     150             :     }
     151             : 
     152           0 :     bounds = bounds->SafeUnion(childBounds.value());
     153           0 :     if (!bounds) {
     154           0 :       return Nothing();
     155             :     }
     156             :   }
     157           0 :   return bounds;
     158             : }
     159             : 
     160             : void
     161           0 : ContainerLayerMLGPU::OnLayerManagerChange(LayerManagerMLGPU* aManager)
     162             : {
     163           0 :   ClearCachedResources();
     164           0 : }
     165             : 
     166             : RefPtr<MLGRenderTarget>
     167           0 : ContainerLayerMLGPU::UpdateRenderTarget(MLGDevice* aDevice, MLGRenderTargetFlags aFlags)
     168             : {
     169           0 :   if (mRenderTarget) {
     170           0 :     return mRenderTarget;
     171             :   }
     172             : 
     173           0 :   mRenderTarget = aDevice->CreateRenderTarget(mTargetSize, aFlags);
     174           0 :   if (!mRenderTarget) {
     175           0 :     gfxWarning() << "Failed to create an intermediate render target for ContainerLayer";
     176           0 :     return nullptr;
     177             :   }
     178             : 
     179           0 :   return mRenderTarget;
     180             : }
     181             : 
     182             : void
     183           0 : ContainerLayerMLGPU::SetInvalidCompositeRect(const gfx::IntRect& aRect)
     184             : {
     185             :   // For simplicity we only track the bounds of the invalid area, since regions
     186             :   // are expensive. We can adjust this in the future if needed.
     187           0 :   gfx::IntRect bounds = aRect;
     188           0 :   bounds.MoveBy(-GetTargetOffset());
     189             : 
     190             :   // Note we add the bounds to the invalid rect from the last frame, since we
     191             :   // only clear the area that we actually paint.
     192           0 :   if (Maybe<gfx::IntRect> result = mInvalidRect.SafeUnion(bounds)) {
     193           0 :     mInvalidRect = result.value();
     194             :   } else {
     195           0 :     mInvalidRect = gfx::IntRect(gfx::IntPoint(0, 0), GetTargetSize());
     196             :   }
     197           0 : }
     198             : 
     199             : void
     200           0 : ContainerLayerMLGPU::ClearCachedResources()
     201             : {
     202           0 :   mRenderTarget = nullptr;
     203           0 : }
     204             : 
     205             : bool
     206           0 : ContainerLayerMLGPU::IsContentOpaque()
     207             : {
     208           0 :   if (GetMixBlendMode() != gfx::CompositionOp::OP_OVER) {
     209             :     // We need to read from what's underneath us, so we consider our content to
     210             :     // be not opaque.
     211           0 :     return false;
     212             :   }
     213           0 :   return LayerMLGPU::IsContentOpaque();
     214             : }
     215             : 
     216             : } // namespace layers
     217             : } // namespace mozilla

Generated by: LCOV version 1.13