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

This commit is contained in:
Ciure Andrei 2019-03-04 23:54:12 +02:00
Родитель b7ac200b5d e97d6d2ed4
Коммит 5ebab45abd
222 изменённых файлов: 1863 добавлений и 1942 удалений

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

@ -1102,7 +1102,9 @@ nsContextMenu.prototype = {
// nsIExternalHelperAppService.doContent, which will wait for the // nsIExternalHelperAppService.doContent, which will wait for the
// appropriate MIME-type headers and then prompt the user with a // appropriate MIME-type headers and then prompt the user with a
// file picker // file picker
function saveAsListener() {} function saveAsListener(principal) {
this._triggeringPrincipal = principal;
}
saveAsListener.prototype = { saveAsListener.prototype = {
extListener: null, extListener: null,
@ -1146,7 +1148,7 @@ nsContextMenu.prototype = {
// do it the old fashioned way, which will pick the best filename // do it the old fashioned way, which will pick the best filename
// it can without waiting. // it can without waiting.
saveURL(linkURL, linkText, dialogTitle, bypassCache, false, docURI, saveURL(linkURL, linkText, dialogTitle, bypassCache, false, docURI,
doc, isContentWindowPrivate); doc, isContentWindowPrivate, this._triggeringPrincipal);
} }
if (this.extListener) if (this.extListener)
this.extListener.onStopRequest(aRequest, aStatusCode); this.extListener.onStopRequest(aRequest, aStatusCode);
@ -1226,7 +1228,7 @@ nsContextMenu.prototype = {
timer.TYPE_ONE_SHOT); timer.TYPE_ONE_SHOT);
// kick off the channel with our proxy object as the listener // kick off the channel with our proxy object as the listener
channel.asyncOpen(new saveAsListener()); channel.asyncOpen(new saveAsListener(this.principal));
}, },
// Save URL of clicked-on link. // Save URL of clicked-on link.

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

@ -22,6 +22,11 @@
display: none; display: none;
} }
.tab-icon-pending[preopened],
.tab-icon-image[preopened] {
visibility: hidden;
}
.tab-sharing-icon-overlay[sharing]:not([selected]), .tab-sharing-icon-overlay[sharing]:not([selected]),
.tab-icon-overlay[soundplaying][pinned], .tab-icon-overlay[soundplaying][pinned],
.tab-icon-overlay[muted][pinned], .tab-icon-overlay[muted][pinned],

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

