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/. */
7 #include "ShadowLayers.h"
9 #include <set> // for _Rb_tree_const_iterator, etc
10 #include <vector> // for vector
12 #include "ClientLayerManager.h" // for ClientLayerManager
13 #include "IPDLActor.h"
14 #include "ISurfaceAllocator.h" // for IsSurfaceDescriptorValid
15 #include "Layers.h" // for Layer
16 #include "RenderTrace.h" // for RenderTraceScope
17 #include "gfx2DGlue.h" // for Moz2D transition helpers
18 #include "gfxPlatform.h" // for gfxImageFormat, gfxPlatform
19 #include "ipc/IPCMessageUtils.h" // for gfxContentType, null_t
20 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
21 #include "mozilla/gfx/Point.h" // for IntSize
22 #include "mozilla/layers/CompositableClient.h" // for CompositableClient, etc
23 #include "mozilla/layers/CompositorBridgeChild.h"
24 #include "mozilla/layers/ContentClient.h"
25 #include "mozilla/layers/ImageBridgeChild.h"
26 #include "mozilla/layers/ImageDataSerializer.h"
27 #include "mozilla/layers/LayerTransactionChild.h"
28 #include "mozilla/layers/LayersMessages.h" // for Edit, etc
29 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
30 #include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
31 #include "mozilla/layers/PTextureChild.h"
32 #include "mozilla/layers/SyncObject.h"
34 # include "mozilla/layers/TextureSync.h"
36 #include "ShadowLayerUtils.h"
37 #include "mozilla/ProfilerLabels.h"
38 #include "mozilla/ReentrantMonitor.h"
39 #include "mozilla/StaticPrefs_layers.h"
40 #include "mozilla/layers/TextureClient.h" // for TextureClient
41 #include "mozilla/mozalloc.h" // for operator new, etc
42 #include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart
43 #include "nsTArray.h" // for AutoTArray, nsTArray, etc
44 #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
53 using namespace mozilla::gfx
;
54 using namespace mozilla::gl
;
55 using namespace mozilla::ipc
;
57 class ClientTiledLayerBuffer
;
59 typedef nsTArray
<SurfaceDescriptor
> BufferArray
;
60 typedef nsTArray
<Edit
> EditVector
;
61 typedef nsTHashtable
<nsPtrHashKey
<ShadowableLayer
>> ShadowableLayerSet
;
62 typedef nsTArray
<OpDestroy
> OpDestroyVector
;
67 : mTargetRotation(ROTATION_0
),
68 mTargetOrientation(hal::eScreenOrientation_None
),
70 mRotationChanged(false) {}
72 void Begin(const gfx::IntRect
& aTargetBounds
, ScreenRotation aRotation
,
73 hal::ScreenOrientation aOrientation
) {
75 mTargetBounds
= aTargetBounds
;
76 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
81 mRotationChanged
= true;
83 mTargetRotation
= aRotation
;
84 mTargetOrientation
= aOrientation
;
86 void AddEdit(const Edit
& aEdit
) {
87 MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
88 mCset
.AppendElement(aEdit
);
90 void AddEdit(const CompositableOperation
& aEdit
) { AddEdit(Edit(aEdit
)); }
92 void AddNoSwapPaint(const CompositableOperation
& aPaint
) {
93 MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
94 mPaints
.AppendElement(Edit(aPaint
));
96 void AddMutant(ShadowableLayer
* aLayer
) {
97 MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
98 mMutants
.PutEntry(aLayer
);
100 void AddSimpleMutant(ShadowableLayer
* aLayer
) {
101 MOZ_ASSERT(!Finished(), "forgot BeginTransaction?");
102 mSimpleMutants
.PutEntry(aLayer
);
108 mSimpleMutants
.Clear();
109 mDestroyedActors
.Clear();
111 mRotationChanged
= false;
115 return mCset
.IsEmpty() && mPaints
.IsEmpty() && mMutants
.IsEmpty() &&
116 mSimpleMutants
.IsEmpty() && mDestroyedActors
.IsEmpty();
118 bool RotationChanged() const { return mRotationChanged
; }
119 bool Finished() const { return !mOpen
&& Empty(); }
121 bool Opened() const { return mOpen
; }
124 nsTArray
<CompositableOperation
> mPaints
;
125 OpDestroyVector mDestroyedActors
;
126 ShadowableLayerSet mMutants
;
127 ShadowableLayerSet mSimpleMutants
;
128 gfx::IntRect mTargetBounds
;
129 ScreenRotation mTargetRotation
;
130 hal::ScreenOrientation mTargetOrientation
;
134 bool mRotationChanged
;
137 Transaction(const Transaction
&);
138 Transaction
& operator=(const Transaction
&);
140 struct AutoTxnEnd final
{
141 explicit AutoTxnEnd(Transaction
* aTxn
) : mTxn(aTxn
) {}
142 ~AutoTxnEnd() { mTxn
->End(); }
146 void KnowsCompositor::IdentifyTextureHost(
147 const TextureFactoryIdentifier
& aIdentifier
) {
148 auto lock
= mData
.Lock();
149 lock
.ref().mTextureFactoryIdentifier
= aIdentifier
;
151 lock
.ref().mSyncObject
=
152 SyncObjectClient::CreateSyncObjectClientForContentDevice(
153 aIdentifier
.mSyncHandle
);
156 KnowsCompositor::KnowsCompositor()
157 : mData("KnowsCompositorMutex"), mSerial(++sSerialCounter
) {}
159 KnowsCompositor::~KnowsCompositor() = default;
161 KnowsCompositorMediaProxy::KnowsCompositorMediaProxy(
162 const TextureFactoryIdentifier
& aIdentifier
) {
163 auto lock
= mData
.Lock();
164 lock
.ref().mTextureFactoryIdentifier
= aIdentifier
;
165 // overwrite mSerial's value set by the parent class because we use the same
166 // serial as the KnowsCompositor we are proxying.
167 mThreadSafeAllocator
= ImageBridgeChild::GetSingleton();
168 lock
.ref().mSyncObject
= mThreadSafeAllocator
->GetSyncObject();
171 KnowsCompositorMediaProxy::~KnowsCompositorMediaProxy() = default;
173 TextureForwarder
* KnowsCompositorMediaProxy::GetTextureForwarder() {
174 return mThreadSafeAllocator
->GetTextureForwarder();
177 LayersIPCActor
* KnowsCompositorMediaProxy::GetLayersIPCActor() {
178 return mThreadSafeAllocator
->GetLayersIPCActor();
181 ActiveResourceTracker
* KnowsCompositorMediaProxy::GetActiveResourceTracker() {
182 return mThreadSafeAllocator
->GetActiveResourceTracker();
185 void KnowsCompositorMediaProxy::SyncWithCompositor() {
186 mThreadSafeAllocator
->SyncWithCompositor();
189 RefPtr
<KnowsCompositor
> ShadowLayerForwarder::GetForMedia() {
190 return MakeAndAddRef
<KnowsCompositorMediaProxy
>(
191 GetTextureFactoryIdentifier());
194 ShadowLayerForwarder::ShadowLayerForwarder(
195 ClientLayerManager
* aClientLayerManager
)
196 : mClientLayerManager(aClientLayerManager
),
197 mThread(NS_GetCurrentThread()),
198 mDiagnosticTypes(DiagnosticTypes::NO_DIAGNOSTIC
),
199 mIsFirstPaint(false),
200 mNextLayerHandle(1) {
201 mTxn
= new Transaction();
202 mEventTarget
= GetMainThreadSerialEventTarget();
204 MOZ_ASSERT(mEventTarget
|| !XRE_IsContentProcess());
205 mActiveResourceTracker
= MakeUnique
<ActiveResourceTracker
>(
206 1000, "CompositableForwarder", mEventTarget
);
209 template <typename T
>
210 struct ReleaseOnMainThreadTask
: public Runnable
{
213 explicit ReleaseOnMainThreadTask(UniquePtr
<T
>& aObj
)
214 : Runnable("layers::ReleaseOnMainThreadTask"), mObj(std::move(aObj
)) {}
216 NS_IMETHOD
Run() override
{
222 ShadowLayerForwarder::~ShadowLayerForwarder() {
223 MOZ_ASSERT(mTxn
->Finished(), "unfinished transaction?");
225 if (mShadowManager
) {
226 mShadowManager
->SetForwarder(nullptr);
227 if (NS_IsMainThread()) {
228 mShadowManager
->Destroy();
231 mEventTarget
->Dispatch(
232 NewRunnableMethod("LayerTransactionChild::Destroy", mShadowManager
,
233 &LayerTransactionChild::Destroy
),
234 nsIEventTarget::DISPATCH_NORMAL
);
236 NS_DispatchToMainThread(
237 NewRunnableMethod("layers::LayerTransactionChild::Destroy",
238 mShadowManager
, &LayerTransactionChild::Destroy
));
243 if (!NS_IsMainThread()) {
244 RefPtr
<ReleaseOnMainThreadTask
<ActiveResourceTracker
>> event
=
245 new ReleaseOnMainThreadTask
<ActiveResourceTracker
>(
246 mActiveResourceTracker
);
248 mEventTarget
->Dispatch(event
.forget(), nsIEventTarget::DISPATCH_NORMAL
);
250 NS_DispatchToMainThread(event
);
255 void ShadowLayerForwarder::BeginTransaction(
256 const gfx::IntRect
& aTargetBounds
, ScreenRotation aRotation
,
257 hal::ScreenOrientation aOrientation
) {
258 MOZ_ASSERT(IPCOpen(), "no manager to forward to");
259 MOZ_ASSERT(mTxn
->Finished(), "uncommitted txn?");
260 UpdateFwdTransactionId();
261 mTxn
->Begin(aTargetBounds
, aRotation
, aOrientation
);
264 static const LayerHandle
& Shadow(ShadowableLayer
* aLayer
) {
265 return aLayer
->GetShadow();
268 template <typename OpCreateT
>
269 static void CreatedLayer(Transaction
* aTxn
, ShadowableLayer
* aLayer
) {
270 aTxn
->AddEdit(OpCreateT(Shadow(aLayer
)));
273 void ShadowLayerForwarder::CreatedPaintedLayer(ShadowableLayer
* aThebes
) {
274 CreatedLayer
<OpCreatePaintedLayer
>(mTxn
, aThebes
);
276 void ShadowLayerForwarder::CreatedContainerLayer(ShadowableLayer
* aContainer
) {
277 CreatedLayer
<OpCreateContainerLayer
>(mTxn
, aContainer
);
279 void ShadowLayerForwarder::CreatedImageLayer(ShadowableLayer
* aImage
) {
280 CreatedLayer
<OpCreateImageLayer
>(mTxn
, aImage
);
282 void ShadowLayerForwarder::CreatedColorLayer(ShadowableLayer
* aColor
) {
283 CreatedLayer
<OpCreateColorLayer
>(mTxn
, aColor
);
285 void ShadowLayerForwarder::CreatedCanvasLayer(ShadowableLayer
* aCanvas
) {
286 CreatedLayer
<OpCreateCanvasLayer
>(mTxn
, aCanvas
);
288 void ShadowLayerForwarder::CreatedRefLayer(ShadowableLayer
* aRef
) {
289 CreatedLayer
<OpCreateRefLayer
>(mTxn
, aRef
);
292 void ShadowLayerForwarder::Mutated(ShadowableLayer
* aMutant
) {
293 mTxn
->AddMutant(aMutant
);
296 void ShadowLayerForwarder::MutatedSimple(ShadowableLayer
* aMutant
) {
297 mTxn
->AddSimpleMutant(aMutant
);
300 void ShadowLayerForwarder::SetRoot(ShadowableLayer
* aRoot
) {
301 mTxn
->AddEdit(OpSetRoot(Shadow(aRoot
)));
303 void ShadowLayerForwarder::InsertAfter(ShadowableLayer
* aContainer
,
304 ShadowableLayer
* aChild
,
305 ShadowableLayer
* aAfter
) {
306 if (!aChild
->HasShadow()) {
310 while (aAfter
&& !aAfter
->HasShadow()) {
311 aAfter
= aAfter
->AsLayer()->GetPrevSibling()
312 ? aAfter
->AsLayer()->GetPrevSibling()->AsShadowableLayer()
318 OpInsertAfter(Shadow(aContainer
), Shadow(aChild
), Shadow(aAfter
)));
320 mTxn
->AddEdit(OpPrependChild(Shadow(aContainer
), Shadow(aChild
)));
323 void ShadowLayerForwarder::RemoveChild(ShadowableLayer
* aContainer
,
324 ShadowableLayer
* aChild
) {
325 MOZ_LAYERS_LOG(("[LayersForwarder] OpRemoveChild container=%p child=%p\n",
326 aContainer
->AsLayer(), aChild
->AsLayer()));
328 if (!aChild
->HasShadow()) {
332 mTxn
->AddEdit(OpRemoveChild(Shadow(aContainer
), Shadow(aChild
)));
334 void ShadowLayerForwarder::RepositionChild(ShadowableLayer
* aContainer
,
335 ShadowableLayer
* aChild
,
336 ShadowableLayer
* aAfter
) {
337 if (!aChild
->HasShadow()) {
341 while (aAfter
&& !aAfter
->HasShadow()) {
342 aAfter
= aAfter
->AsLayer()->GetPrevSibling()
343 ? aAfter
->AsLayer()->GetPrevSibling()->AsShadowableLayer()
349 ("[LayersForwarder] OpRepositionChild container=%p child=%p after=%p",
350 aContainer
->AsLayer(), aChild
->AsLayer(), aAfter
->AsLayer()));
352 OpRepositionChild(Shadow(aContainer
), Shadow(aChild
), Shadow(aAfter
)));
354 MOZ_LAYERS_LOG(("[LayersForwarder] OpRaiseToTopChild container=%p child=%p",
355 aContainer
->AsLayer(), aChild
->AsLayer()));
356 mTxn
->AddEdit(OpRaiseToTopChild(Shadow(aContainer
), Shadow(aChild
)));
361 void ShadowLayerForwarder::CheckSurfaceDescriptor(
362 const SurfaceDescriptor
* aDescriptor
) const {
367 if (aDescriptor
->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer
&&
368 aDescriptor
->get_SurfaceDescriptorBuffer().data().type() ==
369 MemoryOrShmem::TShmem
) {
371 aDescriptor
->get_SurfaceDescriptorBuffer().data().get_Shmem();
372 shmem
.AssertInvariants();
373 MOZ_ASSERT(mShadowManager
&&
374 mShadowManager
->IsTrackingSharedMemory(shmem
.mSegment
));
379 void ShadowLayerForwarder::UseTiledLayerBuffer(
380 CompositableClient
* aCompositable
,
381 const SurfaceDescriptorTiles
& aTileLayerDescriptor
) {
382 MOZ_ASSERT(aCompositable
);
384 if (!aCompositable
->IsConnected()) {
388 mTxn
->AddNoSwapPaint(
389 CompositableOperation(aCompositable
->GetIPCHandle(),
390 OpUseTiledLayerBuffer(aTileLayerDescriptor
)));
393 void ShadowLayerForwarder::UpdateTextureRegion(
394 CompositableClient
* aCompositable
,
395 const ThebesBufferData
& aThebesBufferData
,
396 const nsIntRegion
& aUpdatedRegion
) {
397 MOZ_ASSERT(aCompositable
);
399 if (!aCompositable
->IsConnected()) {
403 mTxn
->AddNoSwapPaint(CompositableOperation(
404 aCompositable
->GetIPCHandle(),
405 OpPaintTextureRegion(aThebesBufferData
, aUpdatedRegion
)));
408 void ShadowLayerForwarder::UseTextures(
409 CompositableClient
* aCompositable
,
410 const nsTArray
<TimedTextureClient
>& aTextures
) {
411 MOZ_ASSERT(aCompositable
);
413 if (!aCompositable
->IsConnected()) {
417 AutoTArray
<TimedTexture
, 4> textures
;
419 for (auto& t
: aTextures
) {
420 MOZ_ASSERT(t
.mTextureClient
);
421 MOZ_ASSERT(t
.mTextureClient
->GetIPDLActor());
422 MOZ_RELEASE_ASSERT(t
.mTextureClient
->GetIPDLActor()->GetIPCChannel() ==
423 mShadowManager
->GetIPCChannel());
424 bool readLocked
= t
.mTextureClient
->OnForwardedToHost();
425 textures
.AppendElement(
426 TimedTexture(nullptr, t
.mTextureClient
->GetIPDLActor(), t
.mTimeStamp
,
427 t
.mPictureRect
, t
.mFrameID
, t
.mProducerID
, readLocked
));
428 mClientLayerManager
->GetCompositorBridgeChild()
429 ->HoldUntilCompositableRefReleasedIfNecessary(t
.mTextureClient
);
431 auto fenceFd
= t
.mTextureClient
->GetInternalData()->GetAcquireFence();
432 if (fenceFd
.IsValid()) {
433 mTxn
->AddEdit(CompositableOperation(
434 aCompositable
->GetIPCHandle(),
435 OpDeliverAcquireFence(nullptr, t
.mTextureClient
->GetIPDLActor(),
439 mTxn
->AddEdit(CompositableOperation(aCompositable
->GetIPCHandle(),
440 OpUseTexture(textures
)));
443 void ShadowLayerForwarder::UseComponentAlphaTextures(
444 CompositableClient
* aCompositable
, TextureClient
* aTextureOnBlack
,
445 TextureClient
* aTextureOnWhite
) {
446 MOZ_ASSERT(aCompositable
);
448 if (!aCompositable
->IsConnected()) {
452 MOZ_ASSERT(aTextureOnWhite
);
453 MOZ_ASSERT(aTextureOnBlack
);
454 MOZ_ASSERT(aCompositable
->GetIPCHandle());
455 MOZ_ASSERT(aTextureOnBlack
->GetIPDLActor());
456 MOZ_ASSERT(aTextureOnWhite
->GetIPDLActor());
457 MOZ_ASSERT(aTextureOnBlack
->GetSize() == aTextureOnWhite
->GetSize());
458 MOZ_RELEASE_ASSERT(aTextureOnWhite
->GetIPDLActor()->GetIPCChannel() ==
459 mShadowManager
->GetIPCChannel());
460 MOZ_RELEASE_ASSERT(aTextureOnBlack
->GetIPDLActor()->GetIPCChannel() ==
461 mShadowManager
->GetIPCChannel());
463 bool readLockedB
= aTextureOnBlack
->OnForwardedToHost();
464 bool readLockedW
= aTextureOnWhite
->OnForwardedToHost();
466 mClientLayerManager
->GetCompositorBridgeChild()
467 ->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnBlack
);
468 mClientLayerManager
->GetCompositorBridgeChild()
469 ->HoldUntilCompositableRefReleasedIfNecessary(aTextureOnWhite
);
471 auto fenceFdB
= aTextureOnBlack
->GetInternalData()->GetAcquireFence();
472 if (fenceFdB
.IsValid()) {
473 mTxn
->AddEdit(CompositableOperation(
474 aCompositable
->GetIPCHandle(),
475 OpDeliverAcquireFence(nullptr, aTextureOnBlack
->GetIPDLActor(),
479 auto fenceFdW
= aTextureOnWhite
->GetInternalData()->GetAcquireFence();
480 if (fenceFdW
.IsValid()) {
481 mTxn
->AddEdit(CompositableOperation(
482 aCompositable
->GetIPCHandle(),
483 OpDeliverAcquireFence(nullptr, aTextureOnWhite
->GetIPDLActor(),
487 mTxn
->AddEdit(CompositableOperation(
488 aCompositable
->GetIPCHandle(),
489 OpUseComponentAlphaTextures(nullptr, aTextureOnBlack
->GetIPDLActor(),
490 nullptr, aTextureOnWhite
->GetIPDLActor(),
491 readLockedB
, readLockedW
)));
494 static bool AddOpDestroy(Transaction
* aTxn
, const OpDestroy
& op
) {
495 if (!aTxn
->Opened()) {
499 aTxn
->mDestroyedActors
.AppendElement(op
);
503 bool ShadowLayerForwarder::DestroyInTransaction(PTextureChild
* aTexture
) {
504 return AddOpDestroy(mTxn
, OpDestroy(aTexture
));
507 bool ShadowLayerForwarder::DestroyInTransaction(
508 const CompositableHandle
& aHandle
) {
509 return AddOpDestroy(mTxn
, OpDestroy(aHandle
));
512 void ShadowLayerForwarder::RemoveTextureFromCompositable(
513 CompositableClient
* aCompositable
, TextureClient
* aTexture
) {
514 MOZ_ASSERT(aCompositable
);
515 MOZ_ASSERT(aTexture
);
516 MOZ_ASSERT(aTexture
->GetIPDLActor());
517 MOZ_RELEASE_ASSERT(aTexture
->GetIPDLActor()->GetIPCChannel() ==
518 mShadowManager
->GetIPCChannel());
519 if (!aCompositable
->IsConnected() || !aTexture
->GetIPDLActor()) {
520 // We don't have an actor anymore, don't try to use it!
524 mTxn
->AddEdit(CompositableOperation(
525 aCompositable
->GetIPCHandle(),
526 OpRemoveTexture(nullptr, aTexture
->GetIPDLActor())));
529 bool ShadowLayerForwarder::InWorkerThread() {
530 return GetTextureForwarder()->GetThread()->IsOnCurrentThread();
533 void ShadowLayerForwarder::StorePluginWidgetConfigurations(
534 const nsTArray
<nsIWidget::Configuration
>& aConfigurations
) {
535 // Cache new plugin widget configs here until we call update, at which
536 // point this data will get shipped over to chrome.
537 mPluginWindowData
.Clear();
538 for (uint32_t idx
= 0; idx
< aConfigurations
.Length(); idx
++) {
539 const nsIWidget::Configuration
& configuration
= aConfigurations
[idx
];
540 mPluginWindowData
.AppendElement(
541 PluginWindowData(configuration
.mWindowID
, configuration
.mClipRegion
,
542 configuration
.mBounds
, configuration
.mVisible
));
546 void ShadowLayerForwarder::SendPaintTime(TransactionId aId
,
547 TimeDuration aPaintTime
) {
548 if (!IPCOpen() || !mShadowManager
->SendPaintTime(aId
, aPaintTime
)) {
549 NS_WARNING("Could not send paint times over IPC");
553 bool ShadowLayerForwarder::EndTransaction(
554 const nsIntRegion
& aRegionToClear
, TransactionId aId
,
555 bool aScheduleComposite
, uint32_t aPaintSequenceNumber
,
556 bool aIsRepeatTransaction
, const mozilla::VsyncId
& aVsyncId
,
557 const mozilla::TimeStamp
& aVsyncStart
,
558 const mozilla::TimeStamp
& aRefreshStart
,
559 const mozilla::TimeStamp
& aTransactionStart
, bool aContainsSVG
,
560 const nsCString
& aURL
, bool* aSent
,
561 const nsTArray
<CompositionPayload
>& aPayload
) {
564 TransactionInfo info
;
566 MOZ_ASSERT(IPCOpen(), "no manager to forward to");
571 Maybe
<TimeStamp
> startTime
;
572 if (StaticPrefs::layers_acceleration_draw_fps()) {
573 startTime
= Some(TimeStamp::Now());
576 GetCompositorBridgeChild()->WillEndTransaction();
578 MOZ_ASSERT(aId
.IsValid());
580 AUTO_PROFILER_LABEL("ShadowLayerForwarder::EndTransaction", GRAPHICS
);
582 RenderTraceScope
rendertrace("Foward Transaction", "000091");
583 MOZ_ASSERT(!mTxn
->Finished(), "forgot BeginTransaction?");
585 DiagnosticTypes diagnostics
=
586 gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes();
587 if (mDiagnosticTypes
!= diagnostics
) {
588 mDiagnosticTypes
= diagnostics
;
589 mTxn
->AddEdit(OpSetDiagnosticTypes(diagnostics
));
594 if (mTxn
->Empty() && !mTxn
->RotationChanged()) {
596 ("[LayersForwarder] 0-length cset (?) and no rotation event, skipping "
601 if (!mTxn
->mPaints
.IsEmpty()) {
602 // With some platforms, telling the drawing backend that there will be no
603 // more drawing for this frame helps with preventing command queues from
604 // spanning across multiple frames.
605 gfxPlatform::GetPlatform()->FlushContentDrawing();
608 MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers..."));
610 MOZ_LAYERS_LOG(("[LayersForwarder] building transaction..."));
612 nsTArray
<OpSetSimpleLayerAttributes
> setSimpleAttrs
;
613 for (ShadowableLayerSet::Iterator
it(&mTxn
->mSimpleMutants
); !it
.Done();
615 ShadowableLayer
* shadow
= it
.Get()->GetKey();
616 if (!shadow
->HasShadow()) {
620 Layer
* mutant
= shadow
->AsLayer();
621 setSimpleAttrs
.AppendElement(OpSetSimpleLayerAttributes(
622 Shadow(shadow
), mutant
->GetSimpleAttributes()));
625 nsTArray
<OpSetLayerAttributes
> setAttrs
;
627 // We purposely add attribute-change ops to the final changeset
628 // before we add paint ops. This allows layers to record the
629 // attribute changes before new pixels arrive, which can be useful
630 // for setting up back/front buffers.
631 RenderTraceScope
rendertrace2("Foward Transaction", "000092");
632 for (ShadowableLayerSet::Iterator
it(&mTxn
->mMutants
); !it
.Done();
634 ShadowableLayer
* shadow
= it
.Get()->GetKey();
636 if (!shadow
->HasShadow()) {
639 Layer
* mutant
= shadow
->AsLayer();
640 MOZ_ASSERT(!!mutant
, "unshadowable layer?");
642 OpSetLayerAttributes op
;
643 op
.layer() = Shadow(shadow
);
645 LayerAttributes
& attrs
= op
.attrs();
646 CommonLayerAttributes
& common
= attrs
.common();
647 common
.visibleRegion() = mutant
->GetVisibleRegion();
648 common
.eventRegions() = mutant
->GetEventRegions();
649 common
.useClipRect() = !!mutant
->GetClipRect();
651 (common
.useClipRect() ? *mutant
->GetClipRect() : ParentLayerIntRect());
652 if (Layer
* maskLayer
= mutant
->GetMaskLayer()) {
653 common
.maskLayer() = Shadow(maskLayer
->AsShadowableLayer());
655 common
.maskLayer() = LayerHandle();
657 common
.compositorAnimations().id() = mutant
->GetCompositorAnimationsId();
658 common
.compositorAnimations().animations() =
659 mutant
->GetAnimations().Clone();
660 common
.invalidRegion() = mutant
->GetInvalidRegion().GetRegion();
661 common
.scrollMetadata() = mutant
->GetAllScrollMetadata().Clone();
662 for (size_t i
= 0; i
< mutant
->GetAncestorMaskLayerCount(); i
++) {
664 Shadow(mutant
->GetAncestorMaskLayerAt(i
)->AsShadowableLayer());
665 common
.ancestorMaskLayers().AppendElement(layer
);
668 mutant
->GetDisplayListLog(log
);
669 common
.displayListLog() = log
;
671 attrs
.specific() = null_t();
672 mutant
->FillSpecificAttributes(attrs
.specific());
674 MOZ_LAYERS_LOG(("[LayersForwarder] OpSetLayerAttributes(%p)\n", mutant
));
676 setAttrs
.AppendElement(op
);
679 if (mTxn
->mCset
.IsEmpty() && mTxn
->mPaints
.IsEmpty() && setAttrs
.IsEmpty() &&
680 !mTxn
->RotationChanged()) {
684 info
.cset() = std::move(mTxn
->mCset
);
685 info
.setSimpleAttrs() = std::move(setSimpleAttrs
);
686 info
.setAttrs() = std::move(setAttrs
);
687 info
.paints() = std::move(mTxn
->mPaints
);
688 info
.toDestroy() = mTxn
->mDestroyedActors
.Clone();
689 info
.fwdTransactionId() = GetFwdTransactionId();
691 info
.plugins() = mPluginWindowData
.Clone();
692 info
.isFirstPaint() = mIsFirstPaint
;
693 info
.focusTarget() = mFocusTarget
;
694 info
.scheduleComposite() = aScheduleComposite
;
695 info
.paintSequenceNumber() = aPaintSequenceNumber
;
696 info
.isRepeatTransaction() = aIsRepeatTransaction
;
697 info
.vsyncId() = aVsyncId
;
698 info
.vsyncStart() = aVsyncStart
;
699 info
.refreshStart() = aRefreshStart
;
700 info
.transactionStart() = aTransactionStart
;
702 info
.containsSVG() = aContainsSVG
;
703 #if defined(ENABLE_FRAME_LATENCY_LOG)
704 info
.fwdTime() = TimeStamp::Now();
706 info
.payload() = aPayload
.Clone();
708 TargetConfig
targetConfig(mTxn
->mTargetBounds
, mTxn
->mTargetRotation
,
709 mTxn
->mTargetOrientation
, aRegionToClear
);
710 info
.targetConfig() = targetConfig
;
712 if (!GetTextureForwarder()->IsSameProcess()) {
713 MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send..."));
714 PlatformSyncBeforeUpdate();
718 mPaintTiming
.serializeMs() =
719 (TimeStamp::Now() - startTime
.value()).ToMilliseconds();
720 startTime
= Some(TimeStamp::Now());
723 // We delay at the last possible minute, to give the paint thread a chance to
724 // finish. If it does we don't have to delay messages at all.
725 GetCompositorBridgeChild()->PostponeMessagesIfAsyncPainting();
727 MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
728 RenderTraceScope
rendertrace3("Forward Transaction", "000093");
729 if (!mShadowManager
->SendUpdate(info
)) {
730 MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
735 mPaintTiming
.sendMs() =
736 (TimeStamp::Now() - startTime
.value()).ToMilliseconds();
737 mShadowManager
->SendRecordPaintTimes(mPaintTiming
);
741 mIsFirstPaint
= false;
742 mFocusTarget
= FocusTarget();
743 MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
747 RefPtr
<CompositableClient
> ShadowLayerForwarder::FindCompositable(
748 const CompositableHandle
& aHandle
) {
749 CompositableClient
* client
= nullptr;
750 if (!mCompositables
.Get(aHandle
.Value(), &client
)) {
756 void ShadowLayerForwarder::SetLayersObserverEpoch(LayersObserverEpoch aEpoch
) {
760 Unused
<< mShadowManager
->SendSetLayersObserverEpoch(aEpoch
);
763 void ShadowLayerForwarder::UpdateTextureLocks() {
769 auto compositorBridge
= GetCompositorBridgeChild();
770 if (compositorBridge
) {
771 auto pid
= compositorBridge
->OtherPid();
772 TextureSync::UpdateTextureLocks(pid
);
777 void ShadowLayerForwarder::SyncTextures(const nsTArray
<uint64_t>& aSerials
) {
783 auto compositorBridge
= GetCompositorBridgeChild();
784 if (compositorBridge
) {
785 auto pid
= compositorBridge
->OtherPid();
786 TextureSync::WaitForTextures(pid
, aSerials
);
791 void ShadowLayerForwarder::ReleaseLayer(const LayerHandle
& aHandle
) {
795 Unused
<< mShadowManager
->SendReleaseLayer(aHandle
);
798 bool ShadowLayerForwarder::IPCOpen() const {
799 return HasShadowManager() && mShadowManager
->IPCOpen();
803 * We bail out when we have no shadow manager. That can happen when the
804 * layer manager is created by the preallocated process.
805 * See bug 914843 for details.
807 LayerHandle
ShadowLayerForwarder::ConstructShadowFor(ShadowableLayer
* aLayer
) {
808 return LayerHandle(mNextLayerHandle
++);
811 #if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
814 void ShadowLayerForwarder::PlatformSyncBeforeUpdate() {}
816 #endif // !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
818 void ShadowLayerForwarder::Connect(CompositableClient
* aCompositable
,
819 ImageContainer
* aImageContainer
) {
820 #ifdef GFX_COMPOSITOR_LOGGING
821 printf("ShadowLayerForwarder::Connect(Compositable)\n");
823 MOZ_ASSERT(aCompositable
);
824 MOZ_ASSERT(mShadowManager
);
829 static uint64_t sNextID
= 1;
830 uint64_t id
= sNextID
++;
832 mCompositables
.Put(id
, aCompositable
);
834 CompositableHandle
handle(id
);
835 aCompositable
->InitIPDL(handle
);
836 mShadowManager
->SendNewCompositable(handle
, aCompositable
->GetTextureInfo());
839 void ShadowLayerForwarder::Attach(CompositableClient
* aCompositable
,
840 ShadowableLayer
* aLayer
) {
842 MOZ_ASSERT(aCompositable
);
844 OpAttachCompositable(Shadow(aLayer
), aCompositable
->GetIPCHandle()));
847 void ShadowLayerForwarder::AttachAsyncCompositable(
848 const CompositableHandle
& aHandle
, ShadowableLayer
* aLayer
) {
851 mTxn
->AddEdit(OpAttachAsyncCompositable(Shadow(aLayer
), aHandle
));
854 void ShadowLayerForwarder::SetShadowManager(
855 PLayerTransactionChild
* aShadowManager
) {
856 mShadowManager
= static_cast<LayerTransactionChild
*>(aShadowManager
);
857 mShadowManager
->SetForwarder(this);
860 void ShadowLayerForwarder::StopReceiveAsyncParentMessge() {
864 mShadowManager
->SetForwarder(nullptr);
867 void ShadowLayerForwarder::ClearCachedResources() {
871 mShadowManager
->SendClearCachedResources();
874 void ShadowLayerForwarder::ScheduleComposite() {
878 mShadowManager
->SendScheduleComposite();
881 bool IsSurfaceDescriptorValid(const SurfaceDescriptor
& aSurface
) {
882 return aSurface
.type() != SurfaceDescriptor::T__None
&&
883 aSurface
.type() != SurfaceDescriptor::Tnull_t
;
886 uint8_t* GetAddressFromDescriptor(const SurfaceDescriptor
& aDescriptor
) {
887 MOZ_ASSERT(IsSurfaceDescriptorValid(aDescriptor
));
889 aDescriptor
.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer
,
890 "GFX: surface descriptor is not the right type.");
892 auto memOrShmem
= aDescriptor
.get_SurfaceDescriptorBuffer().data();
893 if (memOrShmem
.type() == MemoryOrShmem::TShmem
) {
894 return memOrShmem
.get_Shmem().get
<uint8_t>();
896 return reinterpret_cast<uint8_t*>(memOrShmem
.get_uintptr_t());
900 already_AddRefed
<gfx::DataSourceSurface
> GetSurfaceForDescriptor(
901 const SurfaceDescriptor
& aDescriptor
) {
902 if (aDescriptor
.type() != SurfaceDescriptor::TSurfaceDescriptorBuffer
) {
905 uint8_t* data
= GetAddressFromDescriptor(aDescriptor
);
907 aDescriptor
.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
908 uint32_t stride
= ImageDataSerializer::GetRGBStride(rgb
);
909 return gfx::Factory::CreateWrappingDataSourceSurface(data
, stride
, rgb
.size(),
913 already_AddRefed
<gfx::DrawTarget
> GetDrawTargetForDescriptor(
914 const SurfaceDescriptor
& aDescriptor
) {
915 uint8_t* data
= GetAddressFromDescriptor(aDescriptor
);
917 aDescriptor
.get_SurfaceDescriptorBuffer().desc().get_RGBDescriptor();
918 uint32_t stride
= ImageDataSerializer::GetRGBStride(rgb
);
919 return gfx::Factory::CreateDrawTargetForData(
920 gfx::BackendType::SKIA
, data
, rgb
.size(), stride
, rgb
.format());
923 void DestroySurfaceDescriptor(IShmemAllocator
* aAllocator
,
924 SurfaceDescriptor
* aSurface
) {
925 MOZ_ASSERT(aSurface
);
927 SurfaceDescriptorBuffer
& desc
= aSurface
->get_SurfaceDescriptorBuffer();
928 switch (desc
.data().type()) {
929 case MemoryOrShmem::TShmem
: {
930 aAllocator
->DeallocShmem(desc
.data().get_Shmem());
933 case MemoryOrShmem::Tuintptr_t
: {
934 uint8_t* ptr
= (uint8_t*)desc
.data().get_uintptr_t();
935 GfxMemoryImageReporter::WillFree(ptr
);
940 MOZ_CRASH("surface type not implemented!");
942 *aSurface
= SurfaceDescriptor();
945 bool ShadowLayerForwarder::AllocSurfaceDescriptor(const gfx::IntSize
& aSize
,
946 gfxContentType aContent
,
947 SurfaceDescriptor
* aBuffer
) {
951 return AllocSurfaceDescriptorWithCaps(aSize
, aContent
, DEFAULT_BUFFER_CAPS
,
955 bool ShadowLayerForwarder::AllocSurfaceDescriptorWithCaps(
956 const gfx::IntSize
& aSize
, gfxContentType aContent
, uint32_t aCaps
,
957 SurfaceDescriptor
* aBuffer
) {
961 gfx::SurfaceFormat format
=
962 gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aContent
);
963 size_t size
= ImageDataSerializer::ComputeRGBBufferSize(aSize
, format
);
968 MemoryOrShmem bufferDesc
;
969 if (GetTextureForwarder()->IsSameProcess()) {
970 uint8_t* data
= new (std::nothrow
) uint8_t[size
];
974 GfxMemoryImageReporter::DidAlloc(data
);
975 memset(data
, 0, size
);
976 bufferDesc
= reinterpret_cast<uintptr_t>(data
);
978 mozilla::ipc::Shmem shmem
;
979 if (!GetTextureForwarder()->AllocUnsafeShmem(size
, OptimalShmemType(),
984 bufferDesc
= std::move(shmem
);
987 // Use an intermediate buffer by default. Skipping the intermediate buffer is
988 // only possible in certain configurations so let's keep it simple here for
990 const bool hasIntermediateBuffer
= true;
991 *aBuffer
= SurfaceDescriptorBuffer(
992 RGBDescriptor(aSize
, format
, hasIntermediateBuffer
), bufferDesc
);
998 bool ShadowLayerForwarder::IsShmem(SurfaceDescriptor
* aSurface
) {
1000 (aSurface
->type() == SurfaceDescriptor::TSurfaceDescriptorBuffer
) &&
1001 (aSurface
->get_SurfaceDescriptorBuffer().data().type() ==
1002 MemoryOrShmem::TShmem
);
1005 void ShadowLayerForwarder::DestroySurfaceDescriptor(
1006 SurfaceDescriptor
* aSurface
) {
1007 MOZ_ASSERT(aSurface
);
1008 MOZ_ASSERT(IPCOpen());
1009 if (!IPCOpen() || !aSurface
) {
1013 ::mozilla::layers::DestroySurfaceDescriptor(GetTextureForwarder(), aSurface
);
1016 void ShadowLayerForwarder::UpdateFwdTransactionId() {
1017 auto compositorBridge
= GetCompositorBridgeChild();
1018 if (compositorBridge
) {
1019 compositorBridge
->UpdateFwdTransactionId();
1023 uint64_t ShadowLayerForwarder::GetFwdTransactionId() {
1024 auto compositorBridge
= GetCompositorBridgeChild();
1025 MOZ_DIAGNOSTIC_ASSERT(compositorBridge
);
1026 return compositorBridge
? compositorBridge
->GetFwdTransactionId() : 0;
1029 CompositorBridgeChild
* ShadowLayerForwarder::GetCompositorBridgeChild() {
1030 if (mCompositorBridgeChild
) {
1031 return mCompositorBridgeChild
;
1033 if (!mShadowManager
) {
1036 mCompositorBridgeChild
=
1037 static_cast<CompositorBridgeChild
*>(mShadowManager
->Manager());
1038 return mCompositorBridgeChild
;
1041 void ShadowLayerForwarder::SyncWithCompositor() {
1042 auto compositorBridge
= GetCompositorBridgeChild();
1043 if (compositorBridge
&& compositorBridge
->IPCOpen()) {
1044 compositorBridge
->SendSyncWithCompositor();
1048 void ShadowLayerForwarder::ReleaseCompositable(
1049 const CompositableHandle
& aHandle
) {
1050 AssertInForwarderThread();
1051 if (!DestroyInTransaction(aHandle
)) {
1055 mShadowManager
->SendReleaseCompositable(aHandle
);
1057 mCompositables
.Remove(aHandle
.Value());
1060 void ShadowLayerForwarder::SynchronouslyShutdown() {
1062 mShadowManager
->SendShutdownSync();
1063 mShadowManager
->MarkDestroyed();
1067 ShadowableLayer::~ShadowableLayer() {
1069 mForwarder
->ReleaseLayer(GetShadow());
1073 } // namespace layers
1074 } // namespace mozilla