|
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_CLIENTLAYERMANAGER_H |
|
7 #define GFX_CLIENTLAYERMANAGER_H |
|
8 |
|
9 #include <stdint.h> // for int32_t |
|
10 #include "Layers.h" |
|
11 #include "gfxContext.h" // for gfxContext |
|
12 #include "mozilla/Attributes.h" // for MOZ_OVERRIDE |
|
13 #include "mozilla/LinkedList.h" // For LinkedList |
|
14 #include "mozilla/WidgetUtils.h" // for ScreenRotation |
|
15 #include "mozilla/gfx/Rect.h" // for Rect |
|
16 #include "mozilla/layers/CompositorTypes.h" |
|
17 #include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc |
|
18 #include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder, etc |
|
19 #include "nsAutoPtr.h" // for nsRefPtr |
|
20 #include "nsCOMPtr.h" // for already_AddRefed |
|
21 #include "nsDebug.h" // for NS_ABORT_IF_FALSE |
|
22 #include "nsISupportsImpl.h" // for Layer::Release, etc |
|
23 #include "nsRect.h" // for nsIntRect |
|
24 #include "nsTArray.h" // for nsTArray |
|
25 #include "nscore.h" // for nsAString |
|
26 |
|
27 class nsIWidget; |
|
28 |
|
29 namespace mozilla { |
|
30 namespace layers { |
|
31 |
|
32 class ClientThebesLayer; |
|
33 class CompositorChild; |
|
34 class ImageLayer; |
|
35 class PLayerChild; |
|
36 class TextureClientPool; |
|
37 class SimpleTextureClientPool; |
|
38 |
|
39 class ClientLayerManager : public LayerManager |
|
40 { |
|
41 typedef nsTArray<nsRefPtr<Layer> > LayerRefArray; |
|
42 |
|
43 public: |
|
44 ClientLayerManager(nsIWidget* aWidget); |
|
45 virtual ~ClientLayerManager(); |
|
46 |
|
47 virtual ShadowLayerForwarder* AsShadowForwarder() |
|
48 { |
|
49 return mForwarder; |
|
50 } |
|
51 |
|
52 virtual int32_t GetMaxTextureSize() const; |
|
53 |
|
54 virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation); |
|
55 virtual void BeginTransactionWithTarget(gfxContext* aTarget); |
|
56 virtual void BeginTransaction(); |
|
57 virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT); |
|
58 virtual void EndTransaction(DrawThebesLayerCallback aCallback, |
|
59 void* aCallbackData, |
|
60 EndTransactionFlags aFlags = END_DEFAULT); |
|
61 |
|
62 virtual LayersBackend GetBackendType() { return LayersBackend::LAYERS_CLIENT; } |
|
63 virtual LayersBackend GetCompositorBackendType() MOZ_OVERRIDE |
|
64 { |
|
65 return AsShadowForwarder()->GetCompositorBackendType(); |
|
66 } |
|
67 virtual void GetBackendName(nsAString& name); |
|
68 virtual const char* Name() const { return "Client"; } |
|
69 |
|
70 virtual void SetRoot(Layer* aLayer); |
|
71 |
|
72 virtual void Mutated(Layer* aLayer); |
|
73 |
|
74 virtual already_AddRefed<ThebesLayer> CreateThebesLayer(); |
|
75 virtual already_AddRefed<ThebesLayer> CreateThebesLayerWithHint(ThebesLayerCreationHint aHint); |
|
76 virtual already_AddRefed<ContainerLayer> CreateContainerLayer(); |
|
77 virtual already_AddRefed<ImageLayer> CreateImageLayer(); |
|
78 virtual already_AddRefed<CanvasLayer> CreateCanvasLayer(); |
|
79 virtual already_AddRefed<ColorLayer> CreateColorLayer(); |
|
80 virtual already_AddRefed<RefLayer> CreateRefLayer(); |
|
81 |
|
82 TextureFactoryIdentifier GetTextureFactoryIdentifier() |
|
83 { |
|
84 return mForwarder->GetTextureFactoryIdentifier(); |
|
85 } |
|
86 |
|
87 virtual void FlushRendering() MOZ_OVERRIDE; |
|
88 void SendInvalidRegion(const nsIntRegion& aRegion); |
|
89 |
|
90 virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize) MOZ_OVERRIDE; |
|
91 |
|
92 virtual void StopFrameTimeRecording(uint32_t aStartIndex, |
|
93 nsTArray<float>& aFrameIntervals) MOZ_OVERRIDE; |
|
94 |
|
95 virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return false; } |
|
96 |
|
97 ShadowableLayer* Hold(Layer* aLayer); |
|
98 |
|
99 bool HasShadowManager() const { return mForwarder->HasShadowManager(); } |
|
100 |
|
101 virtual bool IsCompositingCheap(); |
|
102 virtual bool HasShadowManagerInternal() const { return HasShadowManager(); } |
|
103 |
|
104 virtual void SetIsFirstPaint() MOZ_OVERRIDE; |
|
105 |
|
106 TextureClientPool *GetTexturePool(gfx::SurfaceFormat aFormat); |
|
107 SimpleTextureClientPool *GetSimpleTileTexturePool(gfx::SurfaceFormat aFormat); |
|
108 |
|
109 // Drop cached resources and ask our shadow manager to do the same, |
|
110 // if we have one. |
|
111 virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE; |
|
112 |
|
113 void SetRepeatTransaction() { mRepeatTransaction = true; } |
|
114 bool GetRepeatTransaction() { return mRepeatTransaction; } |
|
115 |
|
116 bool IsRepeatTransaction() { return mIsRepeatTransaction; } |
|
117 |
|
118 void SetTransactionIncomplete() { mTransactionIncomplete = true; } |
|
119 |
|
120 bool HasShadowTarget() { return !!mShadowTarget; } |
|
121 |
|
122 void SetShadowTarget(gfxContext *aTarget) { mShadowTarget = aTarget; } |
|
123 |
|
124 bool CompositorMightResample() { return mCompositorMightResample; } |
|
125 |
|
126 DrawThebesLayerCallback GetThebesLayerCallback() const |
|
127 { return mThebesLayerCallback; } |
|
128 |
|
129 void* GetThebesLayerCallbackData() const |
|
130 { return mThebesLayerCallbackData; } |
|
131 |
|
132 CompositorChild *GetRemoteRenderer(); |
|
133 |
|
134 /** |
|
135 * Called for each iteration of a progressive tile update. Fills |
|
136 * aCompositionBounds and aZoom with the current scale and composition bounds |
|
137 * being used to composite the layers in this manager, to determine what area |
|
138 * intersects with the target composition bounds. |
|
139 * aDrawingCritical will be true if the current drawing operation is using |
|
140 * the critical displayport. |
|
141 * Returns true if the update should continue, or false if it should be |
|
142 * cancelled. |
|
143 * This is only called if gfxPlatform::UseProgressiveTilePainting() returns |
|
144 * true. |
|
145 */ |
|
146 bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, |
|
147 ParentLayerRect& aCompositionBounds, |
|
148 CSSToParentLayerScale& aZoom, |
|
149 bool aDrawingCritical); |
|
150 |
|
151 bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; } |
|
152 #ifdef DEBUG |
|
153 bool InDrawing() { return mPhase == PHASE_DRAWING; } |
|
154 bool InForward() { return mPhase == PHASE_FORWARD; } |
|
155 #endif |
|
156 bool InTransaction() { return mPhase != PHASE_NONE; } |
|
157 |
|
158 void SetNeedsComposite(bool aNeedsComposite) |
|
159 { |
|
160 mNeedsComposite = aNeedsComposite; |
|
161 } |
|
162 bool NeedsComposite() const { return mNeedsComposite; } |
|
163 |
|
164 virtual void Composite() MOZ_OVERRIDE; |
|
165 |
|
166 virtual void DidComposite(); |
|
167 |
|
168 protected: |
|
169 enum TransactionPhase { |
|
170 PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD |
|
171 }; |
|
172 TransactionPhase mPhase; |
|
173 |
|
174 private: |
|
175 /** |
|
176 * Forward transaction results to the parent context. |
|
177 */ |
|
178 void ForwardTransaction(bool aScheduleComposite); |
|
179 |
|
180 /** |
|
181 * Take a snapshot of the parent context, and copy |
|
182 * it into mShadowTarget. |
|
183 */ |
|
184 void MakeSnapshotIfRequired(); |
|
185 |
|
186 void ClearLayer(Layer* aLayer); |
|
187 |
|
188 bool EndTransactionInternal(DrawThebesLayerCallback aCallback, |
|
189 void* aCallbackData, |
|
190 EndTransactionFlags); |
|
191 |
|
192 // The bounds of |mTarget| in device pixels. |
|
193 nsIntRect mTargetBounds; |
|
194 |
|
195 LayerRefArray mKeepAlive; |
|
196 |
|
197 nsIWidget* mWidget; |
|
198 |
|
199 /* Thebes layer callbacks; valid at the end of a transaciton, |
|
200 * while rendering */ |
|
201 DrawThebesLayerCallback mThebesLayerCallback; |
|
202 void *mThebesLayerCallbackData; |
|
203 |
|
204 // When we're doing a transaction in order to draw to a non-default |
|
205 // target, the layers transaction is only performed in order to send |
|
206 // a PLayers:Update. We save the original non-default target to |
|
207 // mShadowTarget, and then perform the transaction using |
|
208 // mDummyTarget as the render target. After the transaction ends, |
|
209 // we send a message to our remote side to capture the actual pixels |
|
210 // being drawn to the default target, and then copy those pixels |
|
211 // back to mShadowTarget. |
|
212 nsRefPtr<gfxContext> mShadowTarget; |
|
213 |
|
214 // Sometimes we draw to targets that don't natively support |
|
215 // landscape/portrait orientation. When we need to implement that |
|
216 // ourselves, |mTargetRotation| describes the induced transform we |
|
217 // need to apply when compositing content to our target. |
|
218 ScreenRotation mTargetRotation; |
|
219 |
|
220 // Used to repeat the transaction right away (to avoid rebuilding |
|
221 // a display list) to support progressive drawing. |
|
222 bool mRepeatTransaction; |
|
223 bool mIsRepeatTransaction; |
|
224 bool mTransactionIncomplete; |
|
225 bool mCompositorMightResample; |
|
226 bool mNeedsComposite; |
|
227 |
|
228 RefPtr<ShadowLayerForwarder> mForwarder; |
|
229 nsAutoTArray<RefPtr<TextureClientPool>,2> mTexturePools; |
|
230 |
|
231 // indexed by gfx::SurfaceFormat |
|
232 nsTArray<RefPtr<SimpleTextureClientPool> > mSimpleTilePools; |
|
233 }; |
|
234 |
|
235 class ClientLayer : public ShadowableLayer |
|
236 { |
|
237 public: |
|
238 ClientLayer() |
|
239 { |
|
240 MOZ_COUNT_CTOR(ClientLayer); |
|
241 } |
|
242 |
|
243 ~ClientLayer(); |
|
244 |
|
245 void SetShadow(PLayerChild* aShadow) |
|
246 { |
|
247 NS_ABORT_IF_FALSE(!mShadow, "can't have two shadows (yet)"); |
|
248 mShadow = aShadow; |
|
249 } |
|
250 |
|
251 virtual void Disconnect() |
|
252 { |
|
253 // This is an "emergency Disconnect()", called when the compositing |
|
254 // process has died. |mShadow| and our Shmem buffers are |
|
255 // automatically managed by IPDL, so we don't need to explicitly |
|
256 // free them here (it's hard to get that right on emergency |
|
257 // shutdown anyway). |
|
258 mShadow = nullptr; |
|
259 } |
|
260 |
|
261 virtual void ClearCachedResources() { } |
|
262 |
|
263 virtual void RenderLayer() = 0; |
|
264 |
|
265 virtual ClientThebesLayer* AsThebes() { return nullptr; } |
|
266 |
|
267 static inline ClientLayer * |
|
268 ToClientLayer(Layer* aLayer) |
|
269 { |
|
270 return static_cast<ClientLayer*>(aLayer->ImplData()); |
|
271 } |
|
272 }; |
|
273 |
|
274 // Create a shadow layer (PLayerChild) for aLayer, if we're forwarding |
|
275 // our layer tree to a parent process. Record the new layer creation |
|
276 // in the current open transaction as a side effect. |
|
277 template<typename CreatedMethod> void |
|
278 CreateShadowFor(ClientLayer* aLayer, |
|
279 ClientLayerManager* aMgr, |
|
280 CreatedMethod aMethod) |
|
281 { |
|
282 PLayerChild* shadow = aMgr->AsShadowForwarder()->ConstructShadowFor(aLayer); |
|
283 // XXX error handling |
|
284 NS_ABORT_IF_FALSE(shadow, "failed to create shadow"); |
|
285 |
|
286 aLayer->SetShadow(shadow); |
|
287 (aMgr->AsShadowForwarder()->*aMethod)(aLayer); |
|
288 aMgr->Hold(aLayer->AsLayer()); |
|
289 } |
|
290 |
|
291 #define CREATE_SHADOW(_type) \ |
|
292 CreateShadowFor(layer, this, \ |
|
293 &ShadowLayerForwarder::Created ## _type ## Layer) |
|
294 |
|
295 |
|
296 } |
|
297 } |
|
298 |
|
299 #endif /* GFX_CLIENTLAYERMANAGER_H */ |