LCOV - code coverage report
Current view: top level - gfx/layers/ipc - LayerTransactionParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 228 522 43.7 %
Date: 2017-07-14 16:53:18 Functions: 19 47 40.4 %
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 "LayerTransactionParent.h"
       9             : #include <vector>                       // for vector
      10             : #include "apz/src/AsyncPanZoomController.h"
      11             : #include "CompositableHost.h"           // for CompositableParent, Get, etc
      12             : #include "ImageLayers.h"                // for ImageLayer
      13             : #include "Layers.h"                     // for Layer, ContainerLayer, etc
      14             : #include "CompositableTransactionParent.h"  // for EditReplyVector
      15             : #include "CompositorBridgeParent.h"
      16             : #include "gfxPrefs.h"
      17             : #include "mozilla/gfx/BasePoint3D.h"    // for BasePoint3D
      18             : #include "mozilla/layers/AnimationHelper.h" // for GetAnimatedPropValue
      19             : #include "mozilla/layers/CanvasLayerComposite.h"
      20             : #include "mozilla/layers/ColorLayerComposite.h"
      21             : #include "mozilla/layers/Compositor.h"  // for Compositor
      22             : #include "mozilla/layers/ContainerLayerComposite.h"
      23             : #include "mozilla/layers/ImageBridgeParent.h" // for ImageBridgeParent
      24             : #include "mozilla/layers/ImageLayerComposite.h"
      25             : #include "mozilla/layers/LayerManagerComposite.h"
      26             : #include "mozilla/layers/LayersMessages.h"  // for EditReply, etc
      27             : #include "mozilla/layers/LayersTypes.h"  // for MOZ_LAYERS_LOG
      28             : #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
      29             : #include "mozilla/layers/PaintedLayerComposite.h"
      30             : #include "mozilla/mozalloc.h"           // for operator delete, etc
      31             : #include "mozilla/SizePrintfMacros.h"
      32             : #include "mozilla/Unused.h"
      33             : #include "nsCoord.h"                    // for NSAppUnitsToFloatPixels
      34             : #include "nsDebug.h"                    // for NS_RUNTIMEABORT
      35             : #include "nsISupportsImpl.h"            // for Layer::Release, etc
      36             : #include "nsLayoutUtils.h"              // for nsLayoutUtils
      37             : #include "nsMathUtils.h"                // for NS_round
      38             : #include "nsPoint.h"                    // for nsPoint
      39             : #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
      40             : #include "TreeTraversal.h"              // for ForEachNode
      41             : #include "GeckoProfiler.h"
      42             : #include "mozilla/layers/TextureHost.h"
      43             : #include "mozilla/layers/AsyncCompositionManager.h"
      44             : 
      45             : using mozilla::layout::RenderFrameParent;
      46             : 
      47             : namespace mozilla {
      48             : namespace layers {
      49             : 
      50             : //--------------------------------------------------
      51             : // LayerTransactionParent
      52           2 : LayerTransactionParent::LayerTransactionParent(HostLayerManager* aManager,
      53             :                                                CompositorBridgeParentBase* aBridge,
      54             :                                                CompositorAnimationStorage* aAnimStorage,
      55           2 :                                                uint64_t aId)
      56             :   : mLayerManager(aManager)
      57             :   , mCompositorBridge(aBridge)
      58             :   , mAnimStorage(aAnimStorage)
      59             :   , mId(aId)
      60             :   , mChildEpoch(0)
      61             :   , mParentEpoch(0)
      62             :   , mPendingTransaction(0)
      63             :   , mDestroyed(false)
      64           2 :   , mIPCOpen(false)
      65             : {
      66           2 : }
      67             : 
      68           0 : LayerTransactionParent::~LayerTransactionParent()
      69             : {
      70           0 : }
      71             : 
      72             : void
      73           0 : LayerTransactionParent::SetLayerManager(HostLayerManager* aLayerManager, CompositorAnimationStorage* aAnimStorage)
      74             : {
      75           0 :   if (mDestroyed) {
      76           0 :     return;
      77             :   }
      78           0 :   mLayerManager = aLayerManager;
      79           0 :   for (auto iter = mLayerMap.Iter(); !iter.Done(); iter.Next()) {
      80           0 :     auto layer = iter.Data();
      81           0 :     if (mAnimStorage &&
      82           0 :         layer->GetCompositorAnimationsId()) {
      83           0 :       mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
      84             :     }
      85           0 :     layer->AsHostLayer()->SetLayerManager(aLayerManager);
      86             :   }
      87           0 :   mAnimStorage = aAnimStorage;
      88             : }
      89             : 
      90             : mozilla::ipc::IPCResult
      91           0 : LayerTransactionParent::RecvShutdown()
      92             : {
      93           0 :   Destroy();
      94           0 :   IProtocol* mgr = Manager();
      95           0 :   if (!Send__delete__(this)) {
      96           0 :     return IPC_FAIL_NO_REASON(mgr);
      97             :   }
      98           0 :   return IPC_OK();
      99             : }
     100             : 
     101             : mozilla::ipc::IPCResult
     102           0 : LayerTransactionParent::RecvShutdownSync()
     103             : {
     104           0 :   return RecvShutdown();
     105             : }
     106             : 
     107             : void
     108           0 : LayerTransactionParent::Destroy()
     109             : {
     110           0 :   if (mDestroyed) {
     111           0 :     return;
     112             :   }
     113           0 :   mDestroyed = true;
     114           0 :   if (mAnimStorage) {
     115           0 :     for (auto iter = mLayerMap.Iter(); !iter.Done(); iter.Next()) {
     116           0 :       auto layer = iter.Data();
     117           0 :       if (layer->GetCompositorAnimationsId()) {
     118           0 :         mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
     119             :       }
     120             :     }
     121             :   }
     122           0 :   mCompositables.clear();
     123           0 :   mAnimStorage = nullptr;
     124             : }
     125             : 
     126             : class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender
     127             : {
     128             : public:
     129          28 :   explicit AutoLayerTransactionParentAsyncMessageSender(LayerTransactionParent* aLayerTransaction,
     130             :                                                         const InfallibleTArray<OpDestroy>* aDestroyActors = nullptr)
     131          28 :     : mLayerTransaction(aLayerTransaction)
     132          28 :     , mActorsToDestroy(aDestroyActors)
     133             :   {
     134          28 :     mLayerTransaction->SetAboutToSendAsyncMessages();
     135          28 :   }
     136             : 
     137          28 :   ~AutoLayerTransactionParentAsyncMessageSender()
     138          28 :   {
     139          28 :     mLayerTransaction->SendPendingAsyncMessages();
     140          28 :     if (mActorsToDestroy) {
     141             :       // Destroy the actors after sending the async messages because the latter may contain
     142             :       // references to some actors.
     143          30 :       for (const auto& op : *mActorsToDestroy) {
     144           2 :         mLayerTransaction->DestroyActor(op);
     145             :       }
     146             :     }
     147          28 :   }
     148             : private:
     149             :   LayerTransactionParent* mLayerTransaction;
     150             :   const InfallibleTArray<OpDestroy>* mActorsToDestroy;
     151             : };
     152             : 
     153             : mozilla::ipc::IPCResult
     154           0 : LayerTransactionParent::RecvPaintTime(const uint64_t& aTransactionId,
     155             :                                       const TimeDuration& aPaintTime)
     156             : {
     157           0 :   mCompositorBridge->UpdatePaintTime(this, aPaintTime);
     158           0 :   return IPC_OK();
     159             : }
     160             : 
     161             : mozilla::ipc::IPCResult
     162          24 : LayerTransactionParent::RecvInitReadLocks(ReadLockArray&& aReadLocks)
     163             : {
     164          24 :   if (!AddReadLocks(Move(aReadLocks))) {
     165           0 :     return IPC_FAIL_NO_REASON(this);
     166             :   }
     167          24 :   return IPC_OK();
     168             : }
     169             : 
     170             : mozilla::ipc::IPCResult
     171          28 : LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
     172             : {
     173          56 :   AutoProfilerTracing tracing("Paint", "LayerTransaction");
     174          56 :   AUTO_PROFILER_LABEL("LayerTransactionParent::RecvUpdate", GRAPHICS);
     175             : 
     176          28 :   TimeStamp updateStart = TimeStamp::Now();
     177             : 
     178          28 :   MOZ_LAYERS_LOG(("[ParentSide] received txn with %" PRIuSIZE " edits", aInfo.cset().Length()));
     179             : 
     180          28 :   UpdateFwdTransactionId(aInfo.fwdTransactionId());
     181          56 :   AutoClearReadLocks clearLocks(mReadLocks);
     182             : 
     183          28 :   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
     184           0 :     for (const auto& op : aInfo.toDestroy()) {
     185           0 :       DestroyActor(op);
     186             :     }
     187           0 :     return IPC_OK();
     188             :   }
     189             : 
     190             :   // This ensures that destroy operations are always processed. It is not safe
     191             :   // to early-return from RecvUpdate without doing so.
     192          56 :   AutoLayerTransactionParentAsyncMessageSender autoAsyncMessageSender(this, &aInfo.toDestroy());
     193             : 
     194             :   {
     195          56 :     AutoResolveRefLayers resolve(mCompositorBridge->GetCompositionManager(this));
     196          28 :     layer_manager()->BeginTransaction();
     197             :   }
     198             : 
     199             :   // Not all edits require an update to the hit testing tree.
     200          28 :   mUpdateHitTestingTree = false;
     201             : 
     202         165 :   for (EditArray::index_type i = 0; i < aInfo.cset().Length(); ++i) {
     203         137 :     const Edit& edit = const_cast<Edit&>(aInfo.cset()[i]);
     204             : 
     205         137 :     switch (edit.type()) {
     206             :     // Create* ops
     207             :     case Edit::TOpCreatePaintedLayer: {
     208          22 :       MOZ_LAYERS_LOG(("[ParentSide] CreatePaintedLayer"));
     209             : 
     210          22 :       RefPtr<PaintedLayer> layer = layer_manager()->CreatePaintedLayer();
     211          22 :       if (!BindLayer(layer, edit.get_OpCreatePaintedLayer())) {
     212           0 :         return IPC_FAIL_NO_REASON(this);
     213             :       }
     214             : 
     215          22 :       UpdateHitTestingTree(layer, "CreatePaintedLayer");
     216          22 :       break;
     217             :     }
     218             :     case Edit::TOpCreateContainerLayer: {
     219           4 :       MOZ_LAYERS_LOG(("[ParentSide] CreateContainerLayer"));
     220             : 
     221           4 :       RefPtr<ContainerLayer> layer = layer_manager()->CreateContainerLayer();
     222           4 :       if (!BindLayer(layer, edit.get_OpCreateContainerLayer())) {
     223           0 :         return IPC_FAIL_NO_REASON(this);
     224             :       }
     225             : 
     226           4 :       UpdateHitTestingTree(layer, "CreateContainerLayer");
     227           4 :       break;
     228             :     }
     229             :     case Edit::TOpCreateImageLayer: {
     230           0 :       MOZ_LAYERS_LOG(("[ParentSide] CreateImageLayer"));
     231             : 
     232           0 :       RefPtr<ImageLayer> layer = layer_manager()->CreateImageLayer();
     233           0 :       if (!BindLayer(layer, edit.get_OpCreateImageLayer())) {
     234           0 :         return IPC_FAIL_NO_REASON(this);
     235             :       }
     236             : 
     237           0 :       UpdateHitTestingTree(layer, "CreateImageLayer");
     238           0 :       break;
     239             :     }
     240             :     case Edit::TOpCreateColorLayer: {
     241           4 :       MOZ_LAYERS_LOG(("[ParentSide] CreateColorLayer"));
     242             : 
     243           4 :       RefPtr<ColorLayer> layer = layer_manager()->CreateColorLayer();
     244           4 :       if (!BindLayer(layer, edit.get_OpCreateColorLayer())) {
     245           0 :         return IPC_FAIL_NO_REASON(this);
     246             :       }
     247             : 
     248           4 :       UpdateHitTestingTree(layer, "CreateColorLayer");
     249           4 :       break;
     250             :     }
     251             :     case Edit::TOpCreateTextLayer: {
     252           0 :       MOZ_LAYERS_LOG(("[ParentSide] CreateTextLayer"));
     253             : 
     254           0 :       RefPtr<TextLayer> layer = layer_manager()->CreateTextLayer();
     255           0 :       if (!BindLayer(layer, edit.get_OpCreateTextLayer())) {
     256           0 :         return IPC_FAIL_NO_REASON(this);
     257             :       }
     258             : 
     259           0 :       UpdateHitTestingTree(layer, "CreateTextLayer");
     260           0 :       break;
     261             :     }
     262             :     case Edit::TOpCreateBorderLayer: {
     263           0 :       MOZ_LAYERS_LOG(("[ParentSide] CreateBorderLayer"));
     264             : 
     265           0 :       RefPtr<BorderLayer> layer = layer_manager()->CreateBorderLayer();
     266           0 :       if (!BindLayer(layer, edit.get_OpCreateBorderLayer())) {
     267           0 :         return IPC_FAIL_NO_REASON(this);
     268             :       }
     269             : 
     270           0 :       UpdateHitTestingTree(layer, "CreateBorderLayer");
     271           0 :       break;
     272             :     }
     273             :     case Edit::TOpCreateCanvasLayer: {
     274           0 :       MOZ_LAYERS_LOG(("[ParentSide] CreateCanvasLayer"));
     275             : 
     276           0 :       RefPtr<CanvasLayer> layer = layer_manager()->CreateCanvasLayer();
     277           0 :       if (!BindLayer(layer, edit.get_OpCreateCanvasLayer())) {
     278           0 :         return IPC_FAIL_NO_REASON(this);
     279             :       }
     280             : 
     281           0 :       UpdateHitTestingTree(layer, "CreateCanvasLayer");
     282           0 :       break;
     283             :     }
     284             :     case Edit::TOpCreateRefLayer: {
     285           1 :       MOZ_LAYERS_LOG(("[ParentSide] CreateRefLayer"));
     286             : 
     287           1 :       RefPtr<RefLayer> layer = layer_manager()->CreateRefLayer();
     288           1 :       if (!BindLayer(layer, edit.get_OpCreateRefLayer())) {
     289           0 :         return IPC_FAIL_NO_REASON(this);
     290             :       }
     291             : 
     292           1 :       UpdateHitTestingTree(layer, "CreateRefLayer");
     293           1 :       break;
     294             :     }
     295             :     case Edit::TOpSetDiagnosticTypes: {
     296           0 :       mLayerManager->SetDiagnosticTypes(edit.get_OpSetDiagnosticTypes().diagnostics());
     297           0 :       break;
     298             :     }
     299             :     case Edit::TOpWindowOverlayChanged: {
     300           0 :       mLayerManager->SetWindowOverlayChanged();
     301           0 :       break;
     302             :     }
     303             :     // Tree ops
     304             :     case Edit::TOpSetRoot: {
     305           4 :       MOZ_LAYERS_LOG(("[ParentSide] SetRoot"));
     306             : 
     307           4 :       Layer* newRoot = AsLayer(edit.get_OpSetRoot().root());
     308           4 :       if (!newRoot) {
     309           0 :         return IPC_FAIL_NO_REASON(this);
     310             :       }
     311           4 :       if (newRoot->GetParent()) {
     312             :         // newRoot is not a root!
     313           0 :         return IPC_FAIL_NO_REASON(this);
     314             :       }
     315           4 :       mRoot = newRoot;
     316             : 
     317           4 :       UpdateHitTestingTree(mRoot, "SetRoot");
     318           4 :       break;
     319             :     }
     320             :     case Edit::TOpInsertAfter: {
     321          23 :       MOZ_LAYERS_LOG(("[ParentSide] InsertAfter"));
     322             : 
     323          23 :       const OpInsertAfter& oia = edit.get_OpInsertAfter();
     324          23 :       Layer* child = AsLayer(oia.childLayer());
     325          23 :       Layer* layer = AsLayer(oia.container());
     326          23 :       Layer* after = AsLayer(oia.after());
     327          23 :       if (!child || !layer || !after) {
     328           0 :         return IPC_FAIL_NO_REASON(this);
     329             :       }
     330          23 :       ContainerLayer* container = layer->AsContainerLayer();
     331          23 :       if (!container || !container->InsertAfter(child, after)) {
     332           0 :         return IPC_FAIL_NO_REASON(this);
     333             :       }
     334             : 
     335          23 :       UpdateHitTestingTree(layer, "InsertAfter");
     336          23 :       break;
     337             :     }
     338             :     case Edit::TOpPrependChild: {
     339           4 :       MOZ_LAYERS_LOG(("[ParentSide] PrependChild"));
     340             : 
     341           4 :       const OpPrependChild& oac = edit.get_OpPrependChild();
     342           4 :       Layer* child = AsLayer(oac.childLayer());
     343           4 :       Layer* layer = AsLayer(oac.container());
     344           4 :       if (!child || !layer) {
     345           0 :         return IPC_FAIL_NO_REASON(this);
     346             :       }
     347           4 :       ContainerLayer* container = layer->AsContainerLayer();
     348           4 :       if (!container || !container->InsertAfter(child, nullptr)) {
     349           0 :         return IPC_FAIL_NO_REASON(this);
     350             :       }
     351             : 
     352           4 :       UpdateHitTestingTree(layer, "PrependChild");
     353           4 :       break;
     354             :     }
     355             :     case Edit::TOpRemoveChild: {
     356          20 :       MOZ_LAYERS_LOG(("[ParentSide] RemoveChild"));
     357             : 
     358          20 :       const OpRemoveChild& orc = edit.get_OpRemoveChild();
     359          20 :       Layer* childLayer = AsLayer(orc.childLayer());
     360          20 :       Layer* layer = AsLayer(orc.container());
     361          20 :       if (!childLayer || !layer) {
     362           0 :         return IPC_FAIL_NO_REASON(this);
     363             :       }
     364          20 :       ContainerLayer* container = layer->AsContainerLayer();
     365          20 :       if (!container || !container->RemoveChild(childLayer)) {
     366           0 :         return IPC_FAIL_NO_REASON(this);
     367             :       }
     368             : 
     369          20 :       UpdateHitTestingTree(layer, "RemoveChild");
     370          20 :       break;
     371             :     }
     372             :     case Edit::TOpRepositionChild: {
     373           0 :       MOZ_LAYERS_LOG(("[ParentSide] RepositionChild"));
     374             : 
     375           0 :       const OpRepositionChild& orc = edit.get_OpRepositionChild();
     376           0 :       Layer* child = AsLayer(orc.childLayer());
     377           0 :       Layer* after = AsLayer(orc.after());
     378           0 :       Layer* layer = AsLayer(orc.container());
     379           0 :       if (!child || !layer || !after) {
     380           0 :         return IPC_FAIL_NO_REASON(this);
     381             :       }
     382           0 :       ContainerLayer* container = layer->AsContainerLayer();
     383           0 :       if (!container || !container->RepositionChild(child, after)) {
     384           0 :         return IPC_FAIL_NO_REASON(this);
     385             :       }
     386             : 
     387           0 :       UpdateHitTestingTree(layer, "RepositionChild");
     388           0 :       break;
     389             :     }
     390             :     case Edit::TOpRaiseToTopChild: {
     391           0 :       MOZ_LAYERS_LOG(("[ParentSide] RaiseToTopChild"));
     392             : 
     393           0 :       const OpRaiseToTopChild& rtc = edit.get_OpRaiseToTopChild();
     394           0 :       Layer* child = AsLayer(rtc.childLayer());
     395           0 :       if (!child) {
     396           0 :         return IPC_FAIL_NO_REASON(this);
     397             :       }
     398           0 :       Layer* layer = AsLayer(rtc.container());
     399           0 :       if (!layer) {
     400           0 :         return IPC_FAIL_NO_REASON(this);
     401             :       }
     402           0 :       ContainerLayer* container = layer->AsContainerLayer();
     403           0 :       if (!container || !container->RepositionChild(child, nullptr)) {
     404           0 :         return IPC_FAIL_NO_REASON(this);
     405             :       }
     406             : 
     407           0 :       UpdateHitTestingTree(layer, "RaiseToTopChild");
     408           0 :       break;
     409             :     }
     410             :     case Edit::TCompositableOperation: {
     411          33 :       if (!ReceiveCompositableUpdate(edit.get_CompositableOperation())) {
     412           0 :         return IPC_FAIL_NO_REASON(this);
     413             :       }
     414          33 :       break;
     415             :     }
     416             :     case Edit::TOpAttachCompositable: {
     417          22 :       const OpAttachCompositable& op = edit.get_OpAttachCompositable();
     418          22 :       RefPtr<CompositableHost> host = FindCompositable(op.compositable());
     419          22 :       if (!Attach(AsLayer(op.layer()), host, false)) {
     420           0 :         return IPC_FAIL_NO_REASON(this);
     421             :       }
     422          22 :       host->SetCompositorBridgeID(mLayerManager->GetCompositorBridgeID());
     423          22 :       break;
     424             :     }
     425             :     case Edit::TOpAttachAsyncCompositable: {
     426           0 :       const OpAttachAsyncCompositable& op = edit.get_OpAttachAsyncCompositable();
     427           0 :       RefPtr<ImageBridgeParent> imageBridge = ImageBridgeParent::GetInstance(OtherPid());
     428           0 :       if (!imageBridge) {
     429           0 :         return IPC_FAIL_NO_REASON(this);
     430             :       }
     431           0 :       RefPtr<CompositableHost> host = imageBridge->FindCompositable(op.compositable());
     432           0 :       if (!host) {
     433             :         // This normally should not happen, but can after a GPU process crash.
     434             :         // Media may not have had time to update the ImageContainer associated
     435             :         // with a video frame, and we may try to attach a stale CompositableHandle.
     436             :         // Rather than break the whole transaction, we just continue.
     437           0 :         gfxCriticalNote << "CompositableHost " << op.compositable().Value() << " not found";
     438           0 :         continue;
     439             :       }
     440           0 :       if (!Attach(AsLayer(op.layer()), host, true)) {
     441           0 :         return IPC_FAIL_NO_REASON(this);
     442             :       }
     443           0 :       host->SetCompositorBridgeID(mLayerManager->GetCompositorBridgeID());
     444           0 :       break;
     445             :     }
     446             :     default:
     447           0 :       MOZ_CRASH("not reached");
     448             :     }
     449             :   }
     450             : 
     451             :   // Process simple attribute updates.
     452          52 :   for (const auto& op : aInfo.setSimpleAttrs()) {
     453          24 :     MOZ_LAYERS_LOG(("[ParentSide] SetSimpleLayerAttributes"));
     454          24 :     Layer* layer = AsLayer(op.layer());
     455          24 :     if (!layer) {
     456           0 :       return IPC_FAIL_NO_REASON(this);
     457             :     }
     458          24 :     const SimpleLayerAttributes& attrs = op.attrs();
     459          24 :     const SimpleLayerAttributes& orig = layer->GetSimpleAttributes();
     460          24 :     if (!attrs.HitTestingInfoIsEqual(orig)) {
     461           1 :       UpdateHitTestingTree(layer, "scrolling info changed");
     462             :     }
     463          24 :     layer->SetSimpleAttributes(op.attrs());
     464             :   }
     465             : 
     466             :   // Process attribute updates.
     467         152 :   for (const auto& op : aInfo.setAttrs()) {
     468         124 :     MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes"));
     469         124 :     if (!SetLayerAttributes(op)) {
     470           0 :       return IPC_FAIL_NO_REASON(this);
     471             :     }
     472             :   }
     473             : 
     474             :   // Process paints separately, after all normal edits.
     475          61 :   for (const auto& op : aInfo.paints()) {
     476          33 :     if (!ReceiveCompositableUpdate(op)) {
     477           0 :       return IPC_FAIL_NO_REASON(this);
     478             :     }
     479             :   }
     480             : 
     481          28 :   mCompositorBridge->ShadowLayersUpdated(this, aInfo, mUpdateHitTestingTree);
     482             : 
     483             :   {
     484          56 :     AutoResolveRefLayers resolve(mCompositorBridge->GetCompositionManager(this));
     485          28 :     layer_manager()->EndTransaction(TimeStamp(), LayerManager::END_NO_IMMEDIATE_REDRAW);
     486             :   }
     487             : 
     488          28 :   if (!IsSameProcess()) {
     489             :     // Ensure that any pending operations involving back and front
     490             :     // buffers have completed, so that neither process stomps on the
     491             :     // other's buffer contents.
     492           4 :     LayerManagerComposite::PlatformSyncBeforeReplyUpdate();
     493             :   }
     494             : 
     495             : #ifdef COMPOSITOR_PERFORMANCE_WARNING
     496             :   int compositeTime = (int)(mozilla::TimeStamp::Now() - updateStart).ToMilliseconds();
     497             :   if (compositeTime > 15) {
     498             :     printf_stderr("Compositor: Layers update took %i ms (blocking gecko).\n", compositeTime);
     499             :   }
     500             : #endif
     501             : 
     502             :   // Enable visual warning for long transaction when draw FPS option is enabled
     503          28 :   bool drawFps = gfxPrefs::LayersDrawFPS();
     504          28 :   if (drawFps) {
     505           0 :     uint32_t visualWarningTrigger = gfxPrefs::LayerTransactionWarning();
     506             :     // The default theshold is 200ms to trigger, hit red when it take 4 times longer
     507           0 :     TimeDuration latency = TimeStamp::Now() - aInfo.transactionStart();
     508           0 :     if (latency > TimeDuration::FromMilliseconds(visualWarningTrigger)) {
     509           0 :       float severity = (latency - TimeDuration::FromMilliseconds(visualWarningTrigger)).ToMilliseconds() /
     510           0 :                          (4 * visualWarningTrigger);
     511           0 :       if (severity > 1.f) {
     512           0 :         severity = 1.f;
     513             :       }
     514           0 :       mLayerManager->VisualFrameWarning(severity);
     515           0 :       printf_stderr("LayerTransactionParent::RecvUpdate transaction from process %d took %f ms",
     516           0 :                     OtherPid(),
     517           0 :                     latency.ToMilliseconds());
     518             :     }
     519             : 
     520           0 :     mLayerManager->RecordUpdateTime((TimeStamp::Now() - updateStart).ToMilliseconds());
     521             :   }
     522             : 
     523          28 :   return IPC_OK();
     524             : }
     525             : 
     526             : bool
     527         124 : LayerTransactionParent::SetLayerAttributes(const OpSetLayerAttributes& aOp)
     528             : {
     529         124 :   Layer* layer = AsLayer(aOp.layer());
     530         124 :   if (!layer) {
     531           0 :     return false;
     532             :   }
     533             : 
     534         124 :   const LayerAttributes& attrs = aOp.attrs();
     535         124 :   const CommonLayerAttributes& common = attrs.common();
     536         124 :   if (common.visibleRegion() != layer->GetVisibleRegion()) {
     537          16 :     UpdateHitTestingTree(layer, "visible region changed");
     538          16 :     layer->SetVisibleRegion(common.visibleRegion());
     539             :   }
     540         124 :   if (common.eventRegions() != layer->GetEventRegions()) {
     541          24 :     UpdateHitTestingTree(layer, "event regions changed");
     542          24 :     layer->SetEventRegions(common.eventRegions());
     543             :   }
     544         248 :   Maybe<ParentLayerIntRect> clipRect = common.useClipRect() ? Some(common.clipRect()) : Nothing();
     545         124 :   if (clipRect != layer->GetClipRect()) {
     546           6 :     UpdateHitTestingTree(layer, "clip rect changed");
     547           6 :     layer->SetClipRect(clipRect);
     548             :   }
     549         124 :   if (LayerHandle maskLayer = common.maskLayer()) {
     550           0 :     layer->SetMaskLayer(AsLayer(maskLayer));
     551             :   } else {
     552         124 :     layer->SetMaskLayer(nullptr);
     553             :   }
     554         124 :   layer->SetCompositorAnimations(common.compositorAnimations());
     555             :   // Clean up the Animations by id in the CompositorAnimationStorage
     556             :   // if there are no active animations on the layer
     557         248 :   if (mAnimStorage &&
     558         124 :       layer->GetCompositorAnimationsId() &&
     559           0 :       layer->GetAnimations().IsEmpty()) {
     560           0 :     mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
     561             :   }
     562         124 :   if (common.scrollMetadata() != layer->GetAllScrollMetadata()) {
     563           8 :     UpdateHitTestingTree(layer, "scroll metadata changed");
     564           8 :     layer->SetScrollMetadata(common.scrollMetadata());
     565             :   }
     566         124 :   layer->SetDisplayListLog(common.displayListLog().get());
     567             : 
     568             :   // The updated invalid region is added to the existing one, since we can
     569             :   // update multiple times before the next composite.
     570         124 :   layer->AddInvalidRegion(common.invalidRegion());
     571             : 
     572         248 :   nsTArray<RefPtr<Layer>> maskLayers;
     573         124 :   for (size_t i = 0; i < common.ancestorMaskLayers().Length(); i++) {
     574           0 :     Layer* maskLayer = AsLayer(common.ancestorMaskLayers().ElementAt(i));
     575           0 :     if (!maskLayer) {
     576           0 :       return false;
     577             :     }
     578           0 :     maskLayers.AppendElement(maskLayer);
     579             :   }
     580         124 :   layer->SetAncestorMaskLayers(maskLayers);
     581             : 
     582             :   typedef SpecificLayerAttributes Specific;
     583         124 :   const SpecificLayerAttributes& specific = attrs.specific();
     584         124 :   switch (specific.type()) {
     585             :   case Specific::Tnull_t:
     586           0 :     break;
     587             : 
     588             :   case Specific::TPaintedLayerAttributes: {
     589          53 :     MOZ_LAYERS_LOG(("[ParentSide]   painted layer"));
     590             : 
     591          53 :     PaintedLayer* paintedLayer = layer->AsPaintedLayer();
     592          53 :     if (!paintedLayer) {
     593           0 :       return false;
     594             :     }
     595             :     const PaintedLayerAttributes& attrs =
     596          53 :       specific.get_PaintedLayerAttributes();
     597             : 
     598          53 :     paintedLayer->SetValidRegion(attrs.validRegion());
     599          53 :     break;
     600             :   }
     601             :   case Specific::TContainerLayerAttributes: {
     602          43 :     MOZ_LAYERS_LOG(("[ParentSide]   container layer"));
     603             : 
     604          43 :     ContainerLayer* containerLayer = layer->AsContainerLayer();
     605          43 :     if (!containerLayer) {
     606           0 :       return false;
     607             :     }
     608             :     const ContainerLayerAttributes& attrs =
     609          43 :       specific.get_ContainerLayerAttributes();
     610          43 :     containerLayer->SetPreScale(attrs.preXScale(), attrs.preYScale());
     611          43 :     containerLayer->SetInheritedScale(attrs.inheritedXScale(), attrs.inheritedYScale());
     612          43 :     containerLayer->SetScaleToResolution(attrs.scaleToResolution(),
     613          86 :                                          attrs.presShellResolution());
     614          43 :     if (attrs.eventRegionsOverride() != containerLayer->GetEventRegionsOverride()) {
     615           0 :       UpdateHitTestingTree(layer, "event regions override changed");
     616           0 :       containerLayer->SetEventRegionsOverride(attrs.eventRegionsOverride());
     617             :     }
     618          43 :     break;
     619             :   }
     620             :   case Specific::TColorLayerAttributes: {
     621           4 :     MOZ_LAYERS_LOG(("[ParentSide]   color layer"));
     622             : 
     623           4 :     ColorLayer* colorLayer = layer->AsColorLayer();
     624           4 :     if (!colorLayer) {
     625           0 :       return false;
     626             :     }
     627           4 :     colorLayer->SetColor(specific.get_ColorLayerAttributes().color().value());
     628           4 :     colorLayer->SetBounds(specific.get_ColorLayerAttributes().bounds());
     629           4 :     break;
     630             :   }
     631             :   case Specific::TTextLayerAttributes: {
     632           0 :     MOZ_LAYERS_LOG(("[ParentSide]   text layer"));
     633             : 
     634           0 :     TextLayer* textLayer = layer->AsTextLayer();
     635           0 :     if (!textLayer) {
     636           0 :       return false;
     637             :     }
     638           0 :     const auto& tla = specific.get_TextLayerAttributes();
     639           0 :     textLayer->SetBounds(tla.bounds());
     640           0 :     textLayer->SetGlyphs(Move(const_cast<nsTArray<GlyphArray>&>(tla.glyphs())));
     641           0 :     textLayer->SetScaledFont(reinterpret_cast<gfx::ScaledFont*>(tla.scaledFont()));
     642           0 :     break;
     643             :   }
     644             :   case Specific::TBorderLayerAttributes: {
     645           0 :     MOZ_LAYERS_LOG(("[ParentSide]   border layer"));
     646             : 
     647           0 :     BorderLayer* borderLayer = layer->AsBorderLayer();
     648           0 :     if (!borderLayer) {
     649           0 :       return false;
     650             :     }
     651           0 :     borderLayer->SetRect(specific.get_BorderLayerAttributes().rect());
     652           0 :     borderLayer->SetColors(specific.get_BorderLayerAttributes().colors());
     653           0 :     borderLayer->SetCornerRadii(specific.get_BorderLayerAttributes().corners());
     654           0 :     borderLayer->SetWidths(specific.get_BorderLayerAttributes().widths());
     655           0 :     break;
     656             :   }
     657             :   case Specific::TCanvasLayerAttributes: {
     658           0 :     MOZ_LAYERS_LOG(("[ParentSide]   canvas layer"));
     659             : 
     660           0 :     CanvasLayer* canvasLayer = layer->AsCanvasLayer();
     661           0 :     if (!canvasLayer) {
     662           0 :       return false;
     663             :     }
     664           0 :     canvasLayer->SetSamplingFilter(specific.get_CanvasLayerAttributes().samplingFilter());
     665           0 :     canvasLayer->SetBounds(specific.get_CanvasLayerAttributes().bounds());
     666           0 :     break;
     667             :   }
     668             :   case Specific::TRefLayerAttributes: {
     669          24 :     MOZ_LAYERS_LOG(("[ParentSide]   ref layer"));
     670             : 
     671          24 :     RefLayer* refLayer = layer->AsRefLayer();
     672          24 :     if (!refLayer) {
     673           0 :       return false;
     674             :     }
     675          24 :     refLayer->SetReferentId(specific.get_RefLayerAttributes().id());
     676          24 :     refLayer->SetEventRegionsOverride(specific.get_RefLayerAttributes().eventRegionsOverride());
     677          24 :     UpdateHitTestingTree(layer, "event regions override changed");
     678          24 :     break;
     679             :   }
     680             :   case Specific::TImageLayerAttributes: {
     681           0 :     MOZ_LAYERS_LOG(("[ParentSide]   image layer"));
     682             : 
     683           0 :     ImageLayer* imageLayer = layer->AsImageLayer();
     684           0 :     if (!imageLayer) {
     685           0 :       return false;
     686             :     }
     687           0 :     const ImageLayerAttributes& attrs = specific.get_ImageLayerAttributes();
     688           0 :     imageLayer->SetSamplingFilter(attrs.samplingFilter());
     689           0 :     imageLayer->SetScaleToSize(attrs.scaleToSize(), attrs.scaleMode());
     690           0 :     break;
     691             :   }
     692             :   default:
     693           0 :     MOZ_CRASH("not reached");
     694             :   }
     695             : 
     696         124 :   return true;
     697             : }
     698             : 
     699             : mozilla::ipc::IPCResult
     700           2 : LayerTransactionParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch)
     701             : {
     702           2 :   mChildEpoch = aLayerObserverEpoch;
     703           2 :   return IPC_OK();
     704             : }
     705             : 
     706             : bool
     707           4 : LayerTransactionParent::ShouldParentObserveEpoch()
     708             : {
     709           4 :   if (mParentEpoch == mChildEpoch) {
     710           3 :     return false;
     711             :   }
     712             : 
     713           1 :   mParentEpoch = mChildEpoch;
     714           1 :   return true;
     715             : }
     716             : 
     717             : mozilla::ipc::IPCResult
     718           0 : LayerTransactionParent::RecvSetTestSampleTime(const TimeStamp& aTime)
     719             : {
     720           0 :   if (!mCompositorBridge->SetTestSampleTime(GetId(), aTime)) {
     721           0 :     return IPC_FAIL_NO_REASON(this);
     722             :   }
     723           0 :   return IPC_OK();
     724             : }
     725             : 
     726             : mozilla::ipc::IPCResult
     727           0 : LayerTransactionParent::RecvLeaveTestMode()
     728             : {
     729           0 :   mCompositorBridge->LeaveTestMode(GetId());
     730           0 :   return IPC_OK();
     731             : }
     732             : 
     733             : mozilla::ipc::IPCResult
     734           0 : LayerTransactionParent::RecvGetAnimationOpacity(const uint64_t& aCompositorAnimationsId,
     735             :                                                 float* aOpacity,
     736             :                                                 bool* aHasAnimationOpacity)
     737             : {
     738           0 :   *aHasAnimationOpacity = false;
     739           0 :   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
     740           0 :     return IPC_FAIL_NO_REASON(this);
     741             :   }
     742             : 
     743           0 :   mCompositorBridge->ApplyAsyncProperties(this);
     744             : 
     745           0 :   if (!mAnimStorage) {
     746           0 :     return IPC_FAIL_NO_REASON(this);
     747             :   }
     748             : 
     749           0 :   Maybe<float> opacity = mAnimStorage->GetAnimationOpacity(aCompositorAnimationsId);
     750           0 :   if (opacity) {
     751           0 :     *aOpacity = *opacity;
     752           0 :     *aHasAnimationOpacity = true;
     753             :   }
     754           0 :   return IPC_OK();
     755             : }
     756             : 
     757             : mozilla::ipc::IPCResult
     758           0 : LayerTransactionParent::RecvGetAnimationTransform(const uint64_t& aCompositorAnimationsId,
     759             :                                                   MaybeTransform* aTransform)
     760             : {
     761           0 :   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
     762           0 :     return IPC_FAIL_NO_REASON(this);
     763             :   }
     764             : 
     765             :   // Make sure we apply the latest animation style or else we can end up with
     766             :   // a race between when we temporarily clear the animation transform (in
     767             :   // CompositorBridgeParent::SetShadowProperties) and when animation recalculates
     768             :   // the value.
     769           0 :   mCompositorBridge->ApplyAsyncProperties(this);
     770             : 
     771           0 :   if (!mAnimStorage) {
     772           0 :     return IPC_FAIL_NO_REASON(this);
     773             :   }
     774             : 
     775           0 :   Maybe<Matrix4x4> transform = mAnimStorage->GetAnimationTransform(aCompositorAnimationsId);
     776           0 :   if (transform) {
     777           0 :     *aTransform = *transform;
     778             :   } else {
     779           0 :     *aTransform = mozilla::void_t();
     780             :   }
     781           0 :   return IPC_OK();
     782             : }
     783             : 
     784             : static AsyncPanZoomController*
     785           0 : GetAPZCForViewID(Layer* aLayer, FrameMetrics::ViewID aScrollID)
     786             : {
     787           0 :   AsyncPanZoomController* resultApzc = nullptr;
     788           0 :   ForEachNode<ForwardIterator>(
     789             :       aLayer,
     790           0 :       [aScrollID, &resultApzc] (Layer* layer)
     791           0 :       {
     792           0 :         for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
     793           0 :           if (layer->GetFrameMetrics(i).GetScrollId() == aScrollID) {
     794           0 :             resultApzc = layer->GetAsyncPanZoomController(i);
     795           0 :             return TraversalFlag::Abort;
     796             :           }
     797             :         }
     798           0 :         return TraversalFlag::Continue;
     799           0 :       });
     800           0 :   return resultApzc;
     801             : }
     802             : 
     803             : mozilla::ipc::IPCResult
     804           0 : LayerTransactionParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollID,
     805             :                                                  const float& aX, const float& aY)
     806             : {
     807           0 :   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
     808           0 :     return IPC_FAIL_NO_REASON(this);
     809             :   }
     810             : 
     811           0 :   AsyncPanZoomController* controller = GetAPZCForViewID(mRoot, aScrollID);
     812           0 :   if (!controller) {
     813           0 :     return IPC_FAIL_NO_REASON(this);
     814             :   }
     815           0 :   controller->SetTestAsyncScrollOffset(CSSPoint(aX, aY));
     816           0 :   return IPC_OK();
     817             : }
     818             : 
     819             : mozilla::ipc::IPCResult
     820           0 : LayerTransactionParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollID,
     821             :                                          const float& aValue)
     822             : {
     823           0 :   if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) {
     824           0 :     return IPC_FAIL_NO_REASON(this);
     825             :   }
     826             : 
     827           0 :   AsyncPanZoomController* controller = GetAPZCForViewID(mRoot, aScrollID);
     828           0 :   if (!controller) {
     829           0 :     return IPC_FAIL_NO_REASON(this);
     830             :   }
     831           0 :   controller->SetTestAsyncZoom(LayerToParentLayerScale(aValue));
     832           0 :   return IPC_OK();
     833             : }
     834             : 
     835             : mozilla::ipc::IPCResult
     836           0 : LayerTransactionParent::RecvFlushApzRepaints()
     837             : {
     838           0 :   mCompositorBridge->FlushApzRepaints(GetId());
     839           0 :   return IPC_OK();
     840             : }
     841             : 
     842             : mozilla::ipc::IPCResult
     843           0 : LayerTransactionParent::RecvGetAPZTestData(APZTestData* aOutData)
     844             : {
     845           0 :   mCompositorBridge->GetAPZTestData(GetId(), aOutData);
     846           0 :   return IPC_OK();
     847             : }
     848             : 
     849             : mozilla::ipc::IPCResult
     850           0 : LayerTransactionParent::RecvRequestProperty(const nsString& aProperty, float* aValue)
     851             : {
     852           0 :   *aValue = -1;
     853           0 :   return IPC_OK();
     854             : }
     855             : 
     856             : mozilla::ipc::IPCResult
     857           0 : LayerTransactionParent::RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
     858             :                                                    nsTArray<ScrollableLayerGuid>&& aTargets)
     859             : {
     860           0 :   mCompositorBridge->SetConfirmedTargetAPZC(GetId(), aBlockId, aTargets);
     861           0 :   return IPC_OK();
     862             : }
     863             : 
     864             : bool
     865          22 : LayerTransactionParent::Attach(Layer* aLayer,
     866             :                                CompositableHost* aCompositable,
     867             :                                bool aIsAsync)
     868             : {
     869          22 :   if (!aCompositable || !aLayer) {
     870           0 :     return false;
     871             :   }
     872             : 
     873          22 :   HostLayer* layer = aLayer->AsHostLayer();
     874          22 :   if (!layer) {
     875           0 :     return false;
     876             :   }
     877             : 
     878             :   TextureSourceProvider* provider =
     879          22 :     static_cast<HostLayerManager*>(aLayer->Manager())->GetTextureSourceProvider();
     880             : 
     881          22 :   if (!layer->SetCompositableHost(aCompositable)) {
     882             :     // not all layer types accept a compositable, see bug 967824
     883           0 :     return false;
     884             :   }
     885          22 :   aCompositable->Attach(aLayer,
     886             :                         provider,
     887             :                         aIsAsync
     888             :                           ? CompositableHost::ALLOW_REATTACH
     889             :                             | CompositableHost::KEEP_ATTACHED
     890          44 :                           : CompositableHost::NO_FLAGS);
     891          22 :   return true;
     892             : }
     893             : 
     894             : mozilla::ipc::IPCResult
     895           0 : LayerTransactionParent::RecvClearCachedResources()
     896             : {
     897           0 :   if (mRoot) {
     898             :     // NB: |mRoot| here is the *child* context's root.  In this parent
     899             :     // context, it's just a subtree root.  We need to scope the clear
     900             :     // of resources to exactly that subtree, so we specify it here.
     901           0 :     mLayerManager->ClearCachedResources(mRoot);
     902             :   }
     903           0 :   mCompositorBridge->NotifyClearCachedResources(this);
     904           0 :   return IPC_OK();
     905             : }
     906             : 
     907             : mozilla::ipc::IPCResult
     908           0 : LayerTransactionParent::RecvForceComposite()
     909             : {
     910           0 :   mCompositorBridge->ForceComposite(this);
     911           0 :   return IPC_OK();
     912             : }
     913             : 
     914             : void
     915           0 : LayerTransactionParent::ActorDestroy(ActorDestroyReason why)
     916             : {
     917           0 :   Destroy();
     918           0 : }
     919             : 
     920             : bool
     921           0 : LayerTransactionParent::AllocShmem(size_t aSize,
     922             :                                    ipc::SharedMemory::SharedMemoryType aType,
     923             :                                    ipc::Shmem* aShmem)
     924             : {
     925           0 :   if (!mIPCOpen || mDestroyed) {
     926           0 :     return false;
     927             :   }
     928           0 :   return PLayerTransactionParent::AllocShmem(aSize, aType, aShmem);
     929             : }
     930             : 
     931             : bool
     932           0 : LayerTransactionParent::AllocUnsafeShmem(size_t aSize,
     933             :                                          ipc::SharedMemory::SharedMemoryType aType,
     934             :                                          ipc::Shmem* aShmem)
     935             : {
     936           0 :   if (!mIPCOpen || mDestroyed) {
     937           0 :     return false;
     938             :   }
     939             : 
     940           0 :   return PLayerTransactionParent::AllocUnsafeShmem(aSize, aType, aShmem);
     941             : }
     942             : 
     943             : void
     944           0 : LayerTransactionParent::DeallocShmem(ipc::Shmem& aShmem)
     945             : {
     946           0 :   if (!mIPCOpen || mDestroyed) {
     947           0 :     return;
     948             :   }
     949           0 :   PLayerTransactionParent::DeallocShmem(aShmem);
     950             : }
     951             : 
     952          28 : bool LayerTransactionParent::IsSameProcess() const
     953             : {
     954          28 :   return OtherPid() == base::GetCurrentProcId();
     955             : }
     956             : 
     957             : void
     958           0 : LayerTransactionParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
     959             : {
     960           0 :   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
     961             : }
     962             : 
     963             : void
     964          28 : LayerTransactionParent::SendPendingAsyncMessages()
     965             : {
     966          28 :   mCompositorBridge->SendPendingAsyncMessages();
     967          28 : }
     968             : 
     969             : void
     970          28 : LayerTransactionParent::SetAboutToSendAsyncMessages()
     971             : {
     972          28 :   mCompositorBridge->SetAboutToSendAsyncMessages();
     973          28 : }
     974             : 
     975             : void
     976           0 : LayerTransactionParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
     977             : {
     978           0 :   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
     979             : }
     980             : 
     981             : bool
     982          31 : LayerTransactionParent::BindLayerToHandle(RefPtr<Layer> aLayer, const LayerHandle& aHandle)
     983             : {
     984          31 :   if (!aHandle || !aLayer) {
     985           0 :     return false;
     986             :   }
     987          62 :   if (auto entry = mLayerMap.LookupForAdd(aHandle.Value())) {
     988           0 :     return false;
     989             :   } else {
     990          62 :     entry.OrInsert([&aLayer] () { return aLayer; });
     991             :   }
     992          31 :   return true;
     993             : }
     994             : 
     995             : Layer*
     996         291 : LayerTransactionParent::AsLayer(const LayerHandle& aHandle)
     997             : {
     998         291 :   if (!aHandle) {
     999           0 :     return nullptr;
    1000             :   }
    1001         291 :   return mLayerMap.GetWeak(aHandle.Value());
    1002             : }
    1003             : 
    1004             : mozilla::ipc::IPCResult
    1005          22 : LayerTransactionParent::RecvNewCompositable(const CompositableHandle& aHandle, const TextureInfo& aInfo)
    1006             : {
    1007          22 :   if (!AddCompositable(aHandle, aInfo)) {
    1008           0 :     return IPC_FAIL_NO_REASON(this);
    1009             :   }
    1010          22 :   return IPC_OK();
    1011             : }
    1012             : 
    1013             : mozilla::ipc::IPCResult
    1014          23 : LayerTransactionParent::RecvReleaseLayer(const LayerHandle& aHandle)
    1015             : {
    1016          46 :   RefPtr<Layer> layer;
    1017          23 :   if (!aHandle || !mLayerMap.Remove(aHandle.Value(), getter_AddRefs(layer))) {
    1018           0 :     return IPC_FAIL_NO_REASON(this);
    1019             :   }
    1020          46 :   if (mAnimStorage &&
    1021          46 :       layer->GetCompositorAnimationsId()) {
    1022           0 :     mAnimStorage->ClearById(layer->GetCompositorAnimationsId());
    1023             :   }
    1024          23 :   layer->Disconnect();
    1025          23 :   return IPC_OK();
    1026             : }
    1027             : 
    1028             : mozilla::ipc::IPCResult
    1029          19 : LayerTransactionParent::RecvReleaseCompositable(const CompositableHandle& aHandle)
    1030             : {
    1031          19 :   ReleaseCompositable(aHandle);
    1032          19 :   return IPC_OK();
    1033             : }
    1034             : 
    1035             : mozilla::ipc::IPCResult
    1036           0 : LayerTransactionParent::RecvRecordPaintTimes(const PaintTiming& aTiming)
    1037             : {
    1038             :   // Currently we only add paint timings for remote layers. In the future
    1039             :   // we could be smarter and use paint timings from the UI process, either
    1040             :   // as a separate overlay or if no remote layers are attached.
    1041           0 :   if (mLayerManager && mCompositorBridge->IsRemote()) {
    1042           0 :     mLayerManager->RecordPaintTimes(aTiming);
    1043             :   }
    1044           0 :   return IPC_OK();
    1045             : }
    1046             : 
    1047             : mozilla::ipc::IPCResult
    1048           1 : LayerTransactionParent::RecvGetTextureFactoryIdentifier(TextureFactoryIdentifier* aIdentifier)
    1049             : {
    1050           1 :   if (!mLayerManager) {
    1051             :     // Default constructor sets mParentBackend to LAYERS_NONE.
    1052           0 :     return IPC_OK();
    1053             :   }
    1054             : 
    1055           1 :   *aIdentifier = mLayerManager->GetTextureFactoryIdentifier();
    1056           1 :   return IPC_OK();
    1057             : }
    1058             : 
    1059             : } // namespace layers
    1060             : } // namespace mozilla

Generated by: LCOV version 1.13