@ -32,6 +32,7 @@ window._gBrowser = {
window.addEventListener("occlusionstatechange", this); window.addEventListener("occlusionstatechange", this);
this._setupInitialBrowserAndTab(); this._setupInitialBrowserAndTab();
this._preopenPinnedTabs();
if (Services.prefs.getBoolPref("browser.display.use_system_colors")) { if (Services.prefs.getBoolPref("browser.display.use_system_colors")) {
this.tabpanels.style.backgroundColor = "-moz-default-background-color"; this.tabpanels.style.backgroundColor = "-moz-default-background-color";
@ -383,6 +384,29 @@ window._gBrowser = {
browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL); browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
}, },
_preopenPinnedTabs() {
let numPinnedTabs = 0;
let windows = browserWindows();
windows.getNext();
let isOnlyWindow = !windows.hasMoreElements();
if (isOnlyWindow) {
numPinnedTabs = Services.prefs.getIntPref("browser.tabs.firstWindowRestore.numPinnedTabs", 0);
}
for (let i = 0; i < numPinnedTabs; i++) {
let tab = this.addTrustedTab("about:blank", {
skipAnimation: true,
noInitialLabel: true,
skipBackgroundNotify: true,
createLazyBrowser: true,
pinned: true,
isForFirstWindowRestore: true,
});
tab.setAttribute("preopened", "true");
}
},
/** /**
* BEGIN FORWARDED BROWSER PROPERTIES. IF YOU ADD A PROPERTY TO THE BROWSER ELEMENT * BEGIN FORWARDED BROWSER PROPERTIES. IF YOU ADD A PROPERTY TO THE BROWSER ELEMENT
* MAKE SURE TO ADD IT HERE AS WELL. * MAKE SURE TO ADD IT HERE AS WELL.
@ -593,14 +617,32 @@ window._gBrowser = {
this.tabContainer._updateCloseButtons(); this.tabContainer._updateCloseButtons();
}, },
_notifyPinnedStatus(aTab) { _sendPinnedTabContentMessage(aTab) {
this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: aTab.pinned }); this.getBrowserForTab(aTab).messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: aTab.pinned });
},
_notifyPinnedStatus(aTab, aDeferContentMessage = false) {
if (!aDeferContentMessage) {
this._sendPinnedTabContentMessage(aTab);
}
let event = document.createEvent("Events"); let event = document.createEvent("Events");
event.initEvent(aTab.pinned ? "TabPinned" : "TabUnpinned", true, false); event.initEvent(aTab.pinned ? "TabPinned" : "TabUnpinned", true, false);
aTab.dispatchEvent(event); aTab.dispatchEvent(event);
}, },
_maybeUpdateNumPinnedTabsPref() {
if (BrowserWindowTracker.getTopWindow() == window) {
Services.prefs.setIntPref("browser.tabs.firstWindowRestore.numPinnedTabs",
this._numPinnedTabs);
}
},
activatePreopenedPinnedTab(aTab) {
this._insertBrowser(aTab);
this._sendPinnedTabContentMessage(aTab);
},
pinTab(aTab) { pinTab(aTab) {
if (aTab.pinned) if (aTab.pinned)
return; return;
@ -612,6 +654,7 @@ window._gBrowser = {
aTab.setAttribute("pinned", "true"); aTab.setAttribute("pinned", "true");
this._updateTabBarForPinnedTabs(); this._updateTabBarForPinnedTabs();
this._notifyPinnedStatus(aTab); this._notifyPinnedStatus(aTab);
this._maybeUpdateNumPinnedTabsPref();
}, },
unpinTab(aTab) { unpinTab(aTab) {
@ -623,6 +666,7 @@ window._gBrowser = {
aTab.style.marginInlineStart = ""; aTab.style.marginInlineStart = "";
this._updateTabBarForPinnedTabs(); this._updateTabBarForPinnedTabs();
this._notifyPinnedStatus(aTab); this._notifyPinnedStatus(aTab);
this._maybeUpdateNumPinnedTabsPref();
}, },
previewTab(aTab, aCallback) { previewTab(aTab, aCallback) {
@ -2306,6 +2350,7 @@ window._gBrowser = {
forceNotRemote, forceNotRemote,
fromExternal, fromExternal,
index, index,
isForFirstWindowRestore,
lazyTabTitle, lazyTabTitle,
name, name,
nextTabParentId, nextTabParentId,
@ -2489,6 +2534,9 @@ window._gBrowser = {
if (pinned) { if (pinned) {
this._updateTabBarForPinnedTabs(); this._updateTabBarForPinnedTabs();
if (!isForFirstWindowRestore) {
this._maybeUpdateNumPinnedTabsPref();
}
} }
this.tabContainer._setPositionalAttributes(); this.tabContainer._setPositionalAttributes();
@ -2568,13 +2616,15 @@ window._gBrowser = {
userContextId); userContextId);
b.registeredOpenURI = lazyBrowserURI; b.registeredOpenURI = lazyBrowserURI;
} }
SessionStore.setTabState(t, { if (!isForFirstWindowRestore) {
entries: [{ SessionStore.setTabState(t, {
url: lazyBrowserURI ? lazyBrowserURI.spec : "about:blank", entries: [{
title: lazyTabTitle, url: lazyBrowserURI ? lazyBrowserURI.spec : "about:blank",
triggeringPrincipal_base64: E10SUtils.serializePrincipal(triggeringPrincipal), title: lazyTabTitle,
}], triggeringPrincipal_base64: E10SUtils.serializePrincipal(triggeringPrincipal),
}); }],
});
}
} else { } else {
this._insertBrowser(t, true); this._insertBrowser(t, true);
} }
@ -2612,7 +2662,9 @@ window._gBrowser = {
// If we didn't swap docShells with a preloaded browser // If we didn't swap docShells with a preloaded browser
// then let's just continue loading the page normally. // then let's just continue loading the page normally.
if (!usingPreloadedContent && (!uriIsAboutBlank || !allowInheritPrincipal)) { if (!usingPreloadedContent &&
!createLazyBrowser &&
(!uriIsAboutBlank || !allowInheritPrincipal)) {
// pretend the user typed this so it'll be available till // pretend the user typed this so it'll be available till
// the document successfully loads // the document successfully loads
if (aURI && !gInitialPages.includes(aURI)) { if (aURI && !gInitialPages.includes(aURI)) {
@ -2665,7 +2717,7 @@ window._gBrowser = {
// Additionally send pinned tab events // Additionally send pinned tab events
if (pinned) { if (pinned) {
this._notifyPinnedStatus(t); this._notifyPinnedStatus(t, isForFirstWindowRestore);
} }
return t; return t;
@ -3163,8 +3215,10 @@ window._gBrowser = {
this.tabs[i]._tPos = i; this.tabs[i]._tPos = i;
if (!this._windowIsClosing) { if (!this._windowIsClosing) {
if (wasPinned) if (wasPinned) {
this.tabContainer._positionPinnedTabs(); this.tabContainer._positionPinnedTabs();
this._maybeUpdateNumPinnedTabsPref();
}
// update tab close buttons state // update tab close buttons state
this.tabContainer._updateCloseButtons(); this.tabContainer._updateCloseButtons();
@ -3837,7 +3891,6 @@ window._gBrowser = {
skipAnimation: true, skipAnimation: true,
index: aIndex, index: aIndex,
createLazyBrowser, createLazyBrowser,
allowInheritPrincipal: createLazyBrowser,
}; };
let numPinned = this._numPinnedTabs; let numPinned = this._numPinnedTabs;
@ -5014,6 +5067,7 @@ class TabProgressListener {
this.mTab.removeAttribute("crashed"); this.mTab.removeAttribute("crashed");
} }
this.mTab.removeAttribute("preopened");
if (this._shouldShowProgress(aRequest)) { if (this._shouldShowProgress(aRequest)) {
if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_RESTORING) && if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_RESTORING) &&
aWebProgress && aWebProgress.isTopLevel) { aWebProgress && aWebProgress.isTopLevel) {

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

@ -1937,10 +1937,10 @@
anonid="tab-throbber" anonid="tab-throbber"
class="tab-throbber" class="tab-throbber"
layer="true"/> layer="true"/>
<xul:hbox xbl:inherits="fadein,pinned,busy,progress,selected=visuallyselected,pendingicon" <xul:hbox xbl:inherits="fadein,pinned,busy,progress,selected=visuallyselected,pendingicon,preopened"
anonid="tab-icon-pending" anonid="tab-icon-pending"
class="tab-icon-pending"/> class="tab-icon-pending"/>
<xul:image xbl:inherits="src=image,triggeringprincipal=iconloadingprincipal,requestcontextid,fadein,pinned,selected=visuallyselected,busy,crashed,sharing" <xul:image xbl:inherits="src=image,triggeringprincipal=iconloadingprincipal,requestcontextid,fadein,pinned,selected=visuallyselected,busy,crashed,sharing,preopened"
anonid="tab-icon-image" anonid="tab-icon-image"
class="tab-icon-image" class="tab-icon-image"
validate="never" validate="never"

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

@ -66,7 +66,7 @@ add_task(async function() {
// Click once: // Click once:
document.getAnonymousElementByAttribute(testTab, "anonid", "close-button").click(); document.getAnonymousElementByAttribute(testTab, "anonid", "close-button").click();
}); });
await promiseWaitForCondition(() => !testTab.parentNode); await TestUtils.waitForCondition(() => !testTab.parentNode);
ok(!testTab.parentNode, "Tab should be closed completely"); ok(!testTab.parentNode, "Tab should be closed completely");
}); });

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

@ -27,7 +27,7 @@ skip-if = !e10s
run-if = debug || devedition || nightly_build # Requires startupRecorder.js, which isn't shipped everywhere by default run-if = debug || devedition || nightly_build # Requires startupRecorder.js, which isn't shipped everywhere by default
[browser_tabclose_grow.js] [browser_tabclose_grow.js]
[browser_tabclose.js] [browser_tabclose.js]
skip-if = (os == 'win' && bits == 32) || (os == 'mac') # Bug 1488537, Bug 1531417 skip-if = (os == 'win') || (os == 'mac') # Bug 1488537, Bug 1531417, Bug 1497713
[browser_tabdetach.js] [browser_tabdetach.js]
[browser_tabopen.js] [browser_tabopen.js]
skip-if = (verify && (os == 'mac')) skip-if = (verify && (os == 'mac'))

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

@ -126,6 +126,30 @@ add_task(async function testGloballyBlockedOnNewWindow() {
add_task(async function testBFCache() { add_task(async function testBFCache() {
Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED); Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
await BrowserTestUtils.withNewTab("about:home", async function(browser) {
await BrowserTestUtils.loadURI(browser, AUTOPLAY_PAGE);
await blockedIconShown(browser);
gBrowser.goBack();
await TestUtils.waitForCondition(() => {
return BrowserTestUtils.is_hidden(autoplayBlockedIcon());
});
// Not sure why using `gBrowser.goForward()` doesn't trigger document's
// visibility changes in some debug build on try server, which makes us not
// to receive the blocked event.
await ContentTask.spawn(browser, null, () => {
content.history.forward();
});
await blockedIconShown(browser);
});
Services.perms.removeAll();
});
add_task(async function testChangingBlockingSettingDuringNavigation() {
Services.prefs.setIntPref(AUTOPLAY_PREF, Ci.nsIAutoplay.BLOCKED);
await BrowserTestUtils.withNewTab("about:home", async function(browser) { await BrowserTestUtils.withNewTab("about:home", async function(browser) {
await BrowserTestUtils.loadURI(browser, AUTOPLAY_PAGE); await BrowserTestUtils.loadURI(browser, AUTOPLAY_PAGE);
await blockedIconShown(browser); await blockedIconShown(browser);

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

@ -26,7 +26,7 @@ add_task(async function() {
ok(!isFullscreenSizeMode(), "Should not be in fullscreen sizemode before we enter fullscreen."); ok(!isFullscreenSizeMode(), "Should not be in fullscreen sizemode before we enter fullscreen.");
BrowserFullScreen(); BrowserFullScreen();
await waitForCondition(() => isFullscreenSizeMode()); await TestUtils.waitForCondition(() => isFullscreenSizeMode());
ok(fullscreenButton.checked, "Fullscreen button should be checked when in fullscreen."); ok(fullscreenButton.checked, "Fullscreen button should be checked when in fullscreen.");
await startCustomizing(); await startCustomizing();
@ -41,7 +41,7 @@ add_task(async function() {
BrowserFullScreen(); BrowserFullScreen();
fullscreenButton = document.getElementById("fullscreen-button"); fullscreenButton = document.getElementById("fullscreen-button");
await waitForCondition(() => !isFullscreenSizeMode()); await TestUtils.waitForCondition(() => !isFullscreenSizeMode());
ok(!fullscreenButton.checked, "Fullscreen button should not be checked when not in fullscreen."); ok(!fullscreenButton.checked, "Fullscreen button should not be checked when not in fullscreen.");
CustomizableUI.reset(); CustomizableUI.reset();
}); });

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

@ -249,8 +249,8 @@ var SessionStore = {
return SessionStoreInternal.getWindowState(aWindow); return SessionStoreInternal.getWindowState(aWindow);
}, },
setWindowState: function ss_setWindowState(aWindow, aState, aOverwrite) { setWindowState: function ss_setWindowState(aWindow, aState, aOverwrite, aFirstWindow) {
SessionStoreInternal.setWindowState(aWindow, aState, aOverwrite); SessionStoreInternal.setWindowState(aWindow, aState, aOverwrite, aFirstWindow);
}, },
getTabState: function ss_getTabState(aTab) { getTabState: function ss_getTabState(aTab) {
@ -731,6 +731,7 @@ var SessionStoreInternal = {
this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true); this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
this._restore_on_demand = this._prefBranch.getBoolPref("sessionstore.restore_on_demand"); this._restore_on_demand = this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
this._restore_pinned_tabs_on_demand = this._prefBranch.getBoolPref("sessionstore.restore_pinned_tabs_on_demand");
this._prefBranch.addObserver("sessionstore.restore_on_demand", this, true); this._prefBranch.addObserver("sessionstore.restore_on_demand", this, true);
gResistFingerprintingEnabled = Services.prefs.getBoolPref("privacy.resistFingerprinting"); gResistFingerprintingEnabled = Services.prefs.getBoolPref("privacy.resistFingerprinting");
@ -2499,12 +2500,15 @@ var SessionStoreInternal = {
throw Components.Exception("Window is not tracked", Cr.NS_ERROR_INVALID_ARG); throw Components.Exception("Window is not tracked", Cr.NS_ERROR_INVALID_ARG);
}, },
setWindowState: function ssi_setWindowState(aWindow, aState, aOverwrite) { setWindowState: function ssi_setWindowState(aWindow, aState, aOverwrite, aFirstWindow) {
if (!aWindow.__SSi) { if (!aWindow.__SSi) {
throw Components.Exception("Window is not tracked", Cr.NS_ERROR_INVALID_ARG); throw Components.Exception("Window is not tracked", Cr.NS_ERROR_INVALID_ARG);
} }
this.restoreWindows(aWindow, aState, {overwriteTabs: aOverwrite}); this.restoreWindows(aWindow, aState, {
overwriteTabs: aOverwrite,
firstWindow: aFirstWindow,
});
// Notify of changes to closed objects. // Notify of changes to closed objects.
this._notifyOfClosedObjectsChange(); this._notifyOfClosedObjectsChange();
@ -3203,6 +3207,7 @@ var SessionStoreInternal = {
if (!uriObj || (uriObj && !window.gBrowser.isLocalAboutURI(uriObj))) { if (!uriObj || (uriObj && !window.gBrowser.isLocalAboutURI(uriObj))) {
tab.setAttribute("busy", "true"); tab.setAttribute("busy", "true");
} }
tab.removeAttribute("preopened");
// Hack to ensure that the about:home, about:newtab, and about:welcome // Hack to ensure that the about:home, about:newtab, and about:welcome
// favicon is loaded instantaneously, to avoid flickering and improve // favicon is loaded instantaneously, to avoid flickering and improve
@ -3595,6 +3600,36 @@ var SessionStoreInternal = {
return Promise.all([...WINDOW_SHOWING_PROMISES.values()].map(deferred => deferred.promise)); return Promise.all([...WINDOW_SHOWING_PROMISES.values()].map(deferred => deferred.promise));
}, },
/**
* Handles the pinning / unpinning of a selected tab restored with
* restoreWindow.
*
* @param aWindow
* Window reference to the window used for restoration
* @param aWinData
* The window data we're restoring
* @param aRestoreIndex
* The index of the tab data we're currently restoring
* @returns the selected tab
*/
_updateRestoredSelectedTabPinnedState(aWindow, aWinData, aRestoreIndex) {
let tabbrowser = aWindow.gBrowser;
let tabData = aWinData.tabs[aRestoreIndex];
let tab = tabbrowser.selectedTab;
let needsUnpin = tab.pinned && !tabData.pinned;
let needsPin = !tab.pinned && tabData.pinned;
if (needsUnpin) {
tabbrowser.unpinTab(tab);
} else if (needsPin && tab == tabbrowser.tabs[aRestoreIndex]) {
tabbrowser.pinTab(tab);
} else if (needsPin) {
tabbrowser.removeTab(tabbrowser.tabs[aRestoreIndex]);
tabbrowser.pinTab(tab);
tabbrowser.moveTabTo(tab, aRestoreIndex);
}
return tab;
},
/** /**
* restore features to a single window * restore features to a single window
* @param aWindow * @param aWindow
@ -3650,7 +3685,7 @@ var SessionStoreInternal = {
// We need to keep track of the initially open tabs so that they // We need to keep track of the initially open tabs so that they
// can be moved to the end of the restored tabs. // can be moved to the end of the restored tabs.
let initialTabs; let initialTabs = [];
if (!overwriteTabs && firstWindow) { if (!overwriteTabs && firstWindow) {
initialTabs = Array.slice(tabbrowser.tabs); initialTabs = Array.slice(tabbrowser.tabs);
} }
@ -3658,8 +3693,11 @@ var SessionStoreInternal = {
// Get rid of tabs that aren't needed anymore. // Get rid of tabs that aren't needed anymore.
if (overwriteTabs) { if (overwriteTabs) {
for (let i = tabbrowser.browsers.length - 1; i >= 0; i--) { for (let i = tabbrowser.browsers.length - 1; i >= 0; i--) {
if (!tabbrowser.tabs[i].selected) { if (!tabbrowser.tabs[i].selected &&
!tabbrowser.tabs[i].hasAttribute("preopened")) {
tabbrowser.removeTab(tabbrowser.tabs[i]); tabbrowser.removeTab(tabbrowser.tabs[i]);
} else if (tabbrowser.tabs[i].hasAttribute("preopened")) {
initialTabs.push(tabbrowser.tabs[i]);
} }
} }
} }
@ -3677,14 +3715,18 @@ var SessionStoreInternal = {
// selecting a new tab. // selecting a new tab.
if (select && if (select &&
tabbrowser.selectedTab.userContextId == userContextId) { tabbrowser.selectedTab.userContextId == userContextId) {
tab = tabbrowser.selectedTab; tab = this._updateRestoredSelectedTabPinnedState(aWindow, winData, t);
if (!tabData.pinned) {
tabbrowser.unpinTab(tab);
}
tabbrowser.moveTabToEnd(); tabbrowser.moveTabToEnd();
if (aWindow.gMultiProcessBrowser && !tab.linkedBrowser.isRemoteBrowser) { if (aWindow.gMultiProcessBrowser && !tab.linkedBrowser.isRemoteBrowser) {
tabbrowser.updateBrowserRemoteness(tab.linkedBrowser, true); tabbrowser.updateBrowserRemoteness(tab.linkedBrowser, true);
} }
} else if (tabData.pinned &&
tabbrowser.tabs[t] &&
tabbrowser.tabs[t].pinned &&
!tabbrowser.tabs[t].linkedPanel) {
tab = tabbrowser.tabs[t];
tabbrowser.activatePreopenedPinnedTab(tab);
} }
// Add a new tab if needed. // Add a new tab if needed.
@ -3733,11 +3775,14 @@ var SessionStoreInternal = {
} }
// Move the originally open tabs to the end. // Move the originally open tabs to the end.
if (initialTabs) { let endPosition = tabbrowser.tabs.length - 1;
let endPosition = tabbrowser.tabs.length - 1; for (let tab of initialTabs) {
for (let i = 0; i < initialTabs.length; i++) { if (tab.hasAttribute("preopened") &&
tabbrowser.unpinTab(initialTabs[i]); !tab.linkedPanel) {
tabbrowser.moveTabTo(initialTabs[i], endPosition); tabbrowser.removeTab(tab);
} else if (!tab.hasAttribute("preopened")) {
tabbrowser.unpinTab(tab);
tabbrowser.moveTabTo(tab, endPosition);
} }
} }
@ -3998,6 +4043,9 @@ var SessionStoreInternal = {
for (let t = 0; t < aTabs.length; t++) { for (let t = 0; t < aTabs.length; t++) {
if (t != selectedIndex) { if (t != selectedIndex) {
this.restoreTab(aTabs[t], aTabData[t]); this.restoreTab(aTabs[t], aTabData[t]);
if (this._restore_pinned_tabs_on_demand) {
aTabs[t].removeAttribute("preopened");
}
} }
} }
}, },

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

@ -113,6 +113,7 @@ skip-if = (verify && (os == 'win' || os == 'mac'))
[browser_old_favicon.js] [browser_old_favicon.js]
[browser_page_title.js] [browser_page_title.js]
[browser_pending_tabs.js] [browser_pending_tabs.js]
[browser_preopened_apptabs.js]
[browser_privatetabs.js] [browser_privatetabs.js]
[browser_purge_shistory.js] [browser_purge_shistory.js]
skip-if = e10s # Bug 1271024 skip-if = e10s # Bug 1271024

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

@ -0,0 +1,65 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand";
const PREF_NUM_PINNED_TABS = "browser.tabs.firstWindowRestore.numPinnedTabs";
function muffleMainWindowType() {
let oldWinType = document.documentElement.getAttribute("windowtype");
// Check if we've already done this to allow calling multiple times:
if (oldWinType != "navigator:testrunner") {
// Make the main test window not count as a browser window any longer
document.documentElement.setAttribute("windowtype", "navigator:testrunner");
registerCleanupFunction(() => {
document.documentElement.setAttribute("windowtype", oldWinType);
});
}
}
registerCleanupFunction(function() {
Services.prefs.clearUserPref(PREF_NUM_PINNED_TABS);
});
let testCases = [
{numPinnedPref: 5, selected: 3, overrideTabs: false},
{numPinnedPref: 5, selected: 3, overrideTabs: true},
{numPinnedPref: 5, selected: 1, overrideTabs: false},
{numPinnedPref: 5, selected: 1, overrideTabs: true},
{numPinnedPref: 3, selected: 3, overrideTabs: false},
{numPinnedPref: 3, selected: 3, overrideTabs: true},
{numPinnedPref: 3, selected: 1, overrideTabs: false},
{numPinnedPref: 3, selected: 1, overrideTabs: true},
{numPinnedPref: 1, selected: 3, overrideTabs: false},
{numPinnedPref: 1, selected: 3, overrideTabs: true},
{numPinnedPref: 1, selected: 1, overrideTabs: false},
{numPinnedPref: 1, selected: 1, overrideTabs: true},
{numPinnedPref: 0, selected: 3, overrideTabs: false},
{numPinnedPref: 0, selected: 3, overrideTabs: true},
{numPinnedPref: 0, selected: 1, overrideTabs: false},
{numPinnedPref: 0, selected: 1, overrideTabs: true},
];
for (let {numPinnedPref, selected, overrideTabs} of testCases) {
add_task(async function testPrefSynced() {
Services.prefs.setIntPref(PREF_NUM_PINNED_TABS, numPinnedPref);
let state = { windows: [{ tabs: [
{ entries: [{ url: "http://example.org/#1", triggeringPrincipal_base64 }], pinned: true, userContextId: 0 },
{ entries: [{ url: "http://example.org/#2", triggeringPrincipal_base64 }], pinned: true, userContextId: 0 },
{ entries: [{ url: "http://example.org/#3", triggeringPrincipal_base64 }], pinned: true, userContextId: 0 },
], selected }] };
muffleMainWindowType();
let win = await BrowserTestUtils.openNewBrowserWindow();
Assert.equal([...win.gBrowser.tabs].filter(t => t.pinned).length, numPinnedPref);
Assert.equal([...win.gBrowser.tabs].filter(t => !!t.linkedPanel).length, 1);
await setWindowState(win, state, overrideTabs, true);
Assert.equal([...win.gBrowser.tabs].filter(t => t.pinned).length, 3);
Assert.equal([...win.gBrowser.tabs].filter(t => !!t.linkedPanel).length,
overrideTabs ? 3 : 4);
await BrowserTestUtils.closeWindow(win);
});
}

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

@ -190,8 +190,9 @@ async function setBrowserState(state, win = window) {
await promiseWindowRestored(win); await promiseWindowRestored(win);
} }
async function setWindowState(win, state, overwrite = false) { async function setWindowState(win, state, overwrite = false, firstWindow = false) {
ss.setWindowState(win, typeof state != "string" ? JSON.stringify(state) : state, overwrite); ss.setWindowState(win, typeof state != "string" ? JSON.stringify(state) : state,
overwrite, firstWindow);
await promiseWindowRestored(win); await promiseWindowRestored(win);
} }

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

@ -96,6 +96,11 @@ function _untrackWindowOrder(window) {
_trackedWindows.splice(idx, 1); _trackedWindows.splice(idx, 1);
} }
function _trackPinnedTabs(window) {
Services.prefs.setIntPref("browser.tabs.firstWindowRestore.numPinnedTabs",
window.gBrowser._numPinnedTabs);
}
// Methods that impact a window. Put into single object for organization. // Methods that impact a window. Put into single object for organization.
var WindowHelper = { var WindowHelper = {
addWindow(window) { addWindow(window) {
@ -138,6 +143,7 @@ var WindowHelper = {
_untrackWindowOrder(window); _untrackWindowOrder(window);
_trackWindowOrder(window); _trackWindowOrder(window);
_trackPinnedTabs(window);
_updateCurrentContentOuterWindowID(window.gBrowser.selectedBrowser); _updateCurrentContentOuterWindowID(window.gBrowser.selectedBrowser);
}, },

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

@ -185,6 +185,8 @@
list-style-image: url("chrome://browser/skin/send-to-device.svg"); list-style-image: url("chrome://browser/skin/send-to-device.svg");
} }
#pageAction-panel-pinTab:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#pageAction-urlbar-pinTab:-moz-locale-dir(rtl),
#pageAction-panel-sendToDevice:-moz-locale-dir(rtl) > .toolbarbutton-icon, #pageAction-panel-sendToDevice:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#pageAction-urlbar-sendToDevice:-moz-locale-dir(rtl) { #pageAction-urlbar-sendToDevice:-moz-locale-dir(rtl) {
transform: scaleX(-1); transform: scaleX(-1);

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

@ -13,7 +13,7 @@ const { bootstrap, L10N } = require("devtools-launchpad");
window.L10N = L10N; window.L10N = L10N;
// $FlowIgnore: // $FlowIgnore:
window.L10N.setBundle(require("../assets/panel/debugger.properties")); window.L10N.setBundle(require("../../../locales/en-US/debugger.properties"));
bootstrap(React, ReactDOM).then(connection => { bootstrap(React, ReactDOM).then(connection => {
onConnect(connection, require("devtools-source-map"), { onConnect(connection, require("devtools-source-map"), {

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

@ -3193,8 +3193,8 @@ Toolbox.prototype = {
* Opens source in style editor. Falls back to plain "view-source:". * Opens source in style editor. Falls back to plain "view-source:".
* @see devtools/client/shared/source-utils.js * @see devtools/client/shared/source-utils.js
*/ */
viewSourceInStyleEditor: function(sourceURL, sourceLine) { viewSourceInStyleEditor: function(sourceURL, sourceLine, sourceColumn) {
return viewSource.viewSourceInStyleEditor(this, sourceURL, sourceLine); return viewSource.viewSourceInStyleEditor(this, sourceURL, sourceLine, sourceColumn);
}, },
/** /**

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

@ -95,6 +95,7 @@ class DominatorTreeSiblingLinkClass extends Component {
}, },
dom.a( dom.a(
{ {
className: "load-more-link",
onClick: () => onLoadMoreSiblings(item), onClick: () => onLoadMoreSiblings(item),
}, },
L10N.getStr("tree-item.load-more") L10N.getStr("tree-item.load-more")

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

@ -21,11 +21,11 @@ var { gDevTools } = require("devtools/client/framework/devtools");
* @return {Promise<boolean>} * @return {Promise<boolean>}
*/ */
exports.viewSourceInStyleEditor = async function(toolbox, sourceURL, exports.viewSourceInStyleEditor = async function(toolbox, sourceURL,
sourceLine) { sourceLine, sourceColumn) {
const panel = await toolbox.loadTool("styleeditor"); const panel = await toolbox.loadTool("styleeditor");
try { try {
await panel.selectStyleSheet(sourceURL, sourceLine); await panel.selectStyleSheet(sourceURL, sourceLine, sourceColumn);
await toolbox.selectTool("styleeditor"); await toolbox.selectTool("styleeditor");
return true; return true;
} catch (e) { } catch (e) {

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

@ -1,252 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const ENSURE_SELECTION_VISIBLE_DELAY = 50; // ms
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
const { ViewHelpers, setNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
const EventEmitter = require("devtools/shared/event-emitter");
this.EXPORTED_SYMBOLS = ["BreadcrumbsWidget"];
/**
* A breadcrumb-like list of items.
*
* Note: this widget should be used in tandem with the WidgetMethods in
* view-helpers.js.
*
* @param Node aNode
* The element associated with the widget.
* @param Object aOptions
* - smoothScroll: specifies if smooth scrolling on selection is enabled.
*/
this.BreadcrumbsWidget = function BreadcrumbsWidget(aNode, aOptions = {}) {
this.document = aNode.ownerDocument;
this.window = this.document.defaultView;
this._parent = aNode;
// Create an internal arrowscrollbox container.
this._list = this.document.createElement("arrowscrollbox");
this._list.className = "breadcrumbs-widget-container";
this._list.setAttribute("flex", "1");
this._list.setAttribute("orient", "horizontal");
this._list.setAttribute("clicktoscroll", "true");
this._list.setAttribute("smoothscroll", !!aOptions.smoothScroll);
this._list.addEventListener("keydown", e => this.emit("keyDown", e));
this._list.addEventListener("mousedown", e => this.emit("mousePress", e));
this._parent.appendChild(this._list);
// By default, hide the arrows. We let the arrowscrollbox show them
// in case of overflow.
this._list._scrollButtonUp.collapsed = true;
this._list._scrollButtonDown.collapsed = true;
this._list.addEventListener("underflow", this._onUnderflow.bind(this));
this._list.addEventListener("overflow", this._onOverflow.bind(this));
// This widget emits events that can be handled in a MenuContainer.
EventEmitter.decorate(this);
// Delegate some of the associated node's methods to satisfy the interface
// required by MenuContainer instances.
ViewHelpers.delegateWidgetAttributeMethods(this, aNode);
ViewHelpers.delegateWidgetEventMethods(this, aNode);
};
BreadcrumbsWidget.prototype = {
/**
* Inserts an item in this container at the specified index.
*
* @param number aIndex
* The position in the container intended for this item.
* @param Node aContents
* The node displayed in the container.
* @return Node
* The element associated with the displayed item.
*/
insertItemAt: function(aIndex, aContents) {
const list = this._list;
const breadcrumb = new Breadcrumb(this, aContents);
return list.insertBefore(breadcrumb._target, list.childNodes[aIndex]);
},
/**
* Returns the child node in this container situated at the specified index.
*
* @param number aIndex
* The position in the container intended for this item.
* @return Node
* The element associated with the displayed item.
*/
getItemAtIndex: function(aIndex) {
return this._list.childNodes[aIndex];
},
/**
* Removes the specified child node from this container.
*
* @param Node aChild
* The element associated with the displayed item.
*/
removeChild: function(aChild) {
this._list.removeChild(aChild);
if (this._selectedItem == aChild) {
this._selectedItem = null;
}
},
/**
* Removes all of the child nodes from this container.
*/
removeAllItems: function() {
const list = this._list;
while (list.hasChildNodes()) {
list.firstChild.remove();
}
this._selectedItem = null;
},
/**
* Gets the currently selected child node in this container.
* @return Node
*/
get selectedItem() {
return this._selectedItem;
},
/**
* Sets the currently selected child node in this container.
* @param Node aChild
*/
set selectedItem(aChild) {
const childNodes = this._list.childNodes;
if (!aChild) {
this._selectedItem = null;
}
for (const node of childNodes) {
if (node == aChild) {
node.setAttribute("checked", "");
this._selectedItem = node;
} else {
node.removeAttribute("checked");
}
}
},
/**
* Returns the value of the named attribute on this container.
*
* @param string aName
* The name of the attribute.
* @return string
* The current attribute value.
*/
getAttribute: function(aName) {
if (aName == "scrollPosition") {
return this._list.scrollPosition;
}
if (aName == "scrollWidth") {
return this._list.scrollWidth;
}
return this._parent.getAttribute(aName);
},
/**
* Ensures the specified element is visible.
*
* @param Node aElement
* The element to make visible.
*/
ensureElementIsVisible: function(aElement) {
if (!aElement) {
return;
}
// Repeated calls to ensureElementIsVisible would interfere with each other
// and may sometimes result in incorrect scroll positions.
setNamedTimeout("breadcrumb-select", ENSURE_SELECTION_VISIBLE_DELAY, () => {
if (this._list.ensureElementIsVisible) {
this._list.ensureElementIsVisible(aElement);
}
});
},
/**
* The underflow and overflow listener for the arrowscrollbox container.
*/
_onUnderflow: function({ target }) {
if (target != this._list) {
return;
}
target._scrollButtonUp.collapsed = true;
target._scrollButtonDown.collapsed = true;
target.removeAttribute("overflows");
},
/**
* The underflow and overflow listener for the arrowscrollbox container.
*/
_onOverflow: function({ target }) {
if (target != this._list) {
return;
}
target._scrollButtonUp.collapsed = false;
target._scrollButtonDown.collapsed = false;
target.setAttribute("overflows", "");
},
window: null,
document: null,
_parent: null,
_list: null,
_selectedItem: null,
};
/**
* A Breadcrumb constructor for the BreadcrumbsWidget.
*
* @param BreadcrumbsWidget aWidget
* The widget to contain this breadcrumb.
* @param Node aContents
* The node displayed in the container.
*/
function Breadcrumb(aWidget, aContents) {
this.document = aWidget.document;
this.window = aWidget.window;
this.ownerView = aWidget;
this._target = this.document.createElement("hbox");
this._target.className = "breadcrumbs-widget-item";
this._target.setAttribute("align", "center");
this.contents = aContents;
}
Breadcrumb.prototype = {
/**
* Sets the contents displayed in this item's view.
*
* @param string | Node aContents
* The string or node displayed in the container.
*/
set contents(aContents) {
// If there are already some contents displayed, replace them.
if (this._target.hasChildNodes()) {
this._target.replaceChild(aContents, this._target.firstChild);
return;
}
// These are the first contents ever displayed.
this._target.appendChild(aContents);
},
window: null,
document: null,
ownerView: null,
_target: null,
};

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

@ -1,247 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const EventEmitter = require("devtools/shared/event-emitter");
const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers");
/**
* A list menu widget that attempts to be very fast.
*
* Note: this widget should be used in tandem with the WidgetMethods in
* view-helpers.js.
*
* @param Node aNode
* The element associated with the widget.
*/
const FastListWidget = module.exports = function FastListWidget(node) {
this.document = node.ownerDocument;
this.window = this.document.defaultView;
this._parent = node;
this._fragment = this.document.createDocumentFragment();
// This is a prototype element that each item added to the list clones.
this._templateElement = this.document.createElement("hbox");
// Create an internal scrollbox container.
this._list = this.document.createElement("scrollbox");
this._list.className = "fast-list-widget-container theme-body";
this._list.setAttribute("flex", "1");
this._list.setAttribute("orient", "vertical");
this._list.setAttribute("tabindex", "0");
this._list.addEventListener("keydown", e => this.emit("keyDown", e));
this._list.addEventListener("mousedown", e => this.emit("mousePress", e));
this._parent.appendChild(this._list);
this._orderedMenuElementsArray = [];
this._itemsByElement = new Map();
// This widget emits events that can be handled in a MenuContainer.
EventEmitter.decorate(this);
// Delegate some of the associated node's methods to satisfy the interface
// required by MenuContainer instances.
ViewHelpers.delegateWidgetAttributeMethods(this, node);
ViewHelpers.delegateWidgetEventMethods(this, node);
};
FastListWidget.prototype = {
/**
* Inserts an item in this container at the specified index, optionally
* grouping by name.
*
* @param number aIndex
* The position in the container intended for this item.
* @param Node aContents
* The node to be displayed in the container.
* @param Object aAttachment [optional]
* Extra data for the user.
* @return Node
* The element associated with the displayed item.
*/
insertItemAt: function(index, contents, attachment = {}) {
const element = this._templateElement.cloneNode();
element.appendChild(contents);
if (index >= 0) {
throw new Error("FastListWidget only supports appending items.");
}
this._fragment.appendChild(element);
this._orderedMenuElementsArray.push(element);
this._itemsByElement.set(element, this);
return element;
},
/**
* This is a non-standard widget implementation method. When appending items,
* they are queued in a document fragment. This method appends the document
* fragment to the dom.
*/
flush: function() {
this._list.appendChild(this._fragment);
},
/**
* Removes all of the child nodes from this container.
*/
removeAllItems: function() {
const list = this._list;
while (list.hasChildNodes()) {
list.firstChild.remove();
}
this._selectedItem = null;
this._orderedMenuElementsArray.length = 0;
this._itemsByElement.clear();
},
/**
* Remove the given item.
*/
removeChild: function(child) {
throw new Error("Not yet implemented");
},
/**
* Gets the currently selected child node in this container.
* @return Node
*/
get selectedItem() {
return this._selectedItem;
},
/**
* Sets the currently selected child node in this container.
* @param Node child
*/
set selectedItem(child) {
const menuArray = this._orderedMenuElementsArray;
if (!child) {
this._selectedItem = null;
}
for (const node of menuArray) {
if (node == child) {
node.classList.add("selected");
this._selectedItem = node;
} else {
node.classList.remove("selected");
}
}
this.ensureElementIsVisible(this.selectedItem);
},
/**
* Returns the child node in this container situated at the specified index.
*
* @param number index
* The position in the container intended for this item.
* @return Node
* The element associated with the displayed item.
*/
getItemAtIndex: function(index) {
return this._orderedMenuElementsArray[index];
},
/**
* Adds a new attribute or changes an existing attribute on this container.
*
* @param string name
* The name of the attribute.
* @param string value
* The desired attribute value.
*/
setAttribute: function(name, value) {
this._parent.setAttribute(name, value);
if (name == "emptyText") {
this._textWhenEmpty = value;
}
},
/**
* Removes an attribute on this container.
*
* @param string name
* The name of the attribute.
*/
removeAttribute: function(name) {
this._parent.removeAttribute(name);
if (name == "emptyText") {
this._removeEmptyText();
}
},
/**
* Ensures the specified element is visible.
*
* @param Node element
* The element to make visible.
*/
ensureElementIsVisible: function(element) {
if (!element) {
return;
}
// Ensure the element is visible but not scrolled horizontally.
element.scrollIntoView({ block: "nearest" });
this._list.scrollBy(-this._list.clientWidth, 0);
},
/**
* Sets the text displayed in this container when empty.
* @param string aValue
*/
set _textWhenEmpty(value) {
if (this._emptyTextNode) {
this._emptyTextNode.setAttribute("value", value);
}
this._emptyTextValue = value;
this._showEmptyText();
},
/**
* Creates and appends a label signaling that this container is empty.
*/
_showEmptyText: function() {
if (this._emptyTextNode || !this._emptyTextValue) {
return;
}
const label = this.document.createElement("label");
label.className = "plain fast-list-widget-empty-text";
label.setAttribute("value", this._emptyTextValue);
this._parent.insertBefore(label, this._list);
this._emptyTextNode = label;
},
/**
* Removes the label signaling that this container is empty.
*/
_removeEmptyText: function() {
if (!this._emptyTextNode) {
return;
}
this._parent.removeChild(this._emptyTextNode);
this._emptyTextNode = null;
},
window: null,
document: null,
_parent: null,
_list: null,
_selectedItem: null,
_orderedMenuElementsArray: null,
_itemsByElement: null,
_emptyTextNode: null,
_emptyTextValue: "",
};

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

@ -11,11 +11,9 @@ DIRS += [
DevToolsModules( DevToolsModules(
'AbstractTreeItem.jsm', 'AbstractTreeItem.jsm',
'BarGraphWidget.js', 'BarGraphWidget.js',
'BreadcrumbsWidget.jsm',
'Chart.js', 'Chart.js',
'CubicBezierPresets.js', 'CubicBezierPresets.js',
'CubicBezierWidget.js', 'CubicBezierWidget.js',
'FastListWidget.js',
'FilterWidget.js', 'FilterWidget.js',
'FlameGraph.js', 'FlameGraph.js',
'Graphs.js', 'Graphs.js',

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

@ -13,12 +13,6 @@
-moz-user-focus: normal; -moz-user-focus: normal;
} }
/* FastListWidget */
.fast-list-widget-container {
overflow: auto;
}
/* SideMenuWidget */ /* SideMenuWidget */
.side-menu-widget-container { .side-menu-widget-container {

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

@ -9,6 +9,8 @@
--focus-cell-border-color: rgba(255,255,255,0.5); --focus-cell-border-color: rgba(255,255,255,0.5);
--row-alt-background-color: rgba(86, 117, 185, 0.15); --row-alt-background-color: rgba(86, 117, 185, 0.15);
--row-hover-background-color: rgba(86, 117, 185, 0.25); --row-hover-background-color: rgba(86, 117, 185, 0.25);
--link-color: var(--blue-40);
--link-color-active: var(--blue-30);
} }
.theme-light { .theme-light {
@ -17,6 +19,8 @@
--focus-cell-border-color: rgba(0,0,0,0.3); --focus-cell-border-color: rgba(0,0,0,0.3);
--row-alt-background-color: rgba(76,158,217,0.1); --row-alt-background-color: rgba(76,158,217,0.1);
--row-hover-background-color: rgba(76,158,217,0.2); --row-hover-background-color: rgba(76,158,217,0.2);
--link-color: var(--blue-60);
--link-color-active: var(--blue-70);
} }
html, body, #app, #memory-tool { html, body, #app, #memory-tool {
@ -278,7 +282,7 @@ html, body, #app, #memory-tool {
/** /**
* Flex: contains a .heap-view-panel which needs to fill out all the * Flex: contains a .heap-view-panel which needs to fill out all the
* available space, horizontally and vertically. * available space, horizontally and vertically.
*/; */
display: flex; display: flex;
/** /**
* Flexing to fill out remaining horizontal space. The preceeding sibling * Flexing to fill out remaining horizontal space. The preceeding sibling
@ -550,6 +554,19 @@ html, body, #app, #memory-tool {
overflow: hidden; overflow: hidden;
} }
.load-more-link {
cursor: pointer;
color: var(--link-color);
}
.load-more-link:hover {
text-decoration: underline;
}
.load-more-link:active {
color: var(--link-color-active);
}
/** /**
* Heap tree errors. * Heap tree errors.
*/ */

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

@ -963,12 +963,18 @@ body {
height: 10px; height: 10px;
background: url("chrome://devtools/skin/images/arrow.svg") no-repeat center; background: url("chrome://devtools/skin/images/arrow.svg") no-repeat center;
background-size: 10px; background-size: 10px;
transform: rotate(-90deg);
/* Needed for alignment */ /* Needed for alignment */
margin-top: -1px; margin-top: -1px;
-moz-context-properties: fill; -moz-context-properties: fill;
fill: var(--theme-icon-dimmed-color); fill: var(--theme-icon-dimmed-color);
} }
.webconsole-app .tree .arrow.expanded,
.webconsole-app .object-inspector .tree-node .arrow.expanded {
transform: rotate(0deg);
}
/* Sidebar */ /* Sidebar */
.sidebar { .sidebar {
display: flex; display: flex;

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

@ -101,21 +101,6 @@
} }
} }
/* FastListWidget */
.fast-list-widget-container {
/* Hack: force hardware acceleration */
transform: translateZ(1px);
}
.fast-list-widget-empty-text {
padding: 4px 8px;
}
.fast-list-widget-empty-text {
color: var(--theme-body-color-alt);
}
/* SideMenuWidget */ /* SideMenuWidget */
.side-menu-widget-container { .side-menu-widget-container {

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

@ -82,6 +82,21 @@ async function performTests() {
is(getL10NContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"), is(getL10NContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"),
"The context menu has the correct edit menu items"); "The context menu has the correct edit menu items");
const node = hud.jsterm.inputNode || hud.jsterm.node;
const inputContainer = node.closest(".jsterm-input-container");
await openContextMenu(hud, inputContainer);
expectedContextMenu = [
"#editmenu-undo (editmenu-undo) [disabled]",
"#editmenu-cut (editmenu-cut)",
"#editmenu-copy (editmenu-copy)",
"#editmenu-paste (editmenu-paste)",
"#editmenu-delete (editmenu-delete) [disabled]",
"#editmenu-selectAll (editmenu-select-all) [disabled]",
];
is(getL10NContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"),
"The context menu has the required elements");
await hideContextMenu(hud); await hideContextMenu(hud);
// Close the browser console. // Close the browser console.
await HUDService.toggleBrowserConsole(); await HUDService.toggleBrowserConsole();

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

@ -23,18 +23,29 @@ add_task(async function() {
info("Test Copy URL menu item for text log"); info("Test Copy URL menu item for text log");
info("Logging a text message in the content window"); info("Logging a text message in the content window");
const onLogMessage = waitForMessage(hud, "simple text message"); const onLogMessage = waitForMessage(hud, "stringLog");
await ContentTask.spawn(gBrowser.selectedBrowser, null, () => { await ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
content.wrappedJSObject.console.log("simple text message"); content.wrappedJSObject.stringLog();
}); });
let message = await onLogMessage; let message = await onLogMessage;
ok(message, "Text log found in the console"); ok(message, "Text log found in the console");
info("Open and check the context menu for the logged text message"); info("Open and check the context menu for the logged text message");
let menuPopup = await openContextMenu(hud, message.node); let menuPopup = await openContextMenu(hud, message.node);
let copyURLItem = menuPopup.querySelector(CONTEXT_MENU_ID); let copyURLItem = menuPopup.querySelector(CONTEXT_MENU_ID);
ok(!copyURLItem, "Copy URL menu item is hidden for a simple text message"); ok(!copyURLItem, "Copy URL menu item is hidden for a simple text message");
info("Open and check the context menu for the logged text message");
const locationElement = message.node.querySelector(".frame-link-source-inner");
menuPopup = await openContextMenu(hud, locationElement);
copyURLItem = menuPopup.querySelector(CONTEXT_MENU_ID);
ok(copyURLItem, "The Copy Link Location entry is displayed");
info("Click on Copy URL menu item and wait for clipboard to be updated");
await waitForClipboardPromise(() => copyURLItem.click(), TEST_URI);
ok(true, "Expected text was copied to the clipboard.");
await hideContextMenu(hud); await hideContextMenu(hud);
hud.ui.clearOutput(); hud.ui.clearOutput();

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

@ -41,11 +41,12 @@ async function testViewSource(hud, toolbox, text) {
info("style editor window focused"); info("style editor window focused");
const href = frameLinkNode.getAttribute("data-url"); const href = frameLinkNode.getAttribute("data-url");
const line = frameLinkNode.getAttribute("data-line"); const line = frameLinkNode.getAttribute("data-line");
const column = frameLinkNode.getAttribute("data-column");
ok(line, "found source line"); ok(line, "found source line");
const editor = getEditorForHref(panel.UI, href); const editor = getEditorForHref(panel.UI, href);
ok(editor, "found style editor for " + href); ok(editor, "found style editor for " + href);
await performLineCheck(panel.UI, editor, line - 1); await checkCursorPosition(panel.UI, editor, line - 1, column - 1);
} }
async function onStyleEditorReady(panel) { async function onStyleEditorReady(panel) {
@ -72,13 +73,15 @@ function getEditorForHref(styleEditorUI, href) {
return foundEditor; return foundEditor;
} }
async function performLineCheck(styleEditorUI, editor, line) { async function checkCursorPosition(styleEditorUI, editor, line, column) {
info("wait for source editor to load"); info("wait for source editor to load");
// Get out of the styleeditor-selected event loop. // Get out of the styleeditor-selected event loop.
await waitForTick(); await waitForTick();
is(editor.sourceEditor.getCursor().line, line, is(editor.sourceEditor.getCursor().line, line,
"correct line is selected"); "correct line is selected");
is(editor.sourceEditor.getCursor().ch, column,
"correct column is selected");
is(styleEditorUI.selectedStyleSheetIndex, editor.styleSheet.styleSheetIndex, is(styleEditorUI.selectedStyleSheetIndex, editor.styleSheet.styleSheetIndex,
"correct stylesheet is selected in the editor"); "correct stylesheet is selected in the editor");
} }

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

@ -48,6 +48,7 @@ function createContextMenu(webConsoleUI, parentNode, {
rootActorId, rootActorId,
executionPoint, executionPoint,
toolbox, toolbox,
url,
}) { }) {
const win = parentNode.ownerDocument.defaultView; const win = parentNode.ownerDocument.defaultView;
const selection = win.getSelection(); const selection = win.getSelection();
@ -207,6 +208,15 @@ function createContextMenu(webConsoleUI, parentNode, {
})); }));
} }
if (url) {
menu.append(new MenuItem({
id: "console-menu-copy-url",
label: l10n.getStr("webconsole.menu.copyURL.label"),
accesskey: l10n.getStr("webconsole.menu.copyURL.accesskey"),
click: () => clipboardHelper.copyString(url),
}));
}
return menu; return menu;
} }

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

