| OLD | NEW |
| (Empty) |
| 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 <corewindow.h> | |
| 7 #include <windows.applicationmodel.core.h> | |
| 8 #include <windows.graphics.display.h> | |
| 9 | |
| 10 #include "win8/metro_driver/direct3d_helper.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/win/windows_version.h" | |
| 13 #include "ui/gfx/win/dpi.h" | |
| 14 #include "win8/metro_driver/winrt_utils.h" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 void CheckIfFailed(HRESULT hr) { | |
| 19 DCHECK(!FAILED(hr)); | |
| 20 if (FAILED(hr)) | |
| 21 DVLOG(0) << "Direct3D call failed, hr = " << hr; | |
| 22 } | |
| 23 | |
| 24 float ConvertDipsToPixels(float dips) { | |
| 25 return floor(dips * gfx::GetDPIScale() + 0.5f); | |
| 26 } | |
| 27 | |
| 28 } | |
| 29 | |
| 30 namespace metro_driver { | |
| 31 | |
| 32 Direct3DHelper::Direct3DHelper() { | |
| 33 } | |
| 34 | |
| 35 Direct3DHelper::~Direct3DHelper() { | |
| 36 } | |
| 37 | |
| 38 void Direct3DHelper::Initialize(winui::Core::ICoreWindow* window) { | |
| 39 window_ = window; | |
| 40 CreateDeviceResources(); | |
| 41 CreateWindowSizeDependentResources(); | |
| 42 } | |
| 43 | |
| 44 // TODO(scottmg): Need to handle resize messages and recreation. | |
| 45 | |
| 46 void Direct3DHelper::CreateDeviceResources() { | |
| 47 unsigned int creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; | |
| 48 D3D_FEATURE_LEVEL feature_levels[] = { | |
| 49 D3D_FEATURE_LEVEL_11_1, | |
| 50 D3D_FEATURE_LEVEL_11_0, | |
| 51 D3D_FEATURE_LEVEL_10_1, | |
| 52 D3D_FEATURE_LEVEL_10_0, | |
| 53 D3D_FEATURE_LEVEL_9_3, | |
| 54 D3D_FEATURE_LEVEL_9_2, | |
| 55 D3D_FEATURE_LEVEL_9_1, | |
| 56 }; | |
| 57 | |
| 58 mswr::ComPtr<ID3D11Device> device; | |
| 59 mswr::ComPtr<ID3D11DeviceContext> context; | |
| 60 CheckIfFailed( | |
| 61 D3D11CreateDevice( | |
| 62 nullptr, | |
| 63 D3D_DRIVER_TYPE_HARDWARE, | |
| 64 nullptr, | |
| 65 creation_flags, | |
| 66 feature_levels, | |
| 67 ARRAYSIZE(feature_levels), | |
| 68 D3D11_SDK_VERSION, | |
| 69 &device, | |
| 70 &feature_level_, | |
| 71 &context)); | |
| 72 CheckIfFailed(device.As(&d3d_device_)); | |
| 73 CheckIfFailed(context.As(&d3d_context_)); | |
| 74 } | |
| 75 | |
| 76 void Direct3DHelper::CreateWindowSizeDependentResources() { | |
| 77 float window_width = 0; | |
| 78 float window_height = 0; | |
| 79 | |
| 80 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | |
| 81 // Windows 8 returns in DIPs. | |
| 82 CheckIfFailed(window_->get_Bounds(&window_bounds_)); | |
| 83 window_width = ConvertDipsToPixels(window_width); | |
| 84 window_height = ConvertDipsToPixels(window_height); | |
| 85 } | |
| 86 | |
| 87 // TODO(scottmg): Orientation. | |
| 88 | |
| 89 if (swap_chain_ != nullptr) { | |
| 90 // TODO(scottmg): Resize if it already exists. | |
| 91 NOTIMPLEMENTED(); | |
| 92 } else { | |
| 93 DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = { 0 }; | |
| 94 swap_chain_desc.Width = window_width; | |
| 95 swap_chain_desc.Height = window_height; | |
| 96 swap_chain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; | |
| 97 swap_chain_desc.Stereo = false; | |
| 98 swap_chain_desc.SampleDesc.Count = 1; | |
| 99 swap_chain_desc.SampleDesc.Quality = 0; | |
| 100 swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | |
| 101 swap_chain_desc.BufferCount = 2; // TODO(scottmg): Probably 1 is fine. | |
| 102 swap_chain_desc.Scaling = DXGI_SCALING_NONE; | |
| 103 swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; | |
| 104 swap_chain_desc.Flags = 0; | |
| 105 | |
| 106 mswr::ComPtr<IDXGIDevice1> dxgi_device; | |
| 107 CheckIfFailed(d3d_device_.As(&dxgi_device)); | |
| 108 | |
| 109 mswr::ComPtr<IDXGIAdapter> dxgi_adapter; | |
| 110 CheckIfFailed(dxgi_device->GetAdapter(&dxgi_adapter)); | |
| 111 | |
| 112 mswr::ComPtr<IDXGIFactory2> dxgi_factory; | |
| 113 CheckIfFailed(dxgi_adapter->GetParent( | |
| 114 __uuidof(IDXGIFactory2), &dxgi_factory)); | |
| 115 | |
| 116 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | |
| 117 // On Win8 we need the CoreWindow interface to create the Swapchain. | |
| 118 CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow( | |
| 119 d3d_device_.Get(), | |
| 120 reinterpret_cast<IUnknown*>(window_), | |
| 121 &swap_chain_desc, | |
| 122 nullptr, | |
| 123 &swap_chain_)); | |
| 124 } else { | |
| 125 // On Win7 we need the raw HWND to create the Swapchain. | |
| 126 mswr::ComPtr<ICoreWindowInterop> interop; | |
| 127 CheckIfFailed(window_->QueryInterface(interop.GetAddressOf())); | |
| 128 HWND window = NULL; | |
| 129 interop->get_WindowHandle(&window); | |
| 130 | |
| 131 swap_chain_desc.Scaling = DXGI_SCALING_STRETCH; | |
| 132 swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; | |
| 133 | |
| 134 CheckIfFailed(dxgi_factory->CreateSwapChainForHwnd( | |
| 135 d3d_device_.Get(), | |
| 136 window, | |
| 137 &swap_chain_desc, | |
| 138 nullptr, | |
| 139 nullptr, | |
| 140 &swap_chain_)); | |
| 141 // Prevent DXGI from monitoring an application message queue and thus | |
| 142 // attempt mode changes. For e.g. Alt + Enter by default causes | |
| 143 // DXGI to attempt to take the window fullscreen. | |
| 144 CheckIfFailed(dxgi_factory->MakeWindowAssociation( | |
| 145 window, DXGI_MWA_NO_WINDOW_CHANGES)); | |
| 146 } | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 } // namespace metro_driver | |
| OLD | NEW |