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