зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to central, a=merge
MozReview-Commit-ID: 1tRIig3iCAm
This commit is contained in:
Коммит
ab1e399bcd
|
@ -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
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -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
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -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
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -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;
|
||||
|
|
|
@ -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'])
|
||||
|
||||
|
|
|
@ -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);
|
||||
);
|
||||
);
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче