mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Add skeletal code for launching a GPU process. (bug 1271180 part 4, r=billm,jrmuizel)
--HG-- extra : rebase_source : 332f5cf6ca5e1f78fb2283a7e79b6b21654e9e59
This commit is contained in:
parent
39defbc2f7
commit
d2678d4141
@ -22,6 +22,7 @@ namespace gfx {
|
||||
_(D3D9_COMPOSITING, Feature, "Direct3D9 Compositing") \
|
||||
_(DIRECT2D, Feature, "Direct2D") \
|
||||
_(D3D11_HW_ANGLE, Feature, "Direct3D11 hardware ANGLE") \
|
||||
_(GPU_PROCESS, Feature, "GPU Process") \
|
||||
/* Add new entries above this comment */
|
||||
|
||||
enum class Feature : uint32_t {
|
||||
|
22
gfx/ipc/GPUChild.cpp
Normal file
22
gfx/ipc/GPUChild.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "GPUChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
GPUChild::GPUChild()
|
||||
{
|
||||
MOZ_COUNT_CTOR(GPUChild);
|
||||
}
|
||||
|
||||
GPUChild::~GPUChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GPUChild);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
24
gfx/ipc/GPUChild.h
Normal file
24
gfx/ipc/GPUChild.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _include_mozilla_gfx_ipc_GPUChild_h_
|
||||
#define _include_mozilla_gfx_ipc_GPUChild_h_
|
||||
|
||||
#include "mozilla/gfx/PGPUChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class GPUChild final : public PGPUChild
|
||||
{
|
||||
public:
|
||||
GPUChild();
|
||||
~GPUChild();
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _include_mozilla_gfx_ipc_GPUChild_h_
|
55
gfx/ipc/GPUParent.cpp
Normal file
55
gfx/ipc/GPUParent.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "GPUParent.h"
|
||||
#include "gfxConfig.h"
|
||||
#include "GPUProcessHost.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
GPUParent::GPUParent()
|
||||
{
|
||||
}
|
||||
|
||||
GPUParent::~GPUParent()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
GPUParent::Init(base::ProcessId aParentPid,
|
||||
MessageLoop* aIOLoop,
|
||||
IPC::Channel* aChannel)
|
||||
{
|
||||
if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GPUParent::RecvBeginShutdown()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GPUParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (AbnormalShutdown == aWhy) {
|
||||
NS_WARNING("Shutting down GPU process early due to a crash!");
|
||||
ProcessChild::QuickExit();
|
||||
}
|
||||
|
||||
XRE_ShutdownChildProcess();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
32
gfx/ipc/GPUParent.h
Normal file
32
gfx/ipc/GPUParent.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _include_gfx_ipc_GPUParent_h__
|
||||
#define _include_gfx_ipc_GPUParent_h__
|
||||
|
||||
#include "mozilla/gfx/PGPUParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class GPUParent final : public PGPUParent
|
||||
{
|
||||
public:
|
||||
GPUParent();
|
||||
~GPUParent();
|
||||
|
||||
bool Init(base::ProcessId aParentPid,
|
||||
MessageLoop* aIOLoop,
|
||||
IPC::Channel* aChannel);
|
||||
|
||||
bool RecvBeginShutdown() override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _include_gfx_ipc_GPUParent_h__
|
150
gfx/ipc/GPUProcessHost.cpp
Normal file
150
gfx/ipc/GPUProcessHost.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: sts=8 sw=2 ts=2 tw=99 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
#include "GPUProcessHost.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
GPUProcessHost::GPUProcessHost(Listener* aListener)
|
||||
: GeckoChildProcessHost(GeckoProcessType_GPU),
|
||||
mListener(aListener),
|
||||
mTaskFactory(this),
|
||||
mLaunchPhase(LaunchPhase::Unlaunched)
|
||||
{
|
||||
MOZ_COUNT_CTOR(GPUProcessHost);
|
||||
}
|
||||
|
||||
GPUProcessHost::~GPUProcessHost()
|
||||
{
|
||||
MOZ_COUNT_DTOR(GPUProcessHost);
|
||||
}
|
||||
|
||||
bool
|
||||
GPUProcessHost::Launch()
|
||||
{
|
||||
MOZ_ASSERT(mLaunchPhase == LaunchPhase::Unlaunched);
|
||||
MOZ_ASSERT(!mGPUChild);
|
||||
|
||||
mLaunchPhase = LaunchPhase::Waiting;
|
||||
if (!GeckoChildProcessHost::AsyncLaunch()) {
|
||||
mLaunchPhase = LaunchPhase::Complete;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GPUProcessHost::WaitForLaunch()
|
||||
{
|
||||
if (mLaunchPhase == LaunchPhase::Complete) {
|
||||
return !!mGPUChild;
|
||||
}
|
||||
|
||||
int32_t timeoutMs = gfxPrefs::GPUProcessDevTimeoutMs();
|
||||
|
||||
// Our caller expects the connection to be finished after we return, so we
|
||||
// immediately set up the IPDL actor and fire callbacks. The IO thread will
|
||||
// still dispatch a notification to the main thread - we'll just ignore it.
|
||||
bool result = GeckoChildProcessHost::WaitUntilConnected(timeoutMs);
|
||||
InitAfterConnect(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessHost::OnChannelConnected(int32_t peer_pid)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
GeckoChildProcessHost::OnChannelConnected(peer_pid);
|
||||
|
||||
// Post a task to the main thread. Take the lock because mTaskFactory is not
|
||||
// thread-safe.
|
||||
RefPtr<Runnable> runnable;
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
runnable = mTaskFactory.NewRunnableMethod(&GPUProcessHost::OnChannelConnectedTask);
|
||||
}
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessHost::OnChannelError()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
GeckoChildProcessHost::OnChannelError();
|
||||
|
||||
// Post a task to the main thread. Take the lock because mTaskFactory is not
|
||||
// thread-safe.
|
||||
RefPtr<Runnable> runnable;
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
runnable = mTaskFactory.NewRunnableMethod(&GPUProcessHost::OnChannelErrorTask);
|
||||
}
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessHost::OnChannelConnectedTask()
|
||||
{
|
||||
if (mLaunchPhase == LaunchPhase::Waiting) {
|
||||
InitAfterConnect(true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessHost::OnChannelErrorTask()
|
||||
{
|
||||
if (mLaunchPhase == LaunchPhase::Waiting) {
|
||||
InitAfterConnect(false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessHost::InitAfterConnect(bool aSucceeded)
|
||||
{
|
||||
MOZ_ASSERT(mLaunchPhase == LaunchPhase::Waiting);
|
||||
MOZ_ASSERT(!mGPUChild);
|
||||
|
||||
mLaunchPhase = LaunchPhase::Complete;
|
||||
|
||||
if (aSucceeded) {
|
||||
mGPUChild = MakeUnique<GPUChild>();
|
||||
DebugOnly<bool> rv =
|
||||
mGPUChild->Open(GetChannel(), base::GetProcId(GetChildProcessHandle()));
|
||||
MOZ_ASSERT(rv);
|
||||
}
|
||||
|
||||
if (mListener) {
|
||||
mListener->OnProcessLaunchComplete(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessHost::Shutdown()
|
||||
{
|
||||
mListener = nullptr;
|
||||
DestroyProcess();
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessHost::DestroyProcess()
|
||||
{
|
||||
// Cancel all tasks. We don't want anything triggering after our caller
|
||||
// expects this to go away.
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mTaskFactory.RevokeAll();
|
||||
}
|
||||
|
||||
DissociateActor();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
103
gfx/ipc/GPUProcessHost.h
Normal file
103
gfx/ipc/GPUProcessHost.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: sts=8 sw=2 ts=2 tw=99 et :
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _include_mozilla_gfx_ipc_GPUProcessHost_h_
|
||||
#define _include_mozilla_gfx_ipc_GPUProcessHost_h_
|
||||
|
||||
#include "mozilla/Function.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/ipc/TaskFactory.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class GPUChild;
|
||||
|
||||
// GPUProcessHost is the "parent process" container for a subprocess handle and
|
||||
// IPC connection. It owns the parent process IPDL actor, which in this case,
|
||||
// is a GPUChild.
|
||||
//
|
||||
// GPUProcessHosts are allocated and managed by GPUProcessManager. For all
|
||||
// intents and purposes it is a singleton, though more than one may be allocated
|
||||
// at a time due to its shutdown being asynchronous.
|
||||
class GPUProcessHost final : public ipc::GeckoChildProcessHost
|
||||
{
|
||||
public:
|
||||
class Listener {
|
||||
public:
|
||||
virtual void OnProcessLaunchComplete(GPUProcessHost* aHost)
|
||||
{}
|
||||
};
|
||||
|
||||
public:
|
||||
GPUProcessHost(Listener* listener);
|
||||
~GPUProcessHost();
|
||||
|
||||
// Launch the subprocess asynchronously. On failure, false is returned.
|
||||
// Otherwise, true is returned, and the OnLaunchComplete listener callback
|
||||
// will be invoked either when a connection has been established, or if a
|
||||
// connection could not be established due to an asynchronous error.
|
||||
bool Launch();
|
||||
|
||||
// If the process is being launched, block until it has launched and
|
||||
// connected. If a launch task is pending, it will fire immediately.
|
||||
//
|
||||
// Returns true if the process is successfully connected; false otherwise.
|
||||
bool WaitForLaunch();
|
||||
|
||||
// Inform the process that it should clean up its resources and shut down.
|
||||
// This initiates an asynchronous shutdown sequence. After this method returns,
|
||||
// it is safe for the caller to forget its pointer to the GPUProcessHost.
|
||||
//
|
||||
// After this returns, the attached Listener is no longer used.
|
||||
void Shutdown();
|
||||
|
||||
// Return the actor for the top-level actor of the process. If the process
|
||||
// has not connected yet, this returns null.
|
||||
GPUChild* GetActor() const {
|
||||
return mGPUChild.get();
|
||||
}
|
||||
|
||||
bool IsConnected() const {
|
||||
return !!mGPUChild;
|
||||
}
|
||||
|
||||
// Called on the IO thread.
|
||||
void OnChannelConnected(int32_t peer_pid) override;
|
||||
void OnChannelError() override;
|
||||
|
||||
private:
|
||||
// Called on the main thread.
|
||||
void OnChannelConnectedTask();
|
||||
void OnChannelErrorTask();
|
||||
|
||||
// Called on the main thread after a connection has been established.
|
||||
void InitAfterConnect(bool aSucceeded);
|
||||
|
||||
void DestroyProcess();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(GPUProcessHost);
|
||||
|
||||
Listener* mListener;
|
||||
ipc::TaskFactory<GPUProcessHost> mTaskFactory;
|
||||
|
||||
enum class LaunchPhase {
|
||||
Unlaunched,
|
||||
Waiting,
|
||||
Complete
|
||||
};
|
||||
LaunchPhase mLaunchPhase;
|
||||
|
||||
UniquePtr<GPUChild> mGPUChild;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _include_mozilla_gfx_ipc_GPUProcessHost_h_
|
37
gfx/ipc/GPUProcessImpl.cpp
Normal file
37
gfx/ipc/GPUProcessImpl.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "GPUProcessImpl.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
GPUProcessImpl::GPUProcessImpl(ProcessId aParentPid)
|
||||
: ProcessChild(aParentPid)
|
||||
{
|
||||
}
|
||||
|
||||
GPUProcessImpl::~GPUProcessImpl()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
GPUProcessImpl::Init()
|
||||
{
|
||||
return mGPU.Init(ParentPid(),
|
||||
IOThreadChild::message_loop(),
|
||||
IOThreadChild::channel());
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessImpl::CleanUp()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
34
gfx/ipc/GPUProcessImpl.h
Normal file
34
gfx/ipc/GPUProcessImpl.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _include_gfx_ipc_GPUProcessImpl_h__
|
||||
#define _include_gfx_ipc_GPUProcessImpl_h__
|
||||
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
#include "GPUParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
// This class owns the subprocess instance of a PGPU - which in this case,
|
||||
// is a GPUParent. It is instantiated as a singleton in XRE_InitChildProcess.
|
||||
class GPUProcessImpl final : public ipc::ProcessChild
|
||||
{
|
||||
public:
|
||||
explicit GPUProcessImpl(ProcessId aParentPid);
|
||||
~GPUProcessImpl();
|
||||
|
||||
bool Init() override;
|
||||
void CleanUp() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(GPUProcessImpl);
|
||||
GPUParent mGPU;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _include_gfx_ipc_GPUProcessImpl_h__
|
@ -4,8 +4,10 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "GPUProcessManager.h"
|
||||
#include "GPUProcessHost.h"
|
||||
#include "mozilla/layers/CompositorSession.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
@ -34,11 +36,109 @@ GPUProcessManager::Shutdown()
|
||||
}
|
||||
|
||||
GPUProcessManager::GPUProcessManager()
|
||||
: mProcess(nullptr),
|
||||
mGPUChild(nullptr)
|
||||
{
|
||||
mObserver = new Observer(this);
|
||||
nsContentUtils::RegisterShutdownObserver(mObserver);
|
||||
}
|
||||
|
||||
GPUProcessManager::~GPUProcessManager()
|
||||
{
|
||||
// The GPU process should have already been shut down.
|
||||
MOZ_ASSERT(!mProcess && !mGPUChild);
|
||||
|
||||
// We should have already removed observers.
|
||||
MOZ_ASSERT(!mObserver);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(GPUProcessManager::Observer, nsIObserver);
|
||||
|
||||
GPUProcessManager::Observer::Observer(GPUProcessManager* aManager)
|
||||
: mManager(aManager)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GPUProcessManager::Observer::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
mManager->OnXPCOMShutdown();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::OnXPCOMShutdown()
|
||||
{
|
||||
if (mObserver) {
|
||||
nsContentUtils::UnregisterShutdownObserver(mObserver);
|
||||
mObserver = nullptr;
|
||||
}
|
||||
|
||||
DestroyProcess();
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::EnableGPUProcess()
|
||||
{
|
||||
if (mProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The subprocess is launched asynchronously, so we wait for a callback to
|
||||
// acquire the IPDL actor.
|
||||
mProcess = new GPUProcessHost(this);
|
||||
if (!mProcess->Launch()) {
|
||||
DisableGPUProcess("Failed to launch GPU process");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::DisableGPUProcess(const char* aMessage)
|
||||
{
|
||||
gfxConfig::SetFailed(Feature::GPU_PROCESS, FeatureStatus::Failed, aMessage);
|
||||
gfxCriticalNote << aMessage;
|
||||
|
||||
DestroyProcess();
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::EnsureGPUReady()
|
||||
{
|
||||
if (mProcess && mProcess->IsConnected()) {
|
||||
if (!mProcess->WaitForLaunch()) {
|
||||
// If this fails, we should have fired OnProcessLaunchComplete and
|
||||
// removed the process.
|
||||
MOZ_ASSERT(!mProcess && !mGPUChild);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost)
|
||||
{
|
||||
MOZ_ASSERT(mProcess && mProcess == aHost);
|
||||
|
||||
if (!mProcess->IsConnected()) {
|
||||
DisableGPUProcess("Failed to launch GPU process");
|
||||
return;
|
||||
}
|
||||
|
||||
mGPUChild = mProcess->GetActor();
|
||||
}
|
||||
|
||||
void
|
||||
GPUProcessManager::DestroyProcess()
|
||||
{
|
||||
if (!mProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
mProcess->Shutdown();
|
||||
mProcess = nullptr;
|
||||
mGPUChild = nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<CompositorSession>
|
||||
|
@ -10,7 +10,9 @@
|
||||
#include "base/process.h"
|
||||
#include "Units.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "mozilla/gfx/GPUProcessHost.h"
|
||||
#include "mozilla/ipc/Transport.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -32,10 +34,12 @@ class GeckoChildProcessHost;
|
||||
} // namespace ipc
|
||||
namespace gfx {
|
||||
|
||||
class GPUChild;
|
||||
|
||||
// The GPUProcessManager is a singleton responsible for creating GPU-bound
|
||||
// objects that may live in another process. Currently, it provides access
|
||||
// to the compositor via CompositorBridgeParent.
|
||||
class GPUProcessManager final
|
||||
class GPUProcessManager final : public GPUProcessHost::Listener
|
||||
{
|
||||
typedef layers::APZCTreeManager APZCTreeManager;
|
||||
typedef layers::CompositorUpdateObserver CompositorUpdateObserver;
|
||||
@ -47,6 +51,14 @@ public:
|
||||
|
||||
~GPUProcessManager();
|
||||
|
||||
// If not using a GPU process, launch a new GPU process asynchronously.
|
||||
void EnableGPUProcess();
|
||||
|
||||
// Ensure that GPU-bound methods can be used. If no GPU process is being
|
||||
// used, or one is launched and ready, this function returns immediately.
|
||||
// Otherwise it blocks until the GPU process has finished launching.
|
||||
void EnsureGPUReady();
|
||||
|
||||
already_AddRefed<layers::CompositorSession> CreateTopLevelCompositor(
|
||||
widget::CompositorWidgetProxy* aProxy,
|
||||
layers::ClientLayerManager* aLayerManager,
|
||||
@ -92,10 +104,40 @@ public:
|
||||
const dom::TabId& aTabId,
|
||||
dom::TabParent* aBrowserParent);
|
||||
|
||||
void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
|
||||
|
||||
private:
|
||||
// Called from our xpcom-shutdown observer.
|
||||
void OnXPCOMShutdown();
|
||||
|
||||
private:
|
||||
GPUProcessManager();
|
||||
|
||||
// Permanently disable the GPU process and record a message why.
|
||||
void DisableGPUProcess(const char* aMessage);
|
||||
|
||||
// Shutdown the GPU process.
|
||||
void DestroyProcess();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GPUProcessManager);
|
||||
|
||||
class Observer final : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
Observer(GPUProcessManager* aManager);
|
||||
|
||||
protected:
|
||||
~Observer() {}
|
||||
|
||||
GPUProcessManager* mManager;
|
||||
};
|
||||
friend class Observer;
|
||||
|
||||
private:
|
||||
RefPtr<Observer> mObserver;
|
||||
GPUProcessHost* mProcess;
|
||||
GPUChild* mGPUChild;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
17
gfx/ipc/PGPU.ipdl
Normal file
17
gfx/ipc/PGPU.ipdl
Normal file
@ -0,0 +1,17 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
sync protocol PGPU
|
||||
{
|
||||
parent:
|
||||
// Sent by the UI process to initiate shutdown.
|
||||
async BeginShutdown();
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
@ -10,6 +10,10 @@ EXPORTS.mozilla += [
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.gfx += [
|
||||
'GPUChild.h',
|
||||
'GPUParent.h',
|
||||
'GPUProcessHost.h',
|
||||
'GPUProcessImpl.h',
|
||||
'GPUProcessManager.h',
|
||||
'SharedDIB.h',
|
||||
]
|
||||
@ -31,12 +35,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
UNIFIED_SOURCES += [
|
||||
'CompositorSession.cpp',
|
||||
'D3DMessageUtils.cpp',
|
||||
'GPUChild.cpp',
|
||||
'GPUParent.cpp',
|
||||
'GPUProcessHost.cpp',
|
||||
'GPUProcessImpl.cpp',
|
||||
'GPUProcessManager.cpp',
|
||||
'SharedDIB.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES = [
|
||||
'GraphicsMessages.ipdlh',
|
||||
'PGPU.ipdl',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
@ -142,6 +142,7 @@ class mozilla::gl::SkiaGLGlue : public GenericAtomicRefCounted {
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "gfxVR.h"
|
||||
#include "VRManagerChild.h"
|
||||
#include "mozilla/gfx/GPUParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -2119,6 +2120,23 @@ gfxPlatform::InitAcceleration()
|
||||
"media.hardware-video-decoding.failed",
|
||||
false);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
if (gfxPrefs::GPUProcessDevEnabled()) {
|
||||
// We want to hide this from about:support, so only set a default if the
|
||||
// pref is known to be true.
|
||||
gfxConfig::SetDefaultFromPref(
|
||||
Feature::GPU_PROCESS,
|
||||
gfxPrefs::GetGPUProcessDevEnabledPrefName(),
|
||||
true,
|
||||
gfxPrefs::GetGPUProcessDevEnabledPrefDefault());
|
||||
}
|
||||
|
||||
if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
|
||||
GPUProcessManager* gpu = GPUProcessManager::Get();
|
||||
gpu->EnableGPUProcess();
|
||||
}
|
||||
}
|
||||
|
||||
sLayersAccelerationPrefsInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ class PreferenceAccessImpl;
|
||||
class gfxPrefs;
|
||||
class gfxPrefs final
|
||||
{
|
||||
private:
|
||||
private:
|
||||
/// See Logging.h. This lets Moz2D access preference values it owns.
|
||||
PreferenceAccessImpl* mMoz2DPrefAccess;
|
||||
|
||||
@ -365,6 +365,8 @@ private:
|
||||
DECL_GFX_PREF(Live, "layers.flash-borders", FlashLayerBorders, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.force-shmem-tiles", ForceShmemTiles, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.frame-counter", DrawFrameCounter, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.gpu-process.dev.enabled", GPUProcessDevEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.gpu-process.dev.timeout_ms", GPUProcessDevTimeoutMs, int32_t, 5000);
|
||||
DECL_GFX_PREF(Once, "layers.gralloc.disable", DisableGralloc, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.low-precision-buffer", UseLowPrecisionBuffer, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.low-precision-opacity", LowPrecisionOpacity, float, 1.0f);
|
||||
|
@ -1072,6 +1072,8 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
shouldSandboxCurrentProcess = true;
|
||||
}
|
||||
break;
|
||||
case GeckoProcessType_GPU:
|
||||
break;
|
||||
case GeckoProcessType_Default:
|
||||
default:
|
||||
MOZ_CRASH("Bad process type in GeckoChildProcessHost");
|
||||
|
@ -73,6 +73,7 @@
|
||||
|
||||
#include "GMPProcessChild.h"
|
||||
#include "GMPLoader.h"
|
||||
#include "mozilla/gfx/GPUProcessImpl.h"
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
@ -566,6 +567,9 @@ XRE_InitChildProcess(int aArgc,
|
||||
case GeckoProcessType_GMPlugin:
|
||||
uiLoopType = MessageLoop::TYPE_DEFAULT;
|
||||
break;
|
||||
case GeckoProcessType_GPU:
|
||||
uiLoopType = MessageLoop::TYPE_UI;
|
||||
break;
|
||||
default:
|
||||
uiLoopType = MessageLoop::TYPE_UI;
|
||||
break;
|
||||
@ -621,6 +625,10 @@ XRE_InitChildProcess(int aArgc,
|
||||
process = new gmp::GMPProcessChild(parentPID);
|
||||
break;
|
||||
|
||||
case GeckoProcessType_GPU:
|
||||
process = new gfx::GPUProcessImpl(parentPID);
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_RUNTIMEABORT("Unknown main thread class");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user