1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 #include "device/vr/windows_mixed_reality/wrappers/wmr_holographic_space.h" 5 6 #include <Windows.Graphics.DirectX.Direct3D11.interop.h> 7 #include <windows.graphics.holographic.h> 8 #include <wrl.h> 9 10 #include <vector> 11 12 #include "base/logging.h" 13 #include "base/strings/string_util.h" 14 #include "base/win/core_winrt_util.h" 15 #include "base/win/scoped_hstring.h" 16 #include "device/vr/windows_mixed_reality/mixed_reality_statics.h" 17 #include "device/vr/windows_mixed_reality/wrappers/test/mock_wmr_holographic_frame.h" 18 #include "device/vr/windows_mixed_reality/wrappers/test/mock_wmr_holographic_space.h" 19 #include "device/vr/windows_mixed_reality/wrappers/wmr_holographic_frame.h" 20 21 using ABI::Windows::Foundation::ITypedEventHandler; 22 using ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice; 23 using ABI::Windows::Graphics::Holographic::HolographicAdapterId; 24 using ABI::Windows::Graphics::Holographic::HolographicSpace; 25 using HolographicSpaceUserPresence = 26 ABI::Windows::Graphics::Holographic::HolographicSpaceUserPresence; 27 using ABI::Windows::Graphics::Holographic::IHolographicFrame; 28 using ABI::Windows::Graphics::Holographic::IHolographicSpace; 29 using ABI::Windows::Graphics::Holographic::IHolographicSpace2; 30 using Microsoft::WRL::Callback; 31 using Microsoft::WRL::ComPtr; 32 33 typedef ITypedEventHandler<HolographicSpace*, IInspectable*> 34 HolographicSpaceEventHandler; 35 36 namespace device { 37 WMRHolographicSpaceImpl(ComPtr<IHolographicSpace> space)38WMRHolographicSpaceImpl::WMRHolographicSpaceImpl( 39 ComPtr<IHolographicSpace> space) 40 : space_(space) { 41 DCHECK(space_); 42 HRESULT hr = space_.As(&space2_); 43 if (SUCCEEDED(hr)) { 44 SubscribeEvents(); 45 } 46 } 47 ~WMRHolographicSpaceImpl()48WMRHolographicSpaceImpl::~WMRHolographicSpaceImpl() { 49 UnsubscribeEvents(); 50 } 51 PrimaryAdapterId()52HolographicAdapterId WMRHolographicSpaceImpl::PrimaryAdapterId() { 53 HolographicAdapterId id; 54 HRESULT hr = space_->get_PrimaryAdapterId(&id); 55 DCHECK(SUCCEEDED(hr)); 56 return id; 57 } 58 59 std::unique_ptr<WMRHolographicFrame> TryCreateNextFrame()60WMRHolographicSpaceImpl::TryCreateNextFrame() { 61 ComPtr<IHolographicFrame> frame; 62 HRESULT hr = space_->CreateNextFrame(&frame); 63 if (FAILED(hr)) 64 return nullptr; 65 return std::make_unique<WMRHolographicFrameImpl>(frame); 66 } 67 TrySetDirect3D11Device(const ComPtr<IDirect3DDevice> & device)68bool WMRHolographicSpaceImpl::TrySetDirect3D11Device( 69 const ComPtr<IDirect3DDevice>& device) { 70 HRESULT hr = space_->SetDirect3D11Device(device.Get()); 71 return SUCCEEDED(hr); 72 } 73 UserPresence()74HolographicSpaceUserPresence WMRHolographicSpaceImpl::UserPresence() { 75 HolographicSpaceUserPresence user_presence = 76 HolographicSpaceUserPresence::HolographicSpaceUserPresence_PresentActive; 77 if (space2_) { 78 HRESULT hr = space2_->get_UserPresence(&user_presence); 79 DCHECK(SUCCEEDED(hr)); 80 } 81 return user_presence; 82 } 83 84 std::unique_ptr<base::CallbackList<void()>::Subscription> AddUserPresenceChangedCallback(const base::RepeatingCallback<void ()> & cb)85WMRHolographicSpaceImpl::AddUserPresenceChangedCallback( 86 const base::RepeatingCallback<void()>& cb) { 87 return user_presence_changed_callback_list_.Add(cb); 88 } 89 OnUserPresenceChanged(IHolographicSpace *,IInspectable *)90HRESULT WMRHolographicSpaceImpl::OnUserPresenceChanged(IHolographicSpace*, 91 IInspectable*) { 92 user_presence_changed_callback_list_.Notify(); 93 return S_OK; 94 } 95 SubscribeEvents()96void WMRHolographicSpaceImpl::SubscribeEvents() { 97 if (!space2_) { 98 return; 99 } 100 // The destructor ensures that we're unsubscribed so raw this is fine. 101 auto user_presence_changed_callback = Callback<HolographicSpaceEventHandler>( 102 this, &WMRHolographicSpaceImpl::OnUserPresenceChanged); 103 HRESULT hr = space2_->add_UserPresenceChanged( 104 user_presence_changed_callback.Get(), &user_presence_changed_token_); 105 DCHECK(SUCCEEDED(hr)); 106 } 107 UnsubscribeEvents()108void WMRHolographicSpaceImpl::UnsubscribeEvents() { 109 if (!space2_) { 110 return; 111 } 112 113 HRESULT hr = S_OK; 114 if (user_presence_changed_token_.value != 0) { 115 hr = space2_->remove_UserPresenceChanged(user_presence_changed_token_); 116 user_presence_changed_token_.value = 0; 117 DCHECK(SUCCEEDED(hr)); 118 } 119 } 120 121 } // namespace device 122