/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "CEHHelper.h" #ifdef SHOW_CONSOLE #include // _open_osfhandle #endif HANDLE sCon; LPCWSTR metroDX10Available = L"MetroD3DAvailable"; typedef HRESULT (WINAPI*D3D10CreateDevice1Func) (IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, UINT, D3D10_FEATURE_LEVEL1, UINT, ID3D10Device1 **); typedef HRESULT(WINAPI*CreateDXGIFactory1Func)(REFIID , void **); void Log(const wchar_t *fmt, ...) { #if !defined(SHOW_CONSOLE) return; #endif va_list a = NULL; wchar_t szDebugString[1024]; if(!lstrlenW(fmt)) return; va_start(a,fmt); vswprintf(szDebugString, 1024, fmt, a); va_end(a); if(!lstrlenW(szDebugString)) return; DWORD len; WriteConsoleW(sCon, szDebugString, lstrlenW(szDebugString), &len, NULL); WriteConsoleW(sCon, L"\n", 1, &len, NULL); if (IsDebuggerPresent()) { OutputDebugStringW(szDebugString); OutputDebugStringW(L"\n"); } } #if defined(SHOW_CONSOLE) void SetupConsole() { FILE *fp; AllocConsole(); sCon = GetStdHandle(STD_OUTPUT_HANDLE); int fd = _open_osfhandle(reinterpret_cast(sCon), 0); fp = _fdopen(fd, "w"); *stdout = *fp; setvbuf(stdout, NULL, _IONBF, 0); } #endif bool IsDX10Available() { DWORD isDX10Available; if (GetDWORDRegKey(metroDX10Available, isDX10Available)) { return isDX10Available; } HMODULE dxgiModule = LoadLibraryA("dxgi.dll"); if (!dxgiModule) { SetDWORDRegKey(metroDX10Available, 0); return false; } CreateDXGIFactory1Func createDXGIFactory1 = (CreateDXGIFactory1Func) GetProcAddress(dxgiModule, "CreateDXGIFactory1"); if (!createDXGIFactory1) { SetDWORDRegKey(metroDX10Available, 0); return false; } HMODULE d3d10module = LoadLibraryA("d3d10_1.dll"); if (!d3d10module) { SetDWORDRegKey(metroDX10Available, 0); return false; } D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func) GetProcAddress(d3d10module, "D3D10CreateDevice1"); if (!createD3DDevice) { SetDWORDRegKey(metroDX10Available, 0); return false; } CComPtr factory1; if (FAILED(createDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory1))) { SetDWORDRegKey(metroDX10Available, 0); return false; } CComPtr adapter1; if (FAILED(factory1->EnumAdapters1(0, &adapter1))) { SetDWORDRegKey(metroDX10Available, 0); return false; } CComPtr device; // Try for DX10.1 if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, &device))) { // Try for DX10 if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device))) { // Try for DX9.3 (we fall back to cairo and cairo has support for D3D 9.3) if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, D3D10_FEATURE_LEVEL_9_3, D3D10_1_SDK_VERSION, &device))) { SetDWORDRegKey(metroDX10Available, 0); return false; } } } SetDWORDRegKey(metroDX10Available, 1); return true; } bool GetDWORDRegKey(LPCWSTR name, DWORD &value) { HKEY key; LONG result = RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Mozilla\\Firefox", 0, KEY_READ, &key); if (result != ERROR_SUCCESS) { return false; } DWORD bufferSize = sizeof(DWORD); DWORD type; result = RegQueryValueExW(key, name, nullptr, &type, reinterpret_cast(&value), &bufferSize); RegCloseKey(key); return result == ERROR_SUCCESS; } bool SetDWORDRegKey(LPCWSTR name, DWORD value) { HKEY key; LONG result = RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Mozilla\\Firefox", 0, KEY_WRITE, &key); if (result != ERROR_SUCCESS) { return false; } result = RegSetValueEx(key, name, 0, REG_DWORD, reinterpret_cast(&value), sizeof(DWORD)); RegCloseKey(key); return result == ERROR_SUCCESS; }