Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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/. */
6 #ifndef GFX_CLIENTLAYERMANAGER_H
7 #define GFX_CLIENTLAYERMANAGER_H
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
27 class nsIWidget;
29 namespace mozilla {
30 namespace layers {
32 class ClientThebesLayer;
33 class CompositorChild;
34 class ImageLayer;
35 class PLayerChild;
36 class TextureClientPool;
37 class SimpleTextureClientPool;
39 class ClientLayerManager : public LayerManager
40 {
41 typedef nsTArray<nsRefPtr<Layer> > LayerRefArray;
43 public:
44 ClientLayerManager(nsIWidget* aWidget);
45 virtual ~ClientLayerManager();
47 virtual ShadowLayerForwarder* AsShadowForwarder()
48 {
49 return mForwarder;
50 }
52 virtual int32_t GetMaxTextureSize() const;
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);
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"; }
70 virtual void SetRoot(Layer* aLayer);
72 virtual void Mutated(Layer* aLayer);
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();
82 TextureFactoryIdentifier GetTextureFactoryIdentifier()
83 {
84 return mForwarder->GetTextureFactoryIdentifier();
85 }
87 virtual void FlushRendering() MOZ_OVERRIDE;
88 void SendInvalidRegion(const nsIntRegion& aRegion);
90 virtual uint32_t StartFrameTimeRecording(int32_t aBufferSize) MOZ_OVERRIDE;
92 virtual void StopFrameTimeRecording(uint32_t aStartIndex,
93 nsTArray<float>& aFrameIntervals) MOZ_OVERRIDE;
95 virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return false; }
97 ShadowableLayer* Hold(Layer* aLayer);
99 bool HasShadowManager() const { return mForwarder->HasShadowManager(); }
101 virtual bool IsCompositingCheap();
102 virtual bool HasShadowManagerInternal() const { return HasShadowManager(); }
104 virtual void SetIsFirstPaint() MOZ_OVERRIDE;
106 TextureClientPool *GetTexturePool(gfx::SurfaceFormat aFormat);
107 SimpleTextureClientPool *GetSimpleTileTexturePool(gfx::SurfaceFormat aFormat);
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;
113 void SetRepeatTransaction() { mRepeatTransaction = true; }
114 bool GetRepeatTransaction() { return mRepeatTransaction; }
116 bool IsRepeatTransaction() { return mIsRepeatTransaction; }
118 void SetTransactionIncomplete() { mTransactionIncomplete = true; }
120 bool HasShadowTarget() { return !!mShadowTarget; }
122 void SetShadowTarget(gfxContext *aTarget) { mShadowTarget = aTarget; }
124 bool CompositorMightResample() { return mCompositorMightResample; }
126 DrawThebesLayerCallback GetThebesLayerCallback() const
127 { return mThebesLayerCallback; }
129 void* GetThebesLayerCallbackData() const
130 { return mThebesLayerCallbackData; }
132 CompositorChild *GetRemoteRenderer();
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);
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; }
158 void SetNeedsComposite(bool aNeedsComposite)
159 {
160 mNeedsComposite = aNeedsComposite;
161 }
162 bool NeedsComposite() const { return mNeedsComposite; }
164 virtual void Composite() MOZ_OVERRIDE;
166 virtual void DidComposite();
168 protected:
169 enum TransactionPhase {
170 PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
171 };
172 TransactionPhase mPhase;
174 private:
175 /**
176 * Forward transaction results to the parent context.
177 */
178 void ForwardTransaction(bool aScheduleComposite);
180 /**
181 * Take a snapshot of the parent context, and copy
182 * it into mShadowTarget.
183 */
184 void MakeSnapshotIfRequired();
186 void ClearLayer(Layer* aLayer);
188 bool EndTransactionInternal(DrawThebesLayerCallback aCallback,
189 void* aCallbackData,
190 EndTransactionFlags);
192 // The bounds of |mTarget| in device pixels.
193 nsIntRect mTargetBounds;
195 LayerRefArray mKeepAlive;
197 nsIWidget* mWidget;
199 /* Thebes layer callbacks; valid at the end of a transaciton,
200 * while rendering */
201 DrawThebesLayerCallback mThebesLayerCallback;
202 void *mThebesLayerCallbackData;
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;
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;
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;
228 RefPtr<ShadowLayerForwarder> mForwarder;
229 nsAutoTArray<RefPtr<TextureClientPool>,2> mTexturePools;
231 // indexed by gfx::SurfaceFormat
232 nsTArray<RefPtr<SimpleTextureClientPool> > mSimpleTilePools;
233 };
235 class ClientLayer : public ShadowableLayer
236 {
237 public:
238 ClientLayer()
239 {
240 MOZ_COUNT_CTOR(ClientLayer);
241 }
243 ~ClientLayer();
245 void SetShadow(PLayerChild* aShadow)
246 {
247 NS_ABORT_IF_FALSE(!mShadow, "can't have two shadows (yet)");
248 mShadow = aShadow;
249 }
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 }
261 virtual void ClearCachedResources() { }
263 virtual void RenderLayer() = 0;
265 virtual ClientThebesLayer* AsThebes() { return nullptr; }
267 static inline ClientLayer *
268 ToClientLayer(Layer* aLayer)
269 {
270 return static_cast<ClientLayer*>(aLayer->ImplData());
271 }
272 };
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");
286 aLayer->SetShadow(shadow);
287 (aMgr->AsShadowForwarder()->*aMethod)(aLayer);
288 aMgr->Hold(aLayer->AsLayer());
289 }
291 #define CREATE_SHADOW(_type) \
292 CreateShadowFor(layer, this, \
293 &ShadowLayerForwarder::Created ## _type ## Layer)
296 }
297 }
299 #endif /* GFX_CLIENTLAYERMANAGER_H */