Merge mozilla-central to autoland. CLOSED TREE
[gecko.git] / gfx / vr / FxROutputHandler.cpp
blobc0f33e1b689c38a369f0222a09e3202c40080bb9
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "FxROutputHandler.h"
7 #include "mozilla/Assertions.h"
8 #include "moz_external_vr.h"
9 #include "VRShMem.h"
11 // TryInitialize is responsible for associating this output handler with the
12 // calling window's swapchain for subsequent updates. This also creates a
13 // texture that can be shared across processes and updates VRShMem with the
14 // shared texture handle.
15 // See nsFxrCommandLineHandler::Handle for more information about the
16 // bootstrap process.
17 bool FxROutputHandler::TryInitialize(IDXGISwapChain* aSwapChain,
18 ID3D11Device* aDevice) {
19 if (mSwapChain == nullptr) {
20 RefPtr<ID3D11Texture2D> texOrig = nullptr;
21 HRESULT hr =
22 aSwapChain->GetBuffer(0, IID_ID3D11Texture2D, getter_AddRefs(texOrig));
23 if (hr != S_OK) {
24 return false;
27 // Create shareable texture, which will be copied to
28 D3D11_TEXTURE2D_DESC descOrig = {0};
29 texOrig->GetDesc(&descOrig);
30 descOrig.MiscFlags |=
31 D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED;
32 hr = aDevice->CreateTexture2D(&descOrig, nullptr,
33 mTexCopy.StartAssignment());
34 if (hr != S_OK) {
35 return false;
38 // Now, share the texture to a handle that can be marshaled to another
39 // process
40 HANDLE hCopy = nullptr;
41 RefPtr<IDXGIResource1> texResource;
42 hr = mTexCopy->QueryInterface(IID_IDXGIResource1,
43 getter_AddRefs(texResource));
44 if (hr != S_OK) {
45 return false;
48 hr = texResource->CreateSharedHandle(
49 nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
50 nullptr, &hCopy);
51 if (hr != S_OK) {
52 return false;
55 // The texture is successfully created and shared, so cache a
56 // pointer to the swapchain to indicate this success.
57 mSwapChain = aSwapChain;
59 // Finally, marshal the shared texture handle via VRShMem
60 mozilla::gfx::VRShMem shmem(nullptr, true /*aRequiresMutex*/);
61 if (shmem.JoinShMem()) {
62 mozilla::gfx::VRWindowState windowState = {0};
63 shmem.PullWindowState(windowState);
65 // The CLH should have populated hwndFx first
66 MOZ_ASSERT(windowState.hwndFx != 0);
67 MOZ_ASSERT(windowState.textureFx == nullptr);
69 windowState.textureFx = (HANDLE)hCopy;
71 shmem.PushWindowState(windowState);
72 shmem.LeaveShMem();
74 // Notify the waiting host process that the data is now available
75 HANDLE hSignal = ::OpenEventA(EVENT_ALL_ACCESS, // dwDesiredAccess
76 FALSE, // bInheritHandle
77 windowState.signalName // lpName
79 ::SetEvent(hSignal);
80 ::CloseHandle(hSignal);
82 } else {
83 MOZ_ASSERT(aSwapChain == mSwapChain);
86 return mSwapChain != nullptr && aSwapChain == mSwapChain;
89 // Update the contents of the shared texture.
90 void FxROutputHandler::UpdateOutput(ID3D11DeviceContext* aCtx) {
91 MOZ_ASSERT(mSwapChain != nullptr);
93 ID3D11Texture2D* texOrig = nullptr;
94 HRESULT hr = mSwapChain->GetBuffer(0, IID_PPV_ARGS(&texOrig));
95 if (hr == S_OK) {
96 aCtx->CopyResource(mTexCopy, texOrig);
97 texOrig->Release();