diff --git a/Makefile.in b/Makefile.in index 2edf0b60d33c..63278051faa6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -328,7 +328,8 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk3) toolkit/library/target: widget/gtk/mozgtk/gtk3/target endif ifdef MOZ_LDAP_XPCOM -toolkit/library/target: ../ldap/target +ldap/target: config/external/nss/target mozglue/build/target +toolkit/library/target: ldap/target endif ifndef MOZ_FOLD_LIBS ifndef MOZ_NATIVE_SQLITE diff --git a/accessible/base/DocManager.cpp b/accessible/base/DocManager.cpp index 52bc77b171a9..eed51d5ca01a 100644 --- a/accessible/base/DocManager.cpp +++ b/accessible/base/DocManager.cpp @@ -37,7 +37,7 @@ using namespace mozilla::dom; //////////////////////////////////////////////////////////////////////////////// DocManager::DocManager() - : mDocAccessibleCache(4) + : mDocAccessibleCache(2) { } diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index c57d25f00ce0..671cef026cdb 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -78,8 +78,8 @@ DocAccessible:: nsIPresShell* aPresShell) : HyperTextAccessibleWrap(aRootContent, this), // XXX aaronl should we use an algorithm for the initial cache size? - mAccessibleCache(kDefaultCacheSize), - mNodeToAccessibleMap(kDefaultCacheSize), + mAccessibleCache(kDefaultCacheLength), + mNodeToAccessibleMap(kDefaultCacheLength), mDocumentNode(aDocument), mScrollPositionChangedTicks(0), mLoadState(eTreeConstructionPending), mDocFlags(0), mLoadEventType(0), diff --git a/accessible/generic/DocAccessible.h b/accessible/generic/DocAccessible.h index 0588a49d32c6..4c9b9bf41f41 100644 --- a/accessible/generic/DocAccessible.h +++ b/accessible/generic/DocAccessible.h @@ -26,7 +26,7 @@ class nsAccessiblePivot; class nsIScrollableView; -const uint32_t kDefaultCacheSize = 256; +const uint32_t kDefaultCacheLength = 128; namespace mozilla { namespace a11y { diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 4b1e8684d607..96f09f3fb21e 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -1546,7 +1546,9 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset, int16_t hPercent = offsetPointX * 100 / size.width; int16_t vPercent = offsetPointY * 100 / size.height; - nsresult rv = nsCoreUtils::ScrollSubstringTo(frame, range, vPercent, hPercent); + nsresult rv = nsCoreUtils::ScrollSubstringTo(frame, range, + nsIPresShell::ScrollAxis(vPercent), + nsIPresShell::ScrollAxis(hPercent)); if (NS_FAILED(rv)) return; diff --git a/accessible/windows/msaa/nsWinUtils.cpp b/accessible/windows/msaa/nsWinUtils.cpp index bafe0d46a808..3cdfc75a669e 100644 --- a/accessible/windows/msaa/nsWinUtils.cpp +++ b/accessible/windows/msaa/nsWinUtils.cpp @@ -61,7 +61,7 @@ nsWinUtils::MaybeStartWindowEmulation() Compatibility::IsDolphin() || XRE_GetProcessType() == GeckoProcessType_Content) { RegisterNativeWindow(kClassNameTabContent); - sHWNDCache = new nsRefPtrHashtable, DocAccessible>(4); + sHWNDCache = new nsRefPtrHashtable, DocAccessible>(2); return true; } diff --git a/accessible/xul/XULTreeAccessible.cpp b/accessible/xul/XULTreeAccessible.cpp index 64fb2300173d..202b0d497624 100644 --- a/accessible/xul/XULTreeAccessible.cpp +++ b/accessible/xul/XULTreeAccessible.cpp @@ -42,7 +42,7 @@ XULTreeAccessible:: XULTreeAccessible(nsIContent* aContent, DocAccessible* aDoc, nsTreeBodyFrame* aTreeFrame) : AccessibleWrap(aContent, aDoc), - mAccessibleCache(kDefaultTreeCacheSize) + mAccessibleCache(kDefaultTreeCacheLength) { mType = eXULTreeType; mGenericTypes |= eSelect; diff --git a/accessible/xul/XULTreeAccessible.h b/accessible/xul/XULTreeAccessible.h index 0234ef1eb9aa..3efc9ba89365 100644 --- a/accessible/xul/XULTreeAccessible.h +++ b/accessible/xul/XULTreeAccessible.h @@ -20,7 +20,7 @@ namespace a11y { * A class the represents the XUL Tree widget. */ const uint32_t kMaxTreeColumns = 100; -const uint32_t kDefaultTreeCacheSize = 256; +const uint32_t kDefaultTreeCacheLength = 128; /** * Accessible class for XUL tree element. diff --git a/accessible/xul/XULTreeGridAccessible.cpp b/accessible/xul/XULTreeGridAccessible.cpp index 5b17b18b3956..4a6deba251e8 100644 --- a/accessible/xul/XULTreeGridAccessible.cpp +++ b/accessible/xul/XULTreeGridAccessible.cpp @@ -261,7 +261,7 @@ XULTreeGridRowAccessible:: Accessible* aTreeAcc, nsITreeBoxObject* aTree, nsITreeView* aTreeView, int32_t aRow) : XULTreeItemAccessibleBase(aContent, aDoc, aTreeAcc, aTree, aTreeView, aRow), - mAccessibleCache(kDefaultTreeCacheSize) + mAccessibleCache(kDefaultTreeCacheLength) { mGenericTypes |= eTableRow; } diff --git a/b2g/components/ContentPermissionPrompt.js b/b2g/components/ContentPermissionPrompt.js index df882afe570b..4f4e7ea44263 100644 --- a/b2g/components/ContentPermissionPrompt.js +++ b/b2g/components/ContentPermissionPrompt.js @@ -237,7 +237,6 @@ ContentPermissionPrompt.prototype = { return false; }, - _id: 0, prompt: function(request) { // Initialize the typesInfo and set the default value. let typesInfo = []; @@ -294,10 +293,9 @@ ContentPermissionPrompt.prototype = { }); let frame = request.element; - let requestId = this._id++; if (!frame) { - this.delegatePrompt(request, requestId, typesInfo); + this.delegatePrompt(request, typesInfo); return; } @@ -312,7 +310,7 @@ ContentPermissionPrompt.prototype = { if (evt.detail.visible === true) return; - self.cancelPrompt(request, requestId, typesInfo); + self.cancelPrompt(request, typesInfo); cancelRequest(); } @@ -329,7 +327,7 @@ ContentPermissionPrompt.prototype = { // away but the request is still here. frame.addEventListener("mozbrowservisibilitychange", onVisibilityChange); - self.delegatePrompt(request, requestId, typesInfo, function onCallback() { + self.delegatePrompt(request, typesInfo, function onCallback() { frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange); }); }; @@ -340,14 +338,13 @@ ContentPermissionPrompt.prototype = { } }, - cancelPrompt: function(request, requestId, typesInfo) { - this.sendToBrowserWindow("cancel-permission-prompt", request, requestId, + cancelPrompt: function(request, typesInfo) { + this.sendToBrowserWindow("cancel-permission-prompt", request, typesInfo); }, - delegatePrompt: function(request, requestId, typesInfo, callback) { - - this.sendToBrowserWindow("permission-prompt", request, requestId, typesInfo, + delegatePrompt: function(request, typesInfo, callback) { + this.sendToBrowserWindow("permission-prompt", request, typesInfo, function(type, remember, choices) { if (type == "permission-allow") { rememberPermission(typesInfo, request.principal, !remember); @@ -371,16 +368,26 @@ ContentPermissionPrompt.prototype = { 0); } } - typesInfo.forEach(addDenyPermission); + try { + // This will trow if we are canceling because the remote process died. + // Just eat the exception and call the callback that will cleanup the + // visibility event listener. + typesInfo.forEach(addDenyPermission); + } catch(e) { } if (callback) { callback(); } - request.cancel(); + + try { + request.cancel(); + } catch(e) { } }); }, - sendToBrowserWindow: function(type, request, requestId, typesInfo, callback) { + sendToBrowserWindow: function(type, request, typesInfo, callback) { + let requestId = Cc["@mozilla.org/uuid-generator;1"] + .getService(Ci.nsIUUIDGenerator).generateUUID().toString(); if (callback) { SystemAppProxy.addEventListener("mozContentEvent", function contentEvent(evt) { let detail = evt.detail; diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 2719dda34011..65aed14b22ab 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,8 +19,8 @@ - - + + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 16e4857dc92c..e38654a53a41 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,8 +17,8 @@ - - + + @@ -133,7 +133,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 0a73b8111092..cfb1c035a708 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,9 +15,9 @@ - + - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 2719dda34011..65aed14b22ab 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,8 +19,8 @@ - - + + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 66d3eb9c1a3a..a661e3ae51e0 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,8 +17,8 @@ - - + + @@ -145,7 +145,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 403518b056f2..d27f8488391f 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "41b3413a893fef684b380bb344f9d4a5f491f858", + "revision": "8d2554880efe6011591aa8055e3cc8989559ce0a", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index a41c0c3cb855..ea4a7092ff18 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,8 +17,8 @@ - - + + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index bcdba27aaf6e..afdf4d050ad1 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,8 +15,8 @@ - - + + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 23d3fc02ba4f..622507594d9c 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,8 +17,8 @@ - - + + @@ -129,7 +129,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 3bd15ab6b559..8a429345d74f 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,8 +17,8 @@ - - + + diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css index ea6569eec41e..8e18e90c2f24 100644 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -1046,14 +1046,14 @@ toolbarpaletteitem[dragover] { #customization-palette:not([hidden]) { display: block; - flex: 1 1 auto; + flex: 1 1 main-size; overflow: auto; min-height: 3em; } #customization-footer-spacer, #customization-spacer { - flex: 1 1 auto; + flex: 1 1 main-size; } #customization-footer { diff --git a/browser/components/loop/content/js/panel.js b/browser/components/loop/content/js/panel.js index ef194baad3df..a08a1798ce68 100644 --- a/browser/components/loop/content/js/panel.js +++ b/browser/components/loop/content/js/panel.js @@ -211,7 +211,7 @@ loop.panel = (function(_, mozL10n) { _generateMailTo: function() { return encodeURI([ - "mailto:?subject=" + __("share_email_subject") + "&", + "mailto:?subject=" + __("share_email_subject2") + "&", "body=" + __("share_email_body", {callUrl: this.state.callUrl}) ].join("")); }, diff --git a/browser/components/loop/content/js/panel.jsx b/browser/components/loop/content/js/panel.jsx index c074ff167fe8..37e919c060b5 100644 --- a/browser/components/loop/content/js/panel.jsx +++ b/browser/components/loop/content/js/panel.jsx @@ -211,7 +211,7 @@ loop.panel = (function(_, mozL10n) { _generateMailTo: function() { return encodeURI([ - "mailto:?subject=" + __("share_email_subject") + "&", + "mailto:?subject=" + __("share_email_subject2") + "&", "body=" + __("share_email_body", {callUrl: this.state.callUrl}) ].join("")); }, diff --git a/browser/components/loop/test/desktop-local/panel_test.js b/browser/components/loop/test/desktop-local/panel_test.js index 80a0b690f882..1714aa26064c 100644 --- a/browser/components/loop/test/desktop-local/panel_test.js +++ b/browser/components/loop/test/desktop-local/panel_test.js @@ -253,7 +253,7 @@ describe("loop.panel", function() { getStrings: function(key) { var text; - if (key === "share_email_subject") + if (key === "share_email_subject2") text = "email-subject"; else if (key === "share_email_body") text = "{{callUrl}}"; diff --git a/browser/devtools/markupview/markup-view.css b/browser/devtools/markupview/markup-view.css index f8db84abce65..a5d7dff360d4 100644 --- a/browser/devtools/markupview/markup-view.css +++ b/browser/devtools/markupview/markup-view.css @@ -35,7 +35,7 @@ .html-editor-inner { border: solid .1px; - flex: 1 1 auto; + flex: 1 1 main-size; } .html-editor iframe { diff --git a/browser/fuel/src/fuelApplication.js b/browser/fuel/fuelApplication.js similarity index 99% rename from browser/fuel/src/fuelApplication.js rename to browser/fuel/fuelApplication.js index 0b249296f32b..a2136c0265cd 100644 --- a/browser/fuel/src/fuelApplication.js +++ b/browser/fuel/fuelApplication.js @@ -729,7 +729,7 @@ var ApplicationFactory = { }; -#include ../../../toolkit/components/exthelper/extApplication.js +#include ../../toolkit/components/exthelper/extApplication.js //================================================= // Application constructor diff --git a/browser/fuel/src/fuelApplication.manifest b/browser/fuel/fuelApplication.manifest similarity index 100% rename from browser/fuel/src/fuelApplication.manifest rename to browser/fuel/fuelApplication.manifest diff --git a/browser/fuel/public/fuelIApplication.idl b/browser/fuel/fuelIApplication.idl similarity index 100% rename from browser/fuel/public/fuelIApplication.idl rename to browser/fuel/fuelIApplication.idl diff --git a/browser/fuel/moz.build b/browser/fuel/moz.build index 4f82470ff9e5..10562b0f81e5 100644 --- a/browser/fuel/moz.build +++ b/browser/fuel/moz.build @@ -4,5 +4,18 @@ # 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/. -DIRS += ['public', 'src'] BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] + +XPIDL_SOURCES += [ + 'fuelIApplication.idl', +] + +XPIDL_MODULE = 'fuel' + +EXTRA_COMPONENTS += [ + 'fuelApplication.manifest', +] + +EXTRA_PP_COMPONENTS += [ + 'fuelApplication.js', +] diff --git a/browser/fuel/src/moz.build b/browser/fuel/src/moz.build deleted file mode 100644 index 5edbd70ece41..000000000000 --- a/browser/fuel/src/moz.build +++ /dev/null @@ -1,13 +0,0 @@ -# -*- 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/. - -EXTRA_COMPONENTS += [ - 'fuelApplication.manifest', -] - -EXTRA_PP_COMPONENTS += [ - 'fuelApplication.js', -] diff --git a/browser/locales/en-US/chrome/browser/loop/loop.properties b/browser/locales/en-US/chrome/browser/loop/loop.properties index 0b9e6e9d4ba8..1176c22fcc7e 100644 --- a/browser/locales/en-US/chrome/browser/loop/loop.properties +++ b/browser/locales/en-US/chrome/browser/loop/loop.properties @@ -57,9 +57,9 @@ feedback_back_button=Back ## translate the part between {{..}} feedback_window_will_close_in=This window will close in {{countdown}} seconds +share_email_subject2=Invitation to chat ## LOCALIZATION NOTE (share_email_body): In this item, don't translate the ## part between {{..}} and let the \r\n\r\n part -share_email_subject=Loop invitation to chat share_email_body=Please click that link to call me back:\r\n\r\n{{callUrl}} share_button=Email copy_url_button=Copy diff --git a/browser/metro/theme/config.css b/browser/metro/theme/config.css index 5a6f9e048932..65f9ba3a75f6 100644 --- a/browser/metro/theme/config.css +++ b/browser/metro/theme/config.css @@ -57,7 +57,7 @@ body { min-width: 0; color: #000000; opacity: 1; - flex: 1 1 auto; + flex: 1 1 main-size; } #filter-input:-moz-placeholder { @@ -193,7 +193,7 @@ li { .pref-value { color: rgba(0,0,0,0.5); - flex: 1 1 auto; + flex: 1 1 main-size; border: none; -moz-appearance: none; background-image: none; @@ -227,7 +227,7 @@ li { } #new-pref-value-boolean { - flex: 1 1 auto; + flex: 1 1 main-size; } /* Disable newPref dialog spinbuttons, use custom version from Android */ @@ -239,7 +239,7 @@ li { #new-pref-container .pref-button.toggle { display: inline-block; opacity: 1; - flex: 0 1 auto; + flex: 0 1 main-size; float: right; } @@ -247,7 +247,7 @@ li { #new-pref-container .pref-button.create { display: inline-block; opacity: 1; - flex: 1 1 auto; + flex: 1 1 main-size; } .pref-item-line { diff --git a/browser/modules/TabCrashReporter.jsm b/browser/modules/TabCrashReporter.jsm index 3e8449b10890..d46f7e175d81 100644 --- a/browser/modules/TabCrashReporter.jsm +++ b/browser/modules/TabCrashReporter.jsm @@ -58,7 +58,8 @@ this.TabCrashReporter = { if (!dumpID) return - if (CrashSubmit.submit(dumpID)) { + let contentProcessType = Services.crashmanager.PROCESS_TYPE_CONTENT; + if (CrashSubmit.submit(dumpID, { processType: contentProcessType })) { this.childMap.set(childID, null); // Avoid resubmission. } }, diff --git a/browser/themes/shared/customizableui/panelUIOverlay.inc.css b/browser/themes/shared/customizableui/panelUIOverlay.inc.css index 829166b3236e..1cb532843582 100644 --- a/browser/themes/shared/customizableui/panelUIOverlay.inc.css +++ b/browser/themes/shared/customizableui/panelUIOverlay.inc.css @@ -250,7 +250,7 @@ panelview:not([mainview]) .toolbarbutton-text, #PanelUI-contents { display: block; - flex: 1 0 auto; + flex: 1 0 main-size; margin-left: auto; margin-right: auto; padding: .5em 0; diff --git a/browser/themes/shared/devtools/webconsole.inc.css b/browser/themes/shared/devtools/webconsole.inc.css index f56ebbeba1bb..aa49039dfd75 100644 --- a/browser/themes/shared/devtools/webconsole.inc.css +++ b/browser/themes/shared/devtools/webconsole.inc.css @@ -17,24 +17,24 @@ a { .message { display: flex; - flex: 0 0 auto; + flex: 0 0 main-size; padding: 0 7px; width: 100%; box-sizing: border-box; } .message > .timestamp { - flex: 0 0 auto; + flex: 0 0 main-size; color: GrayText; margin: 4px 6px 0 0; } .message > .indent { - flex: 0 0 auto; + flex: 0 0 main-size; } .message > .icon { - flex: 0 0 auto; + flex: 0 0 main-size; margin: 3px 6px 0 0; padding: 0 4px; height: 1em; @@ -66,7 +66,7 @@ a { /* The red bubble that shows the number of times a message is repeated */ .message-repeats { -moz-user-select: none; - flex: 0 0 auto; + flex: 0 0 main-size; margin: 2px 6px; padding: 0 6px; height: 1.25em; @@ -84,7 +84,7 @@ a { .message-location { display: flex; - flex: 0 0 auto; + flex: 0 0 main-size; align-self: flex-start; justify-content: flex-end; width: 10em; @@ -106,7 +106,7 @@ a { } .message-location > .line-number { - flex: 0 0 auto; + flex: 0 0 main-size; } .message-flex-body { @@ -120,7 +120,7 @@ a { .message-flex-body > .message-body { display: block; - flex: 1 1 auto; + flex: 1 1 main-size; vertical-align: middle; } @@ -236,11 +236,11 @@ a { } .message[category=network] .method { - flex: 0 0 auto; + flex: 0 0 main-size; } .message[category=network]:not(.navigation-marker) .url { - flex: 1 1 auto; + flex: 1 1 main-size; /* Make sure the URL is very small initially, let flex change width as needed. */ width: 100px; min-width: 5em; @@ -250,7 +250,7 @@ a { } .message[category=network] .status { - flex: 0 0 auto; + flex: 0 0 main-size; -moz-margin-start: 6px; } @@ -454,7 +454,7 @@ a { .stacktrace .function { display: block; - flex: 1 1 auto; + flex: 1 1 main-size; } .cm-s-mozilla a[class] { diff --git a/chrome/nsChromeRegistryChrome.cpp b/chrome/nsChromeRegistryChrome.cpp index bd508d21e071..45aa5afaec88 100644 --- a/chrome/nsChromeRegistryChrome.cpp +++ b/chrome/nsChromeRegistryChrome.cpp @@ -124,8 +124,7 @@ nsChromeRegistryChrome::Init() mSelectedLocale = NS_LITERAL_CSTRING("en-US"); mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0"); - PL_DHashTableInit(&mPackagesHash, &kTableOps, - nullptr, sizeof(PackageEntry), 16); + PL_DHashTableInit(&mPackagesHash, &kTableOps, nullptr, sizeof(PackageEntry)); bool safeMode = false; nsCOMPtr xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID)); diff --git a/configure.in b/configure.in index e8e0d7f6441c..8c1b0c3bcd19 100644 --- a/configure.in +++ b/configure.in @@ -2524,10 +2524,10 @@ if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then *) case $GCC_VERSION in 4.4*|4.6*) - VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden_dso_handle.h' + VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(MOZILLA_DIR)/config/gcc_hidden_dso_handle.h' ;; *) - VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' + VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(MOZILLA_DIR)/config/gcc_hidden.h' ;; esac WRAP_SYSTEM_INCLUDES=1 @@ -4579,6 +4579,8 @@ fi if test -f "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh"; then . "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh" +elif test -f "${EXTERNAL_SOURCE_DIR}/$REAL_BRANDING_DIRECTORY/configure.sh"; then + . "${EXTERNAL_SOURCE_DIR}/$REAL_BRANDING_DIRECTORY/configure.sh" fi AC_SUBST(MOZ_BRANDING_DIRECTORY) @@ -6395,6 +6397,9 @@ Linux) ;; esac ;; +Darwin) + MOZ_GMP_SANDBOX=1 + ;; esac if test -n "$MOZ_GMP_SANDBOX"; then @@ -9034,10 +9039,13 @@ unset CONFIG_FILES # Run all configure scripts specified by a subconfigure if test -n "$_subconfigure_subdir"; then + _save_srcdir="$srcdir" + srcdir="$srcdir/.." _save_ac_configure_args="$ac_configure_args" ac_configure_args="$_subconfigure_config_args" AC_OUTPUT_SUBDIRS("$_subconfigure_subdir") ac_configure_args="$_save_ac_configure_args" + srcdir="$_save_srcdir" fi # No need to run subconfigures when building with LIBXUL_SDK_DIR diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 610b47f79109..c302b48d33ab 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -133,8 +133,8 @@ typedef CallbackObjectHolder NodeFilterHolder; } // namespace mozilla #define NS_IDOCUMENT_IID \ -{ 0xa45ef8f0, 0x7c5b, 0x425d, \ - { 0xa5, 0xe7, 0x11, 0x41, 0x5c, 0x41, 0x0c, 0x7a } } +{ 0x613ea294, 0x0288, 0x48b4, \ + { 0x9e, 0x7b, 0x0f, 0xe9, 0x3f, 0x8c, 0xf8, 0x95 } } // Enum for requesting a particular type of document when creating a doc enum DocumentFlavor { @@ -532,6 +532,38 @@ public: mHasMixedDisplayContentBlocked = aHasMixedDisplayContentBlocked; } + /** + * Get tracking content blocked flag for this document. + */ + bool GetHasTrackingContentBlocked() + { + return mHasTrackingContentBlocked; + } + + /** + * Set the tracking content blocked flag for this document. + */ + void SetHasTrackingContentBlocked(bool aHasTrackingContentBlocked) + { + mHasTrackingContentBlocked = aHasTrackingContentBlocked; + } + + /** + * Get tracking content loaded flag for this document. + */ + bool GetHasTrackingContentLoaded() + { + return mHasTrackingContentLoaded; + } + + /** + * Set the tracking content loaded flag for this document. + */ + void SetHasTrackingContentLoaded(bool aHasTrackingContentLoaded) + { + mHasTrackingContentLoaded = aHasTrackingContentLoaded; + } + /** * Get the sandbox flags for this document. * @see nsSandboxFlags.h for the possible flags @@ -2531,6 +2563,12 @@ protected: // True if a document has blocked Mixed Display/Passive Content (see nsMixedContentBlocker.cpp) bool mHasMixedDisplayContentBlocked; + // True if a document has blocked Tracking Content + bool mHasTrackingContentBlocked; + + // True if a document has loaded Tracking Content + bool mHasTrackingContentLoaded; + // True if DisallowBFCaching has been called on this document. bool mBFCacheDisallowed; diff --git a/content/base/src/Link.cpp b/content/base/src/Link.cpp index 21f10cf3c1df..9506551441e0 100644 --- a/content/base/src/Link.cpp +++ b/content/base/src/Link.cpp @@ -596,9 +596,10 @@ Link::SetSearchParams(URLSearchParams& aSearchParams) } void -Link::URLSearchParamsUpdated() +Link::URLSearchParamsUpdated(URLSearchParams* aSearchParams) { MOZ_ASSERT(mSearchParams); + MOZ_ASSERT(mSearchParams == aSearchParams); nsString search; mSearchParams->Serialize(search); diff --git a/content/base/src/Link.h b/content/base/src/Link.h index 9ade6e495275..ae0047672924 100644 --- a/content/base/src/Link.h +++ b/content/base/src/Link.h @@ -115,7 +115,7 @@ public: bool ElementHasHref() const; // URLSearchParamsObserver - void URLSearchParamsUpdated() MOZ_OVERRIDE; + void URLSearchParamsUpdated(URLSearchParams* aSearchParams) MOZ_OVERRIDE; protected: virtual ~Link(); diff --git a/content/base/src/nsContentList.cpp b/content/base/src/nsContentList.cpp index ed0027825dad..8448db9683a1 100644 --- a/content/base/src/nsContentList.cpp +++ b/content/base/src/nsContentList.cpp @@ -219,10 +219,8 @@ NS_GetContentList(nsINode* aRootNode, // Initialize the hashtable if needed. if (!gContentListHashTable.ops) { - PL_DHashTableInit(&gContentListHashTable, - &hash_table_ops, nullptr, - sizeof(ContentListHashEntry), - 16); + PL_DHashTableInit(&gContentListHashTable, &hash_table_ops, nullptr, + sizeof(ContentListHashEntry)); } ContentListHashEntry *entry = nullptr; @@ -336,10 +334,8 @@ GetFuncStringContentList(nsINode* aRootNode, // Initialize the hashtable if needed. if (!gFuncStringContentListHashTable.ops) { - PL_DHashTableInit(&gFuncStringContentListHashTable, - &hash_table_ops, nullptr, - sizeof(FuncStringContentListHashEntry), - 16); + PL_DHashTableInit(&gFuncStringContentListHashTable, &hash_table_ops, + nullptr, sizeof(FuncStringContentListHashEntry)); } FuncStringContentListHashEntry *entry = nullptr; diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 04da13085412..88249a443d08 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -486,7 +486,7 @@ nsContentUtils::Init() }; PL_DHashTableInit(&sEventListenerManagersHash, &hash_table_ops, - nullptr, sizeof(EventListenerManagerMapEntry), 16); + nullptr, sizeof(EventListenerManagerMapEntry)); RegisterStrongMemoryReporter(new DOMEventListenerManagersHashReporter()); } @@ -637,9 +637,9 @@ nsContentUtils::InitializeEventTable() { }; sAtomEventTable = new nsDataHashtable( - int(ArrayLength(eventArray) / 0.75) + 1); + ArrayLength(eventArray)); sStringEventTable = new nsDataHashtable( - int(ArrayLength(eventArray) / 0.75) + 1); + ArrayLength(eventArray)); sUserDefinedEvents = new nsCOMArray(64); // Subtract one from the length because of the trailing null diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index cfb884cc4ddd..0b14243ffc17 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -3741,7 +3741,7 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc) }; mSubDocuments = PL_NewDHashTable(&hash_table_ops, nullptr, - sizeof(SubDocMapEntry), 16); + sizeof(SubDocMapEntry)); if (!mSubDocuments) { return NS_ERROR_OUT_OF_MEMORY; } @@ -6818,7 +6818,7 @@ nsDocument::GetBoxObjectFor(Element* aElement, ErrorResult& aRv) } if (!mBoxObjectTable) { - mBoxObjectTable = new nsInterfaceHashtable, nsPIBoxObject>(12); + mBoxObjectTable = new nsInterfaceHashtable, nsPIBoxObject>(6); } else { nsCOMPtr boxObject = mBoxObjectTable->Get(aElement); if (boxObject) { diff --git a/content/base/src/nsFrameLoader.cpp b/content/base/src/nsFrameLoader.cpp index 82a493ac87ca..d53eca5446f7 100644 --- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -1021,7 +1021,7 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size, mRemoteBrowserInitialized = true; } } else { - nsRect dimensions; + nsIntRect dimensions; NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), false); // Don't show remote iframe if we are waiting for the completion of reflow. @@ -1877,7 +1877,7 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI) } nsresult -nsFrameLoader::GetWindowDimensions(nsRect& aRect) +nsFrameLoader::GetWindowDimensions(nsIntRect& aRect) { // Need to get outer window position here nsIDocument* doc = mOwnerContent->GetDocument(); @@ -1917,7 +1917,7 @@ nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame *aIFrame) if (mRemoteFrame) { if (mRemoteBrowser) { nsIntSize size = aIFrame->GetSubdocumentSize(); - nsRect dimensions; + nsIntRect dimensions; NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), NS_ERROR_FAILURE); mRemoteBrowser->UpdateDimensions(dimensions, size); } diff --git a/content/base/src/nsFrameLoader.h b/content/base/src/nsFrameLoader.h index 08a05914573d..6384b4b499e9 100644 --- a/content/base/src/nsFrameLoader.h +++ b/content/base/src/nsFrameLoader.h @@ -370,7 +370,7 @@ private: nsresult EnsureMessageManager(); // Properly retrieves documentSize of any subdocument type. - nsresult GetWindowDimensions(nsRect& aRect); + nsresult GetWindowDimensions(nsIntRect& aRect); // Updates the subdocument position and size. This gets called only // when we have our own in-process DocShell. diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp index 3cb833a21896..79525722ccd4 100644 --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -169,9 +169,8 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, aRequest->GetImageErrorCode(&errorCode); /* Handle image not loading error because source was a tracking URL. - * (Safebrowinsg) We make a note of this image node by including it - * in a dedicated array of blocked tracking nodes under its parent - * document. + * We make a note of this image node by including it in a dedicated + * array of blocked tracking nodes under its parent document. */ if (errorCode == NS_ERROR_TRACKING_URI) { nsCOMPtr thisNode diff --git a/content/base/src/nsPropertyTable.cpp b/content/base/src/nsPropertyTable.cpp index ff4265d7bcdc..cfd4e83a44b6 100644 --- a/content/base/src/nsPropertyTable.cpp +++ b/content/base/src/nsPropertyTable.cpp @@ -294,7 +294,7 @@ nsPropertyTable::PropertyList::PropertyList(nsIAtom *aName, mNext(nullptr) { PL_DHashTableInit(&mObjectValueMap, PL_DHashGetStubOps(), this, - sizeof(PropertyListMapEntry), 16); + sizeof(PropertyListMapEntry)); } nsPropertyTable::PropertyList::~PropertyList() diff --git a/content/base/src/nsScriptLoader.cpp b/content/base/src/nsScriptLoader.cpp index 1f6c6e645c45..e97d236398e8 100644 --- a/content/base/src/nsScriptLoader.cpp +++ b/content/base/src/nsScriptLoader.cpp @@ -1411,9 +1411,8 @@ nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, if (NS_FAILED(rv)) { /* * Handle script not loading error because source was a tracking URL. - * (Safebrowinsg) We make a note of this script node by including it - * in a dedicated array of blocked tracking nodes under its parent - * document. + * We make a note of this script node by including it in a dedicated + * array of blocked tracking nodes under its parent document. */ if (rv == NS_ERROR_TRACKING_URI) { nsCOMPtr cont = do_QueryInterface(request->mElement); diff --git a/content/html/content/src/HTMLFormControlsCollection.cpp b/content/html/content/src/HTMLFormControlsCollection.cpp index 1e23e85e7738..d23c01738c74 100644 --- a/content/html/content/src/HTMLFormControlsCollection.cpp +++ b/content/html/content/src/HTMLFormControlsCollection.cpp @@ -74,7 +74,7 @@ HTMLFormControlsCollection::HTMLFormControlsCollection(HTMLFormElement* aForm) // Initialize the elements list to have an initial capacity // of 8 to reduce allocations on small forms. , mElements(8) - , mNameLookupTable(HTMLFormElement::FORM_CONTROL_LIST_HASHTABLE_SIZE) + , mNameLookupTable(HTMLFormElement::FORM_CONTROL_LIST_HASHTABLE_LENGTH) { SetIsDOMBinding(); } diff --git a/content/html/content/src/HTMLFormElement.cpp b/content/html/content/src/HTMLFormElement.cpp index cb39ce0f85df..839252b71310 100644 --- a/content/html/content/src/HTMLFormElement.cpp +++ b/content/html/content/src/HTMLFormElement.cpp @@ -86,9 +86,9 @@ bool HTMLFormElement::gPasswordManagerInitialized = false; HTMLFormElement::HTMLFormElement(already_AddRefed& aNodeInfo) : nsGenericHTMLElement(aNodeInfo), mControls(new HTMLFormControlsCollection(MOZ_THIS_IN_INITIALIZER_LIST())), - mSelectedRadioButtons(4), - mRequiredRadioButtonCounts(4), - mValueMissingRadioGroups(4), + mSelectedRadioButtons(2), + mRequiredRadioButtonCounts(2), + mValueMissingRadioGroups(2), mGeneratingSubmit(false), mGeneratingReset(false), mIsSubmitting(false), @@ -102,8 +102,8 @@ HTMLFormElement::HTMLFormElement(already_AddRefed& aNode mDefaultSubmitElement(nullptr), mFirstSubmitInElements(nullptr), mFirstSubmitNotInElements(nullptr), - mImageNameLookupTable(FORM_CONTROL_LIST_HASHTABLE_SIZE), - mPastNameLookupTable(FORM_CONTROL_LIST_HASHTABLE_SIZE), + mImageNameLookupTable(FORM_CONTROL_LIST_HASHTABLE_LENGTH), + mPastNameLookupTable(FORM_CONTROL_LIST_HASHTABLE_LENGTH), mInvalidElementsCount(0), mEverTriedInvalidSubmit(false) { diff --git a/content/html/content/src/HTMLFormElement.h b/content/html/content/src/HTMLFormElement.h index e6b5d4b4583e..f8716d9e79cb 100644 --- a/content/html/content/src/HTMLFormElement.h +++ b/content/html/content/src/HTMLFormElement.h @@ -45,7 +45,7 @@ public: HTMLFormElement(already_AddRefed& aNodeInfo); enum { - FORM_CONTROL_LIST_HASHTABLE_SIZE = 16 + FORM_CONTROL_LIST_HASHTABLE_LENGTH = 8 }; // nsISupports diff --git a/content/html/content/src/HTMLMediaElement.cpp b/content/html/content/src/HTMLMediaElement.cpp index 5ecadd72b7b6..e80cb5fe2383 100644 --- a/content/html/content/src/HTMLMediaElement.cpp +++ b/content/html/content/src/HTMLMediaElement.cpp @@ -2653,9 +2653,11 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder, mDecoder->SetPreservesPitch(mPreservesPitch); mDecoder->SetPlaybackRate(mPlaybackRate); +#ifdef MOZ_EME if (mMediaKeys) { mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy()); } +#endif if (mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) { mDecoder->SetMinimizePrerollUntilPlaybackStarts(); } diff --git a/content/html/content/src/nsGenericHTMLFrameElement.cpp b/content/html/content/src/nsGenericHTMLFrameElement.cpp index f9e27edaed8b..e700f01c0e0b 100644 --- a/content/html/content/src/nsGenericHTMLFrameElement.cpp +++ b/content/html/content/src/nsGenericHTMLFrameElement.cpp @@ -23,6 +23,7 @@ #include "nsIScrollable.h" #include "nsPresContext.h" #include "nsServiceManagerUtils.h" +#include "nsSubDocumentFrame.h" using namespace mozilla; using namespace mozilla::dom; @@ -58,6 +59,14 @@ nsGenericHTMLFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent) EnsureFrameLoader(); NS_ENSURE_STATE(mFrameLoader); mFrameLoader->SetRemoteBrowser(aTabParent); + + if (nsSubDocumentFrame* subdocFrame = do_QueryFrame(GetPrimaryFrame())) { + // The reflow for this element already happened while we were waiting + // for the iframe creation. Therefore the subdoc frame didn't have a + // frameloader when UpdatePositionAndSize was supposed to be called in + // ReflowFinished, and we need to do it properly now. + mFrameLoader->UpdatePositionAndSize(subdocFrame); + } return NS_OK; } diff --git a/content/html/content/test/file_iframe_sandbox_e_if6.html b/content/html/content/test/file_iframe_sandbox_e_if6.html index 1da583811899..b1266416cbb6 100644 --- a/content/html/content/test/file_iframe_sandbox_e_if6.html +++ b/content/html/content/test/file_iframe_sandbox_e_if6.html @@ -3,9 +3,7 @@ Test for Bug 341604 - - - diff --git a/content/media/AbstractMediaDecoder.h b/content/media/AbstractMediaDecoder.h index 452e1c4053d7..40b7ec20e5d5 100644 --- a/content/media/AbstractMediaDecoder.h +++ b/content/media/AbstractMediaDecoder.h @@ -25,7 +25,9 @@ class ReentrantMonitor; class VideoFrameContainer; class TimedMetadata; class MediaDecoderOwner; +#ifdef MOZ_EME class CDMProxy; +#endif typedef nsDataHashtable MetadataTags; @@ -139,8 +141,10 @@ public: uint32_t& mDecoded; }; +#ifdef MOZ_EME virtual nsresult SetCDMProxy(CDMProxy* aProxy) { return NS_ERROR_NOT_IMPLEMENTED; } virtual CDMProxy* GetCDMProxy() { return nullptr; } +#endif }; class MetadataEventRunner : public nsRunnable diff --git a/content/media/MediaDecoder.cpp b/content/media/MediaDecoder.cpp index e7dcab3c8879..9c18cc2f9f17 100644 --- a/content/media/MediaDecoder.cpp +++ b/content/media/MediaDecoder.cpp @@ -1666,6 +1666,7 @@ bool MediaDecoder::CanPlayThrough() stats.mDownloadPosition > stats.mPlaybackPosition + readAheadMargin; } +#ifdef MOZ_EME nsresult MediaDecoder::SetCDMProxy(CDMProxy* aProxy) { @@ -1684,6 +1685,7 @@ MediaDecoder::GetCDMProxy() MOZ_ASSERT(OnDecodeThread() || NS_IsMainThread()); return mProxy; } +#endif #ifdef MOZ_RAW bool diff --git a/content/media/MediaDecoder.h b/content/media/MediaDecoder.h index cb37d3f1671d..57577667e549 100644 --- a/content/media/MediaDecoder.h +++ b/content/media/MediaDecoder.h @@ -190,7 +190,9 @@ destroying the MediaDecoder object. #include "MediaStreamGraph.h" #include "AbstractMediaDecoder.h" #include "necko-config.h" +#ifdef MOZ_EME #include "mozilla/CDMProxy.h" +#endif class nsIStreamListener; class nsIPrincipal; @@ -850,11 +852,13 @@ public: // The decoder monitor must be held. bool IsLogicallyPlaying(); +#ifdef MOZ_EME // This takes the decoder monitor. virtual nsresult SetCDMProxy(CDMProxy* aProxy) MOZ_OVERRIDE; // Decoder monitor must be held. virtual CDMProxy* GetCDMProxy() MOZ_OVERRIDE; +#endif #ifdef MOZ_RAW static bool IsRawEnabled(); @@ -1107,7 +1111,9 @@ private: // The |RestrictedAccessMonitor| member object. RestrictedAccessMonitor mReentrantMonitor; +#ifdef MOZ_EME nsRefPtr mProxy; +#endif protected: // Data about MediaStreams that are being fed by this decoder. diff --git a/content/media/MediaDecoderOwner.h b/content/media/MediaDecoderOwner.h index 157f33baf5cc..b2dd8e062995 100644 --- a/content/media/MediaDecoderOwner.h +++ b/content/media/MediaDecoderOwner.h @@ -138,11 +138,13 @@ public: // when the connection between Rtsp server and client gets lost. virtual void ResetConnectionState() = 0; +#ifdef MOZ_EME // Dispatches a "needkey" event to the HTMLMediaElement, with the // provided init data. // Main thread only. virtual void DispatchNeedKey(const nsTArray& aInitData, const nsAString& aInitDataType) = 0; +#endif }; } diff --git a/content/media/eme/CDMProxy.cpp b/content/media/eme/CDMProxy.cpp index 125cb41dd6ab..106eccab4e11 100644 --- a/content/media/eme/CDMProxy.cpp +++ b/content/media/eme/CDMProxy.cpp @@ -302,6 +302,19 @@ CDMProxy::Shutdown() { MOZ_ASSERT(NS_IsMainThread()); mKeys.Clear(); + // Note: This may end up being the last owning reference to the CDMProxy. + nsRefPtr task(NS_NewRunnableMethod(this, &CDMProxy::gmp_Shutdown)); + mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL); +} + +void +CDMProxy::gmp_Shutdown() +{ + MOZ_ASSERT(IsOnGMPThread()); + if (mCDM) { + mCDM->Close(); + mCDM = nullptr; + } } void @@ -485,10 +498,7 @@ CDMProxy::gmp_Terminated() { MOZ_ASSERT(IsOnGMPThread()); EME_LOG("CDM terminated"); - if (mCDM) { - mCDM->Close(); - mCDM = nullptr; - } + gmp_Shutdown(); } } // namespace mozilla diff --git a/content/media/eme/CDMProxy.h b/content/media/eme/CDMProxy.h index 30c05baf6dbb..d03a0bb68253 100644 --- a/content/media/eme/CDMProxy.h +++ b/content/media/eme/CDMProxy.h @@ -167,6 +167,9 @@ private: // GMP thread only. void gmp_Init(uint32_t aPromiseId); + // GMP thread only. + void gmp_Shutdown(); + // Main thread only. void OnCDMCreated(uint32_t aPromiseId); diff --git a/content/media/eme/MediaKeys.cpp b/content/media/eme/MediaKeys.cpp index 9c55959f0fe8..0c1c4a0d3e43 100644 --- a/content/media/eme/MediaKeys.cpp +++ b/content/media/eme/MediaKeys.cpp @@ -44,12 +44,24 @@ MediaKeys::MediaKeys(nsPIDOMWindow* aParent, const nsAString& aKeySystem) SetIsDOMBinding(); } +static PLDHashOperator +RejectPromises(const uint32_t& aKey, + nsRefPtr& aPromise, + void* aClosure) +{ + aPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); + return PL_DHASH_NEXT; +} + MediaKeys::~MediaKeys() { if (mProxy) { mProxy->Shutdown(); mProxy = nullptr; } + + mPromises.Enumerate(&RejectPromises, nullptr); + mPromises.Clear(); } nsPIDOMWindow* diff --git a/content/media/fmp4/MP4Decoder.cpp b/content/media/fmp4/MP4Decoder.cpp index e5acefa77e71..a36ceb922e80 100644 --- a/content/media/fmp4/MP4Decoder.cpp +++ b/content/media/fmp4/MP4Decoder.cpp @@ -8,7 +8,9 @@ #include "MP4Reader.h" #include "MediaDecoderStateMachine.h" #include "mozilla/Preferences.h" +#ifdef MOZ_EME #include "mozilla/CDMProxy.h" +#endif #include "prlog.h" #ifdef XP_WIN @@ -29,6 +31,7 @@ MediaDecoderStateMachine* MP4Decoder::CreateStateMachine() return new MediaDecoderStateMachine(this, new MP4Reader(this)); } +#ifdef MOZ_EME nsresult MP4Decoder::SetCDMProxy(CDMProxy* aProxy) { @@ -45,6 +48,7 @@ MP4Decoder::SetCDMProxy(CDMProxy* aProxy) } return NS_OK; } +#endif bool MP4Decoder::GetSupportedCodecs(const nsACString& aType, diff --git a/content/media/fmp4/MP4Decoder.h b/content/media/fmp4/MP4Decoder.h index b1913d22cefa..31b01f5bbd27 100644 --- a/content/media/fmp4/MP4Decoder.h +++ b/content/media/fmp4/MP4Decoder.h @@ -24,7 +24,9 @@ public: virtual MediaDecoderStateMachine* CreateStateMachine(); +#ifdef MOZ_EME virtual nsresult SetCDMProxy(CDMProxy* aProxy) MOZ_OVERRIDE; +#endif // Returns true if aType is a MIME type that we can render with the // a MP4 platform decoder backend. If aCodecList is non null, diff --git a/content/media/fmp4/MP4Reader.cpp b/content/media/fmp4/MP4Reader.cpp index 69a91ec19498..daa5b3c0f1ce 100644 --- a/content/media/fmp4/MP4Reader.cpp +++ b/content/media/fmp4/MP4Reader.cpp @@ -15,6 +15,10 @@ #include "mozilla/Preferences.h" #include "mozilla/dom/TimeRanges.h" +#ifdef MOZ_EME +#include "mozilla/CDMProxy.h" +#endif + using mozilla::layers::Image; using mozilla::layers::LayerManager; using mozilla::layers::LayersBackend; @@ -204,6 +208,7 @@ MP4Reader::Init(MediaDecoderReader* aCloneDonor) return NS_OK; } +#ifdef MOZ_EME class DispatchKeyNeededEvent : public nsRunnable { public: DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder, @@ -229,9 +234,11 @@ private: nsTArray mInitData; nsString mInitDataType; }; +#endif bool MP4Reader::IsWaitingMediaResources() { +#ifdef MOZ_EME nsRefPtr proxy; { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); @@ -251,6 +258,9 @@ bool MP4Reader::IsWaitingMediaResources() LOG("MP4Reader::IsWaitingMediaResources() capsKnown=%d", caps.AreCapsKnown()); return !caps.AreCapsKnown(); } +#else + return false; +#endif } void @@ -296,6 +306,7 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo, mDemuxerInitialized = true; } if (mDemuxer->Crypto().valid) { +#ifdef MOZ_EME if (!sIsEMEEnabled) { // TODO: Need to signal DRM/EME required somehow... return NS_ERROR_FAILURE; @@ -330,6 +341,10 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo, HasVideo(), GetTaskQueue()); NS_ENSURE_TRUE(mPlatform, NS_ERROR_FAILURE); +#else + // EME not supported. + return NS_ERROR_FAILURE; +#endif } else { mPlatform = PlatformDecoderModule::Create(); NS_ENSURE_TRUE(mPlatform, NS_ERROR_FAILURE); diff --git a/content/media/fmp4/MP4Reader.h b/content/media/fmp4/MP4Reader.h index 7045c68272ab..1fc8822802e3 100644 --- a/content/media/fmp4/MP4Reader.h +++ b/content/media/fmp4/MP4Reader.h @@ -12,7 +12,6 @@ #include "PlatformDecoderModule.h" #include "mp4_demuxer/mp4_demuxer.h" #include "MediaTaskQueue.h" -#include "mozilla/CDMProxy.h" #include #include "mozilla/Monitor.h" diff --git a/content/media/fmp4/PlatformDecoderModule.cpp b/content/media/fmp4/PlatformDecoderModule.cpp index 3acffc29a300..06edf04f6895 100644 --- a/content/media/fmp4/PlatformDecoderModule.cpp +++ b/content/media/fmp4/PlatformDecoderModule.cpp @@ -15,8 +15,10 @@ #include "AppleDecoderModule.h" #endif #include "mozilla/Preferences.h" +#ifdef MOZ_EME #include "EMEDecoderModule.h" #include "mozilla/CDMProxy.h" +#endif #include "SharedThreadPool.h" #include "MediaTaskQueue.h" @@ -70,6 +72,7 @@ CreateTaskQueue() return t->mTaskQueue.forget(); } +#ifdef MOZ_EME /* static */ PlatformDecoderModule* PlatformDecoderModule::CreateCDMWrapper(CDMProxy* aProxy, @@ -101,6 +104,7 @@ PlatformDecoderModule::CreateCDMWrapper(CDMProxy* aProxy, cdmDecodesVideo, CreateTaskQueue()); } +#endif /* static */ PlatformDecoderModule* diff --git a/content/media/fmp4/PlatformDecoderModule.h b/content/media/fmp4/PlatformDecoderModule.h index 7f4f85b09f8b..629a8714ebb7 100644 --- a/content/media/fmp4/PlatformDecoderModule.h +++ b/content/media/fmp4/PlatformDecoderModule.h @@ -66,6 +66,7 @@ public: // This is called on the decode task queue. static PlatformDecoderModule* Create(); +#ifdef MOZ_EME // Creates a PlatformDecoderModule that uses a CDMProxy to decrypt or // decrypt-and-decode EME encrypted content. If the CDM only decrypts and // does not decode, we create a PDM and use that to create MediaDataDecoders @@ -75,6 +76,7 @@ public: bool aHasAudio, bool aHasVideo, MediaTaskQueue* aTaskQueue); +#endif // Called to shutdown the decoder module and cleanup state. The PDM // is deleted immediately after Shutdown() is called. Shutdown() is diff --git a/content/media/fmp4/eme/EMEAACDecoder.cpp b/content/media/fmp4/eme/EMEAACDecoder.cpp index 051eaff6c0ab..db3efbbbcf21 100644 --- a/content/media/fmp4/eme/EMEAACDecoder.cpp +++ b/content/media/fmp4/eme/EMEAACDecoder.cpp @@ -127,11 +127,20 @@ EMEAACDecoder::Shutdown() void EMEAACDecoder::Decoded(const nsTArray& aPCM, - uint64_t aTimeStamp) + uint64_t aTimeStamp, + uint32_t aChannels, + uint32_t aRate) { MOZ_ASSERT(IsOnGMPThread()); - size_t numFrames = aPCM.Length() / mAudioChannels; + if (aRate == 0 || aChannels == 0) { + NS_WARNING("Invalid rate or num channels returned on GMP audio samples"); + mCallback->Error(); + return; + } + + size_t numFrames = aPCM.Length() / aChannels; + MOZ_ASSERT((aPCM.Length() % aChannels) == 0); nsAutoArrayPtr audioData(new AudioDataValue[aPCM.Length()]); for (size_t i = 0; i < aPCM.Length(); ++i) { @@ -140,7 +149,7 @@ EMEAACDecoder::Decoded(const nsTArray& aPCM, if (mMustRecaptureAudioPosition) { mAudioFrameSum = 0; - auto timestamp = UsecsToFrames(aTimeStamp, mAudioRate); + auto timestamp = UsecsToFrames(aTimeStamp, aRate); if (!timestamp.isValid()) { NS_WARNING("Invalid timestamp"); mCallback->Error(); @@ -151,7 +160,7 @@ EMEAACDecoder::Decoded(const nsTArray& aPCM, mMustRecaptureAudioPosition = false; } - auto timestamp = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, mAudioRate); + auto timestamp = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, aRate); if (!timestamp.isValid()) { NS_WARNING("Invalid timestamp on audio samples"); mCallback->Error(); @@ -159,7 +168,7 @@ EMEAACDecoder::Decoded(const nsTArray& aPCM, } mAudioFrameSum += numFrames; - auto duration = FramesToUsecs(numFrames, mAudioRate); + auto duration = FramesToUsecs(numFrames, aRate); if (!duration.isValid()) { NS_WARNING("Invalid duration on audio samples"); mCallback->Error(); @@ -171,7 +180,7 @@ EMEAACDecoder::Decoded(const nsTArray& aPCM, duration.value(), numFrames, audioData.forget(), - mAudioChannels)); + aChannels)); #ifdef LOG_SAMPLE_DECODE LOG("Decoded audio sample! timestamp=%lld duration=%lld currentLength=%u", @@ -211,6 +220,7 @@ void EMEAACDecoder::Error(GMPErr aErr) { MOZ_ASSERT(IsOnGMPThread()); + EME_LOG("EMEAACDecoder::Error"); mCallback->Error(); GmpShutdown(); } @@ -276,7 +286,7 @@ EMEAACDecoder::GmpInput(MP4Sample* aSample) } } - gmp::GMPAudioSamplesImpl samples(sample); + gmp::GMPAudioSamplesImpl samples(sample, mAudioChannels, mAudioRate); mGMP->Decode(samples); mStreamOffset = sample->byte_offset; diff --git a/content/media/fmp4/eme/EMEAACDecoder.h b/content/media/fmp4/eme/EMEAACDecoder.h index 807b4d475e38..9232cdbaa92e 100644 --- a/content/media/fmp4/eme/EMEAACDecoder.h +++ b/content/media/fmp4/eme/EMEAACDecoder.h @@ -38,7 +38,9 @@ public: // GMPAudioDecoderProxyCallback implementation. virtual void Decoded(const nsTArray& aPCM, - uint64_t aTimeStamp) MOZ_OVERRIDE; + uint64_t aTimeStamp, + uint32_t aChannels, + uint32_t aRate) MOZ_OVERRIDE; virtual void InputDataExhausted() MOZ_OVERRIDE; virtual void DrainComplete() MOZ_OVERRIDE; virtual void ResetComplete() MOZ_OVERRIDE; diff --git a/content/media/fmp4/eme/EMEH264Decoder.cpp b/content/media/fmp4/eme/EMEH264Decoder.cpp index 23776b5d0615..104116081311 100644 --- a/content/media/fmp4/eme/EMEH264Decoder.cpp +++ b/content/media/fmp4/eme/EMEH264Decoder.cpp @@ -15,6 +15,7 @@ #include "nsServiceManagerUtils.h" #include "prsystem.h" #include "gfx2DGlue.h" +#include "mozilla/EMELog.h" namespace mozilla { @@ -208,6 +209,7 @@ void EMEH264Decoder::Error(GMPErr aErr) { MOZ_ASSERT(IsOnGMPThread()); + EME_LOG("EMEH264Decoder::Error"); mCallback->Error(); GmpShutdown(); } diff --git a/modules/libpref/src/moz.build b/content/media/fmp4/eme/moz.build similarity index 55% rename from modules/libpref/src/moz.build rename to content/media/fmp4/eme/moz.build index f863f76d9cb5..d22505cf61f5 100644 --- a/modules/libpref/src/moz.build +++ b/content/media/fmp4/eme/moz.build @@ -1,26 +1,30 @@ -# -*- 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/. - -UNIFIED_SOURCES += [ - 'nsPrefBranch.cpp', - 'nsPrefsFactory.cpp', - 'Preferences.cpp', - 'prefread.cpp', -] - -# prefapi.cpp cannot be built in unified mode because it uses plarena.h -SOURCES += [ - 'prefapi.cpp', -] - -MSVC_ENABLE_PGO = True - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' - -DEFINES['OS_ARCH'] = CONFIG['OS_ARCH'] -DEFINES['MOZ_WIDGET_TOOLKIT'] = CONFIG['MOZ_WIDGET_TOOLKIT'] +# -*- 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/. + +EXPORTS += [ + 'EMEAACDecoder.h', + 'EMEDecoderModule.h', + 'EMEH264Decoder.h', +] + +UNIFIED_SOURCES += [ + 'EMEAACDecoder.cpp', + 'EMEDecoderModule.cpp', + 'EMEH264Decoder.cpp', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +LOCAL_INCLUDES += [ + '../base', +] + +FINAL_LIBRARY = 'xul' + +FAIL_ON_WARNINGS = True + +if CONFIG['OS_ARCH'] == 'WINNT': + DEFINES['NOMINMAX'] = True diff --git a/content/media/fmp4/moz.build b/content/media/fmp4/moz.build index 3af0be01fff6..fc830bf542c6 100644 --- a/content/media/fmp4/moz.build +++ b/content/media/fmp4/moz.build @@ -5,9 +5,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. EXPORTS += [ - 'eme/EMEAACDecoder.h', - 'eme/EMEDecoderModule.h', - 'eme/EMEH264Decoder.h', 'MP4Decoder.h', 'MP4Reader.h', 'PlatformDecoderModule.h', @@ -15,9 +12,6 @@ EXPORTS += [ UNIFIED_SOURCES += [ 'BlankDecoderModule.cpp', - 'eme/EMEAACDecoder.cpp', - 'eme/EMEDecoderModule.cpp', - 'eme/EMEH264Decoder.cpp', 'PlatformDecoderModule.cpp', ] @@ -29,6 +23,9 @@ SOURCES += [ if CONFIG['MOZ_WMF']: DIRS += [ 'wmf' ]; +if CONFIG['MOZ_EME']: + DIRS += ['eme'] + if CONFIG['MOZ_FFMPEG']: EXPORTS += [ 'ffmpeg/FFmpegRuntimeLinker.h', diff --git a/content/media/gmp/GMPAudioDecoderChild.cpp b/content/media/gmp/GMPAudioDecoderChild.cpp index 83d7bb7586e1..72ce0710d136 100644 --- a/content/media/gmp/GMPAudioDecoderChild.cpp +++ b/content/media/gmp/GMPAudioDecoderChild.cpp @@ -49,6 +49,8 @@ GMPAudioDecoderChild::Decoded(GMPAudioSamples* aDecodedSamples) samples.mData().AppendElements((int16_t*)aDecodedSamples->Buffer(), aDecodedSamples->Size() / sizeof(int16_t)); samples.mTimeStamp() = aDecodedSamples->TimeStamp(); + samples.mChannelCount() = aDecodedSamples->Channels(); + samples.mSamplesPerSecond() = aDecodedSamples->Rate(); unused << SendDecoded(samples); diff --git a/content/media/gmp/GMPAudioDecoderParent.cpp b/content/media/gmp/GMPAudioDecoderParent.cpp index 86f3705de05a..0e5b4e688940 100644 --- a/content/media/gmp/GMPAudioDecoderParent.cpp +++ b/content/media/gmp/GMPAudioDecoderParent.cpp @@ -200,7 +200,10 @@ GMPAudioDecoderParent::RecvDecoded(const GMPAudioDecodedSampleData& aDecoded) return false; } - mCallback->Decoded(aDecoded.mData(), aDecoded.mTimeStamp()); + mCallback->Decoded(aDecoded.mData(), + aDecoded.mTimeStamp(), + aDecoded.mChannelCount(), + aDecoded.mSamplesPerSecond()); return true; } diff --git a/content/media/gmp/GMPAudioDecoderProxy.h b/content/media/gmp/GMPAudioDecoderProxy.h index 986a3850bc27..6b2a209c4eb1 100644 --- a/content/media/gmp/GMPAudioDecoderProxy.h +++ b/content/media/gmp/GMPAudioDecoderProxy.h @@ -15,7 +15,12 @@ class GMPAudioDecoderProxyCallback : public GMPCallbackBase { public: virtual ~GMPAudioDecoderProxyCallback() {} - virtual void Decoded(const nsTArray& aPCM, uint64_t aTimeStamp) = 0; + // Note: aChannelCount and aSamplesPerSecond may not be consistent from + // one invocation to the next. + virtual void Decoded(const nsTArray& aPCM, + uint64_t aTimeStamp, + uint32_t aChannelCount, + uint32_t aSamplesPerSecond) = 0; virtual void InputDataExhausted() = 0; virtual void DrainComplete() = 0; virtual void ResetComplete() = 0; diff --git a/content/media/gmp/GMPAudioHost.cpp b/content/media/gmp/GMPAudioHost.cpp index 6f5e547f4b3d..4b1b75c29225 100644 --- a/content/media/gmp/GMPAudioHost.cpp +++ b/content/media/gmp/GMPAudioHost.cpp @@ -14,6 +14,8 @@ namespace gmp { GMPAudioSamplesImpl::GMPAudioSamplesImpl(GMPAudioFormat aFormat) : mFormat(aFormat) , mTimeStamp(0) + , mChannels(0) + , mRate(0) { } @@ -21,15 +23,21 @@ GMPAudioSamplesImpl::GMPAudioSamplesImpl(const GMPAudioEncodedSampleData& aData) : mFormat(kGMPAudioEncodedSamples) , mBuffer(aData.mData()) , mTimeStamp(aData.mTimeStamp()) + , mChannels(aData.mChannelCount()) + , mRate(aData.mSamplesPerSecond()) { if (aData.mDecryptionData().mKeyId().Length() > 0) { mCrypto = new GMPEncryptedBufferDataImpl(aData.mDecryptionData()); } } -GMPAudioSamplesImpl::GMPAudioSamplesImpl(mp4_demuxer::MP4Sample* aSample) +GMPAudioSamplesImpl::GMPAudioSamplesImpl(mp4_demuxer::MP4Sample* aSample, + uint32_t aChannels, + uint32_t aRate) : mFormat(kGMPAudioEncodedSamples) , mTimeStamp(aSample->composition_timestamp) + , mChannels(aChannels) + , mRate(aRate) { mBuffer.AppendElements(aSample->data, aSample->size); if (aSample->crypto.valid) { @@ -115,6 +123,31 @@ GMPAudioSamplesImpl::RelinquishData(GMPAudioEncodedSampleData& aData) } } +uint32_t +GMPAudioSamplesImpl::Channels() const +{ + return mChannels; +} + +void +GMPAudioSamplesImpl::SetChannels(uint32_t aChannels) +{ + mChannels = aChannels; +} + +uint32_t +GMPAudioSamplesImpl::Rate() const +{ + return mRate; +} + +void +GMPAudioSamplesImpl::SetRate(uint32_t aRate) +{ + mRate = aRate; +} + + GMPErr GMPAudioHostImpl::CreateSamples(GMPAudioFormat aFormat, GMPAudioSamples** aSamples) diff --git a/content/media/gmp/GMPAudioHost.h b/content/media/gmp/GMPAudioHost.h index 32f09ca573cd..975f45327e53 100644 --- a/content/media/gmp/GMPAudioHost.h +++ b/content/media/gmp/GMPAudioHost.h @@ -22,7 +22,9 @@ class GMPAudioSamplesImpl : public GMPAudioSamples { public: GMPAudioSamplesImpl(GMPAudioFormat aFormat); GMPAudioSamplesImpl(const GMPAudioEncodedSampleData& aData); - GMPAudioSamplesImpl(mp4_demuxer::MP4Sample* aSample); + GMPAudioSamplesImpl(mp4_demuxer::MP4Sample* aSample, + uint32_t aChannels, + uint32_t aRate); virtual ~GMPAudioSamplesImpl(); virtual GMPAudioFormat GetFormat() MOZ_OVERRIDE; @@ -39,11 +41,18 @@ public: void RelinquishData(GMPAudioEncodedSampleData& aData); + virtual uint32_t Channels() const MOZ_OVERRIDE; + virtual void SetChannels(uint32_t aChannels) MOZ_OVERRIDE; + virtual uint32_t Rate() const MOZ_OVERRIDE; + virtual void SetRate(uint32_t aRate) MOZ_OVERRIDE; + private: GMPAudioFormat mFormat; nsTArray mBuffer; int64_t mTimeStamp; nsAutoPtr mCrypto; + uint32_t mChannels; + uint32_t mRate; }; class GMPAudioHostImpl : public GMPAudioHost diff --git a/content/media/gmp/GMPChild.cpp b/content/media/gmp/GMPChild.cpp index d0780dff02c9..1c5f9bb31dc9 100644 --- a/content/media/gmp/GMPChild.cpp +++ b/content/media/gmp/GMPChild.cpp @@ -27,9 +27,11 @@ using mozilla::dom::CrashReporterChild; #if defined(XP_WIN) #define TARGET_SANDBOX_EXPORTS #include "mozilla/sandboxTarget.h" -#elif defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) +#elif defined (MOZ_GMP_SANDBOX) +#if defined(XP_LINUX) || defined(XP_MACOSX) #include "mozilla/Sandbox.h" #endif +#endif namespace mozilla { namespace gmp { @@ -45,34 +47,9 @@ GMPChild::~GMPChild() { } -void -GMPChild::CheckThread() -{ - MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current()); -} - -bool -GMPChild::Init(const std::string& aPluginPath, - base::ProcessHandle aParentProcessHandle, - MessageLoop* aIOLoop, - IPC::Channel* aChannel) -{ - if (!Open(aChannel, aParentProcessHandle, aIOLoop)) { - return false; - } - -#ifdef MOZ_CRASHREPORTER - SendPCrashReporterConstructor(CrashReporter::CurrentThreadId()); -#endif -#if defined(XP_WIN) - mozilla::SandboxTarget::Instance()->StartSandbox(); -#endif - - return LoadPluginLibrary(aPluginPath); -} - -bool -GMPChild::LoadPluginLibrary(const std::string& aPluginPath) +static bool +GetPluginBinaryPath(const std::string& aPluginPath, + nsCString &aPluginBinaryPath) { nsDependentCString pluginPath(aPluginPath.c_str()); @@ -99,8 +76,83 @@ GMPChild::LoadPluginLibrary(const std::string& aPluginPath) #endif libFile->AppendRelativePath(binaryName); + libFile->GetNativePath(aPluginBinaryPath); + return true; +} + +#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) +void +GMPChild::OnChannelConnected(int32_t aPid) +{ + MacSandboxInfo info; + info.type = MacSandboxType_Plugin; + info.pluginInfo.type = MacSandboxPluginType_GMPlugin_Default; + info.pluginInfo.pluginPath.Assign(mPluginPath.c_str()); + + nsAutoCString pluginBinaryPath; + if (!GetPluginBinaryPath(mPluginPath, pluginBinaryPath)) { + MOZ_CRASH("Error scanning plugin path"); + } + mPluginBinaryPath.Assign(pluginBinaryPath); + info.pluginInfo.pluginBinaryPath.Assign(pluginBinaryPath); + + nsAutoCString err; + if (!mozilla::StartMacSandbox(info, err)) { + NS_WARNING(err.get()); + MOZ_CRASH("sandbox_init() failed"); + } + + if (!LoadPluginLibrary(mPluginPath)) { + err.AppendPrintf("Failed to load GMP plugin \"%s\"", + mPluginPath.c_str()); + NS_WARNING(err.get()); + MOZ_CRASH("Failed to load GMP plugin"); + } +} +#endif // XP_MACOSX && MOZ_GMP_SANDBOX + +void +GMPChild::CheckThread() +{ + MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current()); +} + +bool +GMPChild::Init(const std::string& aPluginPath, + base::ProcessHandle aParentProcessHandle, + MessageLoop* aIOLoop, + IPC::Channel* aChannel) +{ + if (!Open(aChannel, aParentProcessHandle, aIOLoop)) { + return false; + } + +#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) + mPluginPath = aPluginPath; + return true; +#endif + +#ifdef MOZ_CRASHREPORTER + SendPCrashReporterConstructor(CrashReporter::CurrentThreadId()); +#endif +#if defined(XP_WIN) + mozilla::SandboxTarget::Instance()->StartSandbox(); +#endif + + return LoadPluginLibrary(aPluginPath); +} + +bool +GMPChild::LoadPluginLibrary(const std::string& aPluginPath) +{ nsAutoCString nativePath; - libFile->GetNativePath(nativePath); +#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) + nativePath.Assign(mPluginBinaryPath); +#else + if (!GetPluginBinaryPath(aPluginPath, nativePath)) { + return false; + } +#endif #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) // Enable sandboxing here -- we know the plugin file's path, but diff --git a/content/media/gmp/GMPChild.h b/content/media/gmp/GMPChild.h index dd453cde4050..d01f1b031dd5 100644 --- a/content/media/gmp/GMPChild.h +++ b/content/media/gmp/GMPChild.h @@ -22,6 +22,10 @@ public: GMPChild(); virtual ~GMPChild(); +#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) + void OnChannelConnected(int32_t aPid); +#endif + bool Init(const std::string& aPluginPath, base::ProcessHandle aParentProcessHandle, MessageLoop* aIOLoop, @@ -68,6 +72,10 @@ private: PRLibrary* mLib; GMPGetAPIFunc mGetAPIFunc; MessageLoop* mGMPMessageLoop; +#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) + std::string mPluginPath; + nsCString mPluginBinaryPath; +#endif }; } // namespace gmp diff --git a/content/media/gmp/GMPTypes.ipdlh b/content/media/gmp/GMPTypes.ipdlh index 87c0e64040b1..df5122e714dd 100644 --- a/content/media/gmp/GMPTypes.ipdlh +++ b/content/media/gmp/GMPTypes.ipdlh @@ -63,12 +63,16 @@ struct GMPAudioEncodedSampleData uint8_t[] mData; uint64_t mTimeStamp; // microseconds. GMPDecryptionData mDecryptionData; + uint32_t mChannelCount; + uint32_t mSamplesPerSecond; }; struct GMPAudioDecodedSampleData { int16_t[] mData; uint64_t mTimeStamp; // microseconds. + uint32_t mChannelCount; + uint32_t mSamplesPerSecond; }; } diff --git a/content/media/gmp/gmp-api/gmp-audio-samples.h b/content/media/gmp/gmp-api/gmp-audio-samples.h index 4edbf7d8bc4b..a47fc74b9918 100644 --- a/content/media/gmp/gmp-api/gmp-audio-samples.h +++ b/content/media/gmp/gmp-api/gmp-audio-samples.h @@ -52,6 +52,23 @@ public: // Get metadata describing how this frame is encrypted, or nullptr if the // buffer is not encrypted. virtual const GMPEncryptedBufferMetadata* GetDecryptionData() const = 0; + + virtual uint32_t Channels() const = 0; + virtual void SetChannels(uint32_t aChannels) = 0; + + // Rate; the number of frames per second, where a "frame" is one sample for + // each channel. + // + // For IS16 samples, the number of samples should be: + // Size() / (Channels() * sizeof(int16_t)). + // + // Note: Channels() and Rate() may not be constant across a decoding + // session. For example the rate for decoded samples may be different + // than the rate advertised by the MP4 container for encoded samples + // for HE-AAC streams with SBR/PS, and an EME-GMP may need to downsample + // to satisfy DRM requirements. + virtual uint32_t Rate() const = 0; + virtual void SetRate(uint32_t aRate) = 0; }; #endif // GMP_AUDIO_FRAME_h_ diff --git a/content/xul/document/src/XULDocument.cpp b/content/xul/document/src/XULDocument.cpp index e8e4fc10c09f..758080cf50e8 100644 --- a/content/xul/document/src/XULDocument.cpp +++ b/content/xul/document/src/XULDocument.cpp @@ -797,8 +797,7 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener, if (! mBroadcasterMap) { mBroadcasterMap = - PL_NewDHashTable(&gOps, nullptr, sizeof(BroadcasterMapEntry), - PL_DHASH_MIN_SIZE); + PL_NewDHashTable(&gOps, nullptr, sizeof(BroadcasterMapEntry)); if (! mBroadcasterMap) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); diff --git a/content/xul/templates/src/nsContentSupportMap.cpp b/content/xul/templates/src/nsContentSupportMap.cpp index 0578a84be65b..224dce752c02 100644 --- a/content/xul/templates/src/nsContentSupportMap.cpp +++ b/content/xul/templates/src/nsContentSupportMap.cpp @@ -9,8 +9,7 @@ void nsContentSupportMap::Init() { - PL_DHashTableInit(&mMap, PL_DHashGetStubOps(), nullptr, - sizeof(Entry), PL_DHASH_MIN_SIZE); + PL_DHashTableInit(&mMap, PL_DHashGetStubOps(), nullptr, sizeof(Entry)); } void @@ -26,7 +25,7 @@ nsContentSupportMap::Remove(nsIContent* aElement) if (!mMap.ops) return NS_ERROR_NOT_INITIALIZED; - nsIContent* child = aElement; + nsIContent* child = aElement; do { PL_DHashTableOperate(&mMap, child, PL_DHASH_REMOVE); child = child->GetNextNode(aElement); diff --git a/content/xul/templates/src/nsTemplateMap.h b/content/xul/templates/src/nsTemplateMap.h index 0b591c84e7ad..fae6f188b154 100644 --- a/content/xul/templates/src/nsTemplateMap.h +++ b/content/xul/templates/src/nsTemplateMap.h @@ -20,7 +20,11 @@ protected: PLDHashTable mTable; void - Init() { PL_DHashTableInit(&mTable, PL_DHashGetStubOps(), nullptr, sizeof(Entry), PL_DHASH_MIN_SIZE); } + Init() + { + PL_DHashTableInit(&mTable, PL_DHashGetStubOps(), nullptr, + sizeof(Entry)); + } void Finish() { PL_DHashTableFinish(&mTable); } diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index c49a33d927c6..3c5628b290a1 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -192,6 +192,7 @@ #include "nsIWidget.h" #include "mozilla/dom/EncodingUtils.h" #include "mozilla/dom/ScriptSettings.h" +#include "mozilla/dom/URLSearchParams.h" static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); @@ -1932,6 +1933,24 @@ nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, mLSHE->GetIsSubFrame(&isSubFrame); } + // nsDocShell owns a URLSearchParams that is used by + // window.location.searchParams to be in sync with the current location. + if (!mURLSearchParams) { + mURLSearchParams = new URLSearchParams(); + } + + nsAutoCString search; + + nsCOMPtr url(do_QueryInterface(mCurrentURI)); + if (url) { + nsresult rv = url->GetQuery(search); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to get the query from a nsIURL."); + } + } + + mURLSearchParams->ParseInput(search, nullptr); + if (!isSubFrame && !isRoot) { /* * We don't want to send OnLocationChange notifications when @@ -2133,6 +2152,22 @@ nsDocShell::GetHasMixedDisplayContentBlocked(bool* aHasMixedDisplayContentBlocke return NS_OK; } +NS_IMETHODIMP +nsDocShell::GetHasTrackingContentBlocked(bool* aHasTrackingContentBlocked) +{ + nsCOMPtr doc(GetDocument()); + *aHasTrackingContentBlocked = doc && doc->GetHasTrackingContentBlocked(); + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetHasTrackingContentLoaded(bool* aHasTrackingContentLoaded) +{ + nsCOMPtr doc(GetDocument()); + *aHasTrackingContentLoaded = doc && doc->GetHasTrackingContentLoaded(); + return NS_OK; +} + NS_IMETHODIMP nsDocShell::GetAllowPlugins(bool * aAllowPlugins) { @@ -5348,6 +5383,11 @@ nsDocShell::Destroy() mParentWidget = nullptr; mCurrentURI = nullptr; + if (mURLSearchParams) { + mURLSearchParams->RemoveObservers(); + mURLSearchParams = nullptr; + } + if (mScriptGlobal) { mScriptGlobal->DetachFromDocShell(); mScriptGlobal = nullptr; @@ -7099,10 +7139,9 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, } // Handle iframe document not loading error because source was - // a tracking URL. (Safebrowsing) We make a note of this iframe - // node by including it in a dedicated array of blocked tracking - // nodes under its parent document. (document of parent window of - // blocked document) + // a tracking URL. We make a note of this iframe node by including + // it in a dedicated array of blocked tracking nodes under its parent + // document. (document of parent window of blocked document) if (isTopFrame == false && aStatus == NS_ERROR_TRACKING_URI) { // frameElement is our nsIContent to be annotated nsCOMPtr frameElement; @@ -13187,3 +13226,9 @@ nsDocShell::GetOpenedRemote() nsCOMPtr openedRemote(do_QueryReferent(mOpenedRemote)); return openedRemote; } + +URLSearchParams* +nsDocShell::GetURLSearchParams() +{ + return mURLSearchParams; +} diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 9b697bff8a71..82b93bcfb7cf 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -50,6 +50,7 @@ namespace mozilla { namespace dom { class EventTarget; +class URLSearchParams; } } @@ -763,6 +764,9 @@ protected: nsCOMPtr mFailedChannel; uint32_t mFailedLoadType; + // window.location.searchParams is updated in sync with this object. + nsRefPtr mURLSearchParams; + // Set in DoURILoad when either the LOAD_RELOAD_ALLOW_MIXED_CONTENT flag or // the LOAD_NORMAL_ALLOW_MIXED_CONTENT flag is set. // Checked in nsMixedContentBlocker, to see if the channels match. diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index f9daf4e71909..e1a203c57e46 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -11,6 +11,13 @@ #include "js/TypeDecls.h" class nsPresContext; class nsIPresShell; + +namespace mozilla { +namespace dom { +class URLSearchParams; +} +} + %} /** @@ -19,6 +26,7 @@ class nsIPresShell; [ptr] native nsPresContext(nsPresContext); [ptr] native nsIPresShell(nsIPresShell); +[ptr] native URLSearchParams(mozilla::dom::URLSearchParams); interface nsIURI; interface nsIChannel; @@ -46,7 +54,7 @@ interface nsITabParent; typedef unsigned long nsLoadFlags; -[scriptable, builtinclass, uuid(e5fe5c76-e511-4da3-9709-f8294b8dc5ce)] +[scriptable, builtinclass, uuid(3646c915-df79-4500-8b57-c65ab9c3b39f)] interface nsIDocShell : nsIDocShellTreeItem { /** @@ -561,6 +569,19 @@ interface nsIDocShell : nsIDocShellTreeItem */ [infallible] readonly attribute boolean hasMixedDisplayContentBlocked; + /** + * This attribute determines whether a document has Tracking Content + * that has been blocked from loading. + */ + [infallible] readonly attribute boolean hasTrackingContentBlocked; + + /** + * This attribute determines whether Tracking Content is loaded on the + * document. When it is true, tracking content was not blocked and has + * loaded (or is about to load) on the page. + */ + [infallible] readonly attribute boolean hasTrackingContentLoaded; + /** * Disconnects this docshell's editor from its window, and stores the * editor data in the open document's session history entry. This @@ -982,4 +1003,7 @@ interface nsIDocShell : nsIDocShellTreeItem */ [noscript,notxpcom,nostdcall] void setOpenedRemote(in nsITabParent aOpenedRemote); [noscript,notxpcom,nostdcall] nsITabParent getOpenedRemote(); + + // URLSearchParams for the window.location is owned by the docShell. + [noscript,notxpcom] URLSearchParams getURLSearchParams(); }; diff --git a/dom/base/URL.cpp b/dom/base/URL.cpp index 80fe487d8471..7a73c265e7e4 100644 --- a/dom/base/URL.cpp +++ b/dom/base/URL.cpp @@ -341,9 +341,10 @@ URL::SetHost(const nsAString& aHost, ErrorResult& aRv) } void -URL::URLSearchParamsUpdated() +URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams) { MOZ_ASSERT(mSearchParams); + MOZ_ASSERT(mSearchParams == aSearchParams); nsAutoString search; mSearchParams->Serialize(search); diff --git a/dom/base/URL.h b/dom/base/URL.h index 1ed7b85dcbcb..23cfa85e0d8b 100644 --- a/dom/base/URL.h +++ b/dom/base/URL.h @@ -121,7 +121,7 @@ public: } // URLSearchParamsObserver - void URLSearchParamsUpdated() MOZ_OVERRIDE; + void URLSearchParamsUpdated(URLSearchParams* aSearchParams) MOZ_OVERRIDE; private: nsIURI* GetURI() const diff --git a/dom/base/URLSearchParams.cpp b/dom/base/URLSearchParams.cpp index 2092146d7f02..dc9d22e9e811 100644 --- a/dom/base/URLSearchParams.cpp +++ b/dom/base/URLSearchParams.cpp @@ -5,6 +5,7 @@ #include "URLSearchParams.h" #include "mozilla/dom/URLSearchParamsBinding.h" +#include "mozilla/dom/EncodingUtils.h" namespace mozilla { namespace dom { @@ -98,30 +99,31 @@ URLSearchParams::ParseInput(const nsACString& aInput, name.Assign(string); } - nsAutoCString decodedName; + nsAutoString decodedName; DecodeString(name, decodedName); - nsAutoCString decodedValue; + nsAutoString decodedValue; DecodeString(value, decodedValue); - AppendInternal(NS_ConvertUTF8toUTF16(decodedName), - NS_ConvertUTF8toUTF16(decodedValue)); + AppendInternal(decodedName, decodedValue); } NotifyObservers(aObserver); } void -URLSearchParams::DecodeString(const nsACString& aInput, nsACString& aOutput) +URLSearchParams::DecodeString(const nsACString& aInput, nsAString& aOutput) { nsACString::const_iterator start, end; aInput.BeginReading(start); aInput.EndReading(end); + nsCString unescaped; + while (start != end) { // replace '+' with U+0020 if (*start == '+') { - aOutput.Append(' '); + unescaped.Append(' '); ++start; continue; } @@ -148,20 +150,62 @@ URLSearchParams::DecodeString(const nsACString& aInput, nsACString& aOutput) if (first != end && second != end && ASCII_HEX_DIGIT(*first) && ASCII_HEX_DIGIT(*second)) { - aOutput.Append(HEX_DIGIT(first) * 16 + HEX_DIGIT(second)); + unescaped.Append(HEX_DIGIT(first) * 16 + HEX_DIGIT(second)); start = ++second; continue; } else { - aOutput.Append('%'); + unescaped.Append('%'); ++start; continue; } } - aOutput.Append(*start); + unescaped.Append(*start); ++start; } + + ConvertString(unescaped, aOutput); +} + +void +URLSearchParams::ConvertString(const nsACString& aInput, nsAString& aOutput) +{ + aOutput.Truncate(); + + if (!mDecoder) { + mDecoder = EncodingUtils::DecoderForEncoding("UTF-8"); + if (!mDecoder) { + MOZ_ASSERT(mDecoder, "Failed to create a decoder."); + return; + } + } + + nsACString::const_iterator iter; + aInput.BeginReading(iter); + + int32_t inputLength = aInput.Length(); + int32_t outputLength = 0; + + nsresult rv = mDecoder->GetMaxLength(iter.get(), inputLength, + &outputLength); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + const mozilla::fallible_t fallible = mozilla::fallible_t(); + nsAutoArrayPtr buf(new (fallible) char16_t[outputLength + 1]); + if (!buf) { + return; + } + + rv = mDecoder->Convert(iter.get(), &inputLength, buf, &outputLength); + if (NS_SUCCEEDED(rv)) { + buf[outputLength] = 0; + if (!aOutput.Assign(buf, outputLength, mozilla::fallible_t())) { + aOutput.Truncate(); + } + } } /* static */ PLDHashOperator @@ -193,6 +237,12 @@ URLSearchParams::RemoveObserver(URLSearchParamsObserver* aObserver) mObservers.RemoveElement(aObserver); } +void +URLSearchParams::RemoveObservers() +{ + mObservers.Clear(); +} + void URLSearchParams::Get(const nsAString& aName, nsString& aRetval) { @@ -343,7 +393,7 @@ URLSearchParams::NotifyObservers(URLSearchParamsObserver* aExceptObserver) { for (uint32_t i = 0; i < mObservers.Length(); ++i) { if (mObservers[i] != aExceptObserver) { - mObservers[i]->URLSearchParamsUpdated(); + mObservers[i]->URLSearchParamsUpdated(this); } } } diff --git a/dom/base/URLSearchParams.h b/dom/base/URLSearchParams.h index 92168f0dddcb..e141f53ddd2a 100644 --- a/dom/base/URLSearchParams.h +++ b/dom/base/URLSearchParams.h @@ -13,16 +13,19 @@ #include "nsClassHashtable.h" #include "nsHashKeys.h" #include "nsISupports.h" +#include "nsIUnicodeDecoder.h" namespace mozilla { namespace dom { +class URLSearchParams; + class URLSearchParamsObserver : public nsISupports { public: virtual ~URLSearchParamsObserver() {} - virtual void URLSearchParamsUpdated() = 0; + virtual void URLSearchParamsUpdated(URLSearchParams* aFromThis) = 0; }; class URLSearchParams MOZ_FINAL : public nsISupports, @@ -58,6 +61,7 @@ public: void AddObserver(URLSearchParamsObserver* aObserver); void RemoveObserver(URLSearchParamsObserver* aObserver); + void RemoveObservers(); void Serialize(nsAString& aValue) const; @@ -83,7 +87,8 @@ private: void DeleteAll(); - void DecodeString(const nsACString& aInput, nsACString& aOutput); + void DecodeString(const nsACString& aInput, nsAString& aOutput); + void ConvertString(const nsACString& aInput, nsAString& aOutput); void NotifyObservers(URLSearchParamsObserver* aExceptObserver); @@ -98,6 +103,7 @@ private: nsClassHashtable> mSearchParams; nsTArray> mObservers; + nsCOMPtr mDecoder; }; } // namespace dom diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 9e68f7e48bb4..509354538b88 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -1612,7 +1612,7 @@ nsDOMWindowUtils::GetTranslationNodes(nsIDOMNode* aRoot, return NS_ERROR_DOM_WRONG_DOCUMENT_ERR; } - nsTHashtable> translationNodesHash(1000); + nsTHashtable> translationNodesHash(500); nsRefPtr list = new nsTranslationNodeList; uint32_t limit = 15000; diff --git a/dom/base/nsLocation.cpp b/dom/base/nsLocation.cpp index 7012d500176c..d16e6c720804 100644 --- a/dom/base/nsLocation.cpp +++ b/dom/base/nsLocation.cpp @@ -68,16 +68,33 @@ nsLocation::nsLocation(nsPIDOMWindow* aWindow, nsIDocShell *aDocShell) nsLocation::~nsLocation() { + RemoveURLSearchParams(); } // QueryInterface implementation for nsLocation NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsLocation) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsIDOMLocation) - NS_INTERFACE_MAP_ENTRY(nsISupports) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMLocation) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsLocation, mInnerWindow) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsLocation) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsLocation) + tmp->RemoveURLSearchParams(); + + NS_IMPL_CYCLE_COLLECTION_UNLINK(mInnerWindow); + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsLocation) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSearchParams) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInnerWindow) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsLocation) + NS_IMPL_CYCLE_COLLECTING_ADDREF(nsLocation) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsLocation) @@ -858,6 +875,17 @@ nsLocation::GetSearch(nsAString& aSearch) NS_IMETHODIMP nsLocation::SetSearch(const nsAString& aSearch) +{ + nsresult rv = SetSearchInternal(aSearch); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +nsresult +nsLocation::SetSearchInternal(const nsAString& aSearch) { if (!CallerSubsumes()) return NS_ERROR_DOM_SECURITY_ERR; @@ -1036,3 +1064,119 @@ nsLocation::WrapObject(JSContext* aCx) { return LocationBinding::Wrap(aCx, this); } + +URLSearchParams* +nsLocation::GetDocShellSearchParams() +{ + nsCOMPtr docShell = GetDocShell(); + if (!docShell) { + return nullptr; + } + + return docShell->GetURLSearchParams(); +} + +URLSearchParams* +nsLocation::SearchParams() +{ + if (!mSearchParams) { + // We must register this object to the URLSearchParams of the docshell in + // order to receive updates. + nsRefPtr searchParams = GetDocShellSearchParams(); + if (searchParams) { + searchParams->AddObserver(this); + } + + mSearchParams = new URLSearchParams(); + mSearchParams->AddObserver(this); + UpdateURLSearchParams(); + } + + return mSearchParams; +} + +void +nsLocation::SetSearchParams(URLSearchParams& aSearchParams) +{ + if (mSearchParams) { + mSearchParams->RemoveObserver(this); + } + + // the observer will be cleared using the cycle collector. + mSearchParams = &aSearchParams; + mSearchParams->AddObserver(this); + + nsAutoString search; + mSearchParams->Serialize(search); + SetSearchInternal(search); + + // We don't need to inform the docShell about this new SearchParams because + // setting the new value the docShell will refresh its value automatically. +} + +void +nsLocation::URLSearchParamsUpdated(URLSearchParams* aSearchParams) +{ + MOZ_ASSERT(mSearchParams); + + // This change comes from content. + if (aSearchParams == mSearchParams) { + nsAutoString search; + mSearchParams->Serialize(search); + SetSearchInternal(search); + return; + } + + // This change comes from the docShell. +#ifdef DEBUG + { + nsRefPtr searchParams = GetDocShellSearchParams(); + MOZ_ASSERT(searchParams); + MOZ_ASSERT(aSearchParams == searchParams); + } +#endif + + nsAutoString search; + aSearchParams->Serialize(search); + mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(search), this); +} + +void +nsLocation::UpdateURLSearchParams() +{ + if (!mSearchParams) { + return; + } + + nsAutoCString search; + + nsCOMPtr uri; + nsresult rv = GetURI(getter_AddRefs(uri)); + if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!uri)) { + return; + } + + nsCOMPtr url(do_QueryInterface(uri)); + if (url) { + nsresult rv = url->GetQuery(search); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to get the query from a nsIURL."); + } + } + + mSearchParams->ParseInput(search, this); +} + +void +nsLocation::RemoveURLSearchParams() +{ + if (mSearchParams) { + mSearchParams->RemoveObserver(this); + mSearchParams = nullptr; + + nsRefPtr docShellSearchParams = GetDocShellSearchParams(); + if (docShellSearchParams) { + docShellSearchParams->RemoveObserver(this); + } + } +} diff --git a/dom/base/nsLocation.h b/dom/base/nsLocation.h index f3fc3b4d73e6..8bc58f6f3543 100644 --- a/dom/base/nsLocation.h +++ b/dom/base/nsLocation.h @@ -14,6 +14,7 @@ #include "nsCycleCollectionParticipant.h" #include "js/TypeDecls.h" #include "mozilla/ErrorResult.h" +#include "mozilla/dom/URLSearchParams.h" #include "nsPIDOMWindow.h" class nsIURI; @@ -26,6 +27,7 @@ class nsIDocShellLoadInfo; class nsLocation MOZ_FINAL : public nsIDOMLocation , public nsWrapperCache + , public mozilla::dom::URLSearchParamsObserver { typedef mozilla::ErrorResult ErrorResult; @@ -33,7 +35,8 @@ public: nsLocation(nsPIDOMWindow* aWindow, nsIDocShell *aDocShell); NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsLocation) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsLocation, + nsIDOMLocation) void SetDocShell(nsIDocShell *aDocShell); nsIDocShell *GetDocShell(); @@ -118,6 +121,11 @@ public: { aError = SetSearch(aSeach); } + + mozilla::dom::URLSearchParams* SearchParams(); + + void SetSearchParams(mozilla::dom::URLSearchParams& aSearchParams); + void GetHash(nsAString& aHash, ErrorResult& aError) { aError = GetHash(aHash); @@ -136,9 +144,18 @@ public: } virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; + // URLSearchParamsObserver + void URLSearchParamsUpdated(mozilla::dom::URLSearchParams* aSearchParams) MOZ_OVERRIDE; + protected: virtual ~nsLocation(); + nsresult SetSearchInternal(const nsAString& aSearch); + void UpdateURLSearchParams(); + void RemoveURLSearchParams(); + + mozilla::dom::URLSearchParams* GetDocShellSearchParams(); + // In the case of jar: uris, we sometimes want the place the jar was // fetched from as the URI instead of the jar: uri itself. Pass in // true for aGetInnermostURI when that's the case. @@ -156,6 +173,7 @@ protected: nsString mCachedHash; nsCOMPtr mInnerWindow; + nsRefPtr mSearchParams; nsWeakPtr mDocShell; }; diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index dfb4184592ca..1b6e962cac7f 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -314,7 +314,7 @@ nsScriptNameSpaceManager::RegisterInterface(const char* aIfName, return NS_OK; } -#define GLOBALNAME_HASHTABLE_INITIAL_SIZE 1024 +#define GLOBALNAME_HASHTABLE_INITIAL_LENGTH 512 nsresult nsScriptNameSpaceManager::Init() @@ -333,14 +333,14 @@ nsScriptNameSpaceManager::Init() mIsInitialized = PL_DHashTableInit(&mGlobalNames, &hash_table_ops, nullptr, sizeof(GlobalNameMapEntry), - GLOBALNAME_HASHTABLE_INITIAL_SIZE, - fallible_t()); + fallible_t(), + GLOBALNAME_HASHTABLE_INITIAL_LENGTH); NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_OUT_OF_MEMORY); mIsInitialized = PL_DHashTableInit(&mNavigatorNames, &hash_table_ops, nullptr, sizeof(GlobalNameMapEntry), - GLOBALNAME_HASHTABLE_INITIAL_SIZE, - fallible_t()); + fallible_t(), + GLOBALNAME_HASHTABLE_INITIAL_LENGTH); if (!mIsInitialized) { PL_DHashTableFinish(&mGlobalNames); diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index c2ce933b4247..c988349f39f2 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -47,6 +47,7 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1 [test_history_state_null.html] [test_Image_constructor.html] [test_innersize_scrollport.html] +[test_location_searchParams.html] [test_messageChannel.html] [test_messageChannel_cloning.html] [test_messageChannel_pingpong.html] @@ -74,6 +75,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec [test_url_malformedHost.html] [test_urlExceptions.html] [test_urlSearchParams.html] +[test_urlSearchParams_utf8.html] [test_urlutils_stringify.html] [test_window_constructor.html] [test_window_cross_origin_props.html] diff --git a/dom/base/test/test_location_searchParams.html b/dom/base/test/test_location_searchParams.html new file mode 100644 index 000000000000..0e7a25d3f926 --- /dev/null +++ b/dom/base/test/test_location_searchParams.html @@ -0,0 +1,89 @@ + + + + + + + Test for Bug 1037715 + + + + + Mozilla Bug 1037715 + + + + + diff --git a/dom/base/test/test_urlSearchParams_utf8.html b/dom/base/test/test_urlSearchParams_utf8.html new file mode 100644 index 000000000000..22c85de45b86 --- /dev/null +++ b/dom/base/test/test_urlSearchParams_utf8.html @@ -0,0 +1,40 @@ + + + + + + + Test for Bug 1032511 + + + + +Mozilla Bug 1032511 +

