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 13 namespace { 14 15 void CheckIfFailed(HRESULT hr) { 16 DCHECK(!FAILED(hr)); 17 if (FAILED(hr)) 18 DVLOG(0) << "Direct3D call failed, hr = " << hr; 19 } 20 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())); 26 float dpi = 0.0; 27 CheckIfFailed(display_properties->get_LogicalDpi(&dpi)); 28 return dpi; 29 } 30 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); 35 } 36 37 } 38 39 namespace metro_driver { 40 41 Direct3DHelper::Direct3DHelper() { 42 } 43 44 Direct3DHelper::~Direct3DHelper() { 45 } 46 47 void 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 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, 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 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); 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