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_BASICLAYERS_H
8 #define GFX_BASICLAYERS_H
9 
10 #include <stdint.h>  // for INT32_MAX, int32_t
11 #include "Layers.h"  // for Layer (ptr only), etc
12 #include "gfxTypes.h"
13 #include "gfxContext.h"                  // for gfxContext
14 #include "mozilla/Attributes.h"          // for override
15 #include "mozilla/WidgetUtils.h"         // for ScreenRotation
16 #include "mozilla/layers/LayersTypes.h"  // for BufferMode, LayersBackend, etc
17 #include "mozilla/TimeStamp.h"
18 #include "nsAString.h"
19 #include "nsCOMPtr.h"         // for already_AddRefed
20 #include "nsISupportsImpl.h"  // for gfxContext::AddRef, etc
21 #include "nsRegion.h"         // for nsIntRegion
22 #include "nscore.h"           // for nsAString, etc
23 
24 class nsIWidget;
25 
26 namespace mozilla {
27 namespace layers {
28 
29 class ImageFactory;
30 class ImageLayer;
31 class PaintLayerContext;
32 class ReadbackLayer;
33 
34 /**
35  * This is a cairo/Thebes-only, main-thread-only implementation of layers.
36  *
37  * In each transaction, the client sets up the layer tree and then during
38  * the drawing phase, each PaintedLayer is painted directly into the target
39  * context (with appropriate clipping and Push/PopGroups performed
40  * between layers).
41  */
42 class BasicLayerManager final : public LayerManager {
43  public:
44   enum BasicLayerManagerType { BLM_WIDGET, BLM_OFFSCREEN, BLM_INACTIVE };
45   /**
46    * Construct a BasicLayerManager which will have no default
47    * target context. SetDefaultTarget or BeginTransactionWithTarget
48    * must be called for any rendering to happen. PaintedLayers will not
49    * be retained.
50    */
51   explicit BasicLayerManager(BasicLayerManagerType aType);
52   /**
53    * Construct a BasicLayerManager which will have no default
54    * target context. SetDefaultTarget or BeginTransactionWithTarget
55    * must be called for any rendering to happen. PaintedLayers will be
56    * retained; that is, we will try to retain the visible contents of
57    * PaintedLayers as cairo surfaces. We create PaintedLayer buffers by
58    * creating similar surfaces to the default target context, or to
59    * aWidget's GetThebesSurface if there is no default target context, or
60    * to the passed-in context if there is no widget and no default
61    * target context.
62    *
63    * This does not keep a strong reference to the widget, so the caller
64    * must ensure that the widget outlives the layer manager or call
65    * ClearWidget before the widget dies.
66    */
67   explicit BasicLayerManager(nsIWidget* aWidget);
68 
69  protected:
70   virtual ~BasicLayerManager();
71 
72  public:
AsBasicLayerManager()73   BasicLayerManager* AsBasicLayerManager() override { return this; }
74 
75   /**
76    * Set the default target context that will be used when BeginTransaction
77    * is called. This can only be called outside a transaction.
78    *
79    * aDoubleBuffering can request double-buffering for drawing to the
80    * default target. When BUFFERED, the layer manager avoids blitting
81    * temporary results to aContext and then overpainting them with final
82    * results, by using a temporary buffer when necessary. In BUFFERED
83    * mode we always completely overwrite the contents of aContext's
84    * destination surface (within the clip region) using OP_SOURCE.
85    */
86   void SetDefaultTarget(gfxContext* aContext);
87   virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
88                                              ScreenRotation aRotation);
GetDefaultTarget()89   gfxContext* GetDefaultTarget() { return mDefaultTarget; }
90 
GetRetainerWidget()91   nsIWidget* GetRetainerWidget() { return mWidget; }
ClearRetainerWidget()92   void ClearRetainerWidget() { mWidget = nullptr; }
93 
IsWidgetLayerManager()94   virtual bool IsWidgetLayerManager() override { return mWidget != nullptr; }
IsInactiveLayerManager()95   virtual bool IsInactiveLayerManager() override {
96     return mType == BLM_INACTIVE;
97   }
98 
99   virtual bool BeginTransaction(const nsCString& aURL = nsCString()) override;
100   virtual bool BeginTransactionWithTarget(
101       gfxContext* aTarget, const nsCString& aURL = nsCString()) override;
102   virtual bool EndEmptyTransaction(
103       EndTransactionFlags aFlags = END_DEFAULT) override;
104   virtual void EndTransaction(
105       DrawPaintedLayerCallback aCallback, void* aCallbackData,
106       EndTransactionFlags aFlags = END_DEFAULT) override;
107   void AbortTransaction();
108 
109   virtual void SetRoot(Layer* aLayer) override;
110 
111   virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
112   virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override;
113   virtual already_AddRefed<ImageLayer> CreateImageLayer() override;
114   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
115   virtual already_AddRefed<ColorLayer> CreateColorLayer() override;
116   virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() override;
117   virtual ImageFactory* GetImageFactory();
118 
GetBackendType()119   virtual LayersBackend GetBackendType() override {
120     return LayersBackend::LAYERS_BASIC;
121   }
GetBackendName(nsAString & name)122   virtual void GetBackendName(nsAString& name) override {
123     name.AssignLiteral("Basic");
124   }
125 
InConstruction()126   bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
127 #ifdef DEBUG
InDrawing()128   bool InDrawing() { return mPhase == PHASE_DRAWING; }
InForward()129   bool InForward() { return mPhase == PHASE_FORWARD; }
130 #endif
InTransaction()131   bool InTransaction() { return mPhase != PHASE_NONE; }
132 
GetTarget()133   gfxContext* GetTarget() { return mTarget; }
SetTarget(gfxContext * aTarget)134   void SetTarget(gfxContext* aTarget) {
135     mUsingDefaultTarget = false;
136     mTarget = aTarget;
137   }
IsRetained()138   bool IsRetained() { return mWidget != nullptr; }
139 
Name()140   virtual const char* Name() const override { return "Basic"; }
141 
142   // Clear the cached contents of this layer tree.
143   virtual void ClearCachedResources(Layer* aSubtree = nullptr) override;
144 
SetTransactionIncomplete()145   void SetTransactionIncomplete() { mTransactionIncomplete = true; }
IsTransactionIncomplete()146   bool IsTransactionIncomplete() { return mTransactionIncomplete; }
147 
148   struct PushedGroup {
PushedGroupPushedGroup149     PushedGroup()
150         : mFinalTarget(nullptr),
151           mNeedsClipToVisibleRegion(false),
152           mOperator(gfx::CompositionOp::OP_COUNT),
153           mOpacity(0.0f) {}
154     gfxContext* mFinalTarget;
155     RefPtr<gfxContext> mGroupTarget;
156     nsIntRegion mVisibleRegion;
157     bool mNeedsClipToVisibleRegion;
158     gfx::IntPoint mGroupOffset;
159     gfx::CompositionOp mOperator;
160     gfx::Float mOpacity;
161     RefPtr<gfx::SourceSurface> mMaskSurface;
162     gfx::Matrix mMaskTransform;
163   };
164 
165   // Construct a PushedGroup for a specific layer.
166   // Return false if it has some errors in PushGroupForLayer(). Then, the
167   // "aGroupResult" is unavailable for future using.
168   bool PushGroupForLayer(gfxContext* aContext, Layer* aLayerContext,
169                          const nsIntRegion& aRegion, PushedGroup& aGroupResult);
170 
171   void PopGroupForLayer(PushedGroup& aGroup);
172 
IsCompositingCheap()173   virtual bool IsCompositingCheap() override { return false; }
GetMaxTextureSize()174   virtual int32_t GetMaxTextureSize() const override { return INT32_MAX; }
CompositorMightResample()175   bool CompositorMightResample() { return mCompositorMightResample; }
176 
GetCompositionTime()177   TimeStamp GetCompositionTime() const { return mCompositionTime; }
178 
179  protected:
180   enum TransactionPhase {
181     PHASE_NONE,
182     PHASE_CONSTRUCTION,
183     PHASE_DRAWING,
184     PHASE_FORWARD
185   };
186   TransactionPhase mPhase;
187 
188   // This is the main body of the PaintLayer routine which will if it has
189   // children, recurse into PaintLayer() otherwise it will paint using the
190   // underlying Paint() method of the Layer. It will not do both.
191   void PaintSelfOrChildren(PaintLayerContext& aPaintContext,
192                            gfxContext* aGroupTarget);
193 
194   // Paint the group onto the underlying target. This is used by PaintLayer to
195   // flush the group to the underlying target.
196   void FlushGroup(PaintLayerContext& aPaintContext,
197                   bool aNeedsClipToVisibleRegion);
198 
199   // Paints aLayer to mTarget.
200   void PaintLayer(gfxContext* aTarget, Layer* aLayer,
201                   DrawPaintedLayerCallback aCallback, void* aCallbackData);
202 
203   // Clear the contents of a layer
204   void ClearLayer(Layer* aLayer);
205 
206   bool EndTransactionInternal(DrawPaintedLayerCallback aCallback,
207                               void* aCallbackData,
208                               EndTransactionFlags aFlags = END_DEFAULT);
209 
210   void FlashWidgetUpdateArea(gfxContext* aContext);
211 
SetCompositionTime(TimeStamp aTimeStamp)212   void SetCompositionTime(TimeStamp aTimeStamp) {
213     mCompositionTime = aTimeStamp;
214   }
215 
216   // Widget whose surface should be used as the basis for PaintedLayer
217   // buffers.
218   nsIWidget* mWidget;
219   // The default context for BeginTransaction.
220   RefPtr<gfxContext> mDefaultTarget;
221   // The context to draw into.
222   RefPtr<gfxContext> mTarget;
223   // Image factory we use.
224   RefPtr<ImageFactory> mFactory;
225 
226   BufferMode mDoubleBuffering;
227   BasicLayerManagerType mType;
228   bool mUsingDefaultTarget;
229   bool mTransactionIncomplete;
230   bool mCompositorMightResample;
231 
232   TimeStamp mCompositionTime;
233 };
234 
235 }  // namespace layers
236 }  // namespace mozilla
237 
238 #endif /* GFX_BASICLAYERS_H */
239