@ -198,6 +198,9 @@ class WebConsoleWrapper {
const messageEl = target.closest(".message"); const messageEl = target.closest(".message");
const clipboardText = getElementText(messageEl); const clipboardText = getElementText(messageEl);
const linkEl = target.closest("a[href]");
const url = linkEl && linkEl.href;
const messageVariable = target.closest(".objectBox"); const messageVariable = target.closest(".objectBox");
// Ensure that console.group and console.groupCollapsed commands are not captured // Ensure that console.group and console.groupCollapsed commands are not captured
const variableText = (messageVariable const variableText = (messageVariable
@ -233,6 +236,7 @@ class WebConsoleWrapper {
rootActorId, rootActorId,
executionPoint, executionPoint,
toolbox: this.toolbox, toolbox: this.toolbox,
url,
}); });
// Emit the "menu-open" event for testing. // Emit the "menu-open" event for testing.
@ -279,7 +283,8 @@ class WebConsoleWrapper {
}), }),
onViewSourceInStyleEditor: frame => this.toolbox.viewSourceInStyleEditor( onViewSourceInStyleEditor: frame => this.toolbox.viewSourceInStyleEditor(
frame.url, frame.url,
frame.line frame.line,
frame.column
).then(() => { ).then(() => {
this.telemetry.recordEvent("jump_to_source", "webconsole", this.telemetry.recordEvent("jump_to_source", "webconsole",
null, { "session_id": this.toolbox.sessionId } null, { "session_id": this.toolbox.sessionId }

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

@ -692,27 +692,6 @@ exports.AnimationsActor = protocol.ActorClassWithSpec(animationsSpec, {
} }
}, },
/**
* Iterates through all nodes below a given rootNode (optionally also in
* nested frames) and finds all existing animation players.
* @param {DOMNode} rootNode The root node to start iterating at. Animation
* players will *not* be reported for this node.
* @param {Boolean} traverseFrames Whether we should iterate through nested
* frames too.
* @return {Array} An array of AnimationPlayer objects.
*/
getAllAnimations: function(rootNode, traverseFrames) {
if (!traverseFrames) {
return rootNode.getAnimations({subtree: true});
}
let animations = [];
for (const {document} of this.targetActor.windows) {
animations = [...animations, ...document.getAnimations({subtree: true})];
}
return animations;
},
onWillNavigate: function({isTopLevel}) { onWillNavigate: function({isTopLevel}) {
if (isTopLevel) { if (isTopLevel) {
this.stopAnimationPlayerUpdates(); this.stopAnimationPlayerUpdates();

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

@ -3871,7 +3871,7 @@ Element* Document::GetRootElement() const {
: GetRootElementInternal(); : GetRootElementInternal();
} }
nsIContent* Document::GetUnfocusedKeyEventTarget() { return GetRootElement(); } Element* Document::GetUnfocusedKeyEventTarget() { return GetRootElement(); }
Element* Document::GetRootElementInternal() const { Element* Document::GetRootElementInternal() const {
// We invoke GetRootElement() immediately before the servo traversal, so we // We invoke GetRootElement() immediately before the servo traversal, so we

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

@ -1342,7 +1342,7 @@ class Document : public nsINode,
* Gets the event target to dispatch key events to if there is no focused * Gets the event target to dispatch key events to if there is no focused
* content in the document. * content in the document.
*/ */
virtual nsIContent* GetUnfocusedKeyEventTarget(); virtual Element* GetUnfocusedKeyEventTarget();
/** /**
* Retrieve information about the viewport as a data structure. * Retrieve information about the viewport as a data structure.

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

@ -7509,7 +7509,7 @@ void nsContentUtils::TransferableToIPCTransferable(
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
item->flavor() = flavorStr; item->flavor() = flavorStr;
item->data() = dataAsShmem; item->data() = std::move(dataAsShmem);
} else if (nsCOMPtr<nsIInputStream> stream = do_QueryInterface(data)) { } else if (nsCOMPtr<nsIInputStream> stream = do_QueryInterface(data)) {
// Images to be pasted on the clipboard are nsIInputStreams // Images to be pasted on the clipboard are nsIInputStreams
nsCString imageData; nsCString imageData;
@ -7522,7 +7522,7 @@ void nsContentUtils::TransferableToIPCTransferable(
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
item->flavor() = flavorStr; item->flavor() = flavorStr;
item->data() = imageDataShmem; item->data() = std::move(imageDataShmem);
} else if (nsCOMPtr<imgIContainer> image = do_QueryInterface(data)) { } else if (nsCOMPtr<imgIContainer> image = do_QueryInterface(data)) {
// Images to be placed on the clipboard are imgIContainers. // Images to be placed on the clipboard are imgIContainers.
RefPtr<mozilla::gfx::SourceSurface> surface = image->GetFrame( RefPtr<mozilla::gfx::SourceSurface> surface = image->GetFrame(
@ -7550,7 +7550,7 @@ void nsContentUtils::TransferableToIPCTransferable(
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement(); IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
item->flavor() = flavorStr; item->flavor() = flavorStr;
// Turn item->data() into an nsCString prior to accessing it. // Turn item->data() into an nsCString prior to accessing it.
item->data() = surfaceData.ref(); item->data() = std::move(surfaceData.ref());
IPCDataTransferImage& imageDetails = item->imageDetails(); IPCDataTransferImage& imageDetails = item->imageDetails();
mozilla::gfx::IntSize size = dataSurface->GetSize(); mozilla::gfx::IntSize size = dataSurface->GetSize();
@ -7581,7 +7581,7 @@ void nsContentUtils::TransferableToIPCTransferable(
IPCDataTransferItem* item = IPCDataTransferItem* item =
aIPCDataTransfer->items().AppendElement(); aIPCDataTransfer->items().AppendElement();
item->flavor() = type; item->flavor() = type;
item->data() = dataAsShmem; item->data() = std::move(dataAsShmem);
} }
continue; continue;

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

@ -396,11 +396,21 @@ nsresult nsFrameLoader::ReallyStartLoadingInternal() {
loadState->SetTriggeringPrincipal(mOwnerContent->NodePrincipal()); loadState->SetTriggeringPrincipal(mOwnerContent->NodePrincipal());
} }
// Currently we query the CSP from the principal, but after // Expanded Principals override the CSP of the document, hence we first check
// Bug 1529877 we should query the CSP from within GetURL and // if the triggeringPrincipal overrides the document's principal. If so, let's
// store it as a member, similar to mTriggeringPrincipal. // query the CSP from that Principal, otherwise we use the document's CSP.
// Note that even after Bug 965637, Expanded Principals will hold their own
// CSP.
nsCOMPtr<nsIContentSecurityPolicy> csp; nsCOMPtr<nsIContentSecurityPolicy> csp;
loadState->TriggeringPrincipal()->GetCsp(getter_AddRefs(csp)); if (BasePrincipal::Cast(loadState->TriggeringPrincipal())
->OverridesCSP(mOwnerContent->NodePrincipal())) {
loadState->TriggeringPrincipal()->GetCsp(getter_AddRefs(csp));
} else {
// Currently the NodePrincipal holds the CSP for a document. After
// Bug 965637 we can query the CSP from mOwnerContent->OwnerDoc()
// instead of mOwnerContent->NodePrincipal().
mOwnerContent->NodePrincipal()->GetCsp(getter_AddRefs(csp));
}
loadState->SetCsp(csp); loadState->SetCsp(csp);
nsCOMPtr<nsIURI> referrer; nsCOMPtr<nsIURI> referrer;

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

@ -0,0 +1,2 @@
<iframe src="http://mochi.test:8888/tests/dom/base/test/iframe_shared_compartment2b.html">
</iframe>

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

@ -0,0 +1,3 @@
<script>
window.onload = () => window.parent.parent.go(this);
</script>

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

@ -230,6 +230,8 @@ support-files =
iframe7_bug431701.xml iframe7_bug431701.xml
iframe1_bug426646.html iframe1_bug426646.html
iframe2_bug426646.html iframe2_bug426646.html
iframe_shared_compartment2a.html
iframe_shared_compartment2b.html
file1_setting_opener.html file1_setting_opener.html
file2_setting_opener.html file2_setting_opener.html
file3_setting_opener.html file3_setting_opener.html
@ -791,6 +793,8 @@ skip-if = debug == false
[test_settimeout_inner.html] [test_settimeout_inner.html]
[test_setTimeoutWith0.html] [test_setTimeoutWith0.html]
[test_setting_opener.html] [test_setting_opener.html]
[test_shared_compartment1.html]
[test_shared_compartment2.html]
[test_style_cssText.html] [test_style_cssText.html]
[test_text_wholeText.html] [test_text_wholeText.html]
[test_textnode_normalize_in_selection.html] [test_textnode_normalize_in_selection.html]

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

@ -0,0 +1,77 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1530608
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1530608</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1530608 **/
SimpleTest.waitForExplicitFinish();
var Cu = SpecialPowers.Cu;
var isSameCompartment = Cu.getJSTestingFunctions().isSameCompartment;
var testsDone = 0;
function finishIfDone() {
testsDone++;
if (testsDone === 4) {
SimpleTest.finish();
}
}
// Test 1: same-origin iframe.
function testFrame1() {
var frameWin = document.getElementById("frame1").contentWindow;
ok(isSameCompartment(window, frameWin),
"Same-origin iframe must be same-compartment");
finishIfDone();
}
// Test 2: cross-origin iframe.
function testFrame2() {
var frameWin = document.getElementById("frame2").contentWindow;
ok(!isSameCompartment(window, frameWin),
"Cross-origin iframe must be cross-compartment");
finishIfDone();
}
// Test 3: same-site, cross-origin iframe.
function testFrame3() {
var frame = document.getElementById("frame3");
ok(!isSameCompartment(window, frame.contentWindow),
"Same-site cross-origin iframe must be cross-compartment");
// Now load a same-origin page in this iframe.
frame.onload = function() {
ok(isSameCompartment(window, frame.contentWindow),
"Frame must be same-compartment now");
finishIfDone();
};
frame.src = "file_empty.html";
}
// Test 4: dynamically created iframe.
addLoadEvent(function() {
var frame = document.createElement("iframe");
document.body.appendChild(frame);
ok(isSameCompartment(window, frame.contentWindow),
"Newly created iframe must be same-compartment");
finishIfDone();
});
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1530608">Mozilla Bug 1530608</a>
<iframe id="frame1" onload="testFrame1()" src="file_empty.html"></iframe>
<iframe id="frame2" onload="testFrame2()" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
<iframe id="frame3" onload="testFrame3()" src="http://test1.mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
</body>
</html>

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

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1530608
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1530608</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1530608 **/
SimpleTest.waitForExplicitFinish();
// We have the following origins:
//
// 1: this page: mochi.test:8888
// 2: iframe: example.org
// 3: inner iframe: mochi.test:8888
//
// Test that 1 and 2 are cross-compartment (because cross-origin), but 1 and 3
// are same-compartment.
function go(innerWin) {
var Cu = SpecialPowers.Cu;
var isSameCompartment = Cu.getJSTestingFunctions().isSameCompartment;
var frame = document.getElementById("frame");
ok(!isSameCompartment(window, frame.contentWindow),
"Cross-origin iframe must be cross-compartment");
ok(isSameCompartment(window, innerWin),
"Same-origin inner iframe must be same-compartment");
SimpleTest.finish();
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1530608">Mozilla Bug 1530608</a>
<iframe id="frame" src="http://example.org/tests/dom/base/test/iframe_shared_compartment2a.html"></iframe>
</body>
</html>

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

@ -3737,6 +3737,7 @@ void HTMLMediaElement::DispatchEventsWhenPlayWasNotAllowed() {
OwnerDoc()->MaybeNotifyAutoplayBlocked(); OwnerDoc()->MaybeNotifyAutoplayBlocked();
ReportToConsole(nsIScriptError::warningFlag, "BlockAutoplayError"); ReportToConsole(nsIScriptError::warningFlag, "BlockAutoplayError");
mHasPlayEverBeenBlocked = true; mHasPlayEverBeenBlocked = true;
mHasEverBeenBlockedForAutoplay = true;
} }
void HTMLMediaElement::PlayInternal(bool aHandlingUserInput) { void HTMLMediaElement::PlayInternal(bool aHandlingUserInput) {
@ -5985,6 +5986,14 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement,
mEventDeliveryPaused = false; mEventDeliveryPaused = false;
DispatchPendingMediaEvents(); DispatchPendingMediaEvents();
} }
// If the media element has been blocked and isn't still allowed to play
// when it comes back from the bfcache, we would notify front end to show
// the blocking icon in order to inform user that the site is still being
// blocked.
if (mHasEverBeenBlockedForAutoplay &&
!AutoplayPolicy::IsAllowedToPlay(*this)) {
OwnerDoc()->MaybeNotifyAutoplayBlocked();
}
} }
} }
} }

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

@ -1669,6 +1669,11 @@ class HTMLMediaElement : public nsGenericHTMLElement,
// audio. // audio.
MozPromiseHolder<GenericNonExclusivePromise> mAllowedToPlayPromise; MozPromiseHolder<GenericNonExclusivePromise> mAllowedToPlayPromise;
// True if media has ever been blocked for autoplay, it's used to notify front
// end to show the correct blocking icon when the document goes back from
// bfcache.
bool mHasEverBeenBlockedForAutoplay = false;
public: public:
// Helper class to measure times for playback telemetry stats // Helper class to measure times for playback telemetry stats
class TimeDurationAccumulator { class TimeDurationAccumulator {

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

@ -755,7 +755,7 @@ void nsHTMLDocument::SetCompatibilityMode(nsCompatibility aMode) {
} }
} }
nsIContent* nsHTMLDocument::GetUnfocusedKeyEventTarget() { Element* nsHTMLDocument::GetUnfocusedKeyEventTarget() {
if (nsGenericHTMLElement* body = GetBody()) { if (nsGenericHTMLElement* body = GetBody()) {
return body; return body;
} }

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

@ -73,7 +73,7 @@ class nsHTMLDocument : public mozilla::dom::Document, public nsIHTMLDocument {
virtual bool IsWriting() override { return mWriteLevel != uint32_t(0); } virtual bool IsWriting() override { return mWriteLevel != uint32_t(0); }
virtual nsIContent* GetUnfocusedKeyEventTarget() override; virtual Element* GetUnfocusedKeyEventTarget() override;
nsContentList* GetExistingForms() const { return mForms; } nsContentList* GetExistingForms() const { return mForms; }

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

@ -2018,7 +2018,7 @@ bool ContentChild::DeallocPPSMContentDownloaderChild(
PExternalHelperAppChild* ContentChild::AllocPExternalHelperAppChild( PExternalHelperAppChild* ContentChild::AllocPExternalHelperAppChild(
const OptionalURIParams& uri, const OptionalURIParams& uri,
const mozilla::net::OptionalLoadInfoArgs& aLoadInfoArgs, const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
const nsCString& aMimeContentType, const nsCString& aContentDisposition, const nsCString& aMimeContentType, const nsCString& aContentDisposition,
const uint32_t& aContentDispositionHint, const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename, const bool& aForceSave, const nsString& aContentDispositionFilename, const bool& aForceSave,
@ -3555,7 +3555,7 @@ mozilla::ipc::IPCResult ContentChild::RecvSaveRecording(
mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect( mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
const uint32_t& aRegistrarId, nsIURI* aURI, const uint32_t& aNewLoadFlags, const uint32_t& aRegistrarId, nsIURI* aURI, const uint32_t& aNewLoadFlags,
const OptionalLoadInfoArgs& aLoadInfo, const uint64_t& aChannelId, const Maybe<LoadInfoArgs>& aLoadInfo, const uint64_t& aChannelId,
nsIURI* aOriginalURI, const uint64_t& aIdentifier) { nsIURI* aOriginalURI, const uint64_t& aIdentifier) {
nsCOMPtr<nsILoadInfo> loadInfo; nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = nsresult rv =

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

@ -280,7 +280,7 @@ class ContentChild final : public PContentChild,
PExternalHelperAppChild* AllocPExternalHelperAppChild( PExternalHelperAppChild* AllocPExternalHelperAppChild(
const OptionalURIParams& uri, const OptionalURIParams& uri,
const mozilla::net::OptionalLoadInfoArgs& aLoadInfoArgs, const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
const nsCString& aMimeContentType, const nsCString& aContentDisposition, const nsCString& aMimeContentType, const nsCString& aContentDisposition,
const uint32_t& aContentDispositionHint, const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename, const bool& aForceSave, const nsString& aContentDispositionFilename, const bool& aForceSave,
@ -680,9 +680,8 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvCrossProcessRedirect( mozilla::ipc::IPCResult RecvCrossProcessRedirect(
const uint32_t& aRegistrarId, nsIURI* aURI, const uint32_t& aNewLoadFlags, const uint32_t& aRegistrarId, nsIURI* aURI, const uint32_t& aNewLoadFlags,
const OptionalLoadInfoArgs& aLoadInfoForwarder, const Maybe<LoadInfoArgs>& aLoadInfoForwarder, const uint64_t& aChannelId,
const uint64_t& aChannelId, nsIURI* aOriginalURI, nsIURI* aOriginalURI, const uint64_t& aIdentifier);
const uint64_t& aIdentifier);
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD
// Fetch the current number of pending input events. // Fetch the current number of pending input events.

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

@ -3632,7 +3632,7 @@ bool ContentParent::DeallocPPSMContentDownloaderParent(
PExternalHelperAppParent* ContentParent::AllocPExternalHelperAppParent( PExternalHelperAppParent* ContentParent::AllocPExternalHelperAppParent(
const OptionalURIParams& uri, const OptionalURIParams& uri,
const mozilla::net::OptionalLoadInfoArgs& aLoadInfoArgs, const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
const nsCString& aMimeContentType, const nsCString& aContentDisposition, const nsCString& aMimeContentType, const nsCString& aContentDisposition,
const uint32_t& aContentDispositionHint, const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename, const bool& aForceSave, const nsString& aContentDispositionFilename, const bool& aForceSave,
@ -3655,8 +3655,9 @@ bool ContentParent::DeallocPExternalHelperAppParent(
mozilla::ipc::IPCResult ContentParent::RecvPExternalHelperAppConstructor( mozilla::ipc::IPCResult ContentParent::RecvPExternalHelperAppConstructor(
PExternalHelperAppParent* actor, const OptionalURIParams& uri, PExternalHelperAppParent* actor, const OptionalURIParams& uri,
const OptionalLoadInfoArgs& loadInfoArgs, const nsCString& aMimeContentType, const Maybe<LoadInfoArgs>& loadInfoArgs, const nsCString& aMimeContentType,
const nsCString& aContentDisposition, const uint32_t& aContentDispositionHint, const nsCString& aContentDisposition,
const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename, const bool& aForceSave, const nsString& aContentDispositionFilename, const bool& aForceSave,
const int64_t& aContentLength, const bool& aWasFileChannel, const int64_t& aContentLength, const bool& aWasFileChannel,
const OptionalURIParams& aReferrer, PBrowserParent* aBrowser) { const OptionalURIParams& aReferrer, PBrowserParent* aBrowser) {

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

@ -876,7 +876,7 @@ class ContentParent final : public PContentParent,
PExternalHelperAppParent* AllocPExternalHelperAppParent( PExternalHelperAppParent* AllocPExternalHelperAppParent(
const OptionalURIParams& aUri, const OptionalURIParams& aUri,
const mozilla::net::OptionalLoadInfoArgs& aLoadInfoArgs, const Maybe<mozilla::net::LoadInfoArgs>& aLoadInfoArgs,
const nsCString& aMimeContentType, const nsCString& aContentDisposition, const nsCString& aMimeContentType, const nsCString& aContentDisposition,
const uint32_t& aContentDispositionHint, const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename, const bool& aForceSave, const nsString& aContentDispositionFilename, const bool& aForceSave,
@ -887,8 +887,9 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvPExternalHelperAppConstructor( mozilla::ipc::IPCResult RecvPExternalHelperAppConstructor(
PExternalHelperAppParent* actor, const OptionalURIParams& uri, PExternalHelperAppParent* actor, const OptionalURIParams& uri,
const OptionalLoadInfoArgs& loadInfoArgs, const nsCString& aMimeContentType, const Maybe<LoadInfoArgs>& loadInfoArgs,
const nsCString& aContentDisposition, const uint32_t& aContentDispositionHint, const nsCString& aMimeContentType, const nsCString& aContentDisposition,
const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename, const bool& aForceSave, const nsString& aContentDispositionFilename, const bool& aForceSave,
const int64_t& aContentLength, const bool& aWasFileChannel, const int64_t& aContentLength, const bool& aWasFileChannel,
const OptionalURIParams& aReferrer, PBrowserParent* aBrowser) override; const OptionalURIParams& aReferrer, PBrowserParent* aBrowser) override;

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

@ -773,7 +773,7 @@ child:
async CrossProcessRedirect(uint32_t aRegistrarId, async CrossProcessRedirect(uint32_t aRegistrarId,
nsIURI aURI, nsIURI aURI,
uint32_t aNewLoadFlags, uint32_t aNewLoadFlags,
OptionalLoadInfoArgs aLoadInfo, LoadInfoArgs? aLoadInfo,
uint64_t aChannelId, uint64_t aChannelId,
nsIURI aOriginalURI, nsIURI aOriginalURI,
uint64_t aIdentifier); uint64_t aIdentifier);
@ -901,7 +901,7 @@ parent:
async PPSMContentDownloader(uint32_t aCertType); async PPSMContentDownloader(uint32_t aCertType);
async PExternalHelperApp(OptionalURIParams uri, async PExternalHelperApp(OptionalURIParams uri,
OptionalLoadInfoArgs loadInfoArgs, LoadInfoArgs? loadInfoArgs,
nsCString aMimeContentType, nsCString aMimeContentType,
nsCString aContentDisposition, nsCString aContentDisposition,
uint32_t aContentDispositionHint, uint32_t aContentDispositionHint,

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

@ -671,7 +671,7 @@ mozilla::ipc::IPCResult ChromiumCDMChild::RecvDecrypt(
// Success! Return the decrypted sample to parent. // Success! Return the decrypted sample to parent.
MOZ_ASSERT(!HasShmemOfSize(outputShmemSize)); MOZ_ASSERT(!HasShmemOfSize(outputShmemSize));
ipc::Shmem shmem = buffer->ExtractShmem(); ipc::Shmem shmem = buffer->ExtractShmem();
if (SendDecrypted(aId, cdm::kSuccess, shmem)) { if (SendDecrypted(aId, cdm::kSuccess, std::move(shmem))) {
// No need to deallocate the output shmem; it should have been returned // No need to deallocate the output shmem; it should have been returned
// to the content process. // to the content process.
autoDeallocateOutputShmem.release(); autoDeallocateOutputShmem.release();
@ -820,7 +820,7 @@ void ChromiumCDMChild::ReturnOutput(WidevineVideoFrame& aFrame) {
CDMBuffer* base = reinterpret_cast<CDMBuffer*>(aFrame.FrameBuffer()); CDMBuffer* base = reinterpret_cast<CDMBuffer*>(aFrame.FrameBuffer());
if (base->AsShmemBuffer()) { if (base->AsShmemBuffer()) {
ipc::Shmem shmem = base->AsShmemBuffer()->ExtractShmem(); ipc::Shmem shmem = base->AsShmemBuffer()->ExtractShmem();
Unused << SendDecodedShmem(output, shmem); Unused << SendDecodedShmem(output, std::move(shmem));
} else { } else {
MOZ_ASSERT(base->AsArrayBuffer()); MOZ_ASSERT(base->AsArrayBuffer());
Unused << SendDecodedData(output, base->AsArrayBuffer()->ExtractBuffer()); Unused << SendDecodedData(output, base->AsArrayBuffer()->ExtractBuffer());

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

@ -270,7 +270,7 @@ bool ChromiumCDMParent::InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer,
? crypto.mIV ? crypto.mIV
: crypto.mConstantIV; : crypto.mConstantIV;
aBuffer = gmp::CDMInputBuffer( aBuffer = gmp::CDMInputBuffer(
shmem, crypto.mKeyId, iv, aSample->mTime.ToMicroseconds(), std::move(shmem), crypto.mKeyId, iv, aSample->mTime.ToMicroseconds(),
aSample->mDuration.ToMicroseconds(), crypto.mPlainSizes, aSample->mDuration.ToMicroseconds(), crypto.mPlainSizes,
crypto.mEncryptedSizes, crypto.mCryptByteBlock, crypto.mSkipByteBlock, crypto.mEncryptedSizes, crypto.mCryptByteBlock, crypto.mSkipByteBlock,
encryptionScheme); encryptionScheme);
@ -291,7 +291,7 @@ bool ChromiumCDMParent::SendBufferToCDM(uint32_t aSizeInBytes) {
if (!AllocShmem(aSizeInBytes, Shmem::SharedMemory::TYPE_BASIC, &shmem)) { if (!AllocShmem(aSizeInBytes, Shmem::SharedMemory::TYPE_BASIC, &shmem)) {
return false; return false;
} }
if (!SendGiveBuffer(shmem)) { if (!SendGiveBuffer(std::move(shmem))) {
DeallocShmem(shmem); DeallocShmem(shmem);
return false; return false;
} }
@ -713,7 +713,7 @@ ipc::IPCResult ChromiumCDMParent::RecvDecodedShmem(const CDMVideoFrame& aFrame,
// Return the shmem to the CDM so the shmem can be reused to send us // Return the shmem to the CDM so the shmem can be reused to send us
// another frame. // another frame.
if (!SendGiveBuffer(aShmem)) { if (!SendGiveBuffer(std::move(aShmem))) {
mDecodePromise.RejectIfExists( mDecodePromise.RejectIfExists(
MediaResult(NS_ERROR_OUT_OF_MEMORY, MediaResult(NS_ERROR_OUT_OF_MEMORY,
RESULT_DETAIL("Can't return shmem to CDM process")), RESULT_DETAIL("Can't return shmem to CDM process")),

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

@ -68,7 +68,7 @@ bool GMPSharedMemManager::MgrDeallocShmem(GMPSharedMem::GMPMemoryClasses aClass,
// XXX This works; there are better pool algorithms. We need to avoid // XXX This works; there are better pool algorithms. We need to avoid
// "falling off a cliff" with too low a number // "falling off a cliff" with too low a number
if (GetGmpFreelist(aClass).Length() > 10) { if (GetGmpFreelist(aClass).Length() > 10) {
Dealloc(GetGmpFreelist(aClass)[0]); Dealloc(std::move(GetGmpFreelist(aClass)[0]));
GetGmpFreelist(aClass).RemoveElementAt(0); GetGmpFreelist(aClass).RemoveElementAt(0);
// The allocation numbers will be fubar on the Child! // The allocation numbers will be fubar on the Child!
mData->mGmpAllocated[aClass]--; mData->mGmpAllocated[aClass]--;

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

@ -68,7 +68,7 @@ class GMPSharedMemManager {
virtual bool Alloc(size_t aSize, virtual bool Alloc(size_t aSize,
ipc::Shmem::SharedMemory::SharedMemoryType aType, ipc::Shmem::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aMem) = 0; ipc::Shmem* aMem) = 0;
virtual void Dealloc(ipc::Shmem& aMem) = 0; virtual void Dealloc(ipc::Shmem&& aMem) = 0;
private: private:
nsTArray<ipc::Shmem>& GetGmpFreelist(GMPSharedMem::GMPMemoryClasses aTypes) { nsTArray<ipc::Shmem>& GetGmpFreelist(GMPSharedMem::GMPMemoryClasses aTypes) {

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

@ -207,9 +207,9 @@ bool GMPVideoDecoderChild::Alloc(size_t aSize,
return rv; return rv;
} }
void GMPVideoDecoderChild::Dealloc(Shmem& aMem) { void GMPVideoDecoderChild::Dealloc(Shmem&& aMem) {
#ifndef SHMEM_ALLOC_IN_CHILD #ifndef SHMEM_ALLOC_IN_CHILD
SendParentShmemForPool(aMem); SendParentShmemForPool(std::move(aMem));
#else #else
DeallocShmem(aMem); DeallocShmem(aMem);
#endif #endif

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

@ -43,7 +43,7 @@ class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
// GMPSharedMemManager // GMPSharedMemManager
bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType,
Shmem* aMem) override; Shmem* aMem) override;
void Dealloc(Shmem& aMem) override; void Dealloc(Shmem&& aMem) override;
private: private:
virtual ~GMPVideoDecoderChild(); virtual ~GMPVideoDecoderChild();

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

@ -60,7 +60,7 @@ class GMPVideoDecoderParent final : public PGMPVideoDecoderParent,
return AllocUnsafeShmem(aSize, aType, aMem); return AllocUnsafeShmem(aSize, aType, aMem);
#endif #endif
} }
void Dealloc(Shmem& aMem) override { DeallocShmem(aMem); } void Dealloc(Shmem&& aMem) override { DeallocShmem(aMem); }
private: private:
~GMPVideoDecoderParent(); ~GMPVideoDecoderParent();

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

@ -199,9 +199,9 @@ bool GMPVideoEncoderChild::Alloc(size_t aSize,
return rv; return rv;
} }
void GMPVideoEncoderChild::Dealloc(Shmem& aMem) { void GMPVideoEncoderChild::Dealloc(Shmem&& aMem) {
#ifndef SHMEM_ALLOC_IN_CHILD #ifndef SHMEM_ALLOC_IN_CHILD
SendParentShmemForPool(aMem); SendParentShmemForPool(std::move(aMem));
#else #else
DeallocShmem(aMem); DeallocShmem(aMem);
#endif #endif

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

@ -39,7 +39,7 @@ class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
// GMPSharedMemManager // GMPSharedMemManager
bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType,
Shmem* aMem) override; Shmem* aMem) override;
void Dealloc(Shmem& aMem) override; void Dealloc(Shmem&& aMem) override;
private: private:
virtual ~GMPVideoEncoderChild(); virtual ~GMPVideoEncoderChild();

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

@ -58,7 +58,7 @@ class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
return AllocUnsafeShmem(aSize, aType, aMem); return AllocUnsafeShmem(aSize, aType, aMem);
#endif #endif
} }
void Dealloc(Shmem& aMem) override { DeallocShmem(aMem); } void Dealloc(Shmem&& aMem) override { DeallocShmem(aMem); }
private: private:
virtual ~GMPVideoEncoderParent(){}; virtual ~GMPVideoEncoderParent(){};

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

@ -114,7 +114,7 @@ void RemoteAudioDecoderParent::ProcessDecodedData(
RemoteAudioDataIPDL output( RemoteAudioDataIPDL output(
MediaDataIPDL(data->mOffset, data->mTime, data->mTimecode, MediaDataIPDL(data->mOffset, data->mTime, data->mTimecode,
data->mDuration, data->mKeyframe), data->mDuration, data->mKeyframe),
audio->mChannels, audio->mRate, audio->mChannelMap, buffer); audio->mChannels, audio->mRate, audio->mChannelMap, std::move(buffer));
Unused << SendOutput(output); Unused << SendOutput(output);
} }

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

@ -114,7 +114,7 @@ RefPtr<MediaDataDecoder::DecodePromise> RemoteDecoderChild::Decode(
MediaRawDataIPDL sample( MediaRawDataIPDL sample(
MediaDataIPDL(aSample->mOffset, aSample->mTime, aSample->mTimecode, MediaDataIPDL(aSample->mOffset, aSample->mTime, aSample->mTimecode,
aSample->mDuration, aSample->mKeyframe), aSample->mDuration, aSample->mKeyframe),
buffer); std::move(buffer));
SendInput(sample); SendInput(sample);
return mDecodePromise.Ensure(__func__); return mDecodePromise.Ensure(__func__);

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

@ -184,7 +184,7 @@ void RemoteVideoDecoderParent::ProcessDecodedData(
if (AllocShmem(image->GetDataSize(), Shmem::SharedMemory::TYPE_BASIC, if (AllocShmem(image->GetDataSize(), Shmem::SharedMemory::TYPE_BASIC,
&buffer) && &buffer) &&
image->GetDataSize() == buffer.Size<uint8_t>()) { image->GetDataSize() == buffer.Size<uint8_t>()) {
sdBuffer.data() = buffer; sdBuffer.data() = std::move(buffer);
image->BuildSurfaceDescriptorBuffer(sdBuffer); image->BuildSurfaceDescriptorBuffer(sdBuffer);
} }

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

@ -243,7 +243,7 @@ RefPtr<MediaDataDecoder::DecodePromise> VideoDecoderChild::Decode(
MediaRawDataIPDL sample( MediaRawDataIPDL sample(
MediaDataIPDL(aSample->mOffset, aSample->mTime, aSample->mTimecode, MediaDataIPDL(aSample->mOffset, aSample->mTime, aSample->mTimecode,
aSample->mDuration, aSample->mKeyframe), aSample->mDuration, aSample->mKeyframe),
buffer); std::move(buffer));
SendInput(sample); SendInput(sample);
return mDecodePromise.Ensure(__func__); return mDecodePromise.Ensure(__func__);
} }

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

@ -265,7 +265,7 @@ mozilla::ipc::IPCResult VideoDecoderManagerParent::RecvReadback(
dt->Flush(); dt->Flush();
*aResult = SurfaceDescriptorBuffer(RGBDescriptor(size, format, true), *aResult = SurfaceDescriptorBuffer(RGBDescriptor(size, format, true),
MemoryOrShmem(buffer)); MemoryOrShmem(std::move(buffer)));
return IPC_OK(); return IPC_OK();
} }

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

@ -575,7 +575,7 @@ mozilla::ipc::IPCResult CamerasChild::RecvDeliverFrame(
} else { } else {
LOG(("DeliverFrame called with dead callback")); LOG(("DeliverFrame called with dead callback"));
} }
SendReleaseFrame(shmem); SendReleaseFrame(std::move(shmem));
return IPC_OK(); return IPC_OK();
} }

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

@ -278,14 +278,15 @@ int CamerasParent::DeliverFrameOverIPC(CaptureEngine capEng, uint32_t aStreamId,
// get() and Size() check for proper alignment of the segment // get() and Size() check for proper alignment of the segment
memcpy(shMemBuff.GetBytes(), altbuffer, aProps.bufferSize()); memcpy(shMemBuff.GetBytes(), altbuffer, aProps.bufferSize());
if (!SendDeliverFrame(capEng, aStreamId, shMemBuff.Get(), aProps)) { if (!SendDeliverFrame(capEng, aStreamId, std::move(shMemBuff.Get()),
aProps)) {
return -1; return -1;
} }
} else { } else {
MOZ_ASSERT(buffer.Valid()); MOZ_ASSERT(buffer.Valid());
// ShmemBuffer was available, we're all good. A single copy happened // ShmemBuffer was available, we're all good. A single copy happened
// in the original webrtc callback. // in the original webrtc callback.
if (!SendDeliverFrame(capEng, aStreamId, buffer.Get(), aProps)) { if (!SendDeliverFrame(capEng, aStreamId, std::move(buffer.Get()), aProps)) {
return -1; return -1;
} }
} }

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

@ -2722,8 +2722,8 @@ void PluginInstanceChild::NPN_SetCurrentAsyncSurface(NPAsyncSurface* surface,
// Need a holder since IPDL zaps the object for mysterious reasons. // Need a holder since IPDL zaps the object for mysterious reasons.
Shmem shmemHolder = bitmap->mShmem; Shmem shmemHolder = bitmap->mShmem;
SendShowDirectBitmap(shmemHolder, bitmap->mFormat, bitmap->mStride, SendShowDirectBitmap(std::move(shmemHolder), bitmap->mFormat,
bitmap->mSize, dirty); bitmap->mStride, bitmap->mSize, dirty);
break; break;
} }
#if defined(XP_WIN) #if defined(XP_WIN)
@ -3569,8 +3569,8 @@ bool PluginInstanceChild::ShowPluginFrame() {
} else } else
#endif #endif
if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface)) { if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface)) {
currSurf = currSurf = std::move(
static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem(); static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem());
} else { } else {
MOZ_CRASH("Surface type is not remotable"); MOZ_CRASH("Surface type is not remotable");
return false; return false;

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

@ -849,8 +849,8 @@ mozilla::ipc::IPCResult PluginInstanceParent::RecvShow(
} }
if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface)) if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
*prevSurface = *prevSurface = std::move(
static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem(); static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem());
else else
*prevSurface = null_t(); *prevSurface = null_t();
@ -1161,7 +1161,7 @@ PluginInstanceParent::BackgroundDescriptor() {
"Expected shared image surface"); "Expected shared image surface");
gfxSharedImageSurface* shmem = gfxSharedImageSurface* shmem =
static_cast<gfxSharedImageSurface*>(mBackground.get()); static_cast<gfxSharedImageSurface*>(mBackground.get());
return shmem->GetShmem(); return mozilla::plugins::SurfaceDescriptor(std::move(shmem->GetShmem()));
#endif #endif
// If this is ever used, which it shouldn't be, it will trigger a // If this is ever used, which it shouldn't be, it will trigger a
@ -1552,8 +1552,8 @@ int16_t PluginInstanceParent::NPP_HandleEvent(void* event) {
return false; return false;
} }
if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface, &handled, if (!CallNPP_HandleEvent_Shmem(npremoteevent, std::move(mShSurface),
&mShSurface)) &handled, &mShSurface))
return false; // no good way to handle errors here... return false; // no good way to handle errors here...
if (!mShSurface.IsReadable()) { if (!mShSurface.IsReadable()) {

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

@ -530,7 +530,7 @@ bool PluginModuleChromeParent::InitCrashReporter() {
} }
NativeThreadId threadId; NativeThreadId threadId;
if (!CallInitCrashReporter(shmem, &threadId)) { if (!CallInitCrashReporter(std::move(shmem), &threadId)) {
return false; return false;
} }

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

@ -1,3 +1,5 @@
const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
// Returns the test H/2 server port, throwing if it's missing or invalid. // Returns the test H/2 server port, throwing if it's missing or invalid.
function getTestServerPort() { function getTestServerPort() {
let portEnv = Cc["@mozilla.org/process/environment;1"] let portEnv = Cc["@mozilla.org/process/environment;1"]
@ -10,52 +12,26 @@ function getTestServerPort() {
return port; return port;
} }
// Support for making sure we can talk to the invalid cert the server presents function readFile(file) {
var CertOverrideListener = function(host, port, bits) { let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
this.host = host; .createInstance(Ci.nsIFileInputStream);
this.port = port || 443; fstream.init(file, -1, 0, 0);
this.bits = bits; let data = NetUtil.readInputStreamToString(fstream, fstream.available());
}; fstream.close();
return data;
CertOverrideListener.prototype = { }
host: null,
bits: null, function addCertFromFile(certdb, filename, trustString) {
let certFile = do_get_file(filename, false);
getInterface: function(aIID) { let pem = readFile(certFile)
return this.QueryInterface(aIID); .replace(/-----BEGIN CERTIFICATE-----/, "")
}, .replace(/-----END CERTIFICATE-----/, "")
.replace(/[\r\n]/g, "");
QueryInterface: function(aIID) { certdb.addCertFromBase64(pem, trustString);
if (aIID.equals(Ci.nsIBadCertListener2) || }
aIID.equals(Ci.nsIInterfaceRequestor) ||
aIID.equals(Ci.nsISupports)) function trustHttp2CA() {
return this; let certdb = Cc["@mozilla.org/security/x509certdb;1"]
throw Cr.NS_ERROR_NO_INTERFACE; .getService(Ci.nsIX509CertDB);
}, addCertFromFile(certdb, "../../../../netwerk/test/unit/http2-ca.pem", "CTu,u,u");
notifyCertProblem: function(socketInfo, secInfo, targetHost) {
var cert = secInfo.serverCert;
var cos = Cc["@mozilla.org/security/certoverride;1"].
getService(Ci.nsICertOverrideService);
cos.rememberValidityOverride(this.host, this.port, cert, this.bits, false);
dump("Certificate Override in place\n");
return true;
},
};
function addCertOverride(host, port, bits) {
var req = new XMLHttpRequest();
try {
var url;
if (port && (port > 0) && (port !== 443)) {
url = "https://" + host + ":" + port + "/";
} else {
url = "https://" + host + "/";
}
req.open("GET", url, false);
req.channel.notificationCallbacks = new CertOverrideListener(host, port, bits);
req.send(null);
} catch (e) {
// This will fail since the server is not trusted yet
}
} }

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

@ -24,10 +24,7 @@ function run_test() {
prefs.setBoolPref("dom.push.enabled", true); prefs.setBoolPref("dom.push.enabled", true);
prefs.setBoolPref("dom.push.connection.enabled", true); prefs.setBoolPref("dom.push.connection.enabled", true);
addCertOverride("localhost", serverPort, trustHttp2CA();
Ci.nsICertOverrideService.ERROR_UNTRUSTED |
Ci.nsICertOverrideService.ERROR_MISMATCH |
Ci.nsICertOverrideService.ERROR_TIME);
prefs.setIntPref("network.http.speculative-parallel-limit", oldPref); prefs.setIntPref("network.http.speculative-parallel-limit", oldPref);

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

@ -54,10 +54,7 @@ add_task(async function test_TLS() {
var oldPref = prefs.getIntPref("network.http.speculative-parallel-limit"); var oldPref = prefs.getIntPref("network.http.speculative-parallel-limit");
prefs.setIntPref("network.http.speculative-parallel-limit", 0); prefs.setIntPref("network.http.speculative-parallel-limit", 0);
addCertOverride("localhost", serverPort, trustHttp2CA();
Ci.nsICertOverrideService.ERROR_UNTRUSTED |
Ci.nsICertOverrideService.ERROR_MISMATCH |
Ci.nsICertOverrideService.ERROR_TIME);
prefs.setIntPref("network.http.speculative-parallel-limit", oldPref); prefs.setIntPref("network.http.speculative-parallel-limit", oldPref);
}); });

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

@ -27,10 +27,7 @@ function run_test() {
prefs.setBoolPref("dom.push.enabled", true); prefs.setBoolPref("dom.push.enabled", true);
prefs.setBoolPref("dom.push.connection.enabled", true); prefs.setBoolPref("dom.push.connection.enabled", true);
addCertOverride("localhost", serverPort, trustHttp2CA();
Ci.nsICertOverrideService.ERROR_UNTRUSTED |
Ci.nsICertOverrideService.ERROR_MISMATCH |
Ci.nsICertOverrideService.ERROR_TIME);
prefs.setIntPref("network.http.speculative-parallel-limit", oldPref); prefs.setIntPref("network.http.speculative-parallel-limit", oldPref);

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

@ -26,10 +26,7 @@ function run_test() {
prefs.setBoolPref("dom.push.enabled", true); prefs.setBoolPref("dom.push.enabled", true);
prefs.setBoolPref("dom.push.connection.enabled", true); prefs.setBoolPref("dom.push.connection.enabled", true);
addCertOverride("localhost", serverPort, trustHttp2CA();
Ci.nsICertOverrideService.ERROR_UNTRUSTED |
Ci.nsICertOverrideService.ERROR_MISMATCH |
Ci.nsICertOverrideService.ERROR_TIME);
prefs.setIntPref("network.http.speculative-parallel-limit", oldPref); prefs.setIntPref("network.http.speculative-parallel-limit", oldPref);

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

@ -88,7 +88,9 @@ UniquePtr<SurfaceFactory> GLScreenBuffer::CreateFactory(
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel, factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel,
mFlags); mFlags);
#elif defined(MOZ_WIDGET_ANDROID) #elif defined(MOZ_WIDGET_ANDROID)
if (XRE_IsParentProcess() && !gfxPrefs::WebGLSurfaceTextureEnabled()) { // XXX WebRender does not support SurfaceFactory_EGLImage usage.
if (XRE_IsParentProcess() && !gfxPrefs::WebGLSurfaceTextureEnabled() &&
backend != layers::LayersBackend::LAYERS_WR) {
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags); factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
} else { } else {
factory = factory =

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

@ -1168,9 +1168,9 @@ struct ParamTraits<mozilla::Array<T, Length>> {
template <> template <>
struct ParamTraits<mozilla::gfx::PaintFragment> { struct ParamTraits<mozilla::gfx::PaintFragment> {
typedef mozilla::gfx::PaintFragment paramType; typedef mozilla::gfx::PaintFragment paramType;
static void Write(Message* aMsg, paramType& aParam) { static void Write(Message* aMsg, paramType&& aParam) {
WriteParam(aMsg, aParam.mSize); WriteParam(aMsg, aParam.mSize);
WriteParam(aMsg, aParam.mRecording); WriteParam(aMsg, std::move(aParam.mRecording));
WriteParam(aMsg, aParam.mDependencies); WriteParam(aMsg, aParam.mDependencies);
} }

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

@ -484,7 +484,8 @@ bool ShmemTextureData::Serialize(SurfaceDescriptor& aOutDescriptor) {
return false; return false;
} }
aOutDescriptor = SurfaceDescriptorBuffer(mDescriptor, MemoryOrShmem(mShmem)); aOutDescriptor =
SurfaceDescriptorBuffer(mDescriptor, MemoryOrShmem(std::move(mShmem)));
return true; return true;
} }

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

@ -143,6 +143,11 @@ already_AddRefed<SourceSurface> D3D11YCbCrImage::GetAsSourceSurface() {
RefPtr<ID3D11Device> dev; RefPtr<ID3D11Device> dev;
texY->GetDevice(getter_AddRefs(dev)); texY->GetDevice(getter_AddRefs(dev));
if (!dev || dev != gfx::DeviceManagerDx::Get()->GetImageDevice()) {
gfxCriticalError() << "D3D11Device is obsoleted";
return nullptr;
}
RefPtr<ID3D10Multithread> mt; RefPtr<ID3D10Multithread> mt;
hr = dev->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt)); hr = dev->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt));

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

@ -1204,7 +1204,7 @@ void LayerManagerComposite::HandlePixelsTarget() {
gl->fReadPixels(0, 0, bufferWidth, bufferHeight, LOCAL_GL_RGBA, gl->fReadPixels(0, 0, bufferWidth, bufferHeight, LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE, mem.get<uint8_t>()); LOCAL_GL_UNSIGNED_BYTE, mem.get<uint8_t>());
Unused << mScreenPixelsTarget->SendScreenPixels( Unused << mScreenPixelsTarget->SendScreenPixels(
mem, ScreenIntSize(bufferWidth, bufferHeight)); std::move(mem), ScreenIntSize(bufferWidth, bufferHeight));
mScreenPixelsTarget = nullptr; mScreenPixelsTarget = nullptr;
} }
#endif #endif

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

@ -964,7 +964,7 @@ bool ShadowLayerForwarder::AllocSurfaceDescriptorWithCaps(
return false; return false;
} }
bufferDesc = shmem; bufferDesc = std::move(shmem);
} }
// Use an intermediate buffer by default. Skipping the intermediate buffer is // Use an intermediate buffer by default. Skipping the intermediate buffer is

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

@ -166,7 +166,7 @@ bool UiCompositorControllerChild::ToolbarPixelsToCompositor(
return false; return false;
} }
return SendToolbarPixelsToCompositor(aMem, aSize); return SendToolbarPixelsToCompositor(std::move(aMem), aSize);
} }
void UiCompositorControllerChild::Destroy() { void UiCompositorControllerChild::Destroy() {

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

@ -98,7 +98,8 @@ void WebRenderBridgeChild::UpdateResources(
nsTArray<ipc::Shmem> largeShmems; nsTArray<ipc::Shmem> largeShmems;
aResources.Flush(resourceUpdates, smallShmems, largeShmems); aResources.Flush(resourceUpdates, smallShmems, largeShmems);
this->SendUpdateResources(resourceUpdates, smallShmems, largeShmems); this->SendUpdateResources(resourceUpdates, smallShmems,
std::move(largeShmems));
} }
void WebRenderBridgeChild::EndTransaction( void WebRenderBridgeChild::EndTransaction(
@ -123,12 +124,12 @@ void WebRenderBridgeChild::EndTransaction(
nsTArray<ipc::Shmem> largeShmems; nsTArray<ipc::Shmem> largeShmems;
aResources.Flush(resourceUpdates, smallShmems, largeShmems); aResources.Flush(resourceUpdates, smallShmems, largeShmems);
this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors, this->SendSetDisplayList(
GetFwdTransactionId(), aTransactionId, aContentSize, aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(),
dlData, aDL.dl_desc, aScrollData, resourceUpdates, aTransactionId, aContentSize, std::move(dlData), aDL.dl_desc, aScrollData,
smallShmems, largeShmems, mIdNamespace, resourceUpdates, smallShmems, std::move(largeShmems), mIdNamespace,
aContainsSVGGroup, aVsyncId, aVsyncStartTime, aContainsSVGGroup, aVsyncId, aVsyncStartTime, aRefreshStartTime,
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime); aTxnStartTime, aTxnURL, fwdTime);
mParentCommands.Clear(); mParentCommands.Clear();
mDestroyedActors.Clear(); mDestroyedActors.Clear();
@ -158,8 +159,8 @@ void WebRenderBridgeChild::EndEmptyTransaction(
this->SendEmptyTransaction( this->SendEmptyTransaction(
aFocusTarget, aUpdates, aPaintSequenceNumber, mParentCommands, aFocusTarget, aUpdates, aPaintSequenceNumber, mParentCommands,
mDestroyedActors, GetFwdTransactionId(), aTransactionId, resourceUpdates, mDestroyedActors, GetFwdTransactionId(), aTransactionId, resourceUpdates,
smallShmems, largeShmems, mIdNamespace, aVsyncId, aVsyncStartTime, smallShmems, std::move(largeShmems), mIdNamespace, aVsyncId,
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime); aVsyncStartTime, aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime);
mParentCommands.Clear(); mParentCommands.Clear();
mDestroyedActors.Clear(); mDestroyedActors.Clear();
mIsInTransaction = false; mIsInTransaction = false;

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

@ -1471,7 +1471,7 @@ impl AlphaBatchBuilder {
.expect("bug: surface must be allocated by now"); .expect("bug: surface must be allocated by now");
let filter_data = &ctx.data_stores.filterdata[handle]; let filter_data = &ctx.data_stores.filter_data[handle];
let filter_mode : i32 = 13 | let filter_mode : i32 = 13 |
((filter_data.data.r_func.to_int() << 28 | ((filter_data.data.r_func.to_int() << 28 |
filter_data.data.g_func.to_int() << 24 | filter_data.data.g_func.to_int() << 24 |

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

@ -2,13 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, DeviceIntSize, LayoutPrimitiveInfo}; use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, LayoutPrimitiveInfo, PrimitiveKeyKind};
use api::{LayoutRect, LayoutSize, LayoutVector2D, MAX_BLUR_RADIUS}; use api::MAX_BLUR_RADIUS;
use api::units::*;
use clip::ClipItemKey; use clip::ClipItemKey;
use display_list_flattener::DisplayListFlattener; use display_list_flattener::DisplayListFlattener;
use gpu_cache::GpuCacheHandle; use gpu_cache::GpuCacheHandle;
use gpu_types::BoxShadowStretchMode; use gpu_types::BoxShadowStretchMode;
use prim_store::{ScrollNodeAndClipChain, PrimitiveKeyKind}; use prim_store::ScrollNodeAndClipChain;
use render_task::RenderTaskCacheEntryHandle; use render_task::RenderTaskCacheEntryHandle;
use util::RectHelpers; use util::RectHelpers;

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

@ -6,7 +6,7 @@ use api::{BorderRadius, ClipMode, ComplexClipRegion, DeviceIntRect, DevicePixelS
use api::{ImageRendering, LayoutRect, LayoutSize, LayoutPoint, LayoutVector2D}; use api::{ImageRendering, LayoutRect, LayoutSize, LayoutPoint, LayoutVector2D};
use api::{BoxShadowClipMode, LayoutToWorldScale, PicturePixel, WorldPixel}; use api::{BoxShadowClipMode, LayoutToWorldScale, PicturePixel, WorldPixel};
use api::{PictureRect, LayoutPixel, WorldPoint, WorldSize, WorldRect, LayoutToWorldTransform}; use api::{PictureRect, LayoutPixel, WorldPoint, WorldSize, WorldRect, LayoutToWorldTransform};
use api::{ImageKey}; use api::{ClipIntern, ImageKey};
use app_units::Au; use app_units::Au;
use border::{ensure_no_corner_overlap, BorderRadiusAu}; use border::{ensure_no_corner_overlap, BorderRadiusAu};
use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowClipSource, BoxShadowCacheKey}; use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowClipSource, BoxShadowCacheKey};
@ -104,8 +104,8 @@ use util::{extract_inner_rect_safe, project_rect, ScaleOffset};
// Type definitions for interning clip nodes. // Type definitions for interning clip nodes.
pub use intern_types::clip::Store as ClipDataStore; pub type ClipDataStore = intern::DataStore<ClipIntern>;
use intern_types::clip::Handle as ClipDataHandle; type ClipDataHandle = intern::Handle<ClipIntern>;
// Result of comparing a clip node instance against a local rect. // Result of comparing a clip node instance against a local rect.
#[derive(Debug)] #[derive(Debug)]
@ -847,6 +847,12 @@ impl ClipItemKey {
impl intern::InternDebug for ClipItemKey {} impl intern::InternDebug for ClipItemKey {}
impl intern::Internable for ClipIntern {
type Key = ClipItemKey;
type StoreData = ClipNode;
type InternData = ();
}
#[derive(Debug, MallocSizeOf)] #[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]

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

@ -3,15 +3,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter}; use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter};
use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, DeviceIntSize}; use api::{ClipId, ColorF, ComplexClipRegion, RasterSpace};
use api::{DisplayItemRef, ExtendMode, ExternalScrollId, AuHelpers}; use api::{DisplayItemRef, ExtendMode, ExternalScrollId};
use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, RasterSpace, GradientStop}; use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayoutPoint, ColorDepth}; use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth};
use api::{LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D}; use api::{LayoutPrimitiveInfo, LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity}; use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
use api::{Shadow, SpaceAndClipInfo, SpatialId, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect}; use api::{Shadow, SpaceAndClipInfo, SpatialId, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem};
use api::{ClipMode, TransformStyle, YuvColorSpace, YuvData, TempFilterData}; use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, YuvData, TempFilterData};
use api::units::*;
use app_units::Au; use app_units::Au;
use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore}; use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore};
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex}; use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex};
@ -19,13 +19,14 @@ use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
use glyph_rasterizer::FontInstance; use glyph_rasterizer::FontInstance;
use hit_test::{HitTestingItem, HitTestingRun}; use hit_test::{HitTestingItem, HitTestingRun};
use image::simplify_repeated_primitive; use image::simplify_repeated_primitive;
use intern::{Handle, Internable, InternDebug}; use intern::Interner;
use internal_types::{FastHashMap, FastHashSet}; use internal_types::{FastHashMap, FastHashSet};
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions}; use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions};
use picture::{BlitReason, OrderedPictureChild, PrimitiveList, TileCache}; use picture::{BlitReason, OrderedPictureChild, PrimitiveList, TileCache};
use prim_store::{PrimitiveInstance, PrimitiveKeyKind, PrimitiveSceneData}; use prim_store::{PrimitiveInstance, PrimitiveSceneData};
use prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore}; use prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore};
use prim_store::{PrimitiveStoreStats, ScrollNodeAndClipChain, PictureIndex}; use prim_store::{PrimitiveStoreStats, ScrollNodeAndClipChain, PictureIndex};
use prim_store::InternablePrimitive;
use prim_store::{register_prim_chase_id, get_line_decoration_sizes}; use prim_store::{register_prim_chase_id, get_line_decoration_sizes};
use prim_store::borders::{ImageBorder, NormalBorderPrim}; use prim_store::borders::{ImageBorder, NormalBorderPrim};
use prim_store::gradient::{GradientStopKey, LinearGradient, RadialGradient, RadialGradientParams}; use prim_store::gradient::{GradientStopKey, LinearGradient, RadialGradient, RadialGradientParams};
@ -36,7 +37,7 @@ use prim_store::text_run::TextRun;
use render_backend::{DocumentView}; use render_backend::{DocumentView};
use resource_cache::{FontInstanceMap, ImageRequest}; use resource_cache::{FontInstanceMap, ImageRequest};
use scene::{Scene, StackingContextHelpers}; use scene::{Scene, StackingContextHelpers};
use scene_builder::{InternerMut, Interners}; use scene_builder::Interners;
use spatial_node::{StickyFrameInfo, ScrollFrameKind, SpatialNodeType}; use spatial_node::{StickyFrameInfo, ScrollFrameKind, SpatialNodeType};
use std::{f32, mem, usize}; use std::{f32, mem, usize};
use std::collections::vec_deque::VecDeque; use std::collections::vec_deque::VecDeque;
@ -1148,16 +1149,14 @@ impl<'a> DisplayListFlattener<'a> {
prim: P, prim: P,
) -> PrimitiveInstance ) -> PrimitiveInstance
where where
P: Internable<InternData=PrimitiveSceneData>, P: InternablePrimitive,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug, Interners: AsMut<Interner<P>>,
Interners: InternerMut<P>,
{ {
// Build a primitive key. // Build a primitive key.
let prim_key = prim.build_key(info); let prim_key = prim.into_key(info);
let interner = self.interners.interner_mut(); let interner = self.interners.as_mut();
let prim_data_handle = let prim_data_handle = interner
interner
.intern(&prim_key, || { .intern(&prim_key, || {
PrimitiveSceneData { PrimitiveSceneData {
prim_size: info.rect.size, prim_size: info.rect.size,
@ -1167,7 +1166,8 @@ impl<'a> DisplayListFlattener<'a> {
let current_offset = self.rf_mapper.current_offset(); let current_offset = self.rf_mapper.current_offset();
let instance_kind = prim_key.as_instance_kind( let instance_kind = P::make_instance_kind(
prim_key,
prim_data_handle, prim_data_handle,
&mut self.prim_store, &mut self.prim_store,
current_offset, current_offset,
@ -1228,9 +1228,8 @@ impl<'a> DisplayListFlattener<'a> {
prim: P, prim: P,
) )
where where
P: Internable<InternData = PrimitiveSceneData> + IsVisible, P: InternablePrimitive + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug, Interners: AsMut<Interner<P>>,
Interners: InternerMut<P>,
{ {
if prim.is_visible() { if prim.is_visible() {
let clip_chain_id = self.build_clip_chain( let clip_chain_id = self.build_clip_chain(
@ -1255,9 +1254,8 @@ impl<'a> DisplayListFlattener<'a> {
prim: P, prim: P,
) )
where where
P: Internable<InternData = PrimitiveSceneData> + IsVisible, P: InternablePrimitive + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug, Interners: AsMut<Interner<P>>,
Interners: InternerMut<P>,
ShadowItem: From<PendingPrimitive<P>> ShadowItem: From<PendingPrimitive<P>>
{ {
// If a shadow context is not active, then add the primitive // If a shadow context is not active, then add the primitive
@ -1290,9 +1288,8 @@ impl<'a> DisplayListFlattener<'a> {
prim: P, prim: P,
) )
where where
P: Internable<InternData = PrimitiveSceneData>, P: InternablePrimitive,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug, Interners: AsMut<Interner<P>>,
Interners: InternerMut<P>,
{ {
let prim_instance = self.create_primitive( let prim_instance = self.create_primitive(
info, info,
@ -1606,7 +1603,7 @@ impl<'a> DisplayListFlattener<'a> {
}; };
let handle = self.interners let handle = self.interners
.filterdata .filter_data
.intern(&filter_data_key, || ()); .intern(&filter_data_key, || ());
PictureCompositeMode::ComponentTransferFilter(handle) PictureCompositeMode::ComponentTransferFilter(handle)
} }
@ -2129,9 +2126,8 @@ impl<'a> DisplayListFlattener<'a> {
prims: &mut Vec<PrimitiveInstance>, prims: &mut Vec<PrimitiveInstance>,
) )
where where
P: Internable<InternData=PrimitiveSceneData> + CreateShadow, P: InternablePrimitive + CreateShadow,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug, Interners: AsMut<Interner<P>>,
Interners: InternerMut<P>,
{ {
// Offset the local rect and clip rect by the shadow offset. // Offset the local rect and clip rect by the shadow offset.
let mut info = pending_primitive.info.clone(); let mut info = pending_primitive.info.clone();
@ -2156,9 +2152,8 @@ impl<'a> DisplayListFlattener<'a> {
&mut self, &mut self,
pending_primitive: PendingPrimitive<P>, pending_primitive: PendingPrimitive<P>,
) where ) where
P: Internable<InternData = PrimitiveSceneData> + IsVisible, P: InternablePrimitive + IsVisible,
P::Source: AsInstanceKind<Handle<P::Marker>> + InternDebug, Interners: AsMut<Interner<P>>,
Interners: InternerMut<P>,
{ {
// For a normal primitive, if it has alpha > 0, then we add this // For a normal primitive, if it has alpha > 0, then we add this
// as a normal primitive to the parent picture. // as a normal primitive to the parent picture.
@ -2681,14 +2676,6 @@ impl<'a> DisplayListFlattener<'a> {
} }
} }
pub trait AsInstanceKind<H> {
fn as_instance_kind(
&self,
data_handle: H,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind;
}
pub trait CreateShadow { pub trait CreateShadow {
fn create_shadow(&self, shadow: &Shadow) -> Self; fn create_shadow(&self, shadow: &Shadow) -> Self;

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

@ -7,10 +7,10 @@ use gpu_cache::{GpuCacheHandle};
use frame_builder::FrameBuildingState; use frame_builder::FrameBuildingState;
use gpu_cache::GpuDataRequest; use gpu_cache::GpuDataRequest;
use intern; use intern;
use api::{ComponentTransferFuncType}; use api::{FilterDataIntern, ComponentTransferFuncType};
pub use intern_types::filterdata::Handle as FilterDataHandle; pub type FilterDataHandle = intern::Handle<FilterDataIntern>;
#[derive(Debug, Clone, MallocSizeOf, PartialEq)] #[derive(Debug, Clone, MallocSizeOf, PartialEq)]
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
@ -144,6 +144,12 @@ impl SFilterDataTemplate {
} }
} }
impl intern::Internable for FilterDataIntern {
type Key = SFilterDataKey;
type StoreData = SFilterDataTemplate;
type InternData = ();
}
fn push_component_transfer_data( fn push_component_transfer_data(
func_comp: &SFilterDataComponent, func_comp: &SFilterDataComponent,
request: &mut GpuDataRequest, request: &mut GpuDataRequest,

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

@ -33,7 +33,6 @@
//! stored inside each handle. This is then used for //! stored inside each handle. This is then used for
//! cache invalidation. //! cache invalidation.
use api::{LayoutPrimitiveInfo};
use internal_types::FastHashMap; use internal_types::FastHashMap;
use malloc_size_of::MallocSizeOf; use malloc_size_of::MallocSizeOf;
use profiler::ResourceProfileCounter; use profiler::ResourceProfileCounter;
@ -79,15 +78,28 @@ impl ItemUid {
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Copy, Clone, MallocSizeOf)] #[derive(Debug, MallocSizeOf)]
pub struct Handle<M: Copy> { pub struct Handle<I> {
index: u32, index: u32,
epoch: Epoch, epoch: Epoch,
uid: ItemUid, uid: ItemUid,
_marker: PhantomData<M>, _marker: PhantomData<I>,
} }
impl <M> Handle<M> where M: Copy { impl<I> Clone for Handle<I> {
fn clone(&self) -> Self {
Handle {
index: self.index,
epoch: self.epoch,
uid: self.uid,
_marker: self._marker,
}
}
}
impl<I> Copy for Handle<I> {}
impl<I> Handle<I> {
pub fn uid(&self) -> ItemUid { pub fn uid(&self) -> ItemUid {
self.uid self.uid
} }
@ -118,46 +130,34 @@ pub trait InternDebug {
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
pub struct DataStore<S, T: MallocSizeOf, M> { pub struct DataStore<I: Internable> {
items: Vec<Option<T>>, items: Vec<Option<I::StoreData>>,
_source: PhantomData<S>,
_marker: PhantomData<M>,
} }
impl<S, T, M> ::std::default::Default for DataStore<S, T, M> impl<I: Internable> Default for DataStore<I> {
where
S: Debug + MallocSizeOf,
T: From<S> + MallocSizeOf,
M: Debug
{
fn default() -> Self { fn default() -> Self {
DataStore { DataStore {
items: Vec::new(), items: Vec::new(),
_source: PhantomData,
_marker: PhantomData,
} }
} }
} }
impl<S, T, M> DataStore<S, T, M> impl<I: Internable> DataStore<I> {
where
S: Debug + MallocSizeOf,
T: From<S> + MallocSizeOf,
M: Debug
{
/// Apply any updates from the scene builder thread to /// Apply any updates from the scene builder thread to
/// this data store. /// this data store.
pub fn apply_updates( pub fn apply_updates(
&mut self, &mut self,
update_list: UpdateList<S>, update_list: UpdateList<I::Key>,
profile_counter: &mut ResourceProfileCounter, profile_counter: &mut ResourceProfileCounter,
) { ) {
let mut data_iter = update_list.data.into_iter(); let mut data_iter = update_list.data.into_iter();
for update in update_list.updates { for update in update_list.updates {
match update.kind { match update.kind {
UpdateKind::Insert => { UpdateKind::Insert => {
self.items.entry(update.index). let value = data_iter.next().unwrap().into();
set(Some(T::from(data_iter.next().unwrap()))); self.items
.entry(update.index)
.set(Some(value));
} }
UpdateKind::Remove => { UpdateKind::Remove => {
self.items[update.index] = None; self.items[update.index] = None;
@ -165,7 +165,7 @@ where
} }
} }
let per_item_size = mem::size_of::<S>() + mem::size_of::<T>(); let per_item_size = mem::size_of::<I::Key>() + mem::size_of::<I::StoreData>();
profile_counter.set(self.items.len(), per_item_size * self.items.len()); profile_counter.set(self.items.len(), per_item_size * self.items.len());
debug_assert!(data_iter.next().is_none()); debug_assert!(data_iter.next().is_none());
@ -173,27 +173,17 @@ where
} }
/// Retrieve an item from the store via handle /// Retrieve an item from the store via handle
impl<S, T, M> ops::Index<Handle<M>> for DataStore<S, T, M> impl<I: Internable> ops::Index<Handle<I>> for DataStore<I> {
where type Output = I::StoreData;
S: MallocSizeOf, fn index(&self, handle: Handle<I>) -> &I::StoreData {
T: MallocSizeOf,
M: Copy
{
type Output = T;
fn index(&self, handle: Handle<M>) -> &T {
self.items[handle.index as usize].as_ref().expect("Bad datastore lookup") self.items[handle.index as usize].as_ref().expect("Bad datastore lookup")
} }
} }
/// Retrieve a mutable item from the store via handle /// Retrieve a mutable item from the store via handle
/// Retrieve an item from the store via handle /// Retrieve an item from the store via handle
impl<S, T, M> ops::IndexMut<Handle<M>> for DataStore<S, T, M> impl<I: Internable> ops::IndexMut<Handle<I>> for DataStore<I> {
where fn index_mut(&mut self, handle: Handle<I>) -> &mut I::StoreData {
S: MallocSizeOf,
T: MallocSizeOf,
M: Copy
{
fn index_mut(&mut self, handle: Handle<M>) -> &mut T {
self.items[handle.index as usize].as_mut().expect("Bad datastore lookup") self.items[handle.index as usize].as_mut().expect("Bad datastore lookup")
} }
} }
@ -206,33 +196,23 @@ where
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
pub struct Interner<S, D, M> pub struct Interner<I: Internable> {
where
S: Eq + Hash + Clone + Debug + MallocSizeOf,
D: MallocSizeOf,
M: Copy + MallocSizeOf,
{
/// Uniquely map an interning key to a handle /// Uniquely map an interning key to a handle
map: FastHashMap<S, Handle<M>>, map: FastHashMap<I::Key, Handle<I>>,
/// List of free slots in the data store for re-use. /// List of free slots in the data store for re-use.
free_list: Vec<usize>, free_list: Vec<usize>,
/// Pending list of updates that need to be applied. /// Pending list of updates that need to be applied.
updates: Vec<Update>, updates: Vec<Update>,
/// Pending new data to insert. /// Pending new data to insert.
update_data: Vec<S>, update_data: Vec<I::Key>,
/// The current epoch for the interner. /// The current epoch for the interner.
current_epoch: Epoch, current_epoch: Epoch,
/// The information associated with each interned /// The information associated with each interned
/// item that can be accessed by the interner. /// item that can be accessed by the interner.
local_data: Vec<D>, local_data: Vec<I::InternData>,
} }
impl<S, D, M> ::std::default::Default for Interner<S, D, M> impl<I: Internable> Default for Interner<I> {
where
S: Eq + Hash + Clone + Debug + MallocSizeOf,
D: MallocSizeOf,
M: Copy + Debug + MallocSizeOf,
{
fn default() -> Self { fn default() -> Self {
Interner { Interner {
map: FastHashMap::default(), map: FastHashMap::default(),
@ -245,12 +225,7 @@ where
} }
} }
impl<S, D, M> Interner<S, D, M> impl<I: Internable> Interner<I> {
where
S: Eq + Hash + Clone + Debug + InternDebug + MallocSizeOf,
D: MallocSizeOf,
M: Copy + Debug + MallocSizeOf
{
/// Intern a data structure, and return a handle to /// Intern a data structure, and return a handle to
/// that data. The handle can then be stored in the /// that data. The handle can then be stored in the
/// frame builder, and safely accessed via the data /// frame builder, and safely accessed via the data
@ -260,9 +235,9 @@ where
/// key isn't already interned. /// key isn't already interned.
pub fn intern<F>( pub fn intern<F>(
&mut self, &mut self,
data: &S, data: &I::Key,
f: F, fun: F,
) -> Handle<M> where F: FnOnce() -> D { ) -> Handle<I> where F: FnOnce() -> I::InternData {
// Use get_mut rather than entry here to avoid // Use get_mut rather than entry here to avoid
// cloning the (sometimes large) key in the common // cloning the (sometimes large) key in the common
// case, where the data already exists in the interner. // case, where the data already exists in the interner.
@ -303,7 +278,7 @@ where
// Create the local data for this item that is // Create the local data for this item that is
// being interned. // being interned.
self.local_data.entry(index).set(f()); self.local_data.entry(index).set(fun());
handle handle
} }
@ -311,7 +286,7 @@ where
/// Retrieve the pending list of updates for an interner /// Retrieve the pending list of updates for an interner
/// that need to be applied to the data store. Also run /// that need to be applied to the data store. Also run
/// a GC step that removes old entries. /// a GC step that removes old entries.
pub fn end_frame_and_get_pending_updates(&mut self) -> UpdateList<S> { pub fn end_frame_and_get_pending_updates(&mut self) -> UpdateList<I::Key> {
let mut updates = self.updates.take_and_preallocate(); let mut updates = self.updates.take_and_preallocate();
let data = self.update_data.take_and_preallocate(); let data = self.update_data.take_and_preallocate();
@ -354,30 +329,36 @@ where
} }
/// Retrieve the local data for an item from the interner via handle /// Retrieve the local data for an item from the interner via handle
impl<S, D, M> ops::Index<Handle<M>> for Interner<S, D, M> impl<I: Internable> ops::Index<Handle<I>> for Interner<I> {
where type Output = I::InternData;
S: Eq + Clone + Hash + Debug + MallocSizeOf, fn index(&self, handle: Handle<I>) -> &I::InternData {
D: MallocSizeOf,
M: Copy + Debug + MallocSizeOf
{
type Output = D;
fn index(&self, handle: Handle<M>) -> &D {
&self.local_data[handle.index as usize] &self.local_data[handle.index as usize]
} }
} }
/// Implement `Internable` for a type that wants participate in interning. // The trick to make trait bounds configurable by features.
/// mod dummy {
/// see DisplayListFlattener::add_interned_primitive<P> #[cfg(not(feature = "capture"))]
pub trait Internable { pub trait Serialize {}
type Marker: Copy + Debug + MallocSizeOf; #[cfg(not(feature = "capture"))]
type Source: Eq + Hash + Clone + Debug + MallocSizeOf; impl<T> Serialize for T {}
type StoreData: From<Self::Source> + MallocSizeOf; #[cfg(not(feature = "replay"))]
type InternData: MallocSizeOf; pub trait Deserialize<'a> {}
#[cfg(not(feature = "replay"))]
/// Build a new key from self with `info`. impl<'a, T> Deserialize<'a> for T {}
fn build_key( }
self, #[cfg(feature = "capture")]
info: &LayoutPrimitiveInfo, use serde::Serialize as InternSerialize;
) -> Self::Source; #[cfg(not(feature = "capture"))]
use self::dummy::Serialize as InternSerialize;
#[cfg(feature = "replay")]
use serde::Deserialize as InternDeserialize;
#[cfg(not(feature = "replay"))]
use self::dummy::Deserialize as InternDeserialize;
/// Implement `Internable` for a type that wants to participate in interning.
pub trait Internable: MallocSizeOf {
type Key: Eq + Hash + Clone + Debug + MallocSizeOf + InternDebug + InternSerialize + for<'a> InternDeserialize<'a>;
type StoreData: From<Self::Key> + MallocSizeOf + InternSerialize + for<'a> InternDeserialize<'a>;
type InternData: MallocSizeOf + InternSerialize + for<'a> InternDeserialize<'a>;
} }

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

@ -1,114 +0,0 @@
/* 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/. */
macro_rules! common {
() => (
use ::intern;
#[allow(unused_imports)]
use ::prim_store::PrimitiveSceneData;
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
pub struct Marker;
pub type Handle = intern::Handle<Marker>;
)
}
pub mod clip {
common!();
use ::clip::{ClipItemKey, ClipNode};
pub type Store = intern::DataStore<ClipItemKey, ClipNode, Marker>;
pub type UpdateList = intern::UpdateList<ClipItemKey>;
pub type Interner = intern::Interner<ClipItemKey, (), Marker>;
}
pub mod prim {
common!();
use ::prim_store::{PrimitiveKey, PrimitiveTemplate};
pub type Store = intern::DataStore<PrimitiveKey, PrimitiveTemplate, Marker>;
pub type UpdateList = intern::UpdateList<PrimitiveKey>;
pub type Interner = intern::Interner<PrimitiveKey, PrimitiveSceneData, Marker>;
}
pub mod normal_border {
common!();
use ::prim_store::borders::{NormalBorderKey, NormalBorderTemplate};
pub type Store = intern::DataStore<NormalBorderKey, NormalBorderTemplate, Marker>;
pub type UpdateList = intern::UpdateList<NormalBorderKey>;
pub type Interner = intern::Interner<NormalBorderKey, PrimitiveSceneData, Marker>;
}
pub mod image_border {
common!();
use ::prim_store::borders::{ImageBorderKey, ImageBorderTemplate};
pub type Store = intern::DataStore<ImageBorderKey, ImageBorderTemplate, Marker>;
pub type UpdateList = intern::UpdateList<ImageBorderKey>;
pub type Interner = intern::Interner<ImageBorderKey, PrimitiveSceneData, Marker>;
}
pub mod image {
common!();
use ::prim_store::image::{ImageKey, ImageTemplate};
pub type Store = intern::DataStore<ImageKey, ImageTemplate, Marker>;
pub type UpdateList = intern::UpdateList<ImageKey>;
pub type Interner = intern::Interner<ImageKey, PrimitiveSceneData, Marker>;
}
pub mod yuv_image {
common!();
use ::prim_store::image::{YuvImageKey, YuvImageTemplate};
pub type Store = intern::DataStore<YuvImageKey, YuvImageTemplate, Marker>;
pub type UpdateList = intern::UpdateList<YuvImageKey>;
pub type Interner = intern::Interner<YuvImageKey, PrimitiveSceneData, Marker>;
}
pub mod line_decoration {
use ::prim_store::line_dec::{LineDecorationKey, LineDecorationTemplate};
common!();
pub type Store = intern::DataStore<LineDecorationKey, LineDecorationTemplate, Marker>;
pub type UpdateList = intern::UpdateList<LineDecorationKey>;
pub type Interner = intern::Interner<LineDecorationKey, PrimitiveSceneData, Marker>;
}
pub mod linear_grad {
common!();
use ::prim_store::gradient::{LinearGradientKey, LinearGradientTemplate};
pub type Store = intern::DataStore<LinearGradientKey, LinearGradientTemplate, Marker>;
pub type UpdateList = intern::UpdateList<LinearGradientKey>;
pub type Interner = intern::Interner<LinearGradientKey, PrimitiveSceneData, Marker>;
}
pub mod radial_grad {
common!();
use ::prim_store::gradient::{RadialGradientKey, RadialGradientTemplate};
pub type Store = intern::DataStore<RadialGradientKey, RadialGradientTemplate, Marker>;
pub type UpdateList = intern::UpdateList<RadialGradientKey>;
pub type Interner = intern::Interner<RadialGradientKey, PrimitiveSceneData, Marker>;
}
pub mod picture {
common!();
use ::prim_store::picture::{PictureKey, PictureTemplate};
pub type Store = intern::DataStore<PictureKey, PictureTemplate, Marker>;
pub type UpdateList = intern::UpdateList<PictureKey>;
pub type Interner = intern::Interner<PictureKey, PrimitiveSceneData, Marker>;
}
pub mod text_run {
common!();
use ::prim_store::text_run::{TextRunKey, TextRunTemplate};
pub type Store = intern::DataStore<TextRunKey, TextRunTemplate, Marker>;
pub type UpdateList = intern::UpdateList<TextRunKey>;
pub type Interner = intern::Interner<TextRunKey, PrimitiveSceneData, Marker>;
}
pub mod filterdata {
common!();
use ::filterdata::{SFilterDataKey, SFilterDataTemplate};
pub type Store = intern::DataStore<SFilterDataKey, SFilterDataTemplate, Marker>;
pub type UpdateList = intern::UpdateList<SFilterDataKey>;
pub type Interner = intern::Interner<SFilterDataKey, (), Marker>;
}

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

@ -104,7 +104,6 @@ mod gpu_types;
mod hit_test; mod hit_test;
mod image; mod image;
mod intern; mod intern;
mod intern_types;
mod internal_types; mod internal_types;
mod picture; mod picture;
mod prim_store; mod prim_store;

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

@ -3114,7 +3114,7 @@ impl PicturePrimitive {
PictureSurface::RenderTask(render_task_id) PictureSurface::RenderTask(render_task_id)
} }
PictureCompositeMode::ComponentTransferFilter(handle) => { PictureCompositeMode::ComponentTransferFilter(handle) => {
let filter_data = &mut data_stores.filterdata[handle]; let filter_data = &mut data_stores.filter_data[handle];
filter_data.update(frame_state); filter_data.update(frame_state);
let uv_rect_kind = calculate_uv_rect_kind( let uv_rect_kind = calculate_uv_rect_kind(

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

@ -9,16 +9,15 @@ use api::{
}; };
use border::create_border_segments; use border::create_border_segments;
use border::NormalBorderAu; use border::NormalBorderAu;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible}; use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState}; use frame_builder::{FrameBuildingState};
use gpu_cache::GpuDataRequest; use gpu_cache::GpuDataRequest;
use intern; use intern;
use intern_types;
use prim_store::{ use prim_store::{
BorderSegmentInfo, BrushSegment, NinePatchDescriptor, PrimKey, BorderSegmentInfo, BrushSegment, NinePatchDescriptor, PrimKey,
PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData, PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData,
PrimitiveStore PrimitiveStore, InternablePrimitive,
}; };
use resource_cache::ImageRequest; use resource_cache::ImageRequest;
use storage; use storage;
@ -49,22 +48,6 @@ impl NormalBorderKey {
impl intern::InternDebug for NormalBorderKey {} impl intern::InternDebug for NormalBorderKey {}
impl AsInstanceKind<NormalBorderDataHandle> for NormalBorderKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: NormalBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::NormalBorder {
data_handle,
cache_handles: storage::Range::empty(),
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -160,16 +143,16 @@ impl From<NormalBorderKey> for NormalBorderTemplate {
} }
} }
pub use intern_types::normal_border::Handle as NormalBorderDataHandle; pub type NormalBorderDataHandle = intern::Handle<NormalBorderPrim>;
impl intern::Internable for NormalBorderPrim { impl intern::Internable for NormalBorderPrim {
type Marker = intern_types::normal_border::Marker; type Key = NormalBorderKey;
type Source = NormalBorderKey;
type StoreData = NormalBorderTemplate; type StoreData = NormalBorderTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for NormalBorderPrim {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> NormalBorderKey { ) -> NormalBorderKey {
@ -178,6 +161,18 @@ impl intern::Internable for NormalBorderPrim {
self, self,
) )
} }
fn make_instance_kind(
_key: NormalBorderKey,
data_handle: NormalBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::NormalBorder {
data_handle,
cache_handles: storage::Range::empty(),
}
}
} }
impl CreateShadow for NormalBorderPrim { impl CreateShadow for NormalBorderPrim {
@ -225,20 +220,6 @@ impl ImageBorderKey {
impl intern::InternDebug for ImageBorderKey {} impl intern::InternDebug for ImageBorderKey {}
impl AsInstanceKind<ImageBorderDataHandle> for ImageBorderKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: ImageBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::ImageBorder {
data_handle
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
@ -330,16 +311,16 @@ impl From<ImageBorderKey> for ImageBorderTemplate {
} }
} }
pub use intern_types::image_border::Handle as ImageBorderDataHandle; pub type ImageBorderDataHandle = intern::Handle<ImageBorder>;
impl intern::Internable for ImageBorder { impl intern::Internable for ImageBorder {
type Marker = intern_types::image_border::Marker; type Key = ImageBorderKey;
type Source = ImageBorderKey;
type StoreData = ImageBorderTemplate; type StoreData = ImageBorderTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for ImageBorder {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> ImageBorderKey { ) -> ImageBorderKey {
@ -348,6 +329,17 @@ impl intern::Internable for ImageBorder {
self, self,
) )
} }
fn make_instance_kind(
_key: ImageBorderKey,
data_handle: ImageBorderDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::ImageBorder {
data_handle
}
}
} }
impl IsVisible for ImageBorder { impl IsVisible for ImageBorder {

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

@ -6,15 +6,14 @@ use api::{
ColorF, ColorU,ExtendMode, GradientStop, LayoutPoint, LayoutSize, ColorF, ColorU,ExtendMode, GradientStop, LayoutPoint, LayoutSize,
LayoutPrimitiveInfo, PremultipliedColorF, LayoutVector2D, LayoutPrimitiveInfo, PremultipliedColorF, LayoutVector2D,
}; };
use display_list_flattener::{AsInstanceKind, IsVisible}; use display_list_flattener::IsVisible;
use frame_builder::FrameBuildingState; use frame_builder::FrameBuildingState;
use gpu_cache::{GpuCacheHandle, GpuDataRequest}; use gpu_cache::{GpuCacheHandle, GpuDataRequest};
use intern::{Internable, InternDebug}; use intern::{Internable, InternDebug, Handle as InternHandle};
use intern_types;
use prim_store::{BrushSegment, GradientTileRange}; use prim_store::{BrushSegment, GradientTileRange};
use prim_store::{PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData}; use prim_store::{PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData};
use prim_store::{PrimKeyCommonData, PrimTemplateCommonData, PrimitiveStore}; use prim_store::{PrimKeyCommonData, PrimTemplateCommonData, PrimitiveStore};
use prim_store::{NinePatchDescriptor, PointKey, SizeKey}; use prim_store::{NinePatchDescriptor, PointKey, SizeKey, InternablePrimitive};
use std::{hash, ops::{Deref, DerefMut}, mem}; use std::{hash, ops::{Deref, DerefMut}, mem};
use util::pack_as_float; use util::pack_as_float;
@ -77,22 +76,6 @@ impl LinearGradientKey {
impl InternDebug for LinearGradientKey {} impl InternDebug for LinearGradientKey {}
impl AsInstanceKind<LinearGradientDataHandle> for LinearGradientKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: LinearGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LinearGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -227,8 +210,11 @@ impl LinearGradientTemplate {
} }
} }
pub type LinearGradientDataHandle = intern_types::linear_grad::Handle; pub type LinearGradientDataHandle = InternHandle<LinearGradient>;
#[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct LinearGradient { pub struct LinearGradient {
pub extend_mode: ExtendMode, pub extend_mode: ExtendMode,
pub start_point: PointKey, pub start_point: PointKey,
@ -241,13 +227,13 @@ pub struct LinearGradient {
} }
impl Internable for LinearGradient { impl Internable for LinearGradient {
type Marker = intern_types::linear_grad::Marker; type Key = LinearGradientKey;
type Source = LinearGradientKey;
type StoreData = LinearGradientTemplate; type StoreData = LinearGradientTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for LinearGradient {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> LinearGradientKey { ) -> LinearGradientKey {
@ -257,6 +243,18 @@ impl Internable for LinearGradient {
self self
) )
} }
fn make_instance_kind(
_key: LinearGradientKey,
data_handle: LinearGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LinearGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
} }
impl IsVisible for LinearGradient { impl IsVisible for LinearGradient {
@ -326,22 +324,6 @@ impl RadialGradientKey {
impl InternDebug for RadialGradientKey {} impl InternDebug for RadialGradientKey {}
impl AsInstanceKind<RadialGradientDataHandle> for RadialGradientKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: RadialGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::RadialGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -447,8 +429,11 @@ impl RadialGradientTemplate {
} }
} }
pub type RadialGradientDataHandle = intern_types::radial_grad::Handle; pub type RadialGradientDataHandle = InternHandle<RadialGradient>;
#[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct RadialGradient { pub struct RadialGradient {
pub extend_mode: ExtendMode, pub extend_mode: ExtendMode,
pub center: PointKey, pub center: PointKey,
@ -460,13 +445,13 @@ pub struct RadialGradient {
} }
impl Internable for RadialGradient { impl Internable for RadialGradient {
type Marker = intern_types::radial_grad::Marker; type Key = RadialGradientKey;
type Source = RadialGradientKey;
type StoreData = RadialGradientTemplate; type StoreData = RadialGradientTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for RadialGradient {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> RadialGradientKey { ) -> RadialGradientKey {
@ -476,6 +461,18 @@ impl Internable for RadialGradient {
self, self,
) )
} }
fn make_instance_kind(
_key: RadialGradientKey,
data_handle: RadialGradientDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::RadialGradient {
data_handle,
visible_tiles_range: GradientTileRange::empty(),
}
}
} }
impl IsVisible for RadialGradient { impl IsVisible for RadialGradient {

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

@ -8,16 +8,15 @@ use api::{
PremultipliedColorF, Shadow, TileOffset, YuvColorSpace, YuvFormat, LayoutVector2D, PremultipliedColorF, Shadow, TileOffset, YuvColorSpace, YuvFormat, LayoutVector2D,
}; };
use api::ImageKey as ApiImageKey; use api::ImageKey as ApiImageKey;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible}; use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::FrameBuildingState; use frame_builder::FrameBuildingState;
use gpu_cache::{GpuDataRequest}; use gpu_cache::{GpuDataRequest};
use intern::{Internable, InternDebug}; use intern::{Internable, InternDebug, Handle as InternHandle};
use intern_types;
use prim_store::{ use prim_store::{
EdgeAaSegmentMask, OpacityBindingIndex, PrimitiveInstanceKind, EdgeAaSegmentMask, OpacityBindingIndex, PrimitiveInstanceKind,
PrimitiveOpacity, PrimitiveSceneData, PrimKey, PrimKeyCommonData, PrimitiveOpacity, PrimitiveSceneData, PrimKey, PrimKeyCommonData,
PrimTemplate, PrimTemplateCommonData, PrimitiveStore, SegmentInstanceIndex, PrimTemplate, PrimTemplateCommonData, PrimitiveStore, SegmentInstanceIndex,
SizeKey SizeKey, InternablePrimitive,
}; };
use render_task::{ use render_task::{
BlitSource, RenderTask, RenderTaskCacheEntryHandle, RenderTaskCacheKey, BlitSource, RenderTask, RenderTaskCacheEntryHandle, RenderTaskCacheKey,
@ -101,31 +100,6 @@ impl ImageKey {
impl InternDebug for ImageKey {} impl InternDebug for ImageKey {}
impl AsInstanceKind<ImageDataHandle> for ImageKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: ImageDataHandle,
prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// TODO(gw): Refactor this to not need a separate image
// instance (see ImageInstance struct).
let image_instance_index = prim_store.images.push(ImageInstance {
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
tight_local_clip_rect: LayoutRect::zero(),
visible_tiles: Vec::new(),
});
PrimitiveInstanceKind::Image {
data_handle,
image_instance_index,
}
}
}
// Where to find the texture data for an image primitive. // Where to find the texture data for an image primitive.
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
@ -338,16 +312,16 @@ impl From<ImageKey> for ImageTemplate {
} }
} }
pub use intern_types::image::Handle as ImageDataHandle; pub type ImageDataHandle = InternHandle<Image>;
impl Internable for Image { impl Internable for Image {
type Marker = intern_types::image::Marker; type Key = ImageKey;
type Source = ImageKey;
type StoreData = ImageTemplate; type StoreData = ImageTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for Image {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> ImageKey { ) -> ImageKey {
@ -357,6 +331,27 @@ impl Internable for Image {
self self
) )
} }
fn make_instance_kind(
_key: ImageKey,
data_handle: ImageDataHandle,
prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// TODO(gw): Refactor this to not need a separate image
// instance (see ImageInstance struct).
let image_instance_index = prim_store.images.push(ImageInstance {
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
tight_local_clip_rect: LayoutRect::zero(),
visible_tiles: Vec::new(),
});
PrimitiveInstanceKind::Image {
data_handle,
image_instance_index,
}
}
} }
impl CreateShadow for Image { impl CreateShadow for Image {
@ -413,22 +408,6 @@ impl YuvImageKey {
impl InternDebug for YuvImageKey {} impl InternDebug for YuvImageKey {}
impl AsInstanceKind<YuvImageDataHandle> for YuvImageKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: YuvImageDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::YuvImage {
data_handle,
segment_instance_index: SegmentInstanceIndex::INVALID
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -505,25 +484,37 @@ impl From<YuvImageKey> for YuvImageTemplate {
} }
} }
pub use intern_types::yuv_image::Handle as YuvImageDataHandle; pub type YuvImageDataHandle = InternHandle<YuvImage>;
impl Internable for YuvImage { impl Internable for YuvImage {
type Marker = intern_types::yuv_image::Marker; type Key = YuvImageKey;
type Source = YuvImageKey;
type StoreData = YuvImageTemplate; type StoreData = YuvImageTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for YuvImage {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> YuvImageKey { ) -> YuvImageKey {
YuvImageKey::new( YuvImageKey::new(
info.is_backface_visible, info.is_backface_visible,
info.rect.size, info.rect.size,
self self,
) )
} }
fn make_instance_kind(
_key: YuvImageKey,
data_handle: YuvImageDataHandle,
_prim_store: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::YuvImage {
data_handle,
segment_instance_index: SegmentInstanceIndex::INVALID
}
}
} }
impl IsVisible for YuvImage { impl IsVisible for YuvImage {

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

@ -0,0 +1,12 @@
/* 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/. */
// list of all interned primitives to match enumerate_interners!
pub use prim_store::borders::{ImageBorder, NormalBorderPrim};
pub use prim_store::image::{Image, YuvImage};
pub use prim_store::line_dec::{LineDecoration};
pub use prim_store::gradient::{LinearGradient, RadialGradient};
pub use prim_store::picture::Picture;
pub use prim_store::text_run::TextRun;

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

@ -7,17 +7,17 @@ use api::{
LineOrientation, LineStyle, PremultipliedColorF, Shadow, LineOrientation, LineStyle, PremultipliedColorF, Shadow,
}; };
use app_units::Au; use app_units::Au;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible}; use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState}; use frame_builder::{FrameBuildingState};
use gpu_cache::GpuDataRequest; use gpu_cache::GpuDataRequest;
use intern; use intern;
use intern_types;
use prim_store::{ use prim_store::{
PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData, PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
PrimitiveSceneData, PrimitiveStore, InternablePrimitive, PrimitiveSceneData, PrimitiveStore,
}; };
use prim_store::PrimitiveInstanceKind; use prim_store::PrimitiveInstanceKind;
#[derive(Clone, Debug, Hash, MallocSizeOf, PartialEq, Eq)] #[derive(Clone, Debug, Hash, MallocSizeOf, PartialEq, Eq)]
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
@ -59,22 +59,6 @@ impl LineDecorationKey {
impl intern::InternDebug for LineDecorationKey {} impl intern::InternDebug for LineDecorationKey {}
impl AsInstanceKind<LineDecorationDataHandle> for LineDecorationKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: LineDecorationDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LineDecoration {
data_handle,
cache_handle: None,
}
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -135,16 +119,16 @@ impl From<LineDecorationKey> for LineDecorationTemplate {
} }
} }
pub use intern_types::line_decoration::Handle as LineDecorationDataHandle; pub type LineDecorationDataHandle = intern::Handle<LineDecoration>;
impl intern::Internable for LineDecoration { impl intern::Internable for LineDecoration {
type Marker = intern_types::line_decoration::Marker; type Key = LineDecorationKey;
type Source = LineDecorationKey;
type StoreData = LineDecorationTemplate; type StoreData = LineDecorationTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for LineDecoration {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> LineDecorationKey { ) -> LineDecorationKey {
@ -153,6 +137,18 @@ impl intern::Internable for LineDecoration {
self, self,
) )
} }
fn make_instance_kind(
_key: LineDecorationKey,
data_handle: LineDecorationDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
PrimitiveInstanceKind::LineDecoration {
data_handle,
cache_handle: None,
}
}
} }
impl CreateShadow for LineDecoration { impl CreateShadow for LineDecoration {

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

@ -2,15 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, ClipMode, ColorF, PictureRect, ColorU, LayoutVector2D}; use api::{BorderRadius, ClipMode, ColorF};
use api::{DeviceIntRect, DevicePixelScale, DeviceRect, WorldVector2D};
use api::{FilterOp, ImageRendering, TileOffset, RepeatMode, WorldPoint, WorldSize}; use api::{FilterOp, ImageRendering, TileOffset, RepeatMode, WorldPoint, WorldSize};
use api::{LayoutPoint, LayoutRect, LayoutSideOffsets, LayoutSize, PicturePoint}; use api::{PremultipliedColorF, PropertyBinding, Shadow};
use api::{PremultipliedColorF, PropertyBinding, Shadow, DeviceVector2D}; use api::{BoxShadowClipMode, LineStyle, LineOrientation, AuHelpers};
use api::{WorldPixel, BoxShadowClipMode, WorldRect, LayoutToWorldScale}; use api::{LayoutPrimitiveInfo, PrimitiveKeyKind};
use api::{PicturePixel, RasterPixel, LineStyle, LineOrientation, AuHelpers}; use api::units::*;
use api::{LayoutPrimitiveInfo};
use api::DevicePoint;
use border::{get_max_scale_for_border, build_border_instances}; use border::{get_max_scale_for_border, build_border_instances};
use border::BorderSegmentCacheKey; use border::BorderSegmentCacheKey;
use clip::{ClipStore}; use clip::{ClipStore};
@ -18,7 +15,7 @@ use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex
use clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance, ClipItem}; use clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance, ClipItem};
use debug_colors; use debug_colors;
use debug_render::DebugItem; use debug_render::DebugItem;
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible}; use display_list_flattener::{CreateShadow, IsVisible};
use euclid::{SideOffsets2D, TypedTransform3D, TypedRect, TypedScale, TypedSize2D}; use euclid::{SideOffsets2D, TypedTransform3D, TypedRect, TypedScale, TypedSize2D};
use frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState}; use frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState};
use frame_builder::{PrimitiveContext, FrameVisibilityContext, FrameVisibilityState}; use frame_builder::{PrimitiveContext, FrameVisibilityContext, FrameVisibilityState};
@ -60,6 +57,7 @@ pub mod image;
pub mod line_dec; pub mod line_dec;
pub mod picture; pub mod picture;
pub mod text_run; pub mod text_run;
pub mod interned;
/// Counter for unique primitive IDs for debug tracing. /// Counter for unique primitive IDs for debug tracing.
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -329,19 +327,6 @@ pub struct PrimitiveSceneData {
pub is_backface_visible: bool, pub is_backface_visible: bool,
} }
/// Information specific to a primitive type that
/// uniquely identifies a primitive template by key.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
pub enum PrimitiveKeyKind {
/// Clear an existing rect, used for special effects on some platforms.
Clear,
Rectangle {
color: ColorU,
},
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Clone, MallocSizeOf, PartialEq)] #[derive(Debug, Clone, MallocSizeOf, PartialEq)]
@ -634,32 +619,6 @@ impl PrimitiveKey {
impl intern::InternDebug for PrimitiveKey {} impl intern::InternDebug for PrimitiveKey {}
impl AsInstanceKind<PrimitiveDataHandle> for PrimitiveKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: PrimitiveDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
match self.kind {
PrimitiveKeyKind::Clear => {
PrimitiveInstanceKind::Clear {
data_handle
}
}
PrimitiveKeyKind::Rectangle { .. } => {
PrimitiveInstanceKind::Rectangle {
data_handle,
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
}
}
}
}
}
/// The shared information for a given primitive. This is interned and retained /// The shared information for a given primitive. This is interned and retained
/// both across frames and display lists, by comparing the matching PrimitiveKey. /// both across frames and display lists, by comparing the matching PrimitiveKey.
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
@ -675,9 +634,9 @@ pub enum PrimitiveTemplateKind {
/// Construct the primitive template data from a primitive key. This /// Construct the primitive template data from a primitive key. This
/// is invoked when a primitive key is created and the interner /// is invoked when a primitive key is created and the interner
/// doesn't currently contain a primitive with this key. /// doesn't currently contain a primitive with this key.
impl PrimitiveKeyKind { impl From<PrimitiveKeyKind> for PrimitiveTemplateKind {
fn into_template(self) -> PrimitiveTemplateKind { fn from(kind: PrimitiveKeyKind) -> Self {
match self { match kind {
PrimitiveKeyKind::Clear => { PrimitiveKeyKind::Clear => {
PrimitiveTemplateKind::Clear PrimitiveTemplateKind::Clear
} }
@ -746,10 +705,10 @@ impl ops::DerefMut for PrimitiveTemplate {
impl From<PrimitiveKey> for PrimitiveTemplate { impl From<PrimitiveKey> for PrimitiveTemplate {
fn from(item: PrimitiveKey) -> Self { fn from(item: PrimitiveKey) -> Self {
let common = PrimTemplateCommonData::with_key_common(item.common); PrimitiveTemplate {
let kind = item.kind.into_template(); common: PrimTemplateCommonData::with_key_common(item.common),
kind: item.kind.into(),
PrimitiveTemplate { common, kind, } }
} }
} }
@ -795,13 +754,16 @@ impl PrimitiveTemplate {
} }
} }
type PrimitiveDataHandle = intern::Handle<PrimitiveKeyKind>;
impl intern::Internable for PrimitiveKeyKind { impl intern::Internable for PrimitiveKeyKind {
type Marker = ::intern_types::prim::Marker; type Key = PrimitiveKey;
type Source = PrimitiveKey;
type StoreData = PrimitiveTemplate; type StoreData = PrimitiveTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
fn build_key( impl InternablePrimitive for PrimitiveKeyKind {
fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> PrimitiveKey { ) -> PrimitiveKey {
@ -811,9 +773,29 @@ impl intern::Internable for PrimitiveKeyKind {
self, self,
) )
} }
}
use intern_types::prim::Handle as PrimitiveDataHandle; fn make_instance_kind(
key: PrimitiveKey,
data_handle: PrimitiveDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
match key.kind {
PrimitiveKeyKind::Clear => {
PrimitiveInstanceKind::Clear {
data_handle
}
}
PrimitiveKeyKind::Rectangle { .. } => {
PrimitiveInstanceKind::Rectangle {
data_handle,
opacity_binding_index: OpacityBindingIndex::INVALID,
segment_instance_index: SegmentInstanceIndex::INVALID,
}
}
}
}
}
// Maintains a list of opacity bindings that have been collapsed into // Maintains a list of opacity bindings that have been collapsed into
// the color of a single primitive. This is an important optimization // the color of a single primitive. This is an important optimization
@ -3706,6 +3688,24 @@ fn update_opacity_binding(
} }
} }
/// Trait for primitives that are directly internable.
/// see DisplayListFlattener::add_primitive<P>
pub trait InternablePrimitive: intern::Internable<InternData = PrimitiveSceneData> + Sized {
/// Build a new key from self with `info`.
fn into_key(
self,
info: &LayoutPrimitiveInfo,
) -> Self::Key;
fn make_instance_kind(
key: Self::Key,
data_handle: intern::Handle<Self>,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind;
}
#[test] #[test]
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
fn test_struct_sizes() { fn test_struct_sizes() {

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

@ -8,13 +8,13 @@ use api::{
}; };
use intern::ItemUid; use intern::ItemUid;
use app_units::Au; use app_units::Au;
use display_list_flattener::{AsInstanceKind, IsVisible}; use display_list_flattener::IsVisible;
use intern::{Internable, InternDebug}; use intern::{Internable, InternDebug, Handle as InternHandle};
use intern_types;
use picture::PictureCompositeMode; use picture::PictureCompositeMode;
use prim_store::{ use prim_store::{
PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData, PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
PrimitiveInstanceKind, PrimitiveSceneData, PrimitiveStore, VectorKey, PrimitiveInstanceKind, PrimitiveSceneData, PrimitiveStore, VectorKey,
InternablePrimitive,
}; };
/// Represents a hashable description of how a picture primitive /// Represents a hashable description of how a picture primitive
@ -161,21 +161,6 @@ impl PictureKey {
impl InternDebug for PictureKey {} impl InternDebug for PictureKey {}
impl AsInstanceKind<PictureDataHandle> for PictureKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
_: PictureDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// Should never be hit as this method should not be
// called for pictures.
unreachable!();
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -194,25 +179,36 @@ impl From<PictureKey> for PictureTemplate {
} }
} }
pub use intern_types::picture::Handle as PictureDataHandle; pub type PictureDataHandle = InternHandle<Picture>;
impl Internable for Picture { impl Internable for Picture {
type Marker = intern_types::picture::Marker; type Key = PictureKey;
type Source = PictureKey;
type StoreData = PictureTemplate; type StoreData = PictureTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for Picture {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> PictureKey { ) -> PictureKey {
PictureKey::new( PictureKey::new(
info.is_backface_visible, info.is_backface_visible,
info.rect.size, info.rect.size,
self self,
) )
} }
fn make_instance_kind(
_key: PictureKey,
_: PictureDataHandle,
_: &mut PrimitiveStore,
_reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
// Should never be hit as this method should not be
// called for pictures.
unreachable!();
}
} }
impl IsVisible for Picture { impl IsVisible for Picture {

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

@ -5,20 +5,19 @@
use api::{ColorF, DevicePixelScale, GlyphInstance, LayoutPrimitiveInfo}; use api::{ColorF, DevicePixelScale, GlyphInstance, LayoutPrimitiveInfo};
use api::{LayoutToWorldTransform, RasterSpace}; use api::{LayoutToWorldTransform, RasterSpace};
use api::{LayoutVector2D, Shadow}; use api::{LayoutVector2D, Shadow};
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible}; use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState, PictureContext}; use frame_builder::{FrameBuildingState, PictureContext};
use glyph_rasterizer::{FontInstance, FontTransform, GlyphKey, FONT_SIZE_LIMIT}; use glyph_rasterizer::{FontInstance, FontTransform, GlyphKey, FONT_SIZE_LIMIT};
use gpu_cache::GpuCache; use gpu_cache::GpuCache;
use gpu_types::RasterizationSpace; use gpu_types::RasterizationSpace;
use intern; use intern;
use intern_types;
use prim_store::{PrimitiveOpacity, PrimitiveSceneData, PrimitiveScratchBuffer}; use prim_store::{PrimitiveOpacity, PrimitiveSceneData, PrimitiveScratchBuffer};
use prim_store::{PrimitiveStore, PrimKeyCommonData, PrimTemplateCommonData}; use prim_store::{PrimitiveStore, PrimKeyCommonData, PrimTemplateCommonData};
use render_task::{RenderTaskTree}; use render_task::{RenderTaskTree};
use renderer::{MAX_VERTEX_TEXTURE_WIDTH}; use renderer::{MAX_VERTEX_TEXTURE_WIDTH};
use resource_cache::{ResourceCache}; use resource_cache::{ResourceCache};
use util::{MatrixHelpers}; use util::{MatrixHelpers};
use prim_store::PrimitiveInstanceKind; use prim_store::{InternablePrimitive, PrimitiveInstanceKind};
use std::ops; use std::ops;
use std::sync::Arc; use std::sync::Arc;
use storage; use storage;
@ -53,28 +52,6 @@ impl TextRunKey {
impl intern::InternDebug for TextRunKey {} impl intern::InternDebug for TextRunKey {}
impl AsInstanceKind<TextRunDataHandle> for TextRunKey {
/// Construct a primitive instance that matches the type
/// of primitive key.
fn as_instance_kind(
&self,
data_handle: TextRunDataHandle,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
let run_index = prim_store.text_runs.push(TextRunPrimitive {
used_font: self.font.clone(),
glyph_keys_range: storage::Range::empty(),
reference_frame_relative_offset,
shadow: self.shadow,
raster_space: RasterizationSpace::Screen,
inverse_raster_scale: 1.0,
});
PrimitiveInstanceKind::TextRun{ data_handle, run_index }
}
}
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
@ -157,22 +134,26 @@ impl TextRunTemplate {
} }
} }
pub use intern_types::text_run::Handle as TextRunDataHandle; pub type TextRunDataHandle = intern::Handle<TextRun>;
#[derive(Debug, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct TextRun { pub struct TextRun {
pub font: FontInstance, pub font: FontInstance,
#[ignore_malloc_size_of = "Measured via PrimaryArc"]
pub glyphs: Arc<Vec<GlyphInstance>>, pub glyphs: Arc<Vec<GlyphInstance>>,
pub shadow: bool, pub shadow: bool,
} }
impl intern::Internable for TextRun { impl intern::Internable for TextRun {
type Marker = intern_types::text_run::Marker; type Key = TextRunKey;
type Source = TextRunKey;
type StoreData = TextRunTemplate; type StoreData = TextRunTemplate;
type InternData = PrimitiveSceneData; type InternData = PrimitiveSceneData;
}
/// Build a new key from self with `info`. impl InternablePrimitive for TextRun {
fn build_key( fn into_key(
self, self,
info: &LayoutPrimitiveInfo, info: &LayoutPrimitiveInfo,
) -> TextRunKey { ) -> TextRunKey {
@ -181,6 +162,24 @@ impl intern::Internable for TextRun {
self, self,
) )
} }
fn make_instance_kind(
key: TextRunKey,
data_handle: TextRunDataHandle,
prim_store: &mut PrimitiveStore,
reference_frame_relative_offset: LayoutVector2D,
) -> PrimitiveInstanceKind {
let run_index = prim_store.text_runs.push(TextRunPrimitive {
used_font: key.font.clone(),
glyph_keys_range: storage::Range::empty(),
reference_frame_relative_offset,
shadow: key.shadow,
raster_space: RasterizationSpace::Screen,
inverse_raster_scale: 1.0,
});
PrimitiveInstanceKind::TextRun{ data_handle, run_index }
}
} }
impl CreateShadow for TextRun { impl CreateShadow for TextRun {

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

@ -453,7 +453,7 @@ pub struct IpcProfileCounters {
} }
macro_rules! declare_intern_profile_counters { macro_rules! declare_intern_profile_counters {
( $( $name: ident, )+ ) => { ( $( $name:ident : $ty:ty, )+ ) => {
#[derive(Clone)] #[derive(Clone)]
pub struct InternProfileCounters { pub struct InternProfileCounters {
$( $(
@ -522,6 +522,7 @@ impl BackendProfileCounters {
total_time: TimeProfileCounter::new("Total Display List Time", false), total_time: TimeProfileCounter::new("Total Display List Time", false),
display_lists: ResourceProfileCounter::new("Display Lists Sent"), display_lists: ResourceProfileCounter::new("Display Lists Sent"),
}, },
//TODO: generate this by a macro
intern: InternProfileCounters { intern: InternProfileCounters {
prim: ResourceProfileCounter::new("Interned primitives"), prim: ResourceProfileCounter::new("Interned primitives"),
image: ResourceProfileCounter::new("Interned images"), image: ResourceProfileCounter::new("Interned images"),
@ -534,7 +535,7 @@ impl BackendProfileCounters {
text_run: ResourceProfileCounter::new("Interned text runs"), text_run: ResourceProfileCounter::new("Interned text runs"),
yuv_image: ResourceProfileCounter::new("Interned YUV images"), yuv_image: ResourceProfileCounter::new("Interned YUV images"),
clip: ResourceProfileCounter::new("Interned clips"), clip: ResourceProfileCounter::new("Interned clips"),
filterdata: ResourceProfileCounter::new("Interned filterdata"), filter_data: ResourceProfileCounter::new("Interned filter data"),
}, },
} }
} }

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