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 #include "ShadowLayers.h"
8 
9 #include <set>     // for _Rb_tree_const_iterator, etc
10 #include <vector>  // for vector
11 
12 #include "ClientLayerManager.h"  // for ClientLayerManager
13 #include "IPDLActor.h"
14 #include "ISurfaceAllocator.h"    // for IsSurfaceDescriptorValid
15 #include "Layers.h"               // for Layer
16 #include "RenderTrace.h"          // for RenderTraceScope
17 #include "gfx2DGlue.h"            // for Moz2D transition helpers
18 #include "gfxPlatform.h"          // for gfxImageFormat, gfxPlatform
19 #include "ipc/IPCMessageUtils.h"  // for gfxContentType, null_t
20 #include "mozilla/Assertions.h"   // for MOZ_ASSERT, etc
21 #include "mozilla/gfx/Point.h"    // for IntSize
22 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient, etc
23 #include "mozilla/layers/CompositorBridgeChild.h"
24 #include "mozilla/layers/ContentClient.h"
25 #include "mozilla/layers/ImageBridgeChild.h"
26 #include "mozilla/layers/ImageDataSerializer.h"
27 #include "mozilla/layers/LayerTransactionChild.h"
28 #include "mozilla/layers/LayersMessages.h"  // for Edit, etc
29 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
30 #include "mozilla/layers/LayersTypes.h"     // for MOZ_LAYERS_LOG
31 #include "mozilla/layers/PTextureChild.h"
32 #include "mozilla/layers/SyncObject.h"
33 #ifdef XP_DARWIN
34 #  include "mozilla/layers/TextureSync.h"
35 #endif
36 #include "ShadowLayerUtils.h"
37 #include "mozilla/ProfilerLabels.h"
38 #include "mozilla/ReentrantMonitor.h"
39 #include "mozilla/StaticPrefs_layers.h"
40 #include "mozilla/layers/TextureClient.h"  // for TextureClient
41 #include "mozilla/mozalloc.h"              // for operator new, etc
42 #include "nsIXULRuntime.h"                 // for BrowserTabsRemoteAutostart
43 #include "nsTArray.h"                      // for AutoTArray, nsTArray, etc
44 #include "nsTHashSet.h"
45 #include "nsXULAppAPI.h"  // for XRE_GetProcessType, etc
46 
47 namespace mozilla {
48 namespace ipc {
49 class Shmem;
50 }  // namespace ipc
51 
52 namespace layers {
53 
54 using namespace mozilla::gfx;
55 using namespace mozilla::gl;
56 using namespace mozilla::ipc;
57 
58 class ClientTiledLayerBuffer;
59 
60 typedef nsTArray<SurfaceDescriptor> BufferArray;
61 typedef nsTArray<Edit> EditVector;
62 typedef nsTHashSet<ShadowableLayer*> ShadowableLayerSet;
63 typedef nsTArray<OpDestroy> OpDestroyVector;
64 
65 class Transaction {
66  public:
Transaction()67   Transaction()
68       : mTargetRotation(ROTATION_0),
69         mTargetOrientation(hal::eScreenOrientation_None),
70         mOpen(false),
71         mRotationChanged(false) {}
72 
Begin(const gfx::IntRect & aTargetBounds,ScreenRotation aRotation,hal::ScreenOrientation aOrientation)73   void Begin(const gfx::IntRect& aTargetBounds, ScreenRotation aRotation,
74              hal::ScreenOrientation aOrientation) {
75     mOpen = true;
76     mTargetBounds = aTargetBounds;
77     if (aRotation != mTargetRotation) {
78       // the first time this is called, mRotationChanged will be false if
79       // aRotation is 0, but we should be OK because for the first transaction
80       // we should only compose if it is non-empty. See the caller(s) of
81       // RotationChanged.
82       mRotationChanged = true;
83     }
84     mTargetRotation = aRotation;
85     mTargetOrientation = aOrientation;
86   }
AddEdit(const Edit & aEdit)87   void AddEdit(const Edit& aEdit) {
88     MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
89     mCset.AppendElement(aEdit);
90   }
AddEdit(const CompositableOperation & aEdit)91   void AddEdit(const CompositableOperation& aEdit) { AddEdit(Edit(aEdit)); }
92 
AddNoSwapPaint(const CompositableOperation & aPaint)93   void AddNoSwapPaint(const CompositableOperation& aPaint) {
94     MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
95     mPaints.AppendElement(Edit(aPaint));
96   }
AddMutant(ShadowableLayer * aLayer)97   void AddMutant(ShadowableLayer* aLayer) {
98     MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
99     mMutants.Insert(aLayer);
100   }
AddSimpleMutant(ShadowableLayer * aLayer)101   void AddSimpleMutant(ShadowableLayer* aLayer) {
102     MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
103     mSimpleMutants.Insert(aLayer);
104   }
End()105   void End() {
106     mCset.Clear();
107     mPaints.Clear();
108     mMutants.Clear();
109     mSimpleMutants.Clear();
110     mDestroyedActors.Clear();
111     mOpen = false;
112     mRotationChanged = false;
113   }
114 
Empty() const115   bool Empty() const {
116     return mCset.IsEmpty() && mPaints.IsEmpty() && mMutants.IsEmpty() &&
117            mSimpleMutants.IsEmpty() && mDestroyedActors.IsEmpty();
118   }
RotationChanged() const119   bool RotationChanged() const { return mRotationChanged; }
Finished() const120   bool Finished() const { return !mOpen && Empty(); }
121 
Opened() const122   bool Opened() const { return mOpen; }
123 
124   EditVector mCset;
125   nsTArray<CompositableOperation> mPaints;
126   OpDestroyVector mDestroyedActors;
127   ShadowableLayerSet mMutants;
128   ShadowableLayerSet mSimpleMutants;
129   gfx::IntRect mTargetBounds;
130   ScreenRotation mTargetRotation;
131   hal::ScreenOrientation mTargetOrientation;
132 
133  private:
134   bool mOpen;
135   bool mRotationChanged;
136 
137   // disabled
138   Transaction(const Transaction&);
139   Transaction& operator=(const Transaction&);
140 };
141 struct AutoTxnEnd final {
AutoTxnEndmozilla::layers::AutoTxnEnd142   explicit AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {}
~AutoTxnEndmozilla::layers::AutoTxnEnd143   ~AutoTxnEnd() { mTxn->End(); }
144   Transaction* mTxn;
145 };
146 
IdentifyTextureHost(const TextureFactoryIdentifier & aIdentifier)147 void KnowsCompositor::IdentifyTextureHost(
148     const TextureFactoryIdentifier& aIdentifier) {
149   auto lock = mData.Lock();
150   lock.ref().mTextureFactoryIdentifier = aIdentifier;
151 
152   lock.ref().mSyncObject =
153       SyncObjectClient::CreateSyncObjectClientForContentDevice(
154           aIdentifier.mSyncHandle);
155 }
156 
KnowsCompositor()157 KnowsCompositor::KnowsCompositor()
158     : mData("KnowsCompositorMutex"), mSerial(++sSerialCounter) {}
159 
160 KnowsCompositor::~KnowsCompositor() = default;
161 
KnowsCompositorMediaProxy(const TextureFactoryIdentifier & aIdentifier)162 KnowsCompositorMediaProxy::KnowsCompositorMediaProxy(
163     const TextureFactoryIdentifier& aIdentifier) {
164   auto lock = mData.Lock();
165   lock.ref().mTextureFactoryIdentifier = aIdentifier;
166   // overwrite mSerial's value set by the parent class because we use the same
167   // serial as the KnowsCompositor we are proxying.
168   mThreadSafeAllocator = ImageBridgeChild::GetSingleton();
169   lock.ref().mSyncObject = mThreadSafeAllocator->GetSyncObject();
170 }
171 
172 KnowsCompositorMediaProxy::~KnowsCompositorMediaProxy() = default;
173 
GetTextureForwarder()174 TextureForwarder* KnowsCompositorMediaProxy::GetTextureForwarder() {
175   return mThreadSafeAllocator->GetTextureForwarder();
176 }
177 
GetLayersIPCActor()178 LayersIPCActor* KnowsCompositorMediaProxy::GetLayersIPCActor() {
179   return mThreadSafeAllocator->GetLayersIPCActor();
180 }
181 
GetActiveResourceTracker()182 ActiveResourceTracker* KnowsCompositorMediaProxy::GetActiveResourceTracker() {
183   return mThreadSafeAllocator->GetActiveResourceTracker();
184 }
185 
SyncWithCompositor()186 void KnowsCompositorMediaProxy::SyncWithCompositor() {
187   mThreadSafeAllocator->SyncWithCompositor();
188 }
189 
GetForMedia()190 RefPtr<KnowsCompositor> ShadowLayerForwarder::GetForMedia() {
191   return MakeAndAddRef<KnowsCompositorMediaProxy>(
192       GetTextureFactoryIdentifier());
193 }
194 
ShadowLayerForwarder(ClientLayerManager * aClientLayerManager)195 ShadowLayerForwarder::ShadowLayerForwarder(
196     ClientLayerManager* aClientLayerManager)
197     : mClientLayerManager(aClientLayerManager),
198       mThread(NS_GetCurrentThread()),
199       mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC),
200       mIsFirstPaint(false),
201       mNextLayerHandle(1) {
202   mTxn = new Transaction();
203   mEventTarget = GetMainThreadSerialEventTarget();
204 
205   MOZ_ASSERT(mEventTarget || !XRE_IsContentProcess());
206   mActiveResourceTracker = MakeUnique<ActiveResourceTracker>(
207       1000, "CompositableForwarder", mEventTarget);
208 }
209 
210 template <typename T>
211 struct ReleaseOnMainThreadTask : public Runnable {
212   UniquePtr<T> mObj;
213 
ReleaseOnMainThreadTaskmozilla::layers::ReleaseOnMainThreadTask214   explicit ReleaseOnMainThreadTask(UniquePtr<T>& aObj)
215       : Runnable("layers::ReleaseOnMainThreadTask"), mObj(std::move(aObj)) {}
216 
Runmozilla::layers::ReleaseOnMainThreadTask217   NS_IMETHOD Run() override {
218     mObj = nullptr;
219     return NS_OK;
220   }
221 };
222 
~ShadowLayerForwarder()223 ShadowLayerForwarder::~ShadowLayerForwarder() {
224   MOZ_ASSERT(mTxn->Finished(), "unfinished transaction?");
225   delete mTxn;
226   if (mShadowManager) {
227     mShadowManager->SetForwarder(nullptr);
228     if (NS_IsMainThread()) {
229       mShadowManager->Destroy();
230     } else {
231       if (mEventTarget) {
232         mEventTarget->Dispatch(
233             NewRunnableMethod("LayerTransactionChild::Destroy", mShadowManager,
234                               &LayerTransactionChild::Destroy),
235             nsIEventTarget::DISPATCH_NORMAL);
236       } else {
237         NS_DispatchToMainThread(
238             NewRunnableMethod("layers::LayerTransactionChild::Destroy",
239                               mShadowManager, &LayerTransactionChild::Destroy));
240       }
241     }
242   }
243 
244   if (!NS_IsMainThread()) {
245     RefPtr<ReleaseOnMainThreadTask<ActiveResourceTracker>> event =
246         new ReleaseOnMainThreadTask<ActiveResourceTracker>(
247             mActiveResourceTracker);
248     if (mEventTarget) {
249       mEventTarget->Dispatch(event.forget(), nsIEventTarget::DISPATCH_NORMAL);
250     } else {
251       NS_DispatchToMainThread(event);
252     }
253   }
254 }
255 
BeginTransaction(const gfx::IntRect & aTargetBounds,ScreenRotation aRotation,hal::ScreenOrientation aOrientation)256 void ShadowLayerForwarder::BeginTransaction(
257     const gfx::IntRect& aTargetBounds, ScreenRotation aRotation,
258     hal::ScreenOrientation aOrientation) {
259   MOZ_ASSERT(IPCOpen(), "no manager to forward to");
260   MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
261   UpdateFwdTransactionId();
262   mTxn->Begin(aTargetBounds, aRotation, aOrientation);
263 }
264 
Shadow(ShadowableLayer * aLayer)265 static const LayerHandle& Shadow(ShadowableLayer* aLayer) {
266   return aLayer->GetShadow();
267 }
268 
269 template <typename OpCreateT>
CreatedLayer(Transaction * aTxn,ShadowableLayer * aLayer)270 static void CreatedLayer(Transaction* aTxn, ShadowableLayer* aLayer) {
271   aTxn->AddEdit(OpCreateT(Shadow(aLayer)));
272 }
273 
CreatedPaintedLayer(ShadowableLayer * aThebes)274 void ShadowLayerForwarder::CreatedPaintedLayer(ShadowableLayer* aThebes) {
275   CreatedLayer<OpCreatePaintedLayer>(mTxn, aThebes);
276 }
CreatedContainerLayer(ShadowableLayer * aContainer)277 void ShadowLayerForwarder::CreatedContainerLayer(ShadowableLayer* aContainer) {
278   CreatedLayer<OpCreateContainerLayer>(mTxn, aContainer);
279 }
CreatedImageLayer(ShadowableLayer * aImage)280 void ShadowLayerForwarder::CreatedImageLayer(ShadowableLayer* aImage) {
281   CreatedLayer<OpCreateImageLayer>(mTxn, aImage);
282 }
CreatedColorLayer(ShadowableLayer * aColor)283 void ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer* aColor) {
284   CreatedLayer<OpCreateColorLayer>(mTxn, aColor);
285 }
CreatedCanvasLayer(ShadowableLayer * aCanvas)286 void ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer* aCanvas) {
287   CreatedLayer<OpCreateCanvasLayer>(mTxn, aCanvas);
288 }
CreatedRefLayer(ShadowableLayer * aRef)289 void ShadowLayerForwarder::CreatedRefLayer(ShadowableLayer* aRef) {
290   CreatedLayer<OpCreateRefLayer>(mTxn, aRef);
291 }
292 
Mutated(ShadowableLayer * aMutant)293 void ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant) {
294   mTxn->AddMutant(aMutant);
295 }
296 
MutatedSimple(ShadowableLayer * aMutant)297 void ShadowLayerForwarder::MutatedSimple(ShadowableLayer* aMutant) {
298   mTxn->AddSimpleMutant(aMutant);
299 }
300 
SetRoot(ShadowableLayer * aRoot)301 void ShadowLayerForwarder::SetRoot(ShadowableLayer* aRoot) {
302   mTxn->AddEdit(OpSetRoot(Shadow(aRoot)));
303 }
InsertAfter(ShadowableLayer * aContainer,ShadowableLayer * aChild,ShadowableLayer * aAfter)304 void ShadowLayerForwarder::InsertAfter(ShadowableLayer* aContainer,
305                                        ShadowableLayer* aChild,
306                                        ShadowableLayer* aAfter) {
307   if (!aChild->HasShadow()) {
308     return;
309   }
310 
311   while (aAfter && !aAfter->HasShadow()) {
312     aAfter = aAfter->AsLayer()->GetPrevSibling()
313                  ? aAfter->AsLayer()->GetPrevSibling()->AsShadowableLayer()
314                  : nullptr;
315   }
316 
317   if (aAfter) {
318     mTxn->AddEdit(
319         OpInsertAfter(Shadow(aContainer), Shadow(aChild), Shadow(aAfter)));
320   } else {
321     mTxn->AddEdit(OpPrependChild(Shadow(aContainer), Shadow(aChild)));
322   }
323 }
RemoveChild(ShadowableLayer * aContainer,ShadowableLayer * aChild)324 void ShadowLayerForwarder::RemoveChild(ShadowableLayer* aContainer,
325                                        ShadowableLayer* aChild) {
326   MOZ_LAYERS_LOG(("[LayersForwarder] OpRemoveChild container=%p child=%p\n",
327                   aContainer->AsLayer(), aChild->AsLayer()));
328 
329   if (!aChild->HasShadow()) {
330     return;
331   }
332 
333   mTxn->AddEdit(OpRemoveChild(Shadow(aContainer), Shadow(aChild)));
334 }
RepositionChild(ShadowableLayer * aContainer,ShadowableLayer * aChild,ShadowableLayer * aAfter)335 void ShadowLayerForwarder::RepositionChild(ShadowableLayer* aContainer,
336                                            ShadowableLayer* aChild,
337                                            ShadowableLayer* aAfter) {
338   if (!aChild->HasShadow()) {
339     return;
340   }
341 
342   while (aAfter && !aAfter->HasShadow()) {
343     aAfter = aAfter->AsLayer()->GetPrevSibling()
344                  ? aAfter->AsLayer()->GetPrevSibling()->AsShadowableLayer()
345                  : nullptr;
346   }
347 
348   if (aAfter) {
349     MOZ_LAYERS_LOG(
350         ("[LayersForwarder] OpRepositionChild container=%p child=%p after=%p",
351          aContainer->AsLayer(), aChild->AsLayer(), aAfter->AsLayer()));
352     mTxn->AddEdit(
353         OpRepositionChild(Shadow(aContainer), Shadow(aChild), Shadow(aAfter)));
354   } else {
355     MOZ_LAYERS_LOG(("[LayersForwarder] OpRaiseToTopChild container=%p child=%p",
356                     aContainer->AsLayer(), aChild->AsLayer()));
357     mTxn->AddEdit(OpRaiseToTopChild(Shadow(aContainer), Shadow(aChild)));
358   }
359 }
360 
361 #ifdef DEBUG
CheckSurfaceDescriptor(const SurfaceDescriptor * aDescriptor) const362 void ShadowLayerForwarder::CheckSurfaceDescriptor(
363     const SurfaceDescriptor* aDescriptor) const {
364   if (!aDescriptor) {
365     return;
366   }
367 
368   if (aDescriptor->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer &&
369       aDescriptor->get_SurfaceDescriptorBuffer().data().type() ==
370           MemoryOrShmem::TShmem) {
371     const Shmem& shmem =
372         aDescriptor->get_SurfaceDescriptorBuffer().data().get_Shmem();
373     shmem.AssertInvariants();
374     MOZ_ASSERT(mShadowManager &&
375                mShadowManager->IsTrackingSharedMemory(shmem.mSegment));
376   }
377 }
378 #endif
379 
UseTiledLayerBuffer(CompositableClient * aCompositable,const SurfaceDescriptorTiles & aTileLayerDescriptor)380 void ShadowLayerForwarder::UseTiledLayerBuffer(
381     CompositableClient* aCompositable,
382     const SurfaceDescriptorTiles& aTileLayerDescriptor) {
383   MOZ_ASSERT(aCompositable);
384 
385   if (!aCompositable->IsConnected()) {
386     return;
387   }
388 
389   mTxn->AddNoSwapPaint(
390       CompositableOperation(aCompositable->GetIPCHandle(),
391                             OpUseTiledLayerBuffer(aTileLayerDescriptor)));
392 }
393 
UpdateTextureRegion(CompositableClient * aCompositable,const ThebesBufferData & aThebesBufferData,const nsIntRegion & aUpdatedRegion)394 void ShadowLayerForwarder::UpdateTextureRegion(
395     CompositableClient* aCompositable,
396     const ThebesBufferData& aThebesBufferData,
397     const nsIntRegion& aUpdatedRegion) {
398   MOZ_ASSERT(aCompositable);
399 
400   if (!aCompositable->IsConnected()) {
401     return;
402   }
403 
404   mTxn->AddNoSwapPaint(CompositableOperation(
405       aCompositable->GetIPCHandle(),
406       OpPaintTextureRegion(aThebesBufferData, aUpdatedRegion)));
407 }
408 
UseTextures(CompositableClient * aCompositable,const nsTArray<TimedTextureClient> & aTextures)409 void ShadowLayerForwarder::UseTextures(
410     CompositableClient* aCompositable,
411     const nsTArray<TimedTextureClient>& aTextures) {
412   MOZ_ASSERT(aCompositable);
413 
414   if (!aCompositable->IsConnected()) {
415     return;
416   }
417 
418   AutoTArray<TimedTexture, 4> textures;
419 
420   for (auto& t : aTextures) {
421     MOZ_ASSERT(t.mTextureClient);
422     MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
423     MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() ==
424                        mShadowManager->GetIPCChannel());
425     bool readLocked = t.mTextureClient->OnForwardedToHost();
426     textures.AppendElement(
427         TimedTexture(nullptr, t.mTextureClient->GetIPDLActor(), t.mTimeStamp,
428                      t.mPictureRect, t.mFrameID, t.mProducerID, readLocked));
429     mClientLayerManager->GetCompositorBridgeChild()
430         ->HoldUntilCompositableRefReleasedIfNecessary(t.mTextureClient);
431 
432     auto fenceFd = t.mTextureClient->GetInternalData()->GetAcquireFence();
433     if (fenceFd.IsValid()) {
434       mTxn->AddEdit(CompositableOperation(
435           aCompositable->GetIPCHandle(),
436           OpDeliverAcquireFence(nullptr, t.mTextureClient->GetIPDLActor(),
437                                 fenceFd)));
438     }
439   }
440   mTxn->AddEdit(CompositableOperation(aCompositable->GetIPCHandle(),
441                                       OpUseTexture(textures)));
442 }
443 
UseComponentAlphaTextures(CompositableClient * aCompositable,TextureClient * aTextureOnBlack,TextureClient * aTextureOnWhite)444 void ShadowLayerForwarder::UseComponentAlphaTextures(
445     CompositableClient* aCompositable, TextureClient* aTextureOnBlack,
446     TextureClient* aTextureOnWhite) {
447   MOZ_ASSERT(aCompositable);
448 
449   if (!aCompositable->IsConnected()) {
450     return;
451   }
452 
453   MOZ_ASSERT(aTextureOnWhite);
454   MOZ_ASSERT(aTextureOnBlack);
455   MOZ_ASSERT(aCompositable->GetIPCHandle());
456   MOZ_ASSERT(aTextureOnBlack->GetIPDLActor());
457   MOZ_ASSERT(aTextureOnWhite->GetIPDLActor());
458   MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize());
459   MOZ_RELEASE_ASSERT(aTextureOnWhite->GetIPDLActor()->GetIPCChannel() ==
460                      mShadowManager->GetIPCChannel());
461   MOZ_RELEASE_ASSERT(aTextureOnBlack->GetIPDLActor()->GetIPCChannel() ==
462                      mShadowManager->GetIPCChannel());
463 
464   bool readLockedB = aTextureOnBlack->OnForwardedToHost();
465   bool readLockedW = aTextureOnWhite->OnForwardedToHost();
466 
467   mClientLayerManager->GetCompositorBridgeChild()
468       ->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack);
469   mClientLayerManager->GetCompositorBridgeChild()
470       ->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite);
471 
472   auto fenceFdB = aTextureOnBlack->GetInternalData()->GetAcquireFence();
473   if (fenceFdB.IsValid()) {
474     mTxn->AddEdit(CompositableOperation(
475         aCompositable->GetIPCHandle(),
476         OpDeliverAcquireFence(nullptr, aTextureOnBlack->GetIPDLActor(),
477                               fenceFdB)));
478   }
479 
480   auto fenceFdW = aTextureOnWhite->GetInternalData()->GetAcquireFence();
481   if (fenceFdW.IsValid()) {
482     mTxn->AddEdit(CompositableOperation(
483         aCompositable->GetIPCHandle(),
484         OpDeliverAcquireFence(nullptr, aTextureOnWhite->GetIPDLActor(),
485                               fenceFdW)));
486   }
487 
488   mTxn->AddEdit(CompositableOperation(
489       aCompositable->GetIPCHandle(),
490       OpUseComponentAlphaTextures(nullptr, aTextureOnBlack->GetIPDLActor(),
491                                   nullptr, aTextureOnWhite->GetIPDLActor(),
492                                   readLockedB, readLockedW)));
493 }
494 
AddOpDestroy(Transaction * aTxn,const OpDestroy & op)495 static bool AddOpDestroy(Transaction* aTxn, const OpDestroy& op) {
496   if (!aTxn->Opened()) {
497     return false;
498   }
499 
500   aTxn->mDestroyedActors.AppendElement(op);
501   return true;
502 }
503 
DestroyInTransaction(PTextureChild * aTexture)504 bool ShadowLayerForwarder::DestroyInTransaction(PTextureChild* aTexture) {
505   return AddOpDestroy(mTxn, OpDestroy(aTexture));
506 }
507 
DestroyInTransaction(const CompositableHandle & aHandle)508 bool ShadowLayerForwarder::DestroyInTransaction(
509     const CompositableHandle& aHandle) {
510   return AddOpDestroy(mTxn, OpDestroy(aHandle));
511 }
512 
RemoveTextureFromCompositable(CompositableClient * aCompositable,TextureClient * aTexture)513 void ShadowLayerForwarder::RemoveTextureFromCompositable(
514     CompositableClient* aCompositable, TextureClient* aTexture) {
515   MOZ_ASSERT(aCompositable);
516   MOZ_ASSERT(aTexture);
517   MOZ_ASSERT(aTexture->GetIPDLActor());
518   MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() ==
519                      mShadowManager->GetIPCChannel());
520   if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) {
521     // We don't have an actor anymore, don't try to use it!
522     return;
523   }
524 
525   mTxn->AddEdit(CompositableOperation(
526       aCompositable->GetIPCHandle(),
527       OpRemoveTexture(nullptr, aTexture->GetIPDLActor())));
528 }
529 
InWorkerThread()530 bool ShadowLayerForwarder::InWorkerThread() {
531   return GetTextureForwarder()->GetThread()->IsOnCurrentThread();
532 }
533 
SendPaintTime(TransactionId aId,TimeDuration aPaintTime)534 void ShadowLayerForwarder::SendPaintTime(TransactionId aId,
535                                          TimeDuration aPaintTime) {
536   if (!IPCOpen() || !mShadowManager->SendPaintTime(aId, aPaintTime)) {
537     NS_WARNING("Could not send paint times over IPC");
538   }
539 }
540 
EndTransaction(const nsIntRegion & aRegionToClear,TransactionId aId,bool aScheduleComposite,uint32_t aPaintSequenceNumber,bool aIsRepeatTransaction,const mozilla::VsyncId & aVsyncId,const mozilla::TimeStamp & aVsyncStart,const mozilla::TimeStamp & aRefreshStart,const mozilla::TimeStamp & aTransactionStart,bool aContainsSVG,const nsCString & aURL,bool * aSent,const nsTArray<CompositionPayload> & aPayload)541 bool ShadowLayerForwarder::EndTransaction(
542     const nsIntRegion& aRegionToClear, TransactionId aId,
543     bool aScheduleComposite, uint32_t aPaintSequenceNumber,
544     bool aIsRepeatTransaction, const mozilla::VsyncId& aVsyncId,
545     const mozilla::TimeStamp& aVsyncStart,
546     const mozilla::TimeStamp& aRefreshStart,
547     const mozilla::TimeStamp& aTransactionStart, bool aContainsSVG,
548     const nsCString& aURL, bool* aSent,
549     const nsTArray<CompositionPayload>& aPayload) {
550   *aSent = false;
551 
552   TransactionInfo info;
553 
554   MOZ_ASSERT(IPCOpen(), "no manager to forward to");
555   if (!IPCOpen()) {
556     return false;
557   }
558 
559   Maybe<TimeStamp> startTime;
560   if (StaticPrefs::layers_acceleration_draw_fps()) {
561     startTime = Some(TimeStamp::Now());
562   }
563 
564   GetCompositorBridgeChild()->WillEndTransaction();
565 
566   MOZ_ASSERT(aId.IsValid());
567 
568   AUTO_PROFILER_LABEL("ShadowLayerForwarder::EndTransaction", GRAPHICS);
569 
570   RenderTraceScope rendertrace("Foward Transaction", "000091");
571   MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
572 
573   DiagnosticTypes diagnostics =
574       gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes();
575   if (mDiagnosticTypes != diagnostics) {
576     mDiagnosticTypes = diagnostics;
577     mTxn->AddEdit(OpSetDiagnosticTypes(diagnostics));
578   }
579 
580   AutoTxnEnd _(mTxn);
581 
582   if (mTxn->Empty() && !mTxn->RotationChanged()) {
583     MOZ_LAYERS_LOG(
584         ("[LayersForwarder] 0-length cset (?) and no rotation event, skipping "
585          "Update()"));
586     return true;
587   }
588 
589   MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers..."));
590 
591   MOZ_LAYERS_LOG(("[LayersForwarder] building transaction..."));
592 
593   nsTArray<OpSetSimpleLayerAttributes> setSimpleAttrs;
594   for (ShadowableLayer* shadow : mTxn->mSimpleMutants) {
595     if (!shadow->HasShadow()) {
596       continue;
597     }
598 
599     Layer* mutant = shadow->AsLayer();
600     setSimpleAttrs.AppendElement(OpSetSimpleLayerAttributes(
601         Shadow(shadow), mutant->GetSimpleAttributes()));
602   }
603 
604   nsTArray<OpSetLayerAttributes> setAttrs;
605 
606   // We purposely add attribute-change ops to the final changeset
607   // before we add paint ops.  This allows layers to record the
608   // attribute changes before new pixels arrive, which can be useful
609   // for setting up back/front buffers.
610   RenderTraceScope rendertrace2("Foward Transaction", "000092");
611   for (ShadowableLayer* shadow : mTxn->mMutants) {
612     if (!shadow->HasShadow()) {
613       continue;
614     }
615     Layer* mutant = shadow->AsLayer();
616     MOZ_ASSERT(!!mutant, "unshadowable layer?");
617 
618     OpSetLayerAttributes op;
619     op.layer() = Shadow(shadow);
620 
621     LayerAttributes& attrs = op.attrs();
622     CommonLayerAttributes& common = attrs.common();
623     common.visibleRegion() = mutant->GetVisibleRegion();
624     common.eventRegions() = mutant->GetEventRegions();
625     common.useClipRect() = !!mutant->GetClipRect();
626     common.clipRect() =
627         (common.useClipRect() ? *mutant->GetClipRect() : ParentLayerIntRect());
628     if (Layer* maskLayer = mutant->GetMaskLayer()) {
629       common.maskLayer() = Shadow(maskLayer->AsShadowableLayer());
630     } else {
631       common.maskLayer() = LayerHandle();
632     }
633     common.compositorAnimations().id() = mutant->GetCompositorAnimationsId();
634     common.compositorAnimations().animations() =
635         mutant->GetAnimations().Clone();
636     common.invalidRegion() = mutant->GetInvalidRegion().GetRegion();
637     common.scrollMetadata() = mutant->GetAllScrollMetadata().Clone();
638     for (size_t i = 0; i < mutant->GetAncestorMaskLayerCount(); i++) {
639       auto layer =
640           Shadow(mutant->GetAncestorMaskLayerAt(i)->AsShadowableLayer());
641       common.ancestorMaskLayers().AppendElement(layer);
642     }
643     nsCString log;
644     mutant->GetDisplayListLog(log);
645     common.displayListLog() = log;
646 
647     attrs.specific() = null_t();
648     mutant->FillSpecificAttributes(attrs.specific());
649 
650     MOZ_LAYERS_LOG(("[LayersForwarder] OpSetLayerAttributes(%p)\n", mutant));
651 
652     setAttrs.AppendElement(op);
653   }
654 
655   if (mTxn->mCset.IsEmpty() && mTxn->mPaints.IsEmpty() && setAttrs.IsEmpty() &&
656       !mTxn->RotationChanged()) {
657     return true;
658   }
659 
660   info.cset() = std::move(mTxn->mCset);
661   info.setSimpleAttrs() = std::move(setSimpleAttrs);
662   info.setAttrs() = std::move(setAttrs);
663   info.paints() = std::move(mTxn->mPaints);
664   info.toDestroy() = mTxn->mDestroyedActors.Clone();
665   info.fwdTransactionId() = GetFwdTransactionId();
666   info.id() = aId;
667   info.isFirstPaint() = mIsFirstPaint;
668   info.focusTarget() = mFocusTarget;
669   info.scheduleComposite() = aScheduleComposite;
670   info.paintSequenceNumber() = aPaintSequenceNumber;
671   info.isRepeatTransaction() = aIsRepeatTransaction;
672   info.vsyncId() = aVsyncId;
673   info.vsyncStart() = aVsyncStart;
674   info.refreshStart() = aRefreshStart;
675   info.transactionStart() = aTransactionStart;
676   info.url() = aURL;
677   info.containsSVG() = aContainsSVG;
678 #if defined(ENABLE_FRAME_LATENCY_LOG)
679   info.fwdTime() = TimeStamp::Now();
680 #endif
681   info.payload() = aPayload.Clone();
682 
683   TargetConfig targetConfig(mTxn->mTargetBounds, mTxn->mTargetRotation,
684                             mTxn->mTargetOrientation, aRegionToClear);
685   info.targetConfig() = targetConfig;
686 
687   if (!GetTextureForwarder()->IsSameProcess()) {
688     MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send..."));
689     PlatformSyncBeforeUpdate();
690   }
691 
692   if (startTime) {
693     mPaintTiming.serializeMs() =
694         (TimeStamp::Now() - startTime.value()).ToMilliseconds();
695     startTime = Some(TimeStamp::Now());
696   }
697 
698   // We delay at the last possible minute, to give the paint thread a chance to
699   // finish. If it does we don't have to delay messages at all.
700   GetCompositorBridgeChild()->PostponeMessagesIfAsyncPainting();
701 
702   MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
703   RenderTraceScope rendertrace3("Forward Transaction", "000093");
704   if (!mShadowManager->SendUpdate(info)) {
705     MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
706     return false;
707   }
708 
709   if (startTime) {
710     mPaintTiming.sendMs() =
711         (TimeStamp::Now() - startTime.value()).ToMilliseconds();
712     mShadowManager->SendRecordPaintTimes(mPaintTiming);
713   }
714 
715   *aSent = true;
716   mIsFirstPaint = false;
717   mFocusTarget = FocusTarget();
718   MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
719   return true;
720 }
721 
FindCompositable(const CompositableHandle & aHandle)722 RefPtr<CompositableClient> ShadowLayerForwarder::FindCompositable(
723     const CompositableHandle& aHandle) {
724   CompositableClient* client = nullptr;
725   if (!mCompositables.Get(aHandle.Value(), &client)) {
726     return nullptr;
727   }
728   return client;
729 }
730 
SetLayersObserverEpoch(LayersObserverEpoch aEpoch)731 void ShadowLayerForwarder::SetLayersObserverEpoch(LayersObserverEpoch aEpoch) {
732   if (!IPCOpen()) {
733     return;
734   }
735   Unused << mShadowManager->SendSetLayersObserverEpoch(aEpoch);
736 }
737 
UpdateTextureLocks()738 void ShadowLayerForwarder::UpdateTextureLocks() {
739 #ifdef XP_DARWIN
740   if (!IPCOpen()) {
741     return;
742   }
743 
744   auto compositorBridge = GetCompositorBridgeChild();
745   if (compositorBridge) {
746     auto pid = compositorBridge->OtherPid();
747     TextureSync::UpdateTextureLocks(pid);
748   }
749 #endif
750 }
751 
SyncTextures(const nsTArray<uint64_t> & aSerials)752 void ShadowLayerForwarder::SyncTextures(const nsTArray<uint64_t>& aSerials) {
753 #ifdef XP_DARWIN
754   if (!IPCOpen()) {
755     return;
756   }
757 
758   auto compositorBridge = GetCompositorBridgeChild();
759   if (compositorBridge) {
760     auto pid = compositorBridge->OtherPid();
761     TextureSync::WaitForTextures(pid, aSerials);
762   }
763 #endif
764 }
765 
ReleaseLayer(const LayerHandle & aHandle)766 void ShadowLayerForwarder::ReleaseLayer(const LayerHandle& aHandle) {
767   if (!IPCOpen()) {
768     return;
769   }
770   Unused << mShadowManager->SendReleaseLayer(aHandle);
771 }
772 
IPCOpen() const773 bool ShadowLayerForwarder::IPCOpen() const {
774   return HasShadowManager() && mShadowManager->IPCOpen();
775 }
776 
777 /**
778  * We bail out when we have no shadow manager. That can happen when the
779  * layer manager is created by the preallocated process.
780  * See bug 914843 for details.
781  */
ConstructShadowFor(ShadowableLayer * aLayer)782 LayerHandle ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer* aLayer) {
783   return LayerHandle(mNextLayerHandle++);
784 }
785 
786 #if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
787 
788 /*static*/
PlatformSyncBeforeUpdate()789 void ShadowLayerForwarder::PlatformSyncBeforeUpdate() {}
790 
791 #endif  // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
792 
Connect(CompositableClient * aCompositable,ImageContainer * aImageContainer)793 void ShadowLayerForwarder::Connect(CompositableClient* aCompositable,
794                                    ImageContainer* aImageContainer) {
795 #ifdef GFX_COMPOSITOR_LOGGING
796   printf("ShadowLayerForwarder::Connect(Compositable)\n");
797 #endif
798   MOZ_ASSERT(aCompositable);
799   MOZ_ASSERT(mShadowManager);
800   if (!IPCOpen()) {
801     return;
802   }
803 
804   static uint64_t sNextID = 1;
805   uint64_t id = sNextID++;
806 
807   mCompositables.InsertOrUpdate(id, aCompositable);
808 
809   CompositableHandle handle(id);
810   aCompositable->InitIPDL(handle);
811   mShadowManager->SendNewCompositable(handle, aCompositable->GetTextureInfo());
812 }
813 
Attach(CompositableClient * aCompositable,ShadowableLayer * aLayer)814 void ShadowLayerForwarder::Attach(CompositableClient* aCompositable,
815                                   ShadowableLayer* aLayer) {
816   MOZ_ASSERT(aLayer);
817   MOZ_ASSERT(aCompositable);
818   mTxn->AddEdit(
819       OpAttachCompositable(Shadow(aLayer), aCompositable->GetIPCHandle()));
820 }
821 
AttachAsyncCompositable(const CompositableHandle & aHandle,ShadowableLayer * aLayer)822 void ShadowLayerForwarder::AttachAsyncCompositable(
823     const CompositableHandle& aHandle, ShadowableLayer* aLayer) {
824   MOZ_ASSERT(aLayer);
825   MOZ_ASSERT(aHandle);
826   mTxn->AddEdit(OpAttachAsyncCompositable(Shadow(aLayer), aHandle));
827 }
828 
SetShadowManager(PLayerTransactionChild * aShadowManager)829 void ShadowLayerForwarder::SetShadowManager(
830     PLayerTransactionChild* aShadowManager) {
831   mShadowManager = static_cast<LayerTransactionChild*>(aShadowManager);
832   mShadowManager->SetForwarder(this);
833 }
834 
StopReceiveAsyncParentMessge()835 void ShadowLayerForwarder::StopReceiveAsyncParentMessge() {
836   if (!IPCOpen()) {
837     return;
838   }
839   mShadowManager->SetForwarder(nullptr);
840 }
841 
ClearCachedResources()842 void ShadowLayerForwarder::ClearCachedResources() {
843   if (!IPCOpen()) {
844     return;
845   }
846   mShadowManager->SendClearCachedResources();
847 }
848 
ScheduleComposite()849 void ShadowLayerForwarder::ScheduleComposite() {
850   if (!IPCOpen()) {
851     return;
852   }
853   mShadowManager->SendScheduleComposite();
854 }
855 
IsSurfaceDescriptorValid(const SurfaceDescriptor & aSurface)856 bool IsSurfaceDescriptorValid(const SurfaceDescriptor& aSurface) {
857   return aSurface.type() != SurfaceDescriptor::T__None &&
858          aSurface.type() != SurfaceDescriptor::Tnull_t;
859 }
860 
GetAddressFromDescriptor(const SurfaceDescriptor & aDescriptor)861 uint8_t* GetAddressFromDescriptor(const SurfaceDescriptor& aDescriptor) {
862   MOZ_ASSERT(IsSurfaceDescriptorValid(aDescriptor));
863   MOZ_RELEASE_ASSERT(
864       aDescriptor.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer,
865       "GFX: surface descriptor is not the right type.");
866 
867   auto memOrShmem = aDescriptor.get_SurfaceDescriptorBuffer().data();
868   if (memOrShmem.type() == MemoryOrShmem::TShmem) {
869     return memOrShmem.get_Shmem().get<uint8_t>();
870   } else {
871     return reinterpret_cast<uint8_t*>(memOrShmem.get_uintptr_t());
872   }
873 }
874 
GetSurfaceForDescriptor(const SurfaceDescriptor & aDescriptor)875 already_AddRefed<gfx::DataSourceSurface> GetSurfaceForDescriptor(
876     const SurfaceDescriptor& aDescriptor) {
877   if (aDescriptor.type() != SurfaceDescriptor::TSurfaceDescriptorBuffer) {
878     return nullptr;
879   }
880   uint8_t* data = GetAddressFromDescriptor(aDescriptor);
881   auto rgb =
882       aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
883   uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
884   return gfx::Factory::CreateWrappingDataSourceSurface(data, stride, rgb.size(),
885                                                        rgb.format());
886 }
887 
GetDrawTargetForDescriptor(const SurfaceDescriptor & aDescriptor)888 already_AddRefed<gfx::DrawTarget> GetDrawTargetForDescriptor(
889     const SurfaceDescriptor& aDescriptor) {
890   uint8_t* data = GetAddressFromDescriptor(aDescriptor);
891   auto rgb =
892       aDescriptor.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
893   uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
894   return gfx::Factory::CreateDrawTargetForData(
895       gfx::BackendType::SKIA, data, rgb.size(), stride, rgb.format());
896 }
897 
DestroySurfaceDescriptor(IShmemAllocator * aAllocator,SurfaceDescriptor * aSurface)898 void DestroySurfaceDescriptor(IShmemAllocator* aAllocator,
899                               SurfaceDescriptor* aSurface) {
900   MOZ_ASSERT(aSurface);
901 
902   SurfaceDescriptorBuffer& desc = aSurface->get_SurfaceDescriptorBuffer();
903   switch (desc.data().type()) {
904     case MemoryOrShmem::TShmem: {
905       aAllocator->DeallocShmem(desc.data().get_Shmem());
906       break;
907     }
908     case MemoryOrShmem::Tuintptr_t: {
909       uint8_t* ptr = (uint8_t*)desc.data().get_uintptr_t();
910       GfxMemoryImageReporter::WillFree(ptr);
911       delete[] ptr;
912       break;
913     }
914     default:
915       MOZ_CRASH("surface type not implemented!");
916   }
917   *aSurface = SurfaceDescriptor();
918 }
919 
AllocSurfaceDescriptor(const gfx::IntSize & aSize,gfxContentType aContent,SurfaceDescriptor * aBuffer)920 bool ShadowLayerForwarder::AllocSurfaceDescriptor(const gfx::IntSize& aSize,
921                                                   gfxContentType aContent,
922                                                   SurfaceDescriptor* aBuffer) {
923   if (!IPCOpen()) {
924     return false;
925   }
926   return AllocSurfaceDescriptorWithCaps(aSize, aContent, DEFAULT_BUFFER_CAPS,
927                                         aBuffer);
928 }
929 
AllocSurfaceDescriptorWithCaps(const gfx::IntSize & aSize,gfxContentType aContent,uint32_t aCaps,SurfaceDescriptor * aBuffer)930 bool ShadowLayerForwarder::AllocSurfaceDescriptorWithCaps(
931     const gfx::IntSize& aSize, gfxContentType aContent, uint32_t aCaps,
932     SurfaceDescriptor* aBuffer) {
933   if (!IPCOpen()) {
934     return false;
935   }
936   gfx::SurfaceFormat format =
937       gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aContent);
938   size_t size = ImageDataSerializer::ComputeRGBBufferSize(aSize, format);
939   if (!size) {
940     return false;
941   }
942 
943   MemoryOrShmem bufferDesc;
944   if (GetTextureForwarder()->IsSameProcess()) {
945     uint8_t* data = new (std::nothrow) uint8_t[size];
946     if (!data) {
947       return false;
948     }
949     GfxMemoryImageReporter::DidAlloc(data);
950     memset(data, 0, size);
951     bufferDesc = reinterpret_cast<uintptr_t>(data);
952   } else {
953     mozilla::ipc::Shmem shmem;
954     if (!GetTextureForwarder()->AllocUnsafeShmem(size, OptimalShmemType(),
955                                                  &shmem)) {
956       return false;
957     }
958 
959     bufferDesc = std::move(shmem);
960   }
961 
962   // Use an intermediate buffer by default. Skipping the intermediate buffer is
963   // only possible in certain configurations so let's keep it simple here for
964   // now.
965   const bool hasIntermediateBuffer = true;
966   *aBuffer = SurfaceDescriptorBuffer(
967       RGBDescriptor(aSize, format, hasIntermediateBuffer), bufferDesc);
968 
969   return true;
970 }
971 
972 /* static */
IsShmem(SurfaceDescriptor * aSurface)973 bool ShadowLayerForwarder::IsShmem(SurfaceDescriptor* aSurface) {
974   return aSurface &&
975          (aSurface->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer) &&
976          (aSurface->get_SurfaceDescriptorBuffer().data().type() ==
977           MemoryOrShmem::TShmem);
978 }
979 
DestroySurfaceDescriptor(SurfaceDescriptor * aSurface)980 void ShadowLayerForwarder::DestroySurfaceDescriptor(
981     SurfaceDescriptor* aSurface) {
982   MOZ_ASSERT(aSurface);
983   MOZ_ASSERT(IPCOpen());
984   if (!IPCOpen() || !aSurface) {
985     return;
986   }
987 
988   ::mozilla::layers::DestroySurfaceDescriptor(GetTextureForwarder(), aSurface);
989 }
990 
UpdateFwdTransactionId()991 void ShadowLayerForwarder::UpdateFwdTransactionId() {
992   auto compositorBridge = GetCompositorBridgeChild();
993   if (compositorBridge) {
994     compositorBridge->UpdateFwdTransactionId();
995   }
996 }
997 
GetFwdTransactionId()998 uint64_t ShadowLayerForwarder::GetFwdTransactionId() {
999   auto compositorBridge = GetCompositorBridgeChild();
1000   MOZ_DIAGNOSTIC_ASSERT(compositorBridge);
1001   return compositorBridge ? compositorBridge->GetFwdTransactionId() : 0;
1002 }
1003 
GetCompositorBridgeChild()1004 CompositorBridgeChild* ShadowLayerForwarder::GetCompositorBridgeChild() {
1005   if (mCompositorBridgeChild) {
1006     return mCompositorBridgeChild;
1007   }
1008   if (!mShadowManager) {
1009     return nullptr;
1010   }
1011   mCompositorBridgeChild =
1012       static_cast<CompositorBridgeChild*>(mShadowManager->Manager());
1013   return mCompositorBridgeChild;
1014 }
1015 
SyncWithCompositor()1016 void ShadowLayerForwarder::SyncWithCompositor() {
1017   auto compositorBridge = GetCompositorBridgeChild();
1018   if (compositorBridge && compositorBridge->IPCOpen()) {
1019     compositorBridge->SendSyncWithCompositor();
1020   }
1021 }
1022 
ReleaseCompositable(const CompositableHandle & aHandle)1023 void ShadowLayerForwarder::ReleaseCompositable(
1024     const CompositableHandle& aHandle) {
1025   AssertInForwarderThread();
1026   if (!DestroyInTransaction(aHandle)) {
1027     if (!IPCOpen()) {
1028       return;
1029     }
1030     mShadowManager->SendReleaseCompositable(aHandle);
1031   }
1032   mCompositables.Remove(aHandle.Value());
1033 }
1034 
SynchronouslyShutdown()1035 void ShadowLayerForwarder::SynchronouslyShutdown() {
1036   if (IPCOpen()) {
1037     mShadowManager->SendShutdownSync();
1038     mShadowManager->MarkDestroyed();
1039   }
1040 }
1041 
~ShadowableLayer()1042 ShadowableLayer::~ShadowableLayer() {
1043   if (mShadow) {
1044     mForwarder->ReleaseLayer(GetShadow());
1045   }
1046 }
1047 
1048 }  // namespace layers
1049 }  // namespace mozilla
1050