mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Merge m-c to inbound, a=merge
MozReview-Commit-ID: HwfVdTF9Np5
This commit is contained in:
commit
1d9dc01136
@ -1,10 +1,6 @@
|
||||
# Always ignore node_modules.
|
||||
**/node_modules/**/*.*
|
||||
|
||||
# Include these to speed up ESLint, see bug 1347906.
|
||||
.hg
|
||||
.git
|
||||
|
||||
# Exclude expected objdirs.
|
||||
obj*/**
|
||||
|
||||
|
@ -630,7 +630,7 @@
|
||||
init for other error types .-->
|
||||
<div id="certificateErrorReporting">
|
||||
<p class="toggle-container-with-text">
|
||||
<input type="checkbox" id="automaticallyReportInFuture" />
|
||||
<input type="checkbox" id="automaticallyReportInFuture" role="checkbox" />
|
||||
<label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic2;</label>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@
|
||||
<h2>&tabCrashed.requestReport;</h2>
|
||||
|
||||
<div class="checkbox-with-label">
|
||||
<input type="checkbox" id="sendReport"/>
|
||||
<input type="checkbox" id="sendReport" role="checkbox"/>
|
||||
<label for="sendReport">&tabCrashed.sendReport2;</label>
|
||||
</div>
|
||||
|
||||
@ -59,13 +59,13 @@
|
||||
</li>
|
||||
|
||||
<li class="checkbox-with-label">
|
||||
<input type="checkbox" id="includeURL"/>
|
||||
<input type="checkbox" id="includeURL" role="checkbox"/>
|
||||
<label for="includeURL">&tabCrashed.includeURL2;</label>
|
||||
</li>
|
||||
|
||||
<li id="requestEmail" hidden="true">
|
||||
<div class="checkbox-with-label">
|
||||
<input type="checkbox" id="emailMe"/>
|
||||
<input type="checkbox" id="emailMe" role="checkbox"/>
|
||||
<label for="emailMe">&tabCrashed.emailMe;</label>
|
||||
</div>
|
||||
<input type="text" id="email" placeholder="&tabCrashed.emailPlaceholder;"/>
|
||||
@ -75,7 +75,7 @@
|
||||
<div id="requestAutoSubmit" hidden="true">
|
||||
<h2>&tabCrashed.requestAutoSubmit2;</h2>
|
||||
<div class="checkbox-with-label">
|
||||
<input type="checkbox" id="autoSubmit"/>
|
||||
<input type="checkbox" id="autoSubmit" role="checkbox"/>
|
||||
<label for="autoSubmit">&tabCrashed.autoSubmit2;</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -21,13 +21,13 @@
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
<menuitem id="context-reload"
|
||||
class="menuitem-iconic"
|
||||
tooltiptext="&reloadButton.tooltip;"
|
||||
tooltip="dynamic-shortcut-tooltip"
|
||||
aria-label="&reloadCmd.label;"
|
||||
oncommand="gContextMenu.reload(event);"
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
<menuitem id="context-stop"
|
||||
class="menuitem-iconic"
|
||||
tooltiptext="&stopButton.tooltip;"
|
||||
tooltip="dynamic-shortcut-tooltip"
|
||||
aria-label="&stopCmd.label;"
|
||||
command="Browser:Stop"/>
|
||||
<menuitem id="context-bookmarkpage"
|
||||
|
@ -5474,19 +5474,29 @@ var gHomeButton = {
|
||||
|
||||
const nodeToTooltipMap = {
|
||||
"bookmarks-menu-button": "bookmarksMenuButton.tooltip",
|
||||
"context-reload": "reloadButton.tooltip",
|
||||
"context-stop": "stopButton.tooltip",
|
||||
"downloads-button": "downloads.tooltip",
|
||||
"fullscreen-button": "fullscreenButton.tooltip",
|
||||
"new-window-button": "newWindowButton.tooltip",
|
||||
"new-tab-button": "newTabButton.tooltip",
|
||||
"tabs-newtab-button": "newTabButton.tooltip",
|
||||
"fullscreen-button": "fullscreenButton.tooltip",
|
||||
"downloads-button": "downloads.tooltip",
|
||||
"urlbar-reload-button": "reloadButton.tooltip",
|
||||
"urlbar-stop-button": "stopButton.tooltip",
|
||||
"urlbar-zoom-button": "urlbar-zoom-button.tooltip",
|
||||
};
|
||||
const nodeToShortcutMap = {
|
||||
"bookmarks-menu-button": "manBookmarkKb",
|
||||
"context-reload": "key_reload",
|
||||
"context-stop": "key_stop",
|
||||
"downloads-button": "key_openDownloads",
|
||||
"fullscreen-button": "key_fullScreen",
|
||||
"new-window-button": "key_newNavigator",
|
||||
"new-tab-button": "key_newNavigatorTab",
|
||||
"tabs-newtab-button": "key_newNavigatorTab",
|
||||
"fullscreen-button": "key_fullScreen",
|
||||
"downloads-button": "key_openDownloads"
|
||||
"urlbar-reload-button": "key_reload",
|
||||
"urlbar-stop-button": "key_stop",
|
||||
"urlbar-zoom-button": "key_fullZoomReset",
|
||||
};
|
||||
|
||||
if (AppConstants.platform == "macosx") {
|
||||
|
@ -776,7 +776,7 @@
|
||||
onclick="ReaderParent.buttonClick(event);"/>
|
||||
<toolbarbutton id="urlbar-zoom-button"
|
||||
onclick="FullZoom.reset();"
|
||||
tooltiptext="&urlbar.zoomReset.tooltip;"
|
||||
tooltip="dynamic-shortcut-tooltip"
|
||||
hidden="true"/>
|
||||
</hbox>
|
||||
<hbox id="userContext-icons" hidden="true">
|
||||
@ -791,11 +791,11 @@
|
||||
class="chromeclass-toolbar-additional"
|
||||
command="Browser:ReloadOrDuplicate"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
tooltiptext="&reloadButton.tooltip;"/>
|
||||
tooltip="dynamic-shortcut-tooltip"/>
|
||||
<toolbarbutton id="urlbar-stop-button"
|
||||
class="chromeclass-toolbar-additional"
|
||||
command="Browser:Stop"
|
||||
tooltiptext="&stopButton.tooltip;"/>
|
||||
tooltip="dynamic-shortcut-tooltip"/>
|
||||
</textbox>
|
||||
</hbox>
|
||||
</toolbaritem>
|
||||
|
@ -2194,6 +2194,7 @@
|
||||
var aDisallowInheritPrincipal;
|
||||
var aOpener;
|
||||
var aCreateLazyBrowser;
|
||||
var aSkipBackgroundNotify;
|
||||
if (arguments.length == 2 &&
|
||||
typeof arguments[1] == "object" &&
|
||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||
@ -2220,6 +2221,7 @@
|
||||
aOpener = params.opener;
|
||||
aIsPrerendered = params.isPrerendered;
|
||||
aCreateLazyBrowser = params.createLazyBrowser;
|
||||
aSkipBackgroundNotify = params.skipBackgroundNotify;
|
||||
}
|
||||
|
||||
// if we're adding tabs, we're past interrupt mode, ditch the owner
|
||||
@ -2254,6 +2256,11 @@
|
||||
}
|
||||
|
||||
t.setAttribute("onerror", "this.removeAttribute('image');");
|
||||
|
||||
if (aSkipBackgroundNotify) {
|
||||
t.setAttribute("skipbackgroundnotify", true);
|
||||
}
|
||||
|
||||
t.className = "tabbrowser-tab";
|
||||
|
||||
this.tabContainer._unlockTabSizing();
|
||||
@ -2656,12 +2663,11 @@
|
||||
!aSkipPermitUnload &&
|
||||
aTab.linkedPanel &&
|
||||
!aAdoptedByTab) {
|
||||
TelemetryStopwatch.start("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
|
||||
|
||||
// We need to block while calling permitUnload() because it
|
||||
// processes the event queue and may lead to another removeTab()
|
||||
// call before permitUnload() returns.
|
||||
|
||||
TelemetryStopwatch.start("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
|
||||
|
||||
aTab._pendingPermitUnload = true;
|
||||
let {permitUnload, timedOut} = browser.permitUnload();
|
||||
delete aTab._pendingPermitUnload;
|
||||
@ -2672,8 +2678,6 @@
|
||||
// so we don't (try to) close the same tab again. Of course, we
|
||||
// also stop if the unload was cancelled by the user:
|
||||
if (aTab.closing || (!timedOut && !permitUnload)) {
|
||||
// NB: deliberately keep the _closedDuringPermitUnload set to
|
||||
// true so we keep exiting early in case of multiple calls.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -6313,10 +6317,10 @@
|
||||
selected.left - scrollRect.left);
|
||||
}
|
||||
|
||||
if (!this._animateElement.hasAttribute("notifybgtab")) {
|
||||
this._animateElement.setAttribute("notifybgtab", "true");
|
||||
if (!this._animateElement.hasAttribute("highlight")) {
|
||||
this._animateElement.setAttribute("highlight", "true");
|
||||
setTimeout(function(ele) {
|
||||
ele.removeAttribute("notifybgtab");
|
||||
ele.removeAttribute("highlight");
|
||||
}, 150, this._animateElement);
|
||||
}
|
||||
]]></body>
|
||||
@ -6404,7 +6408,7 @@
|
||||
if (tab.getAttribute("selected") == "true") {
|
||||
this._fillTrailingGap();
|
||||
this._handleTabSelect();
|
||||
} else {
|
||||
} else if (!tab.hasAttribute("skipbackgroundnotify")) {
|
||||
this._notifyBackgroundTab(tab);
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,15 @@ const DISABLED_OPTGROUP_AND_OPTIONS =
|
||||
' <option value="Two" selected="true">{"end": "true"}</option>' +
|
||||
"</select></body></html>";
|
||||
|
||||
const SELECT_CHANGES_COLOR_ON_FOCUS =
|
||||
"<html><head><style>" +
|
||||
" select:focus { background-color: orange; color: black; }" +
|
||||
"</style></head>" +
|
||||
"<body><select id='one'>" +
|
||||
' <option>{"color": "rgb(0, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
|
||||
' <option selected="true">{"end": "true"}</option>' +
|
||||
"</select></body></html>";
|
||||
|
||||
function getSystemColor(color) {
|
||||
// Need to convert system color to RGB color.
|
||||
let textarea = document.createElementNS("http://www.w3.org/1999/xhtml", "textarea");
|
||||
@ -279,3 +288,12 @@ add_task(function* test_disabled_optgroup_and_options() {
|
||||
yield testSelectColors(DISABLED_OPTGROUP_AND_OPTIONS, 17,
|
||||
{skipSelectColorTest: true});
|
||||
});
|
||||
|
||||
add_task(function* test_disabled_optgroup_and_options() {
|
||||
let options = {
|
||||
selectColor: "rgb(0, 0, 0)",
|
||||
selectBgColor: "rgb(255, 165, 0)"
|
||||
};
|
||||
|
||||
yield testSelectColors(SELECT_CHANGES_COLOR_ON_FOCUS, 2, options);
|
||||
});
|
||||
|
@ -12,29 +12,39 @@ add_task(function* () {
|
||||
const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
|
||||
const URL = BASE + "file_bypass_cache.sjs";
|
||||
|
||||
function awaitLoad(tabId) {
|
||||
return new Promise(resolve => {
|
||||
let tabId = null;
|
||||
let loadPromise, resolveLoad;
|
||||
function resetLoad() {
|
||||
loadPromise = new Promise(resolve => {
|
||||
resolveLoad = resolve;
|
||||
});
|
||||
}
|
||||
function awaitLoad() {
|
||||
return loadPromise.then(() => {
|
||||
resetLoad();
|
||||
});
|
||||
}
|
||||
resetLoad();
|
||||
|
||||
browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
|
||||
if (tabId == tabId_ && changed.status == "complete" && tab.url == URL) {
|
||||
browser.tabs.onUpdated.removeListener(listener);
|
||||
resolve();
|
||||
resolveLoad();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
let tab = await browser.tabs.create({url: URL});
|
||||
await awaitLoad(tab.id);
|
||||
tabId = tab.id;
|
||||
await awaitLoad();
|
||||
|
||||
await browser.tabs.reload(tab.id, {bypassCache: false});
|
||||
await awaitLoad(tab.id);
|
||||
await awaitLoad();
|
||||
|
||||
let [textContent] = await browser.tabs.executeScript(tab.id, {code: "document.body.textContent"});
|
||||
browser.test.assertEq("", textContent, "`textContent` should be empty when bypassCache=false");
|
||||
|
||||
await browser.tabs.reload(tab.id, {bypassCache: true});
|
||||
await awaitLoad(tab.id);
|
||||
await awaitLoad();
|
||||
|
||||
[textContent] = await browser.tabs.executeScript(tab.id, {code: "document.body.textContent"});
|
||||
|
||||
|
@ -888,7 +888,7 @@ PlacesController.prototype = {
|
||||
PlacesUtils.asQuery(node.parent).queryOptions.queryType ==
|
||||
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
|
||||
// This is a uri node inside an history query.
|
||||
PlacesUtils.history.removePage(node.uri).catch(Components.utils.reportError);
|
||||
PlacesUtils.history.remove(node.uri).catch(Components.utils.reportError);
|
||||
// History deletes are not undoable, so we don't have a transaction.
|
||||
} else if (node.itemId == -1 &&
|
||||
PlacesUtils.nodeIsQuery(node) &&
|
||||
|
@ -331,9 +331,7 @@ var gPrivacyPane = {
|
||||
pref.value = false;
|
||||
|
||||
// select the remember history option if needed
|
||||
let rememberHistoryCheckbox = document.getElementById("rememberHistory");
|
||||
if (!rememberHistoryCheckbox.checked)
|
||||
rememberHistoryCheckbox.checked = true;
|
||||
document.getElementById("places.history.enabled").value = true;
|
||||
|
||||
// select the remember forms history option
|
||||
document.getElementById("browser.formfill.enable").value = true;
|
||||
|
@ -331,9 +331,7 @@ var gPrivacyPane = {
|
||||
pref.value = false;
|
||||
|
||||
// select the remember history option if needed
|
||||
let rememberHistoryCheckbox = document.getElementById("rememberHistory");
|
||||
if (!rememberHistoryCheckbox.checked)
|
||||
rememberHistoryCheckbox.checked = true;
|
||||
document.getElementById("places.history.enabled").value = true;
|
||||
|
||||
// select the remember forms history option
|
||||
document.getElementById("browser.formfill.enable").value = true;
|
||||
|
@ -3223,7 +3223,8 @@ var SessionStoreInternal = {
|
||||
let tab = reuseExisting ? this._maybeUpdateBrowserRemoteness(tabbrowser.tabs[t])
|
||||
: tabbrowser.addTab("about:blank",
|
||||
{ skipAnimation: true,
|
||||
userContextId});
|
||||
userContextId,
|
||||
skipBackgroundNotify: true });
|
||||
|
||||
// If we inserted a new tab because the userContextId didn't match with the
|
||||
// open tab, even though `t < openTabCount`, we need to remove that open tab
|
||||
|
@ -14,7 +14,8 @@ this.EXPORTED_SYMBOLS = ["TabAttributes"];
|
||||
// 'pending' is used internal by sessionstore and managed accordingly.
|
||||
// 'iconLoadingPrincipal' is same as 'image' that it should be handled by
|
||||
// using the gBrowser.getIcon()/setIcon() methods.
|
||||
const ATTRIBUTES_TO_SKIP = new Set(["image", "muted", "pending", "iconLoadingPrincipal"]);
|
||||
const ATTRIBUTES_TO_SKIP = new Set(["image", "muted", "pending", "iconLoadingPrincipal",
|
||||
"skipbackgroundnotify"]);
|
||||
|
||||
// A set of tab attributes to persist. We will read a given list of tab
|
||||
// attributes when collecting tab data and will re-set those attributes when
|
||||
|
@ -8,6 +8,6 @@ ac_add_options --disable-crashreporter
|
||||
ac_add_options --disable-elf-hack
|
||||
|
||||
MOZ_CODE_COVERAGE=1
|
||||
export CFLAGS="-fprofile-arcs -ftest-coverage"
|
||||
export CXXFLAGS="-fprofile-arcs -ftest-coverage"
|
||||
export LDFLAGS="-fprofile-arcs -ftest-coverage -lgcov -L$TOOLTOOL_DIR/gtk3/usr/local/lib"
|
||||
export CFLAGS="--coverage"
|
||||
export CXXFLAGS="--coverage"
|
||||
export LDFLAGS="--coverage -L$TOOLTOOL_DIR/gtk3/usr/local/lib"
|
||||
|
@ -1,12 +0,0 @@
|
||||
if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
|
||||
MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
|
||||
MOZ_AUTOMATION_UPDATE_PACKAGING=1
|
||||
fi
|
||||
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
ac_add_options --enable-verify-mar
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
@ -1,18 +0,0 @@
|
||||
# This file is sourced by the nightly, beta, and release mozconfigs.
|
||||
|
||||
. $topsrcdir/build/macosx/universal/mozconfig
|
||||
|
||||
# Universal builds override the default of browser (bug 575283 comment 29)
|
||||
ac_add_options --enable-application=browser
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --with-google-api-keyfile=/builds/gapi.data
|
||||
ac_add_options --with-mozilla-api-keyfile=/builds/mozilla-desktop-geoloc-api.key
|
||||
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
@ -1,22 +0,0 @@
|
||||
. "$topsrcdir/browser/config/mozconfigs/common"
|
||||
. "$topsrcdir/build/macosx/mozconfig.common"
|
||||
|
||||
ac_add_options --with-l10n-base=../../l10n
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --with-branding=browser/branding/nightly
|
||||
|
||||
if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
|
||||
ac_add_options --with-macbundlename-prefix=Firefox
|
||||
fi
|
||||
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
# Enable Telemetry
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
# Don't autoclobber l10n, as this can lead to missing binaries and broken builds
|
||||
# Bug 1283438
|
||||
mk_add_options AUTOCLOBBER=
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
@ -1,20 +0,0 @@
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
|
||||
|
||||
ac_add_options --disable-install-strip
|
||||
ac_add_options --enable-verify-mar
|
||||
ac_add_options --enable-profiling
|
||||
ac_add_options --enable-instruments
|
||||
|
||||
# Cross-universal builds fail when dtrace is enabled
|
||||
if test `uname -s` != Linux; then
|
||||
ac_add_options --enable-dtrace
|
||||
fi
|
||||
|
||||
if test "${MOZ_UPDATE_CHANNEL}" = "nightly"; then
|
||||
ac_add_options --with-macbundlename-prefix=Firefox
|
||||
fi
|
||||
|
||||
ac_add_options --with-branding=browser/branding/nightly
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
@ -1,19 +0,0 @@
|
||||
# This make file should be identical to the beta mozconfig, apart from the
|
||||
# safeguard below
|
||||
|
||||
if [ -n "$ENABLE_RELEASE_PROMOTION" ]; then
|
||||
MOZ_AUTOMATION_UPLOAD_SYMBOLS=${MOZ_AUTOMATION_UPLOAD_SYMBOLS-1}
|
||||
MOZ_AUTOMATION_UPDATE_PACKAGING=1
|
||||
fi
|
||||
|
||||
. "$topsrcdir/browser/config/mozconfigs/macosx-universal/common-opt"
|
||||
|
||||
ac_add_options --enable-official-branding
|
||||
ac_add_options --enable-verify-mar
|
||||
|
||||
# safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
|
||||
# defines.sh during the beta cycle
|
||||
export BUILDING_RELEASE=1
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
@ -198,10 +198,8 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
||||
<!ENTITY backForwardButtonMenu.tooltip "Right-click or pull down to show history">
|
||||
<!ENTITY backForwardButtonMenuMac.tooltip "Pull down to show history">
|
||||
<!ENTITY reloadCmd.label "Reload">
|
||||
<!ENTITY reloadButton.tooltip "Reload current page">
|
||||
<!ENTITY stopCmd.label "Stop">
|
||||
<!ENTITY stopCmd.macCommandKey ".">
|
||||
<!ENTITY stopButton.tooltip "Stop loading this page">
|
||||
<!ENTITY goEndCap.tooltip "Go to the address in the Location Bar">
|
||||
<!ENTITY printButton.label "Print">
|
||||
<!ENTITY printButton.tooltip "Print this page">
|
||||
@ -234,8 +232,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
||||
|
||||
<!ENTITY urlbar.openHistoryPopup.tooltip "Show history">
|
||||
|
||||
<!ENTITY urlbar.zoomReset.tooltip "Reset zoom level">
|
||||
|
||||
<!ENTITY searchItem.title "Search">
|
||||
|
||||
<!-- Toolbar items -->
|
||||
|
@ -386,6 +386,15 @@ tabHistory.goForward=Go forward to this page
|
||||
|
||||
# URL Bar
|
||||
pasteAndGo.label=Paste & Go
|
||||
# LOCALIZATION NOTE (reloadButton.tooltip):
|
||||
# %S is the keyboard shortcut for reloading the current page
|
||||
reloadButton.tooltip=Reload current page (%S)
|
||||
# LOCALIZATION NOTE (stopButton.tooltip):
|
||||
# %S is the keyboard shortcut for stopping loading the page
|
||||
stopButton.tooltip=Stop loading this page (%S)
|
||||
# LOCALIZATION NOTE (urlbar-zoom-button.tooltip):
|
||||
# %S is the keyboard shortcut for resetting the zoom level to 100%
|
||||
urlbar-zoom-button.tooltip=Reset zoom level (%S)
|
||||
|
||||
# LOCALIZATION NOTE(zoom-button.label): %S is the current page zoom level,
|
||||
# %% will be displayed as a single % character (% is commonly used to define
|
||||
|
@ -1376,7 +1376,7 @@ html|span.ac-emphasize-text-url {
|
||||
transition: 1s background-color ease-out;
|
||||
}
|
||||
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down[highlight] {
|
||||
background-color: Highlight;
|
||||
transition: none;
|
||||
}
|
||||
|
@ -2591,7 +2591,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
transition: 1s background-color ease-out;
|
||||
}
|
||||
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down[highlight] {
|
||||
background-color: Highlight;
|
||||
transition: none;
|
||||
}
|
||||
|
@ -1934,7 +1934,7 @@ html|span.ac-emphasize-text-url {
|
||||
transition: 1s background-color ease-out;
|
||||
}
|
||||
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down[highlight] {
|
||||
background-color: Highlight;
|
||||
transition: none;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ altgraph.pth:python/altgraph
|
||||
marionette_driver.pth:testing/marionette/client
|
||||
marionette_harness.pth:testing/marionette/harness
|
||||
browsermobproxy.pth:testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py
|
||||
six.pth:testing/web-platform/tests/tools/six
|
||||
wptserve.pth:testing/web-platform/tests/tools/wptserve
|
||||
blessings.pth:python/blessings
|
||||
configobj.pth:python/configobj
|
||||
|
99
devtools/bootstrap.js
vendored
99
devtools/bootstrap.js
vendored
@ -10,6 +10,24 @@
|
||||
const Cu = Components.utils;
|
||||
const Ci = Components.interfaces;
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||
|
||||
let prefs = {
|
||||
// Enable dump as some errors are only printed on the stdout
|
||||
"browser.dom.window.dump.enabled": true,
|
||||
// Enable the browser toolbox and various chrome-only features
|
||||
"devtools.chrome.enabled": true,
|
||||
"devtools.debugger.remote-enabled": true,
|
||||
// Disable the prompt to ease usage of the browser toolbox
|
||||
"devtools.debugger.prompt-connection": false,
|
||||
};
|
||||
|
||||
// Values of debug pref before overriding them
|
||||
let originalPrefValues = {};
|
||||
// MultiWindowKeyListener instance for Ctrl+Alt+R key
|
||||
let listener;
|
||||
// nsIURI to the addon root folder
|
||||
let resourceURI;
|
||||
|
||||
function actionOccurred(id) {
|
||||
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
@ -18,6 +36,54 @@ function actionOccurred(id) {
|
||||
telemetry.actionOccurred(id);
|
||||
}
|
||||
|
||||
// Synchronously fetch the content of a given URL
|
||||
function readURI(uri) {
|
||||
let stream = NetUtil.newChannel({
|
||||
uri: NetUtil.newURI(uri, "UTF-8"),
|
||||
loadUsingSystemPrincipal: true}
|
||||
).open2();
|
||||
let count = stream.available();
|
||||
let data = NetUtil.readInputStreamToString(stream, count, {
|
||||
charset: "UTF-8"
|
||||
});
|
||||
|
||||
stream.close();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// Read a preference file and set all of its defined pref as default values
|
||||
// (This replicate the behavior of preferences files from mozilla-central)
|
||||
function processPrefFile(url) {
|
||||
let content = readURI(url);
|
||||
content.match(/pref\("[^"]+",\s*.+\s*\)/g).forEach(item => {
|
||||
let m = item.match(/pref\("([^"]+)",\s*(.+)\s*\)/);
|
||||
let name = m[1];
|
||||
let val = m[2];
|
||||
|
||||
// Prevent overriding prefs that have been changed by the user
|
||||
if (Services.prefs.prefHasUserValue(name)) {
|
||||
return;
|
||||
}
|
||||
let defaultBranch = Services.prefs.getDefaultBranch("");
|
||||
if ((val.startsWith("\"") && val.endsWith("\"")) ||
|
||||
(val.startsWith("'") && val.endsWith("'"))) {
|
||||
defaultBranch.setCharPref(name, val.substr(1, val.length - 2));
|
||||
} else if (val.match(/[0-9]+/)) {
|
||||
defaultBranch.setIntPref(name, parseInt(val, 10));
|
||||
} else if (val == "true" || val == "false") {
|
||||
defaultBranch.setBoolPref(name, val == "true");
|
||||
} else {
|
||||
console.log("Unable to match preference type for value:", val);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setPrefs() {
|
||||
processPrefFile(resourceURI.spec + "./client/preferences/devtools.js");
|
||||
processPrefFile(resourceURI.spec + "./client/preferences/debugger.js");
|
||||
}
|
||||
|
||||
// Helper to listen to a key on all windows
|
||||
function MultiWindowKeyListener({ keyCode, ctrlKey, altKey, callback }) {
|
||||
let keyListener = function (event) {
|
||||
@ -76,9 +142,10 @@ let getTopLevelWindow = function (window) {
|
||||
function reload(event) {
|
||||
// We automatically reload the toolbox if we are on a browser tab
|
||||
// with a toolbox already opened
|
||||
let reloadToolbox = false;
|
||||
if (event) {
|
||||
let top = getTopLevelWindow(event.view);
|
||||
let isBrowser = top.location.href.includes("/browser.xul");
|
||||
let reloadToolbox = false;
|
||||
if (isBrowser && top.gBrowser) {
|
||||
// We do not use any devtools code before the call to Loader.jsm reload as
|
||||
// any attempt to use Loader.jsm to load a module will instanciate a new
|
||||
@ -91,6 +158,7 @@ function reload(event) {
|
||||
"devtools-toolbox-side-iframe") ||
|
||||
Services.wm.getMostRecentWindow("devtools:toolbox");
|
||||
}
|
||||
}
|
||||
let browserConsole = Services.wm.getMostRecentWindow("devtools:webconsole");
|
||||
let reopenBrowserConsole = false;
|
||||
if (browserConsole) {
|
||||
@ -136,6 +204,10 @@ function reload(event) {
|
||||
Cu.unload("resource://devtools/client/responsivedesign/responsivedesign.jsm");
|
||||
Cu.unload("resource://devtools/client/shared/widgets/AbstractTreeItem.jsm");
|
||||
Cu.unload("resource://devtools/shared/deprecated-sync-thenables.js");
|
||||
|
||||
// Update the preferences before starting new code
|
||||
setPrefs();
|
||||
|
||||
const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
devtools.require("devtools/client/framework/devtools-browser");
|
||||
|
||||
@ -178,6 +250,7 @@ function reload(event) {
|
||||
setTimeout(() => {
|
||||
let { TargetFactory } = devtools.require("devtools/client/framework/target");
|
||||
let { gDevTools } = devtools.require("devtools/client/framework/devtools");
|
||||
let top = getTopLevelWindow(event.view);
|
||||
let target = TargetFactory.forTab(top.gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target);
|
||||
}, 1000);
|
||||
@ -194,20 +267,11 @@ function reload(event) {
|
||||
actionOccurred("reloadAddonReload");
|
||||
}
|
||||
|
||||
let prefs = {
|
||||
// Enable dump as some errors are only printed on the stdout
|
||||
"browser.dom.window.dump.enabled": true,
|
||||
// Enable the browser toolbox and various chrome-only features
|
||||
"devtools.chrome.enabled": true,
|
||||
"devtools.debugger.remote-enabled": true,
|
||||
// Disable the prompt to ease usage of the browser toolbox
|
||||
"devtools.debugger.prompt-connection": false,
|
||||
};
|
||||
let originalPrefValues = {};
|
||||
|
||||
let listener;
|
||||
function startup() {
|
||||
function startup(data) {
|
||||
dump("DevTools addon started.\n");
|
||||
|
||||
resourceURI = data.resourceURI;
|
||||
|
||||
listener = new MultiWindowKeyListener({
|
||||
keyCode: Ci.nsIDOMKeyEvent.DOM_VK_R, ctrlKey: true, altKey: true,
|
||||
callback: reload
|
||||
@ -225,6 +289,8 @@ function startup() {
|
||||
originalPrefValues[name] = userValue;
|
||||
}
|
||||
}
|
||||
|
||||
reload();
|
||||
}
|
||||
function shutdown() {
|
||||
listener.stop();
|
||||
@ -240,6 +306,11 @@ function shutdown() {
|
||||
}
|
||||
}
|
||||
function install() {
|
||||
try {
|
||||
actionOccurred("reloadAddonInstalled");
|
||||
} catch (e) {
|
||||
// When installing on Firefox builds without devtools, telemetry doesn't
|
||||
// work yet and throws.
|
||||
}
|
||||
}
|
||||
function uninstall() {}
|
||||
|
@ -77,6 +77,7 @@ module.exports = createClass({
|
||||
type: "checkbox",
|
||||
checked: !debugDisabled,
|
||||
onChange: this.onEnableAddonDebuggingChange,
|
||||
role: "checkbox",
|
||||
}),
|
||||
dom.label({
|
||||
className: "addons-debugging-label",
|
||||
|
@ -93,8 +93,13 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId) {
|
||||
|
||||
this._toolPanels = new Map();
|
||||
this._telemetry = new Telemetry();
|
||||
|
||||
// TODO: This approach to source maps uses server-side source maps, which we are
|
||||
// replacing with client-side source maps. Do not use this in new code paths.
|
||||
// To be removed in bug 1349354. Read more about ongoing work with source maps:
|
||||
// https://docs.google.com/document/d/19TKnMJD3CMBzwByNE4aBBVWnl-AEan8Sf4hxi6J-eps/edit
|
||||
if (Services.prefs.getBoolPref("devtools.source-map.locations.enabled")) {
|
||||
this._sourceMapService = new SourceMapService(this._target);
|
||||
this._deprecatedServerSourceMapService = new SourceMapService(this._target);
|
||||
}
|
||||
|
||||
this._initInspector = null;
|
||||
@ -520,6 +525,23 @@ Toolbox.prototype = {
|
||||
return this.browserRequire("devtools/client/framework/components/toolbox-controller");
|
||||
},
|
||||
|
||||
/**
|
||||
* A common access point for the client-side mapping service for source maps that
|
||||
* any panel can use.
|
||||
*/
|
||||
get sourceMapService() {
|
||||
if (!Services.prefs.getBoolPref("devtools.source-map.client-service.enabled")) {
|
||||
return null;
|
||||
}
|
||||
if (this._sourceMapService) {
|
||||
return this._sourceMapService;
|
||||
}
|
||||
// Uses browser loader to access the `Worker` global.
|
||||
this._sourceMapService =
|
||||
this.browserRequire("devtools/client/shared/source-map/index");
|
||||
return this._sourceMapService;
|
||||
},
|
||||
|
||||
// Return HostType id for telemetry
|
||||
_getTelemetryHostId: function () {
|
||||
switch (this.hostType) {
|
||||
@ -2260,8 +2282,14 @@ Toolbox.prototype = {
|
||||
this._applyServiceWorkersTestingSettings);
|
||||
|
||||
this._lastFocusedElement = null;
|
||||
|
||||
if (this._deprecatedServerSourceMapService) {
|
||||
this._deprecatedServerSourceMapService.destroy();
|
||||
this._deprecatedServerSourceMapService = null;
|
||||
}
|
||||
|
||||
if (this._sourceMapService) {
|
||||
this._sourceMapService.destroy();
|
||||
this._sourceMapService.destroyWorker();
|
||||
this._sourceMapService = null;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ const {
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
|
||||
const Actions = require("../actions/index");
|
||||
const { getLongString } = require("../utils/client");
|
||||
const { Prefs } = require("../utils/prefs");
|
||||
const { getFormDataSections } = require("../utils/request-utils");
|
||||
const { getSelectedRequest } = require("../selectors/index");
|
||||
@ -69,7 +70,7 @@ const MonitorPanel = createClass({
|
||||
requestHeaders,
|
||||
requestHeadersFromUploadStream,
|
||||
requestPostData,
|
||||
window.gNetwork.getString.bind(window.gNetwork),
|
||||
getLongString,
|
||||
).then((newFormDataSections) => {
|
||||
updateRequest(
|
||||
request.id,
|
||||
|
@ -269,7 +269,6 @@ HarBuilder.prototype = {
|
||||
file.requestHeaders,
|
||||
file.requestHeadersFromUploadStream,
|
||||
file.requestPostData,
|
||||
this._options.getString
|
||||
).then(formDataSections => {
|
||||
formDataSections.forEach(section => {
|
||||
let paramsArray = parseQueryString(section);
|
||||
|
@ -13,6 +13,8 @@ const {
|
||||
formDataURI,
|
||||
} = require("./utils/request-utils");
|
||||
const {
|
||||
getLongString,
|
||||
getWebConsoleClient,
|
||||
onFirefoxConnect,
|
||||
onFirefoxDisconnect,
|
||||
} = require("./utils/client");
|
||||
@ -87,7 +89,6 @@ var NetMonitorController = {
|
||||
if (this._target.isTabActor) {
|
||||
this.tabClient = this._target.activeTab;
|
||||
}
|
||||
this.webConsoleClient = this._target.activeConsole;
|
||||
|
||||
let connectTimeline = () => {
|
||||
// Don't start up waiting for timeline markers if the server isn't
|
||||
@ -103,6 +104,9 @@ var NetMonitorController = {
|
||||
|
||||
onFirefoxConnect(this._target);
|
||||
this._target.on("close", this._onTabDetached);
|
||||
|
||||
this.webConsoleClient = getWebConsoleClient();
|
||||
this.NetworkEventsHandler = new NetworkEventsHandler();
|
||||
this.NetworkEventsHandler.connect();
|
||||
|
||||
window.emit(EVENTS.CONNECTED);
|
||||
@ -369,7 +373,6 @@ var NetMonitorController = {
|
||||
function NetworkEventsHandler() {
|
||||
this.addRequest = this.addRequest.bind(this);
|
||||
this.updateRequest = this.updateRequest.bind(this);
|
||||
this.getString = this.getString.bind(this);
|
||||
this._onNetworkEvent = this._onNetworkEvent.bind(this);
|
||||
this._onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this);
|
||||
this._onDocLoadingMarker = this._onDocLoadingMarker.bind(this);
|
||||
@ -512,7 +515,7 @@ NetworkEventsHandler.prototype = {
|
||||
let request = getRequestById(gStore.getState(), action.id);
|
||||
|
||||
if (requestHeaders && requestHeaders.headers && requestHeaders.headers.length) {
|
||||
let headers = await fetchHeaders(requestHeaders, this.getString);
|
||||
let headers = await fetchHeaders(requestHeaders, getLongString);
|
||||
if (headers) {
|
||||
await gStore.dispatch(Actions.updateRequest(
|
||||
action.id,
|
||||
@ -523,7 +526,7 @@ NetworkEventsHandler.prototype = {
|
||||
}
|
||||
|
||||
if (responseHeaders && responseHeaders.headers && responseHeaders.headers.length) {
|
||||
let headers = await fetchHeaders(responseHeaders, this.getString);
|
||||
let headers = await fetchHeaders(responseHeaders, getLongString);
|
||||
if (headers) {
|
||||
await gStore.dispatch(Actions.updateRequest(
|
||||
action.id,
|
||||
@ -536,7 +539,7 @@ NetworkEventsHandler.prototype = {
|
||||
if (request && responseContent && responseContent.content) {
|
||||
let { mimeType } = request;
|
||||
let { text, encoding } = responseContent.content;
|
||||
let response = await this.getString(text);
|
||||
let response = await getLongString(text);
|
||||
let payload = {};
|
||||
|
||||
if (mimeType.includes("image/")) {
|
||||
@ -557,7 +560,7 @@ NetworkEventsHandler.prototype = {
|
||||
// them as a separate property, different from the classic headers.
|
||||
if (requestPostData && requestPostData.postData) {
|
||||
let { text } = requestPostData.postData;
|
||||
let postData = await this.getString(text);
|
||||
let postData = await getLongString(text);
|
||||
const headers = CurlUtils.getHeadersFromMultipartText(postData);
|
||||
const headersSize = headers.reduce((acc, { name, value }) => {
|
||||
return acc + name.length + value.length + 2;
|
||||
@ -582,7 +585,7 @@ NetworkEventsHandler.prototype = {
|
||||
if (typeof cookies[Symbol.iterator] === "function") {
|
||||
for (let cookie of cookies) {
|
||||
reqCookies.push(Object.assign({}, cookie, {
|
||||
value: await this.getString(cookie.value),
|
||||
value: await getLongString(cookie.value),
|
||||
}));
|
||||
}
|
||||
if (reqCookies.length) {
|
||||
@ -603,7 +606,7 @@ NetworkEventsHandler.prototype = {
|
||||
if (typeof cookies[Symbol.iterator] === "function") {
|
||||
for (let cookie of cookies) {
|
||||
resCookies.push(Object.assign({}, cookie, {
|
||||
value: await this.getString(cookie.value),
|
||||
value: await getLongString(cookie.value),
|
||||
}));
|
||||
}
|
||||
if (resCookies.length) {
|
||||
@ -800,35 +803,7 @@ NetworkEventsHandler.prototype = {
|
||||
}).then(() => {
|
||||
window.emit(EVENTS.RECEIVED_EVENT_TIMINGS, response.from);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches the full text of a LongString.
|
||||
*
|
||||
* @param object | string stringGrip
|
||||
* The long string grip containing the corresponding actor.
|
||||
* If you pass in a plain string (by accident or because you're lazy),
|
||||
* then a promise of the same string is simply returned.
|
||||
* @return object Promise
|
||||
* A promise that is resolved when the full string contents
|
||||
* are available, or rejected if something goes wrong.
|
||||
*/
|
||||
getString: function (stringGrip) {
|
||||
// FIXME: this.webConsoleClient will be undefined in mochitest,
|
||||
// so we return string instantly to skip undefined error
|
||||
if (typeof stringGrip === "string") {
|
||||
return Promise.resolve(stringGrip);
|
||||
}
|
||||
|
||||
return this.webConsoleClient.getString(stringGrip);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Preliminary setup for the NetMonitorController object.
|
||||
*/
|
||||
NetMonitorController.NetworkEventsHandler = new NetworkEventsHandler();
|
||||
window.NetMonitorController = NetMonitorController;
|
||||
window.gNetwork = NetMonitorController.NetworkEventsHandler;
|
||||
|
||||
exports.NetMonitorController = NetMonitorController;
|
||||
|
@ -11,6 +11,7 @@ const Menu = require("devtools/client/framework/menu");
|
||||
const MenuItem = require("devtools/client/framework/menu-item");
|
||||
const clipboardHelper = require("devtools/shared/platform/clipboard");
|
||||
const { HarExporter } = require("./har/har-exporter");
|
||||
const { getLongString } = require("./utils/client");
|
||||
const { L10N } = require("./utils/l10n");
|
||||
const {
|
||||
formDataURI,
|
||||
@ -146,7 +147,8 @@ RequestListContextMenu.prototype = {
|
||||
|
||||
menu.append(new MenuItem({
|
||||
type: "separator",
|
||||
visible: !!selectedRequest,
|
||||
visible: !!(window.NetMonitorController.supportsCustomRequest &&
|
||||
selectedRequest && !selectedRequest.isCustom),
|
||||
}));
|
||||
|
||||
menu.append(new MenuItem({
|
||||
@ -221,7 +223,7 @@ RequestListContextMenu.prototype = {
|
||||
selected.requestHeaders,
|
||||
selected.requestHeadersFromUploadStream,
|
||||
selected.requestPostData,
|
||||
window.gNetwork.getString.bind(window.gNetwork));
|
||||
getLongString);
|
||||
|
||||
let params = [];
|
||||
formDataSections.forEach(section => {
|
||||
@ -238,7 +240,7 @@ RequestListContextMenu.prototype = {
|
||||
// Fall back to raw payload.
|
||||
if (!string) {
|
||||
let postData = selected.requestPostData.postData.text;
|
||||
string = await window.gNetwork.getString(postData);
|
||||
string = await getLongString(postData);
|
||||
if (Services.appinfo.OS !== "WINNT") {
|
||||
string = string.replace(/\r/g, "");
|
||||
}
|
||||
@ -264,14 +266,14 @@ RequestListContextMenu.prototype = {
|
||||
|
||||
// Fetch header values.
|
||||
for (let { name, value } of selected.requestHeaders.headers) {
|
||||
let text = await window.gNetwork.getString(value);
|
||||
let text = await getLongString(value);
|
||||
data.headers.push({ name: name, value: text });
|
||||
}
|
||||
|
||||
// Fetch the request payload.
|
||||
if (selected.requestPostData) {
|
||||
let postData = selected.requestPostData.postData.text;
|
||||
data.postDataText = await window.gNetwork.getString(postData);
|
||||
data.postDataText = await getLongString(postData);
|
||||
}
|
||||
|
||||
clipboardHelper.copyString(Curl.generateCommand(data));
|
||||
@ -305,7 +307,7 @@ RequestListContextMenu.prototype = {
|
||||
copyImageAsDataUri() {
|
||||
const { mimeType, text, encoding } = this.selectedRequest.responseContent.content;
|
||||
|
||||
window.gNetwork.getString(text).then(string => {
|
||||
getLongString(text).then(string => {
|
||||
let data = formDataURI(mimeType, encoding, string);
|
||||
clipboardHelper.copyString(data);
|
||||
});
|
||||
@ -317,7 +319,7 @@ RequestListContextMenu.prototype = {
|
||||
copyResponse() {
|
||||
const { text } = this.selectedRequest.responseContent.content;
|
||||
|
||||
window.gNetwork.getString(text).then(string => {
|
||||
getLongString(text).then(string => {
|
||||
clipboardHelper.copyString(string);
|
||||
});
|
||||
},
|
||||
@ -341,7 +343,7 @@ RequestListContextMenu.prototype = {
|
||||
let title = form.title || form.url;
|
||||
|
||||
return {
|
||||
getString: window.gNetwork.getString.bind(window.gNetwork),
|
||||
getString: getLongString,
|
||||
items: this.sortedRequests,
|
||||
title: title
|
||||
};
|
||||
|
@ -8,6 +8,7 @@ const {
|
||||
setImageTooltip,
|
||||
getImageDimensions,
|
||||
} = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
|
||||
const { getLongString } = require("./utils/client");
|
||||
const { WEBCONSOLE_L10N } = require("./utils/l10n");
|
||||
const { formDataURI } = require("./utils/request-utils");
|
||||
|
||||
@ -23,7 +24,7 @@ async function setTooltipImageContent(tooltip, itemEl, requestItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let string = await window.gNetwork.getString(text);
|
||||
let string = await getLongString(text);
|
||||
let src = formDataURI(mimeType, encoding, string);
|
||||
let maxDim = REQUESTS_TOOLTIP_IMAGE_MAX_DIM;
|
||||
let { naturalWidth, naturalHeight } = await getImageDimensions(tooltip.doc, src);
|
||||
|
@ -13,9 +13,10 @@ add_task(function* () {
|
||||
let { tab, monitor } = yield initNetMonitor(CURL_UTILS_URL);
|
||||
info("Starting test... ");
|
||||
|
||||
let { gStore, windowRequire, gNetwork } = monitor.panelWin;
|
||||
let { gStore, windowRequire } = monitor.panelWin;
|
||||
let Actions = windowRequire("devtools/client/netmonitor/actions/index");
|
||||
let { getSortedRequests } = windowRequire("devtools/client/netmonitor/selectors/index");
|
||||
let { getLongString } = windowRequire("devtools/client/netmonitor/utils/client");
|
||||
|
||||
gStore.dispatch(Actions.batchEnable(false));
|
||||
|
||||
@ -32,20 +33,20 @@ add_task(function* () {
|
||||
multipartForm: getSortedRequests(gStore.getState()).get(3),
|
||||
};
|
||||
|
||||
let data = yield createCurlData(requests.get, gNetwork);
|
||||
let data = yield createCurlData(requests.get, getLongString);
|
||||
testFindHeader(data);
|
||||
|
||||
data = yield createCurlData(requests.post, gNetwork);
|
||||
data = yield createCurlData(requests.post, getLongString);
|
||||
testIsUrlEncodedRequest(data);
|
||||
testWritePostDataTextParams(data);
|
||||
|
||||
data = yield createCurlData(requests.multipart, gNetwork);
|
||||
data = yield createCurlData(requests.multipart, getLongString);
|
||||
testIsMultipartRequest(data);
|
||||
testGetMultipartBoundary(data);
|
||||
testMultiPartHeaders(data);
|
||||
testRemoveBinaryDataFromMultipartText(data);
|
||||
|
||||
data = yield createCurlData(requests.multipartForm, gNetwork);
|
||||
data = yield createCurlData(requests.multipartForm, getLongString);
|
||||
testMultiPartHeaders(data);
|
||||
|
||||
testGetHeadersFromMultipartText({
|
||||
@ -214,7 +215,7 @@ function testEscapeStringWin() {
|
||||
"Newlines should be escaped.");
|
||||
}
|
||||
|
||||
function* createCurlData(selected, network, controller) {
|
||||
function* createCurlData(selected, getLongString) {
|
||||
let { url, method, httpVersion } = selected;
|
||||
|
||||
// Create a sanitized object for the Curl command generator.
|
||||
@ -228,14 +229,14 @@ function* createCurlData(selected, network, controller) {
|
||||
|
||||
// Fetch header values.
|
||||
for (let { name, value } of selected.requestHeaders.headers) {
|
||||
let text = yield network.getString(value);
|
||||
let text = yield getLongString(value);
|
||||
data.headers.push({ name: name, value: text });
|
||||
}
|
||||
|
||||
// Fetch the request payload.
|
||||
if (selected.requestPostData) {
|
||||
let postData = selected.requestPostData.postData.text;
|
||||
data.postDataText = yield network.getString(postData);
|
||||
data.postDataText = yield getLongString(postData);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -10,6 +10,8 @@ const Services = require("Services");
|
||||
const Actions = require("../actions/index");
|
||||
const { EVENTS } = require("../constants");
|
||||
|
||||
let activeConsole;
|
||||
|
||||
/**
|
||||
* Called for each location change in the monitored tab.
|
||||
*
|
||||
@ -45,6 +47,7 @@ function willNavigate(type) {
|
||||
* @param {Object} tabTarget
|
||||
*/
|
||||
function onFirefoxConnect(tabTarget) {
|
||||
activeConsole = tabTarget.activeConsole;
|
||||
tabTarget.on("navigate", navigated);
|
||||
tabTarget.on("will-navigate", willNavigate);
|
||||
}
|
||||
@ -55,11 +58,44 @@ function onFirefoxConnect(tabTarget) {
|
||||
* @param {Object} tabTarget
|
||||
*/
|
||||
function onFirefoxDisconnect(tabTarget) {
|
||||
activeConsole = null;
|
||||
tabTarget.off("navigate", navigated);
|
||||
tabTarget.off("will-navigate", willNavigate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve webconsole object
|
||||
*
|
||||
* @returns {Object} webConsole
|
||||
*/
|
||||
function getWebConsoleClient() {
|
||||
return activeConsole;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the full text of a LongString.
|
||||
*
|
||||
* @param object | string stringGrip
|
||||
* The long string grip containing the corresponding actor.
|
||||
* If you pass in a plain string (by accident or because you're lazy),
|
||||
* then a promise of the same string is simply returned.
|
||||
* @return object Promise
|
||||
* A promise that is resolved when the full string contents
|
||||
* are available, or rejected if something goes wrong.
|
||||
*/
|
||||
function getLongString(stringGrip) {
|
||||
// FIXME: this.webConsoleClient will be undefined in mochitest,
|
||||
// so we return string instantly to skip undefined error
|
||||
if (typeof stringGrip === "string") {
|
||||
return Promise.resolve(stringGrip);
|
||||
}
|
||||
|
||||
return activeConsole.getString(stringGrip);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getLongString,
|
||||
getWebConsoleClient,
|
||||
onFirefoxConnect,
|
||||
onFirefoxDisconnect,
|
||||
};
|
||||
|
@ -13,10 +13,9 @@
|
||||
* @param {object} headers - the "requestHeaders".
|
||||
* @param {object} uploadHeaders - the "requestHeadersFromUploadStream".
|
||||
* @param {object} postData - the "requestPostData".
|
||||
* @param {function} getString - callback to retrieve a string from a LongStringGrip.
|
||||
* @return {array} a promise list that is resolved with the extracted form data.
|
||||
*/
|
||||
async function getFormDataSections(headers, uploadHeaders, postData, getString) {
|
||||
async function getFormDataSections(headers, uploadHeaders, postData, getLongString) {
|
||||
let formDataSections = [];
|
||||
|
||||
let requestHeaders = headers.headers;
|
||||
@ -29,11 +28,11 @@ async function getFormDataSections(headers, uploadHeaders, postData, getString)
|
||||
|
||||
let contentTypeLongString = contentTypeHeader ? contentTypeHeader.value : "";
|
||||
|
||||
let contentType = await getString(contentTypeLongString);
|
||||
let contentType = await getLongString(contentTypeLongString);
|
||||
|
||||
if (contentType.includes("x-www-form-urlencoded")) {
|
||||
let postDataLongString = postData.postData.text;
|
||||
let text = await getString(postDataLongString);
|
||||
let text = await getLongString(postDataLongString);
|
||||
|
||||
for (let section of text.split(/\r\n|\r|\n/)) {
|
||||
// Before displaying it, make sure this section of the POST data
|
||||
@ -51,12 +50,11 @@ async function getFormDataSections(headers, uploadHeaders, postData, getString)
|
||||
* Fetch headers full content from actor server
|
||||
*
|
||||
* @param {object} headers - a object presents headers data
|
||||
* @param {function} getString - callback to retrieve a string from a LongStringGrip
|
||||
* @return {object} a headers object with updated content payload
|
||||
*/
|
||||
async function fetchHeaders(headers, getString) {
|
||||
async function fetchHeaders(headers, getLongString) {
|
||||
for (let { value } of headers.headers) {
|
||||
headers.headers.value = await getString(value);
|
||||
headers.headers.value = await getLongString(value);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
@ -301,9 +301,16 @@ pref("devtools.webconsole.new-frontend-enabled", true);
|
||||
pref("devtools.webconsole.new-frontend-enabled", false);
|
||||
#endif
|
||||
|
||||
// Enable the experimental support for source maps in console (work in progress)
|
||||
// Enable the server-side mapping service for source maps in console (deprecated)
|
||||
// NOTE: This approach to source maps uses server-side source maps, which we are
|
||||
// replacing with client-side source maps. Do not use this in new code paths.
|
||||
// To be removed in bug 1349354. Read more about ongoing work with source maps:
|
||||
// https://docs.google.com/document/d/19TKnMJD3CMBzwByNE4aBBVWnl-AEan8Sf4hxi6J-eps/edit
|
||||
pref("devtools.source-map.locations.enabled", false);
|
||||
|
||||
// Enable client-side mapping service for source maps
|
||||
pref("devtools.source-map.client-service.enabled", true);
|
||||
|
||||
// The number of lines that are displayed in the web console.
|
||||
pref("devtools.hud.loglimit", 1000);
|
||||
|
||||
|
@ -17,8 +17,9 @@ const BROWSER_BASED_DIRS = [
|
||||
"resource://devtools/client/inspector/grids",
|
||||
"resource://devtools/client/inspector/layout",
|
||||
"resource://devtools/client/jsonview",
|
||||
"resource://devtools/client/shared/vendor",
|
||||
"resource://devtools/client/shared/source-map",
|
||||
"resource://devtools/client/shared/redux",
|
||||
"resource://devtools/client/shared/vendor",
|
||||
];
|
||||
|
||||
const COMMON_LIBRARY_DIRS = [
|
||||
|
@ -85,7 +85,8 @@ NewConsoleOutputWrapper.prototype = {
|
||||
return panel.panelWin.NetMonitorController.inspectRequest(requestId);
|
||||
});
|
||||
},
|
||||
sourceMapService: this.toolbox ? this.toolbox._sourceMapService : null,
|
||||
sourceMapService:
|
||||
this.toolbox ? this.toolbox._deprecatedServerSourceMapService : null,
|
||||
openLink: url => this.jsterm.hud.owner.openLink(url),
|
||||
createElement: nodename => {
|
||||
return this.document.createElementNS("http://www.w3.org/1999/xhtml", nodename);
|
||||
|
@ -2624,7 +2624,7 @@ WebConsoleFrame.prototype = {
|
||||
frame: { source, line, column },
|
||||
showEmptyPathAsHost: true,
|
||||
onClick,
|
||||
sourceMapService: toolbox ? toolbox._sourceMapService : null,
|
||||
sourceMapService: toolbox ? toolbox._deprecatedServerSourceMapService : null,
|
||||
}), locationNode);
|
||||
|
||||
return locationNode;
|
||||
|
@ -11,8 +11,8 @@ load 746813-1.html
|
||||
load 743499-negative-size.html
|
||||
skip-if(Android) load 745818-large-source.html # Bug XXX - Crashes Android mid-run w/o a stack
|
||||
load 767337-1.html
|
||||
asserts-if(stylo,1) skip-if(Android) skip-if(webrender) load 780392-1.html # bug 1324700. bug 1322816 for webrender
|
||||
skip-if(Android) skip-if(gtkWidget&&isDebugBuild) skip-if(webrender) load 789933-1.html # bug 1155252 for linux, bug 1322816 for webrender
|
||||
asserts-if(stylo,1) skip-if(Android) load 780392-1.html # bug 1324700
|
||||
skip-if(Android) skip-if(gtkWidget&&isDebugBuild) load 789933-1.html # bug 1155252 for linux
|
||||
load 794463-1.html
|
||||
load 802926-1.html
|
||||
load 896047-1.html
|
||||
|
@ -5,7 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
with Files('*'):
|
||||
BUG_COMPONENT = ('Core', 'Video/Audio: Recording')
|
||||
BUG_COMPONENT = ('Core', 'Audio/Video: Recording')
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
DIRS += ['fmp4_muxer']
|
||||
|
@ -51,7 +51,7 @@ MFTDecoder::SetMediaTypes(IMFMediaType* aInputType,
|
||||
HRESULT hr = mDecoder->SetInputType(0, aInputType, 0);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = SetDecoderOutputType(aCallback, aData);
|
||||
hr = SetDecoderOutputType(true /* match all attributes */, aCallback, aData);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = mDecoder->GetInputStreamInfo(0, &mInputStreamInfo);
|
||||
@ -76,21 +76,34 @@ MFTDecoder::GetAttributes()
|
||||
}
|
||||
|
||||
HRESULT
|
||||
MFTDecoder::SetDecoderOutputType(ConfigureOutputCallback aCallback, void* aData)
|
||||
MFTDecoder::SetDecoderOutputType(bool aMatchAllAttributes,
|
||||
ConfigureOutputCallback aCallback,
|
||||
void* aData)
|
||||
{
|
||||
NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
|
||||
|
||||
GUID currentSubtype = {0};
|
||||
HRESULT hr = mOutputType->GetGUID(MF_MT_SUBTYPE, ¤tSubtype);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
// Iterate the enumerate the output types, until we find one compatible
|
||||
// with what we need.
|
||||
HRESULT hr;
|
||||
RefPtr<IMFMediaType> outputType;
|
||||
UINT32 typeIndex = 0;
|
||||
while (SUCCEEDED(mDecoder->GetOutputAvailableType(
|
||||
0, typeIndex++, getter_AddRefs(outputType)))) {
|
||||
BOOL resultMatch;
|
||||
hr = mOutputType->Compare(
|
||||
outputType, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &resultMatch);
|
||||
if (SUCCEEDED(hr) && resultMatch == TRUE) {
|
||||
GUID outSubtype = {0};
|
||||
hr = outputType->GetGUID(MF_MT_SUBTYPE, &outSubtype);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
BOOL resultMatch = currentSubtype == outSubtype;
|
||||
|
||||
if (resultMatch && aMatchAllAttributes) {
|
||||
hr = mOutputType->Compare(outputType, MF_ATTRIBUTES_MATCH_OUR_ITEMS,
|
||||
&resultMatch);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
}
|
||||
if (resultMatch == TRUE) {
|
||||
if (aCallback) {
|
||||
hr = aCallback(outputType, aData);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
@ -224,13 +237,6 @@ MFTDecoder::Output(RefPtr<IMFSample>* aOutput)
|
||||
}
|
||||
|
||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
|
||||
// Type change, probably geometric aperture change.
|
||||
// Reconfigure decoder output type, so that GetOutputMediaType()
|
||||
// returns the new type, and return the error code to caller.
|
||||
// This is an expected failure, so don't warn on encountering it.
|
||||
hr = SetDecoderOutputType(nullptr, nullptr);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
// Return the error, so that the caller knows to retry.
|
||||
return MF_E_TRANSFORM_STREAM_CHANGE;
|
||||
}
|
||||
|
||||
|
@ -87,11 +87,10 @@ public:
|
||||
// Sends a message to the MFT.
|
||||
HRESULT SendMFTMessage(MFT_MESSAGE_TYPE aMsg, ULONG_PTR aData);
|
||||
|
||||
|
||||
HRESULT SetDecoderOutputType(ConfigureOutputCallback aCallback, void* aData);
|
||||
HRESULT SetDecoderOutputType(bool aMatchAllAttributes,
|
||||
ConfigureOutputCallback aCallback,
|
||||
void* aData);
|
||||
private:
|
||||
|
||||
|
||||
HRESULT CreateOutputSample(RefPtr<IMFSample>* aOutSample);
|
||||
|
||||
MFT_INPUT_STREAM_INFO mInputStreamInfo;
|
||||
|
@ -180,6 +180,12 @@ WMFAudioMFTManager::Init()
|
||||
hr = outputType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 32);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
||||
hr = outputType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, mAudioChannels);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
||||
hr = outputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
||||
hr = decoder->SetMediaTypes(inputType, outputType);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
||||
@ -233,6 +239,9 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
|
||||
return hr;
|
||||
}
|
||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
|
||||
hr = mDecoder->SetDecoderOutputType(true /* check all attribute */,
|
||||
nullptr,
|
||||
nullptr);
|
||||
hr = UpdateOutputType();
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
// Catch infinite loops, but some decoders perform at least 2 stream
|
||||
|
@ -109,8 +109,8 @@ WMFVideoMFTManager::WMFVideoMFTManager(
|
||||
layers::ImageContainer* aImageContainer,
|
||||
bool aDXVAEnabled)
|
||||
: mVideoInfo(aConfig)
|
||||
, mVideoStride(0)
|
||||
, mImageSize(aConfig.mImage)
|
||||
, mVideoStride(0)
|
||||
, mImageContainer(aImageContainer)
|
||||
, mDXVAEnabled(aDXVAEnabled)
|
||||
, mKnowsCompositor(aKnowsCompositor)
|
||||
@ -572,9 +572,36 @@ WMFVideoMFTManager::InitInternal()
|
||||
hr = SetDecoderMediaTypes();
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
||||
RefPtr<IMFMediaType> outputType;
|
||||
hr = mDecoder->GetOutputMediaType(outputType);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
if (mUseHwAccel && !CanUseDXVA(outputType)) {
|
||||
mDXVAEnabled = false;
|
||||
// DXVA initialization actually failed, re-do initialisation.
|
||||
return InitInternal();
|
||||
}
|
||||
|
||||
LOG("Video Decoder initialized, Using DXVA: %s",
|
||||
(mUseHwAccel ? "Yes" : "No"));
|
||||
|
||||
if (mDXVA2Manager) {
|
||||
hr = mDXVA2Manager->ConfigureForSize(mVideoInfo.ImageRect().width,
|
||||
mVideoInfo.ImageRect().height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
} else {
|
||||
GetDefaultStride(outputType, mVideoInfo.ImageRect().width, &mVideoStride);
|
||||
}
|
||||
LOG("WMFVideoMFTManager frame geometry stride=%u picture=(%d, %d, %d, %d) "
|
||||
"display=(%d,%d)",
|
||||
mVideoStride,
|
||||
mVideoInfo.ImageRect().x,
|
||||
mVideoInfo.ImageRect().y,
|
||||
mVideoInfo.ImageRect().width,
|
||||
mVideoInfo.ImageRect().height,
|
||||
mVideoInfo.mDisplay.width,
|
||||
mVideoInfo.mDisplay.height);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -596,10 +623,7 @@ WMFVideoMFTManager::SetDecoderMediaTypes()
|
||||
MFVideoInterlace_MixedInterlaceOrProgressive);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
// MSFT MFT needs this frame size set for VP9?
|
||||
if (mStreamType == VP9 || mStreamType == VP8) {
|
||||
hr =
|
||||
inputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
|
||||
hr = inputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = MFSetAttributeSize(inputType,
|
||||
@ -607,7 +631,6 @@ WMFVideoMFTManager::SetDecoderMediaTypes()
|
||||
mVideoInfo.ImageRect().width,
|
||||
mVideoInfo.ImageRect().height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
}
|
||||
|
||||
RefPtr<IMFMediaType> outputType;
|
||||
hr = wmf::MFCreateMediaType(getter_AddRefs(outputType));
|
||||
@ -616,6 +639,12 @@ WMFVideoMFTManager::SetDecoderMediaTypes()
|
||||
hr = outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
hr = MFSetAttributeSize(outputType,
|
||||
MF_MT_FRAME_SIZE,
|
||||
mVideoInfo.ImageRect().width,
|
||||
mVideoInfo.ImageRect().height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
GUID outputSubType = mUseHwAccel ? MFVideoFormat_NV12 : MFVideoFormat_YV12;
|
||||
hr = outputType->SetGUID(MF_MT_SUBTYPE, outputSubType);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
@ -635,18 +664,19 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
RefPtr<IMFSample> inputSample;
|
||||
HRESULT hr = mDecoder->CreateInputSample(aSample->Data(),
|
||||
uint32_t(aSample->Size()),
|
||||
aSample->mTime,
|
||||
&mLastInput);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr) && mLastInput != nullptr, hr);
|
||||
&inputSample);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr) && inputSample != nullptr, hr);
|
||||
|
||||
mLastDuration = aSample->mDuration;
|
||||
mLastTime = aSample->mTime;
|
||||
mSamplesCount++;
|
||||
|
||||
// Forward sample data to the decoder.
|
||||
return mDecoder->Input(mLastInput);
|
||||
return mDecoder->Input(inputSample);
|
||||
}
|
||||
|
||||
class SupportsConfigEvent : public Runnable {
|
||||
@ -717,69 +747,6 @@ WMFVideoMFTManager::CanUseDXVA(IMFMediaType* aType)
|
||||
return event->mSupportsConfig;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WMFVideoMFTManager::ConfigureVideoFrameGeometry()
|
||||
{
|
||||
RefPtr<IMFMediaType> mediaType;
|
||||
HRESULT hr = mDecoder->GetOutputMediaType(mediaType);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
// If we enabled/disabled DXVA in response to a resolution
|
||||
// change then we need to renegotiate our media types,
|
||||
// and resubmit our previous frame (since the MFT appears
|
||||
// to lose it otherwise).
|
||||
if (mUseHwAccel && !CanUseDXVA(mediaType)) {
|
||||
mDXVAEnabled = false;
|
||||
if (!Init()) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
mDecoder->Input(mLastInput);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Verify that the video subtype is what we expect it to be.
|
||||
// When using hardware acceleration/DXVA2 the video format should
|
||||
// be NV12, which is DXVA2's preferred format. For software decoding
|
||||
// we use YV12, as that's easier for us to stick into our rendering
|
||||
// pipeline than NV12. NV12 has interleaved UV samples, whereas YV12
|
||||
// is a planar format.
|
||||
GUID videoFormat;
|
||||
hr = mediaType->GetGUID(MF_MT_SUBTYPE, &videoFormat);
|
||||
NS_ENSURE_TRUE(videoFormat == MFVideoFormat_NV12 || !mUseHwAccel, E_FAIL);
|
||||
NS_ENSURE_TRUE(videoFormat == MFVideoFormat_YV12 || mUseHwAccel, E_FAIL);
|
||||
|
||||
nsIntRect pictureRegion;
|
||||
hr = GetPictureRegion(mediaType, pictureRegion);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
UINT32 width = pictureRegion.width;
|
||||
UINT32 height = pictureRegion.height;
|
||||
mImageSize = nsIntSize(width, height);
|
||||
// Calculate and validate the picture region and frame dimensions after
|
||||
// scaling by the pixel aspect ratio.
|
||||
pictureRegion = mVideoInfo.ScaledImageRect(width, height);
|
||||
if (!IsValidVideoRegion(mImageSize, pictureRegion, mVideoInfo.mDisplay)) {
|
||||
// Video track's frame sizes will overflow. Ignore the video track.
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (mDXVA2Manager) {
|
||||
hr = mDXVA2Manager->ConfigureForSize(width, height);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
}
|
||||
|
||||
// Success! Save state.
|
||||
GetDefaultStride(mediaType, width, &mVideoStride);
|
||||
|
||||
LOG("WMFVideoMFTManager frame geometry frame=(%u,%u) stride=%u picture=(%d, %d, %d, %d) display=(%d,%d)",
|
||||
width, height,
|
||||
mVideoStride,
|
||||
pictureRegion.x, pictureRegion.y, pictureRegion.width, pictureRegion.height,
|
||||
mVideoInfo.mDisplay.width, mVideoInfo.mDisplay.height);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
|
||||
@ -973,13 +940,25 @@ WMFVideoMFTManager::Output(int64_t aStreamOffset,
|
||||
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
|
||||
return MF_E_TRANSFORM_NEED_MORE_INPUT;
|
||||
}
|
||||
|
||||
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
|
||||
// Video stream output type change. Probably a geometric apperature
|
||||
// change. Reconfigure the video geometry, so that we output the
|
||||
// correct size frames.
|
||||
MOZ_ASSERT(!sample);
|
||||
hr = ConfigureVideoFrameGeometry();
|
||||
// Video stream output type change, probably geometric aperture change.
|
||||
// We must reconfigure the decoder output type.
|
||||
hr = mDecoder->SetDecoderOutputType(false /* check all attribute */,
|
||||
nullptr,
|
||||
nullptr);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
|
||||
if (!mUseHwAccel) {
|
||||
// The stride may have changed, recheck for it.
|
||||
RefPtr<IMFMediaType> outputType;
|
||||
hr = mDecoder->GetOutputMediaType(outputType);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
hr = GetDefaultStride(outputType, mVideoInfo.ImageRect().width,
|
||||
&mVideoStride);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||
}
|
||||
// Catch infinite loops, but some decoders perform at least 2 stream
|
||||
// changes on consecutive calls, so be permissive.
|
||||
// 100 is arbitrarily > 2.
|
||||
@ -988,6 +967,7 @@ WMFVideoMFTManager::Output(int64_t aStreamOffset,
|
||||
++typeChangeCount;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (!sample) {
|
||||
LOG("Video MFTDecoder returned success but no output!");
|
||||
|
@ -73,8 +73,6 @@ private:
|
||||
|
||||
bool InitInternal();
|
||||
|
||||
HRESULT ConfigureVideoFrameGeometry();
|
||||
|
||||
HRESULT CreateBasicVideoFrame(IMFSample* aSample,
|
||||
int64_t aStreamOffset,
|
||||
VideoData** aOutVideoData);
|
||||
@ -88,15 +86,14 @@ private:
|
||||
bool CanUseDXVA(IMFMediaType* aType);
|
||||
|
||||
// Video frame geometry.
|
||||
VideoInfo mVideoInfo;
|
||||
const VideoInfo mVideoInfo;
|
||||
const nsIntSize mImageSize;
|
||||
uint32_t mVideoStride;
|
||||
nsIntSize mImageSize;
|
||||
|
||||
RefPtr<layers::ImageContainer> mImageContainer;
|
||||
RefPtr<layers::KnowsCompositor> mKnowsCompositor;
|
||||
nsAutoPtr<DXVA2Manager> mDXVA2Manager;
|
||||
|
||||
RefPtr<IMFSample> mLastInput;
|
||||
float mLastDuration;
|
||||
int64_t mLastTime = 0;
|
||||
bool mDraining = false;
|
||||
|
@ -10,7 +10,7 @@ load 493915-1.html
|
||||
load 495794-1.html
|
||||
load 576612-1.html
|
||||
load 752784-1.html
|
||||
skip-if(webrender) load 789075-1.html # bug 1322816 for webrender
|
||||
load 789075-1.html
|
||||
HTTP load 795892-1.html
|
||||
load 844563.html
|
||||
load 846612.html
|
||||
|
@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc
|
||||
the need to run the cargo update command in js/src as well. Hopefully this will
|
||||
be resolved soon.
|
||||
|
||||
Latest Commit: e30fb2914928c0e596d8632ed234647c0fd1492e
|
||||
Latest Commit: 0794911f97cae92496fca992d7430da696fa24eb
|
||||
|
@ -8,13 +8,13 @@
|
||||
#include "gfxConfig.h"
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Tokenizer.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
@ -151,7 +151,7 @@ static bool
|
||||
IsAccelAngleSupported(const nsCOMPtr<nsIGfxInfo>& gfxInfo,
|
||||
nsACString* const out_failureId)
|
||||
{
|
||||
if (CompositorThreadHolder::IsInCompositorThread()) {
|
||||
if (wr::RenderThread::IsInRenderThread()) {
|
||||
// We can only enter here with WebRender, so assert that this is a
|
||||
// WebRender-enabled build.
|
||||
#ifndef MOZ_BUILD_WEBRENDER
|
||||
|
@ -1839,6 +1839,8 @@ CompositorBridgeParent::NotifyDidCompositeToPipeline(const wr::PipelineId& aPipe
|
||||
}
|
||||
MOZ_ASSERT(mWrBridge);
|
||||
|
||||
mWrBridge->CompositableHolder()->Update(aPipelineId, aEpoch);
|
||||
|
||||
if (mWrBridge->PipelineId() == aPipelineId) {
|
||||
uint64_t transactionId = mWrBridge->FlushTransactionIdsForEpoch(aEpoch);
|
||||
Unused << SendDidComposite(0, transactionId, aCompositeStart, aCompositeEnd);
|
||||
|
@ -134,6 +134,11 @@ void
|
||||
CompositorVsyncScheduler::ScheduleComposition()
|
||||
{
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
if (!mVsyncObserver) {
|
||||
// Destroy was already called on this object.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAsapScheduling) {
|
||||
// Used only for performance testing purposes
|
||||
PostCompositeTask(TimeStamp::Now());
|
||||
|
@ -223,7 +223,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli
|
||||
|
||||
WebRenderBridgeParent* parent = nullptr;
|
||||
RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI();
|
||||
RefPtr<WebRenderCompositableHolder> holder = new WebRenderCompositableHolder();
|
||||
RefPtr<WebRenderCompositableHolder> holder = root->CompositableHolder();
|
||||
parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder));
|
||||
|
||||
parent->AddRef(); // IPDL reference
|
||||
|
@ -192,7 +192,6 @@ EXPORTS.mozilla.layers += [
|
||||
'TextureSourceProvider.h',
|
||||
'TextureWrapperImage.h',
|
||||
'TransactionIdAllocator.h',
|
||||
'wr/WebRenderBorderLayer.h',
|
||||
'wr/WebRenderBridgeChild.h',
|
||||
'wr/WebRenderBridgeParent.h',
|
||||
'wr/WebRenderCompositableHolder.h',
|
||||
@ -379,7 +378,6 @@ UNIFIED_SOURCES += [
|
||||
'SourceSurfaceVolatileData.cpp',
|
||||
'TextureSourceProvider.cpp',
|
||||
'TextureWrapperImage.cpp',
|
||||
'wr/WebRenderBorderLayer.cpp',
|
||||
'wr/WebRenderBridgeChild.cpp',
|
||||
'wr/WebRenderBridgeParent.cpp',
|
||||
'wr/WebRenderCanvasLayer.cpp',
|
||||
|
@ -1,79 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebRenderBorderLayer.h"
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "mozilla/webrender/webrender_ffi.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
/* static */void
|
||||
WebRenderBorderLayer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
|
||||
WebRenderLayer* aLayer,
|
||||
BorderColors& aColors,
|
||||
BorderCorners& aCorners,
|
||||
BorderWidths& aWidths,
|
||||
BorderStyles& aBorderStyles,
|
||||
Rect aRect,
|
||||
Rect aClipRect,
|
||||
Rect aRelBounds,
|
||||
Rect aOverflow)
|
||||
{
|
||||
aBuilder.PushStackingContext(wr::ToWrRect(aRelBounds),
|
||||
wr::ToWrRect(aOverflow),
|
||||
nullptr,
|
||||
1.0f,
|
||||
aLayer->GetLayer()->GetTransform(),
|
||||
wr::MixBlendMode::Normal);
|
||||
aBuilder.PushBorder(wr::ToWrRect(aRect), aBuilder.BuildClipRegion(wr::ToWrRect(aClipRect)),
|
||||
wr::ToWrBorderWidths(aWidths[0], aWidths[1], aWidths[2], aWidths[3]),
|
||||
wr::ToWrBorderSide(aColors[0], aBorderStyles[0]),
|
||||
wr::ToWrBorderSide(aColors[1], aBorderStyles[1]),
|
||||
wr::ToWrBorderSide(aColors[2], aBorderStyles[2]),
|
||||
wr::ToWrBorderSide(aColors[3], aBorderStyles[3]),
|
||||
wr::ToWrBorderRadius(aCorners[eCornerTopLeft], aCorners[eCornerTopRight],
|
||||
aCorners[eCornerBottomLeft], aCorners[eCornerBottomRight]));
|
||||
aBuilder.PopStackingContext();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBorderLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
|
||||
{
|
||||
gfx::Rect relBounds = GetWrRelBounds();
|
||||
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
|
||||
|
||||
gfx::Rect rect = GetWrBoundsRect();
|
||||
gfx::Rect clipRect = GetWrClipRect(rect);
|
||||
|
||||
DumpLayerInfo("BorderLayer", rect);
|
||||
|
||||
aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
|
||||
wr::ToWrRect(overflow),
|
||||
nullptr,
|
||||
1.0f,
|
||||
//GetAnimations(),
|
||||
GetTransform(),
|
||||
wr::MixBlendMode::Normal);
|
||||
aBuilder.PushBorder(wr::ToWrRect(rect), aBuilder.BuildClipRegion(wr::ToWrRect(clipRect)),
|
||||
wr::ToWrBorderWidths(mWidths[0], mWidths[1], mWidths[2], mWidths[3]),
|
||||
wr::ToWrBorderSide(mColors[0], mBorderStyles[0]),
|
||||
wr::ToWrBorderSide(mColors[1], mBorderStyles[1]),
|
||||
wr::ToWrBorderSide(mColors[2], mBorderStyles[2]),
|
||||
wr::ToWrBorderSide(mColors[3], mBorderStyles[3]),
|
||||
wr::ToWrBorderRadius(mCorners[eCornerTopLeft], mCorners[eCornerTopRight],
|
||||
mCorners[eCornerBottomLeft], mCorners[eCornerBottomRight]));
|
||||
aBuilder.PopStackingContext();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
@ -1,50 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_WEBRENDERBORDERLAYER_H
|
||||
#define GFX_WEBRENDERBORDERLAYER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "WebRenderLayerManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class WebRenderBorderLayer : public WebRenderLayer,
|
||||
public BorderLayer {
|
||||
public:
|
||||
explicit WebRenderBorderLayer(WebRenderLayerManager* aLayerManager)
|
||||
: BorderLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(WebRenderBorderLayer);
|
||||
}
|
||||
|
||||
static void
|
||||
CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
|
||||
WebRenderLayer* aLayer,
|
||||
BorderColors& aColors,
|
||||
BorderCorners& aCorners,
|
||||
BorderWidths& aWidths,
|
||||
BorderStyles& aBorderStyles,
|
||||
gfx::Rect aRect,
|
||||
gfx::Rect aClipRect,
|
||||
gfx::Rect aRelBounds,
|
||||
gfx::Rect aOverflow);
|
||||
|
||||
protected:
|
||||
virtual ~WebRenderBorderLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderBorderLayer);
|
||||
}
|
||||
|
||||
public:
|
||||
Layer* GetLayer() override { return this; }
|
||||
void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_WEBRENDERBORDERLAYER_H
|
@ -37,6 +37,17 @@ bool is_in_render_thread()
|
||||
return mozilla::wr::RenderThread::IsInRenderThread();
|
||||
}
|
||||
|
||||
bool is_glcontext_egl(void* glcontext_ptr)
|
||||
{
|
||||
MOZ_ASSERT(glcontext_ptr);
|
||||
|
||||
mozilla::gl::GLContext* glcontext = reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
|
||||
if (!glcontext) {
|
||||
return false;
|
||||
}
|
||||
return glcontext->GetContextType() == mozilla::gl::GLContextType::EGL;
|
||||
}
|
||||
|
||||
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
|
||||
{
|
||||
MOZ_ASSERT(glcontext_ptr);
|
||||
@ -102,6 +113,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos
|
||||
, mDestroyed(false)
|
||||
{
|
||||
MOZ_ASSERT(mCompositableHolder);
|
||||
mCompositableHolder->AddPipeline(mPipelineId);
|
||||
if (mWidget) {
|
||||
MOZ_ASSERT(!mCompositorScheduler);
|
||||
mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
|
||||
@ -316,7 +328,7 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
|
||||
mApi->AddExternalImageBuffer(key,
|
||||
descriptor,
|
||||
wrTexture->GetExternalImageKey());
|
||||
mCompositableHolder->HoldExternalImage(aEpoch, texture->AsWebRenderTextureHost());
|
||||
mCompositableHolder->HoldExternalImage(mPipelineId, aEpoch, texture->AsWebRenderTextureHost());
|
||||
keysToDelete.push_back(key);
|
||||
break;
|
||||
}
|
||||
@ -337,10 +349,6 @@ WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
|
||||
|
||||
keysToDelete.push_back(key);
|
||||
dSurf->Unmap();
|
||||
// XXX workaround for releasing Readlock. See Bug 1339625
|
||||
if(host->GetType() == CompositableType::CONTENT_SINGLE) {
|
||||
host->CleanupResources();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WebRenderParentCommand::TCompositableOperation: {
|
||||
@ -563,9 +571,6 @@ WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch)
|
||||
}
|
||||
mPendingTransactionIds.pop();
|
||||
}
|
||||
|
||||
mCompositableHolder->Update(aEpoch);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -602,9 +607,7 @@ WebRenderBridgeParent::ClearResources()
|
||||
DeleteOldImages();
|
||||
}
|
||||
}
|
||||
if (mCompositableHolder) {
|
||||
mCompositableHolder->Destroy();
|
||||
}
|
||||
mCompositableHolder->RemovePipeline(mPipelineId);
|
||||
mExternalImageIds.Clear();
|
||||
|
||||
if (mWidget && mCompositorScheduler) {
|
||||
|
@ -23,36 +23,54 @@ WebRenderCompositableHolder::WebRenderCompositableHolder()
|
||||
WebRenderCompositableHolder::~WebRenderCompositableHolder()
|
||||
{
|
||||
MOZ_COUNT_DTOR(WebRenderCompositableHolder);
|
||||
MOZ_ASSERT(mWebRenderTextureHosts.empty());
|
||||
MOZ_ASSERT(mPipelineTexturesHolders.IsEmpty());
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCompositableHolder::Destroy()
|
||||
WebRenderCompositableHolder::AddPipeline(const wr::PipelineId& aPipelineId)
|
||||
{
|
||||
while (!mWebRenderTextureHosts.empty()) {
|
||||
mWebRenderTextureHosts.pop();
|
||||
uint64_t id = wr::AsUint64(aPipelineId);
|
||||
|
||||
MOZ_ASSERT(!mPipelineTexturesHolders.Get(id));
|
||||
PipelineTexturesHolder* holder = new PipelineTexturesHolder();
|
||||
mPipelineTexturesHolders.Put(id, holder);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCompositableHolder::RemovePipeline(const wr::PipelineId& aPipelineId)
|
||||
{
|
||||
uint64_t id = wr::AsUint64(aPipelineId);
|
||||
if (mPipelineTexturesHolders.Get(id)) {
|
||||
mPipelineTexturesHolders.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCompositableHolder::HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
|
||||
WebRenderCompositableHolder::HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(aTexture);
|
||||
PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId));
|
||||
MOZ_ASSERT(holder);
|
||||
if (!holder) {
|
||||
return;
|
||||
}
|
||||
// Hold WebRenderTextureHost until end of its usage on RenderThread
|
||||
mWebRenderTextureHosts.push(ForwardingTextureHosts(aEpoch, aTexture));
|
||||
holder->mTextureHosts.push(ForwardingTextureHost(aEpoch, aTexture));
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderCompositableHolder::Update(const wr::Epoch& aEpoch)
|
||||
WebRenderCompositableHolder::Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch)
|
||||
{
|
||||
if (mWebRenderTextureHosts.empty()) {
|
||||
PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId));
|
||||
if (!holder || holder->mTextureHosts.empty()) {
|
||||
return;
|
||||
}
|
||||
while (!mWebRenderTextureHosts.empty()) {
|
||||
if (aEpoch <= mWebRenderTextureHosts.front().mEpoch) {
|
||||
|
||||
while (!holder->mTextureHosts.empty()) {
|
||||
if (aEpoch <= holder->mTextureHosts.front().mEpoch) {
|
||||
break;
|
||||
}
|
||||
mWebRenderTextureHosts.pop();
|
||||
holder->mTextureHosts.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
#include "nsClassHashtable.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -33,14 +34,15 @@ protected:
|
||||
~WebRenderCompositableHolder();
|
||||
|
||||
public:
|
||||
void Destroy();
|
||||
void HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
|
||||
void Update(const wr::Epoch& aEpoch);
|
||||
void AddPipeline(const wr::PipelineId& aPipelineId);
|
||||
void RemovePipeline(const wr::PipelineId& aPipelineId);
|
||||
void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
|
||||
void Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch);
|
||||
|
||||
private:
|
||||
|
||||
struct ForwardingTextureHosts {
|
||||
ForwardingTextureHosts(const wr::Epoch& aEpoch, TextureHost* aTexture)
|
||||
struct ForwardingTextureHost {
|
||||
ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
|
||||
: mEpoch(aEpoch)
|
||||
, mTexture(aTexture)
|
||||
{}
|
||||
@ -48,8 +50,12 @@ private:
|
||||
CompositableTextureHostRef mTexture;
|
||||
};
|
||||
|
||||
struct PipelineTexturesHolder {
|
||||
// Holds forwarding WebRenderTextureHosts.
|
||||
std::queue<ForwardingTextureHosts> mWebRenderTextureHosts;
|
||||
std::queue<ForwardingTextureHost> mTextureHosts;
|
||||
};
|
||||
|
||||
nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "mozilla/widget/PlatformWidgetTypes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "TreeTraversal.h"
|
||||
#include "WebRenderBorderLayer.h"
|
||||
#include "WebRenderCanvasLayer.h"
|
||||
#include "WebRenderColorLayer.h"
|
||||
#include "WebRenderContainerLayer.h"
|
||||
@ -541,7 +540,7 @@ WebRenderLayerManager::CreateTextLayer()
|
||||
already_AddRefed<BorderLayer>
|
||||
WebRenderLayerManager::CreateBorderLayer()
|
||||
{
|
||||
return MakeAndAddRef<WebRenderBorderLayer>(this);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<DisplayItemLayer>
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "nsFont.h"
|
||||
#include "gfxFont.h" // for gfxFontStyle
|
||||
#include "gfxFontConstants.h" // for NS_FONT_KERNING_AUTO, etc
|
||||
#include "gfxFontFeatures.h" // for gfxFontFeature, etc
|
||||
#include "gfxFontUtils.h" // for TRUETYPE_TAG
|
||||
#include "nsCRT.h" // for nsCRT
|
||||
@ -20,37 +19,14 @@ using namespace mozilla;
|
||||
|
||||
nsFont::nsFont(const FontFamilyList& aFontlist, nscoord aSize)
|
||||
: fontlist(aFontlist)
|
||||
, size(aSize)
|
||||
{
|
||||
Init();
|
||||
size = aSize;
|
||||
}
|
||||
|
||||
nsFont::nsFont(FontFamilyType aGenericType, nscoord aSize)
|
||||
: fontlist(aGenericType)
|
||||
, size(aSize)
|
||||
{
|
||||
Init();
|
||||
size = aSize;
|
||||
}
|
||||
|
||||
void
|
||||
nsFont::Init()
|
||||
{
|
||||
style = NS_FONT_STYLE_NORMAL;
|
||||
weight = NS_FONT_WEIGHT_NORMAL;
|
||||
stretch = NS_FONT_STRETCH_NORMAL;
|
||||
systemFont = false;
|
||||
smoothing = NS_FONT_SMOOTHING_AUTO;
|
||||
sizeAdjust = -1.0f;
|
||||
kerning = NS_FONT_KERNING_AUTO;
|
||||
synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
|
||||
|
||||
variantAlternates = 0;
|
||||
variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
|
||||
variantEastAsian = 0;
|
||||
variantLigatures = 0;
|
||||
variantNumeric = 0;
|
||||
variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
|
||||
variantWidth = NS_FONT_VARIANT_WIDTH_NORMAL;
|
||||
}
|
||||
|
||||
nsFont::nsFont(const nsFont& aOther) = default;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stdint.h> // for uint8_t, uint16_t
|
||||
#include <sys/types.h> // for int16_t
|
||||
#include "gfxFontFamilyList.h"
|
||||
#include "gfxFontConstants.h" // for NS_FONT_KERNING_AUTO, etc
|
||||
#include "gfxFontFeatures.h"
|
||||
#include "gfxFontVariations.h"
|
||||
#include "mozilla/RefPtr.h" // for RefPtr
|
||||
@ -46,52 +47,52 @@ struct nsFont {
|
||||
mozilla::FontFamilyList fontlist;
|
||||
|
||||
// The style of font (normal, italic, oblique; see gfxFontConstants.h)
|
||||
uint8_t style;
|
||||
uint8_t style = NS_FONT_STYLE_NORMAL;
|
||||
|
||||
// Force this font to not be considered a 'generic' font, even if
|
||||
// the name is the same as a CSS generic font family.
|
||||
bool systemFont;
|
||||
bool systemFont = false;
|
||||
|
||||
// Variant subproperties
|
||||
uint8_t variantCaps;
|
||||
uint8_t variantNumeric;
|
||||
uint8_t variantPosition;
|
||||
uint8_t variantWidth;
|
||||
uint8_t variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
|
||||
uint8_t variantNumeric = 0;
|
||||
uint8_t variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
|
||||
uint8_t variantWidth = NS_FONT_VARIANT_WIDTH_NORMAL;
|
||||
|
||||
uint16_t variantLigatures;
|
||||
uint16_t variantEastAsian;
|
||||
uint16_t variantLigatures = 0;
|
||||
uint16_t variantEastAsian = 0;
|
||||
|
||||
// Some font-variant-alternates property values require
|
||||
// font-specific settings defined via @font-feature-values rules.
|
||||
// These are resolved *after* font matching occurs.
|
||||
|
||||
// -- bitmask for both enumerated and functional propvals
|
||||
uint16_t variantAlternates;
|
||||
uint16_t variantAlternates = 0;
|
||||
|
||||
// Smoothing - controls subpixel-antialiasing (currently OSX only)
|
||||
uint8_t smoothing;
|
||||
uint8_t smoothing = NS_FONT_SMOOTHING_AUTO;
|
||||
|
||||
// The weight of the font; see gfxFontConstants.h.
|
||||
uint16_t weight;
|
||||
uint16_t weight = NS_FONT_WEIGHT_NORMAL;
|
||||
|
||||
// The stretch of the font (the sum of various NS_FONT_STRETCH_*
|
||||
// constants; see gfxFontConstants.h).
|
||||
int16_t stretch;
|
||||
int16_t stretch = NS_FONT_STRETCH_NORMAL;
|
||||
|
||||
// Kerning
|
||||
uint8_t kerning;
|
||||
uint8_t kerning = NS_FONT_KERNING_AUTO;
|
||||
|
||||
// Synthesis setting, controls use of fake bolding/italics
|
||||
uint8_t synthesis;
|
||||
uint8_t synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
|
||||
|
||||
// The logical size of the font, in nscoord units
|
||||
nscoord size;
|
||||
nscoord size = 0;
|
||||
|
||||
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
|
||||
// actual physical font created from this font structure must have when
|
||||
// rendering or measuring a string. A value of -1.0 means no adjustment
|
||||
// needs to be done; otherwise the value must be nonnegative.
|
||||
float sizeAdjust;
|
||||
float sizeAdjust = -1.0f;
|
||||
|
||||
// -- list of value tags for font-specific alternate features
|
||||
nsTArray<gfxAlternateValue> alternateValues;
|
||||
@ -108,7 +109,7 @@ struct nsFont {
|
||||
// Language system tag, to override document language;
|
||||
// this is an OpenType "language system" tag represented as a 32-bit integer
|
||||
// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
|
||||
nsString languageOverride;
|
||||
uint32_t languageOverride = 0;
|
||||
|
||||
// initialize the font with a fontlist
|
||||
nsFont(const mozilla::FontFamilyList& aFontlist, nscoord aSize);
|
||||
@ -142,9 +143,6 @@ struct nsFont {
|
||||
void AddFontFeaturesToStyle(gfxFontStyle *aStyle) const;
|
||||
|
||||
void AddFontVariationsToStyle(gfxFontStyle *aStyle) const;
|
||||
|
||||
protected:
|
||||
void Init(); // helper method for initialization
|
||||
};
|
||||
|
||||
#define NS_FONT_VARIANT_NORMAL 0
|
||||
|
@ -3862,29 +3862,8 @@ gfxFont::RemoveGlyphChangeObserver(GlyphChangeObserver *aObserver)
|
||||
mGlyphChangeObservers->RemoveEntry(aObserver);
|
||||
}
|
||||
|
||||
|
||||
#define DEFAULT_PIXEL_FONT_SIZE 16.0f
|
||||
|
||||
/*static*/ uint32_t
|
||||
gfxFontStyle::ParseFontLanguageOverride(const nsString& aLangTag)
|
||||
{
|
||||
if (!aLangTag.Length() || aLangTag.Length() > 4) {
|
||||
return NO_FONT_LANGUAGE_OVERRIDE;
|
||||
}
|
||||
uint32_t index, result = 0;
|
||||
for (index = 0; index < aLangTag.Length(); ++index) {
|
||||
char16_t ch = aLangTag[index];
|
||||
if (!nsCRT::IsAscii(ch)) { // valid tags are pure ASCII
|
||||
return NO_FONT_LANGUAGE_OVERRIDE;
|
||||
}
|
||||
result = (result << 8) + ch;
|
||||
}
|
||||
while (index++ < 4) {
|
||||
result = (result << 8) + 0x20;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
gfxFontStyle::gfxFontStyle() :
|
||||
language(nsGkAtoms::x_western),
|
||||
size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(-1.0f), baselineOffset(0.0f),
|
||||
@ -3907,10 +3886,10 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
|
||||
bool aPrinterFont,
|
||||
bool aAllowWeightSynthesis,
|
||||
bool aAllowStyleSynthesis,
|
||||
const nsString& aLanguageOverride):
|
||||
uint32_t aLanguageOverride):
|
||||
language(aLanguage),
|
||||
size(aSize), sizeAdjust(aSizeAdjust), baselineOffset(0.0f),
|
||||
languageOverride(ParseFontLanguageOverride(aLanguageOverride)),
|
||||
languageOverride(aLanguageOverride),
|
||||
weight(aWeight), stretch(aStretch),
|
||||
style(aStyle),
|
||||
variantCaps(NS_FONT_VARIANT_CAPS_NORMAL),
|
||||
|
@ -81,7 +81,7 @@ struct gfxFontStyle {
|
||||
float aSizeAdjust, bool aSystemFont,
|
||||
bool aPrinterFont,
|
||||
bool aWeightSynthesis, bool aStyleSynthesis,
|
||||
const nsString& aLanguageOverride);
|
||||
uint32_t aLanguageOverride);
|
||||
|
||||
// the language (may be an internal langGroup code rather than an actual
|
||||
// language code) specified in the document or element's lang property,
|
||||
@ -216,8 +216,6 @@ struct gfxFontStyle {
|
||||
(variationSettings == other.variationSettings) &&
|
||||
(languageOverride == other.languageOverride);
|
||||
}
|
||||
|
||||
static uint32_t ParseFontLanguageOverride(const nsString& aLangTag);
|
||||
};
|
||||
|
||||
struct gfxTextRange {
|
||||
|
@ -684,6 +684,9 @@ gfxPlatform::Init()
|
||||
#error "No gfxPlatform implementation available"
|
||||
#endif
|
||||
gPlatform->InitAcceleration();
|
||||
if (XRE_IsParentProcess()) {
|
||||
gPlatform->InitWebRenderConfig();
|
||||
}
|
||||
|
||||
if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {
|
||||
GPUProcessManager* gpu = GPUProcessManager::Get();
|
||||
@ -2197,7 +2200,6 @@ gfxPlatform::InitAcceleration()
|
||||
Preferences::RegisterCallbackAndCall(VideoDecodingFailedChangedCallback,
|
||||
"media.hardware-video-decoding.failed");
|
||||
InitGPUProcessPrefs();
|
||||
InitWebRenderConfig();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -464,6 +464,7 @@ private:
|
||||
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.bullet-layers", LayersAllowBulletLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.button-foreground-layers", LayersAllowButtonForegroundLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.canvas-background-color", LayersAllowCanvasBackgroundColorLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, bool, false);
|
||||
|
@ -206,7 +206,7 @@ public:
|
||||
// weight - [100, 900] (multiples of 100)
|
||||
// stretch = [NS_FONT_STRETCH_ULTRA_CONDENSED, NS_FONT_STRETCH_ULTRA_EXPANDED]
|
||||
// italic style = constants in gfxFontConstants.h, e.g. NS_FONT_STYLE_NORMAL
|
||||
// language override = result of calling gfxFontStyle::ParseFontLanguageOverride
|
||||
// language override = result of calling nsRuleNode::ParseFontLanguageOverride
|
||||
// TODO: support for unicode ranges not yet implemented
|
||||
virtual already_AddRefed<gfxUserFontEntry> CreateUserFontEntry(
|
||||
const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "webrender"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/servo/webrender"
|
||||
@ -18,11 +18,11 @@ bit-set = "0.4"
|
||||
byteorder = "1.0"
|
||||
euclid = "0.11"
|
||||
fnv = "1.0"
|
||||
gleam = "0.2.30"
|
||||
gleam = "0.4.1"
|
||||
lazy_static = "0.2"
|
||||
log = "0.3"
|
||||
num-traits = "0.1.32"
|
||||
offscreen_gl_context = {version = "0.6", features = ["serde", "osmesa"]}
|
||||
offscreen_gl_context = {version = "0.8.0", features = ["serde", "osmesa"]}
|
||||
time = "0.1"
|
||||
threadpool = "1.3.2"
|
||||
webrender_traits = {path = "../webrender_traits"}
|
||||
|
@ -503,52 +503,104 @@ struct TransformVertexInfo {
|
||||
vec4 clipped_local_rect;
|
||||
};
|
||||
|
||||
float cross2(vec2 v0, vec2 v1) {
|
||||
return v0.x * v1.y - v0.y * v1.x;
|
||||
}
|
||||
|
||||
// Return intersection of line (p0,p1) and line (p2,p3)
|
||||
vec2 intersect_lines(vec2 p0, vec2 p1, vec2 p2, vec2 p3) {
|
||||
vec2 d0 = p0 - p1;
|
||||
vec2 d1 = p2 - p3;
|
||||
|
||||
float s0 = cross2(p0, p1);
|
||||
float s1 = cross2(p2, p3);
|
||||
|
||||
float d = cross2(d0, d1);
|
||||
float nx = s0 * d1.x - d0.x * s1;
|
||||
float ny = s0 * d1.y - d0.y * s1;
|
||||
|
||||
return vec2(nx / d, ny / d);
|
||||
}
|
||||
|
||||
TransformVertexInfo write_transform_vertex(RectWithSize instance_rect,
|
||||
RectWithSize local_clip_rect,
|
||||
float z,
|
||||
Layer layer,
|
||||
AlphaBatchTask task) {
|
||||
vec2 lp0_base = instance_rect.p0;
|
||||
vec2 lp1_base = instance_rect.p0 + instance_rect.size;
|
||||
RectWithEndpoint local_rect = to_rect_with_endpoint(instance_rect);
|
||||
|
||||
vec2 lp0 = clamp_rect(clamp_rect(lp0_base, local_clip_rect),
|
||||
layer.local_clip_rect);
|
||||
vec2 lp1 = clamp_rect(clamp_rect(lp1_base, local_clip_rect),
|
||||
layer.local_clip_rect);
|
||||
vec2 current_local_pos, prev_local_pos, next_local_pos;
|
||||
|
||||
vec4 clipped_local_rect = vec4(lp0, lp1 - lp0);
|
||||
// Select the current vertex and the previous/next vertices,
|
||||
// based on the vertex ID that is known based on the instance rect.
|
||||
switch (gl_VertexID) {
|
||||
case 0:
|
||||
current_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
|
||||
next_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
|
||||
prev_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
|
||||
break;
|
||||
case 1:
|
||||
current_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
|
||||
next_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
|
||||
prev_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
|
||||
break;
|
||||
case 2:
|
||||
current_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
|
||||
prev_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
|
||||
next_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
|
||||
break;
|
||||
case 3:
|
||||
current_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
|
||||
prev_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
|
||||
next_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
|
||||
break;
|
||||
}
|
||||
|
||||
vec2 p0 = lp0;
|
||||
vec2 p1 = vec2(lp1.x, lp0.y);
|
||||
vec2 p2 = vec2(lp0.x, lp1.y);
|
||||
vec2 p3 = lp1;
|
||||
// Transform them to world space
|
||||
vec4 current_world_pos = layer.transform * vec4(current_local_pos, 0.0, 1.0);
|
||||
vec4 prev_world_pos = layer.transform * vec4(prev_local_pos, 0.0, 1.0);
|
||||
vec4 next_world_pos = layer.transform * vec4(next_local_pos, 0.0, 1.0);
|
||||
|
||||
vec4 t0 = layer.transform * vec4(p0, 0, 1);
|
||||
vec4 t1 = layer.transform * vec4(p1, 0, 1);
|
||||
vec4 t2 = layer.transform * vec4(p2, 0, 1);
|
||||
vec4 t3 = layer.transform * vec4(p3, 0, 1);
|
||||
// Convert to device space
|
||||
vec2 current_device_pos = uDevicePixelRatio * current_world_pos.xy / current_world_pos.w;
|
||||
vec2 prev_device_pos = uDevicePixelRatio * prev_world_pos.xy / prev_world_pos.w;
|
||||
vec2 next_device_pos = uDevicePixelRatio * next_world_pos.xy / next_world_pos.w;
|
||||
|
||||
vec2 tp0 = t0.xy / t0.w;
|
||||
vec2 tp1 = t1.xy / t1.w;
|
||||
vec2 tp2 = t2.xy / t2.w;
|
||||
vec2 tp3 = t3.xy / t3.w;
|
||||
// Get the normals of each of the vectors between the current and next/prev vertices.
|
||||
const float amount = 2.0;
|
||||
vec2 dir_prev = normalize(current_device_pos - prev_device_pos);
|
||||
vec2 dir_next = normalize(current_device_pos - next_device_pos);
|
||||
vec2 norm_prev = vec2(-dir_prev.y, dir_prev.x);
|
||||
vec2 norm_next = vec2( dir_next.y, -dir_next.x);
|
||||
|
||||
// compute a CSS space aligned bounding box
|
||||
vec2 min_pos = uDevicePixelRatio * min(min(tp0.xy, tp1.xy), min(tp2.xy, tp3.xy));
|
||||
vec2 max_pos = uDevicePixelRatio * max(max(tp0.xy, tp1.xy), max(tp2.xy, tp3.xy));
|
||||
// Push those lines out along the normal by a specific amount of device pixels.
|
||||
vec2 adjusted_prev_p0 = current_device_pos + norm_prev * amount;
|
||||
vec2 adjusted_prev_p1 = prev_device_pos + norm_prev * amount;
|
||||
vec2 adjusted_next_p0 = current_device_pos + norm_next * amount;
|
||||
vec2 adjusted_next_p1 = next_device_pos + norm_next * amount;
|
||||
|
||||
// compute the device space position of this vertex
|
||||
vec2 device_pos = mix(min_pos, max_pos, aPosition.xy);
|
||||
// Intersect those adjusted lines to find the actual vertex position.
|
||||
vec2 device_pos = intersect_lines(adjusted_prev_p0,
|
||||
adjusted_prev_p1,
|
||||
adjusted_next_p0,
|
||||
adjusted_next_p1);
|
||||
|
||||
// compute the point position in side the layer, in CSS space
|
||||
vec4 layer_pos = get_layer_pos(device_pos / uDevicePixelRatio, layer);
|
||||
// Calculate the snap amount based on the first vertex as a reference point.
|
||||
vec4 world_p0 = layer.transform * vec4(local_rect.p0, 0.0, 1.0);
|
||||
vec2 device_p0 = uDevicePixelRatio * world_p0.xy / world_p0.w;
|
||||
vec2 snap_delta = device_p0 - floor(device_p0 + 0.5);
|
||||
|
||||
// apply the task offset
|
||||
vec2 final_pos = device_pos - task.screen_space_origin + task.render_target_origin;
|
||||
// Apply offsets for the render task to get correct screen location.
|
||||
vec2 final_pos = device_pos -
|
||||
snap_delta -
|
||||
task.screen_space_origin +
|
||||
task.render_target_origin;
|
||||
|
||||
gl_Position = uTransform * vec4(final_pos, z, 1.0);
|
||||
|
||||
return TransformVertexInfo(layer_pos.xyw, device_pos, clipped_local_rect);
|
||||
vec4 layer_pos = get_layer_pos(device_pos / uDevicePixelRatio, layer);
|
||||
|
||||
return TransformVertexInfo(layer_pos.xyw, device_pos, vec4(instance_rect.p0, instance_rect.size));
|
||||
}
|
||||
|
||||
#endif //WR_FEATURE_TRANSFORM
|
||||
@ -663,20 +715,35 @@ void write_clip(vec2 global_pos, ClipArea area) {
|
||||
#endif //WR_VERTEX_SHADER
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
float distance_from_rect(vec2 p, vec2 origin, vec2 size) {
|
||||
vec2 clamped = clamp(p, origin, origin + size);
|
||||
return distance(clamped, p);
|
||||
float signed_distance_rect(vec2 pos, vec2 p0, vec2 p1) {
|
||||
vec2 d = max(p0 - pos, pos - p1);
|
||||
return length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y));
|
||||
}
|
||||
|
||||
vec2 init_transform_fs(vec3 local_pos, vec4 local_rect, out float fragment_alpha) {
|
||||
fragment_alpha = 1.0;
|
||||
vec2 pos = local_pos.xy / local_pos.z;
|
||||
|
||||
float border_distance = distance_from_rect(pos, local_rect.xy, local_rect.zw);
|
||||
if (border_distance != 0.0) {
|
||||
float delta = length(fwidth(local_pos.xy));
|
||||
fragment_alpha = 1.0 - smoothstep(0.0, 1.0, border_distance / delta * 2.0);
|
||||
}
|
||||
// Because the local rect is placed on whole coordinates, but the interpolation
|
||||
// occurs at pixel centers, we need to offset the signed distance by that amount.
|
||||
// In the simple case of no zoom, and no transform, this is 0.5. However, we
|
||||
// need to scale this by the amount that the local rect is changing by per
|
||||
// fragment, based on the current zoom and transform.
|
||||
vec2 fw = fwidth(pos.xy);
|
||||
vec2 dxdy = 0.5 * fw;
|
||||
|
||||
// Now get the actual signed distance. Inset the local rect by the offset amount
|
||||
// above to get correct distance values. This ensures that we only apply
|
||||
// anti-aliasing when the fragment has partial coverage.
|
||||
float d = signed_distance_rect(pos,
|
||||
local_rect.xy + dxdy,
|
||||
local_rect.xy + local_rect.zw - dxdy);
|
||||
|
||||
// Find the appropriate distance to apply the AA smoothstep over.
|
||||
float afwidth = 0.5 / length(fw);
|
||||
|
||||
// Only apply AA to fragments outside the signed distance field.
|
||||
fragment_alpha = 1.0 - smoothstep(0.0, afwidth, d);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
@ -56,12 +56,57 @@ float alpha_for_solid_border(float distance_from_ref,
|
||||
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
|
||||
}
|
||||
|
||||
float alpha_for_solid_border_corner(vec2 local_pos,
|
||||
float inner_radius,
|
||||
float outer_radius,
|
||||
float alpha_for_solid_ellipse_border(vec2 local_pos,
|
||||
vec2 inner_radius,
|
||||
vec2 outer_radius,
|
||||
float pixels_per_fragment) {
|
||||
vec2 distance_from_ref = local_pos - vRefPoint;
|
||||
|
||||
float nudge = pixels_per_fragment;
|
||||
inner_radius += nudge;
|
||||
outer_radius -= nudge;
|
||||
|
||||
float inner_ellipse = distance_from_ref.x * distance_from_ref.x / inner_radius.x / inner_radius.x +
|
||||
distance_from_ref.y * distance_from_ref.y / inner_radius.y / inner_radius.y;
|
||||
float outer_ellipse = distance_from_ref.x * distance_from_ref.x / outer_radius.x / outer_radius.x +
|
||||
distance_from_ref.y * distance_from_ref.y / outer_radius.y / outer_radius.y;
|
||||
if (inner_ellipse > 1.0 && outer_ellipse < 1.0) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
vec2 offset = step(inner_radius.yx, inner_radius.xy) *
|
||||
(sqrt(abs(inner_radius.x * inner_radius.x - inner_radius.y * inner_radius.y)));
|
||||
vec2 focus1 = vRefPoint + offset;
|
||||
vec2 focus2 = vRefPoint - offset;
|
||||
|
||||
float inner_distance_from_border = max(inner_radius.x, inner_radius.y) -
|
||||
(distance(focus1, local_pos) + distance(focus2, local_pos)) / 2.0;
|
||||
|
||||
offset = step(outer_radius.yx, outer_radius.xy) *
|
||||
(sqrt(abs(outer_radius.x * outer_radius.x - outer_radius.y * outer_radius.y)));
|
||||
focus1 = vRefPoint + offset;
|
||||
focus2 = vRefPoint - offset;
|
||||
float outer_distance_from_border = (distance(focus1, local_pos) + distance(focus2, local_pos)) / 2.0 -
|
||||
max(outer_radius.x, outer_radius.y);
|
||||
|
||||
float distance_from_border = max(inner_distance_from_border, outer_distance_from_border);
|
||||
|
||||
// Move the distance back into pixels.
|
||||
distance_from_border /= pixels_per_fragment;
|
||||
|
||||
return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
|
||||
}
|
||||
|
||||
float alpha_for_solid_border_corner(vec2 local_pos,
|
||||
vec2 inner_radius,
|
||||
vec2 outer_radius,
|
||||
float pixels_per_fragment) {
|
||||
if (inner_radius.x == inner_radius.y && outer_radius.x == outer_radius.y) {
|
||||
float distance_from_ref = distance(vRefPoint, local_pos);
|
||||
return alpha_for_solid_border(distance_from_ref, inner_radius, outer_radius, pixels_per_fragment);
|
||||
return alpha_for_solid_border(distance_from_ref, inner_radius.x, outer_radius.x, pixels_per_fragment);
|
||||
} else {
|
||||
return alpha_for_solid_ellipse_border(local_pos, inner_radius, outer_radius, pixels_per_fragment);
|
||||
}
|
||||
}
|
||||
|
||||
vec4 draw_dotted_edge(vec2 local_pos, vec4 piece_rect, float pixels_per_fragment) {
|
||||
@ -144,8 +189,8 @@ void draw_dashed_or_dotted_border(vec2 local_pos, float distance_from_mix_line)
|
||||
oFragColor = get_fragment_color(distance_from_mix_line, pixels_per_fragment);
|
||||
if (vRadii.x > 0.0) {
|
||||
oFragColor *= vec4(1.0, 1.0, 1.0, alpha_for_solid_border_corner(local_pos,
|
||||
vRadii.z,
|
||||
vRadii.x,
|
||||
vRadii.zw,
|
||||
vRadii.xy,
|
||||
pixels_per_fragment));
|
||||
}
|
||||
|
||||
@ -199,16 +244,16 @@ vec4 draw_double_edge_vertical(vec2 local_pos,
|
||||
float distance_from_mix_line,
|
||||
float pixels_per_fragment) {
|
||||
// Get our position within this specific segment
|
||||
float position = local_pos.x - vLocalRect.x;
|
||||
return draw_double_edge(position, vLocalRect.z, distance_from_mix_line, pixels_per_fragment);
|
||||
float position = abs(local_pos.x - vRefPoint.x);
|
||||
return draw_double_edge(position, abs(vPieceRect.z), distance_from_mix_line, pixels_per_fragment);
|
||||
}
|
||||
|
||||
vec4 draw_double_edge_horizontal(vec2 local_pos,
|
||||
float distance_from_mix_line,
|
||||
float pixels_per_fragment) {
|
||||
// Get our position within this specific segment
|
||||
float position = local_pos.y - vLocalRect.y;
|
||||
return draw_double_edge(position, vLocalRect.w, distance_from_mix_line, pixels_per_fragment);
|
||||
float position = abs(local_pos.y - vRefPoint.y);
|
||||
return draw_double_edge(position, abs(vPieceRect.w), distance_from_mix_line, pixels_per_fragment);
|
||||
}
|
||||
|
||||
vec4 draw_double_edge_corner_with_radius(vec2 local_pos,
|
||||
@ -216,17 +261,20 @@ vec4 draw_double_edge_corner_with_radius(vec2 local_pos,
|
||||
float pixels_per_fragment) {
|
||||
float total_border_width = vRadii.x - vRadii.z;
|
||||
float one_third_width = total_border_width / 3.0;
|
||||
float total_border_height = vRadii.y - vRadii.w;
|
||||
float one_third_height = total_border_height / 3.0;
|
||||
|
||||
// Contribution of the outer border segment.
|
||||
float alpha = alpha_for_solid_border_corner(local_pos,
|
||||
vRadii.x - one_third_width,
|
||||
vRadii.x,
|
||||
vec2(vRadii.x - one_third_width,
|
||||
vRadii.y - one_third_height),
|
||||
vec2(vRadii.x, vRadii.y),
|
||||
pixels_per_fragment);
|
||||
|
||||
// Contribution of the inner border segment.
|
||||
alpha += alpha_for_solid_border_corner(local_pos,
|
||||
vRadii.z,
|
||||
vRadii.z + one_third_width,
|
||||
vec2(vRadii.z, vRadii.w),
|
||||
vec2(vRadii.z + one_third_width, vRadii.w + one_third_height),
|
||||
pixels_per_fragment);
|
||||
return get_fragment_color(distance_from_mix_line, pixels_per_fragment) * vec4(1.0, 1.0, 1.0, alpha);
|
||||
}
|
||||
@ -291,7 +339,7 @@ void draw_solid_border(float distanceFromMixLine, vec2 localPos) {
|
||||
oFragColor = get_fragment_color(distanceFromMixLine, pixelsPerFragment);
|
||||
|
||||
if (vRadii.x > 0.0) {
|
||||
float alpha = alpha_for_solid_border_corner(localPos, vRadii.z, vRadii.x, pixelsPerFragment);
|
||||
float alpha = alpha_for_solid_border_corner(localPos, vRadii.zw, vRadii.xy, pixelsPerFragment);
|
||||
oFragColor *= vec4(1.0, 1.0, 1.0, alpha);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,18 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
void main(void) {
|
||||
vec2 uv = min(vec2(1.0), vMirrorPoint - abs(vUv.xy - vMirrorPoint));
|
||||
// Mirror and stretch the box shadow corner over the entire
|
||||
// primitives.
|
||||
vec2 uv = vMirrorPoint - abs(vUv.xy - vMirrorPoint);
|
||||
|
||||
// Ensure that we don't fetch texels outside the box
|
||||
// shadow corner. This can happen, for example, when
|
||||
// drawing the outer parts of an inset box shadow.
|
||||
uv = clamp(uv, vec2(0.0), vec2(1.0));
|
||||
|
||||
// Map the unit UV to the actual UV rect in the cache.
|
||||
uv = mix(vCacheUvRectCoords.xy, vCacheUvRectCoords.zw, uv);
|
||||
|
||||
// Modulate the box shadow by the color.
|
||||
oFragColor = vColor * texture(sCache, vec3(uv, vUv.z));
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use util::TransformedRect;
|
||||
use webrender_traits::{ClipRegion, LayerPixel, LayerPoint, LayerRect, LayerSize};
|
||||
use webrender_traits::{LayerToScrollTransform, LayerToWorldTransform, PipelineId};
|
||||
use webrender_traits::{ScrollEventPhase, ScrollLayerId, ScrollLayerRect, ScrollLocation};
|
||||
use webrender_traits::{ServoScrollRootId, WorldPoint, WorldPoint4D};
|
||||
use webrender_traits::{WorldPoint, WorldPoint4D};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
const CAN_OVERSCROLL: bool = true;
|
||||
@ -38,17 +38,12 @@ pub struct ClipInfo {
|
||||
/// which depends on the screen rectangle and the transformation of all of
|
||||
/// the parents.
|
||||
pub xf_rect: Option<TransformedRect>,
|
||||
|
||||
/// An external identifier that is used to scroll this clipping node
|
||||
/// from the API.
|
||||
pub scroll_root_id: Option<ServoScrollRootId>,
|
||||
}
|
||||
|
||||
impl ClipInfo {
|
||||
pub fn new(clip_region: &ClipRegion,
|
||||
clip_store: &mut VertexDataStore<GpuBlock32>,
|
||||
packed_layer_index: PackedLayerIndex,
|
||||
scroll_root_id: Option<ServoScrollRootId>)
|
||||
packed_layer_index: PackedLayerIndex,)
|
||||
-> ClipInfo {
|
||||
// We pass true here for the MaskCacheInfo because this type of
|
||||
// mask needs an extra clip for the clip rectangle.
|
||||
@ -58,7 +53,6 @@ impl ClipInfo {
|
||||
clip_source: clip_source,
|
||||
packed_layer_index: packed_layer_index,
|
||||
xf_rect: None,
|
||||
scroll_root_id: scroll_root_id,
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +189,15 @@ impl ClipScrollNode {
|
||||
}
|
||||
|
||||
pub fn set_scroll_origin(&mut self, origin: &LayerPoint) -> bool {
|
||||
match self.node_type {
|
||||
NodeType::ReferenceFrame(_) => {
|
||||
warn!("Tried to scroll a reference frame.");
|
||||
return false;
|
||||
}
|
||||
NodeType::Clip(_) => {}
|
||||
};
|
||||
|
||||
|
||||
let scrollable_height = self.scrollable_height();
|
||||
let scrollable_width = self.scrollable_width();
|
||||
if scrollable_height <= 0. && scrollable_width <= 0. {
|
||||
|
@ -7,15 +7,14 @@ use fnv::FnvHasher;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::hash::BuildHasherDefault;
|
||||
use webrender_traits::{LayerPoint, LayerRect, LayerToScrollTransform, LayerToWorldTransform};
|
||||
use webrender_traits::{PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerInfo};
|
||||
use webrender_traits::{ScrollLayerRect, ScrollLayerState, ScrollLocation, ServoScrollRootId};
|
||||
use webrender_traits::{WorldPoint, as_scroll_parent_rect};
|
||||
use webrender_traits::{PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerRect};
|
||||
use webrender_traits::{ScrollLayerState, ScrollLocation, WorldPoint, as_scroll_parent_rect};
|
||||
|
||||
pub type ScrollStates = HashMap<ScrollLayerId, ScrollingState, BuildHasherDefault<FnvHasher>>;
|
||||
|
||||
pub struct ClipScrollTree {
|
||||
pub nodes: HashMap<ScrollLayerId, ClipScrollNode, BuildHasherDefault<FnvHasher>>,
|
||||
pub pending_scroll_offsets: HashMap<(PipelineId, ServoScrollRootId), LayerPoint>,
|
||||
pub pending_scroll_offsets: HashMap<ScrollLayerId, LayerPoint>,
|
||||
|
||||
/// The ScrollLayerId of the currently scrolling node. Used to allow the same
|
||||
/// node to scroll even if a touch operation leaves the boundaries of that node.
|
||||
@ -90,7 +89,7 @@ impl ClipScrollTree {
|
||||
}
|
||||
}
|
||||
|
||||
if let ScrollLayerInfo::ReferenceFrame(_) = scroll_layer_id.info {
|
||||
if scroll_layer_id.is_reference_frame() {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -109,15 +108,10 @@ impl ClipScrollTree {
|
||||
|
||||
pub fn get_scroll_node_state(&self) -> Vec<ScrollLayerState> {
|
||||
let mut result = vec![];
|
||||
for (_, node) in self.nodes.iter() {
|
||||
for (id, node) in self.nodes.iter() {
|
||||
match node.node_type {
|
||||
NodeType::Clip(ref info) if info.scroll_root_id.is_some() => {
|
||||
result.push(ScrollLayerState {
|
||||
pipeline_id: node.pipeline_id,
|
||||
scroll_root_id: info.scroll_root_id.unwrap(),
|
||||
scroll_offset: node.scrolling.offset,
|
||||
})
|
||||
}
|
||||
NodeType::Clip(_) => result.push(
|
||||
ScrollLayerState { id: *id, scroll_offset: node.scrolling.offset }),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
@ -129,7 +123,7 @@ impl ClipScrollTree {
|
||||
|
||||
let mut scroll_states = HashMap::with_hasher(Default::default());
|
||||
for (layer_id, old_node) in &mut self.nodes.drain() {
|
||||
if !self.pipelines_to_discard.contains(&layer_id.pipeline_id) {
|
||||
if !self.pipelines_to_discard.contains(&layer_id.pipeline_id()) {
|
||||
scroll_states.insert(layer_id, old_node.scrolling);
|
||||
}
|
||||
}
|
||||
@ -138,40 +132,24 @@ impl ClipScrollTree {
|
||||
scroll_states
|
||||
}
|
||||
|
||||
pub fn scroll_nodes(&mut self,
|
||||
origin: LayerPoint,
|
||||
pipeline_id: PipelineId,
|
||||
scroll_root_id: ServoScrollRootId)
|
||||
-> bool {
|
||||
pub fn scroll_nodes(&mut self, origin: LayerPoint, id: ScrollLayerId) -> bool {
|
||||
if id.is_reference_frame() {
|
||||
warn!("Tried to scroll a reference frame.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.nodes.is_empty() {
|
||||
self.pending_scroll_offsets.insert((pipeline_id, scroll_root_id), origin);
|
||||
self.pending_scroll_offsets.insert(id, origin);
|
||||
return false;
|
||||
}
|
||||
|
||||
let origin = LayerPoint::new(origin.x.max(0.0), origin.y.max(0.0));
|
||||
|
||||
let mut scrolled_a_node = false;
|
||||
let mut found_node = false;
|
||||
for (layer_id, node) in self.nodes.iter_mut() {
|
||||
if layer_id.pipeline_id != pipeline_id {
|
||||
continue;
|
||||
if let Some(node) = self.nodes.get_mut(&id) {
|
||||
return node.set_scroll_origin(&origin);
|
||||
}
|
||||
|
||||
match node.node_type {
|
||||
NodeType::Clip(ref info) if info.scroll_root_id != Some(scroll_root_id) => continue,
|
||||
NodeType::ReferenceFrame(..) => continue,
|
||||
NodeType::Clip(_) => {},
|
||||
}
|
||||
|
||||
found_node = true;
|
||||
scrolled_a_node |= node.set_scroll_origin(&origin);
|
||||
}
|
||||
|
||||
if !found_node {
|
||||
self.pending_scroll_offsets.insert((pipeline_id, scroll_root_id), origin);
|
||||
}
|
||||
|
||||
scrolled_a_node
|
||||
self.pending_scroll_offsets.insert(id, origin);
|
||||
false
|
||||
}
|
||||
|
||||
pub fn scroll(&mut self,
|
||||
@ -244,37 +222,7 @@ impl ClipScrollTree {
|
||||
scroll_layer_id
|
||||
};
|
||||
|
||||
// TODO(mrobinson): Once we remove the concept of shared scroll root ids we can remove
|
||||
// this entirely and just scroll the node based on the ScrollLayerId.
|
||||
let scroll_root_id = {
|
||||
let node = self.nodes.get_mut(&scroll_layer_id).unwrap();
|
||||
let scroll_root_id = match node.node_type {
|
||||
NodeType::Clip(ref info) => info.scroll_root_id,
|
||||
NodeType::ReferenceFrame(..) => unreachable!("Tried to scroll a reference frame."),
|
||||
};
|
||||
|
||||
if scroll_root_id.is_none() {
|
||||
return node.scroll(scroll_location, phase);
|
||||
}
|
||||
|
||||
scroll_root_id
|
||||
};
|
||||
|
||||
let mut scrolled_a_node = false;
|
||||
for (layer_id, node) in self.nodes.iter_mut() {
|
||||
if layer_id.pipeline_id != scroll_layer_id.pipeline_id {
|
||||
continue;
|
||||
}
|
||||
|
||||
match node.node_type {
|
||||
NodeType::Clip(ref info) if info.scroll_root_id == scroll_root_id => { }
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
let scrolled_this_node = node.scroll(scroll_location, phase);
|
||||
scrolled_a_node = scrolled_a_node || scrolled_this_node;
|
||||
}
|
||||
scrolled_a_node
|
||||
self.nodes.get_mut(&scroll_layer_id).unwrap().scroll(scroll_location, phase)
|
||||
}
|
||||
|
||||
pub fn update_all_node_transforms(&mut self, pan: LayerPoint) {
|
||||
@ -351,16 +299,7 @@ impl ClipScrollTree {
|
||||
|
||||
node.finalize(&scrolling_state);
|
||||
|
||||
let scroll_root_id = match node.node_type {
|
||||
NodeType::Clip(ref info) if info.scroll_root_id.is_some() =>
|
||||
info.scroll_root_id.unwrap(),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
|
||||
let pipeline_id = scroll_layer_id.pipeline_id;
|
||||
if let Some(pending_offset) =
|
||||
self.pending_scroll_offsets.remove(&(pipeline_id, scroll_root_id)) {
|
||||
if let Some(pending_offset) = self.pending_scroll_offsets.remove(&scroll_layer_id) {
|
||||
node.set_scroll_origin(&pending_offset);
|
||||
}
|
||||
}
|
||||
@ -373,10 +312,9 @@ impl ClipScrollTree {
|
||||
pipeline_id: PipelineId,
|
||||
parent_id: Option<ScrollLayerId>)
|
||||
-> ScrollLayerId {
|
||||
let reference_frame_id = ScrollLayerId {
|
||||
pipeline_id: pipeline_id,
|
||||
info: ScrollLayerInfo::ReferenceFrame(self.current_reference_frame_id),
|
||||
};
|
||||
|
||||
let reference_frame_id =
|
||||
ScrollLayerId::ReferenceFrame(self.current_reference_frame_id, pipeline_id);
|
||||
self.current_reference_frame_id += 1;
|
||||
|
||||
let node = ClipScrollNode::new_reference_frame(parent_id,
|
||||
@ -403,7 +341,7 @@ impl ClipScrollTree {
|
||||
self.pipelines_to_discard.insert(pipeline_id);
|
||||
|
||||
match self.current_scroll_layer_id {
|
||||
Some(id) if id.pipeline_id == pipeline_id => self.current_scroll_layer_id = None,
|
||||
Some(id) if id.pipeline_id() == pipeline_id => self.current_scroll_layer_id = None,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ impl DebugRenderer {
|
||||
pub fn render(&mut self,
|
||||
device: &mut Device,
|
||||
viewport_size: &DeviceUintSize) {
|
||||
let _gm = GpuMarker::new("debug");
|
||||
let _gm = GpuMarker::new(device.rc_gl(), "debug");
|
||||
device.disable_depth();
|
||||
device.set_blend(true);
|
||||
device.set_blend_mode_alpha();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,8 +20,8 @@ use webrender_traits::{AuxiliaryLists, ClipDisplayItem, ClipRegion, ColorF, Devi
|
||||
use webrender_traits::{DeviceUintSize, DisplayItem, Epoch, FilterOp, ImageDisplayItem, LayerPoint};
|
||||
use webrender_traits::{LayerRect, LayerSize, LayerToScrollTransform, LayoutTransform};
|
||||
use webrender_traits::{MixBlendMode, PipelineId, ScrollEventPhase, ScrollLayerId};
|
||||
use webrender_traits::{ScrollLayerState, ScrollLocation, ScrollPolicy, ServoScrollRootId};
|
||||
use webrender_traits::{SpecificDisplayItem, StackingContext, TileOffset, WorldPoint};
|
||||
use webrender_traits::{ScrollLayerState, ScrollLocation, ScrollPolicy, SpecificDisplayItem};
|
||||
use webrender_traits::{StackingContext, TileOffset, WorldPoint};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
|
||||
pub struct FrameId(pub u32);
|
||||
@ -231,12 +231,8 @@ impl Frame {
|
||||
}
|
||||
|
||||
/// Returns true if any nodes actually changed position or false otherwise.
|
||||
pub fn scroll_nodes(&mut self,
|
||||
origin: LayerPoint,
|
||||
pipeline_id: PipelineId,
|
||||
scroll_root_id: ServoScrollRootId)
|
||||
-> bool {
|
||||
self.clip_scroll_tree.scroll_nodes(origin, pipeline_id, scroll_root_id)
|
||||
pub fn scroll_nodes(&mut self, origin: LayerPoint, id: ScrollLayerId) -> bool {
|
||||
self.clip_scroll_tree.scroll_nodes(origin, id)
|
||||
}
|
||||
|
||||
/// Returns true if any nodes actually changed position or false otherwise.
|
||||
@ -349,7 +345,6 @@ impl Frame {
|
||||
pipeline_id,
|
||||
&clip_rect,
|
||||
&item.content_size,
|
||||
item.scroll_root_id,
|
||||
clip,
|
||||
&mut self.clip_scroll_tree);
|
||||
|
||||
@ -522,7 +517,6 @@ impl Frame {
|
||||
pipeline_id,
|
||||
&LayerRect::new(LayerPoint::zero(), iframe_rect.size),
|
||||
&iframe_clip.main.size,
|
||||
Some(ServoScrollRootId(0)),
|
||||
iframe_clip,
|
||||
&mut self.clip_scroll_tree);
|
||||
|
||||
|
@ -33,8 +33,7 @@ use webrender_traits::{BoxShadowClipMode, ClipRegion, ColorF, DeviceIntPoint, De
|
||||
use webrender_traits::{DeviceIntSize, DeviceUintRect, DeviceUintSize, ExtendMode, FontKey};
|
||||
use webrender_traits::{FontRenderMode, GlyphOptions, ImageKey, ImageRendering, ItemRange};
|
||||
use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, PipelineId};
|
||||
use webrender_traits::{RepeatMode, ScrollLayerId, ServoScrollRootId, TileOffset, WebGLContextId};
|
||||
use webrender_traits::YuvColorSpace;
|
||||
use webrender_traits::{RepeatMode, ScrollLayerId, TileOffset, WebGLContextId, YuvColorSpace};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct ImageBorderSegment {
|
||||
@ -309,7 +308,6 @@ impl FrameBuilder {
|
||||
pipeline_id,
|
||||
&viewport_rect,
|
||||
content_size,
|
||||
Some(ServoScrollRootId(0)),
|
||||
&ClipRegion::simple(&viewport_rect),
|
||||
clip_scroll_tree);
|
||||
topmost_scroll_layer_id
|
||||
@ -321,13 +319,11 @@ impl FrameBuilder {
|
||||
pipeline_id: PipelineId,
|
||||
local_viewport_rect: &LayerRect,
|
||||
content_size: &LayerSize,
|
||||
scroll_root_id: Option<ServoScrollRootId>,
|
||||
clip_region: &ClipRegion,
|
||||
clip_scroll_tree: &mut ClipScrollTree) {
|
||||
let clip_info = ClipInfo::new(clip_region,
|
||||
&mut self.prim_store.gpu_data32,
|
||||
PackedLayerIndex(self.packed_layers.len()),
|
||||
scroll_root_id);
|
||||
PackedLayerIndex(self.packed_layers.len()));
|
||||
let node = ClipScrollNode::new(pipeline_id,
|
||||
parent_id,
|
||||
local_viewport_rect,
|
||||
|
@ -6,6 +6,7 @@ use app_units::Au;
|
||||
use device::TextureFilter;
|
||||
use euclid::{TypedPoint2D, UnknownUnit};
|
||||
use fnv::FnvHasher;
|
||||
use gleam::gl;
|
||||
use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle};
|
||||
use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher};
|
||||
use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
|
||||
@ -74,6 +75,7 @@ impl GLContextHandleWrapper {
|
||||
let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size.to_untyped(),
|
||||
attributes,
|
||||
ColorAttachmentType::Texture,
|
||||
gl::GlType::default(),
|
||||
Some(handle),
|
||||
dispatcher);
|
||||
ctx.map(GLContextWrapper::Native)
|
||||
@ -82,6 +84,7 @@ impl GLContextHandleWrapper {
|
||||
let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size.to_untyped(),
|
||||
attributes,
|
||||
ColorAttachmentType::Texture,
|
||||
gl::GlType::default(),
|
||||
Some(handle),
|
||||
dispatcher);
|
||||
ctx.map(GLContextWrapper::OSMesa)
|
||||
|
@ -3,7 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use debug_render::DebugRenderer;
|
||||
use device::{GpuMarker, GpuSample, NamedTag};
|
||||
use device::{Device, GpuMarker, GpuSample, NamedTag};
|
||||
use euclid::{Point2D, Size2D, Rect};
|
||||
use std::collections::vec_deque::VecDeque;
|
||||
use std::f32;
|
||||
@ -639,13 +639,14 @@ impl Profiler {
|
||||
}
|
||||
|
||||
pub fn draw_profile(&mut self,
|
||||
device: &mut Device,
|
||||
frame_profile: &FrameProfileCounters,
|
||||
backend_profile: &BackendProfileCounters,
|
||||
renderer_profile: &RendererProfileCounters,
|
||||
renderer_timers: &mut RendererProfileTimers,
|
||||
debug_renderer: &mut DebugRenderer) {
|
||||
|
||||
let _gm = GpuMarker::new("profile");
|
||||
let _gm = GpuMarker::new(device.rc_gl(), "profile");
|
||||
self.x_left = 20.0;
|
||||
self.y_left = 40.0;
|
||||
self.x_right = 400.0;
|
||||
|
@ -260,12 +260,12 @@ impl RenderBackend {
|
||||
None => self.notify_compositor_of_new_scroll_frame(false),
|
||||
}
|
||||
}
|
||||
ApiMsg::ScrollLayersWithScrollId(origin, pipeline_id, scroll_root_id) => {
|
||||
profile_scope!("ScrollLayersWithScrollId");
|
||||
ApiMsg::ScrollLayerWithId(origin, id) => {
|
||||
profile_scope!("ScrollLayerWithScrollId");
|
||||
let frame = {
|
||||
let counters = &mut profile_counters.texture_cache;
|
||||
profile_counters.total_time.profile(|| {
|
||||
if self.frame.scroll_nodes(origin, pipeline_id, scroll_root_id) {
|
||||
if self.frame.scroll_nodes(origin, id) {
|
||||
Some(self.render(counters))
|
||||
} else {
|
||||
None
|
||||
|
@ -16,6 +16,7 @@ use device::{GpuSample, TextureFilter, VAOId, VertexUsageHint, FileWatcherHandle
|
||||
use euclid::Matrix4D;
|
||||
use fnv::FnvHasher;
|
||||
use frame_builder::FrameBuilderConfig;
|
||||
use gleam::gl;
|
||||
use gpu_store::{GpuStore, GpuStoreLayout};
|
||||
use internal_types::{CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp};
|
||||
use internal_types::{ExternalImageUpdateList, TextureUpdateList, PackedVertex, RenderTargetMode};
|
||||
@ -35,6 +36,7 @@ use std::hash::BuildHasherDefault;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::thread;
|
||||
@ -560,7 +562,8 @@ impl Renderer {
|
||||
/// };
|
||||
/// let (renderer, sender) = Renderer::new(opts);
|
||||
/// ```
|
||||
pub fn new(mut options: RendererOptions,
|
||||
pub fn new(gl: Rc<gl::Gl>,
|
||||
mut options: RendererOptions,
|
||||
initial_window_size: DeviceUintSize) -> Result<(Renderer, RenderApiSender), InitError> {
|
||||
let (api_tx, api_rx) = try!{ channel::msg_channel() };
|
||||
let (payload_tx, payload_rx) = try!{ channel::payload_channel() };
|
||||
@ -575,7 +578,8 @@ impl Renderer {
|
||||
notifier: notifier.clone(),
|
||||
};
|
||||
|
||||
let mut device = Device::new(options.resource_override_path.clone(),
|
||||
let mut device = Device::new(gl,
|
||||
options.resource_override_path.clone(),
|
||||
Box::new(file_watch_handler));
|
||||
// device-pixel ratio doesn't matter here - we are just creating resources.
|
||||
device.begin_frame(1.0);
|
||||
@ -858,6 +862,8 @@ impl Renderer {
|
||||
backend.run(backend_profile_counters);
|
||||
})};
|
||||
|
||||
let gpu_profile = GpuProfiler::new(device.rc_gl());
|
||||
|
||||
let renderer = Renderer {
|
||||
result_rx: result_rx,
|
||||
device: device,
|
||||
@ -896,7 +902,7 @@ impl Renderer {
|
||||
clear_color: options.clear_color,
|
||||
last_time: 0,
|
||||
render_targets: Vec::new(),
|
||||
gpu_profile: GpuProfiler::new(),
|
||||
gpu_profile: gpu_profile,
|
||||
prim_vao_id: prim_vao_id,
|
||||
blur_vao_id: blur_vao_id,
|
||||
clip_vao_id: clip_vao_id,
|
||||
@ -917,6 +923,10 @@ impl Renderer {
|
||||
Ok((renderer, sender))
|
||||
}
|
||||
|
||||
pub fn gl(&self) -> &gl::Gl {
|
||||
self.device.gl()
|
||||
}
|
||||
|
||||
/// Sets the new RenderNotifier.
|
||||
///
|
||||
/// The RenderNotifier will be called when processing e.g. of a (scrolling) frame is done,
|
||||
@ -1077,7 +1087,8 @@ impl Renderer {
|
||||
}
|
||||
|
||||
if self.enable_profiler {
|
||||
self.profiler.draw_profile(&frame.profile_counters,
|
||||
self.profiler.draw_profile(&mut self.device,
|
||||
&frame.profile_counters,
|
||||
&self.backend_profile_counters,
|
||||
&self.profile_counters,
|
||||
&mut profile_timers,
|
||||
@ -1122,7 +1133,7 @@ impl Renderer {
|
||||
*/
|
||||
|
||||
fn update_texture_cache(&mut self) {
|
||||
let _gm = GpuMarker::new("texture cache update");
|
||||
let _gm = GpuMarker::new(self.device.rc_gl(), "texture cache update");
|
||||
let mut pending_texture_updates = mem::replace(&mut self.pending_texture_updates, vec![]);
|
||||
for update_list in pending_texture_updates.drain(..) {
|
||||
for update in update_list.updates {
|
||||
@ -1513,7 +1524,7 @@ impl Renderer {
|
||||
self.device.set_blend_mode_multiply();
|
||||
// draw rounded cornered rectangles
|
||||
if !target.clip_batcher.rectangles.is_empty() {
|
||||
let _gm2 = GpuMarker::new("clip rectangles");
|
||||
let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip rectangles");
|
||||
let shader = self.cs_clip_rectangle.get(&mut self.device).unwrap();
|
||||
self.draw_instanced_batch(&target.clip_batcher.rectangles,
|
||||
vao,
|
||||
@ -1523,7 +1534,7 @@ impl Renderer {
|
||||
}
|
||||
// draw image masks
|
||||
for (mask_texture_id, items) in target.clip_batcher.images.iter() {
|
||||
let _gm2 = GpuMarker::new("clip images");
|
||||
let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip images");
|
||||
let texture_id = self.resolve_source_texture(mask_texture_id);
|
||||
self.device.bind_texture(TextureSampler::Mask, texture_id);
|
||||
let shader = self.cs_clip_image.get(&mut self.device).unwrap();
|
||||
@ -1556,7 +1567,7 @@ impl Renderer {
|
||||
&projection);
|
||||
}
|
||||
|
||||
let _gm2 = GpuMarker::new("alpha batches");
|
||||
let _gm2 = GpuMarker::new(self.device.rc_gl(), "alpha batches");
|
||||
self.device.set_blend(false);
|
||||
let mut prev_blend_mode = BlendMode::None;
|
||||
|
||||
@ -1620,7 +1631,7 @@ impl Renderer {
|
||||
.expect("Found external image, but no handler set!");
|
||||
|
||||
for deferred_resolve in &frame.deferred_resolves {
|
||||
GpuMarker::fire("deferred resolve");
|
||||
GpuMarker::fire(self.device.gl(), "deferred resolve");
|
||||
let props = &deferred_resolve.image_properties;
|
||||
let external_id = props.external_id
|
||||
.expect("BUG: Deferred resolves must be external images!");
|
||||
@ -1667,7 +1678,7 @@ impl Renderer {
|
||||
fn draw_tile_frame(&mut self,
|
||||
frame: &mut Frame,
|
||||
framebuffer_size: &DeviceUintSize) {
|
||||
let _gm = GpuMarker::new("tile frame draw");
|
||||
let _gm = GpuMarker::new(self.device.rc_gl(), "tile frame draw");
|
||||
self.update_deferred_resolves(frame);
|
||||
|
||||
// Some tests use a restricted viewport smaller than the main screen size.
|
||||
|
@ -658,33 +658,9 @@ impl ResourceCache {
|
||||
// external handle doesn't need to update the texture_cache.
|
||||
}
|
||||
ImageData::Raw(..) | ImageData::ExternalBuffer(..) | ImageData::Blob(..) => {
|
||||
match self.cached_images.entry(request.clone(), self.current_frame_id) {
|
||||
Occupied(entry) => {
|
||||
let image_id = entry.get().texture_cache_id;
|
||||
|
||||
if entry.get().epoch != image_template.epoch {
|
||||
self.texture_cache.update(image_id,
|
||||
image_template.descriptor,
|
||||
image_data);
|
||||
|
||||
// Update the cached epoch
|
||||
*entry.into_mut() = CachedImageInfo {
|
||||
texture_cache_id: image_id,
|
||||
epoch: image_template.epoch,
|
||||
};
|
||||
}
|
||||
}
|
||||
Vacant(entry) => {
|
||||
let image_id = self.texture_cache.new_item_id();
|
||||
|
||||
let filter = match request.rendering {
|
||||
ImageRendering::Pixelated => TextureFilter::Nearest,
|
||||
ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear,
|
||||
};
|
||||
|
||||
if let Some(tile) = request.tile {
|
||||
let descriptor = if let Some(tile) = request.tile {
|
||||
let tile_size = image_template.tiling.unwrap() as u32;
|
||||
let image_descriptor = image_template.descriptor.clone();
|
||||
let image_descriptor = &image_template.descriptor;
|
||||
let stride = image_descriptor.compute_stride();
|
||||
let bpp = image_descriptor.format.bytes_per_pixel().unwrap();
|
||||
|
||||
@ -705,27 +681,47 @@ impl ResourceCache {
|
||||
let offset = image_descriptor.offset + tile.y as u32 * tile_size * stride
|
||||
+ tile.x as u32 * tile_size * bpp;
|
||||
|
||||
let tile_descriptor = ImageDescriptor {
|
||||
ImageDescriptor {
|
||||
width: actual_width,
|
||||
height: actual_height,
|
||||
stride: Some(stride),
|
||||
offset: offset,
|
||||
format: image_descriptor.format,
|
||||
is_opaque: image_descriptor.is_opaque,
|
||||
}
|
||||
} else {
|
||||
image_template.descriptor.clone()
|
||||
};
|
||||
|
||||
match self.cached_images.entry(request.clone(), self.current_frame_id) {
|
||||
Occupied(entry) => {
|
||||
let image_id = entry.get().texture_cache_id;
|
||||
|
||||
if entry.get().epoch != image_template.epoch {
|
||||
self.texture_cache.update(image_id,
|
||||
descriptor,
|
||||
image_data);
|
||||
|
||||
// Update the cached epoch
|
||||
*entry.into_mut() = CachedImageInfo {
|
||||
texture_cache_id: image_id,
|
||||
epoch: image_template.epoch,
|
||||
};
|
||||
}
|
||||
}
|
||||
Vacant(entry) => {
|
||||
let image_id = self.texture_cache.new_item_id();
|
||||
|
||||
let filter = match request.rendering {
|
||||
ImageRendering::Pixelated => TextureFilter::Nearest,
|
||||
ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear,
|
||||
};
|
||||
|
||||
self.texture_cache.insert(image_id,
|
||||
tile_descriptor,
|
||||
descriptor,
|
||||
filter,
|
||||
image_data,
|
||||
texture_cache_profile);
|
||||
} else {
|
||||
self.texture_cache.insert(image_id,
|
||||
image_template.descriptor,
|
||||
filter,
|
||||
image_data,
|
||||
texture_cache_profile);
|
||||
}
|
||||
|
||||
entry.insert(CachedImageInfo {
|
||||
texture_cache_id: image_id,
|
||||
|
@ -5,12 +5,12 @@ authors = ["The Mozilla Project Developers"]
|
||||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
webrender_traits = {path = "../webrender_traits", version = "0.25.0"}
|
||||
webrender_traits = {path = "../webrender_traits", version = "0.26.0"}
|
||||
euclid = "0.11"
|
||||
app_units = "0.4"
|
||||
gleam = "0.2"
|
||||
gleam = "0.4"
|
||||
|
||||
[dependencies.webrender]
|
||||
path = "../webrender"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
default-features = false
|
||||
|
@ -76,6 +76,8 @@ public:
|
||||
|
||||
RenderTextureHost* GetRenderTexture(uint64_t aExternalImageId);
|
||||
|
||||
WrRenderer* GetWrRenderer() { return mWrRenderer; }
|
||||
|
||||
protected:
|
||||
|
||||
RefPtr<RenderThread> mThread;
|
||||
|
@ -228,7 +228,8 @@ WebRenderAPI::Readback(gfx::IntSize size,
|
||||
virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
|
||||
{
|
||||
aRenderThread.UpdateAndRender(aWindowId);
|
||||
wr_renderer_readback(mSize.width, mSize.height, mBuffer, mBufferSize);
|
||||
wr_renderer_readback(aRenderThread.GetRenderer(aWindowId)->GetWrRenderer(),
|
||||
mSize.width, mSize.height, mBuffer, mBufferSize);
|
||||
layers::AutoCompleteTask complete(mTask);
|
||||
}
|
||||
|
||||
|
@ -201,6 +201,16 @@ static inline WrSize ToWrSize(const LayerSize size)
|
||||
return ls;
|
||||
}
|
||||
|
||||
static inline WrBorderRadius ToWrUniformBorderRadius(const LayerSize& aSize)
|
||||
{
|
||||
WrBorderRadius br;
|
||||
br.top_left = ToWrSize(aSize);
|
||||
br.top_right = ToWrSize(aSize);
|
||||
br.bottom_left = ToWrSize(aSize);
|
||||
br.bottom_right = ToWrSize(aSize);
|
||||
return br;
|
||||
}
|
||||
|
||||
static inline WrBorderRadius ToWrBorderRadius(const LayerSize& topLeft, const LayerSize& topRight,
|
||||
const LayerSize& bottomLeft, const LayerSize& bottomRight)
|
||||
{
|
||||
@ -287,6 +297,16 @@ static inline WrRect ToWrRect(const gfx::IntRectTyped<T>& rect)
|
||||
return ToWrRect(IntRectToRect(rect));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline WrComplexClipRegion ToWrComplexClipRegion(const gfx::RectTyped<T>& rect,
|
||||
const LayerSize& size)
|
||||
{
|
||||
WrComplexClipRegion complex_clip;
|
||||
complex_clip.rect = wr::ToWrRect(rect);
|
||||
complex_clip.radii = wr::ToWrUniformBorderRadius(size);
|
||||
return complex_clip;
|
||||
}
|
||||
|
||||
static inline WrPoint ToWrPoint(const gfx::Point& point)
|
||||
{
|
||||
WrPoint p;
|
||||
|
@ -4,19 +4,16 @@ use std::path::PathBuf;
|
||||
use std::os::raw::{c_void, c_char};
|
||||
use gleam::gl;
|
||||
|
||||
use webrender_traits::{BorderSide, BorderStyle, BorderRadius};
|
||||
use webrender_traits::{BorderWidths, BorderDetails, NormalBorder};
|
||||
use webrender_traits::{RepeatMode, ImageBorder, NinePatchDescriptor};
|
||||
use webrender_traits::{PipelineId, ComplexClipRegion, ClipRegion, PropertyBinding};
|
||||
use webrender_traits::{Epoch, ExtendMode, ColorF, GlyphInstance, GradientStop, ImageDescriptor};
|
||||
use webrender_traits::{ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering};
|
||||
use webrender_traits::{FilterOp, MixBlendMode};
|
||||
use webrender_traits::{ExternalImageId, RenderApi, FontKey};
|
||||
use webrender_traits::{DeviceUintSize, DeviceUintRect, DeviceUintPoint, ExternalEvent};
|
||||
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform};
|
||||
use webrender_traits::{BoxShadowClipMode, LayerPixel, ServoScrollRootId, IdNamespace};
|
||||
use webrender_traits::{BuiltDisplayListDescriptor, AuxiliaryListsDescriptor};
|
||||
use webrender_traits::{BuiltDisplayList, AuxiliaryLists, ItemRange};
|
||||
use webrender_traits::{AuxiliaryLists, AuxiliaryListsDescriptor, BorderDetails, BorderRadius};
|
||||
use webrender_traits::{BorderSide, BorderStyle, BorderWidths, BoxShadowClipMode, BuiltDisplayList};
|
||||
use webrender_traits::{BuiltDisplayListDescriptor, ClipRegion, ColorF, ComplexClipRegion};
|
||||
use webrender_traits::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, Epoch, ExtendMode};
|
||||
use webrender_traits::{ExternalEvent, ExternalImageId, FilterOp, FontKey, GlyphInstance};
|
||||
use webrender_traits::{GradientStop, IdNamespace, ImageBorder, ImageData, ImageDescriptor};
|
||||
use webrender_traits::{ImageFormat, ImageKey, ImageMask, ImageRendering, ItemRange, LayerPixel};
|
||||
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, MixBlendMode};
|
||||
use webrender_traits::{NinePatchDescriptor, NormalBorder, PipelineId, PropertyBinding, RenderApi};
|
||||
use webrender_traits::RepeatMode;
|
||||
use webrender::renderer::{Renderer, RendererOptions};
|
||||
use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource};
|
||||
use webrender::{ApiRecordingReceiver, BinaryRecorder};
|
||||
@ -58,6 +55,20 @@ check_ffi_type!(_mix_blend_mode_repr enum MixBlendMode as u32);
|
||||
check_ffi_type!(_box_shadow_clip_mode_repr enum BoxShadowClipMode as u32);
|
||||
check_ffi_type!(_namespace_id_repr struct IdNamespace as (u32));
|
||||
|
||||
const GL_FORMAT_BGRA_GL: gl::GLuint = gl::BGRA;
|
||||
const GL_FORMAT_BGRA_GLES: gl::GLuint = gl::BGRA_EXT;
|
||||
|
||||
fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
|
||||
match gl.get_type() {
|
||||
gl::GlType::Gl => {
|
||||
GL_FORMAT_BGRA_GL
|
||||
}
|
||||
gl::GlType::Gles => {
|
||||
GL_FORMAT_BGRA_GLES
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub enum WrGradientExtendMode {
|
||||
Clamp,
|
||||
@ -543,6 +554,7 @@ extern "C" {
|
||||
fn is_in_compositor_thread() -> bool;
|
||||
fn is_in_render_thread() -> bool;
|
||||
fn is_in_main_thread() -> bool;
|
||||
fn is_glcontext_egl(glcontext_ptr: *mut c_void) -> bool;
|
||||
}
|
||||
|
||||
struct CppNotifier {
|
||||
@ -605,20 +617,21 @@ pub extern "C" fn wr_renderer_render(renderer: &mut Renderer, width: u32, height
|
||||
|
||||
// Call wr_renderer_render() before calling this function.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wr_renderer_readback(width: u32,
|
||||
pub unsafe extern "C" fn wr_renderer_readback(renderer: &mut Renderer,
|
||||
width: u32,
|
||||
height: u32,
|
||||
dst_buffer: *mut u8,
|
||||
buffer_size: usize) {
|
||||
assert!(is_in_render_thread());
|
||||
|
||||
gl::flush();
|
||||
renderer.gl().flush();
|
||||
|
||||
let mut slice = slice::from_raw_parts_mut(dst_buffer, buffer_size);
|
||||
gl::read_pixels_into_buffer(0,
|
||||
renderer.gl().read_pixels_into_buffer(0,
|
||||
0,
|
||||
width as gl::GLsizei,
|
||||
height as gl::GLsizei,
|
||||
gl::BGRA,
|
||||
get_gl_format_bgra(renderer.gl()),
|
||||
gl::UNSIGNED_BYTE,
|
||||
slice);
|
||||
}
|
||||
@ -690,10 +703,15 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
|
||||
None
|
||||
};
|
||||
|
||||
gl::load_with(|symbol| get_proc_address(gl_context, symbol));
|
||||
gl::clear_color(0.3, 0.0, 0.0, 1.0);
|
||||
let gl;
|
||||
if unsafe { is_glcontext_egl(gl_context) } {
|
||||
gl = unsafe { gl::GlesFns::load_with(|symbol| get_proc_address(gl_context, symbol)) };
|
||||
} else {
|
||||
gl = unsafe { gl::GlFns::load_with(|symbol| get_proc_address(gl_context, symbol)) };
|
||||
}
|
||||
gl.clear_color(0.3, 0.0, 0.0, 1.0);
|
||||
|
||||
let version = gl::get_string(gl::VERSION);
|
||||
let version = gl.get_string(gl::VERSION);
|
||||
|
||||
println!("WebRender - OpenGL version new {}", version);
|
||||
|
||||
@ -706,7 +724,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
|
||||
};
|
||||
|
||||
let window_size = DeviceUintSize::new(window_width, window_height);
|
||||
let (renderer, sender) = match Renderer::new(opts, window_size) {
|
||||
let (renderer, sender) = match Renderer::new(gl, opts, window_size) {
|
||||
Ok((renderer, sender)) => (renderer, sender),
|
||||
Err(e) => {
|
||||
println!(" Failed to create a Renderer: {:?}", e);
|
||||
@ -1036,9 +1054,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
|
||||
None,
|
||||
mix_blend_mode,
|
||||
filters);
|
||||
state.frame_builder.dl_builder.push_scroll_layer(clip_region,
|
||||
bounds.size,
|
||||
Some(ServoScrollRootId(1)));
|
||||
state.frame_builder.dl_builder.push_scroll_layer(clip_region, bounds.size, None);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -1064,9 +1080,7 @@ pub extern "C" fn wr_dp_push_scroll_layer(state: &mut WrState,
|
||||
}
|
||||
});
|
||||
let clip_region = state.frame_builder.dl_builder.new_clip_region(&overflow, vec![], mask);
|
||||
state.frame_builder.dl_builder.push_scroll_layer(clip_region,
|
||||
bounds.size,
|
||||
Some(ServoScrollRootId(1)));
|
||||
state.frame_builder.dl_builder.push_scroll_layer(clip_region, bounds.size, None);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -69,6 +69,7 @@ WR_DECL_FFI_2(WrFontKey, uint32_t, uint32_t)
|
||||
bool is_in_compositor_thread();
|
||||
bool is_in_main_thread();
|
||||
bool is_in_render_thread();
|
||||
bool is_glcontext_egl(void* glcontext_ptr);
|
||||
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname);
|
||||
|
||||
// -----
|
||||
@ -484,7 +485,8 @@ WR_FUNC;
|
||||
// It is the responsibility of the caller to manage the dst_buffer memory
|
||||
// and also free it at the proper time.
|
||||
WR_INLINE const uint8_t*
|
||||
wr_renderer_readback(uint32_t width, uint32_t height,
|
||||
wr_renderer_readback(WrRenderer* renderer,
|
||||
uint32_t width, uint32_t height,
|
||||
uint8_t* dst_buffer, size_t buffer_length)
|
||||
WR_FUNC;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "webrender_traits"
|
||||
version = "0.25.0"
|
||||
version = "0.26.0"
|
||||
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/servo/webrender"
|
||||
@ -13,10 +13,10 @@ ipc = ["ipc-channel"]
|
||||
app_units = "0.4"
|
||||
byteorder = "1.0"
|
||||
euclid = "0.11"
|
||||
gleam = "0.2"
|
||||
gleam = "0.4"
|
||||
heapsize = "0.3.6"
|
||||
ipc-channel = {version = "0.7", optional = true}
|
||||
offscreen_gl_context = {version = "0.6", features = ["serde"]}
|
||||
offscreen_gl_context = {version = "0.8", features = ["serde"]}
|
||||
serde = "0.9"
|
||||
serde_derive = "0.9"
|
||||
|
||||
|
@ -6,14 +6,12 @@ use byteorder::{LittleEndian, WriteBytesExt};
|
||||
use channel::{self, MsgSender, PayloadHelperMethods, PayloadSender};
|
||||
use offscreen_gl_context::{GLContextAttributes, GLLimits};
|
||||
use std::cell::Cell;
|
||||
use {ColorF, ImageDescriptor};
|
||||
use {FontKey, ImageKey, NativeFontHandle, ServoScrollRootId};
|
||||
use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand};
|
||||
use {DeviceIntSize, LayoutPoint, LayoutSize, WorldPoint};
|
||||
use {DeviceIntPoint, DeviceUintRect, DeviceUintSize, LayoutTransform};
|
||||
use {BuiltDisplayList, BuiltDisplayListDescriptor, AuxiliaryLists, AuxiliaryListsDescriptor};
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use {AuxiliaryLists, AuxiliaryListsDescriptor, BuiltDisplayList, BuiltDisplayListDescriptor};
|
||||
use {ColorF, DeviceIntPoint, DeviceIntSize, DeviceUintRect, DeviceUintSize, FontKey};
|
||||
use {GlyphDimensions, GlyphKey, ImageData, ImageDescriptor, ImageKey, LayoutPoint, LayoutSize};
|
||||
use {LayoutTransform, NativeFontHandle, ScrollLayerId, WebGLCommand, WebGLContextId, WorldPoint};
|
||||
|
||||
pub type TileSize = u16;
|
||||
|
||||
@ -48,7 +46,7 @@ pub enum ApiMsg {
|
||||
SetRootPipeline(PipelineId),
|
||||
SetWindowParameters(DeviceUintSize, DeviceUintRect),
|
||||
Scroll(ScrollLocation, WorldPoint, ScrollEventPhase),
|
||||
ScrollLayersWithScrollId(LayoutPoint, PipelineId, ServoScrollRootId),
|
||||
ScrollLayerWithId(LayoutPoint, ScrollLayerId),
|
||||
TickScrollingBounce,
|
||||
TranslatePointToLayerSpace(WorldPoint, MsgSender<(LayoutPoint, PipelineId)>),
|
||||
GetScrollLayerState(MsgSender<Vec<ScrollLayerState>>),
|
||||
@ -79,7 +77,7 @@ impl fmt::Debug for ApiMsg {
|
||||
&ApiMsg::SetRootDisplayList(..) => { write!(f, "ApiMsg::SetRootDisplayList") }
|
||||
&ApiMsg::SetRootPipeline(..) => { write!(f, "ApiMsg::SetRootPipeline") }
|
||||
&ApiMsg::Scroll(..) => { write!(f, "ApiMsg::Scroll") }
|
||||
&ApiMsg::ScrollLayersWithScrollId(..) => { write!(f, "ApiMsg::ScrollLayersWithScrollId") }
|
||||
&ApiMsg::ScrollLayerWithId(..) => { write!(f, "ApiMsg::ScrollLayerWithId") }
|
||||
&ApiMsg::TickScrollingBounce => { write!(f, "ApiMsg::TickScrollingBounce") }
|
||||
&ApiMsg::TranslatePointToLayerSpace(..) => { write!(f, "ApiMsg::TranslatePointToLayerSpace") }
|
||||
&ApiMsg::GetScrollLayerState(..) => { write!(f, "ApiMsg::GetScrollLayerState") }
|
||||
@ -310,11 +308,8 @@ impl RenderApi {
|
||||
self.api_sender.send(msg).unwrap();
|
||||
}
|
||||
|
||||
pub fn scroll_layers_with_scroll_root_id(&self,
|
||||
new_scroll_origin: LayoutPoint,
|
||||
pipeline_id: PipelineId,
|
||||
scroll_root_id: ServoScrollRootId) {
|
||||
let msg = ApiMsg::ScrollLayersWithScrollId(new_scroll_origin, pipeline_id, scroll_root_id);
|
||||
pub fn scroll_layer_with_id(&self, new_scroll_origin: LayoutPoint, id: ScrollLayerId) {
|
||||
let msg = ApiMsg::ScrollLayerWithId(new_scroll_origin, id);
|
||||
self.api_sender.send(msg).unwrap();
|
||||
}
|
||||
|
||||
@ -436,8 +431,7 @@ pub enum ScrollEventPhase {
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct ScrollLayerState {
|
||||
pub pipeline_id: PipelineId,
|
||||
pub scroll_root_id: ServoScrollRootId,
|
||||
pub id: ScrollLayerId,
|
||||
pub scroll_offset: LayoutPoint,
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@ pub struct ClipDisplayItem {
|
||||
pub content_size: LayoutSize,
|
||||
pub id: ScrollLayerId,
|
||||
pub parent_id: ScrollLayerId,
|
||||
pub scroll_root_id: Option<ServoScrollRootId>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
||||
@ -86,6 +85,7 @@ pub struct NormalBorder {
|
||||
pub radius: BorderRadius,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum RepeatMode {
|
||||
Stretch,
|
||||
@ -193,6 +193,7 @@ pub struct BoxShadowDisplayItem {
|
||||
pub clip_mode: BoxShadowClipMode,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
|
||||
pub enum ExtendMode {
|
||||
Clamp,
|
||||
@ -251,7 +252,6 @@ pub struct StackingContext {
|
||||
pub filters: ItemRange,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[repr(u32)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub enum ScrollPolicy {
|
||||
@ -509,48 +509,45 @@ impl ComplexClipRegion {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub struct ServoScrollRootId(pub usize);
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub struct ScrollLayerId {
|
||||
pub pipeline_id: PipelineId,
|
||||
pub info: ScrollLayerInfo,
|
||||
pub enum ScrollLayerId {
|
||||
Clip(usize, PipelineId),
|
||||
ClipExternalId(usize, PipelineId),
|
||||
ReferenceFrame(usize, PipelineId),
|
||||
}
|
||||
|
||||
impl ScrollLayerId {
|
||||
pub fn root_scroll_layer(pipeline_id: PipelineId) -> ScrollLayerId {
|
||||
ScrollLayerId {
|
||||
pipeline_id: pipeline_id,
|
||||
info: ScrollLayerInfo::Scrollable(0),
|
||||
}
|
||||
ScrollLayerId::Clip(0, pipeline_id)
|
||||
}
|
||||
|
||||
pub fn root_reference_frame(pipeline_id: PipelineId) -> ScrollLayerId {
|
||||
ScrollLayerId {
|
||||
pipeline_id: pipeline_id,
|
||||
info: ScrollLayerInfo::ReferenceFrame(0),
|
||||
ScrollLayerId::ReferenceFrame(0, pipeline_id)
|
||||
}
|
||||
|
||||
pub fn new(id: usize, pipeline_id: PipelineId) -> ScrollLayerId {
|
||||
ScrollLayerId::ClipExternalId(id, pipeline_id)
|
||||
}
|
||||
|
||||
pub fn pipeline_id(&self) -> PipelineId {
|
||||
match *self {
|
||||
ScrollLayerId::Clip(_, pipeline_id) => pipeline_id,
|
||||
ScrollLayerId::ClipExternalId(_, pipeline_id) => pipeline_id,
|
||||
ScrollLayerId::ReferenceFrame(_, pipeline_id) => pipeline_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_reference_frame(&self) -> bool {
|
||||
match self.info {
|
||||
ScrollLayerInfo::Scrollable(..) => false,
|
||||
ScrollLayerInfo::ReferenceFrame(..) => true,
|
||||
match *self {
|
||||
ScrollLayerId::ReferenceFrame(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(pipeline_id: PipelineId, index: usize) -> ScrollLayerId {
|
||||
ScrollLayerId {
|
||||
pipeline_id: pipeline_id,
|
||||
info: ScrollLayerInfo::Scrollable(index),
|
||||
pub fn external_id(&self) -> Option<usize> {
|
||||
match *self {
|
||||
ScrollLayerId::ClipExternalId(id, _) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub enum ScrollLayerInfo {
|
||||
Scrollable(usize),
|
||||
ReferenceFrame(usize),
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ use {FontKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem, Gradie
|
||||
use {IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering, ItemRange};
|
||||
use {LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, MixBlendMode, PipelineId};
|
||||
use {PropertyBinding, PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem};
|
||||
use {RectangleDisplayItem, ScrollLayerId, ScrollPolicy, ServoScrollRootId, SpecificDisplayItem};
|
||||
use {StackingContext, TextDisplayItem, WebGLContextId, WebGLDisplayItem, YuvColorSpace};
|
||||
use {RectangleDisplayItem, ScrollLayerId, ScrollPolicy, SpecificDisplayItem, StackingContext};
|
||||
use {TextDisplayItem, WebGLContextId, WebGLDisplayItem, YuvColorSpace};
|
||||
use YuvImageDisplayItem;
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
@ -341,17 +341,20 @@ impl DisplayListBuilder {
|
||||
pub fn define_clip(&mut self,
|
||||
clip: ClipRegion,
|
||||
content_size: LayoutSize,
|
||||
scroll_root_id: Option<ServoScrollRootId>)
|
||||
id: Option<ScrollLayerId>)
|
||||
-> ScrollLayerId {
|
||||
let scroll_layer_id = self.next_scroll_layer_id;
|
||||
let id = match id {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
self.next_scroll_layer_id += 1;
|
||||
ScrollLayerId::Clip(self.next_scroll_layer_id - 1, self.pipeline_id)
|
||||
}
|
||||
};
|
||||
|
||||
let id = ScrollLayerId::new(self.pipeline_id, scroll_layer_id);
|
||||
let item = SpecificDisplayItem::Clip(ClipDisplayItem {
|
||||
content_size: content_size,
|
||||
id: id,
|
||||
parent_id: *self.clip_stack.last().unwrap(),
|
||||
scroll_root_id: scroll_root_id,
|
||||
});
|
||||
|
||||
self.push_item(item, clip.main, clip);
|
||||
@ -361,8 +364,8 @@ impl DisplayListBuilder {
|
||||
pub fn push_scroll_layer(&mut self,
|
||||
clip: ClipRegion,
|
||||
content_size: LayoutSize,
|
||||
scroll_root_id: Option<ServoScrollRootId>) {
|
||||
let id = self.define_clip(clip, content_size, scroll_root_id);
|
||||
id: Option<ScrollLayerId>) {
|
||||
let id = self.define_clip(clip, content_size, id);
|
||||
self.clip_stack.push(id);
|
||||
}
|
||||
|
||||
@ -414,6 +417,7 @@ impl DisplayListBuilder {
|
||||
_ => {}
|
||||
}
|
||||
i.clip.complex = self.auxiliary_lists_builder.add_complex_clip_regions(aux.complex_clip_regions(&i.clip.complex));
|
||||
i.scroll_layer_id = *self.clip_stack.last().unwrap();
|
||||
self.list.push(i);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ impl ImageKey {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
pub struct ExternalImageId(pub u64);
|
||||
|
||||
#[repr(C)]
|
||||
#[repr(u32)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
pub enum ImageFormat {
|
||||
@ -108,6 +107,7 @@ pub type BlobImageData = Vec<u8>;
|
||||
|
||||
pub type BlobImageResult = Result<RasterizedBlobImage, BlobImageError>;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct BlobImageDescriptor {
|
||||
pub width: u32,
|
||||
|
@ -385,262 +385,265 @@ impl WebGLCommand {
|
||||
WebGLCommand::GetContextAttributes(sender) =>
|
||||
sender.send(*ctx.borrow_attributes()).unwrap(),
|
||||
WebGLCommand::ActiveTexture(target) =>
|
||||
gl::active_texture(target),
|
||||
ctx.gl().active_texture(target),
|
||||
WebGLCommand::AttachShader(program_id, shader_id) =>
|
||||
gl::attach_shader(program_id.get(), shader_id.get()),
|
||||
ctx.gl().attach_shader(program_id.get(), shader_id.get()),
|
||||
WebGLCommand::DetachShader(program_id, shader_id) =>
|
||||
gl::detach_shader(program_id.get(), shader_id.get()),
|
||||
ctx.gl().detach_shader(program_id.get(), shader_id.get()),
|
||||
WebGLCommand::BindAttribLocation(program_id, index, name) =>
|
||||
gl::bind_attrib_location(program_id.get(), index, &name),
|
||||
ctx.gl().bind_attrib_location(program_id.get(), index, &name),
|
||||
WebGLCommand::BlendColor(r, g, b, a) =>
|
||||
gl::blend_color(r, g, b, a),
|
||||
ctx.gl().blend_color(r, g, b, a),
|
||||
WebGLCommand::BlendEquation(mode) =>
|
||||
gl::blend_equation(mode),
|
||||
ctx.gl().blend_equation(mode),
|
||||
WebGLCommand::BlendEquationSeparate(mode_rgb, mode_alpha) =>
|
||||
gl::blend_equation_separate(mode_rgb, mode_alpha),
|
||||
ctx.gl().blend_equation_separate(mode_rgb, mode_alpha),
|
||||
WebGLCommand::BlendFunc(src, dest) =>
|
||||
gl::blend_func(src, dest),
|
||||
ctx.gl().blend_func(src, dest),
|
||||
WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha) =>
|
||||
gl::blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha),
|
||||
ctx.gl().blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha),
|
||||
WebGLCommand::BufferData(buffer_type, data, usage) =>
|
||||
gl::buffer_data(buffer_type, &data, usage),
|
||||
gl::buffer_data(ctx.gl(), buffer_type, &data, usage),
|
||||
WebGLCommand::BufferSubData(buffer_type, offset, data) =>
|
||||
gl::buffer_sub_data(buffer_type, offset, &data),
|
||||
gl::buffer_sub_data(ctx.gl(), buffer_type, offset, &data),
|
||||
WebGLCommand::Clear(mask) =>
|
||||
gl::clear(mask),
|
||||
ctx.gl().clear(mask),
|
||||
WebGLCommand::ClearColor(r, g, b, a) =>
|
||||
gl::clear_color(r, g, b, a),
|
||||
ctx.gl().clear_color(r, g, b, a),
|
||||
WebGLCommand::ClearDepth(depth) =>
|
||||
gl::clear_depth(depth),
|
||||
ctx.gl().clear_depth(depth),
|
||||
WebGLCommand::ClearStencil(stencil) =>
|
||||
gl::clear_stencil(stencil),
|
||||
ctx.gl().clear_stencil(stencil),
|
||||
WebGLCommand::ColorMask(r, g, b, a) =>
|
||||
gl::color_mask(r, g, b, a),
|
||||
ctx.gl().color_mask(r, g, b, a),
|
||||
WebGLCommand::CopyTexImage2D(target, level, internal_format, x, y, width, height, border) =>
|
||||
gl::copy_tex_image_2d(target, level, internal_format, x, y, width, height, border),
|
||||
ctx.gl().copy_tex_image_2d(target, level, internal_format, x, y, width, height, border),
|
||||
WebGLCommand::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) =>
|
||||
gl::copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height),
|
||||
ctx.gl().copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height),
|
||||
WebGLCommand::CullFace(mode) =>
|
||||
gl::cull_face(mode),
|
||||
ctx.gl().cull_face(mode),
|
||||
WebGLCommand::DepthFunc(func) =>
|
||||
gl::depth_func(func),
|
||||
ctx.gl().depth_func(func),
|
||||
WebGLCommand::DepthMask(flag) =>
|
||||
gl::depth_mask(flag),
|
||||
ctx.gl().depth_mask(flag),
|
||||
WebGLCommand::DepthRange(near, far) =>
|
||||
gl::depth_range(near, far),
|
||||
ctx.gl().depth_range(near, far),
|
||||
WebGLCommand::Disable(cap) =>
|
||||
gl::disable(cap),
|
||||
ctx.gl().disable(cap),
|
||||
WebGLCommand::Enable(cap) =>
|
||||
gl::enable(cap),
|
||||
ctx.gl().enable(cap),
|
||||
WebGLCommand::FramebufferRenderbuffer(target, attachment, renderbuffertarget, rb) =>
|
||||
gl::framebuffer_renderbuffer(target, attachment, renderbuffertarget, rb.map_or(0, WebGLRenderbufferId::get)),
|
||||
ctx.gl().framebuffer_renderbuffer(target, attachment, renderbuffertarget, rb.map_or(0, WebGLRenderbufferId::get)),
|
||||
WebGLCommand::FramebufferTexture2D(target, attachment, textarget, texture, level) =>
|
||||
gl::framebuffer_texture_2d(target, attachment, textarget, texture.map_or(0, WebGLTextureId::get), level),
|
||||
ctx.gl().framebuffer_texture_2d(target, attachment, textarget, texture.map_or(0, WebGLTextureId::get), level),
|
||||
WebGLCommand::FrontFace(mode) =>
|
||||
gl::front_face(mode),
|
||||
ctx.gl().front_face(mode),
|
||||
WebGLCommand::DisableVertexAttribArray(attrib_id) =>
|
||||
gl::disable_vertex_attrib_array(attrib_id),
|
||||
ctx.gl().disable_vertex_attrib_array(attrib_id),
|
||||
WebGLCommand::DrawArrays(mode, first, count) =>
|
||||
gl::draw_arrays(mode, first, count),
|
||||
ctx.gl().draw_arrays(mode, first, count),
|
||||
WebGLCommand::DrawElements(mode, count, type_, offset) =>
|
||||
gl::draw_elements(mode, count, type_, offset as u32),
|
||||
ctx.gl().draw_elements(mode, count, type_, offset as u32),
|
||||
WebGLCommand::EnableVertexAttribArray(attrib_id) =>
|
||||
gl::enable_vertex_attrib_array(attrib_id),
|
||||
ctx.gl().enable_vertex_attrib_array(attrib_id),
|
||||
WebGLCommand::Hint(name, val) =>
|
||||
gl::hint(name, val),
|
||||
ctx.gl().hint(name, val),
|
||||
WebGLCommand::IsEnabled(cap, chan) =>
|
||||
chan.send(gl::is_enabled(cap) != 0).unwrap(),
|
||||
chan.send(ctx.gl().is_enabled(cap) != 0).unwrap(),
|
||||
WebGLCommand::LineWidth(width) =>
|
||||
gl::line_width(width),
|
||||
ctx.gl().line_width(width),
|
||||
WebGLCommand::PixelStorei(name, val) =>
|
||||
gl::pixel_store_i(name, val),
|
||||
ctx.gl().pixel_store_i(name, val),
|
||||
WebGLCommand::PolygonOffset(factor, units) =>
|
||||
gl::polygon_offset(factor, units),
|
||||
ctx.gl().polygon_offset(factor, units),
|
||||
WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, chan) =>
|
||||
Self::read_pixels(x, y, width, height, format, pixel_type, chan),
|
||||
Self::read_pixels(ctx.gl(), x, y, width, height, format, pixel_type, chan),
|
||||
WebGLCommand::RenderbufferStorage(target, format, width, height) =>
|
||||
gl::renderbuffer_storage(target, format, width, height),
|
||||
ctx.gl().renderbuffer_storage(target, format, width, height),
|
||||
WebGLCommand::SampleCoverage(value, invert) =>
|
||||
gl::sample_coverage(value, invert),
|
||||
ctx.gl().sample_coverage(value, invert),
|
||||
WebGLCommand::Scissor(x, y, width, height) =>
|
||||
gl::scissor(x, y, width, height),
|
||||
ctx.gl().scissor(x, y, width, height),
|
||||
WebGLCommand::StencilFunc(func, ref_, mask) =>
|
||||
gl::stencil_func(func, ref_, mask),
|
||||
ctx.gl().stencil_func(func, ref_, mask),
|
||||
WebGLCommand::StencilFuncSeparate(face, func, ref_, mask) =>
|
||||
gl::stencil_func_separate(face, func, ref_, mask),
|
||||
ctx.gl().stencil_func_separate(face, func, ref_, mask),
|
||||
WebGLCommand::StencilMask(mask) =>
|
||||
gl::stencil_mask(mask),
|
||||
ctx.gl().stencil_mask(mask),
|
||||
WebGLCommand::StencilMaskSeparate(face, mask) =>
|
||||
gl::stencil_mask_separate(face, mask),
|
||||
ctx.gl().stencil_mask_separate(face, mask),
|
||||
WebGLCommand::StencilOp(fail, zfail, zpass) =>
|
||||
gl::stencil_op(fail, zfail, zpass),
|
||||
ctx.gl().stencil_op(fail, zfail, zpass),
|
||||
WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass) =>
|
||||
gl::stencil_op_separate(face, fail, zfail, zpass),
|
||||
ctx.gl().stencil_op_separate(face, fail, zfail, zpass),
|
||||
WebGLCommand::GetActiveAttrib(program_id, index, chan) =>
|
||||
Self::active_attrib(program_id, index, chan),
|
||||
Self::active_attrib(ctx.gl(), program_id, index, chan),
|
||||
WebGLCommand::GetActiveUniform(program_id, index, chan) =>
|
||||
Self::active_uniform(program_id, index, chan),
|
||||
Self::active_uniform(ctx.gl(), program_id, index, chan),
|
||||
WebGLCommand::GetAttribLocation(program_id, name, chan) =>
|
||||
Self::attrib_location(program_id, name, chan),
|
||||
Self::attrib_location(ctx.gl(), program_id, name, chan),
|
||||
WebGLCommand::GetVertexAttrib(index, pname, chan) =>
|
||||
Self::vertex_attrib(index, pname, chan),
|
||||
Self::vertex_attrib(ctx.gl(), index, pname, chan),
|
||||
WebGLCommand::GetBufferParameter(target, param_id, chan) =>
|
||||
Self::buffer_parameter(target, param_id, chan),
|
||||
Self::buffer_parameter(ctx.gl(), target, param_id, chan),
|
||||
WebGLCommand::GetParameter(param_id, chan) =>
|
||||
Self::parameter(param_id, chan),
|
||||
Self::parameter(ctx.gl(), param_id, chan),
|
||||
WebGLCommand::GetProgramParameter(program_id, param_id, chan) =>
|
||||
Self::program_parameter(program_id, param_id, chan),
|
||||
Self::program_parameter(ctx.gl(), program_id, param_id, chan),
|
||||
WebGLCommand::GetShaderParameter(shader_id, param_id, chan) =>
|
||||
Self::shader_parameter(shader_id, param_id, chan),
|
||||
Self::shader_parameter(ctx.gl(), shader_id, param_id, chan),
|
||||
WebGLCommand::GetUniformLocation(program_id, name, chan) =>
|
||||
Self::uniform_location(program_id, name, chan),
|
||||
Self::uniform_location(ctx.gl(), program_id, name, chan),
|
||||
WebGLCommand::GetShaderInfoLog(shader_id, chan) =>
|
||||
Self::shader_info_log(shader_id, chan),
|
||||
Self::shader_info_log(ctx.gl(), shader_id, chan),
|
||||
WebGLCommand::GetProgramInfoLog(program_id, chan) =>
|
||||
Self::program_info_log(program_id, chan),
|
||||
Self::program_info_log(ctx.gl(), program_id, chan),
|
||||
WebGLCommand::CompileShader(shader_id, source) =>
|
||||
Self::compile_shader(shader_id, source),
|
||||
Self::compile_shader(ctx.gl(), shader_id, source),
|
||||
WebGLCommand::CreateBuffer(chan) =>
|
||||
Self::create_buffer(chan),
|
||||
Self::create_buffer(ctx.gl(), chan),
|
||||
WebGLCommand::CreateFramebuffer(chan) =>
|
||||
Self::create_framebuffer(chan),
|
||||
Self::create_framebuffer(ctx.gl(), chan),
|
||||
WebGLCommand::CreateRenderbuffer(chan) =>
|
||||
Self::create_renderbuffer(chan),
|
||||
Self::create_renderbuffer(ctx.gl(), chan),
|
||||
WebGLCommand::CreateTexture(chan) =>
|
||||
Self::create_texture(chan),
|
||||
Self::create_texture(ctx.gl(), chan),
|
||||
WebGLCommand::CreateProgram(chan) =>
|
||||
Self::create_program(chan),
|
||||
Self::create_program(ctx.gl(), chan),
|
||||
WebGLCommand::CreateShader(shader_type, chan) =>
|
||||
Self::create_shader(shader_type, chan),
|
||||
Self::create_shader(ctx.gl(), shader_type, chan),
|
||||
WebGLCommand::DeleteBuffer(id) =>
|
||||
gl::delete_buffers(&[id.get()]),
|
||||
ctx.gl().delete_buffers(&[id.get()]),
|
||||
WebGLCommand::DeleteFramebuffer(id) =>
|
||||
gl::delete_framebuffers(&[id.get()]),
|
||||
ctx.gl().delete_framebuffers(&[id.get()]),
|
||||
WebGLCommand::DeleteRenderbuffer(id) =>
|
||||
gl::delete_renderbuffers(&[id.get()]),
|
||||
ctx.gl().delete_renderbuffers(&[id.get()]),
|
||||
WebGLCommand::DeleteTexture(id) =>
|
||||
gl::delete_textures(&[id.get()]),
|
||||
ctx.gl().delete_textures(&[id.get()]),
|
||||
WebGLCommand::DeleteProgram(id) =>
|
||||
gl::delete_program(id.get()),
|
||||
ctx.gl().delete_program(id.get()),
|
||||
WebGLCommand::DeleteShader(id) =>
|
||||
gl::delete_shader(id.get()),
|
||||
ctx.gl().delete_shader(id.get()),
|
||||
WebGLCommand::BindBuffer(target, id) =>
|
||||
gl::bind_buffer(target, id.map_or(0, WebGLBufferId::get)),
|
||||
ctx.gl().bind_buffer(target, id.map_or(0, WebGLBufferId::get)),
|
||||
WebGLCommand::BindFramebuffer(target, request) =>
|
||||
Self::bind_framebuffer(target, request, ctx),
|
||||
Self::bind_framebuffer(ctx.gl(), target, request, ctx),
|
||||
WebGLCommand::BindRenderbuffer(target, id) =>
|
||||
gl::bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
|
||||
ctx.gl().bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
|
||||
WebGLCommand::BindTexture(target, id) =>
|
||||
gl::bind_texture(target, id.map_or(0, WebGLTextureId::get)),
|
||||
ctx.gl().bind_texture(target, id.map_or(0, WebGLTextureId::get)),
|
||||
WebGLCommand::LinkProgram(program_id) =>
|
||||
gl::link_program(program_id.get()),
|
||||
ctx.gl().link_program(program_id.get()),
|
||||
WebGLCommand::Uniform1f(uniform_id, v) =>
|
||||
gl::uniform_1f(uniform_id, v),
|
||||
ctx.gl().uniform_1f(uniform_id, v),
|
||||
WebGLCommand::Uniform1fv(uniform_id, v) =>
|
||||
gl::uniform_1fv(uniform_id, &v),
|
||||
ctx.gl().uniform_1fv(uniform_id, &v),
|
||||
WebGLCommand::Uniform1i(uniform_id, v) =>
|
||||
gl::uniform_1i(uniform_id, v),
|
||||
ctx.gl().uniform_1i(uniform_id, v),
|
||||
WebGLCommand::Uniform1iv(uniform_id, v) =>
|
||||
gl::uniform_1iv(uniform_id, &v),
|
||||
ctx.gl().uniform_1iv(uniform_id, &v),
|
||||
WebGLCommand::Uniform2f(uniform_id, x, y) =>
|
||||
gl::uniform_2f(uniform_id, x, y),
|
||||
ctx.gl().uniform_2f(uniform_id, x, y),
|
||||
WebGLCommand::Uniform2fv(uniform_id, v) =>
|
||||
gl::uniform_2fv(uniform_id, &v),
|
||||
ctx.gl().uniform_2fv(uniform_id, &v),
|
||||
WebGLCommand::Uniform2i(uniform_id, x, y) =>
|
||||
gl::uniform_2i(uniform_id, x, y),
|
||||
ctx.gl().uniform_2i(uniform_id, x, y),
|
||||
WebGLCommand::Uniform2iv(uniform_id, v) =>
|
||||
gl::uniform_2iv(uniform_id, &v),
|
||||
ctx.gl().uniform_2iv(uniform_id, &v),
|
||||
WebGLCommand::Uniform3f(uniform_id, x, y, z) =>
|
||||
gl::uniform_3f(uniform_id, x, y, z),
|
||||
ctx.gl().uniform_3f(uniform_id, x, y, z),
|
||||
WebGLCommand::Uniform3fv(uniform_id, v) =>
|
||||
gl::uniform_3fv(uniform_id, &v),
|
||||
ctx.gl().uniform_3fv(uniform_id, &v),
|
||||
WebGLCommand::Uniform3i(uniform_id, x, y, z) =>
|
||||
gl::uniform_3i(uniform_id, x, y, z),
|
||||
ctx.gl().uniform_3i(uniform_id, x, y, z),
|
||||
WebGLCommand::Uniform3iv(uniform_id, v) =>
|
||||
gl::uniform_3iv(uniform_id, &v),
|
||||
ctx.gl().uniform_3iv(uniform_id, &v),
|
||||
WebGLCommand::Uniform4f(uniform_id, x, y, z, w) =>
|
||||
gl::uniform_4f(uniform_id, x, y, z, w),
|
||||
ctx.gl().uniform_4f(uniform_id, x, y, z, w),
|
||||
WebGLCommand::Uniform4fv(uniform_id, v) =>
|
||||
gl::uniform_4fv(uniform_id, &v),
|
||||
ctx.gl().uniform_4fv(uniform_id, &v),
|
||||
WebGLCommand::Uniform4i(uniform_id, x, y, z, w) =>
|
||||
gl::uniform_4i(uniform_id, x, y, z, w),
|
||||
ctx.gl().uniform_4i(uniform_id, x, y, z, w),
|
||||
WebGLCommand::Uniform4iv(uniform_id, v) =>
|
||||
gl::uniform_4iv(uniform_id, &v),
|
||||
ctx.gl().uniform_4iv(uniform_id, &v),
|
||||
WebGLCommand::UniformMatrix2fv(uniform_id, transpose, v) =>
|
||||
gl::uniform_matrix_2fv(uniform_id, transpose, &v),
|
||||
ctx.gl().uniform_matrix_2fv(uniform_id, transpose, &v),
|
||||
WebGLCommand::UniformMatrix3fv(uniform_id, transpose, v) =>
|
||||
gl::uniform_matrix_3fv(uniform_id, transpose, &v),
|
||||
ctx.gl().uniform_matrix_3fv(uniform_id, transpose, &v),
|
||||
WebGLCommand::UniformMatrix4fv(uniform_id, transpose, v) =>
|
||||
gl::uniform_matrix_4fv(uniform_id, transpose, &v),
|
||||
ctx.gl().uniform_matrix_4fv(uniform_id, transpose, &v),
|
||||
WebGLCommand::UseProgram(program_id) =>
|
||||
gl::use_program(program_id.get()),
|
||||
ctx.gl().use_program(program_id.get()),
|
||||
WebGLCommand::ValidateProgram(program_id) =>
|
||||
gl::validate_program(program_id.get()),
|
||||
ctx.gl().validate_program(program_id.get()),
|
||||
WebGLCommand::VertexAttrib(attrib_id, x, y, z, w) =>
|
||||
gl::vertex_attrib_4f(attrib_id, x, y, z, w),
|
||||
ctx.gl().vertex_attrib_4f(attrib_id, x, y, z, w),
|
||||
WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset) =>
|
||||
gl::vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset),
|
||||
ctx.gl().vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset),
|
||||
WebGLCommand::VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset) =>
|
||||
gl::vertex_attrib_pointer(attrib_id, size, data_type, normalized, stride, offset),
|
||||
ctx.gl().vertex_attrib_pointer(attrib_id, size, data_type, normalized, stride, offset),
|
||||
WebGLCommand::Viewport(x, y, width, height) =>
|
||||
gl::viewport(x, y, width, height),
|
||||
ctx.gl().viewport(x, y, width, height),
|
||||
WebGLCommand::TexImage2D(target, level, internal, width, height, format, data_type, data) =>
|
||||
gl::tex_image_2d(target, level, internal, width, height, /*border*/0, format, data_type, Some(&data)),
|
||||
ctx.gl().tex_image_2d(target, level, internal, width, height, /*border*/0, format, data_type, Some(&data)),
|
||||
WebGLCommand::TexParameteri(target, name, value) =>
|
||||
gl::tex_parameter_i(target, name, value),
|
||||
ctx.gl().tex_parameter_i(target, name, value),
|
||||
WebGLCommand::TexParameterf(target, name, value) =>
|
||||
gl::tex_parameter_f(target, name, value),
|
||||
ctx.gl().tex_parameter_f(target, name, value),
|
||||
WebGLCommand::TexSubImage2D(target, level, xoffset, yoffset, x, y, width, height, data) =>
|
||||
gl::tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, &data),
|
||||
ctx.gl().tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, &data),
|
||||
WebGLCommand::DrawingBufferWidth(sender) =>
|
||||
sender.send(ctx.borrow_draw_buffer().unwrap().size().width).unwrap(),
|
||||
WebGLCommand::DrawingBufferHeight(sender) =>
|
||||
sender.send(ctx.borrow_draw_buffer().unwrap().size().height).unwrap(),
|
||||
WebGLCommand::Finish(sender) =>
|
||||
Self::finish(sender),
|
||||
Self::finish(ctx.gl(), sender),
|
||||
WebGLCommand::Flush =>
|
||||
gl::flush(),
|
||||
ctx.gl().flush(),
|
||||
WebGLCommand::GenerateMipmap(target) =>
|
||||
gl::generate_mipmap(target),
|
||||
ctx.gl().generate_mipmap(target),
|
||||
}
|
||||
|
||||
// FIXME: Use debug_assertions once tests are run with them
|
||||
let error = gl::get_error();
|
||||
let error = ctx.gl().get_error();
|
||||
assert!(error == gl::NO_ERROR, "Unexpected WebGL error: 0x{:x} ({})", error, error);
|
||||
}
|
||||
|
||||
fn read_pixels(x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
|
||||
fn read_pixels(gl: &gl::Gl, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
|
||||
chan: MsgSender<Vec<u8>>) {
|
||||
let result = gl::read_pixels(x, y, width, height, format, pixel_type);
|
||||
let result = gl.read_pixels(x, y, width, height, format, pixel_type);
|
||||
chan.send(result).unwrap()
|
||||
}
|
||||
|
||||
fn active_attrib(program_id: WebGLProgramId,
|
||||
fn active_attrib(gl: &gl::Gl,
|
||||
program_id: WebGLProgramId,
|
||||
index: u32,
|
||||
chan: MsgSender<WebGLResult<(i32, u32, String)>>) {
|
||||
let result = if index >= gl::get_program_iv(program_id.get(), gl::ACTIVE_ATTRIBUTES) as u32 {
|
||||
let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_ATTRIBUTES) as u32 {
|
||||
Err(WebGLError::InvalidValue)
|
||||
} else {
|
||||
Ok(gl::get_active_attrib(program_id.get(), index))
|
||||
Ok(gl.get_active_attrib(program_id.get(), index))
|
||||
};
|
||||
chan.send(result).unwrap();
|
||||
}
|
||||
|
||||
fn active_uniform(program_id: WebGLProgramId,
|
||||
fn active_uniform(gl: &gl::Gl,
|
||||
program_id: WebGLProgramId,
|
||||
index: u32,
|
||||
chan: MsgSender<WebGLResult<(i32, u32, String)>>) {
|
||||
let result = if index >= gl::get_program_iv(program_id.get(), gl::ACTIVE_UNIFORMS) as u32 {
|
||||
let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_UNIFORMS) as u32 {
|
||||
Err(WebGLError::InvalidValue)
|
||||
} else {
|
||||
Ok(gl::get_active_uniform(program_id.get(), index))
|
||||
Ok(gl.get_active_uniform(program_id.get(), index))
|
||||
};
|
||||
chan.send(result).unwrap();
|
||||
}
|
||||
|
||||
fn attrib_location(program_id: WebGLProgramId,
|
||||
fn attrib_location(gl: &gl::Gl,
|
||||
program_id: WebGLProgramId,
|
||||
name: String,
|
||||
chan: MsgSender<Option<i32>> ) {
|
||||
let attrib_location = gl::get_attrib_location(program_id.get(), &name);
|
||||
let attrib_location = gl.get_attrib_location(program_id.get(), &name);
|
||||
|
||||
let attrib_location = if attrib_location == -1 {
|
||||
None
|
||||
@ -651,7 +654,8 @@ impl WebGLCommand {
|
||||
chan.send(attrib_location).unwrap();
|
||||
}
|
||||
|
||||
fn parameter(param_id: u32,
|
||||
fn parameter(gl: &gl::Gl,
|
||||
param_id: u32,
|
||||
chan: MsgSender<WebGLResult<WebGLParameter>>) {
|
||||
let result = match param_id {
|
||||
gl::ACTIVE_TEXTURE |
|
||||
@ -704,7 +708,7 @@ impl WebGLCommand {
|
||||
gl::SUBPIXEL_BITS |
|
||||
gl::UNPACK_ALIGNMENT =>
|
||||
//gl::UNPACK_COLORSPACE_CONVERSION_WEBGL =>
|
||||
Ok(WebGLParameter::Int(gl::get_integer_v(param_id))),
|
||||
Ok(WebGLParameter::Int(gl.get_integer_v(param_id))),
|
||||
|
||||
gl::BLEND |
|
||||
gl::CULL_FACE |
|
||||
@ -716,14 +720,14 @@ impl WebGLCommand {
|
||||
gl::STENCIL_TEST =>
|
||||
//gl::UNPACK_FLIP_Y_WEBGL |
|
||||
//gl::UNPACK_PREMULTIPLY_ALPHA_WEBGL =>
|
||||
Ok(WebGLParameter::Bool(gl::get_boolean_v(param_id) != 0)),
|
||||
Ok(WebGLParameter::Bool(gl.get_boolean_v(param_id) != 0)),
|
||||
|
||||
gl::DEPTH_CLEAR_VALUE |
|
||||
gl::LINE_WIDTH |
|
||||
gl::POLYGON_OFFSET_FACTOR |
|
||||
gl::POLYGON_OFFSET_UNITS |
|
||||
gl::SAMPLE_COVERAGE_VALUE =>
|
||||
Ok(WebGLParameter::Float(gl::get_float_v(param_id))),
|
||||
Ok(WebGLParameter::Float(gl.get_float_v(param_id))),
|
||||
|
||||
gl::VERSION => Ok(WebGLParameter::String("WebGL 1.0".to_owned())),
|
||||
gl::RENDERER |
|
||||
@ -773,27 +777,28 @@ impl WebGLCommand {
|
||||
chan.send(result).unwrap();
|
||||
}
|
||||
|
||||
fn finish(chan: MsgSender<()>) {
|
||||
gl::finish();
|
||||
fn finish(gl: &gl::Gl, chan: MsgSender<()>) {
|
||||
gl.finish();
|
||||
chan.send(()).unwrap();
|
||||
}
|
||||
|
||||
fn vertex_attrib(index: u32,
|
||||
fn vertex_attrib(gl: &gl::Gl,
|
||||
index: u32,
|
||||
pname: u32,
|
||||
chan: MsgSender<WebGLResult<WebGLParameter>>) {
|
||||
let result = if index >= gl::get_integer_v(gl::MAX_VERTEX_ATTRIBS) as u32 {
|
||||
let result = if index >= gl.get_integer_v(gl::MAX_VERTEX_ATTRIBS) as u32 {
|
||||
Err(WebGLError::InvalidValue)
|
||||
} else {
|
||||
match pname {
|
||||
gl::VERTEX_ATTRIB_ARRAY_ENABLED |
|
||||
gl::VERTEX_ATTRIB_ARRAY_NORMALIZED =>
|
||||
Ok(WebGLParameter::Bool(gl::get_vertex_attrib_iv(index, pname) != 0)),
|
||||
Ok(WebGLParameter::Bool(gl.get_vertex_attrib_iv(index, pname) != 0)),
|
||||
gl::VERTEX_ATTRIB_ARRAY_SIZE |
|
||||
gl::VERTEX_ATTRIB_ARRAY_STRIDE |
|
||||
gl::VERTEX_ATTRIB_ARRAY_TYPE =>
|
||||
Ok(WebGLParameter::Int(gl::get_vertex_attrib_iv(index, pname))),
|
||||
Ok(WebGLParameter::Int(gl.get_vertex_attrib_iv(index, pname))),
|
||||
gl::CURRENT_VERTEX_ATTRIB =>
|
||||
Ok(WebGLParameter::FloatArray(gl::get_vertex_attrib_fv(index, pname))),
|
||||
Ok(WebGLParameter::FloatArray(gl.get_vertex_attrib_fv(index, pname))),
|
||||
// gl::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING should return WebGLBuffer
|
||||
_ => Err(WebGLError::InvalidEnum),
|
||||
}
|
||||
@ -802,56 +807,60 @@ impl WebGLCommand {
|
||||
chan.send(result).unwrap();
|
||||
}
|
||||
|
||||
fn buffer_parameter(target: u32,
|
||||
fn buffer_parameter(gl: &gl::Gl,
|
||||
target: u32,
|
||||
param_id: u32,
|
||||
chan: MsgSender<WebGLResult<WebGLParameter>>) {
|
||||
let result = match param_id {
|
||||
gl::BUFFER_SIZE |
|
||||
gl::BUFFER_USAGE =>
|
||||
Ok(WebGLParameter::Int(gl::get_buffer_parameter_iv(target, param_id))),
|
||||
Ok(WebGLParameter::Int(gl.get_buffer_parameter_iv(target, param_id))),
|
||||
_ => Err(WebGLError::InvalidEnum),
|
||||
};
|
||||
|
||||
chan.send(result).unwrap();
|
||||
}
|
||||
|
||||
fn program_parameter(program_id: WebGLProgramId,
|
||||
fn program_parameter(gl: &gl::Gl,
|
||||
program_id: WebGLProgramId,
|
||||
param_id: u32,
|
||||
chan: MsgSender<WebGLResult<WebGLParameter>>) {
|
||||
let result = match param_id {
|
||||
gl::DELETE_STATUS |
|
||||
gl::LINK_STATUS |
|
||||
gl::VALIDATE_STATUS =>
|
||||
Ok(WebGLParameter::Bool(gl::get_program_iv(program_id.get(), param_id) != 0)),
|
||||
Ok(WebGLParameter::Bool(gl.get_program_iv(program_id.get(), param_id) != 0)),
|
||||
gl::ATTACHED_SHADERS |
|
||||
gl::ACTIVE_ATTRIBUTES |
|
||||
gl::ACTIVE_UNIFORMS =>
|
||||
Ok(WebGLParameter::Int(gl::get_program_iv(program_id.get(), param_id))),
|
||||
Ok(WebGLParameter::Int(gl.get_program_iv(program_id.get(), param_id))),
|
||||
_ => Err(WebGLError::InvalidEnum),
|
||||
};
|
||||
|
||||
chan.send(result).unwrap();
|
||||
}
|
||||
|
||||
fn shader_parameter(shader_id: WebGLShaderId,
|
||||
fn shader_parameter(gl: &gl::Gl,
|
||||
shader_id: WebGLShaderId,
|
||||
param_id: u32,
|
||||
chan: MsgSender<WebGLResult<WebGLParameter>>) {
|
||||
let result = match param_id {
|
||||
gl::SHADER_TYPE =>
|
||||
Ok(WebGLParameter::Int(gl::get_shader_iv(shader_id.get(), param_id))),
|
||||
Ok(WebGLParameter::Int(gl.get_shader_iv(shader_id.get(), param_id))),
|
||||
gl::DELETE_STATUS |
|
||||
gl::COMPILE_STATUS =>
|
||||
Ok(WebGLParameter::Bool(gl::get_shader_iv(shader_id.get(), param_id) != 0)),
|
||||
Ok(WebGLParameter::Bool(gl.get_shader_iv(shader_id.get(), param_id) != 0)),
|
||||
_ => Err(WebGLError::InvalidEnum),
|
||||
};
|
||||
|
||||
chan.send(result).unwrap();
|
||||
}
|
||||
|
||||
fn uniform_location(program_id: WebGLProgramId,
|
||||
fn uniform_location(gl: &gl::Gl,
|
||||
program_id: WebGLProgramId,
|
||||
name: String,
|
||||
chan: MsgSender<Option<i32>>) {
|
||||
let location = gl::get_uniform_location(program_id.get(), &name);
|
||||
let location = gl.get_uniform_location(program_id.get(), &name);
|
||||
let location = if location == -1 {
|
||||
None
|
||||
} else {
|
||||
@ -862,18 +871,18 @@ impl WebGLCommand {
|
||||
}
|
||||
|
||||
|
||||
fn shader_info_log(shader_id: WebGLShaderId, chan: MsgSender<String>) {
|
||||
let log = gl::get_shader_info_log(shader_id.get());
|
||||
fn shader_info_log(gl: &gl::Gl, shader_id: WebGLShaderId, chan: MsgSender<String>) {
|
||||
let log = gl.get_shader_info_log(shader_id.get());
|
||||
chan.send(log).unwrap();
|
||||
}
|
||||
|
||||
fn program_info_log(program_id: WebGLProgramId, chan: MsgSender<String>) {
|
||||
let log = gl::get_program_info_log(program_id.get());
|
||||
fn program_info_log(gl: &gl::Gl, program_id: WebGLProgramId, chan: MsgSender<String>) {
|
||||
let log = gl.get_program_info_log(program_id.get());
|
||||
chan.send(log).unwrap();
|
||||
}
|
||||
|
||||
fn create_buffer(chan: MsgSender<Option<WebGLBufferId>>) {
|
||||
let buffer = gl::gen_buffers(1)[0];
|
||||
fn create_buffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLBufferId>>) {
|
||||
let buffer = gl.gen_buffers(1)[0];
|
||||
let buffer = if buffer == 0 {
|
||||
None
|
||||
} else {
|
||||
@ -882,8 +891,8 @@ impl WebGLCommand {
|
||||
chan.send(buffer).unwrap();
|
||||
}
|
||||
|
||||
fn create_framebuffer(chan: MsgSender<Option<WebGLFramebufferId>>) {
|
||||
let framebuffer = gl::gen_framebuffers(1)[0];
|
||||
fn create_framebuffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLFramebufferId>>) {
|
||||
let framebuffer = gl.gen_framebuffers(1)[0];
|
||||
let framebuffer = if framebuffer == 0 {
|
||||
None
|
||||
} else {
|
||||
@ -893,8 +902,8 @@ impl WebGLCommand {
|
||||
}
|
||||
|
||||
|
||||
fn create_renderbuffer(chan: MsgSender<Option<WebGLRenderbufferId>>) {
|
||||
let renderbuffer = gl::gen_renderbuffers(1)[0];
|
||||
fn create_renderbuffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLRenderbufferId>>) {
|
||||
let renderbuffer = gl.gen_renderbuffers(1)[0];
|
||||
let renderbuffer = if renderbuffer == 0 {
|
||||
None
|
||||
} else {
|
||||
@ -903,8 +912,8 @@ impl WebGLCommand {
|
||||
chan.send(renderbuffer).unwrap();
|
||||
}
|
||||
|
||||
fn create_texture(chan: MsgSender<Option<WebGLTextureId>>) {
|
||||
let texture = gl::gen_textures(1)[0];
|
||||
fn create_texture(gl: &gl::Gl, chan: MsgSender<Option<WebGLTextureId>>) {
|
||||
let texture = gl.gen_textures(1)[0];
|
||||
let texture = if texture == 0 {
|
||||
None
|
||||
} else {
|
||||
@ -914,8 +923,8 @@ impl WebGLCommand {
|
||||
}
|
||||
|
||||
|
||||
fn create_program(chan: MsgSender<Option<WebGLProgramId>>) {
|
||||
let program = gl::create_program();
|
||||
fn create_program(gl: &gl::Gl, chan: MsgSender<Option<WebGLProgramId>>) {
|
||||
let program = gl.create_program();
|
||||
let program = if program == 0 {
|
||||
None
|
||||
} else {
|
||||
@ -924,8 +933,8 @@ impl WebGLCommand {
|
||||
chan.send(program).unwrap();
|
||||
}
|
||||
|
||||
fn create_shader(shader_type: u32, chan: MsgSender<Option<WebGLShaderId>>) {
|
||||
let shader = gl::create_shader(shader_type);
|
||||
fn create_shader(gl: &gl::Gl, shader_type: u32, chan: MsgSender<Option<WebGLShaderId>>) {
|
||||
let shader = gl.create_shader(shader_type);
|
||||
let shader = if shader == 0 {
|
||||
None
|
||||
} else {
|
||||
@ -935,7 +944,8 @@ impl WebGLCommand {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn bind_framebuffer<Native: NativeGLContextMethods>(target: u32,
|
||||
fn bind_framebuffer<Native: NativeGLContextMethods>(gl: &gl::Gl,
|
||||
target: u32,
|
||||
request: WebGLFramebufferBindingRequest,
|
||||
ctx: &GLContext<Native>) {
|
||||
let id = match request {
|
||||
@ -944,13 +954,13 @@ impl WebGLCommand {
|
||||
ctx.borrow_draw_buffer().unwrap().get_framebuffer(),
|
||||
};
|
||||
|
||||
gl::bind_framebuffer(target, id);
|
||||
gl.bind_framebuffer(target, id);
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
fn compile_shader(shader_id: WebGLShaderId, source: String) {
|
||||
gl::shader_source(shader_id.get(), &[source.as_bytes()]);
|
||||
gl::compile_shader(shader_id.get());
|
||||
fn compile_shader(gl: &gl::Gl, shader_id: WebGLShaderId, source: String) {
|
||||
gl.shader_source(shader_id.get(), &[source.as_bytes()]);
|
||||
gl.compile_shader(shader_id.get());
|
||||
}
|
||||
}
|
||||
|
@ -4150,7 +4150,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
ExprAddrOf(ExprVar(p.var().name + 'Copy')),
|
||||
msgexpr, ExprAddrOf(itervar),
|
||||
errfn, p.bareType(side).name,
|
||||
p.name)
|
||||
sentinelKey=p.name,
|
||||
errfnSentinel=errfnSentinel())
|
||||
for p in params ]
|
||||
+ [ self.endRead(msgvar, itervar) ]
|
||||
# Move the message back to its source before sending.
|
||||
|
@ -1859,6 +1859,8 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
|
||||
Preferences::GetInt("nglayout.initialpaint.delay",
|
||||
PAINTLOCK_EVENT_DELAY);
|
||||
|
||||
mPaintSuppressionTimer->SetTarget(
|
||||
mDocument->EventTargetFor(TaskCategory::Other));
|
||||
mPaintSuppressionTimer->InitWithNamedFuncCallback(
|
||||
sPaintSuppressionCallback, this, delay, nsITimer::TYPE_ONE_SHOT,
|
||||
"PresShell::sPaintSuppressionCallback");
|
||||
@ -2005,16 +2007,21 @@ PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord a
|
||||
}
|
||||
if (mAsyncResizeEventTimer) {
|
||||
mAsyncResizeTimerIsActive = true;
|
||||
mAsyncResizeEventTimer->InitWithFuncCallback(AsyncResizeEventCallback,
|
||||
mAsyncResizeEventTimer->SetTarget(
|
||||
mDocument->EventTargetFor(TaskCategory::Other));
|
||||
mAsyncResizeEventTimer->InitWithNamedFuncCallback(AsyncResizeEventCallback,
|
||||
this, 15,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
nsITimer::TYPE_ONE_SHOT,
|
||||
"AsyncResizeEventCallback");
|
||||
}
|
||||
} else {
|
||||
RefPtr<nsRunnableMethod<PresShell> > resizeEvent =
|
||||
NewRunnableMethod("PresShell::FireResizeEvent",
|
||||
this, &PresShell::FireResizeEvent);
|
||||
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(resizeEvent))) {
|
||||
mResizeEvent = resizeEvent;
|
||||
RefPtr<nsRunnableMethod<PresShell>> event =
|
||||
NewRunnableMethod(this, &PresShell::FireResizeEvent);
|
||||
nsresult rv = mDocument->Dispatch("PresShell::FireResizeEvent",
|
||||
TaskCategory::Other,
|
||||
do_AddRef(event));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mResizeEvent = event;
|
||||
SetNeedStyleFlush();
|
||||
}
|
||||
}
|
||||
@ -3687,28 +3694,6 @@ PresShell::GetRectVisibility(nsIFrame* aFrame,
|
||||
return nsRectVisibility_kVisible;
|
||||
}
|
||||
|
||||
class PaintTimerCallBack final : public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
explicit PaintTimerCallBack(PresShell* aShell) : mShell(aShell) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Notify(nsITimer* aTimer) final
|
||||
{
|
||||
mShell->SetNextPaintCompressed();
|
||||
mShell->ScheduleViewManagerFlush();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~PaintTimerCallBack() {}
|
||||
|
||||
PresShell* mShell;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(PaintTimerCallBack, nsITimerCallback)
|
||||
|
||||
void
|
||||
PresShell::ScheduleViewManagerFlush(PaintType aType)
|
||||
{
|
||||
@ -3716,9 +3701,24 @@ PresShell::ScheduleViewManagerFlush(PaintType aType)
|
||||
// Delay paint for 1 second.
|
||||
static const uint32_t kPaintDelayPeriod = 1000;
|
||||
if (!mDelayedPaintTimer) {
|
||||
nsTimerCallbackFunc
|
||||
PaintTimerCallBack = [](nsITimer* aTimer, void* aClosure) {
|
||||
// The passed-in PresShell is always alive here. Because if PresShell
|
||||
// died, mDelayedPaintTimer->Cancel() would be called during the
|
||||
// destruction and this callback would never be invoked.
|
||||
auto self = static_cast<PresShell*>(aClosure);
|
||||
self->SetNextPaintCompressed();
|
||||
self->ScheduleViewManagerFlush();
|
||||
};
|
||||
|
||||
mDelayedPaintTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
RefPtr<PaintTimerCallBack> cb = new PaintTimerCallBack(this);
|
||||
mDelayedPaintTimer->InitWithCallback(cb, kPaintDelayPeriod, nsITimer::TYPE_ONE_SHOT);
|
||||
mDelayedPaintTimer->SetTarget(
|
||||
mDocument->EventTargetFor(TaskCategory::Other));
|
||||
mDelayedPaintTimer->InitWithNamedFuncCallback(PaintTimerCallBack,
|
||||
this,
|
||||
kPaintDelayPeriod,
|
||||
nsITimer::TYPE_ONE_SHOT,
|
||||
"PaintTimerCallBack");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -6256,11 +6256,15 @@ PresShell::ScheduleApproximateFrameVisibilityUpdateNow()
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsRunnableMethod<PresShell> > ev =
|
||||
NewRunnableMethod("PresShell::UpdateApproximateFrameVisibility",
|
||||
this, &PresShell::UpdateApproximateFrameVisibility);
|
||||
if (NS_SUCCEEDED(NS_DispatchToCurrentThread(ev))) {
|
||||
mUpdateApproximateFrameVisibilityEvent = ev;
|
||||
RefPtr<nsRunnableMethod<PresShell>> event =
|
||||
NewRunnableMethod(this, &PresShell::UpdateApproximateFrameVisibility);
|
||||
nsresult rv =
|
||||
mDocument->Dispatch("PresShell::UpdateApproximateFrameVisibility",
|
||||
TaskCategory::Other,
|
||||
do_AddRef(event));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mUpdateApproximateFrameVisibilityEvent = event;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9170,10 +9174,13 @@ PresShell::ScheduleReflowOffTimer()
|
||||
|
||||
if (!mReflowContinueTimer) {
|
||||
mReflowContinueTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mReflowContinueTimer->SetTarget(
|
||||
mDocument->EventTargetFor(TaskCategory::Other));
|
||||
if (!mReflowContinueTimer ||
|
||||
NS_FAILED(mReflowContinueTimer->
|
||||
InitWithFuncCallback(sReflowContinueCallback, this, 30,
|
||||
nsITimer::TYPE_ONE_SHOT))) {
|
||||
InitWithNamedFuncCallback(sReflowContinueCallback, this, 30,
|
||||
nsITimer::TYPE_ONE_SHOT,
|
||||
"sReflowContinueCallback"))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -158,8 +158,12 @@ ZoomConstraintsClient::Observe(nsISupports* aSubject, const char* aTopic, const
|
||||
// We need to run this later because all the pref change listeners need
|
||||
// to execute before we can be guaranteed that gfxPrefs::ForceUserScalable()
|
||||
// returns the updated value.
|
||||
NS_DispatchToMainThread(NewRunnableMethod(
|
||||
this, &ZoomConstraintsClient::RefreshZoomConstraints));
|
||||
|
||||
RefPtr<nsRunnableMethod<ZoomConstraintsClient>> event =
|
||||
NewRunnableMethod(this, &ZoomConstraintsClient::RefreshZoomConstraints);
|
||||
mDocument->Dispatch("ZoomConstraintsClient::RefreshZoomConstraints",
|
||||
TaskCategory::Other,
|
||||
event.forget());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1741,7 +1741,7 @@ nsCSSFrameConstructor::CreateGeneratedContent(nsFrameConstructorState& aState,
|
||||
|
||||
case eStyleContentType_Counter:
|
||||
case eStyleContentType_Counters: {
|
||||
nsCSSValue::Array* counters = data.GetCounters();
|
||||
nsCSSValue::ThreadSafeArray* counters = data.GetCounters();
|
||||
nsCounterList* counterList = mCounterManager.CounterListFor(
|
||||
nsDependentString(counters->Item(0).GetStringBufferValue()));
|
||||
|
||||
|
@ -79,7 +79,7 @@ struct nsCounterUseNode : public nsCounterNode {
|
||||
// The same structure passed through the style system: an array
|
||||
// containing the values in the counter() or counters() in the order
|
||||
// given in the CSS spec.
|
||||
RefPtr<nsCSSValue::Array> mCounterFunction;
|
||||
RefPtr<nsCSSValue::ThreadSafeArray> mCounterFunction;
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
RefPtr<mozilla::CounterStyle> mCounterStyle;
|
||||
@ -89,7 +89,7 @@ struct nsCounterUseNode : public nsCounterNode {
|
||||
|
||||
// args go directly to member variables here and of nsGenConNode
|
||||
nsCounterUseNode(nsPresContext* aPresContext,
|
||||
nsCSSValue::Array* aCounterFunction,
|
||||
nsCSSValue::ThreadSafeArray* aCounterFunction,
|
||||
uint32_t aContentIndex, bool aAllCounters)
|
||||
: nsCounterNode(aContentIndex, USE)
|
||||
, mCounterFunction(aCounterFunction)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user