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

Generated by: LCOV version 1.13-14-ga5dd952