Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-07-27 16:40:43 +02:00
commit bd055a6272
211 changed files with 3571 additions and 2827 deletions

View File

@ -30,7 +30,7 @@ class Accessible;
* Mozilla creates the implementations of nsIAccessible on demand.
* See http://www.mozilla.org/projects/ui/accessibility for more information.
*/
[scriptable, uuid(de2869d9-563c-4943-996b-31a4daa4d097)]
[scriptable, builtinclass, uuid(de2869d9-563c-4943-996b-31a4daa4d097)]
interface nsIAccessible : nsISupports
{
/**

View File

@ -9,7 +9,7 @@
* This interface is implemented by top level accessible object in hierarchy and
* provides information about application.
*/
[scriptable, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
[scriptable, builtinclass, uuid(79251626-387c-4531-89f3-680d31d6cf05)]
interface nsIAccessibleApplication : nsISupports
{
/**

View File

@ -19,7 +19,7 @@ interface mozIDOMWindowProxy;
* the root node of a document or you can get one from
* nsIAccessible::GetDocument().
*/
[scriptable, uuid(5cad5f91-fcce-40e7-913e-4671701d19b4)]
[scriptable, builtinclass, uuid(5cad5f91-fcce-40e7-913e-4671701d19b4)]
interface nsIAccessibleDocument : nsISupports
{
/**

View File

@ -6,7 +6,7 @@
#include "nsISupports.idl"
[scriptable, uuid(28915cca-3366-4034-ba1d-b7afb9b37639)]
[scriptable, builtinclass, uuid(28915cca-3366-4034-ba1d-b7afb9b37639)]
interface nsIAccessibleEditableText : nsISupports
{
/**

View File

@ -13,7 +13,7 @@ interface nsIAccessible;
* A cross-platform interface that supports hyperlink-specific properties and
* methods. Anchors, image maps, xul:labels with class="text-link" implement this interface.
*/
[scriptable, uuid(883643d4-93a5-4f32-922c-6f06e01363c1)]
[scriptable, builtinclass, uuid(883643d4-93a5-4f32-922c-6f06e01363c1)]
interface nsIAccessibleHyperLink : nsISupports
{
/**

View File

@ -15,7 +15,7 @@
* Current implementation assumes every embedded object is a link.
*/
[scriptable, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
[scriptable, builtinclass, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
interface nsIAccessibleHyperText : nsISupports
{
/**

View File

@ -5,7 +5,7 @@
#include "nsISupports.idl"
[scriptable, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
[scriptable, builtinclass, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
interface nsIAccessibleImage : nsISupports
{
/**

View File

@ -11,7 +11,7 @@ interface nsIAccessible;
/**
* This interface gives access to an accessible's set of relations.
*/
[scriptable, uuid(55b308c4-2ae4-46bc-b4cd-4d4370e0a660)]
[scriptable, builtinclass, uuid(55b308c4-2ae4-46bc-b4cd-4d4370e0a660)]
interface nsIAccessibleRelation : nsISupports
{
/**

View File

@ -16,7 +16,7 @@ interface nsIAccessiblePivot;
* nsIAccessible for a given DOM node. More documentation at:
* http://www.mozilla.org/projects/ui/accessibility
*/
[scriptable, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
[scriptable, builtinclass, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
interface nsIAccessibleRetrieval : nsISupports
{
/**

View File

@ -8,7 +8,7 @@
/**
* Defines cross platform (Gecko) roles.
*/
[scriptable, uuid(05a9f33f-dcfd-4e7b-b825-138ba784c1f5)]
[scriptable, builtinclass, uuid(05a9f33f-dcfd-4e7b-b825-138ba784c1f5)]
interface nsIAccessibleRole : nsISupports
{
/**

View File

@ -11,7 +11,7 @@ interface nsIArray;
/**
* An accessibility interface for selectable widgets.
*/
[scriptable, uuid(8efb03d4-1354-4875-94cf-261336057626)]
[scriptable, builtinclass, uuid(8efb03d4-1354-4875-94cf-261336057626)]
interface nsIAccessibleSelectable : nsISupports
{
/**

View File

@ -9,7 +9,7 @@
interface nsIAccessible;
interface nsIArray;
[scriptable, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
[scriptable, builtinclass, uuid(cb0bf7b9-117e-40e2-9e46-189c3d43ce4a)]
interface nsIAccessibleTable : nsISupports
{
/**
@ -221,7 +221,7 @@ interface nsIAccessibleTable : nsISupports
};
[scriptable, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
[scriptable, builtinclass, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
interface nsIAccessibleTableCell : nsISupports
{
/**

View File

@ -13,7 +13,7 @@ interface nsIArray;
interface nsIPersistentProperties;
interface nsIAccessibleTextRange;
[scriptable, uuid(93ad2ca1-f12b-4ab9-a793-95d9fa9d1774)]
[scriptable, builtinclass, uuid(93ad2ca1-f12b-4ab9-a793-95d9fa9d1774)]
interface nsIAccessibleText : nsISupports
{
// In parameters for character offsets:

View File

@ -13,7 +13,7 @@ interface nsIVariant;
/**
* A range representing a piece of text in the document.
*/
[scriptable, uuid(c4515623-55f9-4543-a3d5-c1e9afa588f4)]
[scriptable, builtinclass, uuid(c4515623-55f9-4543-a3d5-c1e9afa588f4)]
interface nsIAccessibleTextRange : nsISupports
{
readonly attribute nsIAccessibleText startContainer;

View File

@ -9,7 +9,7 @@
* These constants control the scrolling of an object or substring into a
* window. Note, keep them synchronized with IA2ScrollType.
*/
[scriptable, uuid(05cd38b1-94b3-4cdf-8371-3935a9611405)]
[scriptable, builtinclass, uuid(05cd38b1-94b3-4cdf-8371-3935a9611405)]
interface nsIAccessibleScrollType : nsISupports
{
/**
@ -59,7 +59,7 @@ interface nsIAccessibleScrollType : nsISupports
/**
* These constants define which coordinate system a point is located in.
*/
[scriptable, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
[scriptable, builtinclass, uuid(c9fbdf10-619e-436f-bf4b-8566686f1577)]
interface nsIAccessibleCoordinateType : nsISupports
{
/**

View File

@ -6,7 +6,7 @@
#include "nsISupports.idl"
[scriptable, uuid(42a1e1dc-58cf-419d-bff0-ed3314c70016)]
[scriptable, builtinclass, uuid(42a1e1dc-58cf-419d-bff0-ed3314c70016)]
interface nsIAccessibleValue : nsISupports
{
readonly attribute double maximumValue;

View File

@ -10,7 +10,7 @@
* XBL controls can implement this interface to provide own implementation of
* accessible properties.
*/
[scriptable, uuid(3716eb86-166b-445b-a94a-9b522fee96e6)]
[scriptable, builtinclass, uuid(3716eb86-166b-445b-a94a-9b522fee96e6)]
interface nsIXBLAccessible : nsISupports
{
/**

2
aclocal.m4 vendored
View File

@ -16,7 +16,6 @@ builtin(include, build/autoconf/codeset.m4)dnl
builtin(include, build/autoconf/altoptions.m4)dnl
builtin(include, build/autoconf/mozprog.m4)dnl
builtin(include, build/autoconf/mozheader.m4)dnl
builtin(include, build/autoconf/mozcommonheader.m4)dnl
builtin(include, build/autoconf/lto.m4)dnl
builtin(include, build/autoconf/frameptr.m4)dnl
builtin(include, build/autoconf/compiler-opts.m4)dnl
@ -25,7 +24,6 @@ builtin(include, build/autoconf/arch.m4)dnl
builtin(include, build/autoconf/android.m4)dnl
builtin(include, build/autoconf/zlib.m4)dnl
builtin(include, build/autoconf/linux.m4)dnl
builtin(include, build/autoconf/winsdk.m4)dnl
builtin(include, build/autoconf/icu.m4)dnl
builtin(include, build/autoconf/ffi.m4)dnl
builtin(include, build/autoconf/clang-plugin.m4)dnl

View File

@ -20,7 +20,7 @@
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="1ec02eda4b375778b3611ebb7fb186faf5f75bb0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>

View File

@ -20,7 +20,7 @@
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="1ec02eda4b375778b3611ebb7fb186faf5f75bb0"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>

View File

@ -26,6 +26,16 @@ function onUnload(aEvent) {
function appUpdater()
{
XPCOMUtils.defineLazyServiceGetter(this, "aus",
"@mozilla.org/updates/update-service;1",
"nsIApplicationUpdateService");
XPCOMUtils.defineLazyServiceGetter(this, "checker",
"@mozilla.org/updates/update-checker;1",
"nsIUpdateChecker");
XPCOMUtils.defineLazyServiceGetter(this, "um",
"@mozilla.org/updates/update-manager;1",
"nsIUpdateManager");
this.updateDeck = document.getElementById("updateDeck");
// Hide the update deck when the update window is already open and it's not
@ -38,16 +48,6 @@ function appUpdater()
return;
}
XPCOMUtils.defineLazyServiceGetter(this, "aus",
"@mozilla.org/updates/update-service;1",
"nsIApplicationUpdateService");
XPCOMUtils.defineLazyServiceGetter(this, "checker",
"@mozilla.org/updates/update-checker;1",
"nsIUpdateChecker");
XPCOMUtils.defineLazyServiceGetter(this, "um",
"@mozilla.org/updates/update-manager;1",
"nsIUpdateManager");
this.bundle = Services.strings.
createBundle("chrome://browser/locale/browser.properties");

View File

@ -19,10 +19,6 @@ var gEMEHandler = {
Services.prefs.getPrefType("media.gmp-eme-adobe.enabled") &&
!Services.prefs.getBoolPref("media.gmp-eme-adobe.enabled")) {
Services.prefs.setBoolPref("media.gmp-eme-adobe.enabled", true);
} else if (keySystem == "org.w3.clearkey" &&
Services.prefs.getPrefType("media.eme.clearkey.enabled") &&
!Services.prefs.getBoolPref("media.eme.clearkey.enabled")) {
Services.prefs.setBoolPref("media.eme.clearkey.enabled", true);
} else if (keySystem == "com.widevine.alpha" &&
Services.prefs.getPrefType("media.gmp-widevinecdm.enabled") &&
!Services.prefs.getBoolPref("media.gmp-widevinecdm.enabled")) {

View File

@ -175,7 +175,6 @@ richlistitem.download button {
#downloadsPanel-multiView > .panel-viewcontainer,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack,
#downloadsPanel-multiView > .panel-viewcontainer > .panel-viewstack > .panel-mainview {
overflow: visible;
max-width: unset;
}

View File

@ -79,11 +79,24 @@ var gCookiesWindow = {
aCookieB.originAttributes);
},
_isPrivateCookie: function (aCookie) {
let { userContextId } = aCookie.originAttributes;
if (!userContextId) {
// Default identity is public.
return false;
}
return !ContextualIdentityService.getIdentityFromId(userContextId).public;
},
observe: function (aCookie, aTopic, aData) {
if (aTopic != "cookie-changed")
return;
if (aCookie instanceof Components.interfaces.nsICookie) {
if (this._isPrivateCookie(aCookie)) {
return;
}
var strippedHost = this._makeStrippedHost(aCookie.host);
if (aData == "changed")
this._handleCookieChanged(aCookie, strippedHost);
@ -490,6 +503,10 @@ var gCookiesWindow = {
while (e.hasMoreElements()) {
var cookie = e.getNext();
if (cookie && cookie instanceof Components.interfaces.nsICookie) {
if (this._isPrivateCookie(cookie)) {
continue;
}
var strippedHost = this._makeStrippedHost(cookie.host);
this._addCookie(strippedHost, cookie, hostCount);
}

View File

@ -397,9 +397,9 @@ PluginContent.prototype = {
if (eventType == "HiddenPlugin") {
let pluginTag = event.tag.QueryInterface(Ci.nsIPluginTag);
if (event.target.defaultView.top.document != this.content.document) {
return;
return;
}
this._showClickToPlayNotification(pluginTag, true);
this._showClickToPlayNotification(pluginTag, false);
}
let plugin = event.target;

View File

@ -22,7 +22,7 @@ AC_CHECK_FUNCS(strndup posix_memalign memalign)
AC_CHECK_FUNCS(malloc_usable_size)
MALLOC_USABLE_SIZE_CONST_PTR=const
MOZ_CHECK_HEADERS([malloc.h], [
if test -n "$HAVE_MALLOC_H"; then
AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
AC_TRY_COMPILE([#include <malloc.h>
#include <stddef.h>
@ -31,7 +31,7 @@ MOZ_CHECK_HEADERS([malloc.h], [
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
MALLOC_USABLE_SIZE_CONST_PTR=)
])
fi
AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])

View File

@ -11,59 +11,9 @@ MOZ_ARG_WITH_STRING(android-cxx-stl,
android_cxx_stl=$withval,
android_cxx_stl=libc++)
define([MIN_ANDROID_VERSION], [9])
android_version=MIN_ANDROID_VERSION
MOZ_ARG_WITH_STRING(android-version,
[ --with-android-version=VER
android platform version, default] MIN_ANDROID_VERSION,
android_version=$withval)
if test $android_version -lt MIN_ANDROID_VERSION ; then
AC_MSG_ERROR([--with-android-version must be at least MIN_ANDROID_VERSION.])
fi
case "$target" in
*-android*|*-linuxandroid*)
AC_MSG_CHECKING([for android platform directory])
case "$target_cpu" in
arm)
target_name=arm
;;
i?86)
target_name=x86
;;
mipsel)
target_name=mips
;;
esac
dnl Not all Android releases have their own platform release. We use
dnl the next lower platform version in these cases.
case $android_version in
11|10)
android_platform_version=9
;;
20)
android_platform_version=19
;;
22)
android_platform_version=21
;;
*)
android_platform_version=$android_version
;;
esac
android_platform="$android_ndk"/platforms/android-"$android_platform_version"/arch-"$target_name"
if test -d "$android_platform" ; then
AC_MSG_RESULT([$android_platform])
else
AC_MSG_ERROR([not found. Please check your NDK. With the current configuration, it should be in $android_platform])
fi
dnl $android_platform will be set for us by Python configure.
CPPFLAGS="-idirafter $android_platform/usr/include $CPPFLAGS"
CFLAGS="-fno-short-enums -fno-exceptions $CFLAGS"
CXXFLAGS="-fno-short-enums -fno-exceptions $CXXFLAGS"

View File

@ -1,9 +0,0 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
AC_DEFUN(MOZ_CHECK_COMMON_HEADERS,
MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h sys/bitypes.h \
memory.h unistd.h gnu/libc-version.h nl_types.h malloc.h \
X11/XKBlib.h io.h cpuid.h)
)

View File

@ -1,22 +0,0 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
dnl Identify which version of the SDK we're building with
dnl Windows Server 2008 and newer SDKs have WinSDKVer.h, get the version
dnl from there
AC_DEFUN([MOZ_FIND_WINSDK_VERSION], [
AC_CACHE_CHECK(for highest Windows version supported by this SDK,
ac_cv_winsdk_maxver,
[cat > conftest.h <<EOF
#include <winsdkver.h>
WINVER_MAXVER
EOF
ac_cv_winsdk_maxver=`$CPP conftest.h 2>/dev/null | tail -n1`
rm -f conftest.h
])
dnl WinSDKVer.h returns the version number in 4-digit format while many
dnl consumers expect 8. Therefore, pad the result with an extra 4 zeroes.
MOZ_WINSDK_MAXVER=${ac_cv_winsdk_maxver}0000
])

View File

@ -14,6 +14,35 @@ js_option('--with-android-toolchain', nargs=1,
js_option('--with-android-gnu-compiler-version', nargs=1,
help='GNU compiler version to use')
@depends('--help')
def min_android_version(_):
return '9'
js_option('--with-android-version',
nargs=1,
help='android platform version',
default=min_android_version)
@depends('--with-android-version', min_android_version)
@imports(_from='__builtin__', _import='ValueError')
def android_version(value, min_version):
if not value:
# Someone has passed --without-android-version.
die('--with-android-version cannot be disabled.')
try:
version = int(value[0])
except ValueError:
die('--with-android-version expects an integer value')
if version < int(min_version):
die('--with-android-version must be at least %s (got %s)',
min_version, value[0])
return version
add_old_configure_assignment('android_version', android_version)
@depends('--with-android-ndk', build_project)
def ndk(value, build_project):
if build_project == 'mobile/android' and not value:
@ -25,6 +54,46 @@ def ndk(value, build_project):
set_config('ANDROID_NDK', ndk)
add_old_configure_assignment('android_ndk', ndk)
@depends(target, android_version, ndk)
@checking('for android platform directory')
def android_platform(target, android_version, ndk):
if target.os != 'Android':
return
if 'mips' in target.cpu:
target_dir_name = 'mips'
else:
target_dir_name = target.cpu
# Not all Android releases have their own platform release. We use
# the next lower platform version in these cases.
if android_version in (11, 10):
platform_version = 9
elif android_version in (20, 22):
platform_version = android_version - 1
else:
platform_version = android_version
platform_dir = os.path.join(ndk,
'platforms',
'android-%s' % platform_version,
'arch-%s' % target_dir_name)
if not os.path.isdir(platform_dir):
die("Android platform directory not found. With the current "
"configuration, it should be in %s" % platform_dir)
return platform_dir
add_old_configure_assignment('android_platform', android_platform)
@depends(android_platform)
def extra_toolchain_flags(platform_dir):
if not platform_dir:
return []
return ['-idirafter',
os.path.join(platform_dir, 'usr', 'include')]
@depends(target, host, ndk, '--with-android-toolchain',
'--with-android-gnu-compiler-version')
@checking('for the Android toolchain directory', lambda x: x or 'not found')

View File

@ -0,0 +1,110 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
# Generates a test program and attempts to compile it. In case of failure, the
# resulting check will return None. If the test program succeeds, it will return
# the output of the test program.
# - `includes` are the includes (as file names) that will appear at the top of
# the generated test program.
# - `body` is the code that will appear in the main function of the generated
# test program. `return 0;` is appended to the function body automatically.
# - `language` is the language selection, so that the appropriate compiler is
# used.
# - `flags` are the flags to be passed to the compiler, in addition to `-c`.
# - `check_msg` is the message to be printed to accompany compiling the test
# program.
@template
@imports('textwrap')
def try_compile(includes=None, body='', language='C++', flags=None, check_msg=None):
includes = includes or []
source_lines = ['#include <%s>' % f for f in includes]
source = '\n'.join(source_lines) + '\n'
source += textwrap.dedent('''\
int
main(void)
{
%s
;
return 0;
}
''' % body)
if check_msg:
def checking_fn(fn):
return checking(check_msg, callback=lambda r: r is not None)(fn)
else:
def checking_fn(fn):
return fn
def get_flags():
if flags:
return flags[:]
@depends(cxx_compiler, c_compiler, extra_toolchain_flags)
@checking_fn
def check(cxx_info, c_info, extra_flags):
flags = get_flags() or []
flags += extra_flags
flags.append('-c')
info = {
'C': c_info,
'C++': cxx_info,
}[language]
return try_invoke_compiler(info.wrapper + [info.compiler] + info.flags,
language, source, flags,
onerror=lambda: None)
return check
# Checks for the presence of the given header on the target system by compiling
# a test program including that header. The return value of the template is a
# check function returning True if the header is present, and None if it is not.
# The value of this check function is also used to set a variable (with set_define)
# corresponding to the checked header. For instance, HAVE_MALLOC_H will be set in
# defines if check_header if called with 'malloc.h' as input and malloc.h is
# present on the target.
# - `header` is the header, as a file name, to check for.
# - `language` is the language selection, so that the appropriate compiler is
# used.
# - `flags` are the flags to be passed to the compiler, in addition to `-c`.
# - `includes` are additional includes, as file names, to appear before the
# header checked for.
# - `when` is a depends function that if present will make performing the check
# conditional on the value of that function.
@template
def check_header(header, language='C++', flags=None, includes=None, when=None):
when = when or depends('--help')(lambda _: True)
if includes:
includes = includes[:]
else:
includes = []
includes.append(header)
@depends_when(try_compile(includes=includes, language=language, flags=flags,
check_msg='for %s' % header), when=when)
def have_header(value):
if value is not None:
return True
header_var = 'HAVE_%s' % (header.upper()
.replace('-', '_')
.replace('/', '_')
.replace('.', '_'))
set_define(header_var, have_header)
return have_header
# A convenience wrapper for check_header for checking multiple headers.
# returns an array of the resulting checks in order corresponding to the
# provided headers.
# - `headers` are the headers to be checked.
# - `kwargs` are keyword arguments passed verbatim to check_header.
@template
def check_headers(*headers, **kwargs):
checks = []
for header in headers:
checks.append(check_header(header, **kwargs))
return checks

View File

@ -0,0 +1,63 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
# Check for headers defining standard int types.
check_header('stdint.h')
have_inttypes = check_header('inttypes.h')
set_config('HAVE_INTTYPES_H', have_inttypes)
# Checks for headers relevant to non-windows systems.
non_msvc_compiler = depends(c_compiler)(lambda info: info.type != 'msvc')
building_linux = depends(target)(lambda target: target.kernel == 'Linux')
have_malloc = check_header('malloc.h')
add_old_configure_assignment('HAVE_MALLOC_H', have_malloc)
check_headers(
'sys/byteorder.h',
'getopt.h',
'unistd.h',
'nl_types.h',
'cpuid.h',
when=non_msvc_compiler,
)
# These are all the places some variant of statfs can be hiding.
check_headers(
'sys/statvfs.h',
'sys/statfs.h',
'sys/vfs.h',
'sys/mount.h',
when=non_msvc_compiler,
)
# Quota support
check_header('sys/quota.h',
when=non_msvc_compiler)
check_header('linux/quota.h',
includes=['sys/socket.h'],
when=building_linux)
# SCTP support - needs various network include headers
check_headers(
'linux/if_addr.h',
'linux/rtnetlink.h',
includes=['sys/socket.h'],
when=building_linux,
)
check_header('sys/queue.h',
when=non_msvc_compiler)
check_headers(
'sys/types.h',
'netinet/in.h',
'byteswap.h',
when=non_msvc_compiler,
)

View File

@ -272,7 +272,6 @@ def old_configure_options(*options):
'--with-android-max-sdk',
'--with-android-min-sdk',
'--with-android-sdk',
'--with-android-version',
'--with-app-basename',
'--with-app-name',
'--with-arch',
@ -322,7 +321,6 @@ def old_configure_options(*options):
'--with-thumb-interwork',
'--with-unify-dist',
'--with-user-appdir',
'--with-windows-version',
'--x-includes',
'--x-libraries',

View File

@ -55,17 +55,20 @@ set_config('HAVE_YASM', have_yasm)
# Until the YASM variable is not necessary in old-configure.
add_old_configure_assignment('YASM', have_yasm)
@depends('--help')
def extra_toolchain_flags(_):
# This value will be overriden for android builds, where
# extra flags are required to do basic checks.
return []
# Android NDK
# ==============================================================
@depends('--disable-compile-environment', build_project, gonkdir, '--help')
def android_ndk_include(compile_env, build_project, gonkdir, _):
if compile_env and (gonkdir or build_project in ('mobile/android', 'js')):
return 'android-ndk.configure'
include(android_ndk_include)
def compiling_android(compile_env, build_project, gonkdir, _):
return compile_env and (gonkdir or build_project in ('mobile/android', 'js'))
include_when('android-ndk.configure', when=compiling_android)
# MacOS deployment target version
# ==============================================================
@ -168,31 +171,8 @@ add_old_configure_assignment('TOOLCHAIN_PREFIX', toolchain_prefix)
# Compilers
# ==============================================================
@imports('os')
@imports('subprocess')
@imports(_from='mozbuild.configure.util', _import='LineIO')
@imports(_from='tempfile', _import='mkstemp')
def try_preprocess(compiler, language, source):
suffix = {
'C': '.c',
'C++': '.cpp',
}[language]
fd, path = mkstemp(prefix='conftest.', suffix=suffix)
try:
source = source.encode('ascii', 'replace')
log.debug('Creating `%s` with content:', path)
with LineIO(lambda l: log.debug('| %s', l)) as out:
out.write(source)
os.write(fd, source)
os.close(fd)
cmd = compiler + ['-E', path]
return check_cmd_output(*cmd)
finally:
os.remove(path)
return try_invoke_compiler(compiler, language, source, ['-E'])
@imports(_from='mozbuild.configure.constants', _import='CompilerType')
@imports(_from='mozbuild.configure.constants',
@ -400,6 +380,71 @@ def check_compiler(compiler, language, target):
)
@imports(_from='collections', _import='defaultdict')
@imports(_from='__builtin__', _import='sorted')
def get_vc_paths(base):
vc = defaultdict(lambda: defaultdict(dict))
subkey = r'Microsoft\VisualStudio\VC\*\*\*\Compiler'
for v, h, t, p in get_registry_values(base + '\\' + subkey):
vc[v][h][t] = p
if not vc:
return
version, data = sorted(vc.iteritems(), key=lambda x: Version(x[0]))[-1]
return data
@depends(host)
@imports('platform')
def vc_compiler_path(host):
if host.kernel != 'WINNT':
return
vc_host = {
'x86': 'x86',
'AMD64': 'x64',
}.get(platform.machine())
if vc_host is None:
return
vc_target = {
'x86': 'x86',
'x86_64': 'x64',
'arm': 'arm',
}.get(host.cpu)
if vc_target is None:
return
base_key = r'HKEY_LOCAL_MACHINE\SOFTWARE'
data = get_vc_paths(base_key)
if not data:
data = get_vc_paths(base_key + r'\Wow6432Node')
if not data:
return
path = data.get(vc_host, {}).get(vc_target)
if not path and vc_host == 'x64':
vc_host = 'x86'
path = data.get(vc_host, {}).get(vc_target)
if not path:
return
path = os.path.dirname(path)
if vc_host != vc_target:
other_path = data.get(vc_host, {}).get(vc_host)
if other_path:
return (path, os.path.dirname(other_path))
return (path,)
@depends(vc_compiler_path)
@imports('os')
def toolchain_search_path(vc_compiler_path):
if vc_compiler_path:
result = [os.environ.get('PATH')]
result.extend(vc_compiler_path)
# We're going to alter PATH for good in windows.configure, but we also
# need to do it for the valid_compiler() check below.
os.environ['PATH'] = os.pathsep.join(result)
return result
@template
def default_c_compilers(host_or_target):
'''Template defining the set of default C compilers for the host and
@ -541,7 +586,8 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
# result from check_prog as CC/CXX/HOST_CC/HOST_CXX and b) have to let
# old-configure AC_SUBST it (because it's autoconf doing it, not us)
compiler = check_prog('_%s' % var, what=what, progs=default_compilers,
input=delayed_getattr(provided_compiler, 'compiler'))
input=delayed_getattr(provided_compiler, 'compiler'),
paths=toolchain_search_path)
@depends(compiler, provided_compiler, compiler_wrapper, host_or_target)
@checking('whether %s can be used' % what, lambda x: bool(x))
@ -699,6 +745,8 @@ host_cxx_compiler = compiler('C++', host, c_compiler=host_c_compiler,
other_compiler=cxx_compiler,
other_c_compiler=c_compiler)
include('compilechecks.configure')
@depends(c_compiler)
def default_debug_flags(compiler_info):
# Debug info is ON by default.
@ -779,4 +827,5 @@ def libcxx_inline_visibility(c_compiler, target):
set_define('_LIBCPP_INLINE_VISIBILITY', libcxx_inline_visibility)
set_define('_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49', libcxx_inline_visibility)
include('windows.configure')
include('rust.configure')

View File

@ -85,6 +85,39 @@ def find_program(file, paths=None):
return None
@imports('os')
@imports('subprocess')
@imports(_from='mozbuild.configure.util', _import='LineIO')
@imports(_from='tempfile', _import='mkstemp')
def try_invoke_compiler(compiler, language, source, flags=None, onerror=None):
flags = flags or []
if not isinstance(flags, (list, tuple)):
die("Flags provided to try_compile must be a list of strings, "
"not %r", paths)
suffix = {
'C': '.c',
'C++': '.cpp',
}[language]
fd, path = mkstemp(prefix='conftest.', suffix=suffix)
try:
source = source.encode('ascii', 'replace')
log.debug('Creating `%s` with content:', path)
with LineIO(lambda l: log.debug('| %s', l)) as out:
out.write(source)
os.write(fd, source)
os.close(fd)
cmd = compiler + list(flags) + [path]
kwargs = {'onerror': onerror}
return check_cmd_output(*cmd, **kwargs)
finally:
os.remove(path)
def unique_list(l):
result = []
for i in l:
@ -92,6 +125,105 @@ def unique_list(l):
result.append(i)
return result
# Get values out of the Windows registry. This function can only be called on
# Windows.
# The `pattern` argument is a string starting with HKEY_ and giving the full
# "path" of the registry key to get the value for, with backslash separators.
# The string can contains wildcards ('*').
# The result of this functions is an enumerator yielding tuples for each
# match. Each of these tuples contains the key name matching wildcards
# followed by the value.
#
# Examples:
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
# r'Windows Kits\Installed Roots\KitsRoot*')
# yields e.g.:
# ('KitsRoot81', r'C:\Program Files (x86)\Windows Kits\8.1\')
# ('KitsRoot10', r'C:\Program Files (x86)\Windows Kits\10\')
#
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
# r'Windows Kits\Installed Roots\KitsRoot8.1')
# yields e.g.:
# (r'C:\Program Files (x86)\Windows Kits\8.1\',)
#
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
# r'Windows Kits\*\KitsRoot*')
# yields e.g.:
# ('Installed Roots', 'KitsRoot81',
# r'C:\Program Files (x86)\Windows Kits\8.1\')
# ('Installed Roots', 'KitsRoot10',
# r'C:\Program Files (x86)\Windows Kits\10\')
#
# get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
# r'VisualStudio\VC\*\x86\*\Compiler')
# yields e.g.:
# ('19.0', 'arm', r'C:\...\amd64_arm\cl.exe')
# ('19.0', 'x64', r'C:\...\amd64\cl.exe')
# ('19.0', 'x86', r'C:\...\amd64_x86\cl.exe')
@imports(_import='_winreg', _as='winreg')
@imports(_from='__builtin__', _import='WindowsError')
@imports(_from='fnmatch', _import='fnmatch')
def get_registry_values(pattern):
def enum_helper(func, key):
i = 0
while True:
try:
yield func(key, i)
except WindowsError:
break
i += 1
def get_keys(key, pattern):
try:
s = winreg.OpenKey(key, '\\'.join(pattern[:-1]))
except WindowsError:
return
for k in enum_helper(winreg.EnumKey, s):
if fnmatch(k, pattern[-1]):
try:
yield k, winreg.OpenKey(s, k)
except WindowsError:
pass
def get_values(key, pattern):
try:
s = winreg.OpenKey(key, '\\'.join(pattern[:-1]))
except WindowsError:
return
for k, v, t in enum_helper(winreg.EnumValue, s):
if fnmatch(k, pattern[-1]):
yield k, v
def split_pattern(pattern):
subpattern = []
for p in pattern:
subpattern.append(p)
if '*' in p:
yield subpattern
subpattern = []
if subpattern:
yield subpattern
pattern = pattern.split('\\')
assert pattern[0].startswith('HKEY_')
keys = [(getattr(winreg, pattern[0]),)]
pattern = list(split_pattern(pattern[1:]))
for i, p in enumerate(pattern):
next_keys = []
for base_key in keys:
matches = base_key[:-1]
base_key = base_key[-1]
if i == len(pattern) - 1:
want_name = '*' in p[-1]
for name, value in get_values(base_key, p):
yield matches + ((name, value) if want_name else (value,))
else:
for name, k in get_keys(base_key, p):
next_keys.append(matches + (name, k))
keys = next_keys
@imports(_from='mozbuild.configure.util', _import='Version', _as='_Version')
def Version(v):
'A version number that can be compared usefully.'
@ -181,3 +313,13 @@ def depends_when(*args, **kwargs):
return fn(*args)
return wrapper
return decorator
# Includes a file when the given condition evaluates to a truthy value.
@template
def include_when(filename, when):
# Assume, for now, our condition already depends on --help.
@depends(when, '--help')
def conditional_include(value, _):
if value:
return filename
include(conditional_include)

View File

@ -0,0 +1,195 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
option('--with-windows-version', nargs=1, default='603',
help='Windows SDK version to target. Win 8.1 (603) is currently'
'the minimum supported version.')
@depends(target)
def is_windows(target):
return target.kernel == 'WINNT'
@template
def depends_win(*args):
return depends_when(*args, when=is_windows)
@depends_win('--with-windows-version')
@imports(_from='__builtin__', _import='ValueError')
def valid_windows_version(value):
if not value:
die('Cannot build with --without-windows-version')
try:
version = int(value[0], 16)
if version in (0x603,):
return version
except ValueError:
pass
die('Invalid value for --with-windows-version (%s)', value[0])
option(env='WINDOWSSDKDIR', nargs=1,
help='Directory containing the Windows SDK')
@depends_win('WINDOWSSDKDIR', host)
def windows_sdk_dir(value, host):
if value:
return value
if host.kernel != 'WINNT':
return ()
return tuple(x[1] for x in get_registry_values(
r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots'
r'\KitsRoot*'))
@imports(_from='mozbuild.shellutil', _import='quote')
def valid_windows_sdk_dir_result(value):
if value:
return '0x%04x in %s' % (value.version, quote(value.path))
@depends_win(c_compiler, windows_sdk_dir, valid_windows_version,
'WINDOWSSDKDIR')
@checking('for Windows SDK', valid_windows_sdk_dir_result)
@imports(_from='__builtin__', _import='sorted')
@imports(_from='textwrap', _import='dedent')
def valid_windows_sdk_dir(compiler, windows_sdk_dir, target_version,
windows_sdk_dir_env):
if windows_sdk_dir_env:
windows_sdk_dir_env = windows_sdk_dir_env[0]
sdks = {}
for d in windows_sdk_dir:
um_dir = os.path.join(d, 'include', 'um')
shared_dir = os.path.join(d, 'include', 'shared')
if os.path.isdir(um_dir) and os.path.isdir(shared_dir):
check = dedent('''\
#include <winsdkver.h>
WINVER_MAXVER
''')
result = try_preprocess(compiler.wrapper + [compiler.compiler] +
compiler.flags +
['-I', um_dir, '-I', shared_dir], 'C',
check)
if result:
maxver = result.splitlines()[-1]
try:
maxver = int(maxver, 0)
except:
pass
else:
sdks[d] = maxver
continue
if d == windows_sdk_dir_env:
raise FatalCheckError(
'Error while checking the version of the SDK in '
'WINDOWSSDKDIR (%s). Please verify it contains a valid and '
'complete SDK installation.' % windows_sdk_dir_env)
valid_sdks = sorted(sdks, key=lambda x: sdks[x], reverse=True)
if valid_sdks:
biggest_version = sdks[valid_sdks[0]]
if not valid_sdks or biggest_version < target_version:
if windows_sdk_dir_env:
raise FatalCheckError(
'You are targeting Windows version 0x%04x, but your SDK only '
'supports up to version 0x%04x. Install and use an updated SDK, '
'or target a lower version using --with-windows-version. '
'Alternatively, try running the Windows SDK Configuration Tool '
'and selecting a newer SDK. See '
'https://developer.mozilla.org/En/Windows_SDK_versions for '
'details on fixing this.' % (target_version, biggest_version))
raise FatalCheckError(
'Cannot find a Windows SDK for version >= 0x%04x.' % target_version)
return namespace(
path=valid_sdks[0],
version=biggest_version,
)
add_old_configure_assignment(
'WINDOWSSDKDIR',
delayed_getattr(valid_windows_sdk_dir, 'path'))
add_old_configure_assignment(
'MOZ_WINSDK_MAXVER',
depends(valid_windows_sdk_dir)(
lambda x: '0x%04X0000' % x.version if x else None))
option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool')
@depends_win(valid_windows_sdk_dir)
@imports(_from='os', _import='environ')
@imports('platform')
def sdk_bin_path(valid_windows_sdk_dir):
if not valid_windows_sdk_dir:
return
vc_host = {
'x86': 'x86',
'AMD64': 'x64',
}.get(platform.machine())
result = [
environ['PATH'],
os.path.join(valid_windows_sdk_dir.path, 'bin', vc_host)
]
if vc_host == 'x64':
result.append(
os.path.join(valid_windows_sdk_dir.path, 'bin', 'x86'))
return result
# Normally, we'd use `MT` instead of `_MT`, but for now, we want MT to only contain
# mt.exe.
mt = check_prog('_MT', depends_win()(lambda: ('mt.exe',)), what='mt',
input='MT', paths=sdk_bin_path)
# Check that MT is not something unexpected like "magnetic tape manipulation
# utility".
@depends_win(mt)
@checking('whether MT is really Microsoft Manifest Tool', lambda x: bool(x))
@imports('re')
@imports('subprocess')
def valid_mt(path):
try:
out = subprocess.check_output([path]).splitlines()
out = '\n'.join(l for l in out
if 'Microsoft (R) Manifest Tool' in l)
if out:
m = re.search(r'(?<=[^!-~])[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+',
out)
if not m:
raise FatalCheckError(
'Unknown version of the Microsoft Manifest Tool')
return namespace(
path=path,
version=Version(m.group(0)),
)
except subprocess.CalledProcessError:
pass
raise FatalCheckError('%s is not Microsoft Manifest Tool')
set_config('MT', depends_if(valid_mt)(lambda x: os.path.basename(x.path)))
set_config('MSMANIFEST_TOOL', depends(valid_mt)(lambda x: bool(x)))
# Normally, we'd just have CC, etc. set to absolute paths, but the build system
# doesn't currently handle properly the case where the paths contain spaces.
# Additionally, there's the issue described in toolchain.configure, in
# valid_compiler().
@depends_win(sdk_bin_path)
@imports('os')
def alter_path(sdk_bin_path):
path = os.pathsep.join(sdk_bin_path)
os.environ['PATH'] = path
return path
set_config('PATH', alter_path)

View File

@ -206,16 +206,19 @@ def prepare(srcdir, objdir, shell, args):
# Msys likes to break environment variables and command line arguments,
# so read those from stdin, as they are passed from the configure script
# when necessary (on windows).
# However, for some reason, $PATH is not handled like other environment
# variables, and msys remangles it even when giving it is already a msys
# $PATH. Fortunately, the mangling/demangling is just find for $PATH, so
# we can just take the value from the environment. Msys will convert it
# back properly when calling subconfigure.
input = sys.stdin.read()
if input:
data = {a: b for [a, b] in eval(input)}
environ = {a: b for a, b in data['env']}
environ['PATH'] = os.environ['PATH']
# These environment variables as passed from old-configure may contain
# posix-style paths, which will not be meaningful to the js
# subconfigure, which runs as a native python process, so use their
# values from the environment. In the case of autoconf implemented
# subconfigures, Msys will re-convert them properly.
for var in ('HOME', 'TERM', 'PATH', 'TMPDIR', 'TMP',
'TEMP', 'INCLUDE'):
if var in environ and var in os.environ:
environ[var] = os.environ[var]
args = data['args']
else:
environ = os.environ

View File

@ -1,9 +1,10 @@
if [ -z "${VSPATH}" ]; then
TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2015u2"
VSWINPATH="$(cd ${TOOLTOOL_DIR} && pwd -W)/vs2015u2"
fi
export WINDOWSSDKDIR="${VSPATH}/SDK"
export WINDOWSSDKDIR="${VSWINPATH}/SDK"
export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC140.CRT"
export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x86"

View File

@ -1,9 +1,10 @@
if [ -z "${VSPATH}" ]; then
TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2015u2"
VSWINPATH="$(cd ${TOOLTOOL_DIR} && pwd -W)/vs2015u2"
fi
export WINDOWSSDKDIR="${VSPATH}/SDK"
export WINDOWSSDKDIR="${VSWINPATH}/SDK"
export WIN32_REDIST_DIR=${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT
export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64"

View File

@ -351,7 +351,7 @@ HTMLBreadcrumbs.prototype = {
this.outer.addEventListener("click", this, true);
this.outer.addEventListener("mouseover", this, true);
this.outer.addEventListener("mouseleave", this, true);
this.outer.addEventListener("mouseout", this, true);
this.outer.addEventListener("focus", this, true);
this.shortcuts = new KeyShortcuts({ window: this.chromeWin, target: this.outer });
@ -482,7 +482,7 @@ HTMLBreadcrumbs.prototype = {
this.handleClick(event);
} else if (event.type == "mouseover") {
this.handleMouseOver(event);
} else if (event.type == "mouseleave") {
} else if (event.type == "mouseout") {
this.handleMouseLeave(event);
} else if (event.type == "focus") {
this.handleFocus(event);
@ -533,10 +533,10 @@ HTMLBreadcrumbs.prototype = {
},
/**
* On mouse leave, make sure to unhighlight.
* On mouse out, make sure to unhighlight.
* @param {DOMEvent} event.
*/
handleMouseLeave: function (event) {
handleMouseOut: function (event) {
this.inspector.toolbox.highlighterUtils.unhighlight();
},
@ -593,7 +593,7 @@ HTMLBreadcrumbs.prototype = {
this.container.removeEventListener("click", this, true);
this.container.removeEventListener("mouseover", this, true);
this.container.removeEventListener("mouseleave", this, true);
this.container.removeEventListener("mouseout", this, true);
this.container.removeEventListener("focus", this, true);
this.shortcuts.destroy();

View File

@ -132,7 +132,7 @@ function MarkupView(inspector, frame, controllerWindow) {
this._onCopy = this._onCopy.bind(this);
this._onFocus = this._onFocus.bind(this);
this._onMouseMove = this._onMouseMove.bind(this);
this._onMouseLeave = this._onMouseLeave.bind(this);
this._onMouseOut = this._onMouseOut.bind(this);
this._onToolboxPickerHover = this._onToolboxPickerHover.bind(this);
this._onCollapseAttributesPrefChange =
this._onCollapseAttributesPrefChange.bind(this);
@ -144,7 +144,7 @@ function MarkupView(inspector, frame, controllerWindow) {
// Listening to various events.
this._elt.addEventListener("click", this._onMouseClick, false);
this._elt.addEventListener("mousemove", this._onMouseMove, false);
this._elt.addEventListener("mouseleave", this._onMouseLeave, false);
this._elt.addEventListener("mouseout", this._onMouseOut, false);
this._elt.addEventListener("blur", this._onBlur, true);
this.win.addEventListener("mouseup", this._onMouseUp);
this.win.addEventListener("copy", this._onCopy);
@ -401,7 +401,12 @@ MarkupView.prototype = {
this._hoveredNode = nodeFront;
},
_onMouseLeave: function () {
_onMouseOut: function (event) {
// Emulate mouseleave by skipping any relatedTarget inside the markup-view.
if (this._elt.contains(event.relatedTarget)) {
return;
}
if (this._autoScrollAnimationFrame) {
this.win.cancelAnimationFrame(this._autoScrollAnimationFrame);
}
@ -1741,7 +1746,7 @@ MarkupView.prototype = {
this._elt.removeEventListener("click", this._onMouseClick, false);
this._elt.removeEventListener("mousemove", this._onMouseMove, false);
this._elt.removeEventListener("mouseleave", this._onMouseLeave, false);
this._elt.removeEventListener("mouseout", this._onMouseOut, false);
this._elt.removeEventListener("blur", this._onBlur, true);
this.win.removeEventListener("mouseup", this._onMouseUp);
this.win.removeEventListener("copy", this._onCopy);

View File

@ -65,7 +65,7 @@ function HighlightersOverlay(view) {
this.highlighterUtils = this.view.inspector.toolbox.highlighterUtils;
this._onMouseMove = this._onMouseMove.bind(this);
this._onMouseLeave = this._onMouseLeave.bind(this);
this._onMouseOut = this._onMouseOut.bind(this);
this.highlighters = {};
@ -91,7 +91,8 @@ HighlightersOverlay.prototype = {
let el = this.view.element;
el.addEventListener("mousemove", this._onMouseMove, false);
el.addEventListener("mouseleave", this._onMouseLeave, false);
el.addEventListener("mouseout", this._onMouseOut, false);
el.ownerDocument.defaultView.addEventListener("mouseout", this._onMouseOut, false);
this._isStarted = true;
},
@ -109,7 +110,7 @@ HighlightersOverlay.prototype = {
let el = this.view.element;
el.removeEventListener("mousemove", this._onMouseMove, false);
el.removeEventListener("mouseleave", this._onMouseLeave, false);
el.removeEventListener("mouseout", this._onMouseOut, false);
this._isStarted = false;
},
@ -150,7 +151,14 @@ HighlightersOverlay.prototype = {
}
},
_onMouseLeave: function () {
_onMouseOut: function (event) {
// Only hide the highlighter if the mouse leaves the currently hovered node.
if (!this._lastHovered ||
(event && this._lastHovered.contains(event.relatedTarget))) {
return;
}
// Otherwise, hide the highlighter.
this._lastHovered = null;
this._hideCurrent();
},

View File

@ -60,7 +60,7 @@ add_task(function* () {
yield onHighlighterShown;
ok(HighlighterFront.isShown, "The highlighter is shown");
let onHighlighterHidden = hs.once("highlighter-hidden");
hs._onMouseLeave();
hs._onMouseOut();
yield onHighlighterHidden;
ok(!HighlighterFront.isShown, "The highlighter is hidden");

View File

@ -24,7 +24,7 @@ function TooltipToggle(tooltip) {
this.win = tooltip.doc.defaultView;
this._onMouseMove = this._onMouseMove.bind(this);
this._onMouseLeave = this._onMouseLeave.bind(this);
this._onMouseOut = this._onMouseOut.bind(this);
this._onTooltipMouseOver = this._onTooltipMouseOver.bind(this);
this._onTooltipMouseOut = this._onTooltipMouseOut.bind(this);
@ -84,7 +84,7 @@ TooltipToggle.prototype = {
this._interactive = interactive;
baseNode.addEventListener("mousemove", this._onMouseMove);
baseNode.addEventListener("mouseleave", this._onMouseLeave);
baseNode.addEventListener("mouseout", this._onMouseOut);
if (this._interactive) {
this.tooltip.container.addEventListener("mouseover", this._onTooltipMouseOver);
@ -105,7 +105,7 @@ TooltipToggle.prototype = {
}
this._baseNode.removeEventListener("mousemove", this._onMouseMove);
this._baseNode.removeEventListener("mouseleave", this._onMouseLeave);
this._baseNode.removeEventListener("mouseout", this._onMouseOut);
if (this._interactive) {
this.tooltip.container.removeEventListener("mouseover", this._onTooltipMouseOver);
@ -152,7 +152,12 @@ TooltipToggle.prototype = {
return null;
}),
_onMouseLeave: function () {
_onMouseOut: function (event) {
// Only hide the tooltip if the mouse leaves baseNode.
if (event && this._baseNode && !this._baseNode.contains(event.relatedTarget)) {
return;
}
this._lastHovered = null;
this.win.clearTimeout(this.toggleTimer);
this.toggleTimer = this.win.setTimeout(() => {

View File

@ -19,7 +19,6 @@ ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
aFunction.mFunc.mX2, aFunction.mFunc.mY2);
} else {
mSteps = aFunction.mSteps;
mStepSyntax = aFunction.mStepSyntax;
}
}
@ -141,9 +140,6 @@ ComputedTimingFunction::Compare(const ComputedTimingFunction& aRhs) const
if (mSteps != aRhs.mSteps) {
return int32_t(mSteps) - int32_t(aRhs.mSteps);
}
if (mStepSyntax != aRhs.mStepSyntax) {
return int32_t(mStepSyntax) - int32_t(aRhs.mStepSyntax);
}
}
return 0;
@ -162,8 +158,7 @@ ComputedTimingFunction::AppendToString(nsAString& aResult) const
break;
case nsTimingFunction::Type::StepStart:
case nsTimingFunction::Type::StepEnd:
nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, mStepSyntax,
aResult);
nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, aResult);
break;
default:
nsStyleUtil::AppendCubicBezierKeywordTimingFunction(mType, aResult);

View File

@ -31,14 +31,12 @@ public:
nsTimingFunction::Type GetType() const { return mType; }
bool HasSpline() const { return nsTimingFunction::IsSplineType(mType); }
uint32_t GetSteps() const { return mSteps; }
nsTimingFunction::StepSyntax GetStepSyntax() const { return mStepSyntax; }
bool operator==(const ComputedTimingFunction& aOther) const
{
return mType == aOther.mType &&
(HasSpline() ?
mTimingFunction == aOther.mTimingFunction :
(mSteps == aOther.mSteps &&
mStepSyntax == aOther.mStepSyntax));
mSteps == aOther.mSteps);
}
bool operator!=(const ComputedTimingFunction& aOther) const
{
@ -60,7 +58,6 @@ private:
nsTimingFunction::Type mType;
nsSMILKeySpline mTimingFunction;
uint32_t mSteps;
nsTimingFunction::StepSyntax mStepSyntax;
};
} // namespace mozilla

View File

@ -171,16 +171,12 @@ const kTimingFunctionValues = [
"ease-in",
"ease-out",
"ease-in-out",
"step-start",
"steps(1, start)",
"steps(2, start)",
"step-end",
"steps(1)",
"steps(1, end)",
"steps(2)",
"steps(2, end)",
"cubic-bezier(0, 0, 1, 1)",
"cubic-bezier(0, 0.25, 0.75, 1)",
"cubic-bezier(0, 0.25, 0.75, 1)"
];
test(function(t) {
@ -256,7 +252,7 @@ test(function(t) {
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "ease-in-out",
"value of 'easing' on ComputedKeyframe #1");
assert_equals(frames[2].easing, "step-end",
assert_equals(frames[2].easing, "steps(1)",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffectReadOnly.getKeyframes() returns frames with expected easing'
+ ' values, when the easing is specified on each keyframe');
@ -270,9 +266,9 @@ test(function(t) {
assert_equals(frames.length, 3, "number of frames");
assert_equals(frames[0].easing, "linear",
"value of 'easing' on ComputedKeyframe #0");
assert_equals(frames[1].easing, "step-start",
assert_equals(frames[1].easing, "steps(1, start)",
"value of 'easing' on ComputedKeyframe #1");
assert_equals(frames[2].easing, "step-start",
assert_equals(frames[2].easing, "steps(1, start)",
"value of 'easing' on ComputedKeyframe #2");
}, 'KeyframeEffectReadOnly.getKeyframes() returns frames with expected easing'
+ ' values, when the easing is specified on some keyframes');
@ -428,7 +424,7 @@ test(function(t) {
var expected = [
{ offset: 0, computedOffset: 0, easing: "linear",
color: "rgb(0, 0, 0)", marginTop: "8px" },
{ offset: 0.25, computedOffset: 0.25, easing: "step-end",
{ offset: 0.25, computedOffset: 0.25, easing: "steps(1)",
color: "rgb(0, 0, 255)" },
{ offset: 0.75, computedOffset: 0.75, easing: "ease-in",
marginTop: "12px" },
@ -474,7 +470,7 @@ test(function(t) {
assert_equals(frames.length, 3, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "step-end",
{ offset: 0, computedOffset: 0, easing: "steps(1)",
color: "rgb(0, 0, 0)", fontSize: "16px" },
{ offset: 0, computedOffset: 0, easing: "linear",
marginTop: "8px", paddingLeft: "2px" },
@ -496,16 +492,12 @@ test(function(t) {
div.style.animation = 'anim-no-merge-equiv-easing 100s';
var frames = getKeyframes(div);
assert_equals(frames.length, 5, "number of frames");
assert_equals(frames.length, 3, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "steps(1, end)",
marginTop: "0px" },
{ offset: 0, computedOffset: 0, easing: "step-end",
marginRight: "0px" },
{ offset: 0, computedOffset: 0, easing: "steps(1)",
marginBottom: "0px" },
{ offset: 0.5, computedOffset: 0.5, easing: "step-end",
marginTop: "0px", marginRight: "0px", marginBottom: "0px" },
{ offset: 0.5, computedOffset: 0.5, easing: "steps(1)",
marginTop: "10px", marginRight: "10px", marginBottom: "10px" },
{ offset: 1, computedOffset: 1, easing: "ease",
marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
@ -675,7 +667,6 @@ test(function(t) {
}
}, 'KeyframeEffectReadOnly.getKeyframes() returns expected values for ' +
'animations with CSS variables as keyframe values in a shorthand property');
done();
</script>
</body>

View File

@ -59,7 +59,7 @@ test(function(t) {
assert_equals(frames.length, 2, "number of frames");
var expected = [
{ offset: 0, computedOffset: 0, easing: "steps(2, end)", left: "0px" },
{ offset: 0, computedOffset: 0, easing: "steps(2)", left: "0px" },
{ offset: 1, computedOffset: 1, easing: "linear", left: "100px" },
];

View File

@ -86,15 +86,13 @@ GetErrorArgCount(const ErrNum aErrorNumber)
return GetErrorMessage(nullptr, aErrorNumber)->argCount;
}
bool
ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...)
void
binding_detail::ThrowErrorMessage(JSContext* aCx, const unsigned aErrorNumber, ...)
{
va_list ap;
va_start(ap, aErrorNumber);
JS_ReportErrorNumberVA(aCx, GetErrorMessage, nullptr,
static_cast<const unsigned>(aErrorNumber), ap);
JS_ReportErrorNumberVA(aCx, GetErrorMessage, nullptr, aErrorNumber, ap);
va_end(ap);
return false;
}
bool

View File

@ -67,8 +67,18 @@ uint16_t constexpr ErrorFormatNumArgs[] = {
uint16_t
GetErrorArgCount(const ErrNum aErrorNumber);
bool
ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
namespace binding_detail {
void ThrowErrorMessage(JSContext* aCx, const unsigned aErrorNumber, ...);
} // namespace binding_detail
template<typename... Ts>
inline bool
ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, Ts&&... aArgs)
{
binding_detail::ThrowErrorMessage(aCx, static_cast<const unsigned>(aErrorNumber),
mozilla::Forward<Ts>(aArgs)...);
return false;
}
struct StringArrayAppender
{

View File

@ -47,8 +47,8 @@ def generate(output, idlFilename, preprocessorHeader):
# to have properties for:
#
# 1) Each supported CSS property name, camelCased.
# 2) Each supported name that contains dashes but doesn't start with a
# dash, without any changes to the name.
# 2) Each supported name that contains or starts with dashes,
# without any changes to the name.
# 3) cssFloat
#
# Note that "float" will cause a property called "float" to exist due to (1)
@ -57,9 +57,9 @@ def generate(output, idlFilename, preprocessorHeader):
# In practice, cssFloat is the only case in which "name" doesn't contain
# "-" but also doesn't match "prop". So the above generatePropLine() call
# covered (3) and all of (1) except "float". If we now output attributes
# for all the cases where "name" doesn't match "prop" and "name" doesn't
# start with "-", that will cover "float" and (2).
if prop != name and name[0] != "-":
# for all the cases where "name" doesn't match "prop", that will cover
# "float" and (2).
if prop != name:
extendedAttrs.append('BinaryName="%s"' % prop)
# Throw in a '_' before the attribute name, because some of these
# property names collide with IDL reserved words.

View File

@ -30,6 +30,7 @@
#include "mozilla/EnumeratedArrayCycleCollection.h"
#include "mozilla/Preferences.h"
#include "mozilla/ProcessPriorityManager.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Services.h"
#include "mozilla/Telemetry.h"
#include "nsContentUtils.h"
@ -285,8 +286,10 @@ WebGLContext::DestroyResourcesAndContext()
mFakeBlack_2D_Array_0000 = nullptr;
mFakeBlack_2D_Array_0001 = nullptr;
if (mFakeVertexAttrib0BufferObject)
if (mFakeVertexAttrib0BufferObject) {
gl->fDeleteBuffers(1, &mFakeVertexAttrib0BufferObject);
mFakeVertexAttrib0BufferObject = 0;
}
// disable all extensions except "WEBGL_lose_context". see bug #927969
// spec: http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
@ -306,7 +309,9 @@ WebGLContext::DestroyResourcesAndContext()
printf_stderr("--- WebGL context destroyed: %p\n", gl.get());
}
gl = nullptr;
MOZ_ASSERT(gl);
mGL_OnlyClearInDestroyResourcesAndContext = nullptr;
MOZ_ASSERT(!gl);
}
void
@ -669,22 +674,27 @@ WebGLContext::CreateAndInitGLWith(FnCreateGL_T fnCreateGL,
PopulateCapFallbackQueue(baseCaps, &fallbackCaps);
MOZ_RELEASE_ASSERT(!gl, "GFX: Already have a context.");
gl = nullptr;
RefPtr<gl::GLContext> potentialGL;
while (!fallbackCaps.empty()) {
const gl::SurfaceCaps& caps = fallbackCaps.front();
gl = fnCreateGL(caps, flags, this, out_failReasons);
if (gl)
potentialGL = fnCreateGL(caps, flags, this, out_failReasons);
if (potentialGL)
break;
fallbackCaps.pop();
}
if (!gl)
if (!potentialGL)
return false;
FailureReason reason;
mGL_OnlyClearInDestroyResourcesAndContext = potentialGL;
MOZ_RELEASE_ASSERT(gl);
if (!InitAndValidateGL(&reason)) {
DestroyResourcesAndContext();
MOZ_RELEASE_ASSERT(!gl);
// The fail reason here should be specific enough for now.
gl = nullptr;
out_failReasons->push_back(reason);
return false;
}
@ -844,6 +854,10 @@ NS_IMETHODIMP
WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
{
if (signedWidth < 0 || signedHeight < 0) {
if (!gl) {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_SIZE"));
}
GenerateWarning("Canvas size is too large (seems like a negative value wrapped)");
return NS_ERROR_OUT_OF_MEMORY;
}
@ -899,6 +913,12 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
return NS_OK;
}
nsCString failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_UNKOWN");
auto autoTelemetry = mozilla::MakeScopeExit([&] {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
failureId);
});
// End of early return cases.
// At this point we know that we're not just resizing an existing context,
// we are initializing a new context.
@ -920,8 +940,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
// resource handles created from older context generations.
if (!(mGeneration + 1).isValid()) {
// exit without changing the value of mGeneration
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_TOO_MANY"));
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_TOO_MANY");
const nsLiteralCString text("Too many WebGL contexts created this run.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@ -938,8 +957,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
disabled |= gfxPlatform::InSafeMode();
if (disabled) {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DISABLED"));
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DISABLED");
const nsLiteralCString text("WebGL is currently disabled.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@ -952,8 +970,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (mOptions.failIfMajorPerformanceCaveat) {
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
if (!HasAcceleratedLayers(gfxInfo)) {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_CAVEAT"));
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_CAVEAT");
const nsLiteralCString text("failIfMajorPerformanceCaveat: Compositor is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
@ -975,6 +992,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
text.AppendASCII("\n* ");
text.Append(cur.info);
}
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_REASON");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
}
@ -983,10 +1001,10 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (mOptions.failIfMajorPerformanceCaveat) {
if (gl->IsWARP()) {
gl = nullptr;
DestroyResourcesAndContext();
MOZ_ASSERT(!gl);
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
NS_LITERAL_CSTRING("FEATURE_FAILURE_PERF_WARP"));
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_WARP");
const nsLiteralCString text("failIfMajorPerformanceCaveat: Driver is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
@ -997,8 +1015,10 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (gl->GetContextType() == gl::GLContextType::WGL &&
!gl::sWGLLib.HasDXInterop2())
{
gl = nullptr;
DestroyResourcesAndContext();
MOZ_ASSERT(!gl);
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DXGL_INTEROP2");
const nsLiteralCString text("Caveat: WGL without DXGLInterop2.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@ -1007,8 +1027,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
}
if (!ResizeBackbuffer(width, height)) {
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_RESIZE"));
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER");
const nsLiteralCString text("Initializing WebGL backbuffer failed.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@ -1093,8 +1112,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
reporter.SetSuccessful();
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
NS_LITERAL_CSTRING("SUCCESS"));
failureId = NS_LITERAL_CSTRING("SUCCESS");
return NS_OK;
}

View File

@ -1393,11 +1393,15 @@ protected:
////////////////////////////////////
class FakeBlackTexture {
public:
static UniquePtr<FakeBlackTexture> Create(gl::GLContext* gl,
TexTarget target,
FakeBlackType type);
gl::GLContext* const mGL;
const GLuint mGLName;
FakeBlackTexture(gl::GLContext* gl, TexTarget target, FakeBlackType type);
~FakeBlackTexture();
protected:
explicit FakeBlackTexture(gl::GLContext* gl);
};
UniquePtr<FakeBlackTexture> mFakeBlack_2D_0000;
@ -1409,7 +1413,7 @@ protected:
UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0000;
UniquePtr<FakeBlackTexture> mFakeBlack_2D_Array_0001;
void BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack);
bool BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack);
////////////////////////////////////

View File

@ -136,7 +136,13 @@ ScopedResolveTexturesForDraw::ScopedResolveTexturesForDraw(WebGLContext* webgl,
if (fakeBlack == FakeBlackType::None)
continue;
mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack);
if (!mWebGL->BindFakeBlack(texUnit, tex->Target(), fakeBlack)) {
mWebGL->ErrorOutOfMemory("%s: Failed to create fake black texture.",
funcName);
*out_error = true;
return;
}
mRebindRequests.push_back({texUnit, tex});
}
}
@ -159,7 +165,7 @@ ScopedResolveTexturesForDraw::~ScopedResolveTexturesForDraw()
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mWebGL->mActiveTexture);
}
void
bool
WebGLContext::BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fakeBlack)
{
MOZ_ASSERT(fakeBlack == FakeBlackType::RGBA0000 ||
@ -198,12 +204,16 @@ WebGLContext::BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fa
UniquePtr<FakeBlackTexture>& fakeBlackTex = *slot;
if (!fakeBlackTex) {
fakeBlackTex.reset(new FakeBlackTexture(gl, target, fakeBlack));
fakeBlackTex = FakeBlackTexture::Create(gl, target, fakeBlack);
if (!fakeBlackTex) {
return false;
}
}
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + texUnit);
gl->fBindTexture(target.get(), fakeBlackTex->mGLName);
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture);
return true;
}
////////////////////////////////////////
@ -873,10 +883,9 @@ CreateGLTexture(gl::GLContext* gl)
return ret;
}
WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget target,
FakeBlackType type)
: mGL(gl)
, mGLName(CreateGLTexture(gl))
UniquePtr<WebGLContext::FakeBlackTexture>
WebGLContext::FakeBlackTexture::Create(gl::GLContext* gl, TexTarget target,
FakeBlackType type)
{
GLenum texFormat;
switch (type) {
@ -892,10 +901,11 @@ WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget ta
MOZ_CRASH("GFX: bad type");
}
gl::ScopedBindTexture scopedBind(mGL, mGLName, target.get());
UniquePtr<FakeBlackTexture> result(new FakeBlackTexture(gl));
gl::ScopedBindTexture scopedBind(gl, result->mGLName, target.get());
mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
mGL->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
// We allocate our zeros on the heap, and we overallocate (16 bytes instead of 4) to
// minimize the risk of running into a driver bug in texImage2D, as it is a bit
@ -906,54 +916,31 @@ WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget ta
UniqueBuffer zeros = moz_xcalloc(1, 16); // Infallible allocation.
MOZ_ASSERT(gl->IsCurrent());
auto logANGLEError = [](GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, const GLvoid* userParam)
{
gfxCriticalNote << message;
};
if (gl->IsANGLE()) {
gl->fEnable(LOCAL_GL_DEBUG_OUTPUT);
gl->fDebugMessageCallback(logANGLEError, nullptr);
gl->fDebugMessageControl(LOCAL_GL_DONT_CARE,
LOCAL_GL_DONT_CARE,
LOCAL_GL_DONT_CARE,
0, nullptr,
true);
}
if (target == LOCAL_GL_TEXTURE_CUBE_MAP) {
for (int i = 0; i < 6; ++i) {
const TexImageTarget curTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
const GLenum error = DoTexImage(mGL, curTarget.get(), 0, &dui, 1, 1, 1,
const GLenum error = DoTexImage(gl, curTarget.get(), 0, &dui, 1, 1, 1,
zeros.get());
if (error) {
const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
"for `curTarget`: 0x%04x, "
"`dui`: {0x%04x, 0x%04x, 0x%04x}.",
error, curTarget.get(), dui.internalFormat,
dui.unpackFormat, dui.unpackType);
gfxCriticalError() << text.BeginReading();
MOZ_CRASH("GFX: Unexpected error during cube map FakeBlack creation.");
return nullptr;
}
}
} else {
const GLenum error = DoTexImage(mGL, target.get(), 0, &dui, 1, 1, 1,
const GLenum error = DoTexImage(gl, target.get(), 0, &dui, 1, 1, 1,
zeros.get());
if (error) {
const nsPrintfCString text("DoTexImage failed with `error`: 0x%04x, "
"for `target`: 0x%04x, "
"`dui`: {0x%04x, 0x%04x, 0x%04x}.",
error, target.get(), dui.internalFormat,
dui.unpackFormat, dui.unpackType);
gfxCriticalError() << text.BeginReading();
MOZ_CRASH("GFX: Unexpected error during FakeBlack creation.");
return nullptr;
}
}
if (gl->IsANGLE()) {
gl->fDisable(LOCAL_GL_DEBUG_OUTPUT);
}
return result;
}
WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl)
: mGL(gl)
, mGLName(CreateGLTexture(gl))
{
}
WebGLContext::FakeBlackTexture::~FakeBlackTexture()

View File

@ -12,8 +12,9 @@
namespace mozilla {
WebGLContextUnchecked::WebGLContextUnchecked(gl::GLContext* gl)
: gl(gl)
WebGLContextUnchecked::WebGLContextUnchecked(gl::GLContext* _gl)
: mGL_OnlyClearInDestroyResourcesAndContext(_gl)
, gl(mGL_OnlyClearInDestroyResourcesAndContext) // const reference
{ }

View File

@ -39,8 +39,14 @@ public:
void SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat param);
void SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const GLfloat* param);
protected: // data
RefPtr<gl::GLContext> gl;
protected:
// We've had issues in the past with nulling `gl` without actually releasing
// all of our resources. This construction ensures that we are aware that we
// should only null `gl` in DestroyResourcesAndContext.
RefPtr<gl::GLContext> mGL_OnlyClearInDestroyResourcesAndContext;
public:
// Grab a const reference so we can see changes, but can't make changes.
const decltype(mGL_OnlyClearInDestroyResourcesAndContext)& gl;
};
} // namespace mozilla

View File

@ -740,7 +740,7 @@ TextTrackManager::TimeMarchesOn()
for (uint32_t i = 0; i < affectedTracks.Length(); ++i) {
TextTrack* ttrack = affectedTracks[i];
if (ttrack) {
ttrack->DispatchTrustedEvent(NS_LITERAL_STRING("cuechange"));
ttrack->DispatchAsyncTrustedEvent(NS_LITERAL_STRING("cuechange"));
HTMLTrackElement* trackElement = ttrack->GetTrackElement();
if (trackElement) {
trackElement->DispatchTrackRunnable(NS_LITERAL_STRING("cuechange"));

View File

@ -318,5 +318,16 @@ TextTrack::GetLanguage(nsAString& aLanguage) const
}
}
void
TextTrack::DispatchAsyncTrustedEvent(const nsString& aEventName)
{
RefPtr<TextTrack> self = this;
NS_DispatchToMainThread(
NS_NewRunnableFunction([self, aEventName]() {
self->DispatchTrustedEvent(aEventName);
})
);
}
} // namespace dom
} // namespace mozilla

View File

@ -116,6 +116,8 @@ public:
void NotifyCueUpdated(TextTrackCue *aCue);
void DispatchAsyncTrustedEvent(const nsString& aEventName);
private:
~TextTrack();

View File

@ -53,6 +53,7 @@ CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId)
continue;
}
if (keys[i].mStatus == kGMPUsable ||
keys[i].mStatus == kGMPOutputRestricted ||
keys[i].mStatus == kGMPOutputDownscaled) {
return true;
}

View File

@ -148,4 +148,10 @@ KeySystemToGMPName(const nsAString& aKeySystem)
return EmptyString();
}
bool
IsClearkeyKeySystem(const nsAString& aKeySystem)
{
return aKeySystem.EqualsLiteral("org.w3.clearkey");
}
} // namespace mozilla

View File

@ -102,6 +102,9 @@ GetArrayBufferViewOrArrayBufferData(const dom::ArrayBufferViewOrArrayBuffer& aBu
nsString
KeySystemToGMPName(const nsAString& aKeySystem);
bool
IsClearkeyKeySystem(const nsAString& aKeySystem);
} // namespace mozilla
#endif // EME_LOG_H_

View File

@ -268,7 +268,7 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
nsACString& aOutMessage,
nsACString& aOutCdmVersion)
{
MOZ_ASSERT(MediaPrefs::EMEEnabled());
MOZ_ASSERT(MediaPrefs::EMEEnabled() || IsClearkeyKeySystem(aKeySystem));
nsCOMPtr<mozIGeckoMediaPluginService> mps =
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
if (NS_WARN_IF(!mps)) {
@ -277,10 +277,6 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
}
if (aKeySystem.EqualsLiteral("org.w3.clearkey")) {
if (!Preferences::GetBool("media.eme.clearkey.enabled", true)) {
aOutMessage = NS_LITERAL_CSTRING("ClearKey was disabled");
return MediaKeySystemStatus::Cdm_disabled;
}
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, aOutMessage, aOutCdmVersion);
}

View File

@ -112,8 +112,10 @@ MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
return;
}
if (!MediaPrefs::EMEEnabled()) {
if (!MediaPrefs::EMEEnabled() && !IsClearkeyKeySystem(aKeySystem)) {
// EME disabled by user, send notification to chrome so UI can inform user.
// Clearkey is allowed even when EME is disabled because we want the pref
// "media.eme.enabled" only taking effect on proprietary DRMs.
MediaKeySystemAccess::NotifyObservers(mWindow,
aKeySystem,
MediaKeySystemStatus::Api_disabled);

View File

@ -8,6 +8,7 @@
#include "mp4_demuxer/AnnexB.h"
#include "WidevineUtils.h"
#include "WidevineVideoFrame.h"
#include "mozilla/Move.h"
using namespace cdm;
@ -19,6 +20,9 @@ WidevineVideoDecoder::WidevineVideoDecoder(GMPVideoHost* aVideoHost,
, mCDMWrapper(Move(aCDMWrapper))
, mExtraData(new MediaByteBuffer())
, mSentInput(false)
, mReturnOutputCallDepth(0)
, mDrainPending(false)
, mResetInProgress(false)
{
// Expect to start with a CDM wrapper, will release it in DecodingComplete().
MOZ_ASSERT(mCDMWrapper);
@ -82,6 +86,8 @@ WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame,
uint32_t aCodecSpecificInfoLength,
int64_t aRenderTimeMs)
{
// We should not be given new input if a drain has been initiated
MOZ_ASSERT(!mDrainPending);
// We may not get the same out of the CDM decoder as we put in, and there
// may be some latency, i.e. we may need to input (say) 30 frames before
// we receive output. So we need to store the durations of the frames input,
@ -124,74 +130,175 @@ WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame,
mCallback->Error(GMPDecodeErr);
return;
}
mCallback->InputDataExhausted();
// A reset should only be started at most at level mReturnOutputCallDepth 1,
// and if it's started it should be finished by that call by the time
// the it returns, so it should always be false by this point.
MOZ_ASSERT(!mResetInProgress);
// Only request more data if we don't have pending samples.
if (mFrameAllocationQueue.empty()) {
MOZ_ASSERT(mCDMWrapper);
mCallback->InputDataExhausted();
}
} else if (rv == kNeedMoreData) {
MOZ_ASSERT(mCDMWrapper);
mCallback->InputDataExhausted();
} else {
mCallback->Error(ToGMPErr(rv));
}
// Finish a drain if pending and we have no pending ReturnOutput calls on the stack.
if (mDrainPending && mReturnOutputCallDepth == 0) {
Drain();
}
}
// Util class to assist with counting mReturnOutputCallDepth.
class CounterHelper {
public:
// RAII, increment counter
explicit CounterHelper(int32_t& counter)
: mCounter(counter)
{
mCounter++;
}
// RAII, decrement counter
~CounterHelper()
{
mCounter--;
}
private:
int32_t& mCounter;
};
// Util class to make sure GMP frames are freed. Holds a GMPVideoi420Frame*
// and will destroy it when the helper is destroyed unless the held frame
// if forgotten with ForgetFrame.
class FrameDestroyerHelper {
public:
explicit FrameDestroyerHelper(GMPVideoi420Frame*& frame)
: frame(frame)
{
}
// RAII, destroy frame if held.
~FrameDestroyerHelper()
{
if (frame) {
frame->Destroy();
}
frame = nullptr;
}
// Forget the frame without destroying it.
void ForgetFrame()
{
frame = nullptr;
}
private:
GMPVideoi420Frame* frame;
};
// Special handing is needed around ReturnOutput as it spins the IPC message
// queue when creating an empty frame and can end up with reentrant calls into
// the class methods.
bool
WidevineVideoDecoder::ReturnOutput(WidevineVideoFrame& aCDMFrame)
{
GMPVideoFrame* f = nullptr;
auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f);
if (GMP_FAILED(err) || !f) {
Log("Failed to create i420 frame!\n");
return false;
MOZ_ASSERT(mReturnOutputCallDepth >= 0);
CounterHelper counterHelper(mReturnOutputCallDepth);
mFrameAllocationQueue.push_back(Move(aCDMFrame));
if (mReturnOutputCallDepth > 1) {
// In a reentrant call.
return true;
}
auto gmpFrame = static_cast<GMPVideoi420Frame*>(f);
Size size = aCDMFrame.Size();
const int32_t yStride = aCDMFrame.Stride(VideoFrame::kYPlane);
const int32_t uStride = aCDMFrame.Stride(VideoFrame::kUPlane);
const int32_t vStride = aCDMFrame.Stride(VideoFrame::kVPlane);
const int32_t halfHeight = size.height / 2;
err = gmpFrame->CreateEmptyFrame(size.width,
size.height,
yStride,
uStride,
vStride);
ENSURE_GMP_SUCCESS(err, false);
while (!mFrameAllocationQueue.empty()) {
MOZ_ASSERT(mReturnOutputCallDepth == 1);
// If we're at call level 1 a reset should not have been started. A
// reset may be received during CreateEmptyFrame below, but we should not
// be in a reset at this stage -- this would indicate receiving decode
// messages before completing our reset, which we should not.
MOZ_ASSERT(!mResetInProgress);
WidevineVideoFrame currentCDMFrame = Move(mFrameAllocationQueue.front());
mFrameAllocationQueue.pop_front();
GMPVideoFrame* f = nullptr;
auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f);
if (GMP_FAILED(err) || !f) {
Log("Failed to create i420 frame!\n");
return false;
}
auto gmpFrame = static_cast<GMPVideoi420Frame*>(f);
FrameDestroyerHelper frameDestroyerHelper(gmpFrame);
Size size = currentCDMFrame.Size();
const int32_t yStride = currentCDMFrame.Stride(VideoFrame::kYPlane);
const int32_t uStride = currentCDMFrame.Stride(VideoFrame::kUPlane);
const int32_t vStride = currentCDMFrame.Stride(VideoFrame::kVPlane);
const int32_t halfHeight = size.height / 2;
// This call can cause a shmem alloc, during this alloc other calls
// may be made to this class and placed on the stack. ***WARNING***:
// other IPC calls can happen during this call, resulting in calls
// being made to the CDM. After this call state can have changed,
// and should be reevaluated.
err = gmpFrame->CreateEmptyFrame(size.width,
size.height,
yStride,
uStride,
vStride);
// Assert possible reentrant calls or resets haven't altered level unexpectedly.
MOZ_ASSERT(mReturnOutputCallDepth == 1);
ENSURE_GMP_SUCCESS(err, false);
err = gmpFrame->SetWidth(size.width);
ENSURE_GMP_SUCCESS(err, false);
// If a reset started we need to dump the current frame and complete the reset.
if (mResetInProgress) {
MOZ_ASSERT(mCDMWrapper);
MOZ_ASSERT(mFrameAllocationQueue.empty());
CompleteReset();
return true;
}
err = gmpFrame->SetHeight(size.height);
ENSURE_GMP_SUCCESS(err, false);
err = gmpFrame->SetWidth(size.width);
ENSURE_GMP_SUCCESS(err, false);
Buffer* buffer = aCDMFrame.FrameBuffer();
uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane);
ENSURE_TRUE(outBuffer != nullptr, false);
MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height);
memcpy(outBuffer,
buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kYPlane),
yStride * size.height);
err = gmpFrame->SetHeight(size.height);
ENSURE_GMP_SUCCESS(err, false);
outBuffer = gmpFrame->Buffer(kGMPUPlane);
ENSURE_TRUE(outBuffer != nullptr, false);
MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight);
memcpy(outBuffer,
buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kUPlane),
uStride * halfHeight);
Buffer* buffer = currentCDMFrame.FrameBuffer();
uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane);
ENSURE_TRUE(outBuffer != nullptr, false);
MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height);
memcpy(outBuffer,
buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kYPlane),
yStride * size.height);
outBuffer = gmpFrame->Buffer(kGMPVPlane);
ENSURE_TRUE(outBuffer != nullptr, false);
MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight);
memcpy(outBuffer,
buffer->Data() + aCDMFrame.PlaneOffset(VideoFrame::kVPlane),
vStride * halfHeight);
outBuffer = gmpFrame->Buffer(kGMPUPlane);
ENSURE_TRUE(outBuffer != nullptr, false);
MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight);
memcpy(outBuffer,
buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kUPlane),
uStride * halfHeight);
gmpFrame->SetTimestamp(aCDMFrame.Timestamp());
outBuffer = gmpFrame->Buffer(kGMPVPlane);
ENSURE_TRUE(outBuffer != nullptr, false);
MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight);
memcpy(outBuffer,
buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kVPlane),
vStride * halfHeight);
auto d = mFrameDurations.find(aCDMFrame.Timestamp());
if (d != mFrameDurations.end()) {
gmpFrame->SetDuration(d->second);
mFrameDurations.erase(d);
gmpFrame->SetTimestamp(currentCDMFrame.Timestamp());
auto d = mFrameDurations.find(currentCDMFrame.Timestamp());
if (d != mFrameDurations.end()) {
gmpFrame->SetDuration(d->second);
mFrameDurations.erase(d);
}
// Forget frame so it's not deleted, call back taking ownership.
frameDestroyerHelper.ForgetFrame();
mCallback->Decoded(gmpFrame);
}
mCallback->Decoded(gmpFrame);
return true;
}
@ -199,18 +306,40 @@ void
WidevineVideoDecoder::Reset()
{
Log("WidevineVideoDecoder::Reset() mSentInput=%d", mSentInput);
// We shouldn't reset if a drain is pending.
MOZ_ASSERT(!mDrainPending);
mResetInProgress = true;
if (mSentInput) {
CDM()->ResetDecoder(kStreamTypeVideo);
}
// Remove queued frames, but do not reset mReturnOutputCallDepth, let the
// ReturnOutput calls unwind and decrement the counter as needed.
mFrameAllocationQueue.clear();
mFrameDurations.clear();
// Only if no ReturnOutput calls are in progress can we complete, otherwise
// ReturnOutput needs to finalize the reset.
if (mReturnOutputCallDepth == 0) {
CompleteReset();
}
}
void
WidevineVideoDecoder::CompleteReset()
{
mCallback->ResetComplete();
mSentInput = false;
mResetInProgress = false;
}
void
WidevineVideoDecoder::Drain()
{
Log("WidevineVideoDecoder::Drain()");
if (mReturnOutputCallDepth > 0) {
Log("Drain call is reentrant, postponing drain");
mDrainPending = true;
return;
}
Status rv = kSuccess;
while (rv == kSuccess) {
@ -227,8 +356,11 @@ WidevineVideoDecoder::Drain()
}
}
}
// Shouldn't be reset while draining.
MOZ_ASSERT(!mResetInProgress);
CDM()->ResetDecoder(kStreamTypeVideo);
mDrainPending = false;
mCallback->DrainComplete();
}

View File

@ -16,6 +16,7 @@
#include "WidevineDecryptor.h"
#include "WidevineVideoFrame.h"
#include <map>
#include <deque>
namespace mozilla {
@ -52,6 +53,7 @@ private:
}
bool ReturnOutput(WidevineVideoFrame& aFrame);
void CompleteReset();
GMPVideoHost* mVideoHost;
RefPtr<CDMWrapper> mCDMWrapper;
@ -60,6 +62,16 @@ private:
GMPVideoDecoderCallback* mCallback;
std::map<uint64_t, uint64_t> mFrameDurations;
bool mSentInput;
// Frames waiting on allocation
std::deque<WidevineVideoFrame> mFrameAllocationQueue;
// Number of calls of ReturnOutput currently in progress.
int32_t mReturnOutputCallDepth;
// If we're waiting to drain. Used to prevent drain completing while
// ReturnOutput calls are still on the stack.
bool mDrainPending;
// If a reset is being performed. Used to track if ReturnOutput should
// dump current frame.
bool mResetInProgress;
};
} // namespace mozilla

View File

@ -22,6 +22,19 @@ WidevineVideoFrame::WidevineVideoFrame()
memset(mPlaneStrides, 0, sizeof(mPlaneStrides));
}
WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&& aOther)
: mFormat(aOther.mFormat)
, mSize(aOther.mSize)
, mBuffer(aOther.mBuffer)
, mTimestamp(aOther.mTimestamp)
{
Log("WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&&) this=%p, other=%p",
this, &aOther);
memcpy(mPlaneOffsets, aOther.mPlaneOffsets, sizeof(mPlaneOffsets));
memcpy(mPlaneStrides, aOther.mPlaneStrides, sizeof(mPlaneStrides));
aOther.mBuffer = nullptr;
}
WidevineVideoFrame::~WidevineVideoFrame()
{
if (mBuffer) {

View File

@ -15,6 +15,7 @@ namespace mozilla {
class WidevineVideoFrame : public cdm::VideoFrame {
public:
WidevineVideoFrame();
WidevineVideoFrame(WidevineVideoFrame&& other);
~WidevineVideoFrame();
void SetFormat(cdm::VideoFormat aFormat) override;

View File

@ -29,6 +29,7 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/TaskQueue.h"
#include "MediaInfo.h"
@ -87,17 +88,31 @@ PDMFactory::~PDMFactory()
void
PDMFactory::EnsureInit() const
{
StaticMutexAutoLock mon(sMonitor);
if (!sInstance) {
sInstance = new PDMFactoryImpl();
{
StaticMutexAutoLock mon(sMonitor);
if (sInstance) {
// Quick exit if we already have an instance.
return;
}
if (NS_IsMainThread()) {
// On the main thread and holding the lock -> Create instance.
sInstance = new PDMFactoryImpl();
ClearOnShutdown(&sInstance);
} else {
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableFunction([]() { ClearOnShutdown(&sInstance); });
NS_DispatchToMainThread(runnable);
return;
}
}
// Not on the main thread -> Sync-dispatch creation to main thread.
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableFunction([]() {
StaticMutexAutoLock mon(sMonitor);
if (!sInstance) {
sInstance = new PDMFactoryImpl();
ClearOnShutdown(&sInstance);
}
});
SyncRunnable::DispatchToThread(mainThread, runnable);
}
already_AddRefed<MediaDataDecoder>

View File

@ -13,7 +13,6 @@
#include "mozIGeckoMediaPluginService.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/SyncRunnable.h"
#include "gmp-audio-decode.h"
#include "gmp-video-decode.h"
#ifdef XP_WIN
@ -169,13 +168,7 @@ GMPDecoderModule::UpdateUsableCodecs()
void
GMPDecoderModule::Init()
{
if (!NS_IsMainThread()) {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableFunction([]() { Init(); });
SyncRunnable::DispatchToThread(mainThread, runnable);
return;
}
MOZ_ASSERT(NS_IsMainThread());
// GMPService::HasPluginForAPI is main thread only, so to implement
// SupportsMimeType() we build a table of the codecs which each whitelisted
// GMP has and update it when any GMPs are removed or added at runtime.

View File

@ -10,6 +10,7 @@
#include "ImageContainer.h"
#include "gfxWindowsPlatform.h"
#include "D3D9SurfaceImage.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/Telemetry.h"
@ -632,7 +633,7 @@ D3D11DXVA2Manager::Init(nsACString& aFailureReason)
return E_FAIL;
}
mDevice = gfxWindowsPlatform::GetPlatform()->CreateD3D11DecoderDevice();
mDevice = gfx::DeviceManagerD3D11::Get()->CreateDecoderDevice();
if (!mDevice) {
aFailureReason.AssignLiteral("Failed to create D3D11 device for decoder");
return E_FAIL;

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <algorithm>
#include <winsdkver.h>
#include "WMFVideoMFTManager.h"
#include "MediaDecoderReader.h"
#include "MediaPrefs.h"
@ -37,7 +38,7 @@ using mozilla::layers::IMFYCbCrImage;
using mozilla::layers::LayerManager;
using mozilla::layers::LayersBackend;
#if MOZ_WINSDK_MAXVER < 0x0A000000
#if WINVER_MAXVER < 0x0A00
// Windows 10+ SDK has VP80 and VP90 defines
const GUID MFVideoFormat_VP80 =
{

View File

@ -62,27 +62,21 @@ function Test(test) {
var tests = [
{
keySystem: CLEARKEY_KEYSYSTEM,
shouldPass: false,
expectedStatus: 'api-disabled',
prefs: [["media.eme.enabled", false], ["media.eme.clearkey.enabled", true]]
shouldPass: true,
expectedStatus: 'cdm-created',
prefs: [["media.eme.enabled", false]]
},
{
keySystem: CLEARKEY_KEYSYSTEM,
shouldPass: false,
expectedStatus: 'cdm-disabled',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", false]]
},
{
keySystem: CLEARKEY_KEYSYSTEM + '.10000' , // A stupendously high min CDM version, presumably not installed.
keySystem: CLEARKEY_KEYSYSTEM + '.10000', // A stupendously high min CDM version, presumably not installed.
shouldPass: false,
expectedStatus: 'cdm-insufficient-version',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
prefs: [["media.eme.enabled", true]]
},
{
keySystem: CLEARKEY_KEYSYSTEM,
shouldPass: true,
expectedStatus: 'cdm-created',
prefs: [["media.eme.enabled", true], ["media.eme.clearkey.enabled", true]]
prefs: [["media.eme.enabled", true]]
},
];
@ -99,4 +93,3 @@ SimpleTest.waitForExplicitFinish();
</pre>
</body>
</html>

View File

@ -4,8 +4,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsDebug.h"
#include "D3D11SurfaceHolder.h"
#include "gfxWindowsPlatform.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#include "mozilla/layers/TextureD3D11.h"
#include <d3d11.h>
@ -18,7 +18,7 @@ using namespace mozilla::layers;
D3D11SurfaceHolder::D3D11SurfaceHolder(ID3D11Texture2D* back,
SurfaceFormat format,
const IntSize& size)
: mDevice11(gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice()),
: mDevice11(DeviceManagerD3D11::Get()->GetContentDevice()),
mBack(back),
mFormat(format),
mSize(size)
@ -33,7 +33,7 @@ bool
D3D11SurfaceHolder::IsValid()
{
// If a TDR occurred, platform devices will be recreated.
if (gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice() != mDevice11) {
if (DeviceManagerD3D11::Get()->GetContentDevice() != mDevice11) {
return false;
}
return true;

View File

@ -45,6 +45,7 @@
#include "mozilla/layers/ImageBridgeChild.h"
#if defined(XP_WIN)
# include "mozilla/layers/D3D11ShareHandleImage.h"
# include "mozilla/gfx/DeviceManagerD3D11.h"
# include "mozilla/layers/TextureD3D11.h"
#endif
@ -400,7 +401,7 @@ PluginInstanceParent::AnswerNPN_GetValue_PreferredDXGIAdapter(DxgiAdapterDesc* a
return false;
}
ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
RefPtr<ID3D11Device> device = DeviceManagerD3D11::Get()->GetContentDevice();
if (!device) {
return false;
}
@ -681,7 +682,7 @@ PluginInstanceParent::RecvInitDXGISurface(const gfx::SurfaceFormat& format,
return true;
}
RefPtr<ID3D11Device> d3d11 = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
RefPtr<ID3D11Device> d3d11 = DeviceManagerD3D11::Get()->GetContentDevice();
if (!d3d11) {
return true;
}

View File

@ -195,7 +195,9 @@ nsXBLDocumentInfo::ReadPrototypeBindings(nsIURI* aURI, nsXBLDocumentInfo** aDocI
NS_ENSURE_SUCCESS(rv, rv);
StartupCache* startupCache = StartupCache::GetSingleton();
NS_ENSURE_TRUE(startupCache, NS_ERROR_FAILURE);
if (!startupCache) {
return NS_ERROR_FAILURE;
}
UniquePtr<char[]> buf;
uint32_t len;
@ -262,7 +264,9 @@ nsXBLDocumentInfo::WritePrototypeBindings()
NS_ENSURE_SUCCESS(rv, rv);
StartupCache* startupCache = StartupCache::GetSingleton();
NS_ENSURE_TRUE(startupCache, rv);
if (!startupCache) {
return rv;
}
nsCOMPtr<nsIObjectOutputStream> stream;
nsCOMPtr<nsIStorageStream> storageStream;

View File

@ -1,6 +1,6 @@
en_US-mozilla Hunspell Dictionary
Generated from SCOWL Version 2016.01.19
Thu Jan 21 14:36:28 EST 2016
Generated from SCOWL Version 2016.06.26
Tue Jul 26 12:40:24 EDT 2016
http://wordlist.sourceforge.net
@ -319,4 +319,4 @@ from the Ispell distribution they are under the Ispell copyright:
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Build Date: Thu Jan 21 14:36:28 EST 2016
Build Date: Tue Jul 26 12:40:24 EDT 2016

View File

@ -4957,7 +4957,6 @@ Vivie
Vivie's
Vivien
Vivien's
VoIP
Vodafone
Vodafone's
Von
@ -5313,7 +5312,6 @@ cultivar's
cyber
cytokine
cytokine's
cytokines
datasheet
datasheet's
datasheets
@ -5426,8 +5424,6 @@ greyest
greying
greyness's
greys
guestbook's
guestbooks
hentai
hexane's
hexanes
@ -5508,7 +5504,6 @@ misandrist
misandrist's
misandrists
misandry
miscommunications
misjudgement
misjudgement's
misjudgements
@ -5530,6 +5525,14 @@ namespace's
namespaces
nano
natively
naďve
naďvely
naďver
naďvest
naďvety
naďvety's
naďveté
naďveté's
neurophysiology's
neuroscience's
neurosciences
@ -5548,7 +5551,6 @@ parallelize
parallelized
parallelizes
parallelizing
parkour
permalink
permalink's
permalinks
@ -5565,7 +5567,6 @@ phosphorylate
phosphorylated
phosphorylates
phosphorylating
phosphorylation
plaintext
polynucleotide
polynucleotide's
@ -5666,7 +5667,6 @@ spelt
spick
spicks
spywares
stent's
substituent's
substituents
subsumptions
@ -5726,7 +5726,6 @@ undesignated
unironic
unironically
unlabelled
username's
validator
validators
vertebrata
@ -5745,7 +5744,6 @@ webdesigns
whitepaper
whitepaper's
whitepapers
widescreen's
wildcard's
wildcards
wop's

View File

@ -1,6 +1,6 @@
en_US-custom Hunspell Dictionary
Generated from SCOWL Version 2016.01.19
Thu Jan 21 14:36:27 EST 2016
Generated from SCOWL Version 2016.06.26
Tue Jul 26 12:40:23 EDT 2016
http://wordlist.sourceforge.net
@ -319,5 +319,5 @@ from the Ispell distribution they are under the Ispell copyright:
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Build Date: Thu Jan 21 14:36:27 EST 2016
Build Date: Tue Jul 26 12:40:23 EDT 2016
With Input Command: ../mk-list -v1 --accents=both en_US 60

View File

@ -1,4 +1,4 @@
49404
49464
0/nm
0th/pt
1/n1
@ -37,6 +37,7 @@ ACTH/M
AD/M
ADC
ADD
ADM
ADP/M
AF
AFAIK
@ -534,6 +535,7 @@ Apocrypha/M
Apollinaire/M
Apollo/SM
Apollonian/M
Apostle/M
Appalachia/M
Appalachian/SM
Appalachians/M
@ -717,6 +719,7 @@ Atlantic/M
Atlantis/M
Atlas/MS
Atman/M
Atonement
Atreus/M
Atria/M
Atropos/M
@ -1279,6 +1282,7 @@ Bolivian/MS
Bollywood/M
Bologna/M
Bolshevik/SM
Bolsheviki
Bolshevism/M
Bolshevist/M
Bolshoi/M
@ -2189,6 +2193,7 @@ Comanche/MS
Combs/M
Comdr
Comintern/M
Commandment
Commons/M
Commonwealth
Communion/SM
@ -2567,6 +2572,7 @@ Deandre/M
Deann/M
Deanna/M
Deanne/M
Death/M
Debbie/M
Debby/M
Debian/M
@ -3566,6 +3572,7 @@ GIF
GIGO
GM/M
GMAT
GMO
GMT/M
GNP/M
GNU/M
@ -4547,6 +4554,7 @@ IRA/SM
IRC
IRS/M
ISBN
ISIS
ISO/M
ISP
ISS
@ -5622,6 +5630,7 @@ Lhotse/M
Li/MY
Libby/M
Liberace/M
Liberal
Liberia/M
Liberian/SM
Libra/MS
@ -5938,6 +5947,7 @@ Macumba/M
Macy/M
Madagascan/SM
Madagascar/M
Madam
Madden/M
Maddox/M
Madeira/SM
@ -6438,6 +6448,7 @@ Messiaen/M
Messiah/M
Messiahs
Messianic
Messieurs
Metallica/M
Metamucil/M
Methodism/SM
@ -6647,6 +6658,7 @@ Monongahela/M
Monroe/M
Monrovia/M
Monsanto/M
Monsieur/M
Monsignor/SM
Mont/M
Montague/M
@ -6843,6 +6855,7 @@ NS
NSA/M
NSC
NSF
NSFW
NT
NV
NW/M
@ -7060,7 +7073,7 @@ Nita/M
Nivea/M
Nixon/M
Nkrumah/M
No/M
No/SM
NoDoz/M
Noah/M
Nobel/M
@ -7283,6 +7296,7 @@ OpenOffice/M
Ophelia/M
Ophiuchus/M
Oppenheimer/M
Opposition
Oprah/M
Ora/M
Oracle/M
@ -7299,6 +7313,7 @@ Oreo/M
Orestes/M
Orient/M
Oriental/MS
Orientalism
Orin/M
Orinoco/M
Orion/M
@ -7472,6 +7487,7 @@ Parisian/MS
Park/SMR
Parker/M
Parkinson/M
Parkinsonism
Parkman/M
Parks/M
Parliament/M
@ -8440,6 +8456,7 @@ SF
SGML/M
SIDS/M
SJ
SJW
SK
SLR
SO/S
@ -8791,6 +8808,7 @@ Seymour/M
Sgt
Shackleton/M
Shaffer/M
Shah/M
Shaka/M
Shaker
Shakespeare/M
@ -9886,6 +9904,7 @@ Uruguayan/MS
Urumqi/M
Usenet/MS
Ustinov/M
Ut
Utah/M
Utahan/MS
Ute/SM
@ -10075,6 +10094,7 @@ Vladimir/M
Vladivostok/M
Vlaminck/M
Vlasic/M
VoIP
Vogue/M
Volcker/M
Voldemort/M
@ -10537,6 +10557,7 @@ Zibo/M
Ziegfeld/M
Ziegler/M
Ziggy/M
Zika
Zimbabwe/M
Zimbabwean/SM
Zimmerman/M
@ -10976,6 +10997,7 @@ addressed/U
addressee/SM
adduce/GDS
adenine/M
adenocarcinoma
adenoid/SM
adenoidal
adept/MYPS
@ -11651,7 +11673,7 @@ amicable
amicably
amid
amide/MS
amidships
amidship/S
amidst
amigo/MS
amino
@ -12315,6 +12337,7 @@ areal
aren't
arena/MS
argent/M
arginine
argon/M
argosy/SM
argot/MS
@ -13217,6 +13240,7 @@ baptizer/M
bar's
bar/ECUTS
barb/SZGMDR
barbacoa
barbarian/SM
barbarianism/MS
barbaric
@ -15122,7 +15146,7 @@ burgle/DSG
burgomaster/SM
burgundy/SM
burial/ASM
burka/S
burka/SM
burl/MDS
burlap/M
burlesque/MGDS
@ -15138,7 +15162,7 @@ burnous/MS
burnout/MS
burnt
burp/MDGS
burqa/S
burqa/SM
burr/MDGS
burrito/MS
burro/SM
@ -16224,6 +16248,7 @@ chateau/SM
chateaux
chatelaine/SM
chatline/S
chatroom/M
chatted
chattel/MS
chatter/MDRZGS
@ -16669,6 +16694,7 @@ city/SM
citywide
civet/MS
civic/S
civically
civics/M
civil/UY
civilian/MS
@ -17965,6 +17991,7 @@ contraceptive/SM
contract/MDG
contractible
contractile
contractility
contraction/S
contractual/Y
contradict/SDG
@ -18367,7 +18394,9 @@ counterintelligence/M
counterman/M
countermand/GMDS
countermeasure/SM
countermelody/S
countermen
countermove/S
counteroffensive/SM
counteroffer/SM
counterpane/SM
@ -19030,7 +19059,7 @@ cw
cwt
cyan/M
cyanide/M
cyberbully/S
cyberbully/SM
cybercafe/S
cybercafé/S
cybernetic/S
@ -19066,6 +19095,7 @@ cypress/MS
cyst/MS
cystic
cystitis
cytokines
cytologist/SM
cytology/M
cytoplasm/M
@ -19973,7 +20003,7 @@ diaphragmatic
diarist/SM
diarrhea/M
diary/SM
diaspora
diaspora/SM
diastase/M
diastole/M
diastolic
@ -21347,7 +21377,7 @@ effete/YP
effeteness/M
efficacious/Y
efficacy/IM
efficiency/IM
efficiency/ISM
efficient/IY
effigy/SM
efflorescence/M
@ -21650,7 +21680,7 @@ emitted
emitter/MS
emitting
emo/SM
emoji
emoji/SM
emollient/MS
emolument/MS
emote/XDSGNV
@ -21782,7 +21812,7 @@ endogenous/Y
endometrial
endometriosis
endometrium
endorphin/M
endorphin/MS
endorse/LZGDRS
endorsement/MS
endorser/M
@ -23029,7 +23059,8 @@ fearsome
feasibility/M
feasible/IU
feasibly
feast/SMDG
feast/SMDRZG
feaster/M
feat/MS
feather/SGMD
featherbedding/M
@ -23615,9 +23646,6 @@ flint/SM
flintlock/SM
flinty/TR
flip/MS
flipflop/S
flipflopped
flipflopping
flippancy/M
flippant/Y
flipped
@ -24261,7 +24289,7 @@ frictional
fridge/SM
friedcake/MS
friend's
friend/US
friend/UGSDY
friendless
friendlies
friendliness/UM
@ -24335,7 +24363,7 @@ frostbite/MGS
frostbitten
frostily
frostiness/M
frosting/M
frosting/SM
frosty/TPR
froth/MDG
frothiness/M
@ -25710,7 +25738,7 @@ guesser/M
guesstimate/DSMG
guesswork/M
guest/SGMD
guestbook
guestbook/SM
guesthouse/S
guestroom/S
guff/M
@ -25875,7 +25903,7 @@ hackish
hackle/MS
hackney/SMDG
hacksaw/SM
hacktivist/S
hacktivist/MS
hackwork/M
had
haddock/SM
@ -26428,6 +26456,7 @@ hell/M
hellbent
hellcat/MS
hellebore/M
hellfire
hellhole/MS
hellion/MS
hellish/YP
@ -28048,7 +28077,6 @@ inedible
ineffability/M
ineffable
ineffably
inefficiency/S
inelastic
ineligible/MS
ineligibly
@ -28986,6 +29014,7 @@ jetted
jetting
jettison/MDSG
jetty/SM
jew
jewel/SZGMDR
jeweler/M
jewelry/SM
@ -29124,6 +29153,7 @@ joyrider/M
joyriding/M
joyrode
joystick/SM
jr
jubilant/Y
jubilation/M
jubilee/SM
@ -29522,7 +29552,8 @@ kuchen/SM
kudos/M
kudzu/SM
kumquat/MS
kvetch/GMDS
kvetch/ZGMDRS
kvetcher/M
kw
l/SDXTGJ
la/M
@ -29618,7 +29649,7 @@ lambkin/SM
lambskin/SM
lambswool
lame/MYZTGDRSP
lamebrain/MS
lamebrain/MDS
lameness/M
lament/BSMDG
lamentably
@ -30036,6 +30067,7 @@ letterpress/M
letting/S
lettuce/MS
letup/SM
leucine
leucotomy/S
leukemia/M
leukemic/SM
@ -30167,6 +30199,7 @@ lightproof
lightship/MS
lightweight/SM
ligneous
lignin
lignite/M
lii
likability/M
@ -30467,16 +30500,16 @@ logic/M
logical/Y
logicality/M
logician/MS
login/S
login/SM
logistic/S
logistical/Y
logistics/M
logjam/SM
logo/MS
logoff/S
logon/S
logoff/SM
logon/SM
logotype/SM
logout/S
logout/SM
logrolling/M
logy/RT
loin/MS
@ -30825,9 +30858,10 @@ madman/M
madmen
madness/M
madras/MS
madrasa/S
madrassah
madrassahs
madrasa/SM
madrasah/M
madrasahs
madrassa/SM
madrigal/SM
madwoman/M
madwomen
@ -31539,7 +31573,7 @@ member/EAS
membership/SM
membrane/SM
membranous
meme/S
meme/MS
memento/MS
memo/MS
memoir/MS
@ -31769,6 +31803,7 @@ mice
mick/S
mickey/MS
micro/SM
microaggression/SM
microbe/MS
microbial
microbiological
@ -31904,7 +31939,7 @@ milky/RTP
mill/MDRSZGJ
millage/M
millennia
millennial/MS
millennial/M
millennium/MS
miller/M
millet/M
@ -31983,7 +32018,7 @@ minim/SM
minimal/Y
minimalism/M
minimalist/MS
minimization
minimization/M
minimize/DSG
minimum/MS
mining/M
@ -32065,7 +32100,7 @@ mischievous/YP
mischievousness/M
miscibility/M
miscible
miscommunication
miscommunication/S
misconceive/GDS
misconception/SM
misconduct/MDGS
@ -32212,6 +32247,7 @@ mitochondrion
mitoses
mitosis/M
mitotic
mitral
mitt/MNSX
mitten/M
mix/ZGMDRSB
@ -32220,6 +32256,7 @@ mixer/M
mixture/SM
mizzen/MS
mizzenmast/SM
mkay
mks
ml
mm
@ -32241,7 +32278,7 @@ mobilize/CDSG
mobilizer/SM
mobster/SM
moccasin/SM
mocha/M
mocha/SM
mock/DRSZG
mocker/M
mockery/SM
@ -32644,6 +32681,7 @@ moussaka/S
mousse/MGDS
mousy/PTR
mouth/GMD
mouthfeel
mouthful/MS
mouthiness/M
mouthpiece/MS
@ -32746,6 +32784,7 @@ multifamily
multifarious/PY
multifariousness/M
multiform
multigrain
multilateral/Y
multilayered
multilevel
@ -32890,6 +32929,7 @@ mutterer/M
muttering/M
mutton/M
muttonchops/M
muttony
mutual/Y
mutuality/M
muumuu/MS
@ -33175,7 +33215,7 @@ neoclassical
neoclassicism/M
neocolonialism/M
neocolonialist/MS
neocon/S
neocon/SM
neoconservative/SM
neodymium/M
neolithic
@ -33193,6 +33233,7 @@ nephew/SM
nephrite/M
nephritic
nephritis/M
nephropathy
nepotism/M
nepotist/SM
nepotistic
@ -33323,7 +33364,7 @@ niece/SM
niff
niffy
nifty/TR
nigga/S
nigga/SM
niggard/SMY
niggardliness/M
niggaz
@ -33629,7 +33670,7 @@ nonobligatory
nonobservance/M
nonobservant
nonoccupational
nonoccurrence/M
nonoccurence
nonofficial
nonoperational
nonoperative
@ -34428,7 +34469,7 @@ orbicular
orbit/MDRZGS
orbital/SM
orbiter/M
orc/S
orc/SM
orchard/SM
orchestra/MS
orchestral
@ -35348,6 +35389,7 @@ park/MDSG
parka/SM
parking/M
parkland
parkour
parkway/MS
parky
parlance/M
@ -35366,6 +35408,7 @@ parodist/SM
parody/GDSM
parole/MGDS
parolee/MS
parotid
paroxysm/SM
paroxysmal
parquet/MDSG
@ -36071,6 +36114,8 @@ phalanges
phalanx/MS
phalli
phallic
phallocentric
phallocentrism
phallus/M
phantasm/MS
phantasmagoria/MS
@ -36085,6 +36130,7 @@ pharmaceutic/MS
pharmaceutical/SM
pharmaceutics/M
pharmacist/MS
pharmacologic
pharmacological
pharmacologist/SM
pharmacology/M
@ -36181,8 +36227,8 @@ phosphorescent/Y
phosphoric
phosphorous
phosphorus/M
phosphorylation
photo/SGMD
photobomb/DGS
photocell/MS
photocopier/M
photocopy/DRSMZG
@ -36692,8 +36738,6 @@ plumbed/U
plumber/M
plumbing/M
plume/MS
plummer
plummest
plummet/SGMD
plummy
plump/MDRYSTGP
@ -36741,7 +36785,7 @@ pocketknife/M
pocketknives
pockmark/MDGS
pod/SM
podcast/SM
podcast/SMG
podded
podding
podiatrist/SM
@ -37083,6 +37127,7 @@ postponement/SM
postprandial
postscript/SM
postseason/SM
postsynaptic
postulate/XDSMGN
postulation/M
postural
@ -37301,6 +37346,7 @@ preferring
prefigure/GDS
prefix/MDSG
preform/GSD
prefrontal
pregame/SM
pregnancy/SM
pregnant
@ -38207,12 +38253,13 @@ pyromaniac/SM
pyrotechnic/S
pyrotechnical
pyrotechnics/M
pyruvate
python/SM
pyx/MS
pzazz
q
qr
qt
qt/S
qty
qua
quack/GMDS
@ -38594,6 +38641,7 @@ rankness/M
ransack/SGD
ransom/SZGMDR
ransomer/M
ransomware
rant/ZGMDJRS
ranter/M
rap/SZGMDR
@ -39197,7 +39245,7 @@ rental/SM
renter/M
renunciation/SM
reopen/SDG
reorg/DSG
reorg/MDSG
rep/SM
repaint/GDS
repair/BZR
@ -39760,7 +39808,7 @@ robbing
robe's
robe/EGDS
robin/MS
robocall/SGD
robocall/SGMD
robot/MS
robotic/S
robotics/M
@ -40055,6 +40103,8 @@ rutting
rutty/RT
rye/M
s/NYXB
sabbath/M
sabbaths
sabbatical/SM
saber/MS
sable/MS
@ -40069,8 +40119,9 @@ saccharine
sacerdotal
sachem/SM
sachet/SM
sack/GMDJS
sack/ZGMDRJS
sackcloth/M
sacker/M
sackful/MS
sacking/M
sacra
@ -40221,6 +40272,7 @@ samovar/SM
sampan/SM
sample/DRSMZGJ
sampler/M
sampling/M
samurai/SM
sanatorium/SM
sanctification/M
@ -41416,7 +41468,7 @@ shiftiness/M
shiftless/PY
shiftlessness/M
shifty/RPT
shiitake/S
shiitake/SM
shill/GMDSJ
shillelagh/M
shillelaghs
@ -41508,7 +41560,7 @@ shooter/M
shooting/M
shootout/MS
shop/MS
shopaholic/S
shopaholic/MS
shopfitter/S
shopfitting
shopfront/S
@ -41771,7 +41823,7 @@ silversmith/M
silversmiths
silverware/M
silvery
sim/S
sim/SM
simian/MS
similar/Y
similarity/ESM
@ -42628,6 +42680,7 @@ soothsayer/MS
soothsaying/M
sooty/RT
sop/SM
soph
sophism/M
sophist/MS
sophistic
@ -42682,7 +42735,7 @@ soul/MS
soulful/YP
soulfulness/M
soulless/YP
soulmate/S
soulmate/SM
sound/JPSMDRYZTG
soundalike/S
soundbar/S
@ -42885,7 +42938,7 @@ spell/JSMDRZG
spellbind/ZGRS
spellbinder/M
spellbound
spellcheck/DRZGS
spellcheck/MDRZGS
spellchecker/M
spelldown/SM
speller/M
@ -43446,7 +43499,7 @@ stenographer/SM
stenographic
stenography/M
stenosis
stent/S
stent/SM
stentorian
step/IMS
stepbrother/SM
@ -43841,7 +43894,7 @@ studiousness/M
studly/RT
study's
study/AGDS
stuff/GSMD
stuff/GSMDJ
stuffily
stuffiness/M
stuffing/M
@ -44170,7 +44223,7 @@ sunbathing/M
sunbaths
sunbeam/SM
sunbed/S
sunbelt
sunbelt/SM
sunblock/MS
sunbonnet/SM
sunburn/SGMD
@ -44936,7 +44989,7 @@ taxonomist/MS
taxonomy/SM
taxpayer/MS
taxpaying
tbs
tb/S
tbsp
tea/SM
teabag/S
@ -45131,7 +45184,7 @@ tendentious/YP
tendentiousness/M
tender/SMDRYTGP
tenderfoot/MS
tenderhearted/PY
tenderhearted/P
tenderheartedness/M
tenderize/ZGDRS
tenderizer/M
@ -45604,6 +45657,7 @@ tights/M
tightwad/MS
tigress/MS
til
tilapia
tilde/SM
tile/MZGDRS
tiler/M
@ -46502,7 +46556,8 @@ trusting/Y
trustworthiness/M
trustworthy/TPR
trusty/TRSM
truth/UM
truth/ZMR
truther/M
truthful/UYP
truthfulness/UM
truthiness
@ -46511,6 +46566,7 @@ try's
try/AGDS
trying/Y
tryout/SM
tryptophan
tryst/SMDG
tsarists
tsetse/MS
@ -46659,8 +46715,9 @@ tweed/SM
tweeds/M
tweedy/RT
tween
tweet/SMDRZG
tweeter/M
tweet's
tweet/ASDG
tweeter/SM
tweezers/M
twelfth/M
twelfths
@ -46769,10 +46826,11 @@ ugh
ugliness/M
ugly/RTP
uh
uhf
ukase/SM
ukulele/SM
ulcer/SM
ulcerate/DSGN
ulcerate/XDSGN
ulceration/M
ulcerous
ulna/M
@ -47055,7 +47113,6 @@ unflinching/Y
unforgettably
unforgivably
unfortunate/MS
unfriend/GD
unfriendly/T
unfrock/DG
unfruitful
@ -47236,6 +47293,7 @@ untouchable/MS
untoward
untrue/RT
untrustworthy
untruth/M
unutterable
unutterably
unwarrantable
@ -47277,6 +47335,7 @@ upland/MS
uplift/JSMDG
upload/SDG
upmarket
upmost
upon
upped
upper/SM
@ -47371,7 +47430,7 @@ usefulness/M
useless/YP
uselessness/M
user/MS
username/S
username/MS
usher/SMDG
usherette/SM
usu
@ -47934,6 +47993,7 @@ vixen/SM
vixenish/Y
viz
vizier/SM
vlf
vocab
vocable/MS
vocabulary/SM
@ -47956,7 +48016,7 @@ voice/IDSMG
voiced/U
voiceless/PY
voicelessness/M
voicemail/M
voicemail/SM
void/MDSGB
voila
voile/M
@ -48036,7 +48096,7 @@ vuvuzela/MS
vying
w/DNXTGVJ
wabbit/S
wack/RTS
wack/MRTS
wackiness/M
wacko/SM
wacky/RPT
@ -48198,7 +48258,7 @@ warty/TR
wary/UPRT
was
wasabi
wash/BMDRSZG
wash/BJMDRSZG
washable/SM
washbasin/SM
washboard/SM
@ -48249,7 +48309,8 @@ watchword/MS
water/GSMD
waterbed/MS
waterbird/SM
waterboard/DJSG
waterboard/MDJSG
waterboarding/M
waterborne
watercolor/MS
watercourse/SM
@ -48367,7 +48428,6 @@ webisode/MS
weblog/MS
webmaster/SM
webmistress/MS
webpage/SM
website/SM
wed/AS
wedded/A
@ -48660,7 +48720,7 @@ widemouthed
widen/SDRZG
widener/M
wideness/M
widescreen/S
widescreen/MS
widespread
widgeon/MS
widget/S
@ -48818,7 +48878,7 @@ wish/MDRSZG
wishbone/SM
wisher/M
wishful/Y
wishlist/SM
wishlist's
wisp/MS
wispy/RT
wist

View File

@ -1,4 +1,4 @@
52286
52342
0/nm
0th/pt
1/n1
@ -37,6 +37,7 @@ ACTH/M
AD/M
ADC
ADD
ADM
ADP/M
AF
AFAIK
@ -711,6 +712,7 @@ Apocrypha/M
Apollinaire/M
Apollo/SM
Apollonian/M
Apostle/M
Appalachia/M
Appalachian/SM
Appalachians/M
@ -936,6 +938,7 @@ Atlantic/M
Atlantis/M
Atlas/MS
Atman/M
Atonement
Atreus/M
Atria/M
Atropos/M
@ -1623,6 +1626,7 @@ Bolivian/MS
Bollywood/M
Bologna/M
Bolshevik/SM
Bolsheviki
Bolshevism/M
Bolshevist/M
Bolshoi/M
@ -2724,6 +2728,7 @@ Combs/M
Comcast/M
Comdr
Comintern/M
Commandment
Commons/M
Commonwealth
Communion/SM
@ -3214,6 +3219,7 @@ Deane/M
Deann/M
Deanna/M
Deanne/M
Death/M
Deb/SM
Debbi/M
Debbie/M
@ -4526,6 +4532,7 @@ GIF
GIGO
GM/M
GMAT
GMO
GMT/M
GNP/M
GNU/M
@ -5782,6 +5789,7 @@ IRA/SM
IRC
IRS/M
ISBN
ISIS
ISO/M
ISP
ISS
@ -7168,6 +7176,7 @@ Libbey/M
Libbie/M
Libby/M
Liberace/M
Liberal
Liberia/M
Liberian/SM
Libra/MS
@ -7563,6 +7572,7 @@ Mada/M
Madagascan/SM
Madagascar/M
Madalyn/M
Madam
Maddalena/M
Madden/M
Maddi/M
@ -8211,6 +8221,7 @@ Messiaen/M
Messiah/M
Messiahs
Messianic
Messieurs
Metacafe/M
Metallica/M
Metamucil/M
@ -8458,6 +8469,7 @@ Monro/M
Monroe/M
Monrovia/M
Monsanto/M
Monsieur/M
Monsignor/SM
Mont/M
Montague/M
@ -8681,6 +8693,7 @@ NS
NSA/M
NSC
NSF
NSFW
NSPR/M
NSS/M
NT
@ -8972,7 +8985,7 @@ Nivea/M
Niven/M
Nixon/M
Nkrumah/M
No/M
No/SM
NoDoz/M
Noah/M
Noam/M
@ -9223,6 +9236,7 @@ OpenOffice/M
Ophelia/M
Ophiuchus/M
Oppenheimer/M
Opposition
Oprah/M
Ora/M
Oracle/M
@ -9243,6 +9257,7 @@ Orestes/M
Oriana/M
Orient/M
Oriental/MS
Orientalism
Orin/M
Orinoco/M
Orion/M
@ -9447,6 +9462,7 @@ Park/SMR
Parke/M
Parker/M
Parkinson/M
Parkinsonism
Parkman/M
Parks/M
Parliament/M
@ -10661,6 +10677,7 @@ SF
SGML/M
SIDS/M
SJ
SJW
SK
SLR
SNP/SM
@ -11060,6 +11077,7 @@ Seymour/M
Sgt
Shackleton/M
Shaffer/M
Shah/M
Shaka/M
Shaker
Shakespeare/M
@ -12396,6 +12414,7 @@ Uruguayan/MS
Urumqi/M
Usenet/MS
Ustinov/M
Ut
Uta/M
Utah/M
Utahan/MS
@ -13208,6 +13227,7 @@ Ziegfeld/M
Ziegler/M
Ziff/M
Ziggy/M
Zika
Zimbabwe/M
Zimbabwean/SM
Zimmerman/M
@ -13651,6 +13671,7 @@ addressed/U
addressee/SM
adduce/GDS
adenine/M
adenocarcinoma
adenoid/SM
adenoidal
adept/MYPS
@ -14329,7 +14350,7 @@ amicable
amicably
amid
amide/MS
amidships
amidship/S
amidst
amigo/MS
amino
@ -15001,6 +15022,7 @@ areal
aren't
arena/MS
argent/M
arginine
argon/M
argosy/SM
argot/MS
@ -15913,6 +15935,7 @@ baptizer/M
bar's
bar/ECUTS
barb/SZGMDR
barbacoa
barbarian/SM
barbarianism/MS
barbaric
@ -17825,7 +17848,7 @@ burgle/DSG
burgomaster/SM
burgundy/SM
burial/ASM
burka/S
burka/SM
burl/MDS
burlap/M
burlesque/MGDS
@ -17841,7 +17864,7 @@ burnous/MS
burnout/MS
burnt
burp/MDGS
burqa/S
burqa/SM
burr/MDGS
burrito/MS
burro/SM
@ -18934,6 +18957,7 @@ chateau/SM
chateaux
chatelaine/SM
chatline/S
chatroom/M
chatted
chattel/MS
chatter/MDRZGS
@ -19380,6 +19404,7 @@ city/SM
citywide
civet/MS
civic/S
civically
civics/M
civil/UY
civilian/MS
@ -20680,6 +20705,7 @@ contraceptive/SM
contract/MDG
contractible
contractile
contractility
contraction/S
contractual/Y
contradict/SDG
@ -21084,7 +21110,9 @@ counterintelligence/M
counterman/M
countermand/GMDS
countermeasure/SM
countermelody/S
countermen
countermove/S
counteroffensive/SM
counteroffer/SM
counterpane/SM
@ -21752,7 +21780,7 @@ cwt
cyan/M
cyanide/M
cyber
cyberbully/S
cyberbully/SM
cybercafe/S
cybercafé/S
cybernetic/S
@ -22699,7 +22727,7 @@ diaphragmatic
diarist/SM
diarrhea/M
diary/SM
diaspora
diaspora/SM
diastase/M
diastole/M
diastolic
@ -24080,7 +24108,7 @@ effete/YP
effeteness/M
efficacious/Y
efficacy/IM
efficiency/IM
efficiency/ISM
efficient/IY
effigy/SM
efflorescence/M
@ -24384,7 +24412,7 @@ emitted
emitter/MS
emitting
emo/SM
emoji
emoji/SM
emollient/MS
emolument/MS
emote/XDSGNV
@ -24517,7 +24545,7 @@ endogenous/Y
endometrial
endometriosis
endometrium
endorphin/M
endorphin/MS
endorse/LZGDRS
endorsement/MS
endorser/M
@ -25769,7 +25797,8 @@ fearsome
feasibility/M
feasible/IU
feasibly
feast/SMDG
feast/SMDRZG
feaster/M
feat/MS
feather/SGMD
featherbedding/M
@ -26356,9 +26385,6 @@ flint/SM
flintlock/SM
flinty/TR
flip/MS
flipflop/S
flipflopped
flipflopping
flippancy/M
flippant/Y
flipped
@ -27008,7 +27034,7 @@ frictional
fridge/SM
friedcake/MS
friend's
friend/US
friend/UGSDY
friendless
friendlies
friendliness/UM
@ -27082,7 +27108,7 @@ frostbite/MGS
frostbitten
frostily
frostiness/M
frosting/M
frosting/SM
frosty/TPR
froth/MDG
frothiness/M
@ -28632,7 +28658,7 @@ hackish
hackle/MS
hackney/SMDG
hacksaw/SM
hacktivist/S
hacktivist/MS
hackwork/M
had
haddock/SM
@ -29185,6 +29211,7 @@ hell/M
hellbent
hellcat/MS
hellebore/M
hellfire
hellhole/MS
hellion/MS
hellish/YP
@ -30810,7 +30837,6 @@ inedible
ineffability/M
ineffable
ineffably
inefficiency/S
inelastic
ineligible/MS
ineligibly
@ -31757,6 +31783,7 @@ jetted
jetting
jettison/MDSG
jetty/SM
jew
jewel/SZGMDR
jeweler/M
jewellery
@ -31896,6 +31923,7 @@ joyrider/M
joyriding/M
joyrode
joystick/SM
jr
jubilant/Y
jubilation/M
jubilee/SM
@ -32298,7 +32326,8 @@ kuchen/SM
kudos/M
kudzu/SM
kumquat/MS
kvetch/GMDS
kvetch/ZGMDRS
kvetcher/M
kw
l/SDXTGJ
la/M
@ -32395,7 +32424,7 @@ lambkin/SM
lambskin/SM
lambswool
lame/MYZTGDRSP
lamebrain/MS
lamebrain/MDS
lameness/M
lament/BSMDG
lamentably
@ -32815,6 +32844,7 @@ letterpress/M
letting/S
lettuce/MS
letup/SM
leucine
leucotomy/S
leukemia/M
leukemic/SM
@ -32946,6 +32976,7 @@ lightproof
lightship/MS
lightweight/SM
ligneous
lignin
lignite/M
lii
likability/M
@ -33248,16 +33279,16 @@ logic/M
logical/Y
logicality/M
logician/MS
login/S
login/SM
logistic/S
logistical/Y
logistics/M
logjam/SM
logo/MS
logoff/S
logon/S
logoff/SM
logon/SM
logotype/SM
logout/S
logout/SM
logrolling/M
logy/RT
loin/MS
@ -33607,9 +33638,10 @@ madman/M
madmen
madness/M
madras/MS
madrasa/S
madrassah
madrassahs
madrasa/SM
madrasah/M
madrasahs
madrassa/SM
madrigal/SM
madwoman/M
madwomen
@ -34324,7 +34356,7 @@ member/EAS
membership/SM
membrane/SM
membranous
meme/S
meme/MS
memento/MS
memo/MS
memoir/MS
@ -34556,6 +34588,7 @@ mice
mick/S
mickey/MS
micro/SM
microaggression/SM
microbe/MS
microbial
microbiological
@ -34692,7 +34725,7 @@ milky/RTP
mill/MDRSZGJ
millage/M
millennia
millennial/MS
millennial/M
millennium/MS
miller/M
millet/M
@ -34771,7 +34804,7 @@ minim/SM
minimal/Y
minimalism/M
minimalist/MS
minimization
minimization/M
minimize/DSG
minimum/MS
mining/M
@ -35003,6 +35036,7 @@ mitochondrion
mitoses
mitosis/M
mitotic
mitral
mitt/MNSX
mitten/M
mix/ZGMDRSB
@ -35011,6 +35045,7 @@ mixer/M
mixture/SM
mizzen/MS
mizzenmast/SM
mkay
mks
ml
mm
@ -35032,7 +35067,7 @@ mobilize/CDSG
mobilizer/SM
mobster/SM
moccasin/SM
mocha/M
mocha/SM
mock/DRSZG
mocker/M
mockery/SM
@ -35438,6 +35473,7 @@ moussaka/S
mousse/MGDS
mousy/PTR
mouth/GMD
mouthfeel
mouthful/MS
mouthiness/M
mouthpiece/MS
@ -35541,6 +35577,7 @@ multifamily
multifarious/PY
multifariousness/M
multiform
multigrain
multilateral/Y
multilayered
multilevel
@ -35687,6 +35724,7 @@ mutterer/M
muttering/M
mutton/M
muttonchops/M
muttony
mutual/Y
mutuality/M
muumuu/MS
@ -35977,7 +36015,7 @@ neoclassical
neoclassicism/M
neocolonialism/M
neocolonialist/MS
neocon/S
neocon/SM
neoconservative/SM
neodymium/M
neolithic
@ -35995,6 +36033,7 @@ nephew/SM
nephrite/M
nephritic
nephritis/M
nephropathy
nepotism/M
nepotist/SM
nepotistic
@ -36130,7 +36169,7 @@ niece/SM
niff
niffy
nifty/TR
nigga/S
nigga/SM
niggard/SMY
niggardliness/M
niggaz
@ -36435,7 +36474,7 @@ nonobligatory
nonobservance/M
nonobservant
nonoccupational
nonoccurrence/M
nonoccurence
nonofficial
nonoperational
nonoperative
@ -37236,7 +37275,7 @@ orbicular
orbit/MDRZGS
orbital/SM
orbiter/M
orc/S
orc/SM
orchard/SM
orchestra/MS
orchestral
@ -38177,6 +38216,7 @@ parodist/SM
parody/GDSM
parole/MGDS
parolee/MS
parotid
paroxysm/SM
paroxysmal
parquet/MDSG
@ -38885,6 +38925,8 @@ phalanges
phalanx/MS
phalli
phallic
phallocentric
phallocentrism
phallus/M
phantasm/MS
phantasmagoria/MS
@ -38899,6 +38941,7 @@ pharmaceutic/MS
pharmaceutical/SM
pharmaceutics/M
pharmacist/MS
pharmacologic
pharmacological
pharmacologist/SM
pharmacology/M
@ -39000,7 +39043,6 @@ phosphorous
phosphorus/M
phosphorylate/DSGN
photo/SGMD
photobomb/DGS
photocell/MS
photocopier/M
photocopy/DRSMZG
@ -39511,8 +39553,6 @@ plumbed/U
plumber/M
plumbing/M
plume/MS
plummer
plummest
plummet/SGMD
plummy
plump/MDRYSTGP
@ -39560,7 +39600,7 @@ pocketknife/M
pocketknives
pockmark/MDGS
pod/SM
podcast/SM
podcast/SMG
podded
podding
podiatrist/SM
@ -39904,6 +39944,7 @@ postponement/SM
postprandial
postscript/SM
postseason/SM
postsynaptic
postulate/XDSMGN
postulation/M
postural
@ -40123,6 +40164,7 @@ preferring
prefigure/GDS
prefix/MDSG
preform/GSD
prefrontal
pregame/SM
pregnancy/SM
pregnant
@ -41035,12 +41077,13 @@ pyromaniac/SM
pyrotechnic/S
pyrotechnical
pyrotechnics/M
pyruvate
python/SM
pyx/MS
pzazz
q
qr
qt
qt/S
qty
qua
quack/GMDS
@ -41424,6 +41467,7 @@ rankness/M
ransack/SGD
ransom/SZGMDR
ransomer/M
ransomware
rant/ZGMDJRS
ranter/M
rap/SZGMDR
@ -42033,7 +42077,7 @@ rental/SM
renter/M
renunciation/SM
reopen/SDG
reorg/DSG
reorg/MDSG
rep/SM
repaint/GDS
repair/BZR
@ -42599,7 +42643,7 @@ robbing
robe's
robe/EGDS
robin/MS
robocall/SGD
robocall/SGMD
robot/MS
robotic/S
robotics/M
@ -42895,6 +42939,8 @@ rutting
rutty/RT
rye/M
s/NYXB
sabbath/M
sabbaths
sabbatical/SM
saber/MS
sable/MS
@ -42909,8 +42955,9 @@ saccharine
sacerdotal
sachem/SM
sachet/SM
sack/GMDJS
sack/ZGMDRJS
sackcloth/M
sacker/M
sackful/MS
sacking/M
sacra
@ -43061,6 +43108,7 @@ samovar/SM
sampan/SM
sample/DRSMZGJ
sampler/M
sampling/M
samurai/SM
sanatorium/SM
sanctification/M
@ -44266,7 +44314,7 @@ shiftiness/M
shiftless/PY
shiftlessness/M
shifty/RPT
shiitake/S
shiitake/SM
shill/GMDSJ
shillelagh/M
shillelaghs
@ -44360,7 +44408,7 @@ shooter/M
shooting/M
shootout/MS
shop/MS
shopaholic/S
shopaholic/MS
shopfitter/S
shopfitting
shopfront/S
@ -44624,7 +44672,7 @@ silversmith/M
silversmiths
silverware/M
silvery
sim/S
sim/SM
simian/MS
similar/Y
similarity/ESM
@ -45481,6 +45529,7 @@ soothsayer/MS
soothsaying/M
sooty/RT
sop/SM
soph
sophism/M
sophist/MS
sophistic
@ -45535,7 +45584,7 @@ soul/MS
soulful/YP
soulfulness/M
soulless/YP
soulmate/S
soulmate/SM
sound/JPSMDRYZTG
soundalike/S
soundbar/S
@ -45738,7 +45787,7 @@ spell/JSMDRZG
spellbind/ZGRS
spellbinder/M
spellbound
spellcheck/DRZGS
spellcheck/MDRZGS
spellchecker/M
spelldown/SM
speller/M
@ -46696,7 +46745,7 @@ studiousness/M
studly/RT
study's
study/AGDS
stuff/GSMD
stuff/GSMDJ
stuffily
stuffiness/M
stuffing/M
@ -47026,7 +47075,7 @@ sunbathing/M
sunbaths
sunbeam/SM
sunbed/S
sunbelt
sunbelt/SM
sunblock/MS
sunbonnet/SM
sunburn/SGMD
@ -47799,7 +47848,7 @@ taxonomist/MS
taxonomy/SM
taxpayer/MS
taxpaying
tbs
tb/S
tbsp
tea/SM
teabag/S
@ -47995,7 +48044,7 @@ tendentious/YP
tendentiousness/M
tender/SMDRYTGP
tenderfoot/MS
tenderhearted/PY
tenderhearted/P
tenderheartedness/M
tenderize/ZGDRS
tenderizer/M
@ -48473,6 +48522,7 @@ tights/M
tightwad/MS
tigress/MS
til
tilapia
tilde/SM
tile/MZGDRS
tiler/M
@ -49377,7 +49427,8 @@ trusting/Y
trustworthiness/M
trustworthy/TPR
trusty/TRSM
truth/UM
truth/ZMR
truther/M
truthful/UYP
truthfulness/UM
truthiness
@ -49386,6 +49437,7 @@ try's
try/AGDS
trying/Y
tryout/SM
tryptophan
tryst/SMDG
tsarists
tsetse/MS
@ -49535,8 +49587,9 @@ tweeds/M
tweedy/RT
tween
tweep/S
tweet/SMDRZG
tweeter/M
tweet's
tweet/ASDG
tweeter/SM
tweezers/M
twelfth/M
twelfths
@ -49645,10 +49698,11 @@ ugh
ugliness/M
ugly/RTP
uh
uhf
ukase/SM
ukulele/SM
ulcer/SM
ulcerate/DSGN
ulcerate/XDSGN
ulceration/M
ulcerous
ulna/M
@ -49931,7 +49985,6 @@ unflinching/Y
unforgettably
unforgivably
unfortunate/MS
unfriend/GD
unfriendly/T
unfrock/DG
unfruitful
@ -50111,6 +50164,7 @@ untouchable/MS
untoward
untrue/RT
untrustworthy
untruth/M
unutterable
unutterably
unwarrantable
@ -50152,6 +50206,7 @@ upland/MS
uplift/JSMDG
upload/SDG
upmarket
upmost
upon
upped
upper/SM
@ -50811,6 +50866,7 @@ vixen/SM
vixenish/Y
viz
vizier/SM
vlf
vocab
vocable/MS
vocabulary/SM
@ -50833,7 +50889,7 @@ voice/IDSMG
voiced/U
voiceless/PY
voicelessness/M
voicemail/M
voicemail/SM
void/MDSGB
voila
voile/M
@ -50916,7 +50972,7 @@ vuvuzela/MS
vying
w/DNXTGVJ
wabbit/S
wack/RTS
wack/MRTS
wackiness/M
wacko/SM
wacky/RPT
@ -51078,7 +51134,7 @@ warty/TR
wary/UPRT
was
wasabi
wash/BMDRSZG
wash/BJMDRSZG
washable/SM
washbasin/SM
washboard/SM
@ -51129,7 +51185,8 @@ watchword/MS
water/GSMD
waterbed/MS
waterbird/SM
waterboard/DJSG
waterboard/MDJSG
waterboarding/M
waterborne
watercolor/MS
watercourse/SM
@ -51248,7 +51305,6 @@ webisode/MS
weblog/MS
webmaster/SM
webmistress/MS
webpage/SM
website/SM
wed/AS
wedded/A
@ -51700,7 +51756,7 @@ wish/MDRSZG
wishbone/SM
wisher/M
wishful/Y
wishlist/SM
wishlist's
wisp/MS
wispy/RT
wist

View File

@ -21,7 +21,7 @@
#ifdef XP_WIN
#include "SharedSurfaceANGLE.h" // for SurfaceFactory_ANGLEShareHandle
#include "SharedSurfaceD3D11Interop.h" // for SurfaceFactory_D3D11Interop
#include "gfxWindowsPlatform.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#endif
#ifdef MOZ_WIDGET_GONK
@ -108,9 +108,10 @@ GLScreenBuffer::CreateFactory(GLContext* gl,
#ifdef XP_WIN
// Enable surface sharing only if ANGLE and compositing devices
// are both WARP or both not WARP
gfx::DeviceManagerD3D11* dm = gfx::DeviceManagerD3D11::Get();
if (gl->IsANGLE() &&
(gl->IsWARP() == gfxWindowsPlatform::GetPlatform()->IsWARP()) &&
gfxWindowsPlatform::GetPlatform()->CompositorD3D11TextureSharingWorks())
(gl->IsWARP() == dm->IsWARP()) &&
dm->TextureSharingWorks())
{
factory = SurfaceFactory_ANGLEShareHandle::Create(gl, caps, allocator, flags);
}

View File

@ -6,9 +6,9 @@
#include "SharedSurfaceANGLE.h"
#include <d3d11.h>
#include "gfxWindowsPlatform.h"
#include "GLContextEGL.h"
#include "GLLibraryEGL.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
namespace mozilla {
@ -196,8 +196,9 @@ public:
}
}
RefPtr<ID3D11Device> device;
if (!gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device)) {
RefPtr<ID3D11Device> device =
gfx::DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
if (!device) {
return;
}
@ -252,8 +253,9 @@ SharedSurface_ANGLEShareHandle::ReadbackBySharedHandle(gfx::DataSourceSurface* o
{
MOZ_ASSERT(out_surface);
RefPtr<ID3D11Device> device;
if (!gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device)) {
RefPtr<ID3D11Device> device =
gfx::DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
if (!device) {
return false;
}

View File

@ -10,6 +10,7 @@
#include "GLContext.h"
#include "WGLLibrary.h"
#include "nsPrintfCString.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
namespace mozilla {
namespace gl {
@ -125,9 +126,8 @@ public:
static already_AddRefed<DXGLDevice> Open(WGLLibrary* wgl)
{
MOZ_ASSERT(wgl->HasDXInterop2());
gfxWindowsPlatform* plat = gfxWindowsPlatform::GetPlatform();
RefPtr<ID3D11Device> d3d = plat->GetD3D11ContentDevice();
RefPtr<ID3D11Device> d3d = gfx::DeviceManagerD3D11::Get()->GetContentDevice();
if (!d3d) {
NS_WARNING("Failed to create D3D11 device.");
return nullptr;

View File

@ -7,6 +7,7 @@
#include "mozilla/layers/TextureD3D11.h"
#include "mozilla/layers/CompositableClient.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/layers/TextureClient.h"
#include "d3d9.h"
@ -224,8 +225,8 @@ IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
return mTextureClient;
}
RefPtr<ID3D11Device> device;
gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(&device);
RefPtr<ID3D11Device> device =
gfx::DeviceManagerD3D11::Get()->GetImageBridgeDevice();
LayersBackend backend = aClient->GetForwarder()->GetCompositorBackendType();
if (!device || backend != LayersBackend::LAYERS_D3D11) {

View File

@ -169,7 +169,7 @@ ScrollFrame(nsIContent* aContent,
// get another repaint request when APZ confirms. In the interval while this
// is happening we can just leave the callback transform as it was.
bool mainThreadScrollChanged =
sf && sf->CurrentScrollGeneration() != aMetrics.GetScrollGeneration();
sf && sf->CurrentScrollGeneration() != aMetrics.GetScrollGeneration() && nsLayoutUtils::CanScrollOriginClobberApz(sf->LastScrollOrigin());
if (aContent && !mainThreadScrollChanged) {
CSSPoint scrollDelta = apzScrollOffset - actualScrollOffset;
aContent->SetProperty(nsGkAtoms::apzCallbackTransform, new CSSPoint(scrollDelta),

View File

@ -35,7 +35,7 @@
#include "LayerMetricsWrapper.h"
#endif
#ifdef XP_WIN
#include "gfxWindowsPlatform.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#endif
namespace mozilla {
@ -772,7 +772,7 @@ ClientLayerManager::GetBackendName(nsAString& aName)
case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
case LayersBackend::LAYERS_D3D11: {
#ifdef XP_WIN
if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
if (DeviceManagerD3D11::Get()->IsWARP()) {
aName.AssignLiteral("Direct3D 11 WARP");
} else {
aName.AssignLiteral("Direct3D 11");

View File

@ -34,6 +34,7 @@
#include "mozilla/layers/ShadowLayers.h"
#ifdef XP_WIN
#include "mozilla/gfx/DeviceManagerD3D11.h"
#include "mozilla/layers/TextureD3D9.h"
#include "mozilla/layers/TextureD3D11.h"
#include "mozilla/layers/TextureDIB.h"
@ -1039,7 +1040,7 @@ TextureClient::CreateForDrawing(TextureForwarder* aAllocator,
(moz2DBackend == gfx::BackendType::DIRECT2D ||
moz2DBackend == gfx::BackendType::DIRECT2D1_1 ||
(!!(aAllocFlags & ALLOC_FOR_OUT_OF_BAND_CONTENT) &&
gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice())) &&
DeviceManagerD3D11::Get()->GetContentDevice())) &&
aSize.width <= maxTextureSize &&
aSize.height <= maxTextureSize)
{

View File

@ -12,6 +12,7 @@
#include "gfxWindowsPlatform.h"
#include "nsIWidget.h"
#include "nsIGfxInfo.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#include "mozilla/layers/ImageHost.h"
#include "mozilla/layers/ContentHost.h"
#include "mozilla/layers/Effects.h"
@ -203,7 +204,8 @@ CompositorD3D11::Initialize(nsCString* const out_failureReason)
HRESULT hr;
if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&mDevice)) {
mDevice = DeviceManagerD3D11::Get()->GetCompositorDevice();
if (!mDevice) {
*out_failureReason = "FEATURE_FAILURE_D3D11_NO_DEVICE";
return false;
}
@ -1257,7 +1259,8 @@ CompositorD3D11::EndFrame()
UINT presentInterval = 0;
if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
bool isWARP = DeviceManagerD3D11::Get()->IsWARP();
if (isWARP) {
// When we're using WARP we cannot present immediately as it causes us
// to tear when rendering. When not using WARP it appears the DWM takes
// care of tearing for us.
@ -1280,8 +1283,7 @@ CompositorD3D11::EndFrame()
nsString vendorID;
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
gfxInfo->GetAdapterVendorID(vendorID);
allowPartialPresent = !vendorID.EqualsLiteral("0x10de") ||
gfxWindowsPlatform::GetPlatform()->IsWARP();
allowPartialPresent = !vendorID.EqualsLiteral("0x10de") || isWARP;
}
if (SUCCEEDED(hr) && chain && allowPartialPresent) {
@ -1505,7 +1507,7 @@ bool
DeviceAttachmentsD3D11::InitSyncObject()
{
// Sync object is not supported on WARP.
if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
if (DeviceManagerD3D11::Get()->IsWARP()) {
return true;
}
@ -1707,8 +1709,7 @@ CompositorD3D11::HandleError(HRESULT hr, Severity aSeverity)
MOZ_CRASH("GFX: Unrecoverable D3D11 error");
}
RefPtr<ID3D11Device> device;
if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device) || device != mDevice) {
if (mDevice && DeviceManagerD3D11::Get()->GetCompositorDevice() != mDevice) {
gfxCriticalError() << "Out of sync D3D11 devices in HandleError, " << (int)mVerifyBuffersFailed;
}

View File

@ -11,6 +11,7 @@
#include "gfx2DGlue.h"
#include "gfxPrefs.h"
#include "ReadbackManagerD3D11.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#include "mozilla/gfx/Logging.h"
namespace mozilla {
@ -361,10 +362,11 @@ D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat, TextureAllocation
ID3D11Device* aDevice)
{
RefPtr<ID3D11Device> device = aDevice;
if (!device &&
!gfxWindowsPlatform::GetPlatform()->GetD3D11DeviceForCurrentThread(&device))
{
return nullptr;
if (!device) {
device = DeviceManagerD3D11::Get()->GetDeviceForCurrentThread();
if (!device) {
return nullptr;
}
}
CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
@ -657,9 +659,7 @@ DXGITextureHostD3D11::GetDevice()
return nullptr;
}
RefPtr<ID3D11Device> device;
gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device);
return device;
return DeviceManagerD3D11::Get()->GetCompositorDevice();
}
static CompositorD3D11* AssertD3D11Compositor(Compositor* aCompositor)
@ -795,9 +795,7 @@ DXGIYCbCrTextureHostD3D11::GetDevice()
return nullptr;
}
RefPtr<ID3D11Device> device;
gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device);
return device;
return DeviceManagerD3D11::Get()->GetCompositorDevice();
}
void
@ -1121,7 +1119,7 @@ SyncObjectD3D11::FinalizeFrame()
HRESULT hr;
if (!mD3D11Texture && mD3D11SyncedTextures.size()) {
ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
RefPtr<ID3D11Device> device = DeviceManagerD3D11::Get()->GetContentDevice();
hr = device->OpenSharedResource(mHandle, __uuidof(ID3D11Texture2D), (void**)(ID3D11Texture2D**)getter_AddRefs(mD3D11Texture));
@ -1164,8 +1162,7 @@ SyncObjectD3D11::FinalizeFrame()
box.front = box.top = box.left = 0;
box.back = box.bottom = box.right = 1;
ID3D11Device* dev = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
RefPtr<ID3D11Device> dev = DeviceManagerD3D11::Get()->GetContentDevice();
if (!dev) {
if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
return;

View File

@ -30,8 +30,7 @@ AnimationUtils::TimingFunctionToComputedTimingFunction(
nsTimingFunction::Type::StepStart :
nsTimingFunction::Type::StepEnd;
ComputedTimingFunction result;
result.Init(nsTimingFunction(type, sf.steps(),
nsTimingFunction::Keyword::Explicit));
result.Init(nsTimingFunction(type, sf.steps()));
return Some(result);
}
default:

View File

@ -30,6 +30,7 @@
#include "mozilla/layers/LayersTypes.h" // for MOZ_LAYERS_LOG
#include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/SharedBufferManagerChild.h"
#include "mozilla/layers/PTextureChild.h"
#include "ShadowLayerUtils.h"
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "mozilla/mozalloc.h" // for operator new, etc
@ -436,6 +437,7 @@ ShadowLayerForwarder::UseTextures(CompositableClient* aCompositable,
for (auto& t : aTextures) {
MOZ_ASSERT(t.mTextureClient);
MOZ_ASSERT(t.mTextureClient->GetIPDLActor());
MOZ_RELEASE_ASSERT(t.mTextureClient->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
FenceHandle fence = t.mTextureClient->GetAcquireFenceHandle();
ReadLockDescriptor readLock;
t.mTextureClient->SerializeReadLock(readLock);
@ -471,6 +473,8 @@ ShadowLayerForwarder::UseComponentAlphaTextures(CompositableClient* aCompositabl
MOZ_ASSERT(aTextureOnBlack->GetIPDLActor());
MOZ_ASSERT(aTextureOnWhite->GetIPDLActor());
MOZ_ASSERT(aTextureOnBlack->GetSize() == aTextureOnWhite->GetSize());
MOZ_RELEASE_ASSERT(aTextureOnWhite->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
MOZ_RELEASE_ASSERT(aTextureOnBlack->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
ReadLockDescriptor readLockW;
ReadLockDescriptor readLockB;
@ -540,6 +544,7 @@ ShadowLayerForwarder::RemoveTextureFromCompositable(CompositableClient* aComposi
MOZ_ASSERT(aTexture);
MOZ_ASSERT(aCompositable->IsConnected());
MOZ_ASSERT(aTexture->GetIPDLActor());
MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == mShadowManager->GetIPCChannel());
if (!aCompositable->IsConnected() || !aTexture->GetIPDLActor()) {
// We don't have an actor anymore, don't try to use it!
return;

View File

@ -55,6 +55,12 @@ const char* FeatureStatusToString(FeatureStatus aStatus);
bool IsFeatureStatusFailure(FeatureStatus aStatus);
bool IsFeatureStatusSuccess(FeatureStatus aStatus);
enum class TelemetryDeviceCode : uint32_t {
Content = 0,
Image = 1,
D2D1 = 2
};
} // namespace gfx
} // namespace mozilla

View File

@ -36,11 +36,11 @@ class TestNodeBase {
nsRegion GetRegion();
virtual bool IsLeaf() = 0;
private:
int mExpectedTraversalRank;
int mActualTraversalRank;
int mValue;
nsRegion mRegion;
T mType;
MOZ_INIT_OUTSIDE_CTOR int mExpectedTraversalRank;
MOZ_INIT_OUTSIDE_CTOR int mActualTraversalRank;
MOZ_INIT_OUTSIDE_CTOR int mValue;
MOZ_INIT_OUTSIDE_CTOR nsRegion mRegion;
MOZ_INIT_OUTSIDE_CTOR T mType;
protected:
virtual ~TestNodeBase<T>() {};
};

394
gfx/thebes/D3D11Checks.cpp Normal file
View File

@ -0,0 +1,394 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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 "D3D11Checks.h"
#include "gfxConfig.h"
#include "GfxDriverInfo.h"
#include "gfxPrefs.h"
#include "gfxWindowsPlatform.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/Logging.h"
#include "nsIGfxInfo.h"
#include <dxgi.h>
#include <d3d10_1.h>
#include <d3d11.h>
namespace mozilla {
namespace gfx {
using namespace mozilla::widget;
/* static */ bool
D3D11Checks::DoesRenderTargetViewNeedRecreating(ID3D11Device *aDevice)
{
bool result = false;
// CreateTexture2D is known to crash on lower feature levels, see bugs
// 1170211 and 1089413.
if (aDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
return true;
}
RefPtr<ID3D11DeviceContext> deviceContext;
aDevice->GetImmediateContext(getter_AddRefs(deviceContext));
int backbufferWidth = 32; int backbufferHeight = 32;
RefPtr<ID3D11Texture2D> offscreenTexture;
RefPtr<IDXGIKeyedMutex> keyedMutex;
D3D11_TEXTURE2D_DESC offscreenTextureDesc = { 0 };
offscreenTextureDesc.Width = backbufferWidth;
offscreenTextureDesc.Height = backbufferHeight;
offscreenTextureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
offscreenTextureDesc.MipLevels = 0;
offscreenTextureDesc.ArraySize = 1;
offscreenTextureDesc.SampleDesc.Count = 1;
offscreenTextureDesc.SampleDesc.Quality = 0;
offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
offscreenTextureDesc.CPUAccessFlags = 0;
offscreenTextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
HRESULT hr = aDevice->CreateTexture2D(&offscreenTextureDesc, NULL, getter_AddRefs(offscreenTexture));
if (FAILED(hr)) {
gfxCriticalNote << "DoesRecreatingCreateTexture2DFail";
return false;
}
hr = offscreenTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(keyedMutex));
if (FAILED(hr)) {
gfxCriticalNote << "DoesRecreatingKeyedMutexFailed";
return false;
}
D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
offscreenRTVDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
offscreenRTVDesc.Texture2D.MipSlice = 0;
RefPtr<ID3D11RenderTargetView> offscreenRTView;
hr = aDevice->CreateRenderTargetView(offscreenTexture, &offscreenRTVDesc, getter_AddRefs(offscreenRTView));
if (FAILED(hr)) {
gfxCriticalNote << "DoesRecreatingCreateRenderTargetViewFailed";
return false;
}
// Acquire and clear
keyedMutex->AcquireSync(0, INFINITE);
FLOAT color1[4] = { 1, 1, 0.5, 1 };
deviceContext->ClearRenderTargetView(offscreenRTView, color1);
keyedMutex->ReleaseSync(0);
keyedMutex->AcquireSync(0, INFINITE);
FLOAT color2[4] = { 1, 1, 0, 1 };
deviceContext->ClearRenderTargetView(offscreenRTView, color2);
D3D11_TEXTURE2D_DESC desc;
offscreenTexture->GetDesc(&desc);
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
desc.BindFlags = 0;
ID3D11Texture2D* cpuTexture;
hr = aDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
if (FAILED(hr)) {
gfxCriticalNote << "DoesRecreatingCreateCPUTextureFailed";
return false;
}
deviceContext->CopyResource(cpuTexture, offscreenTexture);
D3D11_MAPPED_SUBRESOURCE mapped;
hr = deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
if (FAILED(hr)) {
gfxCriticalNote << "DoesRecreatingMapFailed " << hexa(hr);
return false;
}
int resultColor = *(int*)mapped.pData;
deviceContext->Unmap(cpuTexture, 0);
cpuTexture->Release();
// XXX on some drivers resultColor will not have changed to
// match the clear
if (resultColor != 0xffffff00) {
gfxCriticalNote << "RenderTargetViewNeedsRecreating";
result = true;
}
keyedMutex->ReleaseSync(0);
return result;
}
/* static */ bool
D3D11Checks::DoesDeviceWork()
{
static bool checked = false;
static bool result = false;
if (checked)
return result;
checked = true;
if (gfxPrefs::Direct2DForceEnabled() ||
gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
{
result = true;
return true;
}
if (GetModuleHandleW(L"igd10umd32.dll")) {
const wchar_t* checkModules[] = {L"dlumd32.dll",
L"dlumd11.dll",
L"dlumd10.dll"};
for (int i=0; i<PR_ARRAY_SIZE(checkModules); i+=1) {
if (GetModuleHandleW(checkModules[i])) {
nsString displayLinkModuleVersionString;
gfxWindowsPlatform::GetDLLVersion(checkModules[i],
displayLinkModuleVersionString);
uint64_t displayLinkModuleVersion;
if (!ParseDriverVersion(displayLinkModuleVersionString,
&displayLinkModuleVersion)) {
gfxCriticalError() << "DisplayLink: could not parse version "
<< checkModules[i];
return false;
}
if (displayLinkModuleVersion <= V(8,6,1,36484)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DisplayLink: too old version " << displayLinkModuleVersionString.get();
return false;
}
}
}
}
result = true;
return true;
}
static bool
TryCreateTexture2D(ID3D11Device *device,
D3D11_TEXTURE2D_DESC* desc,
D3D11_SUBRESOURCE_DATA* data,
RefPtr<ID3D11Texture2D>& texture)
{
// Older Intel driver version (see bug 1221348 for version #s) crash when
// creating a texture with shared keyed mutex and data.
MOZ_SEH_TRY {
return !FAILED(device->CreateTexture2D(desc, data, getter_AddRefs(texture)));
} MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
// For now we want to aggregrate all the crash signature to a known crash.
gfxDevCrash(LogReason::TextureCreation) << "Crash creating texture. See bug 1221348.";
return false;
}
}
// See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
// with E_OUTOFMEMORY.
static bool
DoesTextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT format, UINT bindflags)
{
// CreateTexture2D is known to crash on lower feature levels, see bugs
// 1170211 and 1089413.
if (device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
return false;
}
if (gfxPrefs::Direct2DForceEnabled() ||
gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING))
{
return true;
}
if (GetModuleHandleW(L"atidxx32.dll")) {
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
if (gfxInfo) {
nsString vendorID, vendorID2;
gfxInfo->GetAdapterVendorID(vendorID);
gfxInfo->GetAdapterVendorID2(vendorID2);
if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
if (!gfxPrefs::LayersAMDSwitchableGfxEnabled()) {
return false;
}
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "PossiblyBrokenSurfaceSharing_UnexpectedAMDGPU";
}
}
}
RefPtr<ID3D11Texture2D> texture;
D3D11_TEXTURE2D_DESC desc;
const int texture_size = 32;
desc.Width = texture_size;
desc.Height = texture_size;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = format;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
desc.BindFlags = bindflags;
uint32_t color[texture_size * texture_size];
for (size_t i = 0; i < sizeof(color)/sizeof(color[0]); i++) {
color[i] = 0xff00ffff;
}
// XXX If we pass the data directly at texture creation time we
// get a crash on Intel 8.5.10.[18xx-1994] drivers.
// We can work around this issue by doing UpdateSubresource.
if (!TryCreateTexture2D(device, &desc, nullptr, texture)) {
gfxCriticalNote << "DoesD3D11TextureSharingWork_TryCreateTextureFailure";
return false;
}
RefPtr<IDXGIKeyedMutex> sourceSharedMutex;
texture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sourceSharedMutex));
if (FAILED(sourceSharedMutex->AcquireSync(0, 30*1000))) {
gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceMutexTimeout";
// only wait for 30 seconds
return false;
}
RefPtr<ID3D11DeviceContext> deviceContext;
device->GetImmediateContext(getter_AddRefs(deviceContext));
int stride = texture_size * 4;
deviceContext->UpdateSubresource(texture, 0, nullptr, color, stride, stride * texture_size);
if (FAILED(sourceSharedMutex->ReleaseSync(0))) {
gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceReleaseSyncTimeout";
return false;
}
HANDLE shareHandle;
RefPtr<IDXGIResource> otherResource;
if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
getter_AddRefs(otherResource))))
{
gfxCriticalError() << "DoesD3D11TextureSharingWork_GetResourceFailure";
return false;
}
if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
return false;
}
RefPtr<ID3D11Resource> sharedResource;
RefPtr<ID3D11Texture2D> sharedTexture;
if (FAILED(device->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
getter_AddRefs(sharedResource))))
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "OpenSharedResource failed for format " << format;
return false;
}
if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
getter_AddRefs(sharedTexture))))
{
gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
return false;
}
// create a staging texture for readback
RefPtr<ID3D11Texture2D> cpuTexture;
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
desc.BindFlags = 0;
if (FAILED(device->CreateTexture2D(&desc, nullptr, getter_AddRefs(cpuTexture)))) {
gfxCriticalError() << "DoesD3D11TextureSharingWork_CreateTextureFailure";
return false;
}
RefPtr<IDXGIKeyedMutex> sharedMutex;
sharedResource->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sharedMutex));
if (FAILED(sharedMutex->AcquireSync(0, 30*1000))) {
gfxCriticalError() << "DoesD3D11TextureSharingWork_AcquireSyncTimeout";
// only wait for 30 seconds
return false;
}
// Copy to the cpu texture so that we can readback
deviceContext->CopyResource(cpuTexture, sharedTexture);
D3D11_MAPPED_SUBRESOURCE mapped;
int resultColor = 0;
if (SUCCEEDED(deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped))) {
// read the texture
resultColor = *(int*)mapped.pData;
deviceContext->Unmap(cpuTexture, 0);
} else {
gfxCriticalError() << "DoesD3D11TextureSharingWork_MapFailed";
return false;
}
sharedMutex->ReleaseSync(0);
// check that the color we put in is the color we get out
if (resultColor != color[0]) {
// Shared surfaces seem to be broken on dual AMD & Intel HW when using the
// AMD GPU
gfxCriticalNote << "DoesD3D11TextureSharingWork_ColorMismatch";
return false;
}
RefPtr<ID3D11ShaderResourceView> sharedView;
// This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, getter_AddRefs(sharedView)))) {
gfxCriticalNote << "CreateShaderResourceView failed for format" << format;
return false;
}
return true;
}
/* static */ bool
D3D11Checks::DoesTextureSharingWork(ID3D11Device *device)
{
return DoesTextureSharingWorkInternal(device, DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
}
/* static */ bool
D3D11Checks::DoesAlphaTextureSharingWork(ID3D11Device *device)
{
return DoesTextureSharingWorkInternal(device, DXGI_FORMAT_R8_UNORM, D3D11_BIND_SHADER_RESOURCE);
}
/* static */ bool
D3D11Checks::GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out)
{
RefPtr<IDXGIDevice> dxgiDevice;
HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), getter_AddRefs(dxgiDevice));
if (FAILED(hr)) {
return false;
}
RefPtr<IDXGIAdapter> dxgiAdapter;
if (FAILED(dxgiDevice->GetAdapter(getter_AddRefs(dxgiAdapter)))) {
return false;
}
return SUCCEEDED(dxgiAdapter->GetDesc(out));
}
/* static */ void
D3D11Checks::WarnOnAdapterMismatch(ID3D11Device *device)
{
DXGI_ADAPTER_DESC desc;
PodZero(&desc);
GetDxgiDesc(device, &desc);
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
nsString vendorID;
gfxInfo->GetAdapterVendorID(vendorID);
nsresult ec;
int32_t vendor = vendorID.ToInteger(&ec, 16);
if (vendor != desc.VendorId) {
gfxCriticalNote << "VendorIDMismatch V " << hexa(vendor) << " " << hexa(desc.VendorId);
}
}
} // namespace gfx
} // namespace mozilla

28
gfx/thebes/D3D11Checks.h Normal file
View File

@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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/. */
#ifndef mozilla_gfx_thebes_D3D11Checks_h
#define mozilla_gfx_thebes_D3D11Checks_h
struct ID3D11Device;
struct DXGI_ADAPTER_DESC;
namespace mozilla {
namespace gfx {
struct D3D11Checks
{
static bool DoesRenderTargetViewNeedRecreating(ID3D11Device* aDevice);
static bool DoesDeviceWork();
static bool DoesTextureSharingWork(ID3D11Device *device);
static bool DoesAlphaTextureSharingWork(ID3D11Device *device);
static void WarnOnAdapterMismatch(ID3D11Device* device);
static bool GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out);
};
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_thebes_D3D11Checks_h

View File

@ -0,0 +1,678 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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 "DeviceManagerD3D11.h"
#include "D3D11Checks.h"
#include "gfxConfig.h"
#include "GfxDriverInfo.h"
#include "gfxPrefs.h"
#include "gfxWindowsPlatform.h"
#include "mozilla/D3DMessageUtils.h"
#include "mozilla/Telemetry.h"
#include "mozilla/WindowsVersion.h"
#include "mozilla/gfx/GraphicsMessages.h"
#include "mozilla/gfx/Logging.h"
#include "nsIGfxInfo.h"
#include "nsWindowsHelpers.h"
#include <d3d11.h>
namespace mozilla {
namespace gfx {
using namespace mozilla::widget;
StaticAutoPtr<DeviceManagerD3D11> DeviceManagerD3D11::sInstance;
// We don't have access to the D3D11CreateDevice type in gfxWindowsPlatform.h,
// since it doesn't include d3d11.h, so we use a static here. It should only
// be used within InitializeD3D11.
decltype(D3D11CreateDevice)* sD3D11CreateDeviceFn = nullptr;
/* static */ void
DeviceManagerD3D11::Init()
{
sInstance = new DeviceManagerD3D11();
}
/* static */ void
DeviceManagerD3D11::Shutdown()
{
sInstance = nullptr;
}
DeviceManagerD3D11::DeviceManagerD3D11()
: mDeviceLock("gfxWindowsPlatform.mDeviceLock"),
mIsWARP(false),
mTextureSharingWorks(false)
{
// Set up the D3D11 feature levels we can ask for.
if (IsWin8OrLater()) {
mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_1);
}
mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_11_0);
mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_1);
mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
mFeatureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
}
static inline bool
IsWARPStable()
{
// It seems like nvdxgiwrap makes a mess of WARP. See bug 1154703.
if (!IsWin8OrLater() || GetModuleHandleA("nvdxgiwrap.dll")) {
return false;
}
return true;
}
bool
DeviceManagerD3D11::CanUseD3D11ImageBridge()
{
if (XRE_IsContentProcess()) {
if (!gfxPlatform::GetPlatform()->GetParentDevicePrefs().useD3D11ImageBridge()) {
return false;
}
}
return !mIsWARP;
}
void
DeviceManagerD3D11::CreateDevices()
{
FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
MOZ_ASSERT(d3d11.IsEnabled());
nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll"));
sD3D11CreateDeviceFn =
(decltype(D3D11CreateDevice)*)GetProcAddress(d3d11Module, "D3D11CreateDevice");
if (!sD3D11CreateDeviceFn) {
// We should just be on Windows Vista or XP in this case.
d3d11.SetFailed(FeatureStatus::Unavailable, "Direct3D11 not available on this computer",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_LIB"));
return;
}
// Check if a failure was injected for testing.
if (gfxPrefs::DeviceFailForTesting()) {
d3d11.SetFailed(FeatureStatus::Failed, "Direct3D11 device failure simulated by preference",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_SIM"));
return;
}
if (XRE_IsParentProcess()) {
if (!gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
AttemptD3D11DeviceCreation(d3d11);
if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
return;
}
// If we failed to get a device, but WARP is allowed and might work,
// re-enable D3D11 and switch to WARP.
if (!mCompositorDevice && IsWARPStable() && !gfxPrefs::LayersD3D11DisableWARP()) {
gfxConfig::Reenable(Feature::D3D11_COMPOSITING, Fallback::USE_D3D11_WARP_COMPOSITOR);
}
}
// If that failed, see if we can use WARP.
if (gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR)) {
MOZ_ASSERT(d3d11.IsEnabled());
MOZ_ASSERT(!mCompositorDevice);
MOZ_ASSERT(IsWARPStable() || gfxPrefs::LayersD3D11ForceWARP());
AttemptWARPDeviceCreation();
if (d3d11.GetValue() == FeatureStatus::CrashedInHandler) {
return;
}
}
// If we still have no device by now, exit.
if (!mCompositorDevice) {
MOZ_ASSERT(!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING));
return;
}
// Either device creation function should have returned Available.
MOZ_ASSERT(d3d11.IsEnabled());
} else {
// Child processes do not need a compositor, but they do need to know
// whether the parent process is using WARP and whether or not texture
// sharing works.
mIsWARP = gfxConfig::UseFallback(Fallback::USE_D3D11_WARP_COMPOSITOR);
mTextureSharingWorks =
gfxPlatform::GetPlatform()->GetParentDevicePrefs().d3d11TextureSharingWorks();
}
if (CanUseD3D11ImageBridge()) {
if (AttemptD3D11ImageBridgeDeviceCreation() == FeatureStatus::CrashedInHandler) {
DisableD3D11AfterCrash();
return;
}
}
if (AttemptD3D11ContentDeviceCreation() == FeatureStatus::CrashedInHandler) {
DisableD3D11AfterCrash();
return;
}
// We leak these everywhere and we need them our entire runtime anyway, let's
// leak it here as well. We keep the pointer to sD3D11CreateDeviceFn around
// as well for D2D1 and device resets.
d3d11Module.disown();
}
IDXGIAdapter1*
DeviceManagerD3D11::GetDXGIAdapter()
{
if (mAdapter) {
return mAdapter;
}
nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
decltype(CreateDXGIFactory1)* createDXGIFactory1 = (decltype(CreateDXGIFactory1)*)
GetProcAddress(dxgiModule, "CreateDXGIFactory1");
if (!createDXGIFactory1) {
return nullptr;
}
// Try to use a DXGI 1.1 adapter in order to share resources
// across processes.
RefPtr<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 nullptr;
}
if (!XRE_IsContentProcess()) {
// In the parent process, we pick the first adapter.
if (FAILED(factory1->EnumAdapters1(0, getter_AddRefs(mAdapter)))) {
return nullptr;
}
} else {
const DxgiAdapterDesc& parent =
gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
// In the child process, we search for the adapter that matches the parent
// process. The first adapter can be mismatched on dual-GPU systems.
for (UINT index = 0; ; index++) {
RefPtr<IDXGIAdapter1> adapter;
if (FAILED(factory1->EnumAdapters1(index, getter_AddRefs(adapter)))) {
break;
}
DXGI_ADAPTER_DESC desc;
if (SUCCEEDED(adapter->GetDesc(&desc)) &&
desc.AdapterLuid.HighPart == parent.AdapterLuid.HighPart &&
desc.AdapterLuid.LowPart == parent.AdapterLuid.LowPart &&
desc.VendorId == parent.VendorId &&
desc.DeviceId == parent.DeviceId)
{
mAdapter = adapter.forget();
break;
}
}
}
if (!mAdapter) {
return nullptr;
}
// We leak this module everywhere, we might as well do so here as well.
dxgiModule.disown();
return mAdapter;
}
bool
DeviceManagerD3D11::AttemptD3D11DeviceCreationHelper(
IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aOutDevice, HRESULT& aResOut)
{
MOZ_SEH_TRY {
aResOut =
sD3D11CreateDeviceFn(
aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
// Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
// to prevent bug 1092260. IE 11 also uses this flag.
D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
mFeatureLevels.Elements(), mFeatureLevels.Length(),
D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
} MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
return false;
}
return true;
}
void
DeviceManagerD3D11::AttemptD3D11DeviceCreation(FeatureState& d3d11)
{
RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
if (!adapter) {
d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGI"));
return;
}
HRESULT hr;
RefPtr<ID3D11Device> device;
if (!AttemptD3D11DeviceCreationHelper(adapter, device, hr)) {
gfxCriticalError() << "Crash during D3D11 device creation";
d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed trying to acquire a D3D11 device",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE1"));
return;
}
if (FAILED(hr) || !device) {
gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr);
d3d11.SetFailed(FeatureStatus::Failed, "Failed to acquire a D3D11 device",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DEVICE2"));
return;
}
if (!D3D11Checks::DoesDeviceWork()) {
d3d11.SetFailed(FeatureStatus::Broken, "Direct3D11 device was determined to be broken",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_BROKEN"));
return;
}
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
}
// Only test this when not using WARP since it can fail and cause
// GetDeviceRemovedReason to return weird values.
mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
if (!mTextureSharingWorks) {
gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
FeatureStatus::Broken,
"Texture sharing doesn't work");
}
if (D3D11Checks::DoesRenderTargetViewNeedRecreating(mCompositorDevice)) {
gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
FeatureStatus::Broken,
"RenderTargetViews need recreating");
}
// It seems like this may only happen when we're using the NVIDIA gpu
D3D11Checks::WarnOnAdapterMismatch(mCompositorDevice);
mCompositorDevice->SetExceptionMode(0);
mIsWARP = false;
}
bool
DeviceManagerD3D11::AttemptWARPDeviceCreationHelper(
ScopedGfxFeatureReporter& aReporterWARP,
RefPtr<ID3D11Device>& aOutDevice,
HRESULT& aResOut)
{
MOZ_SEH_TRY {
aResOut =
sD3D11CreateDeviceFn(
nullptr, D3D_DRIVER_TYPE_WARP, nullptr,
// Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
// to prevent bug 1092260. IE 11 also uses this flag.
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
mFeatureLevels.Elements(), mFeatureLevels.Length(),
D3D11_SDK_VERSION, getter_AddRefs(aOutDevice), nullptr, nullptr);
aReporterWARP.SetSuccessful();
} MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
return false;
}
return true;
}
void
DeviceManagerD3D11::AttemptWARPDeviceCreation()
{
ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP());
FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
HRESULT hr;
RefPtr<ID3D11Device> device;
if (!AttemptWARPDeviceCreationHelper(reporterWARP, device, hr)) {
gfxCriticalError() << "Exception occurred initializing WARP D3D11 device!";
d3d11.SetFailed(FeatureStatus::CrashedInHandler, "Crashed creating a D3D11 WARP device",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE"));
return;
}
if (FAILED(hr) || !device) {
// This should always succeed... in theory.
gfxCriticalError() << "Failed to initialize WARP D3D11 device! " << hexa(hr);
d3d11.SetFailed(FeatureStatus::Failed, "Failed to create a D3D11 WARP device",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_WARP_DEVICE2"));
return;
}
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
}
// Only test for texture sharing on Windows 8 since it puts the device into
// an unusable state if used on Windows 7
if (IsWin8OrLater()) {
mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
}
mCompositorDevice->SetExceptionMode(0);
mIsWARP = true;
}
bool
DeviceManagerD3D11::AttemptD3D11ContentDeviceCreationHelper(
IDXGIAdapter1* aAdapter, HRESULT& aResOut)
{
MOZ_SEH_TRY {
aResOut =
sD3D11CreateDeviceFn(
aAdapter, mIsWARP ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_UNKNOWN,
nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
mFeatureLevels.Elements(), mFeatureLevels.Length(),
D3D11_SDK_VERSION, getter_AddRefs(mContentDevice), nullptr, nullptr);
} MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
return false;
}
return true;
}
FeatureStatus
DeviceManagerD3D11::AttemptD3D11ContentDeviceCreation()
{
RefPtr<IDXGIAdapter1> adapter;
if (!mIsWARP) {
adapter = GetDXGIAdapter();
if (!adapter) {
return FeatureStatus::Unavailable;
}
}
HRESULT hr;
if (!AttemptD3D11ContentDeviceCreationHelper(adapter, hr)) {
gfxCriticalNote << "Recovered from crash while creating a D3D11 content device";
gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
return FeatureStatus::CrashedInHandler;
}
if (FAILED(hr) || !mContentDevice) {
gfxCriticalNote << "Failed to create a D3D11 content device: " << hexa(hr);
gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
return FeatureStatus::Failed;
}
// InitializeD2D() will abort early if the compositor device did not support
// texture sharing. If we're in the content process, we can't rely on the
// parent device alone: some systems have dual GPUs that are capable of
// binding the parent and child processes to different GPUs. As a safety net,
// we re-check texture sharing against the newly created D3D11 content device.
// If it fails, we won't use Direct2D.
if (XRE_IsContentProcess()) {
if (!D3D11Checks::DoesTextureSharingWork(mContentDevice)) {
mContentDevice = nullptr;
return FeatureStatus::Failed;
}
DebugOnly<bool> ok = ContentAdapterIsParentAdapter(mContentDevice);
MOZ_ASSERT(ok);
}
mContentDevice->SetExceptionMode(0);
RefPtr<ID3D10Multithread> multi;
hr = mContentDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
if (SUCCEEDED(hr) && multi) {
multi->SetMultithreadProtected(TRUE);
}
return FeatureStatus::Available;
}
bool
DeviceManagerD3D11::AttemptD3D11ImageBridgeDeviceCreationHelper(
IDXGIAdapter1* aAdapter,
HRESULT& aResOut)
{
MOZ_SEH_TRY {
aResOut =
sD3D11CreateDeviceFn(GetDXGIAdapter(), D3D_DRIVER_TYPE_UNKNOWN, nullptr,
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
mFeatureLevels.Elements(), mFeatureLevels.Length(),
D3D11_SDK_VERSION, getter_AddRefs(mImageBridgeDevice), nullptr, nullptr);
} MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
return false;
}
return true;
}
FeatureStatus
DeviceManagerD3D11::AttemptD3D11ImageBridgeDeviceCreation()
{
HRESULT hr;
if (!AttemptD3D11ImageBridgeDeviceCreationHelper(GetDXGIAdapter(), hr)) {
gfxCriticalNote << "Recovered from crash while creating a D3D11 image bridge device";
gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Image);
return FeatureStatus::CrashedInHandler;
}
if (FAILED(hr) || !mImageBridgeDevice) {
gfxCriticalNote << "Failed to create a content image bridge device: " << hexa(hr);
gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Image);
return FeatureStatus::Failed;
}
mImageBridgeDevice->SetExceptionMode(0);
if (!D3D11Checks::DoesAlphaTextureSharingWork(mImageBridgeDevice)) {
mImageBridgeDevice = nullptr;
return FeatureStatus::Failed;
}
if (XRE_IsContentProcess()) {
ContentAdapterIsParentAdapter(mImageBridgeDevice);
}
return FeatureStatus::Available;
}
bool
DeviceManagerD3D11::CreateD3D11DecoderDeviceHelper(
IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice, HRESULT& aResOut)
{
MOZ_SEH_TRY{
aResOut =
sD3D11CreateDeviceFn(
aAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
mFeatureLevels.Elements(), mFeatureLevels.Length(),
D3D11_SDK_VERSION, getter_AddRefs(aDevice), nullptr, nullptr);
} MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
return false;
}
return true;
}
RefPtr<ID3D11Device>
DeviceManagerD3D11::CreateDecoderDevice()
{
if (!sD3D11CreateDeviceFn) {
// We should just be on Windows Vista or XP in this case.
return nullptr;
}
RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
if (!adapter) {
return nullptr;
}
RefPtr<ID3D11Device> device;
HRESULT hr;
if (!CreateD3D11DecoderDeviceHelper(adapter, device, hr)) {
return nullptr;
}
if (FAILED(hr) || !device || !D3D11Checks::DoesDeviceWork()) {
return nullptr;
}
RefPtr<ID3D10Multithread> multi;
device->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
multi->SetMultithreadProtected(TRUE);
return device;
}
void
DeviceManagerD3D11::ResetDevices()
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = nullptr;
mContentDevice = nullptr;
mImageBridgeDevice = nullptr;
Factory::SetDirect3D11Device(nullptr);
}
bool
DeviceManagerD3D11::ContentAdapterIsParentAdapter(ID3D11Device* device)
{
DXGI_ADAPTER_DESC desc;
if (!D3D11Checks::GetDxgiDesc(device, &desc)) {
gfxCriticalNote << "Could not query device DXGI adapter info";
return false;
}
const DxgiAdapterDesc& parent =
gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
if (desc.VendorId != parent.VendorId ||
desc.DeviceId != parent.DeviceId ||
desc.SubSysId != parent.SubSysId ||
desc.AdapterLuid.HighPart != parent.AdapterLuid.HighPart ||
desc.AdapterLuid.LowPart != parent.AdapterLuid.LowPart)
{
gfxCriticalNote << "VendorIDMismatch P " << hexa(parent.VendorId) << " " << hexa(desc.VendorId);
return false;
}
return true;
}
static DeviceResetReason HResultToResetReason(HRESULT hr)
{
switch (hr) {
case DXGI_ERROR_DEVICE_HUNG:
return DeviceResetReason::HUNG;
case DXGI_ERROR_DEVICE_REMOVED:
return DeviceResetReason::REMOVED;
case DXGI_ERROR_DEVICE_RESET:
return DeviceResetReason::RESET;
case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
return DeviceResetReason::DRIVER_ERROR;
case DXGI_ERROR_INVALID_CALL:
return DeviceResetReason::INVALID_CALL;
case E_OUTOFMEMORY:
return DeviceResetReason::OUT_OF_MEMORY;
default:
MOZ_ASSERT(false);
}
return DeviceResetReason::UNKNOWN;
}
static inline bool
DidDeviceReset(RefPtr<ID3D11Device> aDevice, DeviceResetReason* aOutReason)
{
if (!aDevice) {
return false;
}
HRESULT hr = aDevice->GetDeviceRemovedReason();
if (hr == S_OK) {
return false;
}
*aOutReason = HResultToResetReason(hr);
return true;
}
bool
DeviceManagerD3D11::GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason)
{
// Note: this can be called off the main thread, so we need to use
// our threadsafe getters.
if (DidDeviceReset(GetCompositorDevice(), aOutReason) ||
DidDeviceReset(GetImageBridgeDevice(), aOutReason) ||
DidDeviceReset(GetContentDevice(), aOutReason))
{
return true;
}
return false;
}
void
DeviceManagerD3D11::DisableD3D11AfterCrash()
{
gfxConfig::Disable(Feature::D3D11_COMPOSITING,
FeatureStatus::CrashedInHandler,
"Crashed while acquiring a Direct3D11 device",
NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_CRASH"));
ResetDevices();
}
RefPtr<ID3D11Device>
DeviceManagerD3D11::GetCompositorDevice()
{
MutexAutoLock lock(mDeviceLock);
return mCompositorDevice;
}
RefPtr<ID3D11Device>
DeviceManagerD3D11::GetImageBridgeDevice()
{
MutexAutoLock lock(mDeviceLock);
return mImageBridgeDevice;
}
RefPtr<ID3D11Device>
DeviceManagerD3D11::GetContentDevice()
{
MOZ_ASSERT(NS_IsMainThread());
return mContentDevice;
}
RefPtr<ID3D11Device>
DeviceManagerD3D11::GetDeviceForCurrentThread()
{
if (NS_IsMainThread()) {
return GetContentDevice();
}
return GetCompositorDevice();
}
unsigned
DeviceManagerD3D11::GetD3D11Version() const
{
MOZ_ASSERT(NS_IsMainThread());
if (!mCompositorDevice) {
return 0;
}
return mCompositorDevice->GetFeatureLevel();
}
bool
DeviceManagerD3D11::TextureSharingWorks() const
{
return mTextureSharingWorks;
}
bool
DeviceManagerD3D11::IsWARP() const
{
return mIsWARP;
}
} // namespace gfx
} // namespace mozilla

