1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/thebes/gfxWindowsPlatform.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1548 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "mozilla/ArrayUtils.h" 1.11 + 1.12 +#include "gfxWindowsPlatform.h" 1.13 + 1.14 +#include "gfxImageSurface.h" 1.15 +#include "gfxWindowsSurface.h" 1.16 + 1.17 +#include "nsUnicharUtils.h" 1.18 + 1.19 +#include "mozilla/Preferences.h" 1.20 +#include "mozilla/WindowsVersion.h" 1.21 +#include "nsServiceManagerUtils.h" 1.22 +#include "nsTArray.h" 1.23 + 1.24 +#include "nsIWindowsRegKey.h" 1.25 +#include "nsIFile.h" 1.26 +#include "plbase64.h" 1.27 +#include "nsIXULRuntime.h" 1.28 + 1.29 +#include "nsIGfxInfo.h" 1.30 + 1.31 +#include "gfxCrashReporterUtils.h" 1.32 + 1.33 +#include "gfxGDIFontList.h" 1.34 +#include "gfxGDIFont.h" 1.35 + 1.36 +#include "mozilla/layers/CompositorParent.h" // for CompositorParent::IsInCompositorThread 1.37 +#include "DeviceManagerD3D9.h" 1.38 + 1.39 +#include "WinUtils.h" 1.40 + 1.41 +#ifdef CAIRO_HAS_DWRITE_FONT 1.42 +#include "gfxDWriteFontList.h" 1.43 +#include "gfxDWriteFonts.h" 1.44 +#include "gfxDWriteCommon.h" 1.45 +#include <dwrite.h> 1.46 +#endif 1.47 + 1.48 +#include "gfxUserFontSet.h" 1.49 +#include "nsWindowsHelpers.h" 1.50 +#include "gfx2DGlue.h" 1.51 + 1.52 +#include <string> 1.53 + 1.54 +#ifdef CAIRO_HAS_D2D_SURFACE 1.55 +#include "gfxD2DSurface.h" 1.56 + 1.57 +#include <d3d10_1.h> 1.58 + 1.59 +#include "mozilla/gfx/2D.h" 1.60 + 1.61 +#include "nsMemory.h" 1.62 +#endif 1.63 + 1.64 +#include <d3d11.h> 1.65 + 1.66 +#include "nsIMemoryReporter.h" 1.67 +#include <winternl.h> 1.68 +#include "d3dkmtQueryStatistics.h" 1.69 + 1.70 +#include "SurfaceCache.h" 1.71 +#include "gfxPrefs.h" 1.72 + 1.73 +using namespace mozilla; 1.74 +using namespace mozilla::gfx; 1.75 +using namespace mozilla::layers; 1.76 +using namespace mozilla::widget; 1.77 +using namespace mozilla::image; 1.78 + 1.79 +#ifdef CAIRO_HAS_D2D_SURFACE 1.80 + 1.81 +static const char *kFeatureLevelPref = 1.82 + "gfx.direct3d.last_used_feature_level_idx"; 1.83 +static const int kSupportedFeatureLevels[] = 1.84 + { D3D10_FEATURE_LEVEL_10_1, D3D10_FEATURE_LEVEL_10_0, 1.85 + D3D10_FEATURE_LEVEL_9_3 }; 1.86 + 1.87 +class GfxD2DSurfaceReporter MOZ_FINAL : public nsIMemoryReporter 1.88 +{ 1.89 +public: 1.90 + NS_DECL_ISUPPORTS 1.91 + 1.92 + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, 1.93 + nsISupports* aData) 1.94 + { 1.95 + nsresult rv; 1.96 + 1.97 + int64_t amount = cairo_d2d_get_image_surface_cache_usage(); 1.98 + rv = MOZ_COLLECT_REPORT( 1.99 + "gfx-d2d-surface-cache", KIND_OTHER, UNITS_BYTES, amount, 1.100 + "Memory used by the Direct2D internal surface cache."); 1.101 + NS_ENSURE_SUCCESS(rv, rv); 1.102 + 1.103 + cairo_device_t *device = 1.104 + gfxWindowsPlatform::GetPlatform()->GetD2DDevice(); 1.105 + amount = device ? cairo_d2d_get_surface_vram_usage(device) : 0; 1.106 + rv = MOZ_COLLECT_REPORT( 1.107 + "gfx-d2d-surface-vram", KIND_OTHER, UNITS_BYTES, amount, 1.108 + "Video memory used by D2D surfaces."); 1.109 + NS_ENSURE_SUCCESS(rv, rv); 1.110 + 1.111 + return NS_OK; 1.112 + } 1.113 +}; 1.114 + 1.115 +NS_IMPL_ISUPPORTS(GfxD2DSurfaceReporter, nsIMemoryReporter) 1.116 + 1.117 +#endif 1.118 + 1.119 +class GfxD2DVramReporter MOZ_FINAL : public nsIMemoryReporter 1.120 +{ 1.121 +public: 1.122 + NS_DECL_ISUPPORTS 1.123 + 1.124 + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, 1.125 + nsISupports* aData) 1.126 + { 1.127 + nsresult rv; 1.128 + 1.129 + rv = MOZ_COLLECT_REPORT( 1.130 + "gfx-d2d-vram-draw-target", KIND_OTHER, UNITS_BYTES, 1.131 + Factory::GetD2DVRAMUsageDrawTarget(), 1.132 + "Video memory used by D2D DrawTargets."); 1.133 + NS_ENSURE_SUCCESS(rv, rv); 1.134 + 1.135 + rv = MOZ_COLLECT_REPORT( 1.136 + "gfx-d2d-vram-source-surface", KIND_OTHER, UNITS_BYTES, 1.137 + Factory::GetD2DVRAMUsageSourceSurface(), 1.138 + "Video memory used by D2D SourceSurfaces."); 1.139 + NS_ENSURE_SUCCESS(rv, rv); 1.140 + 1.141 + return NS_OK; 1.142 + } 1.143 +}; 1.144 + 1.145 +NS_IMPL_ISUPPORTS(GfxD2DVramReporter, nsIMemoryReporter) 1.146 + 1.147 +#define GFX_USE_CLEARTYPE_ALWAYS "gfx.font_rendering.cleartype.always_use_for_content" 1.148 +#define GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE "gfx.font_rendering.cleartype.use_for_downloadable_fonts" 1.149 + 1.150 +#define GFX_CLEARTYPE_PARAMS "gfx.font_rendering.cleartype_params." 1.151 +#define GFX_CLEARTYPE_PARAMS_GAMMA "gfx.font_rendering.cleartype_params.gamma" 1.152 +#define GFX_CLEARTYPE_PARAMS_CONTRAST "gfx.font_rendering.cleartype_params.enhanced_contrast" 1.153 +#define GFX_CLEARTYPE_PARAMS_LEVEL "gfx.font_rendering.cleartype_params.cleartype_level" 1.154 +#define GFX_CLEARTYPE_PARAMS_STRUCTURE "gfx.font_rendering.cleartype_params.pixel_structure" 1.155 +#define GFX_CLEARTYPE_PARAMS_MODE "gfx.font_rendering.cleartype_params.rendering_mode" 1.156 + 1.157 +class GPUAdapterReporter : public nsIMemoryReporter 1.158 +{ 1.159 + // Callers must Release the DXGIAdapter after use or risk mem-leak 1.160 + static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter) 1.161 + { 1.162 + ID3D10Device1 *D2D10Device; 1.163 + IDXGIDevice *DXGIDevice; 1.164 + bool result = false; 1.165 + 1.166 + if (D2D10Device = mozilla::gfx::Factory::GetDirect3D10Device()) { 1.167 + if (D2D10Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&DXGIDevice) == S_OK) { 1.168 + result = (DXGIDevice->GetAdapter(DXGIAdapter) == S_OK); 1.169 + DXGIDevice->Release(); 1.170 + } 1.171 + } 1.172 + 1.173 + return result; 1.174 + } 1.175 + 1.176 +public: 1.177 + NS_DECL_ISUPPORTS 1.178 + 1.179 + NS_IMETHOD 1.180 + CollectReports(nsIMemoryReporterCallback* aCb, 1.181 + nsISupports* aClosure) 1.182 + { 1.183 + HANDLE ProcessHandle = GetCurrentProcess(); 1.184 + 1.185 + int64_t dedicatedBytesUsed = 0; 1.186 + int64_t sharedBytesUsed = 0; 1.187 + int64_t committedBytesUsed = 0; 1.188 + IDXGIAdapter *DXGIAdapter; 1.189 + 1.190 + HMODULE gdi32Handle; 1.191 + PFND3DKMTQS queryD3DKMTStatistics; 1.192 + 1.193 + // GPU memory reporting is not available before Windows 7 1.194 + if (!IsWin7OrLater()) 1.195 + return NS_OK; 1.196 + 1.197 + if (gdi32Handle = LoadLibrary(TEXT("gdi32.dll"))) 1.198 + queryD3DKMTStatistics = (PFND3DKMTQS)GetProcAddress(gdi32Handle, "D3DKMTQueryStatistics"); 1.199 + 1.200 + if (queryD3DKMTStatistics && GetDXGIAdapter(&DXGIAdapter)) { 1.201 + // Most of this block is understood thanks to wj32's work on Process Hacker 1.202 + 1.203 + DXGI_ADAPTER_DESC adapterDesc; 1.204 + D3DKMTQS queryStatistics; 1.205 + 1.206 + DXGIAdapter->GetDesc(&adapterDesc); 1.207 + DXGIAdapter->Release(); 1.208 + 1.209 + memset(&queryStatistics, 0, sizeof(D3DKMTQS)); 1.210 + queryStatistics.Type = D3DKMTQS_PROCESS; 1.211 + queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; 1.212 + queryStatistics.hProcess = ProcessHandle; 1.213 + if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { 1.214 + committedBytesUsed = queryStatistics.QueryResult.ProcessInfo.SystemMemory.BytesAllocated; 1.215 + } 1.216 + 1.217 + memset(&queryStatistics, 0, sizeof(D3DKMTQS)); 1.218 + queryStatistics.Type = D3DKMTQS_ADAPTER; 1.219 + queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; 1.220 + if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { 1.221 + ULONG i; 1.222 + ULONG segmentCount = queryStatistics.QueryResult.AdapterInfo.NbSegments; 1.223 + 1.224 + for (i = 0; i < segmentCount; i++) { 1.225 + memset(&queryStatistics, 0, sizeof(D3DKMTQS)); 1.226 + queryStatistics.Type = D3DKMTQS_SEGMENT; 1.227 + queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; 1.228 + queryStatistics.QuerySegment.SegmentId = i; 1.229 + 1.230 + if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { 1.231 + bool aperture; 1.232 + 1.233 + // SegmentInformation has a different definition in Win7 than later versions 1.234 + if (!IsWin8OrLater()) 1.235 + aperture = queryStatistics.QueryResult.SegmentInfoWin7.Aperture; 1.236 + else 1.237 + aperture = queryStatistics.QueryResult.SegmentInfoWin8.Aperture; 1.238 + 1.239 + memset(&queryStatistics, 0, sizeof(D3DKMTQS)); 1.240 + queryStatistics.Type = D3DKMTQS_PROCESS_SEGMENT; 1.241 + queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; 1.242 + queryStatistics.hProcess = ProcessHandle; 1.243 + queryStatistics.QueryProcessSegment.SegmentId = i; 1.244 + if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { 1.245 + ULONGLONG bytesCommitted; 1.246 + if (!IsWin8OrLater()) 1.247 + bytesCommitted = queryStatistics.QueryResult.ProcessSegmentInfo.Win7.BytesCommitted; 1.248 + else 1.249 + bytesCommitted = queryStatistics.QueryResult.ProcessSegmentInfo.Win8.BytesCommitted; 1.250 + if (aperture) 1.251 + sharedBytesUsed += bytesCommitted; 1.252 + else 1.253 + dedicatedBytesUsed += bytesCommitted; 1.254 + } 1.255 + } 1.256 + } 1.257 + } 1.258 + } 1.259 + 1.260 + FreeLibrary(gdi32Handle); 1.261 + 1.262 +#define REPORT(_path, _amount, _desc) \ 1.263 + do { \ 1.264 + nsresult rv; \ 1.265 + rv = aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \ 1.266 + KIND_OTHER, UNITS_BYTES, _amount, \ 1.267 + NS_LITERAL_CSTRING(_desc), aClosure); \ 1.268 + NS_ENSURE_SUCCESS(rv, rv); \ 1.269 + } while (0) 1.270 + 1.271 + REPORT("gpu-committed", committedBytesUsed, 1.272 + "Memory committed by the Windows graphics system."); 1.273 + 1.274 + REPORT("gpu-dedicated", dedicatedBytesUsed, 1.275 + "Out-of-process memory allocated for this process in a " 1.276 + "physical GPU adapter's memory."); 1.277 + 1.278 + REPORT("gpu-shared", sharedBytesUsed, 1.279 + "In-process memory that is shared with the GPU."); 1.280 + 1.281 +#undef REPORT 1.282 + 1.283 + return NS_OK; 1.284 + } 1.285 +}; 1.286 + 1.287 +NS_IMPL_ISUPPORTS(GPUAdapterReporter, nsIMemoryReporter) 1.288 + 1.289 +static __inline void 1.290 +BuildKeyNameFromFontName(nsAString &aName) 1.291 +{ 1.292 + if (aName.Length() >= LF_FACESIZE) 1.293 + aName.Truncate(LF_FACESIZE - 1); 1.294 + ToLowerCase(aName); 1.295 +} 1.296 + 1.297 +gfxWindowsPlatform::gfxWindowsPlatform() 1.298 + : mD3D11DeviceInitialized(false) 1.299 + , mPrefFonts(50) 1.300 +{ 1.301 + mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; 1.302 + mUseClearTypeAlways = UNINITIALIZED_VALUE; 1.303 + 1.304 + mUsingGDIFonts = false; 1.305 + 1.306 + /* 1.307 + * Initialize COM 1.308 + */ 1.309 + CoInitialize(nullptr); 1.310 + 1.311 +#ifdef CAIRO_HAS_D2D_SURFACE 1.312 + RegisterStrongMemoryReporter(new GfxD2DSurfaceReporter()); 1.313 + mD2DDevice = nullptr; 1.314 +#endif 1.315 + RegisterStrongMemoryReporter(new GfxD2DVramReporter()); 1.316 + 1.317 + UpdateRenderMode(); 1.318 + 1.319 + RegisterStrongMemoryReporter(new GPUAdapterReporter()); 1.320 +} 1.321 + 1.322 +gfxWindowsPlatform::~gfxWindowsPlatform() 1.323 +{ 1.324 + mDeviceManager = nullptr; 1.325 + 1.326 + // not calling FT_Done_FreeType because cairo may still hold references to 1.327 + // these FT_Faces. See bug 458169. 1.328 +#ifdef CAIRO_HAS_D2D_SURFACE 1.329 + if (mD2DDevice) { 1.330 + cairo_release_device(mD2DDevice); 1.331 + } 1.332 +#endif 1.333 + 1.334 + mozilla::gfx::Factory::D2DCleanup(); 1.335 + 1.336 + /* 1.337 + * Uninitialize COM 1.338 + */ 1.339 + CoUninitialize(); 1.340 +} 1.341 + 1.342 +double 1.343 +gfxWindowsPlatform::GetDPIScale() 1.344 +{ 1.345 + return WinUtils::LogToPhysFactor(); 1.346 +} 1.347 + 1.348 +void 1.349 +gfxWindowsPlatform::UpdateRenderMode() 1.350 +{ 1.351 +/* Pick the default render mode for 1.352 + * desktop. 1.353 + */ 1.354 + mRenderMode = RENDER_GDI; 1.355 + 1.356 + bool isVistaOrHigher = IsVistaOrLater(); 1.357 + 1.358 + bool safeMode = false; 1.359 + nsCOMPtr<nsIXULRuntime> xr = do_GetService("@mozilla.org/xre/runtime;1"); 1.360 + if (xr) 1.361 + xr->GetInSafeMode(&safeMode); 1.362 + 1.363 + mUseDirectWrite = Preferences::GetBool("gfx.font_rendering.directwrite.enabled", false); 1.364 + 1.365 +#ifdef CAIRO_HAS_D2D_SURFACE 1.366 + bool d2dDisabled = false; 1.367 + bool d2dForceEnabled = false; 1.368 + bool d2dBlocked = false; 1.369 + 1.370 + nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1"); 1.371 + if (gfxInfo) { 1.372 + int32_t status; 1.373 + if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT2D, &status))) { 1.374 + if (status != nsIGfxInfo::FEATURE_NO_INFO) { 1.375 + d2dBlocked = true; 1.376 + } 1.377 + } 1.378 + } 1.379 + 1.380 + // These will only be evaluated once, and any subsequent changes to 1.381 + // the preferences will be ignored until restart. 1.382 + d2dDisabled = gfxPrefs::Direct2DDisabled(); 1.383 + d2dForceEnabled = gfxPrefs::Direct2DForceEnabled(); 1.384 + 1.385 + bool tryD2D = d2dForceEnabled || (!d2dBlocked && !gfxPrefs::LayersPreferD3D9()); 1.386 + 1.387 + // Do not ever try if d2d is explicitly disabled, 1.388 + // or if we're not using DWrite fonts. 1.389 + if (d2dDisabled || mUsingGDIFonts) { 1.390 + tryD2D = false; 1.391 + } 1.392 + 1.393 + if (isVistaOrHigher && !safeMode && tryD2D) { 1.394 + VerifyD2DDevice(d2dForceEnabled); 1.395 + if (mD2DDevice) { 1.396 + mRenderMode = RENDER_DIRECT2D; 1.397 + mUseDirectWrite = true; 1.398 + } 1.399 + } else { 1.400 + mD2DDevice = nullptr; 1.401 + } 1.402 +#endif 1.403 + 1.404 +#ifdef CAIRO_HAS_DWRITE_FONT 1.405 + // Enable when it's preffed on -and- we're using Vista or higher. Or when 1.406 + // we're going to use D2D. 1.407 + if (!mDWriteFactory && (mUseDirectWrite && isVistaOrHigher)) { 1.408 + mozilla::ScopedGfxFeatureReporter reporter("DWrite"); 1.409 + decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) 1.410 + GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); 1.411 + 1.412 + if (createDWriteFactory) { 1.413 + /** 1.414 + * I need a direct pointer to be able to cast to IUnknown**, I also 1.415 + * need to remember to release this because the nsRefPtr will 1.416 + * AddRef it. 1.417 + */ 1.418 + IDWriteFactory *factory; 1.419 + HRESULT hr = createDWriteFactory( 1.420 + DWRITE_FACTORY_TYPE_SHARED, 1.421 + __uuidof(IDWriteFactory), 1.422 + reinterpret_cast<IUnknown**>(&factory)); 1.423 + 1.424 + if (SUCCEEDED(hr) && factory) { 1.425 + mDWriteFactory = factory; 1.426 + factory->Release(); 1.427 + hr = mDWriteFactory->CreateTextAnalyzer( 1.428 + getter_AddRefs(mDWriteAnalyzer)); 1.429 + } 1.430 + 1.431 + SetupClearTypeParams(); 1.432 + 1.433 + if (hr == S_OK) 1.434 + reporter.SetSuccessful(); 1.435 + } 1.436 + } 1.437 +#endif 1.438 + 1.439 + uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO); 1.440 + uint32_t contentMask = BackendTypeBit(BackendType::CAIRO); 1.441 + BackendType defaultBackend = BackendType::CAIRO; 1.442 + if (mRenderMode == RENDER_DIRECT2D) { 1.443 + canvasMask |= BackendTypeBit(BackendType::DIRECT2D); 1.444 + contentMask |= BackendTypeBit(BackendType::DIRECT2D); 1.445 + defaultBackend = BackendType::DIRECT2D; 1.446 + } else { 1.447 + canvasMask |= BackendTypeBit(BackendType::SKIA); 1.448 + } 1.449 + contentMask |= BackendTypeBit(BackendType::SKIA); 1.450 + InitBackendPrefs(canvasMask, defaultBackend, 1.451 + contentMask, defaultBackend); 1.452 +} 1.453 + 1.454 +#ifdef CAIRO_HAS_D2D_SURFACE 1.455 +HRESULT 1.456 +gfxWindowsPlatform::CreateDevice(nsRefPtr<IDXGIAdapter1> &adapter1, 1.457 + int featureLevelIndex) 1.458 +{ 1.459 + nsModuleHandle d3d10module(LoadLibrarySystem32(L"d3d10_1.dll")); 1.460 + if (!d3d10module) 1.461 + return E_FAIL; 1.462 + decltype(D3D10CreateDevice1)* createD3DDevice = 1.463 + (decltype(D3D10CreateDevice1)*) GetProcAddress(d3d10module, "D3D10CreateDevice1"); 1.464 + if (!createD3DDevice) 1.465 + return E_FAIL; 1.466 + 1.467 + nsRefPtr<ID3D10Device1> device; 1.468 + HRESULT hr = 1.469 + createD3DDevice(adapter1, D3D10_DRIVER_TYPE_HARDWARE, nullptr, 1.470 + D3D10_CREATE_DEVICE_BGRA_SUPPORT | 1.471 + D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS, 1.472 + static_cast<D3D10_FEATURE_LEVEL1>(kSupportedFeatureLevels[featureLevelIndex]), 1.473 + D3D10_1_SDK_VERSION, getter_AddRefs(device)); 1.474 + 1.475 + // If we fail here, the DirectX version or video card probably 1.476 + // changed. We previously could use 10.1 but now we can't 1.477 + // anymore. Revert back to doing a 10.0 check first before 1.478 + // the 10.1 check. 1.479 + if (device) { 1.480 + mD2DDevice = cairo_d2d_create_device_from_d3d10device(device); 1.481 + 1.482 + // Setup a pref for future launch optimizaitons when in main process. 1.483 + if (XRE_GetProcessType() == GeckoProcessType_Default) { 1.484 + Preferences::SetInt(kFeatureLevelPref, featureLevelIndex); 1.485 + } 1.486 + } 1.487 + 1.488 + return device ? S_OK : hr; 1.489 +} 1.490 +#endif 1.491 + 1.492 +void 1.493 +gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce) 1.494 +{ 1.495 +#ifdef CAIRO_HAS_D2D_SURFACE 1.496 + if (mD2DDevice) { 1.497 + ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice); 1.498 + 1.499 + if (SUCCEEDED(device->GetDeviceRemovedReason())) { 1.500 + return; 1.501 + } 1.502 + mD2DDevice = nullptr; 1.503 + 1.504 + // Surface cache needs to be invalidated since it may contain vector 1.505 + // images rendered with our old, broken D2D device. 1.506 + SurfaceCache::DiscardAll(); 1.507 + } 1.508 + 1.509 + mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce); 1.510 + 1.511 + nsRefPtr<ID3D10Device1> device; 1.512 + 1.513 + int supportedFeatureLevelsCount = ArrayLength(kSupportedFeatureLevels); 1.514 + // If we're not running in Metro don't allow DX9.3 1.515 + if (!IsRunningInWindowsMetro()) { 1.516 + supportedFeatureLevelsCount--; 1.517 + } 1.518 + 1.519 + nsRefPtr<IDXGIAdapter1> adapter1 = GetDXGIAdapter(); 1.520 + 1.521 + if (!adapter1) { 1.522 + // Unable to create adapter, abort acceleration. 1.523 + return; 1.524 + } 1.525 + 1.526 + // It takes a lot of time (5-10% of startup time or ~100ms) to do both 1.527 + // a createD3DDevice on D3D10_FEATURE_LEVEL_10_0. We therefore store 1.528 + // the last used feature level to go direct to that. 1.529 + int featureLevelIndex = Preferences::GetInt(kFeatureLevelPref, 0); 1.530 + if (featureLevelIndex >= supportedFeatureLevelsCount || featureLevelIndex < 0) 1.531 + featureLevelIndex = 0; 1.532 + 1.533 + // Start with the last used feature level, and move to lower DX versions 1.534 + // until we find one that works. 1.535 + HRESULT hr = E_FAIL; 1.536 + for (int i = featureLevelIndex; i < supportedFeatureLevelsCount; i++) { 1.537 + hr = CreateDevice(adapter1, i); 1.538 + // If it succeeded we found the first available feature level 1.539 + if (SUCCEEDED(hr)) 1.540 + break; 1.541 + } 1.542 + 1.543 + // If we succeeded in creating a device, try for a newer device 1.544 + // that we haven't tried yet. 1.545 + if (SUCCEEDED(hr)) { 1.546 + for (int i = featureLevelIndex - 1; i >= 0; i--) { 1.547 + hr = CreateDevice(adapter1, i); 1.548 + // If it failed then we don't have new hardware 1.549 + if (FAILED(hr)) { 1.550 + break; 1.551 + } 1.552 + } 1.553 + } 1.554 + 1.555 + if (!mD2DDevice && aAttemptForce) { 1.556 + mD2DDevice = cairo_d2d_create_device(); 1.557 + } 1.558 + 1.559 + if (mD2DDevice) { 1.560 + reporter.SetSuccessful(); 1.561 + mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice)); 1.562 + } 1.563 +#endif 1.564 +} 1.565 + 1.566 +gfxPlatformFontList* 1.567 +gfxWindowsPlatform::CreatePlatformFontList() 1.568 +{ 1.569 + mUsingGDIFonts = false; 1.570 + gfxPlatformFontList *pfl; 1.571 +#ifdef CAIRO_HAS_DWRITE_FONT 1.572 + // bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd 1.573 + // crashers so blacklist them altogether 1.574 + if (IsNotWin7PreRTM() && GetDWriteFactory()) { 1.575 + pfl = new gfxDWriteFontList(); 1.576 + if (NS_SUCCEEDED(pfl->InitFontList())) { 1.577 + return pfl; 1.578 + } 1.579 + // DWrite font initialization failed! Don't know why this would happen, 1.580 + // but apparently it can - see bug 594865. 1.581 + // So we're going to fall back to GDI fonts & rendering. 1.582 + gfxPlatformFontList::Shutdown(); 1.583 + SetRenderMode(RENDER_GDI); 1.584 + } 1.585 +#endif 1.586 + pfl = new gfxGDIFontList(); 1.587 + mUsingGDIFonts = true; 1.588 + 1.589 + if (NS_SUCCEEDED(pfl->InitFontList())) { 1.590 + return pfl; 1.591 + } 1.592 + 1.593 + gfxPlatformFontList::Shutdown(); 1.594 + return nullptr; 1.595 +} 1.596 + 1.597 +already_AddRefed<gfxASurface> 1.598 +gfxWindowsPlatform::CreateOffscreenSurface(const IntSize& size, 1.599 + gfxContentType contentType) 1.600 +{ 1.601 + nsRefPtr<gfxASurface> surf = nullptr; 1.602 + 1.603 +#ifdef CAIRO_HAS_WIN32_SURFACE 1.604 + if (mRenderMode == RENDER_GDI) 1.605 + surf = new gfxWindowsSurface(ThebesIntSize(size), 1.606 + OptimalFormatForContent(contentType)); 1.607 +#endif 1.608 + 1.609 +#ifdef CAIRO_HAS_D2D_SURFACE 1.610 + if (mRenderMode == RENDER_DIRECT2D) 1.611 + surf = new gfxD2DSurface(ThebesIntSize(size), 1.612 + OptimalFormatForContent(contentType)); 1.613 +#endif 1.614 + 1.615 + if (!surf || surf->CairoStatus()) { 1.616 + surf = new gfxImageSurface(ThebesIntSize(size), 1.617 + OptimalFormatForContent(contentType)); 1.618 + } 1.619 + 1.620 + return surf.forget(); 1.621 +} 1.622 + 1.623 +already_AddRefed<gfxASurface> 1.624 +gfxWindowsPlatform::CreateOffscreenImageSurface(const gfxIntSize& aSize, 1.625 + gfxContentType aContentType) 1.626 +{ 1.627 +#ifdef CAIRO_HAS_D2D_SURFACE 1.628 + if (mRenderMode == RENDER_DIRECT2D) { 1.629 + nsRefPtr<gfxASurface> surface = 1.630 + new gfxImageSurface(aSize, OptimalFormatForContent(aContentType)); 1.631 + return surface.forget(); 1.632 + } 1.633 +#endif 1.634 + 1.635 + nsRefPtr<gfxASurface> surface = CreateOffscreenSurface(aSize.ToIntSize(), 1.636 + aContentType); 1.637 +#ifdef DEBUG 1.638 + nsRefPtr<gfxImageSurface> imageSurface = surface->GetAsImageSurface(); 1.639 + NS_ASSERTION(imageSurface, "Surface cannot be converted to a gfxImageSurface"); 1.640 +#endif 1.641 + return surface.forget(); 1.642 +} 1.643 + 1.644 +TemporaryRef<ScaledFont> 1.645 +gfxWindowsPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont) 1.646 +{ 1.647 + if (aFont->GetType() == gfxFont::FONT_TYPE_DWRITE) { 1.648 + gfxDWriteFont *font = static_cast<gfxDWriteFont*>(aFont); 1.649 + 1.650 + NativeFont nativeFont; 1.651 + nativeFont.mType = NativeFontType::DWRITE_FONT_FACE; 1.652 + nativeFont.mFont = font->GetFontFace(); 1.653 + 1.654 + if (aTarget->GetType() == BackendType::CAIRO) { 1.655 + return Factory::CreateScaledFontWithCairo(nativeFont, 1.656 + font->GetAdjustedSize(), 1.657 + font->GetCairoScaledFont()); 1.658 + } 1.659 + 1.660 + return Factory::CreateScaledFontForNativeFont(nativeFont, 1.661 + font->GetAdjustedSize()); 1.662 + } 1.663 + 1.664 + NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_GDI, 1.665 + "Fonts on windows should be GDI or DWrite!"); 1.666 + 1.667 + NativeFont nativeFont; 1.668 + nativeFont.mType = NativeFontType::GDI_FONT_FACE; 1.669 + LOGFONT lf; 1.670 + GetObject(static_cast<gfxGDIFont*>(aFont)->GetHFONT(), sizeof(LOGFONT), &lf); 1.671 + nativeFont.mFont = &lf; 1.672 + 1.673 + if (aTarget->GetType() == BackendType::CAIRO) { 1.674 + return Factory::CreateScaledFontWithCairo(nativeFont, 1.675 + aFont->GetAdjustedSize(), 1.676 + aFont->GetCairoScaledFont()); 1.677 + } 1.678 + 1.679 + return Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize()); 1.680 +} 1.681 + 1.682 +already_AddRefed<gfxASurface> 1.683 +gfxWindowsPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget) 1.684 +{ 1.685 +#ifdef XP_WIN 1.686 + if (aTarget->GetType() == BackendType::DIRECT2D) { 1.687 + if (!GetD2DDevice()) { 1.688 + // We no longer have a D2D device, can't do this. 1.689 + return nullptr; 1.690 + } 1.691 + 1.692 + RefPtr<ID3D10Texture2D> texture = 1.693 + static_cast<ID3D10Texture2D*>(aTarget->GetNativeSurface(NativeSurfaceType::D3D10_TEXTURE)); 1.694 + 1.695 + if (!texture) { 1.696 + return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget); 1.697 + } 1.698 + 1.699 + aTarget->Flush(); 1.700 + 1.701 + nsRefPtr<gfxASurface> surf = 1.702 + new gfxD2DSurface(texture, ContentForFormat(aTarget->GetFormat())); 1.703 + 1.704 + // shouldn't this hold a reference? 1.705 + surf->SetData(&kDrawTarget, aTarget, nullptr); 1.706 + return surf.forget(); 1.707 + } 1.708 +#endif 1.709 + 1.710 + return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget); 1.711 +} 1.712 + 1.713 +nsresult 1.714 +gfxWindowsPlatform::GetFontList(nsIAtom *aLangGroup, 1.715 + const nsACString& aGenericFamily, 1.716 + nsTArray<nsString>& aListOfFonts) 1.717 +{ 1.718 + gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup, aGenericFamily, aListOfFonts); 1.719 + 1.720 + return NS_OK; 1.721 +} 1.722 + 1.723 +static void 1.724 +RemoveCharsetFromFontSubstitute(nsAString &aName) 1.725 +{ 1.726 + int32_t comma = aName.FindChar(char16_t(',')); 1.727 + if (comma >= 0) 1.728 + aName.Truncate(comma); 1.729 +} 1.730 + 1.731 +nsresult 1.732 +gfxWindowsPlatform::UpdateFontList() 1.733 +{ 1.734 + gfxPlatformFontList::PlatformFontList()->UpdateFontList(); 1.735 + 1.736 + return NS_OK; 1.737 +} 1.738 + 1.739 +static const char kFontAparajita[] = "Aparajita"; 1.740 +static const char kFontArabicTypesetting[] = "Arabic Typesetting"; 1.741 +static const char kFontArial[] = "Arial"; 1.742 +static const char kFontArialUnicodeMS[] = "Arial Unicode MS"; 1.743 +static const char kFontCambria[] = "Cambria"; 1.744 +static const char kFontCambriaMath[] = "Cambria Math"; 1.745 +static const char kFontEbrima[] = "Ebrima"; 1.746 +static const char kFontEstrangeloEdessa[] = "Estrangelo Edessa"; 1.747 +static const char kFontEuphemia[] = "Euphemia"; 1.748 +static const char kFontGabriola[] = "Gabriola"; 1.749 +static const char kFontJavaneseText[] = "Javanese Text"; 1.750 +static const char kFontKhmerUI[] = "Khmer UI"; 1.751 +static const char kFontLaoUI[] = "Lao UI"; 1.752 +static const char kFontLeelawadeeUI[] = "Leelawadee UI"; 1.753 +static const char kFontLucidaSansUnicode[] = "Lucida Sans Unicode"; 1.754 +static const char kFontMVBoli[] = "MV Boli"; 1.755 +static const char kFontMalgunGothic[] = "Malgun Gothic"; 1.756 +static const char kFontMicrosoftJhengHei[] = "Microsoft JhengHei"; 1.757 +static const char kFontMicrosoftNewTaiLue[] = "Microsoft New Tai Lue"; 1.758 +static const char kFontMicrosoftPhagsPa[] = "Microsoft PhagsPa"; 1.759 +static const char kFontMicrosoftTaiLe[] = "Microsoft Tai Le"; 1.760 +static const char kFontMicrosoftUighur[] = "Microsoft Uighur"; 1.761 +static const char kFontMicrosoftYaHei[] = "Microsoft YaHei"; 1.762 +static const char kFontMicrosoftYiBaiti[] = "Microsoft Yi Baiti"; 1.763 +static const char kFontMeiryo[] = "Meiryo"; 1.764 +static const char kFontMongolianBaiti[] = "Mongolian Baiti"; 1.765 +static const char kFontMyanmarText[] = "Myanmar Text"; 1.766 +static const char kFontNirmalaUI[] = "Nirmala UI"; 1.767 +static const char kFontNyala[] = "Nyala"; 1.768 +static const char kFontPlantagenetCherokee[] = "Plantagenet Cherokee"; 1.769 +static const char kFontSegoeUI[] = "Segoe UI"; 1.770 +static const char kFontSegoeUISymbol[] = "Segoe UI Symbol"; 1.771 +static const char kFontSylfaen[] = "Sylfaen"; 1.772 +static const char kFontTraditionalArabic[] = "Traditional Arabic"; 1.773 +static const char kFontUtsaah[] = "Utsaah"; 1.774 +static const char kFontYuGothic[] = "Yu Gothic"; 1.775 + 1.776 +void 1.777 +gfxWindowsPlatform::GetCommonFallbackFonts(const uint32_t aCh, 1.778 + int32_t aRunScript, 1.779 + nsTArray<const char*>& aFontList) 1.780 +{ 1.781 + // Arial is used as the default fallback for system fallback 1.782 + aFontList.AppendElement(kFontArial); 1.783 + 1.784 + if (!IS_IN_BMP(aCh)) { 1.785 + uint32_t p = aCh >> 16; 1.786 + if (p == 1) { // SMP plane 1.787 + aFontList.AppendElement(kFontSegoeUISymbol); 1.788 + aFontList.AppendElement(kFontEbrima); 1.789 + aFontList.AppendElement(kFontNirmalaUI); 1.790 + aFontList.AppendElement(kFontCambriaMath); 1.791 + } 1.792 + } else { 1.793 + uint32_t b = (aCh >> 8) & 0xff; 1.794 + 1.795 + switch (b) { 1.796 + case 0x05: 1.797 + aFontList.AppendElement(kFontEstrangeloEdessa); 1.798 + aFontList.AppendElement(kFontCambria); 1.799 + break; 1.800 + case 0x06: 1.801 + aFontList.AppendElement(kFontMicrosoftUighur); 1.802 + break; 1.803 + case 0x07: 1.804 + aFontList.AppendElement(kFontEstrangeloEdessa); 1.805 + aFontList.AppendElement(kFontMVBoli); 1.806 + aFontList.AppendElement(kFontEbrima); 1.807 + break; 1.808 + case 0x09: 1.809 + aFontList.AppendElement(kFontNirmalaUI); 1.810 + aFontList.AppendElement(kFontUtsaah); 1.811 + aFontList.AppendElement(kFontAparajita); 1.812 + break; 1.813 + case 0x0e: 1.814 + aFontList.AppendElement(kFontLaoUI); 1.815 + break; 1.816 + case 0x10: 1.817 + aFontList.AppendElement(kFontMyanmarText); 1.818 + break; 1.819 + case 0x11: 1.820 + aFontList.AppendElement(kFontMalgunGothic); 1.821 + break; 1.822 + case 0x12: 1.823 + case 0x13: 1.824 + aFontList.AppendElement(kFontNyala); 1.825 + aFontList.AppendElement(kFontPlantagenetCherokee); 1.826 + break; 1.827 + case 0x14: 1.828 + case 0x15: 1.829 + case 0x16: 1.830 + aFontList.AppendElement(kFontEuphemia); 1.831 + aFontList.AppendElement(kFontSegoeUISymbol); 1.832 + break; 1.833 + case 0x17: 1.834 + aFontList.AppendElement(kFontKhmerUI); 1.835 + break; 1.836 + case 0x18: // Mongolian 1.837 + aFontList.AppendElement(kFontMongolianBaiti); 1.838 + aFontList.AppendElement(kFontEuphemia); 1.839 + break; 1.840 + case 0x19: 1.841 + aFontList.AppendElement(kFontMicrosoftTaiLe); 1.842 + aFontList.AppendElement(kFontMicrosoftNewTaiLue); 1.843 + aFontList.AppendElement(kFontKhmerUI); 1.844 + break; 1.845 + break; 1.846 + case 0x1a: 1.847 + aFontList.AppendElement(kFontLeelawadeeUI); 1.848 + break; 1.849 + case 0x1c: 1.850 + aFontList.AppendElement(kFontNirmalaUI); 1.851 + break; 1.852 + case 0x20: // Symbol ranges 1.853 + case 0x21: 1.854 + case 0x22: 1.855 + case 0x23: 1.856 + case 0x24: 1.857 + case 0x25: 1.858 + case 0x26: 1.859 + case 0x27: 1.860 + case 0x29: 1.861 + case 0x2a: 1.862 + case 0x2b: 1.863 + case 0x2c: 1.864 + aFontList.AppendElement(kFontSegoeUI); 1.865 + aFontList.AppendElement(kFontSegoeUISymbol); 1.866 + aFontList.AppendElement(kFontCambria); 1.867 + aFontList.AppendElement(kFontMeiryo); 1.868 + aFontList.AppendElement(kFontArial); 1.869 + aFontList.AppendElement(kFontLucidaSansUnicode); 1.870 + aFontList.AppendElement(kFontEbrima); 1.871 + break; 1.872 + case 0x2d: 1.873 + case 0x2e: 1.874 + case 0x2f: 1.875 + aFontList.AppendElement(kFontEbrima); 1.876 + aFontList.AppendElement(kFontNyala); 1.877 + aFontList.AppendElement(kFontSegoeUI); 1.878 + aFontList.AppendElement(kFontSegoeUISymbol); 1.879 + aFontList.AppendElement(kFontMeiryo); 1.880 + break; 1.881 + case 0x28: // Braille 1.882 + aFontList.AppendElement(kFontSegoeUISymbol); 1.883 + break; 1.884 + case 0x30: 1.885 + case 0x31: 1.886 + aFontList.AppendElement(kFontMicrosoftYaHei); 1.887 + break; 1.888 + case 0x32: 1.889 + aFontList.AppendElement(kFontMalgunGothic); 1.890 + break; 1.891 + case 0x4d: 1.892 + aFontList.AppendElement(kFontSegoeUISymbol); 1.893 + break; 1.894 + case 0x9f: 1.895 + aFontList.AppendElement(kFontMicrosoftYaHei); 1.896 + aFontList.AppendElement(kFontYuGothic); 1.897 + break; 1.898 + case 0xa0: // Yi 1.899 + case 0xa1: 1.900 + case 0xa2: 1.901 + case 0xa3: 1.902 + case 0xa4: 1.903 + aFontList.AppendElement(kFontMicrosoftYiBaiti); 1.904 + aFontList.AppendElement(kFontSegoeUI); 1.905 + break; 1.906 + case 0xa5: 1.907 + case 0xa6: 1.908 + case 0xa7: 1.909 + aFontList.AppendElement(kFontEbrima); 1.910 + aFontList.AppendElement(kFontSegoeUI); 1.911 + aFontList.AppendElement(kFontCambriaMath); 1.912 + break; 1.913 + case 0xa8: 1.914 + aFontList.AppendElement(kFontMicrosoftPhagsPa); 1.915 + aFontList.AppendElement(kFontNirmalaUI); 1.916 + break; 1.917 + case 0xa9: 1.918 + aFontList.AppendElement(kFontMalgunGothic); 1.919 + aFontList.AppendElement(kFontJavaneseText); 1.920 + break; 1.921 + case 0xaa: 1.922 + aFontList.AppendElement(kFontMyanmarText); 1.923 + break; 1.924 + case 0xab: 1.925 + aFontList.AppendElement(kFontEbrima); 1.926 + aFontList.AppendElement(kFontNyala); 1.927 + break; 1.928 + case 0xd7: 1.929 + aFontList.AppendElement(kFontMalgunGothic); 1.930 + break; 1.931 + case 0xfb: 1.932 + aFontList.AppendElement(kFontMicrosoftUighur); 1.933 + aFontList.AppendElement(kFontGabriola); 1.934 + aFontList.AppendElement(kFontSylfaen); 1.935 + break; 1.936 + case 0xfc: 1.937 + case 0xfd: 1.938 + aFontList.AppendElement(kFontTraditionalArabic); 1.939 + aFontList.AppendElement(kFontArabicTypesetting); 1.940 + break; 1.941 + case 0xfe: 1.942 + aFontList.AppendElement(kFontTraditionalArabic); 1.943 + aFontList.AppendElement(kFontMicrosoftJhengHei); 1.944 + break; 1.945 + case 0xff: 1.946 + aFontList.AppendElement(kFontMicrosoftJhengHei); 1.947 + break; 1.948 + default: 1.949 + break; 1.950 + } 1.951 + } 1.952 + 1.953 + // Arial Unicode MS has lots of glyphs for obscure characters, 1.954 + // use it as a last resort 1.955 + aFontList.AppendElement(kFontArialUnicodeMS); 1.956 +} 1.957 + 1.958 +struct ResolveData { 1.959 + ResolveData(gfxPlatform::FontResolverCallback aCallback, 1.960 + gfxWindowsPlatform *aCaller, const nsAString *aFontName, 1.961 + void *aClosure) : 1.962 + mFoundCount(0), mCallback(aCallback), mCaller(aCaller), 1.963 + mFontName(aFontName), mClosure(aClosure) {} 1.964 + uint32_t mFoundCount; 1.965 + gfxPlatform::FontResolverCallback mCallback; 1.966 + gfxWindowsPlatform *mCaller; 1.967 + const nsAString *mFontName; 1.968 + void *mClosure; 1.969 +}; 1.970 + 1.971 +nsresult 1.972 +gfxWindowsPlatform::ResolveFontName(const nsAString& aFontName, 1.973 + FontResolverCallback aCallback, 1.974 + void *aClosure, 1.975 + bool& aAborted) 1.976 +{ 1.977 + nsAutoString resolvedName; 1.978 + if (!gfxPlatformFontList::PlatformFontList()-> 1.979 + ResolveFontName(aFontName, resolvedName)) { 1.980 + aAborted = false; 1.981 + return NS_OK; 1.982 + } 1.983 + aAborted = !(*aCallback)(resolvedName, aClosure); 1.984 + return NS_OK; 1.985 +} 1.986 + 1.987 +nsresult 1.988 +gfxWindowsPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) 1.989 +{ 1.990 + gfxPlatformFontList::PlatformFontList()->GetStandardFamilyName(aFontName, aFamilyName); 1.991 + return NS_OK; 1.992 +} 1.993 + 1.994 +gfxFontGroup * 1.995 +gfxWindowsPlatform::CreateFontGroup(const nsAString &aFamilies, 1.996 + const gfxFontStyle *aStyle, 1.997 + gfxUserFontSet *aUserFontSet) 1.998 +{ 1.999 + return new gfxFontGroup(aFamilies, aStyle, aUserFontSet); 1.1000 +} 1.1001 + 1.1002 +gfxFontEntry* 1.1003 +gfxWindowsPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry, 1.1004 + const nsAString& aFontName) 1.1005 +{ 1.1006 + return gfxPlatformFontList::PlatformFontList()->LookupLocalFont(aProxyEntry, 1.1007 + aFontName); 1.1008 +} 1.1009 + 1.1010 +gfxFontEntry* 1.1011 +gfxWindowsPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, 1.1012 + const uint8_t *aFontData, uint32_t aLength) 1.1013 +{ 1.1014 + return gfxPlatformFontList::PlatformFontList()->MakePlatformFont(aProxyEntry, 1.1015 + aFontData, 1.1016 + aLength); 1.1017 +} 1.1018 + 1.1019 +bool 1.1020 +gfxWindowsPlatform::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) 1.1021 +{ 1.1022 + // check for strange format flags 1.1023 + NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED), 1.1024 + "strange font format hint set"); 1.1025 + 1.1026 + // accept supported formats 1.1027 + if (aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_WOFF | 1.1028 + gfxUserFontSet::FLAG_FORMAT_OPENTYPE | 1.1029 + gfxUserFontSet::FLAG_FORMAT_TRUETYPE)) { 1.1030 + return true; 1.1031 + } 1.1032 + 1.1033 + // reject all other formats, known and unknown 1.1034 + if (aFormatFlags != 0) { 1.1035 + return false; 1.1036 + } 1.1037 + 1.1038 + // no format hint set, need to look at data 1.1039 + return true; 1.1040 +} 1.1041 + 1.1042 +gfxFontFamily * 1.1043 +gfxWindowsPlatform::FindFontFamily(const nsAString& aName) 1.1044 +{ 1.1045 + return gfxPlatformFontList::PlatformFontList()->FindFamily(aName); 1.1046 +} 1.1047 + 1.1048 +gfxFontEntry * 1.1049 +gfxWindowsPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle) 1.1050 +{ 1.1051 + nsRefPtr<gfxFontFamily> ff = FindFontFamily(aName); 1.1052 + if (!ff) 1.1053 + return nullptr; 1.1054 + 1.1055 + bool aNeedsBold; 1.1056 + return ff->FindFontForStyle(aFontStyle, aNeedsBold); 1.1057 +} 1.1058 + 1.1059 +void 1.1060 +gfxWindowsPlatform::GetPlatformCMSOutputProfile(void* &mem, size_t &mem_size) 1.1061 +{ 1.1062 + WCHAR str[MAX_PATH]; 1.1063 + DWORD size = MAX_PATH; 1.1064 + BOOL res; 1.1065 + 1.1066 + mem = nullptr; 1.1067 + mem_size = 0; 1.1068 + 1.1069 + HDC dc = GetDC(nullptr); 1.1070 + if (!dc) 1.1071 + return; 1.1072 + 1.1073 +#if _MSC_VER 1.1074 + __try { 1.1075 + res = GetICMProfileW(dc, &size, (LPWSTR)&str); 1.1076 + } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) { 1.1077 + res = FALSE; 1.1078 + } 1.1079 +#else 1.1080 + res = GetICMProfileW(dc, &size, (LPWSTR)&str); 1.1081 +#endif 1.1082 + 1.1083 + ReleaseDC(nullptr, dc); 1.1084 + if (!res) 1.1085 + return; 1.1086 + 1.1087 +#ifdef _WIN32 1.1088 + qcms_data_from_unicode_path(str, &mem, &mem_size); 1.1089 + 1.1090 +#ifdef DEBUG_tor 1.1091 + if (mem_size > 0) 1.1092 + fprintf(stderr, 1.1093 + "ICM profile read from %s successfully\n", 1.1094 + NS_ConvertUTF16toUTF8(str).get()); 1.1095 +#endif // DEBUG_tor 1.1096 +#endif // _WIN32 1.1097 +} 1.1098 + 1.1099 +bool 1.1100 +gfxWindowsPlatform::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *array) 1.1101 +{ 1.1102 + return mPrefFonts.Get(aKey, array); 1.1103 +} 1.1104 + 1.1105 +void 1.1106 +gfxWindowsPlatform::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& array) 1.1107 +{ 1.1108 + mPrefFonts.Put(aKey, array); 1.1109 +} 1.1110 + 1.1111 +bool 1.1112 +gfxWindowsPlatform::UseClearTypeForDownloadableFonts() 1.1113 +{ 1.1114 + if (mUseClearTypeForDownloadableFonts == UNINITIALIZED_VALUE) { 1.1115 + mUseClearTypeForDownloadableFonts = Preferences::GetBool(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, true); 1.1116 + } 1.1117 + 1.1118 + return mUseClearTypeForDownloadableFonts; 1.1119 +} 1.1120 + 1.1121 +bool 1.1122 +gfxWindowsPlatform::UseClearTypeAlways() 1.1123 +{ 1.1124 + if (mUseClearTypeAlways == UNINITIALIZED_VALUE) { 1.1125 + mUseClearTypeAlways = Preferences::GetBool(GFX_USE_CLEARTYPE_ALWAYS, false); 1.1126 + } 1.1127 + 1.1128 + return mUseClearTypeAlways; 1.1129 +} 1.1130 + 1.1131 +void 1.1132 +gfxWindowsPlatform::GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion) 1.1133 +{ 1.1134 + DWORD versInfoSize, vers[4] = {0}; 1.1135 + // version info not available case 1.1136 + aVersion.Assign(NS_LITERAL_STRING("0.0.0.0")); 1.1137 + versInfoSize = GetFileVersionInfoSizeW(aDLLPath, nullptr); 1.1138 + nsAutoTArray<BYTE,512> versionInfo; 1.1139 + 1.1140 + if (versInfoSize == 0 || 1.1141 + !versionInfo.AppendElements(uint32_t(versInfoSize))) 1.1142 + { 1.1143 + return; 1.1144 + } 1.1145 + 1.1146 + if (!GetFileVersionInfoW(aDLLPath, 0, versInfoSize, 1.1147 + LPBYTE(versionInfo.Elements()))) 1.1148 + { 1.1149 + return; 1.1150 + } 1.1151 + 1.1152 + UINT len = 0; 1.1153 + VS_FIXEDFILEINFO *fileInfo = nullptr; 1.1154 + if (!VerQueryValue(LPBYTE(versionInfo.Elements()), TEXT("\\"), 1.1155 + (LPVOID *)&fileInfo, &len) || 1.1156 + len == 0 || 1.1157 + fileInfo == nullptr) 1.1158 + { 1.1159 + return; 1.1160 + } 1.1161 + 1.1162 + DWORD fileVersMS = fileInfo->dwFileVersionMS; 1.1163 + DWORD fileVersLS = fileInfo->dwFileVersionLS; 1.1164 + 1.1165 + vers[0] = HIWORD(fileVersMS); 1.1166 + vers[1] = LOWORD(fileVersMS); 1.1167 + vers[2] = HIWORD(fileVersLS); 1.1168 + vers[3] = LOWORD(fileVersLS); 1.1169 + 1.1170 + char buf[256]; 1.1171 + sprintf(buf, "%d.%d.%d.%d", vers[0], vers[1], vers[2], vers[3]); 1.1172 + aVersion.Assign(NS_ConvertUTF8toUTF16(buf)); 1.1173 +} 1.1174 + 1.1175 +void 1.1176 +gfxWindowsPlatform::GetCleartypeParams(nsTArray<ClearTypeParameterInfo>& aParams) 1.1177 +{ 1.1178 + HKEY hKey, subKey; 1.1179 + DWORD i, rv, size, type; 1.1180 + WCHAR displayName[256], subkeyName[256]; 1.1181 + 1.1182 + aParams.Clear(); 1.1183 + 1.1184 + // construct subkeys based on HKLM subkeys, assume they are same for HKCU 1.1185 + rv = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1.1186 + L"Software\\Microsoft\\Avalon.Graphics", 1.1187 + 0, KEY_READ, &hKey); 1.1188 + 1.1189 + if (rv != ERROR_SUCCESS) { 1.1190 + return; 1.1191 + } 1.1192 + 1.1193 + // enumerate over subkeys 1.1194 + for (i = 0, rv = ERROR_SUCCESS; rv != ERROR_NO_MORE_ITEMS; i++) { 1.1195 + size = ArrayLength(displayName); 1.1196 + rv = RegEnumKeyExW(hKey, i, displayName, &size, 1.1197 + nullptr, nullptr, nullptr, nullptr); 1.1198 + if (rv != ERROR_SUCCESS) { 1.1199 + continue; 1.1200 + } 1.1201 + 1.1202 + ClearTypeParameterInfo ctinfo; 1.1203 + ctinfo.displayName.Assign(displayName); 1.1204 + 1.1205 + DWORD subrv, value; 1.1206 + bool foundData = false; 1.1207 + 1.1208 + swprintf_s(subkeyName, ArrayLength(subkeyName), 1.1209 + L"Software\\Microsoft\\Avalon.Graphics\\%s", displayName); 1.1210 + 1.1211 + // subkey for gamma, pixel structure 1.1212 + subrv = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1.1213 + subkeyName, 0, KEY_QUERY_VALUE, &subKey); 1.1214 + 1.1215 + if (subrv == ERROR_SUCCESS) { 1.1216 + size = sizeof(value); 1.1217 + subrv = RegQueryValueExW(subKey, L"GammaLevel", nullptr, &type, 1.1218 + (LPBYTE)&value, &size); 1.1219 + if (subrv == ERROR_SUCCESS && type == REG_DWORD) { 1.1220 + foundData = true; 1.1221 + ctinfo.gamma = value; 1.1222 + } 1.1223 + 1.1224 + size = sizeof(value); 1.1225 + subrv = RegQueryValueExW(subKey, L"PixelStructure", nullptr, &type, 1.1226 + (LPBYTE)&value, &size); 1.1227 + if (subrv == ERROR_SUCCESS && type == REG_DWORD) { 1.1228 + foundData = true; 1.1229 + ctinfo.pixelStructure = value; 1.1230 + } 1.1231 + 1.1232 + RegCloseKey(subKey); 1.1233 + } 1.1234 + 1.1235 + // subkey for cleartype level, enhanced contrast 1.1236 + subrv = RegOpenKeyExW(HKEY_CURRENT_USER, 1.1237 + subkeyName, 0, KEY_QUERY_VALUE, &subKey); 1.1238 + 1.1239 + if (subrv == ERROR_SUCCESS) { 1.1240 + size = sizeof(value); 1.1241 + subrv = RegQueryValueExW(subKey, L"ClearTypeLevel", nullptr, &type, 1.1242 + (LPBYTE)&value, &size); 1.1243 + if (subrv == ERROR_SUCCESS && type == REG_DWORD) { 1.1244 + foundData = true; 1.1245 + ctinfo.clearTypeLevel = value; 1.1246 + } 1.1247 + 1.1248 + size = sizeof(value); 1.1249 + subrv = RegQueryValueExW(subKey, L"EnhancedContrastLevel", 1.1250 + nullptr, &type, (LPBYTE)&value, &size); 1.1251 + if (subrv == ERROR_SUCCESS && type == REG_DWORD) { 1.1252 + foundData = true; 1.1253 + ctinfo.enhancedContrast = value; 1.1254 + } 1.1255 + 1.1256 + RegCloseKey(subKey); 1.1257 + } 1.1258 + 1.1259 + if (foundData) { 1.1260 + aParams.AppendElement(ctinfo); 1.1261 + } 1.1262 + } 1.1263 + 1.1264 + RegCloseKey(hKey); 1.1265 +} 1.1266 + 1.1267 +void 1.1268 +gfxWindowsPlatform::FontsPrefsChanged(const char *aPref) 1.1269 +{ 1.1270 + bool clearTextFontCaches = true; 1.1271 + 1.1272 + gfxPlatform::FontsPrefsChanged(aPref); 1.1273 + 1.1274 + if (!aPref) { 1.1275 + mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; 1.1276 + mUseClearTypeAlways = UNINITIALIZED_VALUE; 1.1277 + } else if (!strcmp(GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE, aPref)) { 1.1278 + mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; 1.1279 + } else if (!strcmp(GFX_USE_CLEARTYPE_ALWAYS, aPref)) { 1.1280 + mUseClearTypeAlways = UNINITIALIZED_VALUE; 1.1281 + } else if (!strncmp(GFX_CLEARTYPE_PARAMS, aPref, strlen(GFX_CLEARTYPE_PARAMS))) { 1.1282 + SetupClearTypeParams(); 1.1283 + } else { 1.1284 + clearTextFontCaches = false; 1.1285 + } 1.1286 + 1.1287 + if (clearTextFontCaches) { 1.1288 + gfxFontCache *fc = gfxFontCache::GetCache(); 1.1289 + if (fc) { 1.1290 + fc->Flush(); 1.1291 + } 1.1292 + } 1.1293 +} 1.1294 + 1.1295 +#define ENHANCED_CONTRAST_REGISTRY_KEY \ 1.1296 + HKEY_CURRENT_USER, "Software\\Microsoft\\Avalon.Graphics\\DISPLAY1\\EnhancedContrastLevel" 1.1297 + 1.1298 +void 1.1299 +gfxWindowsPlatform::SetupClearTypeParams() 1.1300 +{ 1.1301 +#if CAIRO_HAS_DWRITE_FONT 1.1302 + if (GetDWriteFactory()) { 1.1303 + // any missing prefs will default to invalid (-1) and be ignored; 1.1304 + // out-of-range values will also be ignored 1.1305 + FLOAT gamma = -1.0; 1.1306 + FLOAT contrast = -1.0; 1.1307 + FLOAT level = -1.0; 1.1308 + int geometry = -1; 1.1309 + int mode = -1; 1.1310 + int32_t value; 1.1311 + if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_GAMMA, &value))) { 1.1312 + if (value >= 1000 && value <= 2200) { 1.1313 + gamma = FLOAT(value / 1000.0); 1.1314 + } 1.1315 + } 1.1316 + 1.1317 + if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_CONTRAST, &value))) { 1.1318 + if (value >= 0 && value <= 1000) { 1.1319 + contrast = FLOAT(value / 100.0); 1.1320 + } 1.1321 + } 1.1322 + 1.1323 + if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_LEVEL, &value))) { 1.1324 + if (value >= 0 && value <= 100) { 1.1325 + level = FLOAT(value / 100.0); 1.1326 + } 1.1327 + } 1.1328 + 1.1329 + if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_STRUCTURE, &value))) { 1.1330 + if (value >= 0 && value <= 2) { 1.1331 + geometry = value; 1.1332 + } 1.1333 + } 1.1334 + 1.1335 + if (NS_SUCCEEDED(Preferences::GetInt(GFX_CLEARTYPE_PARAMS_MODE, &value))) { 1.1336 + if (value >= 0 && value <= 5) { 1.1337 + mode = value; 1.1338 + } 1.1339 + } 1.1340 + 1.1341 + cairo_dwrite_set_cleartype_params(gamma, contrast, level, geometry, mode); 1.1342 + 1.1343 + switch (mode) { 1.1344 + case DWRITE_RENDERING_MODE_ALIASED: 1.1345 + case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC: 1.1346 + mMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC; 1.1347 + break; 1.1348 + case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL: 1.1349 + mMeasuringMode = DWRITE_MEASURING_MODE_GDI_NATURAL; 1.1350 + break; 1.1351 + default: 1.1352 + mMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; 1.1353 + break; 1.1354 + } 1.1355 + 1.1356 + nsRefPtr<IDWriteRenderingParams> defaultRenderingParams; 1.1357 + GetDWriteFactory()->CreateRenderingParams(getter_AddRefs(defaultRenderingParams)); 1.1358 + // For EnhancedContrast, we override the default if the user has not set it 1.1359 + // in the registry (by using the ClearType Tuner). 1.1360 + if (contrast >= 0.0 && contrast <= 10.0) { 1.1361 + contrast = contrast; 1.1362 + } else { 1.1363 + HKEY hKey; 1.1364 + if (RegOpenKeyExA(ENHANCED_CONTRAST_REGISTRY_KEY, 1.1365 + 0, KEY_READ, &hKey) == ERROR_SUCCESS) 1.1366 + { 1.1367 + contrast = defaultRenderingParams->GetEnhancedContrast(); 1.1368 + RegCloseKey(hKey); 1.1369 + } else { 1.1370 + contrast = 1.0; 1.1371 + } 1.1372 + } 1.1373 + 1.1374 + // For parameters that have not been explicitly set, 1.1375 + // we copy values from default params (or our overridden value for contrast) 1.1376 + if (gamma < 1.0 || gamma > 2.2) { 1.1377 + gamma = defaultRenderingParams->GetGamma(); 1.1378 + } 1.1379 + 1.1380 + if (level < 0.0 || level > 1.0) { 1.1381 + level = defaultRenderingParams->GetClearTypeLevel(); 1.1382 + } 1.1383 + 1.1384 + DWRITE_PIXEL_GEOMETRY dwriteGeometry = 1.1385 + static_cast<DWRITE_PIXEL_GEOMETRY>(geometry); 1.1386 + DWRITE_RENDERING_MODE renderMode = 1.1387 + static_cast<DWRITE_RENDERING_MODE>(mode); 1.1388 + 1.1389 + if (dwriteGeometry < DWRITE_PIXEL_GEOMETRY_FLAT || 1.1390 + dwriteGeometry > DWRITE_PIXEL_GEOMETRY_BGR) { 1.1391 + dwriteGeometry = defaultRenderingParams->GetPixelGeometry(); 1.1392 + } 1.1393 + 1.1394 + if (renderMode < DWRITE_RENDERING_MODE_DEFAULT || 1.1395 + renderMode > DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC) { 1.1396 + renderMode = defaultRenderingParams->GetRenderingMode(); 1.1397 + } 1.1398 + 1.1399 + mRenderingParams[TEXT_RENDERING_NO_CLEARTYPE] = defaultRenderingParams; 1.1400 + 1.1401 + GetDWriteFactory()->CreateCustomRenderingParams(gamma, contrast, level, 1.1402 + dwriteGeometry, renderMode, 1.1403 + getter_AddRefs(mRenderingParams[TEXT_RENDERING_NORMAL])); 1.1404 + 1.1405 + GetDWriteFactory()->CreateCustomRenderingParams(gamma, contrast, level, 1.1406 + dwriteGeometry, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, 1.1407 + getter_AddRefs(mRenderingParams[TEXT_RENDERING_GDI_CLASSIC])); 1.1408 + } 1.1409 +#endif 1.1410 +} 1.1411 + 1.1412 +void 1.1413 +gfxWindowsPlatform::OnDeviceManagerDestroy(DeviceManagerD3D9* aDeviceManager) 1.1414 +{ 1.1415 + if (aDeviceManager == mDeviceManager) { 1.1416 + mDeviceManager = nullptr; 1.1417 + } 1.1418 +} 1.1419 + 1.1420 +IDirect3DDevice9* 1.1421 +gfxWindowsPlatform::GetD3D9Device() 1.1422 +{ 1.1423 + DeviceManagerD3D9* manager = GetD3D9DeviceManager(); 1.1424 + return manager ? manager->device() : nullptr; 1.1425 +} 1.1426 + 1.1427 +DeviceManagerD3D9* 1.1428 +gfxWindowsPlatform::GetD3D9DeviceManager() 1.1429 +{ 1.1430 + // We should only create the d3d9 device on the compositor thread 1.1431 + // or we don't have a compositor thread. 1.1432 + if (!mDeviceManager && 1.1433 + (CompositorParent::IsInCompositorThread() || 1.1434 + !CompositorParent::CompositorLoop())) { 1.1435 + mDeviceManager = new DeviceManagerD3D9(); 1.1436 + if (!mDeviceManager->Init()) { 1.1437 + NS_WARNING("Could not initialise device manager"); 1.1438 + mDeviceManager = nullptr; 1.1439 + } 1.1440 + } 1.1441 + 1.1442 + return mDeviceManager; 1.1443 +} 1.1444 + 1.1445 +ID3D11Device* 1.1446 +gfxWindowsPlatform::GetD3D11Device() 1.1447 +{ 1.1448 + if (mD3D11DeviceInitialized) { 1.1449 + return mD3D11Device; 1.1450 + } 1.1451 + 1.1452 + mD3D11DeviceInitialized = true; 1.1453 + 1.1454 + nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll")); 1.1455 + decltype(D3D11CreateDevice)* d3d11CreateDevice = (decltype(D3D11CreateDevice)*) 1.1456 + GetProcAddress(d3d11Module, "D3D11CreateDevice"); 1.1457 + 1.1458 + if (!d3d11CreateDevice) { 1.1459 + return nullptr; 1.1460 + } 1.1461 + 1.1462 + nsTArray<D3D_FEATURE_LEVEL> featureLevels; 1.1463 + if (IsWin8OrLater()) { 1.1464 + featureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1); 1.1465 + } 1.1466 + featureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0); 1.1467 + featureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1); 1.1468 + featureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0); 1.1469 + featureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3); 1.1470 + 1.1471 + RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter(); 1.1472 + 1.1473 + if (!adapter) { 1.1474 + return nullptr; 1.1475 + } 1.1476 + 1.1477 + HRESULT hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 1.1478 + D3D11_CREATE_DEVICE_BGRA_SUPPORT, 1.1479 + featureLevels.Elements(), featureLevels.Length(), 1.1480 + D3D11_SDK_VERSION, byRef(mD3D11Device), nullptr, nullptr); 1.1481 + 1.1482 + // We leak these everywhere and we need them our entire runtime anyway, let's 1.1483 + // leak it here as well. 1.1484 + d3d11Module.disown(); 1.1485 + 1.1486 + return mD3D11Device; 1.1487 +} 1.1488 + 1.1489 +bool 1.1490 +gfxWindowsPlatform::IsOptimus() 1.1491 +{ 1.1492 + return GetModuleHandleA("nvumdshim.dll"); 1.1493 +} 1.1494 + 1.1495 +int 1.1496 +gfxWindowsPlatform::GetScreenDepth() const 1.1497 +{ 1.1498 + // if the system doesn't have all displays with the same 1.1499 + // pixel format, just return 24 and move on with life. 1.1500 + if (!GetSystemMetrics(SM_SAMEDISPLAYFORMAT)) 1.1501 + return 24; 1.1502 + 1.1503 + HDC hdc = GetDC(nullptr); 1.1504 + if (!hdc) 1.1505 + return 24; 1.1506 + 1.1507 + int depth = GetDeviceCaps(hdc, BITSPIXEL) * 1.1508 + GetDeviceCaps(hdc, PLANES); 1.1509 + 1.1510 + ReleaseDC(nullptr, hdc); 1.1511 + 1.1512 + return depth; 1.1513 +} 1.1514 + 1.1515 +IDXGIAdapter1* 1.1516 +gfxWindowsPlatform::GetDXGIAdapter() 1.1517 +{ 1.1518 + if (mAdapter) { 1.1519 + return mAdapter; 1.1520 + } 1.1521 + 1.1522 + nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll")); 1.1523 + decltype(CreateDXGIFactory1)* createDXGIFactory1 = (decltype(CreateDXGIFactory1)*) 1.1524 + GetProcAddress(dxgiModule, "CreateDXGIFactory1"); 1.1525 + 1.1526 + // Try to use a DXGI 1.1 adapter in order to share resources 1.1527 + // across processes. 1.1528 + if (createDXGIFactory1) { 1.1529 + nsRefPtr<IDXGIFactory1> factory1; 1.1530 + HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1), 1.1531 + getter_AddRefs(factory1)); 1.1532 + 1.1533 + if (FAILED(hr) || !factory1) { 1.1534 + // This seems to happen with some people running the iZ3D driver. 1.1535 + // They won't get acceleration. 1.1536 + return nullptr; 1.1537 + } 1.1538 + 1.1539 + hr = factory1->EnumAdapters1(0, byRef(mAdapter)); 1.1540 + if (FAILED(hr)) { 1.1541 + // We should return and not accelerate if we can't obtain 1.1542 + // an adapter. 1.1543 + return nullptr; 1.1544 + } 1.1545 + } 1.1546 + 1.1547 + // We leak this module everywhere, we might as well do so here as well. 1.1548 + dxgiModule.disown(); 1.1549 + 1.1550 + return mAdapter; 1.1551 +}