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_rendering.h"
5 
6 #include <Windows.Graphics.DirectX.Direct3D11.interop.h>
7 #include <windows.graphics.holographic.h>
8 #include <wrl.h>
9 
10 #include <memory>
11 #include <vector>
12 
13 #include "device/vr/windows/d3d11_texture_helper.h"
14 #include "device/vr/windows_mixed_reality/wrappers/wmr_origins.h"
15 
16 namespace WF = ABI::Windows::Foundation;
17 using ABI::Windows::Foundation::IReference;
18 using ABI::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface;
19 using ABI::Windows::Graphics::Holographic::HolographicStereoTransform;
20 using ABI::Windows::Graphics::Holographic::IHolographicCamera;
21 using ABI::Windows::Graphics::Holographic::IHolographicCameraPose;
22 using ABI::Windows::Graphics::Holographic::
23     IHolographicCameraRenderingParameters;
24 using Microsoft::WRL::ComPtr;
25 using Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess;
26 
27 namespace device {
28 // WMRCamera
WMRCameraImpl(ComPtr<IHolographicCamera> camera)29 WMRCameraImpl::WMRCameraImpl(ComPtr<IHolographicCamera> camera)
30     : camera_(camera) {
31   DCHECK(camera_);
32 }
33 
34 WMRCameraImpl::~WMRCameraImpl() = default;
35 
RenderTargetSize()36 WF::Size WMRCameraImpl::RenderTargetSize() {
37   WF::Size val;
38   HRESULT hr = camera_->get_RenderTargetSize(&val);
39   DCHECK(SUCCEEDED(hr));
40   return val;
41 }
42 
IsStereo()43 bool WMRCameraImpl::IsStereo() {
44   boolean val;
45   HRESULT hr = camera_->get_IsStereo(&val);
46   DCHECK(SUCCEEDED(hr));
47   return val;
48 }
49 
50 // WMRCameraPose
51 ABI::Windows::Graphics::Holographic::IHolographicCameraPose*
GetRawPtr() const52 WMRCameraPose::GetRawPtr() const {
53   // This should only ever be used by the real implementation, so by default
54   // make sure it's not called.
55   NOTREACHED();
56   return nullptr;
57 }
58 
WMRCameraPoseImpl(ComPtr<IHolographicCameraPose> pose)59 WMRCameraPoseImpl::WMRCameraPoseImpl(ComPtr<IHolographicCameraPose> pose)
60     : pose_(pose) {
61   DCHECK(pose_);
62 }
63 
64 WMRCameraPoseImpl::~WMRCameraPoseImpl() = default;
65 
Viewport()66 WF::Rect WMRCameraPoseImpl::Viewport() {
67   WF::Rect val;
68   HRESULT hr = pose_->get_Viewport(&val);
69   DCHECK(SUCCEEDED(hr));
70   return val;
71 }
72 
HolographicCamera()73 std::unique_ptr<WMRCamera> WMRCameraPoseImpl::HolographicCamera() {
74   ComPtr<IHolographicCamera> camera;
75   HRESULT hr = pose_->get_HolographicCamera(&camera);
76   DCHECK(SUCCEEDED(hr));
77   return std::make_unique<WMRCameraImpl>(camera);
78 }
79 
ProjectionTransform()80 HolographicStereoTransform WMRCameraPoseImpl::ProjectionTransform() {
81   HolographicStereoTransform val;
82   HRESULT hr = pose_->get_ProjectionTransform(&val);
83   DCHECK(SUCCEEDED(hr));
84   return val;
85 }
86 
TryGetViewTransform(const WMRCoordinateSystem * origin,HolographicStereoTransform * transform)87 bool WMRCameraPoseImpl::TryGetViewTransform(
88     const WMRCoordinateSystem* origin,
89     HolographicStereoTransform* transform) {
90   ComPtr<IReference<HolographicStereoTransform>> transform_ref;
91   if (FAILED(pose_->TryGetViewTransform(origin->GetRawPtr(), &transform_ref)) ||
92       !transform_ref)
93     return false;
94 
95   HRESULT hr = transform_ref->get_Value(transform);
96   return SUCCEEDED(hr);
97 }
98 
GetRawPtr() const99 IHolographicCameraPose* WMRCameraPoseImpl::GetRawPtr() const {
100   return pose_.Get();
101 }
102 
103 // WMRRenderingParameters
WMRRenderingParametersImpl(ComPtr<IHolographicCameraRenderingParameters> rendering_params)104 WMRRenderingParametersImpl::WMRRenderingParametersImpl(
105     ComPtr<IHolographicCameraRenderingParameters> rendering_params)
106     : rendering_params_(rendering_params) {
107   DCHECK(rendering_params_);
108 }
109 
110 WMRRenderingParametersImpl::~WMRRenderingParametersImpl() = default;
111 
112 ComPtr<ID3D11Texture2D>
TryGetBackbufferAsTexture2D()113 WMRRenderingParametersImpl::TryGetBackbufferAsTexture2D() {
114   ComPtr<IDirect3DSurface> surface;
115   if (FAILED(rendering_params_->get_Direct3D11BackBuffer(&surface)))
116     return nullptr;
117 
118   ComPtr<IDirect3DDxgiInterfaceAccess> dxgi_interface_access;
119   if (FAILED(surface.As(&dxgi_interface_access)))
120     return nullptr;
121 
122   ComPtr<ID3D11Resource> native_resource;
123   if (FAILED(
124           dxgi_interface_access->GetInterface(IID_PPV_ARGS(&native_resource))))
125     return nullptr;
126 
127   ComPtr<ID3D11Texture2D> texture;
128   if (FAILED(native_resource.As(&texture)))
129     return nullptr;
130 
131   return texture;
132 }
133 }  // namespace device
134