Merge m-c to inbound, a=merge

MozReview-Commit-ID: HwfVdTF9Np5
This commit is contained in:
Wes Kocher 2017-03-23 16:55:48 -07:00
commit 1d9dc01136
238 changed files with 23704 additions and 21399 deletions

View File

@ -1,10 +1,6 @@
# Always ignore node_modules.
**/node_modules/**/*.*
# Include these to speed up ESLint, see bug 1347906.
.hg
.git
# Exclude expected objdirs.
obj*/**

View File

@ -630,7 +630,7 @@
init for other error types .-->
<div id="certificateErrorReporting">
<p class="toggle-container-with-text">
<input type="checkbox" id="automaticallyReportInFuture" />
<input type="checkbox" id="automaticallyReportInFuture" role="checkbox" />
<label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic2;</label>
</p>
</div>

View File

@ -49,7 +49,7 @@
<h2>&tabCrashed.requestReport;</h2>
<div class="checkbox-with-label">
<input type="checkbox" id="sendReport"/>
<input type="checkbox" id="sendReport" role="checkbox"/>
<label for="sendReport">&tabCrashed.sendReport2;</label>
</div>
@ -59,13 +59,13 @@
</li>
<li class="checkbox-with-label">
<input type="checkbox" id="includeURL"/>
<input type="checkbox" id="includeURL" role="checkbox"/>
<label for="includeURL">&tabCrashed.includeURL2;</label>
</li>
<li id="requestEmail" hidden="true">
<div class="checkbox-with-label">
<input type="checkbox" id="emailMe"/>
<input type="checkbox" id="emailMe" role="checkbox"/>
<label for="emailMe">&tabCrashed.emailMe;</label>
</div>
<input type="text" id="email" placeholder="&tabCrashed.emailPlaceholder;"/>
@ -75,7 +75,7 @@
<div id="requestAutoSubmit" hidden="true">
<h2>&tabCrashed.requestAutoSubmit2;</h2>
<div class="checkbox-with-label">
<input type="checkbox" id="autoSubmit"/>
<input type="checkbox" id="autoSubmit" role="checkbox"/>
<label for="autoSubmit">&tabCrashed.autoSubmit2;</label>
</div>
</div>

View File

@ -21,13 +21,13 @@
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-reload"
class="menuitem-iconic"
tooltiptext="&reloadButton.tooltip;"
tooltip="dynamic-shortcut-tooltip"
aria-label="&reloadCmd.label;"
oncommand="gContextMenu.reload(event);"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="context-stop"
class="menuitem-iconic"
tooltiptext="&stopButton.tooltip;"
tooltip="dynamic-shortcut-tooltip"
aria-label="&stopCmd.label;"
command="Browser:Stop"/>
<menuitem id="context-bookmarkpage"

View File

@ -5474,19 +5474,29 @@ var gHomeButton = {
const nodeToTooltipMap = {
"bookmarks-menu-button": "bookmarksMenuButton.tooltip",
"context-reload": "reloadButton.tooltip",
"context-stop": "stopButton.tooltip",
"downloads-button": "downloads.tooltip",
"fullscreen-button": "fullscreenButton.tooltip",
"new-window-button": "newWindowButton.tooltip",
"new-tab-button": "newTabButton.tooltip",
"tabs-newtab-button": "newTabButton.tooltip",
"fullscreen-button": "fullscreenButton.tooltip",
"downloads-button": "downloads.tooltip",
"urlbar-reload-button": "reloadButton.tooltip",
"urlbar-stop-button": "stopButton.tooltip",
"urlbar-zoom-button": "urlbar-zoom-button.tooltip",
};
const nodeToShortcutMap = {
"bookmarks-menu-button": "manBookmarkKb",
"context-reload": "key_reload",
"context-stop": "key_stop",
"downloads-button": "key_openDownloads",
"fullscreen-button": "key_fullScreen",
"new-window-button": "key_newNavigator",
"new-tab-button": "key_newNavigatorTab",
"tabs-newtab-button": "key_newNavigatorTab",
"fullscreen-button": "key_fullScreen",
"downloads-button": "key_openDownloads"
"urlbar-reload-button": "key_reload",
"urlbar-stop-button": "key_stop",
"urlbar-zoom-button": "key_fullZoomReset",
};
if (AppConstants.platform == "macosx") {

View File

@ -776,7 +776,7 @@
onclick="ReaderParent.buttonClick(event);"/>
<toolbarbutton id="urlbar-zoom-button"
onclick="FullZoom.reset();"
tooltiptext="&urlbar.zoomReset.tooltip;"
tooltip="dynamic-shortcut-tooltip"
hidden="true"/>
</hbox>
<hbox id="userContext-icons" hidden="true">
@ -791,11 +791,11 @@
class="chromeclass-toolbar-additional"
command="Browser:ReloadOrDuplicate"
onclick="checkForMiddleClick(this, event);"
tooltiptext="&reloadButton.tooltip;"/>
tooltip="dynamic-shortcut-tooltip"/>
<toolbarbutton id="urlbar-stop-button"
class="chromeclass-toolbar-additional"
command="Browser:Stop"
tooltiptext="&stopButton.tooltip;"/>
tooltip="dynamic-shortcut-tooltip"/>
</textbox>
</hbox>
</toolbaritem>

View File

@ -2194,6 +2194,7 @@
var aDisallowInheritPrincipal;
var aOpener;
var aCreateLazyBrowser;
var aSkipBackgroundNotify;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -2220,6 +2221,7 @@
aOpener = params.opener;
aIsPrerendered = params.isPrerendered;
aCreateLazyBrowser = params.createLazyBrowser;
aSkipBackgroundNotify = params.skipBackgroundNotify;
}
// if we're adding tabs, we're past interrupt mode, ditch the owner
@ -2254,6 +2256,11 @@
}
t.setAttribute("onerror", "this.removeAttribute('image');");
if (aSkipBackgroundNotify) {
t.setAttribute("skipbackgroundnotify", true);
}
t.className = "tabbrowser-tab";
this.tabContainer._unlockTabSizing();
@ -2656,12 +2663,11 @@
!aSkipPermitUnload &&
aTab.linkedPanel &&
!aAdoptedByTab) {
TelemetryStopwatch.start("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
// We need to block while calling permitUnload() because it
// processes the event queue and may lead to another removeTab()
// call before permitUnload() returns.
TelemetryStopwatch.start("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
aTab._pendingPermitUnload = true;
let {permitUnload, timedOut} = browser.permitUnload();
delete aTab._pendingPermitUnload;
@ -2672,8 +2678,6 @@
// so we don't (try to) close the same tab again. Of course, we
// also stop if the unload was cancelled by the user:
if (aTab.closing || (!timedOut && !permitUnload)) {
// NB: deliberately keep the _closedDuringPermitUnload set to
// true so we keep exiting early in case of multiple calls.
return false;
}
}
@ -6313,10 +6317,10 @@
selected.left - scrollRect.left);
}
if (!this._animateElement.hasAttribute("notifybgtab")) {
this._animateElement.setAttribute("notifybgtab", "true");
if (!this._animateElement.hasAttribute("highlight")) {
this._animateElement.setAttribute("highlight", "true");
setTimeout(function(ele) {
ele.removeAttribute("notifybgtab");
ele.removeAttribute("highlight");
}, 150, this._animateElement);
}
]]></body>
@ -6404,7 +6408,7 @@
if (tab.getAttribute("selected") == "true") {
this._fillTrailingGap();
this._handleTabSelect();
} else {
} else if (!tab.hasAttribute("skipbackgroundnotify")) {
this._notifyBackgroundTab(tab);
}

View File

@ -91,6 +91,15 @@ const DISABLED_OPTGROUP_AND_OPTIONS =
' <option value="Two" selected="true">{"end": "true"}</option>' +
"</select></body></html>";
const SELECT_CHANGES_COLOR_ON_FOCUS =
"<html><head><style>" +
" select:focus { background-color: orange; color: black; }" +
"</style></head>" +
"<body><select id='one'>" +
' <option>{"color": "rgb(0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
' <option selected="true">{"end": "true"}</option>' +
"</select></body></html>";
function getSystemColor(color) {
// Need to convert system color to RGB color.
let textarea = document.createElementNS("http://www.w3.org/1999/xhtml", "textarea");
@ -279,3 +288,12 @@ add_task(function* test_disabled_optgroup_and_options() {
yield testSelectColors(DISABLED_OPTGROUP_AND_OPTIONS, 17,
{skipSelectColorTest: true});
});
add_task(function* test_disabled_optgroup_and_options() {
let options = {
selectColor: "rgb(0, 0, 0)",
selectBgColor: "rgb(255, 165, 0)"
};
yield testSelectColors(SELECT_CHANGES_COLOR_ON_FOCUS, 2, options);
});

View File

@ -12,29 +12,39 @@ add_task(function* () {
const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
const URL = BASE + "file_bypass_cache.sjs";
function awaitLoad(tabId) {
return new Promise(resolve => {
browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
if (tabId == tabId_ && changed.status == "complete" && tab.url == URL) {
browser.tabs.onUpdated.removeListener(listener);
resolve();
}
});
let tabId = null;
let loadPromise, resolveLoad;
function resetLoad() {
loadPromise = new Promise(resolve => {
resolveLoad = resolve;
});
}
function awaitLoad() {
return loadPromise.then(() => {
resetLoad();
});
}
resetLoad();
browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
if (tabId == tabId_ && changed.status == "complete" && tab.url == URL) {
resolveLoad();
}
});
try {
let tab = await browser.tabs.create({url: URL});
await awaitLoad(tab.id);
tabId = tab.id;
await awaitLoad();
await browser.tabs.reload(tab.id, {bypassCache: false});
await awaitLoad(tab.id);
await awaitLoad();
let [textContent] = await browser.tabs.executeScript(tab.id, {code: "document.body.textContent"});
browser.test.assertEq("", textContent, "`textContent` should be empty when bypassCache=false");
await browser.tabs.reload(tab.id, {bypassCache: true});
await awaitLoad(tab.id);
await awaitLoad();
[textContent] = await browser.tabs.executeScript(tab.id, {code: "document.body.textContent"});

View File

@ -888,7 +888,7 @@ PlacesController.prototype = {
PlacesUtils.asQuery(node.parent).queryOptions.queryType ==
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
// This is a uri node inside an history query.
PlacesUtils.history.removePage(node.uri).catch(Components.utils.reportError);
PlacesUtils.history.remove(node.uri).catch(Components.utils.reportError);
// History deletes are not undoable, so we don't have a transaction.
} else if (node.itemId == -1 &&
PlacesUtils.nodeIsQuery(node) &&

View File

@ -331,9 +331,7 @@ var gPrivacyPane = {
pref.value = false;
// select the remember history option if needed
let rememberHistoryCheckbox = document.getElementById("rememberHistory");
if (!rememberHistoryCheckbox.checked)
rememberHistoryCheckbox.checked = true;
document.getElementById("places.history.enabled").value = true;
// select the remember forms history option
document.getElementById("browser.formfill.enable").value = true;

View File

@ -331,9 +331,7 @@ var gPrivacyPane = {
pref.value = false;
// select the remember history option if needed
let rememberHistoryCheckbox = document.getElementById("rememberHistory");
if (!rememberHistoryCheckbox.checked)
rememberHistoryCheckbox.checked = true;
document.getElementById("places.history.enabled").value = true;
// select the remember forms history option
document.getElementById("browser.formfill.enable").value = true;

View File

@ -3222,8 +3222,9 @@ var SessionStoreInternal = {
(tabbrowser.tabs[t].getAttribute("usercontextid") == (userContextId || ""));
let tab = reuseExisting ? this._maybeUpdateBrowserRemoteness(tabbrowser.tabs[t])
: tabbrowser.addTab("about:blank",
{skipAnimation: true,
userContextId});
{ skipAnimation: true,
userContextId,
skipBackgroundNotify: true });
// If we inserted a new tab because the userContextId didn't match with the
// open tab, even though `t < openTabCount`, we need to remove that open tab

View File

@ -14,7 +14,8 @@ this.EXPORTED_SYMBOLS = ["TabAttributes"];
// 'pending' is used internal by sessionstore and managed accordingly.
// 'iconLoadingPrincipal' is same as 'image' that it should be handled by
// using the gBrowser.getIcon()/setIcon() methods.
const ATTRIBUTES_TO_SKIP = new Set(["image", "muted", "pending", "iconLoadingPrincipal"]);
const ATTRIBUTES_TO_SKIP = new Set(["image", "muted", "pending", "iconLoadingPrincipal",
"skipbackgroundnotify"]);
// A set of tab attributes to persist. We will read a given list of tab
// attributes when collecting tab data and will re-set those attributes when

View File

@ -8,6 +8,6 @@ ac_add_options --disable-crashreporter
ac_add_options --disable-elf-hack
MOZ_CODE_COVERAGE=1
export CFLAGS="-fprofile-arcs -ftest-coverage"
export CXXFLAGS="-fprofile-arcs -ftest-coverage"
export LDFLAGS="-fprofile-arcs -ftest-coverage -lgcov -L$TOOLTOOL_DIR/gtk3/usr/local/lib"
export CFLAGS="--coverage"
export CXXFLAGS="--coverage"
export LDFLAGS="--coverage -L$TOOLTOOL_DIR/gtk3/usr/local/lib"

View File

@ -1,12 +0,0 @@
if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
MOZ_AUTOMATION_UPDATE_PACKAGING=1
fi
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
ac_add_options --enable-official-branding
ac_add_options --enable-verify-mar
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.cache"

View File

@ -1,18 +0,0 @@
# This file is sourced by the nightly, beta, and release mozconfigs.
. $topsrcdir/build/macosx/universal/mozconfig
# Universal builds override the default of browser (bug 575283 comment 29)
ac_add_options --enable-application=browser
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-google-api-keyfile=/builds/gapi.data
ac_add_options --with-mozilla-api-keyfile=/builds/mozilla-desktop-geoloc-api.key
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -1,22 +0,0 @@
. "$topsrcdir/browser/config/mozconfigs/common"
. "$topsrcdir/build/macosx/mozconfig.common"
ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --with-branding=browser/branding/nightly
if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
ac_add_options --with-macbundlename-prefix=Firefox
fi
export MOZILLA_OFFICIAL=1
# Enable Telemetry
export MOZ_TELEMETRY_REPORTING=1
# Don't autoclobber l10n, as this can lead to missing binaries and broken builds
# Bug 1283438
mk_add_options AUTOCLOBBER=
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.cache"

View File

@ -1,20 +0,0 @@
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
ac_add_options --disable-install-strip
ac_add_options --enable-verify-mar
ac_add_options --enable-profiling
ac_add_options --enable-instruments
# Cross-universal builds fail when dtrace is enabled
if test `uname -s` != Linux; then
ac_add_options --enable-dtrace
fi
if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
ac_add_options --with-macbundlename-prefix=Firefox
fi
ac_add_options --with-branding=browser/branding/nightly
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.cache"

View File

@ -1,19 +0,0 @@
# This make file should be identical to the beta mozconfig, apart from the
# safeguard below
if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
MOZ_AUTOMATION_UPDATE_PACKAGING=1
fi
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
ac_add_options --enable-official-branding
ac_add_options --enable-verify-mar
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
# defines.sh during the beta cycle
export BUILDING_RELEASE=1
. "$topsrcdir/build/mozconfig.common.override"
. "$topsrcdir/build/mozconfig.cache"

View File

@ -198,10 +198,8 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY backForwardButtonMenu.tooltip "Right-click or pull down to show history">
<!ENTITY backForwardButtonMenuMac.tooltip "Pull down to show history">
<!ENTITY reloadCmd.label "Reload">
<!ENTITY reloadButton.tooltip "Reload current page">
<!ENTITY stopCmd.label "Stop">
<!ENTITY stopCmd.macCommandKey ".">
<!ENTITY stopButton.tooltip "Stop loading this page">
<!ENTITY goEndCap.tooltip "Go to the address in the Location Bar">
<!ENTITY printButton.label "Print">
<!ENTITY printButton.tooltip "Print this page">
@ -234,8 +232,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY urlbar.openHistoryPopup.tooltip "Show history">
<!ENTITY urlbar.zoomReset.tooltip "Reset zoom level">
<!ENTITY searchItem.title "Search">
<!-- Toolbar items -->

View File

@ -386,6 +386,15 @@ tabHistory.goForward=Go forward to this page
# URL Bar
pasteAndGo.label=Paste & Go
# LOCALIZATION NOTE (reloadButton.tooltip):
# %S is the keyboard shortcut for reloading the current page
reloadButton.tooltip=Reload current page (%S)
# LOCALIZATION NOTE (stopButton.tooltip):
# %S is the keyboard shortcut for stopping loading the page
stopButton.tooltip=Stop loading this page (%S)
# LOCALIZATION NOTE (urlbar-zoom-button.tooltip):
# %S is the keyboard shortcut for resetting the zoom level to 100%
urlbar-zoom-button.tooltip=Reset zoom level (%S)
# LOCALIZATION NOTE(zoom-button.label): %S is the current page zoom level,
# %% will be displayed as a single % character (% is commonly used to define

View File

@ -1376,7 +1376,7 @@ html|span.ac-emphasize-text-url {
transition: 1s background-color ease-out;
}
.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
.tabbrowser-arrowscrollbox > .scrollbutton-down[highlight] {
background-color: Highlight;
transition: none;
}

View File

@ -2591,7 +2591,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
transition: 1s background-color ease-out;
}
.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
.tabbrowser-arrowscrollbox > .scrollbutton-down[highlight] {
background-color: Highlight;
transition: none;
}

View File

@ -1934,7 +1934,7 @@ html|span.ac-emphasize-text-url {
transition: 1s background-color ease-out;
}
.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
.tabbrowser-arrowscrollbox > .scrollbutton-down[highlight] {
background-color: Highlight;
transition: none;
}

View File

@ -2,6 +2,7 @@ altgraph.pth:python/altgraph
marionette_driver.pth:testing/marionette/client
marionette_harness.pth:testing/marionette/harness
browsermobproxy.pth:testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py
six.pth:testing/web-platform/tests/tools/six
wptserve.pth:testing/web-platform/tests/tools/wptserve
blessings.pth:python/blessings
configobj.pth:python/configobj

125
devtools/bootstrap.js vendored
View File

@ -10,6 +10,24 @@
const Cu = Components.utils;
const Ci = Components.interfaces;
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
let prefs = {
// Enable dump as some errors are only printed on the stdout
"browser.dom.window.dump.enabled": true,
// Enable the browser toolbox and various chrome-only features
"devtools.chrome.enabled": true,
"devtools.debugger.remote-enabled": true,
// Disable the prompt to ease usage of the browser toolbox
"devtools.debugger.prompt-connection": false,
};
// Values of debug pref before overriding them
let originalPrefValues = {};
// MultiWindowKeyListener instance for Ctrl+Alt+R key
let listener;
// nsIURI to the addon root folder
let resourceURI;
function actionOccurred(id) {
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
@ -18,6 +36,54 @@ function actionOccurred(id) {
telemetry.actionOccurred(id);
}
// Synchronously fetch the content of a given URL
function readURI(uri) {
let stream = NetUtil.newChannel({
uri: NetUtil.newURI(uri, "UTF-8"),
loadUsingSystemPrincipal: true}
).open2();
let count = stream.available();
let data = NetUtil.readInputStreamToString(stream, count, {
charset: "UTF-8"
});
stream.close();
return data;
}
// Read a preference file and set all of its defined pref as default values
// (This replicate the behavior of preferences files from mozilla-central)
function processPrefFile(url) {
let content = readURI(url);
content.match(/pref\("[^"]+",\s*.+\s*\)/g).forEach(item => {
let m = item.match(/pref\("([^"]+)",\s*(.+)\s*\)/);
let name = m[1];
let val = m[2];
// Prevent overriding prefs that have been changed by the user
if (Services.prefs.prefHasUserValue(name)) {
return;
}
let defaultBranch = Services.prefs.getDefaultBranch("");
if ((val.startsWith("\"") && val.endsWith("\"")) ||
(val.startsWith("'") && val.endsWith("'"))) {
defaultBranch.setCharPref(name, val.substr(1, val.length - 2));
} else if (val.match(/[0-9]+/)) {
defaultBranch.setIntPref(name, parseInt(val, 10));
} else if (val == "true" || val == "false") {
defaultBranch.setBoolPref(name, val == "true");
} else {
console.log("Unable to match preference type for value:", val);
}
});
}
function setPrefs() {
processPrefFile(resourceURI.spec + "./client/preferences/devtools.js");
processPrefFile(resourceURI.spec + "./client/preferences/debugger.js");
}
// Helper to listen to a key on all windows
function MultiWindowKeyListener({ keyCode, ctrlKey, altKey, callback }) {
let keyListener = function (event) {
@ -76,20 +142,22 @@ let getTopLevelWindow = function (window) {
function reload(event) {
// We automatically reload the toolbox if we are on a browser tab
// with a toolbox already opened
let top = getTopLevelWindow(event.view);
let isBrowser = top.location.href.includes("/browser.xul");
let reloadToolbox = false;
if (isBrowser && top.gBrowser) {
// We do not use any devtools code before the call to Loader.jsm reload as
// any attempt to use Loader.jsm to load a module will instanciate a new
// Loader.
let nbox = top.gBrowser.getNotificationBox();
reloadToolbox =
top.document.getAnonymousElementByAttribute(nbox, "class",
"devtools-toolbox-bottom-iframe") ||
top.document.getAnonymousElementByAttribute(nbox, "class",
"devtools-toolbox-side-iframe") ||
Services.wm.getMostRecentWindow("devtools:toolbox");
if (event) {
let top = getTopLevelWindow(event.view);
let isBrowser = top.location.href.includes("/browser.xul");
if (isBrowser && top.gBrowser) {
// We do not use any devtools code before the call to Loader.jsm reload as
// any attempt to use Loader.jsm to load a module will instanciate a new
// Loader.
let nbox = top.gBrowser.getNotificationBox();
reloadToolbox =
top.document.getAnonymousElementByAttribute(nbox, "class",
"devtools-toolbox-bottom-iframe") ||
top.document.getAnonymousElementByAttribute(nbox, "class",
"devtools-toolbox-side-iframe") ||
Services.wm.getMostRecentWindow("devtools:toolbox");
}
}
let browserConsole = Services.wm.getMostRecentWindow("devtools:webconsole");
let reopenBrowserConsole = false;
@ -136,6 +204,10 @@ function reload(event) {
Cu.unload("resource://devtools/client/responsivedesign/responsivedesign.jsm");
Cu.unload("resource://devtools/client/shared/widgets/AbstractTreeItem.jsm");
Cu.unload("resource://devtools/shared/deprecated-sync-thenables.js");
// Update the preferences before starting new code
setPrefs();
const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
devtools.require("devtools/client/framework/devtools-browser");
@ -178,6 +250,7 @@ function reload(event) {
setTimeout(() => {
let { TargetFactory } = devtools.require("devtools/client/framework/target");
let { gDevTools } = devtools.require("devtools/client/framework/devtools");
let top = getTopLevelWindow(event.view);
let target = TargetFactory.forTab(top.gBrowser.selectedTab);
gDevTools.showToolbox(target);
}, 1000);
@ -194,20 +267,11 @@ function reload(event) {
actionOccurred("reloadAddonReload");
}
let prefs = {
// Enable dump as some errors are only printed on the stdout
"browser.dom.window.dump.enabled": true,
// Enable the browser toolbox and various chrome-only features
"devtools.chrome.enabled": true,
"devtools.debugger.remote-enabled": true,
// Disable the prompt to ease usage of the browser toolbox
"devtools.debugger.prompt-connection": false,
};
let originalPrefValues = {};
let listener;
function startup() {
function startup(data) {
dump("DevTools addon started.\n");
resourceURI = data.resourceURI;
listener = new MultiWindowKeyListener({
keyCode: Ci.nsIDOMKeyEvent.DOM_VK_R, ctrlKey: true, altKey: true,
callback: reload
@ -225,6 +289,8 @@ function startup() {
originalPrefValues[name] = userValue;
}
}
reload();
}
function shutdown() {
listener.stop();
@ -240,6 +306,11 @@ function shutdown() {
}
}
function install() {
actionOccurred("reloadAddonInstalled");
try {
actionOccurred("reloadAddonInstalled");
} catch (e) {
// When installing on Firefox builds without devtools, telemetry doesn't
// work yet and throws.
}
}
function uninstall() {}

View File

@ -77,6 +77,7 @@ module.exports = createClass({
type: "checkbox",
checked: !debugDisabled,
onChange: this.onEnableAddonDebuggingChange,
role: "checkbox",
}),
dom.label({
className: "addons-debugging-label",

View File

@ -93,8 +93,13 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId) {
this._toolPanels = new Map();
this._telemetry = new Telemetry();
// TODO: This approach to source maps uses server-side source maps, which we are
// replacing with client-side source maps. Do not use this in new code paths.
// To be removed in bug 1349354. Read more about ongoing work with source maps:
// https://docs.google.com/document/d/19TKnMJD3CMBzwByNE4aBBVWnl-AEan8Sf4hxi6J-eps/edit
if (Services.prefs.getBoolPref("devtools.source-map.locations.enabled")) {
this._sourceMapService = new SourceMapService(this._target);
this._deprecatedServerSourceMapService = new SourceMapService(this._target);
}
this._initInspector = null;
@ -520,6 +525,23 @@ Toolbox.prototype = {
return this.browserRequire("devtools/client/framework/components/toolbox-controller");
},
/**
* A common access point for the client-side mapping service for source maps that
* any panel can use.
*/
get sourceMapService() {
if (!Services.prefs.getBoolPref("devtools.source-map.client-service.enabled")) {
return null;
}
if (this._sourceMapService) {
return this._sourceMapService;
}
// Uses browser loader to access the `Worker` global.
this._sourceMapService =
this.browserRequire("devtools/client/shared/source-map/index");
return this._sourceMapService;
},
// Return HostType id for telemetry
_getTelemetryHostId: function () {
switch (this.hostType) {
@ -2260,8 +2282,14 @@ Toolbox.prototype = {
this._applyServiceWorkersTestingSettings);
this._lastFocusedElement = null;
if (this._deprecatedServerSourceMapService) {
this._deprecatedServerSourceMapService.destroy();
this._deprecatedServerSourceMapService = null;
}
if (this._sourceMapService) {
this._sourceMapService.destroy();
this._sourceMapService.destroyWorker();
this._sourceMapService = null;
}

View File

@ -13,6 +13,7 @@ const {
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
const Actions = require("../actions/index");
const { getLongString } = require("../utils/client");
const { Prefs } = require("../utils/prefs");
const { getFormDataSections } = require("../utils/request-utils");
const { getSelectedRequest } = require("../selectors/index");
@ -69,7 +70,7 @@ const MonitorPanel = createClass({
requestHeaders,
requestHeadersFromUploadStream,
requestPostData,
window.gNetwork.getString.bind(window.gNetwork),
getLongString,
).then((newFormDataSections) => {
updateRequest(
request.id,

View File

@ -269,7 +269,6 @@ HarBuilder.prototype = {
file.requestHeaders,
file.requestHeadersFromUploadStream,
file.requestPostData,
this._options.getString
).then(formDataSections => {
formDataSections.forEach(section => {
let paramsArray = parseQueryString(section);

View File

@ -13,6 +13,8 @@ const {
formDataURI,
} = require("./utils/request-utils");
const {
getLongString,
getWebConsoleClient,
onFirefoxConnect,
onFirefoxDisconnect,
} = require("./utils/client");
@ -87,7 +89,6 @@ var NetMonitorController = {
if (this._target.isTabActor) {
this.tabClient = this._target.activeTab;
}
this.webConsoleClient = this._target.activeConsole;
let connectTimeline = () => {
// Don't start up waiting for timeline markers if the server isn't
@ -103,6 +104,9 @@ var NetMonitorController = {
onFirefoxConnect(this._target);
this._target.on("close", this._onTabDetached);
this.webConsoleClient = getWebConsoleClient();
this.NetworkEventsHandler = new NetworkEventsHandler();
this.NetworkEventsHandler.connect();
window.emit(EVENTS.CONNECTED);
@ -369,7 +373,6 @@ var NetMonitorController = {
function NetworkEventsHandler() {
this.addRequest = this.addRequest.bind(this);
this.updateRequest = this.updateRequest.bind(this);
this.getString = this.getString.bind(this);
this._onNetworkEvent = this._onNetworkEvent.bind(this);
this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this);
this._onDocLoadingMarker = this._onDocLoadingMarker.bind(this);
@ -512,7 +515,7 @@ NetworkEventsHandler.prototype = {
let request = getRequestById(gStore.getState(), action.id);
if (requestHeaders && requestHeaders.headers && requestHeaders.headers.length) {
let headers = await fetchHeaders(requestHeaders, this.getString);
let headers = await fetchHeaders(requestHeaders, getLongString);
if (headers) {
await gStore.dispatch(Actions.updateRequest(
action.id,
@ -523,7 +526,7 @@ NetworkEventsHandler.prototype = {
}
if (responseHeaders && responseHeaders.headers && responseHeaders.headers.length) {
let headers = await fetchHeaders(responseHeaders, this.getString);
let headers = await fetchHeaders(responseHeaders, getLongString);
if (headers) {
await gStore.dispatch(Actions.updateRequest(
action.id,
@ -536,7 +539,7 @@ NetworkEventsHandler.prototype = {
if (request && responseContent && responseContent.content) {
let { mimeType } = request;
let { text, encoding } = responseContent.content;
let response = await this.getString(text);
let response = await getLongString(text);
let payload = {};
if (mimeType.includes("image/")) {
@ -557,7 +560,7 @@ NetworkEventsHandler.prototype = {
// them as a separate property, different from the classic headers.
if (requestPostData && requestPostData.postData) {
let { text } = requestPostData.postData;
let postData = await this.getString(text);
let postData = await getLongString(text);
const headers = CurlUtils.getHeadersFromMultipartText(postData);
const headersSize = headers.reduce((acc, { name, value }) => {
return acc + name.length + value.length + 2;
@ -582,7 +585,7 @@ NetworkEventsHandler.prototype = {
if (typeof cookies[Symbol.iterator] === "function") {
for (let cookie of cookies) {
reqCookies.push(Object.assign({}, cookie, {
value: await this.getString(cookie.value),
value: await getLongString(cookie.value),
}));
}
if (reqCookies.length) {
@ -603,7 +606,7 @@ NetworkEventsHandler.prototype = {
if (typeof cookies[Symbol.iterator] === "function") {
for (let cookie of cookies) {
resCookies.push(Object.assign({}, cookie, {
value: await this.getString(cookie.value),
value: await getLongString(cookie.value),
}));
}
if (resCookies.length) {
@ -800,35 +803,7 @@ NetworkEventsHandler.prototype = {
}).then(() => {
window.emit(EVENTS.RECEIVED_EVENT_TIMINGS, response.from);
});
},
/**
* Fetches the full text of a LongString.
*
* @param object | string stringGrip
* The long string grip containing the corresponding actor.
* If you pass in a plain string (by accident or because you're lazy),
* then a promise of the same string is simply returned.
* @return object Promise
* A promise that is resolved when the full string contents
* are available, or rejected if something goes wrong.
*/
getString: function (stringGrip) {
// FIXME: this.webConsoleClient will be undefined in mochitest,
// so we return string instantly to skip undefined error
if (typeof stringGrip === "string") {
return Promise.resolve(stringGrip);
}
return this.webConsoleClient.getString(stringGrip);
}
};
/**
* Preliminary setup for the NetMonitorController object.
*/
NetMonitorController.NetworkEventsHandler = new NetworkEventsHandler();
window.NetMonitorController = NetMonitorController;
window.gNetwork = NetMonitorController.NetworkEventsHandler;
exports.NetMonitorController = NetMonitorController;

View File

@ -11,6 +11,7 @@ const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
const clipboardHelper = require("devtools/shared/platform/clipboard");
const { HarExporter } = require("./har/har-exporter");
const { getLongString } = require("./utils/client");
const { L10N } = require("./utils/l10n");
const {
formDataURI,
@ -146,7 +147,8 @@ RequestListContextMenu.prototype = {
menu.append(new MenuItem({
type: "separator",
visible: !!selectedRequest,
visible: !!(window.NetMonitorController.supportsCustomRequest &&
selectedRequest && !selectedRequest.isCustom),
}));
menu.append(new MenuItem({
@ -221,7 +223,7 @@ RequestListContextMenu.prototype = {
selected.requestHeaders,
selected.requestHeadersFromUploadStream,
selected.requestPostData,
window.gNetwork.getString.bind(window.gNetwork));
getLongString);
let params = [];
formDataSections.forEach(section => {
@ -238,7 +240,7 @@ RequestListContextMenu.prototype = {
// Fall back to raw payload.
if (!string) {
let postData = selected.requestPostData.postData.text;
string = await window.gNetwork.getString(postData);
string = await getLongString(postData);
if (Services.appinfo.OS !== "WINNT") {
string = string.replace(/\r/g, "");
}
@ -264,14 +266,14 @@ RequestListContextMenu.prototype = {
// Fetch header values.
for (let { name, value } of selected.requestHeaders.headers) {
let text = await window.gNetwork.getString(value);
let text = await getLongString(value);
data.headers.push({ name: name, value: text });
}
// Fetch the request payload.
if (selected.requestPostData) {
let postData = selected.requestPostData.postData.text;
data.postDataText = await window.gNetwork.getString(postData);
data.postDataText = await getLongString(postData);
}
clipboardHelper.copyString(Curl.generateCommand(data));
@ -305,7 +307,7 @@ RequestListContextMenu.prototype = {
copyImageAsDataUri() {
const { mimeType, text, encoding } = this.selectedRequest.responseContent.content;
window.gNetwork.getString(text).then(string => {
getLongString(text).then(string => {
let data = formDataURI(mimeType, encoding, string);
clipboardHelper.copyString(data);
});
@ -317,7 +319,7 @@ RequestListContextMenu.prototype = {
copyResponse() {
const { text } = this.selectedRequest.responseContent.content;
window.gNetwork.getString(text).then(string => {
getLongString(text).then(string => {
clipboardHelper.copyString(string);
});
},
@ -341,7 +343,7 @@ RequestListContextMenu.prototype = {
let title = form.title || form.url;
return {
getString: window.gNetwork.getString.bind(window.gNetwork),
getString: getLongString,
items: this.sortedRequests,
title: title
};

View File

@ -8,6 +8,7 @@ const {
setImageTooltip,
getImageDimensions,
} = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
const { getLongString } = require("./utils/client");
const { WEBCONSOLE_L10N } = require("./utils/l10n");
const { formDataURI } = require("./utils/request-utils");
@ -23,7 +24,7 @@ async function setTooltipImageContent(tooltip, itemEl, requestItem) {
return false;
}
let string = await window.gNetwork.getString(text);
let string = await getLongString(text);
let src = formDataURI(mimeType, encoding, string);
let maxDim = REQUESTS_TOOLTIP_IMAGE_MAX_DIM;
let { naturalWidth, naturalHeight } = await getImageDimensions(tooltip.doc, src);

View File

@ -13,9 +13,10 @@ add_task(function* () {
let { tab, monitor } = yield initNetMonitor(CURL_UTILS_URL);
info("Starting test... ");
let { gStore, windowRequire, gNetwork } = monitor.panelWin;
let { gStore, windowRequire } = monitor.panelWin;
let Actions = windowRequire("devtools/client/netmonitor/actions/index");
let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
let { getLongString } = windowRequire("devtools/client/netmonitor/utils/client");
gStore.dispatch(Actions.batchEnable(false));
@ -32,20 +33,20 @@ add_task(function* () {
multipartForm: getSortedRequests(gStore.getState()).get(3),
};
let data = yield createCurlData(requests.get, gNetwork);
let data = yield createCurlData(requests.get, getLongString);
testFindHeader(data);
data = yield createCurlData(requests.post, gNetwork);
data = yield createCurlData(requests.post, getLongString);
testIsUrlEncodedRequest(data);
testWritePostDataTextParams(data);
data = yield createCurlData(requests.multipart, gNetwork);
data = yield createCurlData(requests.multipart, getLongString);
testIsMultipartRequest(data);
testGetMultipartBoundary(data);
testMultiPartHeaders(data);
testRemoveBinaryDataFromMultipartText(data);
data = yield createCurlData(requests.multipartForm, gNetwork);
data = yield createCurlData(requests.multipartForm, getLongString);
testMultiPartHeaders(data);
testGetHeadersFromMultipartText({
@ -214,7 +215,7 @@ function testEscapeStringWin() {
"Newlines should be escaped.");
}
function* createCurlData(selected, network, controller) {
function* createCurlData(selected, getLongString) {
let { url, method, httpVersion } = selected;
// Create a sanitized object for the Curl command generator.
@ -228,14 +229,14 @@ function* createCurlData(selected, network, controller) {
// Fetch header values.
for (let { name, value } of selected.requestHeaders.headers) {
let text = yield network.getString(value);
let text = yield getLongString(value);
data.headers.push({ name: name, value: text });
}
// Fetch the request payload.
if (selected.requestPostData) {
let postData = selected.requestPostData.postData.text;
data.postDataText = yield network.getString(postData);
data.postDataText = yield getLongString(postData);
}
return data;

View File

@ -10,6 +10,8 @@ const Services = require("Services");
const Actions = require("../actions/index");
const { EVENTS } = require("../constants");
let activeConsole;
/**
* Called for each location change in the monitored tab.
*
@ -45,6 +47,7 @@ function willNavigate(type) {
* @param {Object} tabTarget
*/
function onFirefoxConnect(tabTarget) {
activeConsole = tabTarget.activeConsole;
tabTarget.on("navigate", navigated);
tabTarget.on("will-navigate", willNavigate);
}
@ -55,11 +58,44 @@ function onFirefoxConnect(tabTarget) {
* @param {Object} tabTarget
*/
function onFirefoxDisconnect(tabTarget) {
activeConsole = null;
tabTarget.off("navigate", navigated);
tabTarget.off("will-navigate", willNavigate);
}
/**
* Retrieve webconsole object
*
* @returns {Object} webConsole
*/
function getWebConsoleClient() {
return activeConsole;
}
/**
* Fetches the full text of a LongString.
*
* @param object | string stringGrip
* The long string grip containing the corresponding actor.
* If you pass in a plain string (by accident or because you're lazy),
* then a promise of the same string is simply returned.
* @return object Promise
* A promise that is resolved when the full string contents
* are available, or rejected if something goes wrong.
*/
function getLongString(stringGrip) {
// FIXME: this.webConsoleClient will be undefined in mochitest,
// so we return string instantly to skip undefined error
if (typeof stringGrip === "string") {
return Promise.resolve(stringGrip);
}
return activeConsole.getString(stringGrip);
}
module.exports = {
getLongString,
getWebConsoleClient,
onFirefoxConnect,
onFirefoxDisconnect,
};

View File

@ -13,10 +13,9 @@
* @param {object} headers - the "requestHeaders".
* @param {object} uploadHeaders - the "requestHeadersFromUploadStream".
* @param {object} postData - the "requestPostData".
* @param {function} getString - callback to retrieve a string from a LongStringGrip.
* @return {array} a promise list that is resolved with the extracted form data.
*/
async function getFormDataSections(headers, uploadHeaders, postData, getString) {
async function getFormDataSections(headers, uploadHeaders, postData, getLongString) {
let formDataSections = [];
let requestHeaders = headers.headers;
@ -29,11 +28,11 @@ async function getFormDataSections(headers, uploadHeaders, postData, getString)
let contentTypeLongString = contentTypeHeader ? contentTypeHeader.value : "";
let contentType = await getString(contentTypeLongString);
let contentType = await getLongString(contentTypeLongString);
if (contentType.includes("x-www-form-urlencoded")) {
let postDataLongString = postData.postData.text;
let text = await getString(postDataLongString);
let text = await getLongString(postDataLongString);
for (let section of text.split(/\r\n|\r|\n/)) {
// Before displaying it, make sure this section of the POST data
@ -51,12 +50,11 @@ async function getFormDataSections(headers, uploadHeaders, postData, getString)
* Fetch headers full content from actor server
*
* @param {object} headers - a object presents headers data
* @param {function} getString - callback to retrieve a string from a LongStringGrip
* @return {object} a headers object with updated content payload
*/
async function fetchHeaders(headers, getString) {
async function fetchHeaders(headers, getLongString) {
for (let { value } of headers.headers) {
headers.headers.value = await getString(value);
headers.headers.value = await getLongString(value);
}
return headers;
}

View File

@ -301,9 +301,16 @@ pref("devtools.webconsole.new-frontend-enabled", true);
pref("devtools.webconsole.new-frontend-enabled", false);
#endif
// Enable the experimental support for source maps in console (work in progress)
// Enable the server-side mapping service for source maps in console (deprecated)
// NOTE: This approach to source maps uses server-side source maps, which we are
// replacing with client-side source maps. Do not use this in new code paths.
// To be removed in bug 1349354. Read more about ongoing work with source maps:
// https://docs.google.com/document/d/19TKnMJD3CMBzwByNE4aBBVWnl-AEan8Sf4hxi6J-eps/edit
pref("devtools.source-map.locations.enabled", false);
// Enable client-side mapping service for source maps
pref("devtools.source-map.client-service.enabled", true);
// The number of lines that are displayed in the web console.
pref("devtools.hud.loglimit", 1000);

View File

@ -17,8 +17,9 @@ const BROWSER_BASED_DIRS = [
"resource://devtools/client/inspector/grids",
"resource://devtools/client/inspector/layout",
"resource://devtools/client/jsonview",
"resource://devtools/client/shared/vendor",
"resource://devtools/client/shared/source-map",
"resource://devtools/client/shared/redux",
"resource://devtools/client/shared/vendor",
];
const COMMON_LIBRARY_DIRS = [

View File

@ -85,7 +85,8 @@ NewConsoleOutputWrapper.prototype = {
return panel.panelWin.NetMonitorController.inspectRequest(requestId);
});
},
sourceMapService: this.toolbox ? this.toolbox._sourceMapService : null,
sourceMapService:
this.toolbox ? this.toolbox._deprecatedServerSourceMapService : null,
openLink: url => this.jsterm.hud.owner.openLink(url),
createElement: nodename => {
return this.document.createElementNS("http://www.w3.org/1999/xhtml", nodename);

View File

@ -2624,7 +2624,7 @@ WebConsoleFrame.prototype = {
frame: { source, line, column },
showEmptyPathAsHost: true,
onClick,
sourceMapService: toolbox ? toolbox._sourceMapService : null,
sourceMapService: toolbox ? toolbox._deprecatedServerSourceMapService : null,
}), locationNode);
return locationNode;

View File

@ -11,8 +11,8 @@ load 746813-1.html
load 743499-negative-size.html
skip-if(Android) load 745818-large-source.html # Bug XXX - Crashes Android mid-run w/o a stack
load 767337-1.html
asserts-if(stylo,1) skip-if(Android) skip-if(webrender) load 780392-1.html # bug 1324700. bug 1322816 for webrender
skip-if(Android) skip-if(gtkWidget&&isDebugBuild) skip-if(webrender) load 789933-1.html # bug 1155252 for linux, bug 1322816 for webrender
asserts-if(stylo,1) skip-if(Android) load 780392-1.html # bug 1324700
skip-if(Android) skip-if(gtkWidget&&isDebugBuild) load 789933-1.html # bug 1155252 for linux
load 794463-1.html
load 802926-1.html
load 896047-1.html

View File

@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
with Files('*'):
BUG_COMPONENT = ('Core', 'Video/Audio: Recording')
BUG_COMPONENT = ('Core', 'Audio/Video: Recording')
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['fmp4_muxer']

View File

@ -51,7 +51,7 @@ MFTDecoder::SetMediaTypes(IMFMediaType* aInputType,
HRESULT hr = mDecoder->SetInputType(0, aInputType, 0);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = SetDecoderOutputType(aCallback, aData);
hr = SetDecoderOutputType(true /* match all attributes */, aCallback, aData);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = mDecoder->GetInputStreamInfo(0, &mInputStreamInfo);
@ -76,21 +76,34 @@ MFTDecoder::GetAttributes()
}
HRESULT
MFTDecoder::SetDecoderOutputType(ConfigureOutputCallback aCallback, void* aData)
MFTDecoder::SetDecoderOutputType(bool aMatchAllAttributes,
ConfigureOutputCallback aCallback,
void* aData)
{
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
GUID currentSubtype = {0};
HRESULT hr = mOutputType->GetGUID(MF_MT_SUBTYPE, &currentSubtype);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
// Iterate the enumerate the output types, until we find one compatible
// with what we need.
HRESULT hr;
RefPtr<IMFMediaType> outputType;
UINT32 typeIndex = 0;
while (SUCCEEDED(mDecoder->GetOutputAvailableType(
0, typeIndex++, getter_AddRefs(outputType)))) {
BOOL resultMatch;
hr = mOutputType->Compare(
outputType, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &resultMatch);
if (SUCCEEDED(hr) && resultMatch == TRUE) {
GUID outSubtype = {0};
hr = outputType->GetGUID(MF_MT_SUBTYPE, &outSubtype);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
BOOL resultMatch = currentSubtype == outSubtype;
if (resultMatch && aMatchAllAttributes) {
hr = mOutputType->Compare(outputType, MF_ATTRIBUTES_MATCH_OUR_ITEMS,
&resultMatch);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
}
if (resultMatch == TRUE) {
if (aCallback) {
hr = aCallback(outputType, aData);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
@ -224,13 +237,6 @@ MFTDecoder::Output(RefPtr<IMFSample>* aOutput)
}
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
// Type change, probably geometric aperture change.
// Reconfigure decoder output type, so that GetOutputMediaType()
// returns the new type, and return the error code to caller.
// This is an expected failure, so don't warn on encountering it.
hr = SetDecoderOutputType(nullptr, nullptr);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
// Return the error, so that the caller knows to retry.
return MF_E_TRANSFORM_STREAM_CHANGE;
}

View File

@ -87,11 +87,10 @@ public:
// Sends a message to the MFT.
HRESULT SendMFTMessage(MFT_MESSAGE_TYPE aMsg, ULONG_PTR aData);
HRESULT SetDecoderOutputType(ConfigureOutputCallback aCallback, void* aData);
HRESULT SetDecoderOutputType(bool aMatchAllAttributes,
ConfigureOutputCallback aCallback,
void* aData);
private:
HRESULT CreateOutputSample(RefPtr<IMFSample>* aOutSample);
MFT_INPUT_STREAM_INFO mInputStreamInfo;

View File

@ -180,6 +180,12 @@ WMFAudioMFTManager::Init()
hr = outputType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 32);
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
hr = outputType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, mAudioChannels);
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
hr = outputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
hr = decoder->SetMediaTypes(inputType, outputType);
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
@ -233,6 +239,9 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
return hr;
}
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
hr = mDecoder->SetDecoderOutputType(true /* check all attribute */,
nullptr,
nullptr);
hr = UpdateOutputType();
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
// Catch infinite loops, but some decoders perform at least 2 stream

View File

@ -109,8 +109,8 @@ WMFVideoMFTManager::WMFVideoMFTManager(
layers::ImageContainer* aImageContainer,
bool aDXVAEnabled)
: mVideoInfo(aConfig)
, mVideoStride(0)
, mImageSize(aConfig.mImage)
, mVideoStride(0)
, mImageContainer(aImageContainer)
, mDXVAEnabled(aDXVAEnabled)
, mKnowsCompositor(aKnowsCompositor)
@ -572,9 +572,36 @@ WMFVideoMFTManager::InitInternal()
hr = SetDecoderMediaTypes();
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
RefPtr<IMFMediaType> outputType;
hr = mDecoder->GetOutputMediaType(outputType);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
if (mUseHwAccel && !CanUseDXVA(outputType)) {
mDXVAEnabled = false;
// DXVA initialization actually failed, re-do initialisation.
return InitInternal();
}
LOG("Video Decoder initialized, Using DXVA: %s",
(mUseHwAccel ? "Yes" : "No"));
if (mDXVA2Manager) {
hr = mDXVA2Manager->ConfigureForSize(mVideoInfo.ImageRect().width,
mVideoInfo.ImageRect().height);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
} else {
GetDefaultStride(outputType, mVideoInfo.ImageRect().width, &mVideoStride);
}
LOG("WMFVideoMFTManager frame geometry stride=%u picture=(%d, %d, %d, %d) "
"display=(%d,%d)",
mVideoStride,
mVideoInfo.ImageRect().x,
mVideoInfo.ImageRect().y,
mVideoInfo.ImageRect().width,
mVideoInfo.ImageRect().height,
mVideoInfo.mDisplay.width,
mVideoInfo.mDisplay.height);
return true;
}
@ -596,18 +623,14 @@ WMFVideoMFTManager::SetDecoderMediaTypes()
MFVideoInterlace_MixedInterlaceOrProgressive);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
// MSFT MFT needs this frame size set for VP9?
if (mStreamType == VP9 || mStreamType == VP8) {
hr =
inputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = inputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = MFSetAttributeSize(inputType,
MF_MT_FRAME_SIZE,
mVideoInfo.ImageRect().width,
mVideoInfo.ImageRect().height);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
}
hr = MFSetAttributeSize(inputType,
MF_MT_FRAME_SIZE,
mVideoInfo.ImageRect().width,
mVideoInfo.ImageRect().height);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
RefPtr<IMFMediaType> outputType;
hr = wmf::MFCreateMediaType(getter_AddRefs(outputType));
@ -616,6 +639,12 @@ WMFVideoMFTManager::SetDecoderMediaTypes()
hr = outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = MFSetAttributeSize(outputType,
MF_MT_FRAME_SIZE,
mVideoInfo.ImageRect().width,
mVideoInfo.ImageRect().height);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
GUID outputSubType = mUseHwAccel ? MFVideoFormat_NV12 : MFVideoFormat_YV12;
hr = outputType->SetGUID(MF_MT_SUBTYPE, outputSubType);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
@ -635,18 +664,19 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
return E_FAIL;
}
RefPtr<IMFSample> inputSample;
HRESULT hr = mDecoder->CreateInputSample(aSample->Data(),
uint32_t(aSample->Size()),
aSample->mTime,
&mLastInput);
NS_ENSURE_TRUE(SUCCEEDED(hr) && mLastInput != nullptr, hr);
&inputSample);
NS_ENSURE_TRUE(SUCCEEDED(hr) && inputSample != nullptr, hr);
mLastDuration = aSample->mDuration;
mLastTime = aSample->mTime;
mSamplesCount++;
// Forward sample data to the decoder.
return mDecoder->Input(mLastInput);
return mDecoder->Input(inputSample);
}
class SupportsConfigEvent : public Runnable {
@ -717,69 +747,6 @@ WMFVideoMFTManager::CanUseDXVA(IMFMediaType* aType)
return event->mSupportsConfig;
}
HRESULT
WMFVideoMFTManager::ConfigureVideoFrameGeometry()
{
RefPtr<IMFMediaType> mediaType;
HRESULT hr = mDecoder->GetOutputMediaType(mediaType);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
// If we enabled/disabled DXVA in response to a resolution
// change then we need to renegotiate our media types,
// and resubmit our previous frame (since the MFT appears
// to lose it otherwise).
if (mUseHwAccel && !CanUseDXVA(mediaType)) {
mDXVAEnabled = false;
if (!Init()) {
return E_FAIL;
}
mDecoder->Input(mLastInput);
return S_OK;
}
// Verify that the video subtype is what we expect it to be.
// When using hardware acceleration/DXVA2 the video format should
// be NV12, which is DXVA2's preferred format. For software decoding
// we use YV12, as that's easier for us to stick into our rendering
// pipeline than NV12. NV12 has interleaved UV samples, whereas YV12
// is a planar format.
GUID videoFormat;
hr = mediaType->GetGUID(MF_MT_SUBTYPE, &videoFormat);
NS_ENSURE_TRUE(videoFormat == MFVideoFormat_NV12 || !mUseHwAccel, E_FAIL);
NS_ENSURE_TRUE(videoFormat == MFVideoFormat_YV12 || mUseHwAccel, E_FAIL);
nsIntRect pictureRegion;
hr = GetPictureRegion(mediaType, pictureRegion);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
UINT32 width = pictureRegion.width;
UINT32 height = pictureRegion.height;
mImageSize = nsIntSize(width, height);
// Calculate and validate the picture region and frame dimensions after
// scaling by the pixel aspect ratio.
pictureRegion = mVideoInfo.ScaledImageRect(width, height);
if (!IsValidVideoRegion(mImageSize, pictureRegion, mVideoInfo.mDisplay)) {
// Video track's frame sizes will overflow. Ignore the video track.
return E_FAIL;
}
if (mDXVA2Manager) {
hr = mDXVA2Manager->ConfigureForSize(width, height);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
}
// Success! Save state.
GetDefaultStride(mediaType, width, &mVideoStride);
LOG("WMFVideoMFTManager frame geometry frame=(%u,%u) stride=%u picture=(%d, %d, %d, %d) display=(%d,%d)",
width, height,
mVideoStride,
pictureRegion.x, pictureRegion.y, pictureRegion.width, pictureRegion.height,
mVideoInfo.mDisplay.width, mVideoInfo.mDisplay.height);
return S_OK;
}
HRESULT
WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
@ -973,13 +940,25 @@ WMFVideoMFTManager::Output(int64_t aStreamOffset,
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
return MF_E_TRANSFORM_NEED_MORE_INPUT;
}
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
// Video stream output type change. Probably a geometric apperature
// change. Reconfigure the video geometry, so that we output the
// correct size frames.
MOZ_ASSERT(!sample);
hr = ConfigureVideoFrameGeometry();
// Video stream output type change, probably geometric aperture change.
// We must reconfigure the decoder output type.
hr = mDecoder->SetDecoderOutputType(false /* check all attribute */,
nullptr,
nullptr);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
if (!mUseHwAccel) {
// The stride may have changed, recheck for it.
RefPtr<IMFMediaType> outputType;
hr = mDecoder->GetOutputMediaType(outputType);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
hr = GetDefaultStride(outputType, mVideoInfo.ImageRect().width,
&mVideoStride);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
}
// Catch infinite loops, but some decoders perform at least 2 stream
// changes on consecutive calls, so be permissive.
// 100 is arbitrarily > 2.
@ -988,6 +967,7 @@ WMFVideoMFTManager::Output(int64_t aStreamOffset,
++typeChangeCount;
continue;
}
if (SUCCEEDED(hr)) {
if (!sample) {
LOG("Video MFTDecoder returned success but no output!");

View File

@ -73,8 +73,6 @@ private:
bool InitInternal();
HRESULT ConfigureVideoFrameGeometry();
HRESULT CreateBasicVideoFrame(IMFSample* aSample,
int64_t aStreamOffset,
VideoData** aOutVideoData);
@ -88,15 +86,14 @@ private:
bool CanUseDXVA(IMFMediaType* aType);
// Video frame geometry.
VideoInfo mVideoInfo;
const VideoInfo mVideoInfo;
const nsIntSize mImageSize;
uint32_t mVideoStride;
nsIntSize mImageSize;
RefPtr<layers::ImageContainer> mImageContainer;
RefPtr<layers::KnowsCompositor> mKnowsCompositor;
nsAutoPtr<DXVA2Manager> mDXVA2Manager;
RefPtr<IMFSample> mLastInput;
float mLastDuration;
int64_t mLastTime = 0;
bool mDraining = false;

View File

@ -10,7 +10,7 @@ load 493915-1.html
load 495794-1.html
load 576612-1.html
load 752784-1.html
skip-if(webrender) load 789075-1.html # bug 1322816 for webrender
load 789075-1.html
HTTP load 795892-1.html
load 844563.html
load 846612.html

View File

@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc
the need to run the cargo update command in js/src as well. Hopefully this will
be resolved soon.
Latest Commit: e30fb2914928c0e596d8632ed234647c0fd1492e
Latest Commit: 0794911f97cae92496fca992d7430da696fa24eb

View File

@ -8,13 +8,13 @@
#include "gfxConfig.h"
#include "gfxCrashReporterUtils.h"
#include "gfxUtils.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/Preferences.h"
#include "mozilla/Assertions.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Tokenizer.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Unused.h"
#include "mozilla/webrender/RenderThread.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsIGfxInfo.h"
@ -151,7 +151,7 @@ static bool
IsAccelAngleSupported(const nsCOMPtr<nsIGfxInfo>& gfxInfo,
nsACString* const out_failureId)
{
if (CompositorThreadHolder::IsInCompositorThread()) {
if (wr::RenderThread::IsInRenderThread()) {
// We can only enter here with WebRender, so assert that this is a
// WebRender-enabled build.
#ifndef MOZ_BUILD_WEBRENDER

View File

@ -1839,6 +1839,8 @@ CompositorBridgeParent::NotifyDidCompositeToPipeline(const wr::PipelineId& aPipe
}
MOZ_ASSERT(mWrBridge);
mWrBridge->CompositableHolder()->Update(aPipelineId, aEpoch);
if (mWrBridge->PipelineId() == aPipelineId) {
uint64_t transactionId = mWrBridge->FlushTransactionIdsForEpoch(aEpoch);
Unused << SendDidComposite(0, transactionId, aCompositeStart, aCompositeEnd);

View File

@ -134,6 +134,11 @@ void
CompositorVsyncScheduler::ScheduleComposition()
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
if (!mVsyncObserver) {
// Destroy was already called on this object.
return;
}
if (mAsapScheduling) {
// Used only for performance testing purposes
PostCompositeTask(TimeStamp::Now());

View File

@ -223,7 +223,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
WebRenderBridgeParent* parent = nullptr;
RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI();
RefPtr<WebRenderCompositableHolder> holder = new WebRenderCompositableHolder();
RefPtr<WebRenderCompositableHolder> holder = root->CompositableHolder();
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder));
parent->AddRef(); // IPDL reference

View File

@ -192,7 +192,6 @@ EXPORTS.mozilla.layers += [
'TextureSourceProvider.h',
'TextureWrapperImage.h',
'TransactionIdAllocator.h',
'wr/WebRenderBorderLayer.h',
'wr/WebRenderBridgeChild.h',
'wr/WebRenderBridgeParent.h',
'wr/WebRenderCompositableHolder.h',
@ -379,7 +378,6 @@ UNIFIED_SOURCES += [
'SourceSurfaceVolatileData.cpp',
'TextureSourceProvider.cpp',
'TextureWrapperImage.cpp',
'wr/WebRenderBorderLayer.cpp',
'wr/WebRenderBridgeChild.cpp',
'wr/WebRenderBridgeParent.cpp',
'wr/WebRenderCanvasLayer.cpp',

View File

@ -1,79 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebRenderBorderLayer.h"
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
/* static */void
WebRenderBorderLayer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
BorderColors& aColors,
BorderCorners& aCorners,
BorderWidths& aWidths,
BorderStyles& aBorderStyles,
Rect aRect,
Rect aClipRect,
Rect aRelBounds,
Rect aOverflow)
{
aBuilder.PushStackingContext(wr::ToWrRect(aRelBounds),
wr::ToWrRect(aOverflow),
nullptr,
1.0f,
aLayer->GetLayer()->GetTransform(),
wr::MixBlendMode::Normal);
aBuilder.PushBorder(wr::ToWrRect(aRect), aBuilder.BuildClipRegion(wr::ToWrRect(aClipRect)),
wr::ToWrBorderWidths(aWidths[0], aWidths[1], aWidths[2], aWidths[3]),
wr::ToWrBorderSide(aColors[0], aBorderStyles[0]),
wr::ToWrBorderSide(aColors[1], aBorderStyles[1]),
wr::ToWrBorderSide(aColors[2], aBorderStyles[2]),
wr::ToWrBorderSide(aColors[3], aBorderStyles[3]),
wr::ToWrBorderRadius(aCorners[eCornerTopLeft], aCorners[eCornerTopRight],
aCorners[eCornerBottomLeft], aCorners[eCornerBottomRight]));
aBuilder.PopStackingContext();
}
void
WebRenderBorderLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{
gfx::Rect relBounds = GetWrRelBounds();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
gfx::Rect rect = GetWrBoundsRect();
gfx::Rect clipRect = GetWrClipRect(rect);
DumpLayerInfo("BorderLayer", rect);
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
wr::ToWrRect(overflow),
nullptr,
1.0f,
//GetAnimations(),
GetTransform(),
wr::MixBlendMode::Normal);
aBuilder.PushBorder(wr::ToWrRect(rect), aBuilder.BuildClipRegion(wr::ToWrRect(clipRect)),
wr::ToWrBorderWidths(mWidths[0], mWidths[1], mWidths[2], mWidths[3]),
wr::ToWrBorderSide(mColors[0], mBorderStyles[0]),
wr::ToWrBorderSide(mColors[1], mBorderStyles[1]),
wr::ToWrBorderSide(mColors[2], mBorderStyles[2]),
wr::ToWrBorderSide(mColors[3], mBorderStyles[3]),
wr::ToWrBorderRadius(mCorners[eCornerTopLeft], mCorners[eCornerTopRight],
mCorners[eCornerBottomLeft], mCorners[eCornerBottomRight]));
aBuilder.PopStackingContext();
}
} // namespace layers
} // namespace mozilla

View File

@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_WEBRENDERBORDERLAYER_H
#define GFX_WEBRENDERBORDERLAYER_H
#include "Layers.h"
#include "WebRenderLayerManager.h"
namespace mozilla {
namespace layers {
class WebRenderBorderLayer : public WebRenderLayer,
public BorderLayer {
public:
explicit WebRenderBorderLayer(WebRenderLayerManager* aLayerManager)
: BorderLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
{
MOZ_COUNT_CTOR(WebRenderBorderLayer);
}
static void
CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
BorderColors& aColors,
BorderCorners& aCorners,
BorderWidths& aWidths,
BorderStyles& aBorderStyles,
gfx::Rect aRect,
gfx::Rect aClipRect,
gfx::Rect aRelBounds,
gfx::Rect aOverflow);
protected:
virtual ~WebRenderBorderLayer()
{
MOZ_COUNT_DTOR(WebRenderBorderLayer);
}
public:
Layer* GetLayer() override { return this; }
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
};
} // namespace layers
} // namespace mozilla
#endif // GFX_WEBRENDERBORDERLAYER_H

View File

@ -37,6 +37,17 @@ bool is_in_render_thread()
return mozilla::wr::RenderThread::IsInRenderThread();
}
bool is_glcontext_egl(void* glcontext_ptr)
{
MOZ_ASSERT(glcontext_ptr);
mozilla::gl::GLContext* glcontext = reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
if (!glcontext) {
return false;
}
return glcontext->GetContextType() == mozilla::gl::GLContextType::EGL;
}
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
{
MOZ_ASSERT(glcontext_ptr);
@ -102,6 +113,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos
, mDestroyed(false)
{
MOZ_ASSERT(mCompositableHolder);
mCompositableHolder->AddPipeline(mPipelineId);
if (mWidget) {
MOZ_ASSERT(!mCompositorScheduler);
mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
@ -316,7 +328,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
mApi->AddExternalImageBuffer(key,
descriptor,
wrTexture->GetExternalImageKey());
mCompositableHolder->HoldExternalImage(aEpoch, texture->AsWebRenderTextureHost());
mCompositableHolder->HoldExternalImage(mPipelineId, aEpoch, texture->AsWebRenderTextureHost());
keysToDelete.push_back(key);
break;
}
@ -337,10 +349,6 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
keysToDelete.push_back(key);
dSurf->Unmap();
// XXX workaround for releasing Readlock. See Bug 1339625
if(host->GetType() == CompositableType::CONTENT_SINGLE) {
host->CleanupResources();
}
break;
}
case WebRenderParentCommand::TCompositableOperation: {
@ -563,9 +571,6 @@ WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
}
mPendingTransactionIds.pop();
}
mCompositableHolder->Update(aEpoch);
return id;
}
@ -602,9 +607,7 @@ WebRenderBridgeParent::ClearResources()
DeleteOldImages();
}
}
if (mCompositableHolder) {
mCompositableHolder->Destroy();
}
mCompositableHolder->RemovePipeline(mPipelineId);
mExternalImageIds.Clear();
if (mWidget && mCompositorScheduler) {

View File

@ -23,36 +23,54 @@ WebRenderCompositableHolder::WebRenderCompositableHolder()
WebRenderCompositableHolder::~WebRenderCompositableHolder()
{
MOZ_COUNT_DTOR(WebRenderCompositableHolder);
MOZ_ASSERT(mWebRenderTextureHosts.empty());
MOZ_ASSERT(mPipelineTexturesHolders.IsEmpty());
}
void
WebRenderCompositableHolder::Destroy()
WebRenderCompositableHolder::AddPipeline(const wr::PipelineId& aPipelineId)
{
while (!mWebRenderTextureHosts.empty()) {
mWebRenderTextureHosts.pop();
uint64_t id = wr::AsUint64(aPipelineId);
MOZ_ASSERT(!mPipelineTexturesHolders.Get(id));
PipelineTexturesHolder* holder = new PipelineTexturesHolder();
mPipelineTexturesHolders.Put(id, holder);
}
void
WebRenderCompositableHolder::RemovePipeline(const wr::PipelineId& aPipelineId)
{
uint64_t id = wr::AsUint64(aPipelineId);
if (mPipelineTexturesHolders.Get(id)) {
mPipelineTexturesHolders.Remove(id);
}
}
void
WebRenderCompositableHolder::HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
WebRenderCompositableHolder::HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
{
MOZ_ASSERT(aTexture);
PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId));
MOZ_ASSERT(holder);
if (!holder) {
return;
}
// Hold WebRenderTextureHost until end of its usage on RenderThread
mWebRenderTextureHosts.push(ForwardingTextureHosts(aEpoch, aTexture));
holder->mTextureHosts.push(ForwardingTextureHost(aEpoch, aTexture));
}
void
WebRenderCompositableHolder::Update(const wr::Epoch& aEpoch)
WebRenderCompositableHolder::Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch)
{
if (mWebRenderTextureHosts.empty()) {
PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId));
if (!holder || holder->mTextureHosts.empty()) {
return;
}
while (!mWebRenderTextureHosts.empty()) {
if (aEpoch <= mWebRenderTextureHosts.front().mEpoch) {
while (!holder->mTextureHosts.empty()) {
if (aEpoch <= holder->mTextureHosts.front().mEpoch) {
break;
}
mWebRenderTextureHosts.pop();
holder->mTextureHosts.pop();
}
}

View File

@ -10,6 +10,7 @@
#include "mozilla/layers/TextureHost.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsClassHashtable.h"
namespace mozilla {
@ -33,14 +34,15 @@ protected:
~WebRenderCompositableHolder();
public:
void Destroy();
void HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
void Update(const wr::Epoch& aEpoch);
void AddPipeline(const wr::PipelineId& aPipelineId);
void RemovePipeline(const wr::PipelineId& aPipelineId);
void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
void Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch);
private:
struct ForwardingTextureHosts {
ForwardingTextureHosts(const wr::Epoch& aEpoch, TextureHost* aTexture)
struct ForwardingTextureHost {
ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
: mEpoch(aEpoch)
, mTexture(aTexture)
{}
@ -48,8 +50,12 @@ private:
CompositableTextureHostRef mTexture;
};
// Holds forwarding WebRenderTextureHosts.
std::queue<ForwardingTextureHosts> mWebRenderTextureHosts;
struct PipelineTexturesHolder {
// Holds forwarding WebRenderTextureHosts.
std::queue<ForwardingTextureHost> mTextureHosts;
};
nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders;
};
} // namespace layers

View File

@ -17,7 +17,6 @@
#include "mozilla/widget/PlatformWidgetTypes.h"
#include "nsThreadUtils.h"
#include "TreeTraversal.h"
#include "WebRenderBorderLayer.h"
#include "WebRenderCanvasLayer.h"
#include "WebRenderColorLayer.h"
#include "WebRenderContainerLayer.h"
@ -541,7 +540,7 @@ WebRenderLayerManager::CreateTextLayer()
already_AddRefed<BorderLayer>
WebRenderLayerManager::CreateBorderLayer()
{
return MakeAndAddRef<WebRenderBorderLayer>(this);
return nullptr;
}
already_AddRefed<DisplayItemLayer>

View File

@ -5,7 +5,6 @@
#include "nsFont.h"
#include "gfxFont.h" // for gfxFontStyle
#include "gfxFontConstants.h" // for NS_FONT_KERNING_AUTO, etc
#include "gfxFontFeatures.h" // for gfxFontFeature, etc
#include "gfxFontUtils.h" // for TRUETYPE_TAG
#include "nsCRT.h" // for nsCRT
@ -20,37 +19,14 @@ using namespace mozilla;
nsFont::nsFont(const FontFamilyList& aFontlist, nscoord aSize)
: fontlist(aFontlist)
, size(aSize)
{
Init();
size = aSize;
}
nsFont::nsFont(FontFamilyType aGenericType, nscoord aSize)
: fontlist(aGenericType)
, size(aSize)
{
Init();
size = aSize;
}
void
nsFont::Init()
{
style = NS_FONT_STYLE_NORMAL;
weight = NS_FONT_WEIGHT_NORMAL;
stretch = NS_FONT_STRETCH_NORMAL;
systemFont = false;
smoothing = NS_FONT_SMOOTHING_AUTO;
sizeAdjust = -1.0f;
kerning = NS_FONT_KERNING_AUTO;
synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
variantAlternates = 0;
variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
variantEastAsian = 0;
variantLigatures = 0;
variantNumeric = 0;
variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
variantWidth = NS_FONT_VARIANT_WIDTH_NORMAL;
}
nsFont::nsFont(const nsFont& aOther) = default;

View File

@ -9,6 +9,7 @@
#include <stdint.h> // for uint8_t, uint16_t
#include <sys/types.h> // for int16_t
#include "gfxFontFamilyList.h"
#include "gfxFontConstants.h" // for NS_FONT_KERNING_AUTO, etc
#include "gfxFontFeatures.h"
#include "gfxFontVariations.h"
#include "mozilla/RefPtr.h" // for RefPtr
@ -46,52 +47,52 @@ struct nsFont {
mozilla::FontFamilyList fontlist;
// The style of font (normal, italic, oblique; see gfxFontConstants.h)
uint8_t style;
uint8_t style = NS_FONT_STYLE_NORMAL;
// Force this font to not be considered a 'generic' font, even if
// the name is the same as a CSS generic font family.
bool systemFont;
bool systemFont = false;
// Variant subproperties
uint8_t variantCaps;
uint8_t variantNumeric;
uint8_t variantPosition;
uint8_t variantWidth;
uint8_t variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
uint8_t variantNumeric = 0;
uint8_t variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
uint8_t variantWidth = NS_FONT_VARIANT_WIDTH_NORMAL;
uint16_t variantLigatures;
uint16_t variantEastAsian;
uint16_t variantLigatures = 0;
uint16_t variantEastAsian = 0;
// Some font-variant-alternates property values require
// font-specific settings defined via @font-feature-values rules.
// These are resolved *after* font matching occurs.
// -- bitmask for both enumerated and functional propvals
uint16_t variantAlternates;
uint16_t variantAlternates = 0;
// Smoothing - controls subpixel-antialiasing (currently OSX only)
uint8_t smoothing;
uint8_t smoothing = NS_FONT_SMOOTHING_AUTO;
// The weight of the font; see gfxFontConstants.h.
uint16_t weight;
uint16_t weight = NS_FONT_WEIGHT_NORMAL;
// The stretch of the font (the sum of various NS_FONT_STRETCH_*
// constants; see gfxFontConstants.h).
int16_t stretch;
int16_t stretch = NS_FONT_STRETCH_NORMAL;
// Kerning
uint8_t kerning;
uint8_t kerning = NS_FONT_KERNING_AUTO;
// Synthesis setting, controls use of fake bolding/italics
uint8_t synthesis;
uint8_t synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
// The logical size of the font, in nscoord units
nscoord size;
nscoord size = 0;
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
// actual physical font created from this font structure must have when
// rendering or measuring a string. A value of -1.0 means no adjustment
// needs to be done; otherwise the value must be nonnegative.
float sizeAdjust;
float sizeAdjust = -1.0f;
// -- list of value tags for font-specific alternate features
nsTArray<gfxAlternateValue> alternateValues;
@ -108,7 +109,7 @@ struct nsFont {
// Language system tag, to override document language;
// this is an OpenType "language system" tag represented as a 32-bit integer
// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
nsString languageOverride;
uint32_t languageOverride = 0;
// initialize the font with a fontlist
nsFont(const mozilla::FontFamilyList& aFontlist, nscoord aSize);
@ -142,9 +143,6 @@ struct nsFont {
void AddFontFeaturesToStyle(gfxFontStyle *aStyle) const;
void AddFontVariationsToStyle(gfxFontStyle *aStyle) const;
protected:
void Init(); // helper method for initialization
};
#define NS_FONT_VARIANT_NORMAL 0

View File

@ -3862,29 +3862,8 @@ gfxFont::RemoveGlyphChangeObserver(GlyphChangeObserver *aObserver)
mGlyphChangeObservers->RemoveEntry(aObserver);
}
#define DEFAULT_PIXEL_FONT_SIZE 16.0f
/*static*/ uint32_t
gfxFontStyle::ParseFontLanguageOverride(const nsString& aLangTag)
{
if (!aLangTag.Length() || aLangTag.Length() > 4) {
return NO_FONT_LANGUAGE_OVERRIDE;
}
uint32_t index, result = 0;
for (index = 0; index < aLangTag.Length(); ++index) {
char16_t ch = aLangTag[index];
if (!nsCRT::IsAscii(ch)) { // valid tags are pure ASCII
return NO_FONT_LANGUAGE_OVERRIDE;
}
result = (result << 8) + ch;
}
while (index++ < 4) {
result = (result << 8) + 0x20;
}
return result;
}
gfxFontStyle::gfxFontStyle() :
language(nsGkAtoms::x_western),
size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(-1.0f), baselineOffset(0.0f),
@ -3907,10 +3886,10 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
bool aPrinterFont,
bool aAllowWeightSynthesis,
bool aAllowStyleSynthesis,
const nsString& aLanguageOverride):
uint32_t aLanguageOverride):
language(aLanguage),
size(aSize), sizeAdjust(aSizeAdjust), baselineOffset(0.0f),
languageOverride(ParseFontLanguageOverride(aLanguageOverride)),
languageOverride(aLanguageOverride),
weight(aWeight), stretch(aStretch),
style(aStyle),
variantCaps(NS_FONT_VARIANT_CAPS_NORMAL),

View File

@ -81,7 +81,7 @@ struct gfxFontStyle {
float aSizeAdjust, bool aSystemFont,
bool aPrinterFont,
bool aWeightSynthesis, bool aStyleSynthesis,
const nsString& aLanguageOverride);
uint32_t aLanguageOverride);
// the language (may be an internal langGroup code rather than an actual
// language code) specified in the document or element's lang property,
@ -216,8 +216,6 @@ struct gfxFontStyle {
(variationSettings == other.variationSettings) &&
(languageOverride == other.languageOverride);
}
static uint32_t ParseFontLanguageOverride(const nsString& aLangTag);
};
struct gfxTextRange {

View File

@ -684,6 +684,9 @@ gfxPlatform::Init()
#error "No gfxPlatform implementation available"
#endif
gPlatform->InitAcceleration();
if (XRE_IsParentProcess()) {
gPlatform->InitWebRenderConfig();
}
if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
GPUProcessManager* gpu = GPUProcessManager::Get();
@ -2197,7 +2200,6 @@ gfxPlatform::InitAcceleration()
Preferences::RegisterCallbackAndCall(VideoDecodingFailedChangedCallback,
"media.hardware-video-decoding.failed");
InitGPUProcessPrefs();
InitWebRenderConfig();
}
}

View File

@ -464,6 +464,7 @@ private:
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.bullet-layers", LayersAllowBulletLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.button-foreground-layers", LayersAllowButtonForegroundLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.canvas-background-color", LayersAllowCanvasBackgroundColorLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, bool, false);

View File

@ -206,7 +206,7 @@ public:
// weight - [100, 900] (multiples of 100)
// stretch = [NS_FONT_STRETCH_ULTRA_CONDENSED, NS_FONT_STRETCH_ULTRA_EXPANDED]
// italic style = constants in gfxFontConstants.h, e.g. NS_FONT_STYLE_NORMAL
// language override = result of calling gfxFontStyle::ParseFontLanguageOverride
// language override = result of calling nsRuleNode::ParseFontLanguageOverride
// TODO: support for unicode ranges not yet implemented
virtual already_AddRefed<gfxUserFontEntry> CreateUserFontEntry(
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,

View File

@ -1,6 +1,6 @@
[package]
name = "webrender"
version = "0.24.0"
version = "0.25.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
@ -18,11 +18,11 @@ bit-set = "0.4"
byteorder = "1.0"
euclid = "0.11"
fnv = "1.0"
gleam = "0.2.30"
gleam = "0.4.1"
lazy_static = "0.2"
log = "0.3"
num-traits = "0.1.32"
offscreen_gl_context = {version = "0.6", features = ["serde", "osmesa"]}
offscreen_gl_context = {version = "0.8.0", features = ["serde", "osmesa"]}
time = "0.1"
threadpool = "1.3.2"
webrender_traits = {path = "../webrender_traits"}

View File

@ -503,52 +503,104 @@ struct TransformVertexInfo {
vec4 clipped_local_rect;
};
float cross2(vec2 v0, vec2 v1) {
return v0.x * v1.y - v0.y * v1.x;
}
// Return intersection of line (p0,p1) and line (p2,p3)
vec2 intersect_lines(vec2 p0, vec2 p1, vec2 p2, vec2 p3) {
vec2 d0 = p0 - p1;
vec2 d1 = p2 - p3;
float s0 = cross2(p0, p1);
float s1 = cross2(p2, p3);
float d = cross2(d0, d1);
float nx = s0 * d1.x - d0.x * s1;
float ny = s0 * d1.y - d0.y * s1;
return vec2(nx / d, ny / d);
}
TransformVertexInfo write_transform_vertex(RectWithSize instance_rect,
RectWithSize local_clip_rect,
float z,
Layer layer,
AlphaBatchTask task) {
vec2 lp0_base = instance_rect.p0;
vec2 lp1_base = instance_rect.p0 + instance_rect.size;
RectWithEndpoint local_rect = to_rect_with_endpoint(instance_rect);
vec2 lp0 = clamp_rect(clamp_rect(lp0_base, local_clip_rect),
layer.local_clip_rect);
vec2 lp1 = clamp_rect(clamp_rect(lp1_base, local_clip_rect),
layer.local_clip_rect);
vec2 current_local_pos, prev_local_pos, next_local_pos;
vec4 clipped_local_rect = vec4(lp0, lp1 - lp0);
// Select the current vertex and the previous/next vertices,
// based on the vertex ID that is known based on the instance rect.
switch (gl_VertexID) {
case 0:
current_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
next_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
prev_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
break;
case 1:
current_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
next_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
prev_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
break;
case 2:
current_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
prev_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
next_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
break;
case 3:
current_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
prev_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
next_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
break;
}
vec2 p0 = lp0;
vec2 p1 = vec2(lp1.x, lp0.y);
vec2 p2 = vec2(lp0.x, lp1.y);
vec2 p3 = lp1;
// Transform them to world space
vec4 current_world_pos = layer.transform * vec4(current_local_pos, 0.0, 1.0);
vec4 prev_world_pos = layer.transform * vec4(prev_local_pos, 0.0, 1.0);
vec4 next_world_pos = layer.transform * vec4(next_local_pos, 0.0, 1.0);
vec4 t0 = layer.transform * vec4(p0, 0, 1);
vec4 t1 = layer.transform * vec4(p1, 0, 1);
vec4 t2 = layer.transform * vec4(p2, 0, 1);
vec4 t3 = layer.transform * vec4(p3, 0, 1);
// Convert to device space
vec2 current_device_pos = uDevicePixelRatio * current_world_pos.xy / current_world_pos.w;
vec2 prev_device_pos = uDevicePixelRatio * prev_world_pos.xy / prev_world_pos.w;
vec2 next_device_pos = uDevicePixelRatio * next_world_pos.xy / next_world_pos.w;
vec2 tp0 = t0.xy / t0.w;
vec2 tp1 = t1.xy / t1.w;
vec2 tp2 = t2.xy / t2.w;
vec2 tp3 = t3.xy / t3.w;
// Get the normals of each of the vectors between the current and next/prev vertices.
const float amount = 2.0;
vec2 dir_prev = normalize(current_device_pos - prev_device_pos);
vec2 dir_next = normalize(current_device_pos - next_device_pos);
vec2 norm_prev = vec2(-dir_prev.y, dir_prev.x);
vec2 norm_next = vec2( dir_next.y, -dir_next.x);
// compute a CSS space aligned bounding box
vec2 min_pos = uDevicePixelRatio * min(min(tp0.xy, tp1.xy), min(tp2.xy, tp3.xy));
vec2 max_pos = uDevicePixelRatio * max(max(tp0.xy, tp1.xy), max(tp2.xy, tp3.xy));
// Push those lines out along the normal by a specific amount of device pixels.
vec2 adjusted_prev_p0 = current_device_pos + norm_prev * amount;
vec2 adjusted_prev_p1 = prev_device_pos + norm_prev * amount;
vec2 adjusted_next_p0 = current_device_pos + norm_next * amount;
vec2 adjusted_next_p1 = next_device_pos + norm_next * amount;
// compute the device space position of this vertex
vec2 device_pos = mix(min_pos, max_pos, aPosition.xy);
// Intersect those adjusted lines to find the actual vertex position.
vec2 device_pos = intersect_lines(adjusted_prev_p0,
adjusted_prev_p1,
adjusted_next_p0,
adjusted_next_p1);
// compute the point position in side the layer, in CSS space
vec4 layer_pos = get_layer_pos(device_pos / uDevicePixelRatio, layer);
// Calculate the snap amount based on the first vertex as a reference point.
vec4 world_p0 = layer.transform * vec4(local_rect.p0, 0.0, 1.0);
vec2 device_p0 = uDevicePixelRatio * world_p0.xy / world_p0.w;
vec2 snap_delta = device_p0 - floor(device_p0 + 0.5);
// apply the task offset
vec2 final_pos = device_pos - task.screen_space_origin + task.render_target_origin;
// Apply offsets for the render task to get correct screen location.
vec2 final_pos = device_pos -
snap_delta -
task.screen_space_origin +
task.render_target_origin;
gl_Position = uTransform * vec4(final_pos, z, 1.0);
return TransformVertexInfo(layer_pos.xyw, device_pos, clipped_local_rect);
vec4 layer_pos = get_layer_pos(device_pos / uDevicePixelRatio, layer);
return TransformVertexInfo(layer_pos.xyw, device_pos, vec4(instance_rect.p0, instance_rect.size));
}
#endif //WR_FEATURE_TRANSFORM
@ -663,20 +715,35 @@ void write_clip(vec2 global_pos, ClipArea area) {
#endif //WR_VERTEX_SHADER
#ifdef WR_FRAGMENT_SHADER
float distance_from_rect(vec2 p, vec2 origin, vec2 size) {
vec2 clamped = clamp(p, origin, origin + size);
return distance(clamped, p);
float signed_distance_rect(vec2 pos, vec2 p0, vec2 p1) {
vec2 d = max(p0 - pos, pos - p1);
return length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y));
}
vec2 init_transform_fs(vec3 local_pos, vec4 local_rect, out float fragment_alpha) {
fragment_alpha = 1.0;
vec2 pos = local_pos.xy / local_pos.z;
float border_distance = distance_from_rect(pos, local_rect.xy, local_rect.zw);
if (border_distance != 0.0) {
float delta = length(fwidth(local_pos.xy));
fragment_alpha = 1.0 - smoothstep(0.0, 1.0, border_distance / delta * 2.0);
}
// Because the local rect is placed on whole coordinates, but the interpolation
// occurs at pixel centers, we need to offset the signed distance by that amount.
// In the simple case of no zoom, and no transform, this is 0.5. However, we
// need to scale this by the amount that the local rect is changing by per
// fragment, based on the current zoom and transform.
vec2 fw = fwidth(pos.xy);
vec2 dxdy = 0.5 * fw;
// Now get the actual signed distance. Inset the local rect by the offset amount
// above to get correct distance values. This ensures that we only apply
// anti-aliasing when the fragment has partial coverage.
float d = signed_distance_rect(pos,
local_rect.xy + dxdy,
local_rect.xy + local_rect.zw - dxdy);
// Find the appropriate distance to apply the AA smoothstep over.
float afwidth = 0.5 / length(fw);
// Only apply AA to fragments outside the signed distance field.
fragment_alpha = 1.0 - smoothstep(0.0, afwidth, d);
return pos;
}

View File

@ -56,12 +56,57 @@ float alpha_for_solid_border(float distance_from_ref,
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
}
float alpha_for_solid_ellipse_border(vec2 local_pos,
vec2 inner_radius,
vec2 outer_radius,
float pixels_per_fragment) {
vec2 distance_from_ref = local_pos - vRefPoint;
float nudge = pixels_per_fragment;
inner_radius += nudge;
outer_radius -= nudge;
float inner_ellipse = distance_from_ref.x * distance_from_ref.x / inner_radius.x / inner_radius.x +
distance_from_ref.y * distance_from_ref.y / inner_radius.y / inner_radius.y;
float outer_ellipse = distance_from_ref.x * distance_from_ref.x / outer_radius.x / outer_radius.x +
distance_from_ref.y * distance_from_ref.y / outer_radius.y / outer_radius.y;
if (inner_ellipse > 1.0 && outer_ellipse < 1.0) {
return 1.0;
}
vec2 offset = step(inner_radius.yx, inner_radius.xy) *
(sqrt(abs(inner_radius.x * inner_radius.x - inner_radius.y * inner_radius.y)));
vec2 focus1 = vRefPoint + offset;
vec2 focus2 = vRefPoint - offset;
float inner_distance_from_border = max(inner_radius.x, inner_radius.y) -
(distance(focus1, local_pos) + distance(focus2, local_pos)) / 2.0;
offset = step(outer_radius.yx, outer_radius.xy) *
(sqrt(abs(outer_radius.x * outer_radius.x - outer_radius.y * outer_radius.y)));
focus1 = vRefPoint + offset;
focus2 = vRefPoint - offset;
float outer_distance_from_border = (distance(focus1, local_pos) + distance(focus2, local_pos)) / 2.0 -
max(outer_radius.x, outer_radius.y);
float distance_from_border = max(inner_distance_from_border, outer_distance_from_border);
// Move the distance back into pixels.
distance_from_border /= pixels_per_fragment;
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
}
float alpha_for_solid_border_corner(vec2 local_pos,
float inner_radius,
float outer_radius,
vec2 inner_radius,
vec2 outer_radius,
float pixels_per_fragment) {
float distance_from_ref = distance(vRefPoint, local_pos);
return alpha_for_solid_border(distance_from_ref, inner_radius, outer_radius, pixels_per_fragment);
if (inner_radius.x == inner_radius.y && outer_radius.x == outer_radius.y) {
float distance_from_ref = distance(vRefPoint, local_pos);
return alpha_for_solid_border(distance_from_ref, inner_radius.x, outer_radius.x, pixels_per_fragment);
} else {
return alpha_for_solid_ellipse_border(local_pos, inner_radius, outer_radius, pixels_per_fragment);
}
}
vec4 draw_dotted_edge(vec2 local_pos, vec4 piece_rect, float pixels_per_fragment) {
@ -144,8 +189,8 @@ void draw_dashed_or_dotted_border(vec2 local_pos, float distance_from_mix_line)
oFragColor = get_fragment_color(distance_from_mix_line, pixels_per_fragment);
if (vRadii.x > 0.0) {
oFragColor *= vec4(1.0, 1.0, 1.0, alpha_for_solid_border_corner(local_pos,
vRadii.z,
vRadii.x,
vRadii.zw,
vRadii.xy,
pixels_per_fragment));
}
@ -199,16 +244,16 @@ vec4 draw_double_edge_vertical(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
// Get our position within this specific segment
float position = local_pos.x - vLocalRect.x;
return draw_double_edge(position, vLocalRect.z, distance_from_mix_line, pixels_per_fragment);
float position = abs(local_pos.x - vRefPoint.x);
return draw_double_edge(position, abs(vPieceRect.z), distance_from_mix_line, pixels_per_fragment);
}
vec4 draw_double_edge_horizontal(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
// Get our position within this specific segment
float position = local_pos.y - vLocalRect.y;
return draw_double_edge(position, vLocalRect.w, distance_from_mix_line, pixels_per_fragment);
float position = abs(local_pos.y - vRefPoint.y);
return draw_double_edge(position, abs(vPieceRect.w), distance_from_mix_line, pixels_per_fragment);
}
vec4 draw_double_edge_corner_with_radius(vec2 local_pos,
@ -216,17 +261,20 @@ vec4 draw_double_edge_corner_with_radius(vec2 local_pos,
float pixels_per_fragment) {
float total_border_width = vRadii.x - vRadii.z;
float one_third_width = total_border_width / 3.0;
float total_border_height = vRadii.y - vRadii.w;
float one_third_height = total_border_height / 3.0;
// Contribution of the outer border segment.
float alpha = alpha_for_solid_border_corner(local_pos,
vRadii.x - one_third_width,
vRadii.x,
vec2(vRadii.x - one_third_width,
vRadii.y - one_third_height),
vec2(vRadii.x, vRadii.y),
pixels_per_fragment);
// Contribution of the inner border segment.
alpha += alpha_for_solid_border_corner(local_pos,
vRadii.z,
vRadii.z + one_third_width,
vec2(vRadii.z, vRadii.w),
vec2(vRadii.z + one_third_width, vRadii.w + one_third_height),
pixels_per_fragment);
return get_fragment_color(distance_from_mix_line, pixels_per_fragment) * vec4(1.0, 1.0, 1.0, alpha);
}
@ -291,7 +339,7 @@ void draw_solid_border(float distanceFromMixLine, vec2 localPos) {
oFragColor = get_fragment_color(distanceFromMixLine, pixelsPerFragment);
if (vRadii.x > 0.0) {
float alpha = alpha_for_solid_border_corner(localPos, vRadii.z, vRadii.x, pixelsPerFragment);
float alpha = alpha_for_solid_border_corner(localPos, vRadii.zw, vRadii.xy, pixelsPerFragment);
oFragColor *= vec4(1.0, 1.0, 1.0, alpha);
}

View File

@ -3,7 +3,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
void main(void) {
vec2 uv = min(vec2(1.0), vMirrorPoint - abs(vUv.xy - vMirrorPoint));
// Mirror and stretch the box shadow corner over the entire
// primitives.
vec2 uv = vMirrorPoint - abs(vUv.xy - vMirrorPoint);
// Ensure that we don't fetch texels outside the box
// shadow corner. This can happen, for example, when
// drawing the outer parts of an inset box shadow.
uv = clamp(uv, vec2(0.0), vec2(1.0));
// Map the unit UV to the actual UV rect in the cache.
uv = mix(vCacheUvRectCoords.xy, vCacheUvRectCoords.zw, uv);
// Modulate the box shadow by the color.
oFragColor = vColor * texture(sCache, vec3(uv, vUv.z));
}

View File

@ -13,7 +13,7 @@ use util::TransformedRect;
use webrender_traits::{ClipRegion, LayerPixel, LayerPoint, LayerRect, LayerSize};
use webrender_traits::{LayerToScrollTransform, LayerToWorldTransform, PipelineId};
use webrender_traits::{ScrollEventPhase, ScrollLayerId, ScrollLayerRect, ScrollLocation};
use webrender_traits::{ServoScrollRootId, WorldPoint, WorldPoint4D};
use webrender_traits::{WorldPoint, WorldPoint4D};
#[cfg(target_os = "macos")]
const CAN_OVERSCROLL: bool = true;
@ -38,17 +38,12 @@ pub struct ClipInfo {
/// which depends on the screen rectangle and the transformation of all of
/// the parents.
pub xf_rect: Option<TransformedRect>,
/// An external identifier that is used to scroll this clipping node
/// from the API.
pub scroll_root_id: Option<ServoScrollRootId>,
}
impl ClipInfo {
pub fn new(clip_region: &ClipRegion,
clip_store: &mut VertexDataStore<GpuBlock32>,
packed_layer_index: PackedLayerIndex,
scroll_root_id: Option<ServoScrollRootId>)
packed_layer_index: PackedLayerIndex,)
-> ClipInfo {
// We pass true here for the MaskCacheInfo because this type of
// mask needs an extra clip for the clip rectangle.
@ -58,7 +53,6 @@ impl ClipInfo {
clip_source: clip_source,
packed_layer_index: packed_layer_index,
xf_rect: None,
scroll_root_id: scroll_root_id,
}
}
@ -195,6 +189,15 @@ impl ClipScrollNode {
}
pub fn set_scroll_origin(&mut self, origin: &LayerPoint) -> bool {
match self.node_type {
NodeType::ReferenceFrame(_) => {
warn!("Tried to scroll a reference frame.");
return false;
}
NodeType::Clip(_) => {}
};
let scrollable_height = self.scrollable_height();
let scrollable_width = self.scrollable_width();
if scrollable_height <= 0. && scrollable_width <= 0. {

View File

@ -7,15 +7,14 @@ use fnv::FnvHasher;
use std::collections::{HashMap, HashSet};
use std::hash::BuildHasherDefault;
use webrender_traits::{LayerPoint, LayerRect, LayerToScrollTransform, LayerToWorldTransform};
use webrender_traits::{PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerInfo};
use webrender_traits::{ScrollLayerRect, ScrollLayerState, ScrollLocation, ServoScrollRootId};
use webrender_traits::{WorldPoint, as_scroll_parent_rect};
use webrender_traits::{PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerRect};
use webrender_traits::{ScrollLayerState, ScrollLocation, WorldPoint, as_scroll_parent_rect};
pub type ScrollStates = HashMap<ScrollLayerId, ScrollingState, BuildHasherDefault<FnvHasher>>;
pub struct ClipScrollTree {
pub nodes: HashMap<ScrollLayerId, ClipScrollNode, BuildHasherDefault<FnvHasher>>,
pub pending_scroll_offsets: HashMap<(PipelineId, ServoScrollRootId), LayerPoint>,
pub pending_scroll_offsets: HashMap<ScrollLayerId, LayerPoint>,
/// The ScrollLayerId of the currently scrolling node. Used to allow the same
/// node to scroll even if a touch operation leaves the boundaries of that node.
@ -90,7 +89,7 @@ impl ClipScrollTree {
}
}
if let ScrollLayerInfo::ReferenceFrame(_) = scroll_layer_id.info {
if scroll_layer_id.is_reference_frame() {
return None;
}
@ -109,15 +108,10 @@ impl ClipScrollTree {
pub fn get_scroll_node_state(&self) -> Vec<ScrollLayerState> {
let mut result = vec![];
for (_, node) in self.nodes.iter() {
for (id, node) in self.nodes.iter() {
match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id.is_some() => {
result.push(ScrollLayerState {
pipeline_id: node.pipeline_id,
scroll_root_id: info.scroll_root_id.unwrap(),
scroll_offset: node.scrolling.offset,
})
}
NodeType::Clip(_) => result.push(
ScrollLayerState { id: *id, scroll_offset: node.scrolling.offset }),
_ => {},
}
}
@ -129,7 +123,7 @@ impl ClipScrollTree {
let mut scroll_states = HashMap::with_hasher(Default::default());
for (layer_id, old_node) in &mut self.nodes.drain() {
if !self.pipelines_to_discard.contains(&layer_id.pipeline_id) {
if !self.pipelines_to_discard.contains(&layer_id.pipeline_id()) {
scroll_states.insert(layer_id, old_node.scrolling);
}
}
@ -138,40 +132,24 @@ impl ClipScrollTree {
scroll_states
}
pub fn scroll_nodes(&mut self,
origin: LayerPoint,
pipeline_id: PipelineId,
scroll_root_id: ServoScrollRootId)
-> bool {
pub fn scroll_nodes(&mut self, origin: LayerPoint, id: ScrollLayerId) -> bool {
if id.is_reference_frame() {
warn!("Tried to scroll a reference frame.");
return false;
}
if self.nodes.is_empty() {
self.pending_scroll_offsets.insert((pipeline_id, scroll_root_id), origin);
self.pending_scroll_offsets.insert(id, origin);
return false;
}
let origin = LayerPoint::new(origin.x.max(0.0), origin.y.max(0.0));
let mut scrolled_a_node = false;
let mut found_node = false;
for (layer_id, node) in self.nodes.iter_mut() {
if layer_id.pipeline_id != pipeline_id {
continue;
}
match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id != Some(scroll_root_id) => continue,
NodeType::ReferenceFrame(..) => continue,
NodeType::Clip(_) => {},
}
found_node = true;
scrolled_a_node |= node.set_scroll_origin(&origin);
if let Some(node) = self.nodes.get_mut(&id) {
return node.set_scroll_origin(&origin);
}
if !found_node {
self.pending_scroll_offsets.insert((pipeline_id, scroll_root_id), origin);
}
scrolled_a_node
self.pending_scroll_offsets.insert(id, origin);
false
}
pub fn scroll(&mut self,
@ -244,37 +222,7 @@ impl ClipScrollTree {
scroll_layer_id
};
// TODO(mrobinson): Once we remove the concept of shared scroll root ids we can remove
// this entirely and just scroll the node based on the ScrollLayerId.
let scroll_root_id = {
let node = self.nodes.get_mut(&scroll_layer_id).unwrap();
let scroll_root_id = match node.node_type {
NodeType::Clip(ref info) => info.scroll_root_id,
NodeType::ReferenceFrame(..) => unreachable!("Tried to scroll a reference frame."),
};
if scroll_root_id.is_none() {
return node.scroll(scroll_location, phase);
}
scroll_root_id
};
let mut scrolled_a_node = false;
for (layer_id, node) in self.nodes.iter_mut() {
if layer_id.pipeline_id != scroll_layer_id.pipeline_id {
continue;
}
match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id == scroll_root_id => { }
_ => continue,
}
let scrolled_this_node = node.scroll(scroll_location, phase);
scrolled_a_node = scrolled_a_node || scrolled_this_node;
}
scrolled_a_node
self.nodes.get_mut(&scroll_layer_id).unwrap().scroll(scroll_location, phase)
}
pub fn update_all_node_transforms(&mut self, pan: LayerPoint) {
@ -351,16 +299,7 @@ impl ClipScrollTree {
node.finalize(&scrolling_state);
let scroll_root_id = match node.node_type {
NodeType::Clip(ref info) if info.scroll_root_id.is_some() =>
info.scroll_root_id.unwrap(),
_ => continue,
};
let pipeline_id = scroll_layer_id.pipeline_id;
if let Some(pending_offset) =
self.pending_scroll_offsets.remove(&(pipeline_id, scroll_root_id)) {
if let Some(pending_offset) = self.pending_scroll_offsets.remove(&scroll_layer_id) {
node.set_scroll_origin(&pending_offset);
}
}
@ -373,10 +312,9 @@ impl ClipScrollTree {
pipeline_id: PipelineId,
parent_id: Option<ScrollLayerId>)
-> ScrollLayerId {
let reference_frame_id = ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::ReferenceFrame(self.current_reference_frame_id),
};
let reference_frame_id =
ScrollLayerId::ReferenceFrame(self.current_reference_frame_id, pipeline_id);
self.current_reference_frame_id += 1;
let node = ClipScrollNode::new_reference_frame(parent_id,
@ -403,7 +341,7 @@ impl ClipScrollTree {
self.pipelines_to_discard.insert(pipeline_id);
match self.current_scroll_layer_id {
Some(id) if id.pipeline_id == pipeline_id => self.current_scroll_layer_id = None,
Some(id) if id.pipeline_id() == pipeline_id => self.current_scroll_layer_id = None,
_ => {}
}
}

View File

@ -161,7 +161,7 @@ impl DebugRenderer {
pub fn render(&mut self,
device: &mut Device,
viewport_size: &DeviceUintSize) {
let _gm = GpuMarker::new("debug");
let _gm = GpuMarker::new(device.rc_gl(), "debug");
device.disable_depth();
device.set_blend(true);
device.set_blend_mode_alpha();

File diff suppressed because it is too large Load Diff

View File

@ -20,8 +20,8 @@ use webrender_traits::{AuxiliaryLists, ClipDisplayItem, ClipRegion, ColorF, Devi
use webrender_traits::{DeviceUintSize, DisplayItem, Epoch, FilterOp, ImageDisplayItem, LayerPoint};
use webrender_traits::{LayerRect, LayerSize, LayerToScrollTransform, LayoutTransform};
use webrender_traits::{MixBlendMode, PipelineId, ScrollEventPhase, ScrollLayerId};
use webrender_traits::{ScrollLayerState, ScrollLocation, ScrollPolicy, ServoScrollRootId};
use webrender_traits::{SpecificDisplayItem, StackingContext, TileOffset, WorldPoint};
use webrender_traits::{ScrollLayerState, ScrollLocation, ScrollPolicy, SpecificDisplayItem};
use webrender_traits::{StackingContext, TileOffset, WorldPoint};
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
pub struct FrameId(pub u32);
@ -231,12 +231,8 @@ impl Frame {
}
/// Returns true if any nodes actually changed position or false otherwise.
pub fn scroll_nodes(&mut self,
origin: LayerPoint,
pipeline_id: PipelineId,
scroll_root_id: ServoScrollRootId)
-> bool {
self.clip_scroll_tree.scroll_nodes(origin, pipeline_id, scroll_root_id)
pub fn scroll_nodes(&mut self, origin: LayerPoint, id: ScrollLayerId) -> bool {
self.clip_scroll_tree.scroll_nodes(origin, id)
}
/// Returns true if any nodes actually changed position or false otherwise.
@ -349,7 +345,6 @@ impl Frame {
pipeline_id,
&clip_rect,
&item.content_size,
item.scroll_root_id,
clip,
&mut self.clip_scroll_tree);
@ -522,7 +517,6 @@ impl Frame {
pipeline_id,
&LayerRect::new(LayerPoint::zero(), iframe_rect.size),
&iframe_clip.main.size,
Some(ServoScrollRootId(0)),
iframe_clip,
&mut self.clip_scroll_tree);

View File

@ -33,8 +33,7 @@ use webrender_traits::{BoxShadowClipMode, ClipRegion, ColorF, DeviceIntPoint, De
use webrender_traits::{DeviceIntSize, DeviceUintRect, DeviceUintSize, ExtendMode, FontKey};
use webrender_traits::{FontRenderMode, GlyphOptions, ImageKey, ImageRendering, ItemRange};
use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, PipelineId};
use webrender_traits::{RepeatMode, ScrollLayerId, ServoScrollRootId, TileOffset, WebGLContextId};
use webrender_traits::YuvColorSpace;
use webrender_traits::{RepeatMode, ScrollLayerId, TileOffset, WebGLContextId, YuvColorSpace};
#[derive(Debug, Clone)]
struct ImageBorderSegment {
@ -309,7 +308,6 @@ impl FrameBuilder {
pipeline_id,
&viewport_rect,
content_size,
Some(ServoScrollRootId(0)),
&ClipRegion::simple(&viewport_rect),
clip_scroll_tree);
topmost_scroll_layer_id
@ -321,13 +319,11 @@ impl FrameBuilder {
pipeline_id: PipelineId,
local_viewport_rect: &LayerRect,
content_size: &LayerSize,
scroll_root_id: Option<ServoScrollRootId>,
clip_region: &ClipRegion,
clip_scroll_tree: &mut ClipScrollTree) {
let clip_info = ClipInfo::new(clip_region,
&mut self.prim_store.gpu_data32,
PackedLayerIndex(self.packed_layers.len()),
scroll_root_id);
PackedLayerIndex(self.packed_layers.len()));
let node = ClipScrollNode::new(pipeline_id,
parent_id,
local_viewport_rect,

View File

@ -6,6 +6,7 @@ use app_units::Au;
use device::TextureFilter;
use euclid::{TypedPoint2D, UnknownUnit};
use fnv::FnvHasher;
use gleam::gl;
use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle};
use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher};
use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
@ -74,6 +75,7 @@ impl GLContextHandleWrapper {
let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size.to_untyped(),
attributes,
ColorAttachmentType::Texture,
gl::GlType::default(),
Some(handle),
dispatcher);
ctx.map(GLContextWrapper::Native)
@ -82,6 +84,7 @@ impl GLContextHandleWrapper {
let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size.to_untyped(),
attributes,
ColorAttachmentType::Texture,
gl::GlType::default(),
Some(handle),
dispatcher);
ctx.map(GLContextWrapper::OSMesa)

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use debug_render::DebugRenderer;
use device::{GpuMarker, GpuSample, NamedTag};
use device::{Device, GpuMarker, GpuSample, NamedTag};
use euclid::{Point2D, Size2D, Rect};
use std::collections::vec_deque::VecDeque;
use std::f32;
@ -639,13 +639,14 @@ impl Profiler {
}
pub fn draw_profile(&mut self,
device: &mut Device,
frame_profile: &FrameProfileCounters,
backend_profile: &BackendProfileCounters,
renderer_profile: &RendererProfileCounters,
renderer_timers: &mut RendererProfileTimers,
debug_renderer: &mut DebugRenderer) {
let _gm = GpuMarker::new("profile");
let _gm = GpuMarker::new(device.rc_gl(), "profile");
self.x_left = 20.0;
self.y_left = 40.0;
self.x_right = 400.0;

View File

@ -260,12 +260,12 @@ impl RenderBackend {
None => self.notify_compositor_of_new_scroll_frame(false),
}
}
ApiMsg::ScrollLayersWithScrollId(origin, pipeline_id, scroll_root_id) => {
profile_scope!("ScrollLayersWithScrollId");
ApiMsg::ScrollLayerWithId(origin, id) => {
profile_scope!("ScrollLayerWithScrollId");
let frame = {
let counters = &mut profile_counters.texture_cache;
profile_counters.total_time.profile(|| {
if self.frame.scroll_nodes(origin, pipeline_id, scroll_root_id) {
if self.frame.scroll_nodes(origin, id) {
Some(self.render(counters))
} else {
None

View File

@ -16,6 +16,7 @@ use device::{GpuSample, TextureFilter, VAOId, VertexUsageHint, FileWatcherHandle
use euclid::Matrix4D;
use fnv::FnvHasher;
use frame_builder::FrameBuilderConfig;
use gleam::gl;
use gpu_store::{GpuStore, GpuStoreLayout};
use internal_types::{CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp};
use internal_types::{ExternalImageUpdateList, TextureUpdateList, PackedVertex, RenderTargetMode};
@ -35,6 +36,7 @@ use std::hash::BuildHasherDefault;
use std::marker::PhantomData;
use std::mem;
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;
@ -560,7 +562,8 @@ impl Renderer {
/// };
/// let (renderer, sender) = Renderer::new(opts);
/// ```
pub fn new(mut options: RendererOptions,
pub fn new(gl: Rc<gl::Gl>,
mut options: RendererOptions,
initial_window_size: DeviceUintSize) -> Result<(Renderer, RenderApiSender), InitError> {
let (api_tx, api_rx) = try!{ channel::msg_channel() };
let (payload_tx, payload_rx) = try!{ channel::payload_channel() };
@ -575,7 +578,8 @@ impl Renderer {
notifier: notifier.clone(),
};
let mut device = Device::new(options.resource_override_path.clone(),
let mut device = Device::new(gl,
options.resource_override_path.clone(),
Box::new(file_watch_handler));
// device-pixel ratio doesn't matter here - we are just creating resources.
device.begin_frame(1.0);
@ -858,6 +862,8 @@ impl Renderer {
backend.run(backend_profile_counters);
})};
let gpu_profile = GpuProfiler::new(device.rc_gl());
let renderer = Renderer {
result_rx: result_rx,
device: device,
@ -896,7 +902,7 @@ impl Renderer {
clear_color: options.clear_color,
last_time: 0,
render_targets: Vec::new(),
gpu_profile: GpuProfiler::new(),
gpu_profile: gpu_profile,
prim_vao_id: prim_vao_id,
blur_vao_id: blur_vao_id,
clip_vao_id: clip_vao_id,
@ -917,6 +923,10 @@ impl Renderer {
Ok((renderer, sender))
}
pub fn gl(&self) -> &gl::Gl {
self.device.gl()
}
/// Sets the new RenderNotifier.
///
/// The RenderNotifier will be called when processing e.g. of a (scrolling) frame is done,
@ -1077,7 +1087,8 @@ impl Renderer {
}
if self.enable_profiler {
self.profiler.draw_profile(&frame.profile_counters,
self.profiler.draw_profile(&mut self.device,
&frame.profile_counters,
&self.backend_profile_counters,
&self.profile_counters,
&mut profile_timers,
@ -1122,7 +1133,7 @@ impl Renderer {
*/
fn update_texture_cache(&mut self) {
let _gm = GpuMarker::new("texture cache update");
let _gm = GpuMarker::new(self.device.rc_gl(), "texture cache update");
let mut pending_texture_updates = mem::replace(&mut self.pending_texture_updates, vec![]);
for update_list in pending_texture_updates.drain(..) {
for update in update_list.updates {
@ -1513,7 +1524,7 @@ impl Renderer {
self.device.set_blend_mode_multiply();
// draw rounded cornered rectangles
if !target.clip_batcher.rectangles.is_empty() {
let _gm2 = GpuMarker::new("clip rectangles");
let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip rectangles");
let shader = self.cs_clip_rectangle.get(&mut self.device).unwrap();
self.draw_instanced_batch(&target.clip_batcher.rectangles,
vao,
@ -1523,7 +1534,7 @@ impl Renderer {
}
// draw image masks
for (mask_texture_id, items) in target.clip_batcher.images.iter() {
let _gm2 = GpuMarker::new("clip images");
let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip images");
let texture_id = self.resolve_source_texture(mask_texture_id);
self.device.bind_texture(TextureSampler::Mask, texture_id);
let shader = self.cs_clip_image.get(&mut self.device).unwrap();
@ -1556,7 +1567,7 @@ impl Renderer {
&projection);
}
let _gm2 = GpuMarker::new("alpha batches");
let _gm2 = GpuMarker::new(self.device.rc_gl(), "alpha batches");
self.device.set_blend(false);
let mut prev_blend_mode = BlendMode::None;
@ -1620,7 +1631,7 @@ impl Renderer {
.expect("Found external image, but no handler set!");
for deferred_resolve in &frame.deferred_resolves {
GpuMarker::fire("deferred resolve");
GpuMarker::fire(self.device.gl(), "deferred resolve");
let props = &deferred_resolve.image_properties;
let external_id = props.external_id
.expect("BUG: Deferred resolves must be external images!");
@ -1667,7 +1678,7 @@ impl Renderer {
fn draw_tile_frame(&mut self,
frame: &mut Frame,
framebuffer_size: &DeviceUintSize) {
let _gm = GpuMarker::new("tile frame draw");
let _gm = GpuMarker::new(self.device.rc_gl(), "tile frame draw");
self.update_deferred_resolves(frame);
// Some tests use a restricted viewport smaller than the main screen size.

View File

@ -658,13 +658,48 @@ impl ResourceCache {
// external handle doesn't need to update the texture_cache.
}
ImageData::Raw(..) | ImageData::ExternalBuffer(..) | ImageData::Blob(..) => {
let descriptor = if let Some(tile) = request.tile {
let tile_size = image_template.tiling.unwrap() as u32;
let image_descriptor = &image_template.descriptor;
let stride = image_descriptor.compute_stride();
let bpp = image_descriptor.format.bytes_per_pixel().unwrap();
// Storage for the tiles on the right and bottom edges is shrunk to
// fit the image data (See decompose_tiled_image in frame.rs).
let actual_width = if (tile.x as u32) < image_descriptor.width / tile_size {
tile_size
} else {
image_descriptor.width % tile_size
};
let actual_height = if (tile.y as u32) < image_descriptor.height / tile_size {
tile_size
} else {
image_descriptor.height % tile_size
};
let offset = image_descriptor.offset + tile.y as u32 * tile_size * stride
+ tile.x as u32 * tile_size * bpp;
ImageDescriptor {
width: actual_width,
height: actual_height,
stride: Some(stride),
offset: offset,
format: image_descriptor.format,
is_opaque: image_descriptor.is_opaque,
}
} else {
image_template.descriptor.clone()
};
match self.cached_images.entry(request.clone(), self.current_frame_id) {
Occupied(entry) => {
let image_id = entry.get().texture_cache_id;
if entry.get().epoch != image_template.epoch {
self.texture_cache.update(image_id,
image_template.descriptor,
descriptor,
image_data);
// Update the cached epoch
@ -682,50 +717,11 @@ impl ResourceCache {
ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear,
};
if let Some(tile) = request.tile {
let tile_size = image_template.tiling.unwrap() as u32;
let image_descriptor = image_template.descriptor.clone();
let stride = image_descriptor.compute_stride();
let bpp = image_descriptor.format.bytes_per_pixel().unwrap();
// Storage for the tiles on the right and bottom edges is shrunk to
// fit the image data (See decompose_tiled_image in frame.rs).
let actual_width = if (tile.x as u32) < image_descriptor.width / tile_size {
tile_size
} else {
image_descriptor.width % tile_size
};
let actual_height = if (tile.y as u32) < image_descriptor.height / tile_size {
tile_size
} else {
image_descriptor.height % tile_size
};
let offset = image_descriptor.offset + tile.y as u32 * tile_size * stride
+ tile.x as u32 * tile_size * bpp;
let tile_descriptor = ImageDescriptor {
width: actual_width,
height: actual_height,
stride: Some(stride),
offset: offset,
format: image_descriptor.format,
is_opaque: image_descriptor.is_opaque,
};
self.texture_cache.insert(image_id,
tile_descriptor,
filter,
image_data,
texture_cache_profile);
} else {
self.texture_cache.insert(image_id,
image_template.descriptor,
filter,
image_data,
texture_cache_profile);
}
self.texture_cache.insert(image_id,
descriptor,
filter,
image_data,
texture_cache_profile);
entry.insert(CachedImageInfo {
texture_cache_id: image_id,

View File

@ -5,12 +5,12 @@ authors = ["The Mozilla Project Developers"]
license = "MPL-2.0"
[dependencies]
webrender_traits = {path = "../webrender_traits", version = "0.25.0"}
webrender_traits = {path = "../webrender_traits", version = "0.26.0"}
euclid = "0.11"
app_units = "0.4"
gleam = "0.2"
gleam = "0.4"
[dependencies.webrender]
path = "../webrender"
version = "0.24.0"
version = "0.25.0"
default-features = false

View File

@ -76,6 +76,8 @@ public:
RenderTextureHost* GetRenderTexture(uint64_t aExternalImageId);
WrRenderer* GetWrRenderer() { return mWrRenderer; }
protected:
RefPtr<RenderThread> mThread;

View File

@ -228,7 +228,8 @@ WebRenderAPI::Readback(gfx::IntSize size,
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
{
aRenderThread.UpdateAndRender(aWindowId);
wr_renderer_readback(mSize.width, mSize.height, mBuffer, mBufferSize);
wr_renderer_readback(aRenderThread.GetRenderer(aWindowId)->GetWrRenderer(),
mSize.width, mSize.height, mBuffer, mBufferSize);
layers::AutoCompleteTask complete(mTask);
}

View File

@ -201,6 +201,16 @@ static inline WrSize ToWrSize(const LayerSize size)
return ls;
}
static inline WrBorderRadius ToWrUniformBorderRadius(const LayerSize& aSize)
{
WrBorderRadius br;
br.top_left = ToWrSize(aSize);
br.top_right = ToWrSize(aSize);
br.bottom_left = ToWrSize(aSize);
br.bottom_right = ToWrSize(aSize);
return br;
}
static inline WrBorderRadius ToWrBorderRadius(const LayerSize& topLeft, const LayerSize& topRight,
const LayerSize& bottomLeft, const LayerSize& bottomRight)
{
@ -287,6 +297,16 @@ static inline WrRect ToWrRect(const gfx::IntRectTyped<T>& rect)
return ToWrRect(IntRectToRect(rect));
}
template<class T>
static inline WrComplexClipRegion ToWrComplexClipRegion(const gfx::RectTyped<T>& rect,
const LayerSize& size)
{
WrComplexClipRegion complex_clip;
complex_clip.rect = wr::ToWrRect(rect);
complex_clip.radii = wr::ToWrUniformBorderRadius(size);
return complex_clip;
}
static inline WrPoint ToWrPoint(const gfx::Point& point)
{
WrPoint p;

View File

@ -4,19 +4,16 @@ use std::path::PathBuf;
use std::os::raw::{c_void, c_char};
use gleam::gl;
use webrender_traits::{BorderSide, BorderStyle, BorderRadius};
use webrender_traits::{BorderWidths, BorderDetails, NormalBorder};
use webrender_traits::{RepeatMode, ImageBorder, NinePatchDescriptor};
use webrender_traits::{PipelineId, ComplexClipRegion, ClipRegion, PropertyBinding};
use webrender_traits::{Epoch, ExtendMode, ColorF, GlyphInstance, GradientStop, ImageDescriptor};
use webrender_traits::{ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering};
use webrender_traits::{FilterOp, MixBlendMode};
use webrender_traits::{ExternalImageId, RenderApi, FontKey};
use webrender_traits::{DeviceUintSize, DeviceUintRect, DeviceUintPoint, ExternalEvent};
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform};
use webrender_traits::{BoxShadowClipMode, LayerPixel, ServoScrollRootId, IdNamespace};
use webrender_traits::{BuiltDisplayListDescriptor, AuxiliaryListsDescriptor};
use webrender_traits::{BuiltDisplayList, AuxiliaryLists, ItemRange};
use webrender_traits::{AuxiliaryLists, AuxiliaryListsDescriptor, BorderDetails, BorderRadius};
use webrender_traits::{BorderSide, BorderStyle, BorderWidths, BoxShadowClipMode, BuiltDisplayList};
use webrender_traits::{BuiltDisplayListDescriptor, ClipRegion, ColorF, ComplexClipRegion};
use webrender_traits::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, Epoch, ExtendMode};
use webrender_traits::{ExternalEvent, ExternalImageId, FilterOp, FontKey, GlyphInstance};
use webrender_traits::{GradientStop, IdNamespace, ImageBorder, ImageData, ImageDescriptor};
use webrender_traits::{ImageFormat, ImageKey, ImageMask, ImageRendering, ItemRange, LayerPixel};
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, MixBlendMode};
use webrender_traits::{NinePatchDescriptor, NormalBorder, PipelineId, PropertyBinding, RenderApi};
use webrender_traits::RepeatMode;
use webrender::renderer::{Renderer, RendererOptions};
use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource};
use webrender::{ApiRecordingReceiver, BinaryRecorder};
@ -58,6 +55,20 @@ check_ffi_type!(_mix_blend_mode_repr enum MixBlendMode as u32);
check_ffi_type!(_box_shadow_clip_mode_repr enum BoxShadowClipMode as u32);
check_ffi_type!(_namespace_id_repr struct IdNamespace as (u32));
const GL_FORMAT_BGRA_GL: gl::GLuint = gl::BGRA;
const GL_FORMAT_BGRA_GLES: gl::GLuint = gl::BGRA_EXT;
fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
match gl.get_type() {
gl::GlType::Gl => {
GL_FORMAT_BGRA_GL
}
gl::GlType::Gles => {
GL_FORMAT_BGRA_GLES
}
}
}
#[repr(C)]
pub enum WrGradientExtendMode {
Clamp,
@ -543,6 +554,7 @@ extern "C" {
fn is_in_compositor_thread() -> bool;
fn is_in_render_thread() -> bool;
fn is_in_main_thread() -> bool;
fn is_glcontext_egl(glcontext_ptr: *mut c_void) -> bool;
}
struct CppNotifier {
@ -605,22 +617,23 @@ pub extern "C" fn wr_renderer_render(renderer: &mut Renderer, width: u32, height
// Call wr_renderer_render() before calling this function.
#[no_mangle]
pub unsafe extern "C" fn wr_renderer_readback(width: u32,
pub unsafe extern "C" fn wr_renderer_readback(renderer: &mut Renderer,
width: u32,
height: u32,
dst_buffer: *mut u8,
buffer_size: usize) {
assert!(is_in_render_thread());
gl::flush();
renderer.gl().flush();
let mut slice = slice::from_raw_parts_mut(dst_buffer, buffer_size);
gl::read_pixels_into_buffer(0,
0,
width as gl::GLsizei,
height as gl::GLsizei,
gl::BGRA,
gl::UNSIGNED_BYTE,
slice);
renderer.gl().read_pixels_into_buffer(0,
0,
width as gl::GLsizei,
height as gl::GLsizei,
get_gl_format_bgra(renderer.gl()),
gl::UNSIGNED_BYTE,
slice);
}
#[no_mangle]
@ -690,10 +703,15 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
None
};
gl::load_with(|symbol| get_proc_address(gl_context, symbol));
gl::clear_color(0.3, 0.0, 0.0, 1.0);
let gl;
if unsafe { is_glcontext_egl(gl_context) } {
gl = unsafe { gl::GlesFns::load_with(|symbol| get_proc_address(gl_context, symbol)) };
} else {
gl = unsafe { gl::GlFns::load_with(|symbol| get_proc_address(gl_context, symbol)) };
}
gl.clear_color(0.3, 0.0, 0.0, 1.0);
let version = gl::get_string(gl::VERSION);
let version = gl.get_string(gl::VERSION);
println!("WebRender - OpenGL version new {}", version);
@ -706,7 +724,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
};
let window_size = DeviceUintSize::new(window_width, window_height);
let (renderer, sender) = match Renderer::new(opts, window_size) {
let (renderer, sender) = match Renderer::new(gl, opts, window_size) {
Ok((renderer, sender)) => (renderer, sender),
Err(e) => {
println!(" Failed to create a Renderer: {:?}", e);
@ -1036,9 +1054,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
None,
mix_blend_mode,
filters);
state.frame_builder.dl_builder.push_scroll_layer(clip_region,
bounds.size,
Some(ServoScrollRootId(1)));
state.frame_builder.dl_builder.push_scroll_layer(clip_region, bounds.size, None);
}
#[no_mangle]
@ -1064,9 +1080,7 @@ pub extern "C" fn wr_dp_push_scroll_layer(state: &mut WrState,
}
});
let clip_region = state.frame_builder.dl_builder.new_clip_region(&overflow, vec![], mask);
state.frame_builder.dl_builder.push_scroll_layer(clip_region,
bounds.size,
Some(ServoScrollRootId(1)));
state.frame_builder.dl_builder.push_scroll_layer(clip_region, bounds.size, None);
}
#[no_mangle]

View File

@ -69,6 +69,7 @@ WR_DECL_FFI_2(WrFontKey, uint32_t, uint32_t)
bool is_in_compositor_thread();
bool is_in_main_thread();
bool is_in_render_thread();
bool is_glcontext_egl(void* glcontext_ptr);
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname);
// -----
@ -484,7 +485,8 @@ WR_FUNC;
// It is the responsibility of the caller to manage the dst_buffer memory
// and also free it at the proper time.
WR_INLINE const uint8_t*
wr_renderer_readback(uint32_t width, uint32_t height,
wr_renderer_readback(WrRenderer* renderer,
uint32_t width, uint32_t height,
uint8_t* dst_buffer, size_t buffer_length)
WR_FUNC;

View File

@ -1,6 +1,6 @@
[package]
name = "webrender_traits"
version = "0.25.0"
version = "0.26.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
@ -13,10 +13,10 @@ ipc = ["ipc-channel"]
app_units = "0.4"
byteorder = "1.0"
euclid = "0.11"
gleam = "0.2"
gleam = "0.4"
heapsize = "0.3.6"
ipc-channel = {version = "0.7", optional = true}
offscreen_gl_context = {version = "0.6", features = ["serde"]}
offscreen_gl_context = {version = "0.8", features = ["serde"]}
serde = "0.9"
serde_derive = "0.9"

View File

@ -6,14 +6,12 @@ use byteorder::{LittleEndian, WriteBytesExt};
use channel::{self, MsgSender, PayloadHelperMethods, PayloadSender};
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use std::cell::Cell;
use {ColorF, ImageDescriptor};
use {FontKey, ImageKey, NativeFontHandle, ServoScrollRootId};
use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand};
use {DeviceIntSize, LayoutPoint, LayoutSize, WorldPoint};
use {DeviceIntPoint, DeviceUintRect, DeviceUintSize, LayoutTransform};
use {BuiltDisplayList, BuiltDisplayListDescriptor, AuxiliaryLists, AuxiliaryListsDescriptor};
use std::fmt;
use std::marker::PhantomData;
use {AuxiliaryLists, AuxiliaryListsDescriptor, BuiltDisplayList, BuiltDisplayListDescriptor};
use {ColorF, DeviceIntPoint, DeviceIntSize, DeviceUintRect, DeviceUintSize, FontKey};
use {GlyphDimensions, GlyphKey, ImageData, ImageDescriptor, ImageKey, LayoutPoint, LayoutSize};
use {LayoutTransform, NativeFontHandle, ScrollLayerId, WebGLCommand, WebGLContextId, WorldPoint};
pub type TileSize = u16;
@ -48,7 +46,7 @@ pub enum ApiMsg {
SetRootPipeline(PipelineId),
SetWindowParameters(DeviceUintSize, DeviceUintRect),
Scroll(ScrollLocation, WorldPoint, ScrollEventPhase),
ScrollLayersWithScrollId(LayoutPoint, PipelineId, ServoScrollRootId),
ScrollLayerWithId(LayoutPoint, ScrollLayerId),
TickScrollingBounce,
TranslatePointToLayerSpace(WorldPoint, MsgSender<(LayoutPoint, PipelineId)>),
GetScrollLayerState(MsgSender<Vec<ScrollLayerState>>),
@ -79,7 +77,7 @@ impl fmt::Debug for ApiMsg {
&ApiMsg::SetRootDisplayList(..) => { write!(f, "ApiMsg::SetRootDisplayList") }
&ApiMsg::SetRootPipeline(..) => { write!(f, "ApiMsg::SetRootPipeline") }
&ApiMsg::Scroll(..) => { write!(f, "ApiMsg::Scroll") }
&ApiMsg::ScrollLayersWithScrollId(..) => { write!(f, "ApiMsg::ScrollLayersWithScrollId") }
&ApiMsg::ScrollLayerWithId(..) => { write!(f, "ApiMsg::ScrollLayerWithId") }
&ApiMsg::TickScrollingBounce => { write!(f, "ApiMsg::TickScrollingBounce") }
&ApiMsg::TranslatePointToLayerSpace(..) => { write!(f, "ApiMsg::TranslatePointToLayerSpace") }
&ApiMsg::GetScrollLayerState(..) => { write!(f, "ApiMsg::GetScrollLayerState") }
@ -310,11 +308,8 @@ impl RenderApi {
self.api_sender.send(msg).unwrap();
}
pub fn scroll_layers_with_scroll_root_id(&self,
new_scroll_origin: LayoutPoint,
pipeline_id: PipelineId,
scroll_root_id: ServoScrollRootId) {
let msg = ApiMsg::ScrollLayersWithScrollId(new_scroll_origin, pipeline_id, scroll_root_id);
pub fn scroll_layer_with_id(&self, new_scroll_origin: LayoutPoint, id: ScrollLayerId) {
let msg = ApiMsg::ScrollLayerWithId(new_scroll_origin, id);
self.api_sender.send(msg).unwrap();
}
@ -436,8 +431,7 @@ pub enum ScrollEventPhase {
#[derive(Clone, Deserialize, Serialize)]
pub struct ScrollLayerState {
pub pipeline_id: PipelineId,
pub scroll_root_id: ServoScrollRootId,
pub id: ScrollLayerId,
pub scroll_offset: LayoutPoint,
}

View File

@ -46,7 +46,6 @@ pub struct ClipDisplayItem {
pub content_size: LayoutSize,
pub id: ScrollLayerId,
pub parent_id: ScrollLayerId,
pub scroll_root_id: Option<ServoScrollRootId>,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
@ -86,6 +85,7 @@ pub struct NormalBorder {
pub radius: BorderRadius,
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum RepeatMode {
Stretch,
@ -193,6 +193,7 @@ pub struct BoxShadowDisplayItem {
pub clip_mode: BoxShadowClipMode,
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum ExtendMode {
Clamp,
@ -251,7 +252,6 @@ pub struct StackingContext {
pub filters: ItemRange,
}
#[repr(C)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum ScrollPolicy {
@ -509,48 +509,45 @@ impl ComplexClipRegion {
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ServoScrollRootId(pub usize);
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ScrollLayerId {
pub pipeline_id: PipelineId,
pub info: ScrollLayerInfo,
pub enum ScrollLayerId {
Clip(usize, PipelineId),
ClipExternalId(usize, PipelineId),
ReferenceFrame(usize, PipelineId),
}
impl ScrollLayerId {
pub fn root_scroll_layer(pipeline_id: PipelineId) -> ScrollLayerId {
ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::Scrollable(0),
}
ScrollLayerId::Clip(0, pipeline_id)
}
pub fn root_reference_frame(pipeline_id: PipelineId) -> ScrollLayerId {
ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::ReferenceFrame(0),
ScrollLayerId::ReferenceFrame(0, pipeline_id)
}
pub fn new(id: usize, pipeline_id: PipelineId) -> ScrollLayerId {
ScrollLayerId::ClipExternalId(id, pipeline_id)
}
pub fn pipeline_id(&self) -> PipelineId {
match *self {
ScrollLayerId::Clip(_, pipeline_id) => pipeline_id,
ScrollLayerId::ClipExternalId(_, pipeline_id) => pipeline_id,
ScrollLayerId::ReferenceFrame(_, pipeline_id) => pipeline_id,
}
}
pub fn is_reference_frame(&self) -> bool {
match self.info {
ScrollLayerInfo::Scrollable(..) => false,
ScrollLayerInfo::ReferenceFrame(..) => true,
match *self {
ScrollLayerId::ReferenceFrame(..) => true,
_ => false,
}
}
pub fn new(pipeline_id: PipelineId, index: usize) -> ScrollLayerId {
ScrollLayerId {
pipeline_id: pipeline_id,
info: ScrollLayerInfo::Scrollable(index),
pub fn external_id(&self) -> Option<usize> {
match *self {
ScrollLayerId::ClipExternalId(id, _) => Some(id),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum ScrollLayerInfo {
Scrollable(usize),
ReferenceFrame(usize),
}

View File

@ -11,8 +11,8 @@ use {FontKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem, Gradie
use {IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering, ItemRange};
use {LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, MixBlendMode, PipelineId};
use {PropertyBinding, PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem};
use {RectangleDisplayItem, ScrollLayerId, ScrollPolicy, ServoScrollRootId, SpecificDisplayItem};
use {StackingContext, TextDisplayItem, WebGLContextId, WebGLDisplayItem, YuvColorSpace};
use {RectangleDisplayItem, ScrollLayerId, ScrollPolicy, SpecificDisplayItem, StackingContext};
use {TextDisplayItem, WebGLContextId, WebGLDisplayItem, YuvColorSpace};
use YuvImageDisplayItem;
#[derive(Clone, Deserialize, Serialize)]
@ -341,17 +341,20 @@ impl DisplayListBuilder {
pub fn define_clip(&mut self,
clip: ClipRegion,
content_size: LayoutSize,
scroll_root_id: Option<ServoScrollRootId>)
id: Option<ScrollLayerId>)
-> ScrollLayerId {
let scroll_layer_id = self.next_scroll_layer_id;
self.next_scroll_layer_id += 1;
let id = match id {
Some(id) => id,
None => {
self.next_scroll_layer_id += 1;
ScrollLayerId::Clip(self.next_scroll_layer_id - 1, self.pipeline_id)
}
};
let id = ScrollLayerId::new(self.pipeline_id, scroll_layer_id);
let item = SpecificDisplayItem::Clip(ClipDisplayItem {
content_size: content_size,
id: id,
parent_id: *self.clip_stack.last().unwrap(),
scroll_root_id: scroll_root_id,
});
self.push_item(item, clip.main, clip);
@ -361,8 +364,8 @@ impl DisplayListBuilder {
pub fn push_scroll_layer(&mut self,
clip: ClipRegion,
content_size: LayoutSize,
scroll_root_id: Option<ServoScrollRootId>) {
let id = self.define_clip(clip, content_size, scroll_root_id);
id: Option<ScrollLayerId>) {
let id = self.define_clip(clip, content_size, id);
self.clip_stack.push(id);
}
@ -414,6 +417,7 @@ impl DisplayListBuilder {
_ => {}
}
i.clip.complex = self.auxiliary_lists_builder.add_complex_clip_regions(aux.complex_clip_regions(&i.clip.complex));
i.scroll_layer_id = *self.clip_stack.last().unwrap();
self.list.push(i);
}
}

View File

@ -20,7 +20,6 @@ impl ImageKey {
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ExternalImageId(pub u64);
#[repr(C)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum ImageFormat {
@ -108,6 +107,7 @@ pub type BlobImageData = Vec<u8>;
pub type BlobImageResult = Result<RasterizedBlobImage, BlobImageError>;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct BlobImageDescriptor {
pub width: u32,

View File

@ -385,262 +385,265 @@ impl WebGLCommand {
WebGLCommand::GetContextAttributes(sender) =>
sender.send(*ctx.borrow_attributes()).unwrap(),
WebGLCommand::ActiveTexture(target) =>
gl::active_texture(target),
ctx.gl().active_texture(target),
WebGLCommand::AttachShader(program_id, shader_id) =>
gl::attach_shader(program_id.get(), shader_id.get()),
ctx.gl().attach_shader(program_id.get(), shader_id.get()),
WebGLCommand::DetachShader(program_id, shader_id) =>
gl::detach_shader(program_id.get(), shader_id.get()),
ctx.gl().detach_shader(program_id.get(), shader_id.get()),
WebGLCommand::BindAttribLocation(program_id, index, name) =>
gl::bind_attrib_location(program_id.get(), index, &name),
ctx.gl().bind_attrib_location(program_id.get(), index, &name),
WebGLCommand::BlendColor(r, g, b, a) =>
gl::blend_color(r, g, b, a),
ctx.gl().blend_color(r, g, b, a),
WebGLCommand::BlendEquation(mode) =>
gl::blend_equation(mode),
ctx.gl().blend_equation(mode),
WebGLCommand::BlendEquationSeparate(mode_rgb, mode_alpha) =>
gl::blend_equation_separate(mode_rgb, mode_alpha),
ctx.gl().blend_equation_separate(mode_rgb, mode_alpha),
WebGLCommand::BlendFunc(src, dest) =>
gl::blend_func(src, dest),
ctx.gl().blend_func(src, dest),
WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha) =>
gl::blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha),
ctx.gl().blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha),
WebGLCommand::BufferData(buffer_type, data, usage) =>
gl::buffer_data(buffer_type, &data, usage),
gl::buffer_data(ctx.gl(), buffer_type, &data, usage),
WebGLCommand::BufferSubData(buffer_type, offset, data) =>
gl::buffer_sub_data(buffer_type, offset, &data),
gl::buffer_sub_data(ctx.gl(), buffer_type, offset, &data),
WebGLCommand::Clear(mask) =>
gl::clear(mask),
ctx.gl().clear(mask),
WebGLCommand::ClearColor(r, g, b, a) =>
gl::clear_color(r, g, b, a),
ctx.gl().clear_color(r, g, b, a),
WebGLCommand::ClearDepth(depth) =>
gl::clear_depth(depth),
ctx.gl().clear_depth(depth),
WebGLCommand::ClearStencil(stencil) =>
gl::clear_stencil(stencil),
ctx.gl().clear_stencil(stencil),
WebGLCommand::ColorMask(r, g, b, a) =>
gl::color_mask(r, g, b, a),
ctx.gl().color_mask(r, g, b, a),
WebGLCommand::CopyTexImage2D(target, level, internal_format, x, y, width, height, border) =>
gl::copy_tex_image_2d(target, level, internal_format, x, y, width, height, border),
ctx.gl().copy_tex_image_2d(target, level, internal_format, x, y, width, height, border),
WebGLCommand::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) =>
gl::copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height),
ctx.gl().copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height),
WebGLCommand::CullFace(mode) =>
gl::cull_face(mode),
ctx.gl().cull_face(mode),
WebGLCommand::DepthFunc(func) =>
gl::depth_func(func),
ctx.gl().depth_func(func),
WebGLCommand::DepthMask(flag) =>
gl::depth_mask(flag),
ctx.gl().depth_mask(flag),
WebGLCommand::DepthRange(near, far) =>
gl::depth_range(near, far),
ctx.gl().depth_range(near, far),
WebGLCommand::Disable(cap) =>
gl::disable(cap),
ctx.gl().disable(cap),
WebGLCommand::Enable(cap) =>
gl::enable(cap),
ctx.gl().enable(cap),
WebGLCommand::FramebufferRenderbuffer(target, attachment, renderbuffertarget, rb) =>
gl::framebuffer_renderbuffer(target, attachment, renderbuffertarget, rb.map_or(0, WebGLRenderbufferId::get)),
ctx.gl().framebuffer_renderbuffer(target, attachment, renderbuffertarget, rb.map_or(0, WebGLRenderbufferId::get)),
WebGLCommand::FramebufferTexture2D(target, attachment, textarget, texture, level) =>
gl::framebuffer_texture_2d(target, attachment, textarget, texture.map_or(0, WebGLTextureId::get), level),
ctx.gl().framebuffer_texture_2d(target, attachment, textarget, texture.map_or(0, WebGLTextureId::get), level),
WebGLCommand::FrontFace(mode) =>
gl::front_face(mode),
ctx.gl().front_face(mode),
WebGLCommand::DisableVertexAttribArray(attrib_id) =>
gl::disable_vertex_attrib_array(attrib_id),
ctx.gl().disable_vertex_attrib_array(attrib_id),
WebGLCommand::DrawArrays(mode, first, count) =>
gl::draw_arrays(mode, first, count),
ctx.gl().draw_arrays(mode, first, count),
WebGLCommand::DrawElements(mode, count, type_, offset) =>
gl::draw_elements(mode, count, type_, offset as u32),
ctx.gl().draw_elements(mode, count, type_, offset as u32),
WebGLCommand::EnableVertexAttribArray(attrib_id) =>
gl::enable_vertex_attrib_array(attrib_id),
ctx.gl().enable_vertex_attrib_array(attrib_id),
WebGLCommand::Hint(name, val) =>
gl::hint(name, val),
ctx.gl().hint(name, val),
WebGLCommand::IsEnabled(cap, chan) =>
chan.send(gl::is_enabled(cap) != 0).unwrap(),
chan.send(ctx.gl().is_enabled(cap) != 0).unwrap(),
WebGLCommand::LineWidth(width) =>
gl::line_width(width),
ctx.gl().line_width(width),
WebGLCommand::PixelStorei(name, val) =>
gl::pixel_store_i(name, val),
ctx.gl().pixel_store_i(name, val),
WebGLCommand::PolygonOffset(factor, units) =>
gl::polygon_offset(factor, units),
ctx.gl().polygon_offset(factor, units),
WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, chan) =>
Self::read_pixels(x, y, width, height, format, pixel_type, chan),
Self::read_pixels(ctx.gl(), x, y, width, height, format, pixel_type, chan),
WebGLCommand::RenderbufferStorage(target, format, width, height) =>
gl::renderbuffer_storage(target, format, width, height),
ctx.gl().renderbuffer_storage(target, format, width, height),
WebGLCommand::SampleCoverage(value, invert) =>
gl::sample_coverage(value, invert),
ctx.gl().sample_coverage(value, invert),
WebGLCommand::Scissor(x, y, width, height) =>
gl::scissor(x, y, width, height),
ctx.gl().scissor(x, y, width, height),
WebGLCommand::StencilFunc(func, ref_, mask) =>
gl::stencil_func(func, ref_, mask),
ctx.gl().stencil_func(func, ref_, mask),
WebGLCommand::StencilFuncSeparate(face, func, ref_, mask) =>
gl::stencil_func_separate(face, func, ref_, mask),
ctx.gl().stencil_func_separate(face, func, ref_, mask),
WebGLCommand::StencilMask(mask) =>
gl::stencil_mask(mask),
ctx.gl().stencil_mask(mask),
WebGLCommand::StencilMaskSeparate(face, mask) =>
gl::stencil_mask_separate(face, mask),
ctx.gl().stencil_mask_separate(face, mask),
WebGLCommand::StencilOp(fail, zfail, zpass) =>
gl::stencil_op(fail, zfail, zpass),
ctx.gl().stencil_op(fail, zfail, zpass),
WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass) =>
gl::stencil_op_separate(face, fail, zfail, zpass),
ctx.gl().stencil_op_separate(face, fail, zfail, zpass),
WebGLCommand::GetActiveAttrib(program_id, index, chan) =>
Self::active_attrib(program_id, index, chan),
Self::active_attrib(ctx.gl(), program_id, index, chan),
WebGLCommand::GetActiveUniform(program_id, index, chan) =>
Self::active_uniform(program_id, index, chan),
Self::active_uniform(ctx.gl(), program_id, index, chan),
WebGLCommand::GetAttribLocation(program_id, name, chan) =>
Self::attrib_location(program_id, name, chan),
Self::attrib_location(ctx.gl(), program_id, name, chan),
WebGLCommand::GetVertexAttrib(index, pname, chan) =>
Self::vertex_attrib(index, pname, chan),
Self::vertex_attrib(ctx.gl(), index, pname, chan),
WebGLCommand::GetBufferParameter(target, param_id, chan) =>
Self::buffer_parameter(target, param_id, chan),
Self::buffer_parameter(ctx.gl(), target, param_id, chan),
WebGLCommand::GetParameter(param_id, chan) =>
Self::parameter(param_id, chan),
Self::parameter(ctx.gl(), param_id, chan),
WebGLCommand::GetProgramParameter(program_id, param_id, chan) =>
Self::program_parameter(program_id, param_id, chan),
Self::program_parameter(ctx.gl(), program_id, param_id, chan),
WebGLCommand::GetShaderParameter(shader_id, param_id, chan) =>
Self::shader_parameter(shader_id, param_id, chan),
Self::shader_parameter(ctx.gl(), shader_id, param_id, chan),
WebGLCommand::GetUniformLocation(program_id, name, chan) =>
Self::uniform_location(program_id, name, chan),
Self::uniform_location(ctx.gl(), program_id, name, chan),
WebGLCommand::GetShaderInfoLog(shader_id, chan) =>
Self::shader_info_log(shader_id, chan),
Self::shader_info_log(ctx.gl(), shader_id, chan),
WebGLCommand::GetProgramInfoLog(program_id, chan) =>
Self::program_info_log(program_id, chan),
Self::program_info_log(ctx.gl(), program_id, chan),
WebGLCommand::CompileShader(shader_id, source) =>
Self::compile_shader(shader_id, source),
Self::compile_shader(ctx.gl(), shader_id, source),
WebGLCommand::CreateBuffer(chan) =>
Self::create_buffer(chan),
Self::create_buffer(ctx.gl(), chan),
WebGLCommand::CreateFramebuffer(chan) =>
Self::create_framebuffer(chan),
Self::create_framebuffer(ctx.gl(), chan),
WebGLCommand::CreateRenderbuffer(chan) =>
Self::create_renderbuffer(chan),
Self::create_renderbuffer(ctx.gl(), chan),
WebGLCommand::CreateTexture(chan) =>
Self::create_texture(chan),
Self::create_texture(ctx.gl(), chan),
WebGLCommand::CreateProgram(chan) =>
Self::create_program(chan),
Self::create_program(ctx.gl(), chan),
WebGLCommand::CreateShader(shader_type, chan) =>
Self::create_shader(shader_type, chan),
Self::create_shader(ctx.gl(), shader_type, chan),
WebGLCommand::DeleteBuffer(id) =>
gl::delete_buffers(&[id.get()]),
ctx.gl().delete_buffers(&[id.get()]),
WebGLCommand::DeleteFramebuffer(id) =>
gl::delete_framebuffers(&[id.get()]),
ctx.gl().delete_framebuffers(&[id.get()]),
WebGLCommand::DeleteRenderbuffer(id) =>
gl::delete_renderbuffers(&[id.get()]),
ctx.gl().delete_renderbuffers(&[id.get()]),
WebGLCommand::DeleteTexture(id) =>
gl::delete_textures(&[id.get()]),
ctx.gl().delete_textures(&[id.get()]),
WebGLCommand::DeleteProgram(id) =>
gl::delete_program(id.get()),
ctx.gl().delete_program(id.get()),
WebGLCommand::DeleteShader(id) =>
gl::delete_shader(id.get()),
ctx.gl().delete_shader(id.get()),
WebGLCommand::BindBuffer(target, id) =>
gl::bind_buffer(target, id.map_or(0, WebGLBufferId::get)),
ctx.gl().bind_buffer(target, id.map_or(0, WebGLBufferId::get)),
WebGLCommand::BindFramebuffer(target, request) =>
Self::bind_framebuffer(target, request, ctx),
Self::bind_framebuffer(ctx.gl(), target, request, ctx),
WebGLCommand::BindRenderbuffer(target, id) =>
gl::bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
ctx.gl().bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
WebGLCommand::BindTexture(target, id) =>
gl::bind_texture(target, id.map_or(0, WebGLTextureId::get)),
ctx.gl().bind_texture(target, id.map_or(0, WebGLTextureId::get)),
WebGLCommand::LinkProgram(program_id) =>
gl::link_program(program_id.get()),
ctx.gl().link_program(program_id.get()),
WebGLCommand::Uniform1f(uniform_id, v) =>
gl::uniform_1f(uniform_id, v),
ctx.gl().uniform_1f(uniform_id, v),
WebGLCommand::Uniform1fv(uniform_id, v) =>
gl::uniform_1fv(uniform_id, &v),
ctx.gl().uniform_1fv(uniform_id, &v),
WebGLCommand::Uniform1i(uniform_id, v) =>
gl::uniform_1i(uniform_id, v),
ctx.gl().uniform_1i(uniform_id, v),
WebGLCommand::Uniform1iv(uniform_id, v) =>
gl::uniform_1iv(uniform_id, &v),
ctx.gl().uniform_1iv(uniform_id, &v),
WebGLCommand::Uniform2f(uniform_id, x, y) =>
gl::uniform_2f(uniform_id, x, y),
ctx.gl().uniform_2f(uniform_id, x, y),
WebGLCommand::Uniform2fv(uniform_id, v) =>
gl::uniform_2fv(uniform_id, &v),
ctx.gl().uniform_2fv(uniform_id, &v),
WebGLCommand::Uniform2i(uniform_id, x, y) =>
gl::uniform_2i(uniform_id, x, y),
ctx.gl().uniform_2i(uniform_id, x, y),
WebGLCommand::Uniform2iv(uniform_id, v) =>
gl::uniform_2iv(uniform_id, &v),
ctx.gl().uniform_2iv(uniform_id, &v),
WebGLCommand::Uniform3f(uniform_id, x, y, z) =>
gl::uniform_3f(uniform_id, x, y, z),
ctx.gl().uniform_3f(uniform_id, x, y, z),
WebGLCommand::Uniform3fv(uniform_id, v) =>
gl::uniform_3fv(uniform_id, &v),
ctx.gl().uniform_3fv(uniform_id, &v),
WebGLCommand::Uniform3i(uniform_id, x, y, z) =>
gl::uniform_3i(uniform_id, x, y, z),
ctx.gl().uniform_3i(uniform_id, x, y, z),
WebGLCommand::Uniform3iv(uniform_id, v) =>
gl::uniform_3iv(uniform_id, &v),
ctx.gl().uniform_3iv(uniform_id, &v),
WebGLCommand::Uniform4f(uniform_id, x, y, z, w) =>
gl::uniform_4f(uniform_id, x, y, z, w),
ctx.gl().uniform_4f(uniform_id, x, y, z, w),
WebGLCommand::Uniform4fv(uniform_id, v) =>
gl::uniform_4fv(uniform_id, &v),
ctx.gl().uniform_4fv(uniform_id, &v),
WebGLCommand::Uniform4i(uniform_id, x, y, z, w) =>
gl::uniform_4i(uniform_id, x, y, z, w),
ctx.gl().uniform_4i(uniform_id, x, y, z, w),
WebGLCommand::Uniform4iv(uniform_id, v) =>
gl::uniform_4iv(uniform_id, &v),
ctx.gl().uniform_4iv(uniform_id, &v),
WebGLCommand::UniformMatrix2fv(uniform_id, transpose, v) =>
gl::uniform_matrix_2fv(uniform_id, transpose, &v),
ctx.gl().uniform_matrix_2fv(uniform_id, transpose, &v),
WebGLCommand::UniformMatrix3fv(uniform_id, transpose, v) =>
gl::uniform_matrix_3fv(uniform_id, transpose, &v),
ctx.gl().uniform_matrix_3fv(uniform_id, transpose, &v),
WebGLCommand::UniformMatrix4fv(uniform_id, transpose, v) =>
gl::uniform_matrix_4fv(uniform_id, transpose, &v),
ctx.gl().uniform_matrix_4fv(uniform_id, transpose, &v),
WebGLCommand::UseProgram(program_id) =>
gl::use_program(program_id.get()),
ctx.gl().use_program(program_id.get()),
WebGLCommand::ValidateProgram(program_id) =>
gl::validate_program(program_id.get()),
ctx.gl().validate_program(program_id.get()),
WebGLCommand::VertexAttrib(attrib_id, x, y, z, w) =>
gl::vertex_attrib_4f(attrib_id, x, y, z, w),
ctx.gl().vertex_attrib_4f(attrib_id, x, y, z, w),
WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset) =>
gl::vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset),
ctx.gl().vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset),
WebGLCommand::VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset) =>
gl::vertex_attrib_pointer(attrib_id, size, data_type, normalized, stride, offset),
ctx.gl().vertex_attrib_pointer(attrib_id, size, data_type, normalized, stride, offset),
WebGLCommand::Viewport(x, y, width, height) =>
gl::viewport(x, y, width, height),
ctx.gl().viewport(x, y, width, height),
WebGLCommand::TexImage2D(target, level, internal, width, height, format, data_type, data) =>
gl::tex_image_2d(target, level, internal, width, height, /*border*/0, format, data_type, Some(&data)),
ctx.gl().tex_image_2d(target, level, internal, width, height, /*border*/0, format, data_type, Some(&data)),
WebGLCommand::TexParameteri(target, name, value) =>
gl::tex_parameter_i(target, name, value),
ctx.gl().tex_parameter_i(target, name, value),
WebGLCommand::TexParameterf(target, name, value) =>
gl::tex_parameter_f(target, name, value),
ctx.gl().tex_parameter_f(target, name, value),
WebGLCommand::TexSubImage2D(target, level, xoffset, yoffset, x, y, width, height, data) =>
gl::tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, &data),
ctx.gl().tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, &data),
WebGLCommand::DrawingBufferWidth(sender) =>
sender.send(ctx.borrow_draw_buffer().unwrap().size().width).unwrap(),
WebGLCommand::DrawingBufferHeight(sender) =>
sender.send(ctx.borrow_draw_buffer().unwrap().size().height).unwrap(),
WebGLCommand::Finish(sender) =>
Self::finish(sender),
Self::finish(ctx.gl(), sender),
WebGLCommand::Flush =>
gl::flush(),
ctx.gl().flush(),
WebGLCommand::GenerateMipmap(target) =>
gl::generate_mipmap(target),
ctx.gl().generate_mipmap(target),
}
// FIXME: Use debug_assertions once tests are run with them
let error = gl::get_error();
let error = ctx.gl().get_error();
assert!(error == gl::NO_ERROR, "Unexpected WebGL error: 0x{:x} ({})", error, error);
}
fn read_pixels(x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
fn read_pixels(gl: &gl::Gl, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
chan: MsgSender<Vec<u8>>) {
let result = gl::read_pixels(x, y, width, height, format, pixel_type);
let result = gl.read_pixels(x, y, width, height, format, pixel_type);
chan.send(result).unwrap()
}
fn active_attrib(program_id: WebGLProgramId,
fn active_attrib(gl: &gl::Gl,
program_id: WebGLProgramId,
index: u32,
chan: MsgSender<WebGLResult<(i32, u32, String)>>) {
let result = if index >= gl::get_program_iv(program_id.get(), gl::ACTIVE_ATTRIBUTES) as u32 {
let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_ATTRIBUTES) as u32 {
Err(WebGLError::InvalidValue)
} else {
Ok(gl::get_active_attrib(program_id.get(), index))
Ok(gl.get_active_attrib(program_id.get(), index))
};
chan.send(result).unwrap();
}
fn active_uniform(program_id: WebGLProgramId,
fn active_uniform(gl: &gl::Gl,
program_id: WebGLProgramId,
index: u32,
chan: MsgSender<WebGLResult<(i32, u32, String)>>) {
let result = if index >= gl::get_program_iv(program_id.get(), gl::ACTIVE_UNIFORMS) as u32 {
let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_UNIFORMS) as u32 {
Err(WebGLError::InvalidValue)
} else {
Ok(gl::get_active_uniform(program_id.get(), index))
Ok(gl.get_active_uniform(program_id.get(), index))
};
chan.send(result).unwrap();
}
fn attrib_location(program_id: WebGLProgramId,
fn attrib_location(gl: &gl::Gl,
program_id: WebGLProgramId,
name: String,
chan: MsgSender<Option<i32>> ) {
let attrib_location = gl::get_attrib_location(program_id.get(), &name);
let attrib_location = gl.get_attrib_location(program_id.get(), &name);
let attrib_location = if attrib_location == -1 {
None
@ -651,7 +654,8 @@ impl WebGLCommand {
chan.send(attrib_location).unwrap();
}
fn parameter(param_id: u32,
fn parameter(gl: &gl::Gl,
param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::ACTIVE_TEXTURE |
@ -704,7 +708,7 @@ impl WebGLCommand {
gl::SUBPIXEL_BITS |
gl::UNPACK_ALIGNMENT =>
//gl::UNPACK_COLORSPACE_CONVERSION_WEBGL =>
Ok(WebGLParameter::Int(gl::get_integer_v(param_id))),
Ok(WebGLParameter::Int(gl.get_integer_v(param_id))),
gl::BLEND |
gl::CULL_FACE |
@ -716,14 +720,14 @@ impl WebGLCommand {
gl::STENCIL_TEST =>
//gl::UNPACK_FLIP_Y_WEBGL |
//gl::UNPACK_PREMULTIPLY_ALPHA_WEBGL =>
Ok(WebGLParameter::Bool(gl::get_boolean_v(param_id) != 0)),
Ok(WebGLParameter::Bool(gl.get_boolean_v(param_id) != 0)),
gl::DEPTH_CLEAR_VALUE |
gl::LINE_WIDTH |
gl::POLYGON_OFFSET_FACTOR |
gl::POLYGON_OFFSET_UNITS |
gl::SAMPLE_COVERAGE_VALUE =>
Ok(WebGLParameter::Float(gl::get_float_v(param_id))),
Ok(WebGLParameter::Float(gl.get_float_v(param_id))),
gl::VERSION => Ok(WebGLParameter::String("WebGL 1.0".to_owned())),
gl::RENDERER |
@ -773,27 +777,28 @@ impl WebGLCommand {
chan.send(result).unwrap();
}
fn finish(chan: MsgSender<()>) {
gl::finish();
fn finish(gl: &gl::Gl, chan: MsgSender<()>) {
gl.finish();
chan.send(()).unwrap();
}
fn vertex_attrib(index: u32,
fn vertex_attrib(gl: &gl::Gl,
index: u32,
pname: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = if index >= gl::get_integer_v(gl::MAX_VERTEX_ATTRIBS) as u32 {
let result = if index >= gl.get_integer_v(gl::MAX_VERTEX_ATTRIBS) as u32 {
Err(WebGLError::InvalidValue)
} else {
match pname {
gl::VERTEX_ATTRIB_ARRAY_ENABLED |
gl::VERTEX_ATTRIB_ARRAY_NORMALIZED =>
Ok(WebGLParameter::Bool(gl::get_vertex_attrib_iv(index, pname) != 0)),
Ok(WebGLParameter::Bool(gl.get_vertex_attrib_iv(index, pname) != 0)),
gl::VERTEX_ATTRIB_ARRAY_SIZE |
gl::VERTEX_ATTRIB_ARRAY_STRIDE |
gl::VERTEX_ATTRIB_ARRAY_TYPE =>
Ok(WebGLParameter::Int(gl::get_vertex_attrib_iv(index, pname))),
Ok(WebGLParameter::Int(gl.get_vertex_attrib_iv(index, pname))),
gl::CURRENT_VERTEX_ATTRIB =>
Ok(WebGLParameter::FloatArray(gl::get_vertex_attrib_fv(index, pname))),
Ok(WebGLParameter::FloatArray(gl.get_vertex_attrib_fv(index, pname))),
// gl::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING should return WebGLBuffer
_ => Err(WebGLError::InvalidEnum),
}
@ -802,56 +807,60 @@ impl WebGLCommand {
chan.send(result).unwrap();
}
fn buffer_parameter(target: u32,
fn buffer_parameter(gl: &gl::Gl,
target: u32,
param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::BUFFER_SIZE |
gl::BUFFER_USAGE =>
Ok(WebGLParameter::Int(gl::get_buffer_parameter_iv(target, param_id))),
Ok(WebGLParameter::Int(gl.get_buffer_parameter_iv(target, param_id))),
_ => Err(WebGLError::InvalidEnum),
};
chan.send(result).unwrap();
}
fn program_parameter(program_id: WebGLProgramId,
fn program_parameter(gl: &gl::Gl,
program_id: WebGLProgramId,
param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::DELETE_STATUS |
gl::LINK_STATUS |
gl::VALIDATE_STATUS =>
Ok(WebGLParameter::Bool(gl::get_program_iv(program_id.get(), param_id) != 0)),
Ok(WebGLParameter::Bool(gl.get_program_iv(program_id.get(), param_id) != 0)),
gl::ATTACHED_SHADERS |
gl::ACTIVE_ATTRIBUTES |
gl::ACTIVE_UNIFORMS =>
Ok(WebGLParameter::Int(gl::get_program_iv(program_id.get(), param_id))),
Ok(WebGLParameter::Int(gl.get_program_iv(program_id.get(), param_id))),
_ => Err(WebGLError::InvalidEnum),
};
chan.send(result).unwrap();
}
fn shader_parameter(shader_id: WebGLShaderId,
fn shader_parameter(gl: &gl::Gl,
shader_id: WebGLShaderId,
param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::SHADER_TYPE =>
Ok(WebGLParameter::Int(gl::get_shader_iv(shader_id.get(), param_id))),
Ok(WebGLParameter::Int(gl.get_shader_iv(shader_id.get(), param_id))),
gl::DELETE_STATUS |
gl::COMPILE_STATUS =>
Ok(WebGLParameter::Bool(gl::get_shader_iv(shader_id.get(), param_id) != 0)),
Ok(WebGLParameter::Bool(gl.get_shader_iv(shader_id.get(), param_id) != 0)),
_ => Err(WebGLError::InvalidEnum),
};
chan.send(result).unwrap();
}
fn uniform_location(program_id: WebGLProgramId,
fn uniform_location(gl: &gl::Gl,
program_id: WebGLProgramId,
name: String,
chan: MsgSender<Option<i32>>) {
let location = gl::get_uniform_location(program_id.get(), &name);
let location = gl.get_uniform_location(program_id.get(), &name);
let location = if location == -1 {
None
} else {
@ -862,18 +871,18 @@ impl WebGLCommand {
}
fn shader_info_log(shader_id: WebGLShaderId, chan: MsgSender<String>) {
let log = gl::get_shader_info_log(shader_id.get());
fn shader_info_log(gl: &gl::Gl, shader_id: WebGLShaderId, chan: MsgSender<String>) {
let log = gl.get_shader_info_log(shader_id.get());
chan.send(log).unwrap();
}
fn program_info_log(program_id: WebGLProgramId, chan: MsgSender<String>) {
let log = gl::get_program_info_log(program_id.get());
fn program_info_log(gl: &gl::Gl, program_id: WebGLProgramId, chan: MsgSender<String>) {
let log = gl.get_program_info_log(program_id.get());
chan.send(log).unwrap();
}
fn create_buffer(chan: MsgSender<Option<WebGLBufferId>>) {
let buffer = gl::gen_buffers(1)[0];
fn create_buffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLBufferId>>) {
let buffer = gl.gen_buffers(1)[0];
let buffer = if buffer == 0 {
None
} else {
@ -882,8 +891,8 @@ impl WebGLCommand {
chan.send(buffer).unwrap();
}
fn create_framebuffer(chan: MsgSender<Option<WebGLFramebufferId>>) {
let framebuffer = gl::gen_framebuffers(1)[0];
fn create_framebuffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLFramebufferId>>) {
let framebuffer = gl.gen_framebuffers(1)[0];
let framebuffer = if framebuffer == 0 {
None
} else {
@ -893,8 +902,8 @@ impl WebGLCommand {
}
fn create_renderbuffer(chan: MsgSender<Option<WebGLRenderbufferId>>) {
let renderbuffer = gl::gen_renderbuffers(1)[0];
fn create_renderbuffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLRenderbufferId>>) {
let renderbuffer = gl.gen_renderbuffers(1)[0];
let renderbuffer = if renderbuffer == 0 {
None
} else {
@ -903,8 +912,8 @@ impl WebGLCommand {
chan.send(renderbuffer).unwrap();
}
fn create_texture(chan: MsgSender<Option<WebGLTextureId>>) {
let texture = gl::gen_textures(1)[0];
fn create_texture(gl: &gl::Gl, chan: MsgSender<Option<WebGLTextureId>>) {
let texture = gl.gen_textures(1)[0];
let texture = if texture == 0 {
None
} else {
@ -914,8 +923,8 @@ impl WebGLCommand {
}
fn create_program(chan: MsgSender<Option<WebGLProgramId>>) {
let program = gl::create_program();
fn create_program(gl: &gl::Gl, chan: MsgSender<Option<WebGLProgramId>>) {
let program = gl.create_program();
let program = if program == 0 {
None
} else {
@ -924,8 +933,8 @@ impl WebGLCommand {
chan.send(program).unwrap();
}
fn create_shader(shader_type: u32, chan: MsgSender<Option<WebGLShaderId>>) {
let shader = gl::create_shader(shader_type);
fn create_shader(gl: &gl::Gl, shader_type: u32, chan: MsgSender<Option<WebGLShaderId>>) {
let shader = gl.create_shader(shader_type);
let shader = if shader == 0 {
None
} else {
@ -935,7 +944,8 @@ impl WebGLCommand {
}
#[inline]
fn bind_framebuffer<Native: NativeGLContextMethods>(target: u32,
fn bind_framebuffer<Native: NativeGLContextMethods>(gl: &gl::Gl,
target: u32,
request: WebGLFramebufferBindingRequest,
ctx: &GLContext<Native>) {
let id = match request {
@ -944,13 +954,13 @@ impl WebGLCommand {
ctx.borrow_draw_buffer().unwrap().get_framebuffer(),
};
gl::bind_framebuffer(target, id);
gl.bind_framebuffer(target, id);
}
#[inline]
fn compile_shader(shader_id: WebGLShaderId, source: String) {
gl::shader_source(shader_id.get(), &[source.as_bytes()]);
gl::compile_shader(shader_id.get());
fn compile_shader(gl: &gl::Gl, shader_id: WebGLShaderId, source: String) {
gl.shader_source(shader_id.get(), &[source.as_bytes()]);
gl.compile_shader(shader_id.get());
}
}

View File

@ -4150,7 +4150,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
ExprAddrOf(ExprVar(p.var().name + 'Copy')),
msgexpr, ExprAddrOf(itervar),
errfn, p.bareType(side).name,
p.name)
sentinelKey=p.name,
errfnSentinel=errfnSentinel())
for p in params ]
+ [ self.endRead(msgvar, itervar) ]
# Move the message back to its source before sending.

View File

@ -1859,6 +1859,8 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
Preferences::GetInt("nglayout.initialpaint.delay",
PAINTLOCK_EVENT_DELAY);
mPaintSuppressionTimer->SetTarget(
mDocument->EventTargetFor(TaskCategory::Other));
mPaintSuppressionTimer->InitWithNamedFuncCallback(
sPaintSuppressionCallback, this, delay, nsITimer::TYPE_ONE_SHOT,
"PresShell::sPaintSuppressionCallback");
@ -2005,16 +2007,21 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord a
}
if (mAsyncResizeEventTimer) {
mAsyncResizeTimerIsActive = true;
mAsyncResizeEventTimer->InitWithFuncCallback(AsyncResizeEventCallback,
this, 15,
nsITimer::TYPE_ONE_SHOT);
mAsyncResizeEventTimer->SetTarget(
mDocument->EventTargetFor(TaskCategory::Other));
mAsyncResizeEventTimer->InitWithNamedFuncCallback(AsyncResizeEventCallback,
this, 15,
nsITimer::TYPE_ONE_SHOT,
"AsyncResizeEventCallback");
}
} else {
RefPtr<nsRunnableMethod<PresShell> > resizeEvent =
NewRunnableMethod("PresShell::FireResizeEvent",
this, &PresShell::FireResizeEvent);
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(resizeEvent))) {
mResizeEvent = resizeEvent;
RefPtr<nsRunnableMethod<PresShell>> event =
NewRunnableMethod(this, &PresShell::FireResizeEvent);
nsresult rv = mDocument->Dispatch("PresShell::FireResizeEvent",
TaskCategory::Other,
do_AddRef(event));
if (NS_SUCCEEDED(rv)) {
mResizeEvent = event;
SetNeedStyleFlush();
}
}
@ -3687,28 +3694,6 @@ PresShell::GetRectVisibility(nsIFrame* aFrame,
return nsRectVisibility_kVisible;
}
class PaintTimerCallBack final : public nsITimerCallback
{
public:
explicit PaintTimerCallBack(PresShell* aShell) : mShell(aShell) {}
NS_DECL_ISUPPORTS
NS_IMETHOD Notify(nsITimer* aTimer) final
{
mShell->SetNextPaintCompressed();
mShell->ScheduleViewManagerFlush();
return NS_OK;
}
private:
~PaintTimerCallBack() {}
PresShell* mShell;
};
NS_IMPL_ISUPPORTS(PaintTimerCallBack, nsITimerCallback)
void
PresShell::ScheduleViewManagerFlush(PaintType aType)
{
@ -3716,9 +3701,24 @@ PresShell::ScheduleViewManagerFlush(PaintType aType)
// Delay paint for 1 second.
static const uint32_t kPaintDelayPeriod = 1000;
if (!mDelayedPaintTimer) {
nsTimerCallbackFunc
PaintTimerCallBack = [](nsITimer* aTimer, void* aClosure) {
// The passed-in PresShell is always alive here. Because if PresShell
// died, mDelayedPaintTimer->Cancel() would be called during the
// destruction and this callback would never be invoked.
auto self = static_cast<PresShell*>(aClosure);
self->SetNextPaintCompressed();
self->ScheduleViewManagerFlush();
};
mDelayedPaintTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
RefPtr<PaintTimerCallBack> cb = new PaintTimerCallBack(this);
mDelayedPaintTimer->InitWithCallback(cb, kPaintDelayPeriod, nsITimer::TYPE_ONE_SHOT);
mDelayedPaintTimer->SetTarget(
mDocument->EventTargetFor(TaskCategory::Other));
mDelayedPaintTimer->InitWithNamedFuncCallback(PaintTimerCallBack,
this,
kPaintDelayPeriod,
nsITimer::TYPE_ONE_SHOT,
"PaintTimerCallBack");
}
return;
}
@ -6256,11 +6256,15 @@ PresShell::ScheduleApproximateFrameVisibilityUpdateNow()
return;
}
RefPtr<nsRunnableMethod<PresShell> > ev =
NewRunnableMethod("PresShell::UpdateApproximateFrameVisibility",
this, &PresShell::UpdateApproximateFrameVisibility);
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) {
mUpdateApproximateFrameVisibilityEvent = ev;
RefPtr<nsRunnableMethod<PresShell>> event =
NewRunnableMethod(this, &PresShell::UpdateApproximateFrameVisibility);
nsresult rv =
mDocument->Dispatch("PresShell::UpdateApproximateFrameVisibility",
TaskCategory::Other,
do_AddRef(event));
if (NS_SUCCEEDED(rv)) {
mUpdateApproximateFrameVisibilityEvent = event;
}
}
@ -9170,10 +9174,13 @@ PresShell::ScheduleReflowOffTimer()
if (!mReflowContinueTimer) {
mReflowContinueTimer = do_CreateInstance("@mozilla.org/timer;1");
mReflowContinueTimer->SetTarget(
mDocument->EventTargetFor(TaskCategory::Other));
if (!mReflowContinueTimer ||
NS_FAILED(mReflowContinueTimer->
InitWithFuncCallback(sReflowContinueCallback, this, 30,
nsITimer::TYPE_ONE_SHOT))) {
InitWithNamedFuncCallback(sReflowContinueCallback, this, 30,
nsITimer::TYPE_ONE_SHOT,
"sReflowContinueCallback"))) {
return false;
}
}

View File

@ -158,8 +158,12 @@ ZoomConstraintsClient::Observe(nsISupports* aSubject, const char* aTopic, const
// We need to run this later because all the pref change listeners need
// to execute before we can be guaranteed that gfxPrefs::ForceUserScalable()
// returns the updated value.
NS_DispatchToMainThread(NewRunnableMethod(
this, &ZoomConstraintsClient::RefreshZoomConstraints));
RefPtr<nsRunnableMethod<ZoomConstraintsClient>> event =
NewRunnableMethod(this, &ZoomConstraintsClient::RefreshZoomConstraints);
mDocument->Dispatch("ZoomConstraintsClient::RefreshZoomConstraints",
TaskCategory::Other,
event.forget());
}
return NS_OK;
}

View File

@ -1741,7 +1741,7 @@ nsCSSFrameConstructor::CreateGeneratedContent(nsFrameConstructorState& aState,
case eStyleContentType_Counter:
case eStyleContentType_Counters: {
nsCSSValue::Array* counters = data.GetCounters();
nsCSSValue::ThreadSafeArray* counters = data.GetCounters();
nsCounterList* counterList = mCounterManager.CounterListFor(
nsDependentString(counters->Item(0).GetStringBufferValue()));

View File

@ -79,7 +79,7 @@ struct nsCounterUseNode : public nsCounterNode {
// The same structure passed through the style system: an array
// containing the values in the counter() or counters() in the order
// given in the CSS spec.
RefPtr<nsCSSValue::Array> mCounterFunction;
RefPtr<nsCSSValue::ThreadSafeArray> mCounterFunction;
nsPresContext* mPresContext;
RefPtr<mozilla::CounterStyle> mCounterStyle;
@ -89,7 +89,7 @@ struct nsCounterUseNode : public nsCounterNode {
// args go directly to member variables here and of nsGenConNode
nsCounterUseNode(nsPresContext* aPresContext,
nsCSSValue::Array* aCounterFunction,
nsCSSValue::ThreadSafeArray* aCounterFunction,
uint32_t aContentIndex, bool aAllCounters)
: nsCounterNode(aContentIndex, USE)
, mCounterFunction(aCounterFunction)

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