Merge autoland to central, a=merge

MozReview-Commit-ID: 1tRIig3iCAm
This commit is contained in:
Wes Kocher 2017-07-06 15:34:32 -07:00
Родитель f1472e5b57 7f761bf821
Коммит ab1e399bcd
155 изменённых файлов: 1443 добавлений и 3259 удалений

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

@ -113,10 +113,6 @@ DEFAULT_FIREFOX_PREFS = {
'devtools.browsertoolbox.panel': 'jsdebugger',
'devtools.chrome.enabled' : True,
# From:
# https://hg.mozilla.org/mozilla-central/file/1dd81c324ac7/build/automation.py.in#l388
# Make url-classifier updates so rare that they won't affect tests.
'urlclassifier.updateinterval' : 172800,
# Point the url-classifier to a nonexistent local URL for fast failures.
'browser.safebrowsing.downloads.remote.url': 'http://localhost/safebrowsing-dummy/downloads',
'browser.safebrowsing.provider.google.gethashURL' : 'http://localhost/safebrowsing-dummy/gethash',

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

@ -3,7 +3,6 @@
"startup.homepage_welcome_url": "about:blank",
"devtools.browsertoolbox.panel": "jsdebugger",
"devtools.chrome.enabled": true,
"urlclassifier.updateinterval": 172800,
"browser.safebrowsing.provider.google.gethashURL": "http://localhost/safebrowsing-dummy/gethash",
"browser.safebrowsing.provider.google.updateURL": "http://localhost/safebrowsing-dummy/update",
"browser.safebrowsing.provider.google4.gethashURL": "http://localhost/safebrowsing4-dummy/gethash",

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

@ -1074,7 +1074,7 @@ pref("security.sandbox.gpu.level", 0);
// process is killed when all windows are closed, so a change will take effect
// when the 1st window is opened.
#if defined(NIGHTLY_BUILD)
pref("security.sandbox.content.level", 2);
pref("security.sandbox.content.level", 3);
#else
pref("security.sandbox.content.level", 1);
#endif

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

@ -91,6 +91,23 @@ var gTests = [
await indicator;
await checkSharingUI({screen: "Screen"});
// we always show prompt for screen sharing.
promise = promisePopupNotificationShown("webRTC-shareDevices");
await promiseRequestDevice(false, true, null, "screen");
await promise;
await expectObserverCalled("getUserMedia:request");
is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
"webRTC-shareScreen-notification-icon", "anchored to device icon");
checkDeviceSelectors(false, false, true);
await promiseMessage(permissionError, () => {
PopupNotifications.panel.firstChild.button.click();
});
await expectObserverCalled("getUserMedia:response:deny");
SitePermissions.remove(null, "screen", gBrowser.selectedBrowser);
await closeStream();
}
},

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

@ -330,9 +330,11 @@ this.PanelMultiView = class {
} else {
this._clickCapturer.removeEventListener("click", this);
}
this._panel.removeEventListener("mousemove", this);
this._panel.removeEventListener("popupshowing", this);
this._panel.removeEventListener("popupshown", this);
this._panel.removeEventListener("popuphidden", this);
this.window.removeEventListener("keydown", this);
this.node.dispatchEvent(new this.window.CustomEvent("destructed"));
this.node = this._clickCapturer = this._viewContainer = this._mainViewContainer =
this._subViews = this._viewStack = this.__dwu = this._panelViewCache = null;

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

@ -206,6 +206,8 @@ this.browserAction = class extends ExtensionAPI {
// with the fewest complications.
event.preventDefault();
this.emit("click", tabbrowser.selectedBrowser);
// Ensure we close any popups this node was in:
CustomizableUI.hidePanelForNode(event.target);
}
},
});

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

@ -68,7 +68,8 @@ async function testInArea(area) {
},
() => {
browser.test.log(`Call triggerAction, expect popup "a" again. Leave popup open.`);
sendClick({expectEvent: false, expectPopup: "a", closePopup: false}, "trigger-action");
sendClick({expectEvent: false, expectPopup: "a",
closePopup: false, containingPopupShouldClose: false}, "trigger-action");
},
() => {
browser.test.log(`Call triggerAction again. Expect remaining popup closed.`);
@ -109,7 +110,8 @@ async function testInArea(area) {
() => {
browser.test.log(`Set popup to "a" and click browser action. Expect popup "a", and leave open.`);
browser.browserAction.setPopup({popup: "/popup-a.html"});
sendClick({expectEvent: false, expectPopup: "a", closePopup: false});
sendClick({expectEvent: false, expectPopup: "a", closePopup: false,
containingPopupShouldClose: false});
},
() => {
browser.test.log(`Tell popup "a" to call window.close(). Expect popup closed.`);
@ -118,12 +120,17 @@ async function testInArea(area) {
];
let expect = {};
sendClick = ({expectEvent, expectPopup, runNextTest, waitUntilClosed, closePopup}, message = "send-click") => {
sendClick = ({expectEvent, expectPopup, runNextTest, waitUntilClosed,
closePopup, containingPopupShouldClose = true},
message = "send-click") => {
if (closePopup == undefined) {
closePopup = !expectEvent;
}
expect = {event: expectEvent, popup: expectPopup, runNextTest, waitUntilClosed, closePopup};
expect = {
event: expectEvent, popup: expectPopup, runNextTest,
waitUntilClosed, closePopup, containingPopupShouldClose,
};
browser.test.sendMessage(message);
};
@ -216,6 +223,14 @@ async function testInArea(area) {
await closeBrowserAction(extension);
}
if (area == getCustomizableUIPanelID() && expecting.containingPopupShouldClose) {
let {node} = getBrowserActionWidget(extension).forWindow(window);
let panel = node.closest("panel");
info(`State of panel ${panel.id} is: ${panel.state}`);
ok(!["open", "showing"].includes(panel.state),
"Panel containing the action should be closed");
}
info("Starting next test");
extension.sendMessage("next-test");
});

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

@ -24,13 +24,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"version": "clang + llvm 3.9.0, built from SVN r290136",

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

@ -24,13 +24,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"version": "clang + llvm 3.9.0, built from SVN r290136",

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

@ -24,12 +24,12 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
}
]

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

@ -24,12 +24,12 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
}
]

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

@ -32,13 +32,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"version": "clang + llvm 3.9.0, built from SVN r290136",

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

@ -24,13 +24,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"version": "clang + llvm 3.9.0, built from SVN r290136",

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

@ -16,13 +16,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.bz2",
"unpack": true,
"digest": "6e14c9a19ee4178b105ee2d995c647888a162056c61d2bd5d1d9dce0326af5ea45cc7d2f28d0b9a499ab2aa909ed534e6c545c6d27319bdd598b6dbceaca2e22",
"size": 1669459
"digest": "7ace40311de3d466f20476ce27c24f25208e8dd80151cbff2e72bab75038dee429312703f13a832c9671bb42dc22a00801c5eb5a9e4d807f2723c16e33167d1b",
"size": 1658526
},
{
"version": "cctools port from commit hash 8e9c3f2506b51",

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

@ -32,12 +32,12 @@
"filename": "MacOSX10.10.sdk.tar.xz"
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
}
]

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

@ -24,13 +24,13 @@
"filename": "MacOSX10.7.sdk.tar.bz2"
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"version": "https://github.com/mozilla/libdmg-hfsplus rev ba04b00435a0853f1499d751617177828ee8ec00",

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

@ -24,12 +24,12 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.bz2",
"unpack": true,
"digest": "6e14c9a19ee4178b105ee2d995c647888a162056c61d2bd5d1d9dce0326af5ea45cc7d2f28d0b9a499ab2aa909ed534e6c545c6d27319bdd598b6dbceaca2e22",
"size": 1669459
"digest": "7ace40311de3d466f20476ce27c24f25208e8dd80151cbff2e72bab75038dee429312703f13a832c9671bb42dc22a00801c5eb5a9e4d807f2723c16e33167d1b",
"size": 1658526
}
]

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