View File

@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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/. */
#ifndef mozilla_gfx_thebes_DeviceManagerD3D11_h
#define mozilla_gfx_thebes_DeviceManagerD3D11_h
#include "gfxPlatform.h"
#include "gfxTelemetry.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h"
#include "nsTArray.h"
#include <windows.h>
#include <objbase.h>
#include <dxgi.h>
// This header is available in the June 2010 SDK and in the Win8 SDK
#include <d3dcommon.h>
// Win 8.0 SDK types we'll need when building using older sdks.
#if !defined(D3D_FEATURE_LEVEL_11_1) // defined in the 8.0 SDK only
#define D3D_FEATURE_LEVEL_11_1 static_cast<D3D_FEATURE_LEVEL>(0xb100)
#define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
#endif
struct ID3D11Device;
namespace mozilla {
class ScopedGfxFeatureReporter;
namespace gfx {
class FeatureState;
class DeviceManagerD3D11 final
{
public:
static void Init();
static void Shutdown();
DeviceManagerD3D11();
static DeviceManagerD3D11* Get() {
return sInstance;
}
RefPtr<ID3D11Device> GetCompositorDevice();
RefPtr<ID3D11Device> GetImageBridgeDevice();
RefPtr<ID3D11Device> GetContentDevice();
RefPtr<ID3D11Device> GetDeviceForCurrentThread();
RefPtr<ID3D11Device> CreateDecoderDevice();
unsigned GetD3D11Version() const;
bool TextureSharingWorks() const;
bool IsWARP() const;
void CreateDevices();
void ResetDevices();
// Call GetDeviceRemovedReason on each device until one returns
// a failure.
bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason);
private:
IDXGIAdapter1 *GetDXGIAdapter();
bool CanUseD3D11ImageBridge();
void DisableD3D11AfterCrash();
void AttemptD3D11DeviceCreation(mozilla::gfx::FeatureState& d3d11);
bool AttemptD3D11DeviceCreationHelper(
IDXGIAdapter1* aAdapter,
RefPtr<ID3D11Device>& aOutDevice,
HRESULT& aResOut);
void AttemptWARPDeviceCreation();
bool AttemptWARPDeviceCreationHelper(
mozilla::ScopedGfxFeatureReporter& aReporterWARP,
RefPtr<ID3D11Device>& aOutDevice,
HRESULT& aResOut);
bool AttemptD3D11ImageBridgeDeviceCreationHelper(
IDXGIAdapter1* aAdapter, HRESULT& aResOut);
mozilla::gfx::FeatureStatus AttemptD3D11ImageBridgeDeviceCreation();
mozilla::gfx::FeatureStatus AttemptD3D11ContentDeviceCreation();
bool AttemptD3D11ContentDeviceCreationHelper(
IDXGIAdapter1* aAdapter, HRESULT& aResOut);
// Create a D3D11 device to be used for DXVA decoding.
bool CreateD3D11DecoderDeviceHelper(
IDXGIAdapter1* aAdapter, RefPtr<ID3D11Device>& aDevice,
HRESULT& aResOut);
bool ContentAdapterIsParentAdapter(ID3D11Device* device);
private:
static StaticAutoPtr<DeviceManagerD3D11> sInstance;
mozilla::Mutex mDeviceLock;
nsTArray<D3D_FEATURE_LEVEL> mFeatureLevels;
RefPtr<IDXGIAdapter1> mAdapter;
RefPtr<ID3D11Device> mCompositorDevice;
RefPtr<ID3D11Device> mContentDevice;
RefPtr<ID3D11Device> mImageBridgeDevice;
mozilla::Atomic<bool> mIsWARP;
mozilla::Atomic<bool> mTextureSharingWorks;
};
} // namespace gfx
} // namespace mozilla
#endif // mozilla_gfx_thebes_DeviceManagerD3D11_h

View File

@ -26,6 +26,7 @@
#if XP_WIN
#include "gfxWindowsPlatform.h"
#include "mozilla/gfx/DeviceManagerD3D11.h"
#endif
using namespace mozilla;
@ -1242,7 +1243,8 @@ gfxContext::PushNewDT(gfxContentType content)
if (!newDT) {
if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()
#ifdef XP_WIN
&& !(mDT->GetBackendType() == BackendType::DIRECT2D1_1 && !gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice())
&& !(mDT->GetBackendType() == BackendType::DIRECT2D1_1 &&
!DeviceManagerD3D11::Get()->GetContentDevice())
#endif
) {
// If even this fails.. we're most likely just out of memory!

View File

@ -1778,3 +1778,8 @@ gfxFontUtils::IsCffFont(const uint8_t* aFontData)
#endif
#undef acceptablePlatform
#undef isSymbol
#undef isUVSEncoding
#undef LOG
#undef LOG_ENABLED

Some files were not shown because too many files have changed in this diff Show More