NativeWindow11Win32.cpp (7773B)
1 // 2 // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // NativeWindow11Win32.cpp: Implementation of NativeWindow11 using win32 window APIs. 8 9 #include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h" 10 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" 11 12 #include "common/debug.h" 13 14 // This header must be included before dcomp.h. 15 #include <initguid.h> 16 17 #include <dcomp.h> 18 19 namespace rx 20 { 21 22 NativeWindow11Win32::NativeWindow11Win32(EGLNativeWindowType window, 23 bool hasAlpha, 24 bool directComposition) 25 : NativeWindow11(window), 26 mDirectComposition(directComposition), 27 mHasAlpha(hasAlpha), 28 mDevice(nullptr), 29 mCompositionTarget(nullptr), 30 mVisual(nullptr) 31 {} 32 33 NativeWindow11Win32::~NativeWindow11Win32() 34 { 35 SafeRelease(mCompositionTarget); 36 SafeRelease(mDevice); 37 SafeRelease(mVisual); 38 } 39 40 bool NativeWindow11Win32::initialize() 41 { 42 return true; 43 } 44 45 bool NativeWindow11Win32::getClientRect(LPRECT rect) const 46 { 47 return GetClientRect(getNativeWindow(), rect) == TRUE; 48 } 49 50 bool NativeWindow11Win32::isIconic() const 51 { 52 return IsIconic(getNativeWindow()) == TRUE; 53 } 54 55 HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device, 56 IDXGIFactory *factory, 57 DXGI_FORMAT format, 58 UINT width, 59 UINT height, 60 UINT samples, 61 IDXGISwapChain **swapChain) 62 { 63 if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 || 64 height == 0) 65 { 66 return E_INVALIDARG; 67 } 68 69 if (mDirectComposition) 70 { 71 HMODULE dcomp = ::GetModuleHandle(TEXT("dcomp.dll")); 72 if (!dcomp) 73 { 74 return E_INVALIDARG; 75 } 76 77 typedef HRESULT(WINAPI * PFN_DCOMPOSITION_CREATE_DEVICE)( 78 IDXGIDevice * dxgiDevice, REFIID iid, void **dcompositionDevice); 79 PFN_DCOMPOSITION_CREATE_DEVICE createDComp = 80 reinterpret_cast<PFN_DCOMPOSITION_CREATE_DEVICE>( 81 GetProcAddress(dcomp, "DCompositionCreateDevice")); 82 if (!createDComp) 83 { 84 return E_INVALIDARG; 85 } 86 87 if (!mDevice) 88 { 89 IDXGIDevice *dxgiDevice = d3d11::DynamicCastComObject<IDXGIDevice>(device); 90 HRESULT result = createDComp(dxgiDevice, __uuidof(IDCompositionDevice), 91 reinterpret_cast<void **>(&mDevice)); 92 SafeRelease(dxgiDevice); 93 94 if (FAILED(result)) 95 { 96 return result; 97 } 98 } 99 100 if (!mCompositionTarget) 101 { 102 HRESULT result = 103 mDevice->CreateTargetForHwnd(getNativeWindow(), TRUE, &mCompositionTarget); 104 if (FAILED(result)) 105 { 106 return result; 107 } 108 } 109 110 if (!mVisual) 111 { 112 HRESULT result = mDevice->CreateVisual(&mVisual); 113 if (FAILED(result)) 114 { 115 return result; 116 } 117 } 118 119 IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject<IDXGIFactory2>(factory); 120 DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; 121 swapChainDesc.Width = width; 122 swapChainDesc.Height = height; 123 swapChainDesc.Format = format; 124 swapChainDesc.Stereo = FALSE; 125 swapChainDesc.SampleDesc.Count = 1; 126 swapChainDesc.SampleDesc.Quality = 0; 127 swapChainDesc.BufferUsage = 128 DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT; 129 swapChainDesc.BufferCount = 2; 130 swapChainDesc.Scaling = DXGI_SCALING_STRETCH; 131 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; 132 swapChainDesc.AlphaMode = 133 mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE; 134 swapChainDesc.Flags = 0; 135 IDXGISwapChain1 *swapChain1 = nullptr; 136 HRESULT result = 137 factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1); 138 if (SUCCEEDED(result)) 139 { 140 *swapChain = static_cast<IDXGISwapChain *>(swapChain1); 141 } 142 mVisual->SetContent(swapChain1); 143 mCompositionTarget->SetRoot(mVisual); 144 SafeRelease(factory2); 145 return result; 146 } 147 148 // Use IDXGIFactory2::CreateSwapChainForHwnd if DXGI 1.2 is available to create a 149 // DXGI_SWAP_EFFECT_SEQUENTIAL swap chain. 150 IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject<IDXGIFactory2>(factory); 151 if (factory2 != nullptr) 152 { 153 DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; 154 swapChainDesc.Width = width; 155 swapChainDesc.Height = height; 156 swapChainDesc.Format = format; 157 swapChainDesc.Stereo = FALSE; 158 swapChainDesc.SampleDesc.Count = samples; 159 swapChainDesc.SampleDesc.Quality = 0; 160 swapChainDesc.BufferUsage = 161 DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; 162 swapChainDesc.BufferCount = 1; 163 swapChainDesc.Scaling = DXGI_SCALING_STRETCH; 164 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; 165 swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; 166 swapChainDesc.Flags = 0; 167 IDXGISwapChain1 *swapChain1 = nullptr; 168 HRESULT result = factory2->CreateSwapChainForHwnd(device, getNativeWindow(), &swapChainDesc, 169 nullptr, nullptr, &swapChain1); 170 if (SUCCEEDED(result)) 171 { 172 factory2->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER); 173 *swapChain = static_cast<IDXGISwapChain *>(swapChain1); 174 } 175 SafeRelease(factory2); 176 return result; 177 } 178 179 DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; 180 swapChainDesc.BufferCount = 1; 181 swapChainDesc.BufferDesc.Format = format; 182 swapChainDesc.BufferDesc.Width = width; 183 swapChainDesc.BufferDesc.Height = height; 184 swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; 185 swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 186 swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; 187 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; 188 swapChainDesc.BufferUsage = 189 DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; 190 swapChainDesc.Flags = 0; 191 swapChainDesc.OutputWindow = getNativeWindow(); 192 swapChainDesc.SampleDesc.Count = samples; 193 swapChainDesc.SampleDesc.Quality = 0; 194 swapChainDesc.Windowed = TRUE; 195 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 196 197 HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, swapChain); 198 if (SUCCEEDED(result)) 199 { 200 factory->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER); 201 } 202 return result; 203 } 204 205 void NativeWindow11Win32::commitChange() 206 { 207 if (mDevice) 208 { 209 mDevice->Commit(); 210 } 211 } 212 213 // static 214 bool NativeWindow11Win32::IsValidNativeWindow(EGLNativeWindowType window) 215 { 216 return IsWindow(window) == TRUE; 217 } 218 } // namespace rx