LCOV - code coverage report
Current view: top level - gfx/layers/composite - LayerManagerComposite.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 263 545 48.3 %
Date: 2017-07-14 16:53:18 Functions: 31 81 38.3 %
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 "LayerManagerComposite.h"
       7             : #include <stddef.h>                     // for size_t
       8             : #include <stdint.h>                     // for uint16_t, uint32_t
       9             : #include "CanvasLayerComposite.h"       // for CanvasLayerComposite
      10             : #include "ColorLayerComposite.h"        // for ColorLayerComposite
      11             : #include "CompositableHost.h"           // for CompositableHost
      12             : #include "ContainerLayerComposite.h"    // for ContainerLayerComposite, etc
      13             : #include "Diagnostics.h"
      14             : #include "FPSCounter.h"                 // for FPSState, FPSCounter
      15             : #include "FrameMetrics.h"               // for FrameMetrics
      16             : #include "GeckoProfiler.h"              // for profiler_*
      17             : #include "ImageLayerComposite.h"        // for ImageLayerComposite
      18             : #include "Layers.h"                     // for Layer, ContainerLayer, etc
      19             : #include "LayerScope.h"                 // for LayerScope Tool
      20             : #include "protobuf/LayerScopePacket.pb.h" // for protobuf (LayerScope)
      21             : #include "PaintedLayerComposite.h"      // for PaintedLayerComposite
      22             : #include "TiledContentHost.h"
      23             : #include "Units.h"                      // for ScreenIntRect
      24             : #include "UnitTransforms.h"             // for ViewAs
      25             : #include "apz/src/AsyncPanZoomController.h"  // for AsyncPanZoomController
      26             : #include "gfxPrefs.h"                   // for gfxPrefs
      27             : #ifdef XP_MACOSX
      28             : #include "gfxPlatformMac.h"
      29             : #endif
      30             : #include "gfxRect.h"                    // for gfxRect
      31             : #include "gfxUtils.h"                   // for frame color util
      32             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
      33             : #include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed
      34             : #include "mozilla/gfx/2D.h"             // for DrawTarget
      35             : #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
      36             : #include "mozilla/gfx/Point.h"          // for IntSize, Point
      37             : #include "mozilla/gfx/Rect.h"           // for Rect
      38             : #include "mozilla/gfx/Types.h"          // for Color, SurfaceFormat
      39             : #include "mozilla/layers/Compositor.h"  // for Compositor
      40             : #include "mozilla/layers/CompositorTypes.h"
      41             : #include "mozilla/layers/Effects.h"     // for Effect, EffectChain, etc
      42             : #include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
      43             : #include "mozilla/layers/LayersTypes.h"  // for etc
      44             : #include "mozilla/widget/CompositorWidget.h" // for WidgetRenderingContext
      45             : #include "ipc/CompositorBench.h"        // for CompositorBench
      46             : #include "ipc/ShadowLayerUtils.h"
      47             : #include "mozilla/mozalloc.h"           // for operator new, etc
      48             : #include "nsAppRunner.h"
      49             : #include "mozilla/RefPtr.h"                   // for nsRefPtr
      50             : #include "nsCOMPtr.h"                   // for already_AddRefed
      51             : #include "nsDebug.h"                    // for NS_WARNING, NS_RUNTIMEABORT, etc
      52             : #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
      53             : #include "nsPoint.h"                    // for nsIntPoint
      54             : #include "nsRect.h"                     // for mozilla::gfx::IntRect
      55             : #include "nsRegion.h"                   // for nsIntRegion, etc
      56             : #if defined(MOZ_WIDGET_ANDROID)
      57             : #include <android/log.h>
      58             : #include <android/native_window.h>
      59             : #include "mozilla/widget/AndroidCompositorWidget.h"
      60             : #include "opengl/CompositorOGL.h"
      61             : #include "GLConsts.h"
      62             : #include "GLContextEGL.h"
      63             : #include "GLContextProvider.h"
      64             : #include "mozilla/Unused.h"
      65             : #include "mozilla/widget/AndroidCompositorWidget.h"
      66             : #include "ScopedGLHelpers.h"
      67             : #endif
      68             : #include "GeckoProfiler.h"
      69             : #include "TextRenderer.h"               // for TextRenderer
      70             : #include "mozilla/layers/CompositorBridgeParent.h"
      71             : #include "TreeTraversal.h"              // for ForEachNode
      72             : 
      73             : #ifdef USE_SKIA
      74             : #include "PaintCounter.h"               // For PaintCounter
      75             : #endif
      76             : 
      77             : class gfxContext;
      78             : 
      79             : namespace mozilla {
      80             : namespace layers {
      81             : 
      82             : class ImageLayer;
      83             : 
      84             : using namespace mozilla::gfx;
      85             : using namespace mozilla::gl;
      86             : 
      87             : static LayerComposite*
      88          81 : ToLayerComposite(Layer* aLayer)
      89             : {
      90          81 :   return static_cast<LayerComposite*>(aLayer->ImplData());
      91             : }
      92             : 
      93           0 : static void ClearSubtree(Layer* aLayer)
      94             : {
      95           0 :   ForEachNode<ForwardIterator>(
      96             :       aLayer,
      97           0 :       [] (Layer* layer)
      98             :       {
      99           0 :         ToLayerComposite(layer)->CleanupResources();
     100           0 :       });
     101           0 : }
     102             : 
     103             : void
     104           0 : LayerManagerComposite::ClearCachedResources(Layer* aSubtree)
     105             : {
     106           0 :   MOZ_ASSERT(!aSubtree || aSubtree->Manager() == this);
     107           0 :   Layer* subtree = aSubtree ? aSubtree : mRoot.get();
     108           0 :   if (!subtree) {
     109           0 :     return;
     110             :   }
     111             : 
     112           0 :   ClearSubtree(subtree);
     113             :   // FIXME [bjacob]
     114             :   // XXX the old LayerManagerOGL code had a mMaybeInvalidTree that it set to true here.
     115             :   // Do we need that?
     116             : }
     117             : 
     118           1 : HostLayerManager::HostLayerManager()
     119             :   : mDebugOverlayWantsNextFrame(false)
     120             :   , mWarningLevel(0.0f)
     121             :   , mCompositorBridgeID(0)
     122             :   , mWindowOverlayChanged(false)
     123             :   , mLastPaintTime(TimeDuration::Forever())
     124           1 :   , mRenderStartTime(TimeStamp::Now())
     125           1 : {}
     126             : 
     127           0 : HostLayerManager::~HostLayerManager()
     128           0 : {}
     129             : 
     130             : void
     131           0 : HostLayerManager::RecordPaintTimes(const PaintTiming& aTiming)
     132             : {
     133           0 :   mDiagnostics->RecordPaintTimes(aTiming);
     134           0 : }
     135             : 
     136             : void
     137           0 : HostLayerManager::RecordUpdateTime(float aValue)
     138             : {
     139           0 :   mDiagnostics->RecordUpdateTime(aValue);
     140           0 : }
     141             : 
     142             : /**
     143             :  * LayerManagerComposite
     144             :  */
     145           1 : LayerManagerComposite::LayerManagerComposite(Compositor* aCompositor)
     146             : : mUnusedApzTransformWarning(false)
     147             : , mDisabledApzWarning(false)
     148             : , mCompositor(aCompositor)
     149             : , mInTransaction(false)
     150           1 : , mIsCompositorReady(false)
     151             : #if defined(MOZ_WIDGET_ANDROID)
     152             : , mScreenPixelsTarget(nullptr)
     153             : #endif // defined(MOZ_WIDGET_ANDROID)
     154             : {
     155           1 :   mTextRenderer = new TextRenderer();
     156           1 :   mDiagnostics = MakeUnique<Diagnostics>();
     157           1 :   MOZ_ASSERT(aCompositor);
     158             : 
     159             : #ifdef USE_SKIA
     160           1 :   mPaintCounter = nullptr;
     161             : #endif
     162           1 : }
     163             : 
     164           0 : LayerManagerComposite::~LayerManagerComposite()
     165             : {
     166           0 :   Destroy();
     167           0 : }
     168             : 
     169             : 
     170             : void
     171           0 : LayerManagerComposite::Destroy()
     172             : {
     173           0 :   if (!mDestroyed) {
     174           0 :     mCompositor->GetWidget()->CleanupWindowEffects();
     175           0 :     if (mRoot) {
     176           0 :       RootLayer()->Destroy();
     177             :     }
     178           0 :     mCompositor->CancelFrame();
     179           0 :     mRoot = nullptr;
     180           0 :     mClonedLayerTreeProperties = nullptr;
     181           0 :     mDestroyed = true;
     182             : 
     183             : #ifdef USE_SKIA
     184           0 :     mPaintCounter = nullptr;
     185             : #endif
     186             :   }
     187           0 : }
     188             : 
     189             : void
     190          24 : LayerManagerComposite::UpdateRenderBounds(const IntRect& aRect)
     191             : {
     192          24 :   mRenderBounds = aRect;
     193          24 : }
     194             : 
     195             : bool
     196           0 : LayerManagerComposite::AreComponentAlphaLayersEnabled()
     197             : {
     198           0 :   return mCompositor->GetBackendType() != LayersBackend::LAYERS_BASIC &&
     199           0 :          mCompositor->SupportsEffect(EffectTypes::COMPONENT_ALPHA) &&
     200           0 :          LayerManager::AreComponentAlphaLayersEnabled();
     201             : }
     202             : 
     203             : bool
     204          57 : LayerManagerComposite::BeginTransaction()
     205             : {
     206          57 :   mInTransaction = true;
     207             : 
     208          57 :   if (!mCompositor->Ready()) {
     209           0 :     return false;
     210             :   }
     211             : 
     212          57 :   mIsCompositorReady = true;
     213          57 :   return true;
     214             : }
     215             : 
     216             : void
     217           0 : LayerManagerComposite::BeginTransactionWithDrawTarget(DrawTarget* aTarget, const IntRect& aRect)
     218             : {
     219           0 :   mInTransaction = true;
     220             : 
     221           0 :   if (!mCompositor->Ready()) {
     222           0 :     return;
     223             :   }
     224             : 
     225             : #ifdef MOZ_LAYERS_HAVE_LOG
     226           0 :   MOZ_LAYERS_LOG(("[----- BeginTransaction"));
     227           0 :   Log();
     228             : #endif
     229             : 
     230           0 :   if (mDestroyed) {
     231           0 :     NS_WARNING("Call on destroyed layer manager");
     232           0 :     return;
     233             :   }
     234             : 
     235           0 :   mIsCompositorReady = true;
     236           0 :   mCompositor->SetTargetContext(aTarget, aRect);
     237           0 :   mTarget = aTarget;
     238           0 :   mTargetBounds = aRect;
     239             : }
     240             : 
     241             : void
     242          29 : LayerManagerComposite::PostProcessLayers(nsIntRegion& aOpaqueRegion)
     243             : {
     244          58 :   LayerIntRegion visible;
     245          29 :   LayerComposite* rootComposite = static_cast<LayerComposite*>(mRoot->AsHostLayer());
     246          87 :   PostProcessLayers(mRoot, aOpaqueRegion, visible,
     247          58 :                     ViewAs<RenderTargetPixel>(rootComposite->GetShadowClipRect(),
     248             :                                               PixelCastJustification::RenderTargetIsParentLayerForRoot),
     249          58 :                     Nothing());
     250          29 : }
     251             : 
     252             : // We want to skip directly through ContainerLayers that don't have an intermediate
     253             : // surface. We compute occlusions for leaves and intermediate surfaces against
     254             : // the layer that they actually composite into so that we can use the final (snapped)
     255             : // effective transform.
     256         215 : bool ShouldProcessLayer(Layer* aLayer)
     257             : {
     258         215 :   if (!aLayer->AsContainerLayer()) {
     259         121 :     return true;
     260             :   }
     261             : 
     262          94 :   return aLayer->AsContainerLayer()->UseIntermediateSurface();
     263             : }
     264             : 
     265             : /**
     266             :  * Get accumulated transform of from the context creating layer to the
     267             :  * given layer.
     268             :  */
     269             : static Matrix4x4
     270         115 : GetAccTransformIn3DContext(Layer* aLayer) {
     271         115 :   Matrix4x4 transform = aLayer->GetLocalTransform();
     272         230 :   for (Layer* layer = aLayer->GetParent();
     273         115 :        layer && layer->Extend3DContext();
     274             :        layer = layer->GetParent()) {
     275           0 :     transform = transform * layer->GetLocalTransform();
     276             :   }
     277         115 :   return transform;
     278             : }
     279             : 
     280             : void
     281         215 : LayerManagerComposite::PostProcessLayers(Layer* aLayer,
     282             :                                          nsIntRegion& aOpaqueRegion,
     283             :                                          LayerIntRegion& aVisibleRegion,
     284             :                                          const Maybe<RenderTargetIntRect>& aRenderTargetClip,
     285             :                                          const Maybe<ParentLayerIntRect>& aClipFromAncestors)
     286             : {
     287             : 
     288             :   // Compute a clip that's the combination of our layer clip with the clip
     289             :   // from our ancestors.
     290         215 :   LayerComposite* composite = static_cast<LayerComposite*>(aLayer->AsHostLayer());
     291         336 :   Maybe<ParentLayerIntRect> layerClip = composite->GetShadowClipRect();
     292         215 :   MOZ_ASSERT(!layerClip || !aLayer->Combines3DTransformWithAncestors(),
     293             :              "The layer with a clip should not participate "
     294             :              "a 3D rendering context");
     295             :   Maybe<ParentLayerIntRect> outsideClip =
     296         336 :     IntersectMaybeRects(layerClip, aClipFromAncestors);
     297             : 
     298         336 :   Maybe<LayerIntRect> insideClip;
     299         215 :   if (aLayer->Extend3DContext()) {
     300             :     // If we're preserve-3d just pass the clip rect down directly, and we'll do the
     301             :     // conversion at the preserve-3d leaf Layer.
     302           0 :     if (outsideClip) {
     303           0 :       insideClip = Some(ViewAs<LayerPixel>(*outsideClip, PixelCastJustification::MovingDownToChildren));
     304             :     }
     305         215 :   } else if (outsideClip) {
     306             :     // Convert the combined clip into our pre-transform coordinate space, so
     307             :     // that it can later be intersected with our visible region.
     308             :     // If our transform is a perspective, there's no meaningful insideClip rect
     309             :     // we can compute (it would need to be a cone).
     310         115 :     Matrix4x4 localTransform = GetAccTransformIn3DContext(aLayer);
     311         115 :     if (!localTransform.HasPerspectiveComponent() && localTransform.Invert()) {
     312             :       LayerRect insideClipFloat =
     313         230 :         UntransformBy(ViewAs<ParentLayerToLayerMatrix4x4>(localTransform),
     314         230 :                       ParentLayerRect(*outsideClip),
     315         345 :                       LayerRect::MaxIntRect()).valueOr(LayerRect());
     316         115 :       insideClipFloat.RoundOut();
     317         115 :       LayerIntRect insideClipInt;
     318         115 :       if (insideClipFloat.ToIntRect(&insideClipInt)) {
     319         115 :         insideClip = Some(insideClipInt);
     320             :       }
     321             :     }
     322             :   }
     323             : 
     324         336 :   Maybe<ParentLayerIntRect> ancestorClipForChildren;
     325         215 :   if (insideClip) {
     326             :     ancestorClipForChildren =
     327         115 :       Some(ViewAs<ParentLayerPixel>(*insideClip, PixelCastJustification::MovingDownToChildren));
     328             :   }
     329             : 
     330         215 :   if (!ShouldProcessLayer(aLayer)) {
     331          94 :     MOZ_ASSERT(aLayer->AsContainerLayer() && !aLayer->AsContainerLayer()->UseIntermediateSurface());
     332             :     // For layers participating 3D rendering context, their visible
     333             :     // region should be empty (invisible), so we pass through them
     334             :     // without doing anything.
     335         280 :     for (Layer* child = aLayer->GetLastChild();
     336         280 :          child;
     337             :          child = child->GetPrevSibling()) {
     338         186 :       LayerComposite* childComposite = static_cast<LayerComposite*>(child->AsHostLayer());
     339         372 :       Maybe<RenderTargetIntRect> renderTargetClip = aRenderTargetClip;
     340         186 :       if (childComposite->GetShadowClipRect()) {
     341         128 :         RenderTargetIntRect clip = TransformBy(ViewAs<ParentLayerToRenderTargetMatrix4x4>(
     342          64 :           aLayer->GetEffectiveTransform(),
     343             :           PixelCastJustification::RenderTargetIsParentLayerForRoot),
     344         128 :                                                *childComposite->GetShadowClipRect());
     345          64 :         renderTargetClip = IntersectMaybeRects(renderTargetClip, Some(clip));
     346             :       }
     347             : 
     348             :       PostProcessLayers(child, aOpaqueRegion, aVisibleRegion,
     349         186 :                         renderTargetClip, ancestorClipForChildren);
     350             :     }
     351          94 :     return;
     352             :   }
     353             : 
     354         242 :   nsIntRegion localOpaque;
     355             :   // Treat layers on the path to the root of the 3D rendering context as
     356             :   // a giant layer if it is a leaf.
     357         121 :   Matrix4x4 transform = aLayer->GetEffectiveTransform();
     358         121 :   Matrix transform2d;
     359         242 :   Maybe<IntPoint> integerTranslation;
     360             :   // If aLayer has a simple transform (only an integer translation) then we
     361             :   // can easily convert aOpaqueRegion into pre-transform coordinates and include
     362             :   // that region.
     363         121 :   if (transform.Is2D(&transform2d)) {
     364         121 :     if (transform2d.IsIntegerTranslation()) {
     365         121 :       integerTranslation = Some(IntPoint::Truncate(transform2d.GetTranslation()));
     366         121 :       localOpaque = aOpaqueRegion;
     367         121 :       localOpaque.MoveBy(-*integerTranslation);
     368             :     }
     369             :   }
     370             : 
     371             :   // Save the value of localOpaque, which currently stores the region obscured
     372             :   // by siblings (and uncles and such), before our descendants contribute to it.
     373         242 :   nsIntRegion obscured = localOpaque;
     374             : 
     375             :   // Recurse on our descendants, in front-to-back order. In this process:
     376             :   //  - Occlusions are computed for them, and they contribute to localOpaque.
     377             :   //  - They recalculate their visible regions, taking ancestorClipForChildren
     378             :   //    into account, and accumulate them into descendantsVisibleRegion.
     379         242 :   LayerIntRegion descendantsVisibleRegion;
     380             : 
     381         121 :   bool hasPreserve3DChild = false;
     382         121 :   for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
     383           0 :     MOZ_ASSERT(aLayer->AsContainerLayer()->UseIntermediateSurface());
     384           0 :     LayerComposite* childComposite = static_cast<LayerComposite*>(child->AsHostLayer());
     385             :     PostProcessLayers(child, localOpaque, descendantsVisibleRegion,
     386           0 :                       ViewAs<RenderTargetPixel>(childComposite->GetShadowClipRect(),
     387             :                                                 PixelCastJustification::RenderTargetIsParentLayerForRoot),
     388           0 :                       ancestorClipForChildren);
     389           0 :     if (child->Extend3DContext()) {
     390           0 :       hasPreserve3DChild = true;
     391             :     }
     392             :   }
     393             : 
     394             :   // Recalculate our visible region.
     395         242 :   LayerIntRegion visible = composite->GetShadowVisibleRegion();
     396             : 
     397             :   // If we have descendants, throw away the visible region stored on this
     398             :   // layer, and use the region accumulated by our descendants instead.
     399         121 :   if (aLayer->GetFirstChild() && !hasPreserve3DChild) {
     400           0 :     visible = descendantsVisibleRegion;
     401             :   }
     402             : 
     403             :   // Subtract any areas that we know to be opaque.
     404         121 :   if (!obscured.IsEmpty()) {
     405          23 :     visible.SubOut(LayerIntRegion::FromUnknownRegion(obscured));
     406             :   }
     407             : 
     408             :   // Clip the visible region using the combined clip.
     409         121 :   if (insideClip) {
     410          62 :     visible.AndWith(*insideClip);
     411             :   }
     412         121 :   composite->SetShadowVisibleRegion(visible);
     413             : 
     414             :   // Transform the newly calculated visible region into our parent's space,
     415             :   // apply our clip to it (if any), and accumulate it into |aVisibleRegion|
     416             :   // for the caller to use.
     417             :   ParentLayerIntRegion visibleParentSpace = TransformBy(
     418         242 :       ViewAs<LayerToParentLayerMatrix4x4>(transform), visible);
     419         242 :   aVisibleRegion.OrWith(ViewAs<LayerPixel>(visibleParentSpace,
     420         121 :       PixelCastJustification::MovingDownToChildren));
     421             : 
     422             :   // If we have a simple transform, then we can add our opaque area into
     423             :   // aOpaqueRegion.
     424         242 :   if (integerTranslation &&
     425         242 :       !aLayer->HasMaskLayers() &&
     426         121 :       aLayer->IsOpaqueForVisibility()) {
     427         121 :     if (aLayer->IsOpaque()) {
     428          59 :       localOpaque.OrWith(composite->GetFullyRenderedRegion());
     429             :     }
     430         121 :     localOpaque.MoveBy(*integerTranslation);
     431         121 :     if (aRenderTargetClip) {
     432          62 :       localOpaque.AndWith(aRenderTargetClip->ToUnknownRect());
     433             :     }
     434         121 :     aOpaqueRegion.OrWith(localOpaque);
     435             :   }
     436             : }
     437             : 
     438             : void
     439          57 : LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp,
     440             :                                       EndTransactionFlags aFlags)
     441             : {
     442          57 :   NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?");
     443          57 :   NS_ASSERTION(!(aFlags & END_NO_COMPOSITE),
     444             :                "Shouldn't get END_NO_COMPOSITE here");
     445          57 :   mInTransaction = false;
     446          57 :   mRenderStartTime = TimeStamp::Now();
     447             : 
     448          57 :   if (!mIsCompositorReady) {
     449           0 :     return;
     450             :   }
     451          57 :   mIsCompositorReady = false;
     452             : 
     453             : #ifdef MOZ_LAYERS_HAVE_LOG
     454          57 :   MOZ_LAYERS_LOG(("  ----- (beginning paint)"));
     455          57 :   Log();
     456             : #endif
     457             : 
     458          57 :   if (mDestroyed) {
     459           0 :     NS_WARNING("Call on destroyed layer manager");
     460           0 :     return;
     461             :   }
     462             : 
     463             :   // Set composition timestamp here because we need it in
     464             :   // ComputeEffectiveTransforms (so the correct video frame size is picked) and
     465             :   // also to compute invalid regions properly.
     466          57 :   SetCompositionTime(aTimeStamp);
     467             : 
     468          57 :   if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
     469          29 :     MOZ_ASSERT(!aTimeStamp.IsNull());
     470          29 :     UpdateAndRender();
     471          29 :     mCompositor->FlushPendingNotifyNotUsed();
     472             :   }
     473             : 
     474          57 :   mCompositor->ClearTargetContext();
     475          57 :   mTarget = nullptr;
     476             : 
     477             : #ifdef MOZ_LAYERS_HAVE_LOG
     478          57 :   Log();
     479          57 :   MOZ_LAYERS_LOG(("]----- EndTransaction"));
     480             : #endif
     481             : }
     482             : 
     483             : void
     484          29 : LayerManagerComposite::UpdateAndRender()
     485             : {
     486          56 :   nsIntRegion invalid;
     487             :   // The results of our drawing always go directly into a pixel buffer,
     488             :   // so we don't need to pass any global transform here.
     489          29 :   mRoot->ComputeEffectiveTransforms(gfx::Matrix4x4());
     490             : 
     491          56 :   nsIntRegion opaque;
     492          29 :   PostProcessLayers(opaque);
     493             : 
     494          29 :   if (mClonedLayerTreeProperties) {
     495             :     // We need to compute layer tree differences even if we're not going to
     496             :     // immediately use the resulting damage area, since ComputeDifferences
     497             :     // is also responsible for invalidates intermediate surfaces in
     498             :     // ContainerLayers.
     499          56 :     nsIntRegion changed = mClonedLayerTreeProperties->ComputeDifferences(mRoot, nullptr);
     500             : 
     501          28 :     if (mTarget) {
     502             :       // Since we're composing to an external target, we're not going to use
     503             :       // the damage region from layers changes - we want to composite
     504             :       // everything in the target bounds. Instead we accumulate the layers
     505             :       // damage region for the next window composite.
     506           0 :       mInvalidRegion.Or(mInvalidRegion, changed);
     507             :     } else {
     508          28 :       invalid = Move(changed);
     509             :     }
     510             :   }
     511             : 
     512          29 :   if (mTarget) {
     513           0 :     invalid.Or(invalid, mTargetBounds);
     514             :   } else {
     515             :     // If we didn't have a previous layer tree, invalidate the entire render
     516             :     // area.
     517          29 :     if (!mClonedLayerTreeProperties) {
     518           1 :       invalid.Or(invalid, mRenderBounds);
     519             :     }
     520             : 
     521             :     // Add any additional invalid rects from the window manager or previous
     522             :     // damage computed during ComposeToTarget().
     523          29 :     invalid.Or(invalid, mInvalidRegion);
     524          29 :     mInvalidRegion.SetEmpty();
     525             :   }
     526             : 
     527          29 :   if (invalid.IsEmpty() && !mWindowOverlayChanged) {
     528             :     // Composition requested, but nothing has changed. Don't do any work.
     529           2 :     mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot());
     530           2 :     return;
     531             :   }
     532             : 
     533             :   // We don't want our debug overlay to cause more frames to happen
     534             :   // so we will invalidate after we've decided if something changed.
     535          27 :   InvalidateDebugOverlay(invalid, mRenderBounds);
     536             : 
     537          27 :   Render(invalid, opaque);
     538             : #if defined(MOZ_WIDGET_ANDROID)
     539             :   RenderToPresentationSurface();
     540             : #endif
     541          27 :   mWindowOverlayChanged = false;
     542             : 
     543             :   // Update cached layer tree information.
     544          27 :   mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot());
     545             : }
     546             : 
     547             : already_AddRefed<DrawTarget>
     548           0 : LayerManagerComposite::CreateOptimalMaskDrawTarget(const IntSize &aSize)
     549             : {
     550           0 :   MOZ_CRASH("Should only be called on the drawing side");
     551             :   return nullptr;
     552             : }
     553             : 
     554             : LayerComposite*
     555          81 : LayerManagerComposite::RootLayer() const
     556             : {
     557          81 :   if (mDestroyed) {
     558           0 :     NS_WARNING("Call on destroyed layer manager");
     559           0 :     return nullptr;
     560             :   }
     561             : 
     562          81 :   return ToLayerComposite(mRoot);
     563             : }
     564             : 
     565             : void
     566          27 : LayerManagerComposite::InvalidateDebugOverlay(nsIntRegion& aInvalidRegion, const IntRect& aBounds)
     567             : {
     568          27 :   bool drawFps = gfxPrefs::LayersDrawFPS();
     569          27 :   bool drawFrameColorBars = gfxPrefs::CompositorDrawColorBars();
     570             : 
     571          27 :   if (drawFps) {
     572           0 :     aInvalidRegion.Or(aInvalidRegion, nsIntRect(0, 0, 650, 400));
     573             :   }
     574          27 :   if (drawFrameColorBars) {
     575           0 :     aInvalidRegion.Or(aInvalidRegion, nsIntRect(0, 0, 10, aBounds.height));
     576             :   }
     577             : 
     578             : #ifdef USE_SKIA
     579          27 :   bool drawPaintTimes = gfxPrefs::AlwaysPaint();
     580          27 :   if (drawPaintTimes) {
     581           0 :     aInvalidRegion.Or(aInvalidRegion, nsIntRect(PaintCounter::GetPaintRect()));
     582             :   }
     583             : #endif
     584          27 : }
     585             : 
     586             : #ifdef USE_SKIA
     587             : void
     588           0 : LayerManagerComposite::DrawPaintTimes(Compositor* aCompositor)
     589             : {
     590           0 :   if (!mPaintCounter) {
     591           0 :     mPaintCounter = new PaintCounter();
     592             :   }
     593             : 
     594           0 :   TimeDuration compositeTime = TimeStamp::Now() - mRenderStartTime;
     595           0 :   mPaintCounter->Draw(aCompositor, mLastPaintTime, compositeTime);
     596           0 : }
     597             : #endif
     598             : 
     599             : static uint16_t sFrameCount = 0;
     600             : void
     601          27 : LayerManagerComposite::RenderDebugOverlay(const IntRect& aBounds)
     602             : {
     603          27 :   bool drawFps = gfxPrefs::LayersDrawFPS();
     604          27 :   bool drawFrameColorBars = gfxPrefs::CompositorDrawColorBars();
     605             : 
     606             :   // Don't draw diagnostic overlays if we want to snapshot the output.
     607          27 :   if (mTarget) {
     608           0 :     return;
     609             :   }
     610             : 
     611          27 :   if (drawFps) {
     612           0 :     float alpha = 1;
     613             : #ifdef ANDROID
     614             :     // Draw a translation delay warning overlay
     615             :     int width;
     616             :     int border;
     617             : 
     618             :     TimeStamp now = TimeStamp::Now();
     619             :     if (!mWarnTime.IsNull() && (now - mWarnTime).ToMilliseconds() < kVisualWarningDuration) {
     620             :       EffectChain effects;
     621             : 
     622             :       // Black blorder
     623             :       border = 4;
     624             :       width = 6;
     625             :       effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0, 0, 0, 1));
     626             :       mCompositor->DrawQuad(gfx::Rect(border, border, aBounds.width - 2 * border, width),
     627             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     628             :       mCompositor->DrawQuad(gfx::Rect(border, aBounds.height - border - width, aBounds.width - 2 * border, width),
     629             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     630             :       mCompositor->DrawQuad(gfx::Rect(border, border + width, width, aBounds.height - 2 * border - width * 2),
     631             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     632             :       mCompositor->DrawQuad(gfx::Rect(aBounds.width - border - width, border + width, width, aBounds.height - 2 * border - 2 * width),
     633             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     634             : 
     635             :       // Content
     636             :       border = 5;
     637             :       width = 4;
     638             :       effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(1, 1.f - mWarningLevel, 0, 1));
     639             :       mCompositor->DrawQuad(gfx::Rect(border, border, aBounds.width - 2 * border, width),
     640             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     641             :       mCompositor->DrawQuad(gfx::Rect(border, aBounds.height - border - width, aBounds.width - 2 * border, width),
     642             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     643             :       mCompositor->DrawQuad(gfx::Rect(border, border + width, width, aBounds.height - 2 * border - width * 2),
     644             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     645             :       mCompositor->DrawQuad(gfx::Rect(aBounds.width - border - width, border + width, width, aBounds.height - 2 * border - 2 * width),
     646             :                             aBounds, effects, alpha, gfx::Matrix4x4());
     647             :       SetDebugOverlayWantsNextFrame(true);
     648             :     }
     649             : #endif
     650             : 
     651           0 :     GPUStats stats;
     652           0 :     stats.mScreenPixels = mRenderBounds.width * mRenderBounds.height;
     653           0 :     mCompositor->GetFrameStats(&stats);
     654             : 
     655           0 :     std::string text = mDiagnostics->GetFrameOverlayString(stats);
     656           0 :     mTextRenderer->RenderText(
     657             :       mCompositor,
     658             :       text,
     659           0 :       IntPoint(2, 5),
     660           0 :       Matrix4x4(),
     661             :       24,
     662             :       600,
     663           0 :       TextRenderer::FontType::FixedWidth);
     664             : 
     665           0 :     if (mUnusedApzTransformWarning) {
     666             :       // If we have an unused APZ transform on this composite, draw a 20x20 red box
     667             :       // in the top-right corner
     668           0 :       EffectChain effects;
     669           0 :       effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(1, 0, 0, 1));
     670           0 :       mCompositor->DrawQuad(gfx::Rect(aBounds.width - 20, 0, 20, 20),
     671           0 :                             aBounds, effects, alpha, gfx::Matrix4x4());
     672             : 
     673           0 :       mUnusedApzTransformWarning = false;
     674           0 :       SetDebugOverlayWantsNextFrame(true);
     675             :     }
     676           0 :     if (mDisabledApzWarning) {
     677             :       // If we have a disabled APZ on this composite, draw a 20x20 yellow box
     678             :       // in the top-right corner, to the left of the unused-apz-transform
     679             :       // warning box
     680           0 :       EffectChain effects;
     681           0 :       effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(1, 1, 0, 1));
     682           0 :       mCompositor->DrawQuad(gfx::Rect(aBounds.width - 40, 0, 20, 20),
     683           0 :                             aBounds, effects, alpha, gfx::Matrix4x4());
     684             : 
     685           0 :       mDisabledApzWarning = false;
     686           0 :       SetDebugOverlayWantsNextFrame(true);
     687             :     }
     688             :   }
     689             : 
     690          27 :   if (drawFrameColorBars) {
     691           0 :     gfx::IntRect sideRect(0, 0, 10, aBounds.height);
     692             : 
     693           0 :     EffectChain effects;
     694           0 :     effects.mPrimaryEffect = new EffectSolidColor(gfxUtils::GetColorForFrameNumber(sFrameCount));
     695           0 :     mCompositor->DrawQuad(Rect(sideRect),
     696             :                           sideRect,
     697             :                           effects,
     698             :                           1.0,
     699           0 :                           gfx::Matrix4x4());
     700             : 
     701             :   }
     702             : 
     703          27 :   if (drawFrameColorBars) {
     704             :     // We intentionally overflow at 2^16.
     705           0 :     sFrameCount++;
     706             :   }
     707             : 
     708             : #ifdef USE_SKIA
     709          27 :   bool drawPaintTimes = gfxPrefs::AlwaysPaint();
     710          27 :   if (drawPaintTimes) {
     711           0 :     DrawPaintTimes(mCompositor);
     712             :   }
     713             : #endif
     714             : }
     715             : 
     716             : RefPtr<CompositingRenderTarget>
     717           0 : LayerManagerComposite::PushGroupForLayerEffects()
     718             : {
     719             :   // This is currently true, so just making sure that any new use of this
     720             :   // method is flagged for investigation
     721           0 :   MOZ_ASSERT(gfxPrefs::LayersEffectInvert() ||
     722             :              gfxPrefs::LayersEffectGrayscale() ||
     723             :              gfxPrefs::LayersEffectContrast() != 0.0);
     724             : 
     725           0 :   RefPtr<CompositingRenderTarget> previousTarget = mCompositor->GetCurrentRenderTarget();
     726             :   // make our render target the same size as the destination target
     727             :   // so that we don't have to change size if the drawing area changes.
     728           0 :   IntRect rect(previousTarget->GetOrigin(), previousTarget->GetSize());
     729             :   // XXX: I'm not sure if this is true or not...
     730           0 :   MOZ_ASSERT(rect.x == 0 && rect.y == 0);
     731           0 :   if (!mTwoPassTmpTarget ||
     732           0 :       mTwoPassTmpTarget->GetSize() != previousTarget->GetSize() ||
     733           0 :       mTwoPassTmpTarget->GetOrigin() != previousTarget->GetOrigin()) {
     734           0 :     mTwoPassTmpTarget = mCompositor->CreateRenderTarget(rect, INIT_MODE_NONE);
     735             :   }
     736           0 :   MOZ_ASSERT(mTwoPassTmpTarget);
     737           0 :   mCompositor->SetRenderTarget(mTwoPassTmpTarget);
     738           0 :   return previousTarget;
     739             : }
     740             : void
     741           0 : LayerManagerComposite::PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget,
     742             :                                                IntRect aClipRect,
     743             :                                                bool aGrayscaleEffect,
     744             :                                                bool aInvertEffect,
     745             :                                                float aContrastEffect)
     746             : {
     747           0 :   MOZ_ASSERT(mTwoPassTmpTarget);
     748             : 
     749             :   // This is currently true, so just making sure that any new use of this
     750             :   // method is flagged for investigation
     751           0 :   MOZ_ASSERT(aInvertEffect || aGrayscaleEffect || aContrastEffect != 0.0);
     752             : 
     753           0 :   mCompositor->SetRenderTarget(aPreviousTarget);
     754             : 
     755           0 :   EffectChain effectChain(RootLayer());
     756           0 :   Matrix5x4 effectMatrix;
     757           0 :   if (aGrayscaleEffect) {
     758             :     // R' = G' = B' = luminance
     759             :     // R' = 0.2126*R + 0.7152*G + 0.0722*B
     760             :     // G' = 0.2126*R + 0.7152*G + 0.0722*B
     761             :     // B' = 0.2126*R + 0.7152*G + 0.0722*B
     762             :     Matrix5x4 grayscaleMatrix(0.2126f, 0.2126f, 0.2126f, 0,
     763             :                               0.7152f, 0.7152f, 0.7152f, 0,
     764             :                               0.0722f, 0.0722f, 0.0722f, 0,
     765             :                               0,       0,       0,       1,
     766           0 :                               0,       0,       0,       0);
     767           0 :     effectMatrix = grayscaleMatrix;
     768             :   }
     769             : 
     770           0 :   if (aInvertEffect) {
     771             :     // R' = 1 - R
     772             :     // G' = 1 - G
     773             :     // B' = 1 - B
     774             :     Matrix5x4 colorInvertMatrix(-1,  0,  0, 0,
     775             :                                  0, -1,  0, 0,
     776             :                                  0,  0, -1, 0,
     777             :                                  0,  0,  0, 1,
     778           0 :                                  1,  1,  1, 0);
     779           0 :     effectMatrix = effectMatrix * colorInvertMatrix;
     780             :   }
     781             : 
     782           0 :   if (aContrastEffect != 0.0) {
     783             :     // Multiplying with:
     784             :     // R' = (1 + c) * (R - 0.5) + 0.5
     785             :     // G' = (1 + c) * (G - 0.5) + 0.5
     786             :     // B' = (1 + c) * (B - 0.5) + 0.5
     787           0 :     float cP1 = aContrastEffect + 1;
     788           0 :     float hc = 0.5*aContrastEffect;
     789             :     Matrix5x4 contrastMatrix( cP1,   0,   0, 0,
     790             :                                 0, cP1,   0, 0,
     791             :                                 0,   0, cP1, 0,
     792             :                                 0,   0,   0, 1,
     793           0 :                               -hc, -hc, -hc, 0);
     794           0 :     effectMatrix = effectMatrix * contrastMatrix;
     795             :   }
     796             : 
     797           0 :   effectChain.mPrimaryEffect = new EffectRenderTarget(mTwoPassTmpTarget);
     798           0 :   effectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX] = new EffectColorMatrix(effectMatrix);
     799             : 
     800           0 :   mCompositor->DrawQuad(Rect(Point(0, 0), Size(mTwoPassTmpTarget->GetSize())), aClipRect, effectChain, 1.,
     801           0 :                         Matrix4x4());
     802           0 : }
     803             : 
     804             : // Used to clear the 'mLayerComposited' flag at the beginning of each Render().
     805             : static void
     806          27 : ClearLayerFlags(Layer* aLayer) {
     807          27 :   ForEachNode<ForwardIterator>(
     808             :       aLayer,
     809         202 :       [] (Layer* layer)
     810             :       {
     811         202 :         if (layer->AsHostLayer()) {
     812         202 :           static_cast<LayerComposite*>(layer->AsHostLayer())->SetLayerComposited(false);
     813             :         }
     814         229 :       });
     815          27 : }
     816             : 
     817             : #if defined(MOZ_WIDGET_ANDROID)
     818             : class ScopedCompositorRenderOffset {
     819             : public:
     820             :   ScopedCompositorRenderOffset(CompositorOGL* aCompositor, const ScreenPoint& aOffset) :
     821             :     mCompositor(aCompositor),
     822             :     mOriginalOffset(mCompositor->GetScreenRenderOffset()),
     823             :     mOriginalProjection(mCompositor->GetProjMatrix())
     824             :   {
     825             :     ScreenPoint offset(mOriginalOffset.x + aOffset.x, mOriginalOffset.y + aOffset.y);
     826             :     mCompositor->SetScreenRenderOffset(offset);
     827             :     // Calling CompositorOGL::SetScreenRenderOffset does not affect the projection matrix
     828             :     // so adjust that as well.
     829             :     gfx::Matrix4x4 mat = mOriginalProjection;
     830             :     mat.PreTranslate(aOffset.x, aOffset.y, 0.0f);
     831             :     mCompositor->SetProjMatrix(mat);
     832             :   }
     833             :   ~ScopedCompositorRenderOffset()
     834             :   {
     835             :     mCompositor->SetScreenRenderOffset(mOriginalOffset);
     836             :     mCompositor->SetProjMatrix(mOriginalProjection);
     837             :   }
     838             : private:
     839             :   CompositorOGL* const mCompositor;
     840             :   const ScreenPoint mOriginalOffset;
     841             :   const gfx::Matrix4x4 mOriginalProjection;
     842             : };
     843             : #endif // defined(MOZ_WIDGET_ANDROID)
     844             : 
     845             : void
     846          27 : LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion, const nsIntRegion& aOpaqueRegion)
     847             : {
     848          54 :   AUTO_PROFILER_LABEL("LayerManagerComposite::Render", GRAPHICS);
     849             : 
     850          27 :   if (mDestroyed || !mCompositor || mCompositor->IsDestroyed()) {
     851           0 :     NS_WARNING("Call on destroyed layer manager");
     852           0 :     return;
     853             :   }
     854             : 
     855          27 :   ClearLayerFlags(mRoot);
     856             : 
     857             :   // At this time, it doesn't really matter if these preferences change
     858             :   // during the execution of the function; we should be safe in all
     859             :   // permutations. However, may as well just get the values onces and
     860             :   // then use them, just in case the consistency becomes important in
     861             :   // the future.
     862          27 :   bool invertVal = gfxPrefs::LayersEffectInvert();
     863          27 :   bool grayscaleVal = gfxPrefs::LayersEffectGrayscale();
     864          27 :   float contrastVal = gfxPrefs::LayersEffectContrast();
     865          27 :   bool haveLayerEffects = (invertVal || grayscaleVal || contrastVal != 0.0);
     866             : 
     867             :   // Set LayerScope begin/end frame
     868          54 :   LayerScopeAutoFrame frame(PR_Now());
     869             : 
     870             :   // Dump to console
     871          27 :   if (gfxPrefs::LayersDump()) {
     872           0 :     this->Dump(/* aSorted= */true);
     873          27 :   } else if (profiler_feature_active(ProfilerFeature::LayersDump)) {
     874           0 :     std::stringstream ss;
     875           0 :     Dump(ss);
     876           0 :     profiler_tracing("log", ss.str().c_str());
     877             :   }
     878             : 
     879             :   // Dump to LayerScope Viewer
     880          27 :   if (LayerScope::CheckSendable()) {
     881             :     // Create a LayersPacket, dump Layers into it and transfer the
     882             :     // packet('s ownership) to LayerScope.
     883           0 :     auto packet = MakeUnique<layerscope::Packet>();
     884           0 :     layerscope::LayersPacket* layersPacket = packet->mutable_layers();
     885           0 :     this->Dump(layersPacket);
     886           0 :     LayerScope::SendLayerDump(Move(packet));
     887             :   }
     888             : 
     889             :   mozilla::widget::WidgetRenderingContext widgetContext;
     890             : #if defined(XP_MACOSX)
     891             :   widgetContext.mLayerManager = this;
     892             : #elif defined(MOZ_WIDGET_ANDROID)
     893             :   widgetContext.mCompositor = GetCompositor();
     894             : #endif
     895             : 
     896             :   {
     897          54 :     AUTO_PROFILER_LABEL("LayerManagerComposite::Render:Prerender", GRAPHICS);
     898             : 
     899          27 :     if (!mCompositor->GetWidget()->PreRender(&widgetContext)) {
     900           0 :       return;
     901             :     }
     902             :   }
     903             : 
     904          27 :   ParentLayerIntRect clipRect;
     905          27 :   IntRect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height);
     906          27 :   IntRect actualBounds;
     907             : 
     908          27 :   CompositorBench(mCompositor, bounds);
     909             : 
     910          27 :   MOZ_ASSERT(mRoot->GetOpacity() == 1);
     911             : #if defined(MOZ_WIDGET_ANDROID)
     912             :   LayerMetricsWrapper wrapper = GetRootContentLayer();
     913             :   if (wrapper) {
     914             :     mCompositor->SetClearColor(wrapper.Metadata().GetBackgroundColor());
     915             :   } else {
     916             :     mCompositor->SetClearColorToDefault();
     917             :   }
     918             : #endif
     919          27 :   if (mRoot->GetClipRect()) {
     920           0 :     clipRect = *mRoot->GetClipRect();
     921           0 :     IntRect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
     922           0 :     mCompositor->BeginFrame(aInvalidRegion, &rect, bounds, aOpaqueRegion, nullptr, &actualBounds);
     923             :   } else {
     924          27 :     gfx::IntRect rect;
     925          27 :     mCompositor->BeginFrame(aInvalidRegion, nullptr, bounds, aOpaqueRegion, &rect, &actualBounds);
     926          27 :     clipRect = ParentLayerIntRect(rect.x, rect.y, rect.width, rect.height);
     927             :   }
     928             : #if defined(MOZ_WIDGET_ANDROID)
     929             :   ScreenCoord offset = GetContentShiftForToolbar();
     930             :   ScopedCompositorRenderOffset scopedOffset(mCompositor->AsCompositorOGL(), ScreenPoint(0.0f, offset));
     931             : #endif
     932             : 
     933          27 :   if (actualBounds.IsEmpty()) {
     934           0 :     mCompositor->GetWidget()->PostRender(&widgetContext);
     935           0 :     return;
     936             :   }
     937             : 
     938             :   // Allow widget to render a custom background.
     939          54 :   mCompositor->GetWidget()->DrawWindowUnderlay(
     940          54 :     &widgetContext, LayoutDeviceIntRect::FromUnknownRect(actualBounds));
     941             : 
     942          54 :   RefPtr<CompositingRenderTarget> previousTarget;
     943          27 :   if (haveLayerEffects) {
     944           0 :     previousTarget = PushGroupForLayerEffects();
     945             :   } else {
     946          27 :     mTwoPassTmpTarget = nullptr;
     947             :   }
     948             : 
     949             :   // Render our layers.
     950             :   {
     951          27 :     Diagnostics::Record record(mRenderStartTime);
     952          27 :     RootLayer()->Prepare(ViewAs<RenderTargetPixel>(clipRect, PixelCastJustification::RenderTargetIsParentLayerForRoot));
     953          27 :     if (record.Recording()) {
     954           0 :       mDiagnostics->RecordPrepareTime(record.Duration());
     955             :     }
     956             :   }
     957             :   // Execute draw commands.
     958             :   {
     959          27 :     Diagnostics::Record record;
     960          27 :     RootLayer()->RenderLayer(clipRect.ToUnknownRect(), Nothing());
     961          27 :     if (record.Recording()) {
     962           0 :       mDiagnostics->RecordCompositeTime(record.Duration());
     963             :     }
     964             :   }
     965          27 :   RootLayer()->Cleanup();
     966             : 
     967          27 :   if (!mRegionToClear.IsEmpty()) {
     968           0 :     for (auto iter = mRegionToClear.RectIter(); !iter.Done(); iter.Next()) {
     969           0 :       const IntRect& r = iter.Get();
     970           0 :       mCompositor->ClearRect(Rect(r.x, r.y, r.width, r.height));
     971             :     }
     972             :   }
     973             : 
     974          27 :   if (mTwoPassTmpTarget) {
     975           0 :     MOZ_ASSERT(haveLayerEffects);
     976           0 :     PopGroupForLayerEffects(previousTarget, clipRect.ToUnknownRect(),
     977           0 :                             grayscaleVal, invertVal, contrastVal);
     978             :   }
     979             : 
     980             :   // Allow widget to render a custom foreground.
     981          54 :   mCompositor->GetWidget()->DrawWindowOverlay(
     982          54 :     &widgetContext, LayoutDeviceIntRect::FromUnknownRect(actualBounds));
     983             : 
     984          27 :   mCompositor->NormalDrawingDone();
     985             : 
     986             : #if defined(MOZ_WIDGET_ANDROID)
     987             :   // Depending on the content shift the toolbar may be rendered on top of
     988             :   // some of the content so it must be rendered after the content.
     989             :   RenderToolbar();
     990             :   HandlePixelsTarget();
     991             : #endif // defined(MOZ_WIDGET_ANDROID)
     992             : 
     993             :   // Debugging
     994          27 :   RenderDebugOverlay(actualBounds);
     995             : 
     996             :   {
     997          54 :     AUTO_PROFILER_LABEL("LayerManagerComposite::Render:EndFrame", GRAPHICS);
     998             : 
     999          27 :     mCompositor->EndFrame();
    1000             : 
    1001             :     // Call after EndFrame()
    1002          27 :     mCompositor->SetDispAcquireFence(mRoot);
    1003             :   }
    1004             : 
    1005          27 :   mCompositor->GetWidget()->PostRender(&widgetContext);
    1006             : 
    1007          27 :   RecordFrame();
    1008             : }
    1009             : 
    1010             : #if defined(MOZ_WIDGET_ANDROID)
    1011             : class ScopedCompositorProjMatrix {
    1012             : public:
    1013             :   ScopedCompositorProjMatrix(CompositorOGL* aCompositor, const Matrix4x4& aProjMatrix):
    1014             :     mCompositor(aCompositor),
    1015             :     mOriginalProjMatrix(mCompositor->GetProjMatrix())
    1016             :   {
    1017             :     mCompositor->SetProjMatrix(aProjMatrix);
    1018             :   }
    1019             : 
    1020             :   ~ScopedCompositorProjMatrix()
    1021             :   {
    1022             :     mCompositor->SetProjMatrix(mOriginalProjMatrix);
    1023             :   }
    1024             : private:
    1025             :   CompositorOGL* const mCompositor;
    1026             :   const Matrix4x4 mOriginalProjMatrix;
    1027             : };
    1028             : 
    1029             : class ScopedCompostitorSurfaceSize {
    1030             : public:
    1031             :   ScopedCompostitorSurfaceSize(CompositorOGL* aCompositor, const gfx::IntSize& aSize) :
    1032             :     mCompositor(aCompositor),
    1033             :     mOriginalSize(mCompositor->GetDestinationSurfaceSize())
    1034             :   {
    1035             :     mCompositor->SetDestinationSurfaceSize(aSize);
    1036             :   }
    1037             :   ~ScopedCompostitorSurfaceSize()
    1038             :   {
    1039             :     mCompositor->SetDestinationSurfaceSize(mOriginalSize);
    1040             :   }
    1041             : private:
    1042             :   CompositorOGL* const mCompositor;
    1043             :   const gfx::IntSize mOriginalSize;
    1044             : };
    1045             : 
    1046             : class ScopedContextSurfaceOverride {
    1047             : public:
    1048             :   ScopedContextSurfaceOverride(GLContextEGL* aContext, void* aSurface) :
    1049             :     mContext(aContext)
    1050             :   {
    1051             :     MOZ_ASSERT(aSurface);
    1052             :     mContext->SetEGLSurfaceOverride(aSurface);
    1053             :     mContext->MakeCurrent(true);
    1054             :   }
    1055             :   ~ScopedContextSurfaceOverride()
    1056             :   {
    1057             :     mContext->SetEGLSurfaceOverride(EGL_NO_SURFACE);
    1058             :     mContext->MakeCurrent(true);
    1059             :   }
    1060             : private:
    1061             :   GLContextEGL* const mContext;
    1062             : };
    1063             : 
    1064             : void
    1065             : LayerManagerComposite::RenderToPresentationSurface()
    1066             : {
    1067             :   widget::CompositorWidget* const widget = mCompositor->GetWidget();
    1068             :   ANativeWindow* window = widget->AsAndroid()->GetPresentationANativeWindow();
    1069             : 
    1070             :   if (!window) {
    1071             :     return;
    1072             :   }
    1073             : 
    1074             :   EGLSurface surface = widget->AsAndroid()->GetPresentationEGLSurface();
    1075             : 
    1076             :   if (!surface) {
    1077             :     //create surface;
    1078             :     surface = GLContextProviderEGL::CreateEGLSurface(window);
    1079             :     if (!surface) {
    1080             :       return;
    1081             :     }
    1082             : 
    1083             :     widget->AsAndroid()->SetPresentationEGLSurface(surface);
    1084             :   }
    1085             : 
    1086             :   CompositorOGL* compositor = mCompositor->AsCompositorOGL();
    1087             :   GLContext* gl = compositor->gl();
    1088             :   GLContextEGL* egl = GLContextEGL::Cast(gl);
    1089             : 
    1090             :   if (!egl) {
    1091             :     return;
    1092             :   }
    1093             : 
    1094             :   const IntSize windowSize(ANativeWindow_getWidth(window),
    1095             :                            ANativeWindow_getHeight(window));
    1096             : 
    1097             : 
    1098             :   if ((windowSize.width <= 0) || (windowSize.height <= 0)) {
    1099             :     return;
    1100             :   }
    1101             : 
    1102             :   ScreenRotation rotation = compositor->GetScreenRotation();
    1103             : 
    1104             :   const int actualWidth = windowSize.width;
    1105             :   const int actualHeight = windowSize.height;
    1106             : 
    1107             :   const gfx::IntSize originalSize = compositor->GetDestinationSurfaceSize();
    1108             :   const nsIntRect originalRect = nsIntRect(0, 0, originalSize.width, originalSize.height);
    1109             : 
    1110             :   int pageWidth = originalSize.width;
    1111             :   int pageHeight = originalSize.height;
    1112             :   if (rotation == ROTATION_90 || rotation == ROTATION_270) {
    1113             :     pageWidth = originalSize.height;
    1114             :     pageHeight = originalSize.width;
    1115             :   }
    1116             : 
    1117             :   float scale = 1.0;
    1118             : 
    1119             :   if ((pageWidth > actualWidth) || (pageHeight > actualHeight)) {
    1120             :     const float scaleWidth = (float)actualWidth / (float)pageWidth;
    1121             :     const float scaleHeight = (float)actualHeight / (float)pageHeight;
    1122             :     scale = scaleWidth <= scaleHeight ? scaleWidth : scaleHeight;
    1123             :   }
    1124             : 
    1125             :   const gfx::IntSize actualSize(actualWidth, actualHeight);
    1126             :   ScopedCompostitorSurfaceSize overrideSurfaceSize(compositor, actualSize);
    1127             : 
    1128             :   const ScreenPoint offset((actualWidth - (int)(scale * pageWidth)) / 2, 0);
    1129             :   ScopedContextSurfaceOverride overrideSurface(egl, surface);
    1130             : 
    1131             :   Matrix viewMatrix = ComputeTransformForRotation(originalRect,
    1132             :                                                   rotation);
    1133             :   viewMatrix.Invert(); // unrotate
    1134             :   viewMatrix.PostScale(scale, scale);
    1135             :   viewMatrix.PostTranslate(offset.x, offset.y);
    1136             :   Matrix4x4 matrix = Matrix4x4::From2D(viewMatrix);
    1137             : 
    1138             :   mRoot->ComputeEffectiveTransforms(matrix);
    1139             :   nsIntRegion opaque;
    1140             :   PostProcessLayers(opaque);
    1141             : 
    1142             :   nsIntRegion invalid;
    1143             :   IntRect bounds = IntRect::Truncate(0, 0, scale * pageWidth, actualHeight);
    1144             :   IntRect rect, actualBounds;
    1145             :   MOZ_ASSERT(mRoot->GetOpacity() == 1);
    1146             :   mCompositor->BeginFrame(invalid, nullptr, bounds, nsIntRegion(), &rect, &actualBounds);
    1147             : 
    1148             :   // The Java side of Fennec sets a scissor rect that accounts for
    1149             :   // chrome such as the URL bar. Override that so that the entire frame buffer
    1150             :   // is cleared.
    1151             :   ScopedScissorRect scissorRect(egl, 0, 0, actualWidth, actualHeight);
    1152             :   egl->fClearColor(0.0, 0.0, 0.0, 0.0);
    1153             :   egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
    1154             : 
    1155             :   const IntRect clipRect = IntRect::Truncate(0, 0, actualWidth, actualHeight);
    1156             : 
    1157             :   RootLayer()->Prepare(RenderTargetIntRect::FromUnknownRect(clipRect));
    1158             :   RootLayer()->RenderLayer(clipRect, Nothing());
    1159             : 
    1160             :   mCompositor->EndFrame();
    1161             : }
    1162             : 
    1163             : ScreenCoord
    1164             : LayerManagerComposite::GetContentShiftForToolbar()
    1165             : {
    1166             :   ScreenCoord result(0.0f);
    1167             :   // If GetTargetContext return is not null we are not drawing to the screen so there will not be any content offset.
    1168             :   if (mCompositor->GetTargetContext() != nullptr) {
    1169             :     return result;
    1170             :   }
    1171             : 
    1172             :   if (CompositorBridgeParent* bridge = mCompositor->GetCompositorBridgeParent()) {
    1173             :     AndroidDynamicToolbarAnimator* animator = bridge->GetAPZCTreeManager()->GetAndroidDynamicToolbarAnimator();
    1174             :     MOZ_RELEASE_ASSERT(animator);
    1175             :     result.value = (float)animator->GetCurrentContentOffset().value;
    1176             :   }
    1177             :   return result;
    1178             : }
    1179             : 
    1180             : void
    1181             : LayerManagerComposite::RenderToolbar()
    1182             : {
    1183             :   // If GetTargetContext return is not null we are not drawing to the screen so don't draw the toolbar.
    1184             :   if (mCompositor->GetTargetContext() != nullptr) {
    1185             :     return;
    1186             :   }
    1187             : 
    1188             :   if (CompositorBridgeParent* bridge = mCompositor->GetCompositorBridgeParent()) {
    1189             :     AndroidDynamicToolbarAnimator* animator = bridge->GetAPZCTreeManager()->GetAndroidDynamicToolbarAnimator();
    1190             :     MOZ_RELEASE_ASSERT(animator);
    1191             : 
    1192             :     animator->UpdateToolbarSnapshotTexture(mCompositor->AsCompositorOGL());
    1193             : 
    1194             :     int32_t toolbarHeight = animator->GetCurrentToolbarHeight();
    1195             :     if (toolbarHeight == 0) {
    1196             :       return;
    1197             :     }
    1198             : 
    1199             :     EffectChain effects;
    1200             :     effects.mPrimaryEffect = animator->GetToolbarEffect();
    1201             : 
    1202             :     // If GetToolbarEffect returns null, nothing is rendered for the static snapshot of the toolbar.
    1203             :     // If the real toolbar chrome is not covering this portion of the surface, the clear color
    1204             :     // of the surface will be visible. On Android the clear color is the background color of the page.
    1205             :     if (effects.mPrimaryEffect) {
    1206             :       ScopedCompositorRenderOffset toolbarOffset(mCompositor->AsCompositorOGL(),
    1207             :                                                  ScreenPoint(0.0f, -animator->GetCurrentContentOffset()));
    1208             :       mCompositor->DrawQuad(gfx::Rect(0, 0, mRenderBounds.width, toolbarHeight),
    1209             :                             IntRect(0, 0, mRenderBounds.width, toolbarHeight), effects, 1.0, gfx::Matrix4x4());
    1210             :     }
    1211             :   }
    1212             : }
    1213             : 
    1214             : // Used by robocop tests to get a snapshot of the frame buffer.
    1215             : void
    1216             : LayerManagerComposite::HandlePixelsTarget()
    1217             : {
    1218             :   if (!mScreenPixelsTarget) {
    1219             :     return;
    1220             :   }
    1221             : 
    1222             :   int32_t bufferWidth = mRenderBounds.width;
    1223             :   int32_t bufferHeight = mRenderBounds.height;
    1224             :   ipc::Shmem mem;
    1225             :   if (!mScreenPixelsTarget->AllocPixelBuffer(bufferWidth * bufferHeight * sizeof(uint32_t), &mem)) {
    1226             :     // Failed to alloc shmem, Just bail out.
    1227             :     return;
    1228             :   }
    1229             :   CompositorOGL* compositor = mCompositor->AsCompositorOGL();
    1230             :   GLContext* gl = compositor->gl();
    1231             :   MOZ_ASSERT(gl);
    1232             :   gl->fReadPixels(0, 0, bufferWidth, bufferHeight, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, mem.get<uint8_t>());
    1233             :   Unused << mScreenPixelsTarget->SendScreenPixels(mem, ScreenIntSize(bufferWidth, bufferHeight));
    1234             :   mScreenPixelsTarget = nullptr;
    1235             : }
    1236             : #endif
    1237             : 
    1238             : class TextLayerComposite : public TextLayer,
    1239             :                            public LayerComposite
    1240             : {
    1241             : public:
    1242           0 :   explicit TextLayerComposite(LayerManagerComposite *aManager)
    1243           0 :     : TextLayer(aManager, nullptr)
    1244           0 :     , LayerComposite(aManager)
    1245             :   {
    1246           0 :     MOZ_COUNT_CTOR(TextLayerComposite);
    1247           0 :     mImplData = static_cast<LayerComposite*>(this);
    1248           0 :   }
    1249             : 
    1250             : protected:
    1251           0 :   ~TextLayerComposite()
    1252           0 :   {
    1253           0 :     MOZ_COUNT_DTOR(TextLayerComposite);
    1254           0 :     Destroy();
    1255           0 :   }
    1256             : 
    1257             : public:
    1258             :   // LayerComposite Implementation
    1259           0 :   virtual Layer* GetLayer() override { return this; }
    1260             : 
    1261           0 :   virtual void SetLayerManager(HostLayerManager* aManager) override
    1262             :   {
    1263           0 :     LayerComposite::SetLayerManager(aManager);
    1264           0 :     mManager = aManager;
    1265           0 :   }
    1266             : 
    1267           0 :   virtual void Destroy() override { mDestroyed = true; }
    1268             : 
    1269           0 :   virtual void RenderLayer(const gfx::IntRect& aClipRect,
    1270           0 :                            const Maybe<gfx::Polygon>& aGeometry) override {}
    1271           0 :   virtual void CleanupResources() override {};
    1272             : 
    1273           0 :   virtual void GenEffectChain(EffectChain& aEffect) override {}
    1274             : 
    1275           0 :   CompositableHost* GetCompositableHost() override { return nullptr; }
    1276             : 
    1277           0 :   virtual HostLayer* AsHostLayer() override { return this; }
    1278             : 
    1279           0 :   virtual const char* Name() const override { return "TextLayerComposite"; }
    1280             : };
    1281             : 
    1282             : class BorderLayerComposite : public BorderLayer,
    1283             :                              public LayerComposite
    1284             : {
    1285             : public:
    1286           0 :   explicit BorderLayerComposite(LayerManagerComposite *aManager)
    1287           0 :     : BorderLayer(aManager, nullptr)
    1288           0 :     , LayerComposite(aManager)
    1289             :   {
    1290           0 :     MOZ_COUNT_CTOR(BorderLayerComposite);
    1291           0 :     mImplData = static_cast<LayerComposite*>(this);
    1292           0 :   }
    1293             : 
    1294             : protected:
    1295           0 :   ~BorderLayerComposite()
    1296           0 :   {
    1297           0 :     MOZ_COUNT_DTOR(BorderLayerComposite);
    1298           0 :     Destroy();
    1299           0 :   }
    1300             : 
    1301             : public:
    1302             :   // LayerComposite Implementation
    1303           0 :   virtual Layer* GetLayer() override { return this; }
    1304             : 
    1305           0 :   virtual void SetLayerManager(HostLayerManager* aManager) override
    1306             :   {
    1307           0 :     LayerComposite::SetLayerManager(aManager);
    1308           0 :     mManager = aManager;
    1309           0 :   }
    1310             : 
    1311           0 :   virtual void Destroy() override { mDestroyed = true; }
    1312             : 
    1313           0 :   virtual void RenderLayer(const gfx::IntRect& aClipRect,
    1314           0 :                            const Maybe<gfx::Polygon>& aGeometry) override {}
    1315           0 :   virtual void CleanupResources() override {};
    1316             : 
    1317           0 :   virtual void GenEffectChain(EffectChain& aEffect) override {}
    1318             : 
    1319           0 :   CompositableHost* GetCompositableHost() override { return nullptr; }
    1320             : 
    1321           0 :   virtual HostLayer* AsHostLayer() override { return this; }
    1322             : 
    1323           0 :   virtual const char* Name() const override { return "BorderLayerComposite"; }
    1324             : };
    1325             : 
    1326             : already_AddRefed<PaintedLayer>
    1327          22 : LayerManagerComposite::CreatePaintedLayer()
    1328             : {
    1329          22 :   if (mDestroyed) {
    1330           0 :     NS_WARNING("Call on destroyed layer manager");
    1331           0 :     return nullptr;
    1332             :   }
    1333          22 :   return RefPtr<PaintedLayer>(new PaintedLayerComposite(this)).forget();
    1334             : }
    1335             : 
    1336             : already_AddRefed<ContainerLayer>
    1337           4 : LayerManagerComposite::CreateContainerLayer()
    1338             : {
    1339           4 :   if (mDestroyed) {
    1340           0 :     NS_WARNING("Call on destroyed layer manager");
    1341           0 :     return nullptr;
    1342             :   }
    1343           4 :   return RefPtr<ContainerLayer>(new ContainerLayerComposite(this)).forget();
    1344             : }
    1345             : 
    1346             : already_AddRefed<ImageLayer>
    1347           0 : LayerManagerComposite::CreateImageLayer()
    1348             : {
    1349           0 :   if (mDestroyed) {
    1350           0 :     NS_WARNING("Call on destroyed layer manager");
    1351           0 :     return nullptr;
    1352             :   }
    1353           0 :   return RefPtr<ImageLayer>(new ImageLayerComposite(this)).forget();
    1354             : }
    1355             : 
    1356             : already_AddRefed<ColorLayer>
    1357           4 : LayerManagerComposite::CreateColorLayer()
    1358             : {
    1359           4 :   if (LayerManagerComposite::mDestroyed) {
    1360           0 :     NS_WARNING("Call on destroyed layer manager");
    1361           0 :     return nullptr;
    1362             :   }
    1363           4 :   return RefPtr<ColorLayer>(new ColorLayerComposite(this)).forget();
    1364             : }
    1365             : 
    1366             : already_AddRefed<CanvasLayer>
    1367           0 : LayerManagerComposite::CreateCanvasLayer()
    1368             : {
    1369           0 :   if (LayerManagerComposite::mDestroyed) {
    1370           0 :     NS_WARNING("Call on destroyed layer manager");
    1371           0 :     return nullptr;
    1372             :   }
    1373           0 :   return RefPtr<CanvasLayer>(new CanvasLayerComposite(this)).forget();
    1374             : }
    1375             : 
    1376             : already_AddRefed<RefLayer>
    1377           1 : LayerManagerComposite::CreateRefLayer()
    1378             : {
    1379           1 :   if (LayerManagerComposite::mDestroyed) {
    1380           0 :     NS_WARNING("Call on destroyed layer manager");
    1381           0 :     return nullptr;
    1382             :   }
    1383           1 :   return RefPtr<RefLayer>(new RefLayerComposite(this)).forget();
    1384             : }
    1385             : 
    1386             : already_AddRefed<TextLayer>
    1387           0 : LayerManagerComposite::CreateTextLayer()
    1388             : {
    1389           0 :   if (LayerManagerComposite::mDestroyed) {
    1390           0 :     NS_WARNING("Call on destroyed layer manager");
    1391           0 :     return nullptr;
    1392             :   }
    1393           0 :   return RefPtr<TextLayer>(new TextLayerComposite(this)).forget();
    1394             : }
    1395             : 
    1396             : already_AddRefed<BorderLayer>
    1397           0 : LayerManagerComposite::CreateBorderLayer()
    1398             : {
    1399           0 :   if (LayerManagerComposite::mDestroyed) {
    1400           0 :     NS_WARNING("Call on destroyed layer manager");
    1401           0 :     return nullptr;
    1402             :   }
    1403           0 :   return RefPtr<BorderLayer>(new BorderLayerComposite(this)).forget();
    1404             : }
    1405             : 
    1406          80 : LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
    1407          80 :                                                             EffectChain& aEffects)
    1408          80 :   : mCompositable(nullptr), mFailed(false)
    1409             : {
    1410          80 :   if (!aMaskLayer) {
    1411          80 :     return;
    1412             :   }
    1413             : 
    1414           0 :   mCompositable = ToLayerComposite(aMaskLayer)->GetCompositableHost();
    1415           0 :   if (!mCompositable) {
    1416           0 :     NS_WARNING("Mask layer with no compositable host");
    1417           0 :     mFailed = true;
    1418           0 :     return;
    1419             :   }
    1420             : 
    1421           0 :   if (!mCompositable->AddMaskEffect(aEffects, aMaskLayer->GetEffectiveTransform())) {
    1422           0 :     mCompositable = nullptr;
    1423           0 :     mFailed = true;
    1424             :   }
    1425             : }
    1426             : 
    1427          80 : LayerManagerComposite::AutoAddMaskEffect::~AutoAddMaskEffect()
    1428             : {
    1429          80 :   if (!mCompositable) {
    1430          80 :     return;
    1431             :   }
    1432             : 
    1433           0 :   mCompositable->RemoveMaskEffect();
    1434          80 : }
    1435             : 
    1436             : bool
    1437           0 : LayerManagerComposite::IsCompositingToScreen() const
    1438             : {
    1439           0 :   if (!mCompositor) {
    1440           0 :     return true;
    1441             :   }
    1442           0 :   return !mCompositor->GetTargetContext();
    1443             : }
    1444             : 
    1445          31 : LayerComposite::LayerComposite(LayerManagerComposite *aManager)
    1446             :   : HostLayer(aManager)
    1447             :   , mCompositeManager(aManager)
    1448             :   , mCompositor(aManager->GetCompositor())
    1449             :   , mDestroyed(false)
    1450          31 :   , mLayerComposited(false)
    1451          31 : { }
    1452             : 
    1453          23 : LayerComposite::~LayerComposite()
    1454             : {
    1455          23 : }
    1456             : 
    1457             : void
    1458           0 : LayerComposite::Destroy()
    1459             : {
    1460           0 :   if (!mDestroyed) {
    1461           0 :     mDestroyed = true;
    1462           0 :     CleanupResources();
    1463             :   }
    1464           0 : }
    1465             : 
    1466             : void
    1467          80 : LayerComposite::AddBlendModeEffect(EffectChain& aEffectChain)
    1468             : {
    1469          80 :   gfx::CompositionOp blendMode = GetLayer()->GetEffectiveMixBlendMode();
    1470          80 :   if (blendMode == gfx::CompositionOp::OP_OVER) {
    1471          80 :     return;
    1472             :   }
    1473             : 
    1474           0 :   aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE] = new EffectBlendMode(blendMode);
    1475           0 :   return;
    1476             : }
    1477             : 
    1478             : bool
    1479           0 : LayerManagerComposite::CanUseCanvasLayerForSize(const IntSize &aSize)
    1480             : {
    1481           0 :   return mCompositor->CanUseCanvasLayerForSize(gfx::IntSize(aSize.width,
    1482           0 :                                                             aSize.height));
    1483             : }
    1484             : 
    1485             : void
    1486          28 : LayerManagerComposite::NotifyShadowTreeTransaction()
    1487             : {
    1488          28 :   if (gfxPrefs::LayersDrawFPS()) {
    1489           0 :     mDiagnostics->AddTxnFrame();
    1490             :   }
    1491          28 : }
    1492             : 
    1493             : void
    1494           0 : LayerComposite::SetLayerManager(HostLayerManager* aManager)
    1495             : {
    1496           0 :   HostLayer::SetLayerManager(aManager);
    1497           0 :   mCompositeManager = static_cast<LayerManagerComposite*>(aManager);
    1498           0 :   mCompositor = mCompositeManager->GetCompositor();
    1499           0 : }
    1500             : 
    1501             : bool
    1502           0 : LayerManagerComposite::AsyncPanZoomEnabled() const
    1503             : {
    1504           0 :   if (CompositorBridgeParent* bridge = mCompositor->GetCompositorBridgeParent()) {
    1505           0 :     return bridge->GetOptions().UseAPZ();
    1506             :   }
    1507           0 :   return false;
    1508             : }
    1509             : 
    1510             : bool
    1511          29 : LayerManagerComposite::AlwaysScheduleComposite() const
    1512             : {
    1513          29 :   return !!(mCompositor->GetDiagnosticTypes() & DiagnosticTypes::FLASH_BORDERS);
    1514             : }
    1515             : 
    1516             : nsIntRegion
    1517          59 : LayerComposite::GetFullyRenderedRegion() {
    1518         118 :   if (TiledContentHost* tiled = GetCompositableHost() ? GetCompositableHost()->AsTiledContentHost()
    1519          59 :                                                         : nullptr) {
    1520           0 :     nsIntRegion shadowVisibleRegion = GetShadowVisibleRegion().ToUnknownRegion();
    1521             :     // Discard the region which hasn't been drawn yet when doing
    1522             :     // progressive drawing. Note that if the shadow visible region
    1523             :     // shrunk the tiled valig region may not have discarded this yet.
    1524           0 :     shadowVisibleRegion.And(shadowVisibleRegion, tiled->GetValidRegion());
    1525           0 :     return shadowVisibleRegion;
    1526             :   } else {
    1527          59 :     return GetShadowVisibleRegion().ToUnknownRegion();
    1528             :   }
    1529             : }
    1530             : 
    1531             : Matrix4x4
    1532         880 : HostLayer::GetShadowTransform() {
    1533         880 :   Matrix4x4 transform = mShadowTransform;
    1534         880 :   Layer* layer = GetLayer();
    1535             : 
    1536         880 :   transform.PostScale(layer->GetPostXScale(), layer->GetPostYScale(), 1.0f);
    1537         880 :   if (const ContainerLayer* c = layer->AsContainerLayer()) {
    1538         451 :     transform.PreScale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
    1539             :   }
    1540             : 
    1541         880 :   return transform;
    1542             : }
    1543             : 
    1544             : bool
    1545         141 : LayerComposite::HasStaleCompositor() const
    1546             : {
    1547         141 :   return mCompositeManager->GetCompositor() != mCompositor;
    1548             : }
    1549             : 
    1550             : #ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
    1551             : 
    1552             : /*static*/ bool
    1553             : LayerManagerComposite::SupportsDirectTexturing()
    1554             : {
    1555             :   return false;
    1556             : }
    1557             : 
    1558             : /*static*/ void
    1559             : LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
    1560             : {
    1561             : }
    1562             : 
    1563             : #endif  // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
    1564             : 
    1565             : } // namespace layers
    1566             : } // namespace mozilla

Generated by: LCOV version 1.13