mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
Merge mozilla-inbound to mozilla-central. a=merge
This commit is contained in:
commit
07c6e76122
@ -273,6 +273,26 @@ DocAccessibleChild::SendRoleChangedEvent(const a11y::role& aRole)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::SendScrollingEvent(const uint64_t& aID,
|
||||
const uint64_t& aType,
|
||||
const uint32_t& aScrollX,
|
||||
const uint32_t& aScrollY,
|
||||
const uint32_t& aMaxScrollX,
|
||||
const uint32_t& aMaxScrollY)
|
||||
{
|
||||
if (IsConstructedInParentProcess()) {
|
||||
return PDocAccessibleChild::SendScrollingEvent(aID, aType,
|
||||
aScrollX, aScrollY,
|
||||
aMaxScrollX, aMaxScrollY);
|
||||
}
|
||||
|
||||
PushDeferredEvent(MakeUnique<SerializedScrolling>(this, aID, aType,
|
||||
aScrollX, aScrollY,
|
||||
aMaxScrollX, aMaxScrollY));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::ConstructChildDocInParentProcess(
|
||||
DocAccessibleChild* aNewChildDoc,
|
||||
|
@ -58,6 +58,10 @@ public:
|
||||
bool SendSelectionEvent(const uint64_t& aID, const uint64_t& aWidgetID,
|
||||
const uint32_t& aType);
|
||||
bool SendRoleChangedEvent(const a11y::role& aRole);
|
||||
bool SendScrollingEvent(const uint64_t& aID, const uint64_t& aType,
|
||||
const uint32_t& aScrollX, const uint32_t& aScrollY,
|
||||
const uint32_t& aMaxScrollX,
|
||||
const uint32_t& aMaxScrollY);
|
||||
|
||||
bool ConstructChildDocInParentProcess(DocAccessibleChild* aNewChildDoc,
|
||||
uint64_t aUniqueID, uint32_t aMsaaID);
|
||||
@ -269,6 +273,35 @@ private:
|
||||
a11y::role mRole;
|
||||
};
|
||||
|
||||
struct SerializedScrolling final : public DeferredEvent
|
||||
{
|
||||
explicit SerializedScrolling(DocAccessibleChild* aTarget,
|
||||
uint64_t aID, uint64_t aType,
|
||||
uint32_t aScrollX, uint32_t aScrollY,
|
||||
uint32_t aMaxScrollX, uint32_t aMaxScrollY)
|
||||
: DeferredEvent(aTarget)
|
||||
, mID(aID)
|
||||
, mType(aType)
|
||||
, mScrollX(aScrollX)
|
||||
, mScrollY(aScrollY)
|
||||
, mMaxScrollX(aMaxScrollX)
|
||||
, mMaxScrollY(aMaxScrollY)
|
||||
{}
|
||||
|
||||
void Dispatch(DocAccessibleChild* aIPCDoc) override
|
||||
{
|
||||
Unused << aIPCDoc->SendScrollingEvent(mID, mType, mScrollX, mScrollY,
|
||||
mMaxScrollX, mMaxScrollY);
|
||||
}
|
||||
|
||||
uint64_t mID;
|
||||
uint64_t mType;
|
||||
uint32_t mScrollX;
|
||||
uint32_t mScrollY;
|
||||
uint32_t mMaxScrollX;
|
||||
uint32_t mMaxScrollY;
|
||||
};
|
||||
|
||||
struct SerializedEvent final : public DeferredEvent
|
||||
{
|
||||
SerializedEvent(DocAccessibleChild* aTarget, uint64_t aID, uint32_t aType)
|
||||
|
@ -775,7 +775,7 @@ window._gBrowser = {
|
||||
}
|
||||
},
|
||||
|
||||
setIcon(aTab, aIconURL = "", aOriginalURL = aIconURL) {
|
||||
setIcon(aTab, aIconURL = "", aOriginalURL = aIconURL, aLoadingPrincipal = null) {
|
||||
let makeString = (url) => url instanceof Ci.nsIURI ? url.spec : url;
|
||||
|
||||
aIconURL = makeString(aIconURL);
|
||||
@ -788,8 +788,8 @@ window._gBrowser = {
|
||||
"data:",
|
||||
];
|
||||
|
||||
if (aIconURL && !LOCAL_PROTOCOLS.some(protocol => aIconURL.startsWith(protocol))) {
|
||||
console.error(`Attempt to set a remote URL ${aIconURL} as a tab icon.`);
|
||||
if (aIconURL && !aLoadingPrincipal && !LOCAL_PROTOCOLS.some(protocol => aIconURL.startsWith(protocol))) {
|
||||
console.error(`Attempt to set a remote URL ${aIconURL} as a tab icon without a loading principal.`);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -798,9 +798,15 @@ window._gBrowser = {
|
||||
|
||||
if (aIconURL != aTab.getAttribute("image")) {
|
||||
if (aIconURL) {
|
||||
if (aLoadingPrincipal) {
|
||||
aTab.setAttribute("iconloadingprincipal", aLoadingPrincipal);
|
||||
} else {
|
||||
aTab.removeAttribute("iconloadingprincipal");
|
||||
}
|
||||
aTab.setAttribute("image", aIconURL);
|
||||
} else {
|
||||
aTab.removeAttribute("image");
|
||||
aTab.removeAttribute("iconloadingprincipal");
|
||||
}
|
||||
this._tabAttrModified(aTab, ["image"]);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
<iframe type="content" id="frame2" onload="doTest()"/>
|
||||
<script type="application/javascript"><![CDATA[
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
@ -32,8 +31,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
||||
frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
|
@ -76,8 +76,8 @@ let PaymentFrameScript = {
|
||||
DEFAULT_REGION: FormAutofill.DEFAULT_REGION,
|
||||
supportedCountries: FormAutofill.supportedCountries,
|
||||
|
||||
getAddressLabel(address) {
|
||||
return FormAutofillUtils.getAddressLabel(address);
|
||||
getAddressLabel(address, addressFields = null) {
|
||||
return FormAutofillUtils.getAddressLabel(address, addressFields);
|
||||
},
|
||||
|
||||
isCCNumber(value) {
|
||||
|
@ -57,8 +57,8 @@ export default class AddressOption extends ObservedPropertiesMixin(RichOption) {
|
||||
super.connectedCallback();
|
||||
}
|
||||
|
||||
static formatSingleLineLabel(address) {
|
||||
return PaymentDialogUtils.getAddressLabel(address);
|
||||
static formatSingleLineLabel(address, addressFields) {
|
||||
return PaymentDialogUtils.getAddressLabel(address, addressFields);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -100,7 +100,10 @@ export default class AddressPicker extends RichPicker {
|
||||
}
|
||||
}
|
||||
|
||||
optionEl.textContent = AddressOption.formatSingleLineLabel(address);
|
||||
// fieldNames getter is not used here because it returns a default array with
|
||||
// attributes even when "address-fields" observed attribute is null.
|
||||
let addressFields = this.getAttribute("address-fields");
|
||||
optionEl.textContent = AddressOption.formatSingleLineLabel(address, addressFields);
|
||||
desiredOptions.push(optionEl);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,12 @@ var log = {
|
||||
};
|
||||
|
||||
var PaymentDialogUtils = {
|
||||
getAddressLabel(address) {
|
||||
getAddressLabel(address, addressFields = null) {
|
||||
if (addressFields) {
|
||||
let requestedFields = addressFields.trim().split(/\s+/);
|
||||
return requestedFields.filter(f => f && address[f]).map(f => address[f]).join(", ") +
|
||||
` (${address.guid})`;
|
||||
}
|
||||
return `${address.name} (${address.guid})`;
|
||||
},
|
||||
isCCNumber(str) {
|
||||
|
@ -375,6 +375,89 @@ add_task(async function test_edit_payer_contact_name_email_phone_link() {
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_shipping_address_picker() {
|
||||
await setup();
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: BLANK_PAGE_URL,
|
||||
}, async browser => {
|
||||
let {win, frame} =
|
||||
await setupPaymentDialog(browser, {
|
||||
methodData: [PTU.MethodData.basicCard],
|
||||
details: PTU.Details.total60USD,
|
||||
options: PTU.Options.requestShippingOption,
|
||||
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
|
||||
}
|
||||
);
|
||||
|
||||
await spawnPaymentDialogTask(frame, async function test_picker_option_label(address) {
|
||||
let {
|
||||
PaymentTestUtils: PTU,
|
||||
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
|
||||
ChromeUtils.import("resource://formautofill/FormAutofillUtils.jsm");
|
||||
|
||||
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return Object.keys(state.savedAddresses).length == 1;
|
||||
}, "One saved addresses when starting test");
|
||||
let savedAddress = Object.values(state.savedAddresses)[0];
|
||||
|
||||
let selector = "address-picker[selected-state-key='selectedShippingAddress']";
|
||||
let picker = content.document.querySelector(selector);
|
||||
let option = Cu.waiveXrays(picker).dropdown.popupBox.children[0];
|
||||
ok(option.textContent,
|
||||
FormAutofillUtils.getAddressLabel(savedAddress, null),
|
||||
"Shows correct shipping option label");
|
||||
});
|
||||
|
||||
info("clicking cancel");
|
||||
spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_payer_address_picker() {
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: BLANK_PAGE_URL,
|
||||
}, async browser => {
|
||||
let {win, frame} =
|
||||
await setupPaymentDialog(browser, {
|
||||
methodData: [PTU.MethodData.basicCard],
|
||||
details: PTU.Details.total60USD,
|
||||
options: PTU.Options.requestPayerNameEmailAndPhone,
|
||||
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
|
||||
}
|
||||
);
|
||||
|
||||
await spawnPaymentDialogTask(frame, async function test_picker_option_label(address) {
|
||||
let {
|
||||
PaymentTestUtils: PTU,
|
||||
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
|
||||
ChromeUtils.import("resource://formautofill/FormAutofillUtils.jsm");
|
||||
|
||||
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return Object.keys(state.savedAddresses).length == 1;
|
||||
}, "One saved addresses when starting test");
|
||||
let savedAddress = Object.values(state.savedAddresses)[0];
|
||||
|
||||
let selector = "address-picker[selected-state-key='selectedPayerAddress']";
|
||||
let picker = content.document.querySelector(selector);
|
||||
let option = Cu.waiveXrays(picker).dropdown.popupBox.children[0];
|
||||
is(option.textContent.includes("32 Vassar Street"), false,
|
||||
"Payer option label does not contain street address");
|
||||
ok(option.textContent,
|
||||
FormAutofillUtils.getAddressLabel(savedAddress, "name tel email"),
|
||||
"Shows correct payer option label");
|
||||
});
|
||||
|
||||
info("clicking cancel");
|
||||
spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Test that we can correctly add an address from a private window
|
||||
*/
|
||||
|
@ -1982,7 +1982,6 @@ var SessionStoreInternal = {
|
||||
state: tabState,
|
||||
title: tabTitle,
|
||||
image: tabbrowser.getIcon(aTab),
|
||||
iconLoadingPrincipal: Utils.serializePrincipal(aTab.linkedBrowser.contentPrincipal),
|
||||
pos: aTab._tPos,
|
||||
closedAt: Date.now()
|
||||
};
|
||||
@ -2779,9 +2778,7 @@ var SessionStoreInternal = {
|
||||
|
||||
// Restore the tab icon.
|
||||
if ("image" in tabData) {
|
||||
// Use the serialized contentPrincipal with the new icon load.
|
||||
let loadingPrincipal = Utils.deserializePrincipal(tabData.iconLoadingPrincipal);
|
||||
win.gBrowser.setIcon(tab, tabData.image, loadingPrincipal);
|
||||
win.gBrowser.setIcon(tab, tabData.image, undefined, tabData.iconLoadingPrincipal);
|
||||
TabStateCache.update(browser, { image: null, iconLoadingPrincipal: null });
|
||||
}
|
||||
},
|
||||
|
@ -12,10 +12,7 @@ var EXPORTED_SYMBOLS = ["TabAttributes"];
|
||||
// 'muted' should not be accessed directly but handled by using the
|
||||
// tab.linkedBrowser.audioMuted/toggleMuteAudio methods.
|
||||
// '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",
|
||||
"skipbackgroundnotify"]);
|
||||
const ATTRIBUTES_TO_SKIP = new Set(["image", "muted", "pending", "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
|
||||
|
@ -12,8 +12,6 @@ ChromeUtils.defineModuleGetter(this, "TabStateCache",
|
||||
"resource:///modules/sessionstore/TabStateCache.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "TabAttributes",
|
||||
"resource:///modules/sessionstore/TabAttributes.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Utils",
|
||||
"resource://gre/modules/sessionstore/Utils.jsm");
|
||||
|
||||
/**
|
||||
* Module that contains tab state collection methods.
|
||||
@ -125,11 +123,6 @@ var TabStateInternal = {
|
||||
tabData.image = tabbrowser.getIcon(tab);
|
||||
}
|
||||
|
||||
// Store the serialized contentPrincipal of this tab to use for the icon.
|
||||
if (!("iconLoadingPrincipal" in tabData)) {
|
||||
tabData.iconLoadingPrincipal = Utils.serializePrincipal(browser.mIconLoadingPrincipal);
|
||||
}
|
||||
|
||||
// If there is a userTypedValue set, then either the user has typed something
|
||||
// in the URL bar, or a new tab was opened with a URI to load.
|
||||
// If so, we also track whether we were still in the process of loading something.
|
||||
|
@ -57,6 +57,7 @@ support-files =
|
||||
browser_1234021_page.html
|
||||
browser_1284886_suspend_tab.html
|
||||
browser_1284886_suspend_tab_2.html
|
||||
empty.html
|
||||
|
||||
#NB: the following are disabled
|
||||
# browser_464620_a.html
|
||||
@ -107,6 +108,7 @@ skip-if = (verify && (os == 'win' || os == 'mac'))
|
||||
[browser_history_persist.js]
|
||||
[browser_label_and_icon.js]
|
||||
[browser_merge_closed_tabs.js]
|
||||
[browser_old_favicon.js]
|
||||
[browser_page_title.js]
|
||||
[browser_pending_tabs.js]
|
||||
[browser_privatetabs.js]
|
||||
|
44
browser/components/sessionstore/test/browser_old_favicon.js
Normal file
44
browser/components/sessionstore/test/browser_old_favicon.js
Normal file
@ -0,0 +1,44 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Ensure that we can restore old style favicon and principals.
|
||||
*/
|
||||
add_task(async function test_label_and_icon() {
|
||||
let helper = Cc["@mozilla.org/network/serialization-helper;1"].getService(Ci.nsISerializationHelper);
|
||||
|
||||
// Make sure that tabs are restored on demand as otherwise the tab will start
|
||||
// loading immediately and override the icon.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.sessionstore.restore_on_demand", true]],
|
||||
});
|
||||
|
||||
// Create a new tab.
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, "http://www.example.com/browser/browser/components/sessionstore/test/empty.html");
|
||||
let browser = tab.linkedBrowser;
|
||||
await promiseBrowserLoaded(browser);
|
||||
|
||||
let contentPrincipal = browser.contentPrincipal;
|
||||
let serializedPrincipal = helper.serializeToString(contentPrincipal);
|
||||
|
||||
// Retrieve the tab state.
|
||||
await TabStateFlusher.flush(browser);
|
||||
let state = JSON.parse(ss.getTabState(tab));
|
||||
state.image = "http://www.example.com/favicon.ico";
|
||||
state.iconLoadingPrincipal = serializedPrincipal;
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
||||
// Open a new tab to restore into.
|
||||
tab = BrowserTestUtils.addTab(gBrowser, "about:blank");
|
||||
ss.setTabState(tab, state);
|
||||
await promiseTabRestoring(tab);
|
||||
|
||||
// Check that label and icon are set for the restoring tab.
|
||||
is(gBrowser.getIcon(tab), "http://www.example.com/favicon.ico", "icon is set");
|
||||
is(tab.getAttribute("image"), "http://www.example.com/favicon.ico", "tab image is set");
|
||||
is(tab.getAttribute("iconloadingprincipal"), serializedPrincipal, "tab image loading principal is set");
|
||||
|
||||
// Cleanup.
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
6
browser/components/sessionstore/test/empty.html
Normal file
6
browser/components/sessionstore/test/empty.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -9,8 +9,8 @@ CBINDGEN="${TOOLTOOL_DIR}/cbindgen/cbindgen"
|
||||
|
||||
export NODEJS="${TOOLTOOL_DIR}/node/bin/node"
|
||||
|
||||
CC="${TOOLTOOL_DIR}/gcc/bin/gcc"
|
||||
CXX="${TOOLTOOL_DIR}/gcc/bin/g++"
|
||||
CC="${TOOLTOOL_DIR}/clang/bin/clang"
|
||||
CXX="${TOOLTOOL_DIR}/clang/bin/clang++"
|
||||
|
||||
mk_add_options "export PATH=${TOOLTOOL_DIR}/gcc/bin:${PATH}"
|
||||
mk_add_options "export LD_LIBRARY_PATH=${TOOLTOOL_DIR}/gcc/lib64:${TOOLTOOL_DIR}/gcc/lib32:${TOOLTOOL_DIR}/gcc/lib"
|
||||
|
@ -246,17 +246,18 @@ this.FormAutofillUtils = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Get address display label. It should display up to two pieces of
|
||||
* information, separated by a comma.
|
||||
* Get address display label. It should display information separated
|
||||
* by a comma.
|
||||
*
|
||||
* @param {object} address
|
||||
* @param {string?} addressFields Override the fields which can be displayed, but not the order.
|
||||
* @returns {string}
|
||||
*/
|
||||
getAddressLabel(address) {
|
||||
getAddressLabel(address, addressFields = null) {
|
||||
// TODO: Implement a smarter way for deciding what to display
|
||||
// as option text. Possibly improve the algorithm in
|
||||
// ProfileAutoCompleteResult.jsm and reuse it here.
|
||||
const fieldOrder = [
|
||||
let fieldOrder = [
|
||||
"name",
|
||||
"-moz-street-address-one-line", // Street address
|
||||
"address-level2", // City/Town
|
||||
@ -270,6 +271,10 @@ this.FormAutofillUtils = {
|
||||
|
||||
address = {...address};
|
||||
let parts = [];
|
||||
if (addressFields) {
|
||||
let requiredFields = addressFields.trim().split(/\s+/);
|
||||
fieldOrder = fieldOrder.filter(name => requiredFields.includes(name));
|
||||
}
|
||||
if (address["street-address"]) {
|
||||
address["-moz-street-address-one-line"] = this.toOneLineAddress(
|
||||
address["street-address"]
|
||||
@ -280,7 +285,7 @@ this.FormAutofillUtils = {
|
||||
if (string) {
|
||||
parts.push(string);
|
||||
}
|
||||
if (parts.length == 2) {
|
||||
if (parts.length == 2 && !addressFields) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -156,8 +156,8 @@ if test -n "$MOZ_SYSTEM_NSPR" -o -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then
|
||||
,
|
||||
AC_MSG_ERROR([system NSPR does not support PR_UINT64 or including prtypes.h does not provide it]))
|
||||
CFLAGS=$_SAVE_CFLAGS
|
||||
NSPR_INCLUDE_DIR=`echo ${NSPR_CFLAGS} | sed -e 's/.*-I\([^ ]*\).*/\1/'`
|
||||
NSPR_LIB_DIR=`echo ${NSPR_LIBS} | sed -e 's/.*-L\([^ ]*\).*/\1/'`
|
||||
NSPR_INCLUDE_DIR=`echo ${NSPR_CFLAGS} | sed -e 's/.*-I\([[^ ]]*\).*/\1/'`
|
||||
NSPR_LIB_DIR=`echo ${NSPR_LIBS} | sed -e 's/.*-L\([[^ ]]*\).*/\1/'`
|
||||
elif test -z "$JS_POSIX_NSPR"; then
|
||||
NSPR_INCLUDE_DIR="${DIST}/include/nspr"
|
||||
NSPR_CFLAGS="-I${NSPR_INCLUDE_DIR}"
|
||||
|
@ -4,26 +4,10 @@ dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
AC_DEFUN([MOZ_CONFIG_SANITIZE], [
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Link Time Optimization (LTO)
|
||||
dnl ========================================================
|
||||
if test -n "$MOZ_LTO"; then
|
||||
MOZ_LLVM_HACKS=1
|
||||
AC_DEFINE(MOZ_LTO)
|
||||
MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
|
||||
|
||||
CFLAGS="$CFLAGS $MOZ_LTO_CFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $MOZ_LTO_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $MOZ_LTO_CFLAGS"
|
||||
LDFLAGS="$LDFLAGS $MOZ_LTO_LDFLAGS"
|
||||
fi
|
||||
AC_SUBST(MOZ_LTO)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Use Address Sanitizer
|
||||
dnl ========================================================
|
||||
if test -n "$MOZ_ASAN"; then
|
||||
MOZ_LLVM_HACKS=1
|
||||
if test -n "$CLANG_CL"; then
|
||||
# Look for the ASan runtime binary
|
||||
if test "$CPU_ARCH" = "x86_64"; then
|
||||
@ -61,7 +45,6 @@ MOZ_ARG_ENABLE_BOOL(memory-sanitizer,
|
||||
MOZ_MSAN=1,
|
||||
MOZ_MSAN= )
|
||||
if test -n "$MOZ_MSAN"; then
|
||||
MOZ_LLVM_HACKS=1
|
||||
CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins $CFLAGS"
|
||||
CXXFLAGS="-fsanitize=memory -fsanitize-memory-track-origins $CXXFLAGS"
|
||||
if test -z "$CLANG_CL"; then
|
||||
@ -80,7 +63,6 @@ MOZ_ARG_ENABLE_BOOL(thread-sanitizer,
|
||||
MOZ_TSAN=1,
|
||||
MOZ_TSAN= )
|
||||
if test -n "$MOZ_TSAN"; then
|
||||
MOZ_LLVM_HACKS=1
|
||||
CFLAGS="-fsanitize=thread $CFLAGS"
|
||||
CXXFLAGS="-fsanitize=thread $CXXFLAGS"
|
||||
if test -z "$CLANG_CL"; then
|
||||
@ -105,7 +87,6 @@ MOZ_ARG_ENABLE_BOOL(unsigned-overflow-sanitizer,
|
||||
MOZ_UNSIGNED_OVERFLOW_SANITIZE= )
|
||||
|
||||
if test -n "$MOZ_SIGNED_OVERFLOW_SANITIZE$MOZ_UNSIGNED_OVERFLOW_SANITIZE"; then
|
||||
MOZ_LLVM_HACKS=1
|
||||
MOZ_UBSAN=1
|
||||
SANITIZER_BLACKLISTS=""
|
||||
if test -n "$MOZ_SIGNED_OVERFLOW_SANITIZE"; then
|
||||
@ -138,20 +119,6 @@ AC_SUBST(MOZ_UBSAN)
|
||||
# The LLVM symbolizer is used by all sanitizers
|
||||
AC_SUBST(LLVM_SYMBOLIZER)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable hacks required for LLVM instrumentations
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(llvm-hacks,
|
||||
[ --enable-llvm-hacks Enable workarounds required for several LLVM instrumentations (default=no)],
|
||||
MOZ_LLVM_HACKS=1,
|
||||
MOZ_LLVM_HACKS= )
|
||||
if test -n "$MOZ_LLVM_HACKS"; then
|
||||
MOZ_NO_WLZDEFS=1
|
||||
MOZ_CFLAGS_NSS=1
|
||||
fi
|
||||
AC_SUBST(MOZ_NO_WLZDEFS)
|
||||
AC_SUBST(MOZ_CFLAGS_NSS)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Test for whether the compiler is compatible with the
|
||||
dnl = given sanitize options.
|
||||
|
@ -933,19 +933,19 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
||||
raise FatalCheckError(
|
||||
'This version (%s) of the MSVC compiler is not '
|
||||
'supported.\n'
|
||||
'You must install Visual C++ 2017 Update 6 in '
|
||||
'order to build.\n'
|
||||
'You must install Visual C++ 2017 Update 6 or '
|
||||
'Update 8 or later in order to build.\n'
|
||||
'See https://developer.mozilla.org/en/'
|
||||
'Windows_Build_Prerequisites' % info.version)
|
||||
|
||||
# MSVC version 15.7 and the previews for 15.8, at least,
|
||||
# can't build Firefox.
|
||||
if info.version >= '19.14.0':
|
||||
if info.version >= '19.14.0' and info.version < '19.15.0':
|
||||
raise FatalCheckError(
|
||||
'This version (%s) of the MSVC compiler is not '
|
||||
'supported due to compiler bugs.\n'
|
||||
'You must install Visual C++ 2017 Update 6 in '
|
||||
'order to build.\n'
|
||||
'You must install Visual C++ 2017 Update 6 or '
|
||||
'Update 8 or later in order to build.\n'
|
||||
'See https://developer.mozilla.org/en/'
|
||||
'Windows_Build_Prerequisites' % info.version)
|
||||
|
||||
@ -1403,8 +1403,10 @@ def lto(value, pgo, c_compiler):
|
||||
|
||||
|
||||
add_old_configure_assignment('MOZ_LTO', lto.enabled)
|
||||
add_old_configure_assignment('MOZ_LTO_CFLAGS', lto.cflags)
|
||||
add_old_configure_assignment('MOZ_LTO_LDFLAGS', lto.ldflags)
|
||||
set_config('MOZ_LTO', lto.enabled)
|
||||
set_define('MOZ_LTO', lto.enabled)
|
||||
set_config('MOZ_LTO_CFLAGS', lto.cflags)
|
||||
set_config('MOZ_LTO_LDFLAGS', lto.ldflags)
|
||||
|
||||
# ASAN
|
||||
# ==============================================================
|
||||
|
@ -38,7 +38,7 @@ for v in ('OS_CPPFLAGS', 'OS_CFLAGS', 'DEBUG', 'CLANG_PLUGIN', 'OPTIMIZE',
|
||||
idx += 1
|
||||
COMPILE_FLAGS[v] = flags
|
||||
|
||||
COMPILE_FLAGS['OS_CFLAGS'] += ['-O2', '-fno-stack-protector']
|
||||
COMPILE_FLAGS['OS_CFLAGS'] += ['-O2', '-fno-stack-protector', '-fno-lto']
|
||||
|
||||
AllowCompilerWarnings()
|
||||
NoVisibilityFlags()
|
||||
|
@ -14,11 +14,9 @@ if not CONFIG['CROSS_COMPILE']:
|
||||
'test-ctors.c',
|
||||
]
|
||||
|
||||
for f in CONFIG['OS_CFLAGS']:
|
||||
if f.startswith('-flto'):
|
||||
SOURCES['dummy.c'].flags += ['-fno-lto']
|
||||
SOURCES['test-array.c'].flags += ['-fno-lto']
|
||||
SOURCES['test-ctors.c'].flags += ['-fno-lto']
|
||||
SOURCES['dummy.c'].flags += ['-fno-lto']
|
||||
SOURCES['test-array.c'].flags += ['-fno-lto']
|
||||
SOURCES['test-ctors.c'].flags += ['-fno-lto']
|
||||
|
||||
HOST_SOURCES += [
|
||||
'elf.cpp',
|
||||
|
@ -7,7 +7,7 @@ fi
|
||||
|
||||
TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
|
||||
|
||||
if [ -n "$FORCE_GCC" ]; then
|
||||
if [ -n "$FORCE_GCC" -o -n "$MOZ_PGO" ]; then
|
||||
CC="$TOOLTOOL_DIR/gcc/bin/gcc"
|
||||
CXX="$TOOLTOOL_DIR/gcc/bin/g++"
|
||||
else
|
||||
|
@ -199,12 +199,12 @@ INCLUDES = \
|
||||
|
||||
include $(MOZILLA_DIR)/config/static-checking-config.mk
|
||||
|
||||
LDFLAGS = $(COMPUTED_LDFLAGS) $(PGO_LDFLAGS) $(MK_LDFLAGS)
|
||||
LDFLAGS = $(MOZ_LTO_LDFLAGS) $(COMPUTED_LDFLAGS) $(PGO_LDFLAGS) $(MK_LDFLAGS)
|
||||
|
||||
COMPILE_CFLAGS = $(COMPUTED_CFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
|
||||
COMPILE_CXXFLAGS = $(COMPUTED_CXXFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
|
||||
COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS)
|
||||
COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS)
|
||||
COMPILE_CFLAGS = $(MOZ_LTO_CFLAGS) $(COMPUTED_CFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
|
||||
COMPILE_CXXFLAGS = $(MOZ_LTO_CFLAGS) $(COMPUTED_CXXFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
|
||||
COMPILE_CMFLAGS = $(MOZ_LTO_CFLAGS) $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS)
|
||||
COMPILE_CMMFLAGS = $(MOZ_LTO_CFLAGS) $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS)
|
||||
ASFLAGS = $(COMPUTED_ASFLAGS)
|
||||
SFLAGS = $(COMPUTED_SFLAGS)
|
||||
|
||||
|
@ -388,8 +388,17 @@ endif
|
||||
ifeq (,$(CROSS_COMPILE))
|
||||
HOST_OUTOPTION = $(OUTOPTION)
|
||||
else
|
||||
# Windows-to-Windows cross compiles should always use MSVC-style options for
|
||||
# host compiles.
|
||||
ifeq (WINNT_WINNT,$(HOST_OS_ARCH)_$(OS_ARCH))
|
||||
ifneq (,$(filter-out msvc clang-cl,$(HOST_CC_TYPE)))
|
||||
$(error MSVC-style compilers should be used for host compilations!)
|
||||
endif
|
||||
HOST_OUTOPTION = -Fo# eol
|
||||
else
|
||||
HOST_OUTOPTION = -o # eol
|
||||
endif
|
||||
endif
|
||||
################################################################################
|
||||
|
||||
# Ensure the build config is up to date. This is done automatically when builds
|
||||
|
@ -168,7 +168,7 @@ class TestNsinstall(unittest.TestCase):
|
||||
NSINSTALL_PATH,
|
||||
testfile, testdir])
|
||||
p.run()
|
||||
rv = p.waitForFinish()
|
||||
rv = p.wait()
|
||||
|
||||
self.assertEqual(rv, 0)
|
||||
destfile = os.path.join(testdir, filename)
|
||||
|
@ -51,8 +51,8 @@ async function runTests(inspector) {
|
||||
const onTooltipHidden = tooltip.once("hidden");
|
||||
|
||||
info("Click on another tag to hide the event tooltip");
|
||||
const h1 = await getContainerForSelector("h1", inspector);
|
||||
const tag = h1.elt.querySelector(".tag");
|
||||
const script = await getContainerForSelector("script", inspector);
|
||||
const tag = script.elt.querySelector(".tag");
|
||||
EventUtils.synthesizeMouseAtCenter(tag, {}, inspector.markup.doc.defaultView);
|
||||
|
||||
await onTooltipHidden;
|
||||
|
@ -394,7 +394,7 @@ ul.children + .tag-line::before {
|
||||
/* Markup Badges */
|
||||
.markup-badge {
|
||||
display: inline-block;
|
||||
font-size: 9px;
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
line-height: 11px;
|
||||
vertical-align: 1px;
|
||||
@ -407,6 +407,12 @@ ul.children + .tag-line::before {
|
||||
color: var(--markup-badge-color);
|
||||
}
|
||||
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
.markup-badge {
|
||||
font-size: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
.markup-badge.active {
|
||||
background-color: var(--markup-badge-active-background-color);
|
||||
border-color: var(--theme-selection-color);
|
||||
|
@ -8,6 +8,7 @@
|
||||
// like.
|
||||
|
||||
#include "DevTools.h"
|
||||
#include "js/SavedFrameAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/devtools/DeserializedNode.h"
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsStringStream.h"
|
||||
|
||||
#include "js/JSON.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
#include "mozilla/dom/FetchUtil.h"
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "ChromeUtils.h"
|
||||
|
||||
#include "js/AutoByteString.h"
|
||||
#include "js/SavedFrameAPI.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "WrapperFactory.h"
|
||||
|
||||
|
140
dom/base/VisualViewport.cpp
Normal file
140
dom/base/VisualViewport.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VisualViewport.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
VisualViewport::VisualViewport(nsPIDOMWindowInner* aWindow)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
{
|
||||
}
|
||||
|
||||
VisualViewport::~VisualViewport()
|
||||
{
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
JSObject*
|
||||
VisualViewport::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VisualViewport_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
CSSSize
|
||||
VisualViewport::VisualViewportSize() const
|
||||
{
|
||||
CSSSize size = CSSSize(0,0);
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (presShell) {
|
||||
if (presShell->IsVisualViewportSizeSet()) {
|
||||
size = CSSRect::FromAppUnits(
|
||||
presShell->GetVisualViewportSize());
|
||||
} else {
|
||||
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
size = CSSRect::FromAppUnits(sf->GetScrollPortRect().Size());
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
double
|
||||
VisualViewport::Width() const
|
||||
{
|
||||
CSSSize size = VisualViewportSize();
|
||||
return size.width;
|
||||
}
|
||||
|
||||
double
|
||||
VisualViewport::Height() const
|
||||
{
|
||||
CSSSize size = VisualViewportSize();
|
||||
return size.height;
|
||||
}
|
||||
|
||||
double
|
||||
VisualViewport::Scale() const
|
||||
{
|
||||
double scale = 1;
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (presShell) {
|
||||
scale = presShell->GetResolution();
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
CSSPoint
|
||||
VisualViewport::VisualViewportOffset() const
|
||||
{
|
||||
CSSPoint offset = CSSPoint(0,0);
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (presShell) {
|
||||
offset = CSSPoint::FromAppUnits(presShell->GetVisualViewportOffset());
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
CSSPoint
|
||||
VisualViewport::LayoutViewportOffset() const
|
||||
{
|
||||
CSSPoint offset = CSSPoint(0,0);
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (presShell) {
|
||||
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
offset = CSSPoint::FromAppUnits(sf->GetScrollPosition());
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
double
|
||||
VisualViewport::PageLeft() const
|
||||
{
|
||||
return VisualViewportOffset().X();
|
||||
}
|
||||
|
||||
double
|
||||
VisualViewport::PageTop() const
|
||||
{
|
||||
return VisualViewportOffset().Y();
|
||||
}
|
||||
|
||||
double
|
||||
VisualViewport::OffsetLeft() const
|
||||
{
|
||||
return PageLeft() - LayoutViewportOffset().X();
|
||||
}
|
||||
|
||||
double
|
||||
VisualViewport::OffsetTop() const
|
||||
{
|
||||
return PageTop() - LayoutViewportOffset().Y();
|
||||
}
|
||||
|
||||
nsIPresShell*
|
||||
VisualViewport::GetPresShell() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIDocShell* docShell = window->GetDocShell();
|
||||
if (!docShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return docShell->GetPresShell();
|
||||
}
|
48
dom/base/VisualViewport.h
Normal file
48
dom/base/VisualViewport.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
#ifndef mozilla_dom_VisualViewport_h
|
||||
#define mozilla_dom_VisualViewport_h
|
||||
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/VisualViewportBinding.h"
|
||||
#include "Units.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* Visual Viewport API spec: https://wicg.github.io/visual-viewport/#the-visualviewport-interface */
|
||||
class VisualViewport final: public mozilla::DOMEventTargetHelper
|
||||
{
|
||||
|
||||
public:
|
||||
explicit VisualViewport(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
double OffsetLeft() const;
|
||||
double OffsetTop() const;
|
||||
double PageLeft() const;
|
||||
double PageTop() const;
|
||||
double Width() const;
|
||||
double Height() const;
|
||||
double Scale() const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
private:
|
||||
virtual ~VisualViewport();
|
||||
|
||||
CSSSize VisualViewportSize() const;
|
||||
CSSPoint VisualViewportOffset() const;
|
||||
CSSPoint LayoutViewportOffset() const;
|
||||
nsIPresShell* GetPresShell() const;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_VisualViewport_h
|
@ -227,6 +227,7 @@ EXPORTS.mozilla.dom += [
|
||||
'TimeoutManager.h',
|
||||
'TreeIterator.h',
|
||||
'TreeWalker.h',
|
||||
'VisualViewport.h',
|
||||
'WebKitCSSMatrix.h',
|
||||
'WindowOrientationObserver.h',
|
||||
]
|
||||
@ -383,6 +384,7 @@ UNIFIED_SOURCES += [
|
||||
'TimeoutHandler.cpp',
|
||||
'TimeoutManager.cpp',
|
||||
'TreeWalker.cpp',
|
||||
'VisualViewport.cpp',
|
||||
'WebKitCSSMatrix.cpp',
|
||||
'WindowDestroyedEvent.cpp',
|
||||
'WindowNamedPropertiesHandler.cpp',
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "imgRequestProxy.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/JSON.h"
|
||||
#include "js/Value.h"
|
||||
#include "Layers.h"
|
||||
#include "nsAppRunner.h"
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "js/JSON.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "mozilla/dom/Timeout.h"
|
||||
#include "mozilla/dom/TimeoutHandler.h"
|
||||
#include "mozilla/dom/TimeoutManager.h"
|
||||
#include "mozilla/dom/VisualViewport.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
#include "mozilla/dom/WindowOrientationObserver.h"
|
||||
@ -2217,6 +2218,15 @@ nsPIDOMWindowInner::Navigator()
|
||||
return mNavigator;
|
||||
}
|
||||
|
||||
VisualViewport* nsGlobalWindowInner::VisualViewport()
|
||||
{
|
||||
if (!mVisualViewport) {
|
||||
mVisualViewport = new mozilla::dom::VisualViewport(this);
|
||||
}
|
||||
|
||||
return mVisualViewport;
|
||||
}
|
||||
|
||||
nsScreen*
|
||||
nsGlobalWindowInner::GetScreen(ErrorResult& aError)
|
||||
{
|
||||
|
@ -126,6 +126,7 @@ class SpeechSynthesis;
|
||||
class TabGroup;
|
||||
class Timeout;
|
||||
class U2F;
|
||||
class VisualViewport;
|
||||
class VRDisplay;
|
||||
enum class VRDisplayEventReason : uint8_t;
|
||||
class VREventObserver;
|
||||
@ -764,6 +765,7 @@ public:
|
||||
already_AddRefed<nsICSSDeclaration>
|
||||
GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
|
||||
mozilla::ErrorResult& aError) override;
|
||||
mozilla::dom::VisualViewport* VisualViewport();
|
||||
already_AddRefed<mozilla::dom::MediaQueryList> MatchMedia(
|
||||
const nsAString& aQuery,
|
||||
mozilla::dom::CallerType aCallerType,
|
||||
@ -1393,6 +1395,8 @@ protected:
|
||||
RefPtr<nsHistory> mHistory;
|
||||
RefPtr<mozilla::dom::CustomElementRegistry> mCustomElements;
|
||||
|
||||
RefPtr<mozilla::dom::VisualViewport> mVisualViewport;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
|
||||
// mTabChild is only ever populated in the content process.
|
||||
nsCOMPtr<nsITabChild> mTabChild;
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "AccessCheck.h"
|
||||
#include "jsapi.h"
|
||||
#include "js/JSON.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
@ -19,7 +19,9 @@
|
||||
#include "GeckoProfiler.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/AutoByteString.h"
|
||||
#include "js/Conversions.h"
|
||||
#include "js/StableStringChars.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsIScriptContext;
|
||||
@ -225,7 +227,7 @@ template<typename T>
|
||||
inline bool
|
||||
AssignJSString(JSContext *cx, T &dest, JSString *s)
|
||||
{
|
||||
size_t len = js::GetStringLength(s);
|
||||
size_t len = JS::GetStringLength(s);
|
||||
static_assert(js::MaxStringLength < (1 << 28),
|
||||
"Shouldn't overflow here or in SetCapacity");
|
||||
if (MOZ_UNLIKELY(!dest.SetLength(len, mozilla::fallible))) {
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "mozilla/UseCounter.h"
|
||||
|
||||
#include "AccessCheck.h"
|
||||
#include "js/JSON.h"
|
||||
#include "js/StableStringChars.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -2858,7 +2860,7 @@ ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
length = js::GetStringLength(s);
|
||||
length = JS::GetStringLength(s);
|
||||
}
|
||||
|
||||
static_assert(js::MaxStringLength < UINT32_MAX,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_BindingUtils_h__
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/AutoByteString.h"
|
||||
#include "js/Wrapper.h"
|
||||
#include "js/Conversions.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
@ -1064,6 +1064,10 @@ DOMInterfaces = {
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'VisualViewport': {
|
||||
'nativeType': 'mozilla::dom::VisualViewport',
|
||||
},
|
||||
|
||||
'VTTCue': {
|
||||
'nativeType': 'mozilla::dom::TextTrackCue'
|
||||
},
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef mozilla_dom_DOMJSClass_h
|
||||
#define mozilla_dom_DOMJSClass_h
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/Wrapper.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "jsapi.h"
|
||||
#include "js/SavedFrameAPI.h"
|
||||
#include "mozilla/CycleCollectedJSContext.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
|
@ -46,12 +46,6 @@ ConsoleAPIStorageService.prototype = {
|
||||
classID : CONSOLEAPISTORAGE_CID,
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIConsoleAPIStorage,
|
||||
Ci.nsIObserver]),
|
||||
classInfo: XPCOMUtils.generateCI({
|
||||
classID: CONSOLEAPISTORAGE_CID,
|
||||
contractID: '@mozilla.org/consoleAPI-storage;1',
|
||||
interfaces: [Ci.nsIConsoleAPIStorage, Ci.nsIObserver],
|
||||
flags: Ci.nsIClassInfo.SINGLETON
|
||||
}),
|
||||
|
||||
observe: function CS_observe(aSubject, aTopic, aData)
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "Layers.h"
|
||||
#include "ContentChild.h"
|
||||
#include "TabParent.h"
|
||||
#include "js/JSON.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/BrowserElementParent.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
|
@ -6,7 +6,6 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/vtt.jsm");
|
||||
|
||||
var WEBVTTPARSERWRAPPER_CID = "{acf6e493-0092-4b26-b172-241e375c57ab}";
|
||||
var WEBVTTPARSERWRAPPER_CONTRACTID = "@mozilla.org/webvttParserWrapper;1";
|
||||
|
||||
function WebVTTParserWrapper()
|
||||
{
|
||||
@ -60,11 +59,6 @@ WebVTTParserWrapper.prototype =
|
||||
classDescription: "Wrapper for the JS WebVTT implementation (vtt.js)",
|
||||
classID: Components.ID(WEBVTTPARSERWRAPPER_CID),
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebVTTParserWrapper]),
|
||||
classInfo: XPCOMUtils.generateCI({
|
||||
classID: WEBVTTPARSERWRAPPER_CID,
|
||||
contractID: WEBVTTPARSERWRAPPER_CONTRACTID,
|
||||
interfaces: [Ci.nsIWebVTTParserWrapper]
|
||||
})
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WebVTTParserWrapper]);
|
||||
|
@ -4,6 +4,7 @@
|
||||
* 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 "js/JSON.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "PaymentRequestUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
|
@ -1135,7 +1135,7 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS::Handle<JSObject*> obj,
|
||||
}
|
||||
MOZ_ASSERT(sJSObjWrappersAccessible);
|
||||
|
||||
JSObjWrapperTable::Ptr p = sJSObjWrappers->lookupForAdd(nsJSObjWrapperKey(obj, npp));
|
||||
JSObjWrapperTable::Ptr p = sJSObjWrappers->lookup(nsJSObjWrapperKey(obj, npp));
|
||||
if (p) {
|
||||
MOZ_ASSERT(p->value());
|
||||
// Found a live nsJSObjWrapper, return it.
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "js/StableStringChars.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIDocShell.h"
|
||||
@ -710,7 +711,7 @@ AutoEntryScript::DocshellEntryMonitor::Entry(JSContext* aCx, JSFunction* aFuncti
|
||||
nsString filename;
|
||||
uint32_t lineNumber = 0;
|
||||
|
||||
js::AutoStableStringChars functionName(aCx);
|
||||
JS::AutoStableStringChars functionName(aCx);
|
||||
if (rootedFunction) {
|
||||
JS::Rooted<JSString*> displayId(aCx, JS_GetFunctionDisplayId(rootedFunction));
|
||||
if (displayId) {
|
||||
|
@ -52,7 +52,7 @@ function spawnWithObserver(browser, observerFunc, func) {
|
||||
// This is the observer itself, it calls the passed-in function whenever
|
||||
// it encounters an event
|
||||
" let ConsoleObserver = {",
|
||||
" QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),",
|
||||
" QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),",
|
||||
" observe: function(aSubject, aTopic, aData) {",
|
||||
" try {",
|
||||
" (" + observerFunc.toString() + ")(aSubject.wrappedJSObject);",
|
||||
|
@ -1161,6 +1161,8 @@ var interfaceNamesInGlobalScope =
|
||||
{name: "VideoPlaybackQuality", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VideoStreamTrack", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VisualViewport", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRDisplay", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
21
dom/webidl/VisualViewport.webidl
Normal file
21
dom/webidl/VisualViewport.webidl
Normal file
@ -0,0 +1,21 @@
|
||||
/* -*- Mode: IDL; 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/.
|
||||
*
|
||||
* The origin of this IDL file is:
|
||||
* https://wicg.github.io/visual-viewport/#the-visualviewport-interface
|
||||
*/
|
||||
|
||||
interface VisualViewport : EventTarget {
|
||||
readonly attribute double offsetLeft;
|
||||
readonly attribute double offsetTop;
|
||||
|
||||
readonly attribute double pageLeft;
|
||||
readonly attribute double pageTop;
|
||||
|
||||
readonly attribute double width;
|
||||
readonly attribute double height;
|
||||
|
||||
readonly attribute double scale;
|
||||
};
|
@ -16,6 +16,7 @@
|
||||
* https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object
|
||||
* https://w3c.github.io/requestidlecallback/
|
||||
* https://drafts.css-houdini.org/css-paint-api-1/#dom-window-paintworklet
|
||||
* https://wicg.github.io/visual-viewport/#the-visualviewport-interface
|
||||
*/
|
||||
|
||||
interface IID;
|
||||
@ -565,3 +566,9 @@ partial interface Window {
|
||||
};
|
||||
|
||||
Window implements WebGPUProvider;
|
||||
|
||||
partial interface Window {
|
||||
[SameObject, Pref="dom.visualviewport.enabled", Replaceable]
|
||||
readonly attribute VisualViewport visualViewport;
|
||||
|
||||
};
|
||||
|
@ -918,6 +918,7 @@ WEBIDL_FILES = [
|
||||
'VideoStreamTrack.webidl',
|
||||
'VideoTrack.webidl',
|
||||
'VideoTrackList.webidl',
|
||||
'VisualViewport.webidl',
|
||||
'VRDisplay.webidl',
|
||||
'VRDisplayEvent.webidl',
|
||||
'VRServiceTest.webidl',
|
||||
|
@ -74,6 +74,7 @@
|
||||
#include "nsStringBuffer.h"
|
||||
#include "nsIFileChannel.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "js/JSON.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "mozilla/dom/XMLHttpRequestBinding.h"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "gfxPrefs.h"
|
||||
#include "GPUProcessHost.h"
|
||||
#include "GPUProcessManager.h"
|
||||
#include "VRProcessManager.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TelemetryIPC.h"
|
||||
#include "mozilla/dom/CheckerboardReportService.h"
|
||||
@ -110,6 +111,12 @@ GPUChild::EnsureGPUReady()
|
||||
return true;
|
||||
}
|
||||
|
||||
base::ProcessHandle
|
||||
GPUChild::GetChildProcessHandle()
|
||||
{
|
||||
return mHost->GetChildProcessHandle();
|
||||
}
|
||||
|
||||
PAPZInputBridgeChild*
|
||||
GPUChild::AllocPAPZInputBridgeChild(const LayersId& aLayersId)
|
||||
{
|
||||
@ -170,6 +177,24 @@ GPUChild::RecvInitCrashReporter(Shmem&& aShmem, const NativeThreadId& aThreadId)
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
GPUChild::RecvCreateVRProcess()
|
||||
{
|
||||
// Make sure create VR process at the main process
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
if (gfxPrefs::VRProcessEnabled()) {
|
||||
VRProcessManager::Initialize();
|
||||
VRProcessManager* vr = VRProcessManager::Get();
|
||||
MOZ_ASSERT(vr, "VRProcessManager must be initialized first.");
|
||||
|
||||
if (vr) {
|
||||
vr->LaunchVRProcess();
|
||||
}
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
GPUChild::RecvNotifyUiObservers(const nsCString& aTopic)
|
||||
{
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
void Init();
|
||||
|
||||
bool EnsureGPUReady();
|
||||
base::ProcessHandle GetChildProcessHandle();
|
||||
|
||||
PAPZInputBridgeChild* AllocPAPZInputBridgeChild(const LayersId& aLayersId) override;
|
||||
bool DeallocPAPZInputBridgeChild(PAPZInputBridgeChild* aActor) override;
|
||||
@ -47,6 +48,7 @@ public:
|
||||
mozilla::ipc::IPCResult RecvInitComplete(const GPUDeviceData& aData) override;
|
||||
mozilla::ipc::IPCResult RecvReportCheckerboard(const uint32_t& aSeverity, const nsCString& aLog) override;
|
||||
mozilla::ipc::IPCResult RecvInitCrashReporter(Shmem&& shmem, const NativeThreadId& aThreadId) override;
|
||||
mozilla::ipc::IPCResult RecvCreateVRProcess() override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvAccumulateChildHistograms(InfallibleTArray<HistogramAccumulation>&& aAccumulations) override;
|
||||
mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistograms(InfallibleTArray<KeyedHistogramAccumulation>&& aAccumulations) override;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "nsThreadManager.h"
|
||||
#include "prenv.h"
|
||||
#include "ProcessUtils.h"
|
||||
#include "VRGPUChild.h"
|
||||
#include "VRManager.h"
|
||||
#include "VRManagerParent.h"
|
||||
#include "VRThread.h"
|
||||
@ -306,6 +307,13 @@ GPUParent::RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint)
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
GPUParent::RecvInitVR(Endpoint<PVRGPUChild>&& aEndpoint)
|
||||
{
|
||||
gfx::VRGPUChild::InitForGPUProcess(std::move(aEndpoint));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
GPUParent::RecvInitUiCompositorController(const LayersId& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint)
|
||||
{
|
||||
@ -465,6 +473,15 @@ GPUParent::RecvRequestMemoryReport(const uint32_t& aGeneration,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
GPUParent::RecvShutdownVR()
|
||||
{
|
||||
if (gfxPrefs::VRProcessEnabled()) {
|
||||
VRGPUChild::ShutDown();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void
|
||||
GPUParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
mozilla::ipc::IPCResult RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint) override;
|
||||
mozilla::ipc::IPCResult RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
|
||||
mozilla::ipc::IPCResult RecvInitVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
|
||||
mozilla::ipc::IPCResult RecvInitVR(Endpoint<PVRGPUChild>&& aVRGPUChild) override;
|
||||
mozilla::ipc::IPCResult RecvInitUiCompositorController(const LayersId& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint) override;
|
||||
mozilla::ipc::IPCResult RecvInitProfiler(Endpoint<PProfilerChild>&& aEndpoint) override;
|
||||
mozilla::ipc::IPCResult RecvUpdatePref(const GfxPrefSetting& pref) override;
|
||||
@ -61,6 +62,7 @@ public:
|
||||
const bool& anonymize,
|
||||
const bool& minimizeMemoryUsage,
|
||||
const MaybeFileDesc& DMDFile) override;
|
||||
mozilla::ipc::IPCResult RecvShutdownVR() override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
|
@ -160,6 +160,8 @@ GPUProcessHost::Shutdown()
|
||||
mListener = nullptr;
|
||||
|
||||
if (mGPUChild) {
|
||||
mGPUChild->SendShutdownVR();
|
||||
|
||||
// OnChannelClosed uses this to check if the shutdown was expected or
|
||||
// unexpected.
|
||||
mShutdownRequested = true;
|
||||
|
@ -15,6 +15,19 @@ using gfxImageFormat from "mozilla/gfx/Types.h";
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
union GfxPrefValue {
|
||||
bool;
|
||||
int32_t;
|
||||
uint32_t;
|
||||
float;
|
||||
nsCString;
|
||||
};
|
||||
|
||||
struct GfxPrefSetting {
|
||||
int32_t index;
|
||||
GfxPrefValue value;
|
||||
};
|
||||
|
||||
struct D3D11DeviceStatus
|
||||
{
|
||||
bool isWARP;
|
||||
|
@ -10,6 +10,7 @@ include protocol PAPZInputBridge;
|
||||
include protocol PCompositorManager;
|
||||
include protocol PImageBridge;
|
||||
include protocol PProfiler;
|
||||
include protocol PVRGPU;
|
||||
include protocol PVRManager;
|
||||
include protocol PVsyncBridge;
|
||||
include protocol PUiCompositorController;
|
||||
@ -30,19 +31,6 @@ using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
union GfxPrefValue {
|
||||
bool;
|
||||
int32_t;
|
||||
uint32_t;
|
||||
float;
|
||||
nsCString;
|
||||
};
|
||||
|
||||
struct GfxPrefSetting {
|
||||
int32_t index;
|
||||
GfxPrefValue value;
|
||||
};
|
||||
|
||||
struct LayerTreeIdMapping {
|
||||
LayersId layersId;
|
||||
ProcessId ownerId;
|
||||
@ -72,7 +60,8 @@ parent:
|
||||
async InitVRManager(Endpoint<PVRManagerParent> endpoint);
|
||||
async InitUiCompositorController(LayersId rootLayerTreeId, Endpoint<PUiCompositorControllerParent> endpoint);
|
||||
async InitProfiler(Endpoint<PProfilerChild> endpoint);
|
||||
|
||||
// Forward GPU process its endpoints to the VR process.
|
||||
async InitVR(Endpoint<PVRGPUChild> endpoint);
|
||||
// Called to update a gfx preference or variable.
|
||||
async UpdatePref(GfxPrefSetting pref);
|
||||
async UpdateVar(GfxVarUpdate var);
|
||||
@ -103,6 +92,7 @@ parent:
|
||||
bool anonymize,
|
||||
bool minimizeMemoryUsage,
|
||||
MaybeFileDesc DMDFile);
|
||||
async ShutdownVR();
|
||||
|
||||
child:
|
||||
// Sent when the GPU process has initialized devices. This occurs once, after
|
||||
@ -117,6 +107,8 @@ child:
|
||||
|
||||
async InitCrashReporter(Shmem shmem, NativeThreadId threadId);
|
||||
|
||||
async CreateVRProcess();
|
||||
|
||||
// Have a message be broadcasted to the UI process by the UI process
|
||||
// observer service.
|
||||
async NotifyUiObservers(nsCString aTopic);
|
||||
|
@ -154,6 +154,7 @@ static inline bool
|
||||
ProcessOwnsCompositor()
|
||||
{
|
||||
return XRE_GetProcessType() == GeckoProcessType_GPU ||
|
||||
XRE_GetProcessType() == GeckoProcessType_VR ||
|
||||
(XRE_IsParentProcess() && !gfxConfig::IsEnabled(Feature::GPU_PROCESS));
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "gfxTextRun.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
#include "gfxConfig.h"
|
||||
#include "VRProcessManager.h"
|
||||
#include "VRThread.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
@ -1003,6 +1004,7 @@ gfxPlatform::Shutdown()
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
GPUProcessManager::Shutdown();
|
||||
VRProcessManager::Shutdown();
|
||||
}
|
||||
|
||||
gfx::Factory::ShutDown();
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/gfx/GPUChild.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "VRProcessManager.h"
|
||||
#include "VRChild.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -92,6 +94,13 @@ gfxPrefs::Pref::OnChange()
|
||||
Unused << gpu->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
|
||||
}
|
||||
}
|
||||
if (auto vpm = gfx::VRProcessManager::Get()) {
|
||||
if (gfx::VRChild* vr = vpm->GetVRChild()) {
|
||||
GfxPrefValue value;
|
||||
GetLiveValue(&value);
|
||||
Unused << vr->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
|
||||
}
|
||||
}
|
||||
FireChangeCallback();
|
||||
}
|
||||
|
||||
|
@ -372,6 +372,7 @@ private:
|
||||
|
||||
DECL_GFX_PREF(Live, "dom.ipc.plugins.asyncdrawing.enabled", PluginAsyncDrawingEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "dom.meta-viewport.enabled", MetaViewportEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "dom.visualviewport.enabled", VisualViewportEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "dom.vr.enabled", VREnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "dom.vr.autoactivate.enabled", VRAutoActivateEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "dom.vr.controller_trigger_threshold", VRControllerTriggerThreshold, float, 0.1f);
|
||||
@ -391,6 +392,7 @@ private:
|
||||
DECL_GFX_PREF(Live, "dom.vr.puppet.enabled", VRPuppetEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "dom.vr.puppet.submitframe", VRPuppetSubmitFrame, uint32_t, 0);
|
||||
DECL_GFX_PREF(Live, "dom.vr.display.rafMaxDuration", VRDisplayRafMaxDuration, uint32_t, 50);
|
||||
DECL_GFX_PREF(Once, "dom.vr.process.enabled", VRProcessEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "dom.vr.service.enabled", VRServiceEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "dom.w3c_pointer_events.enabled", PointerEventsEnabled, bool, false);
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "VRManager.h"
|
||||
#include "VRManagerParent.h"
|
||||
#include "VRGPUChild.h"
|
||||
#include "VRThread.h"
|
||||
#include "gfxVR.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
@ -15,6 +16,7 @@
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/gfx/GPUParent.h"
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
#include "gfxVR.h"
|
||||
@ -48,6 +50,8 @@ VRManager::ManagerInit()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// TODO: We should make VRManager::ManagerInit
|
||||
// be called when entering VR content pages.
|
||||
if (sVRManagerSingleton == nullptr) {
|
||||
sVRManagerSingleton = new VRManager();
|
||||
ClearOnShutdown(&sVRManagerSingleton);
|
||||
@ -58,6 +62,7 @@ VRManager::VRManager()
|
||||
: mInitialized(false)
|
||||
, mVRDisplaysRequested(false)
|
||||
, mVRControllersRequested(false)
|
||||
, mVRServiceStarted(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRManager);
|
||||
MOZ_ASSERT(sVRManagerSingleton == nullptr);
|
||||
@ -81,7 +86,13 @@ VRManager::VRManager()
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
// The VR Service accesses all hardware from a separate process
|
||||
// and replaces the other VRSystemManager when enabled.
|
||||
mVRService = VRService::Create();
|
||||
if (!gfxPrefs::VRProcessEnabled()) {
|
||||
mVRService = VRService::Create();
|
||||
} else if (gfxPrefs::VRProcessEnabled() && XRE_IsGPUProcess()) {
|
||||
gfx::GPUParent* gpu = GPUParent::GetSingleton();
|
||||
MOZ_ASSERT(gpu);
|
||||
Unused << gpu->SendCreateVRProcess();
|
||||
}
|
||||
if (mVRService) {
|
||||
mExternalManager = VRSystemManagerExternal::Create(mVRService->GetAPIShmem());
|
||||
}
|
||||
@ -145,7 +156,12 @@ VRManager::Destroy()
|
||||
for (uint32_t i = 0; i < mManagers.Length(); ++i) {
|
||||
mManagers[i]->Destroy();
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
if (mVRService) {
|
||||
mVRService->Stop();
|
||||
mVRService = nullptr;
|
||||
}
|
||||
#endif
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
@ -161,7 +177,18 @@ VRManager::Shutdown()
|
||||
if (mVRService) {
|
||||
mVRService->Stop();
|
||||
}
|
||||
if (gfxPrefs::VRProcessEnabled()) {
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"VRGPUChild::SendStopVRService",
|
||||
[] () -> void {
|
||||
VRGPUChild* vrGPUChild = VRGPUChild::Get();
|
||||
vrGPUChild->SendStopVRService();
|
||||
});
|
||||
|
||||
NS_DispatchToMainThread(task.forget());
|
||||
}
|
||||
#endif
|
||||
mVRServiceStarted = false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -349,8 +376,22 @@ VRManager::RefreshVRDisplays(bool aMustDispatch)
|
||||
*/
|
||||
if (mVRDisplaysRequested || aMustDispatch) {
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
if (mVRService) {
|
||||
mVRService->Start();
|
||||
// Tell VR process to start VR service.
|
||||
if (gfxPrefs::VRProcessEnabled() && !mVRServiceStarted) {
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"VRGPUChild::SendStartVRService",
|
||||
[] () -> void {
|
||||
VRGPUChild* vrGPUChild = VRGPUChild::Get();
|
||||
vrGPUChild->SendStartVRService();
|
||||
});
|
||||
|
||||
NS_DispatchToMainThread(task.forget());
|
||||
mVRServiceStarted = true;
|
||||
} else if (!gfxPrefs::VRProcessEnabled()){
|
||||
if (mVRService) {
|
||||
mVRService->Start();
|
||||
mVRServiceStarted = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
EnumerateVRDisplays();
|
||||
|
@ -102,6 +102,7 @@ private:
|
||||
#endif
|
||||
bool mVRDisplaysRequested;
|
||||
bool mVRControllersRequested;
|
||||
bool mVRServiceStarted;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -354,6 +354,10 @@ VRSystemManagerExternal::VRSystemManagerExternal(VRExternalShmem* aAPIShmem /* =
|
||||
mExternalStructFailed = false;
|
||||
mEnumerationCompleted = false;
|
||||
#endif
|
||||
|
||||
if (!aAPIShmem) {
|
||||
OpenShmem();
|
||||
}
|
||||
}
|
||||
|
||||
VRSystemManagerExternal::~VRSystemManagerExternal()
|
||||
@ -400,7 +404,14 @@ VRSystemManagerExternal::OpenShmem()
|
||||
|
||||
#elif defined(XP_WIN)
|
||||
if (mShmemFile == NULL) {
|
||||
mShmemFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, kShmemName);
|
||||
if (gfxPrefs::VRProcessEnabled()) {
|
||||
mShmemFile = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
|
||||
sizeof(VRExternalShmem), kShmemName);
|
||||
MOZ_ASSERT(GetLastError() == 0);
|
||||
} else {
|
||||
mShmemFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, kShmemName);
|
||||
}
|
||||
|
||||
if (mShmemFile == NULL) {
|
||||
// TODO - Implement logging
|
||||
CloseShmem();
|
||||
@ -504,7 +515,8 @@ VRSystemManagerExternal::Create(VRExternalShmem* aAPIShmem /* = nullptr*/)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!gfxPrefs::VRExternalEnabled() && aAPIShmem == nullptr) {
|
||||
if ((!gfxPrefs::VRExternalEnabled() && aAPIShmem == nullptr) ||
|
||||
!XRE_IsGPUProcess()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ private:
|
||||
#if defined(XP_MACOSX)
|
||||
int mShmemFD;
|
||||
#elif defined(XP_WIN)
|
||||
HANDLE mShmemFile;
|
||||
base::ProcessHandle mShmemFile;
|
||||
#elif defined(MOZ_WIDGET_ANDROID)
|
||||
bool mDoShutdown;
|
||||
bool mExternalStructFailed;
|
||||
|
@ -14,10 +14,18 @@
|
||||
#include "gfxVR.h"
|
||||
#include "VRDisplayLocal.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "CompositorD3D11.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
class MacIOSurface;
|
||||
#endif
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
struct VertexShaderConstants;
|
||||
struct PixelShaderConstants;
|
||||
}
|
||||
namespace gfx {
|
||||
namespace impl {
|
||||
|
||||
|
26
gfx/vr/ipc/PVR.ipdl
Normal file
26
gfx/vr/ipc/PVR.ipdl
Normal file
@ -0,0 +1,26 @@
|
||||
/* -*- Mode: C++; tab-width: 8; 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/. */
|
||||
|
||||
using mozilla::TimeStamp from "mozilla/TimeStamp.h";
|
||||
|
||||
include GraphicsMessages;
|
||||
include protocol PVRGPU;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
async protocol PVR
|
||||
{
|
||||
parent:
|
||||
async NewGPUVRManager(Endpoint<PVRGPUParent> endpoint);
|
||||
async Init(GfxPrefSetting[] prefs, GfxVarUpdate[] vars, DevicePrefs devicePrefs);
|
||||
async NotifyVsync(TimeStamp vsyncTimestamp);
|
||||
|
||||
async UpdatePref(GfxPrefSetting pref);
|
||||
async UpdateVar(GfxVarUpdate var);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
18
gfx/vr/ipc/PVRGPU.ipdl
Normal file
18
gfx/vr/ipc/PVRGPU.ipdl
Normal file
@ -0,0 +1,18 @@
|
||||
/* -*- Mode: C++; tab-width: 8; 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/. */
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
// IPC for VR-Content process
|
||||
async protocol PVRGPU
|
||||
{
|
||||
parent:
|
||||
async StartVRService();
|
||||
async StopVRService();
|
||||
};
|
||||
|
||||
} // gfx
|
||||
} // mozilla
|
94
gfx/vr/ipc/VRChild.cpp
Normal file
94
gfx/vr/ipc/VRChild.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRChild.h"
|
||||
#include "VRProcessParent.h"
|
||||
#include "gfxConfig.h"
|
||||
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/VsyncDispatcher.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
VRChild::VRChild(VRProcessParent* aHost)
|
||||
: mHost(aHost)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
}
|
||||
|
||||
void
|
||||
VRChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
gfxVars::RemoveReceiver(this);
|
||||
mHost->OnChannelClosed();
|
||||
XRE_ShutdownChildProcess();
|
||||
}
|
||||
|
||||
void
|
||||
VRChild::Init()
|
||||
{
|
||||
// Build a list of prefs the VR process will need. Note that because we
|
||||
// limit the VR process to prefs contained in gfxPrefs, we can simplify
|
||||
// the message in two ways: one, we only need to send its index in gfxPrefs
|
||||
// rather than its name, and two, we only need to send prefs that don't
|
||||
// have their default value.
|
||||
// Todo: Consider to make our own vrPrefs that we are interested in VR process.
|
||||
nsTArray<GfxPrefSetting> prefs;
|
||||
for (auto pref : gfxPrefs::all()) {
|
||||
if (pref->HasDefaultValue()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GfxPrefValue value;
|
||||
pref->GetCachedValue(&value);
|
||||
prefs.AppendElement(GfxPrefSetting(pref->Index(), value));
|
||||
}
|
||||
nsTArray<GfxVarUpdate> updates = gfxVars::FetchNonDefaultVars();
|
||||
|
||||
DevicePrefs devicePrefs;
|
||||
devicePrefs.hwCompositing() = gfxConfig::GetValue(Feature::HW_COMPOSITING);
|
||||
devicePrefs.d3d11Compositing() = gfxConfig::GetValue(Feature::D3D11_COMPOSITING);
|
||||
devicePrefs.oglCompositing() = gfxConfig::GetValue(Feature::OPENGL_COMPOSITING);
|
||||
devicePrefs.advancedLayers() = gfxConfig::GetValue(Feature::ADVANCED_LAYERS);
|
||||
devicePrefs.useD2D1() = gfxConfig::GetValue(Feature::DIRECT2D);
|
||||
|
||||
SendInit(prefs, updates, devicePrefs);
|
||||
gfxVars::AddReceiver(this);
|
||||
}
|
||||
|
||||
void
|
||||
VRChild::OnVarChanged(const GfxVarUpdate& aVar)
|
||||
{
|
||||
SendUpdateVar(aVar);
|
||||
}
|
||||
|
||||
class DeferredDeleteVRChild : public Runnable
|
||||
{
|
||||
public:
|
||||
explicit DeferredDeleteVRChild(UniquePtr<VRChild>&& aChild)
|
||||
: Runnable("gfx::DeferredDeleteVRChild")
|
||||
, mChild(std::move(aChild))
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run() override {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
UniquePtr<VRChild> mChild;
|
||||
};
|
||||
|
||||
/* static */ void
|
||||
VRChild::Destroy(UniquePtr<VRChild>&& aChild)
|
||||
{
|
||||
NS_DispatchToMainThread(new DeferredDeleteVRChild(std::move(aChild)));
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
42
gfx/vr/ipc/VRChild.h
Normal file
42
gfx/vr/ipc/VRChild.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_VR_CHILD_H
|
||||
#define GFX_VR_CHILD_H
|
||||
|
||||
#include "mozilla/gfx/PVRChild.h"
|
||||
#include "mozilla/gfx/gfxVarReceiver.h"
|
||||
#include "mozilla/VsyncDispatcher.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class VRProcessParent;
|
||||
class VRChild;
|
||||
|
||||
class VRChild final
|
||||
: public PVRChild,
|
||||
public gfxVarReceiver {
|
||||
|
||||
public:
|
||||
explicit VRChild(VRProcessParent* aHost);
|
||||
~VRChild() = default;
|
||||
|
||||
static void Destroy(UniquePtr<VRChild>&& aChild);
|
||||
void Init();
|
||||
virtual void OnVarChanged(const GfxVarUpdate& aVar) override;
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
VRProcessParent* mHost;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_VR_CHILD_H
|
79
gfx/vr/ipc/VRGPUChild.cpp
Normal file
79
gfx/vr/ipc/VRGPUChild.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRGPUChild.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
static StaticRefPtr<VRGPUChild> sVRGPUChildSingleton;
|
||||
|
||||
/* static */ bool
|
||||
VRGPUChild::InitForGPUProcess(Endpoint<PVRGPUChild>&& aEndpoint)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!sVRGPUChildSingleton);
|
||||
|
||||
RefPtr<VRGPUChild> child(new VRGPUChild());
|
||||
if (!aEndpoint.Bind(child)) {
|
||||
return false;
|
||||
}
|
||||
sVRGPUChildSingleton = child;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
VRGPUChild::IsCreated()
|
||||
{
|
||||
return !!sVRGPUChildSingleton;
|
||||
}
|
||||
|
||||
/* static */ VRGPUChild*
|
||||
VRGPUChild::Get()
|
||||
{
|
||||
MOZ_ASSERT(IsCreated(), "VRGPUChild haven't initialized yet.");
|
||||
return sVRGPUChildSingleton;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
VRGPUChild::ShutDown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (sVRGPUChildSingleton) {
|
||||
sVRGPUChildSingleton->Destroy();
|
||||
sVRGPUChildSingleton = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
class DeferredDeleteVRGPUChild : public Runnable
|
||||
{
|
||||
public:
|
||||
explicit DeferredDeleteVRGPUChild(RefPtr<VRGPUChild> aChild)
|
||||
: Runnable("gfx::DeferredDeleteVRGPUChild")
|
||||
, mChild(std::move(aChild))
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run() override {
|
||||
mChild->Close();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<VRGPUChild> mChild;
|
||||
};
|
||||
|
||||
void
|
||||
VRGPUChild::Destroy()
|
||||
{
|
||||
// Keep ourselves alive until everything has been shut down
|
||||
RefPtr<VRGPUChild> selfRef = this;
|
||||
NS_DispatchToMainThread(new DeferredDeleteVRGPUChild(this));
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
38
gfx/vr/ipc/VRGPUChild.h
Normal file
38
gfx/vr/ipc/VRGPUChild.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_VR_GPU_CHILD_H
|
||||
#define GFX_VR_GPU_CHILD_H
|
||||
|
||||
#include "mozilla/gfx/PVRGPUChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class VRGPUChild final : public PVRGPUChild
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRGPUChild);
|
||||
|
||||
static VRGPUChild* Get();
|
||||
static bool InitForGPUProcess(Endpoint<PVRGPUChild>&& aEndpoint);
|
||||
static bool IsCreated();
|
||||
static void ShutDown();
|
||||
|
||||
protected:
|
||||
explicit VRGPUChild() {}
|
||||
~VRGPUChild() {}
|
||||
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(VRGPUChild);
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_VR_GPU_CHILD_H
|
99
gfx/vr/ipc/VRGPUParent.cpp
Normal file
99
gfx/vr/ipc/VRGPUParent.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRGPUParent.h"
|
||||
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
|
||||
VRGPUParent::VRGPUParent(ProcessId aChildProcessId)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRGPUParent);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
SetOtherProcessId(aChildProcessId);
|
||||
}
|
||||
|
||||
void
|
||||
VRGPUParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
if (mVRService) {
|
||||
mVRService->Stop();
|
||||
mVRService = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
MessageLoop::current()->PostTask(
|
||||
NewRunnableMethod("gfx::VRGPUParent::DeferredDestroy",
|
||||
this,
|
||||
&VRGPUParent::DeferredDestroy));
|
||||
}
|
||||
|
||||
void
|
||||
VRGPUParent::DeferredDestroy()
|
||||
{
|
||||
mSelfRef = nullptr;
|
||||
}
|
||||
|
||||
/* static */ RefPtr<VRGPUParent>
|
||||
VRGPUParent::CreateForGPU(Endpoint<PVRGPUParent>&& aEndpoint)
|
||||
{
|
||||
RefPtr<VRGPUParent> vcp = new VRGPUParent(aEndpoint.OtherPid());
|
||||
MessageLoop::current()->PostTask(
|
||||
NewRunnableMethod<Endpoint<PVRGPUParent>&&>(
|
||||
"gfx::VRGPUParent::Bind",
|
||||
vcp,
|
||||
&VRGPUParent::Bind,
|
||||
std::move(aEndpoint)));
|
||||
|
||||
return vcp;
|
||||
}
|
||||
|
||||
void
|
||||
VRGPUParent::Bind(Endpoint<PVRGPUParent>&& aEndpoint)
|
||||
{
|
||||
if (!aEndpoint.Bind(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSelfRef = this;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
VRGPUParent::RecvStartVRService()
|
||||
{
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
mVRService = VRService::Create();
|
||||
MOZ_ASSERT(mVRService);
|
||||
|
||||
mVRService->Start();
|
||||
#endif
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
VRGPUParent::RecvStopVRService()
|
||||
{
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
if (mVRService) {
|
||||
mVRService->Stop();
|
||||
mVRService = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
43
gfx/vr/ipc/VRGPUParent.h
Normal file
43
gfx/vr/ipc/VRGPUParent.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_VR_GPU_PARENT_H
|
||||
#define GFX_VR_GPU_PARENT_H
|
||||
|
||||
#include "mozilla/gfx/PVRGPUParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class VRGPUParent final : public PVRGPUParent {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRGPUParent)
|
||||
|
||||
public:
|
||||
explicit VRGPUParent(ProcessId aChildProcessId);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
static RefPtr<VRGPUParent> CreateForGPU(Endpoint<PVRGPUParent>&& aEndpoint);
|
||||
|
||||
protected:
|
||||
~VRGPUParent() {}
|
||||
|
||||
void Bind(Endpoint<PVRGPUParent>&& aEndpoint);
|
||||
virtual mozilla::ipc::IPCResult RecvStartVRService() override;
|
||||
virtual mozilla::ipc::IPCResult RecvStopVRService() override;
|
||||
|
||||
private:
|
||||
void DeferredDestroy();
|
||||
|
||||
RefPtr<VRGPUParent> mSelfRef;
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || (defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID))
|
||||
RefPtr<VRService> mVRService;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_VR_CONTENT_PARENT_H
|
143
gfx/vr/ipc/VRParent.cpp
Normal file
143
gfx/vr/ipc/VRParent.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRParent.h"
|
||||
#include "VRGPUParent.h"
|
||||
#include "VRManager.h"
|
||||
#include "gfxConfig.h"
|
||||
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "mozilla/gfx/DeviceManagerDx.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
using mozilla::ipc::IPCResult;
|
||||
|
||||
VRParent::VRParent()
|
||||
: mVRGPUParent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
IPCResult
|
||||
VRParent::RecvNewGPUVRManager(Endpoint<PVRGPUParent>&& aEndpoint)
|
||||
{
|
||||
RefPtr<VRGPUParent> vrGPUParent = VRGPUParent::CreateForGPU(std::move(aEndpoint));
|
||||
if (!vrGPUParent) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
mVRGPUParent = std::move(vrGPUParent);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult
|
||||
VRParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs,
|
||||
nsTArray<GfxVarUpdate>&& vars,
|
||||
const DevicePrefs& devicePrefs)
|
||||
{
|
||||
const nsTArray<gfxPrefs::Pref*>& globalPrefs = gfxPrefs::all();
|
||||
for (auto& setting : prefs) {
|
||||
gfxPrefs::Pref* pref = globalPrefs[setting.index()];
|
||||
pref->SetCachedValue(setting.value());
|
||||
}
|
||||
for (const auto& var : vars) {
|
||||
gfxVars::ApplyUpdate(var);
|
||||
}
|
||||
|
||||
// Inherit device preferences.
|
||||
gfxConfig::Inherit(Feature::HW_COMPOSITING, devicePrefs.hwCompositing());
|
||||
gfxConfig::Inherit(Feature::D3D11_COMPOSITING, devicePrefs.d3d11Compositing());
|
||||
gfxConfig::Inherit(Feature::OPENGL_COMPOSITING, devicePrefs.oglCompositing());
|
||||
gfxConfig::Inherit(Feature::ADVANCED_LAYERS, devicePrefs.advancedLayers());
|
||||
gfxConfig::Inherit(Feature::DIRECT2D, devicePrefs.useD2D1());
|
||||
|
||||
#if defined(XP_WIN)
|
||||
if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
|
||||
DeviceManagerDx::Get()->CreateCompositorDevices();
|
||||
}
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult
|
||||
VRParent::RecvNotifyVsync(const TimeStamp& vsyncTimestamp)
|
||||
{
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->NotifyVsync(vsyncTimestamp);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult
|
||||
VRParent::RecvUpdatePref(const GfxPrefSetting& setting)
|
||||
{
|
||||
gfxPrefs::Pref* pref = gfxPrefs::all()[setting.index()];
|
||||
pref->SetCachedValue(setting.value());
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult
|
||||
VRParent::RecvUpdateVar(const GfxVarUpdate& aUpdate)
|
||||
{
|
||||
gfxVars::ApplyUpdate(aUpdate);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void
|
||||
VRParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (AbnormalShutdown == aWhy) {
|
||||
NS_WARNING("Shutting down VR process early due to a crash!");
|
||||
ProcessChild::QuickExit();
|
||||
}
|
||||
|
||||
mVRGPUParent->Close();
|
||||
#if defined(XP_WIN)
|
||||
DeviceManagerDx::Shutdown();
|
||||
#endif
|
||||
gfxVars::Shutdown();
|
||||
gfxConfig::Shutdown();
|
||||
gfxPrefs::DestroySingleton();
|
||||
XRE_ShutdownChildProcess();
|
||||
}
|
||||
|
||||
bool
|
||||
VRParent::Init(base::ProcessId aParentPid,
|
||||
const char* aParentBuildID,
|
||||
MessageLoop* aIOLoop,
|
||||
IPC::Channel* aChannel)
|
||||
{
|
||||
// Now it's safe to start IPC.
|
||||
if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This must be checked before any IPDL message, which may hit sentinel
|
||||
// errors due to parent and content processes having different
|
||||
// versions.
|
||||
MessageChannel* channel = GetIPCChannel();
|
||||
if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) {
|
||||
// We need to quit this process if the buildID doesn't match the parent's.
|
||||
// This can occur when an update occurred in the background.
|
||||
ProcessChild::QuickExit();
|
||||
}
|
||||
|
||||
// Ensure gfxPrefs are initialized.
|
||||
gfxPrefs::GetSingleton();
|
||||
gfxConfig::Init();
|
||||
gfxVars::Initialize();
|
||||
#if defined(XP_WIN)
|
||||
DeviceManagerDx::Init();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
45
gfx/vr/ipc/VRParent.h
Normal file
45
gfx/vr/ipc/VRParent.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_VR_PARENT_H
|
||||
#define GFX_VR_PARENT_H
|
||||
|
||||
#include "mozilla/gfx/PVRParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class VRGPUParent;
|
||||
class VRService;
|
||||
class VRSystemManagerExternal;
|
||||
|
||||
class VRParent final : public PVRParent {
|
||||
|
||||
public:
|
||||
VRParent();
|
||||
bool Init(base::ProcessId aParentPid,
|
||||
const char* aParentBuildID,
|
||||
MessageLoop* aIOLoop,
|
||||
IPC::Channel* aChannel);
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
protected:
|
||||
virtual mozilla::ipc::IPCResult RecvNewGPUVRManager(Endpoint<PVRGPUParent>&& aEndpoint) override;
|
||||
virtual mozilla::ipc::IPCResult RecvInit(nsTArray<GfxPrefSetting>&& prefs,
|
||||
nsTArray<GfxVarUpdate>&& vars,
|
||||
const DevicePrefs& devicePrefs) override;
|
||||
virtual mozilla::ipc::IPCResult RecvNotifyVsync(const TimeStamp& vsyncTimestamp) override;
|
||||
virtual mozilla::ipc::IPCResult RecvUpdatePref(const GfxPrefSetting& setting) override;
|
||||
virtual mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref) override;
|
||||
|
||||
private:
|
||||
RefPtr<VRGPUParent> mVRGPUParent;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_VR_PARENT_H
|
53
gfx/vr/ipc/VRProcessChild.cpp
Normal file
53
gfx/vr/ipc/VRProcessChild.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRProcessChild.h"
|
||||
|
||||
#include "mozilla/BackgroundHangMonitor.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using mozilla::ipc::IOThreadChild;
|
||||
|
||||
|
||||
VRProcessChild::VRProcessChild(ProcessId aParentPid)
|
||||
: ProcessChild(aParentPid)
|
||||
#if defined(aParentPid)
|
||||
, mVR(nullptr)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
VRProcessChild::~VRProcessChild()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
VRProcessChild::Init(int aArgc, char* aArgv[])
|
||||
{
|
||||
BackgroundHangMonitor::Startup();
|
||||
|
||||
char* parentBuildID = nullptr;
|
||||
for (int i = 1; i < aArgc; i++) {
|
||||
if (strcmp(aArgv[i], "-parentBuildID") == 0) {
|
||||
parentBuildID = aArgv[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
mVR.Init(ParentPid(), parentBuildID,
|
||||
IOThreadChild::message_loop(),
|
||||
IOThreadChild::channel());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessChild::CleanUp()
|
||||
{
|
||||
NS_ShutdownXPCOM(nullptr);
|
||||
}
|
43
gfx/vr/ipc/VRProcessChild.h
Normal file
43
gfx/vr/ipc/VRProcessChild.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_VR_PROCESS_CHILD_H
|
||||
#define GFX_VR_PROCESS_CHILD_H
|
||||
|
||||
#include "mozilla/ipc/ProcessChild.h"
|
||||
#include "VRParent.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
/**
|
||||
* Contains the VRChild object that facilitates IPC communication to/from
|
||||
* the instance of the VR library that is run in this process.
|
||||
*/
|
||||
class VRProcessChild final : public mozilla::ipc::ProcessChild
|
||||
{
|
||||
protected:
|
||||
typedef mozilla::ipc::ProcessChild ProcessChild;
|
||||
|
||||
public:
|
||||
explicit VRProcessChild(ProcessId aParentPid);
|
||||
~VRProcessChild();
|
||||
|
||||
// ProcessChild functions.
|
||||
virtual bool Init(int aArgc, char* aArgv[]) override;
|
||||
virtual void CleanUp() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(VRProcessChild);
|
||||
|
||||
VRParent mVR;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* GFX_VR_PROCESS_CHILD_H */
|
171
gfx/vr/ipc/VRProcessManager.cpp
Normal file
171
gfx/vr/ipc/VRProcessManager.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRProcessManager.h"
|
||||
|
||||
#include "VRProcessParent.h"
|
||||
#include "VRChild.h"
|
||||
#include "VRGPUChild.h"
|
||||
#include "VRGPUParent.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
static StaticAutoPtr<VRProcessManager> sSingleton;
|
||||
|
||||
/* static */ VRProcessManager*
|
||||
VRProcessManager::Get()
|
||||
{
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
VRProcessManager::Initialize()
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
sSingleton = new VRProcessManager();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
VRProcessManager::Shutdown()
|
||||
{
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
||||
VRProcessManager::VRProcessManager()
|
||||
: mProcess(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRProcessManager);
|
||||
|
||||
mObserver = new Observer(this);
|
||||
nsContentUtils::RegisterShutdownObserver(mObserver);
|
||||
}
|
||||
|
||||
VRProcessManager::~VRProcessManager()
|
||||
{
|
||||
MOZ_COUNT_DTOR(VRProcessManager);
|
||||
|
||||
DestroyProcess();
|
||||
// The VR process should have already been shut down.
|
||||
MOZ_ASSERT(!mProcess);
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessManager::LaunchVRProcess()
|
||||
{
|
||||
if (mProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The subprocess is launched asynchronously, so we wait for a callback to
|
||||
// acquire the IPDL actor.
|
||||
mProcess = new VRProcessParent();
|
||||
if (!mProcess->Launch()) {
|
||||
DisableVRProcess("Failed to launch VR process");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessManager::DisableVRProcess(const char* aMessage)
|
||||
{
|
||||
if (!gfxPrefs::VRProcessEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DestroyProcess();
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessManager::DestroyProcess()
|
||||
{
|
||||
if (!mProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
mProcess->Shutdown();
|
||||
mProcess = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
VRProcessManager::CreateGPUBridges(base::ProcessId aOtherProcess,
|
||||
mozilla::ipc::Endpoint<PVRGPUChild>* aOutVRBridge)
|
||||
{
|
||||
if (!CreateGPUVRManager(aOtherProcess, aOutVRBridge)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VRProcessManager::CreateGPUVRManager(base::ProcessId aOtherProcess,
|
||||
mozilla::ipc::Endpoint<PVRGPUChild>* aOutEndpoint)
|
||||
{
|
||||
base::ProcessId vrparentPid = mProcess
|
||||
? mProcess->OtherPid() // VR process id.
|
||||
: base::GetCurrentProcId();
|
||||
|
||||
ipc::Endpoint<PVRGPUParent> vrparentPipe;
|
||||
ipc::Endpoint<PVRGPUChild> vrchildPipe;
|
||||
nsresult rv = PVRGPU::CreateEndpoints(vrparentPid, // vr process id
|
||||
aOtherProcess, // gpu process id
|
||||
&vrparentPipe,
|
||||
&vrchildPipe);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
gfxCriticalNote << "Could not create gpu-vr bridge: " << hexa(int(rv));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind vr-gpu pipe to VRParent and make a PVRGPU connection.
|
||||
VRChild* vrChild = mProcess->GetActor();
|
||||
vrChild->SendNewGPUVRManager(std::move(vrparentPipe));
|
||||
|
||||
*aOutEndpoint = std::move(vrchildPipe);
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(VRProcessManager::Observer, nsIObserver);
|
||||
|
||||
VRProcessManager::Observer::Observer(VRProcessManager* aManager)
|
||||
: mManager(aManager)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
VRProcessManager::Observer::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
mManager->OnXPCOMShutdown();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessManager::CleanShutdown()
|
||||
{
|
||||
DestroyProcess();
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessManager::OnXPCOMShutdown()
|
||||
{
|
||||
if (mObserver) {
|
||||
nsContentUtils::UnregisterShutdownObserver(mObserver);
|
||||
mObserver = nullptr;
|
||||
}
|
||||
|
||||
CleanShutdown();
|
||||
}
|
||||
|
||||
VRChild*
|
||||
VRProcessManager::GetVRChild()
|
||||
{
|
||||
return mProcess->GetActor();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
71
gfx/vr/ipc/VRProcessManager.h
Normal file
71
gfx/vr/ipc/VRProcessManager.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef GFX_VR_PROCESS_MANAGER_H
|
||||
#define GFX_VR_PROCESS_MANAGER_H
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class VRProcessParent;
|
||||
class VRManagerChild;
|
||||
class PVRGPUChild;
|
||||
class VRChild;
|
||||
|
||||
// The VRProcessManager is a singleton responsible for creating VR-bound
|
||||
// objects that may live in another process.
|
||||
class VRProcessManager final
|
||||
{
|
||||
public:
|
||||
static VRProcessManager* Get();
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
|
||||
~VRProcessManager();
|
||||
|
||||
// If not using a VR process, launch a new VR process asynchronously.
|
||||
void LaunchVRProcess();
|
||||
void DestroyProcess();
|
||||
|
||||
bool CreateGPUBridges(base::ProcessId aOtherProcess,
|
||||
mozilla::ipc::Endpoint<PVRGPUChild>* aOutVRBridge);
|
||||
|
||||
VRChild* GetVRChild();
|
||||
|
||||
private:
|
||||
VRProcessManager();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(VRProcessManager);
|
||||
|
||||
bool CreateGPUVRManager(base::ProcessId aOtherProcess,
|
||||
mozilla::ipc::Endpoint<PVRGPUChild>* aOutEndpoint);
|
||||
void OnXPCOMShutdown();
|
||||
void CleanShutdown();
|
||||
|
||||
// Permanently disable the VR process and record a message why.
|
||||
void DisableVRProcess(const char* aMessage);
|
||||
|
||||
class Observer final : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
explicit Observer(VRProcessManager* aManager);
|
||||
|
||||
protected:
|
||||
~Observer() {}
|
||||
|
||||
VRProcessManager* mManager;
|
||||
};
|
||||
friend class Observer;
|
||||
|
||||
RefPtr<Observer> mObserver;
|
||||
VRProcessParent* mProcess;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_VR_PROCESS_MANAGER_H
|
197
gfx/vr/ipc/VRProcessParent.cpp
Normal file
197
gfx/vr/ipc/VRProcessParent.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "VRProcessParent.h"
|
||||
#include "VRGPUChild.h"
|
||||
#include "VRProcessManager.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/gfx/GPUChild.h"
|
||||
#include "mozilla/ipc/ProtocolTypes.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
|
||||
#include "mozilla/TimeStamp.h" // for TimeStamp
|
||||
#include "mozilla/Unused.h"
|
||||
#include "VRChild.h"
|
||||
#include "VRManager.h"
|
||||
#include "VRThread.h"
|
||||
#include "gfxVRPuppet.h"
|
||||
|
||||
#include "nsAppRunner.h" // for IToplevelProtocol
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
VRProcessParent::VRProcessParent()
|
||||
: GeckoChildProcessHost(GeckoProcessType_VR),
|
||||
mTaskFactory(this),
|
||||
mChannelClosed(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(VRProcessParent);
|
||||
}
|
||||
|
||||
VRProcessParent::~VRProcessParent()
|
||||
{
|
||||
// Cancel all tasks. We don't want anything triggering after our caller
|
||||
// expects this to go away.
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mTaskFactory.RevokeAll();
|
||||
}
|
||||
MOZ_COUNT_DTOR(VRProcessParent);
|
||||
}
|
||||
|
||||
bool
|
||||
VRProcessParent::Launch()
|
||||
{
|
||||
mLaunchThread = NS_GetCurrentThread();
|
||||
|
||||
std::vector<std::string> extraArgs;
|
||||
nsCString parentBuildID(mozilla::PlatformBuildID());
|
||||
extraArgs.push_back("-parentBuildID");
|
||||
extraArgs.push_back(parentBuildID.get());
|
||||
|
||||
if (!GeckoChildProcessHost::AsyncLaunch(extraArgs)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::Shutdown()
|
||||
{
|
||||
if (mVRChild) {
|
||||
// The channel might already be closed if we got here unexpectedly.
|
||||
if (!mChannelClosed) {
|
||||
mVRChild->Close();
|
||||
}
|
||||
|
||||
#ifndef NS_FREE_PERMANENT_DATA
|
||||
// No need to communicate shutdown, the VR process doesn't need to
|
||||
// communicate anything back.
|
||||
KillHard("NormalShutdown");
|
||||
#endif
|
||||
|
||||
// If we're shutting down unexpectedly, we're in the middle of handling an
|
||||
// ActorDestroy for PGPUChild, which is still on the stack. We'll return
|
||||
// back to OnChannelClosed.
|
||||
//
|
||||
// Otherwise, we'll wait for OnChannelClose to be called whenever PGPUChild
|
||||
// acknowledges shutdown.
|
||||
return;
|
||||
}
|
||||
|
||||
DestroyProcess();
|
||||
}
|
||||
|
||||
static void
|
||||
DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
|
||||
{
|
||||
XRE_GetIOMessageLoop()->
|
||||
PostTask(mozilla::MakeAndAddRef<DeleteTask<GeckoChildProcessHost>>(aSubprocess));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VRProcessParent::DestroyProcess()
|
||||
{
|
||||
mLaunchThread->Dispatch(NewRunnableFunction("DestroyProcessRunnable", DelayedDeleteSubprocess, this));
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::InitAfterConnect(bool aSucceeded)
|
||||
{
|
||||
if (aSucceeded) {
|
||||
mVRChild = MakeUnique<VRChild>(this);
|
||||
|
||||
DebugOnly<bool> rv =
|
||||
mVRChild->Open(GetChannel(), base::GetProcId(GetChildProcessHandle()));
|
||||
MOZ_ASSERT(rv);
|
||||
|
||||
mVRChild->Init();
|
||||
|
||||
// Make vr-gpu process connection
|
||||
GPUChild* gpuChild = GPUProcessManager::Get()->GetGPUChild();
|
||||
MOZ_ASSERT(gpuChild);
|
||||
|
||||
Endpoint<PVRGPUChild> vrGPUBridge;
|
||||
VRProcessManager* vpm = VRProcessManager::Get();
|
||||
DebugOnly<bool> opened = vpm->CreateGPUBridges(gpuChild->OtherPid(), &vrGPUBridge);
|
||||
MOZ_ASSERT(opened);
|
||||
|
||||
Unused << gpuChild->SendInitVR(std::move(vrGPUBridge));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::KillHard(const char* aReason)
|
||||
{
|
||||
ProcessHandle handle = GetChildProcessHandle();
|
||||
if (!base::KillProcess(handle, base::PROCESS_END_KILLED_BY_USER, false)) {
|
||||
NS_WARNING("failed to kill subprocess!");
|
||||
}
|
||||
|
||||
SetAlreadyDead();
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::OnChannelError()
|
||||
{
|
||||
MOZ_ASSERT(false, "VR process channel error.");
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::OnChannelConnected(int32_t peer_pid)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
GeckoChildProcessHost::OnChannelConnected(peer_pid);
|
||||
|
||||
// Post a task to the main thread. Take the lock because mTaskFactory is not
|
||||
// thread-safe.
|
||||
RefPtr<Runnable> runnable;
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
runnable = mTaskFactory.NewRunnableMethod(&VRProcessParent::OnChannelConnectedTask);
|
||||
}
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::OnChannelConnectedTask()
|
||||
{
|
||||
InitAfterConnect(true);
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::OnChannelErrorTask()
|
||||
{
|
||||
MOZ_ASSERT(false, "VR process channel error.");
|
||||
}
|
||||
|
||||
void
|
||||
VRProcessParent::OnChannelClosed()
|
||||
{
|
||||
mChannelClosed = true;
|
||||
DestroyProcess();
|
||||
|
||||
// Release the actor.
|
||||
VRChild::Destroy(std::move(mVRChild));
|
||||
MOZ_ASSERT(!mVRChild);
|
||||
}
|
||||
|
||||
base::ProcessId
|
||||
VRProcessParent::OtherPid()
|
||||
{
|
||||
return mVRChild->OtherPid();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
57
gfx/vr/ipc/VRProcessParent.h
Normal file
57
gfx/vr/ipc/VRProcessParent.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_VR_PROCESS_PARENT_H
|
||||
#define GFX_VR_PROCESS_PARENT_H
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/ipc/TaskFactory.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class VRChild;
|
||||
|
||||
class VRProcessParent final : public mozilla::ipc::GeckoChildProcessHost
|
||||
{
|
||||
public:
|
||||
explicit VRProcessParent();
|
||||
~VRProcessParent();
|
||||
|
||||
bool Launch();
|
||||
void Shutdown();
|
||||
void DestroyProcess();
|
||||
bool CanShutdown() override { return true; }
|
||||
|
||||
void OnChannelError() override;
|
||||
void OnChannelConnected(int32_t peer_pid) override;
|
||||
void OnChannelConnectedTask();
|
||||
void OnChannelErrorTask();
|
||||
void OnChannelClosed();
|
||||
|
||||
base::ProcessId OtherPid();
|
||||
VRChild* GetActor() const {
|
||||
return mVRChild.get();
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(VRProcessParent);
|
||||
|
||||
void InitAfterConnect(bool aSucceeded);
|
||||
void KillHard(const char* aReason);
|
||||
|
||||
UniquePtr<VRChild> mVRChild;
|
||||
mozilla::ipc::TaskFactory<VRProcessParent> mTaskFactory;
|
||||
nsCOMPtr<nsIThread> mLaunchThread;
|
||||
bool mChannelClosed;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // ifndef GFX_VR_PROCESS_PARENT_H
|
@ -7,11 +7,20 @@
|
||||
EXPORTS += [
|
||||
'external_api/moz_external_vr.h',
|
||||
'gfxVR.h',
|
||||
'gfxVRExternal.h',
|
||||
'ipc/VRChild.h',
|
||||
'ipc/VRGPUChild.h',
|
||||
'ipc/VRGPUParent.h',
|
||||
'ipc/VRLayerChild.h',
|
||||
'ipc/VRManagerChild.h',
|
||||
'ipc/VRManagerParent.h',
|
||||
'ipc/VRMessageUtils.h',
|
||||
'ipc/VRParent.h',
|
||||
'ipc/VRProcessChild.h',
|
||||
'ipc/VRProcessManager.h',
|
||||
'ipc/VRProcessParent.h',
|
||||
'VRDisplayClient.h',
|
||||
'VRDisplayHost.h',
|
||||
'VRDisplayPresentation.h',
|
||||
'VRManager.h',
|
||||
'VRThread.h',
|
||||
@ -25,10 +34,17 @@ LOCAL_INCLUDES += [
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'gfxVR.cpp',
|
||||
'ipc/VRChild.cpp',
|
||||
'ipc/VRGPUChild.cpp',
|
||||
'ipc/VRGPUParent.cpp',
|
||||
'ipc/VRLayerChild.cpp',
|
||||
'ipc/VRLayerParent.cpp',
|
||||
'ipc/VRManagerChild.cpp',
|
||||
'ipc/VRManagerParent.cpp',
|
||||
'ipc/VRParent.cpp',
|
||||
'ipc/VRProcessChild.cpp',
|
||||
'ipc/VRProcessManager.cpp',
|
||||
'ipc/VRProcessParent.cpp',
|
||||
'VRDisplayClient.cpp',
|
||||
'VRDisplayPresentation.cpp',
|
||||
'VRManager.cpp',
|
||||
@ -69,6 +85,8 @@ if CONFIG['OS_TARGET'] == 'Android':
|
||||
LOCAL_INCLUDES += ['/widget/android']
|
||||
|
||||
IPDL_SOURCES = [
|
||||
'ipc/PVR.ipdl',
|
||||
'ipc/PVRGPU.ipdl',
|
||||
'ipc/PVRLayer.ipdl',
|
||||
'ipc/PVRManager.ipdl',
|
||||
]
|
||||
|
@ -59,13 +59,27 @@ VRService::VRService()
|
||||
, mBrowserState{}
|
||||
, mServiceThread(nullptr)
|
||||
, mShutdownRequested(false)
|
||||
, mAPIShmem(nullptr)
|
||||
, mTargetShmemFile(0)
|
||||
{
|
||||
memset(&mAPIShmem, 0, sizeof(mAPIShmem));
|
||||
// When we have the VR process, we map the memory
|
||||
// of mAPIShmem from GPU process.
|
||||
// If we don't have the VR process, we will instantiate
|
||||
// mAPIShmem in VRService.
|
||||
if (!gfxPrefs::VRProcessEnabled()) {
|
||||
mAPIShmem = new VRExternalShmem();
|
||||
memset(mAPIShmem, 0, sizeof(VRExternalShmem));
|
||||
}
|
||||
}
|
||||
|
||||
VRService::~VRService()
|
||||
{
|
||||
Stop();
|
||||
|
||||
if (!gfxPrefs::VRProcessEnabled() && mAPIShmem) {
|
||||
delete mAPIShmem;
|
||||
mAPIShmem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -110,13 +124,63 @@ void
|
||||
VRService::Stop()
|
||||
{
|
||||
if (mServiceThread) {
|
||||
mServiceThread->message_loop()->PostTask(NewRunnableMethod(
|
||||
"gfx::VRService::RequestShutdown",
|
||||
this, &VRService::RequestShutdown
|
||||
));
|
||||
mShutdownRequested = true;
|
||||
delete mServiceThread;
|
||||
mServiceThread = nullptr;
|
||||
}
|
||||
if (mTargetShmemFile) {
|
||||
#if defined(XP_WIN)
|
||||
CloseHandle(mTargetShmemFile);
|
||||
#endif
|
||||
mTargetShmemFile = 0;
|
||||
}
|
||||
if (gfxPrefs::VRProcessEnabled() && mAPIShmem) {
|
||||
#if defined(XP_WIN)
|
||||
UnmapViewOfFile((void *)mAPIShmem);
|
||||
#endif
|
||||
mAPIShmem = nullptr;
|
||||
}
|
||||
mSession = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
VRService::InitShmem()
|
||||
{
|
||||
if (!gfxPrefs::VRProcessEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
const char* kShmemName = "moz.gecko.vr_ext.0.0.1";
|
||||
base::ProcessHandle targetHandle = 0;
|
||||
|
||||
// Opening a file-mapping object by name
|
||||
targetHandle = OpenFileMappingA(
|
||||
FILE_MAP_ALL_ACCESS, // read/write access
|
||||
FALSE, // do not inherit the name
|
||||
kShmemName); // name of mapping object
|
||||
|
||||
MOZ_ASSERT(GetLastError() == 0);
|
||||
|
||||
LARGE_INTEGER length;
|
||||
length.QuadPart = sizeof(VRExternalShmem);
|
||||
mAPIShmem = (VRExternalShmem *)MapViewOfFile(reinterpret_cast<base::ProcessHandle>(targetHandle), // handle to map object
|
||||
FILE_MAP_ALL_ACCESS, // read/write permission
|
||||
0,
|
||||
0,
|
||||
length.QuadPart);
|
||||
MOZ_ASSERT(GetLastError() == 0);
|
||||
// TODO - Implement logging
|
||||
mTargetShmemFile = targetHandle;
|
||||
if (!mAPIShmem) {
|
||||
MOZ_ASSERT(mAPIShmem);
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
// TODO: Implement shmem for other platforms.
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -125,26 +189,23 @@ VRService::IsInServiceThread()
|
||||
return mServiceThread && mServiceThread->thread_id() == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
void
|
||||
VRService::RequestShutdown()
|
||||
{
|
||||
MOZ_ASSERT(IsInServiceThread());
|
||||
mShutdownRequested = true;
|
||||
}
|
||||
|
||||
void
|
||||
VRService::ServiceInitialize()
|
||||
{
|
||||
MOZ_ASSERT(IsInServiceThread());
|
||||
|
||||
if (!InitShmem()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mShutdownRequested = false;
|
||||
memset(&mBrowserState, 0, sizeof(mBrowserState));
|
||||
|
||||
// Try to start a VRSession
|
||||
unique_ptr<VRSession> session;
|
||||
UniquePtr<VRSession> session;
|
||||
|
||||
// Try OpenVR
|
||||
session = make_unique<OpenVRSession>();
|
||||
session = MakeUnique<OpenVRSession>();
|
||||
if (!session->Initialize(mSystemState)) {
|
||||
session = nullptr;
|
||||
}
|
||||
@ -282,6 +343,9 @@ VRService::ServiceImmersiveMode()
|
||||
void
|
||||
VRService::PushState(const mozilla::gfx::VRSystemState& aState)
|
||||
{
|
||||
if (!mAPIShmem) {
|
||||
return;
|
||||
}
|
||||
// Copying the VR service state to the shmem is atomic, infallable,
|
||||
// and non-blocking on x86/x64 architectures. Arm requires a mutex
|
||||
// that is locked for the duration of the memcpy to and from shmem on
|
||||
@ -289,19 +353,22 @@ VRService::PushState(const mozilla::gfx::VRSystemState& aState)
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
if (pthread_mutex_lock((pthread_mutex_t*)&(mExternalShmem->systemMutex)) == 0) {
|
||||
memcpy((void *)&mAPIShmem.state, &aState, sizeof(VRSystemState));
|
||||
memcpy((void *)&mAPIShmem->state, &aState, sizeof(VRSystemState));
|
||||
pthread_mutex_unlock((pthread_mutex_t*)&(mExternalShmem->systemMutex));
|
||||
}
|
||||
#else
|
||||
mAPIShmem.generationA++;
|
||||
memcpy((void *)&mAPIShmem.state, &aState, sizeof(VRSystemState));
|
||||
mAPIShmem.generationB++;
|
||||
mAPIShmem->generationA++;
|
||||
memcpy((void *)&mAPIShmem->state, &aState, sizeof(VRSystemState));
|
||||
mAPIShmem->generationB++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
VRService::PullState(mozilla::gfx::VRBrowserState& aState)
|
||||
{
|
||||
if (!mAPIShmem) {
|
||||
return;
|
||||
}
|
||||
// Copying the browser state from the shmem is non-blocking
|
||||
// on x86/x64 architectures. Arm requires a mutex that is
|
||||
// locked for the duration of the memcpy to and from shmem on
|
||||
@ -318,7 +385,7 @@ VRService::PullState(mozilla::gfx::VRBrowserState& aState)
|
||||
}
|
||||
#else
|
||||
VRExternalShmem tmp;
|
||||
memcpy(&tmp, &mAPIShmem, sizeof(VRExternalShmem));
|
||||
memcpy(&tmp, mAPIShmem, sizeof(VRExternalShmem));
|
||||
if (tmp.browserGenerationA == tmp.browserGenerationB && tmp.browserGenerationA != 0 && tmp.browserGenerationA != -1) {
|
||||
memcpy(&aState, &tmp.browserState, sizeof(VRBrowserState));
|
||||
}
|
||||
@ -328,5 +395,5 @@ VRService::PullState(mozilla::gfx::VRBrowserState& aState)
|
||||
VRExternalShmem*
|
||||
VRService::GetAPIShmem()
|
||||
{
|
||||
return &mAPIShmem;
|
||||
return mAPIShmem;
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "moz_external_vr.h"
|
||||
|
||||
#include <thread>
|
||||
namespace base {
|
||||
class Thread;
|
||||
} // namespace base
|
||||
@ -33,6 +32,8 @@ public:
|
||||
private:
|
||||
VRService();
|
||||
~VRService();
|
||||
|
||||
bool InitShmem();
|
||||
void PushState(const mozilla::gfx::VRSystemState& aState);
|
||||
void PullState(mozilla::gfx::VRBrowserState& aState);
|
||||
|
||||
@ -51,14 +52,14 @@ private:
|
||||
*/
|
||||
VRBrowserState mBrowserState;
|
||||
|
||||
std::unique_ptr<VRSession> mSession;
|
||||
UniquePtr<VRSession> mSession;
|
||||
base::Thread* mServiceThread;
|
||||
bool mShutdownRequested;
|
||||
|
||||
VRExternalShmem mAPIShmem;
|
||||
VRExternalShmem* MOZ_OWNING_REF mAPIShmem;
|
||||
base::ProcessHandle mTargetShmemFile;
|
||||
|
||||
bool IsInServiceThread();
|
||||
void RequestShutdown();
|
||||
|
||||
/**
|
||||
* The VR Service thread is a state machine that always has one
|
||||
|
@ -4,6 +4,7 @@ version = "0.57.2"
|
||||
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||
license = "MPL-2.0"
|
||||
repository = "https://github.com/servo/webrender"
|
||||
description = "A GPU accelerated 2D renderer for web content"
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
@ -40,7 +41,7 @@ serde_json = { optional = true, version = "1.0" }
|
||||
smallvec = "0.6"
|
||||
thread_profiler = "0.1.1"
|
||||
time = "0.1"
|
||||
webrender_api = {path = "../webrender_api"}
|
||||
webrender_api = { version = "0.57.2", path = "../webrender_api" }
|
||||
ws = { optional = true, version = "0.7.3" }
|
||||
|
||||
[dependencies.pathfinder_font_renderer]
|
||||
|
@ -175,6 +175,7 @@ void brush_vs(
|
||||
break;
|
||||
case COLOR_MODE_SUBPX_BG_PASS2:
|
||||
case COLOR_MODE_SUBPX_DUAL_SOURCE:
|
||||
case COLOR_MODE_IMAGE:
|
||||
vMaskSwizzle = vec2(1.0, 0.0);
|
||||
vColor = image_data.color;
|
||||
break;
|
||||
|
@ -42,6 +42,7 @@ varying vec4 vClipMaskUv;
|
||||
#define COLOR_MODE_SUBPX_DUAL_SOURCE 6
|
||||
#define COLOR_MODE_BITMAP 7
|
||||
#define COLOR_MODE_COLOR_BITMAP 8
|
||||
#define COLOR_MODE_IMAGE 9
|
||||
|
||||
uniform HIGHP_SAMPLER_FLOAT sampler2D sPrimitiveHeadersF;
|
||||
uniform HIGHP_SAMPLER_FLOAT isampler2D sPrimitiveHeadersI;
|
||||
|
@ -263,7 +263,6 @@ impl OpaqueBatchList {
|
||||
pub struct BatchList {
|
||||
pub alpha_batch_list: AlphaBatchList,
|
||||
pub opaque_batch_list: OpaqueBatchList,
|
||||
pub combined_bounding_rect: DeviceIntRect,
|
||||
}
|
||||
|
||||
impl BatchList {
|
||||
@ -275,24 +274,14 @@ impl BatchList {
|
||||
BatchList {
|
||||
alpha_batch_list: AlphaBatchList::new(),
|
||||
opaque_batch_list: OpaqueBatchList::new(batch_area_threshold),
|
||||
combined_bounding_rect: DeviceIntRect::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_bounding_rect(
|
||||
&mut self,
|
||||
task_relative_bounding_rect: &DeviceIntRect,
|
||||
) {
|
||||
self.combined_bounding_rect = self.combined_bounding_rect.union(task_relative_bounding_rect);
|
||||
}
|
||||
|
||||
pub fn get_suitable_batch(
|
||||
&mut self,
|
||||
key: BatchKey,
|
||||
task_relative_bounding_rect: &DeviceIntRect,
|
||||
) -> &mut Vec<PrimitiveInstance> {
|
||||
self.add_bounding_rect(task_relative_bounding_rect);
|
||||
|
||||
match key.blend_mode {
|
||||
BlendMode::None => {
|
||||
self.opaque_batch_list
|
||||
@ -409,31 +398,27 @@ pub struct AlphaBatchBuilder {
|
||||
pub batch_list: BatchList,
|
||||
glyph_fetch_buffer: Vec<GlyphFetchResult>,
|
||||
target_rect: DeviceIntRect,
|
||||
can_merge: bool,
|
||||
}
|
||||
|
||||
impl AlphaBatchBuilder {
|
||||
pub fn new(
|
||||
screen_size: DeviceIntSize,
|
||||
target_rect: DeviceIntRect,
|
||||
can_merge: bool,
|
||||
) -> Self {
|
||||
AlphaBatchBuilder {
|
||||
batch_list: BatchList::new(screen_size),
|
||||
glyph_fetch_buffer: Vec::new(),
|
||||
target_rect,
|
||||
can_merge,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(mut self, merged_batches: &mut AlphaBatchContainer) -> Option<AlphaBatchContainer> {
|
||||
self.batch_list.finalize();
|
||||
|
||||
let task_relative_target_rect = DeviceIntRect::new(
|
||||
DeviceIntPoint::zero(),
|
||||
self.target_rect.size,
|
||||
);
|
||||
|
||||
let can_merge = task_relative_target_rect.contains_rect(&self.batch_list.combined_bounding_rect);
|
||||
|
||||
if can_merge {
|
||||
if self.can_merge {
|
||||
merged_batches.merge(self);
|
||||
None
|
||||
} else {
|
||||
@ -473,12 +458,8 @@ impl AlphaBatchBuilder {
|
||||
|
||||
// Add each run in this picture to the batch.
|
||||
for run in &pic.runs {
|
||||
let transform_id = ctx
|
||||
.transforms
|
||||
.get_id(run.spatial_node_index);
|
||||
self.add_run_to_batch(
|
||||
run,
|
||||
transform_id,
|
||||
ctx,
|
||||
gpu_cache,
|
||||
render_tasks,
|
||||
@ -540,7 +521,6 @@ impl AlphaBatchBuilder {
|
||||
fn add_run_to_batch(
|
||||
&mut self,
|
||||
run: &PrimitiveRun,
|
||||
transform_id: TransformPaletteId,
|
||||
ctx: &RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
render_tasks: &RenderTaskTree,
|
||||
@ -556,6 +536,10 @@ impl AlphaBatchBuilder {
|
||||
let metadata = &ctx.prim_store.primitives[prim_index.0].metadata;
|
||||
|
||||
if metadata.screen_rect.is_some() {
|
||||
let transform_id = ctx
|
||||
.transforms
|
||||
.get_id(metadata.spatial_node_index);
|
||||
|
||||
self.add_prim_to_batch(
|
||||
transform_id,
|
||||
prim_index,
|
||||
@ -670,12 +654,12 @@ impl AlphaBatchBuilder {
|
||||
// Push into parent plane splitter.
|
||||
debug_assert!(picture.surface.is_some());
|
||||
let transform = &ctx.transforms
|
||||
.get_transform(picture.original_spatial_node_index);
|
||||
.get_transform_by_id(transform_id);
|
||||
|
||||
match transform.transform_kind {
|
||||
TransformedRectKind::AxisAligned => {
|
||||
let polygon = Polygon::from_transformed_rect(
|
||||
picture.real_local_rect.cast(),
|
||||
prim_metadata.local_rect.cast(),
|
||||
transform.m.cast(),
|
||||
prim_index.0,
|
||||
).unwrap();
|
||||
@ -686,7 +670,7 @@ impl AlphaBatchBuilder {
|
||||
let bounds = (screen_rect.clipped.to_f32() / ctx.device_pixel_scale).to_f64();
|
||||
let matrix = transform.m.cast();
|
||||
let results = clipper.clip_transformed(
|
||||
Polygon::from_rect(picture.real_local_rect.cast(), prim_index.0),
|
||||
Polygon::from_rect(prim_metadata.local_rect.cast(), prim_index.0),
|
||||
&matrix,
|
||||
Some(bounds),
|
||||
);
|
||||
@ -723,7 +707,7 @@ impl AlphaBatchBuilder {
|
||||
let batch = self.batch_list.get_suitable_batch(key, &task_relative_bounding_rect);
|
||||
let prim_header_index = prim_headers.push(&prim_header, [
|
||||
uv_rect_address.as_int(),
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16 |
|
||||
(ShaderColorMode::Image as i32) << 16 |
|
||||
RasterizationSpace::Screen as i32,
|
||||
0,
|
||||
]);
|
||||
@ -786,7 +770,7 @@ impl AlphaBatchBuilder {
|
||||
|
||||
let content_prim_header_index = prim_headers.push(&prim_header, [
|
||||
content_uv_rect_address,
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16 |
|
||||
(ShaderColorMode::Image as i32) << 16 |
|
||||
RasterizationSpace::Screen as i32,
|
||||
0,
|
||||
]);
|
||||
@ -971,7 +955,7 @@ impl AlphaBatchBuilder {
|
||||
.as_int();
|
||||
let prim_header_index = prim_headers.push(&prim_header, [
|
||||
uv_rect_address,
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16 |
|
||||
(ShaderColorMode::Image as i32) << 16 |
|
||||
RasterizationSpace::Screen as i32,
|
||||
0,
|
||||
]);
|
||||
@ -1203,8 +1187,6 @@ impl AlphaBatchBuilder {
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
};
|
||||
|
||||
self.batch_list.add_bounding_rect(task_relative_bounding_rect);
|
||||
|
||||
let batch_key = BatchKey {
|
||||
blend_mode,
|
||||
kind: BatchKind::Brush(batch_kind),
|
||||
@ -1236,8 +1218,6 @@ impl AlphaBatchBuilder {
|
||||
brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
|
||||
};
|
||||
|
||||
self.batch_list.add_bounding_rect(task_relative_bounding_rect);
|
||||
|
||||
match brush.segment_desc {
|
||||
Some(ref segment_desc) => {
|
||||
let alpha_batch_key = BatchKey {
|
||||
@ -1317,7 +1297,6 @@ fn add_gradient_tiles(
|
||||
base_prim_header: &PrimitiveHeader,
|
||||
prim_headers: &mut PrimitiveHeaders,
|
||||
) {
|
||||
batch_list.add_bounding_rect(task_relative_bounding_rect);
|
||||
let batch = batch_list.get_suitable_batch(
|
||||
BatchKey {
|
||||
blend_mode: blend_mode,
|
||||
@ -1373,7 +1352,7 @@ fn get_image_tile_params(
|
||||
textures,
|
||||
[
|
||||
cache_item.uv_rect_handle.as_int(gpu_cache),
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16 |
|
||||
(ShaderColorMode::Image as i32) << 16 |
|
||||
RasterizationSpace::Local as i32,
|
||||
0,
|
||||
],
|
||||
@ -1423,7 +1402,7 @@ impl BrushPrimitive {
|
||||
textures,
|
||||
[
|
||||
cache_item.uv_rect_handle.as_int(gpu_cache),
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16|
|
||||
(ShaderColorMode::Image as i32) << 16|
|
||||
RasterizationSpace::Local as i32,
|
||||
0,
|
||||
],
|
||||
@ -1461,7 +1440,7 @@ impl BrushPrimitive {
|
||||
textures,
|
||||
[
|
||||
cache_item.uv_rect_handle.as_int(gpu_cache),
|
||||
(ShaderColorMode::ColorBitmap as i32) << 16|
|
||||
(ShaderColorMode::Image as i32) << 16|
|
||||
RasterizationSpace::Local as i32,
|
||||
0,
|
||||
],
|
||||
|
@ -11,7 +11,7 @@ use clip_scroll_tree::{CoordinateSystemId, SpatialNodeIndex};
|
||||
use ellipse::Ellipse;
|
||||
use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
|
||||
use gpu_types::BoxShadowStretchMode;
|
||||
use prim_store::{ClipData, ImageMaskData};
|
||||
use prim_store::{BrushClipMaskKind, ClipData, ImageMaskData};
|
||||
use render_task::to_cache_size;
|
||||
use resource_cache::{ImageRequest, ResourceCache};
|
||||
use spatial_node::SpatialNode;
|
||||
@ -352,12 +352,13 @@ pub struct ClipStore {
|
||||
|
||||
// A clip chain instance is what gets built for a given clip
|
||||
// chain id + local primitive region + positioning node.
|
||||
#[derive(Debug)]
|
||||
pub struct ClipChainInstance {
|
||||
pub clips_range: ClipNodeRange,
|
||||
pub local_clip_rect: LayoutRect,
|
||||
pub has_clips_from_other_coordinate_systems: bool,
|
||||
pub has_non_root_coord_system: bool,
|
||||
pub local_bounding_rect: LayoutRect,
|
||||
pub clip_mask_kind: BrushClipMaskKind,
|
||||
}
|
||||
|
||||
impl ClipStore {
|
||||
@ -549,12 +550,19 @@ impl ClipStore {
|
||||
|
||||
let first_clip_node_index = self.clip_node_indices.len() as u32;
|
||||
let mut has_non_root_coord_system = false;
|
||||
let mut has_clips_from_other_coordinate_systems = false;
|
||||
let mut clip_mask_kind = BrushClipMaskKind::Individual;
|
||||
|
||||
// For each potential clip node
|
||||
for node_info in self.clip_node_info.drain(..) {
|
||||
let node = &mut self.clip_nodes[node_info.node_index.0 as usize];
|
||||
|
||||
// TODO(gw): We can easily extend the segment builder to support these clip sources in
|
||||
// the future, but they are rarely used.
|
||||
// We must do this check here in case we continue early below.
|
||||
if node.item.is_image_or_line_decoration_clip() {
|
||||
clip_mask_kind = BrushClipMaskKind::Global;
|
||||
}
|
||||
|
||||
// Convert the prim rect into the clip nodes local space
|
||||
let prim_rect = node_info
|
||||
.conversion
|
||||
@ -600,10 +608,15 @@ impl ClipStore {
|
||||
ClipNodeFlags::SAME_SPATIAL_NODE | ClipNodeFlags::SAME_COORD_SYSTEM
|
||||
}
|
||||
ClipSpaceConversion::Offset(..) => {
|
||||
if !node.item.is_rect() {
|
||||
clip_mask_kind = BrushClipMaskKind::Global;
|
||||
}
|
||||
ClipNodeFlags::SAME_COORD_SYSTEM
|
||||
}
|
||||
ClipSpaceConversion::Transform(..) => {
|
||||
has_clips_from_other_coordinate_systems = true;
|
||||
// If this primitive is clipped by clips from a different coordinate system, then we
|
||||
// need to apply a clip mask for the entire primitive.
|
||||
clip_mask_kind = BrushClipMaskKind::Global;
|
||||
ClipNodeFlags::empty()
|
||||
}
|
||||
};
|
||||
@ -626,10 +639,10 @@ impl ClipStore {
|
||||
// Return a valid clip chain instance
|
||||
Some(ClipChainInstance {
|
||||
clips_range,
|
||||
has_clips_from_other_coordinate_systems,
|
||||
has_non_root_coord_system,
|
||||
local_clip_rect: current_local_clip_rect,
|
||||
local_bounding_rect,
|
||||
clip_mask_kind,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{ExternalScrollId, LayoutPoint, LayoutRect, LayoutVector2D};
|
||||
use api::{ExternalScrollId, LayoutPoint, LayoutRect, LayoutVector2D, LayoutVector3D};
|
||||
use api::{PipelineId, ScrollClamping, ScrollNodeState, ScrollLocation};
|
||||
use api::{LayoutSize, LayoutTransform, PropertyBinding, ScrollSensitivity, WorldPoint};
|
||||
use clip::{ClipStore};
|
||||
@ -24,6 +24,25 @@ pub type ScrollStates = FastHashMap<ExternalScrollId, ScrollFrameInfo>;
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct CoordinateSystemId(pub u32);
|
||||
|
||||
/// A node in the hierarchy of coordinate system
|
||||
/// transforms.
|
||||
#[derive(Debug)]
|
||||
pub struct CoordinateSystem {
|
||||
pub offset: LayoutVector3D,
|
||||
pub transform: LayoutTransform,
|
||||
pub parent: Option<CoordinateSystemId>,
|
||||
}
|
||||
|
||||
impl CoordinateSystem {
|
||||
fn root() -> Self {
|
||||
CoordinateSystem {
|
||||
offset: LayoutVector3D::zero(),
|
||||
transform: LayoutTransform::identity(),
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@ -36,15 +55,6 @@ impl CoordinateSystemId {
|
||||
pub fn root() -> Self {
|
||||
CoordinateSystemId(0)
|
||||
}
|
||||
|
||||
pub fn next(&self) -> Self {
|
||||
let CoordinateSystemId(id) = *self;
|
||||
CoordinateSystemId(id + 1)
|
||||
}
|
||||
|
||||
pub fn advance(&mut self) {
|
||||
self.0 += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClipScrollTree {
|
||||
@ -52,6 +62,11 @@ pub struct ClipScrollTree {
|
||||
/// and clips.
|
||||
pub spatial_nodes: Vec<SpatialNode>,
|
||||
|
||||
/// A list of transforms that establish new coordinate systems.
|
||||
/// Spatial nodes only establish a new coordinate system when
|
||||
/// they have a transform that is not a simple 2d translation.
|
||||
pub coord_systems: Vec<CoordinateSystem>,
|
||||
|
||||
pub pending_scroll_offsets: FastHashMap<ExternalScrollId, (LayoutPoint, ScrollClamping)>,
|
||||
|
||||
/// A set of pipelines which should be discarded the next time this
|
||||
@ -85,11 +100,49 @@ impl ClipScrollTree {
|
||||
pub fn new() -> Self {
|
||||
ClipScrollTree {
|
||||
spatial_nodes: Vec::new(),
|
||||
coord_systems: Vec::new(),
|
||||
pending_scroll_offsets: FastHashMap::default(),
|
||||
pipelines_to_discard: FastHashSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the relative transform from `ref_node_index`
|
||||
/// to `target_node_index`. It's assumed that `ref_node_index`
|
||||
/// is a parent of `target_node_index`. This method will
|
||||
/// panic if that invariant isn't true!
|
||||
pub fn get_relative_transform(
|
||||
&self,
|
||||
ref_node_index: SpatialNodeIndex,
|
||||
target_node_index: SpatialNodeIndex,
|
||||
) -> LayoutTransform {
|
||||
let ref_node = &self.spatial_nodes[ref_node_index.0];
|
||||
let target_node = &self.spatial_nodes[target_node_index.0];
|
||||
|
||||
let mut offset = LayoutVector3D::new(
|
||||
target_node.coordinate_system_relative_offset.x,
|
||||
target_node.coordinate_system_relative_offset.y,
|
||||
0.0,
|
||||
);
|
||||
let mut transform = LayoutTransform::identity();
|
||||
|
||||
// Walk up the tree of coordinate systems, accumulating each
|
||||
// relative transform.
|
||||
let mut current_coordinate_system_id = target_node.coordinate_system_id;
|
||||
while current_coordinate_system_id != ref_node.coordinate_system_id {
|
||||
let coord_system = &self.coord_systems[current_coordinate_system_id.0 as usize];
|
||||
|
||||
let relative_transform = coord_system
|
||||
.transform
|
||||
.post_translate(offset);
|
||||
transform = transform.pre_mul(&relative_transform);
|
||||
|
||||
offset = coord_system.offset;
|
||||
current_coordinate_system_id = coord_system.parent.expect("invalid parent!");
|
||||
}
|
||||
|
||||
transform
|
||||
}
|
||||
|
||||
/// The root reference frame, which is the true root of the ClipScrollTree. Initially
|
||||
/// this ID is not valid, which is indicated by ```spatial_nodes``` being empty.
|
||||
pub fn root_reference_frame_index(&self) -> SpatialNodeIndex {
|
||||
@ -133,6 +186,7 @@ impl ClipScrollTree {
|
||||
}
|
||||
}
|
||||
|
||||
self.coord_systems.clear();
|
||||
self.pipelines_to_discard.clear();
|
||||
scroll_states
|
||||
}
|
||||
@ -191,6 +245,9 @@ impl ClipScrollTree {
|
||||
return transform_palette;
|
||||
}
|
||||
|
||||
self.coord_systems.clear();
|
||||
self.coord_systems.push(CoordinateSystem::root());
|
||||
|
||||
let root_reference_frame_index = self.root_reference_frame_index();
|
||||
let mut state = TransformUpdateState {
|
||||
parent_reference_frame_transform: LayoutVector2D::new(pan.x, pan.y).into(),
|
||||
@ -202,11 +259,9 @@ impl ClipScrollTree {
|
||||
invertible: true,
|
||||
};
|
||||
|
||||
let mut next_coordinate_system_id = state.current_coordinate_system_id.next();
|
||||
self.update_node(
|
||||
root_reference_frame_index,
|
||||
&mut state,
|
||||
&mut next_coordinate_system_id,
|
||||
&mut transform_palette,
|
||||
scene_properties,
|
||||
);
|
||||
@ -218,7 +273,6 @@ impl ClipScrollTree {
|
||||
&mut self,
|
||||
node_index: SpatialNodeIndex,
|
||||
state: &mut TransformUpdateState,
|
||||
next_coordinate_system_id: &mut CoordinateSystemId,
|
||||
transform_palette: &mut TransformPalette,
|
||||
scene_properties: &SceneProperties,
|
||||
) {
|
||||
@ -231,7 +285,7 @@ impl ClipScrollTree {
|
||||
None => return,
|
||||
};
|
||||
|
||||
node.update(&mut state, next_coordinate_system_id, scene_properties);
|
||||
node.update(&mut state, &mut self.coord_systems, scene_properties);
|
||||
node.push_gpu_data(transform_palette, node_index);
|
||||
|
||||
if node.children.is_empty() {
|
||||
@ -246,7 +300,6 @@ impl ClipScrollTree {
|
||||
self.update_node(
|
||||
child_node_index,
|
||||
&mut state,
|
||||
next_coordinate_system_id,
|
||||
transform_palette,
|
||||
scene_properties,
|
||||
);
|
||||
|
@ -513,6 +513,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
info.image_key,
|
||||
info.image_rendering,
|
||||
info.alpha_type,
|
||||
info.color,
|
||||
);
|
||||
}
|
||||
SpecificDisplayItem::YuvImage(ref info) => {
|
||||
@ -776,6 +777,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&mut self,
|
||||
info: &LayoutPrimitiveInfo,
|
||||
clip_chain_id: ClipChainId,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
container: PrimitiveContainer,
|
||||
) -> PrimitiveIndex {
|
||||
let stacking_context = self.sc_stack.last().expect("bug: no stacking context!");
|
||||
@ -785,6 +787,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&info.clip_rect,
|
||||
info.is_backface_visible && stacking_context.is_backface_visible,
|
||||
clip_chain_id,
|
||||
spatial_node_index,
|
||||
info.tag,
|
||||
container,
|
||||
)
|
||||
@ -817,12 +820,11 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
pub fn add_primitive_to_draw_list(
|
||||
&mut self,
|
||||
prim_index: PrimitiveIndex,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
) {
|
||||
// Add primitive to the top-most Picture on the stack.
|
||||
let pic_prim_index = *self.picture_stack.last().unwrap();
|
||||
let pic = self.prim_store.get_pic_mut(pic_prim_index);
|
||||
pic.add_primitive(prim_index, spatial_node_index);
|
||||
pic.add_primitive(prim_index);
|
||||
}
|
||||
|
||||
/// Convenience interface that creates a primitive entry and adds it
|
||||
@ -859,15 +861,13 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
let shadow_prim_index = self.create_primitive(
|
||||
&info,
|
||||
clip_chain_id,
|
||||
clip_and_scroll.spatial_node_index,
|
||||
container.create_shadow(shadow),
|
||||
);
|
||||
|
||||
// Add the new primitive to the shadow picture.
|
||||
let shadow_pic = self.prim_store.get_pic_mut(shadow_pic_prim_index);
|
||||
shadow_pic.add_primitive(
|
||||
shadow_prim_index,
|
||||
clip_and_scroll.spatial_node_index,
|
||||
);
|
||||
shadow_pic.add_primitive(shadow_prim_index);
|
||||
}
|
||||
self.shadow_stack = shadow_stack;
|
||||
}
|
||||
@ -878,7 +878,12 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
clip_and_scroll.spatial_node_index,
|
||||
clip_and_scroll.clip_chain_id,
|
||||
);
|
||||
let prim_index = self.create_primitive(info, clip_chain_id, container);
|
||||
let prim_index = self.create_primitive(
|
||||
info,
|
||||
clip_chain_id,
|
||||
clip_and_scroll.spatial_node_index,
|
||||
container,
|
||||
);
|
||||
if cfg!(debug_assertions) && ChasePrimitive::LocalRect(info.rect) == self.config.chase_primitive {
|
||||
println!("Chasing {:?}", prim_index);
|
||||
self.prim_store.chase_id = Some(prim_index);
|
||||
@ -886,7 +891,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
self.add_primitive_to_hit_testing_list(info, clip_and_scroll);
|
||||
self.add_primitive_to_draw_list(
|
||||
prim_index,
|
||||
clip_and_scroll.spatial_node_index,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -935,7 +939,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
None,
|
||||
false,
|
||||
pipeline_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
@ -945,6 +948,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&max_clip,
|
||||
true,
|
||||
ClipChainId::NONE,
|
||||
spatial_node_index,
|
||||
None,
|
||||
PrimitiveContainer::Brush(BrushPrimitive::new_picture(picture)),
|
||||
);
|
||||
@ -1001,7 +1005,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
None,
|
||||
false,
|
||||
pipeline_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
@ -1013,6 +1016,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&max_clip,
|
||||
is_backface_visible,
|
||||
clip_chain_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
PrimitiveContainer::Brush(prim),
|
||||
);
|
||||
@ -1020,7 +1024,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
let parent_prim_index = *self.picture_stack.last().unwrap();
|
||||
|
||||
let pic = self.prim_store.get_pic_mut(parent_prim_index);
|
||||
pic.add_primitive(prim_index, spatial_node_index);
|
||||
pic.add_primitive(prim_index);
|
||||
|
||||
self.picture_stack.push(prim_index);
|
||||
|
||||
@ -1052,7 +1056,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
Some(PictureCompositeMode::Filter(*filter)),
|
||||
false,
|
||||
pipeline_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
@ -1063,6 +1066,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&max_clip,
|
||||
is_backface_visible,
|
||||
clip_chain_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
PrimitiveContainer::Brush(src_prim),
|
||||
);
|
||||
@ -1070,7 +1074,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
let parent_pic = self.prim_store.get_pic_mut(parent_prim_index);
|
||||
parent_prim_index = src_prim_index;
|
||||
|
||||
parent_pic.add_primitive(src_prim_index, spatial_node_index);
|
||||
parent_pic.add_primitive(src_prim_index);
|
||||
|
||||
self.picture_stack.push(src_prim_index);
|
||||
}
|
||||
@ -1082,7 +1086,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
Some(PictureCompositeMode::MixBlend(mix_blend_mode)),
|
||||
false,
|
||||
pipeline_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
true,
|
||||
);
|
||||
@ -1094,13 +1097,14 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&max_clip,
|
||||
is_backface_visible,
|
||||
clip_chain_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
PrimitiveContainer::Brush(src_prim),
|
||||
);
|
||||
|
||||
let parent_pic = self.prim_store.get_pic_mut(parent_prim_index);
|
||||
parent_prim_index = src_prim_index;
|
||||
parent_pic.add_primitive(src_prim_index, spatial_node_index);
|
||||
parent_pic.add_primitive(src_prim_index);
|
||||
|
||||
self.picture_stack.push(src_prim_index);
|
||||
}
|
||||
@ -1138,7 +1142,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
composite_mode,
|
||||
participating_in_3d_context,
|
||||
pipeline_id,
|
||||
spatial_node_index,
|
||||
frame_output_pipeline_id,
|
||||
true,
|
||||
);
|
||||
@ -1152,12 +1155,13 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&max_clip,
|
||||
is_backface_visible,
|
||||
clip_chain_id,
|
||||
spatial_node_index,
|
||||
None,
|
||||
PrimitiveContainer::Brush(sc_prim),
|
||||
);
|
||||
|
||||
let parent_pic = self.prim_store.get_pic_mut(parent_prim_index);
|
||||
parent_pic.add_primitive(sc_prim_index, spatial_node_index);
|
||||
parent_pic.add_primitive(sc_prim_index);
|
||||
|
||||
// Add this as the top-most picture for primitives to be added to.
|
||||
self.picture_stack.push(sc_prim_index);
|
||||
@ -1384,7 +1388,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
Some(PictureCompositeMode::Filter(FilterOp::Blur(std_deviation))),
|
||||
false,
|
||||
pipeline_id,
|
||||
clip_and_scroll.spatial_node_index,
|
||||
None,
|
||||
apply_local_clip_rect,
|
||||
);
|
||||
@ -1396,6 +1399,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
&max_clip,
|
||||
info.is_backface_visible,
|
||||
clip_and_scroll.clip_chain_id,
|
||||
clip_and_scroll.spatial_node_index,
|
||||
None,
|
||||
PrimitiveContainer::Brush(shadow_prim),
|
||||
);
|
||||
@ -1404,7 +1408,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
// picture on to the shadow stack, to avoid infinite recursion!
|
||||
self.add_primitive_to_draw_list(
|
||||
shadow_prim_index,
|
||||
clip_and_scroll.spatial_node_index,
|
||||
);
|
||||
self.shadow_stack.push((shadow, shadow_prim_index));
|
||||
}
|
||||
@ -1479,12 +1482,12 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
let prim_index = self.create_primitive(
|
||||
info,
|
||||
ClipChainId::NONE,
|
||||
spatial_node_index,
|
||||
PrimitiveContainer::Brush(prim),
|
||||
);
|
||||
|
||||
self.add_primitive_to_draw_list(
|
||||
prim_index,
|
||||
spatial_node_index,
|
||||
);
|
||||
|
||||
self.scrollbar_prims.push(ScrollbarPrimitive {
|
||||
@ -1908,6 +1911,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
image_key: ImageKey,
|
||||
image_rendering: ImageRendering,
|
||||
alpha_type: AlphaType,
|
||||
color: ColorF,
|
||||
) {
|
||||
let mut prim_rect = info.rect;
|
||||
simplify_repeated_primitive(&stretch_size, &mut tile_spacing, &mut prim_rect);
|
||||
@ -1939,6 +1943,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
alpha_type,
|
||||
stretch_size,
|
||||
tile_spacing,
|
||||
color,
|
||||
source: ImageSource::Default,
|
||||
sub_rect,
|
||||
visible_tiles: Vec::new(),
|
||||
|
@ -13,14 +13,14 @@ use gpu_types::{PrimitiveHeaders, TransformPalette, UvRectKind};
|
||||
use hit_test::{HitTester, HitTestingRun};
|
||||
use internal_types::{FastHashMap};
|
||||
use picture::PictureSurface;
|
||||
use prim_store::{PrimitiveIndex, PrimitiveRun, PrimitiveStore, Transform};
|
||||
use prim_store::{PrimitiveIndex, PrimitiveRun, LocalRectBuilder, PrimitiveStore, Transform};
|
||||
use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
|
||||
use render_backend::FrameId;
|
||||
use render_task::{RenderTask, RenderTaskId, RenderTaskLocation, RenderTaskTree};
|
||||
use resource_cache::{ResourceCache};
|
||||
use scene::{ScenePipeline, SceneProperties};
|
||||
use spatial_node::SpatialNode;
|
||||
use std::{mem, f32};
|
||||
use std::f32;
|
||||
use std::sync::Arc;
|
||||
use tiling::{Frame, RenderPass, RenderPassKind, RenderTargetContext};
|
||||
use tiling::{ScrollbarPrimitive, SpecialRenderPasses};
|
||||
@ -89,8 +89,6 @@ pub struct FrameBuildingState<'a> {
|
||||
pub struct PictureContext {
|
||||
pub pipeline_id: PipelineId,
|
||||
pub prim_runs: Vec<PrimitiveRun>,
|
||||
pub spatial_node_index: SpatialNodeIndex,
|
||||
pub original_spatial_node_index: SpatialNodeIndex,
|
||||
pub apply_local_clip_rect: bool,
|
||||
pub inflation_factor: f32,
|
||||
pub allow_subpixel_aa: bool,
|
||||
@ -112,20 +110,20 @@ impl PictureState {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PrimitiveRunContext<'a> {
|
||||
pub scroll_node: &'a SpatialNode,
|
||||
pub struct PrimitiveContext<'a> {
|
||||
pub spatial_node: &'a SpatialNode,
|
||||
pub spatial_node_index: SpatialNodeIndex,
|
||||
pub transform: Transform<'a>,
|
||||
}
|
||||
|
||||
impl<'a> PrimitiveRunContext<'a> {
|
||||
impl<'a> PrimitiveContext<'a> {
|
||||
pub fn new(
|
||||
scroll_node: &'a SpatialNode,
|
||||
spatial_node: &'a SpatialNode,
|
||||
spatial_node_index: SpatialNodeIndex,
|
||||
transform: Transform<'a>,
|
||||
) -> Self {
|
||||
PrimitiveRunContext {
|
||||
scroll_node,
|
||||
PrimitiveContext {
|
||||
spatial_node,
|
||||
spatial_node_index,
|
||||
transform,
|
||||
}
|
||||
@ -195,11 +193,11 @@ impl FrameBuilder {
|
||||
if self.prim_store.primitives.is_empty() {
|
||||
return None
|
||||
}
|
||||
self.prim_store.reset_prim_visibility();
|
||||
|
||||
// The root picture is always the first one added.
|
||||
let root_prim_index = PrimitiveIndex(0);
|
||||
let root_spatial_node_index = clip_scroll_tree.root_reference_frame_index();
|
||||
let root_spatial_node = &clip_scroll_tree.spatial_nodes[root_spatial_node_index.0];
|
||||
|
||||
const MAX_CLIP_COORD: f32 = 1.0e9;
|
||||
|
||||
@ -226,34 +224,33 @@ impl FrameBuilder {
|
||||
special_render_passes,
|
||||
};
|
||||
|
||||
let pic_context = PictureContext {
|
||||
pipeline_id: root_spatial_node.pipeline_id,
|
||||
prim_runs: mem::replace(
|
||||
&mut self.prim_store.get_pic_mut(root_prim_index).runs,
|
||||
Vec::new(),
|
||||
),
|
||||
spatial_node_index: root_spatial_node_index,
|
||||
original_spatial_node_index: root_spatial_node_index,
|
||||
apply_local_clip_rect: true,
|
||||
inflation_factor: 0.0,
|
||||
allow_subpixel_aa: true,
|
||||
};
|
||||
|
||||
let mut pic_state = PictureState::new();
|
||||
|
||||
self.prim_store.reset_prim_visibility();
|
||||
let pic_context = self
|
||||
.prim_store
|
||||
.get_pic_mut(root_prim_index)
|
||||
.take_context(true);
|
||||
|
||||
let mut local_rect_builder = LocalRectBuilder::new(
|
||||
root_spatial_node_index,
|
||||
);
|
||||
|
||||
self.prim_store.prepare_prim_runs(
|
||||
&pic_context,
|
||||
&mut pic_state,
|
||||
&frame_context,
|
||||
&mut frame_state,
|
||||
&mut local_rect_builder,
|
||||
);
|
||||
|
||||
let pic = self.prim_store.get_pic_mut(root_prim_index);
|
||||
pic.runs = pic_context.prim_runs;
|
||||
let pic = self
|
||||
.prim_store
|
||||
.get_pic_mut(root_prim_index);
|
||||
pic.restore_context(pic_context, local_rect_builder);
|
||||
|
||||
let root_render_task = RenderTask::new_picture(
|
||||
RenderTaskLocation::Fixed(frame_context.screen_rect),
|
||||
frame_context.screen_rect.size,
|
||||
root_prim_index,
|
||||
DeviceIntPoint::zero(),
|
||||
pic_state.tasks,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user