mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 969831 - Share code for checking minumum d3d feature level required for running metro and expose this information (including cached check results) via nsIWinMetroUtils. r=bbondy
This commit is contained in:
parent
93c8254d5f
commit
5c647f1701
@ -5,6 +5,7 @@
|
||||
|
||||
#include "CEHHelper.h"
|
||||
#include <tlhelp32.h>
|
||||
#include "mozilla/widget/MetroD3DCheckHelper.h"
|
||||
|
||||
#ifdef SHOW_CONSOLE
|
||||
#include <io.h> // _open_osfhandle
|
||||
@ -139,73 +140,9 @@ IsDX10Available()
|
||||
if (GetDWORDRegKey(metroDX10Available, isDX10Available)) {
|
||||
return isDX10Available;
|
||||
}
|
||||
|
||||
HMODULE dxgiModule = LoadLibraryA("dxgi.dll");
|
||||
if (!dxgiModule) {
|
||||
SetDWORDRegKey(metroDX10Available, 0);
|
||||
return false;
|
||||
}
|
||||
decltype(CreateDXGIFactory1)* createDXGIFactory1 =
|
||||
(decltype(CreateDXGIFactory1)*) GetProcAddress(dxgiModule, "CreateDXGIFactory1");
|
||||
if (!createDXGIFactory1) {
|
||||
SetDWORDRegKey(metroDX10Available, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
HMODULE d3d10module = LoadLibraryA("d3d10_1.dll");
|
||||
if (!d3d10module) {
|
||||
SetDWORDRegKey(metroDX10Available, 0);
|
||||
return false;
|
||||
}
|
||||
decltype(D3D10CreateDevice1)* createD3DDevice =
|
||||
(decltype(D3D10CreateDevice1)*) GetProcAddress(d3d10module,
|
||||
"D3D10CreateDevice1");
|
||||
if (!createD3DDevice) {
|
||||
SetDWORDRegKey(metroDX10Available, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<IDXGIFactory1> factory1;
|
||||
if (FAILED(createDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory1))) {
|
||||
SetDWORDRegKey(metroDX10Available, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<IDXGIAdapter1> adapter1;
|
||||
if (FAILED(factory1->EnumAdapters1(0, &adapter1))) {
|
||||
SetDWORDRegKey(metroDX10Available, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
CComPtr<ID3D10Device1> device;
|
||||
// Try for DX10.1
|
||||
if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, nullptr,
|
||||
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, nullptr,
|
||||
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, nullptr,
|
||||
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 check = D3DFeatureLevelCheck();
|
||||
SetDWORDRegKey(metroDX10Available, check);
|
||||
return check;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -9,15 +9,11 @@
|
||||
#define _WIN32_WINNT 0x602
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d10_1.h>
|
||||
#include <dxgi.h>
|
||||
#include <d3d10misc.h>
|
||||
#include <atlbase.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
//#define SHOW_CONSOLE 1
|
||||
extern HANDLE sCon;
|
||||
extern LPCWSTR metroDX10Available;
|
||||
|
||||
void Log(const wchar_t *fmt, ...);
|
||||
|
||||
|
@ -765,6 +765,11 @@ IFACEMETHODIMP CExecuteCommandVerb::Execute()
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (!IsDX10Available()) {
|
||||
Log(L"Can't launch in metro due to missing hardware acceleration features.");
|
||||
mRequestType = DESKTOP_RESTART;
|
||||
}
|
||||
|
||||
// Deal with metro restart for an update - launch desktop with a command
|
||||
// that tells it to run updater then launch the metro browser.
|
||||
if (mRequestType == METRO_UPDATE) {
|
||||
|
@ -8,13 +8,19 @@
|
||||
/**
|
||||
* Integration with the "Metro"/"Modern" UI environment in Windows 8.
|
||||
*
|
||||
* Note: browser/metro/base/content/browser-scripts.js contains a stub
|
||||
* Note: browser/metro/base/content/browser.js contains a stub
|
||||
* implementation of this interface for non-Windows systems, for testing and
|
||||
* development purposes only.
|
||||
*/
|
||||
[scriptable, uuid(dde6eee6-ad11-475b-b7d7-bee8e46e5756)]
|
||||
[scriptable, uuid(319faae0-82ca-4c2f-8a24-2b2445e5a72a)]
|
||||
interface nsIWinMetroUtils : nsISupports
|
||||
{
|
||||
/**
|
||||
* Determine if the current device has the hardware capabilities to run
|
||||
* in metro mode.
|
||||
*/
|
||||
readonly attribute boolean supported;
|
||||
|
||||
/**
|
||||
* Determine if the current browser is running in the metro immersive
|
||||
* environment.
|
||||
|
96
widget/windows/winrt/MetroD3DCheckHelper.h
Normal file
96
widget/windows/winrt/MetroD3DCheckHelper.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* -*- Mode: C++; tab-width: 4; 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/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
/* this file is included by exe stubs, don't pull xpcom into it. */
|
||||
|
||||
#include <d3d10_1.h>
|
||||
#include <dxgi.h>
|
||||
#include <d3d10misc.h>
|
||||
|
||||
/*
|
||||
* Checks to see if the d3d implementation supports feature level 9.3 or
|
||||
* above. Metrofx can't run on systems that fail this check.
|
||||
*
|
||||
* Note, this can hit perf, don't call this unless you absolutely have to.
|
||||
* Both the ceh and winrt widget code save a cached result in the registry.
|
||||
*/
|
||||
static bool D3DFeatureLevelCheck()
|
||||
{
|
||||
HMODULE dxgiModule = LoadLibraryA("dxgi.dll");
|
||||
if (!dxgiModule) {
|
||||
return false;
|
||||
}
|
||||
decltype(CreateDXGIFactory1)* createDXGIFactory1 =
|
||||
(decltype(CreateDXGIFactory1)*) GetProcAddress(dxgiModule, "CreateDXGIFactory1");
|
||||
if (!createDXGIFactory1) {
|
||||
FreeLibrary(dxgiModule);
|
||||
return false;
|
||||
}
|
||||
|
||||
HMODULE d3d10module = LoadLibraryA("d3d10_1.dll");
|
||||
if (!d3d10module) {
|
||||
FreeLibrary(dxgiModule);
|
||||
return false;
|
||||
}
|
||||
decltype(D3D10CreateDevice1)* createD3DDevice =
|
||||
(decltype(D3D10CreateDevice1)*) GetProcAddress(d3d10module,
|
||||
"D3D10CreateDevice1");
|
||||
if (!createD3DDevice) {
|
||||
FreeLibrary(d3d10module);
|
||||
FreeLibrary(dxgiModule);
|
||||
return false;
|
||||
}
|
||||
|
||||
IDXGIFactory1* factory1;
|
||||
if (FAILED(createDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory1))) {
|
||||
FreeLibrary(d3d10module);
|
||||
FreeLibrary(dxgiModule);
|
||||
return false;
|
||||
}
|
||||
|
||||
IDXGIAdapter1* adapter1;
|
||||
if (FAILED(factory1->EnumAdapters1(0, &adapter1))) {
|
||||
factory1->Release();
|
||||
FreeLibrary(d3d10module);
|
||||
FreeLibrary(dxgiModule);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try for DX10.1
|
||||
ID3D10Device1* device;
|
||||
if (FAILED(createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, nullptr,
|
||||
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, nullptr,
|
||||
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, nullptr,
|
||||
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
||||
D3D10_FEATURE_LEVEL_9_3,
|
||||
D3D10_1_SDK_VERSION, &device))) {
|
||||
adapter1->Release();
|
||||
factory1->Release();
|
||||
FreeLibrary(d3d10module);
|
||||
FreeLibrary(dxgiModule);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
device->Release();
|
||||
adapter1->Release();
|
||||
factory1->Release();
|
||||
FreeLibrary(d3d10module);
|
||||
FreeLibrary(dxgiModule);
|
||||
return true;
|
||||
}
|
@ -25,6 +25,10 @@ EXTRA_COMPONENTS += [
|
||||
'MetroUIUtils.manifest',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.widget += [
|
||||
'MetroD3DCheckHelper.h',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include "FrameworkView.h"
|
||||
#include "MetroApp.h"
|
||||
#include "ToastNotificationHandler.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "nsIWindowsRegKey.h"
|
||||
#include "mozilla/widget/MetroD3DCheckHelper.h"
|
||||
|
||||
#include <shldisp.h>
|
||||
#include <shellapi.h>
|
||||
@ -341,5 +345,58 @@ nsWinMetroUtils::GetForeground(bool* aForeground)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWinMetroUtils::GetSupported(bool *aSupported)
|
||||
{
|
||||
*aSupported = false;
|
||||
if (!IsWin8OrLater()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if last_used_feature_level_idx is set, we've previously created a
|
||||
// d3d device that's compatible. See gfxEindowsPlatform for details.
|
||||
if (Preferences::GetInt("gfx.direct3d.last_used_feature_level_idx", -1) != -1) {
|
||||
*aSupported = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if last_used_feature_level_idx isn't set, gfx hasn't attempted to create
|
||||
// a device yet. This could be a case where d2d is pref'd off or blacklisted
|
||||
// on desktop, or we tried to create a device and failed. This could also be
|
||||
// a first run case where we haven't created an accelerated top level window
|
||||
// yet.
|
||||
|
||||
NS_NAMED_LITERAL_STRING(metroRegValueName, "MetroD3DAvailable");
|
||||
NS_NAMED_LITERAL_STRING(metroRegValuePath, "Software\\Mozilla\\Firefox");
|
||||
|
||||
// Check to see if the ceh launched us, it also does this check and caches
|
||||
// a flag in the registry.
|
||||
nsresult rv;
|
||||
uint32_t value = 0;
|
||||
nsCOMPtr<nsIWindowsRegKey> regKey =
|
||||
do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
|
||||
metroRegValuePath,
|
||||
nsIWindowsRegKey::ACCESS_WRITE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = regKey->ReadIntValue(metroRegValueName, &value);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aSupported = (bool)value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If all else fails, do the check here. This call is costly but
|
||||
// we shouldn't hit this except in rare situations where the
|
||||
// ceh never launched the browser that's running.
|
||||
value = D3DFeatureLevelCheck();
|
||||
regKey->WriteIntValue(metroRegValueName, value);
|
||||
*aSupported = (bool)value;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // widget
|
||||
} // mozilla
|
||||
|
Loading…
Reference in New Issue
Block a user