Merge mozilla-central to inbound. a=merge CLOSED TREE

This commit is contained in:
shindli 2019-03-08 11:42:48 +02:00
commit a0e5b5dae7
145 changed files with 3215 additions and 1719 deletions

View File

@ -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

View File

@ -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,

View File

@ -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.

View File

@ -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");

View File

@ -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

View File

@ -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);

View File

@ -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"
},

View File

@ -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]

View File

@ -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"});
});

View File

@ -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) {

View File

@ -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++"

View File

@ -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.

View File

@ -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

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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; }

View File

@ -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)

View File

@ -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

Binary file not shown.

View 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

View File

@ -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>

View File

@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<html>
<body>
<video id="v1" src="../black.mp4"></video>
</body>
</html>

View File

@ -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;
}

View File

@ -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);

View 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

View File

@ -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,

View File

@ -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.

View File

@ -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;
}
}

View File

@ -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)]

View File

@ -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,
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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(..) |

View File

@ -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,

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -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 = {

View File

@ -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()) {

View File

@ -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"

View File

@ -194,7 +194,7 @@ void js::Nursery::enable() {
if (!allocateNextChunk(0, lock)) {
return;
}
capacity_ = NurseryChunkUsableSize;
capacity_ = SubChunkLimit;
}
setCurrentChunk(0, true);

View 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)); }

View File

@ -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);
}

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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),

View File

@ -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;

View File

@ -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(

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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))

View File

@ -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__':

View File

@ -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();

View File

@ -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(

View File

@ -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:

View File

@ -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

View 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

View File

@ -13,3 +13,4 @@ transforms:
jobs-from:
- benchmarks.yml
- toolchains.yml
- chromium-fetch.yml

View File

@ -69,4 +69,5 @@ jobs:
- linux64-gcc-sixgill
- linux64-rust
- linux64-cbindgen
- linux64-nasm
- linux64-node

View File

@ -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:

View File

@ -29,6 +29,7 @@ jobs-from:
- misc.yml
- mochitest.yml
- raptor.yml
- raptor-chrome.yml
- reftest.yml
- talos.yml
- web-platform.yml

View 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

View File

@ -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

View File

@ -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

View File

@ -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/*

View File

@ -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

View File

@ -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

View 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)

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -17,7 +17,7 @@ class TestSafeBrowsingInitialDownload(PuppeteerMixin, MarionetteTestCase):
]
v4_file_extensions = [
'pset',
'vlpset',
'metadata',
]

View File

@ -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

View File

@ -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",

View File

@ -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"])

View File

@ -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):

View File

@ -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,

View File

@ -0,0 +1,3 @@
[background-gradient-subpixel-fills-area.html]
expected:
if webrender: FAIL

View File

@ -1,4 +0,0 @@
[track-cues-enter-exit.html]
[TextTrack's cues are indexed and updated in order during video playback]
expected: FAIL

View File

@ -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

View File

@ -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();
});

Some files were not shown because too many files have changed in this diff Show More