Update On Mon Feb 26 19:42:19 CET 2024
This commit is contained in:
parent
3d2961ec46
commit
b19f1b34aa
214 changed files with 2393 additions and 962 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -6549,6 +6549,7 @@ dependencies = [
|
|||
name = "wgpu_bindings"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bincode",
|
||||
"d3d12",
|
||||
"log",
|
||||
|
|
|
@ -124,7 +124,6 @@ module.exports = {
|
|||
"consistent-this": ["error", "use-bind"],
|
||||
eqeqeq: "error",
|
||||
"func-name-matching": "error",
|
||||
"getter-return": "error",
|
||||
"guard-for-in": "error",
|
||||
"max-nested-callbacks": ["error", 4],
|
||||
"max-params": ["error", 6],
|
||||
|
|
|
@ -94,7 +94,6 @@ module.exports = {
|
|||
"consistent-this": ["error", "use-bind"],
|
||||
eqeqeq: "error",
|
||||
"func-name-matching": "error",
|
||||
"getter-return": "error",
|
||||
"guard-for-in": "error",
|
||||
"max-nested-callbacks": ["error", 4],
|
||||
"max-params": ["error", 6],
|
||||
|
|
|
@ -123,7 +123,6 @@ module.exports = {
|
|||
"consistent-this": ["error", "use-bind"],
|
||||
eqeqeq: "error",
|
||||
"func-name-matching": "error",
|
||||
"getter-return": "error",
|
||||
"guard-for-in": "error",
|
||||
"max-nested-callbacks": ["error", 4],
|
||||
"max-params": ["error", 6],
|
||||
|
|
|
@ -558,11 +558,17 @@ class MenuHelper {
|
|||
return true;
|
||||
}
|
||||
|
||||
get reportBrokenSite() {}
|
||||
get reportBrokenSite() {
|
||||
throw new Error("Should be defined in derived class");
|
||||
}
|
||||
|
||||
get reportSiteIssue() {}
|
||||
get reportSiteIssue() {
|
||||
throw new Error("Should be defined in derived class");
|
||||
}
|
||||
|
||||
get popup() {}
|
||||
get popup() {
|
||||
throw new Error("Should be defined in derived class");
|
||||
}
|
||||
|
||||
get opened() {
|
||||
return this.popup?.hasAttribute("panelopen");
|
||||
|
|
|
@ -20,8 +20,6 @@ skip-if = ["apple_silicon && !debug"]
|
|||
|
||||
["browser_fr_fields.js"]
|
||||
|
||||
["browser_ignore_unfocusable_fields.js"]
|
||||
|
||||
["browser_label_rules.js"]
|
||||
|
||||
["browser_multiple_section.js"]
|
||||
|
@ -37,3 +35,5 @@ skip-if = ["apple_silicon && !debug"]
|
|||
["browser_section_validation_address.js"]
|
||||
|
||||
["browser_sections_by_name.js"]
|
||||
|
||||
["browser_sections_with_invisible_fields.js"]
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* global add_heuristic_tests */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_heuristic_tests([
|
||||
{
|
||||
description: "All visual fields are considered focusable.",
|
||||
|
||||
fixtureData: `
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type="text" id="name" autocomplete="name" />
|
||||
<input type="text" id="tel" autocomplete="tel" />
|
||||
<input type="text" id="email" autocomplete="email"/>
|
||||
<select id="country" autocomplete="country">
|
||||
<option value="United States">United States</option>
|
||||
</select>
|
||||
<input type="text" id="postal-code" autocomplete="postal-code"/>
|
||||
<input type="text" id="address-line1" autocomplete="address-line1" />
|
||||
<div>
|
||||
<input type="text" id="address-line2" autocomplete="address-line2" />
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "name" },
|
||||
{ fieldName: "tel" },
|
||||
{ fieldName: "email" },
|
||||
{ fieldName: "country" },
|
||||
{ fieldName: "postal-code" },
|
||||
{ fieldName: "address-line1" },
|
||||
{ fieldName: "address-line2" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// ignore opacity (see Bug 1835852),
|
||||
description:
|
||||
"Invisible fields with style.opacity=0 set are considered focusable.",
|
||||
|
||||
fixtureData: `
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type="text" id="name" autocomplete="name" style="opacity:0" />
|
||||
<input type="text" id="tel" autocomplete="tel" />
|
||||
<input type="text" id="email" autocomplete="email" style="opacity:0"/>
|
||||
<select id="country" autocomplete="country">
|
||||
<option value="United States">United States</option>
|
||||
</select>
|
||||
<input type="text" id="postal-code" autocomplete="postal-code" />
|
||||
<input type="text" id="address-line1" autocomplete="address-line1" />
|
||||
<div>
|
||||
<input type="text" id="address-line2" autocomplete="address-line2" />
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "name" },
|
||||
{ fieldName: "tel" },
|
||||
{ fieldName: "email" },
|
||||
{ fieldName: "country" },
|
||||
{ fieldName: "postal-code" },
|
||||
{ fieldName: "address-line1" },
|
||||
{ fieldName: "address-line2" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description:
|
||||
"Some fields are considered unfocusable due to their invisibility.",
|
||||
|
||||
fixtureData: `
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type="text" id="name" autocomplete="name" />
|
||||
<input type="text" id="tel" autocomplete="tel" />
|
||||
<input type="text" id="email" autocomplete="email" />
|
||||
<input type="text" id="country" autocomplete="country" />
|
||||
<input type="text" id="postal-code" autocomplete="postal-code" hidden />
|
||||
<input type="text" id="address-line1" autocomplete="address-line1" style="display:none" />
|
||||
<div style="visibility: hidden">
|
||||
<input type="text" id="address-line2" autocomplete="address-line2" />
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "name" },
|
||||
{ fieldName: "tel" },
|
||||
{ fieldName: "email" },
|
||||
{ fieldName: "country" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description: `Disabled field and field with tabindex="-1" is considered unfocusable`,
|
||||
|
||||
fixtureData: `
|
||||
<html>
|
||||
<body>
|
||||
<form>
|
||||
<input type="text" id="name" autocomplete="name" />
|
||||
<input type="text" id="tel" autocomplete="tel" />
|
||||
<input type="text" id="email" autocomplete="email" />
|
||||
<input type="text" id="country" autocomplete="country" disabled/>
|
||||
<input type="text" id="postal-code" autocomplete="postal-code" tabindex="-1"/>
|
||||
<input type="text" id="address-line1" autocomplete="address-line1" />
|
||||
<input type="text" id="address-line2" autocomplete="address-line2" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "name" },
|
||||
{ fieldName: "tel" },
|
||||
{ fieldName: "email" },
|
||||
{ fieldName: "address-line1" },
|
||||
{ fieldName: "address-line2" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
|
@ -0,0 +1,131 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* global add_heuristic_tests */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_heuristic_tests([
|
||||
{
|
||||
description: `Create a new section when the section already has a field with the same field name`,
|
||||
fixtureData: `
|
||||
<html><body>
|
||||
<input type="text" autocomplete="cc-number"/>
|
||||
<input type="text" autocomplete="cc-name"/>
|
||||
<input type="text" autocomplete="cc-exp"/>
|
||||
<input type="text" autocomplete="cc-exp"/>
|
||||
</body></html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "cc-number" },
|
||||
{ fieldName: "cc-name" },
|
||||
{ fieldName: "cc-exp" },
|
||||
],
|
||||
},
|
||||
{
|
||||
fields: [{ fieldName: "cc-exp", reason: "autocomplete" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description: `Do not create a new section for an invisible field`,
|
||||
fixtureData: `
|
||||
<html><body>
|
||||
<input type="text" autocomplete="cc-number"/>
|
||||
<input type="text" autocomplete="cc-name"/>
|
||||
<input type="text" autocomplete="cc-exp"/>
|
||||
<input type="text" autocomplete="cc-exp" style="display:none"/>
|
||||
</body></html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "cc-number" },
|
||||
{ fieldName: "cc-name" },
|
||||
{ fieldName: "cc-exp" },
|
||||
{ fieldName: "cc-exp" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description: `Do not create a new section when the field with the same field name is an invisible field`,
|
||||
fixtureData: `
|
||||
<html><body>
|
||||
<input type="text" autocomplete="cc-number""/>
|
||||
<input type="text" autocomplete="cc-name"/>
|
||||
<input type="text" autocomplete="cc-exp" style="display:none"/>
|
||||
<input type="text" autocomplete="cc-exp"/>
|
||||
</body></html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "cc-number" },
|
||||
{ fieldName: "cc-name" },
|
||||
{ fieldName: "cc-exp" },
|
||||
{ fieldName: "cc-exp" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description: `Do not create a new section for an invisible field (match field is not adjacent)`,
|
||||
fixtureData: `
|
||||
<html><body>
|
||||
<input type="text" autocomplete="cc-number"/>
|
||||
<input type="text" autocomplete="cc-name"/>
|
||||
<input type="text" autocomplete="cc-exp"/>
|
||||
<input type="text" autocomplete="cc-number" style="display:none"/>
|
||||
</body></html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "cc-number" },
|
||||
{ fieldName: "cc-name" },
|
||||
{ fieldName: "cc-exp" },
|
||||
{ fieldName: "cc-number" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description: `Do not create a new section when the field with the same field name is an invisible field (match field is not adjacent)`,
|
||||
fixtureData: `
|
||||
<html><body>
|
||||
<input type="text" autocomplete="cc-number" style="display:none"/>
|
||||
<input type="text" autocomplete="cc-name"/>
|
||||
<input type="text" autocomplete="cc-exp"/>
|
||||
<input type="text" autocomplete="cc-number"/>
|
||||
</body></html>
|
||||
`,
|
||||
expectedResult: [
|
||||
{
|
||||
default: {
|
||||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "cc-number" },
|
||||
{ fieldName: "cc-name" },
|
||||
{ fieldName: "cc-exp" },
|
||||
{ fieldName: "cc-number" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
|
@ -16,6 +16,8 @@ add_heuristic_tests(
|
|||
//{ fieldName: "cc-cvc" },
|
||||
{ fieldName: "cc-exp-month" },
|
||||
{ fieldName: "cc-exp-year" },
|
||||
{ fieldName: "cc-number", reason: "regex-heuristic" }, // invisible
|
||||
{ fieldName: "cc-number", reason: "regex-heuristic" }, // invisible
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -35,9 +35,16 @@ add_heuristic_tests(
|
|||
reason: "autocomplete",
|
||||
},
|
||||
fields: [
|
||||
{ fieldName: "cc-exp-month" },
|
||||
{ fieldName: "cc-exp-year" },
|
||||
{ fieldName: "cc-number", reason: "fathom" },
|
||||
{ fieldName: "cc-exp-month", reason: "regex-heuristic" },
|
||||
{ fieldName: "cc-exp-year", reason: "regex-heuristic" },
|
||||
],
|
||||
},
|
||||
{
|
||||
invalid: true,
|
||||
fields: [
|
||||
{ fieldName: "cc-exp-month", reason: "regex-heuristic" }, // invisible
|
||||
{ fieldName: "cc-exp-year", reason: "regex-heuristic" }, // invisible
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -71,24 +71,6 @@ region-name-tw = Taiwan
|
|||
L10nRegistry.getInstance().registerSources([mockSource]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock the return value of Services.focus.elementIsFocusable
|
||||
* since a field's focusability can't be tested in a unit test.
|
||||
*/
|
||||
(function ignoreAFieldsFocusability() {
|
||||
let stub = sinon.stub(Services, "focus").get(() => {
|
||||
return {
|
||||
elementIsFocusable() {
|
||||
return true;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
stub.restore();
|
||||
});
|
||||
})();
|
||||
|
||||
do_get_profile();
|
||||
|
||||
const EXTENSION_ID = "formautofill@mozilla.org";
|
||||
|
|
|
@ -421,6 +421,39 @@ const TESTCASES = [
|
|||
"cc-exp-year": "25",
|
||||
},
|
||||
},
|
||||
{
|
||||
description:
|
||||
"Form with hidden input and visible input that share the same autocomplete attribute",
|
||||
document: `<form>
|
||||
<input id="hidden-cc" autocomplete="cc-number" hidden>
|
||||
<input id="hidden-cc-2" autocomplete="cc-number" style="display:none">
|
||||
<input id="visible-cc" autocomplete="cc-number">
|
||||
<input id="hidden-name" autocomplete="cc-name" hidden>
|
||||
<input id="hidden-name-2" autocomplete="cc-name" style="display:none">
|
||||
<input id="visible-name" autocomplete="cc-name">
|
||||
<input id="cc-exp-month" autocomplete="cc-exp-month">
|
||||
<input id="cc-exp-year" autocomplete="cc-exp-year">
|
||||
</form>`,
|
||||
focusedInputId: "visible-cc",
|
||||
profileData: {
|
||||
guid: "123",
|
||||
"cc-number": "4111111111111111",
|
||||
"cc-name": "test name",
|
||||
"cc-exp-month": 6,
|
||||
"cc-exp-year": 25,
|
||||
},
|
||||
expectedResult: {
|
||||
guid: "123",
|
||||
"visible-cc": "4111111111111111",
|
||||
"visible-name": "test name",
|
||||
"cc-exp-month": "06",
|
||||
"cc-exp-year": "25",
|
||||
"hidden-cc": "4111111111111111",
|
||||
"hidden-cc-2": "4111111111111111",
|
||||
"hidden-name": "test name",
|
||||
"hidden-name-2": "test name",
|
||||
},
|
||||
},
|
||||
{
|
||||
description:
|
||||
"Fill credit card fields in a form where the value property is being used as a placeholder for cardholder name",
|
||||
|
|
|
@ -6,6 +6,9 @@ skip-if = [
|
|||
firefox-appdir = "browser"
|
||||
head = "head.js"
|
||||
support-files = ["../fixtures/**"]
|
||||
prefs = [
|
||||
"extensions.formautofill.test.ignoreVisibilityCheck=true",
|
||||
]
|
||||
|
||||
["test_activeStatus.js"]
|
||||
|
||||
|
|
|
@ -519,7 +519,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "9b0d458004c01cd5ad33d0bf7574a662b1fb06bf"
|
||||
"revision": "f5fa929f511c8f87161b973d05788492cb64bfeb"
|
||||
},
|
||||
"es-MX": {
|
||||
"pin": false,
|
||||
|
@ -861,7 +861,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "d78edcbca24f7d3c10f8d63fec4918cc7e4e7b88"
|
||||
"revision": "f19469d560a9371766769d32c955c122788a8850"
|
||||
},
|
||||
"hy-AM": {
|
||||
"pin": false,
|
||||
|
@ -1353,7 +1353,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "7da781a8d4e2461eae5391371fb848ebc61931d2"
|
||||
"revision": "786c4f4f659fe3aa92dc6ac4b22ad19c74cb2b4e"
|
||||
},
|
||||
"oc": {
|
||||
"pin": false,
|
||||
|
@ -1605,7 +1605,7 @@
|
|||
"win64-aarch64-devedition",
|
||||
"win64-devedition"
|
||||
],
|
||||
"revision": "df4417ab0f80a1efebae366ef36e6d4a651fefb7"
|
||||
"revision": "b76336ce9e5c795ffb6db603a8c8bd0490ffeea2"
|
||||
},
|
||||
"skr": {
|
||||
"pin": false,
|
||||
|
|
|
@ -130,3 +130,12 @@ So pushing to try is basically just:
|
|||
Because of the build process, a full opt build will take around 1h45-2h while a
|
||||
debug build will be around 60 minutes, the difference coming from the use of
|
||||
PGO on opt builds.
|
||||
|
||||
If you need to reuse a package from the Snap Store or from the latest
|
||||
mozilla-central or a specific successful build, you can use ``USE_SNAP_FROM_STORE_OR_MC`` en
|
||||
variable ; setting it to ``store`` will download from the Snap Store (warning:
|
||||
no debug builds on the Snap Store, so whatever ``debug`` variants we have will
|
||||
be an ``opt`` build in fact), and setting to a TaskCluster index value will
|
||||
download from the index. Set it to ``latest`` if you want latest, or explore
|
||||
the TaskCluster index for others. Any ``try`` will be pulled from latest
|
||||
``nightly`` while others will be fetched from their respective branches.
|
||||
|
|
|
@ -20,9 +20,9 @@ from mozfile import NamedTemporaryFile, TemporaryDirectory
|
|||
from mozprofile.permissions import ServerLocations
|
||||
|
||||
dbFiles = [
|
||||
re.compile("^cert[0-9]+\.db$"),
|
||||
re.compile("^key[0-9]+\.db$"),
|
||||
re.compile("^secmod\.db$"),
|
||||
re.compile(r"^cert[0-9]+\.db$"),
|
||||
re.compile(r"^key[0-9]+\.db$"),
|
||||
re.compile(r"^secmod\.db$"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -77,7 +77,7 @@ def writeCertspecForServerLocations(fd):
|
|||
i for i in iter(locations) if i.scheme == "https" and "nocert" not in i.options
|
||||
]:
|
||||
customCertOption = False
|
||||
customCertRE = re.compile("^cert=(?:\w+)")
|
||||
customCertRE = re.compile(r"^cert=(?:\w+)")
|
||||
for _ in [i for i in loc.options if customCertRE.match(i)]:
|
||||
customCertOption = True
|
||||
break
|
||||
|
|
|
@ -132,8 +132,6 @@ module.exports = {
|
|||
"no-cond-assign": 2,
|
||||
// Allow using the console API.
|
||||
"no-console": 0,
|
||||
// Allow using constant expressions in conditions like while (true)
|
||||
"no-constant-condition": 0,
|
||||
// Allow use of the continue statement.
|
||||
"no-continue": 0,
|
||||
// Disallow control characters in regular expressions.
|
||||
|
|
|
@ -73,14 +73,6 @@ DevToolsServerConnection.prototype = {
|
|||
return this._prefix;
|
||||
},
|
||||
|
||||
/**
|
||||
* For a DevToolsServerConnection used in content processes,
|
||||
* returns the prefix of the connection it originates from, from the parent process.
|
||||
*/
|
||||
get parentPrefix() {
|
||||
this.prefix.replace(/child\d+\//, "");
|
||||
},
|
||||
|
||||
_transport: null,
|
||||
get transport() {
|
||||
return this._transport;
|
||||
|
|
|
@ -48,7 +48,7 @@ def filter_git_changes(github_path, commit_sha, diff_filter):
|
|||
# out the excluded directory paths (note the lack of trailing '$'
|
||||
# in the regex).
|
||||
regex_excludes = "|".join(
|
||||
["^(M|A|D|R\d\d\d)\t{}".format(i) for i in exclude_dir_list]
|
||||
["^(M|A|D|R\\d\\d\\d)\t{}".format(i) for i in exclude_dir_list]
|
||||
)
|
||||
files_not_excluded = [
|
||||
path for path in changed_files if not re.findall(regex_excludes, path)
|
||||
|
|
|
@ -52,7 +52,7 @@ def save_patch_stack(
|
|||
# remove the commit summary from the file name
|
||||
patches_to_rename = os.listdir(patch_directory)
|
||||
for file in patches_to_rename:
|
||||
shortened_name = re.sub("^(\d\d\d\d)-.*\.patch", "\\1.patch", file)
|
||||
shortened_name = re.sub(r"^(\d\d\d\d)-.*\.patch", "\\1.patch", file)
|
||||
os.rename(
|
||||
os.path.join(patch_directory, file),
|
||||
os.path.join(patch_directory, shortened_name),
|
||||
|
|
|
@ -175,6 +175,7 @@ add_task(async function testThenableJobAccessError() {
|
|||
sandbox.thenable = {
|
||||
get then() {
|
||||
accessed = true;
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1641,7 +1641,7 @@ let interfaceNamesInGlobalScope = [
|
|||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "onbeforeprint", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "onbeforetoggle", insecureContext: true, nightly: true },
|
||||
{ name: "onbeforetoggle", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "onbeforeunload", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -230,24 +230,24 @@ already_AddRefed<RenderPassEncoder> CommandEncoder::BeginRenderPass(
|
|||
return pass.forget();
|
||||
}
|
||||
|
||||
void CommandEncoder::EndComputePass(ffi::WGPUComputePass& aPass) {
|
||||
void CommandEncoder::EndComputePass(ffi::WGPURecordedComputePass& aPass) {
|
||||
if (!mBridge->IsOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipc::ByteBuf byteBuf;
|
||||
ffi::wgpu_compute_pass_finish(&aPass, ToFFI(&byteBuf));
|
||||
mBridge->SendCommandEncoderAction(mId, mParent->mId, std::move(byteBuf));
|
||||
mBridge->SendComputePass(mId, mParent->mId, std::move(byteBuf));
|
||||
}
|
||||
|
||||
void CommandEncoder::EndRenderPass(ffi::WGPURenderPass& aPass) {
|
||||
void CommandEncoder::EndRenderPass(ffi::WGPURecordedRenderPass& aPass) {
|
||||
if (!mBridge->IsOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipc::ByteBuf byteBuf;
|
||||
ffi::wgpu_render_pass_finish(&aPass, ToFFI(&byteBuf));
|
||||
mBridge->SendCommandEncoderAction(mId, mParent->mId, std::move(byteBuf));
|
||||
mBridge->SendRenderPass(mId, mParent->mId, std::move(byteBuf));
|
||||
}
|
||||
|
||||
already_AddRefed<CommandBuffer> CommandEncoder::Finish(
|
||||
|
|
|
@ -32,7 +32,7 @@ using GPUExtent3D = RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict;
|
|||
namespace webgpu {
|
||||
namespace ffi {
|
||||
struct WGPUComputePass;
|
||||
struct WGPURenderPass;
|
||||
struct WGPURecordedRenderPass;
|
||||
struct WGPUImageDataLayout;
|
||||
struct WGPUImageCopyTexture_TextureId;
|
||||
struct WGPUExtent3d;
|
||||
|
@ -72,8 +72,8 @@ class CommandEncoder final : public ObjectBase, public ChildOf<Device> {
|
|||
public:
|
||||
const auto& GetDevice() const { return mParent; };
|
||||
|
||||
void EndComputePass(ffi::WGPUComputePass& aPass);
|
||||
void EndRenderPass(ffi::WGPURenderPass& aPass);
|
||||
void EndComputePass(ffi::WGPURecordedComputePass& aPass);
|
||||
void EndRenderPass(ffi::WGPURecordedRenderPass& aPass);
|
||||
|
||||
void CopyBufferToBuffer(const Buffer& aSource, BufferAddress aSourceOffset,
|
||||
const Buffer& aDestination,
|
||||
|
|
|
@ -17,13 +17,13 @@ GPU_IMPL_CYCLE_COLLECTION(ComputePassEncoder, mParent, mUsedBindGroups,
|
|||
mUsedPipelines)
|
||||
GPU_IMPL_JS_WRAP(ComputePassEncoder)
|
||||
|
||||
void ffiWGPUComputePassDeleter::operator()(ffi::WGPUComputePass* raw) {
|
||||
void ffiWGPUComputePassDeleter::operator()(ffi::WGPURecordedComputePass* raw) {
|
||||
if (raw) {
|
||||
ffi::wgpu_compute_pass_destroy(raw);
|
||||
}
|
||||
}
|
||||
|
||||
ffi::WGPUComputePass* BeginComputePass(
|
||||
ffi::WGPURecordedComputePass* BeginComputePass(
|
||||
RawId aEncoderId, const dom::GPUComputePassDescriptor& aDesc) {
|
||||
MOZ_RELEASE_ASSERT(aEncoderId);
|
||||
ffi::WGPUComputePassDescriptor desc = {};
|
||||
|
@ -31,7 +31,7 @@ ffi::WGPUComputePass* BeginComputePass(
|
|||
webgpu::StringHelper label(aDesc.mLabel);
|
||||
desc.label = label.Get();
|
||||
|
||||
return ffi::wgpu_command_encoder_begin_compute_pass(aEncoderId, &desc);
|
||||
return ffi::wgpu_command_encoder_begin_compute_pass(&desc);
|
||||
}
|
||||
|
||||
ComputePassEncoder::ComputePassEncoder(
|
||||
|
@ -49,16 +49,16 @@ void ComputePassEncoder::SetBindGroup(
|
|||
const dom::Sequence<uint32_t>& aDynamicOffsets) {
|
||||
if (mValid) {
|
||||
mUsedBindGroups.AppendElement(&aBindGroup);
|
||||
ffi::wgpu_compute_pass_set_bind_group(mPass.get(), aSlot, aBindGroup.mId,
|
||||
aDynamicOffsets.Elements(),
|
||||
aDynamicOffsets.Length());
|
||||
ffi::wgpu_recorded_compute_pass_set_bind_group(
|
||||
mPass.get(), aSlot, aBindGroup.mId, aDynamicOffsets.Elements(),
|
||||
aDynamicOffsets.Length());
|
||||
}
|
||||
}
|
||||
|
||||
void ComputePassEncoder::SetPipeline(const ComputePipeline& aPipeline) {
|
||||
if (mValid) {
|
||||
mUsedPipelines.AppendElement(&aPipeline);
|
||||
ffi::wgpu_compute_pass_set_pipeline(mPass.get(), aPipeline.mId);
|
||||
ffi::wgpu_recorded_compute_pass_set_pipeline(mPass.get(), aPipeline.mId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ void ComputePassEncoder::DispatchWorkgroups(uint32_t workgroupCountX,
|
|||
uint32_t workgroupCountY,
|
||||
uint32_t workgroupCountZ) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_compute_pass_dispatch_workgroups(
|
||||
ffi::wgpu_recorded_compute_pass_dispatch_workgroups(
|
||||
mPass.get(), workgroupCountX, workgroupCountY, workgroupCountZ);
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ void ComputePassEncoder::DispatchWorkgroups(uint32_t workgroupCountX,
|
|||
void ComputePassEncoder::DispatchWorkgroupsIndirect(
|
||||
const Buffer& aIndirectBuffer, uint64_t aIndirectOffset) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_compute_pass_dispatch_workgroups_indirect(
|
||||
ffi::wgpu_recorded_compute_pass_dispatch_workgroups_indirect(
|
||||
mPass.get(), aIndirectBuffer.mId, aIndirectOffset);
|
||||
}
|
||||
}
|
||||
|
@ -82,18 +82,20 @@ void ComputePassEncoder::DispatchWorkgroupsIndirect(
|
|||
void ComputePassEncoder::PushDebugGroup(const nsAString& aString) {
|
||||
if (mValid) {
|
||||
const NS_ConvertUTF16toUTF8 utf8(aString);
|
||||
ffi::wgpu_compute_pass_push_debug_group(mPass.get(), utf8.get(), 0);
|
||||
ffi::wgpu_recorded_compute_pass_push_debug_group(mPass.get(), utf8.get(),
|
||||
0);
|
||||
}
|
||||
}
|
||||
void ComputePassEncoder::PopDebugGroup() {
|
||||
if (mValid) {
|
||||
ffi::wgpu_compute_pass_pop_debug_group(mPass.get());
|
||||
ffi::wgpu_recorded_compute_pass_pop_debug_group(mPass.get());
|
||||
}
|
||||
}
|
||||
void ComputePassEncoder::InsertDebugMarker(const nsAString& aString) {
|
||||
if (mValid) {
|
||||
const NS_ConvertUTF16toUTF8 utf8(aString);
|
||||
ffi::wgpu_compute_pass_insert_debug_marker(mPass.get(), utf8.get(), 0);
|
||||
ffi::wgpu_recorded_compute_pass_insert_debug_marker(mPass.get(), utf8.get(),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ struct GPUComputePassDescriptor;
|
|||
|
||||
namespace webgpu {
|
||||
namespace ffi {
|
||||
struct WGPUComputePass;
|
||||
struct WGPURecordedComputePass;
|
||||
} // namespace ffi
|
||||
|
||||
class BindGroup;
|
||||
|
@ -27,7 +27,7 @@ class CommandEncoder;
|
|||
class ComputePipeline;
|
||||
|
||||
struct ffiWGPUComputePassDeleter {
|
||||
void operator()(ffi::WGPUComputePass*);
|
||||
void operator()(ffi::WGPURecordedComputePass*);
|
||||
};
|
||||
|
||||
class ComputePassEncoder final : public ObjectBase,
|
||||
|
@ -43,7 +43,8 @@ class ComputePassEncoder final : public ObjectBase,
|
|||
virtual ~ComputePassEncoder();
|
||||
void Cleanup() {}
|
||||
|
||||
std::unique_ptr<ffi::WGPUComputePass, ffiWGPUComputePassDeleter> mPass;
|
||||
std::unique_ptr<ffi::WGPURecordedComputePass, ffiWGPUComputePassDeleter>
|
||||
mPass;
|
||||
// keep all the used objects alive while the pass is recorded
|
||||
nsTArray<RefPtr<const BindGroup>> mUsedBindGroups;
|
||||
nsTArray<RefPtr<const ComputePipeline>> mUsedPipelines;
|
||||
|
|
|
@ -18,7 +18,7 @@ GPU_IMPL_CYCLE_COLLECTION(RenderPassEncoder, mParent, mUsedBindGroups,
|
|||
mUsedRenderBundles)
|
||||
GPU_IMPL_JS_WRAP(RenderPassEncoder)
|
||||
|
||||
void ffiWGPURenderPassDeleter::operator()(ffi::WGPURenderPass* raw) {
|
||||
void ffiWGPURenderPassDeleter::operator()(ffi::WGPURecordedRenderPass* raw) {
|
||||
if (raw) {
|
||||
ffi::wgpu_render_pass_destroy(raw);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ static ffi::WGPUColor ConvertColor(
|
|||
return ffi::WGPUColor();
|
||||
}
|
||||
|
||||
ffi::WGPURenderPass* BeginRenderPass(
|
||||
ffi::WGPURecordedRenderPass* BeginRenderPass(
|
||||
CommandEncoder* const aParent, const dom::GPURenderPassDescriptor& aDesc) {
|
||||
ffi::WGPURenderPassDescriptor desc = {};
|
||||
|
||||
|
@ -155,7 +155,7 @@ ffi::WGPURenderPass* BeginRenderPass(
|
|||
}
|
||||
}
|
||||
|
||||
return ffi::wgpu_command_encoder_begin_render_pass(aParent->mId, &desc);
|
||||
return ffi::wgpu_command_encoder_begin_render_pass(&desc);
|
||||
}
|
||||
|
||||
RenderPassEncoder::RenderPassEncoder(CommandEncoder* const aParent,
|
||||
|
@ -186,16 +186,16 @@ void RenderPassEncoder::SetBindGroup(
|
|||
const dom::Sequence<uint32_t>& aDynamicOffsets) {
|
||||
if (mValid) {
|
||||
mUsedBindGroups.AppendElement(&aBindGroup);
|
||||
ffi::wgpu_render_pass_set_bind_group(mPass.get(), aSlot, aBindGroup.mId,
|
||||
aDynamicOffsets.Elements(),
|
||||
aDynamicOffsets.Length());
|
||||
ffi::wgpu_recorded_render_pass_set_bind_group(
|
||||
mPass.get(), aSlot, aBindGroup.mId, aDynamicOffsets.Elements(),
|
||||
aDynamicOffsets.Length());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPassEncoder::SetPipeline(const RenderPipeline& aPipeline) {
|
||||
if (mValid) {
|
||||
mUsedPipelines.AppendElement(&aPipeline);
|
||||
ffi::wgpu_render_pass_set_pipeline(mPass.get(), aPipeline.mId);
|
||||
ffi::wgpu_recorded_render_pass_set_pipeline(mPass.get(), aPipeline.mId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,8 +207,8 @@ void RenderPassEncoder::SetIndexBuffer(const Buffer& aBuffer,
|
|||
const auto iformat = aIndexFormat == dom::GPUIndexFormat::Uint32
|
||||
? ffi::WGPUIndexFormat_Uint32
|
||||
: ffi::WGPUIndexFormat_Uint16;
|
||||
ffi::wgpu_render_pass_set_index_buffer(mPass.get(), aBuffer.mId, iformat,
|
||||
aOffset, aSize);
|
||||
ffi::wgpu_recorded_render_pass_set_index_buffer(mPass.get(), aBuffer.mId,
|
||||
iformat, aOffset, aSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,16 +216,17 @@ void RenderPassEncoder::SetVertexBuffer(uint32_t aSlot, const Buffer& aBuffer,
|
|||
uint64_t aOffset, uint64_t aSize) {
|
||||
if (mValid) {
|
||||
mUsedBuffers.AppendElement(&aBuffer);
|
||||
ffi::wgpu_render_pass_set_vertex_buffer(mPass.get(), aSlot, aBuffer.mId,
|
||||
aOffset, aSize);
|
||||
ffi::wgpu_recorded_render_pass_set_vertex_buffer(
|
||||
mPass.get(), aSlot, aBuffer.mId, aOffset, aSize);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPassEncoder::Draw(uint32_t aVertexCount, uint32_t aInstanceCount,
|
||||
uint32_t aFirstVertex, uint32_t aFirstInstance) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_draw(mPass.get(), aVertexCount, aInstanceCount,
|
||||
aFirstVertex, aFirstInstance);
|
||||
ffi::wgpu_recorded_render_pass_draw(mPass.get(), aVertexCount,
|
||||
aInstanceCount, aFirstVertex,
|
||||
aFirstInstance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,24 +235,24 @@ void RenderPassEncoder::DrawIndexed(uint32_t aIndexCount,
|
|||
uint32_t aFirstIndex, int32_t aBaseVertex,
|
||||
uint32_t aFirstInstance) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_draw_indexed(mPass.get(), aIndexCount, aInstanceCount,
|
||||
aFirstIndex, aBaseVertex,
|
||||
aFirstInstance);
|
||||
ffi::wgpu_recorded_render_pass_draw_indexed(mPass.get(), aIndexCount,
|
||||
aInstanceCount, aFirstIndex,
|
||||
aBaseVertex, aFirstInstance);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPassEncoder::DrawIndirect(const Buffer& aIndirectBuffer,
|
||||
uint64_t aIndirectOffset) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_draw_indirect(mPass.get(), aIndirectBuffer.mId,
|
||||
aIndirectOffset);
|
||||
ffi::wgpu_recorded_render_pass_draw_indirect(
|
||||
mPass.get(), aIndirectBuffer.mId, aIndirectOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPassEncoder::DrawIndexedIndirect(const Buffer& aIndirectBuffer,
|
||||
uint64_t aIndirectOffset) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_draw_indexed_indirect(
|
||||
ffi::wgpu_recorded_render_pass_draw_indexed_indirect(
|
||||
mPass.get(), aIndirectBuffer.mId, aIndirectOffset);
|
||||
}
|
||||
}
|
||||
|
@ -259,15 +260,16 @@ void RenderPassEncoder::DrawIndexedIndirect(const Buffer& aIndirectBuffer,
|
|||
void RenderPassEncoder::SetViewport(float x, float y, float width, float height,
|
||||
float minDepth, float maxDepth) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_set_viewport(mPass.get(), x, y, width, height,
|
||||
minDepth, maxDepth);
|
||||
ffi::wgpu_recorded_render_pass_set_viewport(mPass.get(), x, y, width,
|
||||
height, minDepth, maxDepth);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPassEncoder::SetScissorRect(uint32_t x, uint32_t y, uint32_t width,
|
||||
uint32_t height) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_set_scissor_rect(mPass.get(), x, y, width, height);
|
||||
ffi::wgpu_recorded_render_pass_set_scissor_rect(mPass.get(), x, y, width,
|
||||
height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,13 +277,14 @@ void RenderPassEncoder::SetBlendConstant(
|
|||
const dom::DoubleSequenceOrGPUColorDict& color) {
|
||||
if (mValid) {
|
||||
ffi::WGPUColor aColor = ConvertColor(color);
|
||||
ffi::wgpu_render_pass_set_blend_constant(mPass.get(), &aColor);
|
||||
ffi::wgpu_recorded_render_pass_set_blend_constant(mPass.get(), &aColor);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPassEncoder::SetStencilReference(uint32_t reference) {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_set_stencil_reference(mPass.get(), reference);
|
||||
ffi::wgpu_recorded_render_pass_set_stencil_reference(mPass.get(),
|
||||
reference);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,26 +296,27 @@ void RenderPassEncoder::ExecuteBundles(
|
|||
mUsedRenderBundles.AppendElement(bundle);
|
||||
renderBundles.AppendElement(bundle->mId);
|
||||
}
|
||||
ffi::wgpu_render_pass_execute_bundles(mPass.get(), renderBundles.Elements(),
|
||||
renderBundles.Length());
|
||||
ffi::wgpu_recorded_render_pass_execute_bundles(
|
||||
mPass.get(), renderBundles.Elements(), renderBundles.Length());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPassEncoder::PushDebugGroup(const nsAString& aString) {
|
||||
if (mValid) {
|
||||
const NS_ConvertUTF16toUTF8 utf8(aString);
|
||||
ffi::wgpu_render_pass_push_debug_group(mPass.get(), utf8.get(), 0);
|
||||
ffi::wgpu_recorded_render_pass_push_debug_group(mPass.get(), utf8.get(), 0);
|
||||
}
|
||||
}
|
||||
void RenderPassEncoder::PopDebugGroup() {
|
||||
if (mValid) {
|
||||
ffi::wgpu_render_pass_pop_debug_group(mPass.get());
|
||||
ffi::wgpu_recorded_render_pass_pop_debug_group(mPass.get());
|
||||
}
|
||||
}
|
||||
void RenderPassEncoder::InsertDebugMarker(const nsAString& aString) {
|
||||
if (mValid) {
|
||||
const NS_ConvertUTF16toUTF8 utf8(aString);
|
||||
ffi::wgpu_render_pass_insert_debug_marker(mPass.get(), utf8.get(), 0);
|
||||
ffi::wgpu_recorded_render_pass_insert_debug_marker(mPass.get(), utf8.get(),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ class AutoSequence;
|
|||
} // namespace dom
|
||||
namespace webgpu {
|
||||
namespace ffi {
|
||||
struct WGPURenderPass;
|
||||
struct WGPURecordedRenderPass;
|
||||
} // namespace ffi
|
||||
|
||||
class BindGroup;
|
||||
|
@ -35,7 +35,7 @@ class RenderPipeline;
|
|||
class TextureView;
|
||||
|
||||
struct ffiWGPURenderPassDeleter {
|
||||
void operator()(ffi::WGPURenderPass*);
|
||||
void operator()(ffi::WGPURecordedRenderPass*);
|
||||
};
|
||||
|
||||
class RenderPassEncoder final : public ObjectBase,
|
||||
|
@ -51,7 +51,7 @@ class RenderPassEncoder final : public ObjectBase,
|
|||
virtual ~RenderPassEncoder();
|
||||
void Cleanup() {}
|
||||
|
||||
std::unique_ptr<ffi::WGPURenderPass, ffiWGPURenderPassDeleter> mPass;
|
||||
std::unique_ptr<ffi::WGPURecordedRenderPass, ffiWGPURenderPassDeleter> mPass;
|
||||
// keep all the used objects alive while the pass is recorded
|
||||
nsTArray<RefPtr<const BindGroup>> mUsedBindGroups;
|
||||
nsTArray<RefPtr<const Buffer>> mUsedBuffers;
|
||||
|
|
|
@ -44,6 +44,8 @@ parent:
|
|||
async DeviceActionWithAck(RawId selfId, ByteBuf buf) returns (bool dummy);
|
||||
async TextureAction(RawId selfId, RawId aDeviceId, ByteBuf buf);
|
||||
async CommandEncoderAction(RawId selfId, RawId aDeviceId, ByteBuf buf);
|
||||
async RenderPass(RawId selfId, RawId aDeviceId, ByteBuf buf);
|
||||
async ComputePass(RawId selfId, RawId aDeviceId, ByteBuf buf);
|
||||
async BumpImplicitBindGroupLayout(RawId pipelineId, bool isCompute, uint32_t index, RawId assignId);
|
||||
|
||||
async DeviceCreateBuffer(RawId deviceId, RawId bufferId, GPUBufferDescriptor desc, UnsafeSharedMemoryHandle shm);
|
||||
|
|
|
@ -1359,6 +1359,24 @@ ipc::IPCResult WebGPUParent::RecvCommandEncoderAction(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
ipc::IPCResult WebGPUParent::RecvRenderPass(RawId aEncoderId, RawId aDeviceId,
|
||||
const ipc::ByteBuf& aByteBuf) {
|
||||
ErrorBuffer error;
|
||||
ffi::wgpu_server_render_pass(mContext.get(), aEncoderId, ToFFI(&aByteBuf),
|
||||
error.ToFFI());
|
||||
ForwardError(aDeviceId, error);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
ipc::IPCResult WebGPUParent::RecvComputePass(RawId aEncoderId, RawId aDeviceId,
|
||||
const ipc::ByteBuf& aByteBuf) {
|
||||
ErrorBuffer error;
|
||||
ffi::wgpu_server_compute_pass(mContext.get(), aEncoderId, ToFFI(&aByteBuf),
|
||||
error.ToFFI());
|
||||
ForwardError(aDeviceId, error);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
ipc::IPCResult WebGPUParent::RecvBumpImplicitBindGroupLayout(RawId aPipelineId,
|
||||
bool aIsCompute,
|
||||
uint32_t aIndex,
|
||||
|
|
|
@ -118,6 +118,10 @@ class WebGPUParent final : public PWebGPUParent, public SupportsWeakPtr {
|
|||
const ipc::ByteBuf& aByteBuf);
|
||||
ipc::IPCResult RecvCommandEncoderAction(RawId aEncoderId, RawId aDeviceId,
|
||||
const ipc::ByteBuf& aByteBuf);
|
||||
ipc::IPCResult RecvRenderPass(RawId aEncoderId, RawId aDeviceId,
|
||||
const ipc::ByteBuf& aByteBuf);
|
||||
ipc::IPCResult RecvComputePass(RawId aEncoderId, RawId aDeviceId,
|
||||
const ipc::ByteBuf& aByteBuf);
|
||||
ipc::IPCResult RecvBumpImplicitBindGroupLayout(RawId aPipelineId,
|
||||
bool aIsCompute,
|
||||
uint32_t aIndex,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
assert __name__ == "__main__"
|
||||
|
||||
"""
|
||||
r"""
|
||||
To update ANGLE in Gecko, use Windows with git-bash, and setup depot_tools, python2, and
|
||||
python3. Because depot_tools expects `python` to be `python2` (shame!), python2 must come
|
||||
before python3 in your path.
|
||||
|
|
|
@ -893,6 +893,12 @@ struct ScrollMetadata {
|
|||
mScrollUpdates.AppendElements(std::move(aUpdates));
|
||||
}
|
||||
|
||||
void PrependUpdates(const nsTArray<ScrollPositionUpdate>& aUpdates) {
|
||||
MOZ_ASSERT(!aUpdates.IsEmpty());
|
||||
|
||||
mScrollUpdates.InsertElementsAt(0, aUpdates);
|
||||
}
|
||||
|
||||
private:
|
||||
FrameMetrics mMetrics;
|
||||
|
||||
|
|
|
@ -158,6 +158,9 @@ struct APZCTreeManager::TreeBuildingState {
|
|||
// cumulative EventRegionsOverride flags from the reflayers, and is used to
|
||||
// apply them to descendant layers.
|
||||
std::stack<EventRegionsOverride> mOverrideFlags;
|
||||
|
||||
// Wether the APZC correspoinding to the originating LayersId was updated.
|
||||
bool mOriginatingLayersIdUpdated = false;
|
||||
};
|
||||
|
||||
class APZCTreeManager::CheckerboardFlushObserver : public nsIObserver {
|
||||
|
@ -420,9 +423,11 @@ void APZCTreeManager::SetBrowserGestureResponse(
|
|||
mInputQueue->SetBrowserGestureResponse(aInputBlockId, aResponse);
|
||||
}
|
||||
|
||||
void APZCTreeManager::UpdateHitTestingTree(
|
||||
const WebRenderScrollDataWrapper& aRoot, bool aIsFirstPaint,
|
||||
LayersId aOriginatingLayersId, uint32_t aPaintSequenceNumber) {
|
||||
APZCTreeManager::OriginatingLayersIdUpdated
|
||||
APZCTreeManager::UpdateHitTestingTree(const WebRenderScrollDataWrapper& aRoot,
|
||||
bool aIsFirstPaint,
|
||||
LayersId aOriginatingLayersId,
|
||||
uint32_t aPaintSequenceNumber) {
|
||||
AssertOnUpdaterThread();
|
||||
|
||||
RecursiveMutexAutoLock lock(mTreeLock);
|
||||
|
@ -731,6 +736,8 @@ void APZCTreeManager::UpdateHitTestingTree(
|
|||
mRootNode->Dump(" ");
|
||||
}
|
||||
SendSubtreeTransformsToChromeMainThread(nullptr);
|
||||
|
||||
return OriginatingLayersIdUpdated{state.mOriginatingLayersIdUpdated};
|
||||
}
|
||||
|
||||
void APZCTreeManager::UpdateFocusState(LayersId aRootLayerTreeId,
|
||||
|
@ -1232,6 +1239,10 @@ HitTestingTreeNode* APZCTreeManager::PrepareNodeForLayer(
|
|||
"Found APZC %p for layer %p with identifiers %" PRIx64 " %" PRId64 "\n",
|
||||
apzc.get(), aLayer.GetLayer(), uint64_t(guid.mLayersId), guid.mScrollId);
|
||||
|
||||
if (aLayersId == aState.mOriginatingLayersId) {
|
||||
aState.mOriginatingLayersIdUpdated = true;
|
||||
}
|
||||
|
||||
// If we haven't encountered a layer already with the same metrics, then we
|
||||
// need to do the full reuse-or-make-an-APZC algorithm, which is contained
|
||||
// inside the block below.
|
||||
|
|
|
@ -190,10 +190,13 @@ class APZCTreeManager : public IAPZCTreeManager, public APZInputBridge {
|
|||
* this layer update. Note that every child
|
||||
* process' layer subtree has its own sequence
|
||||
* numbers.
|
||||
* @return OriginatingLayersIdUpdated whether the given
|
||||
* |aOriginatingLayersId|'s data was processed.
|
||||
*/
|
||||
void UpdateHitTestingTree(const WebRenderScrollDataWrapper& aRoot,
|
||||
bool aIsFirstPaint, LayersId aOriginatingLayersId,
|
||||
uint32_t aPaintSequenceNumber);
|
||||
enum class OriginatingLayersIdUpdated : bool { No, Yes };
|
||||
OriginatingLayersIdUpdated UpdateHitTestingTree(
|
||||
const WebRenderScrollDataWrapper& aRoot, bool aIsFirstPaint,
|
||||
LayersId aOriginatingLayersId, uint32_t aPaintSequenceNumber);
|
||||
|
||||
/**
|
||||
* Called when webrender is enabled, from the sampler thread. This function
|
||||
|
|
|
@ -191,14 +191,38 @@ void APZUpdater::UpdateScrollDataAndTreeState(
|
|||
auto isFirstPaint = aScrollData.IsFirstPaint();
|
||||
auto paintSequenceNumber = aScrollData.GetPaintSequenceNumber();
|
||||
|
||||
auto previous = self->mScrollData.find(aOriginatingLayersId);
|
||||
// If there's the previous scroll data which hasn't yet been
|
||||
// processed, we need to merge the previous scroll position updates
|
||||
// into the latest one.
|
||||
if (previous != self->mScrollData.end()) {
|
||||
WebRenderScrollData& previousData = previous->second;
|
||||
if (previousData.GetWasUpdateSkipped()) {
|
||||
MOZ_ASSERT(previousData.IsFirstPaint());
|
||||
aScrollData.PrependUpdates(previousData);
|
||||
}
|
||||
}
|
||||
|
||||
self->mScrollData[aOriginatingLayersId] = std::move(aScrollData);
|
||||
auto root = self->mScrollData.find(aRootLayerTreeId);
|
||||
if (root == self->mScrollData.end()) {
|
||||
return;
|
||||
}
|
||||
self->mApz->UpdateHitTestingTree(
|
||||
WebRenderScrollDataWrapper(*self, &(root->second)),
|
||||
isFirstPaint, aOriginatingLayersId, paintSequenceNumber);
|
||||
if ((self->mApz->UpdateHitTestingTree(
|
||||
WebRenderScrollDataWrapper(*self, &(root->second)),
|
||||
isFirstPaint, aOriginatingLayersId, paintSequenceNumber) ==
|
||||
APZCTreeManager::OriginatingLayersIdUpdated::No) &&
|
||||
isFirstPaint) {
|
||||
// If the given |aOriginatingLayersId| data wasn't used for
|
||||
// updating, it's likly that the parent process hasn't yet
|
||||
// received the LayersId as "ReferentId", thus we need to process
|
||||
// it in a subsequent update where we got the "ReferentId".
|
||||
//
|
||||
// NOTE: We restrict the above previous scroll data prepending to
|
||||
// the first paint case, otherwise the cumulative scroll data may
|
||||
// be exploded if we have never received the "ReferenceId".
|
||||
self->mScrollData[aOriginatingLayersId].SetWasUpdateSkipped();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -370,6 +370,22 @@ void WebRenderScrollData::ApplyUpdates(ScrollUpdatesMap&& aUpdates,
|
|||
mPaintSequenceNumber = aPaintSequenceNumber;
|
||||
}
|
||||
|
||||
void WebRenderScrollData::PrependUpdates(
|
||||
const WebRenderScrollData& aPreviousData) {
|
||||
for (auto previousMetadata : aPreviousData.mScrollMetadatas) {
|
||||
const nsTArray<ScrollPositionUpdate>& previousUpdates =
|
||||
previousMetadata.GetScrollUpdates();
|
||||
if (previousUpdates.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Maybe<size_t> index =
|
||||
HasMetadataFor(previousMetadata.GetMetrics().GetScrollId())) {
|
||||
mScrollMetadatas[*index].PrependUpdates(previousUpdates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WebRenderScrollData::DumpSubtree(std::ostream& aOut, size_t aIndex,
|
||||
const std::string& aIndent) const {
|
||||
aOut << aIndent;
|
||||
|
|
|
@ -276,6 +276,13 @@ class WebRenderScrollData {
|
|||
|
||||
void ApplyUpdates(ScrollUpdatesMap&& aUpdates, uint32_t aPaintSequenceNumber);
|
||||
|
||||
// Prepend the scroll position updates in the previous data to this data so
|
||||
// that we can handle all scroll position updates in the proper order.
|
||||
void PrependUpdates(const WebRenderScrollData& aPreviousData);
|
||||
|
||||
void SetWasUpdateSkipped() { mWasUpdateSkipped = true; }
|
||||
bool GetWasUpdateSkipped() const { return mWasUpdateSkipped; }
|
||||
|
||||
friend struct IPC::ParamTraits<WebRenderScrollData>;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& aOut,
|
||||
|
@ -328,6 +335,12 @@ class WebRenderScrollData {
|
|||
|
||||
bool mIsFirstPaint;
|
||||
uint32_t mPaintSequenceNumber;
|
||||
|
||||
// Wether this data was skipped to updated because the parent process hasn't
|
||||
// yet gotten the referent LayersId for this data.
|
||||
//
|
||||
// Note this variable is not copied over IPC.
|
||||
bool mWasUpdateSkipped = false;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -9,7 +9,7 @@ import sys
|
|||
f = open(sys.argv[1] if len(sys.argv) > 1 else "StandardizedVariants.txt")
|
||||
|
||||
line = f.readline()
|
||||
m = re.compile("^# (StandardizedVariants(-\d+(\.\d+)*)?\.txt)").search(line)
|
||||
m = re.compile(r"^# (StandardizedVariants(-\d+(\.\d+)*)?\.txt)").search(line)
|
||||
fileversion = m.group(1)
|
||||
vsdict = {}
|
||||
r = re.compile(
|
||||
|
|
|
@ -68,3 +68,4 @@ parking_lot = "0.12"
|
|||
serde = "1"
|
||||
nsstring = { path = "../../xpcom/rust/nsstring" }
|
||||
static_prefs = { path = "../../modules/libpref/init/static_prefs" }
|
||||
arrayvec = "0.7"
|
||||
|
|
|
@ -770,9 +770,8 @@ pub struct ComputePassTimestampWrites<'a> {
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_command_encoder_begin_compute_pass(
|
||||
encoder_id: id::CommandEncoderId,
|
||||
desc: &ComputePassDescriptor,
|
||||
) -> *mut wgc::command::ComputePass {
|
||||
) -> *mut crate::command::RecordedComputePass {
|
||||
let &ComputePassDescriptor {
|
||||
label,
|
||||
timestamp_writes,
|
||||
|
@ -796,8 +795,7 @@ pub unsafe extern "C" fn wgpu_command_encoder_begin_compute_pass(
|
|||
});
|
||||
let timestamp_writes = timestamp_writes.as_ref();
|
||||
|
||||
let pass = wgc::command::ComputePass::new(
|
||||
encoder_id,
|
||||
let pass = crate::command::RecordedComputePass::new(
|
||||
&wgc::command::ComputePassDescriptor {
|
||||
label,
|
||||
timestamp_writes,
|
||||
|
@ -808,15 +806,15 @@ pub unsafe extern "C" fn wgpu_command_encoder_begin_compute_pass(
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_compute_pass_finish(
|
||||
pass: *mut wgc::command::ComputePass,
|
||||
pass: *mut crate::command::RecordedComputePass,
|
||||
output: &mut ByteBuf,
|
||||
) {
|
||||
let command = Box::from_raw(pass).into_command();
|
||||
let command = Box::from_raw(pass);
|
||||
*output = make_byte_buf(&command);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_compute_pass_destroy(pass: *mut wgc::command::ComputePass) {
|
||||
pub unsafe extern "C" fn wgpu_compute_pass_destroy(pass: *mut crate::command::RecordedComputePass) {
|
||||
let _ = Box::from_raw(pass);
|
||||
}
|
||||
|
||||
|
@ -839,9 +837,8 @@ pub struct RenderPassTimestampWrites<'a> {
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_command_encoder_begin_render_pass(
|
||||
encoder_id: id::CommandEncoderId,
|
||||
desc: &RenderPassDescriptor,
|
||||
) -> *mut wgc::command::RenderPass {
|
||||
) -> *mut crate::command::RecordedRenderPass {
|
||||
let &RenderPassDescriptor {
|
||||
label,
|
||||
color_attachments,
|
||||
|
@ -874,8 +871,7 @@ pub unsafe extern "C" fn wgpu_command_encoder_begin_render_pass(
|
|||
.iter()
|
||||
.map(|format| Some(format.clone()))
|
||||
.collect();
|
||||
let pass = wgc::command::RenderPass::new(
|
||||
encoder_id,
|
||||
let pass = crate::command::RecordedRenderPass::new(
|
||||
&wgc::command::RenderPassDescriptor {
|
||||
label,
|
||||
color_attachments: Cow::Owned(color_attachments),
|
||||
|
@ -889,15 +885,15 @@ pub unsafe extern "C" fn wgpu_command_encoder_begin_render_pass(
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_render_pass_finish(
|
||||
pass: *mut wgc::command::RenderPass,
|
||||
pass: *mut crate::command::RecordedRenderPass,
|
||||
output: &mut ByteBuf,
|
||||
) {
|
||||
let command = Box::from_raw(pass).into_command();
|
||||
let command = Box::from_raw(pass);
|
||||
*output = make_byte_buf(&command);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_render_pass_destroy(pass: *mut wgc::command::RenderPass) {
|
||||
pub unsafe extern "C" fn wgpu_render_pass_destroy(pass: *mut crate::command::RecordedRenderPass) {
|
||||
let _ = Box::from_raw(pass);
|
||||
}
|
||||
|
||||
|
|
1062
gfx/wgpu_bindings/src/command.rs
Normal file
1062
gfx/wgpu_bindings/src/command.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -10,6 +10,7 @@ pub use wgc::command::{compute_ffi::*, render_ffi::*};
|
|||
pub mod client;
|
||||
pub mod error;
|
||||
pub mod server;
|
||||
pub mod command;
|
||||
|
||||
pub use wgc::device::trace::Command as CommandEncoderAction;
|
||||
|
||||
|
|
|
@ -410,7 +410,9 @@ pub extern "C" fn wgpu_server_device_create_shader_module(
|
|||
if let Some(err) = error {
|
||||
out_message.set_error(&err, &source_str[..]);
|
||||
let err_type = match &err {
|
||||
CreateShaderModuleError::Device(DeviceError::OutOfMemory) => ErrorBufferType::OutOfMemory,
|
||||
CreateShaderModuleError::Device(DeviceError::OutOfMemory) => {
|
||||
ErrorBufferType::OutOfMemory
|
||||
}
|
||||
CreateShaderModuleError::Device(DeviceError::Lost) => ErrorBufferType::DeviceLost,
|
||||
_ => ErrorBufferType::Validation,
|
||||
};
|
||||
|
@ -580,9 +582,10 @@ pub extern "C" fn wgpu_server_get_device_fence_handle(
|
|||
if device_id.backend() == wgt::Backend::Dx12 {
|
||||
let mut handle = ptr::null_mut();
|
||||
let dx12_device = unsafe {
|
||||
global.device_as_hal::<wgc::api::Dx12, _, Option<d3d12::Device>>(device_id, |hal_device| {
|
||||
hal_device.map(|device| device.raw_device().clone())
|
||||
})
|
||||
global.device_as_hal::<wgc::api::Dx12, _, Option<d3d12::Device>>(
|
||||
device_id,
|
||||
|hal_device| hal_device.map(|device| device.raw_device().clone()),
|
||||
)
|
||||
};
|
||||
let dx12_device = match dx12_device {
|
||||
Some(device) => device,
|
||||
|
@ -592,9 +595,10 @@ pub extern "C" fn wgpu_server_get_device_fence_handle(
|
|||
};
|
||||
|
||||
let dx12_fence = unsafe {
|
||||
global.device_fence_as_hal::<wgc::api::Dx12, _, Option<d3d12::Fence>>(device_id, |hal_fence| {
|
||||
hal_fence.map(|fence| fence.raw_fence().clone())
|
||||
})
|
||||
global.device_fence_as_hal::<wgc::api::Dx12, _, Option<d3d12::Fence>>(
|
||||
device_id,
|
||||
|hal_fence| hal_fence.map(|fence| fence.raw_fence().clone()),
|
||||
)
|
||||
};
|
||||
let dx12_fence = match dx12_fence {
|
||||
Some(fence) => fence,
|
||||
|
@ -1053,6 +1057,32 @@ pub unsafe extern "C" fn wgpu_server_command_encoder_action(
|
|||
gfx_select!(self_id => global.command_encoder_action(self_id, action, error_buf));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_server_render_pass(
|
||||
global: &Global,
|
||||
encoder_id: id::CommandEncoderId,
|
||||
byte_buf: &ByteBuf,
|
||||
error_buf: ErrorBuffer,
|
||||
) {
|
||||
let pass = bincode::deserialize(byte_buf.as_slice()).unwrap();
|
||||
let action = crate::command::replay_render_pass(encoder_id, &pass).into_command();
|
||||
|
||||
gfx_select!(encoder_id => global.command_encoder_action(encoder_id, action, error_buf));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_server_compute_pass(
|
||||
global: &Global,
|
||||
encoder_id: id::CommandEncoderId,
|
||||
byte_buf: &ByteBuf,
|
||||
error_buf: ErrorBuffer,
|
||||
) {
|
||||
let pass = bincode::deserialize(byte_buf.as_slice()).unwrap();
|
||||
let action = crate::command::replay_compute_pass(encoder_id, &pass).into_command();
|
||||
|
||||
gfx_select!(encoder_id => global.command_encoder_action(encoder_id, action, error_buf));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_server_device_create_encoder(
|
||||
global: &Global,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
uniform HIGHP_SAMPLER_FLOAT sampler2D sGpuBufferF;
|
||||
uniform HIGHP_SAMPLER_FLOAT sampler2D sGpuBufferI;
|
||||
uniform HIGHP_SAMPLER_FLOAT isampler2D sGpuBufferI;
|
||||
|
||||
ivec2 get_gpu_buffer_uv(HIGHP_FS_ADDRESS int address) {
|
||||
return ivec2(uint(address) % WR_MAX_VERTEX_TEXTURE_WIDTH,
|
||||
|
@ -41,3 +41,8 @@ vec4[4] fetch_from_gpu_buffer_4f(HIGHP_FS_ADDRESS int address) {
|
|||
TEXEL_FETCH(sGpuBufferF, uv, 0, ivec2(3, 0))
|
||||
);
|
||||
}
|
||||
|
||||
ivec4 fetch_from_gpu_buffer_1i(HIGHP_FS_ADDRESS int address) {
|
||||
ivec2 uv = get_gpu_buffer_uv(address);
|
||||
return texelFetch(sGpuBufferI, uv, 0);
|
||||
}
|
||||
|
|
|
@ -81,37 +81,51 @@ QuadPrimitive fetch_primitive(int index) {
|
|||
return prim;
|
||||
}
|
||||
|
||||
struct QuadHeader {
|
||||
int transform_id;
|
||||
int z_id;
|
||||
};
|
||||
|
||||
QuadHeader fetch_header(int address) {
|
||||
ivec4 header = fetch_from_gpu_buffer_1i(address);
|
||||
|
||||
QuadHeader qh = QuadHeader(
|
||||
header.x,
|
||||
header.y
|
||||
);
|
||||
|
||||
return qh;
|
||||
}
|
||||
|
||||
struct QuadInstance {
|
||||
// x
|
||||
int prim_address;
|
||||
int prim_address_i;
|
||||
|
||||
// y
|
||||
int quad_flags;
|
||||
int edge_flags;
|
||||
int picture_task_address;
|
||||
int prim_address_f;
|
||||
|
||||
// z
|
||||
int quad_flags;
|
||||
int edge_flags;
|
||||
int part_index;
|
||||
int z_id;
|
||||
int segment_index;
|
||||
|
||||
// w
|
||||
int segment_index;
|
||||
int transform_id;
|
||||
int picture_task_address;
|
||||
};
|
||||
|
||||
QuadInstance decode_instance() {
|
||||
QuadInstance qi = QuadInstance(
|
||||
aData.x,
|
||||
|
||||
(aData.y >> 24) & 0xff,
|
||||
(aData.y >> 16) & 0xff,
|
||||
aData.y & 0xffff,
|
||||
aData.y,
|
||||
|
||||
(aData.z >> 24) & 0xff,
|
||||
aData.z & 0xffffff,
|
||||
(aData.z >> 16) & 0xff,
|
||||
(aData.z >> 8) & 0xff,
|
||||
(aData.z >> 0) & 0xff,
|
||||
|
||||
(aData.w >> 24) & 0xff,
|
||||
aData.w & 0xffffff
|
||||
aData.w
|
||||
);
|
||||
|
||||
return qi;
|
||||
|
@ -165,17 +179,18 @@ float edge_aa_offset(int edge, int flags) {
|
|||
PrimitiveInfo ps_quad_main(void) {
|
||||
QuadInstance qi = decode_instance();
|
||||
|
||||
Transform transform = fetch_transform(qi.transform_id);
|
||||
QuadHeader qh = fetch_header(qi.prim_address_i);
|
||||
Transform transform = fetch_transform(qh.transform_id);
|
||||
PictureTask task = fetch_picture_task(qi.picture_task_address);
|
||||
QuadPrimitive prim = fetch_primitive(qi.prim_address);
|
||||
float z = float(qi.z_id);
|
||||
QuadPrimitive prim = fetch_primitive(qi.prim_address_f);
|
||||
float z = float(qh.z_id);
|
||||
|
||||
QuadSegment seg;
|
||||
if (qi.segment_index == INVALID_SEGMENT_INDEX) {
|
||||
seg.rect = prim.bounds;
|
||||
seg.uv_rect = vec4(0.0);
|
||||
} else {
|
||||
seg = fetch_segment(qi.prim_address, qi.segment_index);
|
||||
seg = fetch_segment(qi.prim_address_f, qi.segment_index);
|
||||
}
|
||||
|
||||
// The local space rect that we will draw, which is effectively:
|
||||
|
|
|
@ -26,8 +26,8 @@ use crate::prim_store::{VECS_PER_SEGMENT, PrimitiveInstanceIndex};
|
|||
use crate::render_target::RenderTargetContext;
|
||||
use crate::render_task_graph::{RenderTaskId, RenderTaskGraph};
|
||||
use crate::render_task::{RenderTaskAddress, RenderTaskKind, SubPass};
|
||||
use crate::renderer::{BlendMode, ShaderColorMode};
|
||||
use crate::renderer::{MAX_VERTEX_TEXTURE_WIDTH, GpuBufferBuilderF, GpuBufferAddress};
|
||||
use crate::renderer::{BlendMode, GpuBufferBuilder, ShaderColorMode};
|
||||
use crate::renderer::{MAX_VERTEX_TEXTURE_WIDTH, GpuBufferAddress};
|
||||
use crate::resource_cache::{GlyphFetchResult, ImageProperties};
|
||||
use crate::space::SpaceMapper;
|
||||
use crate::visibility::{PrimitiveVisibilityFlags, VisibilityState};
|
||||
|
@ -803,7 +803,7 @@ impl BatchBuilder {
|
|||
&mut self,
|
||||
prim_instance_index: PrimitiveInstanceIndex,
|
||||
transform_id: TransformPaletteId,
|
||||
gpu_buffer_address: GpuBufferAddress,
|
||||
prim_address_f: GpuBufferAddress,
|
||||
quad_flags: QuadFlags,
|
||||
edge_flags: EdgeAaSegmentMask,
|
||||
segment_index: u8,
|
||||
|
@ -811,6 +811,7 @@ impl BatchBuilder {
|
|||
z_generator: &mut ZBufferIdGenerator,
|
||||
prim_instances: &[PrimitiveInstance],
|
||||
render_tasks: &RenderTaskGraph,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
) {
|
||||
let prim_instance = &prim_instances[prim_instance_index.0 as usize];
|
||||
let prim_info = &prim_instance.vis;
|
||||
|
@ -820,13 +821,14 @@ impl BatchBuilder {
|
|||
add_quad_to_batch(
|
||||
self.batcher.render_task_address,
|
||||
transform_id,
|
||||
gpu_buffer_address,
|
||||
prim_address_f,
|
||||
quad_flags,
|
||||
edge_flags,
|
||||
segment_index,
|
||||
task_id,
|
||||
z_id,
|
||||
render_tasks,
|
||||
gpu_buffer_builder,
|
||||
|key, instance| {
|
||||
let batch = self.batcher.set_params_and_get_batch(
|
||||
key,
|
||||
|
@ -857,7 +859,7 @@ impl BatchBuilder {
|
|||
surface_spatial_node_index: SpatialNodeIndex,
|
||||
z_generator: &mut ZBufferIdGenerator,
|
||||
prim_instances: &[PrimitiveInstance],
|
||||
_gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
segments: &[RenderTaskId],
|
||||
) {
|
||||
let (prim_instance_index, extra_prim_gpu_address) = match cmd {
|
||||
|
@ -883,6 +885,7 @@ impl BatchBuilder {
|
|||
z_generator,
|
||||
prim_instances,
|
||||
render_tasks,
|
||||
gpu_buffer_builder,
|
||||
);
|
||||
} else {
|
||||
for (i, task_id) in segments.iter().enumerate() {
|
||||
|
@ -900,6 +903,7 @@ impl BatchBuilder {
|
|||
z_generator,
|
||||
prim_instances,
|
||||
render_tasks,
|
||||
gpu_buffer_builder,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3837,13 +3841,14 @@ impl<'a, 'rc> RenderTargetContext<'a, 'rc> {
|
|||
pub fn add_quad_to_batch<F>(
|
||||
render_task_address: RenderTaskAddress,
|
||||
transform_id: TransformPaletteId,
|
||||
gpu_buffer_address: GpuBufferAddress,
|
||||
prim_address_f: GpuBufferAddress,
|
||||
quad_flags: QuadFlags,
|
||||
edge_flags: EdgeAaSegmentMask,
|
||||
segment_index: u8,
|
||||
task_id: RenderTaskId,
|
||||
z_id: ZBufferId,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
mut f: F,
|
||||
) where F: FnMut(BatchKey, PrimitiveInstanceData) {
|
||||
|
||||
|
@ -3857,6 +3862,15 @@ pub fn add_quad_to_batch<F>(
|
|||
All = 5,
|
||||
}
|
||||
|
||||
let mut writer = gpu_buffer_builder.i32.write_blocks(1);
|
||||
writer.push_one([
|
||||
transform_id.0 as i32,
|
||||
z_id.0,
|
||||
0,
|
||||
0,
|
||||
]);
|
||||
let prim_address_i = writer.finish();
|
||||
|
||||
let texture = match task_id {
|
||||
RenderTaskId::INVALID => {
|
||||
TextureSource::Invalid
|
||||
|
@ -3898,7 +3912,8 @@ pub fn add_quad_to_batch<F>(
|
|||
if edge_flags.is_empty() {
|
||||
let instance = QuadInstance {
|
||||
render_task_address,
|
||||
prim_address: gpu_buffer_address,
|
||||
prim_address_i,
|
||||
prim_address_f,
|
||||
z_id,
|
||||
transform_id,
|
||||
edge_flags: edge_flags_bits,
|
||||
|
@ -3911,7 +3926,8 @@ pub fn add_quad_to_batch<F>(
|
|||
} else if quad_flags.contains(QuadFlags::USE_AA_SEGMENTS) {
|
||||
let main_instance = QuadInstance {
|
||||
render_task_address,
|
||||
prim_address: gpu_buffer_address,
|
||||
prim_address_i,
|
||||
prim_address_f,
|
||||
z_id,
|
||||
transform_id,
|
||||
edge_flags: edge_flags_bits,
|
||||
|
@ -3956,7 +3972,8 @@ pub fn add_quad_to_batch<F>(
|
|||
} else {
|
||||
let instance = QuadInstance {
|
||||
render_task_address,
|
||||
prim_address: gpu_buffer_address,
|
||||
prim_address_i,
|
||||
prim_address_f,
|
||||
z_id,
|
||||
transform_id,
|
||||
edge_flags: edge_flags_bits,
|
||||
|
|
|
@ -25,7 +25,7 @@ use crate::prim_store::{PictureIndex, PrimitiveScratchBuffer};
|
|||
use crate::prim_store::{DeferredResolve, PrimitiveInstance};
|
||||
use crate::profiler::{self, TransactionProfile};
|
||||
use crate::render_backend::{DataStores, ScratchBuffer};
|
||||
use crate::renderer::{GpuBufferF, GpuBufferBuilderF, GpuBufferI, GpuBufferBuilderI};
|
||||
use crate::renderer::{GpuBufferF, GpuBufferBuilderF, GpuBufferI, GpuBufferBuilderI, GpuBufferBuilder};
|
||||
use crate::render_target::{RenderTarget, PictureCacheTarget, TextureCacheRenderTarget, PictureCacheTargetKind};
|
||||
use crate::render_target::{RenderTargetContext, RenderTargetKind, AlphaRenderTarget, ColorRenderTarget};
|
||||
use crate::render_task_graph::{RenderTaskGraph, Pass, SubPassSurface};
|
||||
|
@ -171,8 +171,7 @@ pub struct FrameBuildingState<'a> {
|
|||
pub surface_builder: SurfaceBuilder,
|
||||
pub cmd_buffers: &'a mut CommandBufferList,
|
||||
pub clip_tree: &'a ClipTree,
|
||||
pub frame_gpu_data_f: &'a mut GpuBufferBuilderF,
|
||||
pub frame_gpu_data_i: &'a mut GpuBufferBuilderI,
|
||||
pub frame_gpu_data: &'a mut GpuBufferBuilder,
|
||||
}
|
||||
|
||||
impl<'a> FrameBuildingState<'a> {
|
||||
|
@ -277,8 +276,7 @@ impl FrameBuilder {
|
|||
tile_caches: &mut FastHashMap<SliceId, Box<TileCacheInstance>>,
|
||||
spatial_tree: &SpatialTree,
|
||||
cmd_buffers: &mut CommandBufferList,
|
||||
frame_gpu_data_f: &mut GpuBufferBuilderF,
|
||||
frame_gpu_data_i: &mut GpuBufferBuilderI,
|
||||
frame_gpu_data: &mut GpuBufferBuilder,
|
||||
profile: &mut TransactionProfile,
|
||||
) {
|
||||
profile_scope!("build_layer_screen_rects_and_cull_layers");
|
||||
|
@ -430,8 +428,7 @@ impl FrameBuilder {
|
|||
surface_builder: SurfaceBuilder::new(),
|
||||
cmd_buffers,
|
||||
clip_tree: &mut scene.clip_tree,
|
||||
frame_gpu_data_f,
|
||||
frame_gpu_data_i,
|
||||
frame_gpu_data,
|
||||
};
|
||||
|
||||
// Push a default dirty region which culls primitives
|
||||
|
@ -561,8 +558,10 @@ impl FrameBuilder {
|
|||
let mut cmd_buffers = CommandBufferList::new();
|
||||
|
||||
// TODO(gw): Recycle backing vec buffers for gpu buffer builder between frames
|
||||
let mut gpu_buffer_builder_f = GpuBufferBuilderF::new();
|
||||
let mut gpu_buffer_builder_i = GpuBufferBuilderI::new();
|
||||
let mut gpu_buffer_builder = GpuBufferBuilder {
|
||||
f32: GpuBufferBuilderF::new(),
|
||||
i32: GpuBufferBuilderI::new(),
|
||||
};
|
||||
|
||||
self.build_layer_screen_rects_and_cull_layers(
|
||||
scene,
|
||||
|
@ -580,8 +579,7 @@ impl FrameBuilder {
|
|||
tile_caches,
|
||||
spatial_tree,
|
||||
&mut cmd_buffers,
|
||||
&mut gpu_buffer_builder_f,
|
||||
&mut gpu_buffer_builder_i,
|
||||
&mut gpu_buffer_builder,
|
||||
profile,
|
||||
);
|
||||
|
||||
|
@ -637,7 +635,7 @@ impl FrameBuilder {
|
|||
output_size,
|
||||
&mut ctx,
|
||||
gpu_cache,
|
||||
&mut gpu_buffer_builder_f,
|
||||
&mut gpu_buffer_builder,
|
||||
&render_tasks,
|
||||
&scene.clip_store,
|
||||
&mut transform_palette,
|
||||
|
@ -695,8 +693,8 @@ impl FrameBuilder {
|
|||
scene.clip_store.end_frame(&mut scratch.clip_store);
|
||||
scratch.end_frame();
|
||||
|
||||
let gpu_buffer_f = gpu_buffer_builder_f.finalize(&render_tasks);
|
||||
let gpu_buffer_i = gpu_buffer_builder_i.finalize(&render_tasks);
|
||||
let gpu_buffer_f = gpu_buffer_builder.f32.finalize(&render_tasks);
|
||||
let gpu_buffer_i = gpu_buffer_builder.i32.finalize(&render_tasks);
|
||||
|
||||
Frame {
|
||||
device_rect: DeviceIntRect::from_origin_and_size(
|
||||
|
@ -766,7 +764,6 @@ impl FrameBuilder {
|
|||
const LAYOUT_PORT_COLOR: ColorF = debug_colors::RED;
|
||||
const VISUAL_PORT_COLOR: ColorF = debug_colors::BLUE;
|
||||
const DISPLAYPORT_COLOR: ColorF = debug_colors::LIME;
|
||||
const NOTHING: ColorF = ColorF { r: 0.0, g: 0.0, b: 0.0, a: 0.0 };
|
||||
|
||||
let viewport = scroll_frame_info.viewport_rect;
|
||||
|
||||
|
@ -812,9 +809,10 @@ impl FrameBuilder {
|
|||
}
|
||||
|
||||
let mut add_rect = |rect, border, fill| -> Option<()> {
|
||||
const STROKE_WIDTH: f32 = 2.0;
|
||||
// Place rect in scroll frame's local coordinate space
|
||||
let transformed_rect = transform.outer_transformed_box2d(&rect)?;
|
||||
|
||||
|
||||
// Transform to world coordinates, using root-content coords as an intermediate step.
|
||||
let mut root_content_rect = local_to_root_content.outer_transformed_box2d(&transformed_rect)?;
|
||||
// In root-content coords, apply the root content node's viewport clip.
|
||||
|
@ -827,21 +825,28 @@ impl FrameBuilder {
|
|||
}
|
||||
let world_rect = root_content_to_world.outer_transformed_box2d(&root_content_rect)?;
|
||||
|
||||
scratch.push_debug_rect_with_stroke_width(world_rect, border, STROKE_WIDTH);
|
||||
|
||||
// Add world coordinate rects to scratch.debug_items
|
||||
// TODO: Add a parameter to control the border thickness of the rects, and make them a bit thicker.
|
||||
scratch.push_debug_rect(world_rect * DevicePixelScale::new(1.0), border, fill);
|
||||
if let Some(fill_color) = fill {
|
||||
let interior_world_rect = WorldRect::new(
|
||||
world_rect.min + WorldVector2D::new(STROKE_WIDTH, STROKE_WIDTH),
|
||||
world_rect.max - WorldVector2D::new(STROKE_WIDTH, STROKE_WIDTH)
|
||||
);
|
||||
scratch.push_debug_rect(interior_world_rect * DevicePixelScale::new(1.0), border, fill_color);
|
||||
}
|
||||
|
||||
Some(())
|
||||
};
|
||||
|
||||
add_rect(minimap_data.scrollable_rect, PAGE_BORDER_COLOR, BACKGROUND_COLOR);
|
||||
add_rect(minimap_data.visual_viewport, VISUAL_PORT_COLOR, NOTHING);
|
||||
add_rect(minimap_data.displayport, DISPLAYPORT_COLOR, DISPLAYPORT_BACKGROUND_COLOR);
|
||||
add_rect(minimap_data.scrollable_rect, PAGE_BORDER_COLOR, Some(BACKGROUND_COLOR));
|
||||
add_rect(minimap_data.displayport, DISPLAYPORT_COLOR, Some(DISPLAYPORT_BACKGROUND_COLOR));
|
||||
// Only render a distinct layout viewport for the root content.
|
||||
// For other scroll frames, the visual and layout viewports coincide.
|
||||
if minimap_data.is_root_content {
|
||||
add_rect(minimap_data.layout_viewport, LAYOUT_PORT_COLOR, NOTHING);
|
||||
add_rect(minimap_data.layout_viewport, LAYOUT_PORT_COLOR, None);
|
||||
}
|
||||
add_rect(minimap_data.visual_viewport, VISUAL_PORT_COLOR, None);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -901,7 +906,7 @@ pub fn build_render_pass(
|
|||
screen_size: DeviceIntSize,
|
||||
ctx: &mut RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
clip_store: &ClipStore,
|
||||
transforms: &mut TransformPalette,
|
||||
|
@ -974,7 +979,6 @@ pub fn build_render_pass(
|
|||
let task_id = sub_pass.task_ids[0];
|
||||
let task = &render_tasks[task_id];
|
||||
let target_rect = task.get_target_rect();
|
||||
let mut gpu_buffer_builder = GpuBufferBuilderF::new();
|
||||
|
||||
match task.kind {
|
||||
RenderTaskKind::Picture(ref pic_task) => {
|
||||
|
@ -1005,7 +1009,7 @@ pub fn build_render_pass(
|
|||
pic_task.surface_spatial_node_index,
|
||||
z_generator,
|
||||
prim_instances,
|
||||
&mut gpu_buffer_builder,
|
||||
gpu_buffer_builder,
|
||||
segments,
|
||||
);
|
||||
});
|
||||
|
@ -1079,6 +1083,7 @@ pub fn build_render_pass(
|
|||
z_generator,
|
||||
prim_instances,
|
||||
cmd_buffers,
|
||||
gpu_buffer_builder,
|
||||
);
|
||||
pass.alpha.build(
|
||||
ctx,
|
||||
|
@ -1089,6 +1094,7 @@ pub fn build_render_pass(
|
|||
z_generator,
|
||||
prim_instances,
|
||||
cmd_buffers,
|
||||
gpu_buffer_builder,
|
||||
);
|
||||
|
||||
pass
|
||||
|
|
|
@ -547,7 +547,8 @@ impl From<SplitCompositeInstance> for PrimitiveInstanceData {
|
|||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct QuadInstance {
|
||||
pub render_task_address: RenderTaskAddress,
|
||||
pub prim_address: GpuBufferAddress,
|
||||
pub prim_address_i: GpuBufferAddress,
|
||||
pub prim_address_f: GpuBufferAddress,
|
||||
pub z_id: ZBufferId,
|
||||
pub transform_id: TransformPaletteId,
|
||||
pub quad_flags: u8,
|
||||
|
@ -559,19 +560,23 @@ pub struct QuadInstance {
|
|||
impl From<QuadInstance> for PrimitiveInstanceData {
|
||||
fn from(instance: QuadInstance) -> Self {
|
||||
/*
|
||||
[32 bits prim address]
|
||||
[8 bits quad flags] [8 bits edge flags] [16 bits render task address]
|
||||
[8 bits segment flags] [24 bits z_id]
|
||||
[8 bits segment index] [24 bits xf_id]
|
||||
*/
|
||||
[32 prim address_i]
|
||||
[32 prim address_f]
|
||||
[8888 qf ef pi si]
|
||||
[32 render task address]
|
||||
*/
|
||||
|
||||
PrimitiveInstanceData {
|
||||
data: [
|
||||
instance.prim_address.as_int(),
|
||||
((instance.quad_flags as i32) << 24) |
|
||||
((instance.edge_flags as i32) << 16) |
|
||||
instance.prim_address_i.as_int(),
|
||||
instance.prim_address_f.as_int(),
|
||||
|
||||
((instance.quad_flags as i32) << 24) |
|
||||
((instance.edge_flags as i32) << 16) |
|
||||
((instance.part_index as i32) << 8) |
|
||||
((instance.segment_index as i32) << 0),
|
||||
|
||||
instance.render_task_address.0 as i32,
|
||||
((instance.part_index as i32) << 24) | instance.z_id.0,
|
||||
((instance.segment_index as i32) << 24) | instance.transform_id.0 as i32,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -452,7 +452,7 @@ fn prepare_interned_prim_for_render(
|
|||
kind: RenderTaskCacheKeyKind::LineDecoration(cache_key.clone()),
|
||||
},
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
|
@ -607,7 +607,7 @@ fn prepare_interned_prim_for_render(
|
|||
handles.push(frame_state.resource_cache.request_render_task(
|
||||
cache_key,
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false, // TODO(gw): We don't calculate opacity for borders yet!
|
||||
|
@ -764,7 +764,7 @@ fn prepare_interned_prim_for_render(
|
|||
// the written block count) to gpu-buffer, we could add a trait for
|
||||
// writing typed data?
|
||||
let main_prim_address = write_prim_blocks(
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
prim_data.common.prim_rect,
|
||||
prim_instance.vis.clip_chain.local_clip_rect,
|
||||
premul_color,
|
||||
|
@ -1138,7 +1138,7 @@ fn prepare_interned_prim_for_render(
|
|||
|
||||
let stops_address = GradientGpuBlockBuilder::build(
|
||||
prim_data.reverse_stops,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
&prim_data.stops,
|
||||
);
|
||||
|
||||
|
@ -1296,8 +1296,8 @@ fn prepare_interned_prim_for_render(
|
|||
.clipped_local_rect
|
||||
.cast_unit();
|
||||
|
||||
let main_prim_address = write_prim_blocks(
|
||||
frame_state.frame_gpu_data_f,
|
||||
let prim_address_f = write_prim_blocks(
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
prim_local_rect,
|
||||
prim_instance.vis.clip_chain.local_clip_rect,
|
||||
PremultipliedColorF::WHITE,
|
||||
|
@ -1333,7 +1333,7 @@ fn prepare_interned_prim_for_render(
|
|||
let masks = MaskSubPass {
|
||||
clip_node_range,
|
||||
prim_spatial_node_index,
|
||||
main_prim_address,
|
||||
prim_address_f,
|
||||
};
|
||||
|
||||
// Add the mask as a sub-pass of the picture
|
||||
|
@ -1406,7 +1406,7 @@ fn prepare_interned_prim_for_render(
|
|||
let masks = MaskSubPass {
|
||||
clip_node_range,
|
||||
prim_spatial_node_index,
|
||||
main_prim_address,
|
||||
prim_address_f,
|
||||
};
|
||||
|
||||
let clip_task = frame_state.rg_builder.get_task_mut(clip_task_id);
|
||||
|
@ -1820,7 +1820,7 @@ pub fn update_clip_task(
|
|||
root_spatial_node_index,
|
||||
frame_state.clip_store,
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.resource_cache,
|
||||
frame_state.rg_builder,
|
||||
&mut data_stores.clip,
|
||||
|
@ -1881,7 +1881,7 @@ pub fn update_brush_segment_clip_task(
|
|||
root_spatial_node_index,
|
||||
frame_state.clip_store,
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.resource_cache,
|
||||
frame_state.rg_builder,
|
||||
clip_data_store,
|
||||
|
@ -2153,7 +2153,7 @@ fn add_segment(
|
|||
prim_instance: &PrimitiveInstance,
|
||||
prim_spatial_node_index: SpatialNodeIndex,
|
||||
raster_spatial_node_index: SpatialNodeIndex,
|
||||
main_prim_address: GpuBufferAddress,
|
||||
prim_address_f: GpuBufferAddress,
|
||||
transform_id: TransformPaletteId,
|
||||
aa_flags: EdgeAaSegmentMask,
|
||||
quad_flags: QuadFlags,
|
||||
|
@ -2177,7 +2177,7 @@ fn add_segment(
|
|||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
content_origin,
|
||||
main_prim_address,
|
||||
prim_address_f,
|
||||
transform_id,
|
||||
aa_flags,
|
||||
quad_flags,
|
||||
|
@ -2189,7 +2189,7 @@ fn add_segment(
|
|||
let masks = MaskSubPass {
|
||||
clip_node_range: prim_instance.vis.clip_chain.clips_range,
|
||||
prim_spatial_node_index,
|
||||
main_prim_address,
|
||||
prim_address_f,
|
||||
};
|
||||
|
||||
let task = frame_state.rg_builder.get_task_mut(task_id);
|
||||
|
@ -2223,7 +2223,7 @@ fn add_composite_prim(
|
|||
segments: &[QuadSegment],
|
||||
) {
|
||||
let composite_prim_address = write_prim_blocks(
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
rect,
|
||||
rect,
|
||||
color,
|
||||
|
|
|
@ -254,7 +254,7 @@ impl ConicGradientTemplate {
|
|||
kind: RenderTaskCacheKeyKind::ConicGradient(cache_key),
|
||||
},
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
|
|
|
@ -522,7 +522,7 @@ impl LinearGradientTemplate {
|
|||
kind: RenderTaskCacheKeyKind::FastLinearGradient(gradient),
|
||||
},
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
|
@ -552,7 +552,7 @@ impl LinearGradientTemplate {
|
|||
kind: RenderTaskCacheKeyKind::LinearGradient(cache_key),
|
||||
},
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
|
|
|
@ -220,7 +220,7 @@ impl RadialGradientTemplate {
|
|||
kind: RenderTaskCacheKeyKind::RadialGradient(cache_key),
|
||||
},
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
|
|
|
@ -257,7 +257,7 @@ impl ImageData {
|
|||
kind: RenderTaskCacheKeyKind::Image(image_cache_key),
|
||||
},
|
||||
frame_state.gpu_cache,
|
||||
frame_state.frame_gpu_data_f,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
descriptor.is_opaque(),
|
||||
|
|
|
@ -1312,6 +1312,37 @@ impl PrimitiveScratchBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn push_debug_rect_with_stroke_width(
|
||||
&mut self,
|
||||
rect: WorldRect,
|
||||
border: ColorF,
|
||||
stroke_width: f32
|
||||
) {
|
||||
let top_edge = WorldRect::new(
|
||||
WorldPoint::new(rect.min.x + stroke_width, rect.min.y),
|
||||
WorldPoint::new(rect.max.x - stroke_width, rect.min.y + stroke_width)
|
||||
);
|
||||
self.push_debug_rect(top_edge * DevicePixelScale::new(1.0), border, border);
|
||||
|
||||
let bottom_edge = WorldRect::new(
|
||||
WorldPoint::new(rect.min.x + stroke_width, rect.max.y - stroke_width),
|
||||
WorldPoint::new(rect.max.x - stroke_width, rect.max.y)
|
||||
);
|
||||
self.push_debug_rect(bottom_edge * DevicePixelScale::new(1.0), border, border);
|
||||
|
||||
let right_edge = WorldRect::new(
|
||||
WorldPoint::new(rect.max.x - stroke_width, rect.min.y),
|
||||
rect.max
|
||||
);
|
||||
self.push_debug_rect(right_edge * DevicePixelScale::new(1.0), border, border);
|
||||
|
||||
let left_edge = WorldRect::new(
|
||||
rect.min,
|
||||
WorldPoint::new(rect.min.x + stroke_width, rect.max.y)
|
||||
);
|
||||
self.push_debug_rect(left_edge * DevicePixelScale::new(1.0), border, border);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn push_debug_rect(
|
||||
&mut self,
|
||||
|
|
|
@ -24,7 +24,7 @@ use crate::prim_store::gradient::{
|
|||
FastLinearGradientInstance, LinearGradientInstance, RadialGradientInstance,
|
||||
ConicGradientInstance,
|
||||
};
|
||||
use crate::renderer::{GpuBufferBuilderF, GpuBufferAddress};
|
||||
use crate::renderer::{GpuBufferAddress, GpuBufferBuilder};
|
||||
use crate::render_backend::DataStores;
|
||||
use crate::render_task::{RenderTaskKind, RenderTaskAddress, SubPass};
|
||||
use crate::render_task::{RenderTask, ScalingTask, SvgFilterInfo, MaskSubPass};
|
||||
|
@ -104,6 +104,7 @@ pub trait RenderTarget {
|
|||
_z_generator: &mut ZBufferIdGenerator,
|
||||
_prim_instances: &[PrimitiveInstance],
|
||||
_cmd_buffers: &CommandBufferList,
|
||||
_gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -121,7 +122,7 @@ pub trait RenderTarget {
|
|||
task_id: RenderTaskId,
|
||||
ctx: &RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
clip_store: &ClipStore,
|
||||
transforms: &mut TransformPalette,
|
||||
|
@ -183,6 +184,7 @@ impl<T: RenderTarget> RenderTargetList<T> {
|
|||
z_generator: &mut ZBufferIdGenerator,
|
||||
prim_instances: &[PrimitiveInstance],
|
||||
cmd_buffers: &CommandBufferList,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
) {
|
||||
if self.targets.is_empty() {
|
||||
return;
|
||||
|
@ -198,6 +200,7 @@ impl<T: RenderTarget> RenderTargetList<T> {
|
|||
z_generator,
|
||||
prim_instances,
|
||||
cmd_buffers,
|
||||
gpu_buffer_builder,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -274,10 +277,10 @@ impl RenderTarget for ColorRenderTarget {
|
|||
z_generator: &mut ZBufferIdGenerator,
|
||||
prim_instances: &[PrimitiveInstance],
|
||||
cmd_buffers: &CommandBufferList,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
) {
|
||||
profile_scope!("build");
|
||||
let mut merged_batches = AlphaBatchContainer::new(None);
|
||||
let mut gpu_buffer_builder = GpuBufferBuilderF::new();
|
||||
|
||||
for task_id in &self.alpha_tasks {
|
||||
profile_scope!("alpha_task");
|
||||
|
@ -326,7 +329,7 @@ impl RenderTarget for ColorRenderTarget {
|
|||
pic_task.surface_spatial_node_index,
|
||||
z_generator,
|
||||
prim_instances,
|
||||
&mut gpu_buffer_builder,
|
||||
gpu_buffer_builder,
|
||||
segments,
|
||||
);
|
||||
});
|
||||
|
@ -360,7 +363,7 @@ impl RenderTarget for ColorRenderTarget {
|
|||
task_id: RenderTaskId,
|
||||
ctx: &RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
_: &ClipStore,
|
||||
transforms: &mut TransformPalette,
|
||||
|
@ -376,13 +379,14 @@ impl RenderTarget for ColorRenderTarget {
|
|||
add_quad_to_batch(
|
||||
render_task_address,
|
||||
info.transform_id,
|
||||
info.prim_address,
|
||||
info.prim_address_f,
|
||||
info.quad_flags,
|
||||
info.edge_flags,
|
||||
INVALID_SEGMENT_INDEX as u8,
|
||||
RenderTaskId::INVALID,
|
||||
ZBufferId(0),
|
||||
render_tasks,
|
||||
gpu_buffer_builder,
|
||||
|_, instance| {
|
||||
if info.prim_needs_scissor_rect {
|
||||
self.prim_instances_with_scissor
|
||||
|
@ -528,7 +532,7 @@ impl RenderTarget for AlphaRenderTarget {
|
|||
task_id: RenderTaskId,
|
||||
ctx: &RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
clip_store: &ClipStore,
|
||||
transforms: &mut TransformPalette,
|
||||
|
@ -966,7 +970,7 @@ fn build_mask_tasks(
|
|||
clip_store: &ClipStore,
|
||||
data_stores: &DataStores,
|
||||
spatial_tree: &SpatialTree,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
transforms: &mut TransformPalette,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
results: &mut ClipMaskInstanceList,
|
||||
|
@ -978,7 +982,7 @@ fn build_mask_tasks(
|
|||
let (clip_address, fast_path) = match clip_node.item.kind {
|
||||
ClipItemKind::RoundedRectangle { rect, radius, mode } => {
|
||||
let (fast_path, clip_address) = if radius.is_uniform().is_some() {
|
||||
let mut writer = gpu_buffer_builder.write_blocks(3);
|
||||
let mut writer = gpu_buffer_builder.f32.write_blocks(3);
|
||||
writer.push_one(rect);
|
||||
writer.push_one([radius.top_left.width, 0.0, 0.0, 0.0]);
|
||||
writer.push_one([mode as i32 as f32, 0.0, 0.0, 0.0]);
|
||||
|
@ -986,7 +990,7 @@ fn build_mask_tasks(
|
|||
|
||||
(true, clip_address)
|
||||
} else {
|
||||
let mut writer = gpu_buffer_builder.write_blocks(4);
|
||||
let mut writer = gpu_buffer_builder.f32.write_blocks(4);
|
||||
writer.push_one(rect);
|
||||
writer.push_one([
|
||||
radius.top_left.width,
|
||||
|
@ -1011,7 +1015,7 @@ fn build_mask_tasks(
|
|||
ClipItemKind::Rectangle { rect, mode, .. } => {
|
||||
assert_eq!(mode, ClipMode::Clip);
|
||||
|
||||
let mut writer = gpu_buffer_builder.write_blocks(3);
|
||||
let mut writer = gpu_buffer_builder.f32.write_blocks(3);
|
||||
writer.push_one(rect);
|
||||
writer.push_one([0.0, 0.0, 0.0, 0.0]);
|
||||
writer.push_one([mode as i32 as f32, 0.0, 0.0, 0.0]);
|
||||
|
@ -1043,7 +1047,7 @@ fn build_mask_tasks(
|
|||
|
||||
for tile in clip_store.visible_mask_tiles(&clip_instance) {
|
||||
let clip_prim_address = write_prim_blocks(
|
||||
gpu_buffer_builder,
|
||||
&mut gpu_buffer_builder.f32,
|
||||
rect,
|
||||
rect,
|
||||
PremultipliedColorF::WHITE,
|
||||
|
@ -1067,6 +1071,7 @@ fn build_mask_tasks(
|
|||
tile.task_id,
|
||||
ZBufferId(0),
|
||||
render_tasks,
|
||||
gpu_buffer_builder,
|
||||
|_, prim| {
|
||||
if clip_needs_scissor_rect {
|
||||
results
|
||||
|
@ -1107,7 +1112,7 @@ fn build_mask_tasks(
|
|||
);
|
||||
|
||||
let main_prim_address = write_prim_blocks(
|
||||
gpu_buffer_builder,
|
||||
&mut gpu_buffer_builder.f32,
|
||||
task_world_rect.cast_unit(),
|
||||
task_world_rect.cast_unit(),
|
||||
PremultipliedColorF::WHITE,
|
||||
|
@ -1162,6 +1167,7 @@ fn build_mask_tasks(
|
|||
RenderTaskId::INVALID,
|
||||
ZBufferId(0),
|
||||
render_tasks,
|
||||
gpu_buffer_builder,
|
||||
|_, prim| {
|
||||
let instance = MaskInstance {
|
||||
prim,
|
||||
|
@ -1198,7 +1204,7 @@ fn build_mask_tasks(
|
|||
fn build_sub_pass(
|
||||
task_id: RenderTaskId,
|
||||
task: &RenderTask,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilder,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
transforms: &mut TransformPalette,
|
||||
ctx: &RenderTargetContext,
|
||||
|
@ -1235,7 +1241,7 @@ fn build_sub_pass(
|
|||
render_task_address,
|
||||
content_rect / device_pixel_scale,
|
||||
target_rect,
|
||||
masks.main_prim_address,
|
||||
masks.prim_address_f,
|
||||
masks.prim_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
ctx.clip_store,
|
||||
|
|
|
@ -186,7 +186,7 @@ pub struct EmptyTask {
|
|||
pub struct PrimTask {
|
||||
pub device_pixel_scale: DevicePixelScale,
|
||||
pub content_origin: DevicePoint,
|
||||
pub prim_address: GpuBufferAddress,
|
||||
pub prim_address_f: GpuBufferAddress,
|
||||
pub prim_spatial_node_index: SpatialNodeIndex,
|
||||
pub raster_spatial_node_index: SpatialNodeIndex,
|
||||
pub transform_id: TransformPaletteId,
|
||||
|
@ -520,7 +520,7 @@ impl RenderTaskKind {
|
|||
raster_spatial_node_index: SpatialNodeIndex,
|
||||
device_pixel_scale: DevicePixelScale,
|
||||
content_origin: DevicePoint,
|
||||
prim_address: GpuBufferAddress,
|
||||
prim_address_f: GpuBufferAddress,
|
||||
transform_id: TransformPaletteId,
|
||||
edge_flags: EdgeAaSegmentMask,
|
||||
quad_flags: QuadFlags,
|
||||
|
@ -532,7 +532,7 @@ impl RenderTaskKind {
|
|||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
content_origin,
|
||||
prim_address,
|
||||
prim_address_f,
|
||||
transform_id,
|
||||
edge_flags,
|
||||
quad_flags,
|
||||
|
@ -883,7 +883,7 @@ pub type TaskDependencies = SmallVec<[RenderTaskId;2]>;
|
|||
pub struct MaskSubPass {
|
||||
pub clip_node_range: ClipNodeRange,
|
||||
pub prim_spatial_node_index: SpatialNodeIndex,
|
||||
pub main_prim_address: GpuBufferAddress,
|
||||
pub prim_address_f: GpuBufferAddress,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
|
|
|
@ -17,11 +17,16 @@ use api::{PremultipliedColorF, ImageFormat};
|
|||
use crate::device::Texel;
|
||||
use crate::render_task_graph::{RenderTaskGraph, RenderTaskId};
|
||||
|
||||
pub struct GpuBufferBuilder {
|
||||
pub i32: GpuBufferBuilderI,
|
||||
pub f32: GpuBufferBuilderF,
|
||||
}
|
||||
|
||||
pub type GpuBufferF = GpuBuffer<GpuBufferBlockF>;
|
||||
pub type GpuBufferBuilderF = GpuBufferBuilder<GpuBufferBlockF>;
|
||||
pub type GpuBufferBuilderF = GpuBufferBuilderImpl<GpuBufferBlockF>;
|
||||
|
||||
pub type GpuBufferI = GpuBuffer<GpuBufferBlockI>;
|
||||
pub type GpuBufferBuilderI = GpuBufferBuilder<GpuBufferBlockI>;
|
||||
pub type GpuBufferBuilderI = GpuBufferBuilderImpl<GpuBufferBlockI>;
|
||||
|
||||
unsafe impl Texel for GpuBufferBlockF {
|
||||
fn image_format() -> ImageFormat { ImageFormat::RGBAF32 }
|
||||
|
@ -173,6 +178,14 @@ impl Into<GpuBufferBlockF> for [f32; 4] {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<GpuBufferBlockI> for [i32; 4] {
|
||||
fn into(self) -> GpuBufferBlockI {
|
||||
GpuBufferBlockI {
|
||||
data: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Record a patch to the GPU buffer for a render task
|
||||
struct DeferredBlock {
|
||||
task_id: RenderTaskId,
|
||||
|
@ -234,14 +247,14 @@ impl<'a, T> Drop for GpuBufferWriter<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct GpuBufferBuilder<T> {
|
||||
pub struct GpuBufferBuilderImpl<T> {
|
||||
data: Vec<T>,
|
||||
deferred: Vec<DeferredBlock>,
|
||||
}
|
||||
|
||||
impl<T> GpuBufferBuilder<T> where T: Texel + std::convert::From<DeviceIntRect> {
|
||||
impl<T> GpuBufferBuilderImpl<T> where T: Texel + std::convert::From<DeviceIntRect> {
|
||||
pub fn new() -> Self {
|
||||
GpuBufferBuilder {
|
||||
GpuBufferBuilderImpl {
|
||||
data: Vec::new(),
|
||||
deferred: Vec::new(),
|
||||
}
|
||||
|
@ -342,7 +355,7 @@ impl<T> GpuBuffer<T> {
|
|||
#[test]
|
||||
fn test_gpu_buffer_sizing_push() {
|
||||
let render_task_graph = RenderTaskGraph::new_for_testing();
|
||||
let mut builder = GpuBufferBuilder::<GpuBufferBlockF>::new();
|
||||
let mut builder = GpuBufferBuilderF::new();
|
||||
|
||||
let row = vec![GpuBufferBlockF::EMPTY; MAX_VERTEX_TEXTURE_WIDTH];
|
||||
builder.push(&row);
|
||||
|
@ -357,7 +370,7 @@ fn test_gpu_buffer_sizing_push() {
|
|||
#[test]
|
||||
fn test_gpu_buffer_sizing_writer() {
|
||||
let render_task_graph = RenderTaskGraph::new_for_testing();
|
||||
let mut builder = GpuBufferBuilder::<GpuBufferBlockF>::new();
|
||||
let mut builder = GpuBufferBuilderF::new();
|
||||
|
||||
let mut writer = builder.write_blocks(MAX_VERTEX_TEXTURE_WIDTH);
|
||||
for _ in 0 .. MAX_VERTEX_TEXTURE_WIDTH {
|
||||
|
|
|
@ -127,7 +127,7 @@ pub(crate) mod init;
|
|||
pub use debug::DebugRenderer;
|
||||
pub use shade::{Shaders, SharedShaders};
|
||||
pub use vertex::{desc, VertexArrayKind, MAX_VERTEX_TEXTURE_WIDTH};
|
||||
pub use gpu_buffer::{GpuBuffer, GpuBufferF, GpuBufferBuilderF, GpuBufferI, GpuBufferBuilderI, GpuBufferAddress};
|
||||
pub use gpu_buffer::{GpuBuffer, GpuBufferF, GpuBufferBuilderF, GpuBufferI, GpuBufferBuilderI, GpuBufferAddress, GpuBufferBuilder};
|
||||
|
||||
/// The size of the array of each type of vertex data texture that
|
||||
/// is round-robin-ed each frame during bind_frame_data. Doing this
|
||||
|
|
|
@ -283,6 +283,7 @@ impl LazilyCompiledShader {
|
|||
("sPrimitiveHeadersF", TextureSampler::PrimitiveHeadersF),
|
||||
("sPrimitiveHeadersI", TextureSampler::PrimitiveHeadersI),
|
||||
("sGpuBufferF", TextureSampler::GpuBufferF),
|
||||
("sGpuBufferI", TextureSampler::GpuBufferI),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -301,6 +302,7 @@ impl LazilyCompiledShader {
|
|||
("sPrimitiveHeadersI", TextureSampler::PrimitiveHeadersI),
|
||||
("sClipMask", TextureSampler::ClipMask),
|
||||
("sGpuBufferF", TextureSampler::GpuBufferF),
|
||||
("sGpuBufferI", TextureSampler::GpuBufferI),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,41 +23,9 @@ namespace image {
|
|||
// Helpers for sending notifications to the image associated with a decoder.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void IDecodingTask::EnsureHasEventTarget(NotNull<RasterImage*> aImage) {
|
||||
if (!mEventTarget) {
|
||||
// We determine the event target as late as possible, at the first dispatch
|
||||
// time, because the observers bound to an imgRequest will affect it.
|
||||
// We cache it rather than query for the event target each time because the
|
||||
// event target can change. We don't want to risk events being executed in
|
||||
// a different order than they are dispatched, which can happen if we
|
||||
// selected scheduler groups which have no ordering guarantees relative to
|
||||
// each other (e.g. it moves from scheduler group A for doc group DA to
|
||||
// scheduler group B for doc group DB due to changing observers -- if we
|
||||
// dispatched the first event on A, and the second on B, we don't know which
|
||||
// will execute first.)
|
||||
RefPtr<ProgressTracker> tracker = aImage->GetProgressTracker();
|
||||
if (tracker) {
|
||||
mEventTarget = tracker->GetEventTarget();
|
||||
} else {
|
||||
mEventTarget = GetMainThreadSerialEventTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IDecodingTask::IsOnEventTarget() const {
|
||||
// This is essentially equivalent to NS_IsOnMainThread() because all of the
|
||||
// event targets are for the main thread (although perhaps with a different
|
||||
// label / scheduler group). The observers in ProgressTracker may have
|
||||
// different event targets from this, so this is just a best effort guess.
|
||||
bool current = false;
|
||||
mEventTarget->IsOnCurrentThread(¤t);
|
||||
return current;
|
||||
}
|
||||
|
||||
void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
|
||||
NotNull<Decoder*> aDecoder) {
|
||||
MOZ_ASSERT(aDecoder->HasProgress() && !aDecoder->IsMetadataDecode());
|
||||
EnsureHasEventTarget(aImage);
|
||||
|
||||
// Capture the decoder's state. If we need to notify asynchronously, it's
|
||||
// important that we don't wait until the lambda actually runs to capture the
|
||||
|
@ -72,7 +40,7 @@ void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
|
|||
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
|
||||
|
||||
// Synchronously notify if we can.
|
||||
if (IsOnEventTarget() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
|
||||
if (NS_IsMainThread() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
|
||||
aImage->NotifyProgress(progress, invalidRect, frameCount, decoderFlags,
|
||||
surfaceFlags);
|
||||
return;
|
||||
|
@ -86,21 +54,21 @@ void IDecodingTask::NotifyProgress(NotNull<RasterImage*> aImage,
|
|||
|
||||
// We're forced to notify asynchronously.
|
||||
NotNull<RefPtr<RasterImage>> image = aImage;
|
||||
mEventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
|
||||
"IDecodingTask::NotifyProgress",
|
||||
[=]() -> void {
|
||||
image->NotifyProgress(progress, invalidRect,
|
||||
frameCount, decoderFlags,
|
||||
surfaceFlags);
|
||||
})),
|
||||
NS_DISPATCH_NORMAL);
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
|
||||
eventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
|
||||
"IDecodingTask::NotifyProgress",
|
||||
[=]() -> void {
|
||||
image->NotifyProgress(progress, invalidRect,
|
||||
frameCount, decoderFlags,
|
||||
surfaceFlags);
|
||||
})),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
|
||||
NotNull<Decoder*> aDecoder) {
|
||||
MOZ_ASSERT(aDecoder->HasError() || !aDecoder->InFrame(),
|
||||
"Decode complete in the middle of a frame?");
|
||||
EnsureHasEventTarget(aImage);
|
||||
|
||||
// Capture the decoder's state.
|
||||
DecoderFinalStatus finalStatus = aDecoder->FinalStatus();
|
||||
|
@ -113,7 +81,7 @@ void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
|
|||
SurfaceFlags surfaceFlags = aDecoder->GetSurfaceFlags();
|
||||
|
||||
// Synchronously notify if we can.
|
||||
if (IsOnEventTarget() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
|
||||
if (NS_IsMainThread() && !(decoderFlags & DecoderFlags::ASYNC_NOTIFY)) {
|
||||
aImage->NotifyDecodeComplete(finalStatus, metadata, telemetry, progress,
|
||||
invalidRect, frameCount, decoderFlags,
|
||||
surfaceFlags);
|
||||
|
@ -128,15 +96,16 @@ void IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
|
|||
|
||||
// We're forced to notify asynchronously.
|
||||
NotNull<RefPtr<RasterImage>> image = aImage;
|
||||
mEventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
|
||||
"IDecodingTask::NotifyDecodeComplete",
|
||||
[=]() -> void {
|
||||
image->NotifyDecodeComplete(
|
||||
finalStatus, metadata, telemetry, progress,
|
||||
invalidRect, frameCount, decoderFlags,
|
||||
surfaceFlags);
|
||||
})),
|
||||
NS_DISPATCH_NORMAL);
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
|
||||
eventTarget->Dispatch(CreateRenderBlockingRunnable(NS_NewRunnableFunction(
|
||||
"IDecodingTask::NotifyDecodeComplete",
|
||||
[=]() -> void {
|
||||
image->NotifyDecodeComplete(
|
||||
finalStatus, metadata, telemetry, progress,
|
||||
invalidRect, frameCount, decoderFlags,
|
||||
surfaceFlags);
|
||||
})),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -53,13 +53,6 @@ class IDecodingTask : public IResumable {
|
|||
/// Notify @aImage that @aDecoder has finished.
|
||||
void NotifyDecodeComplete(NotNull<RasterImage*> aImage,
|
||||
NotNull<Decoder*> aDecoder);
|
||||
|
||||
private:
|
||||
void EnsureHasEventTarget(NotNull<RasterImage*> aImage);
|
||||
|
||||
bool IsOnEventTarget() const;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include "nsISupports.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ void ImageResource::SendOnUnlockedDraw(uint32_t aFlags) {
|
|||
mProgressTracker->OnUnlockedDraw();
|
||||
} else {
|
||||
NotNull<RefPtr<ImageResource>> image = WrapNotNull(this);
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = mProgressTracker->GetEventTarget();
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
|
||||
nsCOMPtr<nsIRunnable> ev = NS_NewRunnableFunction(
|
||||
"image::ImageResource::SendOnUnlockedDraw", [=]() -> void {
|
||||
RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
|
||||
|
|
|
@ -408,10 +408,6 @@ void ProgressTracker::EmulateRequestFinished(IProgressObserver* aObserver) {
|
|||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIEventTarget> ProgressTracker::GetEventTarget() const {
|
||||
return do_AddRef(GetMainThreadSerialEventTarget());
|
||||
}
|
||||
|
||||
void ProgressTracker::AddObserver(IProgressObserver* aObserver) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<IProgressObserver> observer = aObserver;
|
||||
|
|
|
@ -179,9 +179,6 @@ class ProgressTracker : public mozilla::SupportsWeakPtr {
|
|||
bool RemoveObserver(IProgressObserver* aObserver);
|
||||
uint32_t ObserverCount() const;
|
||||
|
||||
// Get the event target we should currently dispatch events to.
|
||||
already_AddRefed<nsIEventTarget> GetEventTarget() const;
|
||||
|
||||
// Resets our weak reference to our image. Image subclasses should call this
|
||||
// in their destructor.
|
||||
void ResetImage();
|
||||
|
|
|
@ -480,12 +480,7 @@ void RasterImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey) {
|
|||
bool animatedFramesDiscarded =
|
||||
mAnimationState && aSurfaceKey.Playback() == PlaybackType::eAnimated;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> eventTarget;
|
||||
if (mProgressTracker) {
|
||||
eventTarget = mProgressTracker->GetEventTarget();
|
||||
} else {
|
||||
eventTarget = do_GetMainThread();
|
||||
}
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = do_GetMainThread();
|
||||
|
||||
RefPtr<RasterImage> image = this;
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
|
|
|
@ -1557,12 +1557,7 @@ void VectorImage::InvalidateObserversOnNextRefreshDriverTick() {
|
|||
// set by InvalidateFrameInternal in layout/generic/nsFrame.cpp. These bits
|
||||
// get cleared when we repaint the SVG into a surface by
|
||||
// nsIFrame::ClearInvalidationStateBits in nsDisplayList::PaintRoot.
|
||||
nsCOMPtr<nsIEventTarget> eventTarget;
|
||||
if (mProgressTracker) {
|
||||
eventTarget = mProgressTracker->GetEventTarget();
|
||||
} else {
|
||||
eventTarget = do_GetMainThread();
|
||||
}
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = do_GetMainThread();
|
||||
|
||||
RefPtr<VectorImage> self(this);
|
||||
nsCOMPtr<nsIRunnable> ev(NS_NewRunnableFunction(
|
||||
|
|
|
@ -334,8 +334,7 @@ void imgRequest::Cancel(nsresult aStatus) {
|
|||
if (NS_IsMainThread()) {
|
||||
ContinueCancel(aStatus);
|
||||
} else {
|
||||
RefPtr<ProgressTracker> progressTracker = GetProgressTracker();
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = progressTracker->GetEventTarget();
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = GetMainThreadSerialEventTarget();
|
||||
nsCOMPtr<nsIRunnable> ev = new imgRequestMainThreadCancel(this, aStatus);
|
||||
eventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
@ -1027,26 +1026,23 @@ imgRequest::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInStr,
|
|||
|
||||
if (result.mImage) {
|
||||
image = result.mImage;
|
||||
nsCOMPtr<nsIEventTarget> eventTarget;
|
||||
|
||||
// Update our state to reflect this new part.
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mImage = image;
|
||||
|
||||
// We only get an event target if we are not on the main thread, because
|
||||
// we have to dispatch in that case. If we are on the main thread, but
|
||||
// on a different scheduler group than ProgressTracker would give us,
|
||||
// that is okay because nothing in imagelib requires that, just our
|
||||
// listeners (which have their own checks).
|
||||
if (!NS_IsMainThread()) {
|
||||
eventTarget = mProgressTracker->GetEventTarget();
|
||||
MOZ_ASSERT(eventTarget);
|
||||
}
|
||||
|
||||
mProgressTracker = nullptr;
|
||||
}
|
||||
|
||||
// We only get an event target if we are not on the main thread, because
|
||||
// we have to dispatch in that case.
|
||||
nsCOMPtr<nsIEventTarget> eventTarget;
|
||||
if (!NS_IsMainThread()) {
|
||||
eventTarget = GetMainThreadSerialEventTarget();
|
||||
MOZ_ASSERT(eventTarget);
|
||||
}
|
||||
|
||||
// Some property objects are not threadsafe, and we need to send
|
||||
// OnImageAvailable on the main thread, so finish on the main thread.
|
||||
if (!eventTarget) {
|
||||
|
|
|
@ -2213,7 +2213,7 @@ def listIANAFiles(tzdataDir):
|
|||
|
||||
def readIANAFiles(tzdataDir, files):
|
||||
"""Read all IANA time zone files from the given iterable."""
|
||||
nameSyntax = "[\w/+\-]+"
|
||||
nameSyntax = r"[\w/+\-]+"
|
||||
pZone = re.compile(r"Zone\s+(?P<name>%s)\s+.*" % nameSyntax)
|
||||
pLink = re.compile(
|
||||
r"Link\s+(?P<target>%s)\s+(?P<name>%s)(?:\s+#.*)?" % (nameSyntax, nameSyntax)
|
||||
|
@ -2310,7 +2310,7 @@ def readICUResourceFile(filename):
|
|||
maybeMultiComments = r"(?:/\*[^*]*\*/)*"
|
||||
maybeSingleComment = r"(?://.*)?"
|
||||
lineStart = "^%s" % maybeMultiComments
|
||||
lineEnd = "%s\s*%s$" % (maybeMultiComments, maybeSingleComment)
|
||||
lineEnd = r"%s\s*%s$" % (maybeMultiComments, maybeSingleComment)
|
||||
return re.compile(r"\s*".join(chain([lineStart], args, [lineEnd])))
|
||||
|
||||
tableName = r'(?P<quote>"?)(?P<name>.+?)(?P=quote)'
|
||||
|
@ -2554,7 +2554,7 @@ def icuTzDataVersion(icuTzDir):
|
|||
zoneinfo = os.path.join(icuTzDir, "zoneinfo64.txt")
|
||||
if not os.path.isfile(zoneinfo):
|
||||
raise RuntimeError("file not found: %s" % zoneinfo)
|
||||
version = searchInFile("^//\s+tz version:\s+([0-9]{4}[a-z])$", zoneinfo)
|
||||
version = searchInFile(r"^//\s+tz version:\s+([0-9]{4}[a-z])$", zoneinfo)
|
||||
if version is None:
|
||||
raise RuntimeError(
|
||||
"%s does not contain a valid tzdata version string" % zoneinfo
|
||||
|
@ -3711,7 +3711,7 @@ const allUnits = {};
|
|||
""".format(
|
||||
all_units_array
|
||||
)
|
||||
+ """
|
||||
+ r"""
|
||||
// Test only sanctioned unit identifiers are allowed.
|
||||
|
||||
for (const typeAndUnit of allUnits) {
|
||||
|
|
|
@ -22,7 +22,7 @@ ALIGNMENT_COLUMN = 20
|
|||
# The maximum column for comment
|
||||
MAX_CHARS_PER_LINE = 80
|
||||
|
||||
stack_comment_pat = re.compile("^( *//) *(\[stack\].*)$")
|
||||
stack_comment_pat = re.compile(r"^( *//) *(\[stack\].*)$")
|
||||
|
||||
|
||||
def align_stack_comment(path):
|
||||
|
|
|
@ -271,7 +271,7 @@ def implemented_types(t):
|
|||
yield t2
|
||||
|
||||
|
||||
template_regexp = re.compile("([\w_:]+)<")
|
||||
template_regexp = re.compile(r"([\w_:]+)<")
|
||||
|
||||
|
||||
def is_struct_or_union(t):
|
||||
|
|
|
@ -40,9 +40,9 @@ def _relpath(path, start=None):
|
|||
os.path.relpath = _relpath
|
||||
|
||||
# Characters that need to be escaped when used in shell words.
|
||||
shell_need_escapes = re.compile("[^\w\d%+,-./:=@'\"]", re.DOTALL)
|
||||
shell_need_escapes = re.compile("[^\\w\\d%+,-./:=@'\"]", re.DOTALL)
|
||||
# Characters that need to be escaped within double-quoted strings.
|
||||
shell_dquote_escapes = re.compile('[^\w\d%+,-./:=@"]', re.DOTALL)
|
||||
shell_dquote_escapes = re.compile('[^\\w\\d%+,-./:=@"]', re.DOTALL)
|
||||
|
||||
|
||||
def make_shell_cmd(l):
|
||||
|
|
|
@ -13,10 +13,10 @@ run_fragment("ExecutableAllocator.onepool")
|
|||
|
||||
reExecPool = "ExecutablePool [a-f0-9]{8,}-[a-f0-9]{8,}"
|
||||
assert_regexp_pretty("pool", reExecPool)
|
||||
assert_regexp_pretty("execAlloc", "ExecutableAllocator\(\[" + reExecPool + "\]\)")
|
||||
assert_regexp_pretty("execAlloc", r"ExecutableAllocator\(\[" + reExecPool + r"\]\)")
|
||||
|
||||
run_fragment("ExecutableAllocator.twopools")
|
||||
|
||||
assert_regexp_pretty(
|
||||
"execAlloc", "ExecutableAllocator\(\[" + reExecPool + ", " + reExecPool + "\]\)"
|
||||
"execAlloc", r"ExecutableAllocator\(\[" + reExecPool + ", " + reExecPool + r"\]\)"
|
||||
)
|
||||
|
|
|
@ -40,25 +40,33 @@ for (let i of [
|
|||
)`, /(type mismatch|table with non-nullable references requires initializer)/);
|
||||
}
|
||||
|
||||
var t1 = new WebAssembly.Table({initial: 10, element: {ref: 'func', nullable: false }}, sampleWasmFunction);
|
||||
let values = "10 funcref (ref.func $dummy)";
|
||||
let t1 = new wasmEvalText(`(module (func $dummy) (table (export "t1") ${values}))`).exports.t1;
|
||||
assertEq(t1.get(2) != null, true);
|
||||
assertThrows(() => {
|
||||
new WebAssembly.Table({initial: 10, element: {ref: 'func', nullable: false }});
|
||||
});
|
||||
assertThrows(() => {
|
||||
new WebAssembly.Table({initial: 10, element: {ref: 'func', nullable: false }}, null);
|
||||
});
|
||||
|
||||
var t2 = new WebAssembly.Table({initial: 6, maximum: 20, element: {ref: 'extern', nullable: false }}, {foo: "bar"});
|
||||
assertEq(t2.get(1).foo, "bar");
|
||||
wasmFailValidateText(`(module
|
||||
(table $t 10 (ref func))
|
||||
)`, /table with non-nullable references requires initializer/);
|
||||
|
||||
wasmFailValidateText(`
|
||||
(module
|
||||
(func $dummy)
|
||||
(table (export "t") 10 funcref (ref.null none))
|
||||
)`, /type mismatch/);
|
||||
|
||||
const foo = "bar";
|
||||
const { t2, get } = wasmEvalText(`
|
||||
(module
|
||||
(global (import "" "foo") externref)
|
||||
(table (export "t2") 6 20 externref (global.get 0))
|
||||
)`, { "": { "foo": foo } }).exports;
|
||||
|
||||
assertEq(t2.get(5), "bar");
|
||||
assertThrows(() => { t2.get(7) });
|
||||
assertThrows(() => { t2.grow(9, null) });
|
||||
assertThrows(() => { t2.grow(30, null) });
|
||||
t2.grow(8, {t: "test"});
|
||||
assertEq(t2.get(3).foo, "bar");
|
||||
assertEq(t2.get(3), "bar");
|
||||
assertEq(t2.get(7).t, "test");
|
||||
assertThrows(() => {
|
||||
new WebAssembly.Table({initial: 10, element: {ref: 'extern', nullable: false }}, null);
|
||||
});
|
||||
|
||||
// Fail because tables come before globals in the binary format, so tables
|
||||
// cannot refer to globals.
|
||||
|
|
|
@ -16,36 +16,6 @@ assertErrorMessage(
|
|||
assertErrorMessage(
|
||||
() => new WebAssembly.Table({element: true, initial: 1}),
|
||||
TypeError, /bad value type/);
|
||||
|
||||
// RefType/ValueType can be specified as an {ref: 'func', ...} object
|
||||
const t11 = new WebAssembly.Table({element: {ref: 'func', nullable: true}, initial: 3});
|
||||
const t12 = new WebAssembly.Table({element: {ref: 'extern', nullable: true}, initial: 3});
|
||||
const t13 = new WebAssembly.Table({element: {ref: 'extern', nullable: false}, initial: 3}, {});
|
||||
|
||||
assertErrorMessage(
|
||||
() => new WebAssembly.Table({element: {ref: 'func', nullable: false}, initial: 1}, null),
|
||||
TypeError, /cannot pass null to non-nullable WebAssembly reference/);
|
||||
assertErrorMessage(
|
||||
() => new WebAssembly.Table({element: {ref: 'extern', nullable: false}, initial: 1}, null),
|
||||
TypeError, /cannot pass null to non-nullable WebAssembly reference/);
|
||||
|
||||
assertErrorMessage(
|
||||
() => new WebAssembly.Table({element: {ref: 'bar', nullable: true}, initial: 1}),
|
||||
TypeError, /bad value type/);
|
||||
|
||||
const g11 = new WebAssembly.Global({value: {ref: 'func', nullable: true}, mutable: true});
|
||||
const g12 = new WebAssembly.Global({value: {ref: 'extern', nullable: true}, mutable: true});
|
||||
const g13 = new WebAssembly.Global({value: {ref: 'extern', nullable: false}, mutable: true}, {});
|
||||
const g14 = new WebAssembly.Global({value: {ref: 'extern', nullable: false}, mutable: true});
|
||||
const g15 = new WebAssembly.Global({value: {ref: 'extern', nullable: false}, mutable: true}, void 0);
|
||||
|
||||
assertErrorMessage(
|
||||
() => new WebAssembly.Global({value: {ref: 'func', nullable: false}, mutable: true}),
|
||||
TypeError, /cannot pass null to non-nullable WebAssembly reference/);
|
||||
assertErrorMessage(
|
||||
() => new WebAssembly.Global({value: {ref: 'extern', nullable: false}, mutable: true}, null),
|
||||
TypeError, /cannot pass null to non-nullable WebAssembly reference/);
|
||||
|
||||
assertErrorMessage(
|
||||
() => new WebAssembly.Global({value: {ref: 'bar', nullable: true}, mutable: true}),
|
||||
TypeError, /bad value type/);
|
||||
|
|
|
@ -160,7 +160,7 @@ do_test()
|
|||
#
|
||||
# The timeout command send a SIGTERM signal, which should return 143
|
||||
# (=128+15). However, due to a bug in tinybox, it returns 142.
|
||||
if test \( $rc -eq 143 -o $rc -eq 142 \) -a $attempt -lt {retry}; then
|
||||
if test \\( $rc -eq 143 -o $rc -eq 142 \\) -a $attempt -lt {retry}; then
|
||||
echo '\\n{tag}RETRY='$rc,$time
|
||||
attempt=$((attempt + 1))
|
||||
do_test $idx $attempt "$@"
|
||||
|
|
|
@ -18,7 +18,7 @@ def to_code_list(codes):
|
|||
|
||||
|
||||
def convert(dir):
|
||||
ver_pat = re.compile("NormalizationTest-([0-9\.]+)\.txt")
|
||||
ver_pat = re.compile(r"NormalizationTest-([0-9\.]+)\.txt")
|
||||
part_pat = re.compile("^@(Part([0-9]+) .+)$")
|
||||
test_pat = re.compile(
|
||||
"^([0-9A-Fa-f ]+);([0-9A-Fa-f ]+);([0-9A-Fa-f ]+);([0-9A-Fa-f ]+);([0-9A-Fa-f ]+);$"
|
||||
|
|
|
@ -237,7 +237,7 @@ def mergeMeta(reftest, frontmatter, includes):
|
|||
if info:
|
||||
# Open some space in an existing info text
|
||||
if "info" in frontmatter:
|
||||
frontmatter["info"] += "\n\n \%s" % info
|
||||
frontmatter["info"] += "\n\n \\%s" % info
|
||||
else:
|
||||
frontmatter["info"] = info
|
||||
|
||||
|
|
|
@ -1111,7 +1111,7 @@ def make_regexp_space_test(version, test_space_table, codepoint_table):
|
|||
test_space.write(",\n".join(map(hex_and_name, test_space_table)))
|
||||
test_space.write("\n);\n")
|
||||
test_space.write(
|
||||
"""
|
||||
r"""
|
||||
assertEq(/^\s+$/.exec(onlySpace) !== null, true);
|
||||
assertEq(/^[\s]+$/.exec(onlySpace) !== null, true);
|
||||
assertEq(/^[^\s]+$/.exec(onlySpace) === null, true);
|
||||
|
|
|
@ -150,94 +150,7 @@ enum class RefTypeResult {
|
|||
Unparsed,
|
||||
};
|
||||
|
||||
static RefTypeResult MaybeToRefType(JSContext* cx, HandleObject obj,
|
||||
RefType* out) {
|
||||
#ifdef ENABLE_WASM_FUNCTION_REFERENCES
|
||||
if (!wasm::FunctionReferencesAvailable(cx)) {
|
||||
return RefTypeResult::Unparsed;
|
||||
}
|
||||
|
||||
JSAtom* refAtom = Atomize(cx, "ref", strlen("ref"));
|
||||
if (!refAtom) {
|
||||
return RefTypeResult::Failure;
|
||||
}
|
||||
RootedId refId(cx, AtomToId(refAtom));
|
||||
|
||||
RootedValue refVal(cx);
|
||||
if (!GetProperty(cx, obj, obj, refId, &refVal)) {
|
||||
return RefTypeResult::Failure;
|
||||
}
|
||||
|
||||
RootedString typeStr(cx, ToString(cx, refVal));
|
||||
if (!typeStr) {
|
||||
return RefTypeResult::Failure;
|
||||
}
|
||||
|
||||
Rooted<JSLinearString*> typeLinearStr(cx, typeStr->ensureLinear(cx));
|
||||
if (!typeLinearStr) {
|
||||
return RefTypeResult::Failure;
|
||||
}
|
||||
|
||||
if (StringEqualsLiteral(typeLinearStr, "func")) {
|
||||
*out = RefType::func();
|
||||
} else if (StringEqualsLiteral(typeLinearStr, "extern")) {
|
||||
*out = RefType::extern_();
|
||||
# ifdef ENABLE_WASM_EXNREF
|
||||
} else if (ExnRefAvailable(cx) && StringEqualsLiteral(typeLinearStr, "exn")) {
|
||||
*out = RefType::exn();
|
||||
# endif
|
||||
# ifdef ENABLE_WASM_GC
|
||||
} else if (GcAvailable(cx) && StringEqualsLiteral(typeLinearStr, "any")) {
|
||||
*out = RefType::any();
|
||||
} else if (GcAvailable(cx) && StringEqualsLiteral(typeLinearStr, "eq")) {
|
||||
*out = RefType::eq();
|
||||
} else if (GcAvailable(cx) && StringEqualsLiteral(typeLinearStr, "i31")) {
|
||||
*out = RefType::i31();
|
||||
} else if (GcAvailable(cx) && StringEqualsLiteral(typeLinearStr, "struct")) {
|
||||
*out = RefType::struct_();
|
||||
} else if (GcAvailable(cx) && StringEqualsLiteral(typeLinearStr, "array")) {
|
||||
*out = RefType::array();
|
||||
# endif
|
||||
} else {
|
||||
return RefTypeResult::Unparsed;
|
||||
}
|
||||
|
||||
JSAtom* nullableAtom = Atomize(cx, "nullable", strlen("nullable"));
|
||||
if (!nullableAtom) {
|
||||
return RefTypeResult::Failure;
|
||||
}
|
||||
RootedId nullableId(cx, AtomToId(nullableAtom));
|
||||
RootedValue nullableVal(cx);
|
||||
if (!GetProperty(cx, obj, obj, nullableId, &nullableVal)) {
|
||||
return RefTypeResult::Failure;
|
||||
}
|
||||
|
||||
bool nullable = ToBoolean(nullableVal);
|
||||
if (!nullable) {
|
||||
*out = out->asNonNullable();
|
||||
}
|
||||
MOZ_ASSERT(out->isNullable() == nullable);
|
||||
return RefTypeResult::Parsed;
|
||||
#else
|
||||
return RefTypeResult::Unparsed;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool wasm::ToValType(JSContext* cx, HandleValue v, ValType* out) {
|
||||
if (v.isObject()) {
|
||||
RootedObject obj(cx, &v.toObject());
|
||||
RefType refType;
|
||||
switch (MaybeToRefType(cx, obj, &refType)) {
|
||||
case RefTypeResult::Failure:
|
||||
return false;
|
||||
case RefTypeResult::Parsed:
|
||||
*out = ValType(refType);
|
||||
return true;
|
||||
case RefTypeResult::Unparsed:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RootedString typeStr(cx, ToString(cx, v));
|
||||
if (!typeStr) {
|
||||
return false;
|
||||
|
@ -274,18 +187,6 @@ bool wasm::ToValType(JSContext* cx, HandleValue v, ValType* out) {
|
|||
}
|
||||
|
||||
bool wasm::ToRefType(JSContext* cx, HandleValue v, RefType* out) {
|
||||
if (v.isObject()) {
|
||||
RootedObject obj(cx, &v.toObject());
|
||||
switch (MaybeToRefType(cx, obj, out)) {
|
||||
case RefTypeResult::Failure:
|
||||
return false;
|
||||
case RefTypeResult::Parsed:
|
||||
return true;
|
||||
case RefTypeResult::Unparsed:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RootedString typeStr(cx, ToString(cx, v));
|
||||
if (!typeStr) {
|
||||
return false;
|
||||
|
|
|
@ -800,7 +800,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
|
|||
checkThrows(function() { trickyObject.hasOwnProperty = 33; }, /shadow/,
|
||||
"Should reject shadowing of pre-existing inherited properties over Xrays");
|
||||
|
||||
checkThrows(function() { Object.defineProperty(trickyObject, 'rejectedProp', { get() {}}); },
|
||||
checkThrows(function() { Object.defineProperty(trickyObject, 'rejectedProp', { get() { return undefined; }}); },
|
||||
/accessor property/, "Should reject accessor property definition");
|
||||
}
|
||||
|
||||
|
|
|
@ -64,22 +64,29 @@ nsresult nsNumberControlFrame::CreateAnonymousContent(
|
|||
|
||||
nsTextControlFrame::CreateAnonymousContent(aElements);
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
// We don't want spin buttons on Android
|
||||
return NS_OK;
|
||||
#else
|
||||
// The author has elected to hide the spinner by setting this
|
||||
// -moz-appearance. We will reframe if it changes.
|
||||
if (StyleDisplay()->EffectiveAppearance() != StyleAppearance::Textfield) {
|
||||
// Create the ::-moz-number-spin-box pseudo-element:
|
||||
mSpinBox = MakeAnonElement(PseudoStyleType::mozNumberSpinBox);
|
||||
|
||||
// Create the ::-moz-number-spin-up pseudo-element:
|
||||
mSpinUp = MakeAnonElement(PseudoStyleType::mozNumberSpinUp, mSpinBox);
|
||||
|
||||
// Create the ::-moz-number-spin-down pseudo-element:
|
||||
mSpinDown = MakeAnonElement(PseudoStyleType::mozNumberSpinDown, mSpinBox);
|
||||
|
||||
aElements.AppendElement(mSpinBox);
|
||||
if (StyleDisplay()->EffectiveAppearance() == StyleAppearance::Textfield) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create the ::-moz-number-spin-box pseudo-element:
|
||||
mSpinBox = MakeAnonElement(PseudoStyleType::mozNumberSpinBox);
|
||||
|
||||
// Create the ::-moz-number-spin-up pseudo-element:
|
||||
mSpinUp = MakeAnonElement(PseudoStyleType::mozNumberSpinUp, mSpinBox);
|
||||
|
||||
// Create the ::-moz-number-spin-down pseudo-element:
|
||||
mSpinDown = MakeAnonElement(PseudoStyleType::mozNumberSpinDown, mSpinBox);
|
||||
|
||||
aElements.AppendElement(mSpinBox);
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
|
|
@ -5413,7 +5413,15 @@ static FrameTarget GetSelectionClosestFrame(nsIFrame* aFrame,
|
|||
const nsPoint& aPoint,
|
||||
uint32_t aFlags);
|
||||
|
||||
static bool SelfIsSelectable(nsIFrame* aFrame, uint32_t aFlags) {
|
||||
static bool SelfIsSelectable(nsIFrame* aFrame, nsIFrame* aParentFrame,
|
||||
uint32_t aFlags) {
|
||||
// We should not move selection into a native anonymous subtree when handling
|
||||
// selection outside it.
|
||||
if ((aFlags & nsIFrame::IGNORE_NATIVE_ANONYMOUS_SUBTREE) &&
|
||||
aParentFrame->GetClosestNativeAnonymousSubtreeRoot() !=
|
||||
aFrame->GetClosestNativeAnonymousSubtreeRoot()) {
|
||||
return false;
|
||||
}
|
||||
if ((aFlags & nsIFrame::SKIP_HIDDEN) &&
|
||||
!aFrame->StyleVisibility()->IsVisible()) {
|
||||
return false;
|
||||
|
@ -5476,21 +5484,28 @@ static FrameTarget DrillDownToSelectionFrame(nsIFrame* aFrame, bool aEndFrame,
|
|||
nsIFrame* result = nullptr;
|
||||
nsIFrame* frame = aFrame->PrincipalChildList().FirstChild();
|
||||
if (!aEndFrame) {
|
||||
while (frame && (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty()))
|
||||
while (frame &&
|
||||
(!SelfIsSelectable(frame, aFrame, aFlags) || frame->IsEmpty())) {
|
||||
frame = frame->GetNextSibling();
|
||||
if (frame) result = frame;
|
||||
}
|
||||
if (frame) {
|
||||
result = frame;
|
||||
}
|
||||
} else {
|
||||
// Because the frame tree is singly linked, to find the last frame,
|
||||
// we have to iterate through all the frames
|
||||
// XXX I have a feeling this could be slow for long blocks, although
|
||||
// I can't find any slowdowns
|
||||
while (frame) {
|
||||
if (!frame->IsEmpty() && SelfIsSelectable(frame, aFlags))
|
||||
if (!frame->IsEmpty() && SelfIsSelectable(frame, aFrame, aFlags)) {
|
||||
result = frame;
|
||||
}
|
||||
frame = frame->GetNextSibling();
|
||||
}
|
||||
}
|
||||
if (result) return DrillDownToSelectionFrame(result, aEndFrame, aFlags);
|
||||
if (result) {
|
||||
return DrillDownToSelectionFrame(result, aEndFrame, aFlags);
|
||||
}
|
||||
}
|
||||
// If the current frame has no targetable children, target the current frame
|
||||
return FrameTarget{aFrame, true, aEndFrame};
|
||||
|
@ -5502,8 +5517,9 @@ static FrameTarget GetSelectionClosestFrameForLine(
|
|||
nsBlockFrame* aParent, nsBlockFrame::LineIterator aLine,
|
||||
const nsPoint& aPoint, uint32_t aFlags) {
|
||||
// Account for end of lines (any iterator from the block is valid)
|
||||
if (aLine == aParent->LinesEnd())
|
||||
if (aLine == aParent->LinesEnd()) {
|
||||
return DrillDownToSelectionFrame(aParent, true, aFlags);
|
||||
}
|
||||
nsIFrame* frame = aLine->mFirstChild;
|
||||
nsIFrame* closestFromIStart = nullptr;
|
||||
nsIFrame* closestFromIEnd = nullptr;
|
||||
|
@ -5519,7 +5535,7 @@ static FrameTarget GetSelectionClosestFrameForLine(
|
|||
// the previous thing had a different editableness than us, since then we
|
||||
// may end up not being able to select after it if the br is the last thing
|
||||
// on the line.
|
||||
if (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty() ||
|
||||
if (!SelfIsSelectable(frame, aParent, aFlags) || frame->IsEmpty() ||
|
||||
(canSkipBr && frame->IsBrFrame() &&
|
||||
lastFrameWasEditable == frame->GetContent()->IsEditable())) {
|
||||
continue;
|
||||
|
@ -5699,7 +5715,7 @@ static FrameTarget GetSelectionClosestFrame(nsIFrame* aFrame,
|
|||
// Go through all the child frames to find the closest one
|
||||
nsIFrame::FrameWithDistance closest = {nullptr, nscoord_MAX, nscoord_MAX};
|
||||
for (; kid; kid = kid->GetNextSibling()) {
|
||||
if (!SelfIsSelectable(kid, aFlags) || kid->IsEmpty()) {
|
||||
if (!SelfIsSelectable(kid, aFrame, aFlags) || kid->IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -9391,7 +9407,8 @@ nsresult nsIFrame::PeekOffsetForLineEdge(PeekOffsetStruct* aPos) {
|
|||
}
|
||||
}
|
||||
}
|
||||
FrameTarget targetFrame = DrillDownToSelectionFrame(baseFrame, endOfLine, 0);
|
||||
FrameTarget targetFrame = DrillDownToSelectionFrame(
|
||||
baseFrame, endOfLine, nsIFrame::IGNORE_NATIVE_ANONYMOUS_SUBTREE);
|
||||
SetPeekResultFromFrame(*aPos, targetFrame.frame, endOfLine ? -1 : 0,
|
||||
OffsetIsAtLineEdge::Yes);
|
||||
if (endOfLine && targetFrame.frame->HasSignificantTerminalNewline()) {
|
||||
|
|
2
layout/reftests/forms/input/number/number.html
Normal file
2
layout/reftests/forms/input/number/number.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
<!doctype html>
|
||||
<input type=number>
|
|
@ -1,5 +1,5 @@
|
|||
# sanity checks:
|
||||
!= not-other-type-unthemed-1.html not-other-type-unthemed-1a-notref.html
|
||||
fails-if(Android) pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,false) != not-other-type-unthemed-1.html not-other-type-unthemed-1a-notref.html
|
||||
!= not-other-type-unthemed-1.html not-other-type-unthemed-1b-notref.html
|
||||
|
||||
# should look the same as type=text, except for the spin box
|
||||
|
@ -17,7 +17,7 @@ fuzzy(0-2,0-13) == show-value.html show-value-ref.html
|
|||
|
||||
# disabled
|
||||
== number-disabled.html number-disabled-ref.html
|
||||
!= number-spinbox-disabled.html number-spinbox-disabled-notref.html
|
||||
fails-if(Android) pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,false) != number-spinbox-disabled.html number-spinbox-disabled-notref.html
|
||||
|
||||
# auto width:
|
||||
== number-auto-width-1.html number-auto-width-1-ref.html
|
||||
|
@ -72,3 +72,5 @@ fuzzy(0-14,0-4) == clipped-text.html clipped-text-ref.html
|
|||
fails-if(useDrawSnapshot) needs-focus != caret-right.html caret-right-notref.html
|
||||
fails-if(useDrawSnapshot) needs-focus != caret-left-rtl.html caret-left-rtl-notref.html
|
||||
fails-if(useDrawSnapshot) needs-focus != caret-right-vertical.html caret-right-vertical-notref.html
|
||||
|
||||
fails-if(Android) test-pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,true) ref-pref(dom.forms.number.hide_spin_buttons_when_no_hover_or_focus,false) != number.html number.html
|
||||
|
|
|
@ -868,6 +868,13 @@ input[type=number]::-moz-number-spin-box {
|
|||
overflow: clip;
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line media-query-no-invalid */
|
||||
@media (-moz-bool-pref: "dom.forms.number.hide_spin_buttons_when_no_hover_or_focus") {
|
||||
input[type=number]:not(:hover, :focus)::-moz-number-spin-box {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=number]::-moz-number-spin-up,
|
||||
input[type=number]::-moz-number-spin-down {
|
||||
writing-mode: horizontal-tb;
|
||||
|
|
|
@ -252,7 +252,7 @@ class ReftestResolver(object):
|
|||
rv = [
|
||||
(
|
||||
os.path.join(dirname, default_manifest),
|
||||
r".*%s(?:[#?].*)?$" % pathname.replace("?", "\?"),
|
||||
r".*%s(?:[#?].*)?$" % pathname.replace("?", r"\?"),
|
||||
)
|
||||
]
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ def substs(variables, values):
|
|||
|
||||
# Safe substitute leaves unrecognized variables in place.
|
||||
# We replace them with the empty string.
|
||||
new_values.append(re.sub('\$\{\w+\}', '', new_value))
|
||||
new_values.append(re.sub(r'\$\{\w+\}', '', new_value))
|
||||
return new_values
|
||||
|
||||
|
||||
|
@ -240,7 +240,7 @@ def evaluate_boolean(variables, arguments):
|
|||
# If statements can have old-style variables which are not demarcated
|
||||
# like ${VARIABLE}. Attempt to look up the variable both ways.
|
||||
try:
|
||||
if re.search('\$\{\w+\}', argument):
|
||||
if re.search(r'\$\{\w+\}', argument):
|
||||
try:
|
||||
t = Template(argument)
|
||||
value = t.substitute(variables)
|
||||
|
|
|
@ -2351,7 +2351,7 @@
|
|||
# see https://html.spec.whatwg.org/#the-popover-attribute
|
||||
- name: dom.element.popover.enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
value: true
|
||||
mirror: always
|
||||
rust: true
|
||||
|
||||
|
@ -2635,6 +2635,13 @@
|
|||
value: false
|
||||
mirror: always
|
||||
|
||||
# Whether the spin buttons will always appear, or if they
|
||||
# will only appear when the input is focused or hovered.
|
||||
- name: dom.forms.number.hide_spin_buttons_when_no_hover_or_focus
|
||||
type: bool
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
||||
# Whether the Gamepad API is enabled
|
||||
- name: dom.gamepad.enabled
|
||||
type: bool
|
||||
|
|
|
@ -579,6 +579,8 @@ nsresult ResolveHTTPSRecordImpl(const nsACString& aHost, uint16_t aFlags,
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void DNSThreadShutdown() {}
|
||||
|
||||
#endif // MOZ_NO_HTTPS_IMPL
|
||||
|
||||
} // namespace mozilla::net
|
||||
|
|
|
@ -527,6 +527,10 @@ nsresult Http3WebTransportStream::WriteSegments() {
|
|||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
mReceiveStreamPipeOut->Close();
|
||||
rv = NS_OK;
|
||||
}
|
||||
again = false;
|
||||
} else if (NS_FAILED(mSocketInCondition)) {
|
||||
if (mSocketInCondition != NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
|
|
|
@ -3090,30 +3090,19 @@ HttpChannelChild::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
|
|||
|
||||
void HttpChannelChild::TrySendDeletingChannel() {
|
||||
AUTO_PROFILER_LABEL("HttpChannelChild::TrySendDeletingChannel", NETWORK);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mDeletingChannelSent.compareExchange(false, true)) {
|
||||
// SendDeletingChannel is already sent.
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
if (NS_WARN_IF(!CanSend())) {
|
||||
// IPC actor is destroyed already, do not send more messages.
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << PHttpChannelChild::SendDeletingChannel();
|
||||
if (NS_WARN_IF(!CanSend())) {
|
||||
// IPC actor is destroyed already, do not send more messages.
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
|
||||
MOZ_ASSERT(neckoTarget);
|
||||
|
||||
DebugOnly<nsresult> rv = neckoTarget->Dispatch(
|
||||
NewNonOwningRunnableMethod(
|
||||
"net::HttpChannelChild::TrySendDeletingChannel", this,
|
||||
&HttpChannelChild::TrySendDeletingChannel),
|
||||
NS_DISPATCH_NORMAL);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
Unused << PHttpChannelChild::SendDeletingChannel();
|
||||
}
|
||||
|
||||
nsresult HttpChannelChild::AsyncCallImpl(
|
||||
|
|
|
@ -6963,7 +6963,7 @@ nsHttpChannel::OnProxyAvailable(nsICancelable* request, nsIChannel* channel,
|
|||
mProxyInfo->GetType(type);
|
||||
uint32_t flags = 0;
|
||||
mProxyInfo->GetFlags(&flags);
|
||||
printf("type=%s, flags=%i\n", type.get(), flags);
|
||||
|
||||
if (type.EqualsLiteral("socks")) {
|
||||
if (flags & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) {
|
||||
glean::networking::proxy_info_type
|
||||
|
|
|
@ -525,3 +525,27 @@ function makeHTTPChannel(url, with_proxy) {
|
|||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
}
|
||||
|
||||
// Like ChannelListener but does not throw an exception if something
|
||||
// goes wrong. Callback is supposed to do all the work.
|
||||
class SimpleChannelListener {
|
||||
constructor(callback) {
|
||||
this._onStopCallback = callback;
|
||||
this._buffer = "";
|
||||
}
|
||||
get QueryInterface() {
|
||||
return ChromeUtils.generateQI(["nsIStreamListener", "nsIRequestObserver"]);
|
||||
}
|
||||
|
||||
onStartRequest(request) {}
|
||||
|
||||
onDataAvailable(request, stream, offset, count) {
|
||||
this._buffer = this._buffer.concat(read_stream(stream, count));
|
||||
}
|
||||
|
||||
onStopRequest(request, status) {
|
||||
if (this._onStopCallback) {
|
||||
this._onStopCallback(request, this._buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,32 +18,41 @@ var httpbody = "0123456789";
|
|||
|
||||
var live_channels = [];
|
||||
|
||||
function run_test() {
|
||||
add_task(async function test() {
|
||||
httpserver.registerPathHandler(testpath, serverHandler);
|
||||
httpserver.start(-1);
|
||||
registerCleanupFunction(async () => {
|
||||
if (httpserver) {
|
||||
await httpserver.stop();
|
||||
}
|
||||
});
|
||||
|
||||
httpProtocolHandler.EnsureHSTSDataReady().then(function () {
|
||||
var local_channel;
|
||||
await httpProtocolHandler.EnsureHSTSDataReady();
|
||||
|
||||
// Opened channel that has no remaining references on shutdown
|
||||
local_channel = setupChannel(testpath);
|
||||
local_channel.asyncOpen(new ChannelListener(checkRequest, local_channel));
|
||||
// Opened channel that has no remaining references on shutdown
|
||||
let local_channel = setupChannel(testpath);
|
||||
local_channel.asyncOpen(new SimpleChannelListener());
|
||||
|
||||
// Opened channel that has no remaining references after being opened
|
||||
setupChannel(testpath).asyncOpen(new ChannelListener(function () {}, null));
|
||||
// Opened channel that has no remaining references after being opened
|
||||
setupChannel(testpath).asyncOpen(new SimpleChannelListener());
|
||||
|
||||
// Unopened channel that has remaining references on shutdown
|
||||
live_channels.push(setupChannel(testpath));
|
||||
// Unopened channel that has remaining references on shutdown
|
||||
live_channels.push(setupChannel(testpath));
|
||||
|
||||
// Opened channel that has remaining references on shutdown
|
||||
live_channels.push(setupChannel(testpath));
|
||||
// Opened channel that has remaining references on shutdown
|
||||
live_channels.push(setupChannel(testpath));
|
||||
await new Promise(resolve => {
|
||||
live_channels[1].asyncOpen(
|
||||
new ChannelListener(checkRequestFinish, live_channels[1])
|
||||
new SimpleChannelListener((req, data) => {
|
||||
Assert.equal(data, httpbody);
|
||||
resolve();
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
do_test_pending();
|
||||
}
|
||||
await httpserver.stop();
|
||||
httpserver = null;
|
||||
});
|
||||
|
||||
function setupChannel(path) {
|
||||
var chan = NetUtil.newChannel({
|
||||
|
@ -59,12 +68,3 @@ function serverHandler(metadata, response) {
|
|||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.bodyOutputStream.write(httpbody, httpbody.length);
|
||||
}
|
||||
|
||||
function checkRequest(request, data, context) {
|
||||
Assert.equal(data, httpbody);
|
||||
}
|
||||
|
||||
function checkRequestFinish(request, data, context) {
|
||||
checkRequest(request, data, context);
|
||||
httpserver.stop(do_test_finished);
|
||||
}
|
||||
|
|
|
@ -434,7 +434,6 @@ run-sequentially = "node server exceptions dont replay well"
|
|||
run-sequentially = "node server exceptions dont replay well"
|
||||
|
||||
["test_channel_close.js"]
|
||||
skip-if = ["socketprocess_networking"]
|
||||
|
||||
["test_channel_long_domain.js"]
|
||||
|
||||
|
|
|
@ -46,13 +46,13 @@ def toggle_beta_status(is_beta):
|
|||
check_files_exist()
|
||||
if (is_beta):
|
||||
print("adding Beta status to version numbers")
|
||||
sed_inplace('s/^\(#define *PR_VERSION *\"[0-9.]\+\)\" *$/\\1 Beta\"/', prinit_h)
|
||||
sed_inplace('s/^\(#define *PR_BETA *\)PR_FALSE *$/\\1PR_TRUE/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_VERSION *\"[0-9.]\\+\\)\" *$/\\1 Beta\"/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_BETA *\\)PR_FALSE *$/\\1PR_TRUE/', prinit_h)
|
||||
|
||||
else:
|
||||
print("removing Beta status from version numbers")
|
||||
sed_inplace('s/^\(#define *PR_VERSION *\"[0-9.]\+\) *Beta\" *$/\\1\"/', prinit_h)
|
||||
sed_inplace('s/^\(#define *PR_BETA *\)PR_TRUE *$/\\1PR_FALSE/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_VERSION *\"[0-9.]\\+\\) *Beta\" *$/\\1\"/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_BETA *\\)PR_TRUE *$/\\1PR_FALSE/', prinit_h)
|
||||
print("please run 'hg stat' and 'hg diff' to verify the files have been verified correctly")
|
||||
|
||||
def print_beta_versions():
|
||||
|
@ -81,22 +81,22 @@ def ensure_arguments_after_action(how_many, usage):
|
|||
exit_with_failure("incorrect number of arguments, expected parameters are:\n" + usage)
|
||||
|
||||
def set_major_versions(major):
|
||||
sed_inplace('s/^\(#define *PR_VMAJOR *\).*$/\\1' + major + '/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_VMAJOR *\\).*$/\\1' + major + '/', prinit_h)
|
||||
sed_inplace('s/^MOD_MAJOR_VERSION=.*$/MOD_MAJOR_VERSION=' + major + '/', f_conf)
|
||||
sed_inplace('s/^MOD_MAJOR_VERSION=.*$/MOD_MAJOR_VERSION=' + major + '/', f_conf_in)
|
||||
|
||||
def set_minor_versions(minor):
|
||||
sed_inplace('s/^\(#define *PR_VMINOR *\).*$/\\1' + minor + '/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_VMINOR *\\).*$/\\1' + minor + '/', prinit_h)
|
||||
sed_inplace('s/^MOD_MINOR_VERSION=.*$/MOD_MINOR_VERSION=' + minor + '/', f_conf)
|
||||
sed_inplace('s/^MOD_MINOR_VERSION=.*$/MOD_MINOR_VERSION=' + minor + '/', f_conf_in)
|
||||
|
||||
def set_patch_versions(patch):
|
||||
sed_inplace('s/^\(#define *PR_VPATCH *\).*$/\\1' + patch + '/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_VPATCH *\\).*$/\\1' + patch + '/', prinit_h)
|
||||
sed_inplace('s/^MOD_PATCH_VERSION=.*$/MOD_PATCH_VERSION=' + patch + '/', f_conf)
|
||||
sed_inplace('s/^MOD_PATCH_VERSION=.*$/MOD_PATCH_VERSION=' + patch + '/', f_conf_in)
|
||||
|
||||
def set_full_lib_versions(version):
|
||||
sed_inplace('s/^\(#define *PR_VERSION *\"\)\([0-9.]\+\)\(.*\)$/\\1' + version + '\\3/', prinit_h)
|
||||
sed_inplace('s/^\\(#define *PR_VERSION *\"\\)\\([0-9.]\\+\\)\\(.*\\)$/\\1' + version + '\\3/', prinit_h)
|
||||
|
||||
def set_all_lib_versions(version, major, minor, patch):
|
||||
set_full_lib_versions(version)
|
||||
|
|
|
@ -10,7 +10,7 @@ class STRIP_LABEL(TransformPattern):
|
|||
# Used to remove `<label data-l10n-name="remove-search-engine-article">` from a string
|
||||
def visit_TextElement(self, node):
|
||||
node.value = re.sub(
|
||||
'\s?<label data-l10n-name="remove-search-engine-article">.+?</label>\s?',
|
||||
r'\s?<label data-l10n-name="remove-search-engine-article">.+?</label>\s?',
|
||||
"",
|
||||
node.value,
|
||||
)
|
||||
|
|
|
@ -375,7 +375,7 @@ def parse_chrome_manifest(path, base_path, chrome_entries):
|
|||
###
|
||||
def get_version_maybe_buildid(app_version):
|
||||
def _extract_numeric_part(part):
|
||||
matches = re.compile("[^\d]").search(part)
|
||||
matches = re.compile(r"[^\d]").search(part)
|
||||
if matches:
|
||||
part = part[0 : matches.start()]
|
||||
if len(part) == 0:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue