tor-browser

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

VideoBridgeChild.cpp (5617B)


      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 "VideoBridgeChild.h"
      8 #include "VideoBridgeParent.h"
      9 #include "CompositorThread.h"
     10 #include "mozilla/dom/ContentChild.h"
     11 #include "mozilla/ipc/Endpoint.h"
     12 #include "mozilla/StaticMutex.h"
     13 #include "transport/runnable_utils.h"
     14 #include "SynchronousTask.h"
     15 
     16 namespace mozilla {
     17 namespace layers {
     18 
     19 // Singleton
     20 static StaticMutex sVideoBridgeLock MOZ_UNANNOTATED;
     21 StaticRefPtr<VideoBridgeChild> sVideoBridge;
     22 
     23 /* static */
     24 void VideoBridgeChild::StartupForGPUProcess() {
     25  ipc::Endpoint<PVideoBridgeParent> parentPipe;
     26  ipc::Endpoint<PVideoBridgeChild> childPipe;
     27 
     28  PVideoBridge::CreateEndpoints(ipc::EndpointProcInfo::Current(),
     29                                ipc::EndpointProcInfo::Current(), &parentPipe,
     30                                &childPipe);
     31 
     32  VideoBridgeChild::Open(std::move(childPipe));
     33  VideoBridgeParent::Open(std::move(parentPipe), VideoBridgeSource::GpuProcess);
     34 }
     35 
     36 /* static */
     37 void VideoBridgeChild::Open(Endpoint<PVideoBridgeChild>&& aEndpoint) {
     38  StaticMutexAutoLock lock(sVideoBridgeLock);
     39  MOZ_ASSERT(!sVideoBridge || !sVideoBridge->CanSend());
     40  sVideoBridge = new VideoBridgeChild();
     41 
     42  if (!aEndpoint.Bind(sVideoBridge)) {
     43    // We can't recover from this.
     44    MOZ_CRASH("Failed to bind VideoBridgeChild to endpoint");
     45  }
     46 }
     47 
     48 /* static */
     49 void VideoBridgeChild::Shutdown() {
     50  StaticMutexAutoLock lock(sVideoBridgeLock);
     51  if (sVideoBridge) {
     52    sVideoBridge->Close();
     53    sVideoBridge = nullptr;
     54  }
     55 }
     56 
     57 VideoBridgeChild::VideoBridgeChild()
     58    : mThread(GetCurrentSerialEventTarget()), mCanSend(true) {}
     59 
     60 VideoBridgeChild::~VideoBridgeChild() = default;
     61 
     62 VideoBridgeChild* VideoBridgeChild::GetSingleton() {
     63  StaticMutexAutoLock lock(sVideoBridgeLock);
     64  return sVideoBridge;
     65 }
     66 
     67 bool VideoBridgeChild::AllocUnsafeShmem(size_t aSize, ipc::Shmem* aShmem) {
     68  if (!mThread->IsOnCurrentThread()) {
     69    return DispatchAllocShmemInternal(aSize, aShmem, true);  // true: unsafe
     70  }
     71 
     72  if (!CanSend()) {
     73    return false;
     74  }
     75 
     76  return PVideoBridgeChild::AllocUnsafeShmem(aSize, aShmem);
     77 }
     78 
     79 bool VideoBridgeChild::AllocShmem(size_t aSize, ipc::Shmem* aShmem) {
     80  MOZ_ASSERT(CanSend());
     81  return PVideoBridgeChild::AllocShmem(aSize, aShmem);
     82 }
     83 
     84 void VideoBridgeChild::ProxyAllocShmemNow(SynchronousTask* aTask, size_t aSize,
     85                                          ipc::Shmem* aShmem, bool aUnsafe,
     86                                          bool* aSuccess) {
     87  AutoCompleteTask complete(aTask);
     88 
     89  if (!CanSend()) {
     90    return;
     91  }
     92 
     93  bool ok = false;
     94  if (aUnsafe) {
     95    ok = AllocUnsafeShmem(aSize, aShmem);
     96  } else {
     97    ok = AllocShmem(aSize, aShmem);
     98  }
     99  *aSuccess = ok;
    100 }
    101 
    102 bool VideoBridgeChild::DispatchAllocShmemInternal(size_t aSize,
    103                                                  ipc::Shmem* aShmem,
    104                                                  bool aUnsafe) {
    105  SynchronousTask task("AllocatorProxy alloc");
    106 
    107  bool success = false;
    108  RefPtr<Runnable> runnable = WrapRunnable(
    109      RefPtr<VideoBridgeChild>(this), &VideoBridgeChild::ProxyAllocShmemNow,
    110      &task, aSize, aShmem, aUnsafe, &success);
    111  GetThread()->Dispatch(runnable.forget());
    112 
    113  task.Wait();
    114 
    115  return success;
    116 }
    117 
    118 void VideoBridgeChild::ProxyDeallocShmemNow(SynchronousTask* aTask,
    119                                            ipc::Shmem* aShmem, bool* aResult) {
    120  AutoCompleteTask complete(aTask);
    121 
    122  if (!CanSend()) {
    123    return;
    124  }
    125  *aResult = DeallocShmem(*aShmem);
    126 }
    127 
    128 bool VideoBridgeChild::DeallocShmem(ipc::Shmem& aShmem) {
    129  if (GetThread()->IsOnCurrentThread()) {
    130    if (!CanSend()) {
    131      return false;
    132    }
    133    return PVideoBridgeChild::DeallocShmem(aShmem);
    134  }
    135 
    136  SynchronousTask task("AllocatorProxy Dealloc");
    137  bool result = false;
    138 
    139  RefPtr<Runnable> runnable = WrapRunnable(
    140      RefPtr<VideoBridgeChild>(this), &VideoBridgeChild::ProxyDeallocShmemNow,
    141      &task, &aShmem, &result);
    142  GetThread()->Dispatch(runnable.forget());
    143 
    144  task.Wait();
    145  return result;
    146 }
    147 
    148 PTextureChild* VideoBridgeChild::AllocPTextureChild(
    149    const SurfaceDescriptor&, ReadLockDescriptor&, const LayersBackend&,
    150    const TextureFlags&, const dom::ContentParentId& aContentId,
    151    const uint64_t& aSerial) {
    152  MOZ_ASSERT(CanSend());
    153  return TextureClient::CreateIPDLActor();
    154 }
    155 
    156 bool VideoBridgeChild::DeallocPTextureChild(PTextureChild* actor) {
    157  return TextureClient::DestroyIPDLActor(actor);
    158 }
    159 
    160 void VideoBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
    161  mCanSend = false;
    162 }
    163 
    164 PTextureChild* VideoBridgeChild::CreateTexture(
    165    const SurfaceDescriptor& aSharedData, ReadLockDescriptor&& aReadLock,
    166    LayersBackend aLayersBackend, TextureFlags aFlags,
    167    const dom::ContentParentId& aContentId, uint64_t aSerial,
    168    wr::MaybeExternalImageId& aExternalImageId) {
    169  MOZ_ASSERT(CanSend());
    170  return SendPTextureConstructor(aSharedData, std::move(aReadLock),
    171                                 aLayersBackend, aFlags, aContentId, aSerial);
    172 }
    173 
    174 bool VideoBridgeChild::IsSameProcess() const {
    175  return OtherPid() == base::GetCurrentProcId();
    176 }
    177 
    178 void VideoBridgeChild::HandleFatalError(const char* aMsg) {
    179  dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherChildID());
    180 }
    181 
    182 mozilla::ipc::IPCResult VideoBridgeChild::RecvPing(PingResolver&& aResolver) {
    183  aResolver(void_t{});
    184  return IPC_OK();
    185 }
    186 
    187 }  // namespace layers
    188 }  // namespace mozilla