@ -14,13 +14,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.bz2",
"unpack": true,
"digest": "ce3a59557d91e3a874663f64576d184556053430d997b1581874073d067e92e342002bf7c8ee2f056ea86bdbafb9872a81e98d592fc990d40ad43e0539df00ad",
"size": 1878161
"digest": "7a40983b93536aaa9d6953777612b7dcc170b1acab91b377f4f9e697a316b586d477435a93ac32d086f685d52bfe3ea47e99f96e0374c224c3c11c702dbd9ab6",
"size": 1879437
},
{
"version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",

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

@ -14,13 +14,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.bz2",
"unpack": true,
"digest": "ce3a59557d91e3a874663f64576d184556053430d997b1581874073d067e92e342002bf7c8ee2f056ea86bdbafb9872a81e98d592fc990d40ad43e0539df00ad",
"size": 1878161
"digest": "7a40983b93536aaa9d6953777612b7dcc170b1acab91b377f4f9e697a316b586d477435a93ac32d086f685d52bfe3ea47e99f96e0374c224c3c11c702dbd9ab6",
"size": 1879437
},
{
"version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",

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

@ -14,13 +14,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.bz2",
"unpack": true,
"digest": "ce3a59557d91e3a874663f64576d184556053430d997b1581874073d067e92e342002bf7c8ee2f056ea86bdbafb9872a81e98d592fc990d40ad43e0539df00ad",
"size": 1878161
"digest": "7a40983b93536aaa9d6953777612b7dcc170b1acab91b377f4f9e697a316b586d477435a93ac32d086f685d52bfe3ea47e99f96e0374c224c3c11c702dbd9ab6",
"size": 1879437
},
{
"version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",

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

@ -15,13 +15,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.bz2",
"unpack": true,
"digest": "ce3a59557d91e3a874663f64576d184556053430d997b1581874073d067e92e342002bf7c8ee2f056ea86bdbafb9872a81e98d592fc990d40ad43e0539df00ad",
"size": 1878161
"digest": "7a40983b93536aaa9d6953777612b7dcc170b1acab91b377f4f9e697a316b586d477435a93ac32d086f685d52bfe3ea47e99f96e0374c224c3c11c702dbd9ab6",
"size": 1879437
},
{
"version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",

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

@ -15,13 +15,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.bz2",
"unpack": true,
"digest": "ce3a59557d91e3a874663f64576d184556053430d997b1581874073d067e92e342002bf7c8ee2f056ea86bdbafb9872a81e98d592fc990d40ad43e0539df00ad",
"size": 1878161
"digest": "7a40983b93536aaa9d6953777612b7dcc170b1acab91b377f4f9e697a316b586d477435a93ac32d086f685d52bfe3ea47e99f96e0374c224c3c11c702dbd9ab6",
"size": 1879437
},
{
"version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",

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

@ -479,19 +479,22 @@ function prompt(aBrowser, aRequest) {
let activeCamera;
let activeMic;
for (let device of videoDevices) {
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
if (set && set.has(aRequest.windowID + device.mediaSource + device.id)) {
activeCamera = device;
break;
// Always prompt for screen sharing
if (!sharingScreen) {
for (let device of videoDevices) {
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
if (set && set.has(aRequest.windowID + device.mediaSource + device.id)) {
activeCamera = device;
break;
}
}
}
for (let device of audioDevices) {
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
if (set && set.has(aRequest.windowID + device.mediaSource + device.id)) {
activeMic = device;
break;
for (let device of audioDevices) {
let set = webrtcUI.activePerms.get(aBrowser.outerWindowID);
if (set && set.has(aRequest.windowID + device.mediaSource + device.id)) {
activeMic = device;
break;
}
}
}

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

@ -50,15 +50,24 @@
@media not all and (-moz-os-version: windows-win7) {
@media not all and (-moz-os-version: windows-win8) {
@media (-moz-windows-default-theme) {
:root:not(:-moz-lwtheme) {
%ifdef MOZ_PHOTON_THEME
:root:not(:-moz-window-inactive):not(:-moz-lwtheme) {
background-color: hsl(235,33%,19%);
--titlebar-text-color: hsl(240,9%,98%);
%else
background-color: hsl(0, 0%, 78%);
%endif
}
@media (-moz-windows-accent-color-applies) {
:root:not(:-moz-window-inactive):not(:-moz-lwtheme) {
background-color: -moz-win-accentcolor;
--titlebar-text-color: -moz-win-accentcolortext;
}
}
%else
:root:not(:-moz-lwtheme) {
background-color: hsl(0, 0%, 78%);
}
%endif
:root[tabsintitlebar] .tab-label:-moz-window-inactive {
/* Calculated to match the opacity change of Windows Explorer
titlebar text change for inactive windows. */
@ -83,7 +92,7 @@
padding: 10px 17px;
-moz-context-properties: stroke;
%ifdef MOZ_PHOTON_THEME
stroke: white;
stroke: var(--titlebar-text-color);
%else
stroke: black;
%endif

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

@ -15,7 +15,7 @@
%include ../shared/browser.inc.css
:root {
--titlebar-text-color: inherit;
--titlebar-text-color: currentColor;
--toolbarbutton-vertical-text-padding: calc(var(--toolbarbutton-inner-padding) - 1px);

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

@ -15,6 +15,7 @@
# These strings are displayed in the Performance Tool waterfall, identifying markers.
# We want to use the same wording as Google Chrome when appropriate.
marker.label.styles=Recalculate Style
marker.label.stylesApplyChanges=Apply Style Changes
marker.label.reflow=Layout
marker.label.paint=Paint
marker.label.composite=Composite Layers
@ -80,7 +81,7 @@ marker.field.DOMEventPhase=Phase:
marker.field.nonIncrementalCause=Non-incremental Cause:
# For "Recalculate Style" markers
marker.field.restyleHint=Restyle Hint:
marker.field.isAnimationOnly=Animation Only:
# The type of operation performed by a Worker.
marker.worker.serializeDataOffMainThread=Serialize data in Worker

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

@ -6,8 +6,10 @@
"use strict";
const Services = require("Services");
const { Ci, Cc, CC } = require("chrome");
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
const { gDevTools } = require("devtools/client/framework/devtools");
XPCOMUtils.defineLazyGetter(this, "dirService", function () {
return Cc["@mozilla.org/file/directory_service;1"]
@ -23,7 +25,7 @@ XPCOMUtils.defineLazyGetter(this, "LocalFile", function () {
});
XPCOMUtils.defineLazyGetter(this, "getMostRecentBrowserWindow", function () {
return require("sdk/window/utils").getMostRecentBrowserWindow;
return Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
});
const OPEN_FLAGS = {

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

@ -43,23 +43,6 @@ Style markers (labeled as "Recalculating Styles") are triggered when Gecko
needs to figure out the computational style of an element. Fired via
`RestyleTracker::DoProcessRestyles` when there are elements to restyle.
* DOMString restyleHint - A string indicating what kind of restyling will need
to be processed; for example "eRestyle_StyleAttribute" is relatively cheap,
whereas "eRestyle_Subtree" is more expensive. The hint can be a string of
any amount of the following, separated via " | ". All future restyleHints
are from `RestyleManager::RestyleHintToString`.
* "eRestyle_Self"
* "eRestyle_Subtree"
* "eRestyle_LaterSiblings"
* "eRestyle_CSSTransitions"
* "eRestyle_CSSAnimations"
* "eRestyle_StyleAttribute"
* "eRestyle_StyleAttribute_Animations"
* "eRestyle_Force"
* "eRestyle_ForceDescendants"
## Javascript
`Javascript` markers are emitted indicating when JS execution begins and ends,

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

@ -48,10 +48,9 @@ exports.Formatters = {
/* Group 0 - Reflow and Rendering pipeline */
StylesFields: function (marker) {
if ("restyleHint" in marker) {
let label = marker.restyleHint.replace(/eRestyle_/g, "");
if ("isAnimationOnly" in marker) {
return {
[L10N.getStr("marker.field.restyleHint")]: label
[L10N.getStr("marker.field.isAnimationOnly")]: marker.isAnimationOnly
};
}
return null;

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

@ -53,6 +53,11 @@ const TIMELINE_BLUEPRINT = {
label: L10N.getStr("marker.label.styles"),
fields: Formatters.StylesFields,
},
"StylesApplyChanges": {
group: 0,
colorName: "graphs-purple",
label: L10N.getStr("marker.label.stylesApplyChanges"),
},
"Reflow": {
group: 0,
colorName: "graphs-purple",

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

@ -87,9 +87,6 @@ function* spawnTest() {
},
Styles: function (marker) {
info("Got `Styles` marker with data: " + JSON.stringify(marker));
if (marker.restyleHint) {
shouldHaveLabel($, "Restyle Hint:", marker.restyleHint.replace(/eRestyle_/g, ""), marker);
}
if (marker.stack) {
shouldHaveStack($, "stack", marker);
return true;

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

@ -19,15 +19,11 @@ add_task(function* () {
yield front.connect();
let rec = yield front.startRecording({ withMarkers: true });
let markers = yield waitForMarkerType(front, MARKER_NAME, function (marker) {
return marker.some(({restyleHint}) => restyleHint != void 0);
});
let markers = yield waitForMarkerType(front, MARKER_NAME);
yield front.stopRecording(rec);
ok(markers.some(m => m.name === MARKER_NAME), `got some ${MARKER_NAME} markers`);
ok(markers.some(({restyleHint}) => restyleHint != void 0),
"Some markers have a restyleHint.");
yield client.close();
gBrowser.removeCurrentTab();

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

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AutoRestyleTimelineMarker.h"
#include "TimelineConsumers.h"
#include "MainThreadUtils.h"
#include "RestyleTimelineMarker.h"
namespace mozilla {
AutoRestyleTimelineMarker::AutoRestyleTimelineMarker(
nsIDocShell* aDocShell,
bool aIsAnimationOnly
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: mDocShell(nullptr)
, mIsAnimationOnly(aIsAnimationOnly)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
MOZ_ASSERT(NS_IsMainThread());
if (!aDocShell) {
return;
}
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (!timelines || !timelines->HasConsumer(aDocShell)) {
return;
}
mDocShell = aDocShell;
timelines->AddMarkerForDocShell(mDocShell, Move(
MakeUnique<RestyleTimelineMarker>(
mIsAnimationOnly,
MarkerTracingType::START)));
}
AutoRestyleTimelineMarker::~AutoRestyleTimelineMarker()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mDocShell) {
return;
}
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (!timelines || !timelines->HasConsumer(mDocShell)) {
return;
}
timelines->AddMarkerForDocShell(mDocShell, Move(
MakeUnique<RestyleTimelineMarker>(
mIsAnimationOnly,
MarkerTracingType::END)));
}
} // namespace mozilla

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

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_AutoRestyleTimelineMarker_h_
#define mozilla_AutoRestyleTimelineMarker_h_
#include "mozilla/GuardObjects.h"
#include "mozilla/RefPtr.h"
class nsIDocShell;
namespace mozilla {
class MOZ_RAII AutoRestyleTimelineMarker
{
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
RefPtr<nsIDocShell> mDocShell;
bool mIsAnimationOnly;
public:
AutoRestyleTimelineMarker(nsIDocShell* aDocShell,
bool aIsAnimationOnly
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~AutoRestyleTimelineMarker();
AutoRestyleTimelineMarker(const AutoRestyleTimelineMarker& aOther) = delete;
void operator=(const AutoRestyleTimelineMarker& aOther) = delete;
};
} // namespace mozilla
#endif /* mozilla_AutoRestyleTimelineMarker_h_ */

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

@ -15,13 +15,11 @@ namespace mozilla {
class RestyleTimelineMarker : public TimelineMarker
{
public:
RestyleTimelineMarker(nsRestyleHint aRestyleHint,
RestyleTimelineMarker(bool aIsAnimationOnly,
MarkerTracingType aTracingType)
: TimelineMarker("Styles", aTracingType)
{
if (aRestyleHint) {
mRestyleHint.AssignWithConversion(GeckoRestyleManager::RestyleHintToString(aRestyleHint));
}
mIsAnimationOnly = aIsAnimationOnly;
}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
@ -29,12 +27,12 @@ public:
TimelineMarker::AddDetails(aCx, aMarker);
if (GetTracingType() == MarkerTracingType::START) {
aMarker.mRestyleHint.Construct(mRestyleHint);
aMarker.mIsAnimationOnly.Construct(mIsAnimationOnly);
}
}
private:
nsString mRestyleHint;
bool mIsAnimationOnly;
};
} // namespace mozilla

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

@ -10,6 +10,7 @@ with Files('**'):
EXPORTS.mozilla += [
'AbstractTimelineMarker.h',
'AutoGlobalTimelineMarker.h',
'AutoRestyleTimelineMarker.h',
'AutoTimelineMarker.h',
'CompositeTimelineMarker.h',
'ConsoleTimelineMarker.h',
@ -31,6 +32,7 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [
'AbstractTimelineMarker.cpp',
'AutoGlobalTimelineMarker.cpp',
'AutoRestyleTimelineMarker.cpp',
'AutoTimelineMarker.cpp',
'MarkersStorage.cpp',
'ObservedDocShell.cpp',

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

@ -46,9 +46,7 @@ function observeStyling(frameCount, onFrame) {
var markers = docShell.popProfileTimelineMarkers();
docShell.recordProfileTimelineMarkers = false;
var stylingMarkers = markers.filter(function(marker, index) {
return marker.name == 'Styles' &&
(marker.restyleHint == 'eRestyle_CSSAnimations' ||
marker.restyleHint == 'eRestyle_CSSTransitions');
return marker.name == 'Styles' && marker.isAnimationOnly;
});
resolve(stylingMarkers);
});

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

@ -26,7 +26,7 @@ MediaDecoderStateMachine*
ADTSDecoder::CreateStateMachine()
{
RefPtr<MediaDecoderReader> reader =
new MediaFormatReader(this, new ADTSDemuxer(GetResource()));
new MediaFormatReader(this, new ADTSDemuxer(mResource));
return new MediaDecoderStateMachine(this, reader);
}

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

@ -41,10 +41,6 @@ typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags;
class AbstractMediaDecoder : public nsIObserver
{
public:
// Get the current MediaResource being used. Its URI will be returned
// by currentSrc. Returns what was passed to Load(), if Load() has been called.
virtual MediaResource* GetResource() const = 0;
// Increments the parsed, decoded and dropped frame counters by the passed in
// counts.
// Can be called on any thread.

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

@ -339,7 +339,8 @@ DecoderTraits::CreateDecoder(MediaDecoderInit& aInit,
/* static */
MediaDecoderReader*
DecoderTraits::CreateReader(const MediaContainerType& aType,
AbstractMediaDecoder* aDecoder)
AbstractMediaDecoder* aDecoder,
MediaResource* aResource)
{
MOZ_ASSERT(NS_IsMainThread());
MediaDecoderReader* decoderReader = nullptr;
@ -351,33 +352,32 @@ DecoderTraits::CreateReader(const MediaContainerType& aType,
#ifdef MOZ_FMP4
if (MP4Decoder::IsSupportedType(aType,
/* DecoderDoctorDiagnostics* */ nullptr)) {
decoderReader = new MediaFormatReader(aDecoder, new MP4Demuxer(aDecoder->GetResource()));
decoderReader = new MediaFormatReader(aDecoder, new MP4Demuxer(aResource));
} else
#endif
if (MP3Decoder::IsSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new MP3Demuxer(aDecoder->GetResource()));
decoderReader = new MediaFormatReader(aDecoder, new MP3Demuxer(aResource));
} else
if (ADTSDecoder::IsSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aResource));
} else
if (WaveDecoder::IsSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new WAVDemuxer(aDecoder->GetResource()));
decoderReader = new MediaFormatReader(aDecoder, new WAVDemuxer(aResource));
} else
if (FlacDecoder::IsSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new FlacDemuxer(aDecoder->GetResource()));
decoderReader = new MediaFormatReader(aDecoder, new FlacDemuxer(aResource));
} else
if (OggDecoder::IsSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new OggDemuxer(aDecoder->GetResource()));
decoderReader = new MediaFormatReader(aDecoder, new OggDemuxer(aResource));
} else
#ifdef MOZ_ANDROID_OMX
if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
decoderReader = new AndroidMediaReader(aDecoder, aType);
decoderReader = new AndroidMediaReader(aDecoder, aType, aResource);
} else
#endif
if (WebMDecoder::IsSupportedType(aType)) {
decoderReader =
new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()));
decoderReader = new MediaFormatReader(aDecoder, new WebMDemuxer(aResource));
}
return decoderReader;

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

@ -21,6 +21,7 @@ class MediaContainerType;
struct MediaDecoderInit;
class MediaDecoderOwner;
class MediaDecoderReader;
class MediaResource;
enum CanPlayStatus {
CANPLAY_NO,
@ -50,7 +51,8 @@ public:
// Create a reader for thew given MIME type aType. Returns null
// if we were unable to create the reader.
static MediaDecoderReader* CreateReader(const MediaContainerType& aType,
AbstractMediaDecoder* aDecoder);
AbstractMediaDecoder* aDecoder,
MediaResource* aResource);
// Returns true if MIME type aType is supported in video documents,
// or false otherwise. Not all platforms support all MIME types, and

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

@ -138,10 +138,7 @@ public:
// MediaDecoder has been destroyed. You might need to do this if you're
// wrapping the MediaResource in some kind of byte stream interface to be
// passed to a platform decoder.
MediaResource* GetResource() const final override
{
return mResource;
}
MediaResource* GetResource() const { return mResource; }
// Return the principal of the current URI being played or downloaded.
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();

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

@ -68,7 +68,8 @@ public:
size_t mSize;
};
MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder)
MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder,
MediaResource* aResource)
: mAudioCompactor(mAudioQueue)
, mDecoder(aDecoder)
, mTaskQueue(new TaskQueue(
@ -81,6 +82,7 @@ MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder)
, mIgnoreAudioOutputFormat(false)
, mHitAudioDecodeError(false)
, mShutdown(false)
, mResource(aResource)
{
MOZ_COUNT_CTOR(MediaDecoderReader);
MOZ_ASSERT(NS_IsMainThread());
@ -206,7 +208,7 @@ MediaDecoderReader::GetBuffered()
{
MOZ_ASSERT(OnTaskQueue());
AutoPinned<MediaResource> stream(mDecoder->GetResource());
AutoPinned<MediaResource> stream(mResource);
if (!mDuration.Ref().isSome()) {
return TimeIntervals();

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

@ -97,7 +97,8 @@ public:
// The caller must ensure that Shutdown() is called before aDecoder is
// destroyed.
explicit MediaDecoderReader(AbstractMediaDecoder* aDecoder);
explicit MediaDecoderReader(AbstractMediaDecoder* aDecoder,
MediaResource* aResource = nullptr);
// Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
// on failure.
@ -321,6 +322,8 @@ protected:
// Notify if we are waiting for a decryption key.
MediaEventProducer<TrackInfo::TrackType> mOnTrackWaitingForKey;
RefPtr<MediaResource> mResource;
private:
virtual nsresult InitInternal() { return NS_OK; }

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

@ -88,6 +88,10 @@ using namespace mozilla::media;
// constants directly, so we put them in a namespace.
namespace detail {
// Resume a suspended video decoder to the current playback position plus this
// time premium for compensating the seeking delay.
static constexpr auto RESUME_VIDEO_PREMIUM = TimeUnit::FromMicroseconds(125000);
// If audio queue has less than this much decoded audio, we won't risk
// trying to decode the video, we'll skip decoding video up to the next
// keyframe. We may increase this value for an individual decoder if we
@ -957,6 +961,7 @@ public:
EventVisibility aVisibility)
{
mSeekJob = Move(aSeekJob);
mVisibility = aVisibility;
// Always switch off the blank decoder otherwise we might become visible
// in the middle of seeking and won't have a valid video frame to show
@ -967,23 +972,17 @@ public:
Reader()->SetVideoBlankDecode(false);
}
// Dispatch a mozvideoonlyseekbegin event to indicate UI for corresponding
// changes.
if (mSeekJob.mTarget->IsVideoOnly()) {
mMaster->mOnPlaybackEvent.Notify(MediaEventType::VideoOnlySeekBegin);
}
// Don't stop playback for a video-only seek since audio is playing.
if (!mSeekJob.mTarget->IsVideoOnly()) {
// Suppressed visibility comes from two cases: (1) leaving dormant state,
// and (2) resuming suspended video decoder. We want both cases to be
// transparent to the user. So we only notify the change when the seek
// request is from the user.
if (mVisibility == EventVisibility::Observable) {
// Don't stop playback for a video-only seek since we want to keep playing
// audio and we don't need to stop playback while leaving dormant for the
// playback should has been stopped.
mMaster->StopPlayback();
}
mMaster->UpdatePlaybackPositionInternal(mSeekJob.mTarget->GetTime());
if (aVisibility == EventVisibility::Observable) {
mMaster->UpdatePlaybackPositionInternal(mSeekJob.mTarget->GetTime());
mMaster->mOnPlaybackEvent.Notify(MediaEventType::SeekStarted);
// We want dormant actions to be transparent to the user.
// So we only notify the change when the seek request is from the user.
mMaster->UpdateNextFrameStatus(
MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING);
}
@ -1021,6 +1020,7 @@ public:
protected:
SeekJob mSeekJob;
EventVisibility mVisibility;
virtual void DoSeek() = 0;
// Transition to the next state (defined by the subclass) when seek is completed.
@ -1045,15 +1045,6 @@ public:
void Exit() override
{
if (mSeekJob.Exists() &&
mSeekJob.mTarget.isSome() &&
mSeekJob.mTarget->IsVideoOnly()) {
// We are discarding this video-only seek operation now, and we still need
// to dispatch an event so that the UI can change in response to the end
// of video-only seek.
mMaster->mOnPlaybackEvent.Notify(MediaEventType::VideoOnlySeekCompleted);
}
// Disconnect MediaDecoder.
mSeekJob.RejectIfExists(__func__);
@ -1069,15 +1060,6 @@ public:
"Seek shouldn't be finished");
MOZ_ASSERT(aAudio);
// Video-only seek doesn't reset audio decoder. There might be pending audio
// requests when AccurateSeekTask::Seek() begins. We will just store the
// data without checking |mDiscontinuity| or calling
// DropAudioUpToSeekTarget().
if (mSeekJob.mTarget->IsVideoOnly()) {
mMaster->PushAudio(aAudio);
return;
}
AdjustFastSeekIfNeeded(aAudio);
if (mSeekJob.mTarget->IsFast()) {
@ -1128,28 +1110,22 @@ public:
void HandleWaitingForAudio() override
{
if (!mSeekJob.mTarget->IsVideoOnly()) {
MOZ_ASSERT(!mDoneAudioSeeking);
mMaster->WaitForData(MediaData::AUDIO_DATA);
}
MOZ_ASSERT(!mDoneAudioSeeking);
mMaster->WaitForData(MediaData::AUDIO_DATA);
}
void HandleAudioCanceled() override
{
if (!mSeekJob.mTarget->IsVideoOnly()) {
MOZ_ASSERT(!mDoneAudioSeeking);
RequestAudioData();
}
MOZ_ASSERT(!mDoneAudioSeeking);
RequestAudioData();
}
void HandleEndOfAudio() override
{
if (!mSeekJob.mTarget->IsVideoOnly()) {
MOZ_ASSERT(!mDoneAudioSeeking);
AudioQueue().Finish();
mDoneAudioSeeking = true;
MaybeFinishSeek();
}
MOZ_ASSERT(!mDoneAudioSeeking);
AudioQueue().Finish();
mDoneAudioSeeking = true;
MaybeFinishSeek();
}
void HandleWaitingForVideo() override
@ -1182,10 +1158,6 @@ public:
MOZ_ASSERT(!mDoneAudioSeeking || !mDoneVideoSeeking,
"Seek shouldn't be finished");
// Ignore pending requests from video-only seek.
if (mSeekJob.mTarget->IsVideoOnly()) {
return;
}
RequestAudioData();
}
@ -1199,15 +1171,11 @@ public:
void DoSeek() override
{
mDoneAudioSeeking = !Info().HasAudio() || mSeekJob.mTarget->IsVideoOnly();
mDoneAudioSeeking = !Info().HasAudio();
mDoneVideoSeeking = !Info().HasVideo();
if (mSeekJob.mTarget->IsVideoOnly()) {
mMaster->ResetDecode(TrackInfo::kVideoTrack);
} else {
mMaster->ResetDecode();
mMaster->StopMediaSink();
}
mMaster->ResetDecode();
mMaster->StopMediaSink();
DemuxerSeek();
}
@ -1249,7 +1217,7 @@ public:
return TimeUnit::Zero();
}
private:
protected:
void DemuxerSeek()
{
// Request the demuxer to perform seek.
@ -1766,6 +1734,77 @@ private:
}
};
class MediaDecoderStateMachine::VideoOnlySeekingState
: public MediaDecoderStateMachine::AccurateSeekingState
{
public:
explicit VideoOnlySeekingState(Master* aPtr) : AccurateSeekingState(aPtr) { }
RefPtr<MediaDecoder::SeekPromise> Enter(SeekJob&& aSeekJob,
EventVisibility aVisibility)
{
MOZ_ASSERT(aSeekJob.mTarget->IsVideoOnly());
MOZ_ASSERT(aVisibility == EventVisibility::Suppressed);
RefPtr<MediaDecoder::SeekPromise> p =
AccurateSeekingState::Enter(Move(aSeekJob), aVisibility);
// Dispatch a mozvideoonlyseekbegin event to indicate UI for corresponding
// changes.
mMaster->mOnPlaybackEvent.Notify(MediaEventType::VideoOnlySeekBegin);
return p.forget();
}
void Exit() override
{
// We are completing or discarding this video-only seek operation now,
// dispatch an event so that the UI can change in response to the end
// of video-only seek.
mMaster->mOnPlaybackEvent.Notify(MediaEventType::VideoOnlySeekCompleted);
AccurateSeekingState::Exit();
}
void HandleAudioDecoded(AudioData* aAudio) override
{
MOZ_ASSERT(mDoneAudioSeeking && !mDoneVideoSeeking,
"Seek shouldn't be finished");
MOZ_ASSERT(aAudio);
// Video-only seek doesn't reset audio decoder. There might be pending audio
// requests when AccurateSeekTask::Seek() begins. We will just store the
// data without checking |mDiscontinuity| or calling
// DropAudioUpToSeekTarget().
mMaster->PushAudio(aAudio);
}
void HandleWaitingForAudio() override { }
void HandleAudioCanceled() override { }
void HandleEndOfAudio() override { }
void HandleAudioWaited(MediaData::Type aType) override
{
MOZ_ASSERT(!mDoneAudioSeeking || !mDoneVideoSeeking,
"Seek shouldn't be finished");
// Ignore pending requests from video-only seek.
}
void DoSeek() override
{
// TODO: keep decoding audio.
mDoneAudioSeeking = true;
mDoneVideoSeeking = !Info().HasVideo();
mMaster->ResetDecode(TrackInfo::kVideoTrack);
DemuxerSeek();
}
};
RefPtr<MediaDecoder::SeekPromise>
MediaDecoderStateMachine::DormantState::HandleSeek(SeekTarget aTarget)
{
@ -2160,6 +2199,9 @@ MediaDecoderStateMachine::
StateObject::SetSeekingState(SeekJob&& aSeekJob, EventVisibility aVisibility)
{
if (aSeekJob.mTarget->IsAccurate() || aSeekJob.mTarget->IsFast()) {
if (aSeekJob.mTarget->IsVideoOnly()) {
return SetState<VideoOnlySeekingState>(Move(aSeekJob), aVisibility);
}
return SetState<AccurateSeekingState>(Move(aSeekJob), aVisibility);
}
@ -2460,11 +2502,10 @@ SeekingState::SeekCompleted()
mMaster->mAudioDataRequest.DisconnectIfExists();
}
// Cache mTarget for mSeekJob.Resolve() below will reset it.
SeekTarget target = mSeekJob.mTarget.ref();
// We want to resolve the seek request prior finishing the first frame
// to ensure that the seeked event is fired prior loadeded.
// Note: SeekJob.Resolve() resets SeekJob.mTarget. Don't use mSeekJob anymore
// hereafter.
mSeekJob.Resolve(__func__);
// Notify FirstFrameLoaded now if we haven't since we've decoded some data
@ -2474,19 +2515,17 @@ SeekingState::SeekCompleted()
}
// Ensure timestamps are up to date.
if (!target.IsVideoOnly()) {
// Suppressed visibility comes from two cases: (1) leaving dormant state,
// and (2) resuming suspended video decoder. We want both cases to be
// transparent to the user. So we only notify the change when the seek
// request is from the user.
if (mVisibility == EventVisibility::Observable) {
// Don't update playback position for video-only seek.
// Otherwise we might have |newCurrentTime > mMediaSink->GetPosition()|
// and fail the assertion in GetClock() since we didn't stop MediaSink.
mMaster->UpdatePlaybackPositionInternal(newCurrentTime);
}
// Dispatch an event so that the UI can change in response to the end of
// video-only seek
if (target.IsVideoOnly()) {
mMaster->mOnPlaybackEvent.Notify(MediaEventType::VideoOnlySeekCompleted);
}
// Try to decode another frame to detect if we're at the end...
SLOG("Seek completed, mCurrentPosition=%" PRId64,
mMaster->mCurrentPosition.Ref().ToMicroseconds());
@ -3150,7 +3189,8 @@ void MediaDecoderStateMachine::SetVideoDecodeModeInternal(VideoDecodeMode aMode)
CancelSuspendTimer();
if (mVideoDecodeSuspended) {
mStateObj->HandleResumeVideoDecoding(GetMediaTime());
const auto target = mMediaSink->IsStarted() ? GetClock() : GetMediaTime();
mStateObj->HandleResumeVideoDecoding(target + detail::RESUME_VIDEO_PREMIUM);
}
}

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

@ -255,6 +255,7 @@ private:
class AccurateSeekingState;
class NextFrameSeekingState;
class NextFrameSeekingFromDormantState;
class VideoOnlySeekingState;
class BufferingState;
class CompletedState;
class ShutdownState;

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

@ -19,7 +19,8 @@ AndroidMediaDecoder::AndroidMediaDecoder(MediaDecoderInit& aInit,
MediaDecoderStateMachine* AndroidMediaDecoder::CreateStateMachine()
{
return new MediaDecoderStateMachine(this, new AndroidMediaReader(this, mType));
return new MediaDecoderStateMachine(
this, new AndroidMediaReader(this, mType, mResource));
}
} // namespace mozilla

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

@ -26,8 +26,9 @@ typedef mozilla::layers::Image Image;
typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
AndroidMediaReader::AndroidMediaReader(AbstractMediaDecoder *aDecoder,
const MediaContainerType& aContainerType) :
MediaDecoderReader(aDecoder),
const MediaContainerType& aContainerType,
MediaResource* aResource) :
MediaDecoderReader(aDecoder, aResource),
mType(aContainerType),
mPlugin(nullptr),
mHasAudio(false),
@ -43,7 +44,7 @@ nsresult AndroidMediaReader::ReadMetadata(MediaInfo* aInfo,
MOZ_ASSERT(OnTaskQueue());
if (!mPlugin) {
mPlugin = GetAndroidMediaPluginHost()->CreateDecoder(mDecoder->GetResource(), mType);
mPlugin = GetAndroidMediaPluginHost()->CreateDecoder(mResource, mType);
if (!mPlugin) {
return NS_ERROR_FAILURE;
}
@ -169,7 +170,7 @@ bool AndroidMediaReader::DecodeVideoFrame(bool& aKeyframeSkip,
return true;
currentImage = bufferCallback.GetImage();
int64_t pos = mDecoder->GetResource()->Tell();
int64_t pos = mResource->Tell();
IntRect picture = mPicture;
RefPtr<VideoData> v;
@ -274,7 +275,7 @@ bool AndroidMediaReader::DecodeAudioData()
MOZ_ASSERT(OnTaskQueue());
// This is the approximate byte position in the stream.
int64_t pos = mDecoder->GetResource()->Tell();
int64_t pos = mResource->Tell();
// Read next frame
MPAPI::AudioFrame source;

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

@ -38,7 +38,8 @@ class AndroidMediaReader : public MediaDecoderReader
MozPromiseRequestHolder<MediaDecoderReader::VideoDataPromise> mSeekRequest;
public:
AndroidMediaReader(AbstractMediaDecoder* aDecoder,
const MediaContainerType& aContainerType);
const MediaContainerType& aContainerType,
MediaResource* aResource);
nsresult ResetDecode(TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
TrackInfo::kVideoTrack)) override;

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

@ -27,7 +27,7 @@ MediaDecoderStateMachine*
FlacDecoder::CreateStateMachine()
{
RefPtr<MediaDecoderReader> reader =
new MediaFormatReader(this, new FlacDemuxer(GetResource()));
new MediaFormatReader(this, new FlacDemuxer(mResource));
return new MediaDecoderStateMachine(this, reader);
}

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

@ -32,10 +32,8 @@ MP4Decoder::MP4Decoder(MediaDecoderInit& aInit)
MediaDecoderStateMachine* MP4Decoder::CreateStateMachine()
{
mReader =
new MediaFormatReader(this,
new MP4Demuxer(GetResource()),
GetVideoFrameContainer());
mReader = new MediaFormatReader(
this, new MP4Demuxer(mResource), GetVideoFrameContainer());
return new MediaDecoderStateMachine(this, mReader);
}

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

@ -188,7 +188,7 @@ void
MediaSourceDecoder::Ended(bool aEnded)
{
MOZ_ASSERT(NS_IsMainThread());
static_cast<MediaSourceResource*>(GetResource())->SetEnded(aEnded);
static_cast<MediaSourceResource*>(mResource.get())->SetEnded(aEnded);
if (aEnded) {
// We want the MediaSourceReader to refresh its buffered range as it may
// have been modified (end lined up).

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

@ -27,7 +27,7 @@ MP3Decoder::Clone(MediaDecoderInit& aInit)
MediaDecoderStateMachine*
MP3Decoder::CreateStateMachine() {
RefPtr<MediaDecoderReader> reader =
new MediaFormatReader(this, new MP3Demuxer(GetResource()));
new MediaFormatReader(this, new MP3Demuxer(mResource));
return new MediaDecoderStateMachine(this, reader);
}

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

@ -15,7 +15,7 @@ namespace mozilla {
MediaDecoderStateMachine* OggDecoder::CreateStateMachine()
{
RefPtr<OggDemuxer> demuxer = new OggDemuxer(GetResource());
RefPtr<OggDemuxer> demuxer = new OggDemuxer(mResource);
RefPtr<MediaFormatReader> reader =
new MediaFormatReader(this, demuxer, GetVideoFrameContainer());
demuxer->SetChainingEvents(&reader->TimedMetadataProducer(),

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

@ -0,0 +1,10 @@
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:9.97667,
400x300_seg0.ts
#EXTINF:9.97667,
400x300_seg1.ts
#EXT-X-ENDLIST

Двоичные данные
dom/media/test/hls/400x300_seg0.ts Normal file

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

Двоичные данные
dom/media/test/hls/400x300_seg1.ts Normal file

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

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

@ -0,0 +1,10 @@
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:9.97667,
640x480_seg0.ts
#EXTINF:9.97667,
640x480_seg1.ts
#EXT-X-ENDLIST

Двоичные данные
dom/media/test/hls/640x480_seg0.ts Normal file

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

Двоичные данные
dom/media/test/hls/640x480_seg1.ts Normal file

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

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

@ -0,0 +1,10 @@
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:9.97667,
960x720_seg0.ts
#EXTINF:9.97667,
960x720_seg1.ts
#EXT-X-ENDLIST

Двоичные данные
dom/media/test/hls/960x720_seg0.ts Normal file

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

Двоичные данные
dom/media/test/hls/960x720_seg1.ts Normal file

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

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

@ -0,0 +1,10 @@
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=232370,CODECS="mp4a.40.2, avc1.4d4015"
400x300_prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=649879,CODECS="mp4a.40.2, avc1.4d401e"
640x480_prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=649879,CODECS="mp4a.40.2, avc1.4d401e"
960x720_prog_index.m3u8

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

@ -22,6 +22,14 @@ function manifestVideo() {
return gManifestNavigatorSource.contentDocument.createElement('video');
}
// Need to get the server url composed with ip:port instead of mochi.test.
// Since we will provide the url to Exoplayer which cannot recognize the domain
// name "mochi.test".
let serverUrl = SpecialPowers.Services.prefs.getCharPref("media.hls.server.url");
var gHLSTests = [
{ name: serverUrl + "/bipbop_4x3_variant.m3u8", type:"audio/x-mpegurl", duration:19.95334 }
];
// These are small test files, good for just seeing if something loads. We
// really only need one test file per backend here.
var gSmallTests = [

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

@ -644,6 +644,16 @@ support-files =
wavedata_ulaw.wav^headers^
!/dom/canvas/test/captureStream_common.js
!/dom/html/test/reflect.js
hls/bipbop_4x3_variant.m3u8
hls/400x300_prog_index.m3u8
hls/640x480_prog_index.m3u8
hls/960x720_prog_index.m3u8
hls/400x300_seg0.ts
hls/400x300_seg1.ts
hls/640x480_seg0.ts
hls/640x480_seg1.ts
hls/960x720_seg0.ts
hls/960x720_seg1.ts
[test_access_control.html]
skip-if = android_version == '15' || android_version == '17' # bug 1292836, android(bug 1232305)
@ -1188,3 +1198,10 @@ tags = suspend
skip-if = toolkit == 'android' # android(bug 1232305)
[test_video_gzip_encoding.html]
[test_playback_hls.html]
# HLS is only supported on Fennec with API level >= 16
# TODO: This test is similar to test_playback.html, will remove the
# redundant code once test_playback.html is enabled on Fennec.
skip-if = toolkit != 'android' || android_version < '16'
tags = hls

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

@ -0,0 +1,105 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test playback of HLS with simple m3u8 that should play OK</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;
function startTest(test, token) {
var v = document.createElement('video');
v.preload = "metadata";
v.token = token;
v.prevTime = 0;
v.seenEnded = false;
var handler = {
"ontimeout": function() {
Log(token, "timed out: ended=" + v.seenEnded);
}
};
manager.started(token, handler);
v.src = test.name;
v.name = test.name;
var check = function(test, v) { return function() {
is(test.name, v.name, test.name + ": Name should match #1");
checkMetadata(test.name, v, test);
}}(test, v);
var noLoad = function(test, v) { return function() {
ok(false, test.name + " should not fire 'load' event");
}}(test, v);
var finish = function() {
v.finished = true;
v.removeEventListener("timeupdate", timeUpdate);
removeNodeAndSource(v);
manager.finished(v.token);
}
// We should get "ended" events to finish the test.
var mayFinish = function() {
if (v.seenEnded) {
finish();
}
}
var checkEnded = function(test, v) { return function() {
is(test.name, v.name, test.name + ": Name should match #2");
checkMetadata(test.name, v, test);
is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
ok(v.ended, test.name + " checking playback has ended");
ok(!v.finished, test.name + " shouldn't be finished");
ok(!v.seenEnded, test.name + " shouldn't be ended");
v.seenEnded = true;
mayFinish();
}}(test, v);
var timeUpdate = function(test, v) { return function() {
if (v.prevTime > v.currentTime) {
ok(false, test.name + " time should run forwards: p=" +
v.prevTime + " c=" + v.currentTime);
}
v.prevTime = v.currentTime;
}}(test, v);
v.addEventListener("load", noLoad);
v.addEventListener("loadedmetadata", check);
v.addEventListener("timeupdate", timeUpdate);
// We should get "ended" events for the hls resource
v.addEventListener("ended", checkEnded);
document.body.appendChild(v);
v.play();
// Log the event on android devices or emulator for debugging.
if (isSlowPlatform()) {
var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart","loadedmetadata",
"loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
"waiting", "pause"];
function logEvent(e) {
var v = e.target;
Log(e.target.token, "got " + e.type);
}
events.forEach(function(e) {
v.addEventListener(e, logEvent);
});
}
}
manager.runTests(gHLSTests, startTest);
</script>
</pre>
</body>
</html>

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

@ -23,7 +23,7 @@ MediaDecoderStateMachine*
WaveDecoder::CreateStateMachine()
{
return new MediaDecoderStateMachine(
this, new MediaFormatReader(this, new WAVDemuxer(GetResource())));
this, new MediaFormatReader(this, new WAVDemuxer(mResource)));
}
/* static */ bool

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

@ -33,12 +33,6 @@ BufferDecoder::BeginDecoding(TaskQueue* aTaskQueueIdentity)
mTaskQueueIdentity = aTaskQueueIdentity;
}
MediaResource*
BufferDecoder::GetResource() const
{
return mResource;
}
void
BufferDecoder::NotifyDecodedFrames(const FrameStatisticsData& aStats)
{

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

@ -32,8 +32,6 @@ public:
// This has to be called before decoding begins
void BeginDecoding(TaskQueue* aTaskQueueIdentity);
MediaResource* GetResource() const final override;
void NotifyDecodedFrames(const FrameStatisticsData& aStats) final override;
VideoFrameContainer* GetVideoFrameContainer() final override;

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

@ -193,7 +193,8 @@ MediaDecodeTask::CreateReader()
// If you change this list to add support for new decoders, please consider
// updating HTMLMediaElement::CreateDecoder as well.
mDecoderReader = DecoderTraits::CreateReader(mContainerType, mBufferDecoder);
mDecoderReader =
DecoderTraits::CreateReader(mContainerType, mBufferDecoder, resource);
if (!mDecoderReader) {
return false;

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

@ -18,8 +18,8 @@ namespace mozilla {
MediaDecoderStateMachine* WebMDecoder::CreateStateMachine()
{
mReader =
new MediaFormatReader(this, new WebMDemuxer(GetResource()), GetVideoFrameContainer());
mReader = new MediaFormatReader(
this, new WebMDemuxer(mResource), GetVideoFrameContainer());
return new MediaDecoderStateMachine(this, mReader);
}

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

@ -64,7 +64,7 @@ dictionary ProfileTimelineMarker {
sequence<ProfileTimelineLayerRect> rectangles;
/* For Style markers. */
DOMString restyleHint;
boolean isAnimationOnly;
/* For MessagePort markers. */
ProfileTimelineMessagePortOperationType messagePortOperation;

2
js/src/wasm/WasmSignalHandlers.cpp Normal file → Executable file
Просмотреть файл

@ -1679,7 +1679,7 @@ js::InterruptRunningJitCode(JSContext* cx)
// thread is in the middle of a syscall. Rather than retrying in a loop,
// just wait for the next request for interrupt.
HANDLE thread = (HANDLE)cx->threadNative();
if (SuspendThread(thread) != -1) {
if (SuspendThread(thread) != (DWORD)-1) {
CONTEXT context;
context.ContextFlags = CONTEXT_FULL;
if (GetThreadContext(thread, &context)) {

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

@ -11,14 +11,13 @@
#include "RestyleTracker.h"
#include "GeckoProfiler.h"
#include "nsDocShell.h"
#include "nsFrameManager.h"
#include "nsIDocument.h"
#include "nsStyleChangeList.h"
#include "mozilla/GeckoRestyleManager.h"
#include "RestyleTrackerInlines.h"
#include "nsTransitionManager.h"
#include "mozilla/RestyleTimelineMarker.h"
#include "mozilla/AutoRestyleTimelineMarker.h"
namespace mozilla {
@ -117,10 +116,6 @@ RestyleTracker::DoProcessRestyles()
AUTO_PROFILER_LABEL_DYNAMIC("RestyleTracker::DoProcessRestyles", CSS,
docURL.get());
nsDocShell* docShell = static_cast<nsDocShell*>(mRestyleManager->PresContext()->GetDocShell());
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
bool isTimelineRecording = timelines && timelines->HasConsumer(docShell);
// Create a AnimationsWithDestroyedFrame during restyling process to
// stop animations and transitions on elements that have no frame at the end
// of the restyling process.
@ -249,24 +244,17 @@ RestyleTracker::DoProcessRestyles()
continue;
}
if (isTimelineRecording) {
timelines->AddMarkerForDocShell(docShell, Move(
MakeUnique<RestyleTimelineMarker>(
data->mRestyleHint, MarkerTracingType::START)));
}
Maybe<AutoProfilerTracing> tracing;
if (profiler_feature_active(ProfilerFeature::Restyle)) {
tracing.emplace("Paint", "Styles", Move(data->mBacktrace));
}
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint,
data->mRestyleHintData);
AddRestyleRootsIfAwaitingRestyle(data->mDescendants);
if (isTimelineRecording) {
timelines->AddMarkerForDocShell(docShell, Move(
MakeUnique<RestyleTimelineMarker>(
data->mRestyleHint, MarkerTracingType::END)));
{
AutoRestyleTimelineMarker marker(
mRestyleManager->PresContext()->GetDocShell(),
data->mRestyleHint & eRestyle_AllHintsWithAnimations);
Maybe<AutoProfilerTracing> tracing;
if (profiler_feature_active(ProfilerFeature::Restyle)) {
tracing.emplace("Paint", "Styles", Move(data->mBacktrace));
}
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint,
data->mRestyleHintData);
AddRestyleRootsIfAwaitingRestyle(data->mDescendants);
}
}
@ -363,21 +351,15 @@ RestyleTracker::DoProcessRestyles()
if (profiler_feature_active(ProfilerFeature::Restyle)) {
tracing.emplace("Paint", "Styles", Move(currentRestyle->mBacktrace));
}
if (isTimelineRecording) {
timelines->AddMarkerForDocShell(docShell, Move(
MakeUnique<RestyleTimelineMarker>(
currentRestyle->mRestyleHint, MarkerTracingType::START)));
}
ProcessOneRestyle(currentRestyle->mElement,
currentRestyle->mRestyleHint,
currentRestyle->mChangeHint,
currentRestyle->mRestyleHintData);
if (isTimelineRecording) {
timelines->AddMarkerForDocShell(docShell, Move(
MakeUnique<RestyleTimelineMarker>(
currentRestyle->mRestyleHint, MarkerTracingType::END)));
{
AutoRestyleTimelineMarker marker(
mRestyleManager->PresContext()->GetDocShell(),
currentRestyle->mRestyleHint & eRestyle_AllHintsWithAnimations);
ProcessOneRestyle(currentRestyle->mElement,
currentRestyle->mRestyleHint,
currentRestyle->mChangeHint,
currentRestyle->mRestyleHintData);
}
}
}

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

@ -6,6 +6,8 @@
#include "mozilla/ServoRestyleManager.h"
#include "mozilla/AutoRestyleTimelineMarker.h"
#include "mozilla/AutoTimelineMarker.h"
#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoStyleSet.h"
@ -782,14 +784,19 @@ ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
ClearSnapshots();
}
nsStyleChangeList currentChanges(StyleBackendType::Servo);
bool anyStyleChanged = false;
// Recreate style contexts, and queue up change hints (which also handle
// lazy frame construction).
nsStyleChangeList currentChanges(StyleBackendType::Servo);
DocumentStyleRootIterator iter(doc);
bool anyStyleChanged = false;
while (Element* root = iter.GetNextStyleRoot()) {
ServoRestyleState state(*styleSet, currentChanges);
anyStyleChanged |= ProcessPostTraversal(root, nullptr, state);
{
AutoRestyleTimelineMarker marker(
mPresContext->GetDocShell(), animationOnly);
DocumentStyleRootIterator iter(doc);
while (Element* root = iter.GetNextStyleRoot()) {
ServoRestyleState state(*styleSet, currentChanges);
anyStyleChanged |= ProcessPostTraversal(root, nullptr, state);
}
}
// Process the change hints.
@ -797,27 +804,30 @@ ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
// Unfortunately, the frame constructor can generate new change hints while
// processing existing ones. We redirect those into a secondary queue and
// iterate until there's nothing left.
ReentrantChangeList newChanges;
mReentrantChanges = &newChanges;
while (!currentChanges.IsEmpty()) {
ProcessRestyledFrames(currentChanges);
MOZ_ASSERT(currentChanges.IsEmpty());
for (ReentrantChange& change: newChanges) {
if (!(change.mHint & nsChangeHint_ReconstructFrame) &&
!change.mContent->GetPrimaryFrame()) {
// SVG Elements post change hints without ensuring that the primary
// frame will be there after that (see bug 1366142).
//
// Just ignore those, since we can't really process them.
continue;
{
AutoTimelineMarker marker(
mPresContext->GetDocShell(), "StylesApplyChanges");
ReentrantChangeList newChanges;
mReentrantChanges = &newChanges;
while (!currentChanges.IsEmpty()) {
ProcessRestyledFrames(currentChanges);
MOZ_ASSERT(currentChanges.IsEmpty());
for (ReentrantChange& change: newChanges) {
if (!(change.mHint & nsChangeHint_ReconstructFrame) &&
!change.mContent->GetPrimaryFrame()) {
// SVG Elements post change hints without ensuring that the primary
// frame will be there after that (see bug 1366142).
//
// Just ignore those, since we can't really process them.
continue;
}
currentChanges.AppendChange(change.mContent->GetPrimaryFrame(),
change.mContent, change.mHint);
}
currentChanges.AppendChange(change.mContent->GetPrimaryFrame(),
change.mContent, change.mHint);
newChanges.Clear();
}
newChanges.Clear();
mReentrantChanges = nullptr;
}
mReentrantChanges = nullptr;
if (anyStyleChanged) {
// Maybe no styles changed when:

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

@ -162,7 +162,7 @@ skip-if(styloVsGecko) == anim-view-01.svg#view lime.svg # bug 1354406
== anim-class-04.svg anim-class-04-ref.svg
# animate with some paint server values
fails-if(styloVsGecko||stylo) == anim-paintserver-1.svg anim-paintserver-1-ref.svg
== anim-paintserver-1.svg anim-paintserver-1-ref.svg
# animate attributes on text content children
== anim-text-attr-01.svg anim-text-attr-01-ref.svg

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

@ -7,6 +7,7 @@
#include "mozilla/ServoStyleSet.h"
#include "gfxPlatformFontList.h"
#include "mozilla/AutoRestyleTimelineMarker.h"
#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoRestyleManager.h"
@ -341,6 +342,12 @@ ServoStyleSet::PrepareAndTraverseSubtree(
TraversalRootBehavior aRootBehavior,
TraversalRestyleBehavior aRestyleBehavior)
{
bool forAnimationOnly =
aRestyleBehavior == TraversalRestyleBehavior::ForAnimationOnly;
AutoRestyleTimelineMarker marker(
mPresContext->GetDocShell(), forAnimationOnly);
// Get the Document's root element to ensure that the cache is valid before
// calling into the (potentially-parallel) Servo traversal, where a cache hit
// is necessary to avoid a data race when updating the cache.
@ -354,8 +361,6 @@ ServoStyleSet::PrepareAndTraverseSubtree(
bool isInitial = !aRoot->HasServoData();
bool forReconstruct =
aRestyleBehavior == TraversalRestyleBehavior::ForReconstruct;
bool forAnimationOnly =
aRestyleBehavior == TraversalRestyleBehavior::ForAnimationOnly;
#ifdef DEBUG
bool forNewlyBoundElement =
aRestyleBehavior == TraversalRestyleBehavior::ForNewlyBoundElement;

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

@ -49,7 +49,7 @@ to mochitest command.
* test_grid_container_shorthands.html [65]
* test_grid_item_shorthands.html [23]
* test_grid_shorthand_serialization.html [28]
* test_value_storage.html `'grid` [53]
* test_value_storage.html `'grid` [41]
* Unsupported values
* SVG-in-OpenType values not supported servo/servo#15211 bug 1355412
* test_value_storage.html `context-` [7]

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

@ -46,7 +46,7 @@ function observeStyling(frameCount) {
var markers = docShell.popProfileTimelineMarkers();
docShell.recordProfileTimelineMarkers = false;
var stylingMarkers = markers.filter(function(marker, index) {
return marker.restyleHint == "eRestyle_StyleAttribute_Animations";
return marker.name == 'Styles' && marker.isAnimationOnly;
});
resolve(stylingMarkers);
});

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

@ -30,8 +30,6 @@ user_pref("extensions.systemAddon.update.url", "http://localhost/dummy-system-ad
user_pref("extensions.getAddons.cache.enabled", false);
// Disable blocklist updates so we don't have them reported as leaks
user_pref("extensions.blocklist.enabled", false);
// Make url-classifier updates so rare that they won't affect tests
user_pref("urlclassifier.updateinterval", 172800);
// Disable downscale-during-decode, since it makes reftests more difficult.
user_pref("image.downscale-during-decode.enabled", false);
// Checking whether two files are the same is slow on Windows.

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

@ -15,13 +15,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"size": 30899096,

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

@ -23,13 +23,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"size": 30899096,

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

@ -24,13 +24,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"size": 4906080,

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

@ -24,13 +24,13 @@
"unpack": true
},
{
"version": "sccache rev 9155425cfc038d6a60deb50816055f4e93b93ad1",
"version": "sccache rev 69334a26ba65fc88e3934271a2ce6781c51b445e",
"algorithm": "sha512",
"visibility": "public",
"filename": "sccache2.tar.xz",
"unpack": true,
"digest": "da67d4a872f8d23ef0707e02a823e5a644f1988e605d2c46c787641c8c37ae4521ab7d83b1dc4c0cc52d203be6313c7f9580830845536fa7c2a521af9443f69a",
"size": 2192144
"digest": "7bbe53cda3f608826dc6a0266e648cd2ea09c88ef93edf87d582b41185b72740667e2c7bf6e9b2b911fb2915cbfb985e528598c7b3153092ad27d5e937342df7",
"size": 2191380
},
{
"size": 4906080,

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

@ -19,6 +19,7 @@ import android.util.Log;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import org.mozilla.gecko.gfx.GeckoSurface;
@ -58,7 +59,11 @@ public final class RemoteManager implements IBinder.DeathRecipient {
@Override
public void onServiceDisconnected(ComponentName name) {
if (DEBUG) Log.d(LOGTAG, "service disconnected");
mRemote.asBinder().unlinkToDeath(RemoteManager.this, 0);
try {
mRemote.asBinder().unlinkToDeath(RemoteManager.this, 0);
} catch (NoSuchElementException e) {
Log.w(LOGTAG, "death recipient already released");
}
synchronized (this) {
mRemote = null;
notify();

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

@ -375,11 +375,7 @@ pref("media.wmf.enabled", true);
pref("media.wmf.decoder.thread-count", -1);
pref("media.wmf.low-latency.enabled", false);
pref("media.wmf.skip-blacklist", false);
#ifdef NIGHTLY_BUILD
pref("media.wmf.vp9.enabled", true);
#else
pref("media.wmf.vp9.enabled", false);
#endif
pref("media.wmf.allow-unsupported-resolutions", false);
pref("media.windows-media-foundation.allow-d3d11-dxva", true);
pref("media.wmf.disable-d3d11-for-dlls", "igd11dxva64.dll: 20.19.15.4463, 20.19.15.4454, 20.19.15.4444, 20.19.15.4416, 20.19.15.4404, 20.19.15.4390, 20.19.15.4380, 20.19.15.4377, 20.19.15.4364, 20.19.15.4360, 20.19.15.4352, 20.19.15.4331, 20.19.15.4326, 20.19.15.4300; igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4390, 20.19.15.4380, 20.19.15.4360, 10.18.10.4358, 20.19.15.4331, 20.19.15.4312, 20.19.15.4300, 10.18.15.4281, 10.18.15.4279, 10.18.10.4276, 10.18.15.4268, 10.18.15.4256, 10.18.10.4252, 10.18.15.4248, 10.18.14.4112, 10.18.10.3958, 10.18.10.3496, 10.18.10.3431, 10.18.10.3412, 10.18.10.3355, 9.18.10.3234, 9.18.10.3071, 9.18.10.3055, 9.18.10.3006; igd10umd32.dll: 9.17.10.4229, 9.17.10.3040, 9.17.10.2857, 8.15.10.2274, 8.15.10.2272, 8.15.10.2246, 8.15.10.1840, 8.15.10.1808; igd10umd64.dll: 9.17.10.4229, 9.17.10.2857, 10.18.10.3496; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215; nvwgf2um.dll: 22.21.13.8253, 22.21.13.8233, 22.21.13.8205, 22.21.13.8189, 22.21.13.8178, 22.21.13.8165, 21.21.13.7892, 21.21.13.7878, 21.21.13.7866, 21.21.13.7849, 21.21.13.7654, 21.21.13.7653, 21.21.13.7633, 21.21.13.7619, 21.21.13.7563, 21.21.13.7306, 21.21.13.7290, 21.21.13.7270, 21.21.13.7254, 21.21.13.6939, 21.21.13.6926, 21.21.13.6909, 21.21.13.4201, 21.21.13.4200, 10.18.13.6881, 10.18.13.6839, 10.18.13.6510, 10.18.13.6472, 10.18.13.6143, 10.18.13.5946, 10.18.13.5923, 10.18.13.5921, 10.18.13.5891, 10.18.13.5887, 10.18.13.5582, 10.18.13.5445, 10.18.13.5382, 10.18.13.5362, 9.18.13.4788, 9.18.13.4752, 9.18.13.4725, 9.18.13.4709, 9.18.13.4195, 9.18.13.4192, 9.18.13.4144, 9.18.13.4052, 9.18.13.3788, 9.18.13.3523, 9.18.13.3235, 9.18.13.3165, 9.18.13.2723, 9.18.13.2702, 9.18.13.1422, 9.18.13.1407, 9.18.13.1106, 9.18.13.546; atidxx32.dll: 21.19.151.3, 21.19.142.257, 21.19.137.514, 21.19.137.1, 21.19.134.1, 21.19.128.7, 21.19.128.4, 20.19.0.32837, 20.19.0.32832, 8.17.10.682, 8.17.10.671, 8.17.10.661, 8.17.10.648, 8.17.10.644, 8.17.10.625, 8.17.10.605, 8.17.10.581, 8.17.10.569, 8.17.10.560, 8.17.10.545, 8.17.10.539, 8.17.10.531, 8.17.10.525, 8.17.10.520, 8.17.10.519, 8.17.10.514, 8.17.10.511, 8.17.10.494, 8.17.10.489, 8.17.10.483, 8.17.10.453, 8.17.10.451, 8.17.10.441, 8.17.10.436, 8.17.10.432, 8.17.10.425, 8.17.10.418, 8.17.10.414, 8.17.10.401, 8.17.10.395, 8.17.10.385, 8.17.10.378, 8.17.10.362, 8.17.10.355, 8.17.10.342, 8.17.10.331, 8.17.10.318, 8.17.10.310, 8.17.10.286, 8.17.10.269, 8.17.10.261, 8.17.10.247, 8.17.10.240, 8.15.10.212; atidxx64.dll: 21.19.151.3, 21.19.142.257, 21.19.137.514, 21.19.137.1, 21.19.134.1, 21.19.128.7, 21.19.128.4, 20.19.0.32832, 8.17.10.682, 8.17.10.661, 8.17.10.644, 8.17.10.625; nvumdshim.dll: 10.18.13.6822");

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

@ -586,13 +586,13 @@ WalkStackThread(void* aData)
// Suspend the calling thread, dump his stack, and then resume him.
// He's currently waiting for us to finish so now should be a good time.
ret = ::SuspendThread(data->thread);
if (ret == -1) {
if (ret == (DWORD)-1) {
PrintError("ThreadSuspend");
} else {
WalkStackMain64(data);
ret = ::ResumeThread(data->thread);
if (ret == -1) {
if (ret == (DWORD)-1) {
PrintError("ThreadResume");
}
}

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

@ -49,10 +49,13 @@ class MozlintParser(ArgumentParser):
"mercurial or git."
}],
[['-w', '--workdir'],
{'default': False,
'action': 'store_true',
{'const': 'all',
'nargs': '?',
'choices': ['staged', 'all'],
'help': "Lint files touched by changes in the working directory "
"(i.e haven't been committed yet). Works with mercurial or git.",
"(i.e haven't been committed yet). On git, --workdir=staged "
"can be used to only consider staged files. Works with "
"mercurial or git.",
}],
[['extra_args'],
{'nargs': REMAINDER,
@ -67,6 +70,13 @@ class MozlintParser(ArgumentParser):
self.add_argument(*cli, **args)
def parse_known_args(self, *args, **kwargs):
# Allow '-wo' or '-ow' as shorthand for both --workdir and --outgoing.
for token in ('-wo', '-ow'):
if token in args[0]:
i = args[0].index(token)
args[0].pop(i)
args[0][i:i] = [token[:2], '-' + token[2]]
# This is here so the eslint mach command doesn't lose 'extra_args'
# when using mach's dispatch functionality.
args, extra = ArgumentParser.parse_known_args(self, *args, **kwargs)

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

@ -111,7 +111,7 @@ class LintRoller(object):
# Calculate files from VCS
if workdir:
paths.update(self.vcs.by_workdir())
paths.update(self.vcs.by_workdir(workdir))
if outgoing:
paths.update(self.vcs.by_outgoing(outgoing))

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

@ -44,7 +44,7 @@ class VCSHelper(object):
return []
return [os.path.join(self.root, f) for f in files if f]
def by_workdir(self, workdir):
def by_workdir(self, mode):
return []
def by_outgoing(self, dest='default'):
@ -58,7 +58,7 @@ class HgHelper(VCSHelper):
return self.run(['hg', 'outgoing', '--quiet', '--template',
"{file_mods % '\\n{file}'}{file_adds % '\\n{file}'}", '-r', '.', dest])
def by_workdir(self):
def by_workdir(self, mode):
return self.run(['hg', 'status', '-amn'])
@ -95,8 +95,13 @@ class GitHelper(VCSHelper):
return self.run(['git', 'log', '--name-only', '--diff-filter=AM',
'--oneline', '--pretty=format:', comparing])
def by_workdir(self):
return self.run(['git', 'diff', '--name-only', '--diff-filter=AM', 'HEAD'])
def by_workdir(self, mode):
cmd = ['git', 'diff', '--name-only', '--diff-filter=AM']
if mode == 'staged':
cmd.append('--cached')
else:
cmd.append('HEAD')
return self.run(cmd)
vcs_class = {

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

@ -102,13 +102,18 @@ def test_vcs_helper(repo):
next(repo.setup)
assert_files(vcs.by_workdir(), ['bar', 'baz'])
assert_files(vcs.by_workdir('all'), ['bar', 'baz'])
if repo.vcs == 'git':
assert_files(vcs.by_workdir('staged'), ['baz'])
elif repo.vcs == 'hg':
assert_files(vcs.by_workdir('staged'), ['bar', 'baz'])
assert_files(vcs.by_outgoing(), [])
assert_files(vcs.by_outgoing(remotepath), [])
next(repo.setup)
assert_files(vcs.by_workdir(), [])
assert_files(vcs.by_workdir('all'), [])
assert_files(vcs.by_workdir('staged'), [])
assert_files(vcs.by_outgoing(), ['bar', 'baz'])
assert_files(vcs.by_outgoing(remotepath), ['bar', 'baz'])

11
servo/Cargo.lock сгенерированный
Просмотреть файл

@ -1309,6 +1309,15 @@ name = "inflate"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "influent"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "io-surface"
version = "0.7.0"
@ -2164,6 +2173,7 @@ name = "profile"
version = "0.0.1"
dependencies = [
"heartbeats-simple 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"influent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3637,6 +3647,7 @@ dependencies = [
"checksum image 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d95816db758249fe16f23a4e23f1a3a817fe11892dbfd1c5836f625324702158"
"checksum immeta 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0b9260463a221bfe3f02100c56e2d14c050d5ffe7e44a43d0a1b2b1f2b523502"
"checksum inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb"
"checksum influent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a22b311b83431be3ab9af96ca9ea41554bb4a8551ea871ae44c3ce0c57e55f2c"
"checksum io-surface 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c35a3278fa52fb070fdc874dfd057163e6c21e0a9295f87f54daee9dd5530b43"
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
"checksum ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a38ad662f104525ac57012e0b79aad07507e3fc11e3bae668bf416264e760ebb"

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

@ -39,8 +39,13 @@ pub struct Opts {
/// platform default setting.
pub device_pixels_per_px: Option<f32>,
/// `None` to disable the time profiler or `Some` with an interval in seconds to enable it and
/// cause it to produce output on that interval (`-p`).
/// `None` to disable the time profiler or `Some` to enable it with:
/// - an interval in seconds to cause it to produce output on that interval.
/// (`i.e. -p 5`).
/// - a file path to write profiling info to a TSV file upon Servo's termination.
/// (`i.e. -p out.tsv`).
/// - an InfluxDB hostname to store profiling info upon Servo's termination.
/// (`i.e. -p http://localhost:8086`)
pub time_profiling: Option<OutputOptions>,
/// When the profiler is enabled, this is an optional path to dump a self-contained HTML file
@ -419,8 +424,10 @@ fn print_debug_usage(app: &str) -> ! {
#[derive(Clone, Deserialize, Serialize)]
pub enum OutputOptions {
/// Database connection config (hostname, name, user, pass)
DB(ServoUrl, Option<String>, Option<String>, Option<String>),
FileName(String),
Stdout(f64)
Stdout(f64),
}
fn args_fail(msg: &str) -> ! {
@ -598,6 +605,9 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
"config directory following xdg spec on linux platform", "");
opts.optflag("v", "version", "Display servo version information");
opts.optflag("", "unminify-js", "Unminify Javascript");
opts.optopt("", "profiler-db-user", "Profiler database user", "");
opts.optopt("", "profiler-db-pass", "Profiler database password", "");
opts.optopt("", "profiler-db-name", "Profiler database name", "");
let opt_match = match opts.parse(args) {
Ok(m) => m,
@ -666,7 +676,14 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
match opt_match.opt_str("p") {
Some(argument) => match argument.parse::<f64>() {
Ok(interval) => Some(OutputOptions::Stdout(interval)) ,
Err(_) => Some(OutputOptions::FileName(argument)),
Err(_) => {
match ServoUrl::parse(&argument) {
Ok(url) => Some(OutputOptions::DB(url, opt_match.opt_str("profiler-db-name"),
opt_match.opt_str("profiler-db-user"),
opt_match.opt_str("profiler-db-pass"))),
Err(_) => Some(OutputOptions::FileName(argument)),
}
}
},
None => Some(OutputOptions::Stdout(5.0 as f64)),
}

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

@ -11,6 +11,7 @@ path = "lib.rs"
[dependencies]
profile_traits = {path = "../profile_traits"}
influent = "0.4"
ipc-channel = "0.8"
heartbeats-simple = "0.4"
log = "0.3.5"

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

@ -11,6 +11,7 @@
#[cfg(not(target_os = "windows"))]
extern crate alloc_jemalloc;
extern crate heartbeats_simple;
extern crate influent;
extern crate ipc_channel;
#[cfg(not(target_os = "windows"))]
extern crate libc;

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

@ -5,6 +5,9 @@
//! Timing functions.
use heartbeats;
use influent::client::{Client, Credentials};
use influent::create_client;
use influent::measurement::{Measurement, Value};
use ipc_channel::ipc::{self, IpcReceiver};
use profile_traits::energy::{energy_interval_ms, read_energy_uj};
use profile_traits::time::{ProfilerCategory, ProfilerChan, ProfilerMsg, TimerMetadata};
@ -183,7 +186,8 @@ impl Profiler {
}).expect("Thread spawning failed");
// decide if we need to spawn the timer thread
match option {
&OutputOptions::FileName(_) => { /* no timer thread needed */ },
&OutputOptions::FileName(_) |
&OutputOptions::DB(_, _, _, _) => { /* no timer thread needed */ },
&OutputOptions::Stdout(period) => {
// Spawn a timer thread
let chan = chan.clone();
@ -391,7 +395,54 @@ impl Profiler {
}
writeln!(&mut lock, "").unwrap();
},
None => { /* Do nothing if not output option has been set */ },
Some(OutputOptions::DB(ref hostname, ref dbname, ref user, ref password)) => {
// Unfortunately, influent does not like hostnames ending with "/"
let mut hostname = hostname.to_string();
if hostname.ends_with("/") {
hostname.pop();
}
let empty = String::from("");
let username = user.as_ref().unwrap_or(&empty);
let password = password.as_ref().unwrap_or(&empty);
let database = dbname.as_ref().unwrap_or(&empty);
let credentials = Credentials {
username: username,
password: password,
database: database,
};
let hosts = vec![hostname.as_str()];
let client = create_client(credentials, hosts);
for (&(ref category, ref meta), ref mut data) in &mut self.buckets {
data.sort_by(|a, b| {
if a < b {
Ordering::Less
} else {
Ordering::Greater
}
});
let data_len = data.len();
if data_len > 0 {
let (mean, median, min, max) = Self::get_statistics(data);
let category = category.format(&self.output);
let mut measurement = Measurement::new(&category);
measurement.add_field("mean", Value::Float(mean));
measurement.add_field("median", Value::Float(median));
measurement.add_field("min", Value::Float(min));
measurement.add_field("max", Value::Float(max));
if let Some(ref meta) = *meta {
measurement.add_tag("host", meta.url.as_str());
};
if client.write_one(measurement, None).is_err() {
warn!("Could not write measurement to profiler db");
}
}
}
},
None => { /* Do nothing if no output option has been set */ },
};
}
}

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

@ -20,6 +20,7 @@ use dom_struct::dom_struct;
use js::jsapi::{Heap, JSContext, JSObject};
use js::typedarray::{Float64Array, CreateWith};
use std::cell::Cell;
use std::ptr;
use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
#[dom_struct]
@ -86,9 +87,13 @@ impl Gamepad {
data.display_id),
global,
GamepadBinding::Wrap);
let cx = global.get_cx();
rooted!(in (cx) let mut array = ptr::null_mut());
unsafe {
let _ = Float64Array::create(global.get_cx(), CreateWith::Slice(&state.axes), gamepad.axes.handle_mut());
let _ = Float64Array::create(cx, CreateWith::Slice(&state.axes), array.handle_mut());
}
gamepad.axes.set(array.get());
gamepad
}

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

@ -24,6 +24,7 @@ use html5ever::{LocalName, Prefix};
use net_traits::ReferrerPolicy;
use std::default::Default;
use std::f32;
use std::str;
use style::attr::AttrValue;
#[derive(PartialEq)]
@ -68,7 +69,6 @@ impl Area {
//This vector will hold all parsed coordinates
let mut number_list = Vec::new();
let mut array = Vec::new();
let ar_ref = &mut array;
// Step 5: walk till end of string
while index < size {
@ -89,24 +89,24 @@ impl Area {
match val {
b',' | b';' | b' ' | b'\t' | b'\n' | 0x0C | b'\r' => break,
_ => (*ar_ref).push(val),
_ => array.push(val),
}
index += 1;
}
// The input does not consist any valid charecters
if (*ar_ref).is_empty() {
if array.is_empty() {
break;
}
// Convert String to float
match String::from_utf8((*ar_ref).clone()).unwrap().parse::<f32>() {
Ok(v) => number_list.push(v),
Err(_) => number_list.push(0.0),
match str::from_utf8(&array).ok().and_then(|s| s.parse::<f32>().ok()) {
Some(v) => number_list.push(v),
None => number_list.push(0.0),
};
(*ar_ref).clear();
array.clear();
// For rectangle and circle, stop parsing once we have three
// and four coordinates respectively

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

@ -503,6 +503,13 @@ macro_rules! window_event_handlers(
event_handler!(unhandledrejection, GetOnunhandledrejection,
SetOnunhandledrejection);
event_handler!(unload, GetOnunload, SetOnunload);
event_handler!(vrdisplayconnect, GetOnvrdisplayconnect, SetOnvrdisplayconnect);
event_handler!(vrdisplaydisconnect, GetOnvrdisplaydisconnect, SetOnvrdisplaydisconnect);
event_handler!(vrdisplayactivate, GetOnvrdisplayactivate, SetOnvrdisplayactivate);
event_handler!(vrdisplaydeactivate, GetOnvrdisplaydeactivate, SetOnvrdisplaydeactivate);
event_handler!(vrdisplayblur, GetOnvrdisplayblur, SetOnvrdisplayblur);
event_handler!(vrdisplayfocus, GetOnvrdisplayfocus, SetOnvrdisplayfocus);
event_handler!(vrdisplaypresentchange, GetOnvrdisplaypresentchange, SetOnvrdisplaypresentchange);
);
(ForwardToWindow) => (
window_owned_event_handler!(afterprint, GetOnafterprint,
@ -528,6 +535,14 @@ macro_rules! window_event_handlers(
window_owned_event_handler!(unhandledrejection, GetOnunhandledrejection,
SetOnunhandledrejection);
window_owned_event_handler!(unload, GetOnunload, SetOnunload);
window_owned_event_handler!(vrdisplayconnect, GetOnvrdisplayconnect, SetOnvrdisplayconnect);
window_owned_event_handler!(vrdisplaydisconnect, GetOnvrdisplaydisconnect, SetOnvrdisplaydisconnect);
window_owned_event_handler!(vrdisplayactivate, GetOnvrdisplayactivate, SetOnvrdisplayactivate);
window_owned_event_handler!(vrdisplaydeactivate, GetOnvrdisplaydeactivate, SetOnvrdisplaydeactivate);
window_owned_event_handler!(vrdisplayblur, GetOnvrdisplayblur, SetOnvrdisplayblur);
window_owned_event_handler!(vrdisplayfocus, GetOnvrdisplayfocus, SetOnvrdisplayfocus);
window_owned_event_handler!(vrdisplaypresentchange, GetOnvrdisplaypresentchange, SetOnvrdisplaypresentchange);
);
);

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