Merge mozilla-central to inbound. a=merge CLOSED TREE
11
.cron.yml
@ -111,6 +111,17 @@ jobs:
|
||||
by-project:
|
||||
mozilla-central: [{hour: 10, minute: 30}]
|
||||
|
||||
- name: chromium-update
|
||||
job:
|
||||
type: decision-task
|
||||
treeherder-symbol: Chromium
|
||||
target-tasks-method: chromium_update
|
||||
run-on-projects:
|
||||
- mozilla-central
|
||||
when:
|
||||
by-project:
|
||||
mozilla-central: [{hour: 10, minute: 30}]
|
||||
|
||||
- name: bouncer-check
|
||||
job:
|
||||
type: decision-task
|
||||
|
@ -287,7 +287,7 @@ static gint getCaretOffsetCB(AtkText* aText) {
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* text = accWrap->AsHyperText();
|
||||
if (!text || !text->IsTextRole()) {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return static_cast<gint>(text->CaretOffset());
|
||||
@ -297,7 +297,7 @@ static gint getCaretOffsetCB(AtkText* aText) {
|
||||
return static_cast<gint>(proxy->CaretOffset());
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static AtkAttributeSet* getRunAttributesCB(AtkText* aText, gint aOffset,
|
||||
|
@ -1809,7 +1809,10 @@ pref("intl.multilingual.downloadEnabled", false);
|
||||
// development and testing of Fission.
|
||||
// The current simulated conditions are:
|
||||
// - Don't propagate events from subframes to JS child actors
|
||||
pref("browser.fission.simulate", false);
|
||||
pref("fission.frontend.simulate-events", false);
|
||||
// - Only deliver subframe messages that specifies
|
||||
// their destination (using the BrowsingContext id).
|
||||
pref("fission.frontend.simulate-messages", false);
|
||||
|
||||
// Prio preferences
|
||||
// Only enable by default on Nightly.
|
||||
|
@ -52,6 +52,19 @@ async function waitUntilReloadEnabled() {
|
||||
await TestUtils.waitForCondition(() => !button.disabled);
|
||||
}
|
||||
|
||||
// Opens a new, blank tab, executes a task and closes the tab.
|
||||
function withNewBlankTab(taskFn) {
|
||||
return BrowserTestUtils.withNewTab("about:blank", async function() {
|
||||
// For a blank tab, the Reload button should be disabled. However, when we
|
||||
// open about:blank with BrowserTestUtils.withNewTab, this is unreliable.
|
||||
// Therefore, explicitly disable the reload command.
|
||||
// We disable the command (rather than disabling the button directly) so the
|
||||
// button will be updated correctly for future page loads.
|
||||
document.getElementById("Browser:Reload").setAttribute("disabled", "true");
|
||||
await taskFn();
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function setPref() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
@ -63,7 +76,7 @@ add_task(async function setPref() {
|
||||
|
||||
// Test tab stops with no page loaded.
|
||||
add_task(async function testTabStopsNoPage() {
|
||||
await BrowserTestUtils.withNewTab("about:blank", async function() {
|
||||
await withNewBlankTab(async function() {
|
||||
startFromUrlBar();
|
||||
await expectFocusAfterKey("Shift+Tab", "home-button");
|
||||
await expectFocusAfterKey("Shift+Tab", "tabbrowser-tabs", true);
|
||||
@ -125,7 +138,7 @@ add_task(async function testTabStopsWithBookmarksToolbar() {
|
||||
|
||||
// Test a focusable toolbartabstop which has no navigable buttons.
|
||||
add_task(async function testTabStopNoButtons() {
|
||||
await BrowserTestUtils.withNewTab("about:blank", async function() {
|
||||
await withNewBlankTab(async function() {
|
||||
// The Back, Forward and Reload buttons are all currently disabled.
|
||||
// The Home button is the only other button at that tab stop.
|
||||
CustomizableUI.removeWidgetFromArea("home-button");
|
||||
|
@ -286,10 +286,23 @@ EnterprisePoliciesManager.prototype = {
|
||||
getSupportMenu() {
|
||||
return SupportMenu;
|
||||
},
|
||||
|
||||
setExtensionPolicies(extensionPolicies) {
|
||||
ExtensionPolicies = extensionPolicies;
|
||||
},
|
||||
|
||||
getExtensionPolicy(extensionID) {
|
||||
if (ExtensionPolicies &&
|
||||
extensionID in ExtensionPolicies) {
|
||||
return ExtensionPolicies[extensionID];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
let DisallowedFeatures = {};
|
||||
let SupportMenu = null;
|
||||
let ExtensionPolicies = null;
|
||||
|
||||
/**
|
||||
* areEnterpriseOnlyPoliciesAllowed
|
||||
|
@ -66,6 +66,12 @@ var EXPORTED_SYMBOLS = ["Policies"];
|
||||
* The callbacks will be bound to their parent policy object.
|
||||
*/
|
||||
var Policies = {
|
||||
"3rdparty": {
|
||||
onBeforeAddons(manager, param) {
|
||||
manager.setExtensionPolicies(param.Extensions);
|
||||
},
|
||||
},
|
||||
|
||||
"AppUpdateURL": {
|
||||
onBeforeAddons(manager, param) {
|
||||
setDefaultPref("app.update.url", param.href);
|
||||
|
@ -2,6 +2,21 @@
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
"3rdparty": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Extensions" : {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"type": "JSON"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"AppUpdateURL": {
|
||||
"type": "URL"
|
||||
},
|
||||
|
@ -25,6 +25,7 @@ skip-if = os != 'mac'
|
||||
[browser_policies_setAndLockPref_API.js]
|
||||
[browser_policies_simple_pref_policies.js]
|
||||
[browser_policies_sorted_alphabetically.js]
|
||||
[browser_policy_3rdparty.js]
|
||||
[browser_policy_app_update.js]
|
||||
[browser_policy_app_update_URL.js]
|
||||
[browser_policy_block_about_addons.js]
|
||||
|
@ -0,0 +1,20 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
add_task(async function setup() {
|
||||
await setupPolicyEngineWithJson({
|
||||
"policies": {
|
||||
"3rdparty": {
|
||||
"Extensions": {
|
||||
"3rdparty-policy@mozilla.com": {
|
||||
"string": "value",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let extensionPolicy = Services.policies.getExtensionPolicy("3rdparty-policy@mozilla.com");
|
||||
Assert.deepEqual(extensionPolicy, {"string": "value"});
|
||||
});
|
@ -1009,12 +1009,20 @@ class UrlbarInput {
|
||||
if (!UrlbarPrefs.get("ui.popup.disable_autohide")) {
|
||||
this.view.close(UrlbarUtils.CANCEL_REASON.BLUR);
|
||||
}
|
||||
// We may have hidden popup notifications, show them again if necessary.
|
||||
if (this.getAttribute("pageproxystate") != "valid") {
|
||||
this.window.UpdatePopupNotificationsVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
_on_focus(event) {
|
||||
this._updateUrlTooltip();
|
||||
|
||||
this.formatValue();
|
||||
|
||||
// Hide popup notifications, to reduce visual noise.
|
||||
if (this.getAttribute("pageproxystate") != "valid") {
|
||||
this.window.UpdatePopupNotificationsVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
_on_mouseover(event) {
|
||||
|
@ -8,6 +8,7 @@ RUSTFMT="${TOOLTOOL_DIR}/rustc/bin/rustfmt"
|
||||
CBINDGEN="${TOOLTOOL_DIR}/cbindgen/cbindgen"
|
||||
|
||||
export NODEJS="${TOOLTOOL_DIR}/node/bin/node"
|
||||
NASM="${TOOLTOOL_DIR}/nasm/nasm"
|
||||
|
||||
CC="${TOOLTOOL_DIR}/clang/bin/clang"
|
||||
CXX="${TOOLTOOL_DIR}/clang/bin/clang++"
|
||||
|
@ -9,6 +9,8 @@
|
||||
## These are short descriptions for individual policies, to be displayed
|
||||
## in the documentation section in about:policies.
|
||||
|
||||
policy-3rdparty = Set policies that WebExtensions can access via chrome.storage.managed.
|
||||
|
||||
policy-AppUpdateURL = Set custom app update URL.
|
||||
|
||||
policy-Authentication = Configure integrated authentication for websites that support it.
|
||||
|
@ -1,6 +1,7 @@
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
skip-if = (os == 'win' && processor == 'aarch64')
|
||||
support-files =
|
||||
head.js
|
||||
!/devtools/client/shared/test/shared-head.js
|
||||
@ -11,8 +12,11 @@ support-files =
|
||||
!/devtools/client/shared/test/telemetry-test-helpers.js
|
||||
|
||||
[browser_accessibility_context_menu_browser.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
||||
[browser_accessibility_context_menu_inspector.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533484
|
||||
[browser_accessibility_mutations.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533534
|
||||
[browser_accessibility_panel_highlighter.js]
|
||||
[browser_accessibility_panel_highlighter_multi_tab.js]
|
||||
skip-if = (os == 'linux' && debug && bits == 64) # Bug 1511247
|
||||
|
@ -97,8 +97,11 @@ skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keybo
|
||||
[browser_markup_accessibility_semantics.js]
|
||||
[browser_markup_anonymous_01.js]
|
||||
[browser_markup_anonymous_02.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1531584
|
||||
[browser_markup_anonymous_03.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1531584
|
||||
[browser_markup_anonymous_04.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1531584
|
||||
[browser_markup_copy_html.js]
|
||||
subsuite = clipboard
|
||||
[browser_markup_copy_image_data.js]
|
||||
@ -203,6 +206,7 @@ subsuite = clipboard
|
||||
[browser_markup_shadowdom_nested_pick_inspect.js]
|
||||
[browser_markup_shadowdom_noslot.js]
|
||||
[browser_markup_shadowdom_open_debugger.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533507
|
||||
[browser_markup_shadowdom_shadowroot_mode.js]
|
||||
[browser_markup_shadowdom_show_nodes_button.js]
|
||||
[browser_markup_shadowdom_slotted_keyboard_focus.js]
|
||||
|
@ -49,7 +49,9 @@ support-files =
|
||||
!/devtools/client/shared/test/test-actor-registry.js
|
||||
|
||||
[browser_inspector_addNode_01.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533529
|
||||
[browser_inspector_addNode_02.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533529
|
||||
[browser_inspector_addNode_03.js]
|
||||
[browser_inspector_addSidebarTab.js]
|
||||
[browser_inspector_breadcrumbs.js]
|
||||
@ -63,6 +65,7 @@ skip-if = os == "mac" # Full keyboard navigation on OSX only works if Full Keybo
|
||||
[browser_inspector_breadcrumbs_visibility.js]
|
||||
[browser_inspector_delete-selected-node-01.js]
|
||||
[browser_inspector_delete-selected-node-02.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533490
|
||||
[browser_inspector_delete-selected-node-03.js]
|
||||
[browser_inspector_destroy-after-navigation.js]
|
||||
[browser_inspector_destroy-before-ready.js]
|
||||
@ -157,6 +160,7 @@ subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_inspector_menu-04-use-in-console.js]
|
||||
[browser_inspector_menu-05-attribute-items.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533492
|
||||
[browser_inspector_menu-06-other.js]
|
||||
[browser_inspector_navigation.js]
|
||||
[browser_inspector_navigate_to_errors.js]
|
||||
|
@ -38,11 +38,16 @@ support-files =
|
||||
!/devtools/server/tests/mochitest/hello-actor.js
|
||||
|
||||
[browser_accessibility_highlighter_infobar.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
||||
[browser_accessibility_infobar_show.js]
|
||||
[browser_accessibility_node.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
||||
[browser_accessibility_node_events.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
||||
[browser_accessibility_simple.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
||||
[browser_accessibility_walker.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533487
|
||||
[browser_actor_error.js]
|
||||
[browser_animation_actor-lifetime.js]
|
||||
[browser_animation_emitMutations.js]
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "mozilla/dom/TimeRanges.h"
|
||||
#include "mozilla/dom/VideoPlaybackQuality.h"
|
||||
#include "mozilla/dom/VideoStreamTrack.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
@ -180,9 +181,7 @@ nsMapRuleToAttributesFunc HTMLVideoElement::GetAttributeMappingFunction()
|
||||
void HTMLVideoElement::UnbindFromTree(bool aDeep, bool aNullParent) {
|
||||
if (mVisualCloneSource) {
|
||||
mVisualCloneSource->EndCloningVisually();
|
||||
SetVisualCloneSource(nullptr);
|
||||
} else if (mVisualCloneTarget) {
|
||||
mVisualCloneTarget->SetVisualCloneSource(nullptr);
|
||||
EndCloningVisually();
|
||||
}
|
||||
|
||||
@ -457,6 +456,11 @@ void HTMLVideoElement::CloneElementVisually(HTMLVideoElement& aTargetVideo,
|
||||
return;
|
||||
}
|
||||
|
||||
// Do we already have a visual clone target? If so, shut it down.
|
||||
if (mVisualCloneTarget) {
|
||||
EndCloningVisually();
|
||||
}
|
||||
|
||||
if (!SetVisualCloneTarget(&aTargetVideo)) {
|
||||
rv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
@ -513,7 +517,8 @@ void HTMLVideoElement::EndCloningVisually() {
|
||||
}
|
||||
}
|
||||
|
||||
mVisualCloneTarget = nullptr;
|
||||
Unused << mVisualCloneTarget->SetVisualCloneSource(nullptr);
|
||||
Unused << SetVisualCloneTarget(nullptr);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -199,7 +199,7 @@ void TextTrackManager::AddCues(TextTrack* aTextTrack) {
|
||||
for (uint32_t i = 0; i < cueList->Length(); ++i) {
|
||||
mNewCues->AddCue(*cueList->IndexedGetter(i, dummy));
|
||||
}
|
||||
DispatchTimeMarchesOn();
|
||||
TimeMarchesOn();
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,15 +224,12 @@ void TextTrackManager::RemoveTextTrack(TextTrack* aTextTrack,
|
||||
for (uint32_t i = 0; i < removeCueList->Length(); ++i) {
|
||||
mNewCues->RemoveCue(*((*removeCueList)[i]));
|
||||
}
|
||||
DispatchTimeMarchesOn();
|
||||
TimeMarchesOn();
|
||||
}
|
||||
}
|
||||
|
||||
void TextTrackManager::DidSeek() {
|
||||
WEBVTT_LOG("%p DidSeek", this);
|
||||
if (mTextTracks) {
|
||||
mTextTracks->DidSeek();
|
||||
}
|
||||
if (mMediaElement) {
|
||||
mLastTimeMarchesOnCalled = mMediaElement->CurrentTime();
|
||||
WEBVTT_LOGV("DidSeek set mLastTimeMarchesOnCalled %lf",
|
||||
@ -288,7 +285,7 @@ void TextTrackManager::NotifyCueAdded(TextTrackCue& aCue) {
|
||||
if (mNewCues) {
|
||||
mNewCues->AddCue(aCue);
|
||||
}
|
||||
DispatchTimeMarchesOn();
|
||||
TimeMarchesOn();
|
||||
ReportTelemetryForCue();
|
||||
}
|
||||
|
||||
@ -297,11 +294,8 @@ void TextTrackManager::NotifyCueRemoved(TextTrackCue& aCue) {
|
||||
if (mNewCues) {
|
||||
mNewCues->RemoveCue(aCue);
|
||||
}
|
||||
DispatchTimeMarchesOn();
|
||||
if (aCue.GetActive()) {
|
||||
// We remove an active cue, need to update the display.
|
||||
DispatchUpdateCueDisplay();
|
||||
}
|
||||
TimeMarchesOn();
|
||||
DispatchUpdateCueDisplay();
|
||||
}
|
||||
|
||||
void TextTrackManager::PopulatePendingList() {
|
||||
@ -613,6 +607,8 @@ void TextTrackManager::DispatchTimeMarchesOn() {
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#time-marches-on
|
||||
void TextTrackManager::TimeMarchesOn() {
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
mTimeMarchesOnDispatched = false;
|
||||
|
||||
CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
|
||||
if (context && context->IsInStableOrMetaStableState()) {
|
||||
// FireTimeUpdate can be called while at stable state following a
|
||||
@ -625,7 +621,6 @@ void TextTrackManager::TimeMarchesOn() {
|
||||
return;
|
||||
}
|
||||
WEBVTT_LOG("TimeMarchesOn");
|
||||
mTimeMarchesOnDispatched = false;
|
||||
|
||||
// Early return if we don't have any TextTracks or shutting down.
|
||||
if (!mTextTracks || mTextTracks->Length() == 0 || IsShutdown()) {
|
||||
@ -661,13 +656,7 @@ void TextTrackManager::TimeMarchesOn() {
|
||||
TextTrack* ttrack = mTextTracks->IndexedGetter(index, dummy);
|
||||
if (ttrack && dummy) {
|
||||
// TODO: call GetCueListByTimeInterval on mNewCues?
|
||||
ttrack->UpdateActiveCueList();
|
||||
TextTrackCueList* activeCueList = ttrack->GetActiveCues();
|
||||
if (activeCueList) {
|
||||
for (uint32_t i = 0; i < activeCueList->Length(); ++i) {
|
||||
currentCues->AddCue(*((*activeCueList)[i]));
|
||||
}
|
||||
}
|
||||
ttrack->GetCurrentCueList(currentCues);
|
||||
}
|
||||
}
|
||||
WEBVTT_LOGV("TimeMarchesOn currentCues %d", currentCues->Length());
|
||||
@ -831,7 +820,7 @@ void TextTrackManager::TimeMarchesOn() {
|
||||
void TextTrackManager::NotifyCueUpdated(TextTrackCue* aCue) {
|
||||
// TODO: Add/Reorder the cue to mNewCues if we have some optimization?
|
||||
WEBVTT_LOG("NotifyCueUpdated");
|
||||
DispatchTimeMarchesOn();
|
||||
TimeMarchesOn();
|
||||
// For the case "Texttrack.mode = hidden/showing", if the mode
|
||||
// changing between showing and hidden, TimeMarchesOn
|
||||
// doesn't render the cue. Call DispatchUpdateCueDisplay() explicitly.
|
||||
|
@ -67,7 +67,8 @@ uint32_t BitReader::ReadUE() {
|
||||
return 0;
|
||||
}
|
||||
uint32_t r = ReadBits(i);
|
||||
r += (1 << i) - 1;
|
||||
r += (uint32_t(1) << i) - 1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,6 @@ void TextTrack::AddCue(TextTrackCue& aCue) {
|
||||
mediaElement->NotifyCueAdded(aCue);
|
||||
}
|
||||
}
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
void TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv) {
|
||||
@ -145,7 +144,6 @@ void TextTrack::RemoveCue(TextTrackCue& aCue, ErrorResult& aRv) {
|
||||
mediaElement->NotifyCueRemoved(aCue);
|
||||
}
|
||||
}
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
void TextTrack::SetCuesDirty() {
|
||||
@ -154,46 +152,6 @@ void TextTrack::SetCuesDirty() {
|
||||
}
|
||||
}
|
||||
|
||||
void TextTrack::UpdateActiveCueList() {
|
||||
if (!mTextTrackList) {
|
||||
return;
|
||||
}
|
||||
|
||||
HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
||||
if (!mediaElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are dirty, i.e. an event happened that may cause the sorted mCueList
|
||||
// to have changed like a seek or an insert for a cue, than we need to rebuild
|
||||
// the active cue list from scratch.
|
||||
if (mDirty) {
|
||||
mCuePos = 0;
|
||||
mDirty = false;
|
||||
mActiveCueList->RemoveAll();
|
||||
}
|
||||
|
||||
double playbackTime = mediaElement->CurrentTime();
|
||||
// Remove all the cues from the active cue list whose end times now occur
|
||||
// earlier then the current playback time.
|
||||
for (uint32_t i = mActiveCueList->Length(); i > 0; i--) {
|
||||
if ((*mActiveCueList)[i - 1]->EndTime() <= playbackTime) {
|
||||
mActiveCueList->RemoveCueAt(i - 1);
|
||||
}
|
||||
}
|
||||
// Add all the cues, starting from the position of the last cue that was
|
||||
// added, that have valid start and end times for the current playback time.
|
||||
// We can stop iterating safely once we encounter a cue that does not have
|
||||
// a valid start time as the cue list is sorted.
|
||||
for (; mCuePos < mCueList->Length() &&
|
||||
(*mCueList)[mCuePos]->StartTime() <= playbackTime;
|
||||
mCuePos++) {
|
||||
if ((*mCueList)[mCuePos]->EndTime() > playbackTime) {
|
||||
mActiveCueList->AddCue(*(*mCueList)[mCuePos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextTrackCueList* TextTrack::GetActiveCues() {
|
||||
if (mMode != TextTrackMode::Disabled) {
|
||||
return mActiveCueList;
|
||||
@ -252,7 +210,6 @@ void TextTrack::NotifyCueUpdated(TextTrackCue* aCue) {
|
||||
mediaElement->NotifyCueUpdated(aCue);
|
||||
}
|
||||
}
|
||||
SetDirty();
|
||||
}
|
||||
|
||||
void TextTrack::GetLabel(nsAString& aLabel) const {
|
||||
@ -298,5 +255,40 @@ bool TextTrack::IsLoaded() {
|
||||
return (mReadyState >= Loaded);
|
||||
}
|
||||
|
||||
void TextTrack::NotifyCueActiveStateChanged(TextTrackCue* aCue) {
|
||||
MOZ_ASSERT(aCue);
|
||||
if (aCue->GetActive()) {
|
||||
MOZ_ASSERT(!mActiveCueList->IsCueExist(aCue));
|
||||
mActiveCueList->AddCue(*aCue);
|
||||
} else {
|
||||
MOZ_ASSERT(mActiveCueList->IsCueExist(aCue));
|
||||
mActiveCueList->RemoveCue(*aCue);
|
||||
}
|
||||
}
|
||||
|
||||
void TextTrack::GetCurrentCueList(RefPtr<TextTrackCueList>& aCueList) const {
|
||||
if (!mTextTrackList) {
|
||||
return;
|
||||
}
|
||||
|
||||
const HTMLMediaElement* mediaElement = mTextTrackList->GetMediaElement();
|
||||
if (!mediaElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// According to `time marches on` step1, current cue list contains the cues
|
||||
// whose start times are less than or equal to the current playback position
|
||||
// and whose end times are greater than the current playback position.
|
||||
// https://html.spec.whatwg.org/multipage/media.html#time-marches-on
|
||||
MOZ_ASSERT(aCueList);
|
||||
const double playbackTime = mediaElement->CurrentTime();
|
||||
for (uint32_t idx = 0; idx < mCueList->Length(); idx++) {
|
||||
TextTrackCue* cue = (*mCueList)[idx];
|
||||
if (cue->StartTime() <= playbackTime && cue->EndTime() > playbackTime) {
|
||||
aCueList->AddCue(*cue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -69,7 +69,6 @@ class TextTrack final : public DOMEventTargetHelper {
|
||||
}
|
||||
|
||||
TextTrackCueList* GetActiveCues();
|
||||
void UpdateActiveCueList();
|
||||
void GetActiveCueArray(nsTArray<RefPtr<TextTrackCue> >& aCues);
|
||||
|
||||
TextTrackReadyState ReadyState() const;
|
||||
@ -99,6 +98,15 @@ class TextTrack final : public DOMEventTargetHelper {
|
||||
|
||||
bool IsLoaded();
|
||||
|
||||
// Called when associated cue's active flag has been changed, and then we
|
||||
// would add or remove the cue to the active cue list.
|
||||
void NotifyCueActiveStateChanged(TextTrackCue* aCue);
|
||||
|
||||
// Use this function to request current cues which start time are less than or
|
||||
// equal to the current playback position and whose end times are greater than
|
||||
// the current playback position.
|
||||
void GetCurrentCueList(RefPtr<TextTrackCueList>& aCueList) const;
|
||||
|
||||
private:
|
||||
~TextTrack();
|
||||
|
||||
|
@ -216,5 +216,17 @@ void TextTrackCue::NotifyDisplayStatesChanged() {
|
||||
->NotifyCueDisplayStatesChanged();
|
||||
}
|
||||
|
||||
void TextTrackCue::SetActive(bool aActive) {
|
||||
if (mActive == aActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
mActive = aActive;
|
||||
mDisplayState = mActive ? mDisplayState : nullptr;
|
||||
if (mTrack) {
|
||||
mTrack->NotifyCueActiveStateChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -280,14 +280,7 @@ class TextTrackCue final : public DOMEventTargetHelper {
|
||||
|
||||
void SetTrackElement(HTMLTrackElement* aTrackElement);
|
||||
|
||||
void SetActive(bool aActive) {
|
||||
if (mActive == aActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
mActive = aActive;
|
||||
mDisplayState = mActive ? mDisplayState : nullptr;
|
||||
}
|
||||
void SetActive(bool aActive);
|
||||
|
||||
bool GetActive() { return mActive; }
|
||||
|
||||
|
@ -105,12 +105,6 @@ void TextTrackList::RemoveTextTrack(TextTrack* aTrack) {
|
||||
}
|
||||
}
|
||||
|
||||
void TextTrackList::DidSeek() {
|
||||
for (uint32_t i = 0; i < mTextTracks.Length(); i++) {
|
||||
mTextTracks[i]->SetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
class TrackEventRunner : public Runnable {
|
||||
public:
|
||||
TrackEventRunner(TextTrackList* aList, Event* aEvent)
|
||||
|
@ -50,7 +50,6 @@ class TextTrackList final : public DOMEventTargetHelper {
|
||||
void AddTextTrack(TextTrack* aTextTrack, const CompareTextTracks& aCompareTT);
|
||||
|
||||
void RemoveTextTrack(TextTrack* aTrack);
|
||||
void DidSeek();
|
||||
|
||||
HTMLMediaElement* GetMediaElement();
|
||||
void SetTextTrackManager(TextTrackManager* aTextTrackManager);
|
||||
|
BIN
dom/media/test/black.mp4
Normal file
@ -2,3 +2,4 @@ skip-if(Android) fuzzy-if(OSX,0-22,0-49977) fuzzy-if(webrender&&cocoaWidget,23-2
|
||||
skip-if(Android) fuzzy-if(OSX,0-23,0-51392) fuzzy-if(webrender&&cocoaWidget,23-23,76798-76798) fuzzy-if(winWidget,0-59,0-76797) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-60,0-1800) HTTP(..) == short.mp4.lastframe.html short.mp4.lastframe-ref.html
|
||||
skip-if(Android) skip-if(winWidget) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-55,0-4281) fuzzy-if(OSX,0-3,0-111852) HTTP(..) == bipbop_300_215kbps.mp4.lastframe.html bipbop_300_215kbps.mp4.lastframe-ref.html
|
||||
skip-if(Android) fuzzy-if(OSX,0-25,0-175921) fuzzy-if(winWidget,0-71,0-179198) HTTP(..) == gizmo.mp4.seek.html gizmo.mp4.55thframe-ref.html
|
||||
skip-if(Android) == vtt_update_display_after_removed_cue.html vtt_update_display_after_removed_cue_ref.html
|
||||
|
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<video id="v1" autoplay></video>
|
||||
<script type="text/javascript">
|
||||
|
||||
/**
|
||||
* This test is used to ensure we would update the cue display after removing
|
||||
* cue from the text track, the removed cue should not display on the video's
|
||||
* rendering area.
|
||||
*/
|
||||
function testUpdateDisplayAfterRemovedCue() {
|
||||
let video = document.getElementById("v1");
|
||||
video.src = "../black.mp4";
|
||||
let cue = new VTTCue(0, 4, "hello testing");
|
||||
let track = video.addTextTrack("captions");
|
||||
track.mode = "showing";
|
||||
track.addCue(cue);
|
||||
cue.onenter = () => {
|
||||
cue.onenter = null;
|
||||
track.removeCue(cue);
|
||||
video.pause();
|
||||
video.onpause = () => {
|
||||
video.onpause = null;
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("MozReftestInvalidate",
|
||||
testUpdateDisplayAfterRemovedCue);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<video id="v1" src="../black.mp4"></video>
|
||||
</body>
|
||||
</html>
|
@ -227,6 +227,10 @@ Maybe<TextureHost::ResourceUpdateOp> AsyncImagePipelineManager::UpdateImageKeys(
|
||||
aPipeline->mCurrentTexture = texture;
|
||||
|
||||
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
|
||||
MOZ_ASSERT(wrTexture);
|
||||
if (!wrTexture) {
|
||||
gfxCriticalNote << "WebRenderTextureHost is not used";
|
||||
}
|
||||
|
||||
bool useExternalImage = !gfxEnv::EnableWebRenderRecording() && wrTexture;
|
||||
aPipeline->mUseExternalImage = useExternalImage;
|
||||
@ -386,7 +390,7 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
|
||||
aSceneBuilderTxn.UpdateEpoch(aPipelineId, aEpoch);
|
||||
if (aPipeline->mCurrentTexture) {
|
||||
HoldExternalImage(aPipelineId, aEpoch,
|
||||
aPipeline->mCurrentTexture->AsWebRenderTextureHost());
|
||||
aPipeline->mCurrentTexture);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -429,7 +433,7 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline(
|
||||
builder, wr::ToRoundedLayoutRect(rect), wr::ToRoundedLayoutRect(rect),
|
||||
aPipeline->mFilter, range_keys);
|
||||
HoldExternalImage(aPipelineId, aEpoch,
|
||||
aPipeline->mCurrentTexture->AsWebRenderTextureHost());
|
||||
aPipeline->mCurrentTexture);
|
||||
} else {
|
||||
MOZ_ASSERT(keys.Length() == 1);
|
||||
builder.PushImage(wr::ToRoundedLayoutRect(rect),
|
||||
@ -510,7 +514,7 @@ void AsyncImagePipelineManager::SetEmptyDisplayList(
|
||||
|
||||
void AsyncImagePipelineManager::HoldExternalImage(
|
||||
const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch,
|
||||
WebRenderTextureHost* aTexture) {
|
||||
TextureHost* aTexture) {
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class AsyncImagePipelineManager final {
|
||||
|
||||
void HoldExternalImage(const wr::PipelineId& aPipelineId,
|
||||
const wr::Epoch& aEpoch,
|
||||
WebRenderTextureHost* aTexture);
|
||||
TextureHost* aTexture);
|
||||
void HoldExternalImage(const wr::PipelineId& aPipelineId,
|
||||
const wr::Epoch& aEpoch,
|
||||
WebRenderTextureHostWrapper* aWrTextureWrapper);
|
||||
|
56
gfx/wr/webrender/res/cs_gradient.glsl
Normal file
@ -0,0 +1,56 @@
|
||||
/* 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 shared
|
||||
|
||||
varying float vPos;
|
||||
flat varying vec4 vStops;
|
||||
flat varying vec4 vColor0;
|
||||
flat varying vec4 vColor1;
|
||||
flat varying vec4 vColor2;
|
||||
flat varying vec4 vColor3;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
in vec4 aTaskRect;
|
||||
in float aAxisSelect;
|
||||
in vec4 aStops;
|
||||
in vec4 aColor0;
|
||||
in vec4 aColor1;
|
||||
in vec4 aColor2;
|
||||
in vec4 aColor3;
|
||||
in vec2 aStartStop;
|
||||
|
||||
void main(void) {
|
||||
vPos = mix(aStartStop.x, aStartStop.y, mix(aPosition.x, aPosition.y, aAxisSelect));
|
||||
|
||||
vStops = aStops;
|
||||
vColor0 = aColor0;
|
||||
vColor1 = aColor1;
|
||||
vColor2 = aColor2;
|
||||
vColor3 = aColor3;
|
||||
|
||||
gl_Position = uTransform * vec4(aTaskRect.xy + aTaskRect.zw * aPosition.xy, 0.0, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
float linear_step(float edge0, float edge1, float x) {
|
||||
if (edge0 >= edge1) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec4 color = vColor0;
|
||||
|
||||
color = mix(color, vColor1, linear_step(vStops.x, vStops.y, vPos));
|
||||
color = mix(color, vColor2, linear_step(vStops.y, vStops.z, vPos));
|
||||
color = mix(color, vColor3, linear_step(vStops.z, vStops.w, vPos));
|
||||
|
||||
oFragColor = color;
|
||||
}
|
||||
#endif
|
@ -2077,7 +2077,8 @@ impl AlphaBatchBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
PrimitiveInstanceKind::LinearGradient { data_handle, ref visible_tiles_range, .. } => {
|
||||
PrimitiveInstanceKind::LinearGradient { data_handle, gradient_index, .. } => {
|
||||
let gradient = &ctx.prim_store.linear_gradients[gradient_index];
|
||||
let prim_data = &ctx.data_stores.linear_grad[data_handle];
|
||||
let specified_blend_mode = BlendMode::PremultipliedAlpha;
|
||||
|
||||
@ -2090,16 +2091,63 @@ impl AlphaBatchBuilder {
|
||||
transform_id,
|
||||
};
|
||||
|
||||
if visible_tiles_range.is_empty() {
|
||||
let non_segmented_blend_mode = if !prim_data.opacity.is_opaque ||
|
||||
prim_info.clip_task_index != ClipTaskIndex::INVALID ||
|
||||
transform_kind == TransformedRectKind::Complex
|
||||
{
|
||||
specified_blend_mode
|
||||
} else {
|
||||
BlendMode::None
|
||||
let non_segmented_blend_mode = if !prim_data.opacity.is_opaque ||
|
||||
prim_info.clip_task_index != ClipTaskIndex::INVALID ||
|
||||
transform_kind == TransformedRectKind::Complex
|
||||
{
|
||||
specified_blend_mode
|
||||
} else {
|
||||
BlendMode::None
|
||||
};
|
||||
|
||||
if let Some(ref cache_handle) = gradient.cache_handle {
|
||||
let rt_cache_entry = ctx.resource_cache
|
||||
.get_cached_render_task(cache_handle);
|
||||
let cache_item = ctx.resource_cache
|
||||
.get_texture_cache_item(&rt_cache_entry.handle);
|
||||
|
||||
if cache_item.texture_id == TextureSource::Invalid {
|
||||
return;
|
||||
}
|
||||
|
||||
let textures = BatchTextures::color(cache_item.texture_id);
|
||||
let batch_kind = BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id));
|
||||
let prim_user_data = [
|
||||
ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
|
||||
RasterizationSpace::Local as i32,
|
||||
get_shader_opacity(1.0),
|
||||
];
|
||||
let segment_user_data = cache_item.uv_rect_handle.as_int(gpu_cache);
|
||||
prim_header.specific_prim_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
|
||||
|
||||
let prim_header_index = prim_headers.push(
|
||||
&prim_header,
|
||||
z_id,
|
||||
prim_user_data,
|
||||
);
|
||||
|
||||
let batch_key = BatchKey {
|
||||
blend_mode: non_segmented_blend_mode,
|
||||
kind: BatchKind::Brush(batch_kind),
|
||||
textures: textures,
|
||||
};
|
||||
|
||||
let instance = PrimitiveInstanceData::from(BrushInstance {
|
||||
segment_index: INVALID_SEGMENT_INDEX,
|
||||
edge_flags: EdgeAaSegmentMask::all(),
|
||||
clip_task_address,
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
prim_header_index,
|
||||
user_data: segment_user_data,
|
||||
});
|
||||
|
||||
self.current_batch_list().push_single_instance(
|
||||
batch_key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
PrimitiveInstanceData::from(instance),
|
||||
);
|
||||
} else if gradient.visible_tiles_range.is_empty() {
|
||||
let batch_params = BrushBatchParameters::shared(
|
||||
BrushBatchKind::LinearGradient,
|
||||
BatchTextures::no_texture(),
|
||||
@ -2141,7 +2189,7 @@ impl AlphaBatchBuilder {
|
||||
ctx,
|
||||
);
|
||||
} else {
|
||||
let visible_tiles = &ctx.scratch.gradient_tiles[*visible_tiles_range];
|
||||
let visible_tiles = &ctx.scratch.gradient_tiles[gradient.visible_tiles_range];
|
||||
|
||||
add_gradient_tiles(
|
||||
visible_tiles,
|
||||
|
@ -4,28 +4,51 @@
|
||||
|
||||
use api::{
|
||||
ColorF, ColorU,ExtendMode, GradientStop, LayoutPoint, LayoutSize,
|
||||
LayoutPrimitiveInfo, PremultipliedColorF, LayoutVector2D,
|
||||
LayoutPrimitiveInfo, PremultipliedColorF, LayoutVector2D, LineOrientation,
|
||||
};
|
||||
use display_list_flattener::IsVisible;
|
||||
use euclid::approxeq::ApproxEq;
|
||||
use frame_builder::FrameBuildingState;
|
||||
use gpu_cache::{GpuCacheHandle, GpuDataRequest};
|
||||
use intern::{Internable, InternDebug, Handle as InternHandle};
|
||||
use prim_store::{BrushSegment, GradientTileRange};
|
||||
use prim_store::{BrushSegment, GradientTileRange, VectorKey};
|
||||
use prim_store::{PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData};
|
||||
use prim_store::{PrimKeyCommonData, PrimTemplateCommonData, PrimitiveStore};
|
||||
use prim_store::{NinePatchDescriptor, PointKey, SizeKey, InternablePrimitive};
|
||||
use render_task::RenderTaskCacheEntryHandle;
|
||||
use std::{hash, ops::{Deref, DerefMut}, mem};
|
||||
use util::pack_as_float;
|
||||
|
||||
/// The maximum number of stops a gradient may have to use the fast path.
|
||||
pub const GRADIENT_FP_STOPS: usize = 4;
|
||||
|
||||
/// A hashable gradient stop that can be used in primitive keys.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[derive(Debug, Clone, MallocSizeOf, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, MallocSizeOf, PartialEq)]
|
||||
pub struct GradientStopKey {
|
||||
pub offset: f32,
|
||||
pub color: ColorU,
|
||||
}
|
||||
|
||||
impl GradientStopKey {
|
||||
pub fn empty() -> Self {
|
||||
GradientStopKey {
|
||||
offset: 0.0,
|
||||
color: ColorU::new(0, 0, 0, 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<GradientStopKey> for GradientStop {
|
||||
fn into(self) -> GradientStopKey {
|
||||
GradientStopKey {
|
||||
offset: self.offset,
|
||||
color: self.color.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for GradientStopKey {}
|
||||
|
||||
impl hash::Hash for GradientStopKey {
|
||||
@ -76,6 +99,15 @@ impl LinearGradientKey {
|
||||
|
||||
impl InternDebug for LinearGradientKey {}
|
||||
|
||||
#[derive(Clone, Debug, Hash, MallocSizeOf, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct GradientCacheKey {
|
||||
pub orientation: LineOrientation,
|
||||
pub start_stop_point: VectorKey,
|
||||
pub stops: [GradientStopKey; GRADIENT_FP_STOPS],
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[derive(MallocSizeOf)]
|
||||
@ -91,6 +123,9 @@ pub struct LinearGradientTemplate {
|
||||
pub brush_segments: Vec<BrushSegment>,
|
||||
pub reverse_stops: bool,
|
||||
pub stops_handle: GpuCacheHandle,
|
||||
/// If true, this gradient can be drawn via the fast path
|
||||
/// (cache gradient, and draw as image).
|
||||
pub supports_caching: bool,
|
||||
}
|
||||
|
||||
impl Deref for LinearGradientTemplate {
|
||||
@ -111,12 +146,44 @@ impl From<LinearGradientKey> for LinearGradientTemplate {
|
||||
let common = PrimTemplateCommonData::with_key_common(item.common);
|
||||
let mut min_alpha: f32 = 1.0;
|
||||
|
||||
// Check if we can draw this gradient via a fast path by caching the
|
||||
// gradient in a smaller task, and drawing as an image.
|
||||
// TODO(gw): Aim to reduce the constraints on fast path gradients in future,
|
||||
// although this catches the vast majority of gradients on real pages.
|
||||
let mut supports_caching =
|
||||
// No repeating support in fast path
|
||||
item.extend_mode == ExtendMode::Clamp &&
|
||||
// Gradient must cover entire primitive
|
||||
item.tile_spacing.w + item.stretch_size.w >= common.prim_size.width &&
|
||||
item.tile_spacing.h + item.stretch_size.h >= common.prim_size.height &&
|
||||
// Must be a vertical or horizontal gradient
|
||||
(item.start_point.x.approx_eq(&item.end_point.x) ||
|
||||
item.start_point.y.approx_eq(&item.end_point.y)) &&
|
||||
// Fast path supports a limited number of stops
|
||||
item.stops.len() <= GRADIENT_FP_STOPS &&
|
||||
// Fast path not supported on segmented (border-image) gradients.
|
||||
item.nine_patch.is_none();
|
||||
|
||||
// Convert the stops to more convenient representation
|
||||
// for the current gradient builder.
|
||||
let stops = item.stops.iter().map(|stop| {
|
||||
let mut prev_color = None;
|
||||
|
||||
let stops: Vec<GradientStop> = item.stops.iter().map(|stop| {
|
||||
let color: ColorF = stop.color.into();
|
||||
min_alpha = min_alpha.min(color.a);
|
||||
|
||||
if let Some(prev_color) = prev_color {
|
||||
// The fast path doesn't support hard color stops, yet.
|
||||
// Since the length of the gradient is a fixed size (512 device pixels), if there
|
||||
// is a hard stop you will see bilinear interpolation with this method, instead
|
||||
// of an abrupt color change.
|
||||
if prev_color == color {
|
||||
supports_caching = false;
|
||||
}
|
||||
}
|
||||
|
||||
prev_color = Some(color);
|
||||
|
||||
GradientStop {
|
||||
offset: stop.offset,
|
||||
color,
|
||||
@ -146,6 +213,7 @@ impl From<LinearGradientKey> for LinearGradientTemplate {
|
||||
brush_segments,
|
||||
reverse_stops: item.reverse_stops,
|
||||
stops_handle: GpuCacheHandle::new(),
|
||||
supports_caching,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -247,12 +315,17 @@ impl InternablePrimitive for LinearGradient {
|
||||
fn make_instance_kind(
|
||||
_key: LinearGradientKey,
|
||||
data_handle: LinearGradientDataHandle,
|
||||
_prim_store: &mut PrimitiveStore,
|
||||
prim_store: &mut PrimitiveStore,
|
||||
_reference_frame_relative_offset: LayoutVector2D,
|
||||
) -> PrimitiveInstanceKind {
|
||||
let gradient_index = prim_store.linear_gradients.push(LinearGradientPrimitive {
|
||||
cache_handle: None,
|
||||
visible_tiles_range: GradientTileRange::empty(),
|
||||
});
|
||||
|
||||
PrimitiveInstanceKind::LinearGradient {
|
||||
data_handle,
|
||||
visible_tiles_range: GradientTileRange::empty(),
|
||||
gradient_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,6 +336,13 @@ impl IsVisible for LinearGradient {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
pub struct LinearGradientPrimitive {
|
||||
pub cache_handle: Option<RenderTaskCacheEntryHandle>,
|
||||
pub visible_tiles_range: GradientTileRange,
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Hashable radial gradient parameters, for use during prim interning.
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use api::{BorderRadius, ClipMode, ColorF};
|
||||
use api::{FilterOp, ImageRendering, TileOffset, RepeatMode, WorldPoint, WorldSize};
|
||||
use api::{PremultipliedColorF, PropertyBinding, Shadow};
|
||||
use api::{PremultipliedColorF, PropertyBinding, Shadow, GradientStop};
|
||||
use api::{BoxShadowClipMode, LineStyle, LineOrientation, AuHelpers};
|
||||
use api::{LayoutPrimitiveInfo, PrimitiveKeyKind};
|
||||
use api::units::*;
|
||||
@ -17,6 +17,7 @@ use debug_colors;
|
||||
use debug_render::DebugItem;
|
||||
use display_list_flattener::{CreateShadow, IsVisible};
|
||||
use euclid::{SideOffsets2D, TypedTransform3D, TypedRect, TypedScale, TypedSize2D};
|
||||
use euclid::approxeq::ApproxEq;
|
||||
use frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState};
|
||||
use frame_builder::{PrimitiveContext, FrameVisibilityContext, FrameVisibilityState};
|
||||
use glyph_rasterizer::GlyphKey;
|
||||
@ -28,7 +29,8 @@ use malloc_size_of::MallocSizeOf;
|
||||
use picture::{PictureCompositeMode, PicturePrimitive};
|
||||
use picture::{ClusterIndex, PrimitiveList, RecordedDirtyRegion, SurfaceIndex, RetainedTiles, RasterConfig};
|
||||
use prim_store::borders::{ImageBorderDataHandle, NormalBorderDataHandle};
|
||||
use prim_store::gradient::{LinearGradientDataHandle, RadialGradientDataHandle};
|
||||
use prim_store::gradient::{GRADIENT_FP_STOPS, GradientCacheKey, GradientStopKey};
|
||||
use prim_store::gradient::{LinearGradientPrimitive, LinearGradientDataHandle, RadialGradientDataHandle};
|
||||
use prim_store::image::{ImageDataHandle, ImageInstance, VisibleImageTile, YuvImageDataHandle};
|
||||
use prim_store::line_dec::LineDecorationDataHandle;
|
||||
use prim_store::picture::PictureDataHandle;
|
||||
@ -46,6 +48,7 @@ use std::{cmp, fmt, hash, ops, u32, usize, mem};
|
||||
#[cfg(debug_assertions)]
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use storage;
|
||||
use texture_cache::TEXTURE_REGION_DIMENSIONS;
|
||||
use util::{ScaleOffset, MatrixHelpers, MaxRect, Recycler, TransformedRectKind};
|
||||
use util::{pack_as_float, project_rect, raster_rect_to_device_pixels};
|
||||
use util::{scale_factors, clamp_to_scale_factor};
|
||||
@ -1321,7 +1324,7 @@ pub enum PrimitiveInstanceKind {
|
||||
LinearGradient {
|
||||
/// Handle to the common interned data for this primitive.
|
||||
data_handle: LinearGradientDataHandle,
|
||||
visible_tiles_range: GradientTileRange,
|
||||
gradient_index: LinearGradientIndex,
|
||||
},
|
||||
RadialGradient {
|
||||
/// Handle to the common interned data for this primitive.
|
||||
@ -1502,6 +1505,8 @@ pub type ImageInstanceStorage = storage::Storage<ImageInstance>;
|
||||
pub type ImageInstanceIndex = storage::Index<ImageInstance>;
|
||||
pub type GradientTileStorage = storage::Storage<VisibleGradientTile>;
|
||||
pub type GradientTileRange = storage::Range<VisibleGradientTile>;
|
||||
pub type LinearGradientIndex = storage::Index<LinearGradientPrimitive>;
|
||||
pub type LinearGradientStorage = storage::Storage<LinearGradientPrimitive>;
|
||||
|
||||
/// Contains various vecs of data that is used only during frame building,
|
||||
/// where we want to recycle the memory each new display list, to avoid constantly
|
||||
@ -1626,6 +1631,7 @@ pub struct PrimitiveStoreStats {
|
||||
text_run_count: usize,
|
||||
opacity_binding_count: usize,
|
||||
image_count: usize,
|
||||
linear_gradient_count: usize,
|
||||
}
|
||||
|
||||
impl PrimitiveStoreStats {
|
||||
@ -1635,6 +1641,7 @@ impl PrimitiveStoreStats {
|
||||
text_run_count: 0,
|
||||
opacity_binding_count: 0,
|
||||
image_count: 0,
|
||||
linear_gradient_count: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1643,6 +1650,7 @@ impl PrimitiveStoreStats {
|
||||
pub struct PrimitiveStore {
|
||||
pub pictures: Vec<PicturePrimitive>,
|
||||
pub text_runs: TextRunStorage,
|
||||
pub linear_gradients: LinearGradientStorage,
|
||||
|
||||
/// A list of image instances. These are stored separately as
|
||||
/// storing them inline in the instance makes the structure bigger
|
||||
@ -1660,6 +1668,7 @@ impl PrimitiveStore {
|
||||
text_runs: TextRunStorage::new(stats.text_run_count),
|
||||
images: ImageInstanceStorage::new(stats.image_count),
|
||||
opacity_bindings: OpacityBindingStorage::new(stats.opacity_binding_count),
|
||||
linear_gradients: LinearGradientStorage::new(stats.linear_gradient_count),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1669,6 +1678,7 @@ impl PrimitiveStore {
|
||||
text_run_count: self.text_runs.len(),
|
||||
image_count: self.images.len(),
|
||||
opacity_binding_count: self.opacity_bindings.len(),
|
||||
linear_gradient_count: self.linear_gradients.len(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -2730,13 +2740,86 @@ impl PrimitiveStore {
|
||||
image_data.write_prim_gpu_blocks(request);
|
||||
});
|
||||
}
|
||||
PrimitiveInstanceKind::LinearGradient { data_handle, ref mut visible_tiles_range, .. } => {
|
||||
PrimitiveInstanceKind::LinearGradient { data_handle, gradient_index, .. } => {
|
||||
let prim_data = &mut data_stores.linear_grad[*data_handle];
|
||||
let gradient = &mut self.linear_gradients[*gradient_index];
|
||||
|
||||
// Update the template this instane references, which may refresh the GPU
|
||||
// cache with any shared template data.
|
||||
prim_data.update(frame_state);
|
||||
|
||||
if prim_data.supports_caching {
|
||||
let gradient_size = (prim_data.end_point - prim_data.start_point).to_size();
|
||||
|
||||
// Calculate what the range of the gradient is that covers this
|
||||
// primitive. These values are included in the cache key. The
|
||||
// size of the gradient task is the length of a texture cache
|
||||
// region, for maximum accuracy, and a minimal size on the
|
||||
// axis that doesn't matter.
|
||||
let (size, orientation, start_point, end_point) = if prim_data.start_point.x.approx_eq(&prim_data.end_point.x) {
|
||||
let start_point = -prim_data.start_point.y / gradient_size.height;
|
||||
let end_point = (prim_data.common.prim_size.height - prim_data.start_point.y) / gradient_size.height;
|
||||
let size = DeviceIntSize::new(16, TEXTURE_REGION_DIMENSIONS);
|
||||
(size, LineOrientation::Vertical, start_point, end_point)
|
||||
} else {
|
||||
let start_point = -prim_data.start_point.x / gradient_size.width;
|
||||
let end_point = (prim_data.common.prim_size.width - prim_data.start_point.x) / gradient_size.width;
|
||||
let size = DeviceIntSize::new(TEXTURE_REGION_DIMENSIONS, 16);
|
||||
(size, LineOrientation::Horizontal, start_point, end_point)
|
||||
};
|
||||
|
||||
// Build the cache key, including information about the stops.
|
||||
let mut stops = [GradientStopKey::empty(); GRADIENT_FP_STOPS];
|
||||
|
||||
// Reverse the stops as required, same as the gradient builder does
|
||||
// for the slow path.
|
||||
if prim_data.reverse_stops {
|
||||
for (src, dest) in prim_data.stops.iter().rev().zip(stops.iter_mut()) {
|
||||
let stop = GradientStop {
|
||||
offset: 1.0 - src.offset,
|
||||
color: src.color,
|
||||
};
|
||||
*dest = stop.into();
|
||||
}
|
||||
} else {
|
||||
for (src, dest) in prim_data.stops.iter().zip(stops.iter_mut()) {
|
||||
*dest = (*src).into();
|
||||
}
|
||||
}
|
||||
|
||||
let cache_key = GradientCacheKey {
|
||||
orientation,
|
||||
start_stop_point: VectorKey {
|
||||
x: start_point,
|
||||
y: end_point,
|
||||
},
|
||||
stops,
|
||||
};
|
||||
|
||||
// Request the render task each frame.
|
||||
gradient.cache_handle = Some(frame_state.resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
size: size,
|
||||
kind: RenderTaskCacheKeyKind::Gradient(cache_key),
|
||||
},
|
||||
frame_state.gpu_cache,
|
||||
frame_state.render_tasks,
|
||||
None,
|
||||
prim_data.stops_opacity.is_opaque,
|
||||
|render_tasks| {
|
||||
let task = RenderTask::new_gradient(
|
||||
size,
|
||||
stops,
|
||||
orientation,
|
||||
start_point,
|
||||
end_point,
|
||||
);
|
||||
|
||||
render_tasks.add(task)
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
if prim_data.tile_spacing != LayoutSize::zero() {
|
||||
let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
|
||||
let prim_rect = LayoutRect::new(
|
||||
@ -2744,7 +2827,7 @@ impl PrimitiveStore {
|
||||
prim_data.common.prim_size,
|
||||
);
|
||||
|
||||
*visible_tiles_range = decompose_repeated_primitive(
|
||||
gradient.visible_tiles_range = decompose_repeated_primitive(
|
||||
&prim_info.combined_local_clip_rect,
|
||||
&prim_rect,
|
||||
&prim_data.stretch_size,
|
||||
@ -2768,7 +2851,7 @@ impl PrimitiveStore {
|
||||
}
|
||||
);
|
||||
|
||||
if visible_tiles_range.is_empty() {
|
||||
if gradient.visible_tiles_range.is_empty() {
|
||||
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ use internal_types::{CacheTextureId, FastHashMap, LayerIndex, SavedTargetIndex};
|
||||
use pathfinder_partitioner::mesh::Mesh;
|
||||
use prim_store::PictureIndex;
|
||||
use prim_store::image::ImageCacheKey;
|
||||
use prim_store::gradient::{GRADIENT_FP_STOPS, GradientCacheKey, GradientStopKey};
|
||||
use prim_store::line_dec::LineDecorationCacheKey;
|
||||
#[cfg(feature = "debugger")]
|
||||
use print_tree::{PrintTreePrinter};
|
||||
@ -379,6 +380,16 @@ pub struct BlitTask {
|
||||
pub padding: DeviceIntSideOffsets,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct GradientTask {
|
||||
pub stops: [GradientStopKey; GRADIENT_FP_STOPS],
|
||||
pub orientation: LineOrientation,
|
||||
pub start_point: f32,
|
||||
pub end_point: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -411,6 +422,7 @@ pub enum RenderTaskKind {
|
||||
Blit(BlitTask),
|
||||
Border(BorderTask),
|
||||
LineDecoration(LineDecorationTask),
|
||||
Gradient(GradientTask),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
@ -495,6 +507,26 @@ impl RenderTask {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_gradient(
|
||||
size: DeviceIntSize,
|
||||
stops: [GradientStopKey; GRADIENT_FP_STOPS],
|
||||
orientation: LineOrientation,
|
||||
start_point: f32,
|
||||
end_point: f32,
|
||||
) -> Self {
|
||||
RenderTask::with_dynamic_location(
|
||||
size,
|
||||
Vec::new(),
|
||||
RenderTaskKind::Gradient(GradientTask {
|
||||
stops,
|
||||
orientation,
|
||||
start_point,
|
||||
end_point,
|
||||
}),
|
||||
ClearMode::DontCare,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_blit(
|
||||
size: DeviceIntSize,
|
||||
source: BlitSource,
|
||||
@ -865,6 +897,7 @@ impl RenderTask {
|
||||
RenderTaskKind::ClipRegion(..) |
|
||||
RenderTaskKind::Glyph(_) |
|
||||
RenderTaskKind::Border(..) |
|
||||
RenderTaskKind::Gradient(..) |
|
||||
RenderTaskKind::LineDecoration(..) |
|
||||
RenderTaskKind::Blit(..) => {
|
||||
UvRectKind::Rect
|
||||
@ -921,6 +954,7 @@ impl RenderTask {
|
||||
RenderTaskKind::Scaling(..) |
|
||||
RenderTaskKind::Border(..) |
|
||||
RenderTaskKind::LineDecoration(..) |
|
||||
RenderTaskKind::Gradient(..) |
|
||||
RenderTaskKind::Blit(..) => {
|
||||
[0.0; 3]
|
||||
}
|
||||
@ -962,6 +996,7 @@ impl RenderTask {
|
||||
RenderTaskKind::Blit(..) |
|
||||
RenderTaskKind::Border(..) |
|
||||
RenderTaskKind::CacheMask(..) |
|
||||
RenderTaskKind::Gradient(..) |
|
||||
RenderTaskKind::LineDecoration(..) |
|
||||
RenderTaskKind::Glyph(..) => {
|
||||
panic!("texture handle not supported for this task kind");
|
||||
@ -1031,6 +1066,7 @@ impl RenderTask {
|
||||
}
|
||||
|
||||
RenderTaskKind::Border(..) |
|
||||
RenderTaskKind::Gradient(..) |
|
||||
RenderTaskKind::Picture(..) => {
|
||||
RenderTargetKind::Color
|
||||
}
|
||||
@ -1067,6 +1103,7 @@ impl RenderTask {
|
||||
RenderTaskKind::ClipRegion(..) |
|
||||
RenderTaskKind::Border(..) |
|
||||
RenderTaskKind::CacheMask(..) |
|
||||
RenderTaskKind::Gradient(..) |
|
||||
RenderTaskKind::LineDecoration(..) |
|
||||
RenderTaskKind::Glyph(..) => {
|
||||
return;
|
||||
@ -1126,6 +1163,9 @@ impl RenderTask {
|
||||
RenderTaskKind::Glyph(..) => {
|
||||
pt.new_level("Glyph".to_owned());
|
||||
}
|
||||
RenderTaskKind::Gradient(..) => {
|
||||
pt.new_level("Gradient".to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
pt.add_item(format!("clear to: {:?}", self.clear_mode));
|
||||
@ -1164,6 +1204,7 @@ pub enum RenderTaskCacheKeyKind {
|
||||
Glyph(GpuGlyphCacheKey),
|
||||
BorderSegment(BorderSegmentCacheKey),
|
||||
LineDecoration(LineDecorationCacheKey),
|
||||
Gradient(GradientCacheKey),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
|
@ -176,6 +176,10 @@ const GPU_TAG_CACHE_LINE_DECORATION: GpuProfileTag = GpuProfileTag {
|
||||
label: "C_LineDecoration",
|
||||
color: debug_colors::YELLOWGREEN,
|
||||
};
|
||||
const GPU_TAG_CACHE_GRADIENT: GpuProfileTag = GpuProfileTag {
|
||||
label: "C_Gradient",
|
||||
color: debug_colors::BROWN,
|
||||
};
|
||||
const GPU_TAG_SETUP_TARGET: GpuProfileTag = GpuProfileTag {
|
||||
label: "target init",
|
||||
color: debug_colors::SLATEGREY,
|
||||
@ -439,6 +443,62 @@ pub(crate) mod desc {
|
||||
],
|
||||
};
|
||||
|
||||
pub const GRADIENT: VertexDescriptor = VertexDescriptor {
|
||||
vertex_attributes: &[
|
||||
VertexAttribute {
|
||||
name: "aPosition",
|
||||
count: 2,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
],
|
||||
instance_attributes: &[
|
||||
VertexAttribute {
|
||||
name: "aTaskRect",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aStops",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
// TODO(gw): We should probably pack these as u32 colors instead
|
||||
// of passing as full float vec4 here. It won't make much
|
||||
// difference in real world, since these are only invoked
|
||||
// rarely, when creating the cache.
|
||||
VertexAttribute {
|
||||
name: "aColor0",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aColor1",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aColor2",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aColor3",
|
||||
count: 4,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aAxisSelect",
|
||||
count: 1,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
VertexAttribute {
|
||||
name: "aStartStop",
|
||||
count: 2,
|
||||
kind: VertexAttributeKind::F32,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
pub const BORDER: VertexDescriptor = VertexDescriptor {
|
||||
vertex_attributes: &[
|
||||
VertexAttribute {
|
||||
@ -681,6 +741,7 @@ pub(crate) enum VertexArrayKind {
|
||||
Border,
|
||||
Scale,
|
||||
LineDecoration,
|
||||
Gradient,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@ -1506,6 +1567,7 @@ pub struct RendererVAOs {
|
||||
border_vao: VAO,
|
||||
line_vao: VAO,
|
||||
scale_vao: VAO,
|
||||
gradient_vao: VAO,
|
||||
}
|
||||
|
||||
/// The renderer is responsible for submitting to the GPU the work prepared by the
|
||||
@ -1822,6 +1884,7 @@ impl Renderer {
|
||||
let border_vao = device.create_vao_with_new_instances(&desc::BORDER, &prim_vao);
|
||||
let scale_vao = device.create_vao_with_new_instances(&desc::SCALE, &prim_vao);
|
||||
let line_vao = device.create_vao_with_new_instances(&desc::LINE, &prim_vao);
|
||||
let gradient_vao = device.create_vao_with_new_instances(&desc::GRADIENT, &prim_vao);
|
||||
let texture_cache_upload_pbo = device.create_pbo();
|
||||
|
||||
let texture_resolver = TextureResolver::new(&mut device);
|
||||
@ -2025,6 +2088,7 @@ impl Renderer {
|
||||
clip_vao,
|
||||
border_vao,
|
||||
scale_vao,
|
||||
gradient_vao,
|
||||
line_vao,
|
||||
},
|
||||
transforms_texture,
|
||||
@ -3832,24 +3896,42 @@ impl Renderer {
|
||||
self.set_blend(true, FramebufferKind::Other);
|
||||
self.set_blend_mode_premultiplied_alpha(FramebufferKind::Other);
|
||||
|
||||
if !target.line_decorations.is_empty() {
|
||||
self.shaders.borrow_mut().cs_line_decoration.bind(
|
||||
&mut self.device,
|
||||
&projection,
|
||||
&mut self.renderer_errors,
|
||||
);
|
||||
self.shaders.borrow_mut().cs_line_decoration.bind(
|
||||
&mut self.device,
|
||||
&projection,
|
||||
&mut self.renderer_errors,
|
||||
);
|
||||
|
||||
self.draw_instanced_batch(
|
||||
&target.line_decorations,
|
||||
VertexArrayKind::LineDecoration,
|
||||
&BatchTextures::no_texture(),
|
||||
stats,
|
||||
);
|
||||
}
|
||||
self.draw_instanced_batch(
|
||||
&target.line_decorations,
|
||||
VertexArrayKind::LineDecoration,
|
||||
&BatchTextures::no_texture(),
|
||||
stats,
|
||||
);
|
||||
|
||||
self.set_blend(false, FramebufferKind::Other);
|
||||
}
|
||||
|
||||
// Draw any gradients for this target.
|
||||
if !target.gradients.is_empty() {
|
||||
let _timer = self.gpu_profile.start_timer(GPU_TAG_CACHE_GRADIENT);
|
||||
|
||||
self.set_blend(false, FramebufferKind::Other);
|
||||
|
||||
self.shaders.borrow_mut().cs_gradient.bind(
|
||||
&mut self.device,
|
||||
&projection,
|
||||
&mut self.renderer_errors,
|
||||
);
|
||||
|
||||
self.draw_instanced_batch(
|
||||
&target.gradients,
|
||||
VertexArrayKind::Gradient,
|
||||
&BatchTextures::no_texture(),
|
||||
stats,
|
||||
);
|
||||
}
|
||||
|
||||
// Draw any blurs for this target.
|
||||
if !target.horizontal_blurs.is_empty() {
|
||||
let _timer = self.gpu_profile.start_timer(GPU_TAG_BLUR);
|
||||
@ -4713,6 +4795,7 @@ impl Renderer {
|
||||
self.texture_resolver.deinit(&mut self.device);
|
||||
self.device.delete_vao(self.vaos.prim_vao);
|
||||
self.device.delete_vao(self.vaos.clip_vao);
|
||||
self.device.delete_vao(self.vaos.gradient_vao);
|
||||
self.device.delete_vao(self.vaos.blur_vao);
|
||||
self.device.delete_vao(self.vaos.line_vao);
|
||||
self.device.delete_vao(self.vaos.border_vao);
|
||||
@ -5490,6 +5573,7 @@ fn get_vao<'a>(vertex_array_kind: VertexArrayKind,
|
||||
VertexArrayKind::Border => &vaos.border_vao,
|
||||
VertexArrayKind::Scale => &vaos.scale_vao,
|
||||
VertexArrayKind::LineDecoration => &vaos.line_vao,
|
||||
VertexArrayKind::Gradient => &vaos.gradient_vao,
|
||||
}
|
||||
}
|
||||
|
||||
@ -5506,6 +5590,7 @@ fn get_vao<'a>(vertex_array_kind: VertexArrayKind,
|
||||
VertexArrayKind::Border => &vaos.border_vao,
|
||||
VertexArrayKind::Scale => &vaos.scale_vao,
|
||||
VertexArrayKind::LineDecoration => &vaos.line_vao,
|
||||
VertexArrayKind::Gradient => &vaos.gradient_vao,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,6 +167,7 @@ impl LazilyCompiledShader {
|
||||
let vertex_descriptor = match vertex_format {
|
||||
VertexArrayKind::Primitive => &desc::PRIM_INSTANCES,
|
||||
VertexArrayKind::LineDecoration => &desc::LINE,
|
||||
VertexArrayKind::Gradient => &desc::GRADIENT,
|
||||
VertexArrayKind::Blur => &desc::BLUR,
|
||||
VertexArrayKind::Clip => &desc::CLIP,
|
||||
VertexArrayKind::VectorStencil => &desc::VECTOR_STENCIL,
|
||||
@ -447,6 +448,7 @@ pub struct Shaders {
|
||||
pub cs_scale_a8: LazilyCompiledShader,
|
||||
pub cs_scale_rgba8: LazilyCompiledShader,
|
||||
pub cs_line_decoration: LazilyCompiledShader,
|
||||
pub cs_gradient: LazilyCompiledShader,
|
||||
|
||||
// Brush shaders
|
||||
brush_solid: BrushShader,
|
||||
@ -667,6 +669,14 @@ impl Shaders {
|
||||
options.precache_flags,
|
||||
)?;
|
||||
|
||||
let cs_gradient = LazilyCompiledShader::new(
|
||||
ShaderKind::Cache(VertexArrayKind::Gradient),
|
||||
"cs_gradient",
|
||||
&[],
|
||||
device,
|
||||
options.precache_flags,
|
||||
)?;
|
||||
|
||||
let cs_border_segment = LazilyCompiledShader::new(
|
||||
ShaderKind::Cache(VertexArrayKind::Border),
|
||||
"cs_border_segment",
|
||||
@ -696,6 +706,7 @@ impl Shaders {
|
||||
cs_blur_rgba8,
|
||||
cs_border_segment,
|
||||
cs_line_decoration,
|
||||
cs_gradient,
|
||||
cs_border_solid,
|
||||
cs_scale_a8,
|
||||
cs_scale_rgba8,
|
||||
@ -792,6 +803,7 @@ impl Shaders {
|
||||
}
|
||||
}
|
||||
self.cs_border_solid.deinit(device);
|
||||
self.cs_gradient.deinit(device);
|
||||
self.cs_line_decoration.deinit(device);
|
||||
self.cs_border_segment.deinit(device);
|
||||
self.ps_split_composite.deinit(device);
|
||||
|
@ -23,7 +23,7 @@ use std::time::{Duration, SystemTime};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// The size of each region/layer in shared cache texture arrays.
|
||||
const TEXTURE_REGION_DIMENSIONS: i32 = 512;
|
||||
pub const TEXTURE_REGION_DIMENSIONS: i32 = 512;
|
||||
|
||||
/// The number of slices for picture caching to allocate at start.
|
||||
const BASE_PICTURE_TEXTURE_SLICES: usize = 16;
|
||||
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
use api::{ColorF, BorderStyle, MixBlendMode, PipelineId};
|
||||
use api::{DocumentLayer, FilterData, FilterOp, ImageFormat};
|
||||
use api::{ColorF, BorderStyle, MixBlendMode, PipelineId, PremultipliedColorF};
|
||||
use api::{DocumentLayer, FilterData, FilterOp, ImageFormat, LineOrientation};
|
||||
use api::units::*;
|
||||
use batch::{AlphaBatchBuilder, AlphaBatchContainer, ClipBatcher, resolve_image};
|
||||
use clip::ClipStore;
|
||||
@ -20,6 +20,7 @@ use internal_types::{CacheTextureId, FastHashMap, SavedTargetIndex, TextureSourc
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use pathfinder_partitioner::mesh::Mesh;
|
||||
use picture::{RecordedDirtyRegion, SurfaceInfo};
|
||||
use prim_store::gradient::GRADIENT_FP_STOPS;
|
||||
use prim_store::{PictureIndex, PrimitiveStore, DeferredResolve, PrimitiveScratchBuffer};
|
||||
use profiler::FrameProfileCounters;
|
||||
use render_backend::{DataStores, FrameId};
|
||||
@ -332,6 +333,17 @@ pub struct LineDecorationJob {
|
||||
pub orientation: i32,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[repr(C)]
|
||||
pub struct GradientJob {
|
||||
pub task_rect: DeviceRect,
|
||||
pub stops: [f32; GRADIENT_FP_STOPS],
|
||||
pub colors: [PremultipliedColorF; GRADIENT_FP_STOPS],
|
||||
pub axis_select: f32,
|
||||
pub start_stop: [f32; 2],
|
||||
}
|
||||
|
||||
#[cfg(feature = "pathfinder")]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -505,6 +517,7 @@ impl RenderTarget for ColorRenderTarget {
|
||||
RenderTaskKind::ClipRegion(..) |
|
||||
RenderTaskKind::Border(..) |
|
||||
RenderTaskKind::CacheMask(..) |
|
||||
RenderTaskKind::Gradient(..) |
|
||||
RenderTaskKind::LineDecoration(..) => {
|
||||
panic!("Should not be added to color target!");
|
||||
}
|
||||
@ -648,6 +661,7 @@ impl RenderTarget for AlphaRenderTarget {
|
||||
RenderTaskKind::Blit(..) |
|
||||
RenderTaskKind::Border(..) |
|
||||
RenderTaskKind::LineDecoration(..) |
|
||||
RenderTaskKind::Gradient(..) |
|
||||
RenderTaskKind::Glyph(..) => {
|
||||
panic!("BUG: should not be added to alpha target!");
|
||||
}
|
||||
@ -736,6 +750,7 @@ pub struct TextureCacheRenderTarget {
|
||||
pub border_segments_solid: Vec<BorderInstance>,
|
||||
pub clears: Vec<DeviceIntRect>,
|
||||
pub line_decorations: Vec<LineDecorationJob>,
|
||||
pub gradients: Vec<GradientJob>,
|
||||
}
|
||||
|
||||
impl TextureCacheRenderTarget {
|
||||
@ -749,6 +764,7 @@ impl TextureCacheRenderTarget {
|
||||
border_segments_solid: vec![],
|
||||
clears: vec![],
|
||||
line_decorations: vec![],
|
||||
gradients: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,6 +837,28 @@ impl TextureCacheRenderTarget {
|
||||
RenderTaskKind::Glyph(ref mut task_info) => {
|
||||
self.add_glyph_task(task_info, target_rect.0)
|
||||
}
|
||||
RenderTaskKind::Gradient(ref task_info) => {
|
||||
let mut stops = [0.0; 4];
|
||||
let mut colors = [PremultipliedColorF::BLACK; 4];
|
||||
|
||||
let axis_select = match task_info.orientation {
|
||||
LineOrientation::Horizontal => 0.0,
|
||||
LineOrientation::Vertical => 1.0,
|
||||
};
|
||||
|
||||
for (stop, (offset, color)) in task_info.stops.iter().zip(stops.iter_mut().zip(colors.iter_mut())) {
|
||||
*offset = stop.offset;
|
||||
*color = ColorF::from(stop.color).premultiplied();
|
||||
}
|
||||
|
||||
self.gradients.push(GradientJob {
|
||||
task_rect: target_rect.0.to_f32(),
|
||||
axis_select,
|
||||
stops,
|
||||
colors,
|
||||
start_stop: [task_info.start_point, task_info.end_point],
|
||||
});
|
||||
}
|
||||
RenderTaskKind::VerticalBlur(..) |
|
||||
RenderTaskKind::Picture(..) |
|
||||
RenderTaskKind::ClipRegion(..) |
|
||||
|
@ -51,6 +51,10 @@ const SHADERS: &[Shader] = &[
|
||||
name: "cs_line_decoration",
|
||||
features: CACHE_FEATURES,
|
||||
},
|
||||
Shader {
|
||||
name: "cs_gradient",
|
||||
features: CACHE_FEATURES,
|
||||
},
|
||||
Shader {
|
||||
name: "cs_border_solid",
|
||||
features: CACHE_FEATURES,
|
||||
|
@ -1,5 +1,5 @@
|
||||
platform(linux,mac) == border-clamp-corner-radius.yaml border-clamp-corner-radius.png
|
||||
== border-gradient-simple.yaml border-gradient-simple-ref.yaml
|
||||
fuzzy(1,790) == border-gradient-simple.yaml border-gradient-simple-ref.yaml
|
||||
platform(linux,mac) == border-gradient-nine-patch.yaml border-gradient-nine-patch.png
|
||||
== border-radial-gradient-simple.yaml border-radial-gradient-simple-ref.yaml
|
||||
platform(linux,mac) == border-radial-gradient-nine-patch.yaml border-radial-gradient-nine-patch.png
|
||||
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 912 B |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
@ -18,7 +18,7 @@ platform(linux,mac) fuzzy(1,35000) == linear-stops.yaml linear-stops-ref.png
|
||||
fuzzy(1,20000) == linear.yaml linear-ref.yaml
|
||||
fuzzy(1,20000) == linear-reverse.yaml linear-ref.yaml
|
||||
|
||||
== linear-aligned-clip.yaml linear-aligned-clip-ref.yaml
|
||||
fuzzy(1,15200) == linear-aligned-clip.yaml linear-aligned-clip-ref.yaml
|
||||
|
||||
platform(linux,mac) fuzzy(1,80000) == radial-circle.yaml radial-circle-ref.png
|
||||
platform(linux,mac) fuzzy(1,80000) == radial-ellipse.yaml radial-ellipse-ref.png
|
||||
@ -44,9 +44,9 @@ fuzzy(255,2664) == repeat-radial.yaml repeat-radial-ref.yaml
|
||||
fuzzy(255,2664) == repeat-radial-negative.yaml repeat-radial-ref.yaml
|
||||
|
||||
# fuzzy because of thin spaced out column of pixels that are 1 off
|
||||
fuzzy(1,50) == tiling-linear-1.yaml tiling-linear-1-ref.yaml
|
||||
fuzzy(1,38) == tiling-linear-2.yaml tiling-linear-2-ref.yaml
|
||||
== tiling-linear-3.yaml tiling-linear-3-ref.yaml
|
||||
fuzzy(1,83164) == tiling-linear-1.yaml tiling-linear-1-ref.yaml
|
||||
fuzzy(1,46279) == tiling-linear-2.yaml tiling-linear-2-ref.yaml
|
||||
fuzzy(1,62154) == tiling-linear-3.yaml tiling-linear-3-ref.yaml
|
||||
|
||||
fuzzy(1,17) == tiling-radial-1.yaml tiling-radial-1-ref.yaml
|
||||
fuzzy(1,1) == tiling-radial-2.yaml tiling-radial-2-ref.yaml
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@ -75,6 +75,8 @@ var gFunctions = [
|
||||
[2, (n) => n!=0?1:0],
|
||||
// 18: Welsh
|
||||
[6, (n) => n==0?0:n==1?1:n==2?2:n==3?3:n==6?4:5],
|
||||
// 19: Slavic languages (bs, hr, sr). Same as rule 7, but resulting in different CLDR categories
|
||||
[3, (n) => n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2],
|
||||
];
|
||||
|
||||
var PluralForm = {
|
||||
|
@ -657,6 +657,40 @@ function run_test()
|
||||
6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,
|
||||
], [
|
||||
// 19: Slavic languages (bs, hr, sr) 0-9, 10-19, ..., 90-99
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
// 100-109, 110-119, ..., 190-199
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
// 200-209, 210-219, ..., 290-299
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
3,1,2,2,2,3,3,3,3,3,
|
||||
]];
|
||||
|
||||
for (let [rule, expect] of allExpect.entries()) {
|
||||
|
@ -44,3 +44,4 @@ CPPFLAGS="$CPPFLAGS -Wno-attributes -Wno-ignored-attributes"
|
||||
CXXFLAGS="$CXXFLAGS -Wno-attributes -Wno-ignored-attributes"
|
||||
|
||||
NODEJS="$TOOLTOOL_DIR/node/bin/node"
|
||||
NASM="$TOOLTOOL_DIR/nasm/nasm"
|
||||
|
@ -194,7 +194,7 @@ void js::Nursery::enable() {
|
||||
if (!allocateNextChunk(0, lock)) {
|
||||
return;
|
||||
}
|
||||
capacity_ = NurseryChunkUsableSize;
|
||||
capacity_ = SubChunkLimit;
|
||||
}
|
||||
|
||||
setCurrentChunk(0, true);
|
||||
|
11
js/src/jit-test/tests/gc/bug1532289.js
Normal file
@ -0,0 +1,11 @@
|
||||
// |jit-test| --ion-warmup-threshold=0; --ion-offthread-compile=off; skip-if: !getJitCompilerOptions()['baseline.enable']
|
||||
|
||||
// gczeal mode causes test to run too slowly with --no-baseline
|
||||
gczeal(4,40);
|
||||
|
||||
var x;
|
||||
var y = false;
|
||||
|
||||
function f(v) { x = v; while (y) {} }
|
||||
|
||||
for (var z=1; z < 1e5; z++) { f(BigInt(z)); }
|
@ -1852,7 +1852,7 @@ bool HeapTypeSetKey::needsBarrier(CompilerConstraintList* constraints) {
|
||||
return false;
|
||||
}
|
||||
bool result = types->unknownObject() || types->getObjectCount() > 0 ||
|
||||
types->hasAnyFlag(TYPE_FLAG_STRING | TYPE_FLAG_SYMBOL);
|
||||
types->hasAnyFlag(TYPE_FLAG_PRIMITIVE_GCTHING);
|
||||
if (!result) {
|
||||
freeze(constraints);
|
||||
}
|
||||
|
@ -87,10 +87,16 @@ enum : uint32_t {
|
||||
TYPE_FLAG_LAZYARGS = 0x100,
|
||||
TYPE_FLAG_ANYOBJECT = 0x200,
|
||||
|
||||
/* Mask containing all "immediate" primitives (not heap-allocated) */
|
||||
TYPE_FLAG_PRIMITIVE_IMMEDIATE = TYPE_FLAG_UNDEFINED | TYPE_FLAG_NULL |
|
||||
TYPE_FLAG_BOOLEAN | TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE,
|
||||
/* Mask containing all GCThing primitives (heap-allocated) */
|
||||
TYPE_FLAG_PRIMITIVE_GCTHING =
|
||||
TYPE_FLAG_STRING | TYPE_FLAG_SYMBOL | TYPE_FLAG_BIGINT,
|
||||
|
||||
/* Mask containing all primitives */
|
||||
TYPE_FLAG_PRIMITIVE = TYPE_FLAG_UNDEFINED | TYPE_FLAG_NULL |
|
||||
TYPE_FLAG_BOOLEAN | TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE |
|
||||
TYPE_FLAG_STRING | TYPE_FLAG_SYMBOL | TYPE_FLAG_BIGINT,
|
||||
TYPE_FLAG_PRIMITIVE =
|
||||
TYPE_FLAG_PRIMITIVE_IMMEDIATE | TYPE_FLAG_PRIMITIVE_GCTHING,
|
||||
|
||||
/* Mask/shift for the number of objects in objectSet */
|
||||
TYPE_FLAG_OBJECT_COUNT_MASK = 0x3c00,
|
||||
|
@ -7629,302 +7629,307 @@ nsresult PresShell::EventHandler::HandleEventWithTarget(
|
||||
nsresult PresShell::EventHandler::HandleEventInternal(
|
||||
WidgetEvent* aEvent, nsEventStatus* aEventStatus,
|
||||
bool aIsHandlingNativeEvent, nsIContent* aOverrideClickTarget) {
|
||||
MOZ_ASSERT(aEvent);
|
||||
MOZ_ASSERT(aEventStatus);
|
||||
|
||||
RefPtr<EventStateManager> manager = GetPresContext()->EventStateManager();
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!NS_EVENT_NEEDS_FRAME(aEvent) || mPresShell->GetCurrentEventFrame() ||
|
||||
mPresShell->GetCurrentEventContent()) {
|
||||
bool touchIsNew = false;
|
||||
bool isHandlingUserInput = false;
|
||||
// If we cannot handle the event with mPresShell because of no target,
|
||||
// just record the response time.
|
||||
// XXX Is this intentional? In such case, the score is really good because
|
||||
// of nothing to do. So, it may make average and median better.
|
||||
if (NS_EVENT_NEEDS_FRAME(aEvent) && !mPresShell->GetCurrentEventFrame() &&
|
||||
!mPresShell->GetCurrentEventContent()) {
|
||||
RecordEventHandlingResponsePerformance(aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mPresShell->mCurrentEventContent &&
|
||||
aEvent->IsTargetedAtFocusedWindow()) {
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
fm->FlushBeforeEventHandlingIfNeeded(mPresShell->mCurrentEventContent);
|
||||
}
|
||||
bool touchIsNew = false;
|
||||
bool isHandlingUserInput = false;
|
||||
|
||||
if (mPresShell->mCurrentEventContent && aEvent->IsTargetedAtFocusedWindow()) {
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
fm->FlushBeforeEventHandlingIfNeeded(mPresShell->mCurrentEventContent);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX How about IME events and input events for plugins?
|
||||
if (aEvent->IsTrusted()) {
|
||||
if (aEvent->IsUserAction()) {
|
||||
mPresShell->mHasHandledUserInput = true;
|
||||
}
|
||||
|
||||
switch (aEvent->mMessage) {
|
||||
case eKeyPress:
|
||||
case eKeyDown:
|
||||
case eKeyUp: {
|
||||
Document* doc = mPresShell->GetCurrentEventContent()
|
||||
? mPresShell->mCurrentEventContent->OwnerDoc()
|
||||
: nullptr;
|
||||
auto keyCode = aEvent->AsKeyboardEvent()->mKeyCode;
|
||||
if (keyCode == NS_VK_ESCAPE) {
|
||||
Document* root = nsContentUtils::GetRootDocument(doc);
|
||||
if (root && root->GetFullscreenElement()) {
|
||||
// Prevent default action on ESC key press when exiting
|
||||
// DOM fullscreen mode. This prevents the browser ESC key
|
||||
// handler from stopping all loads in the document, which
|
||||
// would cause <video> loads to stop.
|
||||
// XXX We need to claim the Escape key event which will be
|
||||
// dispatched only into chrome is already consumed by
|
||||
// content because we need to prevent its default here
|
||||
// for some reasons (not sure) but we need to detect
|
||||
// if a chrome event handler will call PreventDefault()
|
||||
// again and check it later.
|
||||
aEvent->PreventDefaultBeforeDispatch(
|
||||
CrossProcessForwarding::eStop);
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
|
||||
// The event listeners in chrome can prevent this ESC behavior by
|
||||
// calling prevent default on the preceding keydown/press events.
|
||||
if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed &&
|
||||
aEvent->mMessage == eKeyUp) {
|
||||
// ESC key released while in DOM fullscreen mode.
|
||||
// Fully exit all browser windows and documents from
|
||||
// fullscreen mode.
|
||||
Document::AsyncExitFullscreen(nullptr);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<Document> pointerLockedDoc =
|
||||
do_QueryReferent(EventStateManager::sPointerLockedDoc);
|
||||
if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed &&
|
||||
pointerLockedDoc) {
|
||||
// XXX See above comment to understand the reason why this needs
|
||||
// to claim that the Escape key event is consumed by content
|
||||
// even though it will be dispatched only into chrome.
|
||||
aEvent->PreventDefaultBeforeDispatch(
|
||||
CrossProcessForwarding::eStop);
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
if (aEvent->mMessage == eKeyUp) {
|
||||
Document::UnlockPointer();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (keyCode != NS_VK_ESCAPE && keyCode != NS_VK_SHIFT &&
|
||||
keyCode != NS_VK_CONTROL && keyCode != NS_VK_ALT &&
|
||||
keyCode != NS_VK_WIN && keyCode != NS_VK_META) {
|
||||
// Allow keys other than ESC and modifiers be marked as a
|
||||
// valid user input for triggering popup, fullscreen, and
|
||||
// pointer lock.
|
||||
isHandlingUserInput = true;
|
||||
GetPresContext()->RecordInteractionTime(
|
||||
nsPresContext::InteractionType::eKeyInteraction,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_KEYBOARD_MS, aEvent->mTimeStamp);
|
||||
break;
|
||||
}
|
||||
case eMouseDown:
|
||||
case eMouseUp:
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::INPUT_EVENT_QUEUED_CLICK_MS,
|
||||
aEvent->mTimeStamp);
|
||||
MOZ_FALLTHROUGH;
|
||||
case ePointerDown:
|
||||
case ePointerUp:
|
||||
isHandlingUserInput = true;
|
||||
GetPresContext()->RecordInteractionTime(
|
||||
nsPresContext::InteractionType::eClickInteraction,
|
||||
aEvent->mTimeStamp);
|
||||
break;
|
||||
|
||||
case eMouseMove:
|
||||
if (aEvent->mFlags.mHandledByAPZ) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_APZ_MOUSE_MOVE_MS,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
break;
|
||||
|
||||
case eDrop: {
|
||||
nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession();
|
||||
if (session) {
|
||||
bool onlyChromeDrop = false;
|
||||
session->GetOnlyChromeDrop(&onlyChromeDrop);
|
||||
if (onlyChromeDrop) {
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case eWheel:
|
||||
if (aEvent->mFlags.mHandledByAPZ) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_APZ_WHEEL_MS, aEvent->mTimeStamp);
|
||||
}
|
||||
break;
|
||||
|
||||
case eTouchMove:
|
||||
if (aEvent->mFlags.mHandledByAPZ) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_APZ_TOUCH_MOVE_MS,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mPresShell->mTouchManager.PreHandleEvent(
|
||||
aEvent, aEventStatus, touchIsNew, isHandlingUserInput,
|
||||
mPresShell->mCurrentEventContent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (aEvent->mMessage == eContextMenu) {
|
||||
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
||||
if (mouseEvent->IsContextMenuKeyEvent() &&
|
||||
!AdjustContextMenuKeyEvent(mouseEvent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (mouseEvent->IsShift()) {
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
aEvent->mFlags.mRetargetToNonNativeAnonymous = true;
|
||||
}
|
||||
}
|
||||
|
||||
AutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput,
|
||||
aEvent, GetDocument());
|
||||
|
||||
if (aEvent->IsTrusted() && aEvent->mMessage == eMouseMove) {
|
||||
nsIPresShell::AllowMouseCapture(
|
||||
EventStateManager::GetActiveEventStateManager() == manager);
|
||||
|
||||
GetPresContext()->RecordInteractionTime(
|
||||
nsPresContext::InteractionType::eMouseMoveInteraction,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
|
||||
nsAutoPopupStatePusher popupStatePusher(
|
||||
PopupBlocker::GetEventPopupControlState(aEvent));
|
||||
|
||||
// FIXME. If the event was reused, we need to clear the old target,
|
||||
// bug 329430
|
||||
aEvent->mTarget = nullptr;
|
||||
|
||||
HandlingTimeAccumulator handlingTimeAccumulator(*this, aEvent);
|
||||
|
||||
// 1. Give event to event manager for pre event state changes and
|
||||
// generation of synthetic events.
|
||||
rv = manager->PreHandleEvent(
|
||||
GetPresContext(), aEvent, mPresShell->mCurrentEventFrame,
|
||||
mPresShell->mCurrentEventContent, aEventStatus, aOverrideClickTarget);
|
||||
|
||||
// 2. Give event to the DOM for third party and JS use.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
bool wasHandlingKeyBoardEvent = nsContentUtils::IsHandlingKeyBoardEvent();
|
||||
if (aEvent->mClass == eKeyboardEventClass) {
|
||||
nsContentUtils::SetIsHandlingKeyBoardEvent(true);
|
||||
}
|
||||
// If EventStateManager or something wants reply from remote process and
|
||||
// needs to win any other event listeners in chrome, the event is both
|
||||
// stopped its propagation and marked as "waiting reply from remote
|
||||
// process". In this case, PresShell shouldn't dispatch the event into
|
||||
// the DOM tree because they don't have a chance to stop propagation in
|
||||
// the system event group. On the other hand, if its propagation is not
|
||||
// stopped, that means that the event may be reserved by chrome. If it's
|
||||
// reserved by chrome, the event shouldn't be sent to any remote
|
||||
// processes. In this case, PresShell needs to dispatch the event to
|
||||
// the DOM tree for checking if it's reserved.
|
||||
if (aEvent->IsAllowedToDispatchDOMEvent() &&
|
||||
!(aEvent->PropagationStopped() &&
|
||||
aEvent->IsWaitingReplyFromRemoteProcess())) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
|
||||
"Somebody changed aEvent to cause a DOM event!");
|
||||
nsPresShellEventCB eventCB(mPresShell);
|
||||
if (nsIFrame* target = mPresShell->GetCurrentEventFrame()) {
|
||||
if (target->OnlySystemGroupDispatch(aEvent->mMessage)) {
|
||||
aEvent->StopPropagation();
|
||||
}
|
||||
}
|
||||
if (aEvent->mClass == eTouchEventClass) {
|
||||
DispatchTouchEventToDOM(aEvent, aEventStatus, &eventCB, touchIsNew);
|
||||
} else {
|
||||
DispatchEventToDOM(aEvent, aEventStatus, &eventCB);
|
||||
}
|
||||
}
|
||||
|
||||
nsContentUtils::SetIsHandlingKeyBoardEvent(wasHandlingKeyBoardEvent);
|
||||
|
||||
if (aEvent->mMessage == ePointerUp ||
|
||||
aEvent->mMessage == ePointerCancel) {
|
||||
// Implicitly releasing capture for given pointer.
|
||||
// ePointerLostCapture should be send after ePointerUp or
|
||||
// ePointerCancel.
|
||||
WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent();
|
||||
MOZ_ASSERT(pointerEvent);
|
||||
PointerEventHandler::ReleasePointerCaptureById(pointerEvent->pointerId);
|
||||
PointerEventHandler::CheckPointerCaptureState(pointerEvent);
|
||||
}
|
||||
|
||||
// 3. Give event to event manager for post event state changes and
|
||||
// generation of synthetic events.
|
||||
if (!mPresShell->IsDestroying() && NS_SUCCEEDED(rv)) {
|
||||
rv = manager->PostHandleEvent(GetPresContext(), aEvent,
|
||||
mPresShell->GetCurrentEventFrame(),
|
||||
aEventStatus, aOverrideClickTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mPresShell->IsDestroying() && aIsHandlingNativeEvent) {
|
||||
// Ensure that notifications to IME should be sent before getting next
|
||||
// native event from the event queue.
|
||||
// XXX Should we check the event message or event class instead of
|
||||
// using aIsHandlingNativeEvent?
|
||||
manager->TryToFlushPendingNotificationsToIME();
|
||||
// XXX How about IME events and input events for plugins?
|
||||
if (aEvent->IsTrusted()) {
|
||||
if (aEvent->IsUserAction()) {
|
||||
mPresShell->mHasHandledUserInput = true;
|
||||
}
|
||||
|
||||
switch (aEvent->mMessage) {
|
||||
case eKeyPress:
|
||||
case eKeyDown:
|
||||
case eKeyUp: {
|
||||
if (aEvent->AsKeyboardEvent()->mKeyCode == NS_VK_ESCAPE) {
|
||||
if (aEvent->mMessage == eKeyUp) {
|
||||
// Reset this flag after key up is handled.
|
||||
mPresShell->mIsLastChromeOnlyEscapeKeyConsumed = false;
|
||||
} else {
|
||||
if (aEvent->mFlags.mOnlyChromeDispatch &&
|
||||
aEvent->mFlags.mDefaultPreventedByChrome) {
|
||||
mPresShell->mIsLastChromeOnlyEscapeKeyConsumed = true;
|
||||
Document* doc = mPresShell->GetCurrentEventContent()
|
||||
? mPresShell->mCurrentEventContent->OwnerDoc()
|
||||
: nullptr;
|
||||
auto keyCode = aEvent->AsKeyboardEvent()->mKeyCode;
|
||||
if (keyCode == NS_VK_ESCAPE) {
|
||||
Document* root = nsContentUtils::GetRootDocument(doc);
|
||||
if (root && root->GetFullscreenElement()) {
|
||||
// Prevent default action on ESC key press when exiting
|
||||
// DOM fullscreen mode. This prevents the browser ESC key
|
||||
// handler from stopping all loads in the document, which
|
||||
// would cause <video> loads to stop.
|
||||
// XXX We need to claim the Escape key event which will be
|
||||
// dispatched only into chrome is already consumed by
|
||||
// content because we need to prevent its default here
|
||||
// for some reasons (not sure) but we need to detect
|
||||
// if a chrome event handler will call PreventDefault()
|
||||
// again and check it later.
|
||||
aEvent->PreventDefaultBeforeDispatch(CrossProcessForwarding::eStop);
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
|
||||
// The event listeners in chrome can prevent this ESC behavior by
|
||||
// calling prevent default on the preceding keydown/press events.
|
||||
if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed &&
|
||||
aEvent->mMessage == eKeyUp) {
|
||||
// ESC key released while in DOM fullscreen mode.
|
||||
// Fully exit all browser windows and documents from
|
||||
// fullscreen mode.
|
||||
Document::AsyncExitFullscreen(nullptr);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<Document> pointerLockedDoc =
|
||||
do_QueryReferent(EventStateManager::sPointerLockedDoc);
|
||||
if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed &&
|
||||
pointerLockedDoc) {
|
||||
// XXX See above comment to understand the reason why this needs
|
||||
// to claim that the Escape key event is consumed by content
|
||||
// even though it will be dispatched only into chrome.
|
||||
aEvent->PreventDefaultBeforeDispatch(CrossProcessForwarding::eStop);
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
if (aEvent->mMessage == eKeyUp) {
|
||||
Document::UnlockPointer();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aEvent->mMessage == eKeyDown) {
|
||||
mPresShell->mIsLastKeyDownCanceled = aEvent->mFlags.mDefaultPrevented;
|
||||
if (keyCode != NS_VK_ESCAPE && keyCode != NS_VK_SHIFT &&
|
||||
keyCode != NS_VK_CONTROL && keyCode != NS_VK_ALT &&
|
||||
keyCode != NS_VK_WIN && keyCode != NS_VK_META) {
|
||||
// Allow keys other than ESC and modifiers be marked as a
|
||||
// valid user input for triggering popup, fullscreen, and
|
||||
// pointer lock.
|
||||
isHandlingUserInput = true;
|
||||
GetPresContext()->RecordInteractionTime(
|
||||
nsPresContext::InteractionType::eKeyInteraction,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_KEYBOARD_MS, aEvent->mTimeStamp);
|
||||
break;
|
||||
}
|
||||
case eMouseDown:
|
||||
case eMouseUp:
|
||||
// reset the capturing content now that the mouse button is up
|
||||
nsIPresShell::SetCapturingContent(nullptr, 0);
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::INPUT_EVENT_QUEUED_CLICK_MS,
|
||||
aEvent->mTimeStamp);
|
||||
MOZ_FALLTHROUGH;
|
||||
case ePointerDown:
|
||||
case ePointerUp:
|
||||
isHandlingUserInput = true;
|
||||
GetPresContext()->RecordInteractionTime(
|
||||
nsPresContext::InteractionType::eClickInteraction,
|
||||
aEvent->mTimeStamp);
|
||||
break;
|
||||
|
||||
case eMouseMove:
|
||||
nsIPresShell::AllowMouseCapture(false);
|
||||
if (aEvent->mFlags.mHandledByAPZ) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_APZ_MOUSE_MOVE_MS,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
break;
|
||||
case eDrag:
|
||||
case eDragEnd:
|
||||
case eDragEnter:
|
||||
case eDragExit:
|
||||
case eDragLeave:
|
||||
case eDragOver:
|
||||
|
||||
case eDrop: {
|
||||
// After any drag event other than dragstart (which is handled
|
||||
// separately, as we need to collect the data first), the DataTransfer
|
||||
// needs to be made protected, and then disconnected.
|
||||
DataTransfer* dataTransfer = aEvent->AsDragEvent()->mDataTransfer;
|
||||
if (dataTransfer) {
|
||||
dataTransfer->Disconnect();
|
||||
nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession();
|
||||
if (session) {
|
||||
bool onlyChromeDrop = false;
|
||||
session->GetOnlyChromeDrop(&onlyChromeDrop);
|
||||
if (onlyChromeDrop) {
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case eWheel:
|
||||
if (aEvent->mFlags.mHandledByAPZ) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_APZ_WHEEL_MS, aEvent->mTimeStamp);
|
||||
}
|
||||
break;
|
||||
|
||||
case eTouchMove:
|
||||
if (aEvent->mFlags.mHandledByAPZ) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::INPUT_EVENT_QUEUED_APZ_TOUCH_MOVE_MS,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mPresShell->mTouchManager.PreHandleEvent(
|
||||
aEvent, aEventStatus, touchIsNew, isHandlingUserInput,
|
||||
mPresShell->mCurrentEventContent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (aEvent->mMessage == eContextMenu) {
|
||||
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
||||
if (mouseEvent->IsContextMenuKeyEvent() &&
|
||||
!AdjustContextMenuKeyEvent(mouseEvent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (mouseEvent->IsShift()) {
|
||||
aEvent->mFlags.mOnlyChromeDispatch = true;
|
||||
aEvent->mFlags.mRetargetToNonNativeAnonymous = true;
|
||||
}
|
||||
}
|
||||
|
||||
AutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput,
|
||||
aEvent, GetDocument());
|
||||
|
||||
if (aEvent->IsTrusted() && aEvent->mMessage == eMouseMove) {
|
||||
nsIPresShell::AllowMouseCapture(
|
||||
EventStateManager::GetActiveEventStateManager() == manager);
|
||||
|
||||
GetPresContext()->RecordInteractionTime(
|
||||
nsPresContext::InteractionType::eMouseMoveInteraction,
|
||||
aEvent->mTimeStamp);
|
||||
}
|
||||
|
||||
nsAutoPopupStatePusher popupStatePusher(
|
||||
PopupBlocker::GetEventPopupControlState(aEvent));
|
||||
|
||||
// FIXME. If the event was reused, we need to clear the old target,
|
||||
// bug 329430
|
||||
aEvent->mTarget = nullptr;
|
||||
|
||||
HandlingTimeAccumulator handlingTimeAccumulator(*this, aEvent);
|
||||
|
||||
// 1. Give event to event manager for pre event state changes and
|
||||
// generation of synthetic events.
|
||||
nsresult rv = manager->PreHandleEvent(
|
||||
GetPresContext(), aEvent, mPresShell->mCurrentEventFrame,
|
||||
mPresShell->mCurrentEventContent, aEventStatus, aOverrideClickTarget);
|
||||
|
||||
// 2. Give event to the DOM for third party and JS use.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
bool wasHandlingKeyBoardEvent = nsContentUtils::IsHandlingKeyBoardEvent();
|
||||
if (aEvent->mClass == eKeyboardEventClass) {
|
||||
nsContentUtils::SetIsHandlingKeyBoardEvent(true);
|
||||
}
|
||||
// If EventStateManager or something wants reply from remote process and
|
||||
// needs to win any other event listeners in chrome, the event is both
|
||||
// stopped its propagation and marked as "waiting reply from remote
|
||||
// process". In this case, PresShell shouldn't dispatch the event into
|
||||
// the DOM tree because they don't have a chance to stop propagation in
|
||||
// the system event group. On the other hand, if its propagation is not
|
||||
// stopped, that means that the event may be reserved by chrome. If it's
|
||||
// reserved by chrome, the event shouldn't be sent to any remote
|
||||
// processes. In this case, PresShell needs to dispatch the event to
|
||||
// the DOM tree for checking if it's reserved.
|
||||
if (aEvent->IsAllowedToDispatchDOMEvent() &&
|
||||
!(aEvent->PropagationStopped() &&
|
||||
aEvent->IsWaitingReplyFromRemoteProcess())) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
|
||||
"Somebody changed aEvent to cause a DOM event!");
|
||||
nsPresShellEventCB eventCB(mPresShell);
|
||||
if (nsIFrame* target = mPresShell->GetCurrentEventFrame()) {
|
||||
if (target->OnlySystemGroupDispatch(aEvent->mMessage)) {
|
||||
aEvent->StopPropagation();
|
||||
}
|
||||
}
|
||||
if (aEvent->mClass == eTouchEventClass) {
|
||||
DispatchTouchEventToDOM(aEvent, aEventStatus, &eventCB, touchIsNew);
|
||||
} else {
|
||||
DispatchEventToDOM(aEvent, aEventStatus, &eventCB);
|
||||
}
|
||||
}
|
||||
|
||||
nsContentUtils::SetIsHandlingKeyBoardEvent(wasHandlingKeyBoardEvent);
|
||||
|
||||
if (aEvent->mMessage == ePointerUp || aEvent->mMessage == ePointerCancel) {
|
||||
// Implicitly releasing capture for given pointer.
|
||||
// ePointerLostCapture should be send after ePointerUp or
|
||||
// ePointerCancel.
|
||||
WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent();
|
||||
MOZ_ASSERT(pointerEvent);
|
||||
PointerEventHandler::ReleasePointerCaptureById(pointerEvent->pointerId);
|
||||
PointerEventHandler::CheckPointerCaptureState(pointerEvent);
|
||||
}
|
||||
|
||||
// 3. Give event to event manager for post event state changes and
|
||||
// generation of synthetic events.
|
||||
if (!mPresShell->IsDestroying() && NS_SUCCEEDED(rv)) {
|
||||
rv = manager->PostHandleEvent(GetPresContext(), aEvent,
|
||||
mPresShell->GetCurrentEventFrame(),
|
||||
aEventStatus, aOverrideClickTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mPresShell->IsDestroying() && aIsHandlingNativeEvent) {
|
||||
// Ensure that notifications to IME should be sent before getting next
|
||||
// native event from the event queue.
|
||||
// XXX Should we check the event message or event class instead of
|
||||
// using aIsHandlingNativeEvent?
|
||||
manager->TryToFlushPendingNotificationsToIME();
|
||||
}
|
||||
|
||||
switch (aEvent->mMessage) {
|
||||
case eKeyPress:
|
||||
case eKeyDown:
|
||||
case eKeyUp: {
|
||||
if (aEvent->AsKeyboardEvent()->mKeyCode == NS_VK_ESCAPE) {
|
||||
if (aEvent->mMessage == eKeyUp) {
|
||||
// Reset this flag after key up is handled.
|
||||
mPresShell->mIsLastChromeOnlyEscapeKeyConsumed = false;
|
||||
} else {
|
||||
if (aEvent->mFlags.mOnlyChromeDispatch &&
|
||||
aEvent->mFlags.mDefaultPreventedByChrome) {
|
||||
mPresShell->mIsLastChromeOnlyEscapeKeyConsumed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aEvent->mMessage == eKeyDown) {
|
||||
mPresShell->mIsLastKeyDownCanceled = aEvent->mFlags.mDefaultPrevented;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eMouseUp:
|
||||
// reset the capturing content now that the mouse button is up
|
||||
nsIPresShell::SetCapturingContent(nullptr, 0);
|
||||
break;
|
||||
case eMouseMove:
|
||||
nsIPresShell::AllowMouseCapture(false);
|
||||
break;
|
||||
case eDrag:
|
||||
case eDragEnd:
|
||||
case eDragEnter:
|
||||
case eDragExit:
|
||||
case eDragLeave:
|
||||
case eDragOver:
|
||||
case eDrop: {
|
||||
// After any drag event other than dragstart (which is handled
|
||||
// separately, as we need to collect the data first), the DataTransfer
|
||||
// needs to be made protected, and then disconnected.
|
||||
DataTransfer* dataTransfer = aEvent->AsDragEvent()->mDataTransfer;
|
||||
if (dataTransfer) {
|
||||
dataTransfer->Disconnect();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
RecordEventHandlingResponsePerformance(aEvent);
|
||||
return rv;
|
||||
|
@ -1,17 +1,17 @@
|
||||
== blend-canvas.html blend-canvas-ref.html
|
||||
== blend-constant-background-color.html blend-constant-background-color-ref.html
|
||||
fuzzy-if(webrender,1-3,1291-7888) == blend-gradient-background-color.html blend-gradient-background-color-ref.html
|
||||
== blend-gradient-background-color.html blend-gradient-background-color-ref.html
|
||||
== blend-image.html blend-image-ref.html
|
||||
== blend-difference-stacking.html blend-difference-stacking-ref.html
|
||||
|
||||
fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-10000) fuzzy-if(skiaContent,0-1,0-30000) == background-blending-alpha.html background-blending-alpha-ref.html
|
||||
fuzzy-if(webrender,1-3,1291-7888) == background-blending-gradient-color.html background-blending-gradient-color-ref.html
|
||||
fuzzy-if(azureSkiaGL,0-3,0-7597) fuzzy-if(cocoaWidget,0-3,0-7597) fuzzy-if(d2d,0-1,0-3800) fuzzy-if(d3d11,0-1,0-4200) fuzzy-if(skiaContent,0-2,0-9450) fuzzy-if(webrender,1-5,3938-23925) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html
|
||||
fuzzy-if(azureSkiaGL,0-2,0-7174) fuzzy-if(webrender,1-3,1288-7888) == background-blending-gradient-image.html background-blending-gradient-color-ref.html
|
||||
== background-blending-gradient-color.html background-blending-gradient-color-ref.html
|
||||
fuzzy-if(azureSkiaGL,0-3,0-7597) fuzzy-if(cocoaWidget,0-3,0-7597) fuzzy-if(d2d,0-1,0-3800) fuzzy-if(d3d11,0-1,0-4200) fuzzy-if(skiaContent,0-2,0-9450) fuzzy-if(webrender,1-1,2400-6200) == background-blending-gradient-gradient.html background-blending-gradient-gradient-ref.html
|
||||
fuzzy-if(azureSkiaGL,0-2,0-7174) == background-blending-gradient-image.html background-blending-gradient-color-ref.html
|
||||
fuzzy-if(azureSkia||d2d||gtkWidget,0-1,0-10000) == background-blending-image-color-jpg.html background-blending-image-color-ref.html
|
||||
== background-blending-image-color-png.html background-blending-image-color-ref.html
|
||||
== background-blending-image-color-svg.html background-blending-image-color-ref.html
|
||||
fuzzy-if(azureSkiaGL,0-2,0-7174) fuzzy-if(webrender,1-3,1288-7888) == background-blending-image-gradient.html background-blending-gradient-color-ref.html
|
||||
fuzzy-if(azureSkiaGL,0-2,0-7174) == background-blending-image-gradient.html background-blending-gradient-color-ref.html
|
||||
== background-blending-image-image.html background-blending-image-color-ref.html
|
||||
== background-blending-isolation.html background-blending-isolation-ref.html
|
||||
== background-blending-list-repeat.html background-blending-list-repeat-ref.html
|
||||
|
@ -73,7 +73,7 @@ fuzzy-if(skiaContent,0-73,0-900) == twostops-1e.html twostops-1-ref.html
|
||||
|
||||
# from http://www.xanthir.com/:4bhipd by way of http://a-ja.net/newgrad.html
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-3,0-20000) fuzzy-if(azureSkiaGL||skiaContent&&layersGPUAccelerated,0-8,0-20000) == aja-linear-1a.html aja-linear-1-ref.html
|
||||
fails-if(!d2d&&!skiaContent) fuzzy-if(skiaContent,0-1,0-20000) fuzzy-if(webrender&&winWidget,1-2,11550-11789) == aja-linear-1b.html aja-linear-1-ref.html # bug 526694
|
||||
fails-if(!d2d&&!skiaContent) fuzzy-if(skiaContent,0-1,0-20000) fuzzy-if(webrender&&winWidget,1-1,5300-5500) == aja-linear-1b.html aja-linear-1-ref.html # bug 526694
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-3,0-20000) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) == aja-linear-1c.html aja-linear-1-ref.html
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-3,0-20000) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) == aja-linear-1d.html aja-linear-1-ref.html
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-3,0-20000) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) == aja-linear-1e.html aja-linear-1-ref.html
|
||||
@ -83,7 +83,7 @@ fuzzy-if(!contentSameGfxBackendAsCanvas,0-2,0-19999) fuzzy-if(azureSkiaGL||skiaC
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-2,0-19999) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) == aja-linear-3b.html aja-linear-3-ref.html
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-4,0-20000) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) == aja-linear-4a.html aja-linear-4-ref.html
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-4,0-20000) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) == aja-linear-4b.html aja-linear-4-ref.html
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-4,0-20000) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) fuzzy-if(webrender&&winWidget,4-9,15926-16125) == aja-linear-5a.html aja-linear-5-ref.html
|
||||
fuzzy-if(!contentSameGfxBackendAsCanvas,0-4,0-20000) fuzzy-if(azureSkiaGL||skiaContent,0-8,0-20000) fuzzy-if(webrender&&winWidget,1-1,5900-6100) == aja-linear-5a.html aja-linear-5-ref.html
|
||||
fuzzy-if(Android,0-6,0-10576) == height-dependence-1.html height-dependence-1-ref.html
|
||||
fuzzy-if(cocoaWidget,0-1,0-40000) fuzzy-if(Android,0-6,0-10576) == height-dependence-2.html height-dependence-2-ref.html
|
||||
fuzzy-if(Android,0-6,0-10576) == height-dependence-3.html height-dependence-3-ref.html
|
||||
|
@ -12,8 +12,8 @@ skip-if(!cocoaWidget) fails-if(webrender&&cocoaWidget) == mac-tab-toolbar.xul ma
|
||||
pref(layout.css.xul-tree-pseudos.content.enabled,true) != tree-row-outline-1.xul tree-row-outline-1-notref.xul
|
||||
== text-crop.xul text-crop-ref.xul
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-small-caps-1.xul text-small-caps-1-ref.xul
|
||||
fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,0-1,0-31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,0-1,0-50) == inactive-fixed-bg-bug1205630.xul inactive-fixed-bg-bug1205630-ref.html
|
||||
fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,0-1,0-31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,0-1,0-50) == inactive-fixed-bg-bug1272525.xul inactive-fixed-bg-bug1272525-ref.html
|
||||
fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,0-1,0-31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,0-1,0-50) fuzzy-if(webrender,0-1,350-1050) == inactive-fixed-bg-bug1205630.xul inactive-fixed-bg-bug1205630-ref.html
|
||||
fuzzy-if(skiaContent,0-1,0-60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,0-1,0-31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,0-1,0-50) fuzzy-if(webrender,0-1,450-1100) == inactive-fixed-bg-bug1272525.xul inactive-fixed-bg-bug1272525-ref.html
|
||||
|
||||
# Tests for XUL <image> with 'object-fit' & 'object-position':
|
||||
# These tests should be very similar to tests in our w3c-css/submitted/images3
|
||||
|
@ -81,10 +81,14 @@ function initial_font_family_is_sans_serif()
|
||||
{
|
||||
// The initial value of 'font-family' might be 'serif' or
|
||||
// 'sans-serif'.
|
||||
var div = document.createElement("div");
|
||||
div.setAttribute("style", "font: initial");
|
||||
return getComputedStyle(div, "").fontFamily == "sans-serif";
|
||||
const meta = document.createElement("meta");
|
||||
meta.setAttribute("style", "font: initial;");
|
||||
document.documentElement.appendChild(meta);
|
||||
const family = getComputedStyle(meta).fontFamily;
|
||||
meta.remove();
|
||||
return family == "sans-serif";
|
||||
}
|
||||
|
||||
var gInitialFontFamilyIsSansSerif = initial_font_family_is_sans_serif();
|
||||
|
||||
// shared by background-image and border-image-source
|
||||
|
@ -57,9 +57,6 @@ function testInheritedProperty(property, info) {
|
||||
// is different (normal vs. 19px).
|
||||
if (property == "line-height")
|
||||
return;
|
||||
// Ongoing debugging in bug 1533392.
|
||||
if (property == "font-family")
|
||||
return;
|
||||
|
||||
const div = kInheritedDiv;
|
||||
const initial = getInitialValue(div, property);
|
||||
|
@ -271,9 +271,6 @@ public class GeckoThread extends Thread {
|
||||
|
||||
private static void initGeckoEnvironment() {
|
||||
final Context context = GeckoAppShell.getApplicationContext();
|
||||
GeckoLoader.loadMozGlue(context);
|
||||
setState(State.MOZGLUE_READY);
|
||||
|
||||
final Locale locale = Locale.getDefault();
|
||||
final Resources res = context.getResources();
|
||||
if (locale.toString().equalsIgnoreCase("zh_hk")) {
|
||||
@ -414,11 +411,9 @@ public class GeckoThread extends Thread {
|
||||
};
|
||||
Looper.myQueue().addIdleHandler(idleHandler);
|
||||
|
||||
initGeckoEnvironment();
|
||||
|
||||
// Wait until initialization before calling Gecko entry point.
|
||||
// Wait until initialization before preparing environment.
|
||||
synchronized (this) {
|
||||
while (!mInitialized || !isState(State.LIBS_READY)) {
|
||||
while (!mInitialized) {
|
||||
try {
|
||||
wait();
|
||||
} catch (final InterruptedException e) {
|
||||
@ -426,6 +421,30 @@ public class GeckoThread extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
final Context context = GeckoAppShell.getApplicationContext();
|
||||
final List<String> env = getEnvFromExtras(mInitInfo.extras);
|
||||
|
||||
// In Gecko, the native crash reporter is enabled by default in opt builds, and
|
||||
// disabled by default in debug builds.
|
||||
if ((mInitInfo.flags & FLAG_ENABLE_NATIVE_CRASHREPORTER) == 0 && !BuildConfig.DEBUG_BUILD) {
|
||||
env.add(0, "MOZ_CRASHREPORTER_DISABLE=1");
|
||||
} else if ((mInitInfo.flags & FLAG_ENABLE_NATIVE_CRASHREPORTER) != 0 && BuildConfig.DEBUG_BUILD) {
|
||||
env.add(0, "MOZ_CRASHREPORTER=1");
|
||||
}
|
||||
|
||||
if (!isChildProcess() && ((mInitInfo.flags & FLAG_ENABLE_MARIONETTE) != 0)) {
|
||||
// The presence of this environment variable determines the initial
|
||||
// value of `marionette.enabled`.
|
||||
env.add(0, "MOZ_MARIONETTE=1");
|
||||
}
|
||||
|
||||
GeckoLoader.loadMozGlue(context);
|
||||
setState(State.MOZGLUE_READY);
|
||||
|
||||
GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath(), env, mInitInfo.prefs);
|
||||
|
||||
initGeckoEnvironment();
|
||||
|
||||
if ((mInitInfo.flags & FLAG_PRELOAD_CHILD) != 0) {
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
@ -445,31 +464,12 @@ public class GeckoThread extends Thread {
|
||||
|
||||
Log.w(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() + " - runGecko");
|
||||
|
||||
final Context context = GeckoAppShell.getApplicationContext();
|
||||
final String[] args = isChildProcess() ? mInitInfo.args : getMainProcessArgs();
|
||||
|
||||
if ((mInitInfo.flags & FLAG_DEBUGGING) != 0) {
|
||||
Log.i(LOGTAG, "RunGecko - args = " + TextUtils.join(" ", args));
|
||||
}
|
||||
|
||||
final List<String> env = getEnvFromExtras(mInitInfo.extras);
|
||||
|
||||
// In Gecko, the native crash reporter is enabled by default in opt builds, and
|
||||
// disabled by default in debug builds.
|
||||
if ((mInitInfo.flags & FLAG_ENABLE_NATIVE_CRASHREPORTER) == 0 && !BuildConfig.DEBUG_BUILD) {
|
||||
env.add(0, "MOZ_CRASHREPORTER_DISABLE=1");
|
||||
} else if ((mInitInfo.flags & FLAG_ENABLE_NATIVE_CRASHREPORTER) != 0 && BuildConfig.DEBUG_BUILD) {
|
||||
env.add(0, "MOZ_CRASHREPORTER=1");
|
||||
}
|
||||
|
||||
if (!isChildProcess() && ((mInitInfo.flags & FLAG_ENABLE_MARIONETTE) != 0)) {
|
||||
// The presence of this environment variable determines the initial
|
||||
// value of `marionette.enabled`.
|
||||
env.add(0, "MOZ_MARIONETTE=1");
|
||||
}
|
||||
|
||||
GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath(), env, mInitInfo.prefs);
|
||||
|
||||
// And go.
|
||||
GeckoLoader.nativeRun(args,
|
||||
mInitInfo.extras.getInt(EXTRA_PREFS_FD, -1),
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "stdlib.h"
|
||||
#include "nsDirectoryService.h"
|
||||
#include "nsWildCard.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsZipArchive.h"
|
||||
@ -78,14 +79,8 @@ static uint32_t HashName(const char *aName, uint16_t nameLen);
|
||||
|
||||
class ZipArchiveLogger {
|
||||
public:
|
||||
void Write(const nsACString &zip, const char *entry) const {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return;
|
||||
}
|
||||
void Init(const char *env) {
|
||||
if (!fd) {
|
||||
char *env = PR_GetEnv("MOZ_JAR_LOG_FILE");
|
||||
if (!env) return;
|
||||
|
||||
nsCOMPtr<nsIFile> logFile;
|
||||
nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(env), false,
|
||||
getter_AddRefs(logFile));
|
||||
@ -116,11 +111,16 @@ class ZipArchiveLogger {
|
||||
#endif
|
||||
fd = file;
|
||||
}
|
||||
nsCString buf(zip);
|
||||
buf.Append(' ');
|
||||
buf.Append(entry);
|
||||
buf.Append('\n');
|
||||
PR_Write(fd, buf.get(), buf.Length());
|
||||
}
|
||||
|
||||
void Write(const nsACString &zip, const char *entry) const {
|
||||
if (fd) {
|
||||
nsCString buf(zip);
|
||||
buf.Append(' ');
|
||||
buf.Append(entry);
|
||||
buf.Append('\n');
|
||||
PR_Write(fd, buf.get(), buf.Length());
|
||||
}
|
||||
}
|
||||
|
||||
void AddRef() {
|
||||
@ -138,7 +138,7 @@ class ZipArchiveLogger {
|
||||
|
||||
private:
|
||||
int refCnt;
|
||||
mutable PRFileDesc *fd;
|
||||
PRFileDesc *fd;
|
||||
};
|
||||
|
||||
static ZipArchiveLogger zipLog;
|
||||
@ -336,7 +336,52 @@ nsresult nsZipArchive::OpenArchive(nsZipHandle *aZipHandle, PRFileDesc *aFd) {
|
||||
//-- get table of contents for archive
|
||||
nsresult rv = BuildFileList(aFd);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (aZipHandle->mFile) aZipHandle->mFile.GetURIString(mURI);
|
||||
if (aZipHandle->mFile && XRE_IsParentProcess()) {
|
||||
static char *env = PR_GetEnv("MOZ_JAR_LOG_FILE");
|
||||
if (env) {
|
||||
zipLog.Init(env);
|
||||
// We only log accesses in jar/zip archives within the NS_GRE_DIR
|
||||
// and/or the APK on Android. For the former, we log the archive path
|
||||
// relative to NS_GRE_DIR, and for the latter, the nested-archive
|
||||
// path within the APK. This makes the path match the path of the
|
||||
// archives relative to the packaged dist/$APP_NAME directory in a
|
||||
// build.
|
||||
if (aZipHandle->mFile.IsZip()) {
|
||||
// Nested archive, likely omni.ja in APK.
|
||||
aZipHandle->mFile.GetPath(mURI);
|
||||
} else if (nsDirectoryService::gService) {
|
||||
// We can reach here through the initialization of Omnijar from
|
||||
// XRE_InitCommandLine, which happens before the directory service
|
||||
// is initialized. When that happens, it means the opened archive is
|
||||
// the APK, and we don't care to log that one, so we just skip
|
||||
// when the directory service is not initialized.
|
||||
nsCOMPtr<nsIFile> dir = aZipHandle->mFile.GetBaseFile();
|
||||
nsCOMPtr<nsIFile> gre_dir;
|
||||
nsAutoCString path;
|
||||
if (NS_SUCCEEDED(nsDirectoryService::gService->Get(
|
||||
NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(gre_dir)))) {
|
||||
nsAutoCString leaf;
|
||||
nsCOMPtr<nsIFile> parent;
|
||||
while (NS_SUCCEEDED(dir->GetNativeLeafName(leaf)) &&
|
||||
NS_SUCCEEDED(dir->GetParent(getter_AddRefs(parent)))) {
|
||||
if (!parent) {
|
||||
break;
|
||||
}
|
||||
dir = parent;
|
||||
if (path.Length()) {
|
||||
path.Insert('/', 0);
|
||||
}
|
||||
path.Insert(leaf, 0);
|
||||
bool equals;
|
||||
if (NS_SUCCEEDED(dir->Equals(gre_dir, &equals)) && equals) {
|
||||
mURI.Assign(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -427,7 +472,9 @@ nsZipItem *nsZipArchive::GetItem(const char *aEntryName) {
|
||||
(!memcmp(aEntryName, item->Name(), len))) {
|
||||
// Successful GetItem() is a good indicator that the file is about to be
|
||||
// read
|
||||
zipLog.Write(mURI, aEntryName);
|
||||
if (mURI.Length()) {
|
||||
zipLog.Write(mURI, aEntryName);
|
||||
}
|
||||
return item; //-- found it
|
||||
}
|
||||
item = item->next;
|
||||
|
@ -1624,23 +1624,29 @@ nsresult NS_NewURI(
|
||||
}
|
||||
|
||||
nsresult NS_NewURI(
|
||||
nsIURI **result, const nsAString &spec, const char *charset /* = nullptr */,
|
||||
nsIURI *baseURI /* = nullptr */,
|
||||
nsIURI **result, const nsAString &aSpec,
|
||||
const char *charset /* = nullptr */, nsIURI *baseURI /* = nullptr */,
|
||||
nsIIOService
|
||||
*ioService /* = nullptr */) // pass in nsIIOService to optimize callers
|
||||
{
|
||||
return NS_NewURI(result, NS_ConvertUTF16toUTF8(spec), charset, baseURI,
|
||||
ioService);
|
||||
nsAutoCString spec;
|
||||
if (!AppendUTF16toUTF8(aSpec, spec, mozilla::fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_NewURI(result, spec, charset, baseURI, ioService);
|
||||
}
|
||||
|
||||
nsresult NS_NewURI(
|
||||
nsIURI **result, const nsAString &spec, NotNull<const Encoding *> encoding,
|
||||
nsIURI **result, const nsAString &aSpec, NotNull<const Encoding *> encoding,
|
||||
nsIURI *baseURI /* = nullptr */,
|
||||
nsIIOService
|
||||
*ioService /* = nullptr */) // pass in nsIIOService to optimize callers
|
||||
{
|
||||
return NS_NewURI(result, NS_ConvertUTF16toUTF8(spec), encoding, baseURI,
|
||||
ioService);
|
||||
nsAutoCString spec;
|
||||
if (!AppendUTF16toUTF8(aSpec, spec, mozilla::fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_NewURI(result, spec, encoding, baseURI, ioService);
|
||||
}
|
||||
|
||||
nsresult NS_NewURI(
|
||||
|
@ -168,7 +168,7 @@ void Http2Session::Shutdown() {
|
||||
CloseStream(stream, NS_ERROR_NET_PARTIAL_TRANSFER);
|
||||
} else if (mGoAwayReason == INADEQUATE_SECURITY) {
|
||||
CloseStream(stream, NS_ERROR_NET_INADEQUATE_SECURITY);
|
||||
} else if (!mCleanShutdown) {
|
||||
} else if (!mCleanShutdown && (mGoAwayReason != NO_HTTP_ERROR)) {
|
||||
CloseStream(stream, NS_ERROR_NET_HTTP2_SENT_GOAWAY);
|
||||
} else {
|
||||
CloseStream(stream, NS_ERROR_ABORT);
|
||||
@ -3871,7 +3871,7 @@ void Http2Session::Close(nsresult aReason) {
|
||||
goAwayReason = mGoAwayReason;
|
||||
} else if (NS_SUCCEEDED(aReason)) {
|
||||
goAwayReason = NO_HTTP_ERROR;
|
||||
} else if (aReason == NS_ERROR_ILLEGAL_VALUE) {
|
||||
} else if (aReason == NS_ERROR_NET_HTTP2_SENT_GOAWAY) {
|
||||
goAwayReason = PROTOCOL_ERROR;
|
||||
} else if (mCleanShutdown) {
|
||||
goAwayReason = NO_HTTP_ERROR;
|
||||
|
@ -180,6 +180,7 @@ HttpChannelChild::HttpChannelChild()
|
||||
mAltDataCacheEntryAvailable(false),
|
||||
mSendResumeAt(false),
|
||||
mKeptAlive(false),
|
||||
mIPCActorDeleted(false),
|
||||
mSuspendSent(false),
|
||||
mSynthesizedResponse(false),
|
||||
mShouldInterceptSubsequentRedirect(false),
|
||||
@ -533,7 +534,11 @@ void HttpChannelChild::OnStartRequest(
|
||||
!mDivertingToParent,
|
||||
"mDivertingToParent should be unset before OnStartRequest!");
|
||||
|
||||
if (mOnStartRequestCalled && !mIPCOpen) {
|
||||
// If this channel was aborted by ActorDestroy, then there may be other
|
||||
// OnStartRequest/OnStopRequest/OnDataAvailable IPC messages that need to
|
||||
// be handled. In that case we just ignore them to avoid calling the listener
|
||||
// twice.
|
||||
if (mOnStartRequestCalled && mIPCActorDeleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -663,11 +668,11 @@ void HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest,
|
||||
}
|
||||
|
||||
nsresult rv = mListener->OnStartRequest(aRequest);
|
||||
mOnStartRequestCalled = true;
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
return;
|
||||
}
|
||||
mOnStartRequestCalled = true;
|
||||
|
||||
if (mDivertingToParent) {
|
||||
mListener = nullptr;
|
||||
@ -1033,7 +1038,11 @@ void HttpChannelChild::OnStopRequest(
|
||||
static_cast<uint32_t>(channelStatus)));
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mOnStopRequestCalled && !mIPCOpen) {
|
||||
// If this channel was aborted by ActorDestroy, then there may be other
|
||||
// OnStartRequest/OnStopRequest/OnDataAvailable IPC messages that need to
|
||||
// be handled. In that case we just ignore them to avoid calling the listener
|
||||
// twice.
|
||||
if (mOnStopRequestCalled && mIPCActorDeleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3830,6 +3839,9 @@ void HttpChannelChild::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
// Cleanup the background channel before we resume the eventQ so we don't
|
||||
// get any other events.
|
||||
CleanupBackgroundChannel();
|
||||
|
||||
mIPCActorDeleted = true;
|
||||
mCanceled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -413,6 +413,10 @@ class HttpChannelChild final : public PHttpChannelChild,
|
||||
|
||||
uint8_t mKeptAlive : 1; // IPC kept open, but only for security info
|
||||
|
||||
// Set when ActorDestroy(ActorDestroyReason::Deletion) is called
|
||||
// The channel must ignore any following OnStart/Stop/DataAvailable messages
|
||||
uint8_t mIPCActorDeleted : 1;
|
||||
|
||||
// Set if SendSuspend is called. Determines if SendResume is needed when
|
||||
// diverting callbacks to parent.
|
||||
uint8_t mSuspendSent : 1;
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/LazyIdleThread.h"
|
||||
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/Navigator.h"
|
||||
@ -277,7 +278,6 @@ nsHttpHandler::nsHttpHandler()
|
||||
mConnectTimeout(90000),
|
||||
mTLSHandshakeTimeout(30000),
|
||||
mParallelSpeculativeConnectLimit(6),
|
||||
mSpeculativeConnectEnabled(true),
|
||||
mRequestTokenBucketEnabled(true),
|
||||
mRequestTokenBucketMinParallelism(6),
|
||||
mRequestTokenBucketHz(100),
|
||||
@ -292,6 +292,7 @@ nsHttpHandler::nsHttpHandler()
|
||||
mDefaultHpackBuffer(4096),
|
||||
mMaxHttpResponseHeaderSize(393216),
|
||||
mFocusedWindowTransactionRatio(0.9f),
|
||||
mSpeculativeConnectEnabled(false),
|
||||
mUseFastOpen(true),
|
||||
mFastOpenConsecutiveFailureLimit(5),
|
||||
mFastOpenConsecutiveFailureCounter(0),
|
||||
@ -466,6 +467,9 @@ nsresult nsHttpHandler::Init() {
|
||||
mIOService = new nsMainThreadPtrHolder<nsIIOService>(
|
||||
"nsHttpHandler::mIOService", service);
|
||||
|
||||
mBackgroundThread = new mozilla::LazyIdleThread(
|
||||
10000, NS_LITERAL_CSTRING("HTTP Handler Background"));
|
||||
|
||||
if (IsNeckoChild()) NeckoChild::InitNeckoChild();
|
||||
|
||||
InitUserAgentComponents();
|
||||
@ -559,6 +563,7 @@ nsresult nsHttpHandler::Init() {
|
||||
obsService->AddObserver(this, "psm:user-certificate-added", true);
|
||||
obsService->AddObserver(this, "psm:user-certificate-deleted", true);
|
||||
obsService->AddObserver(this, "intl:app-locales-changed", true);
|
||||
obsService->AddObserver(this, "browser-delayed-startup-finished", true);
|
||||
|
||||
if (!IsNeckoChild()) {
|
||||
obsService->AddObserver(
|
||||
@ -2175,8 +2180,6 @@ nsHttpHandler::GetMisc(nsACString &value) {
|
||||
// nsHttpHandler::nsIObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static bool CanEnableSpeculativeConnect(); // forward declaration
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpHandler::Observe(nsISupports *subject, const char *topic,
|
||||
const char16_t *data) {
|
||||
@ -2326,10 +2329,12 @@ nsHttpHandler::Observe(nsISupports *subject, const char *topic,
|
||||
} else if (!strcmp(topic, "psm:user-certificate-deleted")) {
|
||||
// If a user certificate has been removed, we need to check if there
|
||||
// are others installed
|
||||
mSpeculativeConnectEnabled = CanEnableSpeculativeConnect();
|
||||
MaybeEnableSpeculativeConnect();
|
||||
} else if (!strcmp(topic, "intl:app-locales-changed")) {
|
||||
// If the locale changed, there's a chance the accept language did too
|
||||
mAcceptLanguagesIsDirty = true;
|
||||
} else if (!strcmp(topic, "browser-delayed-startup-finished")) {
|
||||
MaybeEnableSpeculativeConnect();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -2338,13 +2343,9 @@ nsHttpHandler::Observe(nsISupports *subject, const char *topic,
|
||||
// nsISpeculativeConnect
|
||||
|
||||
static bool CanEnableSpeculativeConnect() {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
|
||||
nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID));
|
||||
if (!component) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!NS_IsMainThread(), "Must run on the background thread");
|
||||
// Check if any 3rd party PKCS#11 module are installed, as they may produce
|
||||
// client certificates
|
||||
bool activeSmartCards = false;
|
||||
@ -2361,9 +2362,34 @@ static bool CanEnableSpeculativeConnect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No smart cards and no client certificates means
|
||||
// we can enable speculative connect.
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsHttpHandler::MaybeEnableSpeculativeConnect() {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
|
||||
// We don't need to and can't check this in the child process.
|
||||
if (IsNeckoChild()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBackgroundThread) {
|
||||
NS_WARNING(
|
||||
"nsHttpHandler::MaybeEnableSpeculativeConnect() no background thread");
|
||||
return;
|
||||
}
|
||||
|
||||
net_EnsurePSMInit();
|
||||
|
||||
mBackgroundThread->Dispatch(
|
||||
NS_NewRunnableFunction("CanEnableSpeculativeConnect", [] {
|
||||
gHttpHandler->mSpeculativeConnectEnabled =
|
||||
CanEnableSpeculativeConnect();
|
||||
}));
|
||||
}
|
||||
|
||||
nsresult nsHttpHandler::SpeculativeConnectInternal(
|
||||
nsIURI *aURI, nsIPrincipal *aPrincipal, nsIInterfaceRequestor *aCallbacks,
|
||||
bool anonymous) {
|
||||
@ -2447,12 +2473,6 @@ nsresult nsHttpHandler::SpeculativeConnectInternal(
|
||||
rv = aURI->SchemeIs("https", &usingSSL);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
static bool sCheckedIfSpeculativeEnabled = false;
|
||||
if (!sCheckedIfSpeculativeEnabled) {
|
||||
sCheckedIfSpeculativeEnabled = true;
|
||||
mSpeculativeConnectEnabled = CanEnableSpeculativeConnect();
|
||||
}
|
||||
|
||||
if (usingSSL && !mSpeculativeConnectEnabled) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
@ -437,6 +437,10 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||
|
||||
void EnsureUAOverridesInit();
|
||||
|
||||
// Checks if there are any user certs or active smart cards on a different
|
||||
// thread. Updates mSpeculativeConnectEnabled when done.
|
||||
void MaybeEnableSpeculativeConnect();
|
||||
|
||||
private:
|
||||
// cached services
|
||||
nsMainThreadPtrHandle<nsIIOService> mIOService;
|
||||
@ -451,6 +455,10 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||
// the connection manager
|
||||
RefPtr<nsHttpConnectionMgr> mConnMgr;
|
||||
|
||||
// This thread is used for performing operations that should not block
|
||||
// the main thread.
|
||||
nsCOMPtr<nsIThread> mBackgroundThread;
|
||||
|
||||
//
|
||||
// prefs
|
||||
//
|
||||
@ -597,10 +605,6 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||
// when starting a new speculative connection.
|
||||
uint32_t mParallelSpeculativeConnectLimit;
|
||||
|
||||
// We may disable speculative connect if the browser has user certificates
|
||||
// installed as that might randomly popup the certificate choosing window.
|
||||
bool mSpeculativeConnectEnabled;
|
||||
|
||||
// For Rate Pacing of HTTP/1 requests through a netwerk/base/EventTokenBucket
|
||||
// Active requests <= *MinParallelism are not subject to the rate pacing
|
||||
bool mRequestTokenBucketEnabled;
|
||||
@ -641,6 +645,10 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||
// The ratio for dispatching transactions from the focused window.
|
||||
float mFocusedWindowTransactionRatio;
|
||||
|
||||
// We may disable speculative connect if the browser has user certificates
|
||||
// installed as that might randomly popup the certificate choosing window.
|
||||
Atomic<bool, Relaxed> mSpeculativeConnectEnabled;
|
||||
|
||||
Atomic<bool, Relaxed> mUseFastOpen;
|
||||
Atomic<bool, Relaxed> mFastOpenSupported;
|
||||
uint32_t mFastOpenConsecutiveFailureLimit;
|
||||
|
@ -14,7 +14,6 @@ from zipfile import (
|
||||
ZIP_DEFLATED,
|
||||
)
|
||||
from collections import OrderedDict
|
||||
from urlparse import urlparse, ParseResult
|
||||
import mozpack.path as mozpath
|
||||
from mozbuild.util import memoize
|
||||
|
||||
@ -833,56 +832,18 @@ class BrotliCompress(object):
|
||||
class JarLog(dict):
|
||||
'''
|
||||
Helper to read the file Gecko generates when setting MOZ_JAR_LOG_FILE.
|
||||
The jar log is then available as a dict with the jar path as key (see
|
||||
canonicalize for more details on the key value), and the corresponding
|
||||
access log as a list value. Only the first access to a given member of
|
||||
a jar is stored.
|
||||
The jar log is then available as a dict with the jar path as key, and
|
||||
the corresponding access log as a list value. Only the first access to
|
||||
a given member of a jar is stored.
|
||||
'''
|
||||
|
||||
def __init__(self, file=None, fileobj=None):
|
||||
if not fileobj:
|
||||
fileobj = open(file, 'r')
|
||||
urlmap = {}
|
||||
for line in fileobj:
|
||||
url, path = line.strip().split(None, 1)
|
||||
if not url or not path:
|
||||
jar, path = line.strip().split(None, 1)
|
||||
if not jar or not path:
|
||||
continue
|
||||
if url not in urlmap:
|
||||
urlmap[url] = JarLog.canonicalize(url)
|
||||
jar = urlmap[url]
|
||||
entry = self.setdefault(jar, [])
|
||||
if path not in entry:
|
||||
entry.append(path)
|
||||
|
||||
@staticmethod
|
||||
def canonicalize(url):
|
||||
'''
|
||||
The jar path is stored in a MOZ_JAR_LOG_FILE log as a url. This method
|
||||
returns a unique value corresponding to such urls.
|
||||
- file:///{path} becomes {path}
|
||||
- jar:file:///{path}!/{subpath} becomes ({path}, {subpath})
|
||||
- jar:jar:file:///{path}!/{subpath}!/{subpath2} becomes
|
||||
({path}, {subpath}, {subpath2})
|
||||
'''
|
||||
if not isinstance(url, ParseResult):
|
||||
# Assume that if it doesn't start with jar: or file:, it's a path.
|
||||
if not url.startswith(('jar:', 'file:')):
|
||||
url = 'file:///' + os.path.abspath(url)
|
||||
url = urlparse(url)
|
||||
assert url.scheme
|
||||
assert url.scheme in ('jar', 'file')
|
||||
if url.scheme == 'jar':
|
||||
path = JarLog.canonicalize(url.path)
|
||||
if isinstance(path, tuple):
|
||||
return path[:-1] + tuple(path[-1].split('!/', 1))
|
||||
return tuple(path.split('!/', 1))
|
||||
if url.scheme == 'file':
|
||||
assert os.path.isabs(url.path)
|
||||
path = url.path
|
||||
# On Windows, url.path will be /drive:/path ; on Unix systems,
|
||||
# /path. As we want drive:/path instead of /drive:/path on Windows,
|
||||
# remove the leading /.
|
||||
if os.path.isabs(path[1:]):
|
||||
path = path[1:]
|
||||
path = os.path.realpath(path)
|
||||
return mozpath.normsep(os.path.normcase(path))
|
||||
|
@ -17,7 +17,6 @@ from mozpack.test.test_files import MockDest
|
||||
import unittest
|
||||
import mozunit
|
||||
from cStringIO import StringIO
|
||||
from urllib import pathname2url
|
||||
import mozpack.path as mozpath
|
||||
import os
|
||||
|
||||
@ -290,55 +289,32 @@ class TestPreload(unittest.TestCase):
|
||||
|
||||
class TestJarLog(unittest.TestCase):
|
||||
def test_jarlog(self):
|
||||
base = 'file:' + pathname2url(os.path.abspath(os.curdir))
|
||||
s = StringIO('\n'.join([
|
||||
base + '/bar/baz.jar first',
|
||||
base + '/bar/baz.jar second',
|
||||
base + '/bar/baz.jar third',
|
||||
base + '/bar/baz.jar second',
|
||||
base + '/bar/baz.jar second',
|
||||
'jar:' + base + '/qux.zip!/omni.ja stuff',
|
||||
base + '/bar/baz.jar first',
|
||||
'jar:' + base + '/qux.zip!/omni.ja other/stuff',
|
||||
'jar:' + base + '/qux.zip!/omni.ja stuff',
|
||||
base + '/bar/baz.jar third',
|
||||
'jar:jar:' + base + '/qux.zip!/baz/baz.jar!/omni.ja nested/stuff',
|
||||
'jar:jar:jar:' + base + '/qux.zip!/baz/baz.jar!/foo.zip!/omni.ja' +
|
||||
' deeply/nested/stuff',
|
||||
'bar/baz.jar first',
|
||||
'bar/baz.jar second',
|
||||
'bar/baz.jar third',
|
||||
'bar/baz.jar second',
|
||||
'bar/baz.jar second',
|
||||
'omni.ja stuff',
|
||||
'bar/baz.jar first',
|
||||
'omni.ja other/stuff',
|
||||
'omni.ja stuff',
|
||||
'bar/baz.jar third',
|
||||
]))
|
||||
log = JarLog(fileobj=s)
|
||||
|
||||
def canonicalize(p):
|
||||
return mozpath.normsep(os.path.normcase(os.path.realpath(p)))
|
||||
|
||||
baz_jar = canonicalize('bar/baz.jar')
|
||||
qux_zip = canonicalize('qux.zip')
|
||||
self.assertEqual(set(log.keys()), set([
|
||||
baz_jar,
|
||||
(qux_zip, 'omni.ja'),
|
||||
(qux_zip, 'baz/baz.jar', 'omni.ja'),
|
||||
(qux_zip, 'baz/baz.jar', 'foo.zip', 'omni.ja'),
|
||||
'bar/baz.jar',
|
||||
'omni.ja',
|
||||
]))
|
||||
self.assertEqual(log[baz_jar], [
|
||||
self.assertEqual(log['bar/baz.jar'], [
|
||||
'first',
|
||||
'second',
|
||||
'third',
|
||||
])
|
||||
self.assertEqual(log[(qux_zip, 'omni.ja')], [
|
||||
self.assertEqual(log['omni.ja'], [
|
||||
'stuff',
|
||||
'other/stuff',
|
||||
])
|
||||
self.assertEqual(log[(qux_zip, 'baz/baz.jar', 'omni.ja')],
|
||||
['nested/stuff'])
|
||||
self.assertEqual(log[(qux_zip, 'baz/baz.jar', 'foo.zip',
|
||||
'omni.ja')], ['deeply/nested/stuff'])
|
||||
|
||||
# The above tests also indirectly check the value returned by
|
||||
# JarLog.canonicalize for various jar: and file: urls, but
|
||||
# JarLog.canonicalize also supports plain paths.
|
||||
self.assertEqual(JarLog.canonicalize(os.path.abspath('bar/baz.jar')),
|
||||
baz_jar)
|
||||
self.assertEqual(JarLog.canonicalize('bar/baz.jar'), baz_jar)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -87,13 +87,11 @@ interface nsINSSComponent : nsISupports {
|
||||
|
||||
/**
|
||||
* Returns true if the user has a PKCS#11 module with removable slots.
|
||||
* Main thread only.
|
||||
*/
|
||||
[noscript] bool hasActiveSmartCards();
|
||||
|
||||
/**
|
||||
* Returns true if the user has any client authentication certificates.
|
||||
* Main thread only.
|
||||
*/
|
||||
[noscript] bool hasUserCertsInstalled();
|
||||
|
||||
|
@ -695,14 +695,10 @@ LoadLoadableRootsTask::Run() {
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::HasActiveSmartCards(bool* result) {
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
if (!NS_IsMainThread()) {
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
||||
BlockUntilLoadableRootsLoaded();
|
||||
|
||||
#ifndef MOZ_NO_SMART_CARDS
|
||||
MutexAutoLock nsNSSComponentLock(mMutex);
|
||||
|
||||
AutoSECMODListReadLock secmodLock;
|
||||
SECMODModuleList* list = SECMOD_GetDefaultModuleList();
|
||||
while (list) {
|
||||
@ -720,10 +716,8 @@ nsNSSComponent::HasActiveSmartCards(bool* result) {
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::HasUserCertsInstalled(bool* result) {
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
if (!NS_IsMainThread()) {
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
||||
BlockUntilLoadableRootsLoaded();
|
||||
|
||||
*result = false;
|
||||
UniqueCERTCertList certList(CERT_FindUserCertsByUsage(
|
||||
|
@ -292,7 +292,7 @@ macosx64-ccov/debug:
|
||||
tier: 1
|
||||
worker-type: aws-provisioner-v1/gecko-{level}-b-linux
|
||||
worker:
|
||||
max-run-time: 5400
|
||||
max-run-time: 7200
|
||||
env:
|
||||
TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-releng.manifest"
|
||||
run:
|
||||
|
@ -75,7 +75,6 @@ jobs:
|
||||
parent: debian7-base
|
||||
definition: debian-build
|
||||
packages:
|
||||
- deb7-nasm
|
||||
- deb7-valgrind
|
||||
args:
|
||||
ARCH: amd64
|
||||
@ -90,7 +89,6 @@ jobs:
|
||||
- deb7-gtk3
|
||||
- deb7-harfbuzz
|
||||
- deb7-libxkbcommon
|
||||
- deb7-nasm
|
||||
- deb7-pango
|
||||
- deb7-pcre3
|
||||
- deb7-valgrind
|
||||
@ -116,7 +114,6 @@ jobs:
|
||||
- deb7-glib
|
||||
- deb7-gtk3
|
||||
- deb7-harfbuzz
|
||||
- deb7-nasm
|
||||
- deb7-python-defaults
|
||||
- deb7-pcre3
|
||||
- deb7-valgrind
|
||||
@ -138,9 +135,9 @@ jobs:
|
||||
symbol: I(deb9-raw)
|
||||
definition: debian-raw
|
||||
args:
|
||||
BASE_IMAGE: debian:stretch-20170620
|
||||
BASE_IMAGE: debian:stretch-20190228
|
||||
DIST: stretch
|
||||
SNAPSHOT: '20170830T000511Z'
|
||||
SNAPSHOT: '20190306T040711Z'
|
||||
debian9-packages:
|
||||
symbol: I(deb9-pkg)
|
||||
definition: debian-packages
|
||||
@ -167,8 +164,6 @@ jobs:
|
||||
static-analysis-build:
|
||||
symbol: I(static-analysis-build)
|
||||
parent: android-build
|
||||
packages:
|
||||
- deb9-nasm
|
||||
mingw32-build:
|
||||
symbol: I(mingw)
|
||||
parent: debian9-base
|
||||
@ -182,6 +177,7 @@ jobs:
|
||||
symbol: I(uv)
|
||||
diffoscope:
|
||||
symbol: I(diff)
|
||||
parent: debian9-base
|
||||
partner-repack:
|
||||
symbol: I(PR)
|
||||
parent: debian9-base
|
||||
|
28
taskcluster/ci/fetch/chromium-fetch.yml
Normal file
@ -0,0 +1,28 @@
|
||||
job-defaults:
|
||||
fetch:
|
||||
type: chromium-fetch
|
||||
script: /builds/worker/bin/fetch-chromium.py
|
||||
|
||||
linux64-chromium:
|
||||
description: 'Linux64 Chromium Fetch'
|
||||
fetch:
|
||||
platform: linux
|
||||
artifact-name: chrome-linux.tar.bz2
|
||||
|
||||
win32-chromium:
|
||||
description: 'Windows32 Chromium Fetch'
|
||||
fetch:
|
||||
platform: win32
|
||||
artifact-name: chrome-win32.tar.bz2
|
||||
|
||||
win64-chromium:
|
||||
description: 'Windows64 Chromium Fetch'
|
||||
fetch:
|
||||
platform: win64
|
||||
artifact-name: chrome-win64.tar.bz2
|
||||
|
||||
mac-chromium:
|
||||
description: 'MacOSX Chromium Fetch'
|
||||
fetch:
|
||||
platform: mac
|
||||
artifact-name: chrome-mac.tar.bz2
|
@ -13,3 +13,4 @@ transforms:
|
||||
jobs-from:
|
||||
- benchmarks.yml
|
||||
- toolchains.yml
|
||||
- chromium-fetch.yml
|
||||
|
@ -69,4 +69,5 @@ jobs:
|
||||
- linux64-gcc-sixgill
|
||||
- linux64-rust
|
||||
- linux64-cbindgen
|
||||
- linux64-nasm
|
||||
- linux64-node
|
||||
|
@ -277,30 +277,6 @@ jobs:
|
||||
url: https://github.com/indygreg/python-zstandard/releases/download/0.9.1/python-zstandard-0.9.1.tar.gz
|
||||
sha256: 59c7d6f1f85cebb5124abb50d8ec281c5311e0812e18785e28b197cf1515dd3b
|
||||
|
||||
deb7-nasm:
|
||||
description: "nasm for Debian wheezy"
|
||||
treeherder:
|
||||
symbol: Deb7(nasm)
|
||||
run:
|
||||
using: debian-package
|
||||
dsc:
|
||||
url: http://snapshot.debian.org/archive/debian/20170704T094954Z/pool/main/n/nasm/nasm_2.13.01-1.dsc
|
||||
sha256: 76528365eddc646f3f53c9f501ae9c2ba1678a163303d297e9014e3da36643c8
|
||||
patch: nasm-wheezy.diff
|
||||
|
||||
deb9-nasm:
|
||||
description: "nasm for Debian stretch"
|
||||
treeherder:
|
||||
symbol: Deb9(nasm)
|
||||
run:
|
||||
using: debian-package
|
||||
dist: stretch
|
||||
dsc:
|
||||
url: http://snapshot.debian.org/archive/debian/20170704T094954Z/pool/main/n/nasm/nasm_2.13.01-1.dsc
|
||||
sha256: 76528365eddc646f3f53c9f501ae9c2ba1678a163303d297e9014e3da36643c8
|
||||
# The package source is missing a build dependency on fontconfig.
|
||||
pre-build-command: apt-get install -y fontconfig
|
||||
|
||||
deb7-pcre3:
|
||||
description: "pcre3 8.31 for Debian Wheezy"
|
||||
treeherder:
|
||||
|
@ -29,6 +29,7 @@ jobs-from:
|
||||
- misc.yml
|
||||
- mochitest.yml
|
||||
- raptor.yml
|
||||
- raptor-chrome.yml
|
||||
- reftest.yml
|
||||
- talos.yml
|
||||
- web-platform.yml
|
||||
|
333
taskcluster/ci/test/raptor-chrome.yml
Normal file
@ -0,0 +1,333 @@
|
||||
job-defaults:
|
||||
max-run-time:
|
||||
by-test-platform:
|
||||
.*-qr/.*: 2400
|
||||
.*-ux/.*: 2400
|
||||
default: 1800
|
||||
suite: raptor
|
||||
workdir:
|
||||
by-test-platform:
|
||||
android-hw.*: /builds/worker
|
||||
default: /home/cltbld
|
||||
run-on-projects:
|
||||
by-test-platform:
|
||||
windows10-64-ux: ['try', 'mozilla-central']
|
||||
default: ['try', 'trunk', 'mozilla-beta']
|
||||
tier:
|
||||
by-test-platform:
|
||||
windows10-64-ccov/.*: 3
|
||||
linux64-ccov/.*: 3
|
||||
android-hw-g5.*: 2
|
||||
default: 1
|
||||
virtualization:
|
||||
by-test-platform:
|
||||
windows10-64-ccov/.*: virtual
|
||||
default: hardware
|
||||
mozharness:
|
||||
script: raptor_script.py
|
||||
config:
|
||||
by-test-platform:
|
||||
macosx.*:
|
||||
- raptor/mac_config.py
|
||||
windows.*:
|
||||
- raptor/windows_config.py
|
||||
windows10-64-ccov/debug:
|
||||
- raptor/windows_vm_config.py
|
||||
linux64-ccov/opt:
|
||||
- raptor/linux64_config_taskcluster.py
|
||||
android-hw.*:
|
||||
- raptor/android_hw_config.py
|
||||
default:
|
||||
- raptor/linux_config.py
|
||||
fetches:
|
||||
by-test-platform:
|
||||
win.*64.*:
|
||||
fetch:
|
||||
- win64-chromium
|
||||
win.*32.*:
|
||||
fetch:
|
||||
- win32-chromium
|
||||
macosx.*:
|
||||
fetch:
|
||||
- mac-chromium
|
||||
default:
|
||||
fetch:
|
||||
- linux64-chromium
|
||||
|
||||
raptor-tp6-1-chrome:
|
||||
description: "Raptor tp6-1 on Chrome"
|
||||
try-name: raptor-tp6-1-chrome
|
||||
treeherder-symbol: Rap-C(tp6-1)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1200
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-1
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-2-chrome:
|
||||
description: "Raptor tp6-2 on Chrome"
|
||||
try-name: raptor-tp6-2-chrome
|
||||
treeherder-symbol: Rap-C(tp6-2)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-2
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-3-chrome:
|
||||
description: "Raptor tp6-3 on Chrome"
|
||||
try-name: raptor-tp6-3-chrome
|
||||
treeherder-symbol: Rap-C(tp6-3)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 2400
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-3
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-4-chrome:
|
||||
description: "Raptor tp6-4 on Chrome"
|
||||
try-name: raptor-tp6-4-chrome
|
||||
treeherder-symbol: Rap-C(tp6-4)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-4
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-5-chrome:
|
||||
description: "Raptor tp6-5 on Chrome"
|
||||
try-name: raptor-tp6-5-chrome
|
||||
treeherder-symbol: Rap-C(tp6-5)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-5
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-6-chrome:
|
||||
description: "Raptor tp6-6 on Chrome"
|
||||
try-name: raptor-tp6-6-chrome
|
||||
treeherder-symbol: Rap-C(tp6-6)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-6
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-7-chrome:
|
||||
description: "Raptor tp6-7 on Chrome"
|
||||
try-name: raptor-tp6-7-chrome
|
||||
treeherder-symbol: Rap-C(tp6-7)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-7
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-8-chrome:
|
||||
description: "Raptor tp6-8 on Chrome"
|
||||
try-name: raptor-tp6-8-chrome
|
||||
treeherder-symbol: Rap-C(tp6-8)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-8
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-9-chrome:
|
||||
description: "Raptor tp6-9 on Chrome"
|
||||
try-name: raptor-tp6-9-chrome
|
||||
treeherder-symbol: Rap-C(tp6-9)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-9
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-10-chrome:
|
||||
description: "Raptor tp6-10 on Chrome"
|
||||
try-name: raptor-tp6-10-chrome
|
||||
treeherder-symbol: Rap-C(tp6-10)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-10
|
||||
- --app=chrome
|
||||
|
||||
raptor-speedometer-chrome:
|
||||
description: "Raptor Speedometer on Chrome"
|
||||
try-name: raptor-speedometer-chrome
|
||||
treeherder-symbol: Rap-C(sp)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-speedometer
|
||||
- --app=chrome
|
||||
|
||||
raptor-stylebench-chrome:
|
||||
description: "Raptor StyleBench on Chrome"
|
||||
try-name: raptor-stylebench-chrome
|
||||
treeherder-symbol: Rap-C(sb)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-stylebench
|
||||
- --app=chrome
|
||||
|
||||
raptor-motionmark-htmlsuite-chrome:
|
||||
description: "Raptor MotionMark HtmlSuite on Chrome"
|
||||
try-name: raptor-motionmark-htmlsuite-chrome
|
||||
treeherder-symbol: Rap-C(mm-h)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-motionmark-htmlsuite
|
||||
- --app=chrome
|
||||
|
||||
raptor-motionmark-animometer-chrome:
|
||||
description: "Raptor MotionMark Animometer on Chrome"
|
||||
try-name: raptor-motionmark-animometer-chrome
|
||||
treeherder-symbol: Rap-C(mm-a)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-motionmark-animometer
|
||||
- --app=chrome
|
||||
|
||||
raptor-webaudio-chrome:
|
||||
description: "Raptor WebAudio on Chrome"
|
||||
try-name: raptor-webaudio-chrome
|
||||
treeherder-symbol: Rap-C(wa)
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-webaudio
|
||||
- --app=chrome
|
||||
|
||||
raptor-sunspider-chrome:
|
||||
description: "Raptor SunSpider on Chrome"
|
||||
try-name: raptor-sunspider-chrome
|
||||
treeherder-symbol: Rap-C(ss)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-sunspider
|
||||
- --app=chrome
|
||||
|
||||
raptor-unity-webgl-chrome:
|
||||
description: "Raptor Unity WebGL on Chrome"
|
||||
try-name: raptor-unity-webgl-chrome
|
||||
treeherder-symbol: Rap-C(ugl)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-unity-webgl
|
||||
- --app=chrome
|
||||
fetches:
|
||||
by-test-platform:
|
||||
win.*64.*:
|
||||
fetch:
|
||||
- win64-chromium
|
||||
- unity-webgl
|
||||
win.*32.*:
|
||||
fetch:
|
||||
- win32-chromium
|
||||
- unity-webgl
|
||||
macosx.*:
|
||||
fetch:
|
||||
- mac-chromium
|
||||
- unity-webgl
|
||||
default:
|
||||
fetch:
|
||||
- linux64-chromium
|
||||
- unity-webgl
|
||||
|
||||
raptor-wasm-misc-chrome:
|
||||
description: "Raptor WASM Misc on Chrome"
|
||||
try-name: raptor-wasm-misc-chrome
|
||||
treeherder-symbol: Rap-C(wm)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-wasm-misc
|
||||
- --app=chrome
|
||||
fetches:
|
||||
by-test-platform:
|
||||
win.*64.*:
|
||||
fetch:
|
||||
- win64-chromium
|
||||
- wasm-misc
|
||||
win.*32.*:
|
||||
fetch:
|
||||
- win32-chromium
|
||||
- wasm-misc
|
||||
macosx.*:
|
||||
fetch:
|
||||
- mac-chromium
|
||||
- wasm-misc
|
||||
default:
|
||||
fetch:
|
||||
- linux64-chromium
|
||||
- wasm-misc
|
||||
|
||||
raptor-assorted-dom-chrome:
|
||||
description: "Raptor Assorted-Dom on Chrome"
|
||||
try-name: raptor-assorted-dom-chrome
|
||||
treeherder-symbol: Rap-C(dom)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-assorted-dom
|
||||
- --app=chrome
|
||||
fetches:
|
||||
by-test-platform:
|
||||
win.*64.*:
|
||||
fetch:
|
||||
- win64-chromium
|
||||
- assorted-dom
|
||||
win.*32.*:
|
||||
fetch:
|
||||
- win32-chromium
|
||||
- assorted-dom
|
||||
macosx.*:
|
||||
fetch:
|
||||
- mac-chromium
|
||||
- assorted-dom
|
||||
default:
|
||||
fetch:
|
||||
- linux64-chromium
|
||||
- assorted-dom
|
||||
|
||||
raptor-wasm-godot-chrome:
|
||||
description: "Raptor Wasm Godot on Chrome"
|
||||
try-name: raptor-wasm-godot-chrome
|
||||
treeherder-symbol: Rap-C(godot)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-wasm-godot
|
||||
- --app=chrome
|
@ -61,18 +61,6 @@ raptor-tp6-1-firefox-profiling:
|
||||
- --test=raptor-tp6-1
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-1-chrome:
|
||||
description: "Raptor tp6-1 on Chrome"
|
||||
try-name: raptor-tp6-1-chrome
|
||||
treeherder-symbol: Rap-C(tp6-1)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1200
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-1
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-2-firefox:
|
||||
description: "Raptor tp6-2 on Firefox"
|
||||
try-name: raptor-tp6-2-firefox
|
||||
@ -93,17 +81,6 @@ raptor-tp6-2-firefox-profiling:
|
||||
- --test=raptor-tp6-2
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-2-chrome:
|
||||
description: "Raptor tp6-2 on Chrome"
|
||||
try-name: raptor-tp6-2-chrome
|
||||
treeherder-symbol: Rap-C(tp6-2)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-2
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-3-firefox:
|
||||
description: "Raptor tp6-3 on Firefox"
|
||||
try-name: raptor-tp6-3-firefox
|
||||
@ -124,18 +101,6 @@ raptor-tp6-3-firefox-profiling:
|
||||
- --test=raptor-tp6-3
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-3-chrome:
|
||||
description: "Raptor tp6-3 on Chrome"
|
||||
try-name: raptor-tp6-3-chrome
|
||||
treeherder-symbol: Rap-C(tp6-3)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 2400
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-3
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-4-firefox:
|
||||
description: "Raptor tp6-4 on Firefox"
|
||||
try-name: raptor-tp6-4-firefox
|
||||
@ -156,17 +121,6 @@ raptor-tp6-4-firefox-profiling:
|
||||
- --test=raptor-tp6-4
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-4-chrome:
|
||||
description: "Raptor tp6-4 on Chrome"
|
||||
try-name: raptor-tp6-4-chrome
|
||||
treeherder-symbol: Rap-C(tp6-4)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-4
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-5-firefox:
|
||||
description: "Raptor tp6-5 on Firefox"
|
||||
try-name: raptor-tp6-5-firefox
|
||||
@ -187,17 +141,6 @@ raptor-tp6-5-firefox-profiling:
|
||||
- --test=raptor-tp6-5
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-5-chrome:
|
||||
description: "Raptor tp6-5 on Chrome"
|
||||
try-name: raptor-tp6-5-chrome
|
||||
treeherder-symbol: Rap-C(tp6-5)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-5
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-6-firefox:
|
||||
description: "Raptor tp6-6 on Firefox"
|
||||
try-name: raptor-tp6-6-firefox
|
||||
@ -218,17 +161,6 @@ raptor-tp6-6-firefox-profiling:
|
||||
- --test=raptor-tp6-6
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-6-chrome:
|
||||
description: "Raptor tp6-6 on Chrome"
|
||||
try-name: raptor-tp6-6-chrome
|
||||
treeherder-symbol: Rap-C(tp6-6)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-6
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-7-firefox:
|
||||
description: "Raptor tp6-7 on Firefox"
|
||||
try-name: raptor-tp6-7-firefox
|
||||
@ -249,17 +181,6 @@ raptor-tp6-7-firefox-profiling:
|
||||
- --test=raptor-tp6-7
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-7-chrome:
|
||||
description: "Raptor tp6-7 on Chrome"
|
||||
try-name: raptor-tp6-7-chrome
|
||||
treeherder-symbol: Rap-C(tp6-7)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-7
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-8-firefox:
|
||||
description: "Raptor tp6-8 on Firefox"
|
||||
try-name: raptor-tp6-8-firefox
|
||||
@ -282,17 +203,6 @@ raptor-tp6-8-firefox-profiling:
|
||||
- --test=raptor-tp6-8
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-8-chrome:
|
||||
description: "Raptor tp6-8 on Chrome"
|
||||
try-name: raptor-tp6-8-chrome
|
||||
treeherder-symbol: Rap-C(tp6-8)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-8
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-9-firefox:
|
||||
description: "Raptor tp6-9 on Firefox"
|
||||
try-name: raptor-tp6-9-firefox
|
||||
@ -315,17 +225,6 @@ raptor-tp6-9-firefox-profiling:
|
||||
- --test=raptor-tp6-9
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-9-chrome:
|
||||
description: "Raptor tp6-9 on Chrome"
|
||||
try-name: raptor-tp6-9-chrome
|
||||
treeherder-symbol: Rap-C(tp6-9)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-9
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-10-firefox:
|
||||
description: "Raptor tp6-10 on Firefox"
|
||||
try-name: raptor-tp6-10-firefox
|
||||
@ -348,17 +247,6 @@ raptor-tp6-10-firefox-profiling:
|
||||
- --test=raptor-tp6-10
|
||||
- --gecko-profile
|
||||
|
||||
raptor-tp6-10-chrome:
|
||||
description: "Raptor tp6-10 on Chrome"
|
||||
try-name: raptor-tp6-10-chrome
|
||||
treeherder-symbol: Rap-C(tp6-10)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-tp6-10
|
||||
- --app=chrome
|
||||
|
||||
raptor-tp6-binast-1-firefox:
|
||||
description: "Raptor tp6-binast-1 on Firefox"
|
||||
try-name: raptor-tp6-binast-1
|
||||
@ -513,18 +401,6 @@ raptor-speedometer-fennec:
|
||||
- --app=fennec
|
||||
- --binary=org.mozilla.fennec_aurora
|
||||
|
||||
raptor-speedometer-chrome:
|
||||
description: "Raptor Speedometer on Chrome"
|
||||
try-name: raptor-speedometer-chrome
|
||||
treeherder-symbol: Rap-C(sp)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-speedometer
|
||||
- --app=chrome
|
||||
|
||||
raptor-stylebench-firefox:
|
||||
description: "Raptor StyleBench on Firefox"
|
||||
try-name: raptor-stylebench-firefox
|
||||
@ -545,17 +421,6 @@ raptor-stylebench-firefox-profiling:
|
||||
- --test=raptor-stylebench
|
||||
- --gecko-profile
|
||||
|
||||
raptor-stylebench-chrome:
|
||||
description: "Raptor StyleBench on Chrome"
|
||||
try-name: raptor-stylebench-chrome
|
||||
treeherder-symbol: Rap-C(sb)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-stylebench
|
||||
- --app=chrome
|
||||
|
||||
raptor-motionmark-htmlsuite-firefox:
|
||||
description: "Raptor MotionMark HtmlSuite on Firefox"
|
||||
try-name: raptor-motionmark-htmlsuite-firefox
|
||||
@ -576,17 +441,6 @@ raptor-motionmark-htmlsuite-firefox-profiling:
|
||||
- --test=raptor-motionmark-htmlsuite
|
||||
- --gecko-profile
|
||||
|
||||
raptor-motionmark-htmlsuite-chrome:
|
||||
description: "Raptor MotionMark HtmlSuite on Chrome"
|
||||
try-name: raptor-motionmark-htmlsuite-chrome
|
||||
treeherder-symbol: Rap-C(mm-h)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-motionmark-htmlsuite
|
||||
- --app=chrome
|
||||
|
||||
raptor-motionmark-animometer-firefox:
|
||||
description: "Raptor MotionMark Animometer on Firefox"
|
||||
try-name: raptor-motionmark-animometer-firefox
|
||||
@ -607,17 +461,6 @@ raptor-motionmark-animometer-firefox-profiling:
|
||||
- --test=raptor-motionmark-animometer
|
||||
- --gecko-profile
|
||||
|
||||
raptor-motionmark-animometer-chrome:
|
||||
description: "Raptor MotionMark Animometer on Chrome"
|
||||
try-name: raptor-motionmark-animometer-chrome
|
||||
treeherder-symbol: Rap-C(mm-a)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-motionmark-animometer
|
||||
- --app=chrome
|
||||
|
||||
raptor-webaudio-firefox:
|
||||
description: "Raptor WebAudio on Firefox"
|
||||
try-name: raptor-webaudio-firefox
|
||||
@ -638,16 +481,6 @@ raptor-webaudio-firefox-profiling:
|
||||
- --test=raptor-webaudio
|
||||
- --gecko-profile
|
||||
|
||||
raptor-webaudio-chrome:
|
||||
description: "Raptor WebAudio on Chrome"
|
||||
try-name: raptor-webaudio-chrome
|
||||
treeherder-symbol: Rap-C(wa)
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-webaudio
|
||||
- --app=chrome
|
||||
|
||||
raptor-sunspider-firefox:
|
||||
description: "Raptor SunSpider on Firefox"
|
||||
try-name: raptor-sunspider-firefox
|
||||
@ -668,17 +501,6 @@ raptor-sunspider-firefox-profiling:
|
||||
- --test=raptor-sunspider
|
||||
- --gecko-profile
|
||||
|
||||
raptor-sunspider-chrome:
|
||||
description: "Raptor SunSpider on Chrome"
|
||||
try-name: raptor-sunspider-chrome
|
||||
treeherder-symbol: Rap-C(ss)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-sunspider
|
||||
- --app=chrome
|
||||
|
||||
raptor-unity-webgl-firefox:
|
||||
description: "Raptor Unity WebGL on Firefox"
|
||||
try-name: raptor-unity-webgl-firefox
|
||||
@ -726,20 +548,6 @@ raptor-unity-webgl-geckoview:
|
||||
fetch:
|
||||
- unity-webgl
|
||||
|
||||
raptor-unity-webgl-chrome:
|
||||
description: "Raptor Unity WebGL on Chrome"
|
||||
try-name: raptor-unity-webgl-chrome
|
||||
treeherder-symbol: Rap-C(ugl)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-unity-webgl
|
||||
- --app=chrome
|
||||
fetches:
|
||||
fetch:
|
||||
- unity-webgl
|
||||
|
||||
raptor-wasm-misc-firefox:
|
||||
description: "Raptor WASM Misc on Firefox"
|
||||
try-name: raptor-wasm-misc-firefox
|
||||
@ -818,20 +626,6 @@ raptor-wasm-misc-ion-firefox-profiling:
|
||||
fetch:
|
||||
- wasm-misc
|
||||
|
||||
raptor-wasm-misc-chrome:
|
||||
description: "Raptor WASM Misc on Chrome"
|
||||
try-name: raptor-wasm-misc-chrome
|
||||
treeherder-symbol: Rap-C(wm)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-wasm-misc
|
||||
- --app=chrome
|
||||
fetches:
|
||||
fetch:
|
||||
- wasm-misc
|
||||
|
||||
raptor-assorted-dom-firefox:
|
||||
description: "Raptor Assorted-Dom on Firefox"
|
||||
try-name: raptor-assorted-dom-firefox
|
||||
@ -863,21 +657,6 @@ raptor-assorted-dom-firefox-profiling:
|
||||
fetch:
|
||||
- assorted-dom
|
||||
|
||||
raptor-assorted-dom-chrome:
|
||||
description: "Raptor Assorted-Dom on Chrome"
|
||||
try-name: raptor-assorted-dom-chrome
|
||||
treeherder-symbol: Rap-C(dom)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-assorted-dom
|
||||
- --app=chrome
|
||||
fetches:
|
||||
fetch:
|
||||
- assorted-dom
|
||||
|
||||
raptor-wasm-godot-firefox:
|
||||
description: "Raptor Wasm Godot on Firefox"
|
||||
try-name: raptor-wasm-godot-firefox
|
||||
@ -903,18 +682,6 @@ raptor-wasm-godot-firefox-profiling:
|
||||
- --test=raptor-wasm-godot
|
||||
- --gecko-profile
|
||||
|
||||
raptor-wasm-godot-chrome:
|
||||
description: "Raptor Wasm Godot on Chrome"
|
||||
try-name: raptor-wasm-godot-chrome
|
||||
treeherder-symbol: Rap-C(godot)
|
||||
run-on-projects: ['try', 'mozilla-central']
|
||||
tier: 2
|
||||
max-run-time: 1500
|
||||
mozharness:
|
||||
extra-options:
|
||||
- --test=raptor-wasm-godot
|
||||
- --app=chrome
|
||||
|
||||
raptor-wasm-godot-baseline-firefox:
|
||||
description: "Raptor Wasm Godot on Firefox with baseline JIT"
|
||||
try-name: raptor-wasm-godot-baseline-firefox
|
||||
|
@ -25,6 +25,7 @@ RUN for s in debian_$DIST debian_$DIST-updates debian_$DIST-backports debian-sec
|
||||
) > /etc/apt/apt.conf.d/99taskcluster
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get dist-upgrade && \
|
||||
apt-get install \
|
||||
apt-transport-https \
|
||||
ca-certificates
|
||||
|
@ -1,43 +1,30 @@
|
||||
FROM debian:stretch-20171210
|
||||
# %ARG DOCKER_IMAGE_PARENT
|
||||
FROM $DOCKER_IMAGE_PARENT
|
||||
MAINTAINER Mike Hommey <mhommey@mozilla.com>
|
||||
|
||||
RUN mkdir /builds
|
||||
RUN useradd -d /builds/worker -s /bin/bash -m worker
|
||||
WORKDIR /builds/worker
|
||||
VOLUME /builds/worker/checkouts
|
||||
VOLUME /builds/worker/workspace
|
||||
VOLUME /builds/worker/tooltool-cache
|
||||
|
||||
# Set variable normally configured at login, by the shells parent process, these
|
||||
# are taken from GNU su manual
|
||||
ENV HOME=/builds/worker \
|
||||
SHELL=/bin/bash \
|
||||
USER=worker \
|
||||
LOGNAME=worker \
|
||||
HOSTNAME=taskcluster-worker \
|
||||
LANG=en_US.UTF-8 \
|
||||
LC_ALL=en_US.UTF-8 \
|
||||
DEBIAN_FRONTEND=noninteractive
|
||||
ENV LANG=en_US.UTF-8
|
||||
|
||||
# Set a default command useful for debugging
|
||||
CMD ["/bin/bash", "--login"]
|
||||
|
||||
# Set apt sources list to a snapshot.
|
||||
RUN for s in debian_stretch debian_stretch-updates debian-security_stretch/updates; do \
|
||||
echo "deb [check-valid-until=no] http://snapshot.debian.org/archive/${s%_*}/20171222T153610Z/ ${s#*_} main"; \
|
||||
done > /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update -q && \
|
||||
apt-get install -yyq diffoscope libc++abi1 locales python3-setuptools python2.7 python-pip git && \
|
||||
RUN apt-get install \
|
||||
binutils-multiarch \
|
||||
bzip2 \
|
||||
curl \
|
||||
enjarify \
|
||||
diffoscope/stretch-backports \
|
||||
jsbeautifier \
|
||||
libc++abi1 \
|
||||
locales \
|
||||
openjdk-8-jdk-headless \
|
||||
python3-progressbar \
|
||||
unzip \
|
||||
zip \
|
||||
&& \
|
||||
sed -i '/en_US.UTF-8/s/^# *//' /etc/locale.gen && \
|
||||
locale-gen && \
|
||||
git clone https://salsa.debian.org/reproducible-builds/diffoscope.git /tmp/diffoscope && \
|
||||
git -C /tmp/diffoscope checkout 202caf9d5d134e95f870d5f19f89511d635c27e4 && \
|
||||
(cd /tmp/diffoscope && python3 setup.py install ) && \
|
||||
rm -rf /tmp/diffoscope && \
|
||||
apt-get clean
|
||||
|
||||
# %include taskcluster/scripts/run-task
|
||||
COPY topsrcdir/taskcluster/scripts/run-task /builds/worker/bin/run-task
|
||||
locale-gen
|
||||
|
||||
COPY get_and_diffoscope /builds/worker/bin/get_and_diffoscope
|
||||
|
||||
RUN chown -R worker:worker /builds/worker/bin && chmod 755 /builds/worker/bin/*
|
||||
|
||||
|
@ -36,7 +36,7 @@ case "$ORIG_URL" in
|
||||
curl -sL $queue_base/task/${t#*@}/artifacts/${t%@*} | tar -Jxf -
|
||||
done
|
||||
for tool in lipo otool; do
|
||||
ln -s /builds/worker/cctools/bin/x86_64-apple-darwin*-$tool bin/$tool
|
||||
ln -s /builds/worker/cctools/bin/x86_64-darwin*-$tool bin/$tool
|
||||
done
|
||||
export PATH=$PATH:/builds/worker/bin
|
||||
curl -sL "$ORIG_URL" > a.dmg
|
||||
|
@ -3,7 +3,13 @@ FROM $DOCKER_IMAGE_PARENT
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install \
|
||||
gnupg
|
||||
gnupg \
|
||||
bzip2 \
|
||||
python3-requests \
|
||||
unzip
|
||||
|
||||
# %include taskcluster/scripts/misc/fetch-content
|
||||
ADD topsrcdir/taskcluster/scripts/misc/fetch-content /builds/worker/bin/fetch-content
|
||||
|
||||
# %include taskcluster/scripts/misc/fetch-chromium.py
|
||||
ADD topsrcdir/taskcluster/scripts/misc/fetch-chromium.py /builds/worker/bin/fetch-chromium.py
|
||||
|
206
taskcluster/scripts/misc/fetch-chromium.py
Normal file
@ -0,0 +1,206 @@
|
||||
#!/usr/bin/python3 -u
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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/.
|
||||
|
||||
'''
|
||||
This script downloads the latest chromium build (or a manually
|
||||
defined version) for a given platform. It then uploads the build,
|
||||
with the revision of the build stored in a REVISION file.
|
||||
'''
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
import argparse
|
||||
import errno
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import requests
|
||||
import tempfile
|
||||
|
||||
NEWEST_BASE_URL = 'https://download-chromium.appspot.com/'
|
||||
NEWREV_DOWNLOAD_URL = NEWEST_BASE_URL + 'dl/%s?type=snapshots'
|
||||
NEWREV_REVISION_URL = NEWEST_BASE_URL + 'rev/%s?type=snapshots'
|
||||
|
||||
OLDREV_BASE_URL = 'http://commondatastorage.googleapis.com/chromium-browser-snapshots/'
|
||||
OLDREV_DOWNLOAD_URL = OLDREV_BASE_URL + '%s/%s/%s' # (platform/revision/archive)
|
||||
|
||||
CHROMIUM_INFO = {
|
||||
'linux': {
|
||||
'platform': 'Linux_x64',
|
||||
'archive': 'chrome-linux.zip',
|
||||
'result': 'chrome-linux.tar.bz2'
|
||||
},
|
||||
'win32': {
|
||||
'platform': 'Win_x64',
|
||||
'archive': 'chrome-win.zip',
|
||||
'result': 'chrome-win32.tar.bz2'
|
||||
},
|
||||
'win64': {
|
||||
'platform': 'Win_x64',
|
||||
'archive': 'chrome-win.zip',
|
||||
'result': 'chrome-win64.tar.bz2'
|
||||
},
|
||||
'mac': {
|
||||
'platform': 'Mac',
|
||||
'archive': 'chrome-mac.zip',
|
||||
'result': 'chrome-mac.tar.bz2'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def log(msg):
|
||||
print('build-chromium: %s' % msg)
|
||||
|
||||
|
||||
def fetch_file(url, filepath):
|
||||
'''Download a file from the given url to a given file.'''
|
||||
size = 4096
|
||||
r = requests.get(url, stream=True)
|
||||
r.raise_for_status()
|
||||
|
||||
with open(filepath, 'wb') as fd:
|
||||
for chunk in r.iter_content(size):
|
||||
fd.write(chunk)
|
||||
|
||||
|
||||
def fetch_chromium_revision(platform):
|
||||
'''Get the revision of the latest chromium build. '''
|
||||
chromium_platform = CHROMIUM_INFO[platform]['platform']
|
||||
revision_url = NEWREV_REVISION_URL % chromium_platform
|
||||
|
||||
log(
|
||||
'Getting revision number for latest %s chromium build...' %
|
||||
chromium_platform
|
||||
)
|
||||
|
||||
# Expects a JSON of the form:
|
||||
# {
|
||||
# 'content': '<REVNUM>',
|
||||
# 'last-modified': '<DATE>'
|
||||
# }
|
||||
r = requests.get(revision_url, timeout=30)
|
||||
r.raise_for_status()
|
||||
|
||||
chromium_revision = json.loads(
|
||||
r.content.decode('utf-8')
|
||||
)['content']
|
||||
|
||||
return chromium_revision
|
||||
|
||||
|
||||
def fetch_chromium_build(platform, revision, zippath):
|
||||
'''Download a chromium build for a given revision, or the latest. '''
|
||||
use_oldrev = True
|
||||
if not revision:
|
||||
use_oldrev = False
|
||||
revision = fetch_chromium_revision(platform)
|
||||
|
||||
download_platform = CHROMIUM_INFO[platform]['platform']
|
||||
if use_oldrev:
|
||||
chromium_archive = CHROMIUM_INFO[platform]['archive']
|
||||
download_url = OLDREV_DOWNLOAD_URL % (
|
||||
download_platform, revision, chromium_archive
|
||||
)
|
||||
else:
|
||||
download_url = NEWREV_DOWNLOAD_URL % download_platform
|
||||
|
||||
log(
|
||||
'Downloading %s chromium build revision %s...' %
|
||||
(download_platform, revision)
|
||||
)
|
||||
|
||||
fetch_file(download_url, zippath)
|
||||
return revision
|
||||
|
||||
|
||||
def build_chromium_archive(platform, revision=None):
|
||||
'''
|
||||
Download and store a chromium build for a given platform.
|
||||
|
||||
Retrieves either the latest version, or uses a pre-defined version if
|
||||
the `--revision` option is given a revision.
|
||||
'''
|
||||
upload_dir = os.environ.get('UPLOAD_DIR')
|
||||
if upload_dir:
|
||||
# Create the upload directory if it doesn't exist.
|
||||
try:
|
||||
log('Creating upload directory in %s...' % os.path.abspath(upload_dir))
|
||||
os.makedirs(upload_dir)
|
||||
except OSError as e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
# Make a temporary location for the file
|
||||
tmppath = tempfile.mkdtemp()
|
||||
tmpzip = os.path.join(tmppath, 'tmp-chrome.zip')
|
||||
|
||||
revision = fetch_chromium_build(platform, revision, tmpzip)
|
||||
|
||||
# Unpack archive in `tmpzip` to store the revision number
|
||||
log('Unpacking archive at: %s to: %s' % (tmpzip, tmppath))
|
||||
unzip_command = ['unzip', '-q', '-o', tmpzip, '-d', tmppath]
|
||||
subprocess.check_call(unzip_command)
|
||||
|
||||
dirs = [
|
||||
d for d in os.listdir(tmppath)
|
||||
if os.path.isdir(os.path.join(tmppath, d)) and d.startswith('chrome-')
|
||||
]
|
||||
|
||||
if len(dirs) > 1:
|
||||
raise Exception(
|
||||
"Too many directories starting with 'chrome-' after extracting."
|
||||
)
|
||||
elif len(dirs) == 0:
|
||||
raise Exception(
|
||||
"Could not find any directories after extraction of chromium zip."
|
||||
)
|
||||
|
||||
chrome_dir = os.path.join(tmppath, dirs[0])
|
||||
revision_file = os.path.join(chrome_dir, '.REVISION')
|
||||
with open(revision_file, 'w+') as f:
|
||||
f.write(str(revision))
|
||||
|
||||
tar_file = CHROMIUM_INFO[platform]['result']
|
||||
tar_command = ['tar', 'cjf', tar_file, '-C', tmppath, dirs[0]]
|
||||
log(
|
||||
"Added revision to %s file." % revision_file
|
||||
)
|
||||
|
||||
log('Tarring with the command: %s' % str(tar_command))
|
||||
subprocess.check_call(tar_command)
|
||||
|
||||
upload_dir = os.environ.get('UPLOAD_DIR')
|
||||
if upload_dir:
|
||||
# Move the tarball to the output directory for upload.
|
||||
log('Moving %s to the upload directory...' % tar_file)
|
||||
shutil.copy(tar_file, os.path.join(upload_dir, tar_file))
|
||||
|
||||
shutil.rmtree(tmppath)
|
||||
|
||||
|
||||
def parse_args():
|
||||
'''Read command line arguments and return options.'''
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'--platform',
|
||||
help='Platform version of chromium to build.',
|
||||
required=True
|
||||
)
|
||||
parser.add_argument(
|
||||
'--revision',
|
||||
help='Revision of chromium to build to get. '
|
||||
'(Defaults to the newest chromium build).',
|
||||
default=None
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = vars(parse_args())
|
||||
build_chromium_archive(**args)
|
@ -570,6 +570,15 @@ def target_tasks_customv8_update(full_task_graph, parameters, graph_config):
|
||||
return ['toolchain-linux64-custom-v8']
|
||||
|
||||
|
||||
@_target_task('chromium_update')
|
||||
def target_tasks_chromium_update(full_task_graph, parameters, graph_config):
|
||||
"""Select tasks required for building latest chromium versions."""
|
||||
return ['fetch-linux64-chromium',
|
||||
'fetch-win32-chromium',
|
||||
'fetch-win64-chromium',
|
||||
'fetch-mac-chromium']
|
||||
|
||||
|
||||
@_target_task('pipfile_update')
|
||||
def target_tasks_pipfile_update(full_task_graph, parameters, graph_config):
|
||||
"""Select the set of tasks required to perform nightly in-tree pipfile updates
|
||||
|
@ -7,9 +7,12 @@
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from mozbuild.shellutil import quote as shell_quote
|
||||
|
||||
import os
|
||||
|
||||
from voluptuous import (
|
||||
Any,
|
||||
Optional,
|
||||
Required,
|
||||
)
|
||||
@ -43,35 +46,51 @@ FETCH_SCHEMA = Schema({
|
||||
# Description of the task.
|
||||
Required('description'): basestring,
|
||||
|
||||
Required('fetch'): {
|
||||
'type': 'static-url',
|
||||
Required('fetch'): Any(
|
||||
{
|
||||
'type': 'static-url',
|
||||
|
||||
# The URL to download.
|
||||
Required('url'): basestring,
|
||||
# The URL to download.
|
||||
Required('url'): basestring,
|
||||
|
||||
# The SHA-256 of the downloaded content.
|
||||
Required('sha256'): basestring,
|
||||
# The SHA-256 of the downloaded content.
|
||||
Required('sha256'): basestring,
|
||||
|
||||
# Size of the downloaded entity, in bytes.
|
||||
Required('size'): int,
|
||||
# Size of the downloaded entity, in bytes.
|
||||
Required('size'): int,
|
||||
|
||||
# GPG signature verification.
|
||||
Optional('gpg-signature'): {
|
||||
# URL where GPG signature document can be obtained. Can contain the
|
||||
# value ``{url}``, which will be substituted with the value from
|
||||
# ``url``.
|
||||
Required('sig-url'): basestring,
|
||||
# Path to file containing GPG public key(s) used to validate
|
||||
# download.
|
||||
Required('key-path'): basestring,
|
||||
# GPG signature verification.
|
||||
Optional('gpg-signature'): {
|
||||
# URL where GPG signature document can be obtained. Can contain the
|
||||
# value ``{url}``, which will be substituted with the value from
|
||||
# ``url``.
|
||||
Required('sig-url'): basestring,
|
||||
# Path to file containing GPG public key(s) used to validate
|
||||
# download.
|
||||
Required('key-path'): basestring,
|
||||
},
|
||||
|
||||
# The name to give to the generated artifact.
|
||||
Optional('artifact-name'): basestring,
|
||||
|
||||
# IMPORTANT: when adding anything that changes the behavior of the task,
|
||||
# it is important to update the digest data used to compute cache hits.
|
||||
},
|
||||
{
|
||||
'type': 'chromium-fetch',
|
||||
|
||||
# The name to give to the generated artifact.
|
||||
Optional('artifact-name'): basestring,
|
||||
Required('script'): basestring,
|
||||
|
||||
# IMPORTANT: when adding anything that changes the behavior of the task,
|
||||
# it is important to update the digest data used to compute cache hits.
|
||||
},
|
||||
# Platform type for chromium build
|
||||
Required('platform'): basestring,
|
||||
|
||||
# Chromium revision to obtain
|
||||
Optional('revision'): basestring,
|
||||
|
||||
# The name to give to the generated artifact.
|
||||
Required('artifact-name'): basestring
|
||||
}
|
||||
),
|
||||
})
|
||||
|
||||
transforms = TransformSequence()
|
||||
@ -89,6 +108,8 @@ def process_fetch_job(config, jobs):
|
||||
|
||||
if typ == 'static-url':
|
||||
yield create_fetch_url_task(config, job)
|
||||
elif typ == 'chromium-fetch':
|
||||
yield create_chromium_fetch_task(config, job)
|
||||
else:
|
||||
# validate() should have caught this.
|
||||
assert False
|
||||
@ -189,3 +210,55 @@ def create_fetch_url_task(config, job):
|
||||
)
|
||||
|
||||
return task
|
||||
|
||||
|
||||
def create_chromium_fetch_task(config, job):
|
||||
name = job['name']
|
||||
fetch = job['fetch']
|
||||
artifact_name = fetch.get('artifact-name')
|
||||
|
||||
workdir = '/builds/worker'
|
||||
|
||||
platform = fetch.get('platform')
|
||||
revision = fetch.get('revision')
|
||||
|
||||
args = '--platform ' + shell_quote(platform)
|
||||
if revision:
|
||||
args += ' --revision ' + shell_quote(revision)
|
||||
|
||||
cmd = [
|
||||
'bash',
|
||||
'-c',
|
||||
'cd {} && '
|
||||
'/usr/bin/python3 {} {}'.format(
|
||||
workdir, fetch['script'], args
|
||||
)
|
||||
]
|
||||
|
||||
env = {
|
||||
'UPLOAD_DIR': '/builds/worker/artifacts'
|
||||
}
|
||||
|
||||
task = make_base_task(config, name, job['description'], cmd)
|
||||
task['treeherder']['symbol'] = join_symbol('Fetch-URL', name)
|
||||
task['worker']['artifacts'] = [{
|
||||
'type': 'directory',
|
||||
'name': 'public',
|
||||
'path': '/builds/worker/artifacts',
|
||||
}]
|
||||
task['worker']['env'] = env
|
||||
task['attributes']['fetch-artifact'] = 'public/%s' % artifact_name
|
||||
|
||||
if not taskgraph.fast:
|
||||
cache_name = task['label'].replace('{}-'.format(config.kind), '', 1)
|
||||
|
||||
# This adds the level to the index path automatically.
|
||||
add_optimization(
|
||||
config,
|
||||
task,
|
||||
cache_type=CACHE_TYPE,
|
||||
cache_name=cache_name,
|
||||
digest_data=["revision={}".format(revision), "platform={}".format(platform)],
|
||||
)
|
||||
|
||||
return task
|
||||
|
@ -430,9 +430,12 @@ test_description_schema = Schema({
|
||||
),
|
||||
|
||||
# A list of artifacts to install from 'fetch' tasks.
|
||||
Optional('fetches'): {
|
||||
basestring: [basestring],
|
||||
},
|
||||
Optional('fetches'): optionally_keyed_by(
|
||||
'test-platform',
|
||||
{
|
||||
basestring: [basestring]
|
||||
}
|
||||
),
|
||||
}, required=True)
|
||||
|
||||
|
||||
@ -747,6 +750,7 @@ def handle_keyed_by(config, tests):
|
||||
'workdir',
|
||||
'worker-type',
|
||||
'virtualization',
|
||||
'fetches',
|
||||
]
|
||||
for test in tests:
|
||||
for field in fields:
|
||||
|
@ -17,7 +17,7 @@ class TestSafeBrowsingInitialDownload(PuppeteerMixin, MarionetteTestCase):
|
||||
]
|
||||
|
||||
v4_file_extensions = [
|
||||
'pset',
|
||||
'vlpset',
|
||||
'metadata',
|
||||
]
|
||||
|
||||
|
@ -15,7 +15,7 @@ import mozcrash
|
||||
import mozinfo
|
||||
import mozlog
|
||||
import moznetwork
|
||||
from mozdevice import ADBDevice, ADBError
|
||||
from mozdevice import ADBDevice, ADBError, ADBTimeoutError
|
||||
from mozprofile import Profile, DEFAULT_PORTS
|
||||
from mozprofile.permissions import ServerLocations
|
||||
from runtests import MochitestDesktop, update_mozinfo
|
||||
@ -441,17 +441,21 @@ def run_test_harness(parser, options):
|
||||
runner = JUnitTestRunner(log, options)
|
||||
result = -1
|
||||
try:
|
||||
device_exception = False
|
||||
result = runner.run_tests(options.test_filters)
|
||||
except KeyboardInterrupt:
|
||||
log.info("runjunit.py | Received keyboard interrupt")
|
||||
result = -1
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
log.error(
|
||||
"runjunit.py | Received unexpected exception while running tests")
|
||||
result = 1
|
||||
if isinstance(e, ADBTimeoutError):
|
||||
device_exception = True
|
||||
finally:
|
||||
runner.cleanup()
|
||||
if not device_exception:
|
||||
runner.cleanup()
|
||||
return result
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ deps = []
|
||||
setup(
|
||||
name=PACKAGE_NAME,
|
||||
version=PACKAGE_VERSION,
|
||||
description="Proxy for playback" "left behind by crashed processes",
|
||||
description="Proxy for playback",
|
||||
long_description="see https://firefox-source-docs.mozilla.org/mozbase/index.html",
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 2.7",
|
||||
|
@ -599,8 +599,11 @@ class AndroidMixin(object):
|
||||
|
||||
for t in self.timers:
|
||||
t.cancel()
|
||||
self.check_for_ANRs()
|
||||
self.check_for_tombstones()
|
||||
if self.worst_status != TBPL_RETRY:
|
||||
self.check_for_ANRs()
|
||||
self.check_for_tombstones()
|
||||
else:
|
||||
self.info("ANR and tombstone checks skipped due to TBPL_RETRY")
|
||||
self.logcat_stop()
|
||||
if self.is_emulator:
|
||||
self.kill_processes(self.config["emulator_process_name"])
|
||||
|
@ -11,7 +11,6 @@ import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from shutil import copyfile
|
||||
|
||||
@ -251,7 +250,8 @@ class Raptor(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidMixin):
|
||||
return self.abs_dirs
|
||||
|
||||
def install_chrome(self):
|
||||
# temporary hack to install google chrome in production; until chrome is in our CI
|
||||
'''install google chrome in production; installation
|
||||
requirements depend on the platform'''
|
||||
if self.app != "chrome":
|
||||
self.info("Google Chrome is not required")
|
||||
return
|
||||
@ -260,74 +260,21 @@ class Raptor(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidMixin):
|
||||
self.info("expecting Google Chrome to be pre-installed locally")
|
||||
return
|
||||
|
||||
# in production we can put the chrome build in mozharness/mozilla/testing/chrome
|
||||
self.chrome_dest = os.path.join(here, 'chrome')
|
||||
|
||||
# mozharness/base/script.py.self.platform_name will return one of:
|
||||
# 'linux64', 'linux', 'macosx', 'win64', 'win32'
|
||||
|
||||
base_url = "http://commondatastorage.googleapis.com/chromium-browser-snapshots"
|
||||
|
||||
# note: temporarily use a specified chromium revision number to download; however
|
||||
# in the future we will be using a fetch task to get a new chromium (Bug 1476372)
|
||||
self.info("Getting fetched chromium build")
|
||||
self.chrome_dest = os.path.normpath(os.path.abspath(os.environ['MOZ_FETCHES_DIR']))
|
||||
|
||||
if 'mac' in self.platform_name():
|
||||
# for now hardcoding a revision; but change this to update to newer version; from:
|
||||
# http://commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/LAST_CHANGE
|
||||
|
||||
# Note: Using an older version of Chromium on OSX b/c of an issue with a pop-up
|
||||
# dialog appearing with newer Chromium on OSX; please see:
|
||||
# Bug 1520523 - Update Chromium version running with Raptor in production
|
||||
chromium_rev = "634618"
|
||||
chrome_archive_file = "chrome-mac.zip"
|
||||
chrome_url = "%s/Mac/%s/%s" % (base_url, chromium_rev, chrome_archive_file)
|
||||
self.chrome_path = os.path.join(self.chrome_dest, 'chrome-mac', 'Chromium.app',
|
||||
'Contents', 'MacOS', 'Chromium')
|
||||
|
||||
elif 'linux' in self.platform_name():
|
||||
# for now hardcoding a revision; but change this to update to newer version; from:
|
||||
# http://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/LAST_CHANGE
|
||||
chromium_rev = "634637"
|
||||
chrome_archive_file = "chrome-linux.zip"
|
||||
chrome_url = "%s/Linux_x64/%s/%s" % (base_url, chromium_rev, chrome_archive_file)
|
||||
self.chrome_path = os.path.join(self.chrome_dest, 'chrome-linux', 'chrome')
|
||||
|
||||
else:
|
||||
# windows 7/10
|
||||
# for now hardcoding a revision; but change this to update to newer version; from:
|
||||
# http://commondatastorage.googleapis.com/chromium-browser-snapshots/Win_x64/LAST_CHANGE
|
||||
chromium_rev = "634634"
|
||||
chrome_archive_file = "chrome-win.zip" # same zip name for win32/64
|
||||
|
||||
# one url for Win x64/32
|
||||
chrome_url = "%s/Win_x64/%s/%s" % (base_url, chromium_rev, chrome_archive_file)
|
||||
|
||||
self.chrome_path = os.path.join(self.chrome_dest, 'chrome-win', 'Chrome.exe')
|
||||
|
||||
chrome_archive = os.path.join(self.chrome_dest, chrome_archive_file)
|
||||
|
||||
self.info("installing google chrome - temporary install hack")
|
||||
self.info("chrome archive is: %s" % chrome_archive)
|
||||
self.info("chrome dest is: %s" % self.chrome_dest)
|
||||
|
||||
if os.path.exists(self.chrome_path):
|
||||
self.info("google chrome binary already exists at: %s" % self.chrome_path)
|
||||
return
|
||||
|
||||
if not os.path.exists(chrome_archive):
|
||||
# download the chrome installer
|
||||
self.download_file(chrome_url, parent_dir=self.chrome_dest)
|
||||
|
||||
commands = []
|
||||
commands.append(['unzip', '-q', '-o', chrome_archive_file, '-d', self.chrome_dest])
|
||||
|
||||
# now run the commands to unpack / install google chrome
|
||||
for next_command in commands:
|
||||
return_code = self.run_command(next_command, cwd=self.chrome_dest)
|
||||
time.sleep(30)
|
||||
if return_code not in [0]:
|
||||
self.info("abort: failed to install %s to %s with command: %s"
|
||||
% (chrome_archive_file, self.chrome_dest, next_command))
|
||||
self.info("chrome path is: %s" % self.chrome_path)
|
||||
|
||||
# now ensure chrome binary exists
|
||||
if os.path.exists(self.chrome_path):
|
||||
|
@ -203,6 +203,12 @@
|
||||
"minbytes": 0,
|
||||
"maxbytes": 8192
|
||||
},
|
||||
"{firefox}\\browser\\features\\formautofill@mozilla.org.xpi": {
|
||||
"mincount": 0,
|
||||
"maxcount": 6,
|
||||
"minbytes": 0,
|
||||
"maxbytes": 393216
|
||||
},
|
||||
"{firefox}\\browser\\features\\flyweb@mozilla.org.xpi": {
|
||||
"mincount": 0,
|
||||
"maxcount": 2,
|
||||
|
@ -0,0 +1,3 @@
|
||||
[background-gradient-subpixel-fills-area.html]
|
||||
expected:
|
||||
if webrender: FAIL
|
@ -1,4 +0,0 @@
|
||||
[track-cues-enter-exit.html]
|
||||
[TextTrack's cues are indexed and updated in order during video playback]
|
||||
expected: FAIL
|
||||
|
@ -1,8 +1,4 @@
|
||||
[RTCPeerConnection-transceivers.https.html]
|
||||
[setRemoteDescription(offer): ontrack's track.id is the same as track.id]
|
||||
expected: FAIL
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1531439
|
||||
|
||||
[addTransceiver(track, init): initialize sendEncodings\[0\].active to false]
|
||||
expected: FAIL
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
|
||||
|
@ -77,11 +77,8 @@ test1.step(function(){
|
||||
test3.step(function(){
|
||||
var c3 = new VTTCue(0, 2, "text3");
|
||||
t1.addCue(c3);
|
||||
assert_equals(t1.activeCues.length, 1, "t1.activeCues.length after adding a cue in the same script");
|
||||
test3.step_timeout(function(){
|
||||
assert_equals(t1.activeCues.length, 2, "t1.activeCues.length after the event loop has spun");
|
||||
test3.done();
|
||||
}, 0);
|
||||
assert_equals(t1.activeCues.length, 2, "t1.activeCues.length should be changed immediately");
|
||||
test3.done();
|
||||
});
|
||||
test2.done();
|
||||
});
|
||||
|