void gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce) { #ifdef CAIRO_HAS_D2D_SURFACE if (mD2DDevice) { ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice); if (SUCCEEDED(device->GetDeviceRemovedReason())) { return; } mD2DDevice = nullptr; } mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce); nsRefPtr<ID3D10Device1> device; int supportedFeatureLevelsCount = ArrayLength(kSupportedFeatureLevels); // If we're not running in Metro don't allow DX9.3 if (!IsRunningInWindowsMetro()) { supportedFeatureLevelsCount--; } nsRefPtr<IDXGIAdapter1> adapter1 = GetDXGIAdapter(); if (!adapter1) { // Unable to create adapter, abort acceleration. return; } // It takes a lot of time (5-10% of startup time or ~100ms) to do both // a createD3DDevice on D3D10_FEATURE_LEVEL_10_0. We therefore store // the last used feature level to go direct to that. int featureLevelIndex = Preferences::GetInt(kFeatureLevelPref, 0); if (featureLevelIndex >= supportedFeatureLevelsCount || featureLevelIndex < 0) featureLevelIndex = 0; // Start with the last used feature level, and move to lower DX versions // until we find one that works. HRESULT hr = E_FAIL; for (int i = featureLevelIndex; i < supportedFeatureLevelsCount; i++) { hr = CreateDevice(adapter1, i); // If it succeeded we found the first available feature level if (SUCCEEDED(hr)) break; } // If we succeeded in creating a device, try for a newer device // that we haven't tried yet. if (SUCCEEDED(hr)) { for (int i = featureLevelIndex - 1; i >= 0; i--) { hr = CreateDevice(adapter1, i); // If it failed then we don't have new hardware if (FAILED(hr)) { break; } } } if (!mD2DDevice && aAttemptForce) { mD2DDevice = cairo_d2d_create_device(); } if (mD2DDevice) { reporter.SetSuccessful(); mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice)); } #endif }
void gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce) { #ifdef CAIRO_HAS_D2D_SURFACE if (mD2DDevice) { ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice); if (SUCCEEDED(device->GetDeviceRemovedReason())) { return; } mD2DDevice = nullptr; } mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce); HMODULE d3d10module = LoadLibraryA("d3d10_1.dll"); D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func) GetProcAddress(d3d10module, "D3D10CreateDevice1"); nsRefPtr<ID3D10Device1> device; if (createD3DDevice) { HMODULE dxgiModule = LoadLibraryA("dxgi.dll"); CreateDXGIFactory1Func createDXGIFactory1 = (CreateDXGIFactory1Func) GetProcAddress(dxgiModule, "CreateDXGIFactory1"); // Try to use a DXGI 1.1 adapter in order to share resources // across processes. nsRefPtr<IDXGIAdapter1> adapter1; if (createDXGIFactory1) { nsRefPtr<IDXGIFactory1> factory1; HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1), getter_AddRefs(factory1)); if (FAILED(hr) || !factory1) { // This seems to happen with some people running the iZ3D driver. // They won't get acceleration. return; } hr = factory1->EnumAdapters1(0, getter_AddRefs(adapter1)); if (SUCCEEDED(hr) && adapter1) { hr = adapter1->CheckInterfaceSupport(__uuidof(ID3D10Device), nullptr); if (FAILED(hr)) { // We should return and not accelerate if we don't have // D3D 10.0 support. return; } } } // It takes a lot of time (5-10% of startup time or ~100ms) to do both // a createD3DDevice on D3D10_FEATURE_LEVEL_10_0 and // D3D10_FEATURE_LEVEL_10_1. Therefore we set a pref if we ever get // 10.1 to work and we use that first if the pref is set. // Going direct to a 10.1 check only takes 20-30ms. // The initialization of hr doesn't matter here because it will get // overwritten whether or not the preference is set. // - If the preferD3D10_1 pref is set it gets overwritten immediately. // - If the preferD3D10_1 pref is not set, the if condition after // the one that follows us immediately will short circuit before // checking FAILED(hr) and will again get overwritten immediately. // We initialize it here just so it does not appear to be an // uninitialized value. HRESULT hr = E_FAIL; bool preferD3D10_1 = Preferences::GetBool("gfx.direct3d.prefer_10_1", false); if (preferD3D10_1) { hr = 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, getter_AddRefs(device)); // If we fail here, the DirectX version or video card probably // changed. We previously could use 10.1 but now we can't // anymore. Revert back to doing a 10.0 check first before // the 10.1 check. if (FAILED(hr)) { Preferences::SetBool("gfx.direct3d.prefer_10_1", false); } else { mD2DDevice = cairo_d2d_create_device_from_d3d10device(device); } } if (!preferD3D10_1 || FAILED(hr)) { // If preferD3D10_1 is set and 10.1 failed, fall back to 10.0. // if preferD3D10_1 is not yet set, then first try to create // a 10.0 D3D device, then try to see if 10.1 works. nsRefPtr<ID3D10Device1> device1; hr = 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, getter_AddRefs(device1)); if (SUCCEEDED(hr)) { device = device1; if (preferD3D10_1) { mD2DDevice = cairo_d2d_create_device_from_d3d10device(device); } } } // If preferD3D10_1 is not yet set and 10.0 succeeded if (!preferD3D10_1 && SUCCEEDED(hr)) { // We have 10.0, let's try 10.1. This second check will only // ever be done once if it succeeds. After that an option // will be set to prefer using 10.1 before trying 10.0. // In the case that 10.1 fails, it won't be a long operation // like it is when 10.1 succeeds, so we don't need to optimize // the case where 10.1 is not supported, but 10.0 is supported. nsRefPtr<ID3D10Device1> device1; hr = 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, getter_AddRefs(device1)); if (SUCCEEDED(hr)) { device = device1; Preferences::SetBool("gfx.direct3d.prefer_10_1", true); } mD2DDevice = cairo_d2d_create_device_from_d3d10device(device); } } if (!mD2DDevice && aAttemptForce) { mD2DDevice = cairo_d2d_create_device(); } if (mD2DDevice) { reporter.SetSuccessful(); mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice)); } #endif }
void gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce) { #ifdef CAIRO_HAS_D2D_SURFACE if (mD2DDevice) { ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice); if (SUCCEEDED(device->GetDeviceRemovedReason())) { return; } mD2DDevice = nullptr; } mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce); nsRefPtr<ID3D10Device1> device; nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll")); CreateDXGIFactory1Func createDXGIFactory1 = (CreateDXGIFactory1Func) GetProcAddress(dxgiModule, "CreateDXGIFactory1"); int supportedFeatureLevelsCount = ArrayLength(kSupportedFeatureLevels); // If we're not running in Metro don't allow DX9.3 if (!IsRunningInWindowsMetro()) { supportedFeatureLevelsCount--; } // It takes a lot of time (5-10% of startup time or ~100ms) to do both // a createD3DDevice on D3D10_FEATURE_LEVEL_10_0. We therefore store // the last used feature level to go direct to that. int featureLevelIndex = Preferences::GetInt(kFeatureLevelPref, 0); if (featureLevelIndex >= supportedFeatureLevelsCount || featureLevelIndex < 0) featureLevelIndex = 0; // Try to use a DXGI 1.1 adapter in order to share resources // across processes. nsRefPtr<IDXGIAdapter1> adapter1; if (createDXGIFactory1) { nsRefPtr<IDXGIFactory1> factory1; HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1), getter_AddRefs(factory1)); if (FAILED(hr) || !factory1) { // This seems to happen with some people running the iZ3D driver. // They won't get acceleration. return; } hr = factory1->EnumAdapters1(0, getter_AddRefs(adapter1)); if (FAILED(hr) || !adapter1) { // We should return and not accelerate if we can't obtain // an adapter. return; } } // Start with the last used feature level, and move to lower DX versions // until we find one that works. HRESULT hr = E_FAIL; for (int i = featureLevelIndex; i < supportedFeatureLevelsCount; i++) { hr = CreateDevice(adapter1, i); // If it succeeded we found the first available feature level if (SUCCEEDED(hr)) break; } // If we succeeded in creating a device, try for a newer device // that we haven't tried yet. if (SUCCEEDED(hr)) { for (int i = featureLevelIndex - 1; i >= 0; i--) { hr = CreateDevice(adapter1, i); // If it failed then we don't have new hardware if (FAILED(hr)) { break; } } } if (!mD2DDevice && aAttemptForce) { mD2DDevice = cairo_d2d_create_device(); } if (mD2DDevice) { reporter.SetSuccessful(); mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice)); } #endif }