mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Merge m-c to autoland. a=merge
This commit is contained in:
commit
af691573d4
@ -36,7 +36,11 @@
|
||||
this.invoke = function testTabRelations_invoke()
|
||||
{
|
||||
var docURIs = ["about:", "about:mozilla"];
|
||||
tabBrowser().loadTabs(docURIs, false, true);
|
||||
tabBrowser().loadTabs(docURIs, {
|
||||
inBackground: false,
|
||||
replace: true,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
}
|
||||
|
||||
this.finalCheck = function testTabRelations_finalCheck(aEvent)
|
||||
|
@ -35,7 +35,11 @@
|
||||
this.invoke = function testTabHierarchy_invoke()
|
||||
{
|
||||
var docURIs = ["about:", "about:mozilla"];
|
||||
tabBrowser().loadTabs(docURIs, false, true);
|
||||
tabBrowser().loadTabs(docURIs, {
|
||||
inBackground: false,
|
||||
replace: true,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
}
|
||||
|
||||
this.finalCheck = function testTabHierarchy_finalCheck(aEvent)
|
||||
|
@ -663,6 +663,12 @@ pref("accessibility.loadedInLastSession", false);
|
||||
pref("plugins.click_to_play", true);
|
||||
pref("plugins.testmode", false);
|
||||
|
||||
// Should plugins that are hidden show the infobar UI?
|
||||
pref("plugins.show_infobar", true);
|
||||
|
||||
// Should dismissing the hidden plugin infobar suppress it permanently?
|
||||
pref("plugins.remember_infobar_dismissal", false);
|
||||
|
||||
pref("plugin.default.state", 1);
|
||||
|
||||
// Plugins bundled in XPIs are enabled by default.
|
||||
|
@ -6,6 +6,9 @@
|
||||
var gPluginHandler = {
|
||||
PREF_SESSION_PERSIST_MINUTES: "plugin.sessionPermissionNow.intervalInMinutes",
|
||||
PREF_PERSISTENT_DAYS: "plugin.persistentPermissionAlways.intervalInDays",
|
||||
PREF_SHOW_INFOBAR: "plugins.show_infobar",
|
||||
PREF_INFOBAR_DISMISSAL_PERMANENT: "plugins.remember_infobar_dismissal",
|
||||
|
||||
MESSAGES: [
|
||||
"PluginContent:ShowClickToPlayNotification",
|
||||
"PluginContent:RemoveNotification",
|
||||
@ -345,6 +348,10 @@ var gPluginHandler = {
|
||||
// 2b. Multiple types of plugins are hidden on the page, but none are
|
||||
// vulnerable. Show the nonvulnerable multi-UI.
|
||||
function showNotification() {
|
||||
if (!Services.prefs.getBoolPref(gPluginHandler.PREF_SHOW_INFOBAR, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let n = notificationBox.getNotificationWithValue("plugin-hidden");
|
||||
if (n) {
|
||||
// If something is already shown, just keep it
|
||||
@ -414,9 +421,21 @@ var gPluginHandler = {
|
||||
}
|
||||
}
|
||||
];
|
||||
function notificationCallback(type) {
|
||||
if (type == "dismissed") {
|
||||
Services.telemetry.getHistogramById("PLUGINS_INFOBAR_DISMISSED").
|
||||
add(true);
|
||||
if (Services.prefs.getBoolPref(gPluginHandler.PREF_INFOBAR_DISMISSAL_PERMANENT, false)) {
|
||||
Services.perms.addFromPrincipal(principal,
|
||||
"plugin-hidden-notification",
|
||||
Services.perms.DENY_ACTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
n = notificationBox.
|
||||
appendNotification(message, "plugin-hidden", null,
|
||||
notificationBox.PRIORITY_INFO_HIGH, buttons);
|
||||
notificationBox.PRIORITY_INFO_HIGH, buttons,
|
||||
notificationCallback);
|
||||
if (haveInsecure) {
|
||||
n.classList.add("pluginVulnerable");
|
||||
}
|
||||
|
@ -1429,7 +1429,11 @@ var gBrowserInit = {
|
||||
// This function throws for certain malformed URIs, so use exception handling
|
||||
// so that we don't disrupt startup
|
||||
try {
|
||||
gBrowser.loadTabs(specs, false, true);
|
||||
gBrowser.loadTabs(specs, {
|
||||
inBackground: false,
|
||||
replace: true,
|
||||
// Bug 1365232, provide correct triggeringPrincipal
|
||||
});
|
||||
} catch (e) {}
|
||||
} else if (uriToLoad instanceof XULElement) {
|
||||
// swap the given tab with the default about:blank tab and then close
|
||||
@ -2167,7 +2171,10 @@ function BrowserGoHome(aEvent) {
|
||||
case "tab":
|
||||
urls = homePage.split("|");
|
||||
var loadInBackground = getBoolPref("browser.tabs.loadBookmarksInBackground", false);
|
||||
gBrowser.loadTabs(urls, loadInBackground);
|
||||
gBrowser.loadTabs(urls, {
|
||||
inBackground: loadInBackground,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
break;
|
||||
case "window":
|
||||
OpenBrowserWindow();
|
||||
@ -2185,7 +2192,11 @@ function loadOneOrMoreURIs(aURIString) {
|
||||
// This function throws for certain malformed URIs, so use exception handling
|
||||
// so that we don't disrupt startup
|
||||
try {
|
||||
gBrowser.loadTabs(aURIString.split("|"), false, true);
|
||||
gBrowser.loadTabs(aURIString.split("|"), {
|
||||
inBackground: false,
|
||||
replace: true,
|
||||
// Bug 1365232, provide correct triggeringPrincipal
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
@ -5857,14 +5868,15 @@ function stripUnsafeProtocolOnPaste(pasteData) {
|
||||
}
|
||||
|
||||
// handleDroppedLink has the following 2 overloads:
|
||||
// handleDroppedLink(event, url, name)
|
||||
// handleDroppedLink(event, links)
|
||||
function handleDroppedLink(event, urlOrLinks, name) {
|
||||
// handleDroppedLink(event, url, name, triggeringPrincipal)
|
||||
// handleDroppedLink(event, links, triggeringPrincipal)
|
||||
function handleDroppedLink(event, urlOrLinks, nameOrTriggeringPrincipal, triggeringPrincipal) {
|
||||
let links;
|
||||
if (Array.isArray(urlOrLinks)) {
|
||||
links = urlOrLinks;
|
||||
triggeringPrincipal = nameOrTriggeringPrincipal;
|
||||
} else {
|
||||
links = [{ url: urlOrLinks, name, type: "" }];
|
||||
links = [{ url: urlOrLinks, nameOrTriggeringPrincipal, type: "" }];
|
||||
}
|
||||
|
||||
let lastLocationChange = gBrowser.selectedBrowser.lastLocationChange;
|
||||
@ -5895,6 +5907,7 @@ function handleDroppedLink(event, urlOrLinks, name) {
|
||||
allowThirdPartyFixup: false,
|
||||
postDatas,
|
||||
userContextId,
|
||||
triggeringPrincipal,
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
@ -7026,6 +7026,13 @@
|
||||
let replace = !!targetTab;
|
||||
let newIndex = this._getDropIndex(event, true);
|
||||
let urls = links.map(link => link.url);
|
||||
|
||||
|
||||
// Bug 1367038: mozSourceNode is null if the drag event originated
|
||||
// in an external application - needs better fallback!
|
||||
let triggeringPrincipal = dt.mozSourceNode
|
||||
? dt.mozSourceNode.nodePrincipal
|
||||
: Services.scriptSecurityManager.getSystemPrincipal();
|
||||
this.tabbrowser.loadTabs(urls, {
|
||||
inBackground,
|
||||
replace,
|
||||
@ -7033,6 +7040,7 @@
|
||||
targetTab,
|
||||
newIndex,
|
||||
userContextId,
|
||||
triggeringPrincipal,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,4 @@ BROWSER_CHROME_MANIFESTS += [
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
|
||||
|
||||
if CONFIG['OS_ARCH'] != 'Darwin':
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
'test/xpcshell/xpcshell-remote.ini',
|
||||
]
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
'test/xpcshell/xpcshell.ini',
|
||||
]
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
|
||||
|
@ -4,7 +4,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
/* exported createHttpServer, promiseConsoleOutput */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
|
||||
@ -25,11 +24,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Schemas",
|
||||
"resource://gre/modules/Schemas.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TestUtils",
|
||||
"resource://testing-common/TestUtils.jsm");
|
||||
|
||||
Services.prefs.setBoolPref("extensions.webextensions.remote", false);
|
||||
|
||||
ExtensionTestUtils.init(this);
|
||||
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
Services.prefs.setBoolPref("extensions.webextensions.remote", true);
|
||||
Services.prefs.setIntPref("dom.ipc.keepProcessesAlive.extension", 1);
|
@ -1,8 +0,0 @@
|
||||
[test_ext_bookmarks.js]
|
||||
[test_ext_browsingData.js]
|
||||
[test_ext_browsingData_cookies_cache.js]
|
||||
[test_ext_browsingData_downloads.js]
|
||||
[test_ext_browsingData_passwords.js]
|
||||
[test_ext_browsingData_settings.js]
|
||||
[test_ext_history.js]
|
||||
[test_ext_geckoProfiler_control.js]
|
@ -1,7 +0,0 @@
|
||||
[DEFAULT]
|
||||
head = head.js head_remote.js
|
||||
firefox-appdir = browser
|
||||
tags = webextensions remote-webextensions
|
||||
dupe-manifest =
|
||||
|
||||
[include:xpcshell-common.ini]
|
@ -1,23 +1,16 @@
|
||||
[DEFAULT]
|
||||
head = head.js
|
||||
firefox-appdir = browser
|
||||
tags = webextensions in-process-webextensions
|
||||
dupe-manifest =
|
||||
|
||||
# This file contains tests which are not affected by multi-process
|
||||
# configuration, or do not support out-of-process content or extensions
|
||||
# for one reason or another.
|
||||
#
|
||||
# Tests which are affected by remote content or remote extensions should
|
||||
# go in one of:
|
||||
#
|
||||
# - xpcshell-common.ini
|
||||
# For tests which should run in all configurations.
|
||||
# - xpcshell-remote.ini
|
||||
# For tests which should only run with both remote extensions and remote content.
|
||||
tags = webextensions
|
||||
|
||||
[test_ext_bookmarks.js]
|
||||
[test_ext_browsingData.js]
|
||||
[test_ext_browsingData_cookies_cache.js]
|
||||
[test_ext_browsingData_downloads.js]
|
||||
[test_ext_browsingData_passwords.js]
|
||||
[test_ext_browsingData_settings.js]
|
||||
[test_ext_history.js]
|
||||
[test_ext_manifest_commands.js]
|
||||
[test_ext_manifest_omnibox.js]
|
||||
[test_ext_manifest_permissions.js]
|
||||
|
||||
[include:xpcshell-common.ini]
|
||||
[test_ext_geckoProfiler_control.js]
|
||||
|
@ -13,4 +13,4 @@ MOCHITEST_MANIFESTS += [
|
||||
]
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Firefox', 'OriginAttributes')
|
||||
BUG_COMPONENT = ('Core', 'DOM: Security')
|
||||
|
@ -953,7 +953,11 @@ this.PlacesUIUtils = {
|
||||
// For consistency, we want all the bookmarks to open in new tabs, instead
|
||||
// of having one of them replace the currently focused tab. Hence we call
|
||||
// loadTabs with aReplace set to false.
|
||||
browserWindow.gBrowser.loadTabs(urls, loadInBackground, false);
|
||||
browserWindow.gBrowser.loadTabs(urls, {
|
||||
inBackground: loadInBackground,
|
||||
replace: false,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
},
|
||||
|
||||
openLiveMarkNodesInTabs:
|
||||
|
@ -15,6 +15,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
|
||||
"resource:///modules/BrowserUITelemetry.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUIUtils",
|
||||
"resource:///modules/PlacesUIUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"TabListComponent"
|
||||
@ -127,7 +129,11 @@ TabListComponent.prototype = {
|
||||
"chrome,dialog=no,all", urls.join("|"));
|
||||
} else {
|
||||
let loadInBackground = where == "tabshifted" ? true : false;
|
||||
this._getChromeWindow(this._window).gBrowser.loadTabs(urls, loadInBackground, false);
|
||||
this._getChromeWindow(this._window).gBrowser.loadTabs(urls, {
|
||||
inBackground: loadInBackground,
|
||||
replace: false,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
});
|
||||
}
|
||||
BrowserUITelemetry.countSyncedTabEvent("openmultiple", "sidebar");
|
||||
},
|
||||
|
@ -4,6 +4,7 @@ let { SyncedTabs } = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
|
||||
let { TabListComponent } = Cu.import("resource:///modules/syncedtabs/TabListComponent.js", {});
|
||||
let { SyncedTabsListStore } = Cu.import("resource:///modules/syncedtabs/SyncedTabsListStore.js", {});
|
||||
let { View } = Cu.import("resource:///modules/syncedtabs/TabListView.js", {});
|
||||
let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
|
||||
const ACTION_METHODS = [
|
||||
"onSelectRow",
|
||||
@ -139,9 +140,17 @@ add_task(function* testActions() {
|
||||
let tabsToOpen = ["uri1", "uri2"];
|
||||
component.onOpenTabs(tabsToOpen, "where");
|
||||
Assert.ok(getChromeWindowMock.calledWith(windowMock));
|
||||
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, false, false));
|
||||
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, {
|
||||
inBackground: false,
|
||||
replace: false,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
}));
|
||||
component.onOpenTabs(tabsToOpen, "tabshifted");
|
||||
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, true, false));
|
||||
Assert.ok(chromeWindowMock.gBrowser.loadTabs.calledWith(tabsToOpen, {
|
||||
inBackground: true,
|
||||
replace: false,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
}));
|
||||
|
||||
sinon.spy(clipboardHelperMock, "copyString");
|
||||
component.onCopyTabLocation("uri");
|
||||
|
@ -92,7 +92,12 @@ this.Tabs = {
|
||||
"about:home",
|
||||
DEFAULT_FAVICON_TAB,
|
||||
"about:newtab",
|
||||
], true, true);
|
||||
],
|
||||
{
|
||||
inBackground: true,
|
||||
replace: true,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
|
||||
});
|
||||
browserWindow.gBrowser.pinTab(browserWindow.gBrowser.tabs[1]);
|
||||
browserWindow.gBrowser.pinTab(browserWindow.gBrowser.tabs[2]);
|
||||
browserWindow.gBrowser.selectTabAtIndex(3);
|
||||
@ -119,7 +124,12 @@ function fiveTabsHelper() {
|
||||
DEFAULT_FAVICON_TAB,
|
||||
"about:newtab",
|
||||
CUST_TAB,
|
||||
], true, true);
|
||||
],
|
||||
{
|
||||
inBackground: true,
|
||||
replace: true,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
|
||||
});
|
||||
browserWindow.gBrowser.selectTabAtIndex(1);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ const { addons, createClass, DOM: dom, PropTypes } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
const Types = require("../types");
|
||||
const { getStr } = require("../utils/l10n");
|
||||
|
||||
const COLUMNS = "cols";
|
||||
const ROWS = "rows";
|
||||
@ -15,6 +16,10 @@ const ROWS = "rows";
|
||||
// The delay prior to executing the grid cell highlighting.
|
||||
const GRID_HIGHLIGHTING_DEBOUNCE = 50;
|
||||
|
||||
// Minimum height/width a grid cell can be
|
||||
const MIN_CELL_HEIGHT = 5;
|
||||
const MIN_CELL_WIDTH = 5;
|
||||
|
||||
// Move SVG grid to the right 100 units, so that it is not flushed against the edge of
|
||||
// layout border
|
||||
const TRANSLATE_X = 0;
|
||||
@ -40,8 +45,9 @@ module.exports = createClass({
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
selectedGrid: null,
|
||||
height: 0,
|
||||
selectedGrid: null,
|
||||
showOutline: true,
|
||||
width: 0,
|
||||
};
|
||||
},
|
||||
@ -56,7 +62,7 @@ module.exports = createClass({
|
||||
? this.getTotalWidthAndHeight(selectedGrid)
|
||||
: { width: 0, height: 0 };
|
||||
|
||||
this.setState({ height, width, selectedGrid });
|
||||
this.setState({ height, width, selectedGrid, showOutline: true });
|
||||
},
|
||||
|
||||
/**
|
||||
@ -135,6 +141,7 @@ module.exports = createClass({
|
||||
if (this.highlightTimeout) {
|
||||
clearTimeout(this.highlightTimeout);
|
||||
}
|
||||
|
||||
this.highlightTimeout = setTimeout(() => {
|
||||
this.doHighlightCell(e);
|
||||
this.highlightTimeout = null;
|
||||
@ -164,6 +171,25 @@ module.exports = createClass({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays a message text "Cannot show outline for this grid".
|
||||
*
|
||||
*/
|
||||
renderCannotShowOutlineText() {
|
||||
return dom.div(
|
||||
{
|
||||
className: "grid-outline-text"
|
||||
},
|
||||
dom.span(
|
||||
{
|
||||
className: "grid-outline-text-icon",
|
||||
title: getStr("layout.cannotShowGridOutline.title")
|
||||
}
|
||||
),
|
||||
getStr("layout.cannotShowGridOutline")
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders the grid outline for the given grid container object.
|
||||
*
|
||||
@ -192,6 +218,14 @@ module.exports = createClass({
|
||||
for (let columnNumber = 1; columnNumber <= numberOfColumns; columnNumber++) {
|
||||
width = GRID_CELL_SCALE_FACTOR * (cols.tracks[columnNumber - 1].breadth / 100);
|
||||
|
||||
// If a grid cell is less than the minimum pixels in width or height,
|
||||
// do not render the outline at all.
|
||||
if (width < MIN_CELL_WIDTH || height < MIN_CELL_HEIGHT) {
|
||||
this.setState({ showOutline: false });
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
const gridAreaName = this.getGridAreaName(columnNumber, rowNumber, areas);
|
||||
const gridCell = this.renderGridCell(id, gridFragmentIndex, x, y,
|
||||
rowNumber, columnNumber, color, gridAreaName,
|
||||
@ -420,13 +454,17 @@ module.exports = createClass({
|
||||
lineNumber, type);
|
||||
},
|
||||
|
||||
render() {
|
||||
const { selectedGrid, height, width } = this.state;
|
||||
renderOutline() {
|
||||
const {
|
||||
height,
|
||||
selectedGrid,
|
||||
showOutline,
|
||||
width,
|
||||
} = this.state;
|
||||
|
||||
return selectedGrid ?
|
||||
return showOutline ?
|
||||
dom.svg(
|
||||
{
|
||||
className: "grid-outline",
|
||||
width: "100%",
|
||||
height: this.getHeight(),
|
||||
viewBox: `${TRANSLATE_X} ${TRANSLATE_Y} ${width} ${height}`,
|
||||
@ -435,6 +473,20 @@ module.exports = createClass({
|
||||
this.renderGridLines(selectedGrid)
|
||||
)
|
||||
:
|
||||
this.renderCannotShowOutlineText();
|
||||
},
|
||||
|
||||
render() {
|
||||
const { selectedGrid } = this.state;
|
||||
|
||||
return selectedGrid ?
|
||||
dom.div(
|
||||
{
|
||||
className: "grid-outline",
|
||||
},
|
||||
this.renderOutline()
|
||||
)
|
||||
:
|
||||
null;
|
||||
},
|
||||
|
||||
|
@ -216,6 +216,7 @@ devtools.jar:
|
||||
skin/images/gcli_sec_good.svg (themes/images/gcli_sec_good.svg)
|
||||
skin/images/gcli_sec_moderate.svg (themes/images/gcli_sec_moderate.svg)
|
||||
skin/images/globe.svg (themes/images/globe.svg)
|
||||
skin/images/sad-face.svg (themes/images/sad-face.svg)
|
||||
skin/images/tool-options.svg (themes/images/tool-options.svg)
|
||||
skin/images/tool-webconsole.svg (themes/images/tool-webconsole.svg)
|
||||
skin/images/tool-canvas.svg (themes/images/tool-canvas.svg)
|
||||
|
@ -7,6 +7,11 @@
|
||||
# The Layout Inspector may need to be enabled in about:config by setting
|
||||
# devtools.layoutview.enabled to true.
|
||||
|
||||
# LOCALIZATION NOTE (layout.cannotShowGridOutline, layout.cannotSHowGridOutline.title):
|
||||
# In the case where the grid outline cannot be effectively displayed.
|
||||
layout.cannotShowGridOutline=Cannot show outline for this grid
|
||||
layout.cannotShowGridOutline.title=The selected grid’s outline cannot effectively fit inside the layout panel for it to be usable.
|
||||
|
||||
# LOCALIZATION NOTE (layout.displayNumbersOnLines): Label of the display numbers on lines
|
||||
# setting option in the CSS Grid pane.
|
||||
layout.displayNumbersOnLines=Display numbers on lines
|
||||
|
9
devtools/client/themes/images/sad-face.svg
Normal file
9
devtools/client/themes/images/sad-face.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#D92215">
|
||||
<path d="M8 14.5c-3.6 0-6.5-2.9-6.5-6.5S4.4 1.5 8 1.5s6.5 2.9 6.5 6.5-2.9 6.5-6.5 6.5zm0-12C5 2.5 2.5 5 2.5 8S5 13.5 8 13.5 13.5 11 13.5 8 11 2.5 8 2.5z"/>
|
||||
<circle cx="5" cy="6" r="1" transform="translate(1 1)"/>
|
||||
<circle cx="9" cy="6" r="1" transform="translate(1 1)"/>
|
||||
<path d="M5.5 11c-.1 0-.2 0-.3-.1-.2-.1-.3-.4-.1-.7C6 9 7 8.5 8.1 8.5c1.7.1 2.8 1.7 2.8 1.8.2.2.1.5-.1.7-.2.1-.6 0-.7-.2 0 0-.9-1.3-2-1.3-.7 0-1.4.4-2.1 1.3-.2.2-.4.2-.5.2z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 772 B |
@ -58,15 +58,6 @@
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grid Outline
|
||||
*/
|
||||
|
||||
.grid-outline {
|
||||
margin-top: 10px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grid Content
|
||||
*/
|
||||
@ -75,7 +66,7 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
margin-top: 10px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.grid-container:first-child {
|
||||
@ -86,8 +77,12 @@
|
||||
* Grid Outline
|
||||
*/
|
||||
|
||||
#grid-outline {
|
||||
margin: 5px auto;
|
||||
.grid-outline {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.grid-outline svg {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.grid-outline-border {
|
||||
@ -114,6 +109,20 @@
|
||||
stroke-width: 10;
|
||||
}
|
||||
|
||||
.grid-outline-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--theme-graphs-full-red);
|
||||
}
|
||||
|
||||
.grid-outline-text-icon {
|
||||
background: url("chrome://devtools/skin/images/sad-face.svg");
|
||||
margin-inline-end: 5px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Container when no grids are present
|
||||
*/
|
||||
|
@ -994,7 +994,20 @@ nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
|
||||
if (webBrowserChrome) {
|
||||
nsCOMPtr<nsITabChild> tabChild = do_QueryInterface(webBrowserChrome);
|
||||
if (tabChild) {
|
||||
nsresult rv = tabChild->RemoteDropLinks(linksCount, links);
|
||||
nsCOMPtr<nsIDOMDataTransfer> domDataTransfer;
|
||||
dragEvent->GetDataTransfer(getter_AddRefs(domDataTransfer));
|
||||
NS_ENSURE_TRUE(domDataTransfer, NS_ERROR_UNEXPECTED);
|
||||
nsCOMPtr<nsIDOMNode> domSourceNode;
|
||||
domDataTransfer->GetMozSourceNode(getter_AddRefs(domSourceNode));
|
||||
nsCOMPtr<nsINode> sourceNode = do_QueryInterface(domSourceNode);
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
||||
if (sourceNode) {
|
||||
triggeringPrincipal = sourceNode->NodePrincipal();
|
||||
} else {
|
||||
triggeringPrincipal = NullPrincipal::Create();
|
||||
}
|
||||
nsresult rv = tabChild->RemoteDropLinks(linksCount, links,
|
||||
triggeringPrincipal);
|
||||
for (uint32_t i = 0; i < linksCount; i++) {
|
||||
NS_RELEASE(links[i]);
|
||||
}
|
||||
|
@ -114,6 +114,8 @@
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/dom/TimeoutManager.h"
|
||||
#include "mozilla/PreloadedStyleSheet.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#undef GetClassName
|
||||
@ -2522,6 +2524,14 @@ nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
|
||||
if (!manager) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
|
||||
WebRenderBridgeChild* wrbc = wrlm->WrBridge();
|
||||
if (!wrbc) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
wrbc->SendSetAsyncScrollOffset(viewId, aX, aY);
|
||||
return NS_OK;
|
||||
}
|
||||
ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
|
||||
if (!forwarder || !forwarder->HasShadowManager()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
@ -2549,6 +2559,14 @@ nsDOMWindowUtils::SetAsyncZoom(nsIDOMNode* aRootElement, float aValue)
|
||||
if (!manager) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
|
||||
WebRenderBridgeChild* wrbc = wrlm->WrBridge();
|
||||
if (!wrbc) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
wrbc->SendSetAsyncZoom(viewId, aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
|
||||
if (!forwarder || !forwarder->HasShadowManager()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
@ -2575,6 +2593,14 @@ nsDOMWindowUtils::FlushApzRepaints(bool* aOutResult)
|
||||
*aOutResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
|
||||
WebRenderBridgeChild* wrbc = wrlm->WrBridge();
|
||||
if (!wrbc) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
wrbc->SendFlushApzRepaints();
|
||||
return NS_OK;
|
||||
}
|
||||
ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
|
||||
if (!forwarder || !forwarder->HasShadowManager()) {
|
||||
*aOutResult = false;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIFrameLoader;
|
||||
interface nsIPrincipal;
|
||||
|
||||
[scriptable, uuid(14e5a0cb-e223-4202-95e8-fe53275193ea)]
|
||||
interface nsIBrowser : nsISupports
|
||||
@ -23,9 +24,12 @@ interface nsIBrowser : nsISupports
|
||||
*
|
||||
* @param linksCount length of links
|
||||
* @param links a flat array of url, name, and type for each link
|
||||
* @param triggeringPrincipal a principal that initiated loading
|
||||
* of the dropped links
|
||||
*/
|
||||
void dropLinks(in unsigned long linksCount,
|
||||
[array, size_is(linksCount)] in wstring links);
|
||||
[array, size_is(linksCount)] in wstring links,
|
||||
in nsIPrincipal aTriggeringPrincipal);
|
||||
|
||||
/**
|
||||
* Flags for controlling the behavior of swapBrowsers
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
interface nsIContentFrameMessageManager;
|
||||
interface nsIWebBrowserChrome3;
|
||||
interface nsIPrincipal;
|
||||
|
||||
native CommandsArray(nsTArray<nsCString>);
|
||||
[ref] native CommandsArrayRef(nsTArray<nsCString>);
|
||||
@ -31,7 +32,8 @@ interface nsITabChild : nsISupports
|
||||
in int32_t shellItemWidth, in int32_t shellItemHeight);
|
||||
|
||||
[noscript] void remoteDropLinks(in unsigned long linksCount,
|
||||
[array, size_is(linksCount)] in nsIDroppedLinkItem links);
|
||||
[array, size_is(linksCount)] in nsIDroppedLinkItem links,
|
||||
in nsIPrincipal triggeringPrincipal);
|
||||
|
||||
readonly attribute uint64_t tabId;
|
||||
|
||||
|
@ -5215,18 +5215,6 @@ ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvAllocPipelineId(RefPtr<AllocPipelineIdPromise>&& aPromise)
|
||||
{
|
||||
GPUProcessManager* pm = GPUProcessManager::Get();
|
||||
if (!pm) {
|
||||
aPromise->Reject(PromiseRejectReason::HandlerRejected, __func__);
|
||||
return IPC_OK();
|
||||
}
|
||||
aPromise->Resolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvFileCreationRequest(const nsID& aID,
|
||||
const nsString& aFullPath,
|
||||
|
@ -643,9 +643,6 @@ public:
|
||||
nsresult* aRv,
|
||||
nsTArray<nsCString>* aResults) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvAllocPipelineId(RefPtr<AllocPipelineIdPromise>&& aPromise) override;
|
||||
|
||||
// Use the PHangMonitor channel to ask the child to repaint a tab.
|
||||
void ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch);
|
||||
|
||||
|
@ -21,6 +21,7 @@ include protocol PFileDescriptorSet;
|
||||
include protocol PIPCBlobInputStream;
|
||||
include protocol PPaymentRequest;
|
||||
|
||||
include PBackgroundSharedTypes;
|
||||
include DOMTypes;
|
||||
include IPCBlob;
|
||||
include IPCStream;
|
||||
@ -195,7 +196,7 @@ parent:
|
||||
*
|
||||
* aLinks A flat array of url, name, and type for each link
|
||||
*/
|
||||
async DropLinks(nsString[] aLinks);
|
||||
async DropLinks(nsString[] aLinks, PrincipalInfo aTriggeringPrincipalInfo);
|
||||
|
||||
async Event(RemoteDOMEvent aEvent);
|
||||
|
||||
|
@ -63,7 +63,6 @@ include MemoryReportTypes;
|
||||
// are put into different UnifiedProtocolsXX.cpp files.
|
||||
// XXX Remove this once bug 1069073 is fixed
|
||||
include "mozilla/dom/PContentBridgeParent.h";
|
||||
include "mozilla/layers/WebRenderMessageUtils.h";
|
||||
|
||||
using GeoPosition from "nsGeoPositionIPCSerialiser.h";
|
||||
using AlertNotificationType from "mozilla/AlertNotificationIPCSerializer.h";
|
||||
@ -96,7 +95,6 @@ using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
|
||||
using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
|
||||
using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
|
||||
using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
|
||||
using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
{
|
||||
@ -1104,8 +1102,6 @@ parent:
|
||||
async AddMemoryReport(MemoryReport aReport);
|
||||
async FinishMemoryReport(uint32_t aGeneration);
|
||||
|
||||
async AllocPipelineId() returns (PipelineId pipelineId);
|
||||
|
||||
both:
|
||||
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
|
||||
Principal aPrincipal, ClonedMessageData aData);
|
||||
|
@ -748,7 +748,9 @@ TabChild::RemoteSizeShellTo(int32_t aWidth, int32_t aHeight,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::RemoteDropLinks(uint32_t aLinksCount, nsIDroppedLinkItem** aLinks)
|
||||
TabChild::RemoteDropLinks(uint32_t aLinksCount,
|
||||
nsIDroppedLinkItem** aLinks,
|
||||
nsIPrincipal* aTriggeringPrincipal)
|
||||
{
|
||||
nsTArray<nsString> linksArray;
|
||||
nsresult rv = NS_OK;
|
||||
@ -773,7 +775,9 @@ TabChild::RemoteDropLinks(uint32_t aLinksCount, nsIDroppedLinkItem** aLinks)
|
||||
linksArray.AppendElement(tmp);
|
||||
}
|
||||
|
||||
bool sent = SendDropLinks(linksArray);
|
||||
PrincipalInfo triggeringPrincipalInfo;
|
||||
PrincipalToPrincipalInfo(aTriggeringPrincipal, &triggeringPrincipalInfo);
|
||||
bool sent = SendDropLinks(linksArray, triggeringPrincipalInfo);
|
||||
|
||||
return sent ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -526,7 +526,8 @@ TabParent::RecvSizeShellTo(const uint32_t& aFlags, const int32_t& aWidth, const
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks)
|
||||
TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks,
|
||||
const PrincipalInfo& aTriggeringPrincipalInfo)
|
||||
{
|
||||
nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mFrameElement);
|
||||
if (browser) {
|
||||
@ -535,7 +536,12 @@ TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks)
|
||||
for (uint32_t i = 0; i < aLinks.Length(); i++) {
|
||||
links[i] = aLinks[i].get();
|
||||
}
|
||||
browser->DropLinks(aLinks.Length(), links.get());
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal =
|
||||
PrincipalInfoToPrincipal(aTriggeringPrincipalInfo);
|
||||
if (nsContentUtils::IsSystemPrincipal(triggeringPrincipal)) {
|
||||
return IPC_FAIL(this, "Invalid triggeringPrincipal");
|
||||
}
|
||||
browser->DropLinks(aLinks.Length(), links.get(), triggeringPrincipal);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -161,7 +161,8 @@ public:
|
||||
const int32_t& aShellItemWidth,
|
||||
const int32_t& aShellItemHeight) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvDropLinks(nsTArray<nsString>&& aLinks) override;
|
||||
virtual mozilla::ipc::IPCResult RecvDropLinks(nsTArray<nsString>&& aLinks,
|
||||
const PrincipalInfo& aTriggeringPrincipalInfo) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvEvent(const RemoteDOMEvent& aEvent) override;
|
||||
|
||||
|
@ -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: 102603520d52f335f152ab74b6bcfdae061b6bc8
|
||||
Latest Commit: 76a3213080ca5c2e2a612c3023c50c81a111fd55
|
||||
|
@ -81,8 +81,9 @@ GPUProcessManager::Shutdown()
|
||||
|
||||
GPUProcessManager::GPUProcessManager()
|
||||
: mTaskFactory(this),
|
||||
mNextLayerTreeId(0),
|
||||
mNextNamespace(0),
|
||||
mIdNamespace(0),
|
||||
mResourceId(0),
|
||||
mNumProcessAttempts(0),
|
||||
mDeviceResetCount(0),
|
||||
mProcess(nullptr),
|
||||
@ -90,6 +91,7 @@ GPUProcessManager::GPUProcessManager()
|
||||
{
|
||||
MOZ_COUNT_CTOR(GPUProcessManager);
|
||||
|
||||
mIdNamespace = AllocateNamespace();
|
||||
mObserver = new Observer(this);
|
||||
nsContentUtils::RegisterShutdownObserver(mObserver);
|
||||
|
||||
@ -888,8 +890,20 @@ GPUProcessManager::IsLayerTreeIdMapped(uint64_t aLayersId, base::ProcessId aRequ
|
||||
uint64_t
|
||||
GPUProcessManager::AllocateLayerTreeId()
|
||||
{
|
||||
// Allocate tree id by using id namespace.
|
||||
// By it, tree id does not conflict with external image id and
|
||||
// async image pipeline id.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return ++mNextLayerTreeId;
|
||||
++mResourceId;
|
||||
if (mResourceId == UINT32_MAX) {
|
||||
// Move to next id namespace.
|
||||
mIdNamespace = AllocateNamespace();
|
||||
mResourceId = 1;
|
||||
}
|
||||
|
||||
uint64_t layerTreeId = mIdNamespace;
|
||||
layerTreeId = (layerTreeId << 32) | mResourceId;
|
||||
return layerTreeId;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -244,8 +244,9 @@ private:
|
||||
RefPtr<Observer> mObserver;
|
||||
ipc::TaskFactory<GPUProcessManager> mTaskFactory;
|
||||
RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
|
||||
uint64_t mNextLayerTreeId;
|
||||
uint32_t mNextNamespace;
|
||||
uint32_t mIdNamespace;
|
||||
uint32_t mResourceId;
|
||||
uint32_t mNumProcessAttempts;
|
||||
|
||||
nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4, Matrix
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "nsDebug.h" // for NS_ERROR
|
||||
#include "nsPoint.h" // for nsIntPoint
|
||||
#include "nsRect.h" // for mozilla::gfx::IntRect
|
||||
#include "nsPoint.h" // for nsPoint
|
||||
#include "nsRect.h" // for nsRect
|
||||
#include "base/basictypes.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
@ -70,25 +70,38 @@ AppendToString(std::stringstream& aStream, const nsRect& r,
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const nsIntPoint& p,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString("(x=%d, y=%d)", p.x, p.y).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const IntRect& r,
|
||||
AppendToString(std::stringstream& aStream, const WrColor& c,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"(x=%d, y=%d, w=%d, h=%d)",
|
||||
"rgba(%d, %d, %d, %f)",
|
||||
uint8_t(c.r*255.f), uint8_t(c.g*255.f), uint8_t(c.b*255.f), c.a).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const WrRect& r,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"(x=%f, y=%f, w=%f, h=%f)",
|
||||
r.x, r.y, r.width, r.height).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const WrSize& s,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
aStream << pfx;
|
||||
aStream << nsPrintfCString(
|
||||
"(w=%f, h=%f)",
|
||||
s.width, s.height).get();
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const nsRegion& r,
|
||||
const char* pfx, const char* sfx)
|
||||
|
@ -18,6 +18,10 @@
|
||||
#include "nsRegion.h" // for nsRegion, nsIntRegion
|
||||
#include "nscore.h" // for nsACString, etc
|
||||
|
||||
struct WrColor;
|
||||
struct WrRect;
|
||||
struct WrSize;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
template <class units, class F> struct RectTyped;
|
||||
@ -87,6 +91,18 @@ AppendToString(std::stringstream& aStream, const mozilla::gfx::IntRectTyped<T>&
|
||||
aStream << sfx;
|
||||
}
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const WrColor& c,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const WrRect& r,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const WrSize& s,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
void
|
||||
AppendToString(std::stringstream& aStream, const nsRegion& r,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
@ -1804,6 +1804,25 @@ APZCTreeManager::GetTargetAPZC(const ScrollableLayerGuid& aGuid)
|
||||
return apzc.forget();
|
||||
}
|
||||
|
||||
static bool
|
||||
GuidComparatorIgnoringPresShell(const ScrollableLayerGuid& aOne, const ScrollableLayerGuid& aTwo)
|
||||
{
|
||||
return aOne.mLayersId == aTwo.mLayersId
|
||||
&& aOne.mScrollId == aTwo.mScrollId;
|
||||
}
|
||||
|
||||
already_AddRefed<AsyncPanZoomController>
|
||||
APZCTreeManager::GetTargetAPZC(const uint64_t& aLayersId,
|
||||
const FrameMetrics::ViewID& aScrollId)
|
||||
{
|
||||
MutexAutoLock lock(mTreeLock);
|
||||
ScrollableLayerGuid guid(aLayersId, 0, aScrollId);
|
||||
RefPtr<HitTestingTreeNode> node = GetTargetNode(guid, &GuidComparatorIgnoringPresShell);
|
||||
MOZ_ASSERT(!node || node->GetApzc()); // any node returned must have an APZC
|
||||
RefPtr<AsyncPanZoomController> apzc = node ? node->GetApzc() : nullptr;
|
||||
return apzc.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<HitTestingTreeNode>
|
||||
APZCTreeManager::GetTargetNode(const ScrollableLayerGuid& aGuid,
|
||||
GuidComparator aComparator) const
|
||||
@ -1844,13 +1863,6 @@ APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint,
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
static bool
|
||||
GuidComparatorIgnoringPresShell(const ScrollableLayerGuid& aOne, const ScrollableLayerGuid& aTwo)
|
||||
{
|
||||
return aOne.mLayersId == aTwo.mLayersId
|
||||
&& aOne.mScrollId == aTwo.mScrollId;
|
||||
}
|
||||
|
||||
RefPtr<const OverscrollHandoffChain>
|
||||
APZCTreeManager::BuildOverscrollHandoffChain(const RefPtr<AsyncPanZoomController>& aInitialTarget)
|
||||
{
|
||||
|
@ -460,6 +460,8 @@ public:
|
||||
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint,
|
||||
HitTestResult* aOutHitResult,
|
||||
HitTestingTreeNode** aOutScrollbarNode = nullptr);
|
||||
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const uint64_t& aLayersId,
|
||||
const FrameMetrics::ViewID& aScrollId);
|
||||
ScreenToParentLayerMatrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
|
||||
ParentLayerToScreenMatrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/layers/LayerTransactionChild.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContainerFrame.h"
|
||||
@ -703,6 +705,13 @@ SendLayersDependentApzcTargetConfirmation(nsIPresShell* aShell, uint64_t aInputB
|
||||
return;
|
||||
}
|
||||
|
||||
if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) {
|
||||
if (WebRenderBridgeChild* wrbc = wrlm->WrBridge()) {
|
||||
wrbc->SendSetConfirmedTargetAPZC(aInputBlockId, aTargets);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LayerTransactionChild* shadow = lm->AsShadowForwarder()->GetShadowManager();
|
||||
if (!shadow) {
|
||||
return;
|
||||
|
@ -79,14 +79,15 @@ Atomic<int32_t> KnowsCompositor::sSerialCounter(0);
|
||||
|
||||
CompositorBridgeChild::CompositorBridgeChild(LayerManager *aLayerManager, uint32_t aNamespace)
|
||||
: mLayerManager(aLayerManager)
|
||||
, mNamespace(aNamespace)
|
||||
, mIdNamespace(aNamespace)
|
||||
, mResourceId(0)
|
||||
, mCanSend(false)
|
||||
, mFwdTransactionId(0)
|
||||
, mDeviceResetSequenceNumber(0)
|
||||
, mMessageLoop(MessageLoop::current())
|
||||
, mSectionAllocator(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mNamespace);
|
||||
MOZ_ASSERT(mIdNamespace);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
@ -1169,16 +1170,28 @@ CompositorBridgeChild::DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActo
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
CompositorBridgeChild::GetNextResourceId()
|
||||
{
|
||||
++mResourceId;
|
||||
MOZ_RELEASE_ASSERT(mResourceId != UINT32_MAX);
|
||||
|
||||
uint64_t id = mIdNamespace;
|
||||
id = (id << 32) | mResourceId;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
wr::MaybeExternalImageId
|
||||
CompositorBridgeChild::GetNextExternalImageId()
|
||||
{
|
||||
static uint32_t sNextID = 1;
|
||||
++sNextID;
|
||||
MOZ_RELEASE_ASSERT(sNextID != UINT32_MAX);
|
||||
return Some(wr::ToExternalImageId(GetNextResourceId()));
|
||||
}
|
||||
|
||||
uint64_t imageId = mNamespace;
|
||||
imageId = (imageId << 32) | sNextID;
|
||||
return Some(wr::ToExternalImageId(imageId));
|
||||
wr::PipelineId
|
||||
CompositorBridgeChild::GetNextPipelineId()
|
||||
{
|
||||
return wr::AsPipelineId(GetNextResourceId());
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
@ -235,6 +235,8 @@ public:
|
||||
|
||||
wr::MaybeExternalImageId GetNextExternalImageId() override;
|
||||
|
||||
wr::PipelineId GetNextPipelineId();
|
||||
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
virtual ~CompositorBridgeChild();
|
||||
@ -268,6 +270,8 @@ private:
|
||||
already_AddRefed<nsIEventTarget>
|
||||
GetSpecificMessageEventTarget(const Message& aMsg) override;
|
||||
|
||||
uint64_t GetNextResourceId();
|
||||
|
||||
// Class used to store the shared FrameMetrics, mutex, and APZCId in a hash table
|
||||
class SharedFrameMetricsData {
|
||||
public:
|
||||
@ -296,7 +300,8 @@ private:
|
||||
|
||||
RefPtr<LayerManager> mLayerManager;
|
||||
|
||||
uint32_t mNamespace;
|
||||
uint32_t mIdNamespace;
|
||||
uint32_t mResourceId;
|
||||
|
||||
// When not multi-process, hold a reference to the CompositorBridgeParent to keep it
|
||||
// alive. This reference should be null in multi-process.
|
||||
|
@ -1308,10 +1308,10 @@ CompositorBridgeParent::RecvGetFrameUniformity(FrameUniformityData* aOutData)
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
|
||||
CompositorBridgeParent::FlushApzRepaints(const uint64_t& aLayersId)
|
||||
{
|
||||
MOZ_ASSERT(mApzcTreeManager);
|
||||
uint64_t layersId = aLayerTree->GetId();
|
||||
uint64_t layersId = aLayersId;
|
||||
if (layersId == 0) {
|
||||
// The request is coming from the parent-process layer tree, so we should
|
||||
// use the compositor's root layer tree id.
|
||||
@ -1332,9 +1332,9 @@ CompositorBridgeParent::GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeParent::SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets)
|
||||
CompositorBridgeParent::SetConfirmedTargetAPZC(const uint64_t& aLayersId,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets)
|
||||
{
|
||||
if (!mApzcTreeManager) {
|
||||
return;
|
||||
@ -1347,7 +1347,6 @@ CompositorBridgeParent::SetConfirmedTargetAPZC(const LayerTransactionParent* aLa
|
||||
<uint64_t, StoreCopyPassByConstLRef<nsTArray<ScrollableLayerGuid>>>
|
||||
(mApzcTreeManager.get(), setTargetApzcFunc, aInputBlockId, aTargets);
|
||||
APZThreadUtils::RunOnControllerThread(task.forget());
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -108,10 +108,10 @@ public:
|
||||
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) { }
|
||||
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree) = 0;
|
||||
virtual CompositorAnimationStorage* GetAnimationStorage(const uint64_t& aId) { return nullptr; }
|
||||
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) = 0;
|
||||
virtual void FlushApzRepaints(const uint64_t& aLayersId) = 0;
|
||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData) { }
|
||||
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
virtual void SetConfirmedTargetAPZC(const uint64_t& aLayersId,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
|
||||
virtual void UpdatePaintTime(LayerTransactionParent* aLayerTree, const TimeDuration& aPaintTime) {}
|
||||
@ -231,10 +231,10 @@ public:
|
||||
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
||||
override;
|
||||
virtual CompositorAnimationStorage* GetAnimationStorage(const uint64_t& aId) override;
|
||||
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
|
||||
virtual void FlushApzRepaints(const uint64_t& aLayersId) override;
|
||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData) override;
|
||||
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
virtual void SetConfirmedTargetAPZC(const uint64_t& aLayersId,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets) override;
|
||||
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) override { return mCompositionManager; }
|
||||
|
@ -422,18 +422,17 @@ CrossProcessCompositorBridgeParent::GetAnimationStorage(
|
||||
}
|
||||
|
||||
void
|
||||
CrossProcessCompositorBridgeParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
|
||||
CrossProcessCompositorBridgeParent::FlushApzRepaints(const uint64_t& aLayersId)
|
||||
{
|
||||
uint64_t id = aLayerTree->GetId();
|
||||
MOZ_ASSERT(id != 0);
|
||||
MOZ_ASSERT(aLayersId != 0);
|
||||
const CompositorBridgeParent::LayerTreeState* state =
|
||||
CompositorBridgeParent::GetIndirectShadowTree(id);
|
||||
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state->mParent);
|
||||
state->mParent->FlushApzRepaints(aLayerTree);
|
||||
state->mParent->FlushApzRepaints(aLayersId);
|
||||
}
|
||||
|
||||
void
|
||||
@ -449,19 +448,18 @@ CrossProcessCompositorBridgeParent::GetAPZTestData(
|
||||
|
||||
void
|
||||
CrossProcessCompositorBridgeParent::SetConfirmedTargetAPZC(
|
||||
const LayerTransactionParent* aLayerTree,
|
||||
const uint64_t& aLayersId,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets)
|
||||
{
|
||||
uint64_t id = aLayerTree->GetId();
|
||||
MOZ_ASSERT(id != 0);
|
||||
MOZ_ASSERT(aLayersId != 0);
|
||||
const CompositorBridgeParent::LayerTreeState* state =
|
||||
CompositorBridgeParent::GetIndirectShadowTree(id);
|
||||
CompositorBridgeParent::GetIndirectShadowTree(aLayersId);
|
||||
if (!state || !state->mParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->mParent->SetConfirmedTargetAPZC(aLayerTree, aInputBlockId, aTargets);
|
||||
state->mParent->SetConfirmedTargetAPZC(aLayersId, aInputBlockId, aTargets);
|
||||
}
|
||||
|
||||
AsyncCompositionManager*
|
||||
|
@ -104,10 +104,10 @@ public:
|
||||
override;
|
||||
virtual CompositorAnimationStorage*
|
||||
GetAnimationStorage(const uint64_t& aId) override;
|
||||
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
|
||||
virtual void FlushApzRepaints(const uint64_t& aLayersId) override;
|
||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData) override;
|
||||
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
virtual void SetConfirmedTargetAPZC(const uint64_t& aLayersId,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets) override;
|
||||
|
||||
|
@ -844,7 +844,7 @@ LayerTransactionParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollID,
|
||||
mozilla::ipc::IPCResult
|
||||
LayerTransactionParent::RecvFlushApzRepaints()
|
||||
{
|
||||
mCompositorBridge->FlushApzRepaints(this);
|
||||
mCompositorBridge->FlushApzRepaints(GetId());
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -866,7 +866,7 @@ mozilla::ipc::IPCResult
|
||||
LayerTransactionParent::RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
|
||||
nsTArray<ScrollableLayerGuid>&& aTargets)
|
||||
{
|
||||
mCompositorBridge->SetConfirmedTargetAPZC(this, aBlockId, aTargets);
|
||||
mCompositorBridge->SetConfirmedTargetAPZC(GetId(), aBlockId, aTargets);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,10 @@ parent:
|
||||
async ReleaseLayer(LayerHandle layer);
|
||||
async ReleaseCompositable(CompositableHandle compositable);
|
||||
|
||||
// Tell the compositor to notify APZ that a layer has been confirmed for an
|
||||
// input event.
|
||||
async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
|
||||
|
||||
// Testing APIs
|
||||
|
||||
// Enter test mode, set the sample time to sampleTime, and resample
|
||||
@ -122,10 +126,6 @@ parent:
|
||||
// Return the TextureFactoryIdentifier for this compositor.
|
||||
sync GetTextureFactoryIdentifier() returns (TextureFactoryIdentifier aIdentifier);
|
||||
|
||||
// Tell the compositor to notify APZ that a layer has been confirmed for an
|
||||
// input event.
|
||||
async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
|
||||
|
||||
async RecordPaintTimes(PaintTiming timing);
|
||||
|
||||
async Shutdown();
|
||||
|
@ -14,6 +14,7 @@ include WebRenderMessages;
|
||||
include protocol PCompositorBridge;
|
||||
include protocol PTexture;
|
||||
|
||||
using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
|
||||
using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
|
||||
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
|
||||
using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
|
||||
@ -67,6 +68,14 @@ parent:
|
||||
// Schedule a composite if one isn't already scheduled.
|
||||
async ForceComposite();
|
||||
|
||||
// These correspond exactly to the equivalent APIs in PLayerTransaction -
|
||||
// see those for documentation.
|
||||
async SetConfirmedTargetAPZC(uint64_t aInputBlockId, ScrollableLayerGuid[] aTargets);
|
||||
// More copied from PLayerTransaction, but these are only used for testing.
|
||||
sync SetAsyncScrollOffset(ViewID scrollId, float x, float y);
|
||||
sync SetAsyncZoom(ViewID scrollId, float zoom);
|
||||
async FlushApzRepaints();
|
||||
|
||||
async Shutdown();
|
||||
child:
|
||||
async __delete__();
|
||||
|
@ -32,12 +32,21 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer,
|
||||
if (!fm.IsScrollable()) {
|
||||
return;
|
||||
}
|
||||
LayoutDeviceRect contentRect = fm.GetExpandedScrollableRect()
|
||||
* fm.GetDevPixelsPerCSSPixel();
|
||||
LayerRect contentRect = ViewAs<LayerPixel>(
|
||||
fm.GetExpandedScrollableRect() * fm.GetDevPixelsPerCSSPixel(),
|
||||
PixelCastJustification::WebRenderHasUnitResolution);
|
||||
// TODO: check coordinate systems are sane here
|
||||
LayerRect clipBounds = ViewAs<LayerPixel>(
|
||||
fm.GetCompositionBounds(),
|
||||
PixelCastJustification::MovingDownToChildren);
|
||||
// The content rect that we hand to PushScrollLayer should be relative to
|
||||
// the same origin as the clipBounds that we hand to PushScrollLayer - that
|
||||
// is, both of them should be relative to the stacking context `aStackingContext`.
|
||||
// However, when we get the scrollable rect from the FrameMetrics, it has
|
||||
// a nominal top-left of 0,0 (maybe different for RTL pages?) and so to
|
||||
// get it in the same coordinate space we're going to shift it by the
|
||||
// composition bounds top-left.
|
||||
contentRect.MoveBy(clipBounds.TopLeft());
|
||||
mBuilder->PushScrollLayer(fm.GetScrollId(),
|
||||
aStackingContext.ToRelativeWrRect(contentRect),
|
||||
aStackingContext.ToRelativeWrRect(clipBounds));
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
|
||||
#include "apz/src/AsyncPanZoomController.h"
|
||||
#include "CompositableHost.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "GLContext.h"
|
||||
@ -275,7 +276,7 @@ WebRenderBridgeParent::RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
uint64_t storageId = mWidget ? 0 : mPipelineId.mHandle;
|
||||
uint64_t storageId = mWidget ? 0 : GetLayersId();
|
||||
CompositorAnimationStorage* storage =
|
||||
mCompositorBridge->GetAnimationStorage(storageId);
|
||||
MOZ_ASSERT(storage);
|
||||
@ -346,9 +347,8 @@ WebRenderBridgeParent::GetRootCompositorBridgeParent() const
|
||||
// Otherwise, this WebRenderBridgeParent is attached to a
|
||||
// CrossProcessCompositorBridgeParent so we have an extra level of
|
||||
// indirection to unravel.
|
||||
uint64_t layersId = wr::AsUint64(mPipelineId);
|
||||
CompositorBridgeParent::LayerTreeState* lts =
|
||||
CompositorBridgeParent::GetIndirectShadowTree(layersId);
|
||||
CompositorBridgeParent::GetIndirectShadowTree(GetLayersId());
|
||||
MOZ_ASSERT(lts);
|
||||
return lts->mParent;
|
||||
}
|
||||
@ -367,7 +367,7 @@ WebRenderBridgeParent::UpdateAPZ()
|
||||
}
|
||||
if (RefPtr<APZCTreeManager> apzc = cbp->GetAPZCTreeManager()) {
|
||||
apzc->UpdateHitTestingTree(rootLayersId, rootWrbp->GetScrollData(),
|
||||
mScrollData.IsFirstPaint(), wr::AsUint64(mPipelineId),
|
||||
mScrollData.IsFirstPaint(), GetLayersId(),
|
||||
/* TODO: propagate paint sequence number */ 0);
|
||||
}
|
||||
}
|
||||
@ -538,7 +538,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
|
||||
const OpAddCompositorAnimations& op = cmd.get_OpAddCompositorAnimations();
|
||||
CompositorAnimations data(Move(op.data()));
|
||||
if (data.animations().Length()) {
|
||||
uint64_t id = mWidget ? 0 : wr::AsUint64(mPipelineId);
|
||||
uint64_t id = mWidget ? 0 : GetLayersId();
|
||||
CompositorAnimationStorage* storage =
|
||||
mCompositorBridge->GetAnimationStorage(id);
|
||||
if (storage) {
|
||||
@ -574,7 +574,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
|
||||
DeleteOldImages();
|
||||
|
||||
if (ShouldParentObserveEpoch()) {
|
||||
mCompositorBridge->ObserveLayerUpdate(wr::AsUint64(mPipelineId), GetChildLayerObserverEpoch(), true);
|
||||
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -712,7 +712,7 @@ WebRenderBridgeParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverE
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvClearCachedResources()
|
||||
{
|
||||
mCompositorBridge->ObserveLayerUpdate(wr::AsUint64(mPipelineId), GetChildLayerObserverEpoch(), false);
|
||||
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), false);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -726,6 +726,58 @@ WebRenderBridgeParent::RecvForceComposite()
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<AsyncPanZoomController>
|
||||
WebRenderBridgeParent::GetTargetAPZC(const FrameMetrics::ViewID& aScrollId)
|
||||
{
|
||||
RefPtr<AsyncPanZoomController> apzc;
|
||||
if (CompositorBridgeParent* cbp = GetRootCompositorBridgeParent()) {
|
||||
if (RefPtr<APZCTreeManager> apzctm = cbp->GetAPZCTreeManager()) {
|
||||
apzc = apzctm->GetTargetAPZC(GetLayersId(), aScrollId);
|
||||
}
|
||||
}
|
||||
return apzc.forget();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
|
||||
nsTArray<ScrollableLayerGuid>&& aTargets)
|
||||
{
|
||||
mCompositorBridge->SetConfirmedTargetAPZC(GetLayersId(), aBlockId, aTargets);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
|
||||
const float& aX,
|
||||
const float& aY)
|
||||
{
|
||||
RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
|
||||
if (!apzc) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
apzc->SetTestAsyncScrollOffset(CSSPoint(aX, aY));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
|
||||
const float& aZoom)
|
||||
{
|
||||
RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aScrollId);
|
||||
if (!apzc) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
apzc->SetTestAsyncZoom(LayerToParentLayerScale(aZoom));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
WebRenderBridgeParent::RecvFlushApzRepaints()
|
||||
{
|
||||
mCompositorBridge->FlushApzRepaints(GetLayersId());
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
@ -736,7 +788,7 @@ void
|
||||
WebRenderBridgeParent::SampleAnimations(nsTArray<WrOpacityProperty>& aOpacityArray,
|
||||
nsTArray<WrTransformProperty>& aTransformArray)
|
||||
{
|
||||
uint64_t id = mWidget ? 0 : wr::AsUint64(mPipelineId);
|
||||
uint64_t id = mWidget ? 0 : GetLayersId();
|
||||
CompositorAnimationStorage* storage =
|
||||
mCompositorBridge->GetAnimationStorage(id);
|
||||
|
||||
@ -862,6 +914,12 @@ WebRenderBridgeParent::~WebRenderBridgeParent()
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t
|
||||
WebRenderBridgeParent::GetLayersId() const
|
||||
{
|
||||
return wr::AsUint64(mPipelineId);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::DeleteOldImages()
|
||||
{
|
||||
|
@ -116,6 +116,15 @@ public:
|
||||
mozilla::ipc::IPCResult RecvClearCachedResources() override;
|
||||
mozilla::ipc::IPCResult RecvForceComposite() override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
|
||||
nsTArray<ScrollableLayerGuid>&& aTargets) override;
|
||||
mozilla::ipc::IPCResult RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aScrollId,
|
||||
const float& aX,
|
||||
const float& aY) override;
|
||||
mozilla::ipc::IPCResult RecvSetAsyncZoom(const FrameMetrics::ViewID& aScrollId,
|
||||
const float& aZoom) override;
|
||||
mozilla::ipc::IPCResult RecvFlushApzRepaints() override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
void SetWebRenderProfilerEnabled(bool aEnabled);
|
||||
|
||||
@ -171,6 +180,7 @@ public:
|
||||
private:
|
||||
virtual ~WebRenderBridgeParent();
|
||||
|
||||
uint64_t GetLayersId() const;
|
||||
void DeleteOldImages();
|
||||
void ProcessWebRenderCommands(const gfx::IntSize &aSize,
|
||||
InfallibleTArray<WebRenderParentCommand>& commands,
|
||||
@ -203,6 +213,10 @@ private:
|
||||
// is populated with the property update details.
|
||||
bool PushAPZStateToWR(nsTArray<WrTransformProperty>& aTransformArray);
|
||||
|
||||
// Helper method to get an APZC reference from a scroll id. Uses the layers
|
||||
// id of this bridge, and may return null if the APZC wasn't found.
|
||||
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const FrameMetrics::ViewID& aId);
|
||||
|
||||
private:
|
||||
struct PendingTransactionId {
|
||||
PendingTransactionId(wr::Epoch aEpoch, uint64_t aId)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "gfxPrefs.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/ImageClient.h"
|
||||
#include "mozilla/layers/ScrollingLayersHelper.h"
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
@ -31,7 +32,6 @@ WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
|
||||
WebRenderImageLayer::~WebRenderImageLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderImageLayer);
|
||||
mPipelineIdRequest.DisconnectIfExists();
|
||||
|
||||
for (auto key : mVideoKeys) {
|
||||
WrManager()->AddImageKeyForDiscard(key);
|
||||
@ -116,24 +116,6 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
|
||||
|
||||
MOZ_ASSERT(GetImageClientType() != CompositableType::UNKNOWN);
|
||||
|
||||
// Allocate PipelineId if necessary
|
||||
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE &&
|
||||
mPipelineId.isNothing() && !mPipelineIdRequest.Exists()) {
|
||||
// Use Holder to pass this pointer to lambda.
|
||||
// Static anaysis tool does not permit to pass refcounted variable to lambda.
|
||||
// And we do not want to use RefPtr<WebRenderImageLayer> here.
|
||||
Holder holder(this);
|
||||
WrManager()->AllocPipelineId()
|
||||
->Then(AbstractThread::MainThread(), __func__,
|
||||
[holder] (const wr::PipelineId& aPipelineId) {
|
||||
holder->mPipelineIdRequest.Complete();
|
||||
holder->mPipelineId = Some(aPipelineId);
|
||||
},
|
||||
[holder] (const ipc::PromiseRejectReason &aReason) {
|
||||
holder->mPipelineIdRequest.Complete();
|
||||
})->Track(mPipelineIdRequest);
|
||||
}
|
||||
|
||||
if (GetImageClientType() == CompositableType::IMAGE && !mImageClient) {
|
||||
mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
|
||||
WrBridge(),
|
||||
@ -148,6 +130,8 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
|
||||
if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
|
||||
MOZ_ASSERT(!mImageClient);
|
||||
mExternalImageId = Some(WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle()));
|
||||
// Alloc async image pipeline id.
|
||||
mPipelineId = Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
|
||||
} else {
|
||||
// Handle CompositableType::IMAGE case
|
||||
MOZ_ASSERT(mImageClient);
|
||||
|
@ -38,16 +38,6 @@ protected:
|
||||
|
||||
void AddWRVideoImage(size_t aChannelNumber);
|
||||
|
||||
class Holder {
|
||||
public:
|
||||
explicit Holder(WebRenderImageLayer* aLayer)
|
||||
: mLayer(aLayer)
|
||||
{}
|
||||
WebRenderImageLayer* operator ->() const { return mLayer; }
|
||||
private:
|
||||
WebRenderImageLayer* mLayer;
|
||||
};
|
||||
|
||||
wr::MaybeExternalImageId mExternalImageId;
|
||||
// Some video image format contains multiple channel data.
|
||||
nsTArray<wr::ImageKey> mVideoKeys;
|
||||
@ -56,7 +46,6 @@ protected:
|
||||
RefPtr<ImageClient> mImageClient;
|
||||
CompositableType mImageClientTypeContainer;
|
||||
Maybe<wr::PipelineId> mPipelineId;
|
||||
MozPromiseRequestHolder<PipelineIdPromise> mPipelineIdRequest;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
@ -493,25 +491,6 @@ WebRenderLayerManager::Composite()
|
||||
WrBridge()->SendForceComposite();
|
||||
}
|
||||
|
||||
RefPtr<PipelineIdPromise>
|
||||
WebRenderLayerManager::AllocPipelineId()
|
||||
{
|
||||
if (XRE_IsParentProcess()) {
|
||||
GPUProcessManager* pm = GPUProcessManager::Get();
|
||||
if (!pm) {
|
||||
return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__);
|
||||
}
|
||||
return PipelineIdPromise::CreateAndResolve(wr::AsPipelineId(pm->AllocateLayerTreeId()), __func__);;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
RefPtr<dom::ContentChild> contentChild = dom::ContentChild::GetSingleton();
|
||||
if (!contentChild) {
|
||||
return PipelineIdPromise::CreateAndReject(ipc::PromiseRejectReason::HandlerRejected, __func__);
|
||||
}
|
||||
return contentChild->SendAllocPipelineId();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderLayerManager::SetRoot(Layer* aLayer)
|
||||
{
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define GFX_WEBRENDERLAYERMANAGER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/layers/TransactionIdAllocator.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
@ -22,8 +21,6 @@ class KnowsCompositor;
|
||||
class PCompositorBridgeChild;
|
||||
class WebRenderBridgeChild;
|
||||
|
||||
typedef MozPromise<mozilla::wr::PipelineId, mozilla::ipc::PromiseRejectReason, false> PipelineIdPromise;
|
||||
|
||||
class WebRenderLayerManager final : public LayerManager
|
||||
{
|
||||
typedef nsTArray<RefPtr<Layer> > LayerRefArray;
|
||||
@ -129,8 +126,6 @@ public:
|
||||
void SetTransactionIncomplete() { mTransactionIncomplete = true; }
|
||||
bool IsMutatedLayer(Layer* aLayer);
|
||||
|
||||
RefPtr<PipelineIdPromise> AllocPipelineId();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Take a snapshot of the parent context, and copy
|
||||
|
@ -25,7 +25,7 @@ gfxQuartzNativeDrawing::BeginNativeDrawing()
|
||||
|
||||
DrawTarget *dt = mDrawTarget;
|
||||
if (dt->IsDualDrawTarget() || dt->IsTiledDrawTarget() ||
|
||||
dt->GetBackendType() != BackendType::SKIA) {
|
||||
dt->GetBackendType() != BackendType::SKIA || dt->IsRecording()) {
|
||||
// We need a DrawTarget that we can get a CGContextRef from:
|
||||
Matrix transform = dt->GetTransform();
|
||||
|
||||
|
@ -34,6 +34,7 @@ plane-split = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
angle = {git = "https://github.com/servo/angle", branch = "servo"}
|
||||
rand = "0.3" # for the benchmarks
|
||||
servo-glutin = "0.10.1" # for the example apps
|
||||
|
||||
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
|
||||
|
23
gfx/webrender/benches/coalesce.rs
Normal file
23
gfx/webrender/benches/coalesce.rs
Normal file
@ -0,0 +1,23 @@
|
||||
#![feature(test)]
|
||||
|
||||
extern crate rand;
|
||||
extern crate test;
|
||||
extern crate webrender;
|
||||
extern crate webrender_traits;
|
||||
|
||||
use rand::Rng;
|
||||
use test::Bencher;
|
||||
use webrender::TexturePage;
|
||||
use webrender_traits::{DeviceUintSize as Size};
|
||||
|
||||
#[bench]
|
||||
fn bench_coalesce(b: &mut Bencher) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut page = TexturePage::new_dummy(Size::new(10000, 10000));
|
||||
let mut test_page = TexturePage::new_dummy(Size::new(10000, 10000));
|
||||
while page.allocate(&Size::new(rng.gen_range(1, 100), rng.gen_range(1, 100))).is_some() {}
|
||||
b.iter(|| {
|
||||
test_page.fill_from(&page);
|
||||
test_page.coalesce();
|
||||
});
|
||||
}
|
@ -4,9 +4,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
void main(void) {
|
||||
CachePrimitiveInstance cpi = fetch_cache_instance();
|
||||
RenderTaskData task = fetch_render_task(cpi.render_task_index);
|
||||
BoxShadow bs = fetch_boxshadow(cpi.specific_prim_index);
|
||||
PrimitiveInstance pi = fetch_prim_instance();
|
||||
RenderTaskData task = fetch_render_task(pi.render_task_index);
|
||||
BoxShadow bs = fetch_boxshadow(pi.specific_prim_address);
|
||||
|
||||
vec2 p0 = task.data0.xy;
|
||||
vec2 p1 = p0 + task.data0.zw;
|
||||
|
@ -8,12 +8,12 @@
|
||||
// as text-shadow.
|
||||
|
||||
void main(void) {
|
||||
CachePrimitiveInstance cpi = fetch_cache_instance();
|
||||
RenderTaskData task = fetch_render_task(cpi.render_task_index);
|
||||
TextRun text = fetch_text_run(cpi.specific_prim_index);
|
||||
Glyph glyph = fetch_glyph(cpi.sub_index);
|
||||
PrimitiveGeometry pg = fetch_prim_geometry(cpi.global_prim_index);
|
||||
ResourceRect res = fetch_resource_rect(cpi.user_data.x);
|
||||
PrimitiveInstance pi = fetch_prim_instance();
|
||||
RenderTaskData task = fetch_render_task(pi.render_task_index);
|
||||
TextRun text = fetch_text_run(pi.specific_prim_address);
|
||||
Glyph glyph = fetch_glyph(pi.user_data0);
|
||||
PrimitiveGeometry pg = fetch_prim_geometry(pi.global_prim_index);
|
||||
ResourceRect res = fetch_resource_rect(pi.user_data1);
|
||||
|
||||
// Glyphs size is already in device-pixels.
|
||||
// The render task origin is in device-pixels. Offset that by
|
||||
|
@ -117,7 +117,7 @@ varying vec3 vClipMaskUv;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
#define VECS_PER_LAYER 13
|
||||
#define VECS_PER_LAYER 9
|
||||
#define VECS_PER_RENDER_TASK 3
|
||||
#define VECS_PER_PRIM_GEOM 2
|
||||
#define VECS_PER_SPLIT_GEOM 3
|
||||
@ -133,14 +133,8 @@ uniform sampler2D sData128;
|
||||
uniform sampler2D sResourceRects;
|
||||
|
||||
// Instanced attributes
|
||||
in int aGlobalPrimId;
|
||||
in int aPrimitiveAddress;
|
||||
in int aTaskIndex;
|
||||
in int aClipTaskIndex;
|
||||
in int aLayerIndex;
|
||||
in int aElementIndex;
|
||||
in ivec2 aUserData;
|
||||
in int aZIndex;
|
||||
in ivec4 aData0;
|
||||
in ivec4 aData1;
|
||||
|
||||
// get_fetch_uv is a macro to work around a macOS Intel driver parsing bug.
|
||||
// TODO: convert back to a function once the driver issues are resolved, if ever.
|
||||
@ -190,7 +184,6 @@ struct Layer {
|
||||
mat4 transform;
|
||||
mat4 inv_transform;
|
||||
RectWithSize local_clip_rect;
|
||||
vec4 screen_vertices[4];
|
||||
};
|
||||
|
||||
Layer fetch_layer(int index) {
|
||||
@ -217,11 +210,6 @@ Layer fetch_layer(int index) {
|
||||
vec4 clip_rect = texelFetchOffset(sLayers, uv1, 0, ivec2(0, 0));
|
||||
layer.local_clip_rect = RectWithSize(clip_rect.xy, clip_rect.zw);
|
||||
|
||||
layer.screen_vertices[0] = texelFetchOffset(sLayers, uv1, 0, ivec2(1, 0));
|
||||
layer.screen_vertices[1] = texelFetchOffset(sLayers, uv1, 0, ivec2(2, 0));
|
||||
layer.screen_vertices[2] = texelFetchOffset(sLayers, uv1, 0, ivec2(3, 0));
|
||||
layer.screen_vertices[3] = texelFetchOffset(sLayers, uv1, 0, ivec2(4, 0));
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
@ -447,50 +435,51 @@ PrimitiveGeometry fetch_prim_geometry(int index) {
|
||||
|
||||
struct PrimitiveInstance {
|
||||
int global_prim_index;
|
||||
int specific_prim_index;
|
||||
int specific_prim_address;
|
||||
int render_task_index;
|
||||
int clip_task_index;
|
||||
int layer_index;
|
||||
int sub_index;
|
||||
int z;
|
||||
ivec2 user_data;
|
||||
int user_data0;
|
||||
int user_data1;
|
||||
};
|
||||
|
||||
PrimitiveInstance fetch_prim_instance() {
|
||||
PrimitiveInstance pi;
|
||||
|
||||
pi.global_prim_index = aGlobalPrimId;
|
||||
pi.specific_prim_index = aPrimitiveAddress;
|
||||
pi.render_task_index = aTaskIndex;
|
||||
pi.clip_task_index = aClipTaskIndex;
|
||||
pi.layer_index = aLayerIndex;
|
||||
pi.sub_index = aElementIndex;
|
||||
pi.user_data = aUserData;
|
||||
pi.z = aZIndex;
|
||||
pi.global_prim_index = aData0.x;
|
||||
pi.specific_prim_address = aData0.y;
|
||||
pi.render_task_index = aData0.z;
|
||||
pi.clip_task_index = aData0.w;
|
||||
pi.layer_index = aData1.x;
|
||||
pi.z = aData1.y;
|
||||
pi.user_data0 = aData1.z;
|
||||
pi.user_data1 = aData1.w;
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
struct CachePrimitiveInstance {
|
||||
int global_prim_index;
|
||||
int specific_prim_index;
|
||||
struct CompositeInstance {
|
||||
int render_task_index;
|
||||
int sub_index;
|
||||
ivec2 user_data;
|
||||
int src_task_index;
|
||||
int backdrop_task_index;
|
||||
int user_data0;
|
||||
int user_data1;
|
||||
float z;
|
||||
};
|
||||
|
||||
CachePrimitiveInstance fetch_cache_instance() {
|
||||
CachePrimitiveInstance cpi;
|
||||
CompositeInstance fetch_composite_instance() {
|
||||
CompositeInstance ci;
|
||||
|
||||
PrimitiveInstance pi = fetch_prim_instance();
|
||||
ci.render_task_index = aData0.x;
|
||||
ci.src_task_index = aData0.y;
|
||||
ci.backdrop_task_index = aData0.z;
|
||||
ci.z = float(aData0.w);
|
||||
|
||||
cpi.global_prim_index = pi.global_prim_index;
|
||||
cpi.specific_prim_index = pi.specific_prim_index;
|
||||
cpi.render_task_index = pi.render_task_index;
|
||||
cpi.sub_index = pi.sub_index;
|
||||
cpi.user_data = pi.user_data;
|
||||
ci.user_data0 = aData1.x;
|
||||
ci.user_data1 = aData1.y;
|
||||
|
||||
return cpi;
|
||||
return ci;
|
||||
}
|
||||
|
||||
struct Primitive {
|
||||
@ -500,10 +489,8 @@ struct Primitive {
|
||||
RectWithSize local_rect;
|
||||
RectWithSize local_clip_rect;
|
||||
int prim_index;
|
||||
// when sending multiple primitives of the same type (e.g. border segments)
|
||||
// this index allows the vertex shader to recognize the difference
|
||||
int sub_index;
|
||||
ivec2 user_data;
|
||||
int user_data0;
|
||||
int user_data1;
|
||||
float z;
|
||||
};
|
||||
|
||||
@ -518,9 +505,9 @@ Primitive load_primitive_custom(PrimitiveInstance pi) {
|
||||
prim.local_rect = pg.local_rect;
|
||||
prim.local_clip_rect = pg.local_clip_rect;
|
||||
|
||||
prim.prim_index = pi.specific_prim_index;
|
||||
prim.sub_index = pi.sub_index;
|
||||
prim.user_data = pi.user_data;
|
||||
prim.prim_index = pi.specific_prim_address;
|
||||
prim.user_data0 = pi.user_data0;
|
||||
prim.user_data1 = pi.user_data1;
|
||||
prim.z = float(pi.z);
|
||||
|
||||
return prim;
|
||||
@ -539,7 +526,7 @@ Primitive load_primitive() {
|
||||
bool ray_plane(vec3 normal, vec3 point, vec3 ray_origin, vec3 ray_dir, out float t)
|
||||
{
|
||||
float denom = dot(normal, ray_dir);
|
||||
if (denom > 1e-6) {
|
||||
if (abs(denom) > 1e-6) {
|
||||
vec3 d = point - ray_origin;
|
||||
t = dot(d, normal) / denom;
|
||||
return t >= 0.0;
|
||||
@ -568,12 +555,11 @@ vec4 untransform(vec2 ref, vec3 n, vec3 a, mat4 inv_transform) {
|
||||
|
||||
// Given a CSS space position, transform it back into the layer space.
|
||||
vec4 get_layer_pos(vec2 pos, Layer layer) {
|
||||
// get 3 of the layer corners in CSS space
|
||||
vec3 a = layer.screen_vertices[0].xyz / layer.screen_vertices[0].w;
|
||||
vec3 b = layer.screen_vertices[3].xyz / layer.screen_vertices[3].w;
|
||||
vec3 c = layer.screen_vertices[2].xyz / layer.screen_vertices[2].w;
|
||||
// get a point on the layer plane
|
||||
vec4 ah = layer.transform * vec4(0.0, 0.0, 0.0, 1.0);
|
||||
vec3 a = ah.xyz / ah.w;
|
||||
// get the normal to the layer plane
|
||||
vec3 n = normalize(cross(b-a, c-a));
|
||||
vec3 n = transpose(mat3(layer.inv_transform)) * vec3(0.0, 0.0, 1.0);
|
||||
return untransform(pos, n, a, layer.inv_transform);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main(void) {
|
||||
vTileRepeat = gradient.tile_size_repeat.zw;
|
||||
|
||||
// V coordinate of gradient row in lookup texture.
|
||||
vGradientIndex = float(prim.sub_index);
|
||||
vGradientIndex = float(prim.user_data0);
|
||||
|
||||
// The texture size of the lookup texture
|
||||
vGradientTextureSize = vec2(textureSize(sGradients, 0));
|
||||
|
@ -4,9 +4,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
void main(void) {
|
||||
PrimitiveInstance pi = fetch_prim_instance();
|
||||
AlphaBatchTask dest_task = fetch_alpha_batch_task(pi.render_task_index);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.x);
|
||||
CompositeInstance ci = fetch_composite_instance();
|
||||
AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
|
||||
|
||||
vec2 dest_origin = dest_task.render_target_origin -
|
||||
dest_task.screen_space_origin +
|
||||
@ -24,8 +24,8 @@ void main(void) {
|
||||
vUv = vec3(uv / texture_size, src_task.render_target_layer_index);
|
||||
vUvBounds = vec4(st0 + 0.5, st1 - 0.5) / texture_size.xyxy;
|
||||
|
||||
vOp = pi.sub_index;
|
||||
vAmount = float(pi.user_data.y) / 65535.0;
|
||||
vOp = ci.user_data0;
|
||||
vAmount = float(ci.user_data1) / 65535.0;
|
||||
|
||||
gl_Position = uTransform * vec4(local_pos, pi.z, 1.0);
|
||||
gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ int select_style(int color_select, vec2 fstyle) {
|
||||
|
||||
switch (color_select) {
|
||||
case SIDE_BOTH:
|
||||
{
|
||||
// TODO(gw): A temporary hack! While we don't support
|
||||
// border corners that have dots or dashes
|
||||
// with another style, pretend they are solid
|
||||
@ -102,6 +103,7 @@ int select_style(int color_select, vec2 fstyle) {
|
||||
if (style.x != style.y && (has_dots || has_dashes))
|
||||
return BORDER_STYLE_SOLID;
|
||||
return style.x;
|
||||
}
|
||||
case SIDE_FIRST:
|
||||
return style.x;
|
||||
case SIDE_SECOND:
|
||||
@ -112,7 +114,7 @@ int select_style(int color_select, vec2 fstyle) {
|
||||
void main(void) {
|
||||
Primitive prim = load_primitive();
|
||||
Border border = fetch_border(prim.prim_index);
|
||||
int sub_part = prim.sub_index;
|
||||
int sub_part = prim.user_data0;
|
||||
BorderCorners corners = get_border_corners(border, prim.local_rect);
|
||||
|
||||
vec2 p0, p1;
|
||||
@ -135,7 +137,7 @@ void main(void) {
|
||||
color1 = border.colors[1];
|
||||
vClipCenter = corners.tl_outer + border.radii[0].xy;
|
||||
vClipSign = vec2(1.0);
|
||||
style = select_style(prim.user_data.x, border.style.yx);
|
||||
style = select_style(prim.user_data1, border.style.yx);
|
||||
vec4 adjusted_widths = get_effective_border_widths(border, style);
|
||||
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
|
||||
set_radii(style,
|
||||
@ -157,7 +159,7 @@ void main(void) {
|
||||
color1 = border.colors[2];
|
||||
vClipCenter = corners.tr_outer + vec2(-border.radii[0].z, border.radii[0].w);
|
||||
vClipSign = vec2(-1.0, 1.0);
|
||||
style = select_style(prim.user_data.x, border.style.zy);
|
||||
style = select_style(prim.user_data1, border.style.zy);
|
||||
vec4 adjusted_widths = get_effective_border_widths(border, style);
|
||||
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
|
||||
set_radii(style,
|
||||
@ -181,7 +183,7 @@ void main(void) {
|
||||
color1 = border.colors[3];
|
||||
vClipCenter = corners.br_outer - border.radii[1].xy;
|
||||
vClipSign = vec2(-1.0, -1.0);
|
||||
style = select_style(prim.user_data.x, border.style.wz);
|
||||
style = select_style(prim.user_data1, border.style.wz);
|
||||
vec4 adjusted_widths = get_effective_border_widths(border, style);
|
||||
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
|
||||
set_radii(style,
|
||||
@ -205,7 +207,7 @@ void main(void) {
|
||||
color1 = border.colors[0];
|
||||
vClipCenter = corners.bl_outer + vec2(border.radii[1].z, -border.radii[1].w);
|
||||
vClipSign = vec2(1.0, -1.0);
|
||||
style = select_style(prim.user_data.x, border.style.xw);
|
||||
style = select_style(prim.user_data1, border.style.xw);
|
||||
vec4 adjusted_widths = get_effective_border_widths(border, style);
|
||||
vec4 inv_adjusted_widths = border.widths - adjusted_widths;
|
||||
set_radii(style,
|
||||
@ -253,7 +255,7 @@ void main(void) {
|
||||
}
|
||||
}
|
||||
|
||||
write_color(color0, color1, style, color_delta, prim.user_data.x);
|
||||
write_color(color0, color1, style, color_delta, prim.user_data1);
|
||||
|
||||
RectWithSize segment_rect;
|
||||
segment_rect.p0 = p0;
|
||||
|
@ -42,11 +42,15 @@ void write_color(vec4 color, float style, bool flip) {
|
||||
|
||||
switch (int(style)) {
|
||||
case BORDER_STYLE_GROOVE:
|
||||
{
|
||||
modulate = flip ? vec2(1.3, 0.7) : vec2(0.7, 1.3);
|
||||
break;
|
||||
}
|
||||
case BORDER_STYLE_RIDGE:
|
||||
{
|
||||
modulate = flip ? vec2(0.7, 1.3) : vec2(1.3, 0.7);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
modulate = vec2(1.0);
|
||||
break;
|
||||
@ -101,7 +105,7 @@ void write_clip_params(float style,
|
||||
void main(void) {
|
||||
Primitive prim = load_primitive();
|
||||
Border border = fetch_border(prim.prim_index);
|
||||
int sub_part = prim.sub_index;
|
||||
int sub_part = prim.user_data0;
|
||||
BorderCorners corners = get_border_corners(border, prim.local_rect);
|
||||
vec4 color = border.colors[sub_part];
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
void main(void) {
|
||||
Primitive prim = load_primitive();
|
||||
BoxShadow bs = fetch_boxshadow(prim.prim_index);
|
||||
RectWithSize segment_rect = fetch_instance_geometry(prim.sub_index);
|
||||
RectWithSize segment_rect = fetch_instance_geometry(prim.user_data0);
|
||||
|
||||
VertexInfo vi = write_vertex(segment_rect,
|
||||
prim.local_clip_rect,
|
||||
@ -15,7 +15,7 @@ void main(void) {
|
||||
prim.task,
|
||||
prim.local_rect.p0);
|
||||
|
||||
RenderTaskData child_task = fetch_render_task(prim.user_data.x);
|
||||
RenderTaskData child_task = fetch_render_task(prim.user_data1);
|
||||
vUv.z = child_task.data1.x;
|
||||
|
||||
// Constant offsets to inset from bilinear filtering border.
|
||||
|
@ -16,7 +16,7 @@ void main(void) {
|
||||
prim.task,
|
||||
prim.local_rect.p0);
|
||||
|
||||
RenderTaskData child_task = fetch_render_task(prim.user_data.x);
|
||||
RenderTaskData child_task = fetch_render_task(prim.user_data1);
|
||||
vUv.z = child_task.data1.x;
|
||||
|
||||
vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
|
||||
|
@ -4,10 +4,10 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
void main(void) {
|
||||
PrimitiveInstance pi = fetch_prim_instance();
|
||||
AlphaBatchTask dest_task = fetch_alpha_batch_task(pi.render_task_index);
|
||||
ReadbackTask backdrop_task = fetch_readback_task(pi.user_data.x);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.y);
|
||||
CompositeInstance ci = fetch_composite_instance();
|
||||
AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
|
||||
ReadbackTask backdrop_task = fetch_readback_task(ci.backdrop_task_index);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
|
||||
|
||||
vec2 dest_origin = dest_task.render_target_origin -
|
||||
dest_task.screen_space_origin +
|
||||
@ -27,8 +27,7 @@ void main(void) {
|
||||
st1 = (src_task.render_target_origin + src_task.size) / texture_size;
|
||||
vUv1 = vec3(mix(st0, st1, aPosition.xy), src_task.render_target_layer_index);
|
||||
|
||||
vOp = pi.sub_index;
|
||||
|
||||
gl_Position = uTransform * vec4(local_pos, pi.z, 1.0);
|
||||
vOp = ci.user_data0;
|
||||
|
||||
gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ void main(void) {
|
||||
|
||||
vec4 abs_start_end_point = gradient.start_end_point + prim.local_rect.p0.xyxy;
|
||||
|
||||
GradientStop g0 = fetch_gradient_stop(prim.sub_index + 0);
|
||||
GradientStop g1 = fetch_gradient_stop(prim.sub_index + 1);
|
||||
GradientStop g0 = fetch_gradient_stop(prim.user_data0 + 0);
|
||||
GradientStop g1 = fetch_gradient_stop(prim.user_data0 + 1);
|
||||
|
||||
RectWithSize segment_rect;
|
||||
vec2 axis;
|
||||
|
@ -4,9 +4,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
void main(void) {
|
||||
PrimitiveInstance pi = fetch_prim_instance();
|
||||
AlphaBatchTask dest_task = fetch_alpha_batch_task(pi.render_task_index);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.x);
|
||||
CompositeInstance ci = fetch_composite_instance();
|
||||
AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
|
||||
|
||||
vec2 dest_origin = dest_task.render_target_origin -
|
||||
dest_task.screen_space_origin +
|
||||
@ -21,5 +21,5 @@ void main(void) {
|
||||
vec2 st1 = (src_task.render_target_origin + src_task.size) / texture_size;
|
||||
vUv = vec3(mix(st0, st1, aPosition.xy), src_task.render_target_layer_index);
|
||||
|
||||
gl_Position = uTransform * vec4(local_pos, pi.z, 1.0);
|
||||
gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
void main(void) {
|
||||
Primitive prim = load_primitive();
|
||||
Image image = fetch_image(prim.prim_index);
|
||||
ResourceRect res = fetch_resource_rect(prim.user_data.x);
|
||||
ResourceRect res = fetch_resource_rect(prim.user_data0);
|
||||
|
||||
#ifdef WR_FEATURE_TRANSFORM
|
||||
TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
|
||||
|
@ -35,7 +35,7 @@ void main(void) {
|
||||
vTileRepeat.y *= ratio_xy;
|
||||
|
||||
// V coordinate of gradient row in lookup texture.
|
||||
vGradientIndex = float(prim.sub_index);
|
||||
vGradientIndex = float(prim.user_data0);
|
||||
|
||||
// The texture size of the lookup texture
|
||||
vGradientTextureSize = vec2(textureSize(sGradients, 0));
|
||||
|
@ -31,14 +31,14 @@ vec3 bilerp(vec3 a, vec3 b, vec3 c, vec3 d, float s, float t) {
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
PrimitiveInstance pi = fetch_prim_instance();
|
||||
SplitGeometry geometry = fetch_split_geometry(pi.specific_prim_index);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(pi.user_data.x);
|
||||
CompositeInstance ci = fetch_composite_instance();
|
||||
SplitGeometry geometry = fetch_split_geometry(ci.user_data0);
|
||||
AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
|
||||
|
||||
vec3 world_pos = bilerp(geometry.points[0], geometry.points[1],
|
||||
geometry.points[3], geometry.points[2],
|
||||
aPosition.y, aPosition.x);
|
||||
vec4 final_pos = vec4(world_pos.xy * uDevicePixelRatio, pi.z, 1.0);
|
||||
vec4 final_pos = vec4(world_pos.xy * uDevicePixelRatio, ci.z, 1.0);
|
||||
|
||||
gl_Position = uTransform * final_pos;
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
void main(void) {
|
||||
Primitive prim = load_primitive();
|
||||
TextRun text = fetch_text_run(prim.prim_index);
|
||||
Glyph glyph = fetch_glyph(prim.sub_index);
|
||||
ResourceRect res = fetch_resource_rect(prim.user_data.x);
|
||||
Glyph glyph = fetch_glyph(prim.user_data0);
|
||||
ResourceRect res = fetch_resource_rect(prim.user_data1);
|
||||
|
||||
RectWithSize local_rect = RectWithSize(glyph.offset.xy,
|
||||
(res.uv_rect.zw - res.uv_rect.xy) / uDevicePixelRatio);
|
||||
|
@ -25,11 +25,11 @@ void main(void) {
|
||||
|
||||
write_clip(vi.screen_pos, prim.clip_area);
|
||||
|
||||
ResourceRect y_rect = fetch_resource_rect(prim.user_data.x);
|
||||
ResourceRect y_rect = fetch_resource_rect(prim.user_data0);
|
||||
#ifndef WR_FEATURE_INTERLEAVED_Y_CB_CR // only 1 channel
|
||||
ResourceRect u_rect = fetch_resource_rect(prim.user_data.x + 1);
|
||||
ResourceRect u_rect = fetch_resource_rect(prim.user_data0 + 1);
|
||||
#ifndef WR_FEATURE_NV12 // 2 channel
|
||||
ResourceRect v_rect = fetch_resource_rect(prim.user_data.x + 2);
|
||||
ResourceRect v_rect = fetch_resource_rect(prim.user_data0 + 2);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -6,7 +6,7 @@ use euclid::Matrix4D;
|
||||
use fnv::FnvHasher;
|
||||
use gleam::gl;
|
||||
use internal_types::{PackedVertex, RenderTargetMode, TextureSampler, DEFAULT_TEXTURE};
|
||||
use internal_types::{BlurAttribute, ClearAttribute, ClipAttribute, VertexAttribute};
|
||||
use internal_types::{BlurAttribute, ClipAttribute, VertexAttribute};
|
||||
use internal_types::{DebugFontVertex, DebugColorVertex};
|
||||
//use notify::{self, Watcher};
|
||||
use super::shader_source;
|
||||
@ -76,10 +76,8 @@ pub enum TextureFilter {
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum VertexFormat {
|
||||
Triangles,
|
||||
Rectangles,
|
||||
DebugFont,
|
||||
DebugColor,
|
||||
Clear,
|
||||
Blur,
|
||||
Clip,
|
||||
}
|
||||
@ -89,7 +87,7 @@ enum FBOTarget {
|
||||
Draw,
|
||||
}
|
||||
|
||||
fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
|
||||
pub fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
|
||||
match gl.get_type() {
|
||||
gl::GlType::Gl => {
|
||||
GL_FORMAT_BGRA_GL
|
||||
@ -190,7 +188,6 @@ impl VertexFormat {
|
||||
vertex_stride as gl::GLint,
|
||||
8 + vertex_stride * offset);
|
||||
}
|
||||
VertexFormat::Rectangles |
|
||||
VertexFormat::Triangles => {
|
||||
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
|
||||
gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
|
||||
@ -206,53 +203,18 @@ impl VertexFormat {
|
||||
instance.bind(gl);
|
||||
let mut offset = 0;
|
||||
|
||||
for &attrib in [VertexAttribute::GlobalPrimId,
|
||||
VertexAttribute::PrimitiveAddress,
|
||||
VertexAttribute::TaskIndex,
|
||||
VertexAttribute::ClipTaskIndex,
|
||||
VertexAttribute::LayerIndex,
|
||||
VertexAttribute::ElementIndex,
|
||||
VertexAttribute::ZIndex,
|
||||
for &attrib in [VertexAttribute::Data0,
|
||||
VertexAttribute::Data1,
|
||||
].into_iter() {
|
||||
gl.enable_vertex_attrib_array(attrib as gl::GLuint);
|
||||
gl.vertex_attrib_divisor(attrib as gl::GLuint, 1);
|
||||
gl.vertex_attrib_i_pointer(attrib as gl::GLuint,
|
||||
1,
|
||||
4,
|
||||
gl::INT,
|
||||
instance_stride,
|
||||
offset);
|
||||
offset += 4;
|
||||
offset += 16;
|
||||
}
|
||||
|
||||
gl.enable_vertex_attrib_array(VertexAttribute::UserData as gl::GLuint);
|
||||
gl.vertex_attrib_divisor(VertexAttribute::UserData as gl::GLuint, 1);
|
||||
gl.vertex_attrib_i_pointer(VertexAttribute::UserData as gl::GLuint,
|
||||
2,
|
||||
gl::INT,
|
||||
instance_stride,
|
||||
offset);
|
||||
}
|
||||
VertexFormat::Clear => {
|
||||
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
|
||||
gl.enable_vertex_attrib_array(ClearAttribute::Position as gl::GLuint);
|
||||
gl.vertex_attrib_divisor(ClearAttribute::Position as gl::GLuint, 0);
|
||||
|
||||
gl.vertex_attrib_pointer(ClearAttribute::Position as gl::GLuint,
|
||||
2,
|
||||
gl::FLOAT,
|
||||
false,
|
||||
vertex_stride as gl::GLint,
|
||||
0);
|
||||
|
||||
instance.bind(gl);
|
||||
|
||||
gl.enable_vertex_attrib_array(ClearAttribute::Rectangle as gl::GLuint);
|
||||
gl.vertex_attrib_divisor(ClearAttribute::Rectangle as gl::GLuint, 1);
|
||||
gl.vertex_attrib_i_pointer(ClearAttribute::Rectangle as gl::GLuint,
|
||||
4,
|
||||
gl::INT,
|
||||
instance_stride,
|
||||
0);
|
||||
}
|
||||
VertexFormat::Blur => {
|
||||
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
|
||||
@ -412,24 +374,15 @@ impl Program {
|
||||
self.gl.attach_shader(self.id, fs_id);
|
||||
|
||||
match vertex_format {
|
||||
VertexFormat::Triangles | VertexFormat::Rectangles |
|
||||
VertexFormat::DebugFont | VertexFormat::DebugColor => {
|
||||
VertexFormat::Triangles |
|
||||
VertexFormat::DebugFont |
|
||||
VertexFormat::DebugColor => {
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::Position as gl::GLuint, "aPosition");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::Color as gl::GLuint, "aColor");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::ColorTexCoord as gl::GLuint, "aColorTexCoord");
|
||||
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::GlobalPrimId as gl::GLuint, "aGlobalPrimId");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::PrimitiveAddress as gl::GLuint, "aPrimitiveAddress");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::TaskIndex as gl::GLuint, "aTaskIndex");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::ClipTaskIndex as gl::GLuint, "aClipTaskIndex");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::LayerIndex as gl::GLuint, "aLayerIndex");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::ElementIndex as gl::GLuint, "aElementIndex");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::UserData as gl::GLuint, "aUserData");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::ZIndex as gl::GLuint, "aZIndex");
|
||||
}
|
||||
VertexFormat::Clear => {
|
||||
self.gl.bind_attrib_location(self.id, ClearAttribute::Position as gl::GLuint, "aPosition");
|
||||
self.gl.bind_attrib_location(self.id, ClearAttribute::Rectangle as gl::GLuint, "aClearRectangle");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::Data0 as gl::GLuint, "aData0");
|
||||
self.gl.bind_attrib_location(self.id, VertexAttribute::Data1 as gl::GLuint, "aData1");
|
||||
}
|
||||
VertexFormat::Blur => {
|
||||
self.gl.bind_attrib_location(self.id, BlurAttribute::Position as gl::GLuint, "aPosition");
|
||||
|
@ -118,22 +118,8 @@ pub enum VertexAttribute {
|
||||
Color,
|
||||
ColorTexCoord,
|
||||
// instance-frequency primitive attributes
|
||||
GlobalPrimId,
|
||||
PrimitiveAddress,
|
||||
TaskIndex,
|
||||
ClipTaskIndex,
|
||||
LayerIndex,
|
||||
ElementIndex,
|
||||
UserData,
|
||||
ZIndex,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum ClearAttribute {
|
||||
// vertex frequency
|
||||
Position,
|
||||
// instance frequency
|
||||
Rectangle,
|
||||
Data0,
|
||||
Data1,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -73,6 +73,9 @@ mod texture_cache;
|
||||
mod tiling;
|
||||
mod util;
|
||||
|
||||
#[doc(hidden)] // for benchmarks
|
||||
pub use texture_cache::TexturePage;
|
||||
|
||||
#[cfg(feature = "webgl")]
|
||||
mod webgl_types;
|
||||
|
||||
@ -140,4 +143,4 @@ extern crate plane_split;
|
||||
extern crate gamma_lut;
|
||||
|
||||
pub use renderer::{ExternalImage, ExternalImageSource, ExternalImageHandler};
|
||||
pub use renderer::{Renderer, RendererOptions};
|
||||
pub use renderer::{GraphicsApi, GraphicsApiInfo, ReadPixelsFormat, Renderer, RendererOptions};
|
||||
|
@ -13,6 +13,7 @@ use debug_colors;
|
||||
use debug_render::DebugRenderer;
|
||||
use device::{DepthFunction, Device, FrameId, ProgramId, TextureId, VertexFormat, GpuMarker, GpuProfiler};
|
||||
use device::{GpuSample, TextureFilter, VAOId, VertexUsageHint, FileWatcherHandler, TextureTarget, ShaderError};
|
||||
use device::get_gl_format_bgra;
|
||||
use euclid::Matrix4D;
|
||||
use fnv::FnvHasher;
|
||||
use frame_builder::FrameBuilderConfig;
|
||||
@ -43,7 +44,7 @@ use std::thread;
|
||||
use texture_cache::TextureCache;
|
||||
use rayon::ThreadPool;
|
||||
use rayon::Configuration as ThreadPoolConfig;
|
||||
use tiling::{AlphaBatchKind, BlurCommand, Frame, PrimitiveBatch, RenderTarget};
|
||||
use tiling::{AlphaBatchKind, BlurCommand, CompositePrimitiveInstance, Frame, PrimitiveBatch, RenderTarget};
|
||||
use tiling::{AlphaRenderTarget, CacheClipInstance, PrimitiveInstance, ColorRenderTarget, RenderTargetKind};
|
||||
use time::precise_time_ns;
|
||||
use thread_profiler::{register_thread_with_profiler, write_profile};
|
||||
@ -51,7 +52,7 @@ use util::TransformedRectKind;
|
||||
use webgl_types::GLContextHandleWrapper;
|
||||
use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher};
|
||||
use webrender_traits::{ExternalImageId, ExternalImageType, ImageData, ImageFormat, RenderApiSender};
|
||||
use webrender_traits::{DeviceIntRect, DevicePoint, DeviceIntPoint, DeviceIntSize, DeviceUintSize};
|
||||
use webrender_traits::{DeviceIntRect, DeviceUintRect, DevicePoint, DeviceIntPoint, DeviceIntSize, DeviceUintSize};
|
||||
use webrender_traits::{ImageDescriptor, BlobImageRenderer};
|
||||
use webrender_traits::{channel, FontRenderMode};
|
||||
use webrender_traits::VRCompositorHandler;
|
||||
@ -83,6 +84,18 @@ const GPU_TAG_PRIM_BORDER_EDGE: GpuProfileTag = GpuProfileTag { label: "BorderEd
|
||||
const GPU_TAG_PRIM_CACHE_IMAGE: GpuProfileTag = GpuProfileTag { label: "CacheImage", color: debug_colors::SILVER };
|
||||
const GPU_TAG_BLUR: GpuProfileTag = GpuProfileTag { label: "Blur", color: debug_colors::VIOLET };
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GraphicsApi {
|
||||
OpenGL,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GraphicsApiInfo {
|
||||
pub kind: GraphicsApi,
|
||||
pub renderer: String,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum ImageBufferKind {
|
||||
Texture2D = 0,
|
||||
@ -502,6 +515,12 @@ impl GpuDataTextures {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ReadPixelsFormat {
|
||||
Rgba8,
|
||||
Bgra8,
|
||||
}
|
||||
|
||||
/// The renderer is responsible for submitting to the GPU the work prepared by the
|
||||
/// RenderBackend.
|
||||
pub struct Renderer {
|
||||
@ -1136,12 +1155,16 @@ impl Renderer {
|
||||
Ok((renderer, sender))
|
||||
}
|
||||
|
||||
fn get_yuv_shader_index(buffer_kind: ImageBufferKind, format: YuvFormat, color_space: YuvColorSpace) -> usize {
|
||||
((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() + (color_space as usize)
|
||||
pub fn get_graphics_api_info(&self) -> GraphicsApiInfo {
|
||||
GraphicsApiInfo {
|
||||
kind: GraphicsApi::OpenGL,
|
||||
version: self.device.gl().get_string(gl::VERSION),
|
||||
renderer: self.device.gl().get_string(gl::RENDERER),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gl(&self) -> &gl::Gl {
|
||||
self.device.gl()
|
||||
fn get_yuv_shader_index(buffer_kind: ImageBufferKind, format: YuvFormat, color_space: YuvColorSpace) -> usize {
|
||||
((buffer_kind as usize) * YUV_FORMATS.len() + (format as usize)) * YUV_COLOR_SPACES.len() + (color_space as usize)
|
||||
}
|
||||
|
||||
/// Sets the new RenderNotifier.
|
||||
@ -1505,8 +1528,12 @@ impl Renderer {
|
||||
let transform_kind = batch.key.flags.transform_kind();
|
||||
let needs_clipping = batch.key.flags.needs_clipping();
|
||||
debug_assert!(!needs_clipping ||
|
||||
batch.key.blend_mode == BlendMode::Alpha ||
|
||||
batch.key.blend_mode == BlendMode::PremultipliedAlpha);
|
||||
match batch.key.blend_mode {
|
||||
BlendMode::Alpha |
|
||||
BlendMode::PremultipliedAlpha |
|
||||
BlendMode::Subpixel(..) => true,
|
||||
BlendMode::None => false,
|
||||
});
|
||||
|
||||
let (marker, shader) = match batch.key.kind {
|
||||
AlphaBatchKind::Composite => {
|
||||
@ -1586,7 +1613,7 @@ impl Renderer {
|
||||
// composites can't be grouped together because
|
||||
// they may overlap and affect each other.
|
||||
debug_assert!(batch.instances.len() == 1);
|
||||
let instance = &batch.instances[0];
|
||||
let instance = CompositePrimitiveInstance::from(&batch.instances[0]);
|
||||
|
||||
// TODO(gw): This code branch is all a bit hacky. We rely
|
||||
// on pulling specific values from the render target data
|
||||
@ -1599,9 +1626,9 @@ impl Renderer {
|
||||
// composite operation in this batch.
|
||||
let cache_texture_dimensions = self.device.get_texture_dimensions(cache_texture);
|
||||
|
||||
let backdrop = &render_task_data[instance.task_index as usize];
|
||||
let readback = &render_task_data[instance.user_data[0] as usize];
|
||||
let source = &render_task_data[instance.user_data[1] as usize];
|
||||
let backdrop = &render_task_data[instance.task_index.0 as usize];
|
||||
let readback = &render_task_data[instance.backdrop_task_index.0 as usize];
|
||||
let source = &render_task_data[instance.src_task_index.0 as usize];
|
||||
|
||||
// Bind the FBO to blit the backdrop to.
|
||||
// Called per-instance in case the layer (and therefore FBO)
|
||||
@ -2144,6 +2171,31 @@ impl Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_pixels_rgba8(&self, rect: DeviceUintRect) -> Vec<u8> {
|
||||
let mut pixels = vec![0u8; (4 * rect.size.width * rect.size.height) as usize];
|
||||
self.read_pixels_into(rect, ReadPixelsFormat::Rgba8, &mut pixels);
|
||||
pixels
|
||||
}
|
||||
|
||||
pub fn read_pixels_into(&self,
|
||||
rect: DeviceUintRect,
|
||||
format: ReadPixelsFormat,
|
||||
output: &mut [u8]) {
|
||||
let (gl_format, gl_type, size) = match format {
|
||||
ReadPixelsFormat::Rgba8 => (gl::RGBA, gl::UNSIGNED_BYTE, 4),
|
||||
ReadPixelsFormat::Bgra8 => (get_gl_format_bgra(self.device.gl()), gl::UNSIGNED_BYTE, 4),
|
||||
};
|
||||
assert_eq!(output.len(), (size * rect.size.width * rect.size.height) as usize);
|
||||
self.device.gl().flush();
|
||||
self.device.gl().read_pixels_into_buffer(rect.origin.x as gl::GLint,
|
||||
rect.origin.y as gl::GLint,
|
||||
rect.size.width as gl::GLsizei,
|
||||
rect.size.height as gl::GLsizei,
|
||||
gl_format,
|
||||
gl_type,
|
||||
output);
|
||||
}
|
||||
|
||||
// De-initialize the Renderer safely, assuming the GL is still alive and active.
|
||||
pub fn deinit(mut self) {
|
||||
//Note: this is a fake frame, only needed because texture deletion is require to happen inside a frame
|
||||
|
@ -8,7 +8,7 @@ use freelist::{FreeList, FreeListItem, FreeListItemId};
|
||||
use internal_types::{TextureUpdate, TextureUpdateOp};
|
||||
use internal_types::{CacheTextureId, RenderTargetMode, TextureUpdateList, RectUv};
|
||||
use profiler::TextureCacheProfileCounters;
|
||||
use std::cmp::{self, Ordering};
|
||||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::hash::BuildHasherDefault;
|
||||
@ -50,6 +50,12 @@ const COALESCING_TIMEOUT_CHECKING_INTERVAL: usize = 256;
|
||||
|
||||
pub type TextureCacheItemId = FreeListItemId;
|
||||
|
||||
enum CoalescingStatus {
|
||||
Changed,
|
||||
Unchanged,
|
||||
Timeout,
|
||||
}
|
||||
|
||||
/// A texture allocator using the guillotine algorithm with the rectangle merge improvement. See
|
||||
/// sections 2.2 and 2.2.5 in "A Thousand Ways to Pack the Bin - A Practical Approach to Two-
|
||||
/// Dimensional Rectangle Bin Packing":
|
||||
@ -62,6 +68,7 @@ pub struct TexturePage {
|
||||
texture_id: CacheTextureId,
|
||||
texture_size: DeviceUintSize,
|
||||
free_list: FreeRectList,
|
||||
coalesce_vec: Vec<DeviceUintRect>,
|
||||
allocations: u32,
|
||||
dirty: bool,
|
||||
}
|
||||
@ -72,6 +79,7 @@ impl TexturePage {
|
||||
texture_id: texture_id,
|
||||
texture_size: texture_size,
|
||||
free_list: FreeRectList::new(),
|
||||
coalesce_vec: Vec::new(),
|
||||
allocations: 0,
|
||||
dirty: false,
|
||||
};
|
||||
@ -117,6 +125,9 @@ impl TexturePage {
|
||||
|
||||
pub fn allocate(&mut self,
|
||||
requested_dimensions: &DeviceUintSize) -> Option<DeviceUintPoint> {
|
||||
if requested_dimensions.width == 0 || requested_dimensions.height == 0 {
|
||||
return Some(DeviceUintPoint::new(0, 0))
|
||||
}
|
||||
let index = match self.find_index_of_best_rect(requested_dimensions) {
|
||||
None => return None,
|
||||
Some(index) => index,
|
||||
@ -173,7 +184,66 @@ impl TexturePage {
|
||||
Some(chosen_rect.origin)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn coalesce_impl<F, U>(rects: &mut [DeviceUintRect], deadline: u64, fun_key: F, fun_union: U)
|
||||
-> CoalescingStatus where
|
||||
F: Fn(&DeviceUintRect) -> (u32, u32),
|
||||
U: Fn(&mut DeviceUintRect, &mut DeviceUintRect) -> usize,
|
||||
{
|
||||
let mut num_changed = 0;
|
||||
rects.sort_by_key(&fun_key);
|
||||
|
||||
for work_index in 0..rects.len() {
|
||||
if work_index % COALESCING_TIMEOUT_CHECKING_INTERVAL == 0 &&
|
||||
time::precise_time_ns() >= deadline {
|
||||
return CoalescingStatus::Timeout
|
||||
}
|
||||
|
||||
let (left, candidates) = rects.split_at_mut(work_index + 1);
|
||||
let mut item = left.last_mut().unwrap();
|
||||
if util::rect_is_empty(item) {
|
||||
continue
|
||||
}
|
||||
|
||||
let key = fun_key(item);
|
||||
for candidate in candidates.iter_mut()
|
||||
.take_while(|r| key == fun_key(r)) {
|
||||
num_changed += fun_union(item, candidate);
|
||||
}
|
||||
}
|
||||
|
||||
if num_changed > 0 {
|
||||
CoalescingStatus::Changed
|
||||
} else {
|
||||
CoalescingStatus::Unchanged
|
||||
}
|
||||
}
|
||||
|
||||
/// Combine rects that have the same width and are adjacent.
|
||||
fn coalesce_horisontal(rects: &mut [DeviceUintRect], deadline: u64) -> CoalescingStatus {
|
||||
Self::coalesce_impl(rects, deadline,
|
||||
|item| (item.size.width, item.origin.x),
|
||||
|item, candidate| {
|
||||
if item.origin.y == candidate.max_y() || item.max_y() == candidate.origin.y {
|
||||
*item = item.union(candidate);
|
||||
candidate.size.width = 0;
|
||||
1
|
||||
} else { 0 }
|
||||
})
|
||||
}
|
||||
|
||||
/// Combine rects that have the same height and are adjacent.
|
||||
fn coalesce_vertical(rects: &mut [DeviceUintRect], deadline: u64) -> CoalescingStatus {
|
||||
Self::coalesce_impl(rects, deadline,
|
||||
|item| (item.size.height, item.origin.y),
|
||||
|item, candidate| {
|
||||
if item.origin.x == candidate.max_x() || item.max_x() == candidate.origin.x {
|
||||
*item = item.union(candidate);
|
||||
candidate.size.height = 0;
|
||||
1
|
||||
} else { 0 }
|
||||
})
|
||||
}
|
||||
|
||||
pub fn coalesce(&mut self) -> bool {
|
||||
if !self.dirty {
|
||||
return false
|
||||
@ -181,84 +251,33 @@ impl TexturePage {
|
||||
|
||||
// Iterate to a fixed point or until a timeout is reached.
|
||||
let deadline = time::precise_time_ns() + COALESCING_TIMEOUT;
|
||||
let mut free_list = mem::replace(&mut self.free_list, FreeRectList::new()).into_vec();
|
||||
self.free_list.copy_to_vec(&mut self.coalesce_vec);
|
||||
let mut changed = false;
|
||||
|
||||
// Combine rects that have the same width and are adjacent.
|
||||
let mut new_free_list = Vec::new();
|
||||
free_list.sort_by(|a, b| {
|
||||
match a.size.width.cmp(&b.size.width) {
|
||||
Ordering::Equal => a.origin.x.cmp(&b.origin.x),
|
||||
ordering => ordering,
|
||||
}
|
||||
});
|
||||
for work_index in 0..free_list.len() {
|
||||
if work_index % COALESCING_TIMEOUT_CHECKING_INTERVAL == 0 &&
|
||||
time::precise_time_ns() >= deadline {
|
||||
self.free_list = FreeRectList::from_slice(&free_list[..]);
|
||||
self.dirty = true;
|
||||
//Note: we might want to consider try to use the last sorted order first
|
||||
// but the elements get shuffled around a bit anyway during the bin placement
|
||||
|
||||
match Self::coalesce_horisontal(&mut self.coalesce_vec, deadline) {
|
||||
CoalescingStatus::Changed => changed = true,
|
||||
CoalescingStatus::Unchanged => (),
|
||||
CoalescingStatus::Timeout => {
|
||||
self.free_list.init_from_slice(&self.coalesce_vec);
|
||||
return true
|
||||
}
|
||||
|
||||
if free_list[work_index].size.width == 0 {
|
||||
continue
|
||||
}
|
||||
for candidate_index in (work_index + 1)..free_list.len() {
|
||||
if free_list[work_index].size.width != free_list[candidate_index].size.width ||
|
||||
free_list[work_index].origin.x != free_list[candidate_index].origin.x {
|
||||
break
|
||||
}
|
||||
if free_list[work_index].origin.y == free_list[candidate_index].max_y() ||
|
||||
free_list[work_index].max_y() == free_list[candidate_index].origin.y {
|
||||
changed = true;
|
||||
free_list[work_index] =
|
||||
free_list[work_index].union(&free_list[candidate_index]);
|
||||
free_list[candidate_index].size.width = 0
|
||||
}
|
||||
new_free_list.push(free_list[work_index])
|
||||
}
|
||||
new_free_list.push(free_list[work_index])
|
||||
}
|
||||
free_list = new_free_list;
|
||||
|
||||
// Combine rects that have the same height and are adjacent.
|
||||
let mut new_free_list = Vec::new();
|
||||
free_list.sort_by(|a, b| {
|
||||
match a.size.height.cmp(&b.size.height) {
|
||||
Ordering::Equal => a.origin.y.cmp(&b.origin.y),
|
||||
ordering => ordering,
|
||||
}
|
||||
});
|
||||
for work_index in 0..free_list.len() {
|
||||
if work_index % COALESCING_TIMEOUT_CHECKING_INTERVAL == 0 &&
|
||||
time::precise_time_ns() >= deadline {
|
||||
self.free_list = FreeRectList::from_slice(&free_list[..]);
|
||||
self.dirty = true;
|
||||
match Self::coalesce_vertical(&mut self.coalesce_vec, deadline) {
|
||||
CoalescingStatus::Changed => changed = true,
|
||||
CoalescingStatus::Unchanged => (),
|
||||
CoalescingStatus::Timeout => {
|
||||
self.free_list.init_from_slice(&self.coalesce_vec);
|
||||
return true
|
||||
}
|
||||
|
||||
if free_list[work_index].size.height == 0 {
|
||||
continue
|
||||
}
|
||||
for candidate_index in (work_index + 1)..free_list.len() {
|
||||
if free_list[work_index].size.height !=
|
||||
free_list[candidate_index].size.height ||
|
||||
free_list[work_index].origin.y != free_list[candidate_index].origin.y {
|
||||
break
|
||||
}
|
||||
if free_list[work_index].origin.x == free_list[candidate_index].max_x() ||
|
||||
free_list[work_index].max_x() == free_list[candidate_index].origin.x {
|
||||
changed = true;
|
||||
free_list[work_index] =
|
||||
free_list[work_index].union(&free_list[candidate_index]);
|
||||
free_list[candidate_index].size.height = 0
|
||||
}
|
||||
}
|
||||
new_free_list.push(free_list[work_index])
|
||||
}
|
||||
free_list = new_free_list;
|
||||
|
||||
self.free_list = FreeRectList::from_slice(&free_list[..]);
|
||||
if changed {
|
||||
self.free_list.init_from_slice(&self.coalesce_vec);
|
||||
}
|
||||
self.dirty = changed;
|
||||
changed
|
||||
}
|
||||
@ -273,6 +292,9 @@ impl TexturePage {
|
||||
}
|
||||
|
||||
fn free(&mut self, rect: &DeviceUintRect) {
|
||||
if util::rect_is_empty(rect) {
|
||||
return
|
||||
}
|
||||
debug_assert!(self.allocations > 0);
|
||||
self.allocations -= 1;
|
||||
if self.allocations == 0 {
|
||||
@ -312,6 +334,25 @@ impl TexturePage {
|
||||
}
|
||||
}
|
||||
|
||||
// testing functionality
|
||||
impl TexturePage {
|
||||
#[doc(hidden)]
|
||||
pub fn new_dummy(size: DeviceUintSize) -> TexturePage {
|
||||
Self::new(CacheTextureId(0), size)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn fill_from(&mut self, other: &TexturePage) {
|
||||
self.dirty = true;
|
||||
self.free_list.small.clear();
|
||||
self.free_list.small.extend_from_slice(&other.free_list.small);
|
||||
self.free_list.medium.clear();
|
||||
self.free_list.medium.extend_from_slice(&other.free_list.medium);
|
||||
self.free_list.large.clear();
|
||||
self.free_list.large.extend_from_slice(&other.free_list.large);
|
||||
}
|
||||
}
|
||||
|
||||
/// A binning free list. Binning is important to avoid sifting through lots of small strips when
|
||||
/// allocating many texture items.
|
||||
struct FreeRectList {
|
||||
@ -329,12 +370,15 @@ impl FreeRectList {
|
||||
}
|
||||
}
|
||||
|
||||
fn from_slice(vector: &[DeviceUintRect]) -> FreeRectList {
|
||||
let mut free_list = FreeRectList::new();
|
||||
for rect in vector {
|
||||
free_list.push(rect)
|
||||
fn init_from_slice(&mut self, rects: &[DeviceUintRect]) {
|
||||
self.small.clear();
|
||||
self.medium.clear();
|
||||
self.large.clear();
|
||||
for rect in rects {
|
||||
if !util::rect_is_empty(rect) {
|
||||
self.push(rect)
|
||||
}
|
||||
}
|
||||
free_list
|
||||
}
|
||||
|
||||
fn push(&mut self, rect: &DeviceUintRect) {
|
||||
@ -361,10 +405,11 @@ impl FreeRectList {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_vec(mut self) -> Vec<DeviceUintRect> {
|
||||
self.small.extend(self.medium.drain(..));
|
||||
self.small.extend(self.large.drain(..));
|
||||
self.small
|
||||
fn copy_to_vec(&self, rects: &mut Vec<DeviceUintRect>) {
|
||||
rects.clear();
|
||||
rects.extend_from_slice(&self.small);
|
||||
rects.extend_from_slice(&self.medium);
|
||||
rects.extend_from_slice(&self.large);
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,13 +424,14 @@ enum FreeListBin {
|
||||
}
|
||||
|
||||
impl FreeListBin {
|
||||
pub fn for_size(size: &DeviceUintSize) -> FreeListBin {
|
||||
fn for_size(size: &DeviceUintSize) -> FreeListBin {
|
||||
if size.width >= MINIMUM_LARGE_RECT_SIZE && size.height >= MINIMUM_LARGE_RECT_SIZE {
|
||||
FreeListBin::Large
|
||||
} else if size.width >= MINIMUM_MEDIUM_RECT_SIZE &&
|
||||
size.height >= MINIMUM_MEDIUM_RECT_SIZE {
|
||||
FreeListBin::Medium
|
||||
} else {
|
||||
debug_assert!(size.width > 0 && size.height > 0);
|
||||
FreeListBin::Small
|
||||
}
|
||||
}
|
||||
|
@ -314,16 +314,14 @@ impl AlphaRenderItem {
|
||||
let amount = (amount * 65535.0).round() as i32;
|
||||
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
|
||||
|
||||
batch.add_instance(PrimitiveInstance {
|
||||
global_prim_id: -1,
|
||||
prim_address: GpuStoreAddress(0),
|
||||
task_index: task_index.0 as i32,
|
||||
clip_task_index: -1,
|
||||
layer_index: -1,
|
||||
sub_index: filter_mode,
|
||||
user_data: [src_task_index.0 as i32, amount],
|
||||
z_sort_index: z,
|
||||
});
|
||||
let instance = CompositePrimitiveInstance::new(task_index,
|
||||
src_task_index,
|
||||
RenderTaskIndex(0),
|
||||
filter_mode,
|
||||
amount,
|
||||
z);
|
||||
|
||||
batch.add_instance(PrimitiveInstance::from(instance));
|
||||
}
|
||||
AlphaRenderItem::HardwareComposite(stacking_context_index, src_id, composite_op, z) => {
|
||||
let stacking_context = &ctx.stacking_context_store[stacking_context_index.0];
|
||||
@ -333,16 +331,15 @@ impl AlphaRenderItem {
|
||||
composite_op.to_blend_mode(),
|
||||
BatchTextures::no_texture());
|
||||
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
|
||||
batch.add_instance(PrimitiveInstance {
|
||||
global_prim_id: -1,
|
||||
prim_address: GpuStoreAddress(0),
|
||||
task_index: task_index.0 as i32,
|
||||
clip_task_index: -1,
|
||||
layer_index: -1,
|
||||
sub_index: -1,
|
||||
user_data: [src_task_index.0 as i32, 0],
|
||||
z_sort_index: z,
|
||||
});
|
||||
|
||||
let instance = CompositePrimitiveInstance::new(task_index,
|
||||
src_task_index,
|
||||
RenderTaskIndex(0),
|
||||
0,
|
||||
0,
|
||||
z);
|
||||
|
||||
batch.add_instance(PrimitiveInstance::from(instance));
|
||||
}
|
||||
AlphaRenderItem::Composite(stacking_context_index,
|
||||
backdrop_id,
|
||||
@ -357,17 +354,15 @@ impl AlphaRenderItem {
|
||||
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
|
||||
let backdrop_task = render_tasks.get_task_index(&backdrop_id, child_pass_index);
|
||||
let src_task_index = render_tasks.get_static_task_index(&src_id);
|
||||
batch.add_instance(PrimitiveInstance {
|
||||
global_prim_id: -1,
|
||||
prim_address: GpuStoreAddress(0),
|
||||
task_index: task_index.0 as i32,
|
||||
clip_task_index: -1,
|
||||
layer_index: -1,
|
||||
sub_index: mode as u32 as i32,
|
||||
user_data: [ backdrop_task.0 as i32,
|
||||
src_task_index.0 as i32 ],
|
||||
z_sort_index: z,
|
||||
});
|
||||
|
||||
let instance = CompositePrimitiveInstance::new(task_index,
|
||||
src_task_index,
|
||||
backdrop_task,
|
||||
mode as u32 as i32,
|
||||
0,
|
||||
z);
|
||||
|
||||
batch.add_instance(PrimitiveInstance::from(instance));
|
||||
}
|
||||
AlphaRenderItem::Primitive(clip_scroll_group_index_opt, prim_index, z) => {
|
||||
let prim_metadata = ctx.prim_store.get_metadata(prim_index);
|
||||
@ -375,9 +370,9 @@ impl AlphaRenderItem {
|
||||
Some(group_index) => {
|
||||
let group = &ctx.clip_scroll_group_store[group_index.0];
|
||||
let bounding_rect = group.screen_bounding_rect.as_ref().unwrap();
|
||||
(bounding_rect.0, group.packed_layer_index.0 as i32)
|
||||
(bounding_rect.0, group.packed_layer_index)
|
||||
},
|
||||
None => (TransformedRectKind::AxisAligned, 0),
|
||||
None => (TransformedRectKind::AxisAligned, PackedLayerIndex(0)),
|
||||
};
|
||||
let needs_clipping = prim_metadata.needs_clipping();
|
||||
let mut flags = AlphaBatchKeyFlags::empty();
|
||||
@ -398,24 +393,18 @@ impl AlphaRenderItem {
|
||||
None => {
|
||||
OPAQUE_TASK_INDEX
|
||||
}
|
||||
}.0 as i32;
|
||||
let global_prim_id = prim_index.0 as i32;
|
||||
let prim_address = prim_metadata.gpu_prim_index;
|
||||
let task_index = task_index.0 as i32;
|
||||
};
|
||||
let needs_blending = !prim_metadata.is_opaque ||
|
||||
needs_clipping ||
|
||||
transform_kind == TransformedRectKind::Complex;
|
||||
let blend_mode = ctx.prim_store.get_blend_mode(needs_blending, prim_metadata);
|
||||
let base_instance = PrimitiveInstance {
|
||||
task_index: task_index,
|
||||
clip_task_index: clip_task_index,
|
||||
layer_index: packed_layer_index,
|
||||
global_prim_id: global_prim_id,
|
||||
prim_address: prim_address,
|
||||
sub_index: 0,
|
||||
user_data: [0, 0],
|
||||
z_sort_index: z,
|
||||
};
|
||||
|
||||
let base_instance = SimplePrimitiveInstance::new(prim_index,
|
||||
prim_metadata.gpu_prim_index,
|
||||
task_index,
|
||||
clip_task_index,
|
||||
packed_layer_index,
|
||||
z);
|
||||
|
||||
match prim_metadata.prim_kind {
|
||||
PrimitiveKind::Border => {
|
||||
@ -430,16 +419,13 @@ impl AlphaRenderItem {
|
||||
match *instance_kind {
|
||||
BorderCornerInstance::Single => {
|
||||
batch.add_instance(base_instance.build(sub_index,
|
||||
BorderCornerSide::Both as i32,
|
||||
0));
|
||||
BorderCornerSide::Both as i32,));
|
||||
}
|
||||
BorderCornerInstance::Double => {
|
||||
batch.add_instance(base_instance.build(sub_index,
|
||||
BorderCornerSide::First as i32,
|
||||
0));
|
||||
BorderCornerSide::First as i32));
|
||||
batch.add_instance(base_instance.build(sub_index,
|
||||
BorderCornerSide::Second as i32,
|
||||
0));
|
||||
BorderCornerSide::Second as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,14 +433,14 @@ impl AlphaRenderItem {
|
||||
|
||||
batch_list.with_suitable_batch(&edge_key, item_bounding_rect, |batch| {
|
||||
for border_segment in 0..4 {
|
||||
batch.add_instance(base_instance.build(border_segment, 0, 0));
|
||||
batch.add_instance(base_instance.build(border_segment, 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
PrimitiveKind::Rectangle => {
|
||||
let key = AlphaBatchKey::new(AlphaBatchKind::Rectangle, flags, blend_mode, textures);
|
||||
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
|
||||
batch.add_instance(base_instance);
|
||||
batch.add_instance(base_instance.build(0, 0));
|
||||
}
|
||||
PrimitiveKind::Image => {
|
||||
let image_cpu = &ctx.prim_store.cpu_images[prim_metadata.cpu_prim_index.0];
|
||||
@ -479,7 +465,7 @@ impl AlphaRenderItem {
|
||||
|
||||
let key = AlphaBatchKey::new(batch_kind, flags, blend_mode, textures);
|
||||
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
|
||||
batch.add_instance(base_instance.build(0, image_cpu.resource_address.0, 0));
|
||||
batch.add_instance(base_instance.build(image_cpu.resource_address.0, 0));
|
||||
}
|
||||
PrimitiveKind::TextRun => {
|
||||
let text_cpu = &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0];
|
||||
@ -504,36 +490,33 @@ impl AlphaRenderItem {
|
||||
};
|
||||
|
||||
for glyph_index in 0..prim_metadata.gpu_data_count {
|
||||
let user_data0 = match batch_kind {
|
||||
let user_data1 = match batch_kind {
|
||||
AlphaBatchKind::TextRun => text_cpu.resource_address.0 + glyph_index,
|
||||
AlphaBatchKind::CacheImage => cache_task_index,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + glyph_index,
|
||||
user_data0,
|
||||
0));
|
||||
user_data1));
|
||||
}
|
||||
}
|
||||
PrimitiveKind::AlignedGradient => {
|
||||
let key = AlphaBatchKey::new(AlphaBatchKind::AlignedGradient, flags, blend_mode, textures);
|
||||
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
|
||||
for part_index in 0..(prim_metadata.gpu_data_count - 1) {
|
||||
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + part_index, 0, 0));
|
||||
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + part_index, 0));
|
||||
}
|
||||
}
|
||||
PrimitiveKind::AngleGradient => {
|
||||
let key = AlphaBatchKey::new(AlphaBatchKind::AngleGradient, flags, blend_mode, textures);
|
||||
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
|
||||
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0,
|
||||
prim_metadata.gpu_data_count,
|
||||
0));
|
||||
}
|
||||
PrimitiveKind::RadialGradient => {
|
||||
let key = AlphaBatchKey::new(AlphaBatchKind::RadialGradient, flags, blend_mode, textures);
|
||||
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
|
||||
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0,
|
||||
prim_metadata.gpu_data_count,
|
||||
0));
|
||||
}
|
||||
PrimitiveKind::YuvImage => {
|
||||
@ -571,8 +554,7 @@ impl AlphaRenderItem {
|
||||
textures);
|
||||
let batch = batch_list.get_suitable_batch(&key, item_bounding_rect);
|
||||
|
||||
batch.add_instance(base_instance.build(0,
|
||||
image_yuv_cpu.yuv_resource_address.0,
|
||||
batch.add_instance(base_instance.build(image_yuv_cpu.yuv_resource_address.0,
|
||||
0));
|
||||
}
|
||||
PrimitiveKind::BoxShadow => {
|
||||
@ -585,8 +567,7 @@ impl AlphaRenderItem {
|
||||
|
||||
for rect_index in 0..prim_metadata.gpu_data_count {
|
||||
batch.add_instance(base_instance.build(prim_metadata.gpu_data_address.0 + rect_index,
|
||||
cache_task_index.0 as i32,
|
||||
0));
|
||||
cache_task_index.0 as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -599,16 +580,15 @@ impl AlphaRenderItem {
|
||||
let stacking_context = &ctx.stacking_context_store[sc_index.0];
|
||||
let batch = batch_list.get_suitable_batch(&key, &stacking_context.screen_bounds);
|
||||
let source_task = render_tasks.get_task_index(&task_id, child_pass_index);
|
||||
batch.add_instance(PrimitiveInstance {
|
||||
global_prim_id: -1,
|
||||
prim_address: gpu_address,
|
||||
task_index: task_index.0 as i32,
|
||||
clip_task_index: -1,
|
||||
layer_index: -1, // not be used
|
||||
sub_index: 0,
|
||||
user_data: [ source_task.0 as i32, 0 ],
|
||||
z_sort_index: z,
|
||||
});
|
||||
|
||||
let instance = CompositePrimitiveInstance::new(task_index,
|
||||
source_task,
|
||||
RenderTaskIndex(0),
|
||||
gpu_address.0,
|
||||
0,
|
||||
z);
|
||||
|
||||
batch.add_instance(PrimitiveInstance::from(instance));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -970,16 +950,13 @@ impl RenderTarget for ColorRenderTarget {
|
||||
|
||||
match prim_metadata.prim_kind {
|
||||
PrimitiveKind::BoxShadow => {
|
||||
self.box_shadow_cache_prims.push(PrimitiveInstance {
|
||||
global_prim_id: prim_index.0 as i32,
|
||||
prim_address: prim_metadata.gpu_prim_index,
|
||||
task_index: render_tasks.get_task_index(&task.id, pass_index).0 as i32,
|
||||
clip_task_index: 0,
|
||||
layer_index: 0,
|
||||
sub_index: 0,
|
||||
user_data: [0; 2],
|
||||
z_sort_index: 0, // z is disabled for rendering cache primitives
|
||||
});
|
||||
let instance = SimplePrimitiveInstance::new(prim_index,
|
||||
prim_metadata.gpu_prim_index,
|
||||
render_tasks.get_task_index(&task.id, pass_index),
|
||||
RenderTaskIndex(0),
|
||||
PackedLayerIndex(0),
|
||||
0); // z is disabled for rendering cache primitives
|
||||
self.box_shadow_cache_prims.push(instance.build(0, 0));
|
||||
}
|
||||
PrimitiveKind::TextRun => {
|
||||
let text = &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0];
|
||||
@ -998,17 +975,16 @@ impl RenderTarget for ColorRenderTarget {
|
||||
self.text_run_textures.colors[0] == textures.colors[0]);
|
||||
self.text_run_textures = textures;
|
||||
|
||||
let instance = SimplePrimitiveInstance::new(prim_index,
|
||||
prim_metadata.gpu_prim_index,
|
||||
render_tasks.get_task_index(&task.id, pass_index),
|
||||
RenderTaskIndex(0),
|
||||
PackedLayerIndex(0),
|
||||
0); // z is disabled for rendering cache primitives
|
||||
|
||||
for glyph_index in 0..prim_metadata.gpu_data_count {
|
||||
self.text_run_cache_prims.push(PrimitiveInstance {
|
||||
global_prim_id: prim_index.0 as i32,
|
||||
prim_address: prim_metadata.gpu_prim_index,
|
||||
task_index: render_tasks.get_task_index(&task.id, pass_index).0 as i32,
|
||||
clip_task_index: 0,
|
||||
layer_index: 0,
|
||||
sub_index: prim_metadata.gpu_data_address.0 + glyph_index,
|
||||
user_data: [ text.resource_address.0 + glyph_index, 0],
|
||||
z_sort_index: 0, // z is disabled for rendering cache primitives
|
||||
});
|
||||
self.text_run_cache_prims.push(instance.build(prim_metadata.gpu_data_address.0 + glyph_index,
|
||||
text.resource_address.0 + glyph_index));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -1289,27 +1265,107 @@ pub struct CacheClipInstance {
|
||||
segment: i32,
|
||||
}
|
||||
|
||||
// 32 bytes per instance should be enough for anyone!
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PrimitiveInstance {
|
||||
global_prim_id: i32,
|
||||
prim_address: GpuStoreAddress,
|
||||
pub task_index: i32,
|
||||
clip_task_index: i32,
|
||||
layer_index: i32,
|
||||
sub_index: i32,
|
||||
z_sort_index: i32,
|
||||
pub user_data: [i32; 2],
|
||||
data: [i32; 8],
|
||||
}
|
||||
|
||||
impl PrimitiveInstance {
|
||||
pub fn build(&self,
|
||||
sub_index: i32,
|
||||
user_data0: i32,
|
||||
user_data1: i32) -> PrimitiveInstance {
|
||||
struct SimplePrimitiveInstance {
|
||||
pub global_prim_index: i32,
|
||||
pub specific_prim_address: i32,
|
||||
pub task_index: i32,
|
||||
pub clip_task_index: i32,
|
||||
pub layer_index: i32,
|
||||
pub z_sort_index: i32,
|
||||
}
|
||||
|
||||
impl SimplePrimitiveInstance {
|
||||
fn new(prim_index: PrimitiveIndex,
|
||||
specific_prim_address: GpuStoreAddress,
|
||||
task_index: RenderTaskIndex,
|
||||
clip_task_index: RenderTaskIndex,
|
||||
layer_index: PackedLayerIndex,
|
||||
z_sort_index: i32) -> SimplePrimitiveInstance {
|
||||
SimplePrimitiveInstance {
|
||||
global_prim_index: prim_index.0 as i32,
|
||||
specific_prim_address: specific_prim_address.0 as i32,
|
||||
task_index: task_index.0 as i32,
|
||||
clip_task_index: clip_task_index.0 as i32,
|
||||
layer_index: layer_index.0 as i32,
|
||||
z_sort_index: z_sort_index,
|
||||
}
|
||||
}
|
||||
|
||||
fn build(&self, data0: i32, data1: i32) -> PrimitiveInstance {
|
||||
PrimitiveInstance {
|
||||
sub_index: sub_index,
|
||||
user_data: [user_data0, user_data1],
|
||||
..*self
|
||||
data: [
|
||||
self.global_prim_index,
|
||||
self.specific_prim_address,
|
||||
self.task_index,
|
||||
self.clip_task_index,
|
||||
self.layer_index,
|
||||
self.z_sort_index,
|
||||
data0,
|
||||
data1,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CompositePrimitiveInstance {
|
||||
pub task_index: RenderTaskIndex,
|
||||
pub src_task_index: RenderTaskIndex,
|
||||
pub backdrop_task_index: RenderTaskIndex,
|
||||
pub data0: i32,
|
||||
pub data1: i32,
|
||||
pub z: i32,
|
||||
}
|
||||
|
||||
impl CompositePrimitiveInstance {
|
||||
fn new(task_index: RenderTaskIndex,
|
||||
src_task_index: RenderTaskIndex,
|
||||
backdrop_task_index: RenderTaskIndex,
|
||||
data0: i32,
|
||||
data1: i32,
|
||||
z: i32) -> CompositePrimitiveInstance {
|
||||
CompositePrimitiveInstance {
|
||||
task_index: task_index,
|
||||
src_task_index: src_task_index,
|
||||
backdrop_task_index: backdrop_task_index,
|
||||
data0: data0,
|
||||
data1: data1,
|
||||
z: z,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CompositePrimitiveInstance> for PrimitiveInstance {
|
||||
fn from(instance: CompositePrimitiveInstance) -> PrimitiveInstance {
|
||||
PrimitiveInstance {
|
||||
data: [
|
||||
instance.task_index.0 as i32,
|
||||
instance.src_task_index.0 as i32,
|
||||
instance.backdrop_task_index.0 as i32,
|
||||
instance.z,
|
||||
instance.data0,
|
||||
instance.data1,
|
||||
0,
|
||||
0,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a PrimitiveInstance> for CompositePrimitiveInstance {
|
||||
fn from(instance: &'a PrimitiveInstance) -> CompositePrimitiveInstance {
|
||||
CompositePrimitiveInstance {
|
||||
task_index: RenderTaskIndex(instance.data[0] as usize),
|
||||
src_task_index: RenderTaskIndex(instance.data[1] as usize),
|
||||
backdrop_task_index: RenderTaskIndex(instance.data[2] as usize),
|
||||
z: instance.data[3],
|
||||
data0: instance.data[4],
|
||||
data1: instance.data[5],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1457,7 +1513,6 @@ pub struct PackedLayer {
|
||||
pub transform: LayerToWorldTransform,
|
||||
pub inv_transform: WorldToLayerTransform,
|
||||
pub local_clip_rect: LayerRect,
|
||||
pub screen_vertices: [WorldPoint4D; 4],
|
||||
}
|
||||
|
||||
impl Default for PackedLayer {
|
||||
@ -1466,7 +1521,6 @@ impl Default for PackedLayer {
|
||||
transform: LayerToWorldTransform::identity(),
|
||||
inv_transform: WorldToLayerTransform::identity(),
|
||||
local_clip_rect: LayerRect::zero(),
|
||||
screen_vertices: [WorldPoint4D::zero(); 4],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1488,7 +1542,6 @@ impl PackedLayer {
|
||||
-> Option<(TransformedRectKind, DeviceIntRect)> {
|
||||
let xf_rect = TransformedRect::new(&local_rect, &self.transform, device_pixel_ratio);
|
||||
xf_rect.bounding_rect.intersection(screen_rect).map(|rect| {
|
||||
self.screen_vertices = xf_rect.vertices.clone();
|
||||
self.local_clip_rect = *local_rect;
|
||||
(xf_rect.kind, rect)
|
||||
})
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebRenderAPI.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/webrender/RendererOGL.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
@ -11,9 +12,14 @@
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/layers/SynchronousTask.h"
|
||||
|
||||
#define WRDL_LOG(...)
|
||||
//#define WRDL_LOG(...) printf_stderr("WRDL: " __VA_ARGS__)
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
using layers::Stringify;
|
||||
|
||||
class NewRenderer : public RendererEvent
|
||||
{
|
||||
public:
|
||||
@ -556,6 +562,8 @@ DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
|
||||
matrix = ToWrMatrix(*aTransform);
|
||||
}
|
||||
const WrMatrix* maybeTransform = aTransform ? &matrix : nullptr;
|
||||
WRDL_LOG("PushStackingContext b=%s t=%s\n", Stringify(aBounds).c_str(),
|
||||
aTransform ? Stringify(*aTransform).c_str() : "none");
|
||||
wr_dp_push_stacking_context(mWrState, aBounds, aAnimationId, aOpacity,
|
||||
maybeTransform, aMixBlendMode);
|
||||
}
|
||||
@ -573,6 +581,7 @@ DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
|
||||
void
|
||||
DisplayListBuilder::PopStackingContext()
|
||||
{
|
||||
WRDL_LOG("PopStackingContext\n");
|
||||
wr_dp_pop_stacking_context(mWrState);
|
||||
}
|
||||
|
||||
@ -580,12 +589,14 @@ void
|
||||
DisplayListBuilder::PushClip(const WrRect& aClipRect,
|
||||
const WrImageMask* aMask)
|
||||
{
|
||||
WRDL_LOG("PushClip r=%s m=%p\n", Stringify(aClipRect).c_str(), aMask);
|
||||
wr_dp_push_clip(mWrState, aClipRect, aMask);
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::PopClip()
|
||||
{
|
||||
WRDL_LOG("PopClip\n");
|
||||
wr_dp_pop_clip(mWrState);
|
||||
}
|
||||
|
||||
@ -602,12 +613,15 @@ DisplayListBuilder::PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollI
|
||||
const WrRect& aContentRect,
|
||||
const WrRect& aClipRect)
|
||||
{
|
||||
WRDL_LOG("PushScrollLayer id=%" PRIu64 " co=%s cl=%s\n",
|
||||
aScrollId, Stringify(aContentRect).c_str(), Stringify(aClipRect).c_str());
|
||||
wr_dp_push_scroll_layer(mWrState, aScrollId, aContentRect, aClipRect);
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::PopScrollLayer()
|
||||
{
|
||||
WRDL_LOG("PopScrollLayer\n");
|
||||
wr_dp_pop_scroll_layer(mWrState);
|
||||
}
|
||||
|
||||
@ -616,6 +630,9 @@ DisplayListBuilder::PushRect(const WrRect& aBounds,
|
||||
const WrClipRegionToken aClip,
|
||||
const WrColor& aColor)
|
||||
{
|
||||
WRDL_LOG("PushRect b=%s c=%s\n",
|
||||
Stringify(aBounds).c_str(),
|
||||
Stringify(aColor).c_str());
|
||||
wr_dp_push_rect(mWrState, aBounds, aClip, aColor);
|
||||
}
|
||||
|
||||
@ -675,6 +692,8 @@ DisplayListBuilder::PushImage(const WrRect& aBounds,
|
||||
wr::ImageRendering aFilter,
|
||||
wr::ImageKey aImage)
|
||||
{
|
||||
WRDL_LOG("PushImage b=%s s=%s t=%s\n", Stringify(aBounds).c_str(),
|
||||
Stringify(aStretchSize).c_str(), Stringify(aTileSpacing).c_str());
|
||||
wr_dp_push_image(mWrState, aBounds, aClip, aStretchSize, aTileSpacing, aFilter, aImage);
|
||||
}
|
||||
|
||||
@ -828,6 +847,7 @@ WrClipRegionToken
|
||||
DisplayListBuilder::PushClipRegion(const WrRect& aMain,
|
||||
const WrImageMask* aMask)
|
||||
{
|
||||
WRDL_LOG("PushClipRegion r=%s m=%p\n", Stringify(aMain).c_str(), aMask);
|
||||
return wr_dp_push_clip_region(mWrState,
|
||||
aMain,
|
||||
nullptr, 0,
|
||||
@ -839,6 +859,8 @@ DisplayListBuilder::PushClipRegion(const WrRect& aMain,
|
||||
const nsTArray<WrComplexClipRegion>& aComplex,
|
||||
const WrImageMask* aMask)
|
||||
{
|
||||
WRDL_LOG("PushClipRegion r=%s cl=%d m=%p\n", Stringify(aMain).c_str(),
|
||||
(int)aComplex.Length(), aMask);
|
||||
return wr_dp_push_clip_region(mWrState,
|
||||
aMain,
|
||||
aComplex.Elements(), aComplex.Length(),
|
||||
|
@ -7,7 +7,7 @@ use std::collections::HashMap;
|
||||
use gleam::gl;
|
||||
|
||||
use webrender_traits::*;
|
||||
use webrender::renderer::{Renderer, RendererOptions};
|
||||
use webrender::renderer::{ReadPixelsFormat, Renderer, RendererOptions};
|
||||
use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource};
|
||||
use webrender::{ApiRecordingReceiver, BinaryRecorder};
|
||||
use app_units::Au;
|
||||
@ -70,16 +70,6 @@ impl Into<WrExternalImageId> for ExternalImageId {
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
fn make_slice<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
|
||||
if ptr.is_null() {
|
||||
&[]
|
||||
@ -790,17 +780,12 @@ pub unsafe extern "C" fn wr_renderer_readback(renderer: &mut WrRenderer,
|
||||
buffer_size: usize) {
|
||||
assert!(is_in_render_thread());
|
||||
|
||||
renderer.gl().flush();
|
||||
|
||||
let mut slice = make_slice_mut(dst_buffer, buffer_size);
|
||||
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);
|
||||
renderer.read_pixels_into(DeviceUintRect::new(
|
||||
DeviceUintPoint::new(0, 0),
|
||||
DeviceUintSize::new(width, height)),
|
||||
ReadPixelsFormat::Bgra8,
|
||||
&mut slice);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -1046,6 +1046,10 @@ description =
|
||||
description =
|
||||
[PWebRenderBridge::DPGetSnapshot]
|
||||
description =
|
||||
[PWebRenderBridge::SetAsyncScrollOffset]
|
||||
description = test only
|
||||
[PWebRenderBridge::SetAsyncZoom]
|
||||
description = test only
|
||||
[PVRManager::GetSensorState]
|
||||
description =
|
||||
[PHal::GetCurrentBatteryInformation]
|
||||
|
@ -260,7 +260,7 @@ js::RegExpCreate(JSContext* cx, HandleValue patternValue, HandleValue flagsValue
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
/* Step 1. */
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject));
|
||||
if (!regexp)
|
||||
return false;
|
||||
|
||||
@ -450,7 +450,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, proto));
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject, proto));
|
||||
if (!regexp)
|
||||
return false;
|
||||
|
||||
@ -509,7 +509,7 @@ js::regexp_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
|
||||
return false;
|
||||
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, proto));
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject, proto));
|
||||
if (!regexp)
|
||||
return false;
|
||||
|
||||
@ -542,7 +542,7 @@ js::regexp_construct_raw_flags(JSContext* cx, unsigned argc, Value* vp)
|
||||
int32_t flags = int32_t(args[1].toNumber());
|
||||
|
||||
// Step 7.
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, GenericObject));
|
||||
if (!regexp)
|
||||
return false;
|
||||
|
||||
|
@ -9398,7 +9398,8 @@ Parser<ParseHandler, CharT>::newRegExp()
|
||||
RegExpFlag flags = tokenStream.currentToken().regExpFlags();
|
||||
|
||||
Rooted<RegExpObject*> reobj(context);
|
||||
reobj = RegExpObject::create(context, chars, length, flags, nullptr, &tokenStream, alloc);
|
||||
reobj = RegExpObject::create(context, chars, length, flags, nullptr, &tokenStream, alloc,
|
||||
TenuredObject);
|
||||
if (!reobj)
|
||||
return null();
|
||||
|
||||
|
@ -11979,6 +11979,8 @@ IonBuilder::jsop_delelem()
|
||||
AbortReasonOr<Ok>
|
||||
IonBuilder::jsop_regexp(RegExpObject* reobj)
|
||||
{
|
||||
MOZ_ASSERT(!IsInsideNursery(reobj));
|
||||
|
||||
MRegExp* regexp = MRegExp::New(alloc(), constraints(), reobj);
|
||||
current->add(regexp);
|
||||
current->push(regexp);
|
||||
|
@ -6115,7 +6115,8 @@ JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned fla
|
||||
return nullptr;
|
||||
|
||||
RegExpObject* reobj = RegExpObject::create(cx, chars, length, RegExpFlag(flags),
|
||||
nullptr, nullptr, cx->tempLifoAlloc());
|
||||
nullptr, nullptr, cx->tempLifoAlloc(),
|
||||
GenericObject);
|
||||
return reobj;
|
||||
}
|
||||
|
||||
@ -6125,7 +6126,8 @@ JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsign
|
||||
AssertHeapIsIdle();
|
||||
CHECK_REQUEST(cx);
|
||||
return RegExpObject::create(cx, chars, length, RegExpFlag(flags),
|
||||
nullptr, nullptr, cx->tempLifoAlloc());
|
||||
nullptr, nullptr, cx->tempLifoAlloc(),
|
||||
GenericObject);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -52,13 +52,9 @@ JS_STATIC_ASSERT(StickyFlag == JSREG_STICKY);
|
||||
JS_STATIC_ASSERT(UnicodeFlag == JSREG_UNICODE);
|
||||
|
||||
RegExpObject*
|
||||
js::RegExpAlloc(JSContext* cx, HandleObject proto /* = nullptr */)
|
||||
js::RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto /* = nullptr */)
|
||||
{
|
||||
// Note: RegExp objects are always allocated in the tenured heap. This is
|
||||
// not strictly required, but simplifies embedding them in jitcode.
|
||||
Rooted<RegExpObject*> regexp(cx);
|
||||
|
||||
regexp = NewObjectWithClassProto<RegExpObject>(cx, proto, TenuredObject);
|
||||
Rooted<RegExpObject*> regexp(cx, NewObjectWithClassProto<RegExpObject>(cx, proto, newKind));
|
||||
if (!regexp)
|
||||
return nullptr;
|
||||
|
||||
@ -239,19 +235,19 @@ const Class RegExpObject::protoClass_ = {
|
||||
RegExpObject*
|
||||
RegExpObject::create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags,
|
||||
const ReadOnlyCompileOptions* options, TokenStream* tokenStream,
|
||||
LifoAlloc& alloc)
|
||||
LifoAlloc& alloc, NewObjectKind newKind)
|
||||
{
|
||||
RootedAtom source(cx, AtomizeChars(cx, chars, length));
|
||||
if (!source)
|
||||
return nullptr;
|
||||
|
||||
return create(cx, source, flags, options, tokenStream, alloc);
|
||||
return create(cx, source, flags, options, tokenStream, alloc, newKind);
|
||||
}
|
||||
|
||||
RegExpObject*
|
||||
RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags,
|
||||
const ReadOnlyCompileOptions* options, TokenStream* tokenStream,
|
||||
LifoAlloc& alloc)
|
||||
LifoAlloc& alloc, NewObjectKind newKind)
|
||||
{
|
||||
Maybe<CompileOptions> dummyOptions;
|
||||
if (!tokenStream && !options) {
|
||||
@ -269,7 +265,7 @@ RegExpObject::create(JSContext* cx, HandleAtom source, RegExpFlag flags,
|
||||
if (!irregexp::ParsePatternSyntax(*tokenStream, alloc, source, flags & UnicodeFlag))
|
||||
return nullptr;
|
||||
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx));
|
||||
Rooted<RegExpObject*> regexp(cx, RegExpAlloc(cx, newKind));
|
||||
if (!regexp)
|
||||
return nullptr;
|
||||
|
||||
@ -1342,10 +1338,9 @@ js::CloneRegExpObject(JSContext* cx, JSObject* obj_)
|
||||
{
|
||||
Rooted<RegExpObject*> regex(cx, &obj_->as<RegExpObject>());
|
||||
|
||||
// Unlike RegExpAlloc, all clones must use |regex|'s group. Allocate
|
||||
// in the tenured heap to simplify embedding them in JIT code.
|
||||
// Unlike RegExpAlloc, all clones must use |regex|'s group.
|
||||
RootedObjectGroup group(cx, regex->group());
|
||||
Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, TenuredObject));
|
||||
Rooted<RegExpObject*> clone(cx, NewObjectWithGroup<RegExpObject>(cx, group, GenericObject));
|
||||
if (!clone)
|
||||
return nullptr;
|
||||
clone->initPrivate(nullptr);
|
||||
@ -1466,7 +1461,8 @@ js::XDRScriptRegExpObject(XDRState<mode>* xdr, MutableHandle<RegExpObject*> objp
|
||||
if (xdr->hasOptions())
|
||||
options = &xdr->options();
|
||||
RegExpObject* reobj = RegExpObject::create(xdr->cx(), source, flags,
|
||||
options, nullptr, xdr->lifoAlloc());
|
||||
options, nullptr, xdr->lifoAlloc(),
|
||||
TenuredObject);
|
||||
if (!reobj)
|
||||
return false;
|
||||
|
||||
@ -1490,7 +1486,8 @@ js::CloneScriptRegExpObject(JSContext* cx, RegExpObject& reobj)
|
||||
cx->markAtom(source);
|
||||
|
||||
return RegExpObject::create(cx, source, reobj.getFlags(),
|
||||
nullptr, nullptr, cx->tempLifoAlloc());
|
||||
nullptr, nullptr, cx->tempLifoAlloc(),
|
||||
TenuredObject);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
|
@ -46,7 +46,7 @@ class RegExpStatics;
|
||||
namespace frontend { class TokenStream; }
|
||||
|
||||
extern RegExpObject*
|
||||
RegExpAlloc(JSContext* cx, HandleObject proto = nullptr);
|
||||
RegExpAlloc(JSContext* cx, NewObjectKind newKind, HandleObject proto = nullptr);
|
||||
|
||||
// |regexp| is under-typed because this function's used in the JIT.
|
||||
extern JSObject*
|
||||
@ -74,11 +74,13 @@ class RegExpObject : public NativeObject
|
||||
|
||||
static RegExpObject*
|
||||
create(JSContext* cx, const char16_t* chars, size_t length, RegExpFlag flags,
|
||||
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc);
|
||||
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc,
|
||||
NewObjectKind newKind);
|
||||
|
||||
static RegExpObject*
|
||||
create(JSContext* cx, HandleAtom atom, RegExpFlag flags,
|
||||
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc);
|
||||
const ReadOnlyCompileOptions* options, frontend::TokenStream* ts, LifoAlloc& alloc,
|
||||
NewObjectKind newKind);
|
||||
|
||||
/*
|
||||
* Compute the initial shape to associate with fresh RegExp objects,
|
||||
|
@ -3047,7 +3047,8 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
|
||||
RootedAtom source(cx, reobj.getSource());
|
||||
MOZ_ASSERT(source->isPermanentAtom());
|
||||
clone = RegExpObject::create(cx, source, reobj.getFlags(),
|
||||
nullptr, nullptr, cx->tempLifoAlloc());
|
||||
nullptr, nullptr, cx->tempLifoAlloc(),
|
||||
TenuredObject);
|
||||
} else if (selfHostedObject->is<DateObject>()) {
|
||||
clone = JS::NewDateObject(cx, selfHostedObject->as<DateObject>().clippedTime());
|
||||
} else if (selfHostedObject->is<BooleanObject>()) {
|
||||
|
@ -2127,7 +2127,7 @@ JSStructuredCloneReader::startRead(MutableHandleValue vp)
|
||||
return false;
|
||||
|
||||
RegExpObject* reobj = RegExpObject::create(context(), atom, flags, nullptr, nullptr,
|
||||
context()->tempLifoAlloc());
|
||||
context()->tempLifoAlloc(), GenericObject);
|
||||
if (!reobj)
|
||||
return false;
|
||||
vp.setObject(*reobj);
|
||||
|
@ -1013,11 +1013,10 @@ nsCSSGradientRenderer::BuildWebRenderParameters(float aOpacity,
|
||||
|
||||
aStops.SetLength(mStops.Length());
|
||||
for(uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
Float alpha = mStops[i].mColor.a * aOpacity;
|
||||
aStops[i].color.r = mStops[i].mColor.r * alpha;
|
||||
aStops[i].color.g = mStops[i].mColor.g * alpha;
|
||||
aStops[i].color.b = mStops[i].mColor.b * alpha;
|
||||
aStops[i].color.a = alpha;
|
||||
aStops[i].color.r = mStops[i].mColor.r;
|
||||
aStops[i].color.g = mStops[i].mColor.g;
|
||||
aStops[i].color.b = mStops[i].mColor.b;
|
||||
aStops[i].color.a = mStops[i].mColor.a * aOpacity;
|
||||
aStops[i].offset = mStops[i].mPosition;
|
||||
}
|
||||
|
||||
|
@ -5362,18 +5362,6 @@ nsDisplayBoxShadowInner::CanCreateWebRenderCommands(nsDisplayListBuilder* aBuild
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t i = shadows->Length(); i > 0; --i) {
|
||||
nsCSSShadowItem *shadowItem = shadows->ShadowAt(i - 1);
|
||||
if (!shadowItem->mInset) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shadowItem->mXOffset <= 0 || shadowItem->mYOffset <= 0) {
|
||||
// Need to wait for WR to support clip out.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ random != boxshadow-blur-2.html boxshadow-blur-2-notref.html # fixedpoint divisi
|
||||
== boxshadow-rounding.html boxshadow-rounding-ref.html
|
||||
# One uses old path, one uses WR box shadow.
|
||||
fails-if(Android) fuzzy-if(webrender,50,3310) == boxshadow-button.html boxshadow-button-ref.html
|
||||
fuzzy-if(OSX==1010,1,24) fuzzy-if(d2d,16,908) fuzzy-if(webrender,19,1680) == boxshadow-large-border-radius.html boxshadow-large-border-radius-ref.html # Bug 1209649
|
||||
fuzzy-if(OSX==1010,1,24) fuzzy-if(d2d,16,908) fuzzy-if(webrender,48,2040) == boxshadow-large-border-radius.html boxshadow-large-border-radius-ref.html # Bug 1209649
|
||||
|
||||
fails-if(Android) == boxshadow-fileupload.html boxshadow-fileupload-ref.html
|
||||
fuzzy-if(skiaContent,13,28) == boxshadow-inner-basic.html boxshadow-inner-basic-ref.svg
|
||||
@ -25,8 +25,8 @@ fuzzy(2,440) fuzzy-if(webrender,25,1300) == boxshadow-skiprect.html boxshadow-sk
|
||||
== boxshadow-opacity.html boxshadow-opacity-ref.html
|
||||
== boxshadow-color-rounding.html boxshadow-color-rounding-ref.html
|
||||
== boxshadow-color-rounding-middle.html boxshadow-color-rounding-middle-ref.html
|
||||
fuzzy(3,500) fuzzy-if(d2d,2,1080) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html
|
||||
== boxshadow-inset-neg-spread.html about:blank
|
||||
fuzzy(3,500) fuzzy-if(d2d,2,1080) fuzzy-if(webrender,12,1500) == boxshadow-border-radius-int.html boxshadow-border-radius-int-ref.html
|
||||
fuzzy-if(webrender,1,4) == boxshadow-inset-neg-spread.html about:blank
|
||||
== boxshadow-inset-neg-spread2.html boxshadow-inset-neg-spread2-ref.html
|
||||
fuzzy(26,3610) fuzzy-if(d2d,26,5910) fuzzy-if(webrender,43,200) == boxshadow-rotated.html boxshadow-rotated-ref.html # Bug 1211264
|
||||
== boxshadow-inset-large-border-radius.html boxshadow-inset-large-border-radius-ref.html
|
||||
|
@ -1,7 +1,7 @@
|
||||
default-preferences pref(layout.css.box-decoration-break.enabled,true)
|
||||
|
||||
== box-decoration-break-1.html box-decoration-break-1-ref.html
|
||||
fuzzy(1,20) fuzzy-if(skiaContent,1,700) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
|
||||
fuzzy(1,20) fuzzy-if(skiaContent,1,700) fuzzy-if(webrender,5,450) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html
|
||||
fuzzy(16,460) fuzzy-if(Android,10,3673) fuzzy-if(skiaContent,57,374) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html
|
||||
random-if(!gtkWidget) HTTP(..) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html
|
||||
== box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html
|
||||
|
@ -4728,7 +4728,7 @@ pref("layers.tiles.adjust", true);
|
||||
// 0 -> full-tilt mode: Recomposite even if not transaction occured.
|
||||
pref("layers.offmainthreadcomposition.frame-rate", -1);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#if defined(XP_MACOSX) || defined (OS_OPENBSD)
|
||||
pref("layers.enable-tiles", true);
|
||||
pref("layers.tile-width", 512);
|
||||
pref("layers.tile-height", 512);
|
||||
|
@ -1066,7 +1066,7 @@ public:
|
||||
InterceptFailedOnStop(nsIStreamListener *arg, HttpBaseChannel *chan)
|
||||
: mNext(arg)
|
||||
, mChannel(chan) {}
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) override
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user