diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /gfx/ipc/GPUParent.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/ipc/GPUParent.cpp')
-rw-r--r-- | gfx/ipc/GPUParent.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp new file mode 100644 index 000000000..d63e17e2f --- /dev/null +++ b/gfx/ipc/GPUParent.cpp @@ -0,0 +1,390 @@ +/* -*- 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/. */ +#ifdef XP_WIN +#include "WMF.h" +#endif +#include "GPUParent.h" +#include "gfxConfig.h" +#include "gfxPlatform.h" +#include "gfxPrefs.h" +#include "GPUProcessHost.h" +#include "mozilla/Assertions.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/gfxVars.h" +#include "mozilla/ipc/CrashReporterClient.h" +#include "mozilla/ipc/ProcessChild.h" +#include "mozilla/layers/APZThreadUtils.h" +#include "mozilla/layers/APZCTreeManager.h" +#include "mozilla/layers/CompositorBridgeParent.h" +#include "mozilla/dom/VideoDecoderManagerParent.h" +#include "mozilla/layers/CompositorThread.h" +#include "mozilla/layers/ImageBridgeParent.h" +#include "mozilla/dom/VideoDecoderManagerChild.h" +#include "mozilla/layers/LayerTreeOwnerTracker.h" +#include "nsDebugImpl.h" +#include "nsExceptionHandler.h" +#include "nsThreadManager.h" +#include "prenv.h" +#include "ProcessUtils.h" +#include "VRManager.h" +#include "VRManagerParent.h" +#include "VsyncBridgeParent.h" +#if defined(XP_WIN) +# include "DeviceManagerD3D9.h" +# include "mozilla/gfx/DeviceManagerDx.h" +#endif +#ifdef MOZ_WIDGET_GTK +# include <gtk/gtk.h> +#endif + +namespace mozilla { +namespace gfx { + +using namespace ipc; +using namespace layers; + +static GPUParent* sGPUParent; + +GPUParent::GPUParent() +{ + sGPUParent = this; +} + +GPUParent::~GPUParent() +{ + sGPUParent = nullptr; +} + +/* static */ GPUParent* +GPUParent::GetSingleton() +{ + return sGPUParent; +} + +bool +GPUParent::Init(base::ProcessId aParentPid, + MessageLoop* aIOLoop, + IPC::Channel* aChannel) +{ + // Initialize the thread manager before starting IPC. Otherwise, messages + // may be posted to the main thread and we won't be able to process them. + if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) { + return false; + } + + // Now it's safe to start IPC. + if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) { + return false; + } + + nsDebugImpl::SetMultiprocessMode("GPU"); + +#ifdef MOZ_CRASHREPORTER + // Init crash reporter support. + CrashReporterClient::InitSingleton(this); +#endif + + // Ensure gfxPrefs are initialized. + gfxPrefs::GetSingleton(); + gfxConfig::Init(); + gfxVars::Initialize(); + gfxPlatform::InitNullMetadata(); + // Ensure our Factory is initialised, mainly for gfx logging to work. + gfxPlatform::InitMoz2DLogging(); +#if defined(XP_WIN) + DeviceManagerDx::Init(); + DeviceManagerD3D9::Init(); +#endif + + if (NS_FAILED(NS_InitMinimalXPCOM())) { + return false; + } + + CompositorThreadHolder::Start(); + APZThreadUtils::SetControllerThread(CompositorThreadHolder::Loop()); + APZCTreeManager::InitializeGlobalState(); + VRManager::ManagerInit(); + LayerTreeOwnerTracker::Initialize(); + mozilla::ipc::SetThisProcessName("GPU Process"); +#ifdef XP_WIN + wmf::MFStartup(); +#endif + return true; +} + +void +GPUParent::NotifyDeviceReset() +{ + if (!NS_IsMainThread()) { + NS_DispatchToMainThread(NS_NewRunnableFunction([] () -> void { + GPUParent::GetSingleton()->NotifyDeviceReset(); + })); + return; + } + + // Reset and reinitialize the compositor devices +#ifdef XP_WIN + if (!DeviceManagerDx::Get()->MaybeResetAndReacquireDevices()) { + // If the device doesn't need to be reset then the device + // has already been reset by a previous NotifyDeviceReset message. + return; + } +#endif + + // Notify the main process that there's been a device reset + // and that they should reset their compositors and repaint + Unused << SendNotifyDeviceReset(); +} + +bool +GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs, + nsTArray<GfxVarUpdate>&& vars, + const DevicePrefs& devicePrefs) +{ + const nsTArray<gfxPrefs::Pref*>& globalPrefs = gfxPrefs::all(); + for (auto& setting : prefs) { + gfxPrefs::Pref* pref = globalPrefs[setting.index()]; + pref->SetCachedValue(setting.value()); + } + for (const auto& var : vars) { + gfxVars::ApplyUpdate(var); + } + + // Inherit device preferences. + gfxConfig::Inherit(Feature::HW_COMPOSITING, devicePrefs.hwCompositing()); + gfxConfig::Inherit(Feature::D3D11_COMPOSITING, devicePrefs.d3d11Compositing()); + gfxConfig::Inherit(Feature::D3D9_COMPOSITING, devicePrefs.d3d9Compositing()); + gfxConfig::Inherit(Feature::OPENGL_COMPOSITING, devicePrefs.oglCompositing()); + gfxConfig::Inherit(Feature::DIRECT2D, devicePrefs.useD2D1()); + +#if defined(XP_WIN) + if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) { + DeviceManagerDx::Get()->CreateCompositorDevices(); + } +#endif + +#if defined(MOZ_WIDGET_GTK) + char* display_name = PR_GetEnv("DISPLAY"); + if (display_name) { + int argc = 3; + char option_name[] = "--display"; + char* argv[] = { + // argv0 is unused because g_set_prgname() was called in + // XRE_InitChildProcess(). + nullptr, + option_name, + display_name, + nullptr + }; + char** argvp = argv; + gtk_init(&argc, &argvp); + } else { + gtk_init(nullptr, nullptr); + } +#endif + + // Send a message to the UI process that we're done. + GPUDeviceData data; + RecvGetDeviceStatus(&data); + Unused << SendInitComplete(data); + + return true; +} + +bool +GPUParent::RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint) +{ + mVsyncBridge = VsyncBridgeParent::Start(Move(aVsyncEndpoint)); + return true; +} + +bool +GPUParent::RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) +{ + ImageBridgeParent::CreateForGPUProcess(Move(aEndpoint)); + return true; +} + +bool +GPUParent::RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint) +{ + VRManagerParent::CreateForGPUProcess(Move(aEndpoint)); + return true; +} + +bool +GPUParent::RecvUpdatePref(const GfxPrefSetting& setting) +{ + gfxPrefs::Pref* pref = gfxPrefs::all()[setting.index()]; + pref->SetCachedValue(setting.value()); + return true; +} + +bool +GPUParent::RecvUpdateVar(const GfxVarUpdate& aUpdate) +{ + gfxVars::ApplyUpdate(aUpdate); + return true; +} + +static void +CopyFeatureChange(Feature aFeature, FeatureChange* aOut) +{ + FeatureState& feature = gfxConfig::GetFeature(aFeature); + if (feature.DisabledByDefault() || feature.IsEnabled()) { + // No change: + // - Disabled-by-default means the parent process told us not to use this feature. + // - Enabled means we were told to use this feature, and we didn't discover anything + // that would prevent us from doing so. + *aOut = null_t(); + return; + } + + MOZ_ASSERT(!feature.IsEnabled()); + + nsCString message; + message.AssignASCII(feature.GetFailureMessage()); + + *aOut = FeatureFailure(feature.GetValue(), message, feature.GetFailureId()); +} + +bool +GPUParent::RecvGetDeviceStatus(GPUDeviceData* aOut) +{ + CopyFeatureChange(Feature::D3D11_COMPOSITING, &aOut->d3d11Compositing()); + CopyFeatureChange(Feature::D3D9_COMPOSITING, &aOut->d3d9Compositing()); + CopyFeatureChange(Feature::OPENGL_COMPOSITING, &aOut->oglCompositing()); + +#if defined(XP_WIN) + if (DeviceManagerDx* dm = DeviceManagerDx::Get()) { + D3D11DeviceStatus deviceStatus; + dm->ExportDeviceInfo(&deviceStatus); + aOut->gpuDevice() = deviceStatus; + } +#else + aOut->gpuDevice() = null_t(); +#endif + + return true; +} + +static void +OpenParent(RefPtr<CompositorBridgeParent> aParent, + Endpoint<PCompositorBridgeParent>&& aEndpoint) +{ + if (!aParent->Bind(Move(aEndpoint))) { + MOZ_CRASH("Failed to bind compositor"); + } +} + +bool +GPUParent::RecvNewWidgetCompositor(Endpoint<layers::PCompositorBridgeParent>&& aEndpoint, + const CSSToLayoutDeviceScale& aScale, + const TimeDuration& aVsyncRate, + const bool& aUseExternalSurfaceSize, + const IntSize& aSurfaceSize) +{ + RefPtr<CompositorBridgeParent> cbp = + new CompositorBridgeParent(aScale, aVsyncRate, aUseExternalSurfaceSize, aSurfaceSize); + + MessageLoop* loop = CompositorThreadHolder::Loop(); + loop->PostTask(NewRunnableFunction(OpenParent, cbp, Move(aEndpoint))); + return true; +} + +bool +GPUParent::RecvNewContentCompositorBridge(Endpoint<PCompositorBridgeParent>&& aEndpoint) +{ + return CompositorBridgeParent::CreateForContent(Move(aEndpoint)); +} + +bool +GPUParent::RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) +{ + return ImageBridgeParent::CreateForContent(Move(aEndpoint)); +} + +bool +GPUParent::RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint) +{ + return VRManagerParent::CreateForContent(Move(aEndpoint)); +} + +bool +GPUParent::RecvNewContentVideoDecoderManager(Endpoint<PVideoDecoderManagerParent>&& aEndpoint) +{ + return dom::VideoDecoderManagerParent::CreateForContent(Move(aEndpoint)); +} + +bool +GPUParent::RecvAddLayerTreeIdMapping(nsTArray<LayerTreeIdMapping>&& aMappings) +{ + for (const LayerTreeIdMapping& map : aMappings) { + LayerTreeOwnerTracker::Get()->Map(map.layersId(), map.ownerId()); + } + return true; +} + +bool +GPUParent::RecvRemoveLayerTreeIdMapping(const LayerTreeIdMapping& aMapping) +{ + LayerTreeOwnerTracker::Get()->Unmap(aMapping.layersId(), aMapping.ownerId()); + CompositorBridgeParent::DeallocateLayerTreeId(aMapping.layersId()); + return true; +} + +bool +GPUParent::RecvNotifyGpuObservers(const nsCString& aTopic) +{ + nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService(); + MOZ_ASSERT(obsSvc); + if (obsSvc) { + obsSvc->NotifyObservers(nullptr, aTopic.get(), nullptr); + } + return true; +} + +void +GPUParent::ActorDestroy(ActorDestroyReason aWhy) +{ + if (AbnormalShutdown == aWhy) { + NS_WARNING("Shutting down GPU process early due to a crash!"); + ProcessChild::QuickExit(); + } + +#ifdef XP_WIN + wmf::MFShutdown(); +#endif + +#ifndef NS_FREE_PERMANENT_DATA + // No point in going through XPCOM shutdown because we don't keep persistent + // state. + ProcessChild::QuickExit(); +#endif + + if (mVsyncBridge) { + mVsyncBridge->Shutdown(); + mVsyncBridge = nullptr; + } + dom::VideoDecoderManagerParent::ShutdownVideoBridge(); + CompositorThreadHolder::Shutdown(); + Factory::ShutDown(); +#if defined(XP_WIN) + DeviceManagerDx::Shutdown(); + DeviceManagerD3D9::Shutdown(); +#endif + LayerTreeOwnerTracker::Shutdown(); + gfxVars::Shutdown(); + gfxConfig::Shutdown(); + gfxPrefs::DestroySingleton(); +#ifdef MOZ_CRASHREPORTER + CrashReporterClient::DestroySingleton(); +#endif + XRE_ShutdownChildProcess(); +} + +} // namespace gfx +} // namespace mozilla |