+ +
+
+foobar +foobar + + + diff --git a/dom/bluetooth/bluedroid/BluetoothInterface.cpp b/dom/bluetooth/bluedroid/BluetoothInterface.cpp index d338263ddd5b..e866659ba9e3 100644 --- a/dom/bluetooth/bluedroid/BluetoothInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothInterface.cpp @@ -13,6 +13,16 @@ #include "nsThreadUtils.h" #include "nsXULAppAPI.h" +#if MOZ_IS_GCC && MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) +/* use designated array initializers if supported */ +#define CONVERT(in_, out_) \ + [in_] = out_ +#else +/* otherwise init array element by position */ +#define CONVERT(in_, out_) \ + out_ +#endif + BEGIN_BLUETOOTH_NAMESPACE template @@ -27,17 +37,17 @@ static nsresult Convert(bt_status_t aIn, BluetoothStatus& aOut) { static const BluetoothStatus sStatus[] = { - [BT_STATUS_SUCCESS] = STATUS_SUCCESS, - [BT_STATUS_FAIL] = STATUS_FAIL, - [BT_STATUS_NOT_READY] = STATUS_NOT_READY, - [BT_STATUS_NOMEM] = STATUS_NOMEM, - [BT_STATUS_BUSY] = STATUS_BUSY, - [BT_STATUS_DONE] = STATUS_DONE, - [BT_STATUS_UNSUPPORTED] = STATUS_UNSUPPORTED, - [BT_STATUS_PARM_INVALID] = STATUS_PARM_INVALID, - [BT_STATUS_UNHANDLED] = STATUS_UNHANDLED, - [BT_STATUS_AUTH_FAILURE] = STATUS_AUTH_FAILURE, - [BT_STATUS_RMT_DEV_DOWN] = STATUS_RMT_DEV_DOWN + CONVERT(BT_STATUS_SUCCESS, STATUS_SUCCESS), + CONVERT(BT_STATUS_FAIL, STATUS_FAIL), + CONVERT(BT_STATUS_NOT_READY, STATUS_NOT_READY), + CONVERT(BT_STATUS_NOMEM, STATUS_NOMEM), + CONVERT(BT_STATUS_BUSY, STATUS_BUSY), + CONVERT(BT_STATUS_DONE, STATUS_DONE), + CONVERT(BT_STATUS_UNSUPPORTED, STATUS_UNSUPPORTED), + CONVERT(BT_STATUS_PARM_INVALID, STATUS_PARM_INVALID), + CONVERT(BT_STATUS_UNHANDLED, STATUS_UNHANDLED), + CONVERT(BT_STATUS_AUTH_FAILURE, STATUS_AUTH_FAILURE), + CONVERT(BT_STATUS_RMT_DEV_DOWN, STATUS_RMT_DEV_DOWN) }; if (aIn >= MOZ_ARRAY_LENGTH(sStatus)) { return NS_ERROR_ILLEGAL_VALUE; @@ -72,8 +82,8 @@ static nsresult Convert(bool aIn, bt_scan_mode_t& aOut) { static const bt_scan_mode_t sScanMode[] = { - [false] = BT_SCAN_MODE_CONNECTABLE, - [true] = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE + CONVERT(false, BT_SCAN_MODE_CONNECTABLE), + CONVERT(true, BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE) }; if (aIn >= MOZ_ARRAY_LENGTH(sScanMode)) { return NS_ERROR_ILLEGAL_VALUE; @@ -238,10 +248,10 @@ Convert(BluetoothSocketType aIn, btsock_type_t& aOut) // by gcc. Start values in |BluetoothSocketType| at index // 0 to fix this problem. static const btsock_type_t sSocketType[] = { - [0] = static_cast(0), // invalid, [0] required by gcc - [BluetoothSocketType::RFCOMM] = BTSOCK_RFCOMM, - [BluetoothSocketType::SCO] = BTSOCK_SCO, - [BluetoothSocketType::L2CAP] = BTSOCK_L2CAP, + CONVERT(0, static_cast(0)), // invalid, [0] required by gcc + CONVERT(BluetoothSocketType::RFCOMM, BTSOCK_RFCOMM), + CONVERT(BluetoothSocketType::SCO, BTSOCK_SCO), + CONVERT(BluetoothSocketType::L2CAP, BTSOCK_L2CAP), // EL2CAP is not supported by Bluedroid }; if (aIn == BluetoothSocketType::EL2CAP || @@ -256,8 +266,8 @@ static nsresult Convert(BluetoothHandsfreeAtResponse aIn, bthf_at_response_t& aOut) { static const bthf_at_response_t sAtResponse[] = { - [HFP_AT_RESPONSE_ERROR] = BTHF_AT_RESPONSE_ERROR, - [HFP_AT_RESPONSE_OK] = BTHF_AT_RESPONSE_OK + CONVERT(HFP_AT_RESPONSE_ERROR, BTHF_AT_RESPONSE_ERROR), + CONVERT(HFP_AT_RESPONSE_OK, BTHF_AT_RESPONSE_OK) }; if (aIn >= MOZ_ARRAY_LENGTH(sAtResponse)) { return NS_ERROR_ILLEGAL_VALUE; @@ -270,8 +280,9 @@ static nsresult Convert(BluetoothHandsfreeCallAddressType aIn, bthf_call_addrtype_t& aOut) { static const bthf_call_addrtype_t sCallAddressType[] = { - [HFP_CALL_ADDRESS_TYPE_UNKNOWN] = BTHF_CALL_ADDRTYPE_UNKNOWN, - [HFP_CALL_ADDRESS_TYPE_INTERNATIONAL] = BTHF_CALL_ADDRTYPE_INTERNATIONAL + CONVERT(HFP_CALL_ADDRESS_TYPE_UNKNOWN, BTHF_CALL_ADDRTYPE_UNKNOWN), + CONVERT(HFP_CALL_ADDRESS_TYPE_INTERNATIONAL, + BTHF_CALL_ADDRTYPE_INTERNATIONAL) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallAddressType)) { return NS_ERROR_ILLEGAL_VALUE; @@ -284,8 +295,8 @@ static nsresult Convert(BluetoothHandsfreeCallDirection aIn, bthf_call_direction_t& aOut) { static const bthf_call_direction_t sCallDirection[] = { - [HFP_CALL_DIRECTION_OUTGOING] = BTHF_CALL_DIRECTION_OUTGOING, - [HFP_CALL_DIRECTION_INCOMING] = BTHF_CALL_DIRECTION_INCOMING + CONVERT(HFP_CALL_DIRECTION_OUTGOING, BTHF_CALL_DIRECTION_OUTGOING), + CONVERT(HFP_CALL_DIRECTION_INCOMING, BTHF_CALL_DIRECTION_INCOMING) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallDirection)) { return NS_ERROR_ILLEGAL_VALUE; @@ -298,9 +309,9 @@ static nsresult Convert(BluetoothHandsfreeCallMode aIn, bthf_call_mode_t& aOut) { static const bthf_call_mode_t sCallMode[] = { - [HFP_CALL_MODE_VOICE] = BTHF_CALL_TYPE_VOICE, - [HFP_CALL_MODE_DATA] = BTHF_CALL_TYPE_DATA, - [HFP_CALL_MODE_FAX] = BTHF_CALL_TYPE_FAX + CONVERT(HFP_CALL_MODE_VOICE, BTHF_CALL_TYPE_VOICE), + CONVERT(HFP_CALL_MODE_DATA, BTHF_CALL_TYPE_DATA), + CONVERT(HFP_CALL_MODE_FAX, BTHF_CALL_TYPE_FAX) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallMode)) { return NS_ERROR_ILLEGAL_VALUE; @@ -313,8 +324,8 @@ static nsresult Convert(BluetoothHandsfreeCallMptyType aIn, bthf_call_mpty_type_t& aOut) { static const bthf_call_mpty_type_t sCallMptyType[] = { - [HFP_CALL_MPTY_TYPE_SINGLE] = BTHF_CALL_MPTY_TYPE_SINGLE, - [HFP_CALL_MPTY_TYPE_MULTI] = BTHF_CALL_MPTY_TYPE_MULTI + CONVERT(HFP_CALL_MPTY_TYPE_SINGLE, BTHF_CALL_MPTY_TYPE_SINGLE), + CONVERT(HFP_CALL_MPTY_TYPE_MULTI, BTHF_CALL_MPTY_TYPE_MULTI) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallMptyType)) { return NS_ERROR_ILLEGAL_VALUE; @@ -327,13 +338,13 @@ static nsresult Convert(BluetoothHandsfreeCallState aIn, bthf_call_state_t& aOut) { static const bthf_call_state_t sCallState[] = { - [HFP_CALL_STATE_ACTIVE] = BTHF_CALL_STATE_ACTIVE, - [HFP_CALL_STATE_HELD] = BTHF_CALL_STATE_HELD, - [HFP_CALL_STATE_DIALING] = BTHF_CALL_STATE_DIALING, - [HFP_CALL_STATE_ALERTING] = BTHF_CALL_STATE_ALERTING, - [HFP_CALL_STATE_INCOMING] = BTHF_CALL_STATE_INCOMING, - [HFP_CALL_STATE_WAITING] = BTHF_CALL_STATE_WAITING, - [HFP_CALL_STATE_IDLE] = BTHF_CALL_STATE_IDLE + CONVERT(HFP_CALL_STATE_ACTIVE, BTHF_CALL_STATE_ACTIVE), + CONVERT(HFP_CALL_STATE_HELD, BTHF_CALL_STATE_HELD), + CONVERT(HFP_CALL_STATE_DIALING, BTHF_CALL_STATE_DIALING), + CONVERT(HFP_CALL_STATE_ALERTING, BTHF_CALL_STATE_ALERTING), + CONVERT(HFP_CALL_STATE_INCOMING, BTHF_CALL_STATE_INCOMING), + CONVERT(HFP_CALL_STATE_WAITING, BTHF_CALL_STATE_WAITING), + CONVERT(HFP_CALL_STATE_IDLE, BTHF_CALL_STATE_IDLE) }; if (aIn >= MOZ_ARRAY_LENGTH(sCallState)) { return NS_ERROR_ILLEGAL_VALUE; @@ -346,8 +357,8 @@ static nsresult Convert(BluetoothHandsfreeNetworkState aIn, bthf_network_state_t& aOut) { static const bthf_network_state_t sNetworkState[] = { - [HFP_NETWORK_STATE_NOT_AVAILABLE] = BTHF_NETWORK_STATE_NOT_AVAILABLE, - [HFP_NETWORK_STATE_AVAILABLE] = BTHF_NETWORK_STATE_AVAILABLE + CONVERT(HFP_NETWORK_STATE_NOT_AVAILABLE, BTHF_NETWORK_STATE_NOT_AVAILABLE), + CONVERT(HFP_NETWORK_STATE_AVAILABLE, BTHF_NETWORK_STATE_AVAILABLE) }; if (aIn >= MOZ_ARRAY_LENGTH(sNetworkState)) { return NS_ERROR_ILLEGAL_VALUE; @@ -360,8 +371,8 @@ static nsresult Convert(BluetoothHandsfreeServiceType aIn, bthf_service_type_t& aOut) { static const bthf_service_type_t sServiceType[] = { - [HFP_SERVICE_TYPE_HOME] = BTHF_SERVICE_TYPE_HOME, - [HFP_SERVICE_TYPE_ROAMING] = BTHF_SERVICE_TYPE_ROAMING + CONVERT(HFP_SERVICE_TYPE_HOME, BTHF_SERVICE_TYPE_HOME), + CONVERT(HFP_SERVICE_TYPE_ROAMING, BTHF_SERVICE_TYPE_ROAMING) }; if (aIn >= MOZ_ARRAY_LENGTH(sServiceType)) { return NS_ERROR_ILLEGAL_VALUE; @@ -374,8 +385,8 @@ static nsresult Convert(BluetoothHandsfreeVolumeType aIn, bthf_volume_type_t& aOut) { static const bthf_volume_type_t sVolumeType[] = { - [HFP_VOLUME_TYPE_SPEAKER] = BTHF_VOLUME_TYPE_SPK, - [HFP_VOLUME_TYPE_MICROPHONE] = BTHF_VOLUME_TYPE_MIC + CONVERT(HFP_VOLUME_TYPE_SPEAKER, BTHF_VOLUME_TYPE_SPK), + CONVERT(HFP_VOLUME_TYPE_MICROPHONE, BTHF_VOLUME_TYPE_MIC) }; if (aIn >= MOZ_ARRAY_LENGTH(sVolumeType)) { return NS_ERROR_ILLEGAL_VALUE; @@ -389,11 +400,11 @@ static nsresult Convert(ControlPlayStatus aIn, btrc_play_status_t& aOut) { static const btrc_play_status_t sPlayStatus[] = { - [PLAYSTATUS_STOPPED] = BTRC_PLAYSTATE_STOPPED, - [PLAYSTATUS_PLAYING] = BTRC_PLAYSTATE_PLAYING, - [PLAYSTATUS_PAUSED] = BTRC_PLAYSTATE_PAUSED, - [PLAYSTATUS_FWD_SEEK] = BTRC_PLAYSTATE_FWD_SEEK, - [PLAYSTATUS_REV_SEEK] = BTRC_PLAYSTATE_REV_SEEK + CONVERT(PLAYSTATUS_STOPPED, BTRC_PLAYSTATE_STOPPED), + CONVERT(PLAYSTATUS_PLAYING, BTRC_PLAYSTATE_PLAYING), + CONVERT(PLAYSTATUS_PAUSED, BTRC_PLAYSTATE_PAUSED), + CONVERT(PLAYSTATUS_FWD_SEEK, BTRC_PLAYSTATE_FWD_SEEK), + CONVERT(PLAYSTATUS_REV_SEEK, BTRC_PLAYSTATE_REV_SEEK) }; if (aIn >= MOZ_ARRAY_LENGTH(sPlayStatus)) { return NS_ERROR_ILLEGAL_VALUE; @@ -406,10 +417,10 @@ static nsresult Convert(enum BluetoothAvrcpPlayerAttribute aIn, btrc_player_attr_t& aOut) { static const btrc_player_attr_t sPlayerAttr[] = { - [AVRCP_PLAYER_ATTRIBUTE_EQUALIZER] = BTRC_PLAYER_ATTR_EQUALIZER, - [AVRCP_PLAYER_ATTRIBUTE_REPEAT] = BTRC_PLAYER_ATTR_REPEAT, - [AVRCP_PLAYER_ATTRIBUTE_SHUFFLE] = BTRC_PLAYER_ATTR_SHUFFLE, - [AVRCP_PLAYER_ATTRIBUTE_SCAN] = BTRC_PLAYER_ATTR_SCAN + CONVERT(AVRCP_PLAYER_ATTRIBUTE_EQUALIZER, BTRC_PLAYER_ATTR_EQUALIZER), + CONVERT(AVRCP_PLAYER_ATTRIBUTE_REPEAT, BTRC_PLAYER_ATTR_REPEAT), + CONVERT(AVRCP_PLAYER_ATTRIBUTE_SHUFFLE, BTRC_PLAYER_ATTR_SHUFFLE), + CONVERT(AVRCP_PLAYER_ATTRIBUTE_SCAN, BTRC_PLAYER_ATTR_SCAN) }; if (aIn >= MOZ_ARRAY_LENGTH(sPlayerAttr)) { return NS_ERROR_ILLEGAL_VALUE; @@ -422,11 +433,11 @@ static nsresult Convert(enum BluetoothAvrcpStatus aIn, btrc_status_t& aOut) { static const btrc_status_t sStatus[] = { - [AVRCP_STATUS_BAD_COMMAND] = BTRC_STS_BAD_CMD, - [AVRCP_STATUS_BAD_PARAMETER] = BTRC_STS_BAD_PARAM, - [AVRCP_STATUS_NOT_FOUND] = BTRC_STS_NOT_FOUND, - [AVRCP_STATUS_INTERNAL_ERROR] = BTRC_STS_INTERNAL_ERR, - [AVRCP_STATUS_SUCCESS] = BTRC_STS_NO_ERROR + CONVERT(AVRCP_STATUS_BAD_COMMAND, BTRC_STS_BAD_CMD), + CONVERT(AVRCP_STATUS_BAD_PARAMETER, BTRC_STS_BAD_PARAM), + CONVERT(AVRCP_STATUS_NOT_FOUND, BTRC_STS_NOT_FOUND), + CONVERT(AVRCP_STATUS_INTERNAL_ERROR, BTRC_STS_INTERNAL_ERR), + CONVERT(AVRCP_STATUS_SUCCESS, BTRC_STS_NO_ERROR) }; if (aIn >= MOZ_ARRAY_LENGTH(sStatus)) { return NS_ERROR_ILLEGAL_VALUE; @@ -439,12 +450,12 @@ static nsresult Convert(enum BluetoothAvrcpEvent aIn, btrc_event_id_t& aOut) { static const btrc_event_id_t sEventId[] = { - [AVRCP_EVENT_PLAY_STATUS_CHANGED] = BTRC_EVT_PLAY_STATUS_CHANGED, - [AVRCP_EVENT_TRACK_CHANGE] = BTRC_EVT_TRACK_CHANGE, - [AVRCP_EVENT_TRACK_REACHED_END] = BTRC_EVT_TRACK_REACHED_END, - [AVRCP_EVENT_TRACK_REACHED_START] = BTRC_EVT_TRACK_REACHED_START, - [AVRCP_EVENT_PLAY_POS_CHANGED] = BTRC_EVT_PLAY_POS_CHANGED, - [AVRCP_EVENT_APP_SETTINGS_CHANGED] = BTRC_EVT_APP_SETTINGS_CHANGED + CONVERT(AVRCP_EVENT_PLAY_STATUS_CHANGED, BTRC_EVT_PLAY_STATUS_CHANGED), + CONVERT(AVRCP_EVENT_TRACK_CHANGE, BTRC_EVT_TRACK_CHANGE), + CONVERT(AVRCP_EVENT_TRACK_REACHED_END, BTRC_EVT_TRACK_REACHED_END), + CONVERT(AVRCP_EVENT_TRACK_REACHED_START, BTRC_EVT_TRACK_REACHED_START), + CONVERT(AVRCP_EVENT_PLAY_POS_CHANGED, BTRC_EVT_PLAY_POS_CHANGED), + CONVERT(AVRCP_EVENT_APP_SETTINGS_CHANGED, BTRC_EVT_APP_SETTINGS_CHANGED) }; if (aIn >= MOZ_ARRAY_LENGTH(sEventId)) { return NS_ERROR_ILLEGAL_VALUE; @@ -457,8 +468,8 @@ static nsresult Convert(enum BluetoothAvrcpNotification aIn, btrc_notification_type_t& aOut) { static const btrc_notification_type_t sNotificationType[] = { - [AVRCP_NTF_INTERIM] = BTRC_NOTIFICATION_TYPE_INTERIM, - [AVRCP_NTF_CHANGED] = BTRC_NOTIFICATION_TYPE_CHANGED + CONVERT(AVRCP_NTF_INTERIM, BTRC_NOTIFICATION_TYPE_INTERIM), + CONVERT(AVRCP_NTF_CHANGED, BTRC_NOTIFICATION_TYPE_CHANGED) }; if (aIn >= MOZ_ARRAY_LENGTH(sNotificationType)) { return NS_ERROR_ILLEGAL_VALUE; diff --git a/dom/bluetooth/bluez/BluetoothDBusService.cpp b/dom/bluetooth/bluez/BluetoothDBusService.cpp index 93b5c17b704e..74b778bfa205 100644 --- a/dom/bluetooth/bluez/BluetoothDBusService.cpp +++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp @@ -37,6 +37,7 @@ #include "nsDataHashtable.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Atomics.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/Hal.h" #include "mozilla/ipc/UnixSocket.h" @@ -373,6 +374,7 @@ DispatchToBtThread(nsIRunnable* aRunnable) sBluetoothThread = new LazyIdleThread(BT_LAZY_THREAD_TIMEOUT_MS, NS_LITERAL_CSTRING("BluetoothDBusService"), LazyIdleThread::ManualShutdown); + ClearOnShutdown(&sBluetoothThread); } return sBluetoothThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL); } diff --git a/dom/bluetooth/tests/marionette/head.js b/dom/bluetooth/tests/marionette/head.js index d1afbfb5056e..3e3a599a5c4a 100644 --- a/dom/bluetooth/tests/marionette/head.js +++ b/dom/bluetooth/tests/marionette/head.js @@ -705,17 +705,13 @@ function getDefaultAdapter() { } /** - * Flush permission settings and call |finish()|. + * Wait for pending emulator transactions and call |finish()|. */ function cleanUp() { - waitFor(function() { - SpecialPowers.flushPermissions(function() { - // Use ok here so that we have at least one test run. - ok(true, "permissions flushed"); + // Use ok here so that we have at least one test run. + ok(true, ":: CLEANING UP ::"); - finish(); - }); - }, function() { + waitFor(finish, function() { return pendingEmulatorCmdCount === 0; }); } diff --git a/dom/bluetooth2/bluedroid/BluetoothInterface.cpp b/dom/bluetooth2/bluedroid/BluetoothInterface.cpp index 41c62a5d325b..ebf8f4234409 100644 --- a/dom/bluetooth2/bluedroid/BluetoothInterface.cpp +++ b/dom/bluetooth2/bluedroid/BluetoothInterface.cpp @@ -47,7 +47,7 @@ private: void (Obj::*mMethod)(); }; -template +template class BluetoothInterfaceRunnable1 : public nsRunnable { public: @@ -70,11 +70,12 @@ public: private: nsRefPtr mObj; - void (Obj::*mMethod)(Arg1); - Arg1 mArg1; + Res (Obj::*mMethod)(Arg1); + Tin1 mArg1; }; template class BluetoothInterfaceRunnable3 : public nsRunnable { @@ -102,10 +103,10 @@ public: private: nsRefPtr mObj; - void (Obj::*mMethod)(Arg1, Arg2, Arg3); - Arg1 mArg1; - Arg2 mArg2; - Arg3 mArg3; + Res (Obj::*mMethod)(Arg1, Arg2, Arg3); + Tin1 mArg1; + Tin2 mArg2; + Tin3 mArg3; }; // @@ -124,16 +125,18 @@ struct interface_traits }; typedef - BluetoothInterfaceRunnable1 + BluetoothInterfaceRunnable1 BluetoothSocketIntResultRunnable; typedef - BluetoothInterfaceRunnable3 + BluetoothInterfaceRunnable3 BluetoothSocketIntStringIntResultRunnable; typedef - BluetoothInterfaceRunnable1 + BluetoothInterfaceRunnable1 BluetoothSocketErrorRunnable; static nsresult @@ -581,7 +584,8 @@ typedef BluetoothHandsfreeResultRunnable; typedef - BluetoothInterfaceRunnable1 + BluetoothInterfaceRunnable1 BluetoothHandsfreeErrorRunnable; static nsresult @@ -852,7 +856,8 @@ typedef BluetoothA2dpResultRunnable; typedef - BluetoothInterfaceRunnable1 + BluetoothInterfaceRunnable1 BluetoothA2dpErrorRunnable; static nsresult @@ -956,7 +961,8 @@ typedef BluetoothAvrcpResultRunnable; typedef - BluetoothInterfaceRunnable1 + BluetoothInterfaceRunnable1 BluetoothAvrcpErrorRunnable; static nsresult @@ -1155,7 +1161,7 @@ typedef BluetoothResultRunnable; typedef - BluetoothInterfaceRunnable1 + BluetoothInterfaceRunnable1 BluetoothErrorRunnable; static nsresult diff --git a/dom/bluetooth2/bluedroid/BluetoothSocket.cpp b/dom/bluetooth2/bluedroid/BluetoothSocket.cpp index 19980644ce97..cb04c127fe00 100644 --- a/dom/bluetooth2/bluedroid/BluetoothSocket.cpp +++ b/dom/bluetooth2/bluedroid/BluetoothSocket.cpp @@ -811,10 +811,10 @@ BluetoothSocket::CloseDroidSocket() NotifyDisconnect(); } -class ConnectResultHandler MOZ_FINAL : public BluetoothSocketResultHandler +class ConnectSocketResultHandler MOZ_FINAL : public BluetoothSocketResultHandler { public: - ConnectResultHandler(DroidSocketImpl* aImpl) + ConnectSocketResultHandler(DroidSocketImpl* aImpl) : mImpl(aImpl) { MOZ_ASSERT(mImpl); @@ -861,7 +861,7 @@ BluetoothSocket::Connect(const nsAString& aDeviceAddress, int aChannel) aChannel, (BTSOCK_FLAG_ENCRYPT * mEncrypt) | (BTSOCK_FLAG_AUTH * mAuth), - new ConnectResultHandler(mImpl)); + new ConnectSocketResultHandler(mImpl)); return true; } diff --git a/dom/bluetooth2/bluez/BluetoothDBusService.cpp b/dom/bluetooth2/bluez/BluetoothDBusService.cpp index 69465fd7d1f2..c485af20be92 100644 --- a/dom/bluetooth2/bluez/BluetoothDBusService.cpp +++ b/dom/bluetooth2/bluez/BluetoothDBusService.cpp @@ -37,6 +37,7 @@ #include "nsDataHashtable.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Atomics.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/Hal.h" #include "mozilla/ipc/UnixSocket.h" @@ -370,6 +371,7 @@ DispatchToBtThread(nsIRunnable* aRunnable) sBluetoothThread = new LazyIdleThread(BT_LAZY_THREAD_TIMEOUT_MS, NS_LITERAL_CSTRING("BluetoothDBusService"), LazyIdleThread::ManualShutdown); + ClearOnShutdown(&sBluetoothThread); } return sBluetoothThread->Dispatch(aRunnable, NS_DISPATCH_NORMAL); } diff --git a/dom/bluetooth2/tests/marionette/head.js b/dom/bluetooth2/tests/marionette/head.js index a903e2308512..bbc87082d8e4 100644 --- a/dom/bluetooth2/tests/marionette/head.js +++ b/dom/bluetooth2/tests/marionette/head.js @@ -626,17 +626,13 @@ function isUuidsEqual(aUuidArray1, aUuidArray2) { } /** - * Flush permission settings and call |finish()|. + * Wait for pending emulator transactions and call |finish()|. */ function cleanUp() { - waitFor(function() { - SpecialPowers.flushPermissions(function() { - // Use ok here so that we have at least one test run. - ok(true, "permissions flushed"); + // Use ok here so that we have at least one test run. + ok(true, ":: CLEANING UP ::"); - finish(); - }); - }, function() { + waitFor(finish, function() { return pendingEmulatorCmdCount === 0; }); } diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index f6bf6f009e72..a4a61b369ad1 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -1477,9 +1477,13 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha) if (!gl) return nullptr; - RefPtr surf = Factory::CreateDataSourceSurfaceWithStride(IntSize(mWidth, mHeight), - SurfaceFormat::B8G8R8A8, - mWidth * 4); + bool hasAlpha = mOptions.alpha; + SurfaceFormat surfFormat = hasAlpha ? SurfaceFormat::B8G8R8A8 + : SurfaceFormat::B8G8R8X8; + RefPtr surf; + surf = Factory::CreateDataSourceSurfaceWithStride(IntSize(mWidth, mHeight), + surfFormat, + mWidth * 4); if (!surf) { return nullptr; } diff --git a/dom/cellbroadcast/tests/marionette/head.js b/dom/cellbroadcast/tests/marionette/head.js index 65ab6b2ac56c..95d039cdbbdb 100644 --- a/dom/cellbroadcast/tests/marionette/head.js +++ b/dom/cellbroadcast/tests/marionette/head.js @@ -317,17 +317,13 @@ function sendMultipleRawCbsToEmulatorAndWait(aPdus) { } /** - * Flush permission settings and call |finish()|. + * Wait for pending emulator transactions and call |finish()|. */ function cleanUp() { - waitFor(function() { - SpecialPowers.flushPermissions(function() { - // Use ok here so that we have at least one test run. - ok(true, "permissions flushed"); + // Use ok here so that we have at least one test run. + ok(true, ":: CLEANING UP ::"); - finish(); - }); - }, function() { + waitFor(finish, function() { return pendingEmulatorCmdCount === 0; }); } diff --git a/dom/events/test/marionette/head.js b/dom/events/test/marionette/head.js index 7e6dacd83d06..f8c3075dc52f 100644 --- a/dom/events/test/marionette/head.js +++ b/dom/events/test/marionette/head.js @@ -113,17 +113,13 @@ function waitForWindowEvent(aEventName) { } /** - * Flush permission settings and call |finish()|. + * Wait for pending emulator transactions and call |finish()|. */ function cleanUp() { - waitFor(function() { - SpecialPowers.flushPermissions(function() { - // Use ok here so that we have at least one test run. - ok(true, "permissions flushed"); + // Use ok here so that we have at least one test run. + ok(true, ":: CLEANING UP ::"); - finish(); - }); - }, function() { + waitFor(finish, function() { return _pendingEmulatorCmdCount === 0; }); } diff --git a/dom/indexedDB/Client.cpp b/dom/indexedDB/Client.cpp index 163948e7a9f5..6157ed0d2605 100644 --- a/dom/indexedDB/Client.cpp +++ b/dom/indexedDB/Client.cpp @@ -61,7 +61,7 @@ Client::InitOrigin(PersistenceType aPersistenceType, const nsACString& aGroup, // and also get the usage. nsAutoTArray subdirsToProcess; - nsAutoTArray , 20> unknownFiles; + nsAutoTArray, 20> unknownFiles; nsTHashtable validSubdirs(20); nsCOMPtr entries; diff --git a/dom/inputmethod/Keyboard.jsm b/dom/inputmethod/Keyboard.jsm index c1277457089e..45ad6263dc55 100644 --- a/dom/inputmethod/Keyboard.jsm +++ b/dom/inputmethod/Keyboard.jsm @@ -20,8 +20,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm"); this.Keyboard = { - _formMM: null, // The current web page message manager. - _keyboardMM: null, // The keyboard app message manager. + _formMM: null, // The current web page message manager. + _keyboardMM: null, // The keyboard app message manager. + _keyboardID: -1, // The keyboard app's ID number. -1 = invalid + _nextKeyboardID: 0, // The ID number counter. _systemMessageName: [ 'SetValue', 'RemoveFocus', 'SetSelectedOption', 'SetSelectedOptions' ], @@ -149,6 +151,20 @@ this.Keyboard = { } } + // we don't process kb messages (other than register) + // if they come from a kb that we're currently not regsitered for. + // this decision is made with the kbID kept by us and kb app + let kbID = null; + if ('kbID' in msg.data) { + kbID = msg.data.kbID; + } + + if (0 === msg.name.indexOf('Keyboard:') && + ('Keyboard:Register' !== msg.name && this._keyboardID !== kbID) + ) { + return; + } + switch (msg.name) { case 'Forms:Input': this.handleFocusChange(msg); @@ -212,9 +228,22 @@ this.Keyboard = { break; case 'Keyboard:Register': this._keyboardMM = mm; + if (kbID !== null) { + // keyboard identifies itself, use its kbID + // this msg would be async, so no need to return + this._keyboardID = kbID; + }else{ + // generate the id for the keyboard + this._keyboardID = this._nextKeyboardID; + this._nextKeyboardID++; + // this msg is sync, + // and we want to return the id back to inputmethod + return this._keyboardID; + } break; case 'Keyboard:Unregister': this._keyboardMM = null; + this._keyboardID = -1; break; } }, diff --git a/dom/inputmethod/MozKeyboard.js b/dom/inputmethod/MozKeyboard.js index 7bec21534a5e..830fef35dcdc 100644 --- a/dom/inputmethod/MozKeyboard.js +++ b/dom/inputmethod/MozKeyboard.js @@ -13,16 +13,16 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "cpmm", - "@mozilla.org/childprocessmessagemanager;1", "nsIMessageSender"); + "@mozilla.org/childprocessmessagemanager;1", "nsISyncMessageSender"); XPCOMUtils.defineLazyServiceGetter(this, "tm", "@mozilla.org/thread-manager;1", "nsIThreadManager"); /* - * A WeakMap to map input method iframe window to its active status. + * A WeakMap to map input method iframe window to its active status and kbID. */ let WindowMap = { - // WeakMap of pairs. + // WeakMap of pairs. _map: null, /* @@ -32,7 +32,13 @@ let WindowMap = { if (!this._map || !win) { return false; } - return this._map.get(win) || false; + + let obj = this._map.get(win); + if (obj && 'active' in obj) { + return obj.active; + }else{ + return false; + } }, /* @@ -45,10 +51,50 @@ let WindowMap = { if (!this._map) { this._map = new WeakMap(); } - this._map.set(win, isActive); + if (!this._map.has(win)) { + this._map.set(win, {}); + } + this._map.get(win).active = isActive; + }, + + /* + * Get the keyboard ID (assigned by Keyboard.ksm) of the given window. + */ + getKbID: function(win) { + if (!this._map || !win) { + return null; + } + + let obj = this._map.get(win); + if (obj && 'kbID' in obj) { + return obj.kbID; + }else{ + return null; + } + }, + + /* + * Set the keyboard ID (assigned by Keyboard.ksm) of the given window. + */ + setKbID: function(win, kbID) { + if (!win) { + return; + } + if (!this._map) { + this._map = new WeakMap(); + } + if (!this._map.has(win)) { + this._map.set(win, {}); + } + this._map.get(win).kbID = kbID; } }; +let cpmmSendAsyncMessageWithKbID = function (self, msg, data) { + data.kbID = WindowMap.getKbID(self._window); + cpmm.sendAsyncMessage(msg, data); +}; + /** * ============================================== * InputMethodManager @@ -70,14 +116,14 @@ MozInputMethodManager.prototype = { if (!WindowMap.isActive(this._window)) { return; } - cpmm.sendAsyncMessage('Keyboard:ShowInputMethodPicker', {}); + cpmmSendAsyncMessageWithKbID(this, 'Keyboard:ShowInputMethodPicker', {}); }, next: function() { if (!WindowMap.isActive(this._window)) { return; } - cpmm.sendAsyncMessage('Keyboard:SwitchToNextInputMethod', {}); + cpmmSendAsyncMessageWithKbID(this, 'Keyboard:SwitchToNextInputMethod', {}); }, supportsSwitching: function() { @@ -91,7 +137,7 @@ MozInputMethodManager.prototype = { if (!WindowMap.isActive(this._window)) { return; } - cpmm.sendAsyncMessage('Keyboard:RemoveFocus', {}); + cpmmSendAsyncMessageWithKbID(this, 'Keyboard:RemoveFocus', {}); } }; @@ -261,11 +307,23 @@ MozInputMethod.prototype = { // If there is already an active context, then this will trigger // a GetContext:Result:OK event, and we can initialize ourselves. // Otherwise silently ignored. - cpmm.sendAsyncMessage('Keyboard:Register', {}); - cpmm.sendAsyncMessage("Keyboard:GetContext", {}); + + // get keyboard ID from Keyboard.jsm, + // or if we already have it, get it from our map + // Note: if we need to get it from Keyboard.jsm, + // we have to use a synchronous message + var kbID = WindowMap.getKbID(this._window); + if (kbID !== null) { + cpmmSendAsyncMessageWithKbID(this, 'Keyboard:Register', {}); + }else{ + let res = cpmm.sendSyncMessage('Keyboard:Register', {}); + WindowMap.setKbID(this._window, res[0]); + } + + cpmmSendAsyncMessageWithKbID(this, 'Keyboard:GetContext', {}); } else { // Deactive current input method. - cpmm.sendAsyncMessage('Keyboard:Unregister', {}); + cpmmSendAsyncMessageWithKbID(this, 'Keyboard:Unregister', {}); if (this._inputcontext) { this.setInputContext(null); } @@ -489,7 +547,7 @@ MozInputContext.prototype = { getText: function ic_getText(offset, length) { let self = this; return this._sendPromise(function(resolverId) { - cpmm.sendAsyncMessage('Keyboard:GetText', { + cpmmSendAsyncMessageWithKbID(self, 'Keyboard:GetText', { contextId: self._contextId, requestId: resolverId, offset: offset, @@ -517,7 +575,7 @@ MozInputContext.prototype = { setSelectionRange: function ic_setSelectionRange(start, length) { let self = this; return this._sendPromise(function(resolverId) { - cpmm.sendAsyncMessage("Keyboard:SetSelectionRange", { + cpmmSendAsyncMessageWithKbID(self, 'Keyboard:SetSelectionRange', { contextId: self._contextId, requestId: resolverId, selectionStart: start, @@ -545,7 +603,7 @@ MozInputContext.prototype = { replaceSurroundingText: function ic_replaceSurrText(text, offset, length) { let self = this; return this._sendPromise(function(resolverId) { - cpmm.sendAsyncMessage('Keyboard:ReplaceSurroundingText', { + cpmmSendAsyncMessageWithKbID(self, 'Keyboard:ReplaceSurroundingText', { contextId: self._contextId, requestId: resolverId, text: text, @@ -562,7 +620,7 @@ MozInputContext.prototype = { sendKey: function ic_sendKey(keyCode, charCode, modifiers, repeat) { let self = this; return this._sendPromise(function(resolverId) { - cpmm.sendAsyncMessage('Keyboard:SendKey', { + cpmmSendAsyncMessageWithKbID(self, 'Keyboard:SendKey', { contextId: self._contextId, requestId: resolverId, keyCode: keyCode, @@ -576,7 +634,7 @@ MozInputContext.prototype = { setComposition: function ic_setComposition(text, cursor, clauses) { let self = this; return this._sendPromise(function(resolverId) { - cpmm.sendAsyncMessage('Keyboard:SetComposition', { + cpmmSendAsyncMessageWithKbID(self, 'Keyboard:SetComposition', { contextId: self._contextId, requestId: resolverId, text: text, @@ -589,7 +647,7 @@ MozInputContext.prototype = { endComposition: function ic_endComposition(text) { let self = this; return this._sendPromise(function(resolverId) { - cpmm.sendAsyncMessage('Keyboard:EndComposition', { + cpmmSendAsyncMessageWithKbID(self, 'Keyboard:EndComposition', { contextId: self._contextId, requestId: resolverId, text: text || '' diff --git a/dom/inputmethod/mochitest/file_inputmethod_1043828.html b/dom/inputmethod/mochitest/file_inputmethod_1043828.html new file mode 100644 index 000000000000..7879e1ce9fd7 --- /dev/null +++ b/dom/inputmethod/mochitest/file_inputmethod_1043828.html @@ -0,0 +1,4 @@ + + + + diff --git a/dom/inputmethod/mochitest/mochitest.ini b/dom/inputmethod/mochitest/mochitest.ini index 6b4be4b9ec97..88d4cd0ee5be 100644 --- a/dom/inputmethod/mochitest/mochitest.ini +++ b/dom/inputmethod/mochitest/mochitest.ini @@ -4,6 +4,7 @@ skip-if = (toolkit == 'android' || toolkit == 'gonk') || e10s support-files = inputmethod_common.js file_inputmethod.html + file_inputmethod_1043828.html file_test_app.html file_test_sendkey_cancel.html file_test_sms_app.html @@ -14,5 +15,6 @@ support-files = [test_bug953044.html] [test_bug960946.html] [test_bug978918.html] +[test_bug1043828.html] [test_delete_focused_element.html] [test_sendkey_cancel.html] diff --git a/dom/inputmethod/mochitest/test_bug1043828.html b/dom/inputmethod/mochitest/test_bug1043828.html new file mode 100644 index 000000000000..e1a14b880a7d --- /dev/null +++ b/dom/inputmethod/mochitest/test_bug1043828.html @@ -0,0 +1,183 @@ + + + + + Basic test for Switching Keyboards. + + + + + +Mozilla Bug 1043828 +

