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