1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef GFX_LayerManagerComposite_H
8 #define GFX_LayerManagerComposite_H
9 
10 #include <cstdint>             // for uint64_t, int32_t
11 #include <deque>               // for deque
12 #include <new>                 // for operator new
13 #include <type_traits>         // for remove_reference<>::type
14 #include <utility>             // for move, forward
15 #include "CompositableHost.h"  // for ImageCompositeNotificationInfo
16 #include "Units.h"  // for LayerIntRegion, ParentLayerIntRect, RenderTargetIntRect
17 #include "mozilla/AlreadyAddRefed.h"  // for already_AddRefed
18 #include "mozilla/Assertions.h"  // for MOZ_CRASH, AssertionConditionType, MOZ_ASSERT, MOZ_AS...
19 #include "mozilla/Maybe.h"        // for Maybe
20 #include "mozilla/RefPtr.h"       // for RefPtr
21 #include "mozilla/TimeStamp.h"    // for TimeStamp, BaseTimeDuration
22 #include "mozilla/UniquePtr.h"    // for UniquePtr
23 #include "mozilla/gfx/2D.h"       // for DrawTarget
24 #include "mozilla/gfx/Matrix.h"   // for Matrix4x4
25 #include "mozilla/gfx/Point.h"    // for IntSize
26 #include "mozilla/gfx/Polygon.h"  // for Polygon
27 #include "mozilla/gfx/Rect.h"     // for IntRect
28 #include "mozilla/gfx/Types.h"    // for DeviceColor (ptr only), SurfaceFormat
29 #include "mozilla/layers/CompositionRecorder.h"  // for CompositionRecorder, CollectedFrames (ptr only)
30 #include "mozilla/layers/Compositor.h"  // for Compositor
31 #include "mozilla/layers/CompositorTypes.h"  // for DiagnosticTypes, TextureFactoryIdentifier
32 #include "mozilla/layers/LayerManager.h"  // for LayerManager::END_DEFAULT, LayerManager::EndTransacti...
33 #include "mozilla/layers/LayersTypes.h"  // for CompositionOpportunityId, LayersBackend, LayersBacken...
34 #include "mozilla/layers/ScreenshotGrabber.h"  // for ScreenshotGrabber
35 #include "nsDebug.h"                           // for NS_WARNING
36 #include "nsIThread.h"                         // for TimeDuration
37 #include "nsRegion.h"                          // for nsIntRegion
38 #include "nsRegionFwd.h"                       // for IntRegion
39 #include "nsStringFwd.h"                       // for nsCString, nsAString
40 #include "nsTArray.h"                          // for nsTArray
41 
42 class gfxContext;
43 
44 #ifdef XP_WIN
45 #  include <windows.h>
46 #endif
47 
48 namespace mozilla {
49 namespace layers {
50 
51 class CanvasLayer;
52 class CanvasLayerComposite;
53 class ColorLayer;
54 class ColorLayerComposite;
55 class ContainerLayer;
56 class ContainerLayerComposite;
57 class Diagnostics;
58 struct EffectChain;
59 class ImageLayer;
60 class ImageLayerComposite;
61 class LayerComposite;
62 class NativeLayer;
63 class NativeLayerRoot;
64 class RefLayerComposite;
65 class PaintTiming;
66 class PaintedLayer;
67 class PaintedLayerComposite;
68 class RefLayer;
69 class SurfacePoolHandle;
70 class TextRenderer;
71 class TextureSourceProvider;
72 class CompositingRenderTarget;
73 struct FPSState;
74 class PaintCounter;
75 class UiCompositorControllerParent;
76 class Layer;
77 struct LayerProperties;
78 
79 static const int kVisualWarningDuration = 150;  // ms
80 
81 // An implementation of LayerManager that acts as a pair with ClientLayerManager
82 // and is mirrored across IPDL. This gets managed/updated by
83 // LayerTransactionParent.
84 class HostLayerManager : public LayerManager {
85  public:
86   HostLayerManager();
87   virtual ~HostLayerManager();
88 
BeginTransactionWithTarget(gfxContext * aTarget,const nsCString & aURL)89   bool BeginTransactionWithTarget(gfxContext* aTarget,
90                                   const nsCString& aURL) override {
91     MOZ_CRASH("GFX: Use BeginTransactionWithDrawTarget");
92   }
93 
94   bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override {
95     MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)");
96     return false;
97   }
98 
99   void EndTransaction(DrawPaintedLayerCallback aCallback, void* aCallbackData,
100                       EndTransactionFlags aFlags = END_DEFAULT) override {
101     MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)");
102   }
103 
GetMaxTextureSize()104   int32_t GetMaxTextureSize() const override {
105     MOZ_CRASH("GFX: Call on compositor, not LayerManagerComposite");
106   }
107 
GetBackendName(nsAString & name)108   void GetBackendName(nsAString& name) override {
109     MOZ_CRASH("GFX: Shouldn't be called for composited layer manager");
110   }
111 
112   virtual void ForcePresent() = 0;
113   virtual void AddInvalidRegion(const nsIntRegion& aRegion) = 0;
114 
NotifyShadowTreeTransaction()115   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;
UpdateRenderBounds(const gfx::IntRect & aRect)122   virtual void UpdateRenderBounds(const gfx::IntRect& aRect) {}
SetDiagnosticTypes(DiagnosticTypes aDiagnostics)123   virtual void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) {}
124   virtual void InvalidateAll() = 0;
125 
AsHostLayerManager()126   HostLayerManager* AsHostLayerManager() override { return this; }
127 
ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo> * aNotifications)128   void ExtractImageCompositeNotifications(
129       nsTArray<ImageCompositeNotificationInfo>* aNotifications) {
130     aNotifications->AppendElements(std::move(mImageCompositeNotifications));
131   }
132 
AppendImageCompositeNotification(const ImageCompositeNotificationInfo & aNotification)133   void AppendImageCompositeNotification(
134       const ImageCompositeNotificationInfo& aNotification) {
135     // Only send composite notifications when we're drawing to the screen,
136     // because that's what they mean.
137     // Also when we're not drawing to the screen, DidComposite will not be
138     // called to extract and send these notifications, so they might linger
139     // and contain stale ImageContainerParent pointers.
140     if (IsCompositingToScreen()) {
141       mImageCompositeNotifications.AppendElement(aNotification);
142     }
143   }
144 
145   /**
146    * LayerManagerComposite provides sophisticated debug overlays
147    * that can request a next frame.
148    */
DebugOverlayWantsNextFrame()149   bool DebugOverlayWantsNextFrame() { return mDebugOverlayWantsNextFrame; }
SetDebugOverlayWantsNextFrame(bool aVal)150   void SetDebugOverlayWantsNextFrame(bool aVal) {
151     mDebugOverlayWantsNextFrame = aVal;
152   }
153 
154   /**
155    * Add an on frame warning.
156    * @param severity ranges from 0 to 1. It's used to compute the warning color.
157    */
VisualFrameWarning(float severity)158   void VisualFrameWarning(float severity) {
159     mozilla::TimeStamp now = TimeStamp::Now();
160     if (mWarnTime.IsNull() || severity > mWarningLevel ||
161         mWarnTime + TimeDuration::FromMilliseconds(kVisualWarningDuration) <
162             now) {
163       mWarnTime = now;
164       mWarningLevel = severity;
165     }
166   }
167 
SetPaintTime(const TimeDuration & aPaintTime)168   void SetPaintTime(const TimeDuration& aPaintTime) {
169     mLastPaintTime = aPaintTime;
170   }
171 
AlwaysScheduleComposite()172   virtual bool AlwaysScheduleComposite() const { return false; }
IsCompositingToScreen()173   virtual bool IsCompositingToScreen() const { return false; }
174 
175   void RecordPaintTimes(const PaintTiming& aTiming);
176   void RecordUpdateTime(float aValue);
177 
GetCompositionOpportunityId()178   CompositionOpportunityId GetCompositionOpportunityId() const {
179     return mCompositionOpportunityId;
180   }
181 
GetCompositionTime()182   TimeStamp GetCompositionTime() const { return mCompositionTime; }
SetCompositionTime(TimeStamp aTimeStamp)183   void SetCompositionTime(TimeStamp aTimeStamp) {
184     mCompositionTime = aTimeStamp;
185     if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() &&
186         mCompositionTime >= mCompositeUntilTime) {
187       mCompositeUntilTime = TimeStamp();
188     }
189   }
190 
CompositeUntil(TimeStamp aTimeStamp)191   void CompositeUntil(TimeStamp aTimeStamp) {
192     if (mCompositeUntilTime.IsNull() || mCompositeUntilTime < aTimeStamp) {
193       mCompositeUntilTime = aTimeStamp;
194     }
195   }
GetCompositeUntilTime()196   TimeStamp GetCompositeUntilTime() const { return mCompositeUntilTime; }
197 
198   // We maintaining a global mapping from ID to CompositorBridgeParent for
199   // async compositables.
GetCompositorBridgeID()200   uint64_t GetCompositorBridgeID() const { return mCompositorBridgeID; }
SetCompositorBridgeID(uint64_t aID)201   void SetCompositorBridgeID(uint64_t aID) {
202     MOZ_ASSERT(mCompositorBridgeID == 0,
203                "The compositor ID must be set only once.");
204     mCompositorBridgeID = aID;
205   }
206 
SetCompositionRecorder(UniquePtr<CompositionRecorder> aRecorder)207   void SetCompositionRecorder(UniquePtr<CompositionRecorder> aRecorder) {
208     mCompositionRecorder = std::move(aRecorder);
209   }
210 
211   /**
212    * Write the frames collected by the |CompositionRecorder| to disk.
213    *
214    * If there is not currently a |CompositionRecorder|, this is a no-op.
215    */
216   void WriteCollectedFrames();
217 
218   Maybe<CollectedFrames> GetCollectedFrames();
219 
220  protected:
221   bool mDebugOverlayWantsNextFrame;
222   nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications;
223   // Testing property. If hardware composer is supported, this will return
224   // true if the last frame was deemed 'too complicated' to be rendered.
225   float mWarningLevel;
226   mozilla::TimeStamp mWarnTime;
227   UniquePtr<Diagnostics> mDiagnostics;
228   uint64_t mCompositorBridgeID;
229 
230   TimeDuration mLastPaintTime;
231   TimeStamp mRenderStartTime;
232   UniquePtr<CompositionRecorder> mCompositionRecorder = nullptr;
233 
234   // Render time for the current composition.
235   TimeStamp mCompositionTime;
236 
237   // CompositionOpportunityId of the current composition.
238   CompositionOpportunityId mCompositionOpportunityId;
239 
240   // When nonnull, during rendering, some compositable indicated that it will
241   // change its rendering at this time. In order not to miss it, we composite
242   // on every vsync until this time occurs (this is the latest such time).
243   TimeStamp mCompositeUntilTime;
244 #if defined(MOZ_WIDGET_ANDROID)
245  public:
246   // Used by UiCompositorControllerParent to set itself as the target for the
247   // contents of the frame buffer after a composite.
248   // Implemented in LayerManagerComposite
RequestScreenPixels(UiCompositorControllerParent * aController)249   virtual void RequestScreenPixels(UiCompositorControllerParent* aController) {}
250 #endif  // defined(MOZ_WIDGET_ANDROID)
251 };
252 
253 // A layer manager implementation that uses the Compositor API
254 // to render layers.
255 class LayerManagerComposite final : public HostLayerManager {
256   typedef mozilla::gfx::DrawTarget DrawTarget;
257   typedef mozilla::gfx::IntSize IntSize;
258   typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
259 
260  public:
261   explicit LayerManagerComposite(Compositor* aCompositor);
262   virtual ~LayerManagerComposite();
263 
264   void Destroy() override;
265 
266   /**
267    * Sets the clipping region for this layer manager. This is important on
268    * windows because using OGL we no longer have GDI's native clipping. Therefor
269    * widget must tell us what part of the screen is being invalidated,
270    * and we should clip to this.
271    *
272    * \param aClippingRegion Region to clip to. Setting an empty region
273    * will disable clipping.
274    */
SetClippingRegion(const nsIntRegion & aClippingRegion)275   void SetClippingRegion(const nsIntRegion& aClippingRegion) {
276     mClippingRegion = aClippingRegion;
277   }
278 
279   /**
280    * LayerManager implementation.
281    */
AsLayerManagerComposite()282   LayerManagerComposite* AsLayerManagerComposite() override { return this; }
283 
284   void UpdateRenderBounds(const gfx::IntRect& aRect) override;
285 
286   bool BeginTransaction(const nsCString& aURL) 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   virtual void EndTransaction(
292       DrawPaintedLayerCallback aCallback, void* aCallbackData,
293       EndTransactionFlags aFlags = END_DEFAULT) override {
294     MOZ_CRASH("GFX: Use EndTransaction(aTimeStamp)");
295   }
296 
297   void SetRoot(Layer* aLayer) override;
298 
299   // XXX[nrc]: never called, we should move this logic to ClientLayerManager
300   // (bug 946926).
301   bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) override;
302 
303   void ClearCachedResources(Layer* aSubtree = nullptr) override;
304 
305   already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
306   already_AddRefed<ContainerLayer> CreateContainerLayer() override;
307   already_AddRefed<ImageLayer> CreateImageLayer() override;
308   already_AddRefed<ColorLayer> CreateColorLayer() override;
309   already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
310   already_AddRefed<RefLayer> CreateRefLayer() override;
311 
312   bool AreComponentAlphaLayersEnabled() override;
313 
314   already_AddRefed<DrawTarget> CreateOptimalMaskDrawTarget(
315       const IntSize& aSize) override;
316 
Name()317   const char* Name() const override { return ""; }
318   bool IsCompositingToScreen() const override;
319 
320   bool AlwaysScheduleComposite() const override;
321 
322   /**
323    * Post-processes layers before composition. This performs the following:
324    *
325    *   - Applies occlusion culling. This restricts the shadow visible region of
326    *     layers that are covered with opaque content.  |aOpaqueRegion| is the
327    *     region already known to be covered with opaque content, in the
328    *     post-transform coordinate space of aLayer.
329    *
330    *   - Recomputes visible regions to account for async transforms.
331    *     Each layer accumulates into |aVisibleRegion| its post-transform
332    *     (including async transforms) visible region.
333    *
334    *   - aRenderTargetClip is the exact clip required for aLayer, in the
335    *     coordinates of the nearest render target (the same as
336    *     GetEffectiveTransform).
337    *
338    *   - aClipFromAncestors is the approximate combined clip from all
339    *     ancestors, in the coordinate space of our parent, but maybe be an
340    *     overestimate in the presence of complex transforms.
341    */
342   void PostProcessLayers(nsIntRegion& aOpaqueRegion);
343   void PostProcessLayers(Layer* aLayer, nsIntRegion& aOpaqueRegion,
344                          LayerIntRegion& aVisibleRegion,
345                          const Maybe<RenderTargetIntRect>& aRenderTargetClip,
346                          const Maybe<ParentLayerIntRect>& aClipFromAncestors,
347                          bool aCanContributeOpaque);
348 
349   /**
350    * RAII helper class to add a mask effect with the compositable from
351    * aMaskLayer to the EffectChain aEffect and notify the compositable when we
352    * are done.
353    */
354   class AutoAddMaskEffect {
355    public:
356     AutoAddMaskEffect(Layer* aMaskLayer, EffectChain& aEffect);
357     ~AutoAddMaskEffect();
358 
Failed()359     bool Failed() const { return mFailed; }
360 
361    private:
362     CompositableHost* mCompositable;
363     bool mFailed;
364   };
365 
366   /**
367    * returns true if PlatformAllocBuffer will return a buffer that supports
368    * direct texturing
369    */
370   static bool SupportsDirectTexturing();
371 
372   static void PlatformSyncBeforeReplyUpdate();
373 
AddInvalidRegion(const nsIntRegion & aRegion)374   void AddInvalidRegion(const nsIntRegion& aRegion) override {
375     mInvalidRegion.Or(mInvalidRegion, aRegion);
376   }
377 
GetCompositor()378   Compositor* GetCompositor() const override { return mCompositor; }
GetTextureSourceProvider()379   TextureSourceProvider* GetTextureSourceProvider() const override {
380     return mCompositor;
381   }
382 
383   void NotifyShadowTreeTransaction() override;
384 
GetTextRenderer()385   TextRenderer* GetTextRenderer() { return mTextRenderer; }
386 
UnusedApzTransformWarning()387   void UnusedApzTransformWarning() { mUnusedApzTransformWarning = true; }
DisabledApzWarning()388   void DisabledApzWarning() { mDisabledApzWarning = true; }
389 
390   bool AsyncPanZoomEnabled() const override;
391 
392  public:
GetTextureFactoryIdentifier()393   TextureFactoryIdentifier GetTextureFactoryIdentifier() override {
394     return mCompositor->GetTextureFactoryIdentifier();
395   }
GetBackendType()396   LayersBackend GetBackendType() override {
397     return mCompositor ? mCompositor->GetBackendType()
398                        : LayersBackend::LAYERS_NONE;
399   }
SetDiagnosticTypes(DiagnosticTypes aDiagnostics)400   void SetDiagnosticTypes(DiagnosticTypes aDiagnostics) override {
401     mCompositor->SetDiagnosticTypes(aDiagnostics);
402   }
403 
InvalidateAll()404   void InvalidateAll() override {
405     AddInvalidRegion(nsIntRegion(mRenderBounds));
406   }
407 
ForcePresent()408   void ForcePresent() override { mCompositor->ForcePresent(); }
409 
410  private:
411   /** Region we're clipping our current drawing to. */
412   nsIntRegion mClippingRegion;
413   gfx::IntRect mRenderBounds;
414 
415   /** Current root layer. */
416   LayerComposite* RootLayer() const;
417 
418   /**
419    * Update the invalid region and render it.
420    */
421   void UpdateAndRender();
422 
423   /**
424    * Render the current layer tree to the active target.
425    * Returns true if the current invalid region can be cleared, false if
426    * rendering was canceled.
427    */
428   bool Render(const nsIntRegion& aInvalidRegion,
429               const nsIntRegion& aOpaqueRegion);
430 #if defined(MOZ_WIDGET_ANDROID)
431   void RenderToPresentationSurface();
432   // Shifts the content down so the toolbar does not cover it.
433   // Returns the Y shift of the content in screen pixels
434   ScreenCoord GetContentShiftForToolbar();
435   // Renders the static snapshot after the content has been rendered.
436   void RenderToolbar();
437   // Used by robocop tests to get a snapshot of the frame buffer.
438   void HandlePixelsTarget();
439 #endif
440 
441   /**
442    * We need to know our invalid region before we're ready to render.
443    */
444   void InvalidateDebugOverlay(nsIntRegion& aInvalidRegion,
445                               const gfx::IntRect& aBounds);
446 
447   /**
448    * Render debug overlays such as the FPS/FrameCounter above the frame.
449    */
450   void RenderDebugOverlay(const gfx::IntRect& aBounds);
451 
452   void DrawBorder(const gfx::IntRect& aOuter, int32_t aBorderWidth,
453                   const gfx::DeviceColor& aColor,
454                   const gfx::Matrix4x4& aTransform);
455   void DrawTranslationWarningOverlay(const gfx::IntRect& aBounds);
456 
457   void UpdateDebugOverlayNativeLayers();
458 
459   RefPtr<CompositingRenderTarget> PushGroupForLayerEffects();
460   void PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget,
461                                gfx::IntRect aClipRect, bool aGrayscaleEffect,
462                                bool aInvertEffect, float aContrastEffect);
463 
464   /**
465    * Create or recycle native layers to cover aRegion or aRect.
466    * This method takes existing layers from the front of aLayersToRecycle (or
467    * creates new layers if no layers are left to recycle) and appends them to
468    * the end of mNativeLayers. The "take from front, add to back" approach keeps
469    * the layer to rect assignment stable between frames.
470    * Updates the rect and opaqueness on the layers. For layers that moved or
471    * resized, *aWindowInvalidRegion is updated to include the area impacted by
472    * the move.
473    * Any layers left in aLayersToRecycle are not needed and can be disposed of.
474    */
475   void PlaceNativeLayers(const gfx::IntRegion& aRegion, bool aOpaque,
476                          std::deque<RefPtr<NativeLayer>>* aLayersToRecycle,
477                          gfx::IntRegion* aWindowInvalidRegion);
478   void PlaceNativeLayer(const gfx::IntRect& aRect, bool aOpaque,
479                         std::deque<RefPtr<NativeLayer>>* aLayersToRecycle,
480                         gfx::IntRegion* aWindowInvalidRegion);
481 
482   bool mUnusedApzTransformWarning;
483   bool mDisabledApzWarning;
484   RefPtr<Compositor> mCompositor;
485   UniquePtr<LayerProperties> mClonedLayerTreeProperties;
486 
487   /**
488    * Context target, nullptr when drawing directly to our swap chain.
489    */
490   RefPtr<gfx::DrawTarget> mTarget;
491   gfx::IntRect mTargetBounds;
492 
493   nsIntRegion mInvalidRegion;
494 
495   bool mInTransaction;
496   bool mIsCompositorReady;
497 
498   RefPtr<CompositingRenderTarget> mTwoPassTmpTarget;
499   ScreenshotGrabber mProfilerScreenshotGrabber;
500   RefPtr<TextRenderer> mTextRenderer;
501   RefPtr<NativeLayerRoot> mNativeLayerRoot;
502   RefPtr<SurfacePoolHandle> mSurfacePoolHandle;
503   std::deque<RefPtr<NativeLayer>> mNativeLayers;
504   RefPtr<NativeLayer> mGPUStatsLayer;
505   RefPtr<NativeLayer> mUnusedTransformWarningLayer;
506   RefPtr<NativeLayer> mDisabledApzWarningLayer;
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:
RequestScreenPixels(UiCompositorControllerParent * aController)517   virtual void RequestScreenPixels(
518       UiCompositorControllerParent* aController) override {
519     mScreenPixelsTarget = aController;
520   }
521 
522  private:
523   UiCompositorControllerParent* mScreenPixelsTarget;
524 #endif  // defined(MOZ_WIDGET_ANDROID)
525 };
526 
527 /**
528  * Compositor layers are for use with OMTC on the compositor thread only. There
529  * must be corresponding Client layers on the content thread. For composite
530  * layers, the layer manager only maintains the layer tree.
531  */
532 class HostLayer {
533  public:
HostLayer(HostLayerManager * aManager)534   explicit HostLayer(HostLayerManager* aManager)
535       : mCompositorManager(aManager),
536         mShadowOpacity(1.0),
537         mShadowTransformSetByAnimation(false),
538         mShadowOpacitySetByAnimation(false) {}
539 
SetLayerManager(HostLayerManager * aManager)540   virtual void SetLayerManager(HostLayerManager* aManager) {
541     mCompositorManager = aManager;
542   }
GetLayerManager()543   HostLayerManager* GetLayerManager() const { return mCompositorManager; }
544 
545   virtual ~HostLayer() = default;
546 
GetFirstChildComposite()547   virtual LayerComposite* GetFirstChildComposite() { return nullptr; }
548 
549   virtual Layer* GetLayer() = 0;
550 
SetCompositableHost(CompositableHost *)551   virtual bool SetCompositableHost(CompositableHost*) {
552     // We must handle this gracefully, see bug 967824
553     NS_WARNING(
554         "called SetCompositableHost for a layer type not accepting a "
555         "compositable");
556     return false;
557   }
558   virtual CompositableHost* GetCompositableHost() = 0;
559 
560   /**
561    * The following methods are
562    *
563    * CONSTRUCTION PHASE ONLY
564    *
565    * They are analogous to the Layer interface.
566    */
SetShadowVisibleRegion(const LayerIntRegion & aRegion)567   void SetShadowVisibleRegion(const LayerIntRegion& aRegion) {
568     mShadowVisibleRegion = aRegion;
569   }
SetShadowVisibleRegion(LayerIntRegion && aRegion)570   void SetShadowVisibleRegion(LayerIntRegion&& aRegion) {
571     mShadowVisibleRegion = std::move(aRegion);
572   }
573 
SetShadowOpacity(float aOpacity)574   void SetShadowOpacity(float aOpacity) { mShadowOpacity = aOpacity; }
SetShadowOpacitySetByAnimation(bool aSetByAnimation)575   void SetShadowOpacitySetByAnimation(bool aSetByAnimation) {
576     mShadowOpacitySetByAnimation = aSetByAnimation;
577   }
578 
SetShadowClipRect(const Maybe<ParentLayerIntRect> & aRect)579   void SetShadowClipRect(const Maybe<ParentLayerIntRect>& aRect) {
580     mShadowClipRect = aRect;
581   }
582 
SetShadowBaseTransform(const gfx::Matrix4x4 & aMatrix)583   void SetShadowBaseTransform(const gfx::Matrix4x4& aMatrix) {
584     mShadowTransform = aMatrix;
585   }
SetShadowTransformSetByAnimation(bool aSetByAnimation)586   void SetShadowTransformSetByAnimation(bool aSetByAnimation) {
587     mShadowTransformSetByAnimation = aSetByAnimation;
588   }
589 
590   // These getters can be used anytime.
GetShadowOpacity()591   float GetShadowOpacity() { return mShadowOpacity; }
GetShadowClipRect()592   const Maybe<ParentLayerIntRect>& GetShadowClipRect() {
593     return mShadowClipRect;
594   }
GetShadowVisibleRegion()595   virtual const LayerIntRegion& GetShadowVisibleRegion() {
596     return mShadowVisibleRegion;
597   }
GetShadowBaseTransform()598   const gfx::Matrix4x4& GetShadowBaseTransform() { return mShadowTransform; }
599   gfx::Matrix4x4 GetShadowTransform();
GetShadowTransformSetByAnimation()600   bool GetShadowTransformSetByAnimation() {
601     return mShadowTransformSetByAnimation;
602   }
GetShadowOpacitySetByAnimation()603   bool GetShadowOpacitySetByAnimation() { return mShadowOpacitySetByAnimation; }
604 
605   void RecomputeShadowVisibleRegionFromChildren();
606 
607  protected:
608   HostLayerManager* mCompositorManager;
609 
610   gfx::Matrix4x4 mShadowTransform;
611   LayerIntRegion mShadowVisibleRegion;
612   Maybe<ParentLayerIntRect> mShadowClipRect;
613   float mShadowOpacity;
614   bool mShadowTransformSetByAnimation;
615   bool mShadowOpacitySetByAnimation;
616 };
617 
618 /**
619  * Composite layers are for use with OMTC on the compositor thread only. There
620  * must be corresponding Client layers on the content thread. For composite
621  * layers, the layer manager only maintains the layer tree, all rendering is
622  * done by a Compositor (see Compositor.h). As such, composite layers are
623  * platform-independent and can be used on any platform for which there is a
624  * Compositor implementation.
625  *
626  * The composite layer tree reflects exactly the basic layer tree. To
627  * composite to screen, the layer manager walks the layer tree calling render
628  * methods which in turn call into their CompositableHosts' Composite methods.
629  * These call Compositor::DrawQuad to do the rendering.
630  *
631  * Mostly, layers are updated during the layers transaction. This is done from
632  * CompositableClient to CompositableHost without interacting with the layer.
633  *
634  * A reference to the Compositor is stored in LayerManagerComposite.
635  */
636 class LayerComposite : public HostLayer {
637  public:
638   explicit LayerComposite(LayerManagerComposite* aManager);
639 
640   virtual ~LayerComposite();
641 
642   void SetLayerManager(HostLayerManager* aManager) override;
643 
GetFirstChildComposite()644   LayerComposite* GetFirstChildComposite() override { return nullptr; }
645 
646   /* Do NOT call this from the generic LayerComposite destructor.  Only from the
647    * concrete class destructor
648    */
649   virtual void Destroy();
Cleanup()650   virtual void Cleanup() {}
651 
652   /**
653    * Perform a first pass over the layer tree to render all of the intermediate
654    * surfaces that we can. This allows us to avoid framebuffer switches in the
655    * middle of our render which is inefficient especially on mobile GPUs. This
656    * must be called before RenderLayer.
657    */
Prepare(const RenderTargetIntRect & aClipRect)658   virtual void Prepare(const RenderTargetIntRect& aClipRect) {}
659 
660   // TODO: This should also take RenderTargetIntRect like Prepare.
661   virtual void RenderLayer(const gfx::IntRect& aClipRect,
662                            const Maybe<gfx::Polygon>& aGeometry) = 0;
663 
SetCompositableHost(CompositableHost *)664   bool SetCompositableHost(CompositableHost*) override {
665     // We must handle this gracefully, see bug 967824
666     NS_WARNING(
667         "called SetCompositableHost for a layer type not accepting a "
668         "compositable");
669     return false;
670   }
671 
672   virtual void CleanupResources() = 0;
673 
DestroyFrontBuffer()674   virtual void DestroyFrontBuffer() {}
675 
676   void AddBlendModeEffect(EffectChain& aEffectChain);
677 
GenEffectChain(EffectChain & aEffect)678   virtual void GenEffectChain(EffectChain& aEffect) {}
679 
SetLayerComposited(bool value)680   void SetLayerComposited(bool value) { mLayerComposited = value; }
681 
SetClearRect(const gfx::IntRect & aRect)682   void SetClearRect(const gfx::IntRect& aRect) { mClearRect = aRect; }
683 
HasLayerBeenComposited()684   bool HasLayerBeenComposited() { return mLayerComposited; }
GetClearRect()685   gfx::IntRect GetClearRect() { return mClearRect; }
686 
687   // Returns false if the layer is attached to an older compositor.
688   bool HasStaleCompositor() const;
689 
690   /**
691    * Return the part of the visible region that has been fully rendered.
692    * While progressive drawing is in progress this region will be
693    * a subset of the shadow visible region.
694    */
695   virtual nsIntRegion GetFullyRenderedRegion();
696 
697  protected:
698   LayerManagerComposite* mCompositeManager;
699 
700   RefPtr<Compositor> mCompositor;
701   bool mDestroyed;
702   bool mLayerComposited;
703   gfx::IntRect mClearRect;
704 };
705 
706 class WindowLMC : public profiler_screenshots::Window {
707  public:
WindowLMC(Compositor * aCompositor)708   explicit WindowLMC(Compositor* aCompositor) : mCompositor(aCompositor) {}
709 
710   already_AddRefed<profiler_screenshots::RenderSource> GetWindowContents(
711       const gfx::IntSize& aWindowSize) override;
712   already_AddRefed<profiler_screenshots::DownscaleTarget> CreateDownscaleTarget(
713       const gfx::IntSize& aSize) override;
714   already_AddRefed<profiler_screenshots::AsyncReadbackBuffer>
715   CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) override;
716 
717  protected:
718   Compositor* mCompositor;
719 };
720 
721 }  // namespace layers
722 }  // namespace mozilla
723 
724 #endif /* GFX_LayerManagerComposite_H */
725