зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1570125 - Create VR window via vrhost r=kip,mossop
This change creates the new export CreateVRWindow from vrhost.dll. This API results in spawning a new Firefox window with the Firefox Reality 2D UI and returns data needed for the host to interact with it. VRShMem is used to pass data across process boundaries during this bootstrap process. Additional tests are added to vrhost to be later converted to unittests. Differential Revision: https://phabricator.services.mozilla.com/D40236 --HG-- rename : gfx/vr/vrhost/vrhost.cpp => gfx/vr/vrhost/vrhosttest.cpp extra : moz-landing-system : lando
This commit is contained in:
Родитель
26c2894a62
Коммит
94cc4efcb3
|
@ -30,11 +30,12 @@ using namespace mozilla::gfx;
|
|||
// and mapped files if we have both release and nightlies
|
||||
// running at the same time? Or...what if we have multiple
|
||||
// release builds running on same machine? (Bug 1563232)
|
||||
#define SHMEM_VERSION "0.0.2"
|
||||
#ifdef XP_WIN
|
||||
static const char* kShmemName = "moz.gecko.vr_ext.0.0.1";
|
||||
static LPCTSTR kMutexName = TEXT("mozilla::vr::ShmemMutex");
|
||||
static const char* kShmemName = "moz.gecko.vr_ext." SHMEM_VERSION;
|
||||
static LPCTSTR kMutexName = TEXT("mozilla::vr::ShmemMutex" SHMEM_VERSION);
|
||||
#elif defined(XP_MACOSX)
|
||||
static const char* kShmemName = "/moz.gecko.vr_ext.0.0.1";
|
||||
static const char* kShmemName = "/moz.gecko.vr_ext." SHMEM_VERSION;
|
||||
#endif // XP_WIN
|
||||
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
|
@ -571,3 +572,34 @@ void VRShMem::PullSystemState(
|
|||
} // while (!true)
|
||||
}
|
||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
void VRShMem::PushWindowState(VRWindowState& aState) {
|
||||
#if defined(XP_WIN)
|
||||
if (!mExternalShmem) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool status = true;
|
||||
WaitForMutex lock(mMutex);
|
||||
status = lock.GetStatus();
|
||||
if (status) {
|
||||
memcpy((void*)&(mExternalShmem->windowState), (void*)&aState,
|
||||
sizeof(VRWindowState));
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
void VRShMem::PullWindowState(VRWindowState& aState) {
|
||||
#if defined(XP_WIN)
|
||||
if (!mExternalShmem) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool status = true;
|
||||
WaitForMutex lock(mMutex);
|
||||
status = lock.GetStatus();
|
||||
if (status) {
|
||||
memcpy((void*)&aState, (void*)&(mExternalShmem->windowState),
|
||||
sizeof(VRWindowState));
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
|
|
|
@ -43,6 +43,9 @@ class VRShMem final {
|
|||
bool& aEnumerationCompleted,
|
||||
const std::function<bool()>& aWaitCondition = nullptr);
|
||||
|
||||
void PushWindowState(VRWindowState& aState);
|
||||
void PullWindowState(VRWindowState& aState);
|
||||
|
||||
bool HasExternalShmem() const { return mExternalShmem != nullptr; }
|
||||
volatile VRExternalShmem* GetExternalShmem() const;
|
||||
bool IsDisplayStateShutdown() const;
|
||||
|
|
|
@ -430,6 +430,23 @@ struct VRSystemState {
|
|||
VRControllerState controllerState[kVRControllerMaxCount];
|
||||
};
|
||||
|
||||
// Data shared via shmem for running Firefox in a VR windowed environment
|
||||
struct VRWindowState {
|
||||
// State from Firefox
|
||||
uint64_t hwndFx;
|
||||
uint32_t widthFx;
|
||||
uint32_t heightFx;
|
||||
VRLayerTextureHandle textureFx;
|
||||
|
||||
// State from VRHost
|
||||
uint32_t dxgiAdapterHost;
|
||||
uint32_t widthHost;
|
||||
uint32_t heightHost;
|
||||
|
||||
// Name of synchronization primitive to signal change to this struct
|
||||
char signalName[32];
|
||||
};
|
||||
|
||||
struct VRExternalShmem {
|
||||
int32_t version;
|
||||
int32_t size;
|
||||
|
@ -455,6 +472,9 @@ struct VRExternalShmem {
|
|||
int64_t geckoGenerationB;
|
||||
int64_t servoGenerationB;
|
||||
#endif // !defined(__ANDROID__)
|
||||
#if defined(XP_WIN)
|
||||
VRWindowState windowState;
|
||||
#endif
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
void Clear() volatile {
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include "nsICommandLine.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "mozIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "mozilla/WidgetUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsArray.h"
|
||||
|
@ -20,6 +23,8 @@
|
|||
|
||||
#include "windows.h"
|
||||
|
||||
#include "VRShMem.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFxrCommandLineHandler, nsICommandLineHandler)
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -43,6 +48,39 @@ nsFxrCommandLineHandler::Handle(nsICommandLine* aCmdLine) {
|
|||
getter_AddRefs(newWindow));
|
||||
|
||||
MOZ_ASSERT(result == NS_OK);
|
||||
|
||||
// Send the window's HWND to vrhost through VRShMem
|
||||
mozilla::gfx::VRShMem shmem(nullptr, true, false);
|
||||
if (shmem.JoinShMem()) {
|
||||
mozilla::gfx::VRWindowState windowState = {0};
|
||||
shmem.PullWindowState(windowState);
|
||||
|
||||
nsCOMPtr<nsIWidget> newWidget =
|
||||
mozilla::widget::WidgetUtils::DOMWindowToWidget(
|
||||
nsPIDOMWindowOuter::From(newWindow));
|
||||
HWND hwndWidget = (HWND)newWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
|
||||
// The CLH should have populated this first
|
||||
MOZ_ASSERT(windowState.hwndFx == 0);
|
||||
MOZ_ASSERT(windowState.textureFx == nullptr);
|
||||
windowState.hwndFx = (uint64_t)hwndWidget;
|
||||
|
||||
shmem.PushWindowState(windowState);
|
||||
|
||||
// Notify the waiting process that the data is now available
|
||||
HANDLE hSignal = ::OpenEventA(EVENT_ALL_ACCESS, // dwDesiredAccess
|
||||
FALSE, // bInheritHandle
|
||||
windowState.signalName // lpName
|
||||
);
|
||||
|
||||
::SetEvent(hSignal);
|
||||
|
||||
shmem.LeaveShMem();
|
||||
|
||||
::CloseHandle(hSignal);
|
||||
} else {
|
||||
MOZ_CRASH("failed to start with --fxr");
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -6,9 +6,14 @@
|
|||
|
||||
SOURCES += [
|
||||
'/gfx/vr/VRShMem.cpp',
|
||||
'vrhost.cpp'
|
||||
'vrhostapi.cpp'
|
||||
]
|
||||
|
||||
if CONFIG['NIGHTLY_BUILD']:
|
||||
SOURCES += [
|
||||
'vrhosttest.cpp'
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/gfx/vr',
|
||||
'/gfx/vr/external_api',
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
int main(int argc, char* argv[], char* envp[]) {
|
||||
HINSTANCE hVR = ::LoadLibrary("vrhost.dll");
|
||||
if (hVR != nullptr) {
|
||||
// Sometimes LoadLibrary can set an error, but, if it returns a handle,
|
||||
// then it succeeded. Clear the last error so that subsequent calls to
|
||||
// GetLastError don't improperly attribute failure to another API.
|
||||
::SetLastError(0);
|
||||
|
||||
PFN_SAMPLE lpfnSample = (PFN_SAMPLE)GetProcAddress(hVR, "SampleExport");
|
||||
if (lpfnSample != nullptr) {
|
||||
lpfnSample();
|
||||
|
@ -18,11 +23,16 @@ int main(int argc, char* argv[], char* envp[]) {
|
|||
if (strcmp(argv[1], "-testsvc") == 0) {
|
||||
PFN_SAMPLE lpfnService =
|
||||
(PFN_SAMPLE)GetProcAddress(hVR, "TestTheService");
|
||||
|
||||
lpfnService();
|
||||
} else if (strcmp(argv[1], "-testmgr") == 0) {
|
||||
PFN_SAMPLE lpfnManager =
|
||||
(PFN_SAMPLE)GetProcAddress(hVR, "TestTheManager");
|
||||
lpfnManager();
|
||||
} else if (strcmp(argv[1], "-testvrwin") == 0) {
|
||||
PFN_SAMPLE lpfnManager =
|
||||
(PFN_SAMPLE)GetProcAddress(hVR, "TestCreateVRWindow");
|
||||
lpfnManager();
|
||||
}
|
||||
|
||||
::FreeLibrary(hVR);
|
||||
|
@ -30,4 +40,4 @@ int main(int argc, char* argv[], char* envp[]) {
|
|||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
LIBRARY vrhost.dll
|
||||
|
||||
EXPORTS SampleExport PRIVATE
|
||||
TestTheManager PRIVATE
|
||||
TestTheService PRIVATE
|
||||
EXPORTS SampleExport PRIVATE
|
||||
TestTheManager PRIVATE
|
||||
TestTheService PRIVATE
|
||||
TestCreateVRWindow PRIVATE
|
||||
|
||||
CreateVRWindow PRIVATE
|
||||
CloseVRWindow PRIVATE
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
// vrhostapi.cpp
|
||||
// Definition of functions that are exported from this dll
|
||||
|
||||
#include "vrhostex.h"
|
||||
#include "VRShMem.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <random>
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
// VRWindowManager adds a level of indirection so that system HWND isn't exposed
|
||||
// outside of these APIs
|
||||
class VRWindowManager {
|
||||
public:
|
||||
HWND GetHWND(uint32_t nId) {
|
||||
if (nId == nWindow) {
|
||||
return hWindow;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE GetProc(uint32_t nId) {
|
||||
if (nId == nWindow) {
|
||||
return hProc;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t SetHWND(HWND hwnd, HANDLE hproc) {
|
||||
if (hWindow == nullptr) {
|
||||
MOZ_ASSERT(hwnd != nullptr && hproc != nullptr);
|
||||
hWindow = hwnd;
|
||||
hProc = hproc;
|
||||
nWindow = GetRandomUInt();
|
||||
#if defined(DEBUG) && defined(NIGHTLY_BUILD)
|
||||
printf("VRWindowManager: Storing HWND: 0x%p as ID: 0x%X\n", hWindow,
|
||||
nWindow);
|
||||
#endif
|
||||
return nWindow;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GetRandomUInt() { return randomGenerator(); }
|
||||
|
||||
static VRWindowManager* GetManager() {
|
||||
if (Instance == nullptr) {
|
||||
Instance = new VRWindowManager();
|
||||
}
|
||||
return Instance;
|
||||
}
|
||||
|
||||
private:
|
||||
static VRWindowManager* Instance;
|
||||
|
||||
// For now, simply store the ID and HWND, and expand
|
||||
// to a map when multiple windows/instances are supported.
|
||||
uint32_t nWindow = 0;
|
||||
HWND hWindow = nullptr;
|
||||
HANDLE hProc = nullptr;
|
||||
std::random_device randomGenerator;
|
||||
};
|
||||
VRWindowManager* VRWindowManager::Instance = nullptr;
|
||||
|
||||
// Struct to send params to StartFirefoxThreadProc
|
||||
struct StartFirefoxParams {
|
||||
char* firefoxFolder;
|
||||
char* firefoxProfileFolder;
|
||||
HANDLE hProcessFx;
|
||||
};
|
||||
|
||||
// Helper threadproc function for CreateVRWindow
|
||||
DWORD StartFirefoxThreadProc(_In_ LPVOID lpParameter) {
|
||||
char cmd[] = "%sfirefox.exe -wait-for-browser -profile %s --fxr";
|
||||
|
||||
StartFirefoxParams* params = static_cast<StartFirefoxParams*>(lpParameter);
|
||||
char cmdWithPath[MAX_PATH + MAX_PATH] = {0};
|
||||
int err = sprintf_s(cmdWithPath, ARRAYSIZE(cmdWithPath), cmd,
|
||||
params->firefoxFolder, params->firefoxProfileFolder);
|
||||
|
||||
if (err != -1) {
|
||||
PROCESS_INFORMATION procFx = {0};
|
||||
STARTUPINFO startupInfoFx = {0};
|
||||
|
||||
#if defined(DEBUG) && defined(NIGHTLY_BUILD)
|
||||
printf("Starting Firefox via: %s\n", cmdWithPath);
|
||||
#endif
|
||||
|
||||
// Start Firefox
|
||||
bool fCreateContentProc = ::CreateProcess(nullptr, // lpApplicationName,
|
||||
cmdWithPath,
|
||||
nullptr, // lpProcessAttributes,
|
||||
nullptr, // lpThreadAttributes,
|
||||
TRUE, // bInheritHandles,
|
||||
0, // dwCreationFlags,
|
||||
nullptr, // lpEnvironment,
|
||||
nullptr, // lpCurrentDirectory,
|
||||
&startupInfoFx, &procFx);
|
||||
|
||||
if (!fCreateContentProc) {
|
||||
printf("Failed to create Firefox process");
|
||||
}
|
||||
|
||||
params->hProcessFx = procFx.hProcess;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This export is responsible for starting up a new VR window in Firefox and
|
||||
// returning data related to its creation back to the caller.
|
||||
void CreateVRWindow(char* firefoxFolderPath, char* firefoxProfilePath,
|
||||
uint32_t dxgiAdapterID, uint32_t widthHost,
|
||||
uint32_t heightHost, uint32_t* windowId, void** hTex,
|
||||
uint32_t* width, uint32_t* height) {
|
||||
mozilla::gfx::VRWindowState windowState = {0};
|
||||
|
||||
int err = sprintf_s(windowState.signalName, ARRAYSIZE(windowState.signalName),
|
||||
"fxr::CreateVRWindow::%X",
|
||||
VRWindowManager::GetManager()->GetRandomUInt());
|
||||
|
||||
if (err > 0) {
|
||||
HANDLE hEvent = ::CreateEventA(nullptr, // attributes
|
||||
TRUE, // bManualReset
|
||||
FALSE, // bInitialState
|
||||
windowState.signalName);
|
||||
|
||||
if (hEvent != nullptr) {
|
||||
// Create Shmem and push state
|
||||
mozilla::gfx::VRShMem shmem(nullptr, true, false);
|
||||
shmem.CreateShMem();
|
||||
shmem.PushWindowState(windowState);
|
||||
|
||||
// Start Firefox in another thread so that this thread can wait for the
|
||||
// window state to be updated during Firefox startup
|
||||
StartFirefoxParams fxParams = {0};
|
||||
fxParams.firefoxFolder = firefoxFolderPath;
|
||||
fxParams.firefoxProfileFolder = firefoxProfilePath;
|
||||
DWORD dwTid = 0;
|
||||
HANDLE hThreadFx = CreateThread(nullptr, 0, StartFirefoxThreadProc,
|
||||
&fxParams, 0, &dwTid);
|
||||
if (hThreadFx != nullptr) {
|
||||
// Wait for Firefox to populate rest of window state
|
||||
::WaitForSingleObject(hEvent, INFINITE);
|
||||
|
||||
// Update local WindowState with data from Firefox
|
||||
shmem.PullWindowState(windowState);
|
||||
|
||||
(*hTex) = windowState.textureFx;
|
||||
(*windowId) = VRWindowManager::GetManager()->SetHWND(
|
||||
(HWND)windowState.hwndFx, fxParams.hProcessFx);
|
||||
(*width) = windowState.widthFx;
|
||||
(*height) = windowState.heightFx;
|
||||
|
||||
// Neither the Shmem nor its window state are needed anymore
|
||||
windowState = {0};
|
||||
shmem.PushWindowState(windowState);
|
||||
} else {
|
||||
// How do I failfast?
|
||||
}
|
||||
|
||||
shmem.CloseShMem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sends a message to the VR window to close.
|
||||
void CloseVRWindow(uint32_t nVRWindowID, bool waitForTerminate) {
|
||||
::SendMessage(VRWindowManager::GetManager()->GetHWND(nVRWindowID), WM_CLOSE,
|
||||
0, 0);
|
||||
|
||||
if (waitForTerminate) {
|
||||
// Wait for Firefox main process to exit
|
||||
::WaitForSingleObject(VRWindowManager::GetManager()->GetProc(nVRWindowID),
|
||||
INFINITE);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,16 @@
|
|||
// by vrhost.dll
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
// void SampleExport();
|
||||
typedef void (*PFN_SAMPLE)();
|
||||
typedef void (*PFN_SAMPLE)();
|
||||
|
||||
typedef void (*PFN_CREATEVRWINDOW)(char* firefoxFolderPath,
|
||||
char* firefoxProfilePath,
|
||||
uint32_t dxgiAdapterID, uint32_t widthHost,
|
||||
uint32_t heightHost, uint32_t* windowId,
|
||||
void** hTex, uint32_t* width,
|
||||
uint32_t* height);
|
||||
|
||||
typedef void (*PFN_CLOSEVRWINDOW)(uint32_t nVRWindowID, bool waitForTerminate);
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* 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/. */
|
||||
|
||||
// vrhost.cpp
|
||||
// Definition of functions that are exported from this dll
|
||||
// vrhosttest.cpp
|
||||
// Definition of testing and validation functions that are exported from this
|
||||
// dll
|
||||
|
||||
#include "vrhostex.h"
|
||||
#include "VRShMem.h"
|
||||
|
@ -16,7 +17,7 @@
|
|||
static const char s_pszSharedEvent[] = "vrhost_test_event_signal";
|
||||
static const DWORD s_dwWFSO_WAIT = 20000;
|
||||
|
||||
void SampleExport() { printf("vrhost.cpp hello world"); }
|
||||
void SampleExport() { printf("vrhost.cpp hello world\n"); }
|
||||
|
||||
// For testing ShMem as Manager and Service:
|
||||
// The two processes should output the steps, synchronously, to validate
|
||||
|
@ -33,9 +34,19 @@ void SampleExport() { printf("vrhost.cpp hello world"); }
|
|||
// 10 svc: verify data
|
||||
// 11 svc: push system
|
||||
// 12 svc: send signal
|
||||
// 13 mgr: pull system
|
||||
// 14 mgr: verify data
|
||||
// 15 return
|
||||
// 13 svc: wait for signal
|
||||
// 14 mgr: pull system
|
||||
// 15 mgr: verify data
|
||||
// 16 mgr: push window
|
||||
// 17 mgr: send signal
|
||||
// 18 mgr: wait for signal
|
||||
// 19 svc: pull window
|
||||
// 20 svc: verify data
|
||||
// 21 svc: push window
|
||||
// 22 svc: send signal
|
||||
// 23 mgr: pull window
|
||||
// 24 mgr: verify data
|
||||
// 25 return
|
||||
// These tests can be run with two instances of vrtesthost.exe, one first
|
||||
// running with -testmgr and the second running with -testsvc.
|
||||
// TODO: Bug 1563235 - Convert vrtesthost.exe tests into unit tests
|
||||
|
@ -43,6 +54,10 @@ void SampleExport() { printf("vrhost.cpp hello world"); }
|
|||
// For testing VRShMem as the Manager (i.e., the one who creates the
|
||||
// shmem). The sequence of how it tests with the service is listed above.
|
||||
void TestTheManager() {
|
||||
printf("TestTheManager Start\n");
|
||||
|
||||
MOZ_ASSERT(GetLastError() == 0,
|
||||
"TestTheManager should start with no OS errors");
|
||||
HANDLE hEvent = ::CreateEventA(nullptr, // lpEventAttributes
|
||||
FALSE, // bManualReset
|
||||
FALSE, // bInitialState
|
||||
|
@ -72,14 +87,14 @@ void TestTheManager() {
|
|||
printf("08 mgr: wait for signal\n");
|
||||
::WaitForSingleObject(hEvent, s_dwWFSO_WAIT);
|
||||
|
||||
printf("13 mgr: pull system\n");
|
||||
printf("14 mgr: pull system\n");
|
||||
mozilla::gfx::VRSystemState state;
|
||||
shmem.PullSystemState(state.displayState, state.sensorState,
|
||||
state.controllerState, state.enumerationCompleted,
|
||||
nullptr);
|
||||
|
||||
printf(
|
||||
"14 mgr: verify data\n"
|
||||
"15 mgr: verify data\n"
|
||||
"\tstate.enumerationCompleted = %d\n"
|
||||
"\tstate.displayState.displayName = \"%s\"\n"
|
||||
"\tstate.controllerState[1].hand = %hhu\n"
|
||||
|
@ -87,16 +102,48 @@ void TestTheManager() {
|
|||
state.enumerationCompleted, state.displayState.displayName,
|
||||
state.controllerState[1].hand, state.sensorState.inputFrameID);
|
||||
|
||||
// Test the WindowState functions as the host
|
||||
mozilla::gfx::VRWindowState windowState = {0};
|
||||
strcpy(windowState.signalName, "randomsignalstring");
|
||||
windowState.dxgiAdapterHost = 99;
|
||||
windowState.heightHost = 42;
|
||||
windowState.widthHost = 24;
|
||||
|
||||
printf("16 mgr: push window\n");
|
||||
shmem.PushWindowState(windowState);
|
||||
|
||||
printf("17 mgr: send signal\n");
|
||||
::SetEvent(hEvent);
|
||||
|
||||
printf("18 mgr: wait for signal\n");
|
||||
::WaitForSingleObject(hEvent, s_dwWFSO_WAIT);
|
||||
|
||||
printf("23 mgr: pull window\n");
|
||||
shmem.PullWindowState(windowState);
|
||||
|
||||
printf(
|
||||
"24 svc: verify data\n"
|
||||
"\tstate.hwndFx = 0x%llX\n"
|
||||
"\tstate.heightFx = %d\n"
|
||||
"\tstate.widthFx = %d\n"
|
||||
"\tstate.textureHandle = %p\n",
|
||||
windowState.hwndFx, windowState.heightFx, windowState.widthFx,
|
||||
windowState.textureFx);
|
||||
|
||||
shmem.CloseShMem();
|
||||
|
||||
printf("mgr complete");
|
||||
printf("TestTheManager complete");
|
||||
fflush(nullptr);
|
||||
}
|
||||
|
||||
// For testing VRShMem as the Service (i.e., the one who consumes the
|
||||
// shmem). The sequence of how it tests with the service is listed above.
|
||||
void TestTheService() {
|
||||
// Handle created by BeTheManager above.
|
||||
printf("TestTheService Start\n");
|
||||
|
||||
MOZ_ASSERT(GetLastError() == 0,
|
||||
"TestTheService should start with no OS errors");
|
||||
// Handle created by TestTheManager above.
|
||||
HANDLE hEvent = ::OpenEventA(EVENT_ALL_ACCESS, // dwDesiredAccess
|
||||
FALSE, // bInheritHandle
|
||||
s_pszSharedEvent // lpName
|
||||
|
@ -138,8 +185,83 @@ void TestTheService() {
|
|||
printf("12 svc: send signal\n");
|
||||
::SetEvent(hEvent);
|
||||
|
||||
printf("13 svc: wait for signal\n");
|
||||
::WaitForSingleObject(hEvent, s_dwWFSO_WAIT);
|
||||
|
||||
// Test the WindowState functions as Firefox
|
||||
printf("19 svc: pull window\n");
|
||||
mozilla::gfx::VRWindowState windowState;
|
||||
shmem.PullWindowState(windowState);
|
||||
|
||||
printf(
|
||||
"20 svc: verify data\n"
|
||||
"\tstate.signalName = \"%s\"\n"
|
||||
"\tstate.dxgiAdapterHost = %d\n"
|
||||
"\tstate.heightHost = %d\n"
|
||||
"\tstate.widthHost = %d\n",
|
||||
windowState.signalName, windowState.dxgiAdapterHost,
|
||||
windowState.heightHost, windowState.widthHost);
|
||||
|
||||
windowState.hwndFx = 0x1234;
|
||||
windowState.heightFx = 1234;
|
||||
windowState.widthFx = 4321;
|
||||
windowState.textureFx = (HANDLE)0x77777;
|
||||
|
||||
printf("21 svc: push window\n");
|
||||
shmem.PushWindowState(windowState);
|
||||
|
||||
printf("22 svc: send signal\n");
|
||||
::SetEvent(hEvent);
|
||||
|
||||
shmem.LeaveShMem();
|
||||
|
||||
printf("svc complete");
|
||||
printf("TestTheService complete");
|
||||
fflush(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// This function tests the export CreateVRWindow by outputting the return values
|
||||
// from the call to the console, as well as testing CloseVRWindow after the data
|
||||
// is retrieved.
|
||||
void TestCreateVRWindow() {
|
||||
printf("TestCreateVRWindow Start\n");
|
||||
|
||||
// Cache function calls to test real-world export and usage
|
||||
HMODULE hVRHost = ::GetModuleHandleA("vrhost.dll");
|
||||
PFN_CREATEVRWINDOW fnCreate =
|
||||
(PFN_CREATEVRWINDOW)::GetProcAddress(hVRHost, "CreateVRWindow");
|
||||
PFN_CLOSEVRWINDOW fnClose =
|
||||
(PFN_CLOSEVRWINDOW)::GetProcAddress(hVRHost, "CloseVRWindow");
|
||||
|
||||
// Create the VR Window and store data from creation
|
||||
char currentDir[MAX_PATH] = {0};
|
||||
char currentDirProfile[MAX_PATH] = {0};
|
||||
DWORD currentDirLength =
|
||||
::GetCurrentDirectory(ARRAYSIZE(currentDir), currentDir);
|
||||
currentDir[currentDirLength] = '\\';
|
||||
|
||||
int err = sprintf_s(currentDirProfile, ARRAYSIZE(currentDirProfile),
|
||||
"%svrhosttest-profile", currentDir);
|
||||
if (err > 0) {
|
||||
printf("Starting Firefox from %s\n", currentDir);
|
||||
|
||||
UINT windowId;
|
||||
HANDLE hTex;
|
||||
UINT width;
|
||||
UINT height;
|
||||
fnCreate(currentDir, currentDirProfile, 0, 100, 200, &windowId, &hTex,
|
||||
&width, &height);
|
||||
|
||||
// Close the Firefox VR Window
|
||||
fnClose(windowId, true);
|
||||
|
||||
// Print output from CreateVRWindow
|
||||
printf(
|
||||
"\n\nTestCreateVRWindow End:\n"
|
||||
"\twindowId = 0x%X\n"
|
||||
"\thTex = 0x%p\n"
|
||||
"\twidth = %d\n"
|
||||
"\theight = %d\n",
|
||||
windowId, hTex, width, height);
|
||||
printf("\n***Note: profile folder created at %s***\n", currentDirProfile);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче