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