зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
bd055a6272
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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])
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
)
|
|
@ -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
|
||||
])
|
|
@ -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')
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
)
|
|
@ -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',
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
},
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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(() => {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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" },
|
||||
];
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
////////////////////////////////////
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
{ }
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -116,6 +116,8 @@ public:
|
|||
|
||||
void NotifyCueUpdated(TextTrackCue *aCue);
|
||||
|
||||
void DispatchAsyncTrustedEvent(const nsString& aEventName);
|
||||
|
||||
private:
|
||||
~TextTrack();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -148,4 +148,10 @@ KeySystemToGMPName(const nsAString& aKeySystem)
|
|||
return EmptyString();
|
||||
}
|
||||
|
||||
bool
|
||||
IsClearkeyKeySystem(const nsAString& aKeySystem)
|
||||
{
|
||||
return aKeySystem.EqualsLiteral("org.w3.clearkey");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace mozilla {
|
|||
class WidevineVideoFrame : public cdm::VideoFrame {
|
||||
public:
|
||||
WidevineVideoFrame();
|
||||
WidevineVideoFrame(WidevineVideoFrame&& other);
|
||||
~WidevineVideoFrame();
|
||||
|
||||
void SetFormat(cdm::VideoFormat aFormat) override;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 =
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>() {};
|
||||
};
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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!
|
||||
|
|
|
@ -1778,3 +1778,8 @@ gfxFontUtils::IsCffFont(const uint8_t* aFontData)
|
|||
|
||||
#endif
|
||||
|
||||
#undef acceptablePlatform
|
||||
#undef isSymbol
|
||||
#undef isUVSEncoding
|
||||
#undef LOG
|
||||
#undef LOG_ENABLED
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче