MozReview-Commit-ID: GvQyuOvxr8o
This commit is contained in:
Kartikaya Gupta 2017-03-28 09:12:16 -04:00
Родитель bb6943a029 5b9719c5fc
Коммит cbf426c332
355 изменённых файлов: 10119 добавлений и 3248 удалений

Просмотреть файл

@ -55,7 +55,6 @@ b2g/locales/en-US/b2g-l10n.js
# browser/ exclusions
browser/app/**
browser/branding/**/firefox-branding.js
browser/base/content/nsContextMenu.js
browser/base/content/sanitizeDialog.js
browser/base/content/test/general/file_csp_block_all_mixedcontent.html
browser/base/content/test/urlbar/file_blank_but_not_blank.html

Просмотреть файл

@ -66,9 +66,8 @@ require('../../system/unload').when( _ =>
);
function getNode(id, window) {
return !views.has(id) || ignoreWindow(window)
? null
: CustomizableUI.getWidget(id).forWindow(window).node
let view = views.get(id);
return view && view.nodes.get(window);
};
function isInToolbar(id) {
@ -133,9 +132,6 @@ function create(options) {
let image = getImage(icon, true, window.devicePixelRatio);
if (ignoreWindow(window))
node.style.display = 'none';
node.setAttribute('id', this.id);
node.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional badged-button');
node.setAttribute('type', type);
@ -144,12 +140,24 @@ function create(options) {
node.setAttribute('image', image);
node.setAttribute('constrain-size', 'true');
views.set(id, {
if (!views.get(id)) {
views.set(id, {
nodes: new WeakMap(),
});
}
let view = views.get(id);
Object.assign(view, {
area: this.currentArea,
icon: icon,
label: label
});
if (ignoreWindow(window))
node.style.display = 'none';
else
view.nodes.set(window, node);
node.addEventListener('command', function(event) {
if (views.has(id)) {
emit(viewEvents, 'data', {
@ -219,7 +227,7 @@ function setBadge(id, window, badge, color) {
if (node) {
// `Array.from` is needed to handle unicode symbol properly:
// '𝐀𝐁'.length is 4 where Array.from('𝐀𝐁').length is 2
let text = isNil(badge)
let text = badge == null
? ''
: Array.from(String(badge)).slice(0, 4).join('');
@ -229,7 +237,7 @@ function setBadge(id, window, badge, color) {
'class', 'toolbarbutton-badge');
if (badgeNode)
badgeNode.style.backgroundColor = isNil(color) ? '' : color;
badgeNode.style.backgroundColor = color == null ? '' : color;
}
}
exports.setBadge = setBadge;

Просмотреть файл

@ -97,7 +97,9 @@ tools repackage:: $(DIST)/bin/$(MOZ_APP_NAME)
cp -RL $(DIST)/branding/firefox.icns $(dist_dest)/Contents/Resources/firefox.icns
cp -RL $(DIST)/branding/document.icns $(dist_dest)/Contents/Resources/document.icns
$(MKDIR) -p $(dist_dest)/Contents/Library/LaunchServices
ifdef MOZ_UPDATER
mv -f $(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater $(dist_dest)/Contents/Library/LaunchServices
ln -s ../../../../Library/LaunchServices/org.mozilla.updater $(dist_dest)/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater
endif
printf APPLMOZB > $(dist_dest)/Contents/PkgInfo
endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -7106,8 +7106,7 @@
class="tab-content" align="center">
<xul:image xbl:inherits="fadein,pinned,busy,progress,selected=visuallyselected"
class="tab-throbber"
role="presentation"
layer="true" />
role="presentation"/>
<xul:image xbl:inherits="src=image,loadingprincipal=iconLoadingPrincipal,fadein,pinned,selected=visuallyselected,busy,crashed,sharing"
anonid="tab-icon-image"
class="tab-icon-image"

Просмотреть файл

@ -3,7 +3,7 @@ support-files =
head.js
[browser_all_files_referenced.js]
skip-if = debug # no point in running on both opt and debug, and will likely intermittently timeout on debug
skip-if = debug || (os == 'linux' && bits == 32) # no point in running on both opt and debug, and will likely intermittently timeout on debug; oom crashes on linux32 (bug 1349307)
[browser_misused_characters_in_strings.js]
support-files =
bug1262648_string_with_newlines.dtd

Просмотреть файл

@ -1,6 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Slow on asan builds.
requestLongerTimeout(5);
var isDevtools = SimpleTest.harnessParameters.subsuite == "devtools";
var gExceptionPaths = ["chrome://browser/content/defaultthemes/",
@ -149,8 +152,6 @@ var whitelist = new Set([
{file: "chrome://marionette/content/test_anonymous_content.xul"},
{file: "chrome://marionette/content/test_dialog.properties"},
{file: "chrome://marionette/content/test_dialog.xul"},
// Bug 1348532
{file: "chrome://mozapps/content/extensions/list.xul"},
// Bug 1348533
{file: "chrome://mozapps/skin/downloads/buttons.png", platforms: ["macosx"]},
{file: "chrome://mozapps/skin/downloads/downloadButtons.png", platforms: ["linux", "win"]},

Просмотреть файл

@ -157,7 +157,7 @@ browser.jar:
content/browser/webext-panels.js (content/webext-panels.js)
* content/browser/webext-panels.xul (content/webext-panels.xul)
* content/browser/baseMenuOverlay.xul (content/baseMenuOverlay.xul)
* content/browser/nsContextMenu.js (content/nsContextMenu.js)
content/browser/nsContextMenu.js (content/nsContextMenu.js)
# XXX: We should exclude this one as well (bug 71895)
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)
#ifdef XP_MACOSX

Просмотреть файл

@ -42,7 +42,6 @@ DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY']
DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1
DEFINES['CONTEXT_COPY_IMAGE_CONTENTS'] = 1
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):

Просмотреть файл

@ -179,7 +179,7 @@ var MessageListener = {
onLoadStarted() {
// Notify the parent that the tab is no longer pending.
sendSyncMessage("SessionStore:restoreTabContentStarted", {epoch});
sendAsyncMessage("SessionStore:restoreTabContentStarted", {epoch});
},
onLoadFinished() {
@ -189,13 +189,21 @@ var MessageListener = {
}
});
// When restoreHistory finishes, we send a synchronous message to
// SessionStore.jsm so that it can run SSTabRestoring. Users of
// SSTabRestoring seem to get confused if chrome and content are out of
// sync about the state of the restore (particularly regarding
// docShell.currentURI). Using a synchronous message is the easiest way
// to temporarily synchronize them.
sendSyncMessage("SessionStore:restoreHistoryComplete", {epoch, isRemotenessUpdate});
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
// For non-remote tabs, when restoreHistory finishes, we send a synchronous
// message to SessionStore.jsm so that it can run SSTabRestoring. Users of
// SSTabRestoring seem to get confused if chrome and content are out of
// sync about the state of the restore (particularly regarding
// docShell.currentURI). Using a synchronous message is the easiest way
// to temporarily synchronize them.
//
// For remote tabs, because all nsIWebProgress notifications are sent
// asynchronously using messages, we get the same-order guarantees of the
// message manager, and can use an async message.
sendSyncMessage("SessionStore:restoreHistoryComplete", {epoch, isRemotenessUpdate});
} else {
sendAsyncMessage("SessionStore:restoreHistoryComplete", {epoch, isRemotenessUpdate});
}
},
restoreTabContent({loadArguments, isRemotenessUpdate, reason}) {
@ -326,20 +334,24 @@ var SessionHistoryListener = {
},
OnHistoryNewEntry(newURI, oldIndex) {
// We ought to collect the previously current entry as well, see bug 1350567.
this.collectFrom(oldIndex);
},
OnHistoryGoBack(backURI) {
// We ought to collect the previously current entry as well, see bug 1350567.
this.collectFrom(kLastIndex);
return true;
},
OnHistoryGoForward(forwardURI) {
// We ought to collect the previously current entry as well, see bug 1350567.
this.collectFrom(kLastIndex);
return true;
},
OnHistoryGotoIndex(index, gotoURI) {
// We ought to collect the previously current entry as well, see bug 1350567.
this.collectFrom(kLastIndex);
return true;
},

Просмотреть файл

@ -31,6 +31,7 @@ support-files =
browser_pageStyle_sample_nested.html
browser_sessionHistory_slow.sjs
browser_scrollPositions_sample.html
browser_scrollPositions_sample2.html
browser_scrollPositions_sample_frameset.html
browser_scrollPositions_readerModeArticle.html
browser_sessionStorage.html

Просмотреть файл

@ -5,6 +5,7 @@
const BASE = "http://example.com/browser/browser/components/sessionstore/test/"
const URL = BASE + "browser_scrollPositions_sample.html";
const URL2 = BASE + "browser_scrollPositions_sample2.html";
const URL_FRAMESET = BASE + "browser_scrollPositions_sample_frameset.html";
// Randomized set of scroll positions we will use in this test.
@ -108,6 +109,8 @@ add_task(function* test_scroll_nested() {
/**
* Test that scroll positions persist after restoring background tabs in
* a restored window (bug 1228518).
* Also test that scroll positions for previous session history entries
* are preserved as well (bug 1265818).
*/
add_task(function* test_scroll_background_tabs() {
pushPrefs(["browser.sessionstore.restore_on_demand", true]);
@ -119,7 +122,15 @@ add_task(function* test_scroll_background_tabs() {
// Scroll down a little.
yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL_X, y: SCROLL_Y});
yield checkScroll(tab, {scroll: SCROLL_STR}, "scroll is fine");
yield checkScroll(tab, {scroll: SCROLL_STR}, "scroll on first page is fine");
// Navigate to a different page and scroll there as well.
browser.loadURI(URL2);
yield BrowserTestUtils.browserLoaded(browser);
// Scroll down a little.
yield sendMessage(browser, "ss-test:setScrollPosition", {x: SCROLL2_X, y: SCROLL2_Y});
yield checkScroll(tab, {scroll: SCROLL2_STR}, "scroll on second page is fine");
// Close the window
yield BrowserTestUtils.closeWindow(newWin);
@ -149,7 +160,17 @@ add_task(function* test_scroll_background_tabs() {
newWin.gBrowser.selectedTab = tab;
yield promiseTabRestored(tab);
yield checkScroll(tab, {scroll: SCROLL_STR}, "scroll is still fine");
yield checkScroll(tab, {scroll: SCROLL2_STR}, "scroll is still fine");
// Now go back in history and check that the scroll position
// is restored there as well.
is(browser.canGoBack, true, "can go back");
browser.goBack();
yield BrowserTestUtils.browserLoaded(browser);
yield TabStateFlusher.flush(browser);
yield checkScroll(tab, {scroll: SCROLL_STR}, "scroll is still fine after navigating back");
yield BrowserTestUtils.closeWindow(newWin);
});

Просмотреть файл

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>browser_scrollPositions_sample.html</title>
</head>
<body style='width: 100000px; height: 100000px;'>top</body>
</html>

Просмотреть файл

@ -35,7 +35,9 @@
#ifdef XP_MACOSX
; Mac bundle stuff
@APPNAME@/Contents/Info.plist
#ifdef MOZ_UPDATER
@APPNAME@/Contents/Library/LaunchServices
#endif
@APPNAME@/Contents/PkgInfo
@RESPATH@/firefox.icns
@RESPATH@/document.icns

Просмотреть файл

@ -441,7 +441,14 @@ Function .onInit
StrCpy $CheckboxShortcuts "1"
StrCpy $CheckboxSendPing "1"
!ifdef MOZ_MAINTENANCE_SERVICE
StrCpy $CheckboxInstallMaintSvc "1"
; We can only install the maintenance service if the user is an admin.
Call IsUserAdmin
Pop $0
${If} "$0" == "true"
StrCpy $CheckboxInstallMaintSvc "1"
${Else}
StrCpy $CheckboxInstallMaintSvc "0"
${EndIf}
!else
StrCpy $CheckboxInstallMaintSvc "0"
!endif

Просмотреть файл

@ -517,7 +517,6 @@ webNotifications.allow.accesskey=A
webNotifications.notNow=Not Now
webNotifications.notNow.accesskey=n
webNotifications.never=Never Allow
webNotifications.neverForSession=Never For This Session
webNotifications.never.accesskey=v
webNotifications.receiveFromSite2=Will you allow %S to send notifications?
# LOCALIZATION NOTE (webNotifications.upgradeTitle): When using native notifications on OS X, the title may be truncated around 32 characters.

Просмотреть файл

@ -12,7 +12,6 @@ this.EXPORTED_SYMBOLS = [ "ContentLinkHandler" ];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Feeds",
"resource:///modules/Feeds.jsm");

Просмотреть файл

@ -568,7 +568,7 @@ DesktopNotificationPermissionPrompt.prototype = {
},
get promptActions() {
return [
let actions = [
{
label: gBrowserBundle.GetStringFromName("webNotifications.allow"),
accessKey:
@ -582,16 +582,17 @@ DesktopNotificationPermissionPrompt.prototype = {
gBrowserBundle.GetStringFromName("webNotifications.notNow.accesskey"),
action: SitePermissions.BLOCK,
},
{
label: PrivateBrowsingUtils.isBrowserPrivate(this.browser) ?
gBrowserBundle.GetStringFromName("webNotifications.neverForSession") :
gBrowserBundle.GetStringFromName("webNotifications.never"),
];
if (!PrivateBrowsingUtils.isBrowserPrivate(this.browser)) {
actions.push({
label: gBrowserBundle.GetStringFromName("webNotifications.never"),
accessKey:
gBrowserBundle.GetStringFromName("webNotifications.never.accesskey"),
action: SitePermissions.BLOCK,
scope: SitePermissions.SCOPE_PERSISTENT,
},
];
});
}
return actions;
},
};

Просмотреть файл

@ -5,11 +5,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* Global Styles */
.checkbox-check {
-moz-appearance: checkbox;
}
/* General Pane */
#useFirefoxSync,
#getStarted {

Просмотреть файл

@ -98,9 +98,9 @@
skin/classic/browser/search-indicator-magnifying-glass.svg (../shared/search/search-indicator-magnifying-glass.svg)
skin/classic/browser/search-arrow-go.svg (../shared/search/search-arrow-go.svg)
skin/classic/browser/gear.svg (../shared/search/gear.svg)
skin/classic/browser/tabbrowser/connecting.png (../shared/tabbrowser/connecting.png)
skin/classic/browser/tabbrowser/connecting@2x.png (../shared/tabbrowser/connecting@2x.png)
skin/classic/browser/tabbrowser/connecting.svg (../shared/tabbrowser/connecting.svg)
skin/classic/browser/tabbrowser/crashed.svg (../shared/tabbrowser/crashed.svg)
skin/classic/browser/tabbrowser/loading.svg (../shared/tabbrowser/loading.svg)
skin/classic/browser/tabbrowser/pendingpaint.png (../shared/tabbrowser/pendingpaint.png)
skin/classic/browser/tabbrowser/tab-audio.svg (../shared/tabbrowser/tab-audio.svg)
skin/classic/browser/tabbrowser/tab-audio-small.svg (../shared/tabbrowser/tab-audio-small.svg)

Двоичные данные
browser/themes/shared/tabbrowser/connecting.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 8.3 KiB

Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path d="M8,0A8,8,0,0,0,0,8a8,8,0,0,0,8,8,8,8,0,0,0,8-8A8,8,0,0,0,8,0ZM8,13A5,5,0,0,1,3,8,5,5,0,0,1,8,3a5,5,0,0,1,5,5A5,5,0,0,1,8,13Z" fill="context-fill" fill-opacity=".2"/>
<circle cx="14.5" cy="8" r="1.5" fill="context-fill" fill-opacity=".8"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 495 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 29 KiB

Просмотреть файл

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<defs>
<radialGradient id="radialGradient" cx=".85" cy=".65" r=".75">
<stop stop-color="#000" offset=".2"/>
<stop stop-color="#fff" offset="1"/>
</radialGradient>
<mask id="myMask">
<rect width="16" height="16" fill="#fff"/>
<path d="M11.8,9.3A4,4,0,1,1,5.2,5.2L1.6,1.6a9,9,0,1,0,14.9,9.2Z" fill="url(#radialGradient)"/>
</mask>
</defs>
<path fill="#0077ff" fill-opacity=".15" d="M8,0A8,8,0,0,0,0,8a8,8,0,0,0,8,8,8,8,0,0,0,8-8A8,8,0,0,0,8,0ZM8,13A5,5,0,0,1,3,8,5,5,0,0,1,8,3a5,5,0,0,1,5,5A5,5,0,0,1,8,13Z"/>
<path mask="url(#myMask)" fill="#0090ff" d="M8,3a5,5,0,0,1,5,5h0a1.5,1.5,0,0,0,3,0h0a8,8,0,1,0-.8,3.5l-2.7-1.3A5,5,0,1,1,8,3Z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 932 B

Просмотреть файл

@ -178,12 +178,34 @@
list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-small.svg#tab-audio-white-blocked");
}
@keyframes tab-throbber-loading {
to {
transform: rotate(360deg);
}
}
@keyframes tab-throbber-connecting {
from {
transform: rotate(360deg);
}
}
.tab-throbber[busy] {
list-style-image: url("chrome://browser/skin/tabbrowser/connecting.png");
list-style-image: url("chrome://browser/skin/tabbrowser/connecting.svg");
animation-duration: 960ms;
animation-iteration-count: infinite;
animation-name: tab-throbber-connecting;
animation-timing-function: linear;
/* uncomment after bug 1350010:
context-properties: fill;
*/
fill: currentColor;
}
.tab-throbber[progress] {
list-style-image: url("chrome://global/skin/icons/loading.png");
list-style-image: url("chrome://browser/skin/tabbrowser/loading.svg");
animation-duration: 800ms;
animation-name: tab-throbber-loading;
}
.tab-label {
@ -562,17 +584,9 @@
var(--lwt-header-image);
}
.tab-throbber[busy] {
list-style-image: url("chrome://browser/skin/tabbrowser/connecting@2x.png");
}
.tab-icon-image {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
}
.tab-throbber[progress] {
list-style-image: url("chrome://global/skin/icons/loading@2x.png");
}
}
/* All tabs menupopup */

Просмотреть файл

@ -101,6 +101,22 @@ if test "$OS_TARGET" = "Android"; then
AC_MSG_ERROR([Couldn't find path to llvm-libc++ in the android ndk])
fi
if ! test -e "$cxx_include"; then
# NDK r13 removes the inner "libcxx" directory.
cxx_include="$cxx_base/include"
if ! test -e "$cxx_include"; then
AC_MSG_ERROR([Couldn't find path to libc++ includes in the android ndk])
fi
fi
if ! test -e "$cxxabi_include"; then
# NDK r13 removes the inner "libcxxabi" directory.
cxxabi_include="$cxxabi_base/include"
if ! test -e "$cxxabi_include"; then
AC_MSG_ERROR([Couldn't find path to libc++abi includes in the android ndk])
fi
fi
STLPORT_LIBS="-L$cxx_libs -lc++_static"
# NDK r12 split the libc++ runtime libraries into pieces.
for lib in c++abi unwind android_support; do
@ -111,7 +127,7 @@ if test "$OS_TARGET" = "Android"; then
# Add android/support/include/ for prototyping long double math
# functions, locale-specific C library functions, multibyte support,
# etc.
STLPORT_CPPFLAGS="-I$android_ndk/sources/android/support/include -I$cxx_include -I$cxxabi_include"
STLPORT_CPPFLAGS="-I$cxx_include -I$android_ndk/sources/android/support/include -I$cxxabi_include"
;;
*)
AC_MSG_ERROR([Bad value for --enable-android-cxx-stl])

Просмотреть файл

@ -4,6 +4,7 @@
"use strict";
const {Cu} = require("chrome");
const Services = require("Services");
const promise = require("promise");
const defer = require("devtools/shared/defer");

Просмотреть файл

@ -1,47 +1,43 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" height="16" width="16">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
<defs>
<linearGradient id="b">
<stop offset="0" stop-color="#747254"/>
<stop offset="1" stop-color="#8b8965"/>
<stop stop-color="#747254" offset="0"/>
<stop stop-color="#8b8965" offset="1"/>
</linearGradient>
<linearGradient id="a">
<stop offset="0" stop-color="#e1e1d7"/>
<stop offset="1" stop-color="#f2f2ee"/>
<stop stop-color="#e1e1d7" offset="0"/>
<stop stop-color="#f2f2ee" offset="1"/>
</linearGradient>
<linearGradient gradientTransform="translate(-2.38 -2.38) scale(1.17241)" gradientUnits="userSpaceOnUse" y2="4.847" x2="2.94" y1="12.978" x1="13.037" id="g" xlink:href="#a"/>
<linearGradient gradientTransform="translate(-2.38 -2.38) scale(1.17241)" gradientUnits="userSpaceOnUse" y2="2.729" x2="4.832" y1="11.063" x1="14.997" id="h" xlink:href="#b"/>
<linearGradient gradientTransform="matrix(.64 0 0 .6988 .88 .987)" gradientUnits="userSpaceOnUse" xlink:href="#c" id="i" y2=".583" x2="6.34" y1="4.311" x1="8.637"/>
<linearGradient xlink:href="#a" id="g" x1="13" y1="13" x2="2.9" y2="4.8" gradientUnits="userSpaceOnUse" gradientTransform="translate(-2.28 -2.28) scale(1.1724)"/>
<linearGradient xlink:href="#b" id="h" x1="15" y1="11.1" x2="4.8" y2="2.7" gradientUnits="userSpaceOnUse" gradientTransform="translate(-2.28 -2.28) scale(1.1724)"/>
<linearGradient x1="8.6" y1="4.3" x2="6.3" y2=".6" id="i" xlink:href="#c" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.62854 0 0 .6863 5.97 6.076)"/>
<linearGradient id="c">
<stop offset="0" stop-color="#c8c8c8"/>
<stop offset="1" stop-color="#dcdcdc"/>
<stop stop-color="#c8c8c8" offset="0"/>
<stop stop-color="#dcdcdc" offset="1"/>
</linearGradient>
<linearGradient gradientTransform="matrix(.64 0 0 .6988 .88 .987)" gradientUnits="userSpaceOnUse" xlink:href="#d" id="j" y2="1.392" x2="4.956" y1="5.078" x1="7.188"/>
<linearGradient x1="7.2" y1="5.1" x2="5" y2="1.4" id="j" xlink:href="#d" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.62854 0 0 .6863 5.97 6.076)"/>
<linearGradient id="d">
<stop offset="0" stop-color="#a0a0a0"/>
<stop offset="1" stop-color="#c8c8c8"/>
<stop stop-color="#787878" offset="0"/>
<stop stop-color="#8c8c8c" offset="1"/>
</linearGradient>
<linearGradient gradientTransform="matrix(.62152 0 0 .5895 1.028 -609.403)" gradientUnits="userSpaceOnUse" xlink:href="#c" id="k" y2="1040.666" x2="4.559" y1="1052.085" x1="11.377"/>
<linearGradient gradientTransform="matrix(.62152 0 0 .5895 1.028 -609.403)" gradientUnits="userSpaceOnUse" xlink:href="#d" id="l" y2="1041.923" x2="1.917" y1="1053.385" x1="8.842"/>
<linearGradient gradientTransform="matrix(.71429 0 0 .71492 .286 .276)" gradientUnits="userSpaceOnUse" xlink:href="#e" id="m" y2="7.825" x2="6.608" y1="12.498" x1="8.54"/>
<linearGradient x1="11.4" y1="1052.1" x2="4.6" y2="1040.7" id="k" xlink:href="#c" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.6104 0 0 .57897 6.117 -593.406)"/>
<linearGradient x1="8.8" y1="1053.4" x2="1.9" y2="1041.9" id="l" xlink:href="#d" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.6104 0 0 .57897 6.117 -593.406)"/>
<linearGradient x1="8.5" y1="12.5" x2="6.6" y2="7.8" id="m" xlink:href="#e" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.7015 0 0 .70214 5.388 5.378)"/>
<linearGradient id="e">
<stop offset="0" stop-color="#505050"/>
<stop offset="1" stop-color="#787878"/>
<stop stop-color="#505050" offset="0"/>
<stop stop-color="#787878" offset="1"/>
</linearGradient>
<linearGradient gradientTransform="matrix(.71429 0 0 .71492 .286 .276)" gradientUnits="userSpaceOnUse" xlink:href="#f" id="n" y2="7.414" x2="7.402" y1="12.116" x1="9.392"/>
<linearGradient x1="9.4" y1="12.1" x2="7.4" y2="7.4" id="n" xlink:href="#f" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.7015 0 0 .70214 5.388 5.378)"/>
<linearGradient id="f">
<stop offset="0" stop-color="#787878"/>
<stop offset="1" stop-color="#b4b4b4"/>
<stop stop-color="#787878" offset="0"/>
<stop stop-color="#b4b4b4" offset="1"/>
</linearGradient>
</defs>
<g stroke-linejoin="round">
<path d="M9.351.2l1.603 1.575.833.819h.84c.65 0 1.173.52 1.173 1.167v8.872c0 .646-.523 1.167-1.172 1.167H1.372C.722 13.8.2 13.28.2 12.633V3.76c0-.647.523-1.167 1.172-1.167h5.543l.834-.819L9.35.2z" fill="url(#g)" stroke="url(#h)" stroke-width=".4"/>
<g transform="matrix(.9821 0 0 .98213 5.107 5.107)">
<path d="M6 1.215a2.982 2.982 0 0 0-2.991 2.904c.114-.019.238-.045.357-.045h.938C4.386 3.194 5.1 2.421 6 2.421c.899 0 1.614.773 1.696 1.653h.938c.119 0 .243.026.357.045A2.982 2.982 0 0 0 6 1.215z" fill="url(#i)" stroke="url(#j)" stroke-width=".611"/>
<rect y="4.065" x="1.214" ry=".787" rx=".787" height="6.72" width="9.571" fill="url(#k)" stroke="url(#l)" stroke-width=".611"/>
<path d="M6 5.504A1.2 1.2 0 0 0 4.795 6.71c0 .562.375 1.023.893 1.162v1.475h.625V7.872c.517-.139.892-.6.892-1.162A1.2 1.2 0 0 0 6 5.504z" fill="url(#m)" stroke="url(#n)" stroke-width=".407"/>
</g>
</g>
<path d="M9.5.3L11 2l1 .7h.7c.7 0 1.2.5 1.2 1.2v8.7c0 .7-.6 1.2-1.3 1.2H1.5c-.7 0-1.2-.6-1.2-1.3V4c0-.8.5-1.3 1.2-1.3H7l.8-.8L9.4.2z" fill="url(#g)" stroke="url(#h)" stroke-width=".6" stroke-linejoin="round"/>
<path d="M11 6.3a3 3 0 0 0-3 3l.4-.2h1c0-.8.7-1.5 1.6-1.5 1 0 1.6.7 1.7 1.6h1l.2.2a3 3 0 0 0-3-3z" fill="url(#i)" stroke="url(#j)" stroke-width=".6" stroke-linejoin="round"/>
<rect width="9.4" height="6.6" rx=".8" ry=".8" x="6.3" y="9.1" fill="url(#k)" stroke="url(#l)" stroke-width=".6" stroke-linejoin="round"/>
<path d="M11 10.5a1.2 1.2 0 0 0-1.2 1.2c0 .5.4 1 1 1v1.6h.5v-1.5c.5 0 1-.6 1-1a1.2 1.2 0 0 0-1.3-1.3z" fill="url(#m)" stroke="url(#n)" stroke-width=".4" stroke-linejoin="round"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 3.5 KiB

После

Ширина:  |  Высота:  |  Размер: 3.2 KiB

Просмотреть файл

@ -50,6 +50,17 @@ function consoleOpened(hud) {
// Use another js script to not depend on the test file line numbers.
Services.scriptloader.loadSubScript(TEST_FILE, hud.iframeWindow);
// Bug 1348885: test that error from nuked globals do not throw
let sandbox = new Cu.Sandbox(null, {
wantComponents: false,
wantGlobalProperties: ["URL", "URLSearchParams"],
});
let error = Cu.evalInSandbox(`
new Error("1348885");
`, sandbox);
Cu.reportError(error);
Cu.nukeSandbox(sandbox);
// Add a message from a content window.
content.console.log("bug587757b");
@ -99,6 +110,12 @@ function consoleOpened(hud) {
// and consoleOpened call
]
},
{
name: "Error from nuked global works",
text: "1348885",
category: CATEGORY_JS,
severity: SEVERITY_ERROR,
},
{
name: "content window console.log() is displayed",
text: "bug587757b",

Просмотреть файл

@ -1512,7 +1512,9 @@ WebConsoleActor.prototype =
{
let stack = null;
// Convert stack objects to the JSON attributes expected by client code
if (aPageError.stack) {
// Bug 1348885: If the global from which this error came from has been
// nuked, stack is going to be a dead wrapper.
if (aPageError.stack && !Cu.isDeadWrapper(aPageError.stack)) {
stack = [];
let s = aPageError.stack;
while (s !== null) {

Просмотреть файл

@ -155,8 +155,7 @@ exports.Memory = Class({
boundaries = { debugger: this.dbg };
}
}
const path = ThreadSafeChromeUtils.saveHeapSnapshot(boundaries);
return HeapSnapshotFileUtils.getSnapshotIdFromPath(path);
return ThreadSafeChromeUtils.saveHeapSnapshotGetId(boundaries);
}, "saveHeapSnapshot"),
/**

Просмотреть файл

@ -1444,13 +1444,19 @@ msSinceProcessCreation(const TimeStamp& now)
/* static */ already_AddRefed<nsIFile>
HeapSnapshot::CreateUniqueCoreDumpFile(ErrorResult& rv,
const TimeStamp& now,
nsAString& outFilePath)
nsAString& outFilePath,
nsAString& outSnapshotId)
{
nsCOMPtr<nsIFile> file;
rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(file));
if (NS_WARN_IF(rv.Failed()))
return nullptr;
nsAutoString tempPath;
rv = file->GetPath(tempPath);
if (NS_WARN_IF(rv.Failed()))
return nullptr;
auto ms = msSinceProcessCreation(now);
rv = file->AppendNative(nsPrintfCString("%lu.fxsnapshot", ms));
if (NS_WARN_IF(rv.Failed()))
@ -1462,7 +1468,12 @@ HeapSnapshot::CreateUniqueCoreDumpFile(ErrorResult& rv,
rv = file->GetPath(outFilePath);
if (NS_WARN_IF(rv.Failed()))
return nullptr;
return nullptr;
// The snapshot ID must be computed in the process that created the
// temp file, because TmpD may not be the same in all processes.
outSnapshotId.Assign(Substring(outFilePath, tempPath.Length() + 1,
outFilePath.Length() - tempPath.Length() - sizeof(".fxsnapshot")));
return file.forget();
}
@ -1489,14 +1500,18 @@ using UniqueHeapSnapshotTempFileHelperChild = UniquePtr<PHeapSnapshotTempFileHel
// the filesystem. Use IPDL to request a file descriptor from the parent
// process.
static already_AddRefed<nsIOutputStream>
getCoreDumpOutputStream(ErrorResult& rv, TimeStamp& start, nsAString& outFilePath)
getCoreDumpOutputStream(ErrorResult& rv,
TimeStamp& start,
nsAString& outFilePath,
nsAString& outSnapshotId)
{
if (XRE_IsParentProcess()) {
// Create the file and open the output stream directly.
nsCOMPtr<nsIFile> file = HeapSnapshot::CreateUniqueCoreDumpFile(rv,
start,
outFilePath);
outFilePath,
outSnapshotId);
if (NS_WARN_IF(rv.Failed()))
return nullptr;
@ -1535,6 +1550,7 @@ getCoreDumpOutputStream(ErrorResult& rv, TimeStamp& start, nsAString& outFilePat
auto opened = response.get_OpenedFile();
outFilePath = opened.path();
outSnapshotId = opened.snapshotId();
nsCOMPtr<nsIOutputStream> outputStream =
FileDescriptorOutputStream::Create(opened.descriptor());
if (NS_WARN_IF(!outputStream)) {
@ -1553,10 +1569,11 @@ using namespace JS;
using namespace devtools;
/* static */ void
ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outFilePath,
ErrorResult& rv)
ThreadSafeChromeUtils::SaveHeapSnapshotShared(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outFilePath,
nsAString& outSnapshotId,
ErrorResult& rv)
{
auto start = TimeStamp::Now();
@ -1565,7 +1582,9 @@ ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
uint32_t nodeCount = 0;
uint32_t edgeCount = 0;
nsCOMPtr<nsIOutputStream> outputStream = getCoreDumpOutputStream(rv, start, outFilePath);
nsCOMPtr<nsIOutputStream> outputStream = getCoreDumpOutputStream(rv, start,
outFilePath,
outSnapshotId);
if (NS_WARN_IF(rv.Failed()))
return;
@ -1618,6 +1637,26 @@ ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
edgeCount);
}
/* static */ void
ThreadSafeChromeUtils::SaveHeapSnapshot(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outFilePath,
ErrorResult& rv)
{
nsAutoString snapshotId;
SaveHeapSnapshotShared(global, boundaries, outFilePath, snapshotId, rv);
}
/* static */ void
ThreadSafeChromeUtils::SaveHeapSnapshotGetId(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& outSnapshotId,
ErrorResult& rv)
{
nsAutoString filePath;
SaveHeapSnapshotShared(global, boundaries, filePath, outSnapshotId, rv);
}
/* static */ already_AddRefed<HeapSnapshot>
ThreadSafeChromeUtils::ReadHeapSnapshot(GlobalObject& global,
const nsAString& filePath,

Просмотреть файл

@ -126,7 +126,8 @@ public:
// snapshots are serialized into.
static already_AddRefed<nsIFile> CreateUniqueCoreDumpFile(ErrorResult& rv,
const TimeStamp& now,
nsAString& outFilePath);
nsAString& outFilePath,
nsAString& outSnapshotId);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HeapSnapshot)

Просмотреть файл

@ -81,15 +81,3 @@ exports.haveHeapSnapshotTempFile = function (snapshotId) {
return OS.File.stat(path).then(() => true,
() => false);
};
/**
* Given a heap snapshot's file path, extricate the snapshot id.
*
* @param {String} path
*
* @returns String
*/
exports.getSnapshotIdFromPath = function (path) {
return path.slice(OS.Constants.Path.tmpDir.length + 1,
path.length - ".fxsnapshot".length);
};

Просмотреть файл

@ -31,9 +31,11 @@ HeapSnapshotTempFileHelperParent::RecvOpenHeapSnapshotTempFile(
auto start = TimeStamp::Now();
ErrorResult rv;
nsAutoString filePath;
nsAutoString snapshotId;
nsCOMPtr<nsIFile> file = HeapSnapshot::CreateUniqueCoreDumpFile(rv,
start,
filePath);
filePath,
snapshotId);
if (NS_WARN_IF(rv.Failed())) {
if (!openFileFailure(rv, outResponse)) {
return IPC_FAIL_NO_REASON(this);
@ -53,7 +55,7 @@ HeapSnapshotTempFileHelperParent::RecvOpenHeapSnapshotTempFile(
FileDescriptor::PlatformHandleType handle =
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(prfd));
FileDescriptor fd(handle);
*outResponse = OpenedFile(filePath, fd);
*outResponse = OpenedFile(filePath, snapshotId, fd);
return IPC_OK();
}

Просмотреть файл

@ -12,6 +12,7 @@ namespace devtools {
struct OpenedFile
{
nsString path;
nsString snapshotId;
FileDescriptor descriptor;
};

Просмотреть файл

@ -139,6 +139,12 @@ interface nsISHEntry : nsISupports
/** LayoutHistoryState for scroll position and form values */
attribute nsILayoutHistoryState layoutHistoryState;
/**
* Initialises the LayoutHistoryState if it doesn't already exist
* and returns a reference to it.
*/
nsILayoutHistoryState initLayoutHistoryState();
/** parent of this entry */
attribute nsISHEntry parent;

Просмотреть файл

@ -292,6 +292,19 @@ nsSHEntry::SetLayoutHistoryState(nsILayoutHistoryState* aState)
return NS_OK;
}
NS_IMETHODIMP
nsSHEntry::InitLayoutHistoryState(nsILayoutHistoryState** aState)
{
if (!mShared->mLayoutHistoryState) {
nsCOMPtr<nsILayoutHistoryState> historyState;
historyState = NS_NewLayoutHistoryState();
nsresult rv = SetLayoutHistoryState(historyState);
NS_ENSURE_SUCCESS(rv, rv);
}
return GetLayoutHistoryState(aState);
}
NS_IMETHODIMP
nsSHEntry::GetLoadType(uint32_t* aResult)
{

Просмотреть файл

@ -74,7 +74,7 @@ var data = [
},
{
wrong: 'user:@example.com:8080/this/is/a/test.html',
fixed: 'http://user:@example.com:8080/this/is/a/test.html',
fixed: 'http://user@example.com:8080/this/is/a/test.html',
},
{
wrong: '//user:pass@example.com:8080/this/is/a/test.html',

Просмотреть файл

@ -40,12 +40,20 @@ struct OwningAnimationTarget
struct NonOwningAnimationTarget
{
NonOwningAnimationTarget() = default;
NonOwningAnimationTarget(dom::Element* aElement, CSSPseudoElementType aType)
: mElement(aElement), mPseudoType(aType) { }
explicit NonOwningAnimationTarget(const OwningAnimationTarget& aOther)
: mElement(aOther.mElement), mPseudoType(aOther.mPseudoType) { }
bool operator==(const NonOwningAnimationTarget& aOther) const
{
return mElement == aOther.mElement &&
mPseudoType == aOther.mPseudoType;
}
// mElement represents the parent element of a pseudo-element, not the
// generated content element.
dom::Element* MOZ_NON_OWNING_REF mElement = nullptr;

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/RestyleManagerInlines.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/TypeTraits.h" // For Forward<>
#include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetPresShellForContent
#include "nsContentUtils.h"
#include "nsCSSPseudoElements.h"
@ -360,9 +361,10 @@ EffectCompositor::PostRestyleForThrottledAnimations()
}
}
template<typename StyleType>
void
EffectCompositor::UpdateEffectProperties(nsStyleContext* aStyleContext,
dom::Element* aElement,
EffectCompositor::UpdateEffectProperties(StyleType&& aStyleType,
Element* aElement,
CSSPseudoElementType aPseudoType)
{
EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
@ -370,12 +372,13 @@ EffectCompositor::UpdateEffectProperties(nsStyleContext* aStyleContext,
return;
}
// Style context change might cause CSS cascade level,
// e.g removing !important, so we should update the cascading result.
// Style context (Gecko) or computed values (Stylo) change might cause CSS
// cascade level, e.g removing !important, so we should update the cascading
// result.
effectSet->MarkCascadeNeedsUpdate();
for (KeyframeEffectReadOnly* effect : *effectSet) {
effect->UpdateProperties(aStyleContext);
effect->UpdateProperties(Forward<StyleType>(aStyleType));
}
}
@ -1156,4 +1159,18 @@ EffectCompositor::AnimationStyleRuleProcessor::SizeOfIncludingThis(
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
template
void
EffectCompositor::UpdateEffectProperties<RefPtr<nsStyleContext>&>(
RefPtr<nsStyleContext>& aStyleContext,
Element* aElement,
CSSPseudoElementType aPseudoType);
template
void
EffectCompositor::UpdateEffectProperties<const ServoComputedValuesWithParent&>(
const ServoComputedValuesWithParent& aServoValues,
Element* aElement,
CSSPseudoElementType aPseudoType);
} // namespace mozilla

Просмотреть файл

@ -116,11 +116,12 @@ public:
// posted because updates on the main thread are throttled.
void PostRestyleForThrottledAnimations();
// Called when the style context on the specified (pseudo-) element might
// Called when computed style on the specified (pseudo-) element might
// have changed so that any context-sensitive values stored within
// animation effects (e.g. em-based endpoints used in keyframe effects)
// can be re-resolved to computed values.
void UpdateEffectProperties(nsStyleContext* aStyleContext,
template<typename StyleType>
void UpdateEffectProperties(StyleType&& aStyleType,
dom::Element* aElement,
CSSPseudoElementType aPseudoType);

Просмотреть файл

@ -867,6 +867,127 @@ waitForAllPaints(function() {
yield ensureElementRemoval(div);
});
add_task(function *no_throttling_animations_in_view_svg() {
/*
On Android throttled animations are left behind on the main thread in some
frames, We will fix this in bug 1247800.
*/
if (isAndroid) {
return;
}
var div = addDiv(null, { style: 'overflow: scroll;' +
'height: 100px; width: 100px;' });
var svg = addSVGElement(div, 'svg', { viewBox: '-10 -10 0.1 0.1',
width: '50px',
height: '50px' });
var rect = addSVGElement(svg, 'rect', { x: '-10',
y: '-10',
width: '10',
height: '10',
fill: 'red' });
var animation = rect.animate({ fill: ['blue', 'lime'] }, 100 * MS_PER_SEC);
yield animation.ready;
var markers = yield observeStyling(5);
is(markers.length, 5,
'CSS animations on an in-view svg element with post-transform should ' +
'not be throttled.');
yield ensureElementRemoval(div);
});
add_task(function *throttling_animations_out_of_view_svg() {
if (!SpecialPowers.getBoolPref('dom.animations.offscreen-throttling')) {
return;
}
/*
On Android throttled animations are left behind on the main thread in some
frames, We will fix this in bug 1247800.
*/
if (isAndroid) {
return;
}
var div = addDiv(null, { style: 'overflow: scroll;' +
'height: 100px; width: 100px;' });
var svg = addSVGElement(div, 'svg', { viewBox: '-10 -10 0.1 0.1',
width: '50px',
height: '50px' });
var rect = addSVGElement(svg, 'rect', { width: '10',
height: '10',
fill: 'red' });
var animation = rect.animate({ fill: ['blue', 'lime'] }, 100 * MS_PER_SEC);
yield animation.ready;
var markers = yield observeStyling(5);
is(markers.length, 0,
'CSS animations on an out-of-view svg element with post-transform ' +
'should be throttled.');
yield ensureElementRemoval(div);
});
add_task(function *no_throttling_animations_in_view_css_transform() {
/*
On Android throttled animations are left behind on the main thread in some
frames, We will fix this in bug 1247800.
*/
if (isAndroid) {
return;
}
var scrollDiv = addDiv(null, { style: 'overflow: scroll; ' +
'height: 100px; width: 100px;' });
var targetDiv = addDiv(null,
{ style: 'animation: background-color 100s;' +
'transform: translate(-50px, -50px);' });
scrollDiv.appendChild(targetDiv);
var animation = targetDiv.getAnimations()[0];
yield animation.ready;
var markers = yield observeStyling(5);
is(markers.length, 5,
'CSS animation on an in-view element with pre-transform should not ' +
'be throttled.');
yield ensureElementRemoval(scrollDiv);
});
add_task(function *throttling_animations_out_of_view_css_transform() {
if (!SpecialPowers.getBoolPref('dom.animations.offscreen-throttling')) {
return;
}
/*
On Android throttled animations are left behind on the main thread in some
frames, We will fix this in bug 1247800.
*/
if (isAndroid) {
return;
}
var scrollDiv = addDiv(null, { style: 'overflow: scroll;' +
'height: 100px; width: 100px;' });
var targetDiv = addDiv(null,
{ style: 'animation: background-color 100s;' +
'transform: translate(100px, 100px);' });
scrollDiv.appendChild(targetDiv);
var animation = targetDiv.getAnimations()[0];
yield animation.ready;
var markers = yield observeStyling(5);
is(markers.length, 0,
'CSS animation on an out-of-view element with pre-transform should be ' +
'throttled.');
yield ensureElementRemoval(scrollDiv);
});
});
</script>

Просмотреть файл

@ -332,3 +332,25 @@ function isOMTAEnabled() {
return SpecialPowers.DOMWindowUtils.layerManagerRemote &&
SpecialPowers.getBoolPref(OMTAPrefKey);
}
/**
* Append an SVG element to the target element.
*
* @param target The element which want to append.
* @param attrs A array object with attribute name and values to set on
* the SVG element.
* @return An SVG outer element.
*/
function addSVGElement(target, tag, attrs) {
if (!target) {
return null;
}
var element = document.createElementNS('http://www.w3.org/2000/svg', tag);
if (attrs) {
for (var attrName in attrs) {
element.setAttributeNS(null, attrName, attrs[attrName]);
}
}
target.appendChild(element);
return element;
}

Просмотреть файл

@ -26,6 +26,14 @@ class Promise;
class ThreadSafeChromeUtils
{
private:
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static void SaveHeapSnapshotShared(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& filePath,
nsAString& snapshotId,
ErrorResult& rv);
public:
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static void SaveHeapSnapshot(GlobalObject& global,
@ -33,6 +41,12 @@ public:
nsAString& filePath,
ErrorResult& rv);
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static void SaveHeapSnapshotGetId(GlobalObject& global,
const HeapSnapshotBoundaries& boundaries,
nsAString& snapshotId,
ErrorResult& rv);
// Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
static already_AddRefed<devtools::HeapSnapshot> ReadHeapSnapshot(GlobalObject& global,
const nsAString& filePath,

Просмотреть файл

@ -8052,7 +8052,11 @@ GetSurfaceDataImpl(mozilla::gfx::DataSourceSurface* aSurface,
mozilla::gfx::IntSize size = aSurface->GetSize();
mozilla::CheckedInt32 requiredBytes =
mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
size_t maxBufLen = requiredBytes.isValid() ? requiredBytes.value() : 0;
if (!requiredBytes.isValid()) {
return GetSurfaceDataContext::NullValue();
}
size_t maxBufLen = requiredBytes.value();
mozilla::gfx::SurfaceFormat format = aSurface->GetFormat();
// Surface data handling is totally nuts. This is the magic one needs to

Просмотреть файл

@ -1327,6 +1327,9 @@ nsIDocument::nsIDocument()
mFontFaceSetDirty(true),
mGetUserFontSetCalled(false),
mPostedFlushUserFontSet(false),
mDidFireDOMContentLoaded(true),
mHasScrollLinkedEffect(false),
mFrameRequestCallbacksScheduled(false),
mCompatMode(eCompatibility_FullStandards),
mReadyState(ReadyState::READYSTATE_UNINITIALIZED),
mStyleBackendType(StyleBackendType::None),
@ -1355,8 +1358,6 @@ nsIDocument::nsIDocument()
mBFCacheEntry(nullptr),
mInSyncOperationCount(0),
mBlockDOMContentLoaded(0),
mDidFireDOMContentLoaded(true),
mHasScrollLinkedEffect(false),
mUseCounters(0),
mChildDocumentUseCounters(0),
mNotifiedPageForUseCounter(0),
@ -1922,6 +1923,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
tmp->mSubDocuments = nullptr;
tmp->mFrameRequestCallbacks.Clear();
MOZ_RELEASE_ASSERT(!tmp->mFrameRequestCallbacksScheduled,
"How did we get here without our presshell going away "
"first?");
tmp->mRadioGroups.Clear();
@ -3797,7 +3801,7 @@ nsDocument::CreateShell(nsPresContext* aContext, nsViewManager* aViewManager,
mExternalResourceMap.ShowViewers();
MaybeRescheduleAnimationFrameNotifications();
UpdateFrameRequestCallbackSchedulingState();
// Now that we have a shell, we might have @font-face rules.
RebuildUserFontSet();
@ -3806,17 +3810,29 @@ nsDocument::CreateShell(nsPresContext* aContext, nsViewManager* aViewManager,
}
void
nsDocument::MaybeRescheduleAnimationFrameNotifications()
nsIDocument::UpdateFrameRequestCallbackSchedulingState(nsIPresShell* aOldShell)
{
if (!mPresShell || !IsEventHandlingEnabled()) {
// bail out for now, until one of those conditions changes
// If the condition for shouldBeScheduled changes to depend on some other
// variable, add UpdateFrameRequestCallbackSchedulingState() calls to the
// places where that variable can change.
bool shouldBeScheduled =
mPresShell && IsEventHandlingEnabled() && !mFrameRequestCallbacks.IsEmpty();
if (shouldBeScheduled == mFrameRequestCallbacksScheduled) {
// nothing to do
return;
}
nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
if (!mFrameRequestCallbacks.IsEmpty()) {
nsIPresShell* presShell = aOldShell ? aOldShell : mPresShell;
MOZ_RELEASE_ASSERT(presShell);
nsRefreshDriver* rd = presShell->GetPresContext()->RefreshDriver();
if (shouldBeScheduled) {
rd->ScheduleFrameRequestCallbacks(this);
} else {
rd->RevokeFrameRequestCallbacks(this);
}
mFrameRequestCallbacksScheduled = shouldBeScheduled;
}
void
@ -3824,6 +3840,9 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
{
aCallbacks.AppendElements(mFrameRequestCallbacks);
mFrameRequestCallbacks.Clear();
// No need to manually remove ourselves from the refresh driver; it will
// handle that part. But we do have to update our state.
mFrameRequestCallbacksScheduled = false;
}
bool
@ -3871,9 +3890,6 @@ void
nsDocument::DeleteShell()
{
mExternalResourceMap.HideViewers();
if (IsEventHandlingEnabled()) {
RevokeAnimationFrameNotifications();
}
if (nsPresContext* presContext = mPresShell->GetPresContext()) {
presContext->RefreshDriver()->CancelPendingEvents(this);
}
@ -3887,19 +3903,12 @@ nsDocument::DeleteShell()
// objects for @font-face rules that came from the style set.
RebuildUserFontSet();
nsIPresShell* oldShell = mPresShell;
mPresShell = nullptr;
UpdateFrameRequestCallbackSchedulingState(oldShell);
mStyleSetFilled = false;
}
void
nsDocument::RevokeAnimationFrameNotifications()
{
if (!mFrameRequestCallbacks.IsEmpty()) {
mPresShell->GetPresContext()->RefreshDriver()->
RevokeFrameRequestCallbacks(this);
}
}
static void
SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
@ -4654,10 +4663,6 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
// our layout history state now.
mLayoutHistoryState = GetLayoutHistoryState();
if (mPresShell && !EventHandlingSuppressed()) {
RevokeAnimationFrameNotifications();
}
// Also make sure to remove our onload blocker now if we haven't done it yet
if (mOnloadBlockCount != 0) {
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
@ -4719,6 +4724,8 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
EnsureOnloadBlocker();
}
UpdateFrameRequestCallbackSchedulingState();
if (aScriptGlobalObject) {
// Go back to using the docshell for the layout history state
mLayoutHistoryState = nullptr;
@ -4752,8 +4759,6 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
}
}
MaybeRescheduleAnimationFrameNotifications();
// If we are set in a window that is already focused we should remember this
// as the time the document gained focus.
bool focused = false;
@ -9396,12 +9401,8 @@ SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData)
void
nsDocument::SuppressEventHandling(uint32_t aIncrease)
{
if (mEventsSuppressed == 0 && aIncrease != 0 && mPresShell &&
mScriptGlobalObject) {
RevokeAnimationFrameNotifications();
}
mEventsSuppressed += aIncrease;
UpdateFrameRequestCallbackSchedulingState();
for (uint32_t i = 0; i < aIncrease; ++i) {
ScriptLoader()->AddExecuteBlocker();
}
@ -10069,14 +10070,10 @@ nsIDocument::ScheduleFrameRequestCallback(FrameRequestCallback& aCallback,
}
int32_t newHandle = ++mFrameRequestCallbackCounter;
bool alreadyRegistered = !mFrameRequestCallbacks.IsEmpty();
DebugOnly<FrameRequest*> request =
mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle));
NS_ASSERTION(request, "This is supposed to be infallible!");
if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
mPresShell->GetPresContext()->RefreshDriver()->
ScheduleFrameRequestCallbacks(this);
}
UpdateFrameRequestCallbackSchedulingState();
*aHandle = newHandle;
return NS_OK;
@ -10086,11 +10083,8 @@ void
nsIDocument::CancelFrameRequestCallback(int32_t aHandle)
{
// mFrameRequestCallbacks is stored sorted by handle
if (mFrameRequestCallbacks.RemoveElementSorted(aHandle) &&
mFrameRequestCallbacks.IsEmpty() &&
mPresShell && IsEventHandlingEnabled()) {
mPresShell->GetPresContext()->RefreshDriver()->
RevokeFrameRequestCallbacks(this);
if (mFrameRequestCallbacks.RemoveElementSorted(aHandle)) {
UpdateFrameRequestCallbackSchedulingState();
}
}

Просмотреть файл

@ -920,7 +920,7 @@ public:
void DecreaseEventSuppression() {
MOZ_ASSERT(mEventsSuppressed);
--mEventsSuppressed;
MaybeRescheduleAnimationFrameNotifications();
UpdateFrameRequestCallbackSchedulingState();
}
virtual nsIDocument* GetTemplateContentsOwner() override;
@ -1535,12 +1535,6 @@ private:
void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
bool aUpdateCSSLoader);
// Revoke any pending notifications due to requestAnimationFrame calls
void RevokeAnimationFrameNotifications();
// Reschedule any notifications we need to handle
// requestAnimationFrame, if it's OK to do so.
void MaybeRescheduleAnimationFrameNotifications();
void ClearAllBoxObjects();
// Returns true if the scheme for the url for this document is "about"

Просмотреть файл

@ -2967,6 +2967,13 @@ protected:
return mId;
}
// Update our frame request callback scheduling state, if needed. This will
// schedule or unschedule them, if necessary, and update
// mFrameRequestCallbacksScheduled. aOldShell should only be passed when
// mPresShell is becoming null; in that case it will be used to get hold of
// the relevant refresh driver.
void UpdateFrameRequestCallbackSchedulingState(nsIPresShell* aOldShell = nullptr);
nsCString mReferrer;
nsString mLastModified;
@ -3183,6 +3190,18 @@ protected:
// Do we currently have an event posted to call FlushUserFontSet?
bool mPostedFlushUserFontSet : 1;
// True if we have fired the DOMContentLoaded event, or don't plan to fire one
// (e.g. we're not being parsed at all).
bool mDidFireDOMContentLoaded : 1;
// True if ReportHasScrollLinkedEffect() has been called.
bool mHasScrollLinkedEffect : 1;
// True if we have frame request callbacks scheduled with the refresh driver.
// This should generally be updated only via
// UpdateFrameRequestCallbackSchedulingState.
bool mFrameRequestCallbacksScheduled : 1;
// Compatibility mode
nsCompatibility mCompatMode;
@ -3333,9 +3352,6 @@ protected:
nsTArray<RefPtr<mozilla::dom::AnonymousContent>> mAnonymousContents;
uint32_t mBlockDOMContentLoaded;
bool mDidFireDOMContentLoaded:1;
bool mHasScrollLinkedEffect:1;
// Our live MediaQueryLists
PRCList mDOMMediaQueryLists;

Просмотреть файл

@ -1495,30 +1495,37 @@ DataTransfer::FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex,
return;
}
stream->SetInputStream(stringStream);
rv = stream->SetInputStream(stringStream);
NS_ENSURE_SUCCESS_VOID(rv);
uint32_t type;
do {
stream->Read32(&type);
rv = stream->Read32(&type);
NS_ENSURE_SUCCESS_VOID(rv);
if (type == eCustomClipboardTypeId_String) {
uint32_t formatLength;
stream->Read32(&formatLength);
rv = stream->Read32(&formatLength);
NS_ENSURE_SUCCESS_VOID(rv);
char* formatBytes;
stream->ReadBytes(formatLength, &formatBytes);
rv = stream->ReadBytes(formatLength, &formatBytes);
NS_ENSURE_SUCCESS_VOID(rv);
nsAutoString format;
format.Adopt(reinterpret_cast<char16_t*>(formatBytes),
formatLength / sizeof(char16_t));
uint32_t dataLength;
stream->Read32(&dataLength);
rv = stream->Read32(&dataLength);
NS_ENSURE_SUCCESS_VOID(rv);
char* dataBytes;
stream->ReadBytes(dataLength, &dataBytes);
rv = stream->ReadBytes(dataLength, &dataBytes);
NS_ENSURE_SUCCESS_VOID(rv);
nsAutoString data;
data.Adopt(reinterpret_cast<char16_t*>(dataBytes),
dataLength / sizeof(char16_t));
RefPtr<nsVariantCC> variant = new nsVariantCC();
variant->SetAsAString(data);
rv = variant->SetAsAString(data);
NS_ENSURE_SUCCESS_VOID(rv);
SetDataWithPrincipal(format, variant, aIndex, aPrincipal);
}

Просмотреть файл

@ -463,10 +463,18 @@ DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
nsString mStringData;
};
nsCOMPtr<nsINode> parentNode =
do_QueryInterface(mDataTransfer->GetParentObject());
MOZ_ASSERT(parentNode);
RefPtr<GASRunnable> runnable = new GASRunnable(aCallback, stringData);
rv = NS_DispatchToMainThread(runnable);
if (nsIDocument* doc = parentNode->OwnerDoc()) {
rv = doc->Dispatch("GASRunnable", TaskCategory::Other,
runnable.forget());
} else {
rv = NS_DispatchToMainThread(runnable);
}
if (NS_FAILED(rv)) {
NS_WARNING("NS_DispatchToMainThread Failed in "
NS_WARNING("Dispatch to main thread Failed in "
"DataTransferItem::GetAsString!");
}
}

Просмотреть файл

@ -366,8 +366,17 @@ EventListenerService::NotifyAboutMainThreadListenerChangeInternal(dom::EventTarg
if (!mPendingListenerChanges) {
mPendingListenerChanges = nsArrayBase::Create();
NS_DispatchToCurrentThread(NewRunnableMethod(this,
&EventListenerService::NotifyPendingChanges));
nsCOMPtr<nsIRunnable> runnable =
NewRunnableMethod("EventListenerService::NotifyPendingChanges",
this, &EventListenerService::NotifyPendingChanges);
if (nsCOMPtr<nsIGlobalObject> global = aTarget->GetOwnerGlobal()) {
global->Dispatch(nullptr, TaskCategory::Other, runnable.forget());
} else if (nsCOMPtr<nsINode> node = do_QueryInterface(aTarget)) {
node->OwnerDoc()->Dispatch(nullptr, TaskCategory::Other,
runnable.forget());
} else {
NS_DispatchToCurrentThread(runnable);
}
}
RefPtr<EventListenerChange> changes = mPendingListenerChangesSet.Get(aTarget);

Просмотреть файл

@ -339,8 +339,13 @@ EventStateManager::UpdateUserActivityTimer()
if (!gUserInteractionTimerCallback)
return NS_OK;
if (!gUserInteractionTimer)
if (!gUserInteractionTimer) {
CallCreateInstance("@mozilla.org/timer;1", &gUserInteractionTimer);
if (gUserInteractionTimer) {
gUserInteractionTimer->SetTarget(
SystemGroup::EventTargetFor(TaskCategory::Other));
}
}
if (gUserInteractionTimer) {
gUserInteractionTimer->InitWithCallback(gUserInteractionTimerCallback,
@ -1419,6 +1424,7 @@ EventStateManager::CreateClickHoldTimer(nsPresContext* inPresContext,
if (mClickHoldTimer) {
int32_t clickHoldDelay =
Preferences::GetInt("ui.click_hold_context_menus.delay", 500);
mClickHoldTimer->SetTarget(SystemGroup::EventTargetFor(TaskCategory::Other));
mClickHoldTimer->InitWithFuncCallback(sClickHoldCallback, this,
clickHoldDelay,
nsITimer::TYPE_ONE_SHOT);

Просмотреть файл

@ -1414,8 +1414,16 @@ IMEContentObserver::FlushMergeableNotifications()
// it may kick runnable event immediately after DOM tree is changed but
// the selection range isn't modified yet.
mQueuedSender = new IMENotificationSender(this);
NS_DispatchToCurrentThread(mQueuedSender);
nsIScriptGlobalObject* globalObject = mDocShell ?
mDocShell->GetScriptGlobalObject() :
nullptr;
if (globalObject) {
RefPtr<IMENotificationSender> queuedSender = mQueuedSender;
globalObject->Dispatch("IMENotificationSender",
TaskCategory::Other, queuedSender.forget());
} else {
NS_DispatchToCurrentThread(mQueuedSender);
}
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("0x%p IMEContentObserver::FlushMergeableNotifications(), "
"finished", this));
@ -1540,7 +1548,17 @@ IMEContentObserver::IMENotificationSender::Run()
"posting IMENotificationSender to current thread", this));
mIMEContentObserver->mQueuedSender =
new IMENotificationSender(mIMEContentObserver);
NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender);
nsIScriptGlobalObject* globalObject =
mIMEContentObserver->mDocShell ?
mIMEContentObserver->mDocShell->GetScriptGlobalObject() : nullptr;
if (globalObject) {
RefPtr<IMENotificationSender> queuedSender =
mIMEContentObserver->mQueuedSender;
globalObject->Dispatch("IMENotificationSender",
TaskCategory::Other, queuedSender.forget());
} else {
NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender);
}
return NS_OK;
}
// This is the first notification to IME. So, we don't need to notify
@ -1604,7 +1622,17 @@ IMEContentObserver::IMENotificationSender::Run()
"posting IMENotificationSender to current thread", this));
mIMEContentObserver->mQueuedSender =
new IMENotificationSender(mIMEContentObserver);
NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender);
nsIScriptGlobalObject* globalObject =
mIMEContentObserver->mDocShell ?
mIMEContentObserver->mDocShell->GetScriptGlobalObject() : nullptr;
if (globalObject) {
RefPtr<IMENotificationSender> queuedSender =
mIMEContentObserver->mQueuedSender;
globalObject->Dispatch("IMENotificationSender",
TaskCategory::Other, queuedSender.forget());
} else {
NS_DispatchToCurrentThread(mIMEContentObserver->mQueuedSender);
}
}
}
return NS_OK;

Просмотреть файл

@ -89,6 +89,10 @@ FileSystemSecurity::ContentProcessHasAccessTo(ContentParentId aId,
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
if (FindInReadable(NS_LITERAL_STRING(".."), aPath)) {
return false;
}
nsTArray<nsString>* paths;
if (!mPaths.Get(aId, &paths)) {
return false;

Просмотреть файл

@ -2734,7 +2734,11 @@ TabChild::InitAPZState()
// The ContentProcessController will hold a reference to the tab, and will be destroyed by the compositor or ipdl
// during destruction.
RefPtr<GeckoContentController> contentController = new ContentProcessController(this);
cbc->SendPAPZConstructor(new APZChild(contentController), mLayersId);
APZChild* apzChild = new APZChild(contentController);
cbc->SetEventTargetForActor(
apzChild, TabGroup()->EventTargetFor(TaskCategory::Other));
MOZ_ASSERT(apzChild->GetActorEventTarget());
cbc->SendPAPZConstructor(apzChild, mLayersId);
}
void

Просмотреть файл

@ -2700,7 +2700,8 @@ MediaDecoderStateMachine::CreateAudioSink()
auto audioSinkCreator = [self] () {
MOZ_ASSERT(self->OnTaskQueue());
AudioSink* audioSink = new AudioSink(
self->mTaskQueue, self->mAudioQueue, self->GetMediaTime(),
self->mTaskQueue, self->mAudioQueue,
TimeUnit::FromMicroseconds(self->GetMediaTime()),
self->Info().mAudio, self->mAudioChannel);
self->mAudibleListener = audioSink->AudibleEvent().Connect(
@ -3492,7 +3493,7 @@ MediaDecoderStateMachine::UpdatePlaybackPositionPeriodically()
// Cap the current time to the larger of the audio and video end time.
// This ensures that if we're running off the system clock, we don't
// advance the clock to after the media end time.
if (VideoEndTime() != -1 || AudioEndTime() != -1) {
if (VideoEndTime() > 0 || AudioEndTime() > 0) {
const int64_t clockTime = GetClock();
// Skip frames up to the frame at the playback position, and figure out
@ -3651,7 +3652,7 @@ MediaDecoderStateMachine::AudioEndTime() const
if (mMediaSink->IsStarted()) {
return mMediaSink->GetEndTime(TrackInfo::kAudioTrack);
}
return -1;
return 0;
}
int64_t
@ -3661,7 +3662,7 @@ MediaDecoderStateMachine::VideoEndTime() const
if (mMediaSink->IsStarted()) {
return mMediaSink->GetEndTime(TrackInfo::kVideoTrack);
}
return -1;
return 0;
}
void

Просмотреть файл

@ -170,7 +170,11 @@ private:
DECL_MEDIA_PREF("media.rust.test_mode", RustTestMode, bool, false);
#endif
#if defined(OS_LINUX) && defined(DEBUG)
DECL_MEDIA_PREF("media.rust.mp4parser", EnableRustMP4Parser, bool, true);
#else
DECL_MEDIA_PREF("media.rust.mp4parser", EnableRustMP4Parser, bool, false);
#endif
public:
// Manage the singleton:

Просмотреть файл

@ -11,6 +11,7 @@
#include "nsDeque.h"
#include "MediaEventSource.h"
#include "TimeUnits.h"
namespace mozilla {
@ -131,6 +132,11 @@ public:
}
}
void GetElementsAfter(const media::TimeUnit& aTime,
nsTArray<RefPtr<T>>* aResult) {
GetElementsAfter(aTime.ToMicroseconds(), aResult);
}
void GetFirstElements(uint32_t aMaxElements, nsTArray<RefPtr<T>>* aResult) {
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
for (size_t i = 0; i < aMaxElements && i < GetSize(); ++i) {

Просмотреть файл

@ -12,6 +12,7 @@
#include "mozilla/FloatingPoint.h"
#include "mozilla/Maybe.h"
#include "mozilla/dom/TimeRanges.h"
#include "mozilla/TimeStamp.h"
namespace mozilla {
namespace media {
@ -105,7 +106,7 @@ public:
}
}
static TimeUnit FromMicroseconds(int64_t aValue) {
static constexpr TimeUnit FromMicroseconds(int64_t aValue) {
return TimeUnit(aValue);
}
@ -113,14 +114,22 @@ public:
return TimeUnit(aValue.mValue);
}
static TimeUnit FromNanoseconds(int64_t aValue) {
static constexpr TimeUnit FromNanoseconds(int64_t aValue) {
return TimeUnit(aValue / 1000);
}
static TimeUnit FromInfinity() {
static constexpr TimeUnit FromInfinity() {
return TimeUnit(INT64_MAX);
}
static TimeUnit FromTimeDuration(const TimeDuration& aDuration) {
return FromSeconds(aDuration.ToSeconds());
}
static constexpr TimeUnit Zero() {
return TimeUnit(0);
}
static TimeUnit Invalid() {
TimeUnit ret;
ret.mValue = CheckedInt64(INT64_MAX);
@ -144,6 +153,10 @@ public:
return double(mValue.value()) / USECS_PER_S;
}
TimeDuration ToTimeDuration() const {
return TimeDuration::FromMicroseconds(mValue.value());
}
bool IsInfinite() const {
return mValue.value() == INT64_MAX;
}
@ -207,7 +220,7 @@ public:
return mValue.isValid();
}
TimeUnit()
constexpr TimeUnit()
: mValue(CheckedInt64(0))
{}
@ -225,7 +238,7 @@ public:
TimeUnit& operator = (const TimeUnit&) = default;
private:
explicit TimeUnit(CheckedInt64 aMicroseconds)
explicit constexpr TimeUnit(CheckedInt64 aMicroseconds)
: mValue(aMicroseconds)
{}

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/Unused.h"
#include "nsPrintfCString.h"
#include "base/time.h"
#include "GMPUtils.h"
namespace mozilla {
namespace gmp {
@ -154,15 +155,11 @@ ToString(const cdm::KeyInformation* aKeysInfo, uint32_t aKeysInfoCount)
{
nsCString str;
for (uint32_t i = 0; i < aKeysInfoCount; i++) {
nsCString keyId;
const cdm::KeyInformation& key = aKeysInfo[i];
for (size_t k = 0; k < key.key_id_size; k++) {
keyId.Append(nsPrintfCString("%hhX", key.key_id[k]));
}
if (!str.IsEmpty()) {
str.AppendLiteral(",");
}
str.Append(keyId);
const cdm::KeyInformation& key = aKeysInfo[i];
str.Append(ToHexString(key.key_id, key.key_id_size));
str.AppendLiteral("=");
str.AppendInt(key.status);
}
@ -509,7 +506,8 @@ mozilla::ipc::IPCResult
ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer)
{
MOZ_ASSERT(IsOnMessageLoopThread());
GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame()");
GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() t=%" PRId64 ")",
aBuffer.mTimestamp());
MOZ_ASSERT(mDecoderInitialized);
// The output frame may not have the same timestamp as the frame we put in.
@ -525,8 +523,9 @@ ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer)
WidevineVideoFrame frame;
cdm::Status rv = mCDM->DecryptAndDecodeFrame(input, &frame);
GMP_LOG("WidevineVideoDecoder::Decode(timestamp=%" PRId64 ") rv=%d",
input.timestamp,
GMP_LOG("ChromiumCDMChild::RecvDecryptAndDecodeFrame() t=%" PRId64
" CDM decoder rv=%d",
aBuffer.mTimestamp(),
rv);
switch (rv) {

Просмотреть файл

@ -33,11 +33,10 @@ static const int32_t LOW_AUDIO_USECS = 300000;
AudioSink::AudioSink(AbstractThread* aThread,
MediaQueue<AudioData>& aAudioQueue,
int64_t aStartTime,
TimeUnit aStartTime,
const AudioInfo& aInfo,
dom::AudioChannel aChannel)
: mStartTime(aStartTime)
, mLastGoodPosition(0)
, mInfo(aInfo)
, mChannel(aChannel)
, mPlaying(true)
@ -48,7 +47,6 @@ AudioSink::AudioSink(AbstractThread* aThread,
, mOwnerThread(aThread)
, mProcessedQueueLength(0)
, mFramesParsed(0)
, mLastEndTime(0)
, mIsAudioDataAudible(false)
, mAudioQueue(aAudioQueue)
{
@ -103,12 +101,13 @@ AudioSink::Init(const PlaybackParams& aParams)
return p;
}
int64_t
TimeUnit
AudioSink::GetPosition()
{
int64_t pos;
int64_t tmp;
if (mAudioStream &&
(pos = mAudioStream->GetPosition()) >= 0) {
(tmp = mAudioStream->GetPosition()) >= 0) {
TimeUnit pos = TimeUnit::FromMicroseconds(tmp);
NS_ASSERTION(pos >= mLastGoodPosition,
"AudioStream position shouldn't go backward");
// Update the last good position when we got a good one.
@ -221,7 +220,7 @@ AudioSink::InitializeAudioStream(const PlaybackParams& aParams)
return NS_OK;
}
int64_t
TimeUnit
AudioSink::GetEndTime() const
{
int64_t written;
@ -229,14 +228,14 @@ AudioSink::GetEndTime() const
MonitorAutoLock mon(mMonitor);
written = mWritten;
}
CheckedInt64 playedUsecs = FramesToUsecs(written, mOutputRate) + mStartTime;
if (!playedUsecs.isValid()) {
TimeUnit played = FramesToTimeUnit(written, mOutputRate) + mStartTime;
if (!played.IsValid()) {
NS_WARNING("Int overflow calculating audio end time");
return -1;
return TimeUnit::Zero();
}
// As we may be resampling, rounding errors may occur. Ensure we never get
// past the original end time.
return std::min<int64_t>(mLastEndTime, playedUsecs.value());
return std::min(mLastEndTime, played);
}
UniquePtr<AudioStream::Chunk>
@ -407,8 +406,8 @@ AudioSink::NotifyAudioNeeded()
// audio hardware, so we can play across the gap.
// Calculate the timestamp of the next chunk of audio in numbers of
// samples.
CheckedInt64 sampleTime = UsecsToFrames(data->mTime - mStartTime,
data->mRate);
CheckedInt64 sampleTime = TimeUnitToFrames(
TimeUnit::FromMicroseconds(data->mTime) - mStartTime, data->mRate);
// Calculate the number of frames that have been pushed onto the audio hardware.
CheckedInt64 missingFrames = sampleTime - mFramesParsed;
@ -450,7 +449,7 @@ AudioSink::NotifyAudioNeeded()
}
}
mLastEndTime = data->GetEndTime();
mLastEndTime = TimeUnit::FromMicroseconds(data->GetEndTime());
mFramesParsed += data->mFrames;
if (mConverter->InputConfig() != mConverter->OutputConfig()) {

Просмотреть файл

@ -32,7 +32,7 @@ class AudioSink : private AudioStream::DataSource {
public:
AudioSink(AbstractThread* aThread,
MediaQueue<AudioData>& aAudioQueue,
int64_t aStartTime,
TimeUnit aStartTime,
const AudioInfo& aInfo,
dom::AudioChannel aChannel);
@ -46,8 +46,8 @@ public:
* All public functions are not thread-safe.
* Called on the task queue of MDSM only.
*/
int64_t GetPosition();
int64_t GetEndTime() const;
TimeUnit GetPosition();
TimeUnit GetEndTime() const;
// Check whether we've pushed more frames to the audio hardware than it has
// played.
@ -80,15 +80,15 @@ private:
// The audio stream resource. Used on the task queue of MDSM only.
RefPtr<AudioStream> mAudioStream;
// The presentation time of the first audio frame that was played in
// microseconds. We can add this to the audio stream position to determine
// The presentation time of the first audio frame that was played.
// We can add this to the audio stream position to determine
// the current audio time.
const int64_t mStartTime;
const TimeUnit mStartTime;
// Keep the last good position returned from the audio stream. Used to ensure
// position returned by GetPosition() is mono-increasing in spite of audio
// stream error. Used on the task queue of MDSM only.
int64_t mLastGoodPosition;
TimeUnit mLastGoodPosition;
const AudioInfo mInfo;
@ -149,7 +149,7 @@ private:
// at the current input framerate.
int64_t mFramesParsed;
Maybe<RefPtr<AudioData>> mLastProcessedPacket;
int64_t mLastEndTime;
TimeUnit mLastEndTime;
// Never modifed after construction.
uint32_t mOutputRate;
uint32_t mOutputChannels;

Просмотреть файл

@ -58,9 +58,9 @@ AudioSinkWrapper::GetEndTime(TrackType aType) const
AssertOwnerThread();
MOZ_ASSERT(mIsStarted, "Must be called after playback starts.");
if (aType == TrackInfo::kAudioTrack && mAudioSink) {
return mAudioSink->GetEndTime();
return mAudioSink->GetEndTime().ToMicroseconds();
}
return -1;
return 0;
}
int64_t
@ -85,7 +85,7 @@ AudioSinkWrapper::GetPosition(TimeStamp* aTimeStamp) const
if (!mAudioEnded) {
// Rely on the audio sink to report playback position when it is not ended.
pos = mAudioSink->GetPosition();
pos = mAudioSink->GetPosition().ToMicroseconds();
} else if (!mPlayStartTime.IsNull()) {
// Calculate playback position using system clock if we are still playing.
pos = GetVideoPosition(t);

Просмотреть файл

@ -27,7 +27,7 @@ namespace mozilla {
* way to DecodedStreamGraphListener from DecodedStream.
*/
struct PlaybackInfoInit {
int64_t mStartTime;
media::TimeUnit mStartTime;
MediaInfo mInfo;
};
@ -144,8 +144,8 @@ public:
// mNextVideoTime is the end timestamp for the last packet sent to the stream.
// Therefore video packets starting at or after this time need to be copied
// to the output stream.
int64_t mNextVideoTime; // microseconds
int64_t mNextAudioTime; // microseconds
media::TimeUnit mNextVideoTime;
media::TimeUnit mNextAudioTime;
// The last video image sent to the stream. Useful if we need to replicate
// the image.
RefPtr<layers::Image> mLastVideoImage;
@ -234,8 +234,9 @@ DecodedStreamData::GetDebugInfo()
"DecodedStreamData=%p mPlaying=%d mAudioFramesWritten=%" PRId64
" mNextAudioTime=%" PRId64 " mNextVideoTime=%" PRId64 " mHaveSentFinish=%d "
"mHaveSentFinishAudio=%d mHaveSentFinishVideo=%d",
this, mPlaying, mAudioFramesWritten, mNextAudioTime, mNextVideoTime,
mHaveSentFinish, mHaveSentFinishAudio, mHaveSentFinishVideo);
this, mPlaying, mAudioFramesWritten, mNextAudioTime.ToMicroseconds(),
mNextVideoTime.ToMicroseconds(), mHaveSentFinish, mHaveSentFinishAudio,
mHaveSentFinishVideo);
}
DecodedStream::DecodedStream(AbstractThread* aOwnerThread,
@ -298,8 +299,8 @@ DecodedStream::Start(int64_t aStartTime, const MediaInfo& aInfo)
AssertOwnerThread();
MOZ_ASSERT(mStartTime.isNothing(), "playback already started.");
mStartTime.emplace(aStartTime);
mLastOutputTime = 0;
mStartTime.emplace(FromMicroseconds(aStartTime));
mLastOutputTime = media::TimeUnit::Zero();
mInfo = aInfo;
mPlaying = true;
ConnectListener();
@ -345,7 +346,7 @@ DecodedStream::Start(int64_t aStartTime, const MediaInfo& aInfo)
MozPromiseHolder<GenericPromise> promise;
mFinishPromise = promise.Ensure(__func__);
PlaybackInfoInit init {
aStartTime, aInfo
FromMicroseconds(aStartTime), aInfo
};
nsCOMPtr<nsIRunnable> r =
new R(Move(init), Move(promise), mOutputStreamManager, mAbstractMainThread);
@ -447,7 +448,7 @@ DecodedStream::SetPreservesPitch(bool aPreservesPitch)
}
static void
SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
SendStreamAudio(DecodedStreamData* aStream, const media::TimeUnit& aStartTime,
AudioData* aData, AudioSegment* aOutput, uint32_t aRate,
const PrincipalHandle& aPrincipalHandle)
{
@ -458,14 +459,14 @@ SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
AudioData* audio = aData;
// This logic has to mimic AudioSink closely to make sure we write
// the exact same silences
CheckedInt64 audioWrittenOffset = aStream->mAudioFramesWritten +
UsecsToFrames(aStartTime, aRate);
CheckedInt64 audioWrittenOffset = aStream->mAudioFramesWritten
+ TimeUnitToFrames(aStartTime, aRate);
CheckedInt64 frameOffset = UsecsToFrames(audio->mTime, aRate);
if (!audioWrittenOffset.isValid() ||
!frameOffset.isValid() ||
// ignore packet that we've already processed
audio->GetEndTime() <= aStream->mNextAudioTime) {
audio->GetEndTime() <= aStream->mNextAudioTime.ToMicroseconds()) {
return;
}
@ -491,7 +492,7 @@ SendStreamAudio(DecodedStreamData* aStream, int64_t aStartTime,
aOutput->AppendFrames(buffer.forget(), channels, audio->mFrames, aPrincipalHandle);
aStream->mAudioFramesWritten += audio->mFrames;
aStream->mNextAudioTime = audio->GetEndTime();
aStream->mNextAudioTime = media::TimeUnit::FromMicroseconds(audio->GetEndTime());
}
void
@ -540,17 +541,17 @@ DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin,
static void
WriteVideoToMediaStream(MediaStream* aStream,
layers::Image* aImage,
int64_t aEndMicroseconds,
int64_t aStartMicroseconds,
const media::TimeUnit& aEnd,
const media::TimeUnit& aStart,
const mozilla::gfx::IntSize& aIntrinsicSize,
const TimeStamp& aTimeStamp,
VideoSegment* aOutput,
const PrincipalHandle& aPrincipalHandle)
{
RefPtr<layers::Image> image = aImage;
StreamTime duration =
aStream->MicrosecondsToStreamTimeRoundDown(aEndMicroseconds) -
aStream->MicrosecondsToStreamTimeRoundDown(aStartMicroseconds);
auto end = aStream->MicrosecondsToStreamTimeRoundDown(aEnd.ToMicroseconds());
auto start = aStream->MicrosecondsToStreamTimeRoundDown(aStart.ToMicroseconds());
StreamTime duration = end - start;
aOutput->AppendFrame(image.forget(), duration, aIntrinsicSize,
aPrincipalHandle, false, aTimeStamp);
}
@ -594,7 +595,7 @@ DecodedStream::SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHa
for (uint32_t i = 0; i < video.Length(); ++i) {
VideoData* v = video[i];
if (mData->mNextVideoTime < v->mTime) {
if (mData->mNextVideoTime.ToMicroseconds() < v->mTime) {
// Write last video frame to catch up. mLastVideoImage can be null here
// which is fine, it just means there's no video.
@ -604,19 +605,21 @@ DecodedStream::SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHa
// video frame). E.g. if we have a video frame that is 30 sec long
// and capture happens at 15 sec, we'll have to append a black frame
// that is 15 sec long.
WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage, v->mTime,
mData->mNextVideoTime, mData->mLastVideoImageDisplaySize,
tracksStartTimeStamp + TimeDuration::FromMicroseconds(v->mTime),
&output, aPrincipalHandle);
mData->mNextVideoTime = v->mTime;
WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage,
FromMicroseconds(v->mTime),
mData->mNextVideoTime, mData->mLastVideoImageDisplaySize,
tracksStartTimeStamp + TimeDuration::FromMicroseconds(v->mTime),
&output, aPrincipalHandle);
mData->mNextVideoTime = FromMicroseconds(v->mTime);
}
if (mData->mNextVideoTime < v->GetEndTime()) {
WriteVideoToMediaStream(sourceStream, v->mImage, v->GetEndTime(),
mData->mNextVideoTime, v->mDisplay,
tracksStartTimeStamp + TimeDuration::FromMicroseconds(v->GetEndTime()),
&output, aPrincipalHandle);
mData->mNextVideoTime = v->GetEndTime();
if (mData->mNextVideoTime.ToMicroseconds() < v->GetEndTime()) {
WriteVideoToMediaStream(sourceStream, v->mImage,
FromMicroseconds(v->GetEndTime()),
mData->mNextVideoTime, v->mDisplay,
tracksStartTimeStamp + TimeDuration::FromMicroseconds(v->GetEndTime()),
&output, aPrincipalHandle);
mData->mNextVideoTime = FromMicroseconds(v->GetEndTime());
mData->mLastVideoImage = v->mImage;
mData->mLastVideoImageDisplaySize = v->mDisplay;
}
@ -639,13 +642,13 @@ DecodedStream::SendVideo(bool aIsSameOrigin, const PrincipalHandle& aPrincipalHa
if (mData->mEOSVideoCompensation) {
VideoSegment endSegment;
// Calculate the deviation clock time from DecodedStream.
int64_t deviation_usec = sourceStream->StreamTimeToMicroseconds(1);
auto deviation = FromMicroseconds(sourceStream->StreamTimeToMicroseconds(1));
WriteVideoToMediaStream(sourceStream, mData->mLastVideoImage,
mData->mNextVideoTime + deviation_usec, mData->mNextVideoTime,
mData->mLastVideoImageDisplaySize,
tracksStartTimeStamp + TimeDuration::FromMicroseconds(mData->mNextVideoTime + deviation_usec),
&endSegment, aPrincipalHandle);
mData->mNextVideoTime += deviation_usec;
mData->mNextVideoTime + deviation, mData->mNextVideoTime,
mData->mLastVideoImageDisplaySize,
tracksStartTimeStamp + (mData->mNextVideoTime + deviation).ToTimeDuration(),
&endSegment, aPrincipalHandle);
mData->mNextVideoTime += deviation;
MOZ_ASSERT(endSegment.GetDuration() > 0);
if (!aIsSameOrigin) {
endSegment.ReplaceWithDisabled();
@ -672,7 +675,7 @@ DecodedStream::AdvanceTracks()
if (mInfo.HasVideo()) {
StreamTime videoEnd = mData->mStream->MicrosecondsToStreamTimeRoundDown(
mData->mNextVideoTime - mStartTime.ref());
(mData->mNextVideoTime - mStartTime.ref()).ToMicroseconds());
endPosition = std::max(endPosition, videoEnd);
}
@ -715,15 +718,15 @@ DecodedStream::GetEndTime(TrackType aType) const
{
AssertOwnerThread();
if (aType == TrackInfo::kAudioTrack && mInfo.HasAudio() && mData) {
CheckedInt64 t = mStartTime.ref() +
FramesToUsecs(mData->mAudioFramesWritten, mInfo.mAudio.mRate);
if (t.isValid()) {
return t.value();
auto t = mStartTime.ref() + FramesToTimeUnit(
mData->mAudioFramesWritten, mInfo.mAudio.mRate);
if (t.IsValid()) {
return t.ToMicroseconds();
}
} else if (aType == TrackInfo::kVideoTrack && mData) {
return mData->mNextVideoTime;
return mData->mNextVideoTime.ToMicroseconds();
}
return -1;
return 0;
}
int64_t
@ -736,14 +739,14 @@ DecodedStream::GetPosition(TimeStamp* aTimeStamp) const
if (aTimeStamp) {
*aTimeStamp = TimeStamp::Now();
}
return mStartTime.ref() + mLastOutputTime;
return (mStartTime.ref() + mLastOutputTime).ToMicroseconds();
}
void
DecodedStream::NotifyOutput(int64_t aTime)
{
AssertOwnerThread();
mLastOutputTime = aTime;
mLastOutputTime = FromMicroseconds(aTime);
int64_t currentTime = GetPosition();
// Remove audio samples that have been played by MSG from the queue.
@ -784,9 +787,10 @@ nsCString
DecodedStream::GetDebugInfo()
{
AssertOwnerThread();
int64_t startTime = mStartTime.isSome() ? mStartTime->ToMicroseconds() : -1;
return nsPrintfCString(
"DecodedStream=%p mStartTime=%" PRId64 " mLastOutputTime=%" PRId64 " mPlaying=%d mData=%p",
this, mStartTime.valueOr(-1), mLastOutputTime, mPlaying, mData.get())
this, startTime, mLastOutputTime.ToMicroseconds(), mPlaying, mData.get())
+ (mData ? nsCString("\n") + mData->GetDebugInfo() : nsCString());
}

Просмотреть файл

@ -71,6 +71,10 @@ protected:
virtual ~DecodedStream();
private:
media::TimeUnit FromMicroseconds(int64_t aTime)
{
return media::TimeUnit::FromMicroseconds(aTime);
}
void DestroyData(UniquePtr<DecodedStreamData> aData);
void AdvanceTracks();
void SendAudio(double aVolume, bool aIsSameOrigin, const PrincipalHandle& aPrincipalHandle);
@ -107,8 +111,8 @@ private:
PlaybackParams mParams;
Maybe<int64_t> mStartTime;
int64_t mLastOutputTime = 0; // microseconds
media::NullableTimeUnit mStartTime;
media::TimeUnit mLastOutputTime;
MediaInfo mInfo;
MediaQueue<AudioData>& mAudioQueue;

Просмотреть файл

@ -60,7 +60,7 @@ public:
virtual RefPtr<GenericPromise> OnEnded(TrackType aType) = 0;
// Return the end time of the audio/video data that has been consumed
// or -1 if no such track.
// or 0 if no such track.
// Must be called after playback starts.
virtual int64_t GetEndTime(TrackType aType) const = 0;

Просмотреть файл

@ -41,7 +41,7 @@ VideoSink::VideoSink(AbstractThread* aThread,
, mContainer(aContainer)
, mProducerID(ImageContainer::AllocateProducerID())
, mFrameStats(aFrameStats)
, mVideoFrameEndTime(-1)
, mVideoFrameEndTime(0)
, mHasVideo(false)
, mUpdateScheduler(aThread)
, mVideoQueueSendToCompositorSize(aVQueueSentToCompositerSize)
@ -95,7 +95,7 @@ VideoSink::GetEndTime(TrackType aType) const
} else if (aType == TrackInfo::kAudioTrack) {
return mAudioSink->GetEndTime(aType);
}
return -1;
return 0;
}
int64_t
@ -225,7 +225,7 @@ VideoSink::Stop()
mEndPromiseHolder.ResolveIfExists(true, __func__);
mEndPromise = nullptr;
}
mVideoFrameEndTime = -1;
mVideoFrameEndTime = 0;
}
bool

Просмотреть файл

@ -1073,6 +1073,10 @@ WebMTrackDemuxer::Seek(const media::TimeUnit& aTime)
mParent->SeekInternal(mType, aTime);
nsresult rv = mParent->GetNextPacket(mType, &mSamples);
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
// Ignore the error for now, the next GetSample will be rejected with EOS.
return SeekPromise::CreateAndResolve(media::TimeUnit(), __func__);
}
return SeekPromise::CreateAndReject(rv, __func__);
}
mNeedKeyframe = true;

Просмотреть файл

@ -112,7 +112,9 @@ class AudioRunnable : public mozilla::Runnable
public:
NS_DECL_NSIRUNNABLE
AudioRunnable(ANPAudioTrack* aAudioTrack) {
AudioRunnable(ANPAudioTrack* aAudioTrack) :
Runnable("AudioRunnable")
{
mTrack = aAudioTrack;
}

Просмотреть файл

@ -557,7 +557,10 @@ NPPExceptionAutoHolder::~NPPExceptionAutoHolder()
nsPluginThreadRunnable::nsPluginThreadRunnable(NPP instance,
PluginThreadCallback func,
void *userData)
: mInstance(instance), mFunc(func), mUserData(userData)
: Runnable("nsPluginThreadRunnable"),
mInstance(instance),
mFunc(func),
mUserData(userData)
{
if (!sPluginThreadAsyncCallLock) {
// Failed to create lock, not much we can do here then...

Просмотреть файл

@ -68,7 +68,12 @@ class PluginEventRunnable : public Runnable
{
public:
PluginEventRunnable(nsNPAPIPluginInstance* instance, ANPEvent* event)
: mInstance(instance), mEvent(*event), mCanceled(false) {}
: Runnable("PluginEventRunnable"),
mInstance(instance),
mEvent(*event),
mCanceled(false)
{
}
virtual nsresult Run() {
if (mCanceled)

Просмотреть файл

@ -1301,7 +1301,10 @@ nsPluginHost::GetPluginForContentProcess(uint32_t aPluginId, nsNPAPIPlugin** aPl
class nsPluginUnloadRunnable : public Runnable
{
public:
explicit nsPluginUnloadRunnable(uint32_t aPluginId) : mPluginId(aPluginId) {}
explicit nsPluginUnloadRunnable(uint32_t aPluginId) :
Runnable("nsPluginUnloadRunnable"),
mPluginId(aPluginId)
{}
NS_IMETHOD Run() override
{
@ -3964,7 +3967,8 @@ class nsPluginDestroyRunnable : public Runnable,
{
public:
explicit nsPluginDestroyRunnable(nsNPAPIPluginInstance *aInstance)
: mInstance(aInstance)
: Runnable("nsPluginDestroyRunnable"),
mInstance(aInstance)
{
PR_INIT_CLIST(this);
PR_APPEND_LINK(this, &sRunnableListHead);

Просмотреть файл

@ -134,7 +134,9 @@ class AsyncPaintWaitEvent : public Runnable
{
public:
AsyncPaintWaitEvent(nsIContent* aContent, bool aFinished) :
mContent(aContent), mFinished(aFinished)
Runnable("AsyncPaintWaitEvent"),
mContent(aContent),
mFinished(aFinished)
{
}

Просмотреть файл

@ -67,7 +67,8 @@ protected:
LPARAM mLParam;
};
PluginWindowEvent::PluginWindowEvent()
PluginWindowEvent::PluginWindowEvent() :
Runnable("PluginWindowEvent")
{
Clear();
}
@ -160,7 +161,8 @@ class nsDelayedPopupsEnabledEvent : public Runnable
{
public:
explicit nsDelayedPopupsEnabledEvent(nsNPAPIPluginInstance *inst)
: mInst(inst)
: Runnable("nsDelayedPopupsEnabledEvent"),
mInst(inst)
{}
NS_DECL_NSIRUNNABLE

Просмотреть файл

@ -38,7 +38,8 @@ class nsPluginHangUITelemetry : public mozilla::Runnable
public:
nsPluginHangUITelemetry(int aResponseCode, int aDontAskCode,
uint32_t aResponseTimeMs, uint32_t aTimeoutMs)
: mResponseCode(aResponseCode),
: Runnable("nsPluginHangUITelemetry"),
mResponseCode(aResponseCode),
mDontAskCode(aDontAskCode),
mResponseTimeMs(aResponseTimeMs),
mTimeoutMs(aTimeoutMs)

Просмотреть файл

@ -23,7 +23,8 @@ class DeferNPObjectReleaseRunnable : public mozilla::Runnable
{
public:
DeferNPObjectReleaseRunnable(const NPNetscapeFuncs* f, NPObject* o)
: mFuncs(f)
: Runnable("DeferNPObjectReleaseRunnable")
, mFuncs(f)
, mObject(o)
{
NS_ASSERTION(o, "no release null objects");

Просмотреть файл

@ -2070,7 +2070,10 @@ class GetKeyStateTask : public Runnable
public:
explicit GetKeyStateTask(int aVirtKey, HANDLE aSemaphore, SHORT* aKeyState) :
mVirtKey(aVirtKey), mSemaphore(aSemaphore), mKeyState(aKeyState)
Runnable("GetKeyStateTask"),
mVirtKey(aVirtKey),
mSemaphore(aSemaphore),
mKeyState(aKeyState)
{}
NS_IMETHOD Run() override
@ -2141,8 +2144,9 @@ class GetFileNameTask : public Runnable
public:
explicit GetFileNameTask(GetFileNameFunc func, void* aLpOpenFileName,
HANDLE aSemaphore, BOOL* aReturnValue) :
mLpOpenFileName(aLpOpenFileName), mSemaphore(aSemaphore),
mReturnValue(aReturnValue), mFunc(func)
Runnable("GetFileNameTask"), mLpOpenFileName(aLpOpenFileName),
mSemaphore(aSemaphore), mReturnValue(aReturnValue),
mFunc(func)
{}
NS_IMETHOD Run() override

Просмотреть файл

@ -154,7 +154,8 @@ class mozilla::plugins::FinishInjectorInitTask : public mozilla::CancelableRunna
{
public:
FinishInjectorInitTask()
: mMutex("FlashInjectorInitTask::mMutex")
: CancelableRunnable("FinishInjectorInitTask")
, mMutex("FlashInjectorInitTask::mMutex")
, mParent(nullptr)
, mMainThreadMsgLoop(MessageLoop::current())
{

Просмотреть файл

@ -22,7 +22,8 @@ class AudioDeviceChangedRunnable : public Runnable
public:
explicit AudioDeviceChangedRunnable(const PluginModuleSet* aAudioNotificationSet,
NPAudioDeviceChangeDetailsIPC aChangeDetails) :
mChangeDetails(aChangeDetails)
Runnable("AudioDeviceChangedRunnable")
, mChangeDetails(aChangeDetails)
, mAudioNotificationSet(aAudioNotificationSet)
{}

Просмотреть файл

@ -16,14 +16,17 @@
#include "dirent.h"
#include "poll.h"
#include "sys/stat.h"
#if defined(ANDROID)
#if defined(XP_LINUX)
#include <sys/vfs.h>
#define statvfs statfs
#define f_frsize f_bsize
#else
#include "sys/statvfs.h"
#endif // defined(XP_LINUX)
#if !defined(ANDROID)
#include "sys/wait.h"
#include <spawn.h>
#endif // defined(ANDROID)
#endif // !defined(ANDROID)
#endif // defined(XP_UNIX)
#if defined(XP_LINUX)
@ -699,7 +702,7 @@ static const dom::ConstantSpec gLibcProperties[] =
{ "OSFILE_SIZEOF_STATVFS", JS::Int32Value(sizeof (struct statvfs)) },
{ "OSFILE_OFFSETOF_STATVFS_F_BSIZE", JS::Int32Value(offsetof (struct statvfs, f_bsize)) },
{ "OSFILE_OFFSETOF_STATVFS_F_FRSIZE", JS::Int32Value(offsetof (struct statvfs, f_frsize)) },
{ "OSFILE_OFFSETOF_STATVFS_F_BAVAIL", JS::Int32Value(offsetof (struct statvfs, f_bavail)) },
#endif // defined(XP_UNIX)

Просмотреть файл

@ -6,9 +6,15 @@ var success = 0;
try {
parent[name].success = 1;
parent.postMessage(success ? "success" : "failure", "http://mochi.test:8888");
parent.postMessage({
from: name,
result: success ? "success" : "failure"
}, "http://mochi.test:8888");
} catch (e) {
parent.postMessage(e.toString(), "http://mochi.test:8888");
parent.postMessage({
from: name,
result: e.toString()
}, "http://mochi.test:8888");
}
</script>

Просмотреть файл

@ -15,22 +15,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=440572
/** Test for Bug 440572 **/
var messages = [];
var messages = new Map();
function receiveMessage(e)
{
is(e.origin, "http://example.org", "wrong sender!");
messages.push(e.data);
messages.set(e.data.from, e.data.result);
}
window.addEventListener("message", receiveMessage);
function runtests()
{
is(messages.length, 3, "received the right number of messages.");
is(messages[0], "success", "test in frame failed.");
isnot(messages[1], "success", "parent[\"content\"] should be the WebIDL property of Window.");
isnot(messages[2], "success", "parent[\"dump\"] should be the WebIDL property of Window.");
is(messages.size, 3, "received the right number of messages.");
is(messages.get("test"), "success", "test in frame failed.");
isnot(messages.get("content"), "success", "parent[\"content\"] should be the WebIDL property of Window.");
isnot(messages.get("dump"), "success", "parent[\"dump\"] should be the WebIDL property of Window.");
SimpleTest.finish();
}

Просмотреть файл

@ -548,7 +548,7 @@ var interfaceNamesInGlobalScope =
// IMPORTANT: Do not change this list without review from a DOM peer!
"HTMLVideoElement",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "IdleDeadline", nightly: true},
{name: "IdleDeadline"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"IDBCursor",
// IMPORTANT: Do not change this list without review from a DOM peer!

Просмотреть файл

@ -6,5 +6,6 @@ support-files =
WebVRHelpers.js
[test_vrDisplay_getFrameData.html]
[test_vrDisplay_exitPresent.html]
[test_vrDisplay_requestPresent.html]
skip-if = true

Просмотреть файл

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>VRDisplay ExitPresent</title>
<meta name="timeout" content="long"/>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="runVRTest.js"></script>
</head>
<body>
<script>
function testExitPresentOnOtherIframe(content) {
return content.navigator.getVRDisplays().then((displays) => {
content.vrDisplay = displays[0];
return content.vrDisplay.exitPresent();
});
}
var initVRPresentation = function(content) {
return content.navigator.getVRDisplays().then((displays) => {
console.log("GetVRDisplay!!");
content.vrDisplay = displays[0];
content.canvas = content.document.createElement("canvas");
content.canvas.id = "vrCanvas";
return content.vrDisplay.requestPresent([{source:content.canvas}]);
});
}
function startTest() {
var ifr1 = document.getElementById("iframe1");
var ifr2 = document.getElementById("iframe2");
var frame1 = ifr1.contentWindow;
var frame2 = ifr2.contentWindow;
initVRPresentation(frame1).then(() => {
promise_test((test) => {
return promise_rejects(test, null, testExitPresentOnOtherIframe(frame2));
}, "We cannot exist VR presentation established by another content, this promise is expected to be rejected.")
});
}
runVRTest(startTest);
</script>
<iframe id="iframe1"></iframe>
<iframe id="iframe2"></iframe>
</body>
</html>

Просмотреть файл

@ -24,6 +24,16 @@ interface ThreadSafeChromeUtils {
[Throws]
static DOMString saveHeapSnapshot(optional HeapSnapshotBoundaries boundaries);
/**
* This is the same as saveHeapSnapshot, but with a different return value.
*
* @returns The snapshot ID of the file. This is the file name
* without the temp directory or the trailing
* `.fxsnapshot`.
*/
[Throws]
static DOMString saveHeapSnapshotGetId(optional HeapSnapshotBoundaries boundaries);
/**
* Deserialize a core dump into a HeapSnapshot.
*

Просмотреть файл

@ -675,7 +675,6 @@ nsBindingManager::WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc,
do {
nsXBLBinding *binding = content->GetXBLBinding();
if (binding) {
aData->mTreeMatchContext.mScopedRoot = content;
binding->WalkRules(aFunc, aData);
// If we're not looking at our original content, allow the binding to cut
// off style inheritance
@ -698,9 +697,6 @@ nsBindingManager::WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc,
// in the loop.
*aCutOffInheritance = (content != nullptr);
// Null out the scoped root that we set repeatedly
aData->mTreeMatchContext.mScopedRoot = nullptr;
return NS_OK;
}

Просмотреть файл

@ -10,6 +10,8 @@
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Move.h"
#include "mozilla/Preferences.h"
@ -205,6 +207,12 @@ APZEventState::ProcessSingleTap(const CSSPoint& aPoint,
APZES_LOG("Active element uses style, scheduling timer for click event\n");
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
TabChild* tabChild = widget->GetOwningTabChild();
if (tabChild && XRE_IsContentProcess()) {
timer->SetTarget(
tabChild->TabGroup()->EventTargetFor(TaskCategory::Other));
}
RefPtr<DelayedFireSingleTapEvent> callback =
new DelayedFireSingleTapEvent(mWidget, ldPoint, aModifiers, aClickCount,
timer, touchRollup);

Просмотреть файл

@ -6,8 +6,8 @@
#include "mozilla/layers/AnimationMetricsTracker.h"
#include <algorithm>
#include <cmath>
#include <inttypes.h>
#include "mozilla/Telemetry.h"
#define AMT_LOG(...)
// #define AMT_LOG(...) printf_stderr("AMT: " __VA_ARGS__)
@ -16,6 +16,7 @@ namespace mozilla {
namespace layers {
AnimationMetricsTracker::AnimationMetricsTracker()
: mMaxLayerAreaAnimated(0)
{
}
@ -24,15 +25,17 @@ AnimationMetricsTracker::~AnimationMetricsTracker()
}
void
AnimationMetricsTracker::UpdateAnimationInProgress(bool aInProgress,
uint64_t aLayerArea)
AnimationMetricsTracker::UpdateAnimationInProgress(AnimationProcessTypes aActive,
uint64_t aLayerArea,
TimeDuration aVsyncInterval)
{
MOZ_ASSERT(aInProgress || aLayerArea == 0);
if (mCurrentAnimationStart && !aInProgress) {
bool inProgress = (aActive != AnimationProcessTypes::eNone);
MOZ_ASSERT(inProgress || aLayerArea == 0);
if (mCurrentAnimationStart && !inProgress) {
AnimationEnded();
mCurrentAnimationStart = TimeStamp();
mMaxLayerAreaAnimated = 0;
} else if (aInProgress) {
} else if (inProgress) {
if (!mCurrentAnimationStart) {
mCurrentAnimationStart = TimeStamp::Now();
mMaxLayerAreaAnimated = aLayerArea;
@ -41,6 +44,31 @@ AnimationMetricsTracker::UpdateAnimationInProgress(bool aInProgress,
mMaxLayerAreaAnimated = std::max(mMaxLayerAreaAnimated, aLayerArea);
}
}
UpdateAnimationThroughput("chrome",
(aActive & AnimationProcessTypes::eChrome) != AnimationProcessTypes::eNone,
mChromeAnimation,
aVsyncInterval,
Telemetry::COMPOSITOR_ANIMATION_THROUGHPUT_CHROME,
Telemetry::COMPOSITOR_ANIMATION_MAX_CONTIGUOUS_DROPS_CHROME);
UpdateAnimationThroughput("content",
(aActive & AnimationProcessTypes::eContent) != AnimationProcessTypes::eNone,
mContentAnimation,
aVsyncInterval,
Telemetry::COMPOSITOR_ANIMATION_THROUGHPUT_CONTENT,
Telemetry::COMPOSITOR_ANIMATION_MAX_CONTIGUOUS_DROPS_CONTENT);
}
void
AnimationMetricsTracker::UpdateApzAnimationInProgress(bool aInProgress,
TimeDuration aVsyncInterval)
{
UpdateAnimationThroughput("apz",
aInProgress,
mApzAnimation,
aVsyncInterval,
Telemetry::COMPOSITOR_ANIMATION_THROUGHPUT_APZ,
Telemetry::COMPOSITOR_ANIMATION_MAX_CONTIGUOUS_DROPS_APZ);
}
void
@ -52,6 +80,7 @@ void
AnimationMetricsTracker::AnimationEnded()
{
MOZ_ASSERT(mCurrentAnimationStart);
Telemetry::AccumulateTimeDelta(Telemetry::COMPOSITOR_ANIMATION_DURATION, mCurrentAnimationStart);
Telemetry::Accumulate(Telemetry::COMPOSITOR_ANIMATION_MAX_LAYER_AREA, mMaxLayerAreaAnimated);
AMT_LOG("Ended animation; duration: %f ms, area: %" PRIu64 "\n",
@ -59,5 +88,78 @@ AnimationMetricsTracker::AnimationEnded()
mMaxLayerAreaAnimated);
}
void
AnimationMetricsTracker::UpdateAnimationThroughput(const char* aLabel,
bool aInProgress,
AnimationData& aAnimation,
TimeDuration aVsyncInterval,
Telemetry::HistogramID aThroughputHistogram,
Telemetry::HistogramID aMaxDropsHistogram)
{
if (aInProgress && !aAnimation.mStart) {
// the animation just started
aAnimation.mStart = TimeStamp::Now();
aAnimation.mLastFrameTime = aAnimation.mStart;
aAnimation.mLongestFrame = TimeDuration();
aAnimation.mFrameCount = 1;
AMT_LOG("Compositor animation of type %s just started\n", aLabel);
} else if (aInProgress && aAnimation.mStart) {
// the animation continues
aAnimation.mFrameCount++;
TimeStamp now = TimeStamp::Now();
aAnimation.mLongestFrame = std::max(aAnimation.mLongestFrame, now - aAnimation.mLastFrameTime);
aAnimation.mLastFrameTime = now;
} else if (!aInProgress && aAnimation.mStart) {
// the animation just ended
TimeStamp now = TimeStamp::Now();
// Get the length and clear aAnimation.mStart before the early-returns below
TimeDuration animationLength = now - aAnimation.mStart;
aAnimation.mStart = TimeStamp();
if (aVsyncInterval == TimeDuration::Forever()) {
AMT_LOG("Invalid vsync interval: forever\n");
return;
}
double vsyncIntervalMs = aVsyncInterval.ToMilliseconds();
if (vsyncIntervalMs < 1.0f) {
// Guard to avoid division by zero or other crazy results below
AMT_LOG("Invalid vsync interval: %fms\n", vsyncIntervalMs);
return;
}
// We round the expectedFrameCount because it's a count and should be an
// integer. The animationLength might not be an exact vsync multiple because
// it's taken during the composition process and the amount of work done
// between the vsync signal and the Timestamp::Now() call may vary slightly
// from one composite to another.
uint32_t expectedFrameCount = std::lround(animationLength.ToMilliseconds() / vsyncIntervalMs);
AMT_LOG("Type %s ran for %fms (interval: %fms), %u frames (expected: %u)\n",
aLabel, animationLength.ToMilliseconds(), vsyncIntervalMs,
aAnimation.mFrameCount, expectedFrameCount);
if (expectedFrameCount <= 0) {
// Graceful handling of probably impossible thing, unless the clock
// changes while running?
// Note that we also skip the frames-dropped probe if this happens,
// because we cannot be sure that the frame length measurements are valid.
return;
}
// Scale up by 1000 because telemetry takes ints, truncate intentionally
// to avoid artificial inflation of the result.
uint32_t frameHitRatio = (uint32_t)(1000.0f * aAnimation.mFrameCount / expectedFrameCount);
Telemetry::Accumulate(aThroughputHistogram, frameHitRatio);
AMT_LOG("Reported frameHitRatio %u\n", frameHitRatio);
// Get the longest frame time (make sure to check the final frame as well)
TimeDuration longestFrame = std::max(aAnimation.mLongestFrame, now - aAnimation.mLastFrameTime);
// As above, we round to get the frame count. Additionally we subtract one
// from the frame count to get the number of dropped frames.
uint32_t framesDropped = std::lround(longestFrame.ToMilliseconds() / vsyncIntervalMs) - 1;
AMT_LOG("Longest frame was %fms (%d drops)\n", longestFrame.ToMilliseconds(), framesDropped);
Telemetry::Accumulate(aMaxDropsHistogram, framesDropped);
}
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -6,11 +6,21 @@
#ifndef mozilla_layers_AnimationMetricsTracker_h
#define mozilla_layers_AnimationMetricsTracker_h
#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/TypedEnumBits.h"
namespace mozilla {
namespace layers {
enum class AnimationProcessTypes {
eNone = 0x0,
eContent = 0x1,
eChrome = 0x2
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AnimationProcessTypes)
/**
* Tracks the start and end of compositor animations.
*/
@ -21,17 +31,58 @@ public:
/**
* This function should be called per composite, to inform the metrics
* tracker if any animation is in progress, and if so, what area is
* being animated. The aLayerArea is in Layer pixels squared.
* tracker which processes have active animations. If there is are animations
* in progress, the sum of their areas should also be provided, along with
* the vsync interval.
*/
void UpdateAnimationInProgress(bool aInProgress, uint64_t aLayerArea);
void UpdateAnimationInProgress(AnimationProcessTypes aActive, uint64_t aLayerArea,
TimeDuration aVsyncInterval);
/**
* Similar to UpdateAnimationInProgress, but this is for APZ animations. Again,
* this should be called per composite.
*/
void UpdateApzAnimationInProgress(bool aInProgress, TimeDuration aVsyncInterval);
private:
// A struct to group data that we need for each type of compositor animation.
struct AnimationData {
// The start time of the current animation.
TimeStamp mStart;
// The timestamp of the most recent animation frame.
TimeStamp mLastFrameTime;
// The longest animation frame length encountered so far.
TimeDuration mLongestFrame;
// The number of frames composited for the current animation.
uint32_t mFrameCount;
AnimationData()
: mFrameCount(0)
{
}
};
void AnimationStarted();
void AnimationEnded();
void UpdateAnimationThroughput(const char* aLabel,
bool aInProgress,
AnimationData& aAnimationData,
TimeDuration aVsyncInterval,
Telemetry::HistogramID aThroughputHistogram,
Telemetry::HistogramID aMaxDropsHistogram);
// The start time of the current compositor animation. This just tracks
// whether the compositor is running an animation, without regard to which
// process the animation is coming from.
TimeStamp mCurrentAnimationStart;
// The max area (in layer pixels) that the current compositor animation
// has touched on any given animation frame.
uint64_t mMaxLayerAreaAnimated;
// We keep an instance of the struct for each type of compositor animation.
AnimationData mChromeAnimation;
AnimationData mContentAnimation;
AnimationData mApzAnimation;
};
} // namespace layers

Просмотреть файл

@ -645,26 +645,41 @@ ApplyAnimatedValue(Layer* aLayer,
}
}
static bool
static AnimationProcessTypes
SampleAnimations(Layer* aLayer,
CompositorAnimationStorage* aStorage,
TimeStamp aPoint,
uint64_t* aLayerAreaAnimated)
{
bool activeAnimations = false;
// This tracks the first-encountered RefLayer in the layer tree. Since we are
// doing a depth-first traversal, it is set to a non-null value if and only if
// the currently-being-traversed node has a RefLayer ancestor. In the case of
// nested RefLayers it points to the rootmost RefLayer.
RefLayer* ancestorRefLayer = nullptr;
// This bitfield-enum tracks which processes have active animations. Anything
// "above" the |ancestorRefLayer| in the layer tree is assumed to be the
// chrome process, and anything "below" is assumed to be the content process.
AnimationProcessTypes animProcess = AnimationProcessTypes::eNone;
ForEachNode<ForwardIterator>(
aLayer,
[aStorage, &activeAnimations, &aPoint, &aLayerAreaAnimated] (Layer* layer)
[&] (Layer* layer)
{
if (!ancestorRefLayer) {
ancestorRefLayer = layer->AsRefLayer();
}
bool hasInEffectAnimations = false;
StyleAnimationValue animationValue = layer->GetBaseAnimationStyle();
activeAnimations |=
AnimationHelper::SampleAnimationForEachNode(aPoint,
layer->GetAnimations(),
layer->GetAnimationData(),
animationValue,
hasInEffectAnimations);
if (AnimationHelper::SampleAnimationForEachNode(aPoint,
layer->GetAnimations(),
layer->GetAnimationData(),
animationValue,
hasInEffectAnimations)) {
animProcess |= (ancestorRefLayer ? AnimationProcessTypes::eContent
: AnimationProcessTypes::eChrome);
}
if (hasInEffectAnimations) {
Animation& animation = layer->GetAnimations().LastElement();
ApplyAnimatedValue(layer,
@ -676,9 +691,16 @@ SampleAnimations(Layer* aLayer,
*aLayerAreaAnimated += (layer->GetVisibleRegion().Area());
}
}
},
[&ancestorRefLayer] (Layer* aLayer)
{
// If we're unwinding up past the rootmost RefLayer, clear our pointer
if (ancestorRefLayer && aLayer->AsRefLayer() == ancestorRefLayer) {
ancestorRefLayer = nullptr;
}
});
return activeAnimations;
return animProcess;
}
static bool
@ -1336,15 +1358,16 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
// On the initial frame we use aVsyncTimestamp here so the timestamp on the
// second frame are the same as the initial frame, but it does not matter.
uint64_t layerAreaAnimated = 0;
bool wantNextFrame =
AnimationProcessTypes animationProcess =
SampleAnimations(root,
storage,
!mPreviousFrameTimeStamp.IsNull() ?
mPreviousFrameTimeStamp : aCurrentFrame,
&layerAreaAnimated);
bool wantNextFrame = (animationProcess != AnimationProcessTypes::eNone);
mAnimationMetricsTracker.UpdateAnimationInProgress(
wantNextFrame, layerAreaAnimated);
animationProcess, layerAreaAnimated, aVsyncRate);
if (!wantNextFrame) {
// Clean up the CompositorAnimationStorage because
@ -1388,7 +1411,9 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
nextFrame += aVsyncRate;
}
wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), nextFrame);
bool apzAnimating = SampleAPZAnimations(LayerMetricsWrapper(root), nextFrame);
mAnimationMetricsTracker.UpdateApzAnimationInProgress(apzAnimating, aVsyncRate);
wantNextFrame |= apzAnimating;
}
HostLayer* rootComposite = root->AsHostLayer();

Просмотреть файл

@ -737,20 +737,21 @@ DXGITextureHostD3D11::GetDevice()
if (mFlags & TextureFlags::INVALID_COMPOSITOR) {
return nullptr;
}
return mProvider->GetD3D11Device();
return mDevice;
}
void
DXGITextureHostD3D11::SetTextureSourceProvider(TextureSourceProvider* aProvider)
{
if (!aProvider || !aProvider->GetD3D11Device()) {
mDevice = nullptr;
mProvider = nullptr;
mTextureSource = nullptr;
return;
}
mProvider = aProvider;
mDevice = aProvider->GetD3D11Device();
if (mTextureSource) {
mTextureSource->SetTextureSourceProvider(aProvider);
@ -776,6 +777,9 @@ DXGITextureHostD3D11::LockWithoutCompositor()
// Unlike the normal Lock() function, this function may be called when
// mCompositor is nullptr such as during WebVR frame submission. So, there is
// no 'mCompositor' checking here.
if (!mDevice) {
mDevice = DeviceManagerDx::Get()->GetCompositorDevice();
}
return LockInternal();
}
@ -805,7 +809,11 @@ DXGITextureHostD3D11::LockInternal()
return false;
}
mTextureSource = new DataTextureSourceD3D11(mFormat, mProvider, mTexture);
if (mProvider) {
mTextureSource = new DataTextureSourceD3D11(mFormat, mProvider, mTexture);
} else {
mTextureSource = new DataTextureSourceD3D11(mDevice, mFormat, mTexture);
}
}
mIsLocked = LockD3DTexture(mTextureSource->GetD3D11Texture());
@ -895,12 +903,15 @@ void
DXGIYCbCrTextureHostD3D11::SetTextureSourceProvider(TextureSourceProvider* aProvider)
{
if (!aProvider || !aProvider->GetD3D11Device()) {
mProvider = nullptr;
mTextureSources[0] = nullptr;
mTextureSources[1] = nullptr;
mTextureSources[2] = nullptr;
return;
}
mProvider = aProvider;
if (mTextureSources[0]) {
mTextureSources[0]->SetTextureSourceProvider(aProvider);
}

Просмотреть файл

@ -333,6 +333,7 @@ protected:
bool OpenSharedHandle();
RefPtr<ID3D11Device> mDevice;
RefPtr<ID3D11Texture2D> mTexture;
RefPtr<DataTextureSourceD3D11> mTextureSource;
gfx::IntSize mSize;

Просмотреть файл

@ -12,6 +12,7 @@
#include "base/message_loop.h" // for MessageLoop
#include "base/task.h" // for NewRunnableMethod, etc
#include "gfxPrefs.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/APZChild.h"
#include "mozilla/layers/IAPZCTreeManager.h"
@ -1083,6 +1084,15 @@ CompositorBridgeChild::AllocPAPZCTreeManagerChild(const uint64_t& aLayersId)
{
APZCTreeManagerChild* child = new APZCTreeManagerChild();
child->AddRef();
if (aLayersId != 0) {
TabChild* tabChild = TabChild::GetFrom(aLayersId);
if (tabChild) {
SetEventTargetForActor(
child, tabChild->TabGroup()->EventTargetFor(TaskCategory::Other));
MOZ_ASSERT(child->GetActorEventTarget());
}
}
return child;
}

Просмотреть файл

@ -148,3 +148,9 @@ CompositorThreadHolder::IsInCompositorThread()
} // namespace mozilla
} // namespace layers
bool
NS_IsInCompositorThread()
{
return mozilla::layers::CompositorThreadHolder::IsInCompositorThread();
}

Просмотреть файл

@ -48,6 +48,11 @@ bool is_glcontext_egl(void* glcontext_ptr)
return glcontext->GetContextType() == mozilla::gl::GLContextType::EGL;
}
void gfx_critical_note(const char* msg)
{
gfxCriticalNote << msg;
}
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
{
MOZ_ASSERT(glcontext_ptr);

Просмотреть файл

@ -2296,10 +2296,13 @@ gfxPlatform::InitWebRenderConfig()
"WebRender is an opt-in feature",
NS_LITERAL_CSTRING("FEATURE_FAILURE_DEFAULT_OFF"));
if (Preferences::GetBool("gfx.webrender.enabled", false)) {
bool prefEnabled = Preferences::GetBool("gfx.webrender.enabled", false);
if (prefEnabled) {
featureWebRender.UserEnable("Enabled by pref");
}
ScopedGfxFeatureReporter reporter("WR", prefEnabled);
// WebRender relies on the GPU process when on Windows
#ifdef XP_WIN
if (!gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
@ -2325,7 +2328,10 @@ gfxPlatform::InitWebRenderConfig()
#endif
// gfxFeature is not usable in the GPU process, so we use gfxVars to transmit this feature
gfxVars::SetUseWebRender(gfxConfig::IsEnabled(Feature::WEBRENDER));
if (gfxConfig::IsEnabled(Feature::WEBRENDER)) {
gfxVars::SetUseWebRender(true);
reporter.SetSuccessful();
}
}
bool

Просмотреть файл

@ -5,6 +5,7 @@
#include "VRDisplayPresentation.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/Unused.h"
#include "VRDisplayClient.h"
#include "VRLayerChild.h"
@ -70,7 +71,16 @@ VRDisplayPresentation::CreateLayers()
continue;
}
RefPtr<VRLayerChild> vrLayer = static_cast<VRLayerChild*>(manager->CreateVRLayer(mDisplayClient->GetDisplayInfo().GetDisplayID(), leftBounds, rightBounds));
nsCOMPtr<nsIEventTarget> target;
nsIDocument* doc;
doc = canvasElement->OwnerDoc();
if (doc) {
target = doc->EventTargetFor(TaskCategory::Other);
}
RefPtr<VRLayerChild> vrLayer =
static_cast<VRLayerChild*>(manager->CreateVRLayer(mDisplayClient->GetDisplayInfo().GetDisplayID(),
leftBounds, rightBounds, target));
if (!vrLayer) {
NS_WARNING("CreateVRLayer returned null!");
continue;

Просмотреть файл

@ -401,11 +401,26 @@ VRManagerChild::DeallocShmem(ipc::Shmem& aShmem)
}
PVRLayerChild*
VRManagerChild::CreateVRLayer(uint32_t aDisplayID, const Rect& aLeftEyeRect, const Rect& aRightEyeRect)
VRManagerChild::CreateVRLayer(uint32_t aDisplayID,
const Rect& aLeftEyeRect,
const Rect& aRightEyeRect,
nsIEventTarget* aTarget)
{
return SendPVRLayerConstructor(aDisplayID,
aLeftEyeRect.x, aLeftEyeRect.y, aLeftEyeRect.width, aLeftEyeRect.height,
aRightEyeRect.x, aRightEyeRect.y, aRightEyeRect.width, aRightEyeRect.height);
PVRLayerChild* vrLayerChild = AllocPVRLayerChild(aDisplayID, aLeftEyeRect.x,
aLeftEyeRect.y, aLeftEyeRect.width,
aLeftEyeRect.height, aRightEyeRect.x,
aRightEyeRect.y, aRightEyeRect.width,
aRightEyeRect.height);
// Do the DOM labeling.
if (aTarget) {
SetEventTargetForActor(vrLayerChild, aTarget);
MOZ_ASSERT(vrLayerChild->GetActorEventTarget());
}
return SendPVRLayerConstructor(vrLayerChild, aDisplayID, aLeftEyeRect.x,
aLeftEyeRect.y, aLeftEyeRect.width,
aLeftEyeRect.height, aRightEyeRect.x,
aRightEyeRect.y, aRightEyeRect.width,
aRightEyeRect.height);
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше