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