nsFxrCommandLineHandler.cpp (5550B)
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/. */ 6 7 #ifndef XP_WIN 8 # error "nsFxrCommandLineHandler currently only supported on Windows" 9 #endif 10 11 #include "nsFxrCommandLineHandler.h" 12 #include "FxRWindowManager.h" 13 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" 25 26 #include <windows.h> 27 #include "WinUtils.h" 28 29 #include "VRShMem.h" 30 31 NS_IMPL_ISUPPORTS(nsFxrCommandLineHandler, nsICommandLineHandler) 32 33 // nsFxrCommandLineHandler acts in the middle of bootstrapping Firefox 34 // Reality with desktop Firefox. Details of the processes involved are 35 // described below: 36 // 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 // ... ... ... 62 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"); 70 } 71 72 MOZ_ASSERT(mozilla::StaticPrefs::extensions_webextensions_remote(), 73 "Remote extensions are the only supported configuration on " 74 "desktop platforms"); 75 76 aCmdLine->SetPreventDefault(true); 77 78 nsCOMPtr<nsIWindowWatcher> wwatch = 79 do_GetService(NS_WINDOWWATCHER_CONTRACTID); 80 NS_ENSURE_TRUE(wwatch, NS_ERROR_FAILURE); 81 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)); 90 91 MOZ_ASSERT(result == NS_OK); 92 93 nsPIDOMWindowOuter* newWindowOuter = nsPIDOMWindowOuter::From(newWindow); 94 FxRWindowManager::GetInstance()->AddWindow(newWindowOuter); 95 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(); 101 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); 107 108 nsCOMPtr<nsIWidget> newWidget = 109 mozilla::widget::WidgetUtils::DOMWindowToWidget(newWindowOuter); 110 HWND hwndWidget = (HWND)newWidget->GetNativeData(NS_NATIVE_WINDOW); 111 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; 116 117 shmem.PushWindowState(windowState); 118 shmem.LeaveShMem(); 119 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 127 } 128 } 129 130 return NS_OK; 131 } 132 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; 139 }