LCOV - code coverage report
Current view: top level - gfx/layers/ipc - ShadowLayers.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 309 562 55.0 %
Date: 2017-07-14 16:53:18 Functions: 52 92 56.5 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13