Bug 1914004 - Part 1: Add RootedTuple and RootedField to allow rooting multiple thing...
[gecko.git] / gfx / vr / nsFxrCommandLineHandler.cpp
blob126e30ef8732d657fbdef8ef0379d3dde1733065
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 // vim:cindent:tabstop=4:expandtab:shiftwidth=4:
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/. */
7 #ifndef XP_WIN
8 # error "nsFxrCommandLineHandler currently only supported on Windows"
9 #endif
11 #include "nsFxrCommandLineHandler.h"
12 #include "FxRWindowManager.h"
14 #include "nsICommandLine.h"
15 #include "nsIWindowWatcher.h"
16 #include "mozIDOMWindow.h"
17 #include "nsPIDOMWindow.h"
18 #include "mozilla/WidgetUtils.h"
19 #include "nsIWidget.h"
20 #include "nsServiceManagerUtils.h"
21 #include "nsString.h"
22 #include "nsArray.h"
23 #include "nsCOMPtr.h"
24 #include "mozilla/StaticPrefs_extensions.h"
26 #include <windows.h>
27 #include "WinUtils.h"
29 #include "VRShMem.h"
31 NS_IMPL_ISUPPORTS(nsFxrCommandLineHandler, nsICommandLineHandler)
33 // nsFxrCommandLineHandler acts in the middle of bootstrapping Firefox
34 // Reality with desktop Firefox. Details of the processes involved are
35 // described below:
37 // Host
38 // (vrhost!CreateVRWindow) Fx Main Fx GPU
39 // | + +
40 // VRShMem creates shared + +
41 // memory in OS + +
42 // | + +
43 // Launch firefox.exe + +
44 // with --fxr + +
45 // | | +
46 // Wait for Signal... nsFxrCLH handles param +
47 // | joins VRShMem +
48 // | creates new window |
49 // | sets .hwndFx in VRShMem |
50 // | | |
51 // | | After compositor and
52 // | | swapchain created,
53 // | | share texture handle to
54 // | | VRShMem and set signal
55 // CreateVRWindow returns | |
56 // to host with relevant | |
57 // return data from VRShMem | |
58 // | Fx continues to run |
59 // | | Fx continues to render
60 // | | |
61 // ... ... ...
63 NS_IMETHODIMP
64 nsFxrCommandLineHandler::Handle(nsICommandLine* aCmdLine) {
65 bool handleFlagRetVal = false;
66 nsresult result = aCmdLine->HandleFlag(u"fxr"_ns, false, &handleFlagRetVal);
67 if (result == NS_OK && handleFlagRetVal) {
68 if (XRE_IsParentProcess() && !XRE_IsE10sParentProcess()) {
69 MOZ_CRASH("--fxr not supported without e10s");
72 MOZ_ASSERT(mozilla::StaticPrefs::extensions_webextensions_remote(),
73 "Remote extensions are the only supported configuration on "
74 "desktop platforms");
76 aCmdLine->SetPreventDefault(true);
78 nsCOMPtr<nsIWindowWatcher> wwatch =
79 do_GetService(NS_WINDOWWATCHER_CONTRACTID);
80 NS_ENSURE_TRUE(wwatch, NS_ERROR_FAILURE);
82 nsCOMPtr<mozIDOMWindowProxy> newWindow;
83 result = wwatch->OpenWindow(
84 nullptr, // aParent
85 "chrome://fxr/content/fxrui.html"_ns, // aUrl
86 "_blank"_ns, // aName
87 "chrome,dialog=no,all,private,alwaysontop"_ns, // aFeatures
88 nullptr, // aArguments
89 getter_AddRefs(newWindow));
91 MOZ_ASSERT(result == NS_OK);
93 nsPIDOMWindowOuter* newWindowOuter = nsPIDOMWindowOuter::From(newWindow);
94 FxRWindowManager::GetInstance()->AddWindow(newWindowOuter);
96 // Set ForceFullScreenInWidget so that full-screen (in an FxR window)
97 // fills only the window and thus the same texture that will already be
98 // shared with the host. Also, this is set here per-window because
99 // changing the related pref would impact all browser window instances.
100 newWindowOuter->ForceFullScreenInWidget();
102 // Send the window's HWND to vrhost through VRShMem
103 mozilla::gfx::VRShMem shmem(nullptr, true /*aRequiresMutex*/);
104 if (shmem.JoinShMem()) {
105 mozilla::gfx::VRWindowState windowState = {0};
106 shmem.PullWindowState(windowState);
108 nsCOMPtr<nsIWidget> newWidget =
109 mozilla::widget::WidgetUtils::DOMWindowToWidget(newWindowOuter);
110 HWND hwndWidget = (HWND)newWidget->GetNativeData(NS_NATIVE_WINDOW);
112 // The CLH should populate these members first
113 MOZ_ASSERT(windowState.hwndFx == 0);
114 MOZ_ASSERT(windowState.textureFx == nullptr);
115 windowState.hwndFx = (uint64_t)hwndWidget;
117 shmem.PushWindowState(windowState);
118 shmem.LeaveShMem();
120 // The GPU process will notify the host that window creation is complete
121 // after output data is set in VRShMem
122 newWidget->RequestFxrOutput();
123 } else {
124 #ifndef NIGHTLY_BUILD
125 MOZ_CRASH("failed to start with --fxr");
126 #endif
130 return NS_OK;
133 NS_IMETHODIMP
134 nsFxrCommandLineHandler::GetHelpInfo(nsACString& aResult) {
135 aResult.AssignLiteral(
136 " --fxr Creates a new window for Firefox Reality on Desktop when "
137 "available\n");
138 return NS_OK;