+
+
+
+ + + diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index af21e3ca82e0..fb24f9d89d26 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -406,7 +406,7 @@ child: CacheFileDescriptor(nsString path, FileDescriptor fd); - UpdateDimensions(nsRect rect, nsIntSize size, ScreenOrientation orientation) compress; + UpdateDimensions(nsIntRect rect, nsIntSize size, ScreenOrientation orientation) compress; UpdateFrame(FrameMetrics frame); diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index f7e51bf67b9d..2bfed37c7bab 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -1743,16 +1743,13 @@ TabChild::RecvShow(const nsIntSize& size) } bool -TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation) +TabChild::RecvUpdateDimensions(const nsIntRect& rect, const nsIntSize& size, const ScreenOrientation& orientation) { if (!mRemoteFrame) { return true; } - mOuterRect.x = rect.x; - mOuterRect.y = rect.y; - mOuterRect.width = rect.width; - mOuterRect.height = rect.height; + mOuterRect = rect; bool initialSizing = !HasValidInnerSize() && (size.width != 0 && size.height != 0); diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 35447c3a1976..ec55dc6a5ef1 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -318,7 +318,7 @@ public: const FileDescriptor& aFileDescriptor) MOZ_OVERRIDE; virtual bool RecvShow(const nsIntSize& size) MOZ_OVERRIDE; - virtual bool RecvUpdateDimensions(const nsRect& rect, + virtual bool RecvUpdateDimensions(const nsIntRect& rect, const nsIntSize& size, const ScreenOrientation& orientation) MOZ_OVERRIDE; virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index a5e166ea787c..1ec2a3116ffd 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -560,7 +560,7 @@ TabParent::Show(const nsIntSize& size) } void -TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size) +TabParent::UpdateDimensions(const nsIntRect& rect, const nsIntSize& size) { if (mIsDestroyed) { return; diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index f7c81ea7105e..1ee0c3002b95 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -208,7 +208,7 @@ public: // message-sending functions under a layer of indirection and // eating the return values void Show(const nsIntSize& size); - void UpdateDimensions(const nsRect& rect, const nsIntSize& size); + void UpdateDimensions(const nsIntRect& rect, const nsIntSize& size); void UpdateFrame(const layers::FrameMetrics& aFrameMetrics); void UIResolutionChanged(); void AcknowledgeScrollUpdate(const ViewID& aScrollId, const uint32_t& aScrollGeneration); @@ -374,7 +374,7 @@ protected: // The number of event series we're currently capturing. int32_t mEventCaptureDepth; - nsRect mRect; + nsIntRect mRect; nsIntSize mDimensions; ScreenOrientation mOrientation; float mDPI; diff --git a/dom/mobileconnection/src/MobileConnection.cpp b/dom/mobileconnection/src/MobileConnection.cpp index 5a0601bf19b2..29e7920f2574 100644 --- a/dom/mobileconnection/src/MobileConnection.cpp +++ b/dom/mobileconnection/src/MobileConnection.cpp @@ -85,6 +85,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection, DOMEventTargetHelper) + tmp->Shutdown(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mVoice) NS_IMPL_CYCLE_COLLECTION_UNLINK(mData) NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -126,19 +127,28 @@ MobileConnection::MobileConnection(nsPIDOMWindow* aWindow, uint32_t aClientId) void MobileConnection::Shutdown() { - if (mProvider && mListener) { + if (mListener) { + if (mProvider) { + mProvider->UnregisterMobileConnectionMsg(mClientId, mListener); + } + mListener->Disconnect(); - mProvider->UnregisterMobileConnectionMsg(mClientId, mListener); - mProvider = nullptr; mListener = nullptr; - mVoice = nullptr; - mData = nullptr; } } MobileConnection::~MobileConnection() { - MOZ_ASSERT(!(mProvider || mListener || mVoice || mData)); + Shutdown(); +} + +void +MobileConnection::DisconnectFromOwner() +{ + DOMEventTargetHelper::DisconnectFromOwner(); + // Event listeners can't be handled anymore, so we can shutdown + // the MobileConnection. + Shutdown(); } JSObject* @@ -214,20 +224,12 @@ MobileConnection::GetLastKnownHomeNetwork(nsString& aRetVal) const MobileConnectionInfo* MobileConnection::Voice() const { - if (!mProvider) { - return nullptr; - } - return mVoice; } MobileConnectionInfo* MobileConnection::Data() const { - if (!mProvider) { - return nullptr; - } - return mData; } diff --git a/dom/mobileconnection/src/MobileConnection.h b/dom/mobileconnection/src/MobileConnection.h index 14adf7f1187f..21be008e5b3c 100644 --- a/dom/mobileconnection/src/MobileConnection.h +++ b/dom/mobileconnection/src/MobileConnection.h @@ -41,6 +41,9 @@ public: void Shutdown(); + virtual void + DisconnectFromOwner() MOZ_OVERRIDE; + nsPIDOMWindow* GetParentObject() const { diff --git a/dom/mobileconnection/src/MobileConnectionArray.cpp b/dom/mobileconnection/src/MobileConnectionArray.cpp index 981de544d013..4e62d8505969 100644 --- a/dom/mobileconnection/src/MobileConnectionArray.cpp +++ b/dom/mobileconnection/src/MobileConnectionArray.cpp @@ -10,22 +10,9 @@ using namespace mozilla::dom; -NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnectionArray) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MobileConnectionArray) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow) - // Notify our mobile connections that we're going away. - tmp->DropConnections(); - NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MobileConnectionArray) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(MobileConnectionArray) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MobileConnectionArray, + mWindow, + mMobileConnections) NS_IMPL_CYCLE_COLLECTING_ADDREF(MobileConnectionArray) NS_IMPL_CYCLE_COLLECTING_RELEASE(MobileConnectionArray) @@ -49,7 +36,6 @@ MobileConnectionArray::MobileConnectionArray(nsPIDOMWindow* aWindow) MobileConnectionArray::~MobileConnectionArray() { - DropConnections(); } void @@ -63,18 +49,6 @@ MobileConnectionArray::Init() } } -void -MobileConnectionArray::DropConnections() -{ - if (mInitialized) { - for (uint32_t i = 0; i < mMobileConnections.Length(); i++) { - mMobileConnections[i]->Shutdown(); - } - } - - mMobileConnections.Clear(); -} - nsPIDOMWindow* MobileConnectionArray::GetParentObject() const { diff --git a/dom/mobileconnection/src/MobileConnectionArray.h b/dom/mobileconnection/src/MobileConnectionArray.h index b2f2ab6e5f89..9f800f362cd7 100644 --- a/dom/mobileconnection/src/MobileConnectionArray.h +++ b/dom/mobileconnection/src/MobileConnectionArray.h @@ -45,9 +45,6 @@ private: void Init(); - void - DropConnections(); - bool mInitialized; nsCOMPtr mWindow; diff --git a/dom/mobileconnection/tests/marionette/head.js b/dom/mobileconnection/tests/marionette/head.js index 1524d234a73c..61141d6e4cb6 100644 --- a/dom/mobileconnection/tests/marionette/head.js +++ b/dom/mobileconnection/tests/marionette/head.js @@ -1128,17 +1128,13 @@ function getNumOfRadioInterfaces() { } /** - * Flush permission settings and call |finish()|. + * Wait for pending emulator transactions and call |finish()|. */ function cleanUp() { - waitFor(function() { - SpecialPowers.flushPermissions(function() { - // Use ok here so that we have at least one test run. - ok(true, "permissions flushed"); + // Use ok here so that we have at least one test run. + ok(true, ":: CLEANING UP ::"); - finish(); - }); - }, function() { + waitFor(finish, function() { return _pendingEmulatorCmdCount === 0 && _pendingEmulatorShellCmdCount === 0; }); diff --git a/dom/mobilemessage/tests/marionette/head.js b/dom/mobilemessage/tests/marionette/head.js index b62c17a993cd..aab56904164f 100644 --- a/dom/mobilemessage/tests/marionette/head.js +++ b/dom/mobilemessage/tests/marionette/head.js @@ -562,22 +562,12 @@ function compareSmsMessage(aFrom, aTo) { } /** - * Flush permission settings and call |finish()|. + * Wait for pending emulator transactions and call |finish()|. */ function cleanUp() { ok(true, ":: CLEANING UP ::"); - waitFor(function() { - SpecialPowers.flushPermissions(function() { - ok(true, "permissions flushed"); - - SpecialPowers.flushPrefEnv(function() { - ok(true, "preferences flushed"); - - finish(); - }) - }); - }, function() { + waitFor(finish, function() { return pendingEmulatorCmdCount === 0; }); } diff --git a/dom/nfc/nsNfc.js b/dom/nfc/nsNfc.js index ccbaad40202b..6f97e04febe2 100644 --- a/dom/nfc/nsNfc.js +++ b/dom/nfc/nsNfc.js @@ -212,7 +212,7 @@ mozNfc.prototype = { return null; } - if (!this.nfcObject) { + if (!this.nfcObject || this.nfcObject.token != sessionToken) { let obj = new MozNFCPeer(); obj.initialize(this._window, sessionToken); this.nfcObject = obj; diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index e0a658af1969..b4cae271bee7 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1725,7 +1725,7 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj) if (!sNPObjWrappers.ops) { // No hash yet (or any more), initialize it. PL_DHashTableInit(&sNPObjWrappers, PL_DHashGetStubOps(), nullptr, - sizeof(NPObjWrapperHashEntry), 16); + sizeof(NPObjWrapperHashEntry)); } NPObjWrapperHashEntry *entry = static_cast diff --git a/dom/src/storage/DOMStorageManager.cpp b/dom/src/storage/DOMStorageManager.cpp index 6b554d68b295..577d0036a241 100644 --- a/dom/src/storage/DOMStorageManager.cpp +++ b/dom/src/storage/DOMStorageManager.cpp @@ -98,7 +98,7 @@ NS_IMPL_ISUPPORTS(DOMStorageManager, nsIDOMStorageManager) DOMStorageManager::DOMStorageManager(DOMStorage::StorageType aType) - : mCaches(10) + : mCaches(8) , mType(aType) , mLowDiskSpace(false) { diff --git a/dom/system/gonk/SystemWorkerManager.cpp b/dom/system/gonk/SystemWorkerManager.cpp index 5830dacce456..9d1573702928 100644 --- a/dom/system/gonk/SystemWorkerManager.cpp +++ b/dom/system/gonk/SystemWorkerManager.cpp @@ -129,6 +129,11 @@ SystemWorkerManager::Shutdown() } mWifiWorker = nullptr; + if (mKeyStore) { + mKeyStore->CloseSocket(); + mKeyStore = nullptr; + } + nsCOMPtr obs = mozilla::services::GetObserverService(); if (obs) { obs->RemoveObserver(this, WORKERS_SHUTDOWN_TOPIC); diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index b7341345c8f2..64ce49beb2ce 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -6013,6 +6013,7 @@ RilObject.prototype[REQUEST_GET_IMEI] = function REQUEST_GET_IMEI(length, option return; } + options.mmiServiceCode = MMI_KS_SC_IMEI; options.success = (options.rilRequestError === 0); options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError]; if ((!options.success || this.IMEI == null) && !options.errorMsg) { diff --git a/dom/webidl/Location.webidl b/dom/webidl/Location.webidl index 7cc105890d02..59999602010f 100644 --- a/dom/webidl/Location.webidl +++ b/dom/webidl/Location.webidl @@ -22,4 +22,4 @@ interface Location { void reload(optional boolean forceget = false); }; // No support for .searchParams on Location yet. See bug 1037715. -Location implements URLUtilsNoSearchParams; +Location implements URLUtils; diff --git a/dom/webidl/MozWifiManager.webidl b/dom/webidl/MozWifiManager.webidl index 47fa1947a005..fb2382e6920d 100644 --- a/dom/webidl/MozWifiManager.webidl +++ b/dom/webidl/MozWifiManager.webidl @@ -124,6 +124,14 @@ dictionary IPConfiguration { NavigatorProperty="mozWifiManager", Func="Navigator::HasWifiManagerSupport"] interface MozWifiManager : EventTarget { + /** + * Turn on/off wifi functionality. + * @param enable true for enable, false for disable. + * onsuccess: Wifi enable/disable successfully, including no status change. + * onerror: Wifi enable/disable failed or prohibited. + */ + DOMRequest setWifiEnabled(boolean enabled); + /** * Returns the list of currently available networks. * onsuccess: We have obtained the current list of networks. request.value diff --git a/dom/webidl/URLUtils.webidl b/dom/webidl/URLUtils.webidl index 05cb644e6c57..ad3216220142 100644 --- a/dom/webidl/URLUtils.webidl +++ b/dom/webidl/URLUtils.webidl @@ -15,7 +15,7 @@ [NoInterfaceObject, Exposed=(Window, Worker)] -interface URLUtilsNoSearchParams { +interface URLUtils { // Bug 824857: no support for stringifier attributes yet. // stringifier attribute DOMString href; [Throws, CrossOriginWritable=Location] @@ -39,7 +39,9 @@ interface URLUtilsNoSearchParams { attribute DOMString pathname; [Throws] attribute DOMString search; - // searchParams should go here once Location implements it. See bug 1037715. + + attribute URLSearchParams searchParams; + [Throws] attribute DOMString hash; @@ -47,10 +49,3 @@ interface URLUtilsNoSearchParams { [Throws] stringifier; }; - -[NoInterfaceObject, - Exposed=(Window, Worker)] -interface URLUtils : URLUtilsNoSearchParams -{ - attribute URLSearchParams searchParams; -}; diff --git a/dom/wifi/DOMWifiManager.js b/dom/wifi/DOMWifiManager.js index f10743aea279..5ab1146b741c 100644 --- a/dom/wifi/DOMWifiManager.js +++ b/dom/wifi/DOMWifiManager.js @@ -113,6 +113,7 @@ DOMWifiManager.prototype = { "WifiManager:importCert:Return:OK", "WifiManager:importCert:Return:NO", "WifiManager:getImportedCerts:Return:OK", "WifiManager:getImportedCerts:Return:NO", "WifiManager:deleteCert:Return:OK", "WifiManager:deleteCert:Return:NO", + "WifiManager:setWifiEnabled:Return:OK", "WifiManager:setWifiEnabled:Return:NO", "WifiManager:wifiDown", "WifiManager:wifiUp", "WifiManager:onconnecting", "WifiManager:onassociate", "WifiManager:onconnect", "WifiManager:ondisconnect", @@ -233,6 +234,14 @@ DOMWifiManager.prototype = { } switch (aMessage.name) { + case "WifiManager:setWifiEnabled:Return:OK": + Services.DOMRequest.fireSuccess(request, msg.data); + break; + + case "WifiManager:setWifiEnabled:Return:NO": + Services.DOMRequest.fireError(request, "Unable to enable/disable Wifi"); + break; + case "WifiManager:getNetworks:Return:OK": Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data)); break; @@ -432,6 +441,12 @@ DOMWifiManager.prototype = { this.__DOM_IMPL__.dispatchEvent(evt); }, + setWifiEnabled: function setWifiEnabled(enabled) { + var request = this.createRequest(); + this._sendMessageForRequest("WifiManager:setWifiEnabled", enabled, request); + return request; + }, + getNetworks: function getNetworks() { var request = this.createRequest(); this._sendMessageForRequest("WifiManager:getNetworks", null, request); diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js index 8139c96fd788..28014e6a365c 100644 --- a/dom/wifi/WifiWorker.js +++ b/dom/wifi/WifiWorker.js @@ -670,7 +670,7 @@ var WifiManager = (function() { // 2. current network if no SSID is provided, it's not guaranteed that // current network matches requested SSID. if ((!ssid && network.status === "CURRENT") || - (ssid && ssid === dequote(network.ssid))) { + (ssid && network.ssid && ssid === dequote(network.ssid))) { return callback(net); } } @@ -1764,6 +1764,7 @@ function WifiWorker() { "WifiManager:importCert", "WifiManager:getImportedCerts", "WifiManager:deleteCert", + "WifiManager:setWifiEnabled", "child-process-shutdown"]; messages.forEach((function(msgName) { @@ -2028,8 +2029,8 @@ function WifiWorker() { WifiManager.getNetworkId(connectionInfo.ssid, function(netId) { // Trying to get netId from current network. if (!netId && - self.currentNetwork && - self.currentNetwork.ssid == dequote(connectionInfo.ssid) && + self.currentNetwork && self.currentNetwork.ssid && + dequote(self.currentNetwork.ssid) == connectionInfo.ssid && typeof self.currentNetwork.netId !== "undefined") { netId = self.currentNetwork.netId; } @@ -2714,6 +2715,9 @@ WifiWorker.prototype = { } switch (aMessage.name) { + case "WifiManager:setWifiEnabled": + this.setWifiEnabled(msg); + break; case "WifiManager:getNetworks": this.getNetworks(msg); break; @@ -2909,7 +2913,47 @@ WifiWorker.prototype = { WifiManager.start(); }, - setWifiEnabled: function(enabled, callback) { + /** + * Compatibility flags for detecting if Gaia is controlling wifi by settings + * or API, once API is called, gecko will no longer accept wifi enable + * control from settings. + * This is used to deal with compatibility issue while Gaia adopted to use + * API but gecko doesn't remove the settings code in time. + * TODO: Remove this flag in Bug 1050147 + */ + ignoreWifiEnabledFromSettings: false, + setWifiEnabled: function(msg) { + const message = "WifiManager:setWifiEnabled:Return"; + let self = this; + let enabled = msg.data; + + self.ignoreWifiEnabledFromSettings = true; + // No change. + if (enabled === WifiManager.enabled) { + this._sendMessage(message, true, true, msg); + } + + // Can't enable wifi while hotspot mode is enabled. + if (enabled && (this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] || + WifiManager.isWifiTetheringEnabled(WifiManager.tetheringState))) { + self._sendMessage(message, false, "Can't enable Wifi while hotspot mode is enabled", msg); + } + + // Reply error to pending requests. + if (!enabled) { + this._clearPendingRequest(); + } + + WifiManager.setWifiEnabled(enabled, function(ok) { + if (ok === 0 || ok === "no change") { + self._sendMessage(message, true, true, msg); + } else { + self._sendMessage(message, false, "Set power saving mode failed", msg); + } + }); + }, + + _setWifiEnabled: function(enabled, callback) { // Reply error to pending requests. if (!enabled) { this._clearPendingRequest(); @@ -2920,6 +2964,7 @@ WifiWorker.prototype = { // requestDone() must be called to before callback complete(or error) // so next queue in the request quene can be executed. + // TODO: Remove command queue in Bug 1050147 queueRequest: function(data, callback) { if (!callback) { throw "Try to enqueue a request without callback"; @@ -3362,10 +3407,11 @@ WifiWorker.prototype = { shutdown: function() { debug("shutting down ..."); this.queueRequest({command: "setWifiEnabled", value: false}, function(data) { - this.setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); + this._setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); }.bind(this)); }, + // TODO: Remove command queue in Bug 1050147. requestProcessing: false, // Hold while dequeue and execution a request. // Released upon the request is fully executed, // i.e, mostly after callback is done. @@ -3437,6 +3483,10 @@ WifiWorker.prototype = { }, handleWifiEnabled: function(enabled) { + if (this.ignoreWifiEnabledFromSettings) { + return; + } + // Make sure Wifi hotspot is idle before switching to Wifi mode. if (enabled) { this.queueRequest({command: "setWifiApEnabled", value: false}, function(data) { @@ -3451,7 +3501,7 @@ WifiWorker.prototype = { } this.queueRequest({command: "setWifiEnabled", value: enabled}, function(data) { - this.setWifiEnabled(enabled, this._setWifiEnabledCallback.bind(this)); + this._setWifiEnabled(enabled, this._setWifiEnabledCallback.bind(this)); }.bind(this)); if (!enabled) { @@ -3472,7 +3522,7 @@ WifiWorker.prototype = { this.queueRequest({command: "setWifiEnabled", value: false}, function(data) { if (WifiManager.isWifiEnabled(WifiManager.state)) { this.disconnectedByWifiTethering = true; - this.setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); + this._setWifiEnabled(false, this._setWifiEnabledCallback.bind(this)); } else { this.requestDone(); } @@ -3486,7 +3536,7 @@ WifiWorker.prototype = { if (!enabled) { this.queueRequest({command: "setWifiEnabled", value: true}, function(data) { if (this.disconnectedByWifiTethering) { - this.setWifiEnabled(true, this._setWifiEnabledCallback.bind(this)); + this._setWifiEnabled(true, this._setWifiEnabledCallback.bind(this)); } else { this.requestDone(); } @@ -3523,6 +3573,7 @@ WifiWorker.prototype = { handle: function handle(aName, aResult) { switch(aName) { + // TODO: Remove function call in Bug 1050147. case SETTINGS_WIFI_ENABLED: this.handleWifiEnabled(aResult) break; diff --git a/dom/workers/URL.cpp b/dom/workers/URL.cpp index 6c0313158217..9a44abb0fc8a 100644 --- a/dom/workers/URL.cpp +++ b/dom/workers/URL.cpp @@ -894,9 +894,10 @@ URL::RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aUrl) } void -URL::URLSearchParamsUpdated() +URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams) { MOZ_ASSERT(mSearchParams); + MOZ_ASSERT(mSearchParams == aSearchParams); nsString search; mSearchParams->Serialize(search); diff --git a/dom/workers/URL.h b/dom/workers/URL.h index 50492b61b04b..7a7c47559828 100644 --- a/dom/workers/URL.h +++ b/dom/workers/URL.h @@ -119,7 +119,7 @@ public: } // IURLSearchParamsObserver - void URLSearchParamsUpdated() MOZ_OVERRIDE; + void URLSearchParamsUpdated(URLSearchParams* aSearchParams) MOZ_OVERRIDE; private: URLProxy* GetURLProxy() const diff --git a/dom/xbl/nsBindingManager.cpp b/dom/xbl/nsBindingManager.cpp index f11e1e826d3c..c4e6f8b0aa18 100644 --- a/dom/xbl/nsBindingManager.cpp +++ b/dom/xbl/nsBindingManager.cpp @@ -490,7 +490,7 @@ nsBindingManager::PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo) NS_PRECONDITION(aDocumentInfo, "Must have a non-null documentinfo!"); if (!mDocumentTable) { - mDocumentTable = new nsRefPtrHashtable(16); + mDocumentTable = new nsRefPtrHashtable(); } mDocumentTable->Put(aDocumentInfo->DocumentURI(), aDocumentInfo); @@ -521,7 +521,8 @@ nsBindingManager::PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListen NS_PRECONDITION(aListener, "Must have a non-null listener!"); if (!mLoadingDocTable) { - mLoadingDocTable = new nsInterfaceHashtable(16); + mLoadingDocTable = + new nsInterfaceHashtable(); } mLoadingDocTable->Put(aURL, aListener); diff --git a/dom/xbl/nsXBLPrototypeBinding.cpp b/dom/xbl/nsXBLPrototypeBinding.cpp index 2eeefc39dfdb..7b7781b7bad8 100644 --- a/dom/xbl/nsXBLPrototypeBinding.cpp +++ b/dom/xbl/nsXBLPrototypeBinding.cpp @@ -598,7 +598,8 @@ void nsXBLPrototypeBinding::EnsureAttributeTable() { if (!mAttributeTable) { - mAttributeTable = new nsClassHashtable(4); + mAttributeTable = + new nsClassHashtable(2); } } @@ -609,7 +610,7 @@ nsXBLPrototypeBinding::AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* { InnerAttributeTable* attributesNS = mAttributeTable->Get(aSourceNamespaceID); if (!attributesNS) { - attributesNS = new InnerAttributeTable(4); + attributesNS = new InnerAttributeTable(2); mAttributeTable->Put(aSourceNamespaceID, attributesNS); } diff --git a/dom/xslt/xslt/txExecutionState.h b/dom/xslt/xslt/txExecutionState.h index dcd1cb998f71..70a6835e9eba 100644 --- a/dom/xslt/xslt/txExecutionState.h +++ b/dom/xslt/xslt/txExecutionState.h @@ -57,7 +57,7 @@ class txLoadedDocumentsHash : public nsTHashtable { public: txLoadedDocumentsHash() - : nsTHashtable(8), + : nsTHashtable(4), mSourceDocument(nullptr) { } diff --git a/dom/xslt/xslt/txKey.h b/dom/xslt/xslt/txKey.h index 62f47d3bfb90..a52066f87190 100644 --- a/dom/xslt/xslt/txKey.h +++ b/dom/xslt/xslt/txKey.h @@ -179,7 +179,7 @@ class txKeyHash { public: txKeyHash(const txOwningExpandedNameMap& aKeys) - : mKeyValues(8) + : mKeyValues(4) , mIndexedKeys(1) , mKeys(aKeys) { diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index 9c6017372df3..5e5a84ce7faf 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -2323,9 +2323,6 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode) } } else { // Do we ever get here? -#if DEBUG_cmanske - printf("Attribute in sourceAttribute has empty value in nsEditor::CloneAttributes()\n"); -#endif } } } diff --git a/editor/libeditor/html/nsHTMLDataTransfer.cpp b/editor/libeditor/html/nsHTMLDataTransfer.cpp index e75be6c16214..53c24a11afa3 100644 --- a/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -1135,10 +1135,6 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable nsAutoString flavor; flavor.AssignWithConversion(bestFlavor); nsAutoString stuffToPaste; -#ifdef DEBUG_clipboard - printf("Got flavor [%s]\n", bestFlavor.get()); -#endif - bool isSafe = IsSafeToInsertData(aSourceDoc); if (0 == nsCRT::strcmp(bestFlavor, kFileMime) || @@ -1646,9 +1642,6 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation(int32_t aSelectionType) if (flav && 0 == nsCRT::strcmp(flav, kUnicodeMime)) { -#ifdef DEBUG_clipboard - printf("Got flavor [%s]\n", flav); -#endif nsCOMPtr textDataObj = do_QueryInterface(genericDataObj); if (textDataObj && len > 0) { @@ -1732,11 +1725,6 @@ nsHTMLEditor::InsertTextWithQuotations(const nsAString &aStringToInsert) // inserting from curHunk to lineStart then returning. const nsAString &curHunk = Substring(hunkStart, lineStart); nsCOMPtr dummyNode; -#ifdef DEBUG_akkana_verbose - printf("==== Inserting text as %squoted: ---\n%s---\n", - curHunkIsQuoted ? "" : "non-", - NS_LossyConvertUTF16toASCII(curHunk).get()); -#endif if (curHunkIsQuoted) rv = InsertAsPlaintextQuotation(curHunk, false, getter_AddRefs(dummyNode)); diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index df4703ce06e1..094756459f64 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -1553,16 +1553,6 @@ nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, bool aDeleteSele // XXX: ERROR_HANDLING bad XPCOM usage if (NS_SUCCEEDED(res) && NS_SUCCEEDED(selection->GetAnchorOffset(&offsetForInsert)) && parentSelectedNode) { -#ifdef DEBUG_cmanske - { - nsAutoString name; - parentSelectedNode->GetNodeName(name); - printf("InsertElement: Anchor node of selection: "); - wprintf(name.get()); - printf(" Offset: %d\n", offsetForInsert); - } -#endif - // Adjust position based on the node we are going to insert. NormalizeEOLInsertPosition(node, address_of(parentSelectedNode), &offsetForInsert); diff --git a/editor/libeditor/html/nsHTMLURIRefObject.cpp b/editor/libeditor/html/nsHTMLURIRefObject.cpp index e5dd430358d6..3ae85bf4e290 100644 --- a/editor/libeditor/html/nsHTMLURIRefObject.cpp +++ b/editor/libeditor/html/nsHTMLURIRefObject.cpp @@ -126,10 +126,7 @@ nsHTMLURIRefObject::GetNextURI(nsAString & aURI) NS_ENSURE_TRUE(mAttributeCnt, NS_ERROR_FAILURE); mCurAttrIndex = 0; } -#ifdef DEBUG_akkana - printf("Looking at tag '%s'\n", - NS_LossyConvertUTF16toASCII(tagName).get()); -#endif + while (mCurAttrIndex < mAttributeCnt) { nsCOMPtr attrNode; @@ -141,10 +138,6 @@ nsHTMLURIRefObject::GetNextURI(nsAString & aURI) NS_ENSURE_SUCCESS(rv, rv); // href >> A, AREA, BASE, LINK -#ifdef DEBUG_akkana - printf("Trying to match attribute '%s'\n", - NS_LossyConvertUTF16toASCII(curAttr).get()); -#endif if (MATCHES(curAttr, "href")) { if (!MATCHES(tagName, "a") && !MATCHES(tagName, "area") @@ -248,9 +241,6 @@ nsHTMLURIRefObject::RewriteAllURIs(const nsAString & aOldPat, const nsAString & aNewPat, bool aMakeRel) { -#ifdef DEBUG_akkana - printf("Can't rewrite URIs yet\n"); -#endif return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/editor/libeditor/html/nsTableEditor.cpp b/editor/libeditor/html/nsTableEditor.cpp index 259c9da4f983..a7e8a2bde94b 100644 --- a/editor/libeditor/html/nsTableEditor.cpp +++ b/editor/libeditor/html/nsTableEditor.cpp @@ -349,9 +349,7 @@ nsHTMLEditor::GetNextRow(nsIDOMNode* aCurrentRowNode, nsIDOMNode **aRowNode) NS_ADDREF(*aRowNode); return NS_OK; } -#ifdef DEBUG_cmanske - printf("GetNextRow: firstChild of row's parent's sibling is not a TR!\n"); -#endif + // We arrive here only if a table section has no children // or first child of section is not a row (bad HTML or more "_moz_text" nodes!) // So look for another section sibling @@ -457,11 +455,6 @@ nsHTMLEditor::InsertTableColumn(int32_t aNumber, bool aAfter) nsCOMPtr rowNode; for ( rowIndex = 0; rowIndex < rowCount; rowIndex++) { -#ifdef DEBUG_cmanske - if (rowIndex == rowCount-1) - printf(" ***InsertTableColumn: Inserting cell at last row: %d\n", rowIndex); -#endif - if (startColIndex < colCount) { // We are inserting before an existing column @@ -3023,10 +3016,6 @@ nsHTMLEditor::GetNextSelectedCell(nsIDOMRange **aRange, nsIDOMElement **aCell) // We found a selected cell if (*aCell) break; -#ifdef DEBUG_cmanske - else - printf("GetNextSelectedCell: Collapsed range found\n"); -#endif // If we didn't find a cell, continue to next range in selection } @@ -3091,9 +3080,6 @@ nsHTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, int32_t aRow, in if (!selection) { -#ifdef DEBUG_cmanske - printf("Selection not found after table manipulation!\n"); -#endif return NS_ERROR_FAILURE; } diff --git a/editor/libeditor/text/nsInternetCiter.cpp b/editor/libeditor/text/nsInternetCiter.cpp index a71c045f7135..4cd658aa3435 100644 --- a/editor/libeditor/text/nsInternetCiter.cpp +++ b/editor/libeditor/text/nsInternetCiter.cpp @@ -171,20 +171,8 @@ nsInternetCiter::Rewrap(const nsAString& aInString, uint32_t citeLevel = 0; const nsPromiseFlatString &tString = PromiseFlatString(aInString); length = tString.Length(); -#ifdef DEBUG_wrapping - int loopcount = 0; -#endif while (posInString < length) { -#ifdef DEBUG_wrapping - printf("Outer loop: '%s'\n", - NS_LossyConvertUTF16toASCII(Substring(tString, posInString, - length-posInString)).get()); - printf("out string is now: '%s'\n", - NS_LossyConvertUTF16toASCII(aOutString).get()); - -#endif - // Get the new cite level here since we're at the beginning of a line uint32_t newCiteLevel = 0; while (posInString < length && tString[posInString] == gt) @@ -265,15 +253,6 @@ nsInternetCiter::Rewrap(const nsAString& aInString, // over this line of the input string to get all of it: while ((int32_t)posInString < nextNewline) { -#ifdef DEBUG_wrapping - if (++loopcount > 1000) - NS_ASSERTION(false, "possible infinite loop in nsInternetCiter\n"); - - printf("Inner loop: '%s'\n", - NS_LossyConvertUTF16toASCII(Substring(tString, posInString, - nextNewline-posInString)).get()); -#endif - // Skip over initial spaces: while ((int32_t)posInString < nextNewline && nsCRT::IsAsciiSpace(tString[posInString])) @@ -341,9 +320,6 @@ nsInternetCiter::Rewrap(const nsAString& aInString, // breaker. Just break the line, hard. if (NS_FAILED(rv)) { -#ifdef DEBUG_akkana - printf("nsInternetCiter: LineBreaker not working -- breaking hard\n"); -#endif breakPt = eol; } @@ -380,17 +356,8 @@ nsInternetCiter::Rewrap(const nsAString& aInString, BreakLine(aOutString, outStringCol, citeLevel); } // end inner loop within one line of aInString -#ifdef DEBUG_wrapping - printf("---------\nEnd inner loop: out string is now '%s'\n-----------\n", - NS_LossyConvertUTF16toASCII(aOutString).get()); -#endif } // end outer loop over lines of aInString -#ifdef DEBUG_wrapping - printf("Final out string is now: '%s'\n", - NS_LossyConvertUTF16toASCII(aOutString).get()); - -#endif return NS_OK; } diff --git a/editor/libeditor/text/nsPlaintextEditor.cpp b/editor/libeditor/text/nsPlaintextEditor.cpp index 1180501aecf0..ed113b555323 100644 --- a/editor/libeditor/text/nsPlaintextEditor.cpp +++ b/editor/libeditor/text/nsPlaintextEditor.cpp @@ -1363,14 +1363,9 @@ nsPlaintextEditor::PasteAsQuotation(int32_t aSelectionType) &len); if (NS_FAILED(rv) || !flav) { -#ifdef DEBUG_akkana - printf("PasteAsPlaintextQuotation: GetAnyTransferData failed, %d\n", rv); -#endif return rv; } -#ifdef DEBUG_clipboard - printf("Got flavor [%s]\n", flav); -#endif + if (0 == nsCRT::strcmp(flav, kUnicodeMime) || 0 == nsCRT::strcmp(flav, kMozTextInternal)) { @@ -1479,10 +1474,6 @@ nsPlaintextEditor::Rewrap(bool aRespectNewlines) if (wrapCol <= 0) wrapCol = 72; -#ifdef DEBUG_akkana - printf("nsPlaintextEditor::Rewrap to %ld columns\n", (long)wrapCol); -#endif - nsAutoString current; bool isCollapsed; rv = SharedOutputString(nsIDocumentEncoder::OutputFormatted @@ -1505,10 +1496,6 @@ nsPlaintextEditor::Rewrap(bool aRespectNewlines) NS_IMETHODIMP nsPlaintextEditor::StripCites() { -#ifdef DEBUG_akkana - printf("nsPlaintextEditor::StripCites()\n"); -#endif - nsAutoString current; bool isCollapsed; nsresult rv = SharedOutputString(nsIDocumentEncoder::OutputFormatted, diff --git a/editor/txtsvc/nsTextServicesDocument.cpp b/editor/txtsvc/nsTextServicesDocument.cpp index d3dcd52834fe..25c1a3675d24 100644 --- a/editor/txtsvc/nsTextServicesDocument.cpp +++ b/editor/txtsvc/nsTextServicesDocument.cpp @@ -3711,44 +3711,6 @@ nsTextServicesDocument::FindWordBounds(nsTArray *aOffsetTable, return NS_OK; } -#ifdef DEBUG_kin -void -nsTextServicesDocument::PrintOffsetTable() -{ - OffsetEntry *entry; - uint32_t i; - - for (i = 0; i < mOffsetTable.Length(); i++) - { - entry = mOffsetTable[i]; - printf("ENTRY %4d: %p %c %c %4d %4d %4d\n", - i, entry->mNode, entry->mIsValid ? 'V' : 'N', - entry->mIsInsertedText ? 'I' : 'B', - entry->mNodeOffset, entry->mStrOffset, entry->mLength); - } - - fflush(stdout); -} - -void -nsTextServicesDocument::PrintContentNode(nsIContent *aContent) -{ - nsString tmpStr, str; - - aContent->Tag()->ToString(tmpStr); - printf("%s", NS_LossyConvertUTF16toASCII(tmpStr).get()); - - if (nsIDOMNode::TEXT_NODE == aContent->NodeType()) - { - aContent->AppendTextTo(str); - printf(": \"%s\"", NS_LossyConvertUTF16toASCII(str).get()); - } - - printf("\n"); - fflush(stdout); -} -#endif - NS_IMETHODIMP nsTextServicesDocument::WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, diff --git a/editor/txtsvc/nsTextServicesDocument.h b/editor/txtsvc/nsTextServicesDocument.h index 882c28739288..383e2b5ca30e 100644 --- a/editor/txtsvc/nsTextServicesDocument.h +++ b/editor/txtsvc/nsTextServicesDocument.h @@ -224,11 +224,6 @@ private: int32_t *aWordStartOffset, nsIDOMNode **aWordEndNode, int32_t *aWordEndOffset); - -#ifdef DEBUG_kin - void PrintOffsetTable(); - void PrintContentNode(nsIContent *aContent); -#endif }; #endif // nsTextServicesDocument_h__ diff --git a/embedding/components/commandhandler/src/nsCommandParams.cpp b/embedding/components/commandhandler/src/nsCommandParams.cpp index c885ef539dbf..225601ad6936 100644 --- a/embedding/components/commandhandler/src/nsCommandParams.cpp +++ b/embedding/components/commandhandler/src/nsCommandParams.cpp @@ -42,8 +42,8 @@ nsCommandParams::~nsCommandParams() nsresult nsCommandParams::Init() { - PL_DHashTableInit(&mValuesHash, &sHashOps, (void *)this, sizeof(HashEntry), 4); - + PL_DHashTableInit(&mValuesHash, &sHashOps, (void *)this, + sizeof(HashEntry), 2); return NS_OK; } @@ -263,17 +263,16 @@ nsCommandParams::HashEntry* nsCommandParams::GetIndexedEntry(int32_t index) { HashEntry* entry = reinterpret_cast(mValuesHash.entryStore); - HashEntry* limit = entry + PL_DHASH_TABLE_SIZE(&mValuesHash); + HashEntry* limit = entry + PL_DHASH_TABLE_CAPACITY(&mValuesHash); uint32_t entryCount = 0; - - do - { + + do { if (!PL_DHASH_ENTRY_IS_LIVE(entry)) continue; if ((int32_t)entryCount == index) return entry; - + entryCount ++; } while (++entry < limit); @@ -285,11 +284,10 @@ uint32_t nsCommandParams::GetNumEntries() { HashEntry* entry = reinterpret_cast(mValuesHash.entryStore); - HashEntry* limit = entry + PL_DHASH_TABLE_SIZE(&mValuesHash); + HashEntry* limit = entry + PL_DHASH_TABLE_CAPACITY(&mValuesHash); uint32_t entryCount = 0; - - do - { + + do { if (PL_DHASH_ENTRY_IS_LIVE(entry)) entryCount ++; } while (++entry < limit); diff --git a/embedding/components/commandhandler/src/nsControllerCommandTable.cpp b/embedding/components/commandhandler/src/nsControllerCommandTable.cpp index 34e5095c4b84..274eda363e3d 100644 --- a/embedding/components/commandhandler/src/nsControllerCommandTable.cpp +++ b/embedding/components/commandhandler/src/nsControllerCommandTable.cpp @@ -13,11 +13,11 @@ NS_NewControllerCommandTable(nsIControllerCommandTable** aResult); // this value is used to size the hash table. Just a sensible upper bound -#define NUM_COMMANDS_BOUNDS 64 +#define NUM_COMMANDS_LENGTH 32 nsControllerCommandTable::nsControllerCommandTable() -: mCommandsTable(NUM_COMMANDS_BOUNDS) +: mCommandsTable(NUM_COMMANDS_LENGTH) , mMutable(true) { } diff --git a/gfx/2d/BaseRect.h b/gfx/2d/BaseRect.h index c6b91d533e25..fff44ffba52f 100644 --- a/gfx/2d/BaseRect.h +++ b/gfx/2d/BaseRect.h @@ -208,6 +208,20 @@ struct BaseRect { } void Inflate(const SizeT& aSize) { Inflate(aSize.width, aSize.height); } + void InflateToMultiple(const SizeT& aMultiple) + { + T xMost = XMost(); + T yMost = YMost(); + + x = static_cast(floor(x / aMultiple.width)) * aMultiple.width; + y = static_cast(floor(y / aMultiple.height)) * aMultiple.height; + xMost = static_cast(ceil(x / aMultiple.width)) * aMultiple.width; + yMost = static_cast(ceil(y / aMultiple.height)) * aMultiple.height; + + width = xMost - x; + height = yMost - y; + } + void Deflate(T aD) { Deflate(aD, aD); } void Deflate(T aDx, T aDy) { diff --git a/gfx/2d/ImageScalingSSE2.cpp b/gfx/2d/ImageScalingSSE2.cpp index f87653b4cab9..92bad43a17fd 100644 --- a/gfx/2d/ImageScalingSSE2.cpp +++ b/gfx/2d/ImageScalingSSE2.cpp @@ -248,7 +248,7 @@ ImageHalfScaler::HalfImageVertical_SSE2(uint8_t *aSource, int32_t aSourceStride, *storage++ = avg_sse2_4x2_4x1(a, b); } - } else if (!(uintptr_t(aSource + (y * aSourceStride)) % 16)) { + } else if (!(uintptr_t(aSource + ((y + 1) * aSourceStride)) % 16)) { for (; x < (aSourceSize.width - 3); x += 4) { uint8_t *upperRow = aSource + (y * aSourceStride + x * 4); uint8_t *lowerRow = aSource + ((y + 1) * aSourceStride + x * 4); diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index 5ae43098b8c7..8b6e59a0313e 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -546,7 +546,8 @@ GLBlitHelper::DeleteTexBlitProgram() void GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB, const gfx::IntSize& srcSize, - const gfx::IntSize& destSize) + const gfx::IntSize& destSize, + bool internalFBs) { MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB)); MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB)); @@ -556,8 +557,13 @@ GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB, ScopedBindFramebuffer boundFB(mGL); ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false); - mGL->BindReadFB(srcFB); - mGL->BindDrawFB(destFB); + if (internalFBs) { + mGL->Screen()->BindReadFB_Internal(srcFB); + mGL->Screen()->BindDrawFB_Internal(destFB); + } else { + mGL->BindReadFB(srcFB); + mGL->BindDrawFB(destFB); + } mGL->fBlitFramebuffer(0, 0, srcSize.width, srcSize.height, 0, 0, destSize.width, destSize.height, @@ -569,22 +575,24 @@ void GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB, const gfx::IntSize& srcSize, const gfx::IntSize& destSize, - const GLFormats& srcFormats) + const GLFormats& srcFormats, + bool internalFBs) { MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB)); MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB)); if (mGL->IsSupported(GLFeature::framebuffer_blit)) { BlitFramebufferToFramebuffer(srcFB, destFB, - srcSize, destSize); + srcSize, destSize, + internalFBs); return; } GLuint tex = CreateTextureForOffscreen(mGL, srcFormats, srcSize); MOZ_ASSERT(tex); - BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize); - BlitTextureToFramebuffer(tex, destFB, srcSize, destSize); + BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize, internalFBs); + BlitTextureToFramebuffer(tex, destFB, srcSize, destSize, internalFBs); mGL->fDeleteTextures(1, &tex); } @@ -782,7 +790,8 @@ void GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, const gfx::IntSize& srcSize, const gfx::IntSize& destSize, - GLenum srcTarget) + GLenum srcTarget, + bool internalFBs) { MOZ_ASSERT(mGL->fIsTexture(srcTex)); MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB)); @@ -792,7 +801,8 @@ GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, MOZ_ASSERT(srcWrapper.IsComplete()); BlitFramebufferToFramebuffer(srcWrapper.FB(), destFB, - srcSize, destSize); + srcSize, destSize, + internalFBs); return; } @@ -812,6 +822,11 @@ GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, } ScopedGLDrawState autoStates(mGL); + if (internalFBs) { + mGL->Screen()->BindFB_Internal(destFB); + } else { + mGL->BindFB(destFB); + } // Does destructive things to (only!) what we just saved above. bool good = UseTexQuadProgram(type, srcSize); @@ -828,7 +843,8 @@ void GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex, const gfx::IntSize& srcSize, const gfx::IntSize& destSize, - GLenum destTarget) + GLenum destTarget, + bool internalFBs) { MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB)); MOZ_ASSERT(mGL->fIsTexture(destTex)); @@ -837,14 +853,21 @@ GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex, ScopedFramebufferForTexture destWrapper(mGL, destTex, destTarget); BlitFramebufferToFramebuffer(srcFB, destWrapper.FB(), - srcSize, destSize); + srcSize, destSize, + internalFBs); return; } ScopedBindTexture autoTex(mGL, destTex, destTarget); - ScopedBindFramebuffer boundFB(mGL, srcFB); - ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false); + ScopedBindFramebuffer boundFB(mGL); + if (internalFBs) { + mGL->Screen()->BindFB_Internal(srcFB); + } else { + mGL->BindFB(srcFB); + } + + ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false); mGL->fCopyTexSubImage2D(destTarget, 0, 0, 0, 0, 0, diff --git a/gfx/gl/GLBlitHelper.h b/gfx/gl/GLBlitHelper.h index 1f9c6be25860..a3330797c8fc 100644 --- a/gfx/gl/GLBlitHelper.h +++ b/gfx/gl/GLBlitHelper.h @@ -153,19 +153,23 @@ public: // the first BlitFramebufferToFramebuffer. void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB, const gfx::IntSize& srcSize, - const gfx::IntSize& destSize); + const gfx::IntSize& destSize, + bool internalFBs = false); void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB, const gfx::IntSize& srcSize, const gfx::IntSize& destSize, - const GLFormats& srcFormats); + const GLFormats& srcFormats, + bool internalFBs = false); void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, const gfx::IntSize& srcSize, const gfx::IntSize& destSize, - GLenum srcTarget = LOCAL_GL_TEXTURE_2D); + GLenum srcTarget = LOCAL_GL_TEXTURE_2D, + bool internalFBs = false); void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex, const gfx::IntSize& srcSize, const gfx::IntSize& destSize, - GLenum destTarget = LOCAL_GL_TEXTURE_2D); + GLenum destTarget = LOCAL_GL_TEXTURE_2D, + bool internalFBs = false); void BlitTextureToTexture(GLuint srcTex, GLuint destTex, const gfx::IntSize& srcSize, const gfx::IntSize& destSize, diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index fb83cb0aaab2..74fc127979ac 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -147,17 +147,13 @@ GLScreenBuffer::BindFB(GLuint fb) void GLScreenBuffer::BindDrawFB(GLuint fb) { - if (!mGL->IsSupported(GLFeature::framebuffer_blit)) { - NS_WARNING("DRAW_FRAMEBUFFER requested, but unsupported."); + MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit)); - mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb); - } else { - GLuint drawFB = DrawFB(); - mUserDrawFB = fb; - mInternalDrawFB = (fb == 0) ? drawFB : fb; + GLuint drawFB = DrawFB(); + mUserDrawFB = fb; + mInternalDrawFB = (fb == 0) ? drawFB : fb; - mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB); - } + mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB); #ifdef DEBUG mInInternalMode_DrawFB = false; @@ -167,28 +163,39 @@ GLScreenBuffer::BindDrawFB(GLuint fb) void GLScreenBuffer::BindReadFB(GLuint fb) { - if (!mGL->IsSupported(GLFeature::framebuffer_blit)) { - NS_WARNING("READ_FRAMEBUFFER requested, but unsupported."); + MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit)); - mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb); - } else { - GLuint readFB = ReadFB(); - mUserReadFB = fb; - mInternalReadFB = (fb == 0) ? readFB : fb; + GLuint readFB = ReadFB(); + mUserReadFB = fb; + mInternalReadFB = (fb == 0) ? readFB : fb; - mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB); - } + mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB); #ifdef DEBUG mInInternalMode_ReadFB = false; #endif } +void +GLScreenBuffer::BindFB_Internal(GLuint fb) +{ + mInternalDrawFB = mUserDrawFB = fb; + mInternalReadFB = mUserReadFB = fb; + mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB); + +#ifdef DEBUG + mInInternalMode_DrawFB = true; + mInInternalMode_ReadFB = true; +#endif +} + void GLScreenBuffer::BindDrawFB_Internal(GLuint fb) { - mInternalDrawFB = mUserDrawFB = fb; - mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB); + MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit)); + + mInternalDrawFB = mUserDrawFB = fb; + mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB); #ifdef DEBUG mInInternalMode_DrawFB = true; @@ -198,8 +205,10 @@ GLScreenBuffer::BindDrawFB_Internal(GLuint fb) void GLScreenBuffer::BindReadFB_Internal(GLuint fb) { - mInternalReadFB = mUserReadFB = fb; - mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB); + MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit)); + + mInternalReadFB = mUserReadFB = fb; + mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB); #ifdef DEBUG mInInternalMode_ReadFB = true; diff --git a/gfx/gl/GLScreenBuffer.h b/gfx/gl/GLScreenBuffer.h index 60965970fbd4..5f39512a58ab 100644 --- a/gfx/gl/GLScreenBuffer.h +++ b/gfx/gl/GLScreenBuffer.h @@ -269,6 +269,7 @@ public: // Here `fb` is the actual framebuffer you want bound. Binding 0 will // bind the (generally useless) default framebuffer. + void BindFB_Internal(GLuint fb); void BindDrawFB_Internal(GLuint fb); void BindReadFB_Internal(GLuint fb); }; diff --git a/gfx/gl/SharedSurface.cpp b/gfx/gl/SharedSurface.cpp index 443c18847063..27743607fce7 100644 --- a/gfx/gl/SharedSurface.cpp +++ b/gfx/gl/SharedSurface.cpp @@ -59,13 +59,20 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, GLuint destTex = dest->ProdTexture(); GLenum destTarget = dest->ProdTextureTarget(); - gl->BlitHelper()->BlitFramebufferToTexture(0, destTex, src->mSize, dest->mSize, destTarget); + gl->BlitHelper()->BlitFramebufferToTexture(0, destTex, + src->mSize, + dest->mSize, + destTarget, + true); } else if (dest->mAttachType == AttachmentType::GLRenderbuffer) { GLuint destRB = dest->ProdRenderbuffer(); ScopedFramebufferForRenderbuffer destWrapper(gl, destRB); - gl->BlitHelper()->BlitFramebufferToFramebuffer(0, destWrapper.FB(), - src->mSize, dest->mSize); + gl->BlitHelper()->BlitFramebufferToFramebuffer(0, + destWrapper.FB(), + src->mSize, + dest->mSize, + true); } else { MOZ_CRASH("Unhandled dest->mAttachType."); } @@ -97,13 +104,20 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, GLuint srcTex = src->ProdTexture(); GLenum srcTarget = src->ProdTextureTarget(); - gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0, src->mSize, dest->mSize, srcTarget); + gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0, + src->mSize, + dest->mSize, + srcTarget, + true); } else if (src->mAttachType == AttachmentType::GLRenderbuffer) { GLuint srcRB = src->ProdRenderbuffer(); ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB); - gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(), 0, - src->mSize, dest->mSize); + gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(), + 0, + src->mSize, + dest->mSize, + true); } else { MOZ_CRASH("Unhandled src->mAttachType."); } diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index fe93bb44d70a..6ab050e17119 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1434,6 +1434,14 @@ public: virtual int32_t GetMaxLayerSize() { return Manager()->GetMaxTextureSize(); } + /** + * Returns true if this layer's effective transform is not just + * a translation by integers, or if this layer or some ancestor layer + * is marked as having a transform that may change without a full layer + * transaction. + */ + bool MayResample(); + protected: Layer(LayerManager* aManager, void* aImplData); @@ -1482,14 +1490,6 @@ protected: const gfxRect& aSnapRect, gfx::Matrix* aResidualTransform); - /** - * Returns true if this layer's effective transform is not just - * a translation by integers, or if this layer or some ancestor layer - * is marked as having a transform that may change without a full layer - * transaction. - */ - bool MayResample(); - LayerManager* mManager; ContainerLayer* mParent; Layer* mNextSibling; diff --git a/gfx/layers/client/ClientContainerLayer.h b/gfx/layers/client/ClientContainerLayer.h index 4a8ace8d404f..23329689c0a2 100644 --- a/gfx/layers/client/ClientContainerLayer.h +++ b/gfx/layers/client/ClientContainerLayer.h @@ -66,11 +66,7 @@ public: continue; } - if (child->GetType() != TYPE_THEBES) { - ToClientLayer(child)->RenderLayer(); - } else { - static_cast(child)->RenderLayer(&readback); - } + ToClientLayer(child)->RenderLayerWithReadback(&readback); if (!ClientManager()->GetRepeatTransaction() && !child->GetInvalidRegion().IsEmpty()) { diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index d9e414bd4ca1..f5dd326738ae 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -334,6 +334,7 @@ public: virtual void ClearCachedResources() { } virtual void RenderLayer() = 0; + virtual void RenderLayerWithReadback(ReadbackProcessor *aReadback) { RenderLayer(); } virtual ClientThebesLayer* AsThebes() { return nullptr; } diff --git a/gfx/layers/client/ClientThebesLayer.cpp b/gfx/layers/client/ClientThebesLayer.cpp index 8dd569d20036..da7b8cd04059 100644 --- a/gfx/layers/client/ClientThebesLayer.cpp +++ b/gfx/layers/client/ClientThebesLayer.cpp @@ -105,7 +105,7 @@ ClientThebesLayer::PaintThebes() } void -ClientThebesLayer::RenderLayer(ReadbackProcessor *aReadback) +ClientThebesLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback) { if (GetMaskLayer()) { ToClientLayer(GetMaskLayer())->RenderLayer(); diff --git a/gfx/layers/client/ClientThebesLayer.h b/gfx/layers/client/ClientThebesLayer.h index ca63a9bf5637..b5864ef448f4 100644 --- a/gfx/layers/client/ClientThebesLayer.h +++ b/gfx/layers/client/ClientThebesLayer.h @@ -69,9 +69,9 @@ public: mValidRegion.Sub(mValidRegion, mInvalidRegion); } - virtual void RenderLayer() { RenderLayer(nullptr); } + virtual void RenderLayer() { RenderLayerWithReadback(nullptr); } - virtual void RenderLayer(ReadbackProcessor *aReadback); + virtual void RenderLayerWithReadback(ReadbackProcessor *aReadback) MOZ_OVERRIDE; virtual void ClearCachedResources() { diff --git a/gfx/layers/client/ClientTiledThebesLayer.cpp b/gfx/layers/client/ClientTiledThebesLayer.cpp index 004c174d86e1..cd83742f4264 100644 --- a/gfx/layers/client/ClientTiledThebesLayer.cpp +++ b/gfx/layers/client/ClientTiledThebesLayer.cpp @@ -195,6 +195,7 @@ ClientTiledThebesLayer::UseFastPath() bool ClientTiledThebesLayer::RenderHighPrecision(nsIntRegion& aInvalidRegion, + const nsIntRegion& aVisibleRegion, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData) { @@ -213,7 +214,7 @@ ClientTiledThebesLayer::RenderHighPrecision(nsIntRegion& aInvalidRegion, // We clip the old valid region to the visible region, as it only gets // used to decide stale content (currently valid and previously visible) nsIntRegion oldValidRegion = mContentClient->mTiledBuffer.GetValidRegion(); - oldValidRegion.And(oldValidRegion, mVisibleRegion); + oldValidRegion.And(oldValidRegion, aVisibleRegion); if (!mPaintData.mCriticalDisplayPort.IsEmpty()) { oldValidRegion.And(oldValidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); } @@ -226,7 +227,7 @@ ClientTiledThebesLayer::RenderHighPrecision(nsIntRegion& aInvalidRegion, // Otherwise do a non-progressive paint - mValidRegion = mVisibleRegion; + mValidRegion = aVisibleRegion; if (!mPaintData.mCriticalDisplayPort.IsEmpty()) { mValidRegion.And(mValidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); } @@ -241,14 +242,15 @@ ClientTiledThebesLayer::RenderHighPrecision(nsIntRegion& aInvalidRegion, bool ClientTiledThebesLayer::RenderLowPrecision(nsIntRegion& aInvalidRegion, + const nsIntRegion& aVisibleRegion, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData) { // Render the low precision buffer, if the visible region is larger than the // critical display port. - if (!nsIntRegion(LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)).Contains(mVisibleRegion)) { + if (!nsIntRegion(LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)).Contains(aVisibleRegion)) { nsIntRegion oldValidRegion = mContentClient->mLowPrecisionTiledBuffer.GetValidRegion(); - oldValidRegion.And(oldValidRegion, mVisibleRegion); + oldValidRegion.And(oldValidRegion, aVisibleRegion); bool updatedBuffer = false; @@ -261,12 +263,12 @@ ClientTiledThebesLayer::RenderLowPrecision(nsIntRegion& aInvalidRegion, oldValidRegion.SetEmpty(); mLowPrecisionValidRegion.SetEmpty(); mContentClient->mLowPrecisionTiledBuffer.SetFrameResolution(mPaintData.mResolution); - aInvalidRegion = mVisibleRegion; + aInvalidRegion = aVisibleRegion; } // Invalidate previously valid content that is no longer visible if (mPaintData.mLowPrecisionPaintCount == 1) { - mLowPrecisionValidRegion.And(mLowPrecisionValidRegion, mVisibleRegion); + mLowPrecisionValidRegion.And(mLowPrecisionValidRegion, aVisibleRegion); } mPaintData.mLowPrecisionPaintCount++; @@ -335,8 +337,23 @@ ClientTiledThebesLayer::RenderLayer() TILING_LOG("TILING %p: Initial valid region %s\n", this, Stringify(mValidRegion).c_str()); TILING_LOG("TILING %p: Initial low-precision valid region %s\n", this, Stringify(mLowPrecisionValidRegion).c_str()); + nsIntRegion neededRegion = mVisibleRegion; + if (MayResample()) { + // If we're resampling then bilinear filtering can read up to 1 pixel + // outside of our texture coords. Make the visible region a single rect, + // and pad it out by 1 pixel (restricted to tile boundaries) so that + // we always have valid content or transparent pixels to sample from. + nsIntRect bounds = neededRegion.GetBounds(); + nsIntRect wholeTiles = bounds; + wholeTiles.Inflate(nsIntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight())); + nsIntRect padded = bounds; + padded.Inflate(1); + padded.IntersectRect(padded, wholeTiles); + neededRegion = padded; + } + nsIntRegion invalidRegion; - invalidRegion.Sub(mVisibleRegion, mValidRegion); + invalidRegion.Sub(neededRegion, mValidRegion); if (invalidRegion.IsEmpty()) { EndPaint(); return; @@ -351,7 +368,7 @@ ClientTiledThebesLayer::RenderLayer() // In some cases we can take a fast path and just be done with it. if (UseFastPath()) { TILING_LOG("TILING %p: Taking fast-path\n", this); - mValidRegion = mVisibleRegion; + mValidRegion = neededRegion; mContentClient->mTiledBuffer.PaintThebes(mValidRegion, invalidRegion, callback, data); ClientManager()->Hold(this); mContentClient->UseTiledLayerBuffer(TiledContentClient::TILED_BUFFER); @@ -368,7 +385,7 @@ ClientTiledThebesLayer::RenderLayer() // Make sure that tiles that fall outside of the visible region or outside of the // critical displayport are discarded on the first update. Also make sure that we // only draw stuff inside the critical displayport on the first update. - mValidRegion.And(mValidRegion, mVisibleRegion); + mValidRegion.And(mValidRegion, neededRegion); if (!mPaintData.mCriticalDisplayPort.IsEmpty()) { mValidRegion.And(mValidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); invalidRegion.And(invalidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); @@ -387,12 +404,14 @@ ClientTiledThebesLayer::RenderLayer() if (gfxPrefs::UseLowPrecisionBuffer()) { // Calculate the invalid region for the low precision buffer. Make sure // to remove the valid high-precision area so we don't double-paint it. - lowPrecisionInvalidRegion.Sub(mVisibleRegion, mLowPrecisionValidRegion); + lowPrecisionInvalidRegion.Sub(neededRegion, mLowPrecisionValidRegion); lowPrecisionInvalidRegion.Sub(lowPrecisionInvalidRegion, mValidRegion); } TILING_LOG("TILING %p: Low-precision invalid region %s\n", this, Stringify(lowPrecisionInvalidRegion).c_str()); - bool updatedHighPrecision = RenderHighPrecision(invalidRegion, callback, data); + bool updatedHighPrecision = RenderHighPrecision(invalidRegion, + neededRegion, + callback, data); if (updatedHighPrecision) { ClientManager()->Hold(this); mContentClient->UseTiledLayerBuffer(TiledContentClient::TILED_BUFFER); @@ -423,7 +442,9 @@ ClientTiledThebesLayer::RenderLayer() return; } - bool updatedLowPrecision = RenderLowPrecision(lowPrecisionInvalidRegion, callback, data); + bool updatedLowPrecision = RenderLowPrecision(lowPrecisionInvalidRegion, + neededRegion, + callback, data); if (updatedLowPrecision) { ClientManager()->Hold(this); mContentClient->UseTiledLayerBuffer(TiledContentClient::LOW_PRECISION_TILED_BUFFER); diff --git a/gfx/layers/client/ClientTiledThebesLayer.h b/gfx/layers/client/ClientTiledThebesLayer.h index 0582c982e8a6..91ee0494ebd1 100644 --- a/gfx/layers/client/ClientTiledThebesLayer.h +++ b/gfx/layers/client/ClientTiledThebesLayer.h @@ -103,6 +103,7 @@ private: * This function returns true if it updated the paint buffer. */ bool RenderHighPrecision(nsIntRegion& aInvalidRegion, + const nsIntRegion& aVisibleRegion, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData); @@ -111,6 +112,7 @@ private: * This function returns true if it updated the paint buffer. */ bool RenderLowPrecision(nsIntRegion& aInvalidRegion, + const nsIntRegion& aVisibleRegion, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData); diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 964b04d36d31..184d041adc3d 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -327,6 +327,11 @@ ClientTiledLayerBuffer::GetContentType(SurfaceMode* aMode) const content = gfxContentType::COLOR; } #endif + } else if (mode == SurfaceMode::SURFACE_OPAQUE) { + if (mThebesLayer->MayResample()) { + mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA; + content = gfxContentType::COLOR_ALPHA; + } } if (aMode) { diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 8f6b3cddebb0..33a2f4b16efe 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -37,14 +37,6 @@ class DataSourceSurface; namespace layers { -// Some properties of a Layer required for tiling -struct TiledLayerProperties -{ - nsIntRegion mVisibleRegion; - nsIntRegion mValidRegion; - CSSToScreenScale mEffectiveResolution; -}; - class Layer; class SurfaceDescriptor; class Compositor; @@ -121,8 +113,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr) = 0; + const nsIntRegion* aVisibleRegion = nullptr) = 0; /** * Update the content host. diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index d54ec10a4467..72d4dd7495d5 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -27,7 +27,6 @@ namespace layers { ContentHostBase::ContentHostBase(const TextureInfo& aTextureInfo) : ContentHost(aTextureInfo) - , mPaintWillResample(false) , mInitialised(false) {} @@ -41,8 +40,7 @@ ContentHostBase::Composite(EffectChain& aEffectChain, const gfx::Matrix4x4& aTransform, const Filter& aFilter, const Rect& aClipRect, - const nsIntRegion* aVisibleRegion, - TiledLayerProperties* aLayerProperties) + const nsIntRegion* aVisibleRegion) { NS_ASSERTION(aVisibleRegion, "Requires a visible region"); diff --git a/gfx/layers/composite/ContentHost.h b/gfx/layers/composite/ContentHost.h index 40580fcea78a..e5aa7156aa9d 100644 --- a/gfx/layers/composite/ContentHost.h +++ b/gfx/layers/composite/ContentHost.h @@ -64,12 +64,16 @@ public: const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) = 0; - virtual void SetPaintWillResample(bool aResample) { } + virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; } + bool PaintWillResample() { return mPaintWillResample; } protected: ContentHost(const TextureInfo& aTextureInfo) : CompositableHost(aTextureInfo) + , mPaintWillResample(false) {} + + bool mPaintWillResample; }; /** @@ -97,10 +101,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr); - - virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; } + const nsIntRegion* aVisibleRegion = nullptr); virtual NewTextureSource* GetTextureSource() = 0; virtual NewTextureSource* GetTextureSourceOnWhite() = 0; @@ -113,11 +114,9 @@ protected: return mBufferRect.TopLeft() - mBufferRotation; } - bool PaintWillResample() { return mPaintWillResample; } nsIntRect mBufferRect; nsIntPoint mBufferRotation; - bool mPaintWillResample; bool mInitialised; }; diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index 2025fe0b493b..4e67991e23ec 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -65,8 +65,7 @@ ImageHost::Composite(EffectChain& aEffectChain, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion, - TiledLayerProperties* aLayerProperties) + const nsIntRegion* aVisibleRegion) { if (!GetCompositor()) { // should only happen when a tab is dragged to another window and diff --git a/gfx/layers/composite/ImageHost.h b/gfx/layers/composite/ImageHost.h index 5002a00a52a7..bae8ed772072 100644 --- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -50,8 +50,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr) MOZ_OVERRIDE; + const nsIntRegion* aVisibleRegion = nullptr) MOZ_OVERRIDE; virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE; diff --git a/gfx/layers/composite/ThebesLayerComposite.cpp b/gfx/layers/composite/ThebesLayerComposite.cpp index 3b4870f3f835..e47aaeb4adca 100644 --- a/gfx/layers/composite/ThebesLayerComposite.cpp +++ b/gfx/layers/composite/ThebesLayerComposite.cpp @@ -38,7 +38,6 @@ ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager) : ThebesLayer(aManager, nullptr) , LayerComposite(aManager) , mBuffer(nullptr) - , mRequiresTiledProperties(false) { MOZ_COUNT_CTOR(ThebesLayerComposite); mImplData = static_cast(this); @@ -135,13 +134,6 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect) const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion(); - TiledLayerProperties tiledLayerProps; - if (mRequiresTiledProperties) { - tiledLayerProps.mVisibleRegion = visibleRegion; - tiledLayerProps.mEffectiveResolution = GetEffectiveResolution(); - tiledLayerProps.mValidRegion = mValidRegion; - } - mBuffer->SetPaintWillResample(MayResample()); mBuffer->Composite(effectChain, @@ -149,15 +141,9 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect) GetEffectiveTransform(), GetEffectFilter(), clipRect, - &visibleRegion, - mRequiresTiledProperties ? &tiledLayerProps - : nullptr); + &visibleRegion); mBuffer->BumpFlashCounter(); - if (mRequiresTiledProperties) { - mValidRegion = tiledLayerProps.mValidRegion; - } - mCompositeManager->GetCompositor()->MakeCurrent(); } diff --git a/gfx/layers/composite/ThebesLayerComposite.h b/gfx/layers/composite/ThebesLayerComposite.h index 49fbc3994222..0a09112cf82a 100644 --- a/gfx/layers/composite/ThebesLayerComposite.h +++ b/gfx/layers/composite/ThebesLayerComposite.h @@ -65,8 +65,6 @@ public: virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; } - void EnsureTiled() { mRequiresTiledProperties = true; } - virtual void InvalidateRegion(const nsIntRegion& aRegion) { NS_RUNTIMEABORT("ThebesLayerComposites can't fill invalidated regions"); @@ -92,7 +90,6 @@ private: private: RefPtr mBuffer; - bool mRequiresTiledProperties; }; } /* layers */ diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index 13847958a083..6d4aee59ce5c 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -241,7 +241,6 @@ TiledContentHost::Attach(Layer* aLayer, AttachFlags aFlags /* = NO_FLAGS */) { CompositableHost::Attach(aLayer, aCompositor, aFlags); - static_cast(aLayer)->EnsureTiled(); } void @@ -324,11 +323,8 @@ TiledContentHost::Composite(EffectChain& aEffectChain, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion /* = nullptr */, - TiledLayerProperties* aLayerProperties /* = nullptr */) + const nsIntRegion* aVisibleRegion /* = nullptr */) { - MOZ_ASSERT(aLayerProperties, "aLayerProperties required for TiledContentHost"); - if (mPendingUpload) { mTiledBuffer.SetCompositor(mCompositor); mTiledBuffer.Upload(); @@ -374,13 +370,25 @@ TiledContentHost::Composite(EffectChain& aEffectChain, (aOpacity == 1.0f && backgroundColor.a == 1.0f) ? gfxPrefs::LowPrecisionOpacity() : 1.0f; + nsIntRegion tmpRegion; + const nsIntRegion* renderRegion; + if (PaintWillResample()) { + // If we're resampling, then the texture image will contain exactly the + // entire visible region's bounds, and we should draw it all in one quad + // to avoid unexpected aliasing. + tmpRegion = aVisibleRegion->GetBounds(); + renderRegion = &tmpRegion; + } else { + renderRegion = aVisibleRegion; + } + // Render the low and high precision buffers. RenderLayerBuffer(mLowPrecisionTiledBuffer, lowPrecisionOpacityReduction < 1.0f ? &backgroundColor : nullptr, aEffectChain, lowPrecisionOpacityReduction * aOpacity, - aFilter, aClipRect, aLayerProperties->mVisibleRegion, aTransform); + aFilter, aClipRect, *renderRegion, aTransform); RenderLayerBuffer(mTiledBuffer, nullptr, aEffectChain, aOpacity, aFilter, - aClipRect, aLayerProperties->mVisibleRegion, aTransform); + aClipRect, *renderRegion, aTransform); // Now release the old buffer if it had double-buffered tiles, as we can // guarantee that they're no longer on the screen (and so any locks that may diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index db595e7d82f4..1c29651a4551 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -223,8 +223,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr); + const nsIntRegion* aVisibleRegion = nullptr); virtual CompositableType GetType() { return CompositableType::BUFFER_TILED; } diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index 80eb823a1197..b1619abe432e 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -583,7 +583,7 @@ int32_t gfxDWriteFont::GetGlyphWidth(gfxContext *aCtx, uint16_t aGID) { if (!mGlyphWidths) { - mGlyphWidths = new nsDataHashtable(200); + mGlyphWidths = new nsDataHashtable(128); } int32_t width = -1; diff --git a/gfx/thebes/gfxFT2Fonts.cpp b/gfx/thebes/gfxFT2Fonts.cpp index fdc0e0e40cc2..deb055d8af4e 100644 --- a/gfx/thebes/gfxFT2Fonts.cpp +++ b/gfx/thebes/gfxFT2Fonts.cpp @@ -162,7 +162,7 @@ gfxFT2Font::gfxFT2Font(cairo_scaled_font_t *aCairoFont, const gfxFontStyle *aFontStyle, bool aNeedsBold) : gfxFT2FontBase(aCairoFont, aFontEntry, aFontStyle) - , mCharGlyphCache(64) + , mCharGlyphCache(32) { NS_ASSERTION(mFontEntry, "Unable to find font entry for font. Something is whack."); mApplySyntheticBold = aNeedsBold; diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 77b373f217bd..f50b144a6ada 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -673,7 +673,7 @@ gfxFontEntry::GetExistingFontTable(uint32_t aTag, hb_blob_t **aBlob) if (!mFontTableCache) { // we do this here rather than on fontEntry construction // because not all shapers will access the table cache at all - mFontTableCache = new nsTHashtable(10); + mFontTableCache = new nsTHashtable(8); } FontTableHashEntry *entry = mFontTableCache->GetEntry(aTag); @@ -692,7 +692,7 @@ gfxFontEntry::ShareFontTableAndGetBlob(uint32_t aTag, if (MOZ_UNLIKELY(!mFontTableCache)) { // we do this here rather than on fontEntry construction // because not all shapers will access the table cache at all - mFontTableCache = new nsTHashtable(10); + mFontTableCache = new nsTHashtable(8); } FontTableHashEntry *entry = mFontTableCache->PutEntry(aTag); diff --git a/gfx/thebes/gfxFontFeatures.cpp b/gfx/thebes/gfxFontFeatures.cpp index 3c1c0a9c4a2a..dcc5e369a95f 100644 --- a/gfx/thebes/gfxFontFeatures.cpp +++ b/gfx/thebes/gfxFontFeatures.cpp @@ -10,7 +10,7 @@ using namespace mozilla; gfxFontFeatureValueSet::gfxFontFeatureValueSet() - : mFontFeatureValues(10) + : mFontFeatureValues(8) { } diff --git a/gfx/thebes/gfxFontconfigUtils.cpp b/gfx/thebes/gfxFontconfigUtils.cpp index 45b364494002..8aec4eeeba0a 100644 --- a/gfx/thebes/gfxFontconfigUtils.cpp +++ b/gfx/thebes/gfxFontconfigUtils.cpp @@ -313,9 +313,9 @@ gfxFontconfigUtils::NewPattern(const nsTArray& aFamilies, } gfxFontconfigUtils::gfxFontconfigUtils() - : mFontsByFamily(50) - , mFontsByFullname(50) - , mLangSupportTable(50) + : mFontsByFamily(32) + , mFontsByFullname(32) + , mLangSupportTable(32) , mLastConfig(nullptr) #ifdef MOZ_BUNDLED_FONTS , mBundledFontsInitialized(false) diff --git a/gfx/thebes/gfxGDIFont.cpp b/gfx/thebes/gfxGDIFont.cpp index f58d43426249..0dfad23f5f7b 100644 --- a/gfx/thebes/gfxGDIFont.cpp +++ b/gfx/thebes/gfxGDIFont.cpp @@ -431,7 +431,7 @@ gfxGDIFont::GetGlyph(uint32_t aUnicode, uint32_t aVarSelector) } if (!mGlyphIDs) { - mGlyphIDs = new nsDataHashtable(128); + mGlyphIDs = new nsDataHashtable(64); } uint32_t gid; @@ -459,7 +459,7 @@ int32_t gfxGDIFont::GetGlyphWidth(gfxContext *aCtx, uint16_t aGID) { if (!mGlyphWidths) { - mGlyphWidths = new nsDataHashtable(200); + mGlyphWidths = new nsDataHashtable(128); } int32_t width; diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp index 5c1dbb98d0f6..cce003820ef1 100644 --- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -572,7 +572,7 @@ GDIFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) */ gfxGDIFontList::gfxGDIFontList() - : mFontSubstitutes(50) + : mFontSubstitutes(32) { #ifdef MOZ_BUNDLED_FONTS ActivateBundledFonts(); diff --git a/gfx/thebes/gfxPangoFonts.cpp b/gfx/thebes/gfxPangoFonts.cpp index 83bac100429c..4a031cb03d63 100644 --- a/gfx/thebes/gfxPangoFonts.cpp +++ b/gfx/thebes/gfxPangoFonts.cpp @@ -915,7 +915,7 @@ gfxFcFontSet::SortPreferredFonts(bool &aWaitForUserFont) double requestedSize = -1.0; FcPatternGetDouble(mSortPattern, FC_PIXEL_SIZE, 0, &requestedSize); - nsTHashtable existingFamilies(50); + nsTHashtable existingFamilies(32); FcChar8 *family; for (int v = 0; FcPatternGetString(mSortPattern, diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 611f4c8b6799..d153b21e4f56 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -167,8 +167,8 @@ gfxPlatformFontList::MemoryReporter::CollectReports( } gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames) - : mFontFamilies(100), mOtherFamilyNames(30), - mPrefFonts(10), mBadUnderlineFamilyNames(10), mSharedCmaps(16), + : mFontFamilies(64), mOtherFamilyNames(16), + mPrefFonts(8), mBadUnderlineFamilyNames(8), mSharedCmaps(8), mStartIndex(0), mIncrement(1), mNumFamilies(0) { mOtherFamilyNamesInitialized = false; @@ -397,7 +397,7 @@ gfxPlatformFontList::LookupInFaceNameLists(const nsAString& aFaceName) // names not completely initialized, so keep track of lookup misses if (!mFaceNameListsInitialized) { if (!mFaceNamesMissed) { - mFaceNamesMissed = new nsTHashtable(4); + mFaceNamesMissed = new nsTHashtable(2); } mFaceNamesMissed->PutEntry(aFaceName); } @@ -416,7 +416,7 @@ gfxPlatformFontList::PreloadNamesList() for (uint32_t i = 0; i < numFonts; i++) { nsAutoString key; GenerateFontListKey(preloadFonts[i], key); - + // only search canonical names! gfxFontFamily *familyEntry = mFontFamilies.GetWeak(key); if (familyEntry) { @@ -760,7 +760,7 @@ gfxPlatformFontList::FindFamily(const nsAString& aFamily) // localized family names load timed out, add name to list of // names to check after localized names are loaded if (!mOtherNamesMissed) { - mOtherNamesMissed = new nsTHashtable(4); + mOtherNamesMissed = new nsTHashtable(2); } mOtherNamesMissed->PutEntry(key); } diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index 8e55a97c10e0..7c1a5a179b12 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -303,7 +303,7 @@ protected: bool mFaceNameListsInitialized; struct ExtraNames { - ExtraNames() : mFullnames(100), mPostscriptNames(100) {} + ExtraNames() : mFullnames(64), mPostscriptNames(64) {} // fullname ==> font entry (unique, one name per font entry) nsRefPtrHashtable mFullnames; // Postscript name ==> font entry (unique, one name per font entry) diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index 97f0e5a7394e..6dfdb0745982 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -565,7 +565,7 @@ gfxProxyFontEntry::LoadFont(gfxMixedFontFamily *aFamily, } gfxUserFontSet::gfxUserFontSet() - : mFontFamilies(5), mLocalRulesUsed(false) + : mFontFamilies(4), mLocalRulesUsed(false) { IncrementGeneration(); gfxPlatformFontList *fp = gfxPlatformFontList::PlatformFontList(); diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 3237de3f6e28..eac418fe23e5 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -292,7 +292,7 @@ NS_IMPL_ISUPPORTS(GPUAdapterReporter, nsIMemoryReporter) gfxWindowsPlatform::gfxWindowsPlatform() : mD3D11DeviceInitialized(false) - , mPrefFonts(50) + , mPrefFonts(32) { mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE; mUseClearTypeAlways = UNINITIALIZED_VALUE; diff --git a/ipc/glue/WindowsMessageLoop.cpp b/ipc/glue/WindowsMessageLoop.cpp index aad27382200f..3de93a765b14 100644 --- a/ipc/glue/WindowsMessageLoop.cpp +++ b/ipc/glue/WindowsMessageLoop.cpp @@ -642,6 +642,11 @@ MessageChannel::SyncStackFrame::SyncStackFrame(MessageChannel* channel, bool int , mPrev(mChannel->mTopFrame) , mStaticPrev(sStaticTopFrame) { + // Only track stack frames when we are on the gui thread. + if (GetCurrentThreadId() != gUIThreadId) { + return; + } + mChannel->mTopFrame = this; sStaticTopFrame = this; @@ -654,6 +659,10 @@ MessageChannel::SyncStackFrame::SyncStackFrame(MessageChannel* channel, bool int MessageChannel::SyncStackFrame::~SyncStackFrame() { + if (GetCurrentThreadId() != gUIThreadId) { + return; + } + NS_ASSERTION(this == mChannel->mTopFrame, "Mismatched interrupt stack frames"); NS_ASSERTION(this == sStaticTopFrame, @@ -692,6 +701,8 @@ MessageChannel::NotifyGeckoEventDispatch() void MessageChannel::ProcessNativeEventsInInterruptCall() { + NS_ASSERTION(GetCurrentThreadId() == gUIThreadId, + "Shouldn't be on a non-main thread in here!"); if (!mTopFrame) { NS_ERROR("Spin logic error: no Interrupt frame"); return; @@ -775,6 +786,10 @@ MessageChannel::WaitForSyncNotify() MOZ_ASSERT(gUIThreadId, "InitUIThread was not called!"); + // We jump through a lot of unique hoops in dealing with Windows message + // trapping to prevent re-entrancy when we are blocked waiting on a sync + // reply or new rpc in-call. However none of this overhead is needed when + // we aren't on the main (gui) thread. if (GetCurrentThreadId() != gUIThreadId) { PRIntervalTime timeout = (kNoTimeout == mTimeoutMs) ? PR_INTERVAL_NO_TIMEOUT : @@ -795,9 +810,13 @@ MessageChannel::WaitForSyncNotify() // If the timeout didn't expire, we know we received an event. The // converse is not true. - return WaitResponse(timeout == PR_INTERVAL_NO_TIMEOUT ? false : IsTimeoutExpired(waitStart, timeout)); + return WaitResponse(timeout == PR_INTERVAL_NO_TIMEOUT ? + false : IsTimeoutExpired(waitStart, timeout)); } + NS_ASSERTION(GetCurrentThreadId() == gUIThreadId, + "Shouldn't be on a non-main thread in here!"); + NS_ASSERTION(mTopFrame && !mTopFrame->mInterrupt, "Top frame is not a sync frame!"); @@ -919,10 +938,16 @@ MessageChannel::WaitForInterruptNotify() MOZ_ASSERT(gUIThreadId, "InitUIThread was not called!"); + // Re-use sync notification wait code when we aren't on the + // gui thread, which bypasses the gui thread hoops we jump + // through in dealing with Windows messaging. if (GetCurrentThreadId() != gUIThreadId) { return WaitForSyncNotify(); } + NS_ASSERTION(GetCurrentThreadId() == gUIThreadId, + "Shouldn't be on a non-main thread in here!"); + if (!InterruptStackDepth()) { // There is currently no way to recover from this condition. NS_RUNTIMEABORT("StackDepth() is 0 in call to MessageChannel::WaitForNotify!"); diff --git a/ipc/keystore/KeyStore.cpp b/ipc/keystore/KeyStore.cpp index 460c483be349..c5f01d592d25 100644 --- a/ipc/keystore/KeyStore.cpp +++ b/ipc/keystore/KeyStore.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=4 ts=8 et ft=cpp: */ /* 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 @@ -359,10 +359,16 @@ KeyStoreConnector::GetSocketAddr(const sockaddr_any& aAddr, KeyStore::KeyStore() { + MOZ_COUNT_CTOR(KeyStore); ::startKeyStoreService(); Listen(); } +KeyStore::~KeyStore() +{ + MOZ_COUNT_DTOR(KeyStore); +} + void KeyStore::Shutdown() { diff --git a/ipc/keystore/KeyStore.h b/ipc/keystore/KeyStore.h index a11caddc01db..028e0ff9a6c7 100644 --- a/ipc/keystore/KeyStore.h +++ b/ipc/keystore/KeyStore.h @@ -98,11 +98,12 @@ class KeyStore : public mozilla::ipc::UnixSocketConsumer { public: KeyStore(); - virtual ~KeyStore() {} void Shutdown(); private: + virtual ~KeyStore(); + virtual void ReceiveSocketData(nsAutoPtr& aMessage); virtual void OnConnectSuccess(); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 5faf05de8854..db74730e29e8 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3215,8 +3215,8 @@ ReallocateElements(ThreadSafeContext *cx, JSObject *obj, ObjectElements *oldHead oldCount, newCount)); } -// Round up |count| to one of our standard slot counts. Up to 1 mebislot (i.e. -// 1,048,576 slots) the slot count is always a power-of-two: +// Round up |reqAllocated| to a good size. Up to 1 Mebi (i.e. 1,048,576) the +// slot count is usually a power-of-two: // // 8, 16, 32, 64, ..., 256 Ki, 512 Ki, 1 Mi // @@ -3230,11 +3230,46 @@ ReallocateElements(ThreadSafeContext *cx, JSObject *obj, ObjectElements *oldHead // Having the second class means that for bigger arrays the constant factor is // higher, but we waste less space. // +// There are two exceptions to the above rules. Both exceptions optimize for +// cases where the requested capacity is near the array's length. +// +// - If |reqAllocated| would give us a capacity equal to |length|, it's +// probably due to code like this: +// +// var a = new Array(1024); +// +// 1024 is smaller than |EagerAllocationMaxLength|, so the array elements +// are allocated immediately. This is likely to be the final size of the +// array, so we just allocate the exact length immediately. In this case, the +// capacity is 1024 and |goodAllocated| is 1026. +// +// - If the |goodAllocated| value we compute gives a capacity slightly smaller +// than |length|, we nudge |goodAllocated| up so that the capacity equals the +// length. Consider the following code, which is very much like some code +// that appears in the Kraken benchmark suite: +// +// var a = new Array(8192); +// for (var i = 0; i < 8192; i++) { a[i] = i; } +// +// 8192 is larger than |EagerAllocationMaxLength|, so the elements will be +// resized up to the final size rather than allocated immediately. Without +// this exception, it would be repeatedly resized and |goodAllocated| would +// reach 8192, which gives a capacity of 8190, which isn't quite enough, so +// it would then be have to be resized one more time to 16382 elements, +// wasting time and memory. But with the exception, the final resizing is +// nudged, resulting in a capacity of 8192 and |goodAllocated| value of 8194. +// /* static */ uint32_t JSObject::goodAllocated(uint32_t reqAllocated, uint32_t length = 0) { static const uint32_t Mebi = 1024 * 1024; + uint32_t reqCapacity = reqAllocated - ObjectElements::VALUES_PER_HEADER; + if (reqCapacity == length && reqAllocated >= JSObject::SLOT_CAPACITY_MIN) { + // This is the first exception mentioned above. + return length + ObjectElements::VALUES_PER_HEADER; + } + // This table was generated with this JavaScript code and a small amount // subsequent reformatting: // @@ -3280,26 +3315,10 @@ JSObject::goodAllocated(uint32_t reqAllocated, uint32_t length = 0) } } - // |goodAllocated| is typically a power-of-two, e.g. 8192, which gives us a - // capacity of 8190. This leads to bad behaviour if the user code uses - // array lengths that are powers of two. For example, code very much like - // this appears in the Kraken benchmark suite: - // - // var a = new Array(8192); - // for (var i = 0; i < 8192; i++) { a[i] = i; } - // - // The array will be repeatedly resized up to a capacity of 8190, which - // isn't quite enough, so it'll be resized one more time to 16382. - // - // So if the capacity that |goodAllocated| would have given us is slightly - // smaller than |length|, we nudge |goodAllocated| up so that the capacity - // equals the length. This results in some slop, but the amount wasted is - // equal to or (more commonly) smaller than the size increase we'd get from - // re-doubling, and we don't have to pay the cost of re-doubling. - // - uint32_t capacity = goodAllocated - ObjectElements::VALUES_PER_HEADER; - if (length > capacity && (length - capacity) < 16) { - goodAllocated = length + ObjectElements::VALUES_PER_HEADER; + uint32_t goodCapacity = goodAllocated - ObjectElements::VALUES_PER_HEADER; + if (length > goodCapacity && (length - goodCapacity) < 16) { + // This is the second exception mentioned above. + return length + ObjectElements::VALUES_PER_HEADER; } return goodAllocated; diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index efd060ba42c2..59e28994dd16 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -309,9 +309,9 @@ ReportOnCaller(JSCLContextHelper &helper, mozJSComponentLoader::mozJSComponentLoader() : mRuntime(nullptr), mContext(nullptr), - mModules(32), - mImports(32), - mInProgressImports(32), + mModules(16), + mImports(16), + mInProgressImports(16), mInitialized(false), mReuseLoaderGlobal(false) { diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 7e331c5edd9f..166a8f0694ed 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -3114,15 +3114,15 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) mAutoRoots(nullptr), mResolveName(JSID_VOID), mResolvingWrapper(nullptr), - mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)), - mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_SIZE)), - mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_SIZE)), - mClassInfo2NativeSetMap(ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_SIZE)), - mNativeSetMap(NativeSetMap::newMap(XPC_NATIVE_SET_MAP_SIZE)), - mThisTranslatorMap(IID2ThisTranslatorMap::newMap(XPC_THIS_TRANSLATOR_MAP_SIZE)), - mNativeScriptableSharedMap(XPCNativeScriptableSharedMap::newMap(XPC_NATIVE_JSCLASS_MAP_SIZE)), - mDyingWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DYING_NATIVE_PROTO_MAP_SIZE)), - mDetachedWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DETACHED_NATIVE_PROTO_MAP_SIZE)), + mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH)), + mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_LENGTH)), + mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_LENGTH)), + mClassInfo2NativeSetMap(ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH)), + mNativeSetMap(NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH)), + mThisTranslatorMap(IID2ThisTranslatorMap::newMap(XPC_THIS_TRANSLATOR_MAP_LENGTH)), + mNativeScriptableSharedMap(XPCNativeScriptableSharedMap::newMap(XPC_NATIVE_JSCLASS_MAP_LENGTH)), + mDyingWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DYING_NATIVE_PROTO_MAP_LENGTH)), + mDetachedWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DETACHED_NATIVE_PROTO_MAP_LENGTH)), mGCIsRunning(false), mWrappedJSToReleaseArray(), mNativesToReleaseArray(), diff --git a/js/xpconnect/src/XPCMaps.cpp b/js/xpconnect/src/XPCMaps.cpp index 32b628674cb5..695bac411334 100644 --- a/js/xpconnect/src/XPCMaps.cpp +++ b/js/xpconnect/src/XPCMaps.cpp @@ -116,9 +116,9 @@ JSObject2WrappedJSMap::ShutdownMarker() // static Native2WrappedNativeMap* -Native2WrappedNativeMap::newMap(int size) +Native2WrappedNativeMap::newMap(int length) { - Native2WrappedNativeMap* map = new Native2WrappedNativeMap(size); + Native2WrappedNativeMap* map = new Native2WrappedNativeMap(length); if (map && map->mTable) return map; // Allocation of the map or the creation of its hash table has @@ -129,10 +129,10 @@ Native2WrappedNativeMap::newMap(int size) return nullptr; } -Native2WrappedNativeMap::Native2WrappedNativeMap(int size) +Native2WrappedNativeMap::Native2WrappedNativeMap(int length) { mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, - sizeof(Entry), size); + sizeof(Entry), length); } Native2WrappedNativeMap::~Native2WrappedNativeMap() @@ -173,18 +173,18 @@ const struct PLDHashTableOps IID2WrappedJSClassMap::Entry::sOps = // static IID2WrappedJSClassMap* -IID2WrappedJSClassMap::newMap(int size) +IID2WrappedJSClassMap::newMap(int length) { - IID2WrappedJSClassMap* map = new IID2WrappedJSClassMap(size); + IID2WrappedJSClassMap* map = new IID2WrappedJSClassMap(length); if (map && map->mTable) return map; delete map; return nullptr; } -IID2WrappedJSClassMap::IID2WrappedJSClassMap(int size) +IID2WrappedJSClassMap::IID2WrappedJSClassMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), length); } IID2WrappedJSClassMap::~IID2WrappedJSClassMap() @@ -210,18 +210,18 @@ const struct PLDHashTableOps IID2NativeInterfaceMap::Entry::sOps = // static IID2NativeInterfaceMap* -IID2NativeInterfaceMap::newMap(int size) +IID2NativeInterfaceMap::newMap(int length) { - IID2NativeInterfaceMap* map = new IID2NativeInterfaceMap(size); + IID2NativeInterfaceMap* map = new IID2NativeInterfaceMap(length); if (map && map->mTable) return map; delete map; return nullptr; } -IID2NativeInterfaceMap::IID2NativeInterfaceMap(int size) +IID2NativeInterfaceMap::IID2NativeInterfaceMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), length); } IID2NativeInterfaceMap::~IID2NativeInterfaceMap() @@ -252,19 +252,19 @@ IID2NativeInterfaceMap::SizeOfEntryExcludingThis(PLDHashEntryHdr *hdr, // static ClassInfo2NativeSetMap* -ClassInfo2NativeSetMap::newMap(int size) +ClassInfo2NativeSetMap::newMap(int length) { - ClassInfo2NativeSetMap* map = new ClassInfo2NativeSetMap(size); + ClassInfo2NativeSetMap* map = new ClassInfo2NativeSetMap(length); if (map && map->mTable) return map; delete map; return nullptr; } -ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int size) +ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int length) { mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, - sizeof(Entry), size); + sizeof(Entry), length); } ClassInfo2NativeSetMap::~ClassInfo2NativeSetMap() @@ -288,9 +288,9 @@ ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocS // static ClassInfo2WrappedNativeProtoMap* -ClassInfo2WrappedNativeProtoMap::newMap(int size) +ClassInfo2WrappedNativeProtoMap::newMap(int length) { - ClassInfo2WrappedNativeProtoMap* map = new ClassInfo2WrappedNativeProtoMap(size); + ClassInfo2WrappedNativeProtoMap* map = new ClassInfo2WrappedNativeProtoMap(length); if (map && map->mTable) return map; // Allocation of the map or the creation of its hash table has @@ -301,10 +301,10 @@ ClassInfo2WrappedNativeProtoMap::newMap(int size) return nullptr; } -ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int size) +ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int length) { mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, - sizeof(Entry), size); + sizeof(Entry), length); } ClassInfo2WrappedNativeProtoMap::~ClassInfo2WrappedNativeProtoMap() @@ -417,18 +417,18 @@ const struct PLDHashTableOps NativeSetMap::Entry::sOps = // static NativeSetMap* -NativeSetMap::newMap(int size) +NativeSetMap::newMap(int length) { - NativeSetMap* map = new NativeSetMap(size); + NativeSetMap* map = new NativeSetMap(length); if (map && map->mTable) return map; delete map; return nullptr; } -NativeSetMap::NativeSetMap(int size) +NativeSetMap::NativeSetMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), length); } NativeSetMap::~NativeSetMap() @@ -484,18 +484,18 @@ const struct PLDHashTableOps IID2ThisTranslatorMap::Entry::sOps = // static IID2ThisTranslatorMap* -IID2ThisTranslatorMap::newMap(int size) +IID2ThisTranslatorMap::newMap(int length) { - IID2ThisTranslatorMap* map = new IID2ThisTranslatorMap(size); + IID2ThisTranslatorMap* map = new IID2ThisTranslatorMap(length); if (map && map->mTable) return map; delete map; return nullptr; } -IID2ThisTranslatorMap::IID2ThisTranslatorMap(int size) +IID2ThisTranslatorMap::IID2ThisTranslatorMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), length); } IID2ThisTranslatorMap::~IID2ThisTranslatorMap() @@ -564,19 +564,19 @@ const struct PLDHashTableOps XPCNativeScriptableSharedMap::Entry::sOps = // static XPCNativeScriptableSharedMap* -XPCNativeScriptableSharedMap::newMap(int size) +XPCNativeScriptableSharedMap::newMap(int length) { XPCNativeScriptableSharedMap* map = - new XPCNativeScriptableSharedMap(size); + new XPCNativeScriptableSharedMap(length); if (map && map->mTable) return map; delete map; return nullptr; } -XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int size) +XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int length) { - mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), length); } XPCNativeScriptableSharedMap::~XPCNativeScriptableSharedMap() @@ -619,19 +619,19 @@ XPCNativeScriptableSharedMap::GetNewOrUsed(uint32_t flags, // static XPCWrappedNativeProtoMap* -XPCWrappedNativeProtoMap::newMap(int size) +XPCWrappedNativeProtoMap::newMap(int length) { - XPCWrappedNativeProtoMap* map = new XPCWrappedNativeProtoMap(size); + XPCWrappedNativeProtoMap* map = new XPCWrappedNativeProtoMap(length); if (map && map->mTable) return map; delete map; return nullptr; } -XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int size) +XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int length) { mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, - sizeof(PLDHashEntryStub), size); + sizeof(PLDHashEntryStub), length); } XPCWrappedNativeProtoMap::~XPCWrappedNativeProtoMap() diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 35838766d7f9..9464d73ba12a 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -30,9 +30,9 @@ class JSObject2WrappedJSMap js::SystemAllocPolicy> Map; public: - static JSObject2WrappedJSMap* newMap(int size) { + static JSObject2WrappedJSMap* newMap(int length) { JSObject2WrappedJSMap* map = new JSObject2WrappedJSMap(); - if (map && map->mTable.init(size)) + if (map && map->mTable.init(length)) return map; delete map; return nullptr; @@ -106,7 +106,7 @@ public: XPCWrappedNative* value; }; - static Native2WrappedNativeMap* newMap(int size); + static Native2WrappedNativeMap* newMap(int length); inline XPCWrappedNative* Find(nsISupports* Obj) { @@ -177,7 +177,7 @@ public: static const struct PLDHashTableOps sOps; }; - static IID2WrappedJSClassMap* newMap(int size); + static IID2WrappedJSClassMap* newMap(int length); inline nsXPCWrappedJSClass* Find(REFNSIID iid) { @@ -234,7 +234,7 @@ public: static const struct PLDHashTableOps sOps; }; - static IID2NativeInterfaceMap* newMap(int size); + static IID2NativeInterfaceMap* newMap(int length); inline XPCNativeInterface* Find(REFNSIID iid) { @@ -294,7 +294,7 @@ public: XPCNativeSet* value; }; - static ClassInfo2NativeSetMap* newMap(int size); + static ClassInfo2NativeSetMap* newMap(int length); inline XPCNativeSet* Find(nsIClassInfo* info) { @@ -354,7 +354,7 @@ public: XPCWrappedNativeProto* value; }; - static ClassInfo2WrappedNativeProtoMap* newMap(int size); + static ClassInfo2WrappedNativeProtoMap* newMap(int length); inline XPCWrappedNativeProto* Find(nsIClassInfo* info) { @@ -419,7 +419,7 @@ public: static const struct PLDHashTableOps sOps; }; - static NativeSetMap* newMap(int size); + static NativeSetMap* newMap(int length); inline XPCNativeSet* Find(XPCNativeSetKey* key) { @@ -496,7 +496,7 @@ public: static const struct PLDHashTableOps sOps; }; - static IID2ThisTranslatorMap* newMap(int size); + static IID2ThisTranslatorMap* newMap(int length); inline nsIXPCFunctionThisTranslator* Find(REFNSIID iid) { @@ -557,7 +557,7 @@ public: static const struct PLDHashTableOps sOps; }; - static XPCNativeScriptableSharedMap* newMap(int size); + static XPCNativeScriptableSharedMap* newMap(int length); bool GetNewOrUsed(uint32_t flags, char* name, uint32_t interfacesBitmap, XPCNativeScriptableInfo* si); @@ -579,7 +579,7 @@ private: class XPCWrappedNativeProtoMap { public: - static XPCWrappedNativeProtoMap* newMap(int size); + static XPCWrappedNativeProtoMap* newMap(int length); inline XPCWrappedNativeProto* Add(XPCWrappedNativeProto* proto) { @@ -620,9 +620,9 @@ class JSObject2JSObjectMap js::SystemAllocPolicy> Map; public: - static JSObject2JSObjectMap* newMap(int size) { + static JSObject2JSObjectMap* newMap(int length) { JSObject2JSObjectMap* map = new JSObject2JSObjectMap(); - if (map && map->mTable.init(size)) + if (map && map->mTable.init(length)) return map; delete map; return nullptr; diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index d2db11d6acd2..2c85c40f2da3 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -77,8 +77,8 @@ RemoteXULForbidsXBLScope(nsIPrincipal *aPrincipal, HandleObject aGlobal) XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext *cx, JS::HandleObject aGlobal) - : mWrappedNativeMap(Native2WrappedNativeMap::newMap(XPC_NATIVE_MAP_SIZE)), - mWrappedNativeProtoMap(ClassInfo2WrappedNativeProtoMap::newMap(XPC_NATIVE_PROTO_MAP_SIZE)), + : mWrappedNativeMap(Native2WrappedNativeMap::newMap(XPC_NATIVE_MAP_LENGTH)), + mWrappedNativeProtoMap(ClassInfo2WrappedNativeProtoMap::newMap(XPC_NATIVE_PROTO_MAP_LENGTH)), mComponents(nullptr), mNext(nullptr), mGlobalJSObject(aGlobal), diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 8c6767112f0b..ff5729419cad 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -175,20 +175,20 @@ /***************************************************************************/ // default initial sizes for maps (hashtables) -#define XPC_CONTEXT_MAP_SIZE 16 -#define XPC_JS_MAP_SIZE 64 -#define XPC_JS_CLASS_MAP_SIZE 64 +#define XPC_CONTEXT_MAP_LENGTH 8 +#define XPC_JS_MAP_LENGTH 32 +#define XPC_JS_CLASS_MAP_LENGTH 32 -#define XPC_NATIVE_MAP_SIZE 64 -#define XPC_NATIVE_PROTO_MAP_SIZE 16 -#define XPC_DYING_NATIVE_PROTO_MAP_SIZE 16 -#define XPC_DETACHED_NATIVE_PROTO_MAP_SIZE 32 -#define XPC_NATIVE_INTERFACE_MAP_SIZE 64 -#define XPC_NATIVE_SET_MAP_SIZE 64 -#define XPC_NATIVE_JSCLASS_MAP_SIZE 32 -#define XPC_THIS_TRANSLATOR_MAP_SIZE 8 -#define XPC_NATIVE_WRAPPER_MAP_SIZE 16 -#define XPC_WRAPPER_MAP_SIZE 16 +#define XPC_NATIVE_MAP_LENGTH 32 +#define XPC_NATIVE_PROTO_MAP_LENGTH 8 +#define XPC_DYING_NATIVE_PROTO_MAP_LENGTH 8 +#define XPC_DETACHED_NATIVE_PROTO_MAP_LENGTH 16 +#define XPC_NATIVE_INTERFACE_MAP_LENGTH 32 +#define XPC_NATIVE_SET_MAP_LENGTH 32 +#define XPC_NATIVE_JSCLASS_MAP_LENGTH 16 +#define XPC_THIS_TRANSLATOR_MAP_LENGTH 4 +#define XPC_NATIVE_WRAPPER_MAP_LENGTH 8 +#define XPC_WRAPPER_MAP_LENGTH 8 /***************************************************************************/ // data declarations... diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index b4298539f8fa..3267bed23dc0 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -86,7 +86,7 @@ WrapperFactory::CreateXrayWaiver(JSContext *cx, HandleObject obj) // one waiver for the lifetime of the target object. if (!scope->mWaiverWrapperMap) { scope->mWaiverWrapperMap = - JSObject2JSObjectMap::newMap(XPC_WRAPPER_MAP_SIZE); + JSObject2JSObjectMap::newMap(XPC_WRAPPER_MAP_LENGTH); MOZ_ASSERT(scope->mWaiverWrapperMap); } if (!scope->mWaiverWrapperMap->Add(cx, obj, waiver)) diff --git a/layout/base/DisplayListClipState.h b/layout/base/DisplayListClipState.h index 39630d7f9fcc..cd29d2dde721 100644 --- a/layout/base/DisplayListClipState.h +++ b/layout/base/DisplayListClipState.h @@ -131,7 +131,7 @@ private: */ class DisplayListClipState::AutoSaveRestore { public: - AutoSaveRestore(nsDisplayListBuilder* aBuilder); + explicit AutoSaveRestore(nsDisplayListBuilder* aBuilder); void Restore() { mState = mSavedState; @@ -227,7 +227,7 @@ public: */ class DisplayListClipState::AutoClipMultiple : public AutoSaveRestore { public: - AutoClipMultiple(nsDisplayListBuilder* aBuilder) + explicit AutoClipMultiple(nsDisplayListBuilder* aBuilder) : AutoSaveRestore(aBuilder) , mExtraClipUsed(false) {} diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index b3f2b88a329b..1db33c9ed62b 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -595,7 +595,7 @@ protected: public: class ThebesLayerItemsEntry : public nsPtrHashKey { public: - ThebesLayerItemsEntry(const ThebesLayer *key) + explicit ThebesLayerItemsEntry(const ThebesLayer *key) : nsPtrHashKey(key) , mContainerLayerFrame(nullptr) , mLastCommonClipCount(0) diff --git a/layout/base/FramePropertyTable.h b/layout/base/FramePropertyTable.h index b8bf6c7dcee4..739115b35c31 100644 --- a/layout/base/FramePropertyTable.h +++ b/layout/base/FramePropertyTable.h @@ -192,7 +192,7 @@ protected: class Entry : public nsPtrHashKey { public: - Entry(KeyTypePointer aKey) : nsPtrHashKey(aKey) {} + explicit Entry(KeyTypePointer aKey) : nsPtrHashKey(aKey) {} Entry(const Entry &toCopy) : nsPtrHashKey(toCopy), mProp(toCopy.mProp) {} diff --git a/layout/base/nsCounterManager.cpp b/layout/base/nsCounterManager.cpp index 3865bfff327f..c4e81f3a168d 100644 --- a/layout/base/nsCounterManager.cpp +++ b/layout/base/nsCounterManager.cpp @@ -199,7 +199,7 @@ nsCounterList::RecalcAll() } nsCounterManager::nsCounterManager() - : mNames(16) + : mNames() { } diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index db4bc9dc2266..8fedee235f9d 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -832,12 +832,13 @@ static void RecordFrameMetrics(nsIFrame* aForFrame, // Also compute and set the background color on the container. // This is needed for APZ overscrolling support. if (aScrollFrame) { - // FindBackground() does not work for a root scroll frame, need to use the - // root frame instead. - nsIFrame* backgroundFrame = isRootScrollFrame ? presShell->GetRootFrame() : aScrollFrame; - nsStyleContext* backgroundStyle; - if (nsCSSRendering::FindBackground(backgroundFrame, &backgroundStyle)) { - aRoot->SetBackgroundColor(backgroundStyle->StyleBackground()->mBackgroundColor); + if (isRootScrollFrame) { + aRoot->SetBackgroundColor(presShell->GetCanvasBackground()); + } else { + nsStyleContext* backgroundStyle; + if (nsCSSRendering::FindBackground(aScrollFrame, &backgroundStyle)) { + aRoot->SetBackgroundColor(backgroundStyle->StyleBackground()->mBackgroundColor); + } } } } @@ -3005,7 +3006,8 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mToReferenceFrame = i->ToReferenceFrame(); } } - mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame; + mVisibleRect = aBuilder->GetDirtyRect() + + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, @@ -3034,7 +3036,8 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mToReferenceFrame = aItem->ToReferenceFrame(); } } - mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame; + mVisibleRect = aBuilder->GetDirtyRect() + + aBuilder->GetCurrentFrameOffsetToReferenceFrame(); } nsDisplayWrapList::~nsDisplayWrapList() { diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 8f275e39eb73..8121a7ef47a8 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -533,6 +533,10 @@ public: void SetDirtyRect(const nsRect& aRect) { mBuilder->mDirtyRect = aRect; } + void SetReferenceFrameAndCurrentOffset(const nsIFrame* aFrame, const nsPoint& aOffset) { + mBuilder->mCurrentReferenceFrame = aFrame; + mBuilder->mCurrentOffsetToReferenceFrame = aOffset; + } ~AutoBuildingDisplayList() { mBuilder->mCurrentFrame = mPrevFrame; mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame; @@ -624,7 +628,7 @@ public: : mContainingBlockClip(aContainingBlockClip) , mDirtyRect(aDirtyRect) {} - OutOfFlowDisplayData(const nsRect &aDirtyRect) + explicit OutOfFlowDisplayData(const nsRect &aDirtyRect) : mDirtyRect(aDirtyRect) {} DisplayItemClip mContainingBlockClip; @@ -808,7 +812,7 @@ public: * This constructor is only used in rare cases when we need to construct * temporary items. */ - nsDisplayItem(nsIFrame* aFrame) + explicit nsDisplayItem(nsIFrame* aFrame) : mFrame(aFrame) , mClip(nullptr) , mReferenceFrame(nullptr) @@ -830,7 +834,7 @@ public: struct HitTestState { typedef nsTArray ShadowArray; - HitTestState(ShadowArray* aShadows = nullptr) + explicit HitTestState(ShadowArray* aShadows = nullptr) : mShadows(aShadows) { } @@ -1744,7 +1748,7 @@ struct nsDisplayListCollection : public nsDisplayListSet { nsDisplayListCollection() : nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4], &mLists[5]) {} - nsDisplayListCollection(nsDisplayList* aBorderBackground) : + explicit nsDisplayListCollection(nsDisplayList* aBorderBackground) : nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4], &mLists[5]) {} @@ -3412,7 +3416,7 @@ public: nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : nsDisplayItem(aBuilder, aFrame), mLeftEdge(0), mRightEdge(0) {} - nsCharClipDisplayItem(nsIFrame* aFrame) + explicit nsCharClipDisplayItem(nsIFrame* aFrame) : nsDisplayItem(aFrame) {} struct ClipEdges { diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 92e254b6c7d7..98dd7993085c 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -427,7 +427,7 @@ protected: class nsPrintEventDispatcher { public: - nsPrintEventDispatcher(nsIDocument* aTop) : mTop(aTop) + explicit nsPrintEventDispatcher(nsIDocument* aTop) : mTop(aTop) { nsDocumentViewer::DispatchBeforePrint(mTop); } @@ -442,7 +442,7 @@ public: class nsDocumentShownDispatcher : public nsRunnable { public: - nsDocumentShownDispatcher(nsCOMPtr aDocument) + explicit nsDocumentShownDispatcher(nsCOMPtr aDocument) : mDocument(aDocument) {} NS_IMETHOD Run() MOZ_OVERRIDE; diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index 3ac3d6470a11..de59a69bdb27 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -171,7 +171,7 @@ nsFrameManager::RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame) "unexpected frame type"); if (!mPlaceholderMap.ops) { PL_DHashTableInit(&mPlaceholderMap, &PlaceholderMapOps, nullptr, - sizeof(PlaceholderMapEntry), 16); + sizeof(PlaceholderMapEntry)); } PlaceholderMapEntry *entry = static_cast(PL_DHashTableOperate(&mPlaceholderMap, aPlaceholderFrame->GetOutOfFlowFrame(), diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 22767a09fce1..10df929885f3 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -654,9 +654,9 @@ public: * no scrollbar showing and less than one device pixel of * scrollable distance), don't scroll. Defaults to false. */ - ScrollAxis(int16_t aWhere = SCROLL_MINIMUM, - WhenToScroll aWhen = SCROLL_IF_NOT_FULLY_VISIBLE, - bool aOnlyIfPerceivedScrollableDirection = false) : + explicit ScrollAxis(int16_t aWhere = SCROLL_MINIMUM, + WhenToScroll aWhen = SCROLL_IF_NOT_FULLY_VISIBLE, + bool aOnlyIfPerceivedScrollableDirection = false) : mWhereToScroll(aWhere), mWhenToScroll(aWhen), mOnlyIfPerceivedScrollableDirection(aOnlyIfPerceivedScrollableDirection) {} diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index da1a91abe622..850fa99d094a 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -69,6 +69,7 @@ #include "SVGTextFrame.h" #include "nsStyleStructInlines.h" #include "nsStyleTransformMatrix.h" +#include "nsStyleUtil.h" #include "nsIFrameInlines.h" #include "ImageContainer.h" #include "nsComputedDOMStyle.h" @@ -4195,8 +4196,8 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions( if (isFlexItem) { // Flex items use their "flex-basis" property in place of their main-size // property (e.g. "width") for sizing purposes, *unless* they have - // "flex-basis:auto", in which case they use their main-size property after - // all. + // "flex-basis:main-size", in which case they use their main-size property + // after all. uint32_t flexDirection = aFrame->GetParent()->StylePosition()->mFlexDirection; isHorizontalFlexItem = @@ -4206,21 +4207,8 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions( // NOTE: The logic here should match the similar chunk for determining // widthStyleCoord and heightStyleCoord in nsFrame::ComputeSize(). const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis); - if (flexBasis->GetUnit() != eStyleUnit_Auto) { - if (isHorizontalFlexItem) { - widthStyleCoord = flexBasis; - } else { - // One caveat for vertical flex items: We don't support enumerated - // values (e.g. "max-content") for height properties yet. So, if our - // computed flex-basis is an enumerated value, we'll just behave as if - // it were "auto", which means "use the main-size property after all" - // (which is "height", in this case). - // NOTE: Once we support intrinsic sizing keywords for "height", - // we should remove this check. - if (flexBasis->GetUnit() != eStyleUnit_Enumerated) { - heightStyleCoord = flexBasis; - } - } + if (!nsStyleUtil::IsFlexBasisMainSize(*flexBasis, isHorizontalFlexItem)) { + (isHorizontalFlexItem ? widthStyleCoord : heightStyleCoord) = flexBasis; } } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index e4034e905ad6..83d55b93a131 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -1000,7 +1000,7 @@ public: struct RectListBuilder : public RectCallback { DOMRectList* mRectList; - RectListBuilder(DOMRectList* aList); + explicit RectListBuilder(DOMRectList* aList); virtual void AddRect(const nsRect& aRect); }; @@ -2346,7 +2346,7 @@ namespace mozilla { */ class AutoMaybeDisableFontInflation { public: - AutoMaybeDisableFontInflation(nsIFrame *aFrame); + explicit AutoMaybeDisableFontInflation(nsIFrame *aFrame); ~AutoMaybeDisableFontInflation(); private: diff --git a/layout/base/nsPresArena.h b/layout/base/nsPresArena.h index 4b667b9eb771..fd44497379ac 100644 --- a/layout/base/nsPresArena.h +++ b/layout/base/nsPresArena.h @@ -118,7 +118,7 @@ private: typedef const void* KeyTypePointer; KeyTypePointer mKey; - FreeList(KeyTypePointer aKey) + explicit FreeList(KeyTypePointer aKey) : mEntrySize(0), mEntriesEverAllocated(0), mKey(aKey) {} // Default copy constructor and destructor are ok. diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 5ac784adc4f4..2cef783198ba 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -937,7 +937,7 @@ public: friend class InterruptPreventer; class MOZ_STACK_CLASS InterruptPreventer { public: - InterruptPreventer(nsPresContext* aCtx) : + explicit InterruptPreventer(nsPresContext* aCtx) : mCtx(aCtx), mInterruptsEnabled(aCtx->mInterruptsEnabled), mHasPendingInterrupt(aCtx->mHasPendingInterrupt) @@ -1492,7 +1492,7 @@ protected: class RunWillPaintObservers : public nsRunnable { public: - RunWillPaintObservers(nsRootPresContext* aPresContext) : mPresContext(aPresContext) {} + explicit RunWillPaintObservers(nsRootPresContext* aPresContext) : mPresContext(aPresContext) {} void Revoke() { mPresContext = nullptr; } NS_IMETHOD Run() MOZ_OVERRIDE { diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index b0e60152b64b..61b058327348 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6983,12 +6983,16 @@ PresShell::HandleEvent(nsIFrame* aFrame, nsIDocument::UnlockPointer(); } + nsWeakFrame weakFrame(frame); { // scope for scriptBlocker. nsAutoScriptBlocker scriptBlocker; GetRootPresShell()->GetDocument()-> EnumerateSubDocuments(FlushThrottledStyles, nullptr); } - frame = GetNearestFrameContainingPresShell(this); + + if (!weakFrame.IsAlive()) { + frame = GetNearestFrameContainingPresShell(this); + } } NS_WARN_IF_FALSE(frame, "Nothing to handle this event!"); diff --git a/layout/base/nsRefreshDriver.h b/layout/base/nsRefreshDriver.h index 5c51df7b7e2e..8de27d5133ec 100644 --- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -66,7 +66,7 @@ public: class nsRefreshDriver MOZ_FINAL : public mozilla::layers::TransactionIdAllocator, public nsARefreshObserver { public: - nsRefreshDriver(nsPresContext *aPresContext); + explicit nsRefreshDriver(nsPresContext *aPresContext); ~nsRefreshDriver(); static void InitializeStatics(); diff --git a/layout/generic/FrameChildList.h b/layout/generic/FrameChildList.h index 7bf6ba29c9c1..34bce1e1f4e7 100644 --- a/layout/generic/FrameChildList.h +++ b/layout/generic/FrameChildList.h @@ -26,7 +26,7 @@ friend class FrameChildListIterator; public: FrameChildListIDs() : mIDs(0) {} FrameChildListIDs(const FrameChildListIDs& aOther) : mIDs(aOther.mIDs) {} - FrameChildListIDs(FrameChildListID aListID) : mIDs(aListID) {} + MOZ_IMPLICIT FrameChildListIDs(FrameChildListID aListID) : mIDs(aListID) {} FrameChildListIDs operator|(FrameChildListIDs aOther) const { return FrameChildListIDs(mIDs | aOther.mIDs); @@ -46,7 +46,7 @@ friend class FrameChildListIterator; } protected: - FrameChildListIDs(uint32_t aIDs) : mIDs(aIDs) {} + explicit FrameChildListIDs(uint32_t aIDs) : mIDs(aIDs) {} uint32_t mIDs; }; @@ -63,7 +63,7 @@ class FrameChildList { */ class MOZ_STACK_CLASS FrameChildListArrayIterator { public: - FrameChildListArrayIterator(const nsTArray& aLists) + explicit FrameChildListArrayIterator(const nsTArray& aLists) : mLists(aLists), mCurrentIndex(0) {} bool IsDone() const { return mCurrentIndex >= mLists.Length(); } FrameChildListID CurrentID() const { @@ -90,7 +90,7 @@ protected: class MOZ_STACK_CLASS FrameChildListIterator : public FrameChildListArrayIterator { public: - FrameChildListIterator(const nsIFrame* aFrame); + explicit FrameChildListIterator(const nsIFrame* aFrame); protected: nsAutoTArray mLists; diff --git a/layout/generic/Selection.h b/layout/generic/Selection.h index c0fe97c87917..03ef8f3da76d 100644 --- a/layout/generic/Selection.h +++ b/layout/generic/Selection.h @@ -30,7 +30,7 @@ class ErrorResult; struct RangeData { - RangeData(nsRange* aRange) + explicit RangeData(nsRange* aRange) : mRange(aRange) {} @@ -55,7 +55,7 @@ protected: public: Selection(); - Selection(nsFrameSelection *aList); + explicit Selection(nsFrameSelection *aList); NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Selection, nsISelectionPrivate) diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index 9693a04a8611..29d514f4aa69 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -573,8 +573,8 @@ TextOverflow::ProcessLine(const nsDisplayListSet& aLists, mLeft.mActive = mLeft.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP; mRight.Reset(); mRight.mActive = mRight.mStyle->mType != NS_STYLE_TEXT_OVERFLOW_CLIP; - - FrameHashtable framesToHide(100); + + FrameHashtable framesToHide(64); AlignmentEdges alignmentEdges; ExamineLineFrames(aLine, &framesToHide, &alignmentEdges); bool needLeft = mLeft.IsNeeded(); diff --git a/layout/generic/WritingModes.h b/layout/generic/WritingModes.h index 48208527eb92..40a8ab0f2f51 100644 --- a/layout/generic/WritingModes.h +++ b/layout/generic/WritingModes.h @@ -220,7 +220,7 @@ public: /** * Construct writing mode based on a style context */ - WritingMode(const nsStyleVisibility* aStyleVisibility) + explicit WritingMode(const nsStyleVisibility* aStyleVisibility) { NS_ASSERTION(aStyleVisibility, "we need an nsStyleVisibility here"); @@ -301,7 +301,7 @@ private: * Constructing a WritingMode with an arbitrary value is a private operation * currently only used by the Unknown() static method. */ - WritingMode(uint8_t aValue) + explicit WritingMode(uint8_t aValue) : mWritingMode(aValue) { } @@ -365,7 +365,7 @@ private: */ class LogicalPoint { public: - LogicalPoint(WritingMode aWritingMode) + explicit LogicalPoint(WritingMode aWritingMode) : #ifdef DEBUG mWritingMode(aWritingMode), @@ -569,7 +569,7 @@ private: */ class LogicalSize { public: - LogicalSize(WritingMode aWritingMode) + explicit LogicalSize(WritingMode aWritingMode) : #ifdef DEBUG mWritingMode(aWritingMode), @@ -734,7 +734,7 @@ private: */ class LogicalMargin { public: - LogicalMargin(WritingMode aWritingMode) + explicit LogicalMargin(WritingMode aWritingMode) : #ifdef DEBUG mWritingMode(aWritingMode), @@ -1020,7 +1020,7 @@ private: */ class LogicalRect { public: - LogicalRect(WritingMode aWritingMode) + explicit LogicalRect(WritingMode aWritingMode) : #ifdef DEBUG mWritingMode(aWritingMode), diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index d4be9e33ed06..2a9c61af17a1 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -421,7 +421,7 @@ public: NS_DECLARE_FRAME_PROPERTY_FRAMELIST(ExcessOverflowContainersProperty) protected: - nsContainerFrame(nsStyleContext* aContext) : nsSplittableFrame(aContext) {} + explicit nsContainerFrame(nsStyleContext* aContext) : nsSplittableFrame(aContext) {} ~nsContainerFrame(); /** diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 270e98462a81..1bf2815649ce 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -17,6 +17,7 @@ #include "nsPresContext.h" #include "nsRenderingContext.h" #include "nsStyleContext.h" +#include "nsStyleUtil.h" #include "prlog.h" #include #include "mozilla/LinkedList.h" @@ -571,7 +572,8 @@ protected: // These are non-const so that we can lazily update them with the item's // intrinsic size (obtained via a "measuring" reflow), when necessary. - // (e.g. for "flex-basis:auto;height:auto" & "min-height:auto") + // (e.g. if we have a vertical flex item with "flex-basis:auto", + // "flex-basis:main-size;height:auto", or "min-height:auto") nscoord mFlexBaseSize; nscoord mMainMinSize; nscoord mMainMaxSize; @@ -1166,10 +1168,10 @@ PartiallyResolveAutoMinSize(const FlexItem& aFlexItem, // from here, w/ std::min(). // We need the smallest of: - // * the used flex-basis, if the computed flex-basis was 'auto': - // XXXdholbert ('auto' might be renamed to 'main-size'; see bug 1032922) - if (eStyleUnit_Auto == - aItemReflowState.mStylePosition->mFlexBasis.GetUnit() && + // * the used flex-basis, if the computed flex-basis was 'main-size': + const nsStyleCoord& flexBasis = aItemReflowState.mStylePosition->mFlexBasis; + const bool isHorizontal = IsAxisHorizontal(aAxisTracker.GetMainAxis()); + if (nsStyleUtil::IsFlexBasisMainSize(flexBasis, isHorizontal) && aFlexItem.GetFlexBaseSize() != NS_AUTOHEIGHT) { // NOTE: We skip this if the flex base size depends on content & isn't yet // resolved. This is OK, because the caller is responsible for computing @@ -1223,7 +1225,7 @@ ResolveAutoFlexBasisFromRatio(FlexItem& aFlexItem, "Should only be called to resolve an 'auto' flex-basis"); // If the flex item has ... // - an intrinsic aspect ratio, - // - a [used] flex-basis of 'main-size' [auto?] [We have this, if we're here.] + // - a [used] flex-basis of 'main-size' [We have this, if we're here.] // - a definite cross size // then the flex base size is calculated from its inner cross size and the // flex item’s intrinsic aspect ratio. diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index f18b3e8e713d..18938f23fc07 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -26,6 +26,7 @@ #include "nsIScrollableFrame.h" #include "nsPresContext.h" #include "nsStyleConsts.h" +#include "nsStyleUtil.h" #include "nsIPresShell.h" #include "prlog.h" #include "prprf.h" @@ -1922,8 +1923,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, AutoSaveRestoreBlendMode autoRestoreBlendMode(*aBuilder); aBuilder->SetContainsBlendModes(BlendModeSet()); - nsPoint offsetToReferenceFrame = aBuilder->ToReferenceFrame(this); - if (isTransformed) { const nsRect overflow = GetVisualOverflowRectRelativeToSelf(); if (aBuilder->IsForPainting() && @@ -1934,10 +1933,9 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, return; } - dirtyRect += offsetToReferenceFrame; nsRect untransformedDirtyRect; if (nsDisplayTransform::UntransformRect(dirtyRect, overflow, this, - offsetToReferenceFrame, &untransformedDirtyRect)) { + nsPoint(0,0), &untransformedDirtyRect)) { dirtyRect = untransformedDirtyRect; } else { NS_WARNING("Unable to untransform dirty rect!"); @@ -2105,7 +2103,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, clipState.Restore(); // Revert to the dirtyrect coming in from the parent, without our transform // taken into account. - buildingDisplayList.SetDirtyRect(aDirtyRect + offsetToReferenceFrame); + buildingDisplayList.SetDirtyRect(aDirtyRect); + // Revert to the outer reference frame and offset because all display + // items we create from now on are outside the transform. + const nsIFrame* outerReferenceFrame = + aBuilder->FindReferenceFrameFor(nsLayoutUtils::GetTransformRootFrame(this)); + buildingDisplayList.SetReferenceFrameAndCurrentOffset(outerReferenceFrame, + GetOffsetToCrossDoc(outerReferenceFrame)); if (Preserves3DChildren()) { WrapPreserve3DList(this, aBuilder, &resultList); @@ -4057,8 +4061,8 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext, if (isFlexItem) { // Flex items use their "flex-basis" property in place of their main-size // property (e.g. "width") for sizing purposes, *unless* they have - // "flex-basis:auto", in which case they use their main-size property after - // all. + // "flex-basis:main-size", in which case they use their main-size property + // after all. uint32_t flexDirection = GetParent()->StylePosition()->mFlexDirection; isHorizontalFlexItem = flexDirection == NS_STYLE_FLEX_DIRECTION_ROW || @@ -4068,21 +4072,9 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext, // widthStyleCoord and heightStyleCoord in // nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(). const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis); - if (flexBasis->GetUnit() != eStyleUnit_Auto) { - if (isHorizontalFlexItem) { - widthStyleCoord = flexBasis; - } else { - // One caveat for vertical flex items: We don't support enumerated - // values (e.g. "max-content") for height properties yet. So, if our - // computed flex-basis is an enumerated value, we'll just behave as if - // it were "auto", which means "use the main-size property after all" - // (which is "height", in this case). - // NOTE: Once we support intrinsic sizing keywords for "height", - // we should remove this check. - if (flexBasis->GetUnit() != eStyleUnit_Enumerated) { - heightStyleCoord = flexBasis; - } - } + if (!nsStyleUtil::IsFlexBasisMainSize(*flexBasis, isHorizontalFlexItem)) { + (isHorizontalFlexItem ? + widthStyleCoord : heightStyleCoord) = flexBasis; } } diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index e61e0a1574fa..aef4767a8896 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -517,7 +517,7 @@ public: protected: // Protected constructor and destructor - nsFrame(nsStyleContext* aContext); + explicit nsFrame(nsStyleContext* aContext); virtual ~nsFrame(); /** @@ -751,7 +751,7 @@ public: }; struct DR_layout_cookie { - DR_layout_cookie(nsIFrame* aFrame); + explicit DR_layout_cookie(nsIFrame* aFrame); ~DR_layout_cookie(); nsIFrame* mFrame; diff --git a/layout/generic/nsFrameList.h b/layout/generic/nsFrameList.h index 904fd1b9f702..b89aaa6353f1 100644 --- a/layout/generic/nsFrameList.h +++ b/layout/generic/nsFrameList.h @@ -299,7 +299,7 @@ public: public: // Implicit on purpose, so that we can easily create enumerators from // nsFrameList via this impicit constructor. - Slice(const nsFrameList& aList) : + MOZ_IMPLICIT Slice(const nsFrameList& aList) : #ifdef DEBUG mList(aList), #endif @@ -334,7 +334,7 @@ public: class Enumerator { public: - Enumerator(const Slice& aSlice) : + explicit Enumerator(const Slice& aSlice) : #ifdef DEBUG mSlice(aSlice), #endif @@ -415,7 +415,7 @@ public: public: friend class nsFrameList; - FrameLinkEnumerator(const nsFrameList& aList) : + explicit FrameLinkEnumerator(const nsFrameList& aList) : Enumerator(aList), mPrev(nullptr) {} diff --git a/layout/generic/nsHTMLReflowMetrics.h b/layout/generic/nsHTMLReflowMetrics.h index 2b0e23d75f3e..de611bf05ec8 100644 --- a/layout/generic/nsHTMLReflowMetrics.h +++ b/layout/generic/nsHTMLReflowMetrics.h @@ -204,7 +204,7 @@ public: // XXX width/height/ascent are OUT parameters and so they shouldn't // have to be initialized, but there are some bad frame classes that // aren't properly setting them when returning from Reflow()... - nsHTMLReflowMetrics(mozilla::WritingMode aWritingMode, uint32_t aFlags = 0) + explicit nsHTMLReflowMetrics(mozilla::WritingMode aWritingMode, uint32_t aFlags = 0) : mISize(0) , mBSize(0) , mBlockStartAscent(ASK_FOR_BASELINE) @@ -212,7 +212,7 @@ public: , mWritingMode(aWritingMode) {} - nsHTMLReflowMetrics(const nsHTMLReflowState& aState, uint32_t aFlags = 0); + explicit nsHTMLReflowMetrics(const nsHTMLReflowState& aState, uint32_t aFlags = 0); // ISize and BSize are logical-coordinate dimensions: // ISize is the size in the writing mode's inline direction (which equates to diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 94ffb11f6620..f709494b02f3 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -3178,7 +3178,7 @@ public: Init(aOther.GetFrame()); } - nsWeakFrame(nsIFrame* aFrame) : mPrev(nullptr), mFrame(nullptr) + MOZ_IMPLICIT nsWeakFrame(nsIFrame* aFrame) : mPrev(nullptr), mFrame(nullptr) { Init(aFrame); } diff --git a/layout/generic/nsLeafFrame.h b/layout/generic/nsLeafFrame.h index cdd295692226..e7459e865828 100644 --- a/layout/generic/nsLeafFrame.h +++ b/layout/generic/nsLeafFrame.h @@ -72,7 +72,7 @@ public: } protected: - nsLeafFrame(nsStyleContext* aContext) : nsFrame(aContext) {} + explicit nsLeafFrame(nsStyleContext* aContext) : nsFrame(aContext) {} virtual ~nsLeafFrame(); /** diff --git a/layout/generic/nsLineBox.h b/layout/generic/nsLineBox.h index 1f9c7b0c11e8..d60d832a3294 100644 --- a/layout/generic/nsLineBox.h +++ b/layout/generic/nsLineBox.h @@ -342,9 +342,9 @@ private: MOZ_ASSERT(!mFlags.mHasHashedFrames); uint32_t count = GetChildCount(); mFlags.mHasHashedFrames = 1; - uint32_t minSize = - std::max(kMinChildCountForHashtable, uint32_t(PL_DHASH_MIN_SIZE)); - mFrames = new nsTHashtable< nsPtrHashKey >(std::max(count, minSize)); + uint32_t minLength = std::max(kMinChildCountForHashtable, + uint32_t(PL_DHASH_DEFAULT_INITIAL_LENGTH)); + mFrames = new nsTHashtable< nsPtrHashKey >(std::max(count, minLength)); for (nsIFrame* f = mFirstChild; count-- > 0; f = f->GetNextSibling()) { mFrames->PutEntry(f); } diff --git a/layout/generic/nsQueryFrame.h b/layout/generic/nsQueryFrame.h index 539921ee8df8..63f501ba9872 100644 --- a/layout/generic/nsQueryFrame.h +++ b/layout/generic/nsQueryFrame.h @@ -77,7 +77,13 @@ public: class do_QueryFrame { public: - do_QueryFrame(nsQueryFrame *s) : mRawPtr(s) { } + explicit do_QueryFrame(nsQueryFrame *s) : mRawPtr(s) { } + + // The return and argument types here are arbitrarily selected so no + // corresponding member function exists. + typedef void (do_QueryFrame::* MatchNullptr)(double, float); + // Implicit constructor for nullptr, trick borrowed from already_AddRefed. + MOZ_IMPLICIT do_QueryFrame(MatchNullptr aRawPtr) : mRawPtr(nullptr) {} template operator Dest*() { diff --git a/layout/generic/nsSimplePageSequenceFrame.cpp b/layout/generic/nsSimplePageSequenceFrame.cpp index 5fb154e044bd..822fd7d35cd3 100644 --- a/layout/generic/nsSimplePageSequenceFrame.cpp +++ b/layout/generic/nsSimplePageSequenceFrame.cpp @@ -201,7 +201,8 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, // Tile the pages vertically nsHTMLReflowMetrics kidSize(aReflowState); - for (nsIFrame* kidFrame = mFrames.FirstChild(); nullptr != kidFrame; ) { + for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) { + nsIFrame* kidFrame = e.get(); // Set the shared data into the page frame before reflow nsPageFrame * pf = static_cast(kidFrame); pf->SetSharedPageData(mPageData); @@ -244,25 +245,21 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, // Add it to our child list mFrames.InsertFrame(nullptr, kidFrame, continuingPage); } - - // Get the next page - kidFrame = kidFrame->GetNextSibling(); } // Get Total Page Count - nsIFrame* page; - int32_t pageTot = 0; - for (page = mFrames.FirstChild(); page; page = page->GetNextSibling()) { - pageTot++; - } + // XXXdholbert technically we could calculate this in the loop above, + // instead of needing a separate walk. + int32_t pageTot = mFrames.GetLength(); // Set Page Number Info int32_t pageNum = 1; - for (page = mFrames.FirstChild(); page; page = page->GetNextSibling()) { - nsPageFrame * pf = static_cast(page); - if (pf != nullptr) { - pf->SetPageNumInfo(pageNum, pageTot); - } + for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) { + MOZ_ASSERT(e.get()->GetType() == nsGkAtoms::pageFrame, + "only expecting nsPageFrame children. Other children will make " + "this static_cast bogus & probably violate other assumptions"); + nsPageFrame* pf = static_cast(e.get()); + pf->SetPageNumInfo(pageNum, pageTot); pageNum++; } @@ -421,8 +418,8 @@ nsSimplePageSequenceFrame::StartPrint(nsPresContext* aPresContext, int32_t pageNum = 1; nscoord y = 0;//mMargin.top; - for (nsIFrame* page = mFrames.FirstChild(); page; - page = page->GetNextSibling()) { + for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) { + nsIFrame* page = e.get(); if (pageNum >= mFromPageNum && pageNum <= mToPageNum) { nsRect rect = page->GetRect(); rect.y = y; diff --git a/layout/generic/nsSplittableFrame.h b/layout/generic/nsSplittableFrame.h index 47ce69e13543..7b57bf020ecf 100644 --- a/layout/generic/nsSplittableFrame.h +++ b/layout/generic/nsSplittableFrame.h @@ -74,7 +74,7 @@ public: static void RemoveFromFlow(nsIFrame* aFrame); protected: - nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {} + explicit nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {} /** * Determine the height consumed by our previous-in-flows. diff --git a/layout/generic/nsSubDocumentFrame.h b/layout/generic/nsSubDocumentFrame.h index f079b7ec43c8..c4397f8bab8d 100644 --- a/layout/generic/nsSubDocumentFrame.h +++ b/layout/generic/nsSubDocumentFrame.h @@ -21,7 +21,7 @@ public: NS_DECL_QUERYFRAME_TARGET(nsSubDocumentFrame) NS_DECL_FRAMEARENA_HELPERS - nsSubDocumentFrame(nsStyleContext* aContext); + explicit nsSubDocumentFrame(nsStyleContext* aContext); #ifdef DEBUG_FRAME_DUMP void List(FILE* out = stderr, const char* aPrefix = "", uint32_t aFlags = 0) const MOZ_OVERRIDE; diff --git a/layout/printing/nsPrintData.h b/layout/printing/nsPrintData.h index a2823130ca1e..af121d3181d5 100644 --- a/layout/printing/nsPrintData.h +++ b/layout/printing/nsPrintData.h @@ -41,7 +41,7 @@ public: typedef enum {eIsPrinting, eIsPrintPreview } ePrintDataType; - nsPrintData(ePrintDataType aType); + explicit nsPrintData(ePrintDataType aType); ~nsPrintData(); // non-virtual // Listener Helper Methods diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index d63b9745a634..af567f66200a 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1650,9 +1650,9 @@ skip-if(Android||B2G) random-if(winWidget) == 632781-verybig.html 632781-ref.htm == 633344-1.html 633344-1-ref.html == 634232-1.html 634232-1-ref.html fails-if(Android&&AndroidVersion<17&&AndroidVersion!=10) == 635302-1.html 635302-1-ref.html -skip-if(B2G) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,11) == 635373-1.html 635373-1-ref.html -skip-if(B2G) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,15) == 635373-2.html 635373-2-ref.html -skip-if(B2G) random-if(d2d) fails-if(Android) fuzzy-if(winWidget&&!d2d,1,15) == 635373-3.html 635373-3-ref.html +skip-if(B2G) random-if(d2d) fuzzy-if(winWidget&&!d2d,1,11) == 635373-1.html 635373-1-ref.html +skip-if(B2G) random-if(d2d) fuzzy-if(winWidget&&!d2d,1,15) == 635373-2.html 635373-2-ref.html +skip-if(B2G) random-if(d2d) fuzzy-if(winWidget&&!d2d,1,15) == 635373-3.html 635373-3-ref.html HTTP(..) == 635639-1.html 635639-1-ref.html HTTP(..) == 635639-2.html 635639-2-ref.html random == 637597-1.html 637597-1-ref.html # bug 637597 was never really fixed! diff --git a/layout/reftests/css-gradients/reftest.list b/layout/reftests/css-gradients/reftest.list index 61fa9c52b90d..80cd71cf422a 100644 --- a/layout/reftests/css-gradients/reftest.list +++ b/layout/reftests/css-gradients/reftest.list @@ -68,7 +68,7 @@ fuzzy(3,7860) fuzzy-if(cocoaWidget,5,89041) fuzzy-if(azureSkiaGL,2,90000) == rad == radial-position-1a.html radial-position-1-ref.html == radial-position-1b.html radial-position-1-ref.html fuzzy-if(azureQuartz,4,22317) == radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html -fuzzy(1,232) fuzzy-if(cocoaWidget,3,460) fuzzy-if(azureQuartz,4,22608) == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html +fuzzy(1,238) fuzzy-if(cocoaWidget,3,460) fuzzy-if(azureQuartz,4,22608) == radial-shape-closest-corner-1b.html radial-shape-closest-corner-1-ref.html fuzzy-if(azureQuartz,2,41171) == radial-shape-closest-corner-1c.html radial-shape-closest-corner-1-ref.html fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,17,3880) == radial-shape-closest-side-1b.html radial-shape-closest-side-1-ref.html diff --git a/layout/reftests/flexbox/flexbox-position-absolute-1.xhtml b/layout/reftests/flexbox/flexbox-position-absolute-1.xhtml index aa89dd714c24..f00a88efea29 100644 --- a/layout/reftests/flexbox/flexbox-position-absolute-1.xhtml +++ b/layout/reftests/flexbox/flexbox-position-absolute-1.xhtml @@ -28,13 +28,13 @@ display: flex; } div.a { - flex: 1 0 auto; + flex: 1 0 main-size; width: 30px; height: 100px; background: lightgreen; } div.b { - flex: 2 0 auto; + flex: 2 0 main-size; width: 20px; height: 100px; background: yellow; diff --git a/layout/reftests/flexbox/flexbox-position-absolute-2.xhtml b/layout/reftests/flexbox/flexbox-position-absolute-2.xhtml index d676272c037a..4fecea94d8aa 100644 --- a/layout/reftests/flexbox/flexbox-position-absolute-2.xhtml +++ b/layout/reftests/flexbox/flexbox-position-absolute-2.xhtml @@ -29,13 +29,13 @@ display: flex; } div.a { - flex: 1 0 auto; + flex: 1 0 main-size; width: 30px; height: 100px; background: lightgreen; } div.b { - flex: 2 0 auto; + flex: 2 0 main-size; width: 20px; height: 100px; background: yellow; diff --git a/layout/reftests/flexbox/flexbox-position-absolute-4.xhtml b/layout/reftests/flexbox/flexbox-position-absolute-4.xhtml index 67974fcf67a9..7218599c2bde 100644 --- a/layout/reftests/flexbox/flexbox-position-absolute-4.xhtml +++ b/layout/reftests/flexbox/flexbox-position-absolute-4.xhtml @@ -32,7 +32,7 @@ border: 1px solid black; } div.a { - flex: 1 0 auto; + flex: 1 0 main-size; width: 30px; height: 100px; background: lightgreen; diff --git a/layout/reftests/flexbox/flexbox-position-fixed-1.xhtml b/layout/reftests/flexbox/flexbox-position-fixed-1.xhtml index 6401fb2cb194..e0e8a1e995e5 100644 --- a/layout/reftests/flexbox/flexbox-position-fixed-1.xhtml +++ b/layout/reftests/flexbox/flexbox-position-fixed-1.xhtml @@ -28,13 +28,13 @@ display: flex; } div.a { - flex: 1 0 auto; + flex: 1 0 main-size; width: 30px; height: 100px; background: lightgreen; } div.b { - flex: 2 0 auto; + flex: 2 0 main-size; width: 20px; height: 100px; background: yellow; diff --git a/layout/reftests/flexbox/flexbox-position-fixed-2.xhtml b/layout/reftests/flexbox/flexbox-position-fixed-2.xhtml index c4f02bc9ce47..94753951840a 100644 --- a/layout/reftests/flexbox/flexbox-position-fixed-2.xhtml +++ b/layout/reftests/flexbox/flexbox-position-fixed-2.xhtml @@ -29,13 +29,13 @@ display: flex; } div.a { - flex: 1 0 auto; + flex: 1 0 main-size; width: 30px; height: 100px; background: lightgreen; } div.b { - flex: 2 0 auto; + flex: 2 0 main-size; width: 20px; height: 100px; background: yellow; diff --git a/layout/reftests/flexbox/flexbox-position-fixed-4.xhtml b/layout/reftests/flexbox/flexbox-position-fixed-4.xhtml index 05c75baeeb42..d01a0bb117c3 100644 --- a/layout/reftests/flexbox/flexbox-position-fixed-4.xhtml +++ b/layout/reftests/flexbox/flexbox-position-fixed-4.xhtml @@ -32,7 +32,7 @@ border: 2px dashed teal; } div.a { - flex: 1 0 auto; + flex: 1 0 main-size; width: 30px; height: 100px; background: lightgreen; diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-1.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-1.xhtml index 60f5faed660a..70c2c70d78a6 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-1.xhtml +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-1.xhtml @@ -62,8 +62,8 @@ 1st element gets 3/5 of space: 13px + 3/5 * 150px = 103px -->
- - + +
- - + +
- - + +
- - + +
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-1.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-1.xhtml index 6bc088c906e3..8c3ac123b31f 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-1.xhtml +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-1.xhtml @@ -64,8 +64,8 @@ 1st element gets 3/5 of space: 13px + 3/5 * 150px = 103px -->
- - + +
- - + +
- - + +
- - + +
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-horiz-1.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-horiz-1.xhtml index 50ef7baa8d92..d277c1aa5b4b 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-horiz-1.xhtml +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-horiz-1.xhtml @@ -66,8 +66,8 @@ 1st element gets 3/5 of space: 13px + 3/5 * 150px = 103px -->
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-vert-1.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-vert-1.xhtml index b032af5512f4..c8b110b88a64 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-vert-1.xhtml +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-vert-1.xhtml @@ -68,8 +68,8 @@ 1st element gets 3/5 of space: 13px + 3/5 * 150px = 103px -->
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-horiz-1.xhtml b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-horiz-1.xhtml index 4019bcaae99c..9804f5e1f554 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-horiz-1.xhtml +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-horiz-1.xhtml @@ -63,8 +63,8 @@ 1st element gets 3/5 of space: 13px + 3/5 * 150px = 103px -->
-