tor-browser

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

VsyncBridgeChild.cpp (4134B)


      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 #include "VsyncBridgeChild.h"
      7 #include "VsyncIOThreadHolder.h"
      8 #include "mozilla/dom/ContentChild.h"
      9 #include "mozilla/gfx/GPUProcessManager.h"
     10 #include "mozilla/ipc/Endpoint.h"
     11 
     12 namespace mozilla {
     13 namespace gfx {
     14 
     15 VsyncBridgeChild::VsyncBridgeChild(RefPtr<VsyncIOThreadHolder> aThread,
     16                                   const uint64_t& aProcessToken)
     17    : mThread(aThread), mProcessToken(aProcessToken) {}
     18 
     19 VsyncBridgeChild::~VsyncBridgeChild() = default;
     20 
     21 /* static */
     22 RefPtr<VsyncBridgeChild> VsyncBridgeChild::Create(
     23    RefPtr<VsyncIOThreadHolder> aThread, const uint64_t& aProcessToken,
     24    Endpoint<PVsyncBridgeChild>&& aEndpoint) {
     25  RefPtr<VsyncBridgeChild> child = new VsyncBridgeChild(aThread, aProcessToken);
     26 
     27  RefPtr<nsIRunnable> task = NewRunnableMethod<Endpoint<PVsyncBridgeChild>&&>(
     28      "gfx::VsyncBridgeChild::Open", child, &VsyncBridgeChild::Open,
     29      std::move(aEndpoint));
     30  aThread->GetThread()->Dispatch(task.forget(), nsIThread::DISPATCH_NORMAL);
     31 
     32  return child;
     33 }
     34 
     35 void VsyncBridgeChild::Open(Endpoint<PVsyncBridgeChild>&& aEndpoint) {
     36  if (!aEndpoint.Bind(this)) {
     37    // The GPU Process Manager might be gone if we receive ActorDestroy very
     38    // late in shutdown.
     39    if (GPUProcessManager* gpm = GPUProcessManager::Get())
     40      gpm->NotifyRemoteActorDestroyed(mProcessToken);
     41    return;
     42  }
     43 }
     44 
     45 class NotifyVsyncTask : public Runnable {
     46 public:
     47  NotifyVsyncTask(RefPtr<VsyncBridgeChild> aVsyncBridge,
     48                  const VsyncEvent& aVsync, const layers::LayersId& aLayersId)
     49      : Runnable("gfx::NotifyVsyncTask"),
     50        mVsyncBridge(aVsyncBridge),
     51        mVsync(aVsync),
     52        mLayersId(aLayersId) {}
     53 
     54  NS_IMETHOD Run() override {
     55    mVsyncBridge->NotifyVsyncImpl(mVsync, mLayersId);
     56    return NS_OK;
     57  }
     58 
     59 private:
     60  RefPtr<VsyncBridgeChild> mVsyncBridge;
     61  VsyncEvent mVsync;
     62  layers::LayersId mLayersId;
     63 };
     64 
     65 bool VsyncBridgeChild::IsOnVsyncIOThread() const {
     66  return mThread->IsOnCurrentThread();
     67 }
     68 
     69 void VsyncBridgeChild::NotifyVsync(const VsyncEvent& aVsync,
     70                                   const layers::LayersId& aLayersId) {
     71  // This should be on the Vsync thread (not the Vsync I/O thread).
     72  MOZ_ASSERT(!IsOnVsyncIOThread());
     73 
     74  RefPtr<NotifyVsyncTask> task = new NotifyVsyncTask(this, aVsync, aLayersId);
     75  mThread->Dispatch(task.forget());
     76 }
     77 
     78 void VsyncBridgeChild::NotifyVsyncImpl(const VsyncEvent& aVsync,
     79                                       const layers::LayersId& aLayersId) {
     80  // This should be on the Vsync I/O thread.
     81  MOZ_ASSERT(IsOnVsyncIOThread());
     82 
     83  if (!mProcessToken) {
     84    return;
     85  }
     86  SendNotifyVsync(aVsync, aLayersId);
     87 }
     88 
     89 void VsyncBridgeChild::Close() {
     90  if (!IsOnVsyncIOThread()) {
     91    mThread->Dispatch(NewRunnableMethod("gfx::VsyncBridgeChild::Close", this,
     92                                        &VsyncBridgeChild::Close));
     93    return;
     94  }
     95 
     96  // We clear mProcessToken when the channel is closed.
     97  if (!mProcessToken) {
     98    return;
     99  }
    100 
    101  // Clear the process token so we don't notify the GPUProcessManager. It
    102  // already knows we're closed since it manually called Close, and in fact the
    103  // GPM could have already been destroyed during shutdown.
    104  mProcessToken = 0;
    105 
    106  // Close the underlying IPC channel.
    107  PVsyncBridgeChild::Close();
    108 }
    109 
    110 void VsyncBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
    111  if (mProcessToken) {
    112    GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
    113    mProcessToken = 0;
    114  }
    115 }
    116 
    117 void VsyncBridgeChild::ProcessingError(Result aCode, const char* aReason) {
    118  MOZ_RELEASE_ASSERT(aCode == MsgDropped,
    119                     "Processing error in VsyncBridgeChild");
    120 }
    121 
    122 void VsyncBridgeChild::HandleFatalError(const char* aMsg) {
    123  dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherChildID());
    124 }
    125 
    126 }  // namespace gfx
    127 }  // namespace mozilla