direct3d_helper.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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.
4
5#include "stdafx.h"
6#include "win8/metro_driver/direct3d_helper.h"
7#include "win8/metro_driver/winrt_utils.h"
8
9#include "base/logging.h"
10
11#include <windows.graphics.display.h>
12
13namespace {
14
15void CheckIfFailed(HRESULT hr) {
16  DCHECK(!FAILED(hr));
17  if (FAILED(hr))
18    DVLOG(ERROR) << "Direct3D call failed, hr = " << hr;
19}
20
21float GetLogicalDpi() {
22  mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties;
23  CheckIfFailed(winrt_utils::CreateActivationFactory(
24      RuntimeClass_Windows_Graphics_Display_DisplayProperties,
25      display_properties.GetAddressOf()));
26  float dpi = 0.0;
27  CheckIfFailed(display_properties->get_LogicalDpi(&dpi));
28  return dpi;
29}
30
31float 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);
35}
36
37}
38
39namespace metro_driver {
40
41Direct3DHelper::Direct3DHelper() {
42}
43
44Direct3DHelper::~Direct3DHelper() {
45}
46
47void Direct3DHelper::Initialize(winui::Core::ICoreWindow* window) {
48  window_ = window;
49  CreateDeviceResources();
50  CreateWindowSizeDependentResources();
51}
52
53// TODO(scottmg): Need to handle resize messages and recreation.
54
55void 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,
65  };
66
67  mswr::ComPtr<ID3D11Device> device;
68  mswr::ComPtr<ID3D11DeviceContext> context;
69  CheckIfFailed(
70      D3D11CreateDevice(
71          nullptr,
72          D3D_DRIVER_TYPE_HARDWARE,
73          nullptr,
74          creation_flags,
75          feature_levels,
76          ARRAYSIZE(feature_levels),
77          D3D11_SDK_VERSION,
78          &device,
79          &feature_level_,
80          &context));
81  CheckIfFailed(device.As(&d3d_device_));
82  CheckIfFailed(context.As(&d3d_context_));
83}
84
85void 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);
89
90  // TODO(scottmg): Orientation.
91
92  if (swap_chain_ != nullptr) {
93    // TODO(scottmg): Resize if it already exists.
94    NOTIMPLEMENTED();
95  } else {
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;
108
109    mswr::ComPtr<IDXGIDevice1> dxgi_device;
110    CheckIfFailed(d3d_device_.As(&dxgi_device));
111
112    mswr::ComPtr<IDXGIAdapter> dxgi_adapter;
113    CheckIfFailed(dxgi_device->GetAdapter(&dxgi_adapter));
114
115    mswr::ComPtr<IDXGIFactory2> dxgi_factory;
116    CheckIfFailed(dxgi_adapter->GetParent(
117        __uuidof(IDXGIFactory2), &dxgi_factory));
118
119    CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow(
120        d3d_device_.Get(),
121        reinterpret_cast<IUnknown*>(window_),
122        &swap_chain_desc,
123        nullptr,
124        &swap_chain_));
125  }
126}
127
128}  // namespace metro_driver
129