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"
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
17 bool FxROutputHandler::TryInitialize(IDXGISwapChain
* aSwapChain
,
18 ID3D11Device
* aDevice
) {
19 if (mSwapChain
== nullptr) {
20 RefPtr
<ID3D11Texture2D
> texOrig
= nullptr;
22 aSwapChain
->GetBuffer(0, IID_ID3D11Texture2D
, getter_AddRefs(texOrig
));
27 // Create shareable texture, which will be copied to
28 D3D11_TEXTURE2D_DESC descOrig
= {0};
29 texOrig
->GetDesc(&descOrig
);
31 D3D11_RESOURCE_MISC_SHARED_NTHANDLE
| D3D11_RESOURCE_MISC_SHARED
;
32 hr
= aDevice
->CreateTexture2D(&descOrig
, nullptr,
33 mTexCopy
.StartAssignment());
38 // Now, share the texture to a handle that can be marshaled to another
40 HANDLE hCopy
= nullptr;
41 RefPtr
<IDXGIResource1
> texResource
;
42 hr
= mTexCopy
->QueryInterface(IID_IDXGIResource1
,
43 getter_AddRefs(texResource
));
48 hr
= texResource
->CreateSharedHandle(
49 nullptr, DXGI_SHARED_RESOURCE_READ
| DXGI_SHARED_RESOURCE_WRITE
,
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
);
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
80 ::CloseHandle(hSignal
);
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
));
96 aCtx
->CopyResource(mTexCopy
, texOrig
);