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

This commit is contained in:
Dorel Luca 2018-08-21 12:54:24 +03:00
commit 07c6e76122
243 changed files with 3874 additions and 1564 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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"]);
}

View File

@ -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)

View File

@ -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) {

View File

@ -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() {

View File

@ -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);
}

View File

@ -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) {

View File

@ -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
*/

View File

@ -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 });
}
},

View File

@ -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

View File

@ -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.

View File

@ -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]

View 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);
});

View File

@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body>
</body>
</html>

View File

@ -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"

View File

@ -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;
}
}

View File

@ -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}"

View File

@ -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.

View File

@ -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
# ==============================================================

View File

@ -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()

View File

@ -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',

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -8,6 +8,7 @@
// like.
#include "DevTools.h"
#include "js/SavedFrameAPI.h"
#include "js/TypeDecls.h"
#include "mozilla/devtools/DeserializedNode.h"

View File

@ -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"

View File

@ -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
View 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
View 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

View File

@ -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',

View File

@ -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"

View File

@ -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"

View File

@ -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)
{

View File

@ -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;

View File

@ -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"

View File

@ -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))) {

View File

@ -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,

View File

@ -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"

View File

@ -1064,6 +1064,10 @@ DOMInterfaces = {
'wrapperCache': False,
},
'VisualViewport': {
'nativeType': 'mozilla::dom::VisualViewport',
},
'VTTCue': {
'nativeType': 'mozilla::dom::TextTrackCue'
},

View File

@ -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"

View File

@ -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"

View File

@ -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)
{

View File

@ -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"

View File

@ -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]);

View File

@ -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"

View File

@ -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.

View File

@ -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) {

View File

@ -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);",

View File

@ -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!

View 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;
};

View File

@ -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;
};

View File

@ -918,6 +918,7 @@ WEBIDL_FILES = [
'VideoStreamTrack.webidl',
'VideoTrack.webidl',
'VideoTrackList.webidl',
'VisualViewport.webidl',
'VRDisplay.webidl',
'VRDisplayEvent.webidl',
'VRServiceTest.webidl',

View File

@ -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"

View File

@ -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)
{

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -154,6 +154,7 @@ static inline bool
ProcessOwnsCompositor()
{
return XRE_GetProcessType() == GeckoProcessType_GPU ||
XRE_GetProcessType() == GeckoProcessType_VR ||
(XRE_IsParentProcess() && !gfxConfig::IsEnabled(Feature::GPU_PROCESS));
}

View File

@ -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();

View File

@ -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();
}

View File

@ -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);

View File

@ -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();

View File

@ -102,6 +102,7 @@ private:
#endif
bool mVRDisplaysRequested;
bool mVRControllersRequested;
bool mVRServiceStarted;
};
} // namespace gfx

View File

@ -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;
}

View File

@ -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;

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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
View 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

View 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);
}

View 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 */

View 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

View 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

View 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

View 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

View File

@ -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',
]

View File

@ -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;
}

View File

@ -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

View File

@ -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]

View File

@ -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;

View File

@ -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;

View File

@ -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,
],

View File

@ -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,
})
}
}

View File

@ -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,
);

View File

@ -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(),

View File

@ -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