1 // Copyright 2012 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.
6 #include "win8/metro_driver/direct3d_helper.h"
7 #include "win8/metro_driver/winrt_utils.h"
9 #include "base/logging.h"
11 #include <windows.graphics.display.h>
15 void CheckIfFailed(HRESULT hr
) {
18 DVLOG(0) << "Direct3D call failed, hr = " << hr
;
21 float GetLogicalDpi() {
22 mswr::ComPtr
<wingfx::Display::IDisplayPropertiesStatics
> display_properties
;
23 CheckIfFailed(winrt_utils::CreateActivationFactory(
24 RuntimeClass_Windows_Graphics_Display_DisplayProperties
,
25 display_properties
.GetAddressOf()));
27 CheckIfFailed(display_properties
->get_LogicalDpi(&dpi
));
31 float ConvertDipsToPixels(float dips
) {
32 static const float dips_per_inch
= 96.f
;
33 float logical_dpi
= GetLogicalDpi();
34 return floor(dips
* logical_dpi
/ dips_per_inch
+ 0.5f
);
39 namespace metro_driver
{
41 Direct3DHelper::Direct3DHelper() {
44 Direct3DHelper::~Direct3DHelper() {
47 void Direct3DHelper::Initialize(winui::Core::ICoreWindow
* window
) {
49 CreateDeviceResources();
50 CreateWindowSizeDependentResources();
53 // TODO(scottmg): Need to handle resize messages and recreation.
55 void Direct3DHelper::CreateDeviceResources() {
56 unsigned int creation_flags
= D3D11_CREATE_DEVICE_BGRA_SUPPORT
;
57 D3D_FEATURE_LEVEL feature_levels
[] = {
58 D3D_FEATURE_LEVEL_11_1
,
59 D3D_FEATURE_LEVEL_11_0
,
60 D3D_FEATURE_LEVEL_10_1
,
61 D3D_FEATURE_LEVEL_10_0
,
62 D3D_FEATURE_LEVEL_9_3
,
63 D3D_FEATURE_LEVEL_9_2
,
64 D3D_FEATURE_LEVEL_9_1
,
67 mswr::ComPtr
<ID3D11Device
> device
;
68 mswr::ComPtr
<ID3D11DeviceContext
> context
;
72 D3D_DRIVER_TYPE_HARDWARE
,
76 ARRAYSIZE(feature_levels
),
81 CheckIfFailed(device
.As(&d3d_device_
));
82 CheckIfFailed(context
.As(&d3d_context_
));
85 void Direct3DHelper::CreateWindowSizeDependentResources() {
86 CheckIfFailed(window_
->get_Bounds(&window_bounds_
));
87 float window_width
= ConvertDipsToPixels(window_bounds_
.Width
);
88 float window_height
= ConvertDipsToPixels(window_bounds_
.Height
);
90 // TODO(scottmg): Orientation.
92 if (swap_chain_
!= nullptr) {
93 // TODO(scottmg): Resize if it already exists.
96 DXGI_SWAP_CHAIN_DESC1 swap_chain_desc
= { 0 };
97 swap_chain_desc
.Width
= window_width
;
98 swap_chain_desc
.Height
= window_height
;
99 swap_chain_desc
.Format
= DXGI_FORMAT_B8G8R8A8_UNORM
;
100 swap_chain_desc
.Stereo
= false;
101 swap_chain_desc
.SampleDesc
.Count
= 1;
102 swap_chain_desc
.SampleDesc
.Quality
= 0;
103 swap_chain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
104 swap_chain_desc
.BufferCount
= 2; // TODO(scottmg): Probably 1 is fine.
105 swap_chain_desc
.Scaling
= DXGI_SCALING_NONE
;
106 swap_chain_desc
.SwapEffect
= DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
;
107 swap_chain_desc
.Flags
= 0;
109 mswr::ComPtr
<IDXGIDevice1
> dxgi_device
;
110 CheckIfFailed(d3d_device_
.As(&dxgi_device
));
112 mswr::ComPtr
<IDXGIAdapter
> dxgi_adapter
;
113 CheckIfFailed(dxgi_device
->GetAdapter(&dxgi_adapter
));
115 mswr::ComPtr
<IDXGIFactory2
> dxgi_factory
;
116 CheckIfFailed(dxgi_adapter
->GetParent(
117 __uuidof(IDXGIFactory2
), &dxgi_factory
));
119 CheckIfFailed(dxgi_factory
->CreateSwapChainForCoreWindow(
121 reinterpret_cast<IUnknown
*>(window_
),
128 } // namespace metro_driver