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