tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CompositorBridgeChild.cpp (20181B)


      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 "mozilla/layers/CompositorBridgeChild.h"
      8 #include "mozilla/layers/CompositorBridgeParent.h"
      9 #include "mozilla/layers/CompositorThread.h"
     10 #include <stddef.h>     // for size_t
     11 #include "base/task.h"  // for NewRunnableMethod, etc
     12 #include "mozilla/StaticPrefs_layers.h"
     13 #include "mozilla/layers/CompositorManagerChild.h"
     14 #include "mozilla/layers/ImageBridgeChild.h"
     15 #include "mozilla/layers/APZChild.h"
     16 #include "mozilla/layers/IAPZCTreeManager.h"
     17 #include "mozilla/layers/APZCTreeManagerChild.h"
     18 #include "mozilla/layers/CanvasChild.h"
     19 #include "mozilla/layers/WebRenderLayerManager.h"
     20 #include "mozilla/layers/PTextureChild.h"
     21 #include "mozilla/layers/TextureClient.h"  // for TextureClient
     22 #include "mozilla/layers/WebRenderBridgeChild.h"
     23 #include "mozilla/layers/SyncObject.h"  // for SyncObjectClient
     24 #include "mozilla/gfx/CanvasManagerChild.h"
     25 #include "mozilla/gfx/gfxVars.h"
     26 #include "mozilla/gfx/GPUProcessManager.h"
     27 #include "mozilla/gfx/Logging.h"
     28 #include "mozilla/ipc/Endpoint.h"
     29 #include "mozilla/mozalloc.h"  // for operator new, etc
     30 #include "gfxConfig.h"
     31 #include "nsDebug.h"          // for NS_WARNING
     32 #include "nsISupportsImpl.h"  // for MOZ_COUNT_CTOR, etc
     33 #include "nsTArray.h"         // for nsTArray, nsTArray_Impl
     34 #include "mozilla/dom/BrowserChild.h"
     35 #include "mozilla/dom/BrowserParent.h"
     36 #include "mozilla/dom/ContentChild.h"
     37 #include "mozilla/SpinEventLoopUntil.h"
     38 #include "nsThreadUtils.h"
     39 #if defined(XP_WIN)
     40 #  include "WinUtils.h"
     41 #endif
     42 #include "mozilla/widget/CompositorWidget.h"
     43 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
     44 #  include "mozilla/widget/CompositorWidgetChild.h"
     45 #endif
     46 #include "VsyncSource.h"
     47 
     48 using mozilla::gfx::GPUProcessManager;
     49 
     50 namespace mozilla {
     51 namespace layers {
     52 
     53 static int sShmemCreationCounter = 0;
     54 
     55 static void ResetShmemCounter() { sShmemCreationCounter = 0; }
     56 
     57 static void ShmemAllocated(CompositorBridgeChild* aProtocol) {
     58  sShmemCreationCounter++;
     59  if (sShmemCreationCounter > 256) {
     60    aProtocol->SendSyncWithCompositor();
     61    ResetShmemCounter();
     62    MOZ_PERFORMANCE_WARNING(
     63        "gfx", "The number of shmem allocations is too damn high!");
     64  }
     65 }
     66 
     67 static StaticRefPtr<CompositorBridgeChild> sCompositorBridge;
     68 
     69 Atomic<int32_t> KnowsCompositor::sSerialCounter(0);
     70 
     71 CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild* aManager)
     72    : mCompositorManager(aManager),
     73      mIdNamespace(0),
     74      mResourceId(0),
     75      mCanSend(false),
     76      mActorDestroyed(false),
     77      mPaused(false),
     78      mForceSyncFlushRendering(false),
     79      mThread(NS_GetCurrentThread()),
     80      mProcessToken(0),
     81      mSectionAllocator(nullptr) {
     82  MOZ_ASSERT(NS_IsMainThread());
     83 }
     84 
     85 CompositorBridgeChild::~CompositorBridgeChild() {
     86  if (mCanSend) {
     87    gfxCriticalError() << "CompositorBridgeChild was not deinitialized";
     88  }
     89 }
     90 
     91 bool CompositorBridgeChild::IsSameProcess() const {
     92  return OtherPid() == base::GetCurrentProcId();
     93 }
     94 
     95 void CompositorBridgeChild::PrepareFinalDestroy() {
     96  // Because of medium high priority DidComposite, we need to repost to
     97  // medium high priority queue to ensure the actor is destroyed after possible
     98  // pending DidComposite message.
     99  nsCOMPtr<nsIRunnable> runnable =
    100      NewRunnableMethod("CompositorBridgeChild::AfterDestroy", this,
    101                        &CompositorBridgeChild::AfterDestroy);
    102  NS_DispatchToCurrentThreadQueue(runnable.forget(),
    103                                  EventQueuePriority::MediumHigh);
    104 }
    105 
    106 void CompositorBridgeChild::AfterDestroy() {
    107  // Note that we cannot rely upon mCanSend here because we already set that to
    108  // false to prevent normal IPDL calls from being made after SendWillClose.
    109  // The only time we should not issue Send__delete__ is if the actor is already
    110  // destroyed, e.g. the compositor process crashed.
    111  if (!mActorDestroyed) {
    112    // We saw this send fail quite often with "Channel closing", probably a race
    113    // with the other side closing or some event scheduling order.
    114    if (GetIPCChannel()->CanSend()) {
    115      Send__delete__(this);
    116    }
    117    mActorDestroyed = true;
    118  }
    119 
    120  if (sCompositorBridge == this) {
    121    sCompositorBridge = nullptr;
    122  }
    123 }
    124 
    125 void CompositorBridgeChild::Destroy() {
    126  // This must not be called from the destructor!
    127  mTexturesWaitingNotifyNotUsed.clear();
    128 
    129  // Destroying the layer manager may cause all sorts of things to happen, so
    130  // let's make sure there is still a reference to keep this alive whatever
    131  // happens.
    132  RefPtr<CompositorBridgeChild> selfRef = this;
    133 
    134  if (mSectionAllocator) {
    135    delete mSectionAllocator;
    136    mSectionAllocator = nullptr;
    137  }
    138 
    139  if (mLayerManager) {
    140    mLayerManager->Destroy();
    141    mLayerManager = nullptr;
    142  }
    143 
    144  if (!mCanSend) {
    145    // We may have already called destroy but still have lingering references
    146    // or CompositorBridgeChild::ActorDestroy was called. Ensure that we do our
    147    // post destroy clean up no matter what. It is safe to call multiple times.
    148    NS_GetCurrentThread()->Dispatch(
    149        NewRunnableMethod("CompositorBridgeChild::PrepareFinalDestroy", selfRef,
    150                          &CompositorBridgeChild::PrepareFinalDestroy));
    151    return;
    152  }
    153 
    154  AutoTArray<PWebRenderBridgeChild*, 16> wrBridges;
    155  ManagedPWebRenderBridgeChild(wrBridges);
    156  for (int i = wrBridges.Length() - 1; i >= 0; --i) {
    157    RefPtr<WebRenderBridgeChild> wrBridge =
    158        static_cast<WebRenderBridgeChild*>(wrBridges[i]);
    159    wrBridge->Destroy(/* aIsSync */ false);
    160  }
    161 
    162  AutoTArray<PAPZChild*, 16> apzChildren;
    163  ManagedPAPZChild(apzChildren);
    164  for (PAPZChild* child : apzChildren) {
    165    (void)child->SendDestroy();
    166  }
    167 
    168  const ManagedContainer<PTextureChild>& textures = ManagedPTextureChild();
    169  for (const auto& key : textures) {
    170    RefPtr<TextureClient> texture = TextureClient::AsTextureClient(key);
    171 
    172    if (texture) {
    173      texture->Destroy();
    174    }
    175  }
    176 
    177  // The WillClose message is synchronous, so we know that after it returns
    178  // any messages sent by the above code will have been processed on the
    179  // other side.
    180  SendWillClose();
    181  mCanSend = false;
    182 
    183  // We no longer care about unexpected shutdowns, in the remote process case.
    184  mProcessToken = 0;
    185 
    186  // The call just made to SendWillClose can result in IPC from the
    187  // CompositorBridgeParent to the CompositorBridgeChild (e.g. caused by the
    188  // destruction of shared memory). We need to ensure this gets processed by the
    189  // CompositorBridgeChild before it gets destroyed. It suffices to ensure that
    190  // events already in the thread get processed before the
    191  // CompositorBridgeChild is destroyed, so we add a task to the thread to
    192  // handle compositor destruction.
    193 
    194  // From now on we can't send any message message.
    195  NS_GetCurrentThread()->Dispatch(
    196      NewRunnableMethod("CompositorBridgeChild::PrepareFinalDestroy", selfRef,
    197                        &CompositorBridgeChild::PrepareFinalDestroy));
    198 }
    199 
    200 // static
    201 void CompositorBridgeChild::ShutDown() {
    202  if (sCompositorBridge) {
    203    sCompositorBridge->Destroy();
    204    SpinEventLoopUntil("CompositorBridgeChild::ShutDown"_ns,
    205                       [&]() { return !sCompositorBridge; });
    206  }
    207 }
    208 
    209 void CompositorBridgeChild::InitForContent(uint32_t aNamespace) {
    210  MOZ_ASSERT(NS_IsMainThread());
    211  MOZ_ASSERT(aNamespace);
    212 
    213  if (RefPtr<CompositorBridgeChild> old = sCompositorBridge.forget()) {
    214    // Note that at this point, ActorDestroy may not have been called yet,
    215    // meaning mCanSend is still true. In this case we will try to send a
    216    // synchronous WillClose message to the parent, and will certainly get
    217    // a false result and a MsgDropped processing error. This is okay.
    218    old->Destroy();
    219  }
    220 
    221  mCanSend = true;
    222  mIdNamespace = aNamespace;
    223 
    224  sCompositorBridge = this;
    225 }
    226 
    227 void CompositorBridgeChild::InitForWidget(uint64_t aProcessToken,
    228                                          WebRenderLayerManager* aLayerManager,
    229                                          uint32_t aNamespace) {
    230  MOZ_ASSERT(NS_IsMainThread());
    231  MOZ_ASSERT(aProcessToken);
    232  MOZ_ASSERT(aLayerManager);
    233  MOZ_ASSERT(aNamespace);
    234 
    235  mCanSend = true;
    236  mProcessToken = aProcessToken;
    237  mLayerManager = aLayerManager;
    238  mIdNamespace = aNamespace;
    239 }
    240 
    241 /*static*/
    242 CompositorBridgeChild* CompositorBridgeChild::Get() {
    243  // This is only expected to be used in child processes. While the parent
    244  // process does have CompositorBridgeChild instances, it has _multiple_ (one
    245  // per window), and therefore there is no global singleton available.
    246  MOZ_ASSERT(!XRE_IsParentProcess());
    247  return sCompositorBridge;
    248 }
    249 
    250 /* static */
    251 bool CompositorBridgeChild::CompositorIsInGPUProcess() {
    252  MOZ_ASSERT(NS_IsMainThread());
    253 
    254  if (XRE_IsParentProcess()) {
    255    return !!GPUProcessManager::Get()->GetGPUChild();
    256  }
    257 
    258  MOZ_ASSERT(XRE_IsContentProcess());
    259  CompositorBridgeChild* bridge = CompositorBridgeChild::Get();
    260  if (!bridge) {
    261    return false;
    262  }
    263 
    264  return bridge->OtherPid() != dom::ContentChild::GetSingleton()->OtherPid();
    265 }
    266 
    267 mozilla::ipc::IPCResult CompositorBridgeChild::RecvDidComposite(
    268    const LayersId& aId, const nsTArray<TransactionId>& aTransactionIds,
    269    const TimeStamp& aCompositeStart, const TimeStamp& aCompositeEnd) {
    270  for (const auto& id : aTransactionIds) {
    271    if (mLayerManager) {
    272      MOZ_ASSERT(!aId.IsValid());
    273      MOZ_ASSERT(mLayerManager->GetBackendType() == LayersBackend::LAYERS_WR);
    274      // Hold a reference to keep LayerManager alive. See Bug 1242668.
    275      RefPtr<WebRenderLayerManager> m = mLayerManager;
    276      m->DidComposite(id, aCompositeStart, aCompositeEnd);
    277    } else if (aId.IsValid()) {
    278      RefPtr<dom::BrowserChild> child = dom::BrowserChild::GetFrom(aId);
    279      if (child) {
    280        child->DidComposite(id, aCompositeStart, aCompositeEnd);
    281      }
    282    }
    283  }
    284 
    285  return IPC_OK();
    286 }
    287 
    288 mozilla::ipc::IPCResult CompositorBridgeChild::RecvNotifyFrameStats(
    289    nsTArray<FrameStats>&& aFrameStats) {
    290  gfxPlatform::GetPlatform()->NotifyFrameStats(std::move(aFrameStats));
    291  return IPC_OK();
    292 }
    293 
    294 void CompositorBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
    295  if (aWhy == AbnormalShutdown) {
    296    // If the parent side runs into a problem then the actor will be destroyed.
    297    // There is nothing we can do in the child side, here sets mCanSend as
    298    // false.
    299    gfxCriticalNote << "CompositorBridgeChild receives IPC close with "
    300                       "reason=AbnormalShutdown";
    301  }
    302 
    303  mCanSend = false;
    304  mActorDestroyed = true;
    305 
    306  if (mProcessToken && XRE_IsParentProcess()) {
    307    GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
    308  }
    309 }
    310 
    311 bool CompositorBridgeChild::SendWillClose() {
    312  MOZ_RELEASE_ASSERT(mCanSend);
    313  return PCompositorBridgeChild::SendWillClose();
    314 }
    315 
    316 bool CompositorBridgeChild::SendPause() {
    317  if (!mCanSend) {
    318    return false;
    319  }
    320  mPaused = true;
    321  return PCompositorBridgeChild::SendPause();
    322 }
    323 
    324 bool CompositorBridgeChild::SendResume() {
    325  if (!mCanSend) {
    326    return false;
    327  }
    328  mPaused = false;
    329  return PCompositorBridgeChild::SendResume();
    330 }
    331 
    332 bool CompositorBridgeChild::SendResumeAsync() {
    333  if (!mCanSend) {
    334    return false;
    335  }
    336  mPaused = false;
    337  return PCompositorBridgeChild::SendResumeAsync();
    338 }
    339 
    340 bool CompositorBridgeChild::SendAdoptChild(const LayersId& id) {
    341  if (!mCanSend) {
    342    return false;
    343  }
    344  return PCompositorBridgeChild::SendAdoptChild(id);
    345 }
    346 
    347 bool CompositorBridgeChild::SendFlushRendering(
    348    const wr::RenderReasons& aReasons) {
    349  if (!mCanSend) {
    350    return false;
    351  }
    352  return PCompositorBridgeChild::SendFlushRendering(aReasons);
    353 }
    354 
    355 bool CompositorBridgeChild::SendFlushRenderingAsync(
    356    const wr::RenderReasons& aReasons) {
    357  if (mForceSyncFlushRendering) {
    358    return SendFlushRendering(aReasons);
    359  }
    360  if (!mCanSend) {
    361    return false;
    362  }
    363  return PCompositorBridgeChild::SendFlushRenderingAsync(aReasons);
    364 }
    365 
    366 void CompositorBridgeChild::SetForceSyncFlushRendering(
    367    bool aForceSyncFlushRendering) {
    368  mForceSyncFlushRendering = aForceSyncFlushRendering;
    369 }
    370 
    371 bool CompositorBridgeChild::SendStartFrameTimeRecording(
    372    const int32_t& bufferSize, uint32_t* startIndex) {
    373  if (!mCanSend) {
    374    return false;
    375  }
    376  return PCompositorBridgeChild::SendStartFrameTimeRecording(bufferSize,
    377                                                             startIndex);
    378 }
    379 
    380 bool CompositorBridgeChild::SendStopFrameTimeRecording(
    381    const uint32_t& startIndex, nsTArray<float>* intervals) {
    382  if (!mCanSend) {
    383    return false;
    384  }
    385  return PCompositorBridgeChild::SendStopFrameTimeRecording(startIndex,
    386                                                            intervals);
    387 }
    388 
    389 PTextureChild* CompositorBridgeChild::AllocPTextureChild(
    390    const SurfaceDescriptor&, ReadLockDescriptor&, const LayersBackend&,
    391    const TextureFlags&, const LayersId&, const uint64_t& aSerial,
    392    const wr::MaybeExternalImageId& aExternalImageId) {
    393  return TextureClient::CreateIPDLActor();
    394 }
    395 
    396 bool CompositorBridgeChild::DeallocPTextureChild(PTextureChild* actor) {
    397  return TextureClient::DestroyIPDLActor(actor);
    398 }
    399 
    400 mozilla::ipc::IPCResult CompositorBridgeChild::RecvParentAsyncMessages(
    401    nsTArray<AsyncParentMessageData>&& aMessages) {
    402  for (AsyncParentMessageArray::index_type i = 0; i < aMessages.Length(); ++i) {
    403    const AsyncParentMessageData& message = aMessages[i];
    404 
    405    switch (message.type()) {
    406      case AsyncParentMessageData::TOpNotifyNotUsed: {
    407        const OpNotifyNotUsed& op = message.get_OpNotifyNotUsed();
    408        NotifyNotUsed(op.TextureId(), op.fwdTransactionId());
    409        break;
    410      }
    411      default:
    412        NS_ERROR("unknown AsyncParentMessageData type");
    413        return IPC_FAIL_NO_REASON(this);
    414    }
    415  }
    416  return IPC_OK();
    417 }
    418 
    419 mozilla::ipc::IPCResult CompositorBridgeChild::RecvObserveLayersUpdate(
    420    const LayersId& aLayersId, const bool& aActive) {
    421  // This message is sent via the window compositor, not the tab compositor -
    422  // however it still has a layers id.
    423  MOZ_ASSERT(aLayersId.IsValid());
    424  MOZ_ASSERT(XRE_IsParentProcess());
    425 
    426  if (RefPtr<dom::BrowserParent> tab =
    427          dom::BrowserParent::GetBrowserParentFromLayersId(aLayersId)) {
    428    tab->LayerTreeUpdate(aActive);
    429  }
    430  return IPC_OK();
    431 }
    432 
    433 mozilla::ipc::IPCResult CompositorBridgeChild::RecvCompositorOptionsChanged(
    434    const LayersId& aLayersId, const CompositorOptions& aNewOptions) {
    435  MOZ_ASSERT(aLayersId.IsValid());
    436  MOZ_ASSERT(XRE_IsParentProcess());
    437 
    438  if (RefPtr<dom::BrowserParent> tab =
    439          dom::BrowserParent::GetBrowserParentFromLayersId(aLayersId)) {
    440    (void)tab->SendCompositorOptionsChanged(aNewOptions);
    441  }
    442  return IPC_OK();
    443 }
    444 
    445 mozilla::ipc::IPCResult CompositorBridgeChild::RecvNotifyJankedAnimations(
    446    const LayersId& aLayersId, nsTArray<uint64_t>&& aJankedAnimations) {
    447  if (mLayerManager) {
    448    MOZ_ASSERT(!aLayersId.IsValid());
    449    mLayerManager->UpdatePartialPrerenderedAnimations(aJankedAnimations);
    450  } else if (aLayersId.IsValid()) {
    451    RefPtr<dom::BrowserChild> child = dom::BrowserChild::GetFrom(aLayersId);
    452    if (child) {
    453      child->NotifyJankedAnimations(aJankedAnimations);
    454    }
    455  }
    456 
    457  return IPC_OK();
    458 }
    459 
    460 void CompositorBridgeChild::HoldUntilCompositableRefReleasedIfNecessary(
    461    TextureClient* aClient) {
    462  if (!aClient) {
    463    return;
    464  }
    465 
    466  bool waitNotifyNotUsed =
    467      aClient->GetFlags() & TextureFlags::RECYCLE ||
    468      aClient->GetFlags() & TextureFlags::WAIT_HOST_USAGE_END;
    469  if (!waitNotifyNotUsed) {
    470    return;
    471  }
    472 
    473  aClient->SetLastFwdTransactionId(
    474      GetFwdTransactionCounter().mFwdTransactionId);
    475  mTexturesWaitingNotifyNotUsed.emplace(aClient->GetSerial(), aClient);
    476 }
    477 
    478 void CompositorBridgeChild::NotifyNotUsed(uint64_t aTextureId,
    479                                          uint64_t aFwdTransactionId) {
    480  auto it = mTexturesWaitingNotifyNotUsed.find(aTextureId);
    481  if (it != mTexturesWaitingNotifyNotUsed.end()) {
    482    if (aFwdTransactionId < it->second->GetLastFwdTransactionId()) {
    483      // Released on host side, but client already requested newer use texture.
    484      return;
    485    }
    486    mTexturesWaitingNotifyNotUsed.erase(it);
    487  }
    488 }
    489 
    490 void CompositorBridgeChild::CancelWaitForNotifyNotUsed(uint64_t aTextureId) {
    491  mTexturesWaitingNotifyNotUsed.erase(aTextureId);
    492 }
    493 
    494 FixedSizeSmallShmemSectionAllocator*
    495 CompositorBridgeChild::GetTileLockAllocator() {
    496  if (!IPCOpen()) {
    497    return nullptr;
    498  }
    499 
    500  if (!mSectionAllocator) {
    501    mSectionAllocator = new FixedSizeSmallShmemSectionAllocator(this);
    502  }
    503  return mSectionAllocator;
    504 }
    505 
    506 PTextureChild* CompositorBridgeChild::CreateTexture(
    507    const SurfaceDescriptor& aSharedData, ReadLockDescriptor&& aReadLock,
    508    LayersBackend aLayersBackend, TextureFlags aFlags,
    509    const dom::ContentParentId& aContentId, uint64_t aSerial,
    510    wr::MaybeExternalImageId& aExternalImageId) {
    511  PTextureChild* textureChild =
    512      AllocPTextureChild(aSharedData, aReadLock, aLayersBackend, aFlags,
    513                         LayersId{0} /* FIXME */, aSerial, aExternalImageId);
    514 
    515  return SendPTextureConstructor(
    516      textureChild, aSharedData, std::move(aReadLock), aLayersBackend, aFlags,
    517      LayersId{0} /* FIXME? */, aSerial, aExternalImageId);
    518 }
    519 
    520 already_AddRefed<CanvasChild> CompositorBridgeChild::GetCanvasChild() {
    521  MOZ_ASSERT(gfxPlatform::UseRemoteCanvas());
    522  if (auto* cm = gfx::CanvasManagerChild::Get()) {
    523    return cm->GetCanvasChild().forget();
    524  }
    525  return nullptr;
    526 }
    527 
    528 void CompositorBridgeChild::EndCanvasTransaction() {
    529  if (auto* cm = gfx::CanvasManagerChild::Get()) {
    530    cm->EndCanvasTransaction();
    531  }
    532 }
    533 
    534 void CompositorBridgeChild::ClearCachedResources() {
    535  if (auto* cm = gfx::CanvasManagerChild::Get()) {
    536    cm->ClearCachedResources();
    537  }
    538 }
    539 
    540 bool CompositorBridgeChild::AllocUnsafeShmem(size_t aSize, ipc::Shmem* aShmem) {
    541  ShmemAllocated(this);
    542  return PCompositorBridgeChild::AllocUnsafeShmem(aSize, aShmem);
    543 }
    544 
    545 bool CompositorBridgeChild::AllocShmem(size_t aSize, ipc::Shmem* aShmem) {
    546  ShmemAllocated(this);
    547  return PCompositorBridgeChild::AllocShmem(aSize, aShmem);
    548 }
    549 
    550 bool CompositorBridgeChild::DeallocShmem(ipc::Shmem& aShmem) {
    551  if (!mCanSend) {
    552    return false;
    553  }
    554  return PCompositorBridgeChild::DeallocShmem(aShmem);
    555 }
    556 
    557 PAPZCTreeManagerChild* CompositorBridgeChild::AllocPAPZCTreeManagerChild(
    558    const LayersId& aLayersId) {
    559  APZCTreeManagerChild* child = new APZCTreeManagerChild();
    560  child->AddIPDLReference();
    561 
    562  return child;
    563 }
    564 
    565 PAPZChild* CompositorBridgeChild::AllocPAPZChild(const LayersId& aLayersId) {
    566  // We send the constructor manually.
    567  MOZ_CRASH("Should not be called");
    568  return nullptr;
    569 }
    570 
    571 bool CompositorBridgeChild::DeallocPAPZChild(PAPZChild* aActor) {
    572  delete aActor;
    573  return true;
    574 }
    575 
    576 bool CompositorBridgeChild::DeallocPAPZCTreeManagerChild(
    577    PAPZCTreeManagerChild* aActor) {
    578  APZCTreeManagerChild* child = static_cast<APZCTreeManagerChild*>(aActor);
    579  child->ReleaseIPDLReference();
    580  return true;
    581 }
    582 
    583 // -
    584 
    585 PWebRenderBridgeChild* CompositorBridgeChild::AllocPWebRenderBridgeChild(
    586    const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize&,
    587    const WindowKind&) {
    588  WebRenderBridgeChild* child = new WebRenderBridgeChild(aPipelineId);
    589  child->AddIPDLReference();
    590  return child;
    591 }
    592 
    593 bool CompositorBridgeChild::DeallocPWebRenderBridgeChild(
    594    PWebRenderBridgeChild* aActor) {
    595  WebRenderBridgeChild* child = static_cast<WebRenderBridgeChild*>(aActor);
    596  child->ReleaseIPDLReference();
    597  return true;
    598 }
    599 
    600 uint64_t CompositorBridgeChild::GetNextResourceId() {
    601  ++mResourceId;
    602  MOZ_RELEASE_ASSERT(mResourceId != UINT32_MAX);
    603 
    604  uint64_t id = mIdNamespace;
    605  id = (id << 32) | mResourceId;
    606 
    607  return id;
    608 }
    609 
    610 wr::MaybeExternalImageId CompositorBridgeChild::GetNextExternalImageId() {
    611  return Some(wr::ToExternalImageId(GetNextResourceId()));
    612 }
    613 
    614 wr::PipelineId CompositorBridgeChild::GetNextPipelineId() {
    615  return wr::AsPipelineId(GetNextResourceId());
    616 }
    617 
    618 FwdTransactionCounter& CompositorBridgeChild::GetFwdTransactionCounter() {
    619  return mCompositorManager->GetFwdTransactionCounter();
    620 }
    621 
    622 }  // namespace layers
    623 }  // namespace mozilla