FxROutputHandler.cpp (3515B)
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/. */ 5 6 #include "FxROutputHandler.h" 7 #include "mozilla/Assertions.h" 8 #include "moz_external_vr.h" 9 #include "VRShMem.h" 10 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; 25 } 26 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; 36 } 37 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; 46 } 47 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; 53 } 54 55 // The texture is successfully created and shared, so cache a 56 // pointer to the swapchain to indicate this success. 57 mSwapChain = aSwapChain; 58 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); 64 65 // The CLH should have populated hwndFx first 66 MOZ_ASSERT(windowState.hwndFx != 0); 67 MOZ_ASSERT(windowState.textureFx == nullptr); 68 69 windowState.textureFx = (HANDLE)hCopy; 70 71 shmem.PushWindowState(windowState); 72 shmem.LeaveShMem(); 73 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 78 ); 79 ::SetEvent(hSignal); 80 ::CloseHandle(hSignal); 81 } 82 } else { 83 MOZ_ASSERT(aSwapChain == mSwapChain); 84 } 85 86 return mSwapChain != nullptr && aSwapChain == mSwapChain; 87 } 88 89 // Update the contents of the shared texture. 90 void FxROutputHandler::UpdateOutput(ID3D11DeviceContext* aCtx) { 91 MOZ_ASSERT(mSwapChain != nullptr); 92 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(); 98 } 99 }