1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=8 et :
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at:
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is Mozilla Code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * The Mozilla Foundation
21 : * Portions created by the Initial Developer are Copyright (C) 2010
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Chris Jones <jones.chris.g@gmail.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #ifndef mozilla_layers_ShadowLayers_h
42 : #define mozilla_layers_ShadowLayers_h 1
43 :
44 : #include "gfxASurface.h"
45 :
46 : #include "ImageLayers.h"
47 : #include "Layers.h"
48 :
49 : class gfxSharedImageSurface;
50 :
51 : namespace mozilla {
52 : namespace layers {
53 :
54 : class Edit;
55 : class EditReply;
56 : class OptionalThebesBuffer;
57 : class PLayerChild;
58 : class PLayersChild;
59 : class PLayersParent;
60 : class ShadowableLayer;
61 : class ShadowThebesLayer;
62 : class ShadowContainerLayer;
63 : class ShadowImageLayer;
64 : class ShadowColorLayer;
65 : class ShadowCanvasLayer;
66 : class SurfaceDescriptor;
67 : class ThebesBuffer;
68 : class Transaction;
69 : class SharedImage;
70 : class CanvasSurface;
71 :
72 : /**
73 : * We want to share layer trees across thread contexts and address
74 : * spaces for several reasons; chief among them
75 : *
76 : * - a parent process can paint a child process's layer tree while
77 : * the child process is blocked, say on content script. This is
78 : * important on mobile devices where UI responsiveness is key.
79 : *
80 : * - a dedicated "compositor" process can asynchronously (wrt the
81 : * browser process) composite and animate layer trees, allowing a
82 : * form of pipeline parallelism between compositor/browser/content
83 : *
84 : * - a dedicated "compositor" process can take all responsibility for
85 : * accessing the GPU, which is desirable on systems with
86 : * buggy/leaky drivers because the compositor process can die while
87 : * browser and content live on (and failover mechanisms can be
88 : * installed to quickly bring up a replacement compositor)
89 : *
90 : * The Layers model has a crisply defined API, which makes it easy to
91 : * safely "share" layer trees. The ShadowLayers API extends Layers to
92 : * allow a remote, parent process to access a child process's layer
93 : * tree.
94 : *
95 : * ShadowLayerForwarder publishes a child context's layer tree to a
96 : * parent context. This comprises recording layer-tree modifications
97 : * into atomic transactions and pushing them over IPC.
98 : *
99 : * ShadowLayerManager grafts layer subtrees published by child-context
100 : * ShadowLayerForwarder(s) into a parent-context layer tree.
101 : *
102 : * (Advanced note: because our process tree may have a height >2, a
103 : * non-leaf subprocess may both receive updates from child processes
104 : * and publish them to parent processes. Put another way,
105 : * LayerManagers may be both ShadowLayerManagers and
106 : * ShadowLayerForwarders.)
107 : *
108 : * There are only shadow types for layers that have different shadow
109 : * vs. not-shadow behavior. ColorLayers and ContainerLayers behave
110 : * the same way in both regimes (so far).
111 : */
112 :
113 : class ShadowLayerForwarder
114 : {
115 : public:
116 : typedef LayerManager::LayersBackend LayersBackend;
117 :
118 : virtual ~ShadowLayerForwarder();
119 :
120 : /**
121 : * Begin recording a transaction to be forwarded atomically to a
122 : * ShadowLayerManager.
123 : */
124 : void BeginTransaction();
125 :
126 : /**
127 : * The following methods may only be called after BeginTransaction()
128 : * but before EndTransaction(). They mirror the LayerManager
129 : * interface in Layers.h.
130 : */
131 :
132 : /**
133 : * Notify the shadow manager that a new, "real" layer has been
134 : * created, and a corresponding shadow layer should be created in
135 : * the compositing process.
136 : */
137 : void CreatedThebesLayer(ShadowableLayer* aThebes);
138 : void CreatedContainerLayer(ShadowableLayer* aContainer);
139 : void CreatedImageLayer(ShadowableLayer* aImage);
140 : void CreatedColorLayer(ShadowableLayer* aColor);
141 : void CreatedCanvasLayer(ShadowableLayer* aCanvas);
142 :
143 : /**
144 : * The specified layer is destroying its buffers.
145 : * |aBackBufferToDestroy| is deallocated when this transaction is
146 : * posted to the parent. During the parent-side transaction, the
147 : * shadow is told to destroy its front buffer. This can happen when
148 : * a new front/back buffer pair have been created because of a layer
149 : * resize, e.g.
150 : */
151 : void DestroyedThebesBuffer(ShadowableLayer* aThebes,
152 : const SurfaceDescriptor& aBackBufferToDestroy);
153 :
154 : /**
155 : * At least one attribute of |aMutant| has changed, and |aMutant|
156 : * needs to sync to its shadow layer. This initial implementation
157 : * forwards all attributes when any is mutated.
158 : */
159 : void Mutated(ShadowableLayer* aMutant);
160 :
161 : void SetRoot(ShadowableLayer* aRoot);
162 : /**
163 : * Insert |aChild| after |aAfter| in |aContainer|. |aAfter| can be
164 : * NULL to indicated that |aChild| should be appended to the end of
165 : * |aContainer|'s child list.
166 : */
167 : void InsertAfter(ShadowableLayer* aContainer,
168 : ShadowableLayer* aChild,
169 : ShadowableLayer* aAfter=NULL);
170 : void RemoveChild(ShadowableLayer* aContainer,
171 : ShadowableLayer* aChild);
172 :
173 : /**
174 : * Notify the shadow manager that the specified layer's back buffer
175 : * has new pixels and should become the new front buffer, and be
176 : * re-rendered, in the compositing process. The former front buffer
177 : * is swapped for |aNewFrontBuffer| and becomes the new back buffer
178 : * for the "real" layer.
179 : */
180 : /**
181 : * |aBufferRect| is the screen rect covered as a whole by the
182 : * possibly-toroidally-rotated |aNewFrontBuffer|. |aBufferRotation|
183 : * is buffer's rotation, if any.
184 : */
185 : void PaintedThebesBuffer(ShadowableLayer* aThebes,
186 : const nsIntRegion& aUpdatedRegion,
187 : const nsIntRect& aBufferRect,
188 : const nsIntPoint& aBufferRotation,
189 : const SurfaceDescriptor& aNewFrontBuffer);
190 : /**
191 : * NB: this initial implementation only forwards RGBA data for
192 : * ImageLayers. This is slow, and will be optimized.
193 : */
194 : void PaintedImage(ShadowableLayer* aImage,
195 : const SharedImage& aNewFrontImage);
196 : void PaintedCanvas(ShadowableLayer* aCanvas,
197 : bool aNeedYFlip,
198 : const SurfaceDescriptor& aNewFrontSurface);
199 :
200 : /**
201 : * End the current transaction and forward it to ShadowLayerManager.
202 : * |aReplies| are directions from the ShadowLayerManager to the
203 : * caller of EndTransaction().
204 : */
205 : bool EndTransaction(InfallibleTArray<EditReply>* aReplies);
206 :
207 : /**
208 : * Set an actor through which layer updates will be pushed.
209 : */
210 : void SetShadowManager(PLayersChild* aShadowManager)
211 : {
212 : mShadowManager = aShadowManager;
213 : }
214 :
215 : void SetParentBackendType(LayersBackend aBackendType)
216 : {
217 : mParentBackend = aBackendType;
218 : }
219 :
220 : /**
221 : * True if this is forwarding to a ShadowLayerManager.
222 : */
223 0 : bool HasShadowManager() const { return !!mShadowManager; }
224 : PLayersChild* GetShadowManager() const { return mShadowManager; }
225 :
226 : /**
227 : * The following Alloc/Open/Destroy interfaces abstract over the
228 : * details of working with surfaces that are shared across
229 : * processes. They provide the glue between C++ Layers and the
230 : * ShadowLayer IPC system.
231 : *
232 : * The basic lifecycle is
233 : *
234 : * - a Layer needs a buffer. Its ShadowableLayer subclass calls
235 : * AllocDoubleBuffer(), then calls one of the Created*Buffer()
236 : * methods above to transfer the (temporary) front buffer to its
237 : * ShadowLayer in the other process. The Layer needs a
238 : * gfxASurface to paint, so the ShadowableLayer uses
239 : * OpenDescriptor(backBuffer) to get that surface, and hands it
240 : * out to the Layer.
241 : *
242 : * - a Layer has painted new pixels. Its ShadowableLayer calls one
243 : * of the Painted*Buffer() methods above with the back buffer
244 : * descriptor. This notification is forwarded to the ShadowLayer,
245 : * which uses OpenDescriptor() to access the newly-painted pixels.
246 : * The ShadowLayer then updates its front buffer in a Layer- and
247 : * platform-dependent way, and sends a surface descriptor back to
248 : * the ShadowableLayer that becomes its new back back buffer.
249 : *
250 : * - a Layer wants to destroy its buffers. Its ShadowableLayer
251 : * calls Destroyed*Buffer(), which gives up control of the back
252 : * buffer descriptor. The actual back buffer surface is then
253 : * destroyed using DestroySharedSurface() just before notifying
254 : * the parent process. When the parent process is notified, the
255 : * ShadowLayer also calls DestroySharedSurface() on its front
256 : * buffer, and the double-buffer pair is gone.
257 : */
258 :
259 : /**
260 : * Shmem (gfxSharedImageSurface) buffers are available on all
261 : * platforms, but they may not be optimal.
262 : *
263 : * NB: this interface is being deprecated in favor of the
264 : * SurfaceDescriptor variant below.
265 : */
266 : bool AllocDoubleBuffer(const gfxIntSize& aSize,
267 : gfxASurface::gfxContentType aContent,
268 : gfxSharedImageSurface** aFrontBuffer,
269 : gfxSharedImageSurface** aBackBuffer);
270 : void DestroySharedSurface(gfxSharedImageSurface* aSurface);
271 :
272 : bool AllocBuffer(const gfxIntSize& aSize,
273 : gfxASurface::gfxContentType aContent,
274 : gfxSharedImageSurface** aBuffer);
275 :
276 : /**
277 : * In the absence of platform-specific buffers these fall back to
278 : * Shmem/gfxSharedImageSurface.
279 : */
280 : bool AllocDoubleBuffer(const gfxIntSize& aSize,
281 : gfxASurface::gfxContentType aContent,
282 : SurfaceDescriptor* aFrontBuffer,
283 : SurfaceDescriptor* aBackBuffer);
284 :
285 : bool AllocBuffer(const gfxIntSize& aSize,
286 : gfxASurface::gfxContentType aContent,
287 : SurfaceDescriptor* aBuffer);
288 :
289 : static already_AddRefed<gfxASurface>
290 : OpenDescriptor(const SurfaceDescriptor& aSurface);
291 :
292 : void DestroySharedSurface(SurfaceDescriptor* aSurface);
293 :
294 : /**
295 : * Construct a shadow of |aLayer| on the "other side", at the
296 : * ShadowLayerManager.
297 : */
298 : PLayerChild* ConstructShadowFor(ShadowableLayer* aLayer);
299 :
300 : LayersBackend GetParentBackendType()
301 : {
302 : return mParentBackend;
303 : }
304 :
305 : /*
306 : * No need to use double buffer in system memory with GPU rendering,
307 : * texture used as front buffer.
308 : */
309 : bool ShouldDoubleBuffer() { return GetParentBackendType() == LayerManager::LAYERS_BASIC; }
310 :
311 : protected:
312 : ShadowLayerForwarder();
313 :
314 : PLayersChild* mShadowManager;
315 :
316 : private:
317 : bool PlatformAllocDoubleBuffer(const gfxIntSize& aSize,
318 : gfxASurface::gfxContentType aContent,
319 : SurfaceDescriptor* aFrontBuffer,
320 : SurfaceDescriptor* aBackBuffer);
321 :
322 : bool PlatformAllocBuffer(const gfxIntSize& aSize,
323 : gfxASurface::gfxContentType aContent,
324 : SurfaceDescriptor* aBuffer);
325 :
326 : static already_AddRefed<gfxASurface>
327 : PlatformOpenDescriptor(const SurfaceDescriptor& aDescriptor);
328 :
329 : bool PlatformDestroySharedSurface(SurfaceDescriptor* aSurface);
330 :
331 : static void PlatformSyncBeforeUpdate();
332 :
333 : Transaction* mTxn;
334 : LayersBackend mParentBackend;
335 : };
336 :
337 :
338 : class ShadowLayerManager : public LayerManager
339 : {
340 : public:
341 : virtual ~ShadowLayerManager() {}
342 :
343 : virtual void GetBackendName(nsAString& name) { name.AssignLiteral("Shadow"); }
344 :
345 : void DestroySharedSurface(gfxSharedImageSurface* aSurface,
346 : PLayersParent* aDeallocator);
347 :
348 : void DestroySharedSurface(SurfaceDescriptor* aSurface,
349 : PLayersParent* aDeallocator);
350 :
351 : /** CONSTRUCTION PHASE ONLY */
352 : virtual already_AddRefed<ShadowThebesLayer> CreateShadowThebesLayer() = 0;
353 : /** CONSTRUCTION PHASE ONLY */
354 : virtual already_AddRefed<ShadowContainerLayer> CreateShadowContainerLayer() = 0;
355 : /** CONSTRUCTION PHASE ONLY */
356 : virtual already_AddRefed<ShadowImageLayer> CreateShadowImageLayer() = 0;
357 : /** CONSTRUCTION PHASE ONLY */
358 : virtual already_AddRefed<ShadowColorLayer> CreateShadowColorLayer() = 0;
359 : /** CONSTRUCTION PHASE ONLY */
360 : virtual already_AddRefed<ShadowCanvasLayer> CreateShadowCanvasLayer() = 0;
361 :
362 : static void PlatformSyncBeforeReplyUpdate();
363 :
364 : protected:
365 : ShadowLayerManager() {}
366 :
367 : bool PlatformDestroySharedSurface(SurfaceDescriptor* aSurface);
368 : };
369 :
370 :
371 : /**
372 : * A ShadowableLayer is a Layer can be shared with a parent context
373 : * through a ShadowLayerForwarder. A ShadowableLayer maps to a
374 : * Shadow*Layer in a parent context.
375 : *
376 : * Note that ShadowLayers can themselves be ShadowableLayers.
377 : */
378 : class ShadowableLayer
379 : {
380 : public:
381 : virtual ~ShadowableLayer() {}
382 :
383 : virtual Layer* AsLayer() = 0;
384 :
385 : /**
386 : * True if this layer has a shadow in a parent process.
387 : */
388 : bool HasShadow() { return !!mShadow; }
389 :
390 : /**
391 : * Return the IPC handle to a Shadow*Layer referring to this if one
392 : * exists, NULL if not.
393 : */
394 0 : PLayerChild* GetShadow() { return mShadow; }
395 :
396 : protected:
397 : ShadowableLayer() : mShadow(NULL) {}
398 :
399 : PLayerChild* mShadow;
400 : };
401 :
402 : /**
403 : * SurfaceDeallocator interface
404 : */
405 : class ISurfaceDeAllocator
406 0 : {
407 : public:
408 : virtual void DestroySharedSurface(gfxSharedImageSurface* aSurface) = 0;
409 : virtual void DestroySharedSurface(SurfaceDescriptor* aSurface) = 0;
410 : protected:
411 0 : ~ISurfaceDeAllocator() {};
412 : };
413 :
414 : /**
415 : * A ShadowLayer is the representation of a child-context's Layer in a
416 : * parent context. They can be transformed, clipped,
417 : * etc. independently of their origin Layers.
418 : *
419 : * Note that ShadowLayers can themselves have a shadow in a parent
420 : * context.
421 : */
422 : class ShadowLayer
423 : {
424 : public:
425 : virtual ~ShadowLayer() {}
426 :
427 : /**
428 : * Set deallocator for data recieved from IPC protocol
429 : * We should be able to set allocator right before swap call
430 : * that is why allowed multiple call with the same Allocator
431 : */
432 : virtual void SetAllocator(ISurfaceDeAllocator* aAllocator)
433 : {
434 : NS_ASSERTION(!mAllocator || mAllocator == aAllocator, "Stomping allocator?");
435 : mAllocator = aAllocator;
436 : }
437 :
438 : virtual void DestroyFrontBuffer() { };
439 :
440 : /**
441 : * The following methods are
442 : *
443 : * CONSTRUCTION PHASE ONLY
444 : *
445 : * They are analogous to the Layer interface.
446 : */
447 0 : void SetShadowVisibleRegion(const nsIntRegion& aRegion)
448 : {
449 0 : mShadowVisibleRegion = aRegion;
450 0 : }
451 :
452 0 : void SetShadowClipRect(const nsIntRect* aRect)
453 : {
454 0 : mUseShadowClipRect = aRect != nsnull;
455 0 : if (aRect) {
456 0 : mShadowClipRect = *aRect;
457 : }
458 0 : }
459 :
460 0 : void SetShadowTransform(const gfx3DMatrix& aMatrix)
461 : {
462 0 : mShadowTransform = aMatrix;
463 0 : }
464 :
465 : // These getters can be used anytime.
466 : const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nsnull; }
467 : const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
468 : const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; }
469 :
470 : protected:
471 : ShadowLayer()
472 : : mAllocator(nsnull)
473 : , mUseShadowClipRect(false)
474 : {}
475 :
476 : ISurfaceDeAllocator* mAllocator;
477 : nsIntRegion mShadowVisibleRegion;
478 : gfx3DMatrix mShadowTransform;
479 : nsIntRect mShadowClipRect;
480 : bool mUseShadowClipRect;
481 : };
482 :
483 :
484 : class ShadowThebesLayer : public ShadowLayer,
485 : public ThebesLayer
486 : {
487 : public:
488 : virtual void InvalidateRegion(const nsIntRegion& aRegion)
489 : {
490 : NS_RUNTIMEABORT("ShadowThebesLayers can't fill invalidated regions");
491 : }
492 :
493 : /**
494 : * CONSTRUCTION PHASE ONLY
495 : */
496 : virtual void SetValidRegion(const nsIntRegion& aRegion)
497 : {
498 : mValidRegion = aRegion;
499 : Mutated();
500 : }
501 :
502 : /**
503 : * CONSTRUCTION PHASE ONLY
504 : *
505 : * Publish the remote layer's back ThebesLayerBuffer to this shadow,
506 : * swapping out the old front ThebesLayerBuffer (the new back buffer
507 : * for the remote layer).
508 : */
509 : virtual void
510 : Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
511 : OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
512 : OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion) = 0;
513 :
514 : /**
515 : * CONSTRUCTION PHASE ONLY
516 : *
517 : * Destroy the current front buffer.
518 : */
519 : virtual void DestroyFrontBuffer() = 0;
520 :
521 : virtual ShadowLayer* AsShadowLayer() { return this; }
522 :
523 : MOZ_LAYER_DECL_NAME("ShadowThebesLayer", TYPE_SHADOW)
524 :
525 : protected:
526 : ShadowThebesLayer(LayerManager* aManager, void* aImplData)
527 : : ThebesLayer(aManager, aImplData)
528 : {}
529 : };
530 :
531 :
532 : class ShadowContainerLayer : public ShadowLayer,
533 : public ContainerLayer
534 : {
535 : public:
536 : virtual ShadowLayer* AsShadowLayer() { return this; }
537 :
538 : MOZ_LAYER_DECL_NAME("ShadowContainerLayer", TYPE_SHADOW)
539 :
540 : protected:
541 : ShadowContainerLayer(LayerManager* aManager, void* aImplData)
542 : : ContainerLayer(aManager, aImplData)
543 : {}
544 : };
545 :
546 :
547 : class ShadowCanvasLayer : public ShadowLayer,
548 : public CanvasLayer
549 : {
550 : public:
551 : /**
552 : * CONSTRUCTION PHASE ONLY
553 : *
554 : * Publish the remote layer's back surface to this shadow, swapping
555 : * out the old front surface (the new back surface for the remote
556 : * layer).
557 : */
558 : virtual void Swap(const CanvasSurface& aNewFront, bool needYFlip,
559 : CanvasSurface* aNewBack) = 0;
560 :
561 : virtual ShadowLayer* AsShadowLayer() { return this; }
562 :
563 : MOZ_LAYER_DECL_NAME("ShadowCanvasLayer", TYPE_SHADOW)
564 :
565 : protected:
566 : ShadowCanvasLayer(LayerManager* aManager, void* aImplData)
567 : : CanvasLayer(aManager, aImplData)
568 : {}
569 : };
570 :
571 :
572 : class ShadowImageLayer : public ShadowLayer,
573 : public ImageLayer
574 : {
575 : public:
576 : /**
577 : * CONSTRUCTION PHASE ONLY
578 : * @see ShadowCanvasLayer::Swap
579 : */
580 : virtual void Swap(const SharedImage& aFront,
581 : SharedImage* aNewBack) = 0;
582 :
583 : virtual ShadowLayer* AsShadowLayer() { return this; }
584 :
585 : MOZ_LAYER_DECL_NAME("ShadowImageLayer", TYPE_SHADOW)
586 :
587 : protected:
588 : ShadowImageLayer(LayerManager* aManager, void* aImplData)
589 : : ImageLayer(aManager, aImplData)
590 : {}
591 : };
592 :
593 :
594 : class ShadowColorLayer : public ShadowLayer,
595 : public ColorLayer
596 : {
597 : public:
598 : virtual ShadowLayer* AsShadowLayer() { return this; }
599 :
600 : MOZ_LAYER_DECL_NAME("ShadowColorLayer", TYPE_SHADOW)
601 :
602 : protected:
603 : ShadowColorLayer(LayerManager* aManager, void* aImplData)
604 : : ColorLayer(aManager, aImplData)
605 : {}
606 : };
607 :
608 : bool IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface);
609 :
610 : } // namespace layers
611 : } // namespace mozilla
612 :
613 : #endif // ifndef mozilla_layers_ShadowLayers_h
|