LCOV - code coverage report
Current view: top level - gfx/layers/composite - LayerManagerComposite.h (source / functions) Hit Total Coverage
Test: output.info Lines: 74 218 33.9 %
Date: 2017-07-14 16:53:18 Functions: 30 80 37.5 %
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             : #ifndef GFX_LayerManagerComposite_H
       7             : #define GFX_LayerManagerComposite_H
       8             : 
       9             : #include <stdint.h>                     // for int32_t, uint32_t
      10             : #include "CompositableHost.h"           // for CompositableHost, ImageCompositeNotificationInfo
      11             : #include "GLDefs.h"                     // for GLenum
      12             : #include "Layers.h"
      13             : #include "Units.h"                      // for ParentLayerIntRect
      14             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
      15             : #include "mozilla/Attributes.h"         // for override
      16             : #include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed
      17             : #include "mozilla/gfx/2D.h"
      18             : #include "mozilla/gfx/Point.h"          // for IntSize
      19             : #include "mozilla/gfx/Rect.h"           // for Rect
      20             : #include "mozilla/gfx/Types.h"          // for SurfaceFormat
      21             : #include "mozilla/layers/CompositorTypes.h"
      22             : #include "mozilla/layers/Effects.h"     // for EffectChain
      23             : #include "mozilla/layers/LayersMessages.h"
      24             : #include "mozilla/layers/LayersTypes.h"  // for LayersBackend, etc
      25             : #include "mozilla/Maybe.h"              // for Maybe
      26             : #include "mozilla/RefPtr.h"
      27             : #include "mozilla/UniquePtr.h"
      28             : #include "nsAString.h"
      29             : #include "mozilla/RefPtr.h"                   // for nsRefPtr
      30             : #include "nsCOMPtr.h"                   // for already_AddRefed
      31             : #include "nsDebug.h"                    // for NS_ASSERTION
      32             : #include "nsISupportsImpl.h"            // for Layer::AddRef, etc
      33             : #include "nsRect.h"                     // for mozilla::gfx::IntRect
      34             : #include "nsRegion.h"                   // for nsIntRegion
      35             : #include "nscore.h"                     // for nsAString, etc
      36             : #include "LayerTreeInvalidation.h"
      37             : 
      38             : class gfxContext;
      39             : 
      40             : #ifdef XP_WIN
      41             : #include <windows.h>
      42             : #endif
      43             : 
      44             : namespace mozilla {
      45             : namespace gfx {
      46             : class DrawTarget;
      47             : } // namespace gfx
      48             : 
      49             : namespace layers {
      50             : 
      51             : class CanvasLayerComposite;
      52             : class ColorLayerComposite;
      53             : class Compositor;
      54             : class ContainerLayerComposite;
      55             : class Diagnostics;
      56             : struct EffectChain;
      57             : class ImageLayer;
      58             : class ImageLayerComposite;
      59             : class LayerComposite;
      60             : class RefLayerComposite;
      61             : class PaintedLayerComposite;
      62             : class TextRenderer;
      63             : class CompositingRenderTarget;
      64             : struct FPSState;
      65             : class PaintCounter;
      66             : class LayerMLGPU;
      67             : class LayerManagerMLGPU;
      68             : class UiCompositorControllerParent;
      69             : 
      70             : static const int kVisualWarningDuration = 150; // ms
      71             : 
      72             : // An implementation of LayerManager that acts as a pair with ClientLayerManager
      73             : // and is mirrored across IPDL. This gets managed/updated by LayerTransactionParent.
      74             : class HostLayerManager : public LayerManager
      75             : {
      76             : public:
      77             :   HostLayerManager();
      78             :   ~HostLayerManager();
      79             : 
      80           0 :   virtual bool BeginTransactionWithTarget(gfxContext* aTarget) override
      81             :   {
      82           0 :     MOZ_CRASH("GFX: Use BeginTransactionWithDrawTarget");
      83             :   }
      84             : 
      85           0 :   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override
      86             :   {
      87           0 :     MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)");
      88             :     return false;
      89             :   }
      90             : 
      91           0 :   virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
      92             :                               void* aCallbackData,
      93             :                               EndTransactionFlags aFlags = END_DEFAULT) override
      94             :   {
      95           0 :     MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)");
      96             :   }
      97             : 
      98           0 :   virtual int32_t GetMaxTextureSize() const override
      99             :   {
     100           0 :     MOZ_CRASH("GFX: Call on compositor, not LayerManagerComposite");
     101             :   }
     102             : 
     103           0 :   virtual void GetBackendName(nsAString& name) override
     104             :   {
     105           0 :     MOZ_CRASH("GFX: Shouldn't be called for composited layer manager");
     106             :   }
     107             : 
     108             :   virtual void ForcePresent() = 0;
     109             :   virtual void AddInvalidRegion(const nsIntRegion& aRegion) = 0;
     110             :   virtual void ClearApproximatelyVisibleRegions(uint64_t aLayersId,
     111             :                                                 const Maybe<uint32_t>& aPresShellId) = 0;
     112             :   virtual void UpdateApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
     113             :                                                 const CSSIntRegion& aRegion) = 0;
     114             : 
     115           0 :   virtual void NotifyShadowTreeTransaction() {}
     116             :   virtual void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget,
     117             :                                               const gfx::IntRect& aRect) = 0;
     118             :   virtual Compositor* GetCompositor() const = 0;
     119             :   virtual TextureSourceProvider* GetTextureSourceProvider() const = 0;
     120             :   virtual void EndTransaction(const TimeStamp& aTimeStamp,
     121             :                               EndTransactionFlags aFlags = END_DEFAULT) = 0;
     122           0 :   virtual void UpdateRenderBounds(const gfx::IntRect& aRect) {}
     123           0 :   virtual void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) {}
     124             : 
     125           0 :   virtual HostLayerManager* AsHostLayerManager() override {
     126           0 :     return this;
     127             :   }
     128           0 :   virtual LayerManagerMLGPU* AsLayerManagerMLGPU() {
     129           0 :     return nullptr;
     130             :   }
     131             : 
     132          29 :   void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications)
     133             :   {
     134          29 :     aNotifications->AppendElements(Move(mImageCompositeNotifications));
     135          29 :   }
     136             : 
     137           0 :   void AppendImageCompositeNotification(const ImageCompositeNotificationInfo& aNotification)
     138             :   {
     139             :     // Only send composite notifications when we're drawing to the screen,
     140             :     // because that's what they mean.
     141             :     // Also when we're not drawing to the screen, DidComposite will not be
     142             :     // called to extract and send these notifications, so they might linger
     143             :     // and contain stale ImageContainerParent pointers.
     144           0 :     if (IsCompositingToScreen()) {
     145           0 :       mImageCompositeNotifications.AppendElement(aNotification);
     146             :     }
     147           0 :   }
     148             : 
     149             :   /**
     150             :    * LayerManagerComposite provides sophisticated debug overlays
     151             :    * that can request a next frame.
     152             :    */
     153          29 :   bool DebugOverlayWantsNextFrame() { return mDebugOverlayWantsNextFrame; }
     154          29 :   void SetDebugOverlayWantsNextFrame(bool aVal)
     155          29 :   { mDebugOverlayWantsNextFrame = aVal; }
     156             : 
     157             :   /**
     158             :    * Add an on frame warning.
     159             :    * @param severity ranges from 0 to 1. It's used to compute the warning color.
     160             :    */
     161           0 :   void VisualFrameWarning(float severity) {
     162           0 :     mozilla::TimeStamp now = TimeStamp::Now();
     163           0 :     if (mWarnTime.IsNull() ||
     164           0 :         severity > mWarningLevel ||
     165           0 :         mWarnTime + TimeDuration::FromMilliseconds(kVisualWarningDuration) < now) {
     166           0 :       mWarnTime = now;
     167           0 :       mWarningLevel = severity;
     168             :     }
     169           0 :   }
     170             : 
     171             :   // Indicate that we need to composite even if nothing in our layers has
     172             :   // changed, so that the widget can draw something different in its window
     173             :   // overlay.
     174           0 :   void SetWindowOverlayChanged() { mWindowOverlayChanged = true; }
     175             : 
     176           0 :   void SetPaintTime(const TimeDuration& aPaintTime) { mLastPaintTime = aPaintTime; }
     177             : 
     178           0 :   virtual bool AlwaysScheduleComposite() const {
     179           0 :     return false;
     180             :   }
     181           0 :   virtual bool IsCompositingToScreen() const {
     182           0 :     return false;
     183             :   }
     184             : 
     185             :   void RecordPaintTimes(const PaintTiming& aTiming);
     186             :   void RecordUpdateTime(float aValue);
     187             : 
     188           0 :   TimeStamp GetCompositionTime() const {
     189           0 :     return mCompositionTime;
     190             :   }
     191          86 :   void SetCompositionTime(TimeStamp aTimeStamp) {
     192          86 :     mCompositionTime = aTimeStamp;
     193          86 :     if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() &&
     194           0 :         mCompositionTime >= mCompositeUntilTime) {
     195           0 :       mCompositeUntilTime = TimeStamp();
     196             :     }
     197          86 :   }
     198           0 :   void CompositeUntil(TimeStamp aTimeStamp) {
     199           0 :     if (mCompositeUntilTime.IsNull() ||
     200           0 :         mCompositeUntilTime < aTimeStamp) {
     201           0 :       mCompositeUntilTime = aTimeStamp;
     202             :     }
     203           0 :   }
     204          29 :   TimeStamp GetCompositeUntilTime() const {
     205          29 :     return mCompositeUntilTime;
     206             :   }
     207             : 
     208             :   // We maintaining a global mapping from ID to CompositorBridgeParent for
     209             :   // async compositables.
     210          22 :   uint32_t GetCompositorBridgeID() const {
     211          22 :     return mCompositorBridgeID;
     212             :   }
     213           1 :   void SetCompositorBridgeID(uint32_t aID) {
     214           1 :     MOZ_ASSERT(mCompositorBridgeID == 0, "The compositor ID must be set only once.");
     215           1 :     mCompositorBridgeID = aID;
     216           1 :   }
     217             : 
     218             : protected:
     219             :   bool mDebugOverlayWantsNextFrame;
     220             :   nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications;
     221             :   // Testing property. If hardware composer is supported, this will return
     222             :   // true if the last frame was deemed 'too complicated' to be rendered.
     223             :   float mWarningLevel;
     224             :   mozilla::TimeStamp mWarnTime;
     225             :   UniquePtr<Diagnostics> mDiagnostics;
     226             :   uint32_t mCompositorBridgeID;
     227             : 
     228             :   bool mWindowOverlayChanged;
     229             :   TimeDuration mLastPaintTime;
     230             :   TimeStamp mRenderStartTime;
     231             : 
     232             :   // Render time for the current composition.
     233             :   TimeStamp mCompositionTime;
     234             : 
     235             :   // When nonnull, during rendering, some compositable indicated that it will
     236             :   // change its rendering at this time. In order not to miss it, we composite
     237             :   // on every vsync until this time occurs (this is the latest such time).
     238             :   TimeStamp mCompositeUntilTime;
     239             : #if defined(MOZ_WIDGET_ANDROID)
     240             : public:
     241             :   // Used by UiCompositorControllerParent to set itself as the target for the
     242             :   // contents of the frame buffer after a composite.
     243             :   // Implemented in LayerManagerComposite
     244             :   virtual void RequestScreenPixels(UiCompositorControllerParent* aController) {}
     245             : #endif // defined(MOZ_WIDGET_ANDROID)
     246             : };
     247             : 
     248             : // A layer manager implementation that uses the Compositor API
     249             : // to render layers.
     250             : class LayerManagerComposite final : public HostLayerManager
     251             : {
     252             :   typedef mozilla::gfx::DrawTarget DrawTarget;
     253             :   typedef mozilla::gfx::IntSize IntSize;
     254             :   typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
     255             : 
     256             : public:
     257             :   explicit LayerManagerComposite(Compositor* aCompositor);
     258             :   ~LayerManagerComposite();
     259             : 
     260             :   virtual void Destroy() override;
     261             : 
     262             :   /**
     263             :    * Sets the clipping region for this layer manager. This is important on
     264             :    * windows because using OGL we no longer have GDI's native clipping. Therefor
     265             :    * widget must tell us what part of the screen is being invalidated,
     266             :    * and we should clip to this.
     267             :    *
     268             :    * \param aClippingRegion Region to clip to. Setting an empty region
     269             :    * will disable clipping.
     270             :    */
     271             :   void SetClippingRegion(const nsIntRegion& aClippingRegion)
     272             :   {
     273             :     mClippingRegion = aClippingRegion;
     274             :   }
     275             : 
     276             :   /**
     277             :    * LayerManager implementation.
     278             :    */
     279           0 :   virtual LayerManagerComposite* AsLayerManagerComposite() override
     280             :   {
     281           0 :     return this;
     282             :   }
     283             : 
     284             :   void UpdateRenderBounds(const gfx::IntRect& aRect) override;
     285             : 
     286             :   virtual bool BeginTransaction() override;
     287             :   void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget,
     288             :                                       const gfx::IntRect& aRect) override;
     289             :   void EndTransaction(const TimeStamp& aTimeStamp,
     290             :                       EndTransactionFlags aFlags = END_DEFAULT) override;
     291           0 :   virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
     292             :                               void* aCallbackData,
     293             :                               EndTransactionFlags aFlags = END_DEFAULT) override
     294             :   {
     295           0 :     MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)");
     296             :   }
     297             : 
     298          24 :   virtual void SetRoot(Layer* aLayer) override { mRoot = aLayer; }
     299             : 
     300             :   // XXX[nrc]: never called, we should move this logic to ClientLayerManager
     301             :   // (bug 946926).
     302             :   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override;
     303             : 
     304             :   virtual void ClearCachedResources(Layer* aSubtree = nullptr) override;
     305             : 
     306             :   virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
     307             :   virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override;
     308             :   virtual already_AddRefed<ImageLayer> CreateImageLayer() override;
     309             :   virtual already_AddRefed<ColorLayer> CreateColorLayer() override;
     310             :   virtual already_AddRefed<TextLayer> CreateTextLayer() override;
     311             :   virtual already_AddRefed<BorderLayer> CreateBorderLayer() override;
     312             :   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
     313             :   virtual already_AddRefed<RefLayer> CreateRefLayer() override;
     314             : 
     315             :   virtual bool AreComponentAlphaLayersEnabled() override;
     316             : 
     317             :   virtual already_AddRefed<DrawTarget>
     318             :     CreateOptimalMaskDrawTarget(const IntSize &aSize) override;
     319             : 
     320           0 :   virtual const char* Name() const override { return ""; }
     321             :   virtual bool IsCompositingToScreen() const override;
     322             : 
     323             :   bool AlwaysScheduleComposite() const override;
     324             : 
     325             :   /**
     326             :    * Post-processes layers before composition. This performs the following:
     327             :    *
     328             :    *   - Applies occlusion culling. This restricts the shadow visible region
     329             :    *     of layers that are covered with opaque content.
     330             :    *     |aOpaqueRegion| is the region already known to be covered with opaque
     331             :    *     content, in the post-transform coordinate space of aLayer.
     332             :    *
     333             :    *   - Recomputes visible regions to account for async transforms.
     334             :    *     Each layer accumulates into |aVisibleRegion| its post-transform
     335             :    *     (including async transforms) visible region.
     336             :    *
     337             :    *   - aRenderTargetClip is the exact clip required for aLayer, in the coordinates
     338             :    *     of the nearest render target (the same as GetEffectiveTransform).
     339             :    *
     340             :    *   - aClipFromAncestors is the approximate combined clip from all ancestors, in
     341             :    *     the coordinate space of our parent, but maybe be an overestimate in the
     342             :    *     presence of complex transforms.
     343             :    */
     344             :   void PostProcessLayers(nsIntRegion& aOpaqueRegion);
     345             :   void PostProcessLayers(Layer* aLayer,
     346             :                          nsIntRegion& aOpaqueRegion,
     347             :                          LayerIntRegion& aVisibleRegion,
     348             :                          const Maybe<RenderTargetIntRect>& aRenderTargetClip,
     349             :                          const Maybe<ParentLayerIntRect>& aClipFromAncestors);
     350             : 
     351             :   /**
     352             :    * RAII helper class to add a mask effect with the compositable from aMaskLayer
     353             :    * to the EffectChain aEffect and notify the compositable when we are done.
     354             :    */
     355             :   class AutoAddMaskEffect
     356             :   {
     357             :   public:
     358             :     AutoAddMaskEffect(Layer* aMaskLayer,
     359             :                       EffectChain& aEffect);
     360             :     ~AutoAddMaskEffect();
     361             : 
     362           0 :     bool Failed() const { return mFailed; }
     363             :   private:
     364             :     CompositableHost* mCompositable;
     365             :     bool mFailed;
     366             :   };
     367             : 
     368             :   /**
     369             :    * returns true if PlatformAllocBuffer will return a buffer that supports
     370             :    * direct texturing
     371             :    */
     372             :   static bool SupportsDirectTexturing();
     373             : 
     374             :   static void PlatformSyncBeforeReplyUpdate();
     375             : 
     376           1 :   void AddInvalidRegion(const nsIntRegion& aRegion) override
     377             :   {
     378           1 :     mInvalidRegion.Or(mInvalidRegion, aRegion);
     379           1 :   }
     380             : 
     381           0 :   void ClearApproximatelyVisibleRegions(uint64_t aLayersId,
     382             :                                         const Maybe<uint32_t>& aPresShellId) override
     383             :   {
     384           0 :     for (auto iter = mVisibleRegions.Iter(); !iter.Done(); iter.Next()) {
     385           0 :       if (iter.Key().mLayersId == aLayersId &&
     386           0 :           (!aPresShellId || iter.Key().mPresShellId == *aPresShellId)) {
     387           0 :         iter.Remove();
     388             :       }
     389             :     }
     390           0 :   }
     391             : 
     392           0 :   void UpdateApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
     393             :                                         const CSSIntRegion& aRegion) override
     394             :   {
     395           0 :     CSSIntRegion* regionForScrollFrame = mVisibleRegions.LookupOrAdd(aGuid);
     396           0 :     MOZ_ASSERT(regionForScrollFrame);
     397             : 
     398           0 :     *regionForScrollFrame = aRegion;
     399           0 :   }
     400             : 
     401           0 :   CSSIntRegion* GetApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid)
     402             :   {
     403           0 :     return mVisibleRegions.Get(aGuid);
     404             :   }
     405             : 
     406         458 :   Compositor* GetCompositor() const override {
     407         458 :     return mCompositor;
     408             :   }
     409          22 :   TextureSourceProvider* GetTextureSourceProvider() const override {
     410          22 :     return mCompositor;
     411             :   }
     412             : 
     413             :   void NotifyShadowTreeTransaction() override;
     414             : 
     415           0 :   TextRenderer* GetTextRenderer() { return mTextRenderer; }
     416             : 
     417           0 :   void UnusedApzTransformWarning() {
     418           0 :     mUnusedApzTransformWarning = true;
     419           0 :   }
     420           0 :   void DisabledApzWarning() {
     421           0 :     mDisabledApzWarning = true;
     422           0 :   }
     423             : 
     424             :   bool AsyncPanZoomEnabled() const override;
     425             : 
     426             : public:
     427           1 :   virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() override {
     428           1 :     return mCompositor->GetTextureFactoryIdentifier();
     429             :   }
     430           0 :   virtual LayersBackend GetBackendType() override {
     431           0 :     return mCompositor ? mCompositor->GetBackendType() : LayersBackend::LAYERS_NONE;
     432             :   }
     433           0 :   virtual void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) override {
     434           0 :     mCompositor->SetDiagnosticTypes(aDiagnostics);
     435           0 :   }
     436             : 
     437           0 :   void ForcePresent() override { mCompositor->ForcePresent(); }
     438             : 
     439             : private:
     440             :   /** Region we're clipping our current drawing to. */
     441             :   nsIntRegion mClippingRegion;
     442             :   gfx::IntRect mRenderBounds;
     443             : 
     444             :   /** Current root layer. */
     445             :   LayerComposite* RootLayer() const;
     446             : 
     447             :   /**
     448             :    * Update the invalid region and render it.
     449             :    */
     450             :   void UpdateAndRender();
     451             : 
     452             :   /**
     453             :    * Render the current layer tree to the active target.
     454             :    */
     455             :   void Render(const nsIntRegion& aInvalidRegion, const nsIntRegion& aOpaqueRegion);
     456             : #if defined(MOZ_WIDGET_ANDROID)
     457             :   void RenderToPresentationSurface();
     458             :   // Shifts the content down so the toolbar does not cover it.
     459             :   // Returns the Y shift of the content in screen pixels
     460             :   ScreenCoord GetContentShiftForToolbar();
     461             :   // Renders the static snapshot after the content has been rendered.
     462             :   void RenderToolbar();
     463             :   // Used by robocop tests to get a snapshot of the frame buffer.
     464             :   void HandlePixelsTarget();
     465             : #endif
     466             : 
     467             :   /**
     468             :    * We need to know our invalid region before we're ready to render.
     469             :    */
     470             :   void InvalidateDebugOverlay(nsIntRegion& aInvalidRegion, const gfx::IntRect& aBounds);
     471             : 
     472             :   /**
     473             :    * Render debug overlays such as the FPS/FrameCounter above the frame.
     474             :    */
     475             :   void RenderDebugOverlay(const gfx::IntRect& aBounds);
     476             : 
     477             : 
     478             :   RefPtr<CompositingRenderTarget> PushGroupForLayerEffects();
     479             :   void PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget,
     480             :                                gfx::IntRect aClipRect,
     481             :                                bool aGrayscaleEffect,
     482             :                                bool aInvertEffect,
     483             :                                float aContrastEffect);
     484             : 
     485             :   bool mUnusedApzTransformWarning;
     486             :   bool mDisabledApzWarning;
     487             :   RefPtr<Compositor> mCompositor;
     488             :   UniquePtr<LayerProperties> mClonedLayerTreeProperties;
     489             : 
     490             :   /**
     491             :    * Context target, nullptr when drawing directly to our swap chain.
     492             :    */
     493             :   RefPtr<gfx::DrawTarget> mTarget;
     494             :   gfx::IntRect mTargetBounds;
     495             : 
     496             :   nsIntRegion mInvalidRegion;
     497             : 
     498             :   typedef nsClassHashtable<nsGenericHashKey<ScrollableLayerGuid>,
     499             :                            CSSIntRegion> VisibleRegions;
     500             :   VisibleRegions mVisibleRegions;
     501             : 
     502             :   bool mInTransaction;
     503             :   bool mIsCompositorReady;
     504             : 
     505             :   RefPtr<CompositingRenderTarget> mTwoPassTmpTarget;
     506             :   RefPtr<TextRenderer> mTextRenderer;
     507             : 
     508             : #ifdef USE_SKIA
     509             :   /**
     510             :    * Render paint and composite times above the frame.
     511             :    */
     512             :   void DrawPaintTimes(Compositor* aCompositor);
     513             :   RefPtr<PaintCounter> mPaintCounter;
     514             : #endif
     515             : #if defined(MOZ_WIDGET_ANDROID)
     516             : public:
     517             :   virtual void RequestScreenPixels(UiCompositorControllerParent* aController) override
     518             :   {
     519             :     mScreenPixelsTarget = aController;
     520             :   }
     521             : private:
     522             :   UiCompositorControllerParent* mScreenPixelsTarget;
     523             : #endif // defined(MOZ_WIDGET_ANDROID)
     524             : };
     525             : 
     526             : /**
     527             :  * Compositor layers are for use with OMTC on the compositor thread only. There
     528             :  * must be corresponding Client layers on the content thread. For composite
     529             :  * layers, the layer manager only maintains the layer tree.
     530             :  */
     531             : class HostLayer
     532             : {
     533             : public:
     534          31 :   explicit HostLayer(HostLayerManager* aManager)
     535          31 :     : mCompositorManager(aManager)
     536             :     , mShadowOpacity(1.0)
     537             :     , mShadowTransformSetByAnimation(false)
     538          31 :     , mShadowOpacitySetByAnimation(false)
     539             :   {
     540          31 :   }
     541             : 
     542           0 :   virtual void SetLayerManager(HostLayerManager* aManager)
     543             :   {
     544           0 :     mCompositorManager = aManager;
     545           0 :   }
     546           0 :   HostLayerManager* GetLayerManager() const { return mCompositorManager; }
     547             : 
     548             : 
     549          23 :   virtual ~HostLayer() {}
     550             : 
     551           0 :   virtual LayerComposite* GetFirstChildComposite()
     552             :   {
     553           0 :     return nullptr;
     554             :   }
     555             : 
     556             :   virtual Layer* GetLayer() = 0;
     557             : 
     558           0 :   virtual LayerMLGPU* AsLayerMLGPU() { return nullptr; }
     559             : 
     560           0 :   virtual bool SetCompositableHost(CompositableHost*)
     561             :   {
     562             :     // We must handle this gracefully, see bug 967824
     563           0 :     NS_WARNING("called SetCompositableHost for a layer type not accepting a compositable");
     564           0 :     return false;
     565             :   }
     566             :   virtual CompositableHost* GetCompositableHost() = 0;
     567             : 
     568             :   /**
     569             :    * The following methods are
     570             :    *
     571             :    * CONSTRUCTION PHASE ONLY
     572             :    *
     573             :    * They are analogous to the Layer interface.
     574             :    */
     575         492 :   void SetShadowVisibleRegion(const LayerIntRegion& aRegion)
     576             :   {
     577         492 :     mShadowVisibleRegion = aRegion;
     578         492 :   }
     579           0 :   void SetShadowVisibleRegion(LayerIntRegion&& aRegion)
     580             :   {
     581           0 :     mShadowVisibleRegion = Move(aRegion);
     582           0 :   }
     583             : 
     584         371 :   void SetShadowOpacity(float aOpacity)
     585             :   {
     586         371 :     mShadowOpacity = aOpacity;
     587         371 :   }
     588         371 :   void SetShadowOpacitySetByAnimation(bool aSetByAnimation)
     589             :   {
     590         371 :     mShadowOpacitySetByAnimation = aSetByAnimation;
     591         371 :   }
     592             : 
     593         411 :   void SetShadowClipRect(const Maybe<ParentLayerIntRect>& aRect)
     594             :   {
     595         411 :     mShadowClipRect = aRect;
     596         411 :   }
     597             : 
     598         440 :   void SetShadowBaseTransform(const gfx::Matrix4x4& aMatrix)
     599             :   {
     600         440 :     mShadowTransform = aMatrix;
     601         440 :   }
     602         371 :   void SetShadowTransformSetByAnimation(bool aSetByAnimation)
     603             :   {
     604         371 :     mShadowTransformSetByAnimation = aSetByAnimation;
     605         371 :   }
     606             : 
     607             :   // These getters can be used anytime.
     608        1122 :   float GetShadowOpacity() { return mShadowOpacity; }
     609        1615 :   const Maybe<ParentLayerIntRect>& GetShadowClipRect() { return mShadowClipRect; }
     610           0 :   const LayerIntRegion& GetShadowVisibleRegion() const { return mShadowVisibleRegion; }
     611          29 :   const gfx::Matrix4x4& GetShadowBaseTransform() { return mShadowTransform; }
     612             :   gfx::Matrix4x4 GetShadowTransform();
     613           0 :   bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; }
     614             :   bool GetShadowOpacitySetByAnimation() { return mShadowOpacitySetByAnimation; }
     615         967 :   LayerIntRegion&& GetShadowVisibleRegion() { return Move(mShadowVisibleRegion); }
     616             : 
     617             : protected:
     618             :   HostLayerManager* mCompositorManager;
     619             : 
     620             :   gfx::Matrix4x4 mShadowTransform;
     621             :   LayerIntRegion mShadowVisibleRegion;
     622             :   Maybe<ParentLayerIntRect> mShadowClipRect;
     623             :   float mShadowOpacity;
     624             :   bool mShadowTransformSetByAnimation;
     625             :   bool mShadowOpacitySetByAnimation;
     626             : };
     627             : 
     628             : /**
     629             :  * Composite layers are for use with OMTC on the compositor thread only. There
     630             :  * must be corresponding Client layers on the content thread. For composite
     631             :  * layers, the layer manager only maintains the layer tree, all rendering is
     632             :  * done by a Compositor (see Compositor.h). As such, composite layers are
     633             :  * platform-independent and can be used on any platform for which there is a
     634             :  * Compositor implementation.
     635             :  *
     636             :  * The composite layer tree reflects exactly the basic layer tree. To
     637             :  * composite to screen, the layer manager walks the layer tree calling render
     638             :  * methods which in turn call into their CompositableHosts' Composite methods.
     639             :  * These call Compositor::DrawQuad to do the rendering.
     640             :  *
     641             :  * Mostly, layers are updated during the layers transaction. This is done from
     642             :  * CompositableClient to CompositableHost without interacting with the layer.
     643             :  *
     644             :  * A reference to the Compositor is stored in LayerManagerComposite.
     645             :  */
     646             : class LayerComposite : public HostLayer
     647             : {
     648             : public:
     649             :   explicit LayerComposite(LayerManagerComposite* aManager);
     650             : 
     651             :   virtual ~LayerComposite();
     652             : 
     653             :   virtual void SetLayerManager(HostLayerManager* aManager);
     654             : 
     655           0 :   virtual LayerComposite* GetFirstChildComposite()
     656             :   {
     657           0 :     return nullptr;
     658             :   }
     659             : 
     660             :   /* Do NOT call this from the generic LayerComposite destructor.  Only from the
     661             :    * concrete class destructor
     662             :    */
     663             :   virtual void Destroy();
     664         114 :   virtual void Cleanup() {}
     665             : 
     666             :   /**
     667             :    * Perform a first pass over the layer tree to render all of the intermediate
     668             :    * surfaces that we can. This allows us to avoid framebuffer switches in the
     669             :    * middle of our render which is inefficient especially on mobile GPUs. This
     670             :    * must be called before RenderLayer.
     671             :    */
     672          80 :   virtual void Prepare(const RenderTargetIntRect& aClipRect) {}
     673             : 
     674             :   // TODO: This should also take RenderTargetIntRect like Prepare.
     675             :   virtual void RenderLayer(const gfx::IntRect& aClipRect,
     676             :                            const Maybe<gfx::Polygon>& aGeometry) = 0;
     677             : 
     678           0 :   virtual bool SetCompositableHost(CompositableHost*)
     679             :   {
     680             :     // We must handle this gracefully, see bug 967824
     681           0 :     NS_WARNING("called SetCompositableHost for a layer type not accepting a compositable");
     682           0 :     return false;
     683             :   }
     684             : 
     685             :   virtual void CleanupResources() = 0;
     686             : 
     687           0 :   virtual void DestroyFrontBuffer() { }
     688             : 
     689             :   void AddBlendModeEffect(EffectChain& aEffectChain);
     690             : 
     691           0 :   virtual void GenEffectChain(EffectChain& aEffect) { }
     692             : 
     693         202 :   void SetLayerComposited(bool value)
     694             :   {
     695         202 :     mLayerComposited = value;
     696         202 :   }
     697             : 
     698           0 :   void SetClearRect(const gfx::IntRect& aRect)
     699             :   {
     700           0 :     mClearRect = aRect;
     701           0 :   }
     702             : 
     703         141 :   bool HasLayerBeenComposited() { return mLayerComposited; }
     704           0 :   gfx::IntRect GetClearRect() { return mClearRect; }
     705             : 
     706             :   // Returns false if the layer is attached to an older compositor.
     707             :   bool HasStaleCompositor() const;
     708             : 
     709             :   /**
     710             :    * Return the part of the visible region that has been fully rendered.
     711             :    * While progressive drawing is in progress this region will be
     712             :    * a subset of the shadow visible region.
     713             :    */
     714             :   virtual nsIntRegion GetFullyRenderedRegion();
     715             : 
     716             : protected:
     717             :   LayerManagerComposite* mCompositeManager;
     718             : 
     719             :   RefPtr<Compositor> mCompositor;
     720             :   bool mDestroyed;
     721             :   bool mLayerComposited;
     722             :   gfx::IntRect mClearRect;
     723             : };
     724             : 
     725             : // Render aLayer using aCompositor and apply all mask layers of aLayer: The
     726             : // layer's own mask layer (aLayer->GetMaskLayer()), and any ancestor mask
     727             : // layers.
     728             : // If more than one mask layer needs to be applied, we use intermediate surfaces
     729             : // (CompositingRenderTargets) for rendering, applying one mask layer at a time.
     730             : // Callers need to provide a callback function aRenderCallback that does the
     731             : // actual rendering of the source. It needs to have the following form:
     732             : // void (EffectChain& effectChain, const Rect& clipRect)
     733             : // aRenderCallback is called exactly once, inside this function, unless aLayer's
     734             : // visible region is completely clipped out (in that case, aRenderCallback won't
     735             : // be called at all).
     736             : // This function calls aLayer->AsHostLayer()->AddBlendModeEffect for the
     737             : // final rendering pass.
     738             : //
     739             : // (This function should really live in LayerManagerComposite.cpp, but we
     740             : // need to use templates for passing lambdas until bug 1164522 is resolved.)
     741             : template<typename RenderCallbackType>
     742             : void
     743          80 : RenderWithAllMasks(Layer* aLayer, Compositor* aCompositor,
     744             :                    const gfx::IntRect& aClipRect,
     745             :                    RenderCallbackType aRenderCallback)
     746             : {
     747          80 :   Layer* firstMask = nullptr;
     748          80 :   size_t maskLayerCount = 0;
     749          80 :   size_t nextAncestorMaskLayer = 0;
     750             : 
     751          80 :   size_t ancestorMaskLayerCount = aLayer->GetAncestorMaskLayerCount();
     752          80 :   if (Layer* ownMask = aLayer->GetMaskLayer()) {
     753           0 :     firstMask = ownMask;
     754           0 :     maskLayerCount = ancestorMaskLayerCount + 1;
     755           0 :     nextAncestorMaskLayer = 0;
     756          80 :   } else if (ancestorMaskLayerCount > 0) {
     757           0 :     firstMask = aLayer->GetAncestorMaskLayerAt(0);
     758           0 :     maskLayerCount = ancestorMaskLayerCount;
     759           0 :     nextAncestorMaskLayer = 1;
     760             :   } else {
     761             :     // no mask layers at all
     762             :   }
     763             : 
     764          80 :   if (maskLayerCount <= 1) {
     765             :     // This is the common case. Render in one pass and return.
     766         160 :     EffectChain effectChain(aLayer);
     767             :     LayerManagerComposite::AutoAddMaskEffect
     768         160 :       autoMaskEffect(firstMask, effectChain);
     769          80 :     static_cast<LayerComposite*>(aLayer->AsHostLayer())->AddBlendModeEffect(effectChain);
     770          80 :     aRenderCallback(effectChain, aClipRect);
     771          80 :     return;
     772             :   }
     773             : 
     774             :   // We have multiple mask layers.
     775             :   // We split our list of mask layers into three parts:
     776             :   //  (1) The first mask
     777             :   //  (2) The list of intermediate masks (every mask except first and last)
     778             :   //  (3) The final mask.
     779             :   // Part (2) can be empty.
     780             :   // For parts (1) and (2) we need to allocate intermediate surfaces to render
     781             :   // into. The final mask gets rendered into the original render target.
     782             : 
     783             :   // Calculate the size of the intermediate surfaces.
     784           0 :   gfx::Rect visibleRect(aLayer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
     785           0 :   gfx::Matrix4x4 transform = aLayer->GetEffectiveTransform();
     786             :   // TODO: Use RenderTargetIntRect and TransformBy here
     787             :   gfx::IntRect surfaceRect =
     788           0 :     RoundedOut(transform.TransformAndClipBounds(visibleRect, gfx::Rect(aClipRect)));
     789           0 :   if (surfaceRect.IsEmpty()) {
     790           0 :     return;
     791             :   }
     792             : 
     793             :   RefPtr<CompositingRenderTarget> originalTarget =
     794           0 :     aCompositor->GetCurrentRenderTarget();
     795             : 
     796             :   RefPtr<CompositingRenderTarget> firstTarget =
     797           0 :     aCompositor->CreateRenderTarget(surfaceRect, INIT_MODE_CLEAR);
     798           0 :   if (!firstTarget) {
     799           0 :     return;
     800             :   }
     801             : 
     802             :   // Render the source while applying the first mask.
     803           0 :   aCompositor->SetRenderTarget(firstTarget);
     804             :   {
     805           0 :     EffectChain firstEffectChain(aLayer);
     806             :     LayerManagerComposite::AutoAddMaskEffect
     807           0 :       firstMaskEffect(firstMask, firstEffectChain);
     808           0 :     aRenderCallback(firstEffectChain, aClipRect - surfaceRect.TopLeft());
     809             :     // firstTarget now contains the transformed source with the first mask and
     810             :     // opacity already applied.
     811             :   }
     812             : 
     813             :   // Apply the intermediate masks.
     814           0 :   gfx::IntRect intermediateClip(surfaceRect - surfaceRect.TopLeft());
     815           0 :   RefPtr<CompositingRenderTarget> previousTarget = firstTarget;
     816           0 :   for (size_t i = nextAncestorMaskLayer; i < ancestorMaskLayerCount - 1; i++) {
     817           0 :     Layer* intermediateMask = aLayer->GetAncestorMaskLayerAt(i);
     818             :     RefPtr<CompositingRenderTarget> intermediateTarget =
     819           0 :       aCompositor->CreateRenderTarget(surfaceRect, INIT_MODE_CLEAR);
     820           0 :     if (!intermediateTarget) {
     821           0 :       break;
     822             :     }
     823           0 :     aCompositor->SetRenderTarget(intermediateTarget);
     824           0 :     EffectChain intermediateEffectChain(aLayer);
     825             :     LayerManagerComposite::AutoAddMaskEffect
     826           0 :       intermediateMaskEffect(intermediateMask, intermediateEffectChain);
     827           0 :     if (intermediateMaskEffect.Failed()) {
     828           0 :       continue;
     829             :     }
     830           0 :     intermediateEffectChain.mPrimaryEffect = new EffectRenderTarget(previousTarget);
     831           0 :     aCompositor->DrawQuad(gfx::Rect(surfaceRect), intermediateClip,
     832             :                           intermediateEffectChain, 1.0, gfx::Matrix4x4());
     833           0 :     previousTarget = intermediateTarget;
     834             :   }
     835             : 
     836           0 :   aCompositor->SetRenderTarget(originalTarget);
     837             : 
     838             :   // Apply the final mask, rendering into originalTarget.
     839           0 :   EffectChain finalEffectChain(aLayer);
     840           0 :   finalEffectChain.mPrimaryEffect = new EffectRenderTarget(previousTarget);
     841           0 :   Layer* finalMask = aLayer->GetAncestorMaskLayerAt(ancestorMaskLayerCount - 1);
     842             : 
     843             :   // The blend mode needs to be applied in this final step, because this is
     844             :   // where we're blending with the actual background (which is in originalTarget).
     845           0 :   static_cast<LayerComposite*>(aLayer->AsHostLayer())->AddBlendModeEffect(finalEffectChain);
     846           0 :   LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(finalMask, finalEffectChain);
     847           0 :   if (!autoMaskEffect.Failed()) {
     848           0 :     aCompositor->DrawQuad(gfx::Rect(surfaceRect), aClipRect,
     849             :                           finalEffectChain, 1.0, gfx::Matrix4x4());
     850             :   }
     851             : }
     852             : 
     853             : } // namespace layers
     854             : } // namespace mozilla
     855             : 
     856             : #endif /* GFX_LayerManagerComposite_H */

Generated by: LCOV version 1.13