Merge autoland to mozilla-central. a=merge

This commit is contained in:
Ciure Andrei 2019-05-24 06:52:59 +03:00
Родитель 90fa4c6afd ed8cf51b98
Коммит c7c661056f
236 изменённых файлов: 18667 добавлений и 4652 удалений

53
Cargo.lock сгенерированный
Просмотреть файл

@ -1211,7 +1211,7 @@ dependencies = [
"malloc_size_of 0.0.1",
"nsstring 0.1.0",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.21.0",
"servo_arc 0.1.1",
"smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1280,7 +1280,7 @@ dependencies = [
"rsdparsa_capi 0.1.0",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"storage 0.1.0",
"u2fhid 0.2.3",
"u2fhid 0.2.4",
"webrender_bindings 0.1.0",
"xpcom 0.1.0",
"xulstore 0.1.0",
@ -1648,11 +1648,10 @@ dependencies = [
[[package]]
name = "lock_api"
version = "0.1.5"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1890,7 +1889,7 @@ dependencies = [
"nserror 0.1.0",
"nsstring 0.1.0",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"xpcom 0.1.0",
]
@ -2119,20 +2118,25 @@ dependencies = [
[[package]]
name = "parking_lot"
version = "0.6.3"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.2.14"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
]
@ -2527,7 +2531,7 @@ dependencies = [
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2626,6 +2630,11 @@ name = "scopeguard"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scopeguard"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scroll"
version = "0.9.2"
@ -2889,7 +2898,7 @@ dependencies = [
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3290,7 +3299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "u2fhid"
version = "0.2.3"
version = "0.2.4"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3299,7 +3308,7 @@ dependencies = [
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
"libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
]
@ -3379,8 +3388,11 @@ dependencies = [
[[package]]
name = "uuid"
version = "0.7.1"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vcpkg"
@ -3851,7 +3863,7 @@ dependencies = [
"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
"checksum lmdb-rkv 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1452294309db7977dc75e1e8135a8c654d9e52e04ff0c0bd06c880897a91defd"
"checksum lmdb-rkv-sys 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1470e0168f1832e35afd6d0931ae60db625685332837b97aa156773ec9c5e393"
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
@ -3891,8 +3903,8 @@ dependencies = [
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
"checksum packed_simd 0.3.3 (git+https://github.com/hsivonen/packed_simd?branch=rust_1_32)" = "<none>"
"checksum parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69376b761943787ebd5cc85a5bc95958651a22609c5c1c2b65de21786baec72b"
"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7"
"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
@ -3947,6 +3959,7 @@ dependencies = [
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
"checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
@ -4012,7 +4025,7 @@ dependencies = [
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363"
"checksum uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dab5c5526c5caa3d106653401a267fed923e7046f35895ffcb5ca42db64942e6"
"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

Просмотреть файл

@ -56,11 +56,6 @@ RANLIB=llvm-ranlib
# For Stylo
BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/i686-w64-mingw32/include"
# Bug 1471698 - Work around binutils corrupting mingw clang binaries.
LDFLAGS="-Wl,-S"
STRIP=/bin/true
OBJCOPY=/bin/true
# We want to make sure we use binutils and other binaries in the tooltool
# package.
mk_add_options "export PATH=$TOOLTOOL_DIR/clang/bin:$TOOLTOOL_DIR/mingw32/bin:$TOOLTOOL_DIR/wine/bin:$TOOLTOOL_DIR/upx/bin:$TOOLTOOL_DIR/fxc2/bin:$PATH"

Просмотреть файл

@ -56,11 +56,6 @@ RANLIB=llvm-ranlib
# For Stylo
BINDGEN_CFLAGS="-I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include/c++/v1 -I$TOOLTOOL_DIR/clang/x86_64-w64-mingw32/include"
# Bug 1471698 - Work around binutils corrupting mingw clang binaries.
LDFLAGS="-Wl,-S"
STRIP=/bin/true
OBJCOPY=/bin/true
# We want to make sure we use binutils and other binaries in the tooltool
# package.
mk_add_options "export PATH=$TOOLTOOL_DIR/clang/bin:$TOOLTOOL_DIR/mingw32/bin:$TOOLTOOL_DIR/wine/bin:$TOOLTOOL_DIR/upx/bin:$TOOLTOOL_DIR/fxc2/bin:$PATH"

Просмотреть файл

@ -140,18 +140,6 @@ var OSKeyStore = {
}
});
if (nativeOSKeyStore.isNSSKeyStore) {
// Workaround bug 1492305: NSS-implemented methods don't reject when user cancels.
unlockPromise = unlockPromise.then(() => {
log.debug("ensureLoggedIn: isNSSKeyStore: ", reauth, Services.logins.isLoggedIn);
// User has hit the cancel button on the master password prompt.
// We must reject the promise chain here.
if (!Services.logins.isLoggedIn) {
throw Components.Exception("User canceled OS unlock entry (Workaround)", Cr.NS_ERROR_FAILURE);
}
});
}
unlockPromise = unlockPromise.then(() => {
log.debug("ensureLoggedIn: Logged in");
this._pendingUnlockPromise = null;

Просмотреть файл

@ -15,7 +15,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -36,7 +36,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -57,7 +57,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -78,7 +78,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -99,7 +99,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -120,7 +120,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -141,7 +141,7 @@
"byName": {},
"byBlocks": {},
"usedIds": {
"0": 0
"1": 1
}
}
}
@ -639,7 +639,16 @@
"../../babel-loader/lib/index.js?ignore=src/lib!../../../packages/devtools-reps/src/object-inspector/utils/selection.js": 488,
"../../css-loader/lib/css-base.js": 489,
"external \"devtools/client/framework/menu\"": 490,
"external \"devtools/client/framework/menu-item\"": 491
"external \"devtools/client/framework/menu-item\"": 491,
"../../whatwg-url/lib/url-state-machine.js": 492,
"../../whatwg-url/lib/urlencoded.js": 493,
"../../whatwg-url/lib/utils.js": 494,
"../../whatwg-url/lib/infra.js": 495,
"../../whatwg-url/lib/URLSearchParams.js": 496,
"../../whatwg-url/lib/public-api.js": 497,
"../../whatwg-url/lib/URL.js": 498,
"../../whatwg-url/lib/URL-impl.js": 499,
"../../whatwg-url/lib/URLSearchParams-impl.js": 500
},
"usedIds": {
"0": 0,
@ -1133,7 +1142,16 @@
"488": 488,
"489": 489,
"490": 490,
"491": 491
"491": 491,
"492": 492,
"493": 493,
"494": 494,
"495": 495,
"496": 496,
"497": 497,
"498": 498,
"499": 499,
"500": 500
}
},
"chunks": {

8363
devtools/client/debugger/dist/vendors.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

7
devtools/client/debugger/flow-typed/npm/whatwg-url_vx.x.x.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
declare module "whatwg-url" {
declare module.exports: any;
}

Просмотреть файл

@ -77,7 +77,8 @@
"react-transition-group": "^2.2.1",
"reselect": "^4.0.0",
"svg-inline-react": "^3.0.0",
"wasmparser": "^0.7.0"
"wasmparser": "^0.7.0",
"whatwg-url": "^7.0.0"
},
"private": true,
"workspaces": [

Просмотреть файл

@ -93,8 +93,8 @@ function traverseTree(
source: Source,
thread: string
): TreeNode {
const parts = url.path.split("/").filter(p => p !== "");
parts.unshift(url.group);
const parts = url.path.replace(/\/$/, "").split("/");
parts[0] = url.group;
if (thread) {
parts.unshift(thread);
}

Просмотреть файл

@ -88,24 +88,3 @@ exports[`sources-tree addToTree supports data URLs 1`] = `
- data:text/html,<script>console.log(123)</script> path=data:text/html,<script>console.log(123)</script> source_id=server1.conn13.child1/39
"
`;
exports[`sources-tree addToTree uses debuggeeUrl as default 1`] = `
" - root path=
- localhost:4242 path=localhost:4242
- components path=localhost:4242/components
- Header.js path=localhost:4242/components/Header.js source_id=undefined
- TodoItem.js path=localhost:4242/components/TodoItem.js source_id=undefined
- TodoTextInput.js path=localhost:4242/components/TodoTextInput.js source_id=undefined
- reducers path=localhost:4242/reducers
- index.js path=localhost:4242/reducers/index.js source_id=undefined
- index.js path=localhost:4242/index.js source_id=undefined
- resource://gre path=resource://gre
- modules path=resource://gre/modules
- ExtensionContent.jsm path=resource://gre/modules/ExtensionContent.jsm source_id=undefined
- voz37vlg5.codesandbox.io path=voz37vlg5.codesandbox.io
- static path=voz37vlg5.codesandbox.io/static
- js path=voz37vlg5.codesandbox.io/static/js
- components path=voz37vlg5.codesandbox.io/static/js/components
- TodoItem.js path=voz37vlg5.codesandbox.io/static/js/components/TodoItem.js source_id=undefined
"
`;

Просмотреть файл

@ -78,6 +78,70 @@ describe("sources-tree", () => {
expect(source1Node.name).toBe("source1.js");
});
it("builds a path-based tree for webpack URLs", () => {
const source1 = makeMockSource("webpack:///foo/source1.js", "actor1");
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source1, "http://example.com/", "");
expect(tree.contents).toHaveLength(1);
const base = tree.contents[0];
expect(base.name).toBe("webpack://");
expect(base.contents).toHaveLength(1);
const fooNode = base.contents[0];
expect(fooNode.name).toBe("foo");
expect(fooNode.contents).toHaveLength(1);
const source1Node = fooNode.contents[0];
expect(source1Node.name).toBe("source1.js");
});
it("builds a path-based tree for webpack URLs with absolute path", () => {
const source1 = makeMockSource(
"webpack:////Users/foo/source1.js",
"actor1"
);
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source1, "http://example.com/", "");
expect(tree.contents).toHaveLength(1);
const base = tree.contents[0];
expect(base.name).toBe("webpack://");
expect(base.contents).toHaveLength(1);
const emptyNode = base.contents[0];
expect(emptyNode.name).toBe("");
expect(emptyNode.contents).toHaveLength(1);
const userNode = emptyNode.contents[0];
expect(userNode.name).toBe("Users");
expect(userNode.contents).toHaveLength(1);
const fooNode = userNode.contents[0];
expect(fooNode.name).toBe("foo");
expect(fooNode.contents).toHaveLength(1);
const source1Node = fooNode.contents[0];
expect(source1Node.name).toBe("source1.js");
});
it("handles url with no filename", function() {
const source1 = makeMockSource("http://example.com/", "actor1");
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source1, "http://example.com/", "");
expect(tree.contents).toHaveLength(1);
const base = tree.contents[0];
expect(base.name).toBe("example.com");
expect(base.contents).toHaveLength(1);
const indexNode = base.contents[0];
expect(indexNode.name).toBe("(index)");
});
it("does not mangle encoded URLs", () => {
const sourceName = // eslint-disable-next-line max-len
"B9724220.131821496;dc_ver=42.111;sz=468x60;u_sd=2;dc_adk=2020465299;ord=a53rpc;dc_rfl=1,https%3A%2F%2Fdavidwalsh.name%2F$0;xdt=1";
@ -293,38 +357,5 @@ describe("sources-tree", () => {
);
expect(formatTree(tree)).toMatchSnapshot();
});
it.skip("uses debuggeeUrl as default", () => {
const testData = [
{
url: "components/TodoTextInput.js",
},
{
url: "components/Header.js",
},
{
url: "reducers/index.js",
},
{
url: "components/TodoItem.js",
},
{
url: "resource://gre/modules/ExtensionContent.jsm",
},
{
url:
"https://voz37vlg5.codesandbox.io/static/js/components/TodoItem.js",
},
{
url: "index.js",
},
];
const domain = "http://localhost:4242";
const sources = createSourcesList(testData);
const tree = createDirectoryNode("root", "", []);
sources.forEach(source => addToTree(tree, source, domain, "FakeThread"));
expect(formatTree(tree)).toMatchSnapshot();
});
});
});

Просмотреть файл

@ -88,10 +88,20 @@ describe("getUrl", () => {
it("creates a group name for webpack", () => {
const urlObject = getURL(
createMockSource({
url: "webpack://src/component.jsx",
url: "webpack:///src/component.jsx",
id: "c3",
})
);
expect(urlObject.group).toBe("webpack://");
});
it("creates a group name for angular source", () => {
const urlObject = getURL(
createMockSource({
url: "ng://src/component.jsx",
id: "c3",
})
);
expect(urlObject.group).toBe("ng://");
});
});

Просмотреть файл

@ -3,8 +3,8 @@
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
// @flow
import { memoize } from "lodash";
import { URL } from "whatwg-url";
const defaultUrl = {
hash: "",

Просмотреть файл

@ -28,6 +28,7 @@ import * as fuzzaldrinPlus from "fuzzaldrin-plus";
import * as transition from "react-transition-group/Transition";
import * as reactAriaComponentsTabs from "react-aria-components/src/tabs";
import * as reselect from "reselect";
import * as whatwgUrl from "whatwg-url";
// Modules imported without destructuring
import classnames from "classnames";
@ -51,5 +52,6 @@ export const vendored = {
"lodash-move": move,
"react-aria-components/src/tabs": reactAriaComponentsTabs,
"react-transition-group/Transition": transition,
"whatwg-url": whatwgUrl,
reselect,
};

Просмотреть файл

@ -37,7 +37,9 @@ add_task(async function() {
ok(refreshedDoc.querySelector(".debug-target-info"),
"about:devtools-toolbox header is correctly displayed");
const onToolboxDestroy = gDevTools.once("toolbox-destroyed");
await removeTab(tab);
await onToolboxDestroy;
await removeTab(targetTab);
});

Просмотреть файл

@ -16,7 +16,7 @@ const EXCLUDED_FILES = {
"devtools-launchpad": "devtools/shared/flags",
};
const mappings = Object.assign(
const mappings = Object.assign(
{
"./source-editor": "devtools/client/shared/sourceeditor/editor",
"../editor/source-editor": "devtools/client/shared/sourceeditor/editor",
@ -64,6 +64,7 @@ const VENDORS = [
"react-aria-components/src/tabs",
"react-transition-group/Transition",
"reselect",
"whatwg-url",
"Svg",
];
@ -73,13 +74,13 @@ const moduleMapping = {
};
/*
* Updates devtools-modules imports such as
* `import { Telemetry } from "devtools-modules"`
* so that we can customize how we resolve certain modules in the package
*
* In the case of multiple declarations we need to move
* the telemetry module into its own import.
*/
* Updates devtools-modules imports such as
* `import { Telemetry } from "devtools-modules"`
* so that we can customize how we resolve certain modules in the package
*
* In the case of multiple declarations we need to move
* the telemetry module into its own import.
*/
function updateDevtoolsModulesImport(path, t) {
const specifiers = path.node.specifiers;
@ -106,9 +107,9 @@ function updateDevtoolsModulesImport(path, t) {
}
/**
* This Babel plugin is used to transpile a single Debugger module into a module that
* can be loaded in Firefox via the regular DevTools loader.
*/
* This Babel plugin is used to transpile a single Debugger module into a module that
* can be loaded in Firefox via the regular DevTools loader.
*/
function transformMC({ types: t }) {
return {
visitor: {

Просмотреть файл

@ -40,6 +40,7 @@ var gObserver = new MutationObserver(newRecords => {
});
function setupAsynchronousObserver(t, options) {
gRecords = [];
t.add_cleanup(() => {
gObserver.disconnect();
@ -647,5 +648,17 @@ promise_test(async t => {
);
}, 'Animations automatically removed are reported');
runTest();
setup({explicit_done: true});
SpecialPowers.pushPrefEnv(
{
set: [
["dom.animations-api.autoremove.enabled", true],
["dom.animations-api.implicit-keyframes.enabled", true],
],
},
function() {
runTest();
done();
}
);
</script>

Просмотреть файл

@ -7885,10 +7885,6 @@ void Document::Destroy() {
mIsGoingAway = true;
if (mDocumentL10n) {
mDocumentL10n->Destroy();
}
ScriptLoader()->Destroy();
SetScriptGlobalObject(nullptr);
RemovedFromDocShell();

Просмотреть файл

@ -224,10 +224,6 @@ DOMInterfaces = {
'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
},
'DocumentL10n': {
'implicitJSContext': ['translateFragment'],
},
'DominatorTree': {
'nativeType': 'mozilla::devtools::DominatorTree'
},
@ -1175,6 +1171,11 @@ DOMInterfaces = {
'headerFile': 'WebGLExtensions.h'
},
'OVR_multiview2': {
'nativeType': 'mozilla::WebGLExtensionMultiview',
'headerFile': 'WebGLExtensions.h'
},
'WEBGL_compressed_texture_astc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureASTC',
'headerFile': 'WebGLExtensions.h'

Просмотреть файл

@ -58,8 +58,6 @@ class WebGL2Context : public WebGLContext {
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
void FramebufferTextureLayer(GLenum target, GLenum attachment,
WebGLTexture* texture, GLint level, GLint layer);
virtual JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
GLenum target,

Просмотреть файл

@ -66,34 +66,6 @@ void WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1,
dstY0, dstX1, dstY1, mask, filter);
}
void WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment,
WebGLTexture* texture, GLint level,
GLint layer) {
const FuncScope funcScope(*this, "framebufferTextureLayer");
if (IsContextLost()) return;
if (!ValidateFramebufferTarget(target)) return;
WebGLFramebuffer* fb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
break;
default:
MOZ_CRASH("GFX: Bad target.");
}
if (!fb) return ErrorInvalidOperation("Cannot modify framebuffer 0.");
fb->FramebufferTextureLayer(attachment, texture, level, layer);
}
JS::Value WebGL2Context::GetFramebufferAttachmentParameter(
JSContext* cx, GLenum target, GLenum attachment, GLenum pname,
ErrorResult& out_error) {

Просмотреть файл

@ -99,6 +99,7 @@ class MozFramebuffer;
namespace webgl {
class AvailabilityRunnable;
struct CachedDrawFetchLimits;
struct FbAttachInfo;
struct FormatInfo;
class FormatUsageAuthority;
struct FormatUsageInfo;
@ -598,11 +599,24 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
void DrawBuffers(const dom::Sequence<GLenum>& buffers);
void Flush();
void Finish();
private:
void FramebufferAttach(GLenum target, GLenum attachEnum,
TexTarget reqTexTarget,
const webgl::FbAttachInfo& toAttach) const;
public:
void FramebufferRenderbuffer(GLenum target, GLenum attachment,
GLenum rbTarget, WebGLRenderbuffer* rb);
GLenum rbTarget, WebGLRenderbuffer* rb) const;
void FramebufferTexture2D(GLenum target, GLenum attachment,
GLenum texImageTarget, WebGLTexture* tex,
GLint level);
GLint level) const;
void FramebufferTextureLayer(GLenum target, GLenum attachment,
WebGLTexture* tex, GLint level,
GLint layer) const;
void FramebufferTextureMultiview(GLenum target, GLenum attachment,
WebGLTexture* texture, GLint level,
GLint baseViewIndex, GLsizei numViews) const;
void FrontFace(GLenum mode);
already_AddRefed<WebGLActiveInfo> GetActiveAttrib(const WebGLProgram& prog,
@ -1533,6 +1547,7 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
uint32_t mGLMaxCubeMapTextureSize = 0;
uint32_t mGLMax3DTextureSize = 0;
uint32_t mGLMaxArrayTextureLayers = 0;
uint32_t mGLMaxMultiviewViews = 1;
uint32_t mGLMaxRenderbufferSize = 0;
public:
@ -1738,7 +1753,7 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
//////
public:
bool ValidateObjectAllowDeleted(const char* const argName,
const WebGLContextBoundObject& object) {
const WebGLContextBoundObject& object) const {
if (!object.IsCompatibleWithContext(this)) {
ErrorInvalidOperation(
"%s: Object from different WebGL context (or older"
@ -1752,7 +1767,7 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
bool ValidateObject(const char* const argName,
const WebGLDeletableObject& object,
const bool isShaderOrProgram = false) {
const bool isShaderOrProgram = false) const {
if (!ValidateObjectAllowDeleted(argName, object)) return false;
if (isShaderOrProgram) {
@ -1789,8 +1804,10 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
// Program and Shader are incomplete, so we can't inline the conversion to
// WebGLDeletableObject here.
bool ValidateObject(const char* const argName, const WebGLProgram& object);
bool ValidateObject(const char* const argName, const WebGLShader& object);
bool ValidateObject(const char* const argName,
const WebGLProgram& object) const;
bool ValidateObject(const char* const argName,
const WebGLShader& object) const;
////
@ -1821,7 +1838,7 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
WebGLRefPtr<WebGLProgram> mCurrentProgram;
RefPtr<const webgl::LinkedProgramInfo> mActiveProgramLinkInfo;
bool ValidateFramebufferTarget(GLenum target);
bool ValidateFramebufferTarget(GLenum target) const;
bool ValidateInvalidateFramebuffer(GLenum target,
const dom::Sequence<GLenum>& attachments,
ErrorResult* const out_rv,
@ -1835,6 +1852,10 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
WebGLRefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
public:
const auto& BoundReadFb() const { return mBoundReadFramebuffer; }
protected:
LinkedList<WebGLBuffer> mBuffers;
LinkedList<WebGLFramebuffer> mFramebuffers;
LinkedList<WebGLProgram> mPrograms;

Просмотреть файл

@ -279,6 +279,15 @@ const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
const auto& tfo = webgl->mBoundTransformFeedback;
if (tfo && tfo->IsActiveAndNotPaused()) {
if (fb) {
const auto& info = *fb->GetCompletenessInfo();
if (info.isMultiview) {
webgl->ErrorInvalidOperation(
"Cannot render to multiview with transform feedback.");
return nullptr;
}
}
uint32_t numUsed;
switch (linkInfo->transformFeedbackBufferMode) {
case LOCAL_GL_INTERLEAVED_ATTRIBS:
@ -339,7 +348,11 @@ const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
};
if (!webgl->mRasterizerDiscardEnabled) {
uint8_t fbZLayerCount = 1;
if (fb) {
const auto& info = *fb->GetCompletenessInfo();
fbZLayerCount = info.zLayerCount;
for (const auto& attach : fb->ColorDrawBuffers()) {
const auto i =
uint8_t(attach->mAttachmentPoint - LOCAL_GL_COLOR_ATTACHMENT0);
@ -352,6 +365,13 @@ const webgl::CachedDrawFetchLimits* ValidateDraw(WebGLContext* const webgl,
if (!fnValidateFragOutputType(0, webgl::TextureBaseType::Float))
return nullptr;
}
if (fbZLayerCount != linkInfo->zLayerCount) {
webgl->ErrorInvalidOperation(
"Multiview count mismatch: shader: %u, framebuffer: %u",
uint32_t{linkInfo->zLayerCount}, uint32_t{fbZLayerCount});
return nullptr;
}
}
// -

Просмотреть файл

@ -51,6 +51,7 @@ namespace mozilla {
WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float)
WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float_linear)
WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object)
WEBGL_EXTENSION_IDENTIFIER(OVR_multiview2)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_astc)
WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc)
@ -186,6 +187,10 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const {
case WebGLExtensionID::OES_vertex_array_object:
return !IsWebGL2(); // Always supported in webgl1.
// OVR_
case WebGLExtensionID::OVR_multiview2:
return WebGLExtensionMultiview::IsSupported(this);
// WEBGL_
case WebGLExtensionID::WEBGL_color_buffer_float:
return WebGLExtensionColorBufferFloat::IsSupported(this);
@ -389,6 +394,11 @@ void WebGLContext::EnableExtension(WebGLExtensionID ext) {
obj = new WebGLExtensionVertexArray(this);
break;
// WEBGL_
case WebGLExtensionID::OVR_multiview2:
obj = new WebGLExtensionMultiview(this);
break;
// WEBGL_
case WebGLExtensionID::WEBGL_color_buffer_float:
obj = new WebGLExtensionColorBufferFloat(this);

Просмотреть файл

@ -59,12 +59,12 @@
namespace mozilla {
bool WebGLContext::ValidateObject(const char* const argName,
const WebGLProgram& object) {
const WebGLProgram& object) const {
return ValidateObject(argName, object, true);
}
bool WebGLContext::ValidateObject(const char* const argName,
const WebGLShader& object) {
const WebGLShader& object) const {
return ValidateObject(argName, object, true);
}
@ -446,62 +446,204 @@ void WebGLContext::DepthRange(GLfloat zNear, GLfloat zFar) {
gl->fDepthRange(zNear, zFar);
}
void WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment,
GLenum rbtarget,
WebGLRenderbuffer* wrb) {
// -
void WebGLContext::FramebufferAttach(
const GLenum target, const GLenum attachEnum, const TexTarget reqTexTarget,
const webgl::FbAttachInfo& toAttach) const {
if (!ValidateFramebufferTarget(target)) return;
WebGLFramebuffer* fb = mBoundDrawFramebuffer;
if (target == LOCAL_GL_READ_FRAMEBUFFER) {
fb = mBoundReadFramebuffer;
}
if (!fb) return ErrorInvalidOperation("Cannot modify framebuffer 0.");
// `rb`
if (toAttach.rb) {
if (!ValidateObject("rb", *toAttach.rb)) return;
if (!toAttach.rb->mHasBeenBound) {
ErrorInvalidOperation(
"bindRenderbuffer must be called before"
" attachment.");
return;
}
}
// `tex`
if (toAttach.tex) {
if (!ValidateObject("tex", *toAttach.tex)) return;
const auto texTarget = toAttach.tex->Target();
bool targetOk = bool(texTarget);
if (reqTexTarget) {
targetOk = texTarget == reqTexTarget;
}
if (!targetOk) {
ErrorInvalidOperation("`tex`'s binding target type is not valid.");
return;
}
GLint maxMipLevel;
GLint maxZLayer;
const char* maxMipLevelText;
const char* maxZLayerText;
switch (texTarget.get()) {
case LOCAL_GL_TEXTURE_2D:
maxMipLevel = FloorLog2(mGLMaxTextureSize);
maxMipLevelText = "log2(MAX_TEXTURE_SIZE)";
maxZLayer = 1;
maxZLayerText = "1";
break;
case LOCAL_GL_TEXTURE_CUBE_MAP:
maxMipLevel = FloorLog2(mGLMaxCubeMapTextureSize);
maxMipLevelText = "log2(MAX_CUBE_MAP_TEXTURE_SIZE)";
maxZLayer = 6;
maxZLayerText = "6";
break;
case LOCAL_GL_TEXTURE_3D:
maxMipLevel = FloorLog2(mGLMax3DTextureSize);
maxMipLevelText = "log2(MAX_3D_TEXTURE_SIZE)";
maxZLayer = mGLMax3DTextureSize - 1;
maxZLayerText = "MAX_3D_TEXTURE_SIZE";
break;
case LOCAL_GL_TEXTURE_2D_ARRAY:
maxMipLevel = FloorLog2(mGLMaxTextureSize);
maxMipLevelText = "log2(MAX_TEXTURE_SIZE)";
maxZLayer = mGLMaxArrayTextureLayers;
maxZLayerText = "MAX_ARRAY_TEXTURE_LAYERS";
break;
default:
MOZ_CRASH();
}
if (!IsWebGL2() &&
!IsExtensionEnabled(WebGLExtensionID::OES_fbo_render_mipmap)) {
maxMipLevel = 0;
maxMipLevelText = "0";
}
if (toAttach.mipLevel < 0)
return ErrorInvalidValue("`level` must be >= 0.");
if (toAttach.mipLevel > maxMipLevel) {
ErrorInvalidValue("`level` must be <= %s.", maxMipLevelText);
return;
}
if (toAttach.zLayer < 0) return ErrorInvalidValue("`layer` must be >= 0.");
if (toAttach.zLayerCount < 1)
return ErrorInvalidValue("`numViews` must be >= 1.");
if (AssertedCast<uint32_t>(toAttach.zLayerCount) > mGLMaxMultiviewViews)
return ErrorInvalidValue("`numViews` must be <= MAX_VIEWS_OVR.");
const auto lastZLayer = toAttach.zLayer + toAttach.zLayerCount;
if (lastZLayer > maxZLayer) {
const char* formatText = "`layer` must be < %s.";
if (toAttach.zLayerCount != 1) {
formatText = "`layer` + `numViews` must be <= %s.";
}
ErrorInvalidValue(formatText, maxZLayerText);
return;
}
}
fb->FramebufferAttach(attachEnum, toAttach);
}
void WebGLContext::FramebufferRenderbuffer(const GLenum target,
const GLenum attachEnum,
const GLenum rbTarget,
WebGLRenderbuffer* const rb) const {
const FuncScope funcScope(*this, "framebufferRenderbuffer");
if (IsContextLost()) return;
if (!ValidateFramebufferTarget(target)) return;
WebGLFramebuffer* fb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
break;
default:
MOZ_CRASH("GFX: Bad target.");
if (rbTarget != LOCAL_GL_RENDERBUFFER) {
ErrorInvalidEnumArg("rbTarget", rbTarget);
return;
}
if (!fb) return ErrorInvalidOperation("Cannot modify framebuffer 0.");
fb->FramebufferRenderbuffer(attachment, rbtarget, wrb);
const auto toAttach = webgl::FbAttachInfo{rb};
FramebufferAttach(target, attachEnum, 0, toAttach);
}
void WebGLContext::FramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, WebGLTexture* tobj,
GLint level) {
void WebGLContext::FramebufferTexture2D(const GLenum target,
const GLenum attachEnum,
const GLenum imageTarget,
WebGLTexture* const tex,
const GLint level) const {
const FuncScope funcScope(*this, "framebufferTexture2D");
if (IsContextLost()) return;
if (!ValidateFramebufferTarget(target)) return;
WebGLFramebuffer* fb;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
case LOCAL_GL_DRAW_FRAMEBUFFER:
fb = mBoundDrawFramebuffer;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
fb = mBoundReadFramebuffer;
break;
default:
MOZ_CRASH("GFX: Bad target.");
TexTarget reqTexTarget = LOCAL_GL_TEXTURE_2D;
auto toAttach = webgl::FbAttachInfo{nullptr, tex, level, 0};
if (toAttach.tex) {
switch (imageTarget) {
case LOCAL_GL_TEXTURE_2D:
break;
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
toAttach.zLayer = imageTarget - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
reqTexTarget = LOCAL_GL_TEXTURE_CUBE_MAP;
break;
default:
ErrorInvalidEnumArg("texImageTarget", imageTarget);
return;
}
}
if (!fb) return ErrorInvalidOperation("Cannot modify framebuffer 0.");
fb->FramebufferTexture2D(attachment, textarget, tobj, level);
FramebufferAttach(target, attachEnum, reqTexTarget, toAttach);
}
void WebGLContext::FramebufferTextureLayer(const GLenum target,
const GLenum attachEnum,
WebGLTexture* const tex,
const GLint mipLevel,
const GLint zLayer) const {
const FuncScope funcScope(*this, "framebufferTextureLayer");
if (IsContextLost()) return;
const auto toAttach = webgl::FbAttachInfo{nullptr, tex, mipLevel, zLayer};
if (toAttach.tex) {
if (!ValidateObject("tex", *toAttach.tex))
return; // Technically we need to check this first...
switch (toAttach.tex->Target().get()) {
case LOCAL_GL_TEXTURE_3D:
case LOCAL_GL_TEXTURE_2D_ARRAY:
break;
default:
ErrorInvalidOperation(
"`texture` must be a TEXTURE_3D or"
" TEXTURE_2D_ARRAY.");
return;
}
}
FramebufferAttach(target, attachEnum, 0, toAttach);
}
void WebGLContext::FramebufferTextureMultiview(
const GLenum target, const GLenum attachEnum, WebGLTexture* const tex,
const GLint mipLevel, const GLint zLayerBase,
const GLsizei numViewLayers) const {
if (IsContextLost()) return;
const auto toAttach = webgl::FbAttachInfo{nullptr, tex, mipLevel,
zLayerBase, numViewLayers, true};
FramebufferAttach(target, attachEnum, LOCAL_GL_TEXTURE_2D_ARRAY, toAttach);
}
// -
void WebGLContext::FrontFace(GLenum mode) {
const FuncScope funcScope(*this, "frontFace");
if (IsContextLost()) return;

Просмотреть файл

@ -410,6 +410,12 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_MAX_VARYING_VECTORS:
return JS::Int32Value(mGLMaxFragmentInputVectors);
case LOCAL_GL_MAX_VIEWS_OVR:
if (IsExtensionEnabled(WebGLExtensionID::OVR_multiview2)) {
return JS::NumberValue(mGLMaxMultiviewViews);
}
break;
case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: {
uint32_t length = mCompressedTextureFormats.Length();
JSObject* obj = dom::Uint32Array::Create(

Просмотреть файл

@ -411,6 +411,9 @@ bool WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) {
(GLint*)&mGLMaxArrayTextureLayers))
mGLMaxArrayTextureLayers = 0;
(void)gl->GetPotentialInteger(LOCAL_GL_MAX_VIEWS_OVR,
(GLint*)&mGLMaxMultiviewViews);
gl->GetUIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS,
&mGLMaxFragmentTextureImageUnits);
gl->GetUIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
@ -676,7 +679,7 @@ bool WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) {
return true;
}
bool WebGLContext::ValidateFramebufferTarget(GLenum target) {
bool WebGLContext::ValidateFramebufferTarget(GLenum target) const {
bool isValid = true;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:

Просмотреть файл

@ -72,4 +72,38 @@ bool WebGLExtensionFBORenderMipmap::IsSupported(
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionFBORenderMipmap, OES_fbo_render_mipmap)
// -
WebGLExtensionMultiview::WebGLExtensionMultiview(WebGLContext* const webgl)
: WebGLExtensionBase(webgl) {
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
WebGLExtensionMultiview::~WebGLExtensionMultiview() = default;
bool WebGLExtensionMultiview::IsSupported(const WebGLContext* const webgl) {
if (!webgl->IsWebGL2()) return false;
if (!gfxPrefs::WebGLDraftExtensionsEnabled()) return false;
const auto& gl = webgl->gl;
return gl->IsSupported(gl::GLFeature::multiview);
}
void WebGLExtensionMultiview::FramebufferTextureMultiviewOVR(
const GLenum target, const GLenum attachment, WebGLTexture* const texture,
const GLint level, const GLint baseViewIndex,
const GLsizei numViews) const {
const WebGLContext::FuncScope funcScope(*mContext,
"framebufferTextureMultiviewOVR");
if (mIsLost) {
mContext->ErrorInvalidOperation("Extension is lost.");
return;
}
mContext->FramebufferTextureMultiview(target, attachment, texture, level,
baseViewIndex, numViews);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionMultiview, OVR_multiview2)
} // namespace mozilla

Просмотреть файл

@ -28,8 +28,9 @@ class FormatUsageAuthority;
} // namespace webgl
class WebGLContext;
class WebGLShader;
class WebGLQuery;
class WebGLShader;
class WebGLTexture;
class WebGLVertexArray;
class WebGLExtensionBase : public nsWrapperCache,
@ -405,6 +406,20 @@ class WebGLExtensionMOZDebug final : public WebGLExtensionBase {
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionMultiview : public WebGLExtensionBase {
public:
explicit WebGLExtensionMultiview(WebGLContext*);
virtual ~WebGLExtensionMultiview();
static bool IsSupported(const WebGLContext*);
void FramebufferTextureMultiviewOVR(GLenum target, GLenum attachment,
WebGLTexture* texture, GLint level,
GLint baseViewIndex,
GLsizei numViews) const;
DECL_WEBGL_EXTENSION_GOOP
};
} // namespace mozilla
#endif // WEBGL_EXTENSIONS_H_

Просмотреть файл

@ -51,44 +51,31 @@ bool WebGLFBAttachPoint::IsDeleteRequested() const {
: Renderbuffer() ? Renderbuffer()->IsDeleteRequested() : false;
}
void WebGLFBAttachPoint::Clear() {
mRenderbufferPtr = nullptr;
mTexturePtr = nullptr;
mTexImageTarget = 0;
mTexImageLevel = 0;
mTexImageLayer = 0;
}
void WebGLFBAttachPoint::Clear() { Set(nullptr, {}); }
void WebGLFBAttachPoint::SetTexImage(gl::GLContext* const gl,
WebGLTexture* const tex,
TexImageTarget target, GLint level,
GLint layer) {
Clear();
void WebGLFBAttachPoint::Set(gl::GLContext* const gl,
const webgl::FbAttachInfo& toAttach) {
mRenderbufferPtr = toAttach.rb;
mTexturePtr = toAttach.tex;
mTexImageLayer = AssertedCast<uint32_t>(toAttach.zLayer);
mTexImageZLayerCount = AssertedCast<uint8_t>(toAttach.zLayerCount);
mTexImageLevel = AssertedCast<uint8_t>(toAttach.mipLevel);
mIsMultiview = toAttach.isMultiview;
mTexturePtr = tex;
mTexImageTarget = target;
mTexImageLevel = level;
mTexImageLayer = layer;
if (!mDeferAttachment) {
DoAttachment(gl);
}
}
void WebGLFBAttachPoint::SetRenderbuffer(gl::GLContext* const gl,
WebGLRenderbuffer* const rb) {
Clear();
mRenderbufferPtr = rb;
if (!mDeferAttachment) {
if (gl && !mDeferAttachment) {
DoAttachment(gl);
}
}
const webgl::ImageInfo* WebGLFBAttachPoint::GetImageInfo() const {
if (mTexturePtr)
return &mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel);
if (mTexturePtr) {
const auto target = Texture()->Target();
uint8_t face = 0;
if (target == LOCAL_GL_TEXTURE_CUBE_MAP) {
face = Layer() % 6;
}
return &mTexturePtr->ImageInfoAtFace(face, mTexImageLevel);
}
if (mRenderbufferPtr) return &mRenderbufferPtr->ImageInfo();
return nullptr;
}
@ -99,6 +86,7 @@ bool WebGLFBAttachPoint::IsComplete(WebGLContext* webgl,
const auto fnWriteErrorInfo = [&](const char* const text) {
WebGLContext::EnumName(mAttachmentPoint, out_info);
out_info->AppendLiteral(": ");
out_info->AppendASCII(text);
};
@ -117,7 +105,9 @@ bool WebGLFBAttachPoint::IsComplete(WebGLContext* webgl,
// because immutable textures are *always* texture-complete. We need to
// check immutable textures though, because checking completeness is also
// when we zero invalidated/no-data tex images.
const bool complete = [&]() {
const auto attachedMipLevel = MipLevel();
const bool withinValidMipLevels = [&]() {
const bool ensureInit = false;
const auto texCompleteness = tex->CalcCompletenessInfo(ensureInit);
if (!texCompleteness) // OOM
@ -126,10 +116,18 @@ bool WebGLFBAttachPoint::IsComplete(WebGLContext* webgl,
const auto baseLevel = tex->BaseMipmapLevel();
const auto maxLevel = baseLevel + texCompleteness->levels - 1;
return baseLevel <= mTexImageLevel && mTexImageLevel <= maxLevel;
return baseLevel <= attachedMipLevel && attachedMipLevel <= maxLevel;
}();
if (!complete) {
fnWriteErrorInfo("Attached texture is not texture-complete.");
if (!withinValidMipLevels) {
fnWriteErrorInfo("Attached mip level is invalid for texture.");
return false;
}
const auto& levelInfo = tex->ImageInfoAtFace(0, attachedMipLevel);
const auto faceDepth = levelInfo.mDepth * tex->FaceCount();
const bool withinValidZLayers = Layer() + ZLayerCount() - 1 < faceDepth;
if (!withinValidZLayers) {
fnWriteErrorInfo("Attached z layer is invalid for texture.");
return false;
}
}
@ -216,32 +214,38 @@ void WebGLFBAttachPoint::DoAttachment(gl::GLContext* const gl) const {
const auto& texName = Texture()->mGLName;
switch (mTexImageTarget.get()) {
switch (Texture()->Target().get()) {
case LOCAL_GL_TEXTURE_2D:
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
case LOCAL_GL_TEXTURE_CUBE_MAP: {
TexImageTarget imageTarget = LOCAL_GL_TEXTURE_2D;
if (Texture()->Target() == LOCAL_GL_TEXTURE_CUBE_MAP) {
imageTarget = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + Layer();
}
if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferTexture2D(
LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
mTexImageTarget.get(), texName, mTexImageLevel);
gl->fFramebufferTexture2D(
LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
mTexImageTarget.get(), texName, mTexImageLevel);
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT, imageTarget.get(),
texName, MipLevel());
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_STENCIL_ATTACHMENT,
imageTarget.get(), texName, MipLevel());
} else {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, mAttachmentPoint,
mTexImageTarget.get(), texName,
mTexImageLevel);
imageTarget.get(), texName, MipLevel());
}
break;
}
case LOCAL_GL_TEXTURE_2D_ARRAY:
case LOCAL_GL_TEXTURE_3D:
gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER, mAttachmentPoint,
texName, mTexImageLevel, mTexImageLayer);
if (ZLayerCount() != 1) {
gl->fFramebufferTextureMultiview(LOCAL_GL_FRAMEBUFFER, mAttachmentPoint,
texName, MipLevel(), Layer(),
ZLayerCount());
} else {
gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER, mAttachmentPoint,
texName, MipLevel(), Layer());
}
break;
}
}
@ -308,7 +312,7 @@ JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
if (mTexturePtr) {
GLenum face = 0;
if (mTexturePtr->Target() == LOCAL_GL_TEXTURE_CUBE_MAP) {
face = ImageTarget().get();
face = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + Layer();
}
return JS::Int32Value(face);
}
@ -317,13 +321,20 @@ JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
//////
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
if (webgl->IsWebGL2() && mTexturePtr) {
int32_t layer = 0;
if (ImageTarget() == LOCAL_GL_TEXTURE_2D_ARRAY ||
ImageTarget() == LOCAL_GL_TEXTURE_3D) {
layer = Layer();
}
return JS::Int32Value(layer);
if (webgl->IsWebGL2()) {
return JS::Int32Value(AssertedCast<int32_t>(Layer()));
}
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
if (webgl->IsExtensionEnabled(WebGLExtensionID::OVR_multiview2)) {
return JS::Int32Value(AssertedCast<int32_t>(Layer()));
}
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
if (webgl->IsExtensionEnabled(WebGLExtensionID::OVR_multiview2)) {
return JS::Int32Value(ZLayerCount());
}
break;
@ -674,6 +685,20 @@ FBStatus WebGLFramebuffer::PrecheckFramebufferStatus(
if (depthOrStencilCount > 1) return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
}
{
const WebGLFBAttachPoint* example = nullptr;
for (const auto& x : mAttachments) {
if (!x->HasAttachment()) continue;
if (!example) {
example = x;
continue;
}
if (x->ZLayerCount() != example->ZLayerCount()) {
return LOCAL_GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR;
}
}
}
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
}
@ -736,6 +761,12 @@ bool WebGLFramebuffer::ValidateForColorRead(
return false;
}
if (mColorReadBuffer->ZLayerCount() > 1) {
mContext->GenerateError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION,
"The READ_BUFFER attachment has multiple views.");
return false;
}
const auto& imageInfo = mColorReadBuffer->GetImageInfo();
if (!imageInfo) {
mContext->ErrorInvalidOperation(
@ -841,18 +872,15 @@ void WebGLFramebuffer::ResolveAttachmentData() const {
};
if (imageInfo->mDepth > 1) {
// Todo: Use glClearTexImage.
const auto& tex = cur->Texture();
const gl::ScopedFramebuffer scopedFB(gl);
const gl::ScopedBindFramebuffer scopedBindFB(gl, scopedFB.FB());
for (uint32_t z = 0; z < imageInfo->mDepth; z++) {
gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER,
cur->mAttachmentPoint, tex->mGLName,
cur->MipLevel(), z);
fnClearBuffer();
}
gl->fFramebufferTextureLayer(LOCAL_GL_FRAMEBUFFER,
cur->mAttachmentPoint, tex->mGLName,
cur->MipLevel(), cur->Layer());
} else {
fnClearBuffer();
}
@ -979,6 +1007,8 @@ FBStatus WebGLFramebuffer::CheckFramebufferStatus() const {
info.width = std::min(info.width, imageInfo->mWidth);
info.height = std::min(info.height, imageInfo->mHeight);
info.hasFloat32 |= fnIsFloat32(*imageInfo->mFormat->format);
info.zLayerCount = cur->ZLayerCount();
info.isMultiview = cur->IsMultiview();
}
mCompletenessInfo = Some(std::move(info));
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
@ -1103,9 +1133,8 @@ void WebGLFramebuffer::ReadBuffer(GLenum attachPoint) {
////
void WebGLFramebuffer::FramebufferRenderbuffer(GLenum attachEnum,
GLenum rbtarget,
WebGLRenderbuffer* rb) {
void WebGLFramebuffer::FramebufferAttach(const GLenum attachEnum,
const webgl::FbAttachInfo& toAttach) {
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
@ -1117,202 +1146,17 @@ void WebGLFramebuffer::FramebufferRenderbuffer(GLenum attachEnum,
}
const auto& attach = maybeAttach.value();
// `rbTarget`
if (rbtarget != LOCAL_GL_RENDERBUFFER) {
mContext->ErrorInvalidEnumInfo("rbtarget", rbtarget);
return;
}
// `rb`
if (rb) {
if (!mContext->ValidateObject("rb", *rb)) return;
if (!rb->mHasBeenBound) {
mContext->ErrorInvalidOperation(
"bindRenderbuffer must be called before"
" attachment to %04x",
attachEnum);
return;
}
}
// End of validation.
const auto& gl = mContext->gl;
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGLName);
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mDepthAttachment.SetRenderbuffer(gl, rb);
mStencilAttachment.SetRenderbuffer(gl, rb);
mDepthAttachment.Set(gl, toAttach);
mStencilAttachment.Set(gl, toAttach);
} else {
attach->SetRenderbuffer(gl, rb);
attach->Set(gl, toAttach);
}
InvalidateCaches();
}
void WebGLFramebuffer::FramebufferTexture2D(GLenum attachEnum,
GLenum texImageTarget,
WebGLTexture* tex, GLint level) {
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
// `attachment`
const auto maybeAttach = GetAttachPoint(attachEnum);
if (!maybeAttach || !maybeAttach.value()) {
mContext->ErrorInvalidEnum("Bad `attachment`: 0x%x.", attachEnum);
return;
}
const auto& attach = maybeAttach.value();
// `texImageTarget`
if (texImageTarget != LOCAL_GL_TEXTURE_2D &&
(texImageTarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
texImageTarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)) {
mContext->ErrorInvalidEnumInfo("texImageTarget", texImageTarget);
return;
}
// `texture`
if (tex) {
if (!mContext->ValidateObject("texture", *tex)) return;
if (!tex->Target()) {
mContext->ErrorInvalidOperation("`texture` has never been bound.");
return;
}
const TexTarget destTexTarget = TexImageTargetToTexTarget(texImageTarget);
if (tex->Target() != destTexTarget) {
mContext->ErrorInvalidOperation("Mismatched texture and texture target.");
return;
}
}
// `level`
if (level < 0)
return mContext->ErrorInvalidValue("`level` must not be negative.");
if (mContext->IsWebGL2() ||
mContext->IsExtensionEnabled(WebGLExtensionID::OES_fbo_render_mipmap)) {
/* GLES 3.0.4 p208:
* If textarget is one of TEXTURE_CUBE_MAP_POSITIVE_X,
* TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z,
* TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_Y,
* or TEXTURE_CUBE_MAP_NEGATIVE_Z, then level must be greater
* than or equal to zero and less than or equal to log2 of the
* value of MAX_CUBE_MAP_TEXTURE_SIZE. If textarget is TEXTURE_2D,
* level must be greater than or equal to zero and no larger than
* log2 of the value of MAX_TEXTURE_SIZE. Otherwise, an
* INVALID_VALUE error is generated.
*/
if (texImageTarget == LOCAL_GL_TEXTURE_2D) {
if (uint32_t(level) > FloorLog2(mContext->mGLMaxTextureSize))
return mContext->ErrorInvalidValue("`level` is too large.");
} else {
MOZ_ASSERT(texImageTarget >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
texImageTarget <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
if (uint32_t(level) > FloorLog2(mContext->mGLMaxCubeMapTextureSize))
return mContext->ErrorInvalidValue("`level` is too large.");
}
} else if (level != 0) {
return mContext->ErrorInvalidValue("`level` must be 0.");
}
// End of validation.
const auto& gl = mContext->gl;
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGLName);
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mDepthAttachment.SetTexImage(gl, tex, texImageTarget, level);
mStencilAttachment.SetTexImage(gl, tex, texImageTarget, level);
} else {
attach->SetTexImage(gl, tex, texImageTarget, level);
}
InvalidateCaches();
}
void WebGLFramebuffer::FramebufferTextureLayer(GLenum attachEnum,
WebGLTexture* tex, GLint level,
GLint layer) {
MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
mContext->mBoundReadFramebuffer == this);
// `attachment`
const auto maybeAttach = GetAttachPoint(attachEnum);
if (!maybeAttach || !maybeAttach.value()) {
mContext->ErrorInvalidEnum("Bad `attachment`: 0x%x.", attachEnum);
return;
}
const auto& attach = maybeAttach.value();
// `level`, `layer`
if (layer < 0) return mContext->ErrorInvalidValue("`layer` must be >= 0.");
if (level < 0) return mContext->ErrorInvalidValue("`level` must be >= 0.");
// `texture`
GLenum texImageTarget = LOCAL_GL_TEXTURE_3D;
if (tex) {
if (!mContext->ValidateObject("texture", *tex)) return;
if (!tex->Target()) {
mContext->ErrorInvalidOperation("`texture` has never been bound.");
return;
}
texImageTarget = tex->Target().get();
switch (texImageTarget) {
case LOCAL_GL_TEXTURE_3D:
if (uint32_t(layer) >= mContext->mGLMax3DTextureSize) {
mContext->ErrorInvalidValue("`layer` must be < %s.",
"MAX_3D_TEXTURE_SIZE");
return;
}
if (uint32_t(level) > FloorLog2(mContext->mGLMax3DTextureSize)) {
mContext->ErrorInvalidValue("`level` must be <= log2(%s).",
"MAX_3D_TEXTURE_SIZE");
return;
}
break;
case LOCAL_GL_TEXTURE_2D_ARRAY:
if (uint32_t(layer) >= mContext->mGLMaxArrayTextureLayers) {
mContext->ErrorInvalidValue("`layer` must be < %s.",
"MAX_ARRAY_TEXTURE_LAYERS");
return;
}
if (uint32_t(level) > FloorLog2(mContext->mGLMaxTextureSize)) {
mContext->ErrorInvalidValue("`level` must be <= log2(%s).",
"MAX_TEXTURE_SIZE");
return;
}
break;
default:
mContext->ErrorInvalidOperation(
"`texture` must be a TEXTURE_3D or"
" TEXTURE_2D_ARRAY.");
return;
}
}
// End of validation.
const auto& gl = mContext->gl;
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGLName);
if (mContext->IsWebGL2() && attachEnum == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mDepthAttachment.SetTexImage(gl, tex, texImageTarget, level, layer);
mStencilAttachment.SetTexImage(gl, tex, texImageTarget, level, layer);
} else {
attach->SetTexImage(gl, tex, texImageTarget, level, layer);
}
InvalidateCaches();
}
JS::Value WebGLFramebuffer::GetAttachmentParameter(
JSContext* cx, GLenum target, GLenum attachEnum, GLenum pname,
ErrorResult* const out_error) {
@ -1417,6 +1261,12 @@ void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0,
const webgl::FormatInfo* srcStencilFormat;
if (srcFB) {
const auto& info = *srcFB->GetCompletenessInfo();
if (info.zLayerCount != 1) {
webgl->GenerateError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION,
"Source framebuffer cannot have multiple views.");
return;
}
srcColorFormat = nullptr;
if (srcFB->mColorReadBuffer) {
const auto& imageInfo = srcFB->mColorReadBuffer->GetImageInfo();

Просмотреть файл

@ -31,6 +31,17 @@ namespace gl {
class GLContext;
} // namespace gl
namespace webgl {
struct FbAttachInfo final {
WebGLRenderbuffer* rb = nullptr;
WebGLTexture* tex = nullptr;
GLint mipLevel = 0;
GLint zLayer = 0;
GLsizei zLayerCount = 1;
bool isMultiview = false;
};
} // namespace webgl
class WebGLFBAttachPoint final {
friend class WebGLFramebuffer;
@ -41,9 +52,10 @@ class WebGLFBAttachPoint final {
private:
WebGLRefPtr<WebGLTexture> mTexturePtr;
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
TexImageTarget mTexImageTarget = 0;
GLint mTexImageLayer = 0;
uint32_t mTexImageLevel = 0;
uint32_t mTexImageLayer = 0;
uint8_t mTexImageZLayerCount = 1;
uint8_t mTexImageLevel = 0;
bool mIsMultiview = false;
////
@ -67,16 +79,16 @@ class WebGLFBAttachPoint final {
void Clear();
void SetTexImage(gl::GLContext* gl, WebGLTexture* tex, TexImageTarget target,
GLint level, GLint layer = 0);
void SetRenderbuffer(gl::GLContext* gl, WebGLRenderbuffer* rb);
void Set(gl::GLContext* gl, const webgl::FbAttachInfo&);
WebGLTexture* Texture() const { return mTexturePtr; }
WebGLRenderbuffer* Renderbuffer() const { return mRenderbufferPtr; }
TexImageTarget ImageTarget() const { return mTexImageTarget; }
GLint Layer() const { return mTexImageLayer; }
uint32_t MipLevel() const { return mTexImageLevel; }
auto Layer() const { return mTexImageLayer; }
auto ZLayerCount() const { return mTexImageZLayerCount; }
auto MipLevel() const { return mTexImageLevel; }
const auto& IsMultiview() const { return mIsMultiview; }
void AttachmentName(nsCString* out) const;
const webgl::ImageInfo* GetImageInfo() const;
@ -93,8 +105,8 @@ class WebGLFBAttachPoint final {
if (!HasAttachment() | !other.HasAttachment()) return false;
#define _(X) (X == other.X)
return (_(mRenderbufferPtr) & _(mTexturePtr) & _(mTexImageTarget.get()) &
_(mTexImageLevel) & _(mTexImageLayer));
return (_(mRenderbufferPtr) && _(mTexturePtr) && _(mTexImageLevel) &&
_(mTexImageLayer) && _(mTexImageZLayerCount));
#undef _
}
@ -113,9 +125,9 @@ class WebGLFBAttachPoint final {
ORDER_BY(mRef.mRenderbufferPtr)
ORDER_BY(mRef.mTexturePtr)
ORDER_BY(mRef.mTexImageTarget.get())
ORDER_BY(mRef.mTexImageLevel)
ORDER_BY(mRef.mTexImageLayer)
ORDER_BY(mRef.mTexImageZLayerCount)
#undef ORDER_BY
return false;
@ -167,6 +179,8 @@ class WebGLFramebuffer final : public nsWrapperCache,
uint32_t width = 0;
uint32_t height = 0;
bool hasFloat32 = false;
uint8_t zLayerCount = 1;
bool isMultiview = false;
// IsFeedback
std::vector<const WebGLFBAttachPoint*> texAttachments; // Non-null
@ -256,12 +270,8 @@ class WebGLFramebuffer final : public nsWrapperCache,
}
FBStatus CheckFramebufferStatus() const;
void FramebufferRenderbuffer(GLenum attachment, GLenum rbtarget,
WebGLRenderbuffer* rb);
void FramebufferTexture2D(GLenum attachment, GLenum texImageTarget,
WebGLTexture* tex, GLint level);
void FramebufferTextureLayer(GLenum attachment, WebGLTexture* tex,
GLint level, GLint layer);
void FramebufferAttach(GLenum attachEnum,
const webgl::FbAttachInfo& toAttach);
void DrawBuffers(const dom::Sequence<GLenum>& buffers);
void ReadBuffer(GLenum attachPoint);

Просмотреть файл

@ -535,6 +535,15 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
}
}
const auto& vertShader = prog->VertShader();
MOZ_RELEASE_ASSERT(vertShader);
MOZ_RELEASE_ASSERT(vertShader->Validator());
const auto& handle = vertShader->Validator()->mHandle;
const auto numViews = sh::GetVertexShaderNumViews(handle);
if (numViews != -1) {
info->zLayerCount = AssertedCast<uint8_t>(numViews);
}
return info;
}

Просмотреть файл

@ -107,6 +107,7 @@ struct LinkedProgramInfo final : public RefCounted<LinkedProgramInfo>,
std::vector<UniformBlockInfo*> uniformBlocks; // Owns its contents.
std::vector<RefPtr<WebGLActiveInfo>> transformFeedbackVaryings;
std::unordered_map<uint8_t, const FragOutputInfo> fragOutputs;
uint8_t zLayerCount = 1;
// Needed for draw call validation.
std::vector<UniformInfo*> uniformSamplers;
@ -207,6 +208,7 @@ class WebGLProgram final : public nsWrapperCache,
return mMostRecentLinkInfo.get();
}
const auto& VertShader() const { return mVertShader; }
const auto& FragShader() const { return mFragShader; }
WebGLContext* GetParentObject() const { return mContext; }

Просмотреть файл

@ -182,6 +182,11 @@ webgl::ShaderValidator* WebGLContext::CreateShaderValidator(
if (IsExtensionEnabled(WebGLExtensionID::EXT_shader_texture_lod))
resources.EXT_shader_texture_lod = 1;
if (IsExtensionEnabled(WebGLExtensionID::OVR_multiview2)) {
resources.OVR_multiview2 = 1;
resources.MaxViewsOVR = mGLMaxMultiviewViews;
}
// Tell ANGLE to allow highp in frag shaders. (unless disabled)
// If underlying GLES doesn't have highp in frag shaders, it should complain
// anyways.

Просмотреть файл

@ -349,6 +349,7 @@ STRONG_GLENUM_VALUE(NONE), STRONG_GLENUM_VALUE(TEXTURE_2D),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_READ_BUFFER),
STRONG_GLENUM_VALUE(FRAMEBUFFER_UNSUPPORTED),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR),
STRONG_GLENUM_END(FBStatus)
STRONG_GLENUM_BEGIN(RBParam) STRONG_GLENUM_VALUE(RENDERBUFFER_SAMPLES),

Просмотреть файл

@ -154,6 +154,7 @@ class WebGLTexture final : public nsWrapperCache,
const auto& Immutable() const { return mImmutable; }
const auto& BaseMipmapLevel() const { return mBaseMipmapLevel; }
const auto& FaceCount() const { return mFaceCount; }
// We can just max this out to 31, which is the number of unsigned bits in
// GLsizei.
@ -208,7 +209,6 @@ class WebGLTexture final : public nsWrapperCache,
uint32_t width, uint32_t height,
uint32_t depth,
webgl::ImageInfo** const out_imageInfo);
bool ValidateCopyTexImageForFeedback(uint32_t level, GLint layer = 0) const;
bool ValidateUnpack(const webgl::TexUnpackBlob* blob, bool isFunc3D,
const webgl::PackingInfo& srcPI) const;
@ -278,6 +278,7 @@ class WebGLTexture final : public nsWrapperCache,
}
}
public:
auto& ImageInfoAtFace(uint8_t face, uint32_t level) {
MOZ_ASSERT(face < mFaceCount);
MOZ_ASSERT(level < kMaxLevelCount);
@ -289,7 +290,6 @@ class WebGLTexture final : public nsWrapperCache,
return const_cast<WebGLTexture*>(this)->ImageInfoAtFace(face, level);
}
public:
auto& ImageInfoAt(TexImageTarget texImageTarget, GLint level) {
const auto& face = FaceForTarget(texImageTarget);
return ImageInfoAtFace(face, level);

Просмотреть файл

@ -1893,22 +1893,26 @@ static const webgl::FormatUsageInfo* ValidateCopyDestUsage(
return dstUsage;
}
bool WebGLTexture::ValidateCopyTexImageForFeedback(uint32_t level,
GLint layer) const {
const auto& fb = mContext->mBoundReadFramebuffer;
static bool ValidateCopyTexImageForFeedback(const WebGLContext& webgl,
const WebGLTexture& tex,
const uint8_t mipLevel,
const uint32_t zLayer) {
const auto& fb = webgl.BoundReadFb();
if (fb) {
const auto& attach = fb->ColorReadBuffer();
MOZ_ASSERT(attach);
MOZ_ASSERT(fb->ColorReadBuffer());
const auto& attach = *fb->ColorReadBuffer();
MOZ_ASSERT(attach.ZLayerCount() ==
1); // Multiview invalid for copyTexImage.
if (attach->Texture() == this && attach->Layer() == layer &&
uint32_t(attach->MipLevel()) == level) {
if (attach.Texture() == &tex && attach.Layer() == zLayer &&
attach.MipLevel() == mipLevel) {
// Note that the TexImageTargets *don't* have to match for this to be
// undefined per GLES 3.0.4 p211, thus an INVALID_OP in WebGL.
mContext->ErrorInvalidOperation(
webgl.ErrorInvalidOperation(
"Feedback loop detected, as this texture"
" is already attached to READ_FRAMEBUFFER's"
" READ_BUFFER-selected COLOR_ATTACHMENT%u.",
attach->mAttachmentPoint);
attach.mAttachmentPoint);
return false;
}
}
@ -2052,7 +2056,10 @@ void WebGLTexture::CopyTexImage2D(TexImageTarget target, GLint level,
return;
}
if (!ValidateCopyTexImageForFeedback(level)) return;
const uint32_t zOffset = 0;
if (!ValidateCopyTexImageForFeedback(*mContext, *this,
AssertedCast<uint8_t>(level), zOffset))
return;
////////////////////////////////////
// Check that source and dest info are compatible
@ -2138,7 +2145,10 @@ void WebGLTexture::CopyTexSubImage(TexImageTarget target, GLint level,
return;
}
if (!ValidateCopyTexImageForFeedback(level, zOffset)) return;
if (!ValidateCopyTexImageForFeedback(*mContext, *this,
AssertedCast<uint8_t>(level),
AssertedCast<uint32_t>(zOffset)))
return;
////////////////////////////////////
// Check that source and dest info are compatible

Просмотреть файл

@ -178,6 +178,7 @@ enum class WebGLExtensionID : uint8_t {
OES_texture_half_float,
OES_texture_half_float_linear,
OES_vertex_array_object,
OVR_multiview2,
WEBGL_color_buffer_float,
WEBGL_compressed_texture_astc,
WEBGL_compressed_texture_etc,

Просмотреть файл

@ -5074,6 +5074,7 @@ subsuite = webgl2-core
subsuite = webgl2-core
[generated/test_2_conformance2__extensions__ovr_multiview2.html]
subsuite = webgl2-core
fail-if = (os == 'win')
[generated/test_2_conformance2__extensions__ovr_multiview2_depth.html]
subsuite = webgl2-core
[generated/test_2_conformance2__extensions__ovr_multiview2_draw_buffers.html]
@ -5086,6 +5087,7 @@ subsuite = webgl2-core
subsuite = webgl2-core
[generated/test_2_conformance2__extensions__ovr_multiview2_single_view_operations.html]
subsuite = webgl2-core
fail-if = (os == 'win')
[generated/test_2_conformance2__extensions__ovr_multiview2_timer_query.html]
subsuite = webgl2-core
[generated/test_2_conformance2__extensions__ovr_multiview2_transform_feedback.html]

Просмотреть файл

@ -79,6 +79,12 @@ skip-if = (os == 'win')
[generated/test_2_conformance__extensions__webgl-compressed-texture-s3tc.html]
# getError expected: NO_ERROR. Was INVALID_OPERATION : uploading a texture from a PBO subrange
fail-if = 1
[generated/test_2_conformance2__extensions__ovr_multiview2.html]
# Test fixed upstream, just needs revendor.
fail-if = (os == 'win')
[generated/test_2_conformance2__extensions__ovr_multiview2_single_view_operations.html]
# Test fixed upstream, just needs revendor.
fail-if = (os == 'win')
[generated/test_conformance__offscreencanvas__context-attribute-preserve-drawing-buffer.html]
# Timeout, likely issue with unsupported OffscreenCanvas.
skip-if = 1

Просмотреть файл

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'/>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='ensure-ext.js'></script>
</head>
<body>
<script>
'use strict';
Lastly_WithDraftExtsEnabled(function() {
EnsureExtFor('webgl2', 'OVR_multiview2');
});
</script>
</body>
</html>

Просмотреть файл

@ -54,7 +54,8 @@ var defaultExts = [
];
var draftExts = [
['OES_fbo_render_mipmap', [MACHINE_SPECIFIC, FORBID ]],
['OES_fbo_render_mipmap', [MACHINE_SPECIFIC, FORBID]],
['OVR_multiview2' , [FORBID, MACHINE_SPECIFIC]],
];
////////////////////

Просмотреть файл

@ -38,6 +38,8 @@ fail-if = (os == 'android') || (os == 'linux')
fail-if = (os == 'android') || (os == 'win')
[ensure-exts/test_OES_standard_derivatives.html]
fail-if = (os == 'android')
[ensure-exts/test_OVR_multiview2.html]
fail-if = (os == 'linux') || (os == 'mac')
[ensure-exts/test_WEBGL_color_buffer_float.html]
fail-if = (os == 'android')
[ensure-exts/test_WEBGL_compressed_texture_astc.html]

Просмотреть файл

@ -219,3 +219,4 @@ skip-if = toolkit == 'android' # Bug 1312791
[test_slotted_mouse_event.html]
[test_slotted_text_click.html]
[test_unbound_before_in_active_chain.html]
[test_submitevent_on_form.html]

Просмотреть файл

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test submit event on form</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<form action="javascript:doDefault()" id="form">
<input type="submit" value="Do Default Action">
</form>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTests);
var doDefaultAction = false;
function doDefault()
{
doDefaultAction = true;
}
function runTests()
{
let form = document.getElementById("form");
form.dispatchEvent(new Event('submit'));
setTimeout(() => {
ok(!doDefaultAction, "untrusted submit event shouldn't trigger form default action");
SimpleTest.finish();
});
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -405,7 +405,10 @@ void HTMLFormElement::UnbindFromTree(bool aDeep, bool aNullParent) {
void HTMLFormElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
aVisitor.mWantsWillHandleEvent = true;
if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
// According to the UI events spec section "Trusted events", we shouldn't
// trigger UA default action with an untrusted event except click.
if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this) &&
aVisitor.mEvent->IsTrusted()) {
uint32_t msg = aVisitor.mEvent->mMessage;
if (msg == eFormSubmit) {
if (mGeneratingSubmit) {
@ -442,7 +445,10 @@ void HTMLFormElement::WillHandleEvent(EventChainPostVisitor& aVisitor) {
}
nsresult HTMLFormElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
// According to the UI events spec section "Trusted events", we shouldn't
// trigger UA default action with an untrusted event except click.
if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this) &&
aVisitor.mEvent->IsTrusted()) {
EventMessage msg = aVisitor.mEvent->mMessage;
if (msg == eFormSubmit) {
// let the form know not to defer subsequent submissions

178
dom/l10n/Mutations.cpp Normal file
Просмотреть файл

@ -0,0 +1,178 @@
#include "Mutations.h"
#include "mozilla/dom/DocumentInlines.h"
namespace mozilla {
namespace dom {
namespace l10n {
NS_IMPL_CYCLE_COLLECTION_CLASS(Mutations)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Mutations)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingElementsHash)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Mutations)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingElements)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingElementsHash)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Mutations)
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(Mutations)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Mutations)
Mutations::Mutations(DocumentL10n* aDocumentL10n)
: mDocumentL10n(aDocumentL10n) {
mObserving = true;
}
void Mutations::AttributeChanged(dom::Element* aElement, int32_t aNameSpaceID,
nsAtom* aAttribute, int32_t aModType,
const nsAttrValue* aOldValue) {
if (!mObserving) {
return;
}
Document* uncomposedDoc = aElement->GetUncomposedDoc();
if (uncomposedDoc) {
if (aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::datal10nid ||
aAttribute == nsGkAtoms::datal10nargs)) {
L10nElementChanged(aElement);
}
}
}
void Mutations::ContentAppended(nsIContent* aChild) {
if (!mObserving) {
return;
}
ErrorResult rv;
Sequence<OwningNonNull<Element>> elements;
nsINode* node = aChild;
while (node) {
if (node->IsElement()) {
Element* elem = node->AsElement();
Document* uncomposedDoc = elem->GetUncomposedDoc();
if (uncomposedDoc) {
mDocumentL10n->GetTranslatables(*node, elements, rv);
}
}
node = node->GetNextSibling();
}
for (auto& elem : elements) {
L10nElementChanged(elem);
}
}
void Mutations::ContentInserted(nsIContent* aChild) {
if (!mObserving) {
return;
}
ErrorResult rv;
Sequence<OwningNonNull<Element>> elements;
if (!aChild->IsElement()) {
return;
}
Element* elem = aChild->AsElement();
Document* uncomposedDoc = elem->GetUncomposedDoc();
if (!uncomposedDoc) {
return;
}
mDocumentL10n->GetTranslatables(*aChild, elements, rv);
for (auto& elem : elements) {
L10nElementChanged(elem);
}
}
void Mutations::L10nElementChanged(Element* aElement) {
if (!mPendingElementsHash.Contains(aElement)) {
mPendingElements.AppendElement(aElement);
mPendingElementsHash.PutEntry(aElement);
}
if (!mRefreshObserver) {
StartRefreshObserver();
}
}
void Mutations::PauseObserving() { mObserving = false; }
void Mutations::ResumeObserving() { mObserving = true; }
void Mutations::WillRefresh(mozilla::TimeStamp aTime) {
StopRefreshObserver();
FlushPendingTranslations();
}
void Mutations::FlushPendingTranslations() {
if (!mDocumentL10n) {
return;
}
ErrorResult rv;
Sequence<OwningNonNull<Element>> elements;
for (auto& elem : mPendingElements) {
if (!elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nid)) {
continue;
}
elements.AppendElement(*elem, fallible);
}
mPendingElementsHash.Clear();
mPendingElements.Clear();
RefPtr<Promise> promise = mDocumentL10n->TranslateElements(elements, rv);
}
void Mutations::Disconnect() {
StopRefreshObserver();
mDocumentL10n = nullptr;
}
void Mutations::StartRefreshObserver() {
if (!mDocumentL10n) {
return;
}
if (!mRefreshDriver) {
nsPresContext* ctx = mDocumentL10n->GetDocument()->GetPresContext();
if (!ctx) {
return;
}
mRefreshDriver = ctx->RefreshDriver();
}
if (mRefreshDriver) {
mRefreshDriver->AddRefreshObserver(this, FlushType::Style);
mRefreshObserver = true;
}
}
void Mutations::StopRefreshObserver() {
if (!mDocumentL10n) {
return;
}
if (mRefreshDriver) {
mRefreshDriver->RemoveRefreshObserver(this, FlushType::Style);
mRefreshObserver = false;
}
}
} // namespace l10n
} // namespace dom
} // namespace mozilla

78
dom/l10n/Mutations.h Normal file
Просмотреть файл

@ -0,0 +1,78 @@
#ifndef mozilla_dom_l10n_Mutations_h__
#define mozilla_dom_l10n_Mutations_h__
#include "nsRefreshDriver.h"
#include "nsStubMutationObserver.h"
#include "nsTHashtable.h"
#include "mozilla/dom/DocumentL10n.h"
namespace mozilla {
namespace dom {
namespace l10n {
/**
* Mutations manage observing roots for localization
* changes and coalescing pending translations into
* batches - one per animation frame.
*/
class Mutations final : public nsStubMutationObserver,
public nsARefreshObserver {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(Mutations, nsIMutationObserver)
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
explicit Mutations(DocumentL10n* aDocumentL10n);
/**
* Pause root observation.
* This is useful for injecting already-translated
* content into an observed root, without causing
* superflues translation.
*/
void PauseObserving();
/**
* Resume root observation.
*/
void ResumeObserving();
/**
* Disconnect roots, stop refresh observer
* and break the cycle collection deadlock
* by removing the reference to mDocumentL10n.
*/
void Disconnect();
protected:
bool mObserving = false;
bool mRefreshObserver = false;
RefPtr<nsRefreshDriver> mRefreshDriver;
DocumentL10n* mDocumentL10n;
// The hash is used to speed up lookups into mPendingElements.
nsTHashtable<nsRefPtrHashKey<Element>> mPendingElementsHash;
nsTArray<RefPtr<Element>> mPendingElements;
virtual void WillRefresh(mozilla::TimeStamp aTime) override;
void StartRefreshObserver();
void StopRefreshObserver();
void L10nElementChanged(Element* aElement);
void FlushPendingTranslations();
private:
~Mutations() {
StopRefreshObserver();
MOZ_ASSERT(!mDocumentL10n,
"DocumentL10n<-->Mutations cycle should be broken.");
}
};
} // namespace l10n
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_l10n_Mutations_h__

Просмотреть файл

@ -9,10 +9,12 @@ with Files("**"):
EXPORTS.mozilla.dom.l10n += [
'DOMOverlays.h',
'Mutations.h',
]
UNIFIED_SOURCES += [
'DOMOverlays.cpp',
'Mutations.cpp',
]
LOCAL_INCLUDES += [

Просмотреть файл

@ -16,7 +16,7 @@ using mozilla::NullPrincipal;
using namespace mozilla::dom;
using namespace mozilla::dom::l10n;
already_AddRefed<Document> SetUpDocument() {
static already_AddRefed<Document> SetUpDocument() {
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), "about:blank");
nsCOMPtr<nsIPrincipal> principal =

Просмотреть файл

@ -3,3 +3,9 @@
[test_domoverlays_text_children.html]
[test_domoverlays_extra_text_markup.html]
[test_domoverlays.xul]
[mutations/test_append_content_post_dcl.html]
[mutations/test_append_content_pre_dcl.html]
[mutations/test_append_fragment_post_dcl.html]
[mutations/test_set_attributes.html]
[mutations/test_pause_observing.html]

Просмотреть файл

@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test L10n Mutations for ContentAppended after DOMContentLoaded</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<link rel="localization" href="crashreporter/aboutcrashes.ftl"/>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
document.addEventListener("DOMContentLoaded", function() {
let elem = document.createElement("div");
document.l10n.setAttributes(elem, "crash-reports-title");
is(elem.textContent.length, 0);
let verifyL10n = () => {
if (elem.textContent.length > 0) {
window.removeEventListener("MozAfterPaint", verifyL10n);
SimpleTest.finish();
}
};
window.addEventListener("MozAfterPaint", verifyL10n);
document.body.appendChild(elem);
});
</script>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test L10n Mutations for ContentAppended before DOMContentLoaded</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<link rel="localization" href="crashreporter/aboutcrashes.ftl"/>
</head>
<body>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
let elem = document.createElement("div");
document.l10n.setAttributes(elem, "crash-reports-title");
is(elem.textContent.length, 0);
let verifyL10n = () => {
if (elem.textContent.length > 0) {
window.removeEventListener("MozAfterPaint", verifyL10n);
SimpleTest.finish();
}
};
window.addEventListener("MozAfterPaint", verifyL10n);
document.body.appendChild(elem);
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test L10n Mutations for appending a fragment after DOMContentLoaded</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<link rel="localization" href="crashreporter/aboutcrashes.ftl"/>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
document.addEventListener("DOMContentLoaded", function() {
let frag = document.createDocumentFragment();
let elem = document.createElement("div");
document.l10n.setAttributes(elem, "crash-reports-title");
frag.appendChild(elem);
let elem2 = document.createElement("div");
document.l10n.setAttributes(elem2, "crash-reports-title");
frag.appendChild(elem2);
is(elem.textContent.length, 0);
is(elem2.textContent.length, 0);
let verifyL10n = () => {
if (elem.textContent.length > 0 && elem2.textContent.length > 0) {
window.removeEventListener("MozAfterPaint", verifyL10n);
SimpleTest.finish();
}
};
window.addEventListener("MozAfterPaint", verifyL10n);
document.body.appendChild(frag);
});
</script>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -0,0 +1,44 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test L10n Mutations for Pause/Resume Observing</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<link rel="localization" href="crashreporter/aboutcrashes.ftl"/>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
document.addEventListener("DOMContentLoaded", function() {
let elem1 = document.createElement("div");
let elem2 = document.createElement("div");
let elem3 = document.createElement("div");
is(elem1.textContent.length, 0);
is(elem2.textContent.length, 0);
is(elem3.textContent.length, 0);
document.l10n.setAttributes(elem1, "crash-reports-title");
document.l10n.setAttributes(elem2, "crash-reports-title");
document.l10n.setAttributes(elem3, "crash-reports-title");
let verifyL10n = () => {
if (elem1.textContent.length > 0 &&
elem2.textContent.length == 0 &&
elem3.textContent.length > 0) {
window.removeEventListener("MozAfterPaint", verifyL10n);
SimpleTest.finish();
}
};
window.addEventListener("MozAfterPaint", verifyL10n);
document.body.appendChild(elem1);
document.l10n.pauseObserving();
document.body.appendChild(elem2);
document.l10n.resumeObserving();
document.body.appendChild(elem3);
});
</script>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test L10n Mutations for AttributeChange after DOMContentLoaded</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<link rel="localization" href="crashreporter/aboutcrashes.ftl"/>
<link rel="localization" href="toolkit/about/aboutConfig.ftl"/>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
document.addEventListener("DOMContentLoaded", async function() {
await document.l10n.ready;
let elem = document.getElementById("elem1");
let elem2 = document.getElementById("elem2");
is(elem.textContent.length, 0);
is(elem2.textContent.includes("Type 1"), true);
document.l10n.setAttributes(elem, "crash-reports-title");
elem2.setAttribute("data-l10n-args", JSON.stringify({type: "Type 2"}));
let verifyL10n = () => {
if (elem.textContent.length > 0 && elem2.textContent.includes("Type 2")) {
window.removeEventListener("MozAfterPaint", verifyL10n);
SimpleTest.finish();
}
};
window.addEventListener("MozAfterPaint", verifyL10n);
});
</script>
</head>
<body>
<div id="elem1"></div>
<div id="elem2" data-l10n-id="config-new-title" data-l10n-args='{"type":"Type 1"}'></div>
</body>
</html>

Просмотреть файл

@ -1,6 +1,6 @@
[package]
name = "u2fhid"
version = "0.2.3"
version = "0.2.4"
authors = ["Kyle Machulis <kyle@nonpolynomial.com>", "J.C. Jones <jc@mozilla.com>", "Tim Taubert <ttaubert@mozilla.com>"]
[target.'cfg(target_os = "linux")'.dependencies]
@ -23,7 +23,7 @@ features = [
]
[dependencies]
rand = "0.3"
rand = "0.6"
log = "0.4"
libc = "^0.2"
boxfnonce = "0.0.3"

Просмотреть файл

@ -6,7 +6,7 @@
extern crate std;
use rand::{thread_rng, Rng};
use rand::{thread_rng, RngCore};
use std::ffi::CString;
use std::io;
use std::io::{Read, Write};
@ -214,7 +214,7 @@ where
#[cfg(test)]
mod tests {
use rand::{thread_rng, Rng};
use rand::{thread_rng, RngCore};
use super::{init_device, send_apdu, sendrecv, U2FDevice};
use consts::{CID_BROADCAST, SW_NO_ERROR, U2FHID_INIT, U2FHID_MSG, U2FHID_PING};

Просмотреть файл

@ -700,3 +700,13 @@ WebGL2RenderingContext implements WebGL2RenderingContextBase;
[NoInterfaceObject]
interface EXT_color_buffer_float {
};
[NoInterfaceObject]
interface OVR_multiview2 {
const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR = 0x9630;
const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR = 0x9632;
const GLenum MAX_VIEWS_OVR = 0x9631;
const GLenum FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR = 0x9633;
void framebufferTextureMultiviewOVR(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level, GLint baseViewIndex, GLsizei numViews);
};

Просмотреть файл

@ -101,6 +101,12 @@ class DWriteFontFileStream final : public IDWriteFontFileStream {
IFACEMETHOD_(ULONG, Release)() {
uint32_t count = --mRefCnt;
if (count == 0) {
// Avoid locking unless necessary. Verify the refcount hasn't changed
// while locked. Delete within the scope of the lock when zero.
StaticMutexAutoLock lock(sFontFileStreamsMutex);
if (0 != mRefCnt) {
return mRefCnt;
}
delete this;
}
return count;
@ -151,7 +157,6 @@ DWriteFontFileStream::DWriteFontFileStream(uint64_t aFontFileKey)
: mRefCnt(0), mFontFileKey(aFontFileKey) {}
DWriteFontFileStream::~DWriteFontFileStream() {
StaticMutexAutoLock lock(sFontFileStreamsMutex);
sFontFileStreams.erase(mFontFileKey);
}

Просмотреть файл

@ -230,7 +230,7 @@ const ShCompileOptions SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW = UINT64_C
// With the flag enabled the GLSL/ESSL vertex shader is modified to include code for viewport
// selection in the following way:
// - Code to enable the extension NV_viewport_array2 is included.
// - Code to enable the extension ARB_shader_viewport_layer_array/NV_viewport_array2 is included.
// - Code to select the viewport index or layer is inserted at the beginning of main after
// ViewID_OVR's initialization.
// - A declaration of the uniform multiviewBaseViewLayerIndex.

Просмотреть файл

@ -1,3 +1,3 @@
#define ANGLE_COMMIT_HASH "5814bb88b10e"
#define ANGLE_COMMIT_HASH "1d5494fc3e85"
#define ANGLE_COMMIT_HASH_SIZE 12
#define ANGLE_COMMIT_DATE "2019-05-06 18:40:01 -0700"
#define ANGLE_COMMIT_DATE "2019-05-22 18:13:00 -0700"

Просмотреть файл

@ -1373,4 +1373,40 @@ bool TCompiler::isVaryingDefined(const char *varyingName)
return false;
}
void EmitMultiviewGLSL(const TCompiler &compiler,
const ShCompileOptions &compileOptions,
const TBehavior behavior,
TInfoSinkBase &sink)
{
ASSERT(behavior != EBhUndefined);
if (behavior == EBhDisable)
return;
const bool isVertexShader = (compiler.getShaderType() == GL_VERTEX_SHADER);
if (compileOptions & SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW)
{
// Emit ARB_shader_viewport_layer_array/NV_viewport_array2 in a vertex shader if the
// SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the
// OVR_multiview(2) extension is requested.
if (isVertexShader && (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER))
{
sink << "#if defined(GL_ARB_shader_viewport_layer_array)\n"
<< "#extension GL_ARB_shader_viewport_layer_array : require\n"
<< "#elif defined(GL_NV_viewport_array2)\n"
<< "#extension GL_NV_viewport_array2 : require\n"
<< "#endif\n";
}
}
else
{
sink << "#extension GL_OVR_multiview2 : " << GetBehaviorString(behavior) << "\n";
const auto &numViews = compiler.getNumViews();
if (isVertexShader && numViews != -1)
{
sink << "layout(num_views=" << numViews << ") in;\n";
}
}
}
} // namespace sh

Просмотреть файл

@ -296,6 +296,8 @@ class TCompiler : public TShHandleBase
TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
void DeleteCompiler(TCompiler *);
void EmitMultiviewGLSL(const TCompiler &, const ShCompileOptions &, TBehavior, TInfoSinkBase &sink);
} // namespace sh
#endif // COMPILER_TRANSLATOR_COMPILER_H_

Просмотреть файл

@ -124,9 +124,6 @@ void TranslatorESSL::writeExtensionBehavior(ShCompileOptions compileOptions)
{
TInfoSinkBase &sink = getInfoSink().obj;
const TExtensionBehavior &extBehavior = getExtensionBehavior();
const bool isMultiviewExtEmulated =
(compileOptions & (SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW |
SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER)) != 0u;
for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end();
++iter)
{
@ -144,16 +141,9 @@ void TranslatorESSL::writeExtensionBehavior(ShCompileOptions compileOptions)
sink << "#extension GL_NV_draw_buffers : " << GetBehaviorString(iter->second)
<< "\n";
}
else if (isMultiview && isMultiviewExtEmulated)
else if (isMultiview)
{
if (getShaderType() == GL_VERTEX_SHADER &&
(compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u)
{
// Emit the NV_viewport_array2 extension in a vertex shader if the
// SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the
// OVR_multiview2 extension is requested.
sink << "#extension GL_NV_viewport_array2 : require\n";
}
EmitMultiviewGLSL(*this, compileOptions, iter->second, sink);
}
else if (iter->first == TExtension::EXT_geometry_shader)
{

Просмотреть файл

@ -278,13 +278,9 @@ void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root, ShCompileOptions
}
const bool isMultiview = (iter.first == TExtension::OVR_multiview2);
if (isMultiview && getShaderType() == GL_VERTEX_SHADER &&
(compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u)
if (isMultiview)
{
// Emit the NV_viewport_array2 extension in a vertex shader if the
// SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the OVR_multiview2(2)
// extension is requested.
sink << "#extension GL_NV_viewport_array2 : require\n";
EmitMultiviewGLSL(*this, compileOptions, iter.second, sink);
}
// Support ANGLE_texture_multisample extension on GLSL300

Просмотреть файл

@ -1,3 +1,15 @@
commit 1d5494fc3e856d4d722e266d2b2075debac5146f
Author: Jeff Gilbert <jgilbert@mozilla.com>
Date: Thu Apr 25 14:57:26 2019 -0700
Emit OVR_multiview2 on ESSL/GLSL outputs.
Add ARB_shader_viewport_layer_array support to
SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER.
Bug: angleproject:3404
Change-Id: Ia89517d0cc92400ce47c9118e8c1abf8285aec41
commit 5814bb88b10ef903abcf297f2de72619d853b4e9
Author: Lee Salzman <lsalzman@mozilla.com>
Date: Tue Apr 30 23:42:31 2019 -0400

Просмотреть файл

@ -11,7 +11,7 @@ DEFINES['DYNAMIC_ANNOTATIONS_ENABLED'] = '1'
#DEFINES['FULL_SAFE_BROWSING'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -45,7 +45,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',

Просмотреть файл

@ -11,7 +11,7 @@ DEFINES['DYNAMIC_ANNOTATIONS_ENABLED'] = '1'
DEFINES['GPU_INFO_USE_SETUPAPI'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -45,7 +45,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',

Просмотреть файл

@ -10,7 +10,7 @@ DEFINES['DYNAMIC_ANNOTATIONS_ENABLED'] = '1'
#DEFINES['FULL_SAFE_BROWSING'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -44,7 +44,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',

Просмотреть файл

@ -16,7 +16,7 @@ DEFINES['DYNAMIC_ANNOTATIONS_ENABLED'] = '1'
DEFINES['LIBANGLE_IMPLEMENTATION'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -50,7 +50,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',

Просмотреть файл

@ -20,7 +20,7 @@ DEFINES['GL_GLEXT_PROTOTYPES'] = True
DEFINES['LIBEGL_IMPLEMENTATION'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -53,7 +53,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',
@ -165,7 +164,6 @@ OS_LIBS += [
#LDFLAGS += [
# '/DEBUG',
# '/DYNAMICBASE',
# '/fastfail',
# '/FIXED:NO',
# '/ignore:4199',
# '/ignore:4221',

Просмотреть файл

@ -21,7 +21,7 @@ DEFINES['LIBANGLE_IMPLEMENTATION'] = True
DEFINES['LIBGLESV2_IMPLEMENTATION'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -55,7 +55,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',
@ -173,7 +172,6 @@ OS_LIBS += [
#LDFLAGS += [
# '/DEBUG',
# '/DYNAMICBASE',
# '/fastfail',
# '/FIXED:NO',
# '/ignore:4199',
# '/ignore:4221',

Просмотреть файл

@ -10,7 +10,7 @@ DEFINES['DYNAMIC_ANNOTATIONS_ENABLED'] = '1'
#DEFINES['FULL_SAFE_BROWSING'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -44,7 +44,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',

Просмотреть файл

@ -13,7 +13,7 @@ DEFINES['DYNAMIC_ANNOTATIONS_ENABLED'] = '1'
#DEFINES['FULL_SAFE_BROWSING'] = True
DEFINES['NOMINMAX'] = True
#DEFINES['NO_TCMALLOC'] = True
DEFINES['NTDDI_VERSION'] = '0x0A000003'
DEFINES['NTDDI_VERSION'] = 'NTDDI_WIN10_RS2'
#DEFINES['PSAPI_VERSION'] = '2'
#DEFINES['SAFE_BROWSING_CSD'] = True
#DEFINES['SAFE_BROWSING_DB_LOCAL'] = True
@ -47,7 +47,6 @@ LOCAL_INCLUDES += [
#CXXFLAGS += [
# '/bigobj',
# '/d2FastFail',
# '/D__DATE__=',
# '/D__TIME__=',
# '/D__TIMESTAMP__=',

Просмотреть файл

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// clang-format off
#ifndef GLCONSTS_H_
#define GLCONSTS_H_
@ -7000,3 +7002,5 @@
#define LOCAL_WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
#endif // GLCONSTS_H_
// clang-format on

Просмотреть файл

@ -79,6 +79,7 @@ static const char* const sExtensionNames[] = {
"GL_ANGLE_framebuffer_blit",
"GL_ANGLE_framebuffer_multisample",
"GL_ANGLE_instanced_arrays",
"GL_ANGLE_multiview",
"GL_ANGLE_texture_compression_dxt3",
"GL_ANGLE_texture_compression_dxt5",
"GL_ANGLE_timer_query",
@ -204,7 +205,8 @@ static const char* const sExtensionNames[] = {
"GL_OES_texture_half_float",
"GL_OES_texture_half_float_linear",
"GL_OES_texture_npot",
"GL_OES_vertex_array_object"};
"GL_OES_vertex_array_object",
"GL_OVR_multiview2"};
static bool ShouldUseTLSIsCurrent(bool useTLSIsCurrent) {
if (gfxPrefs::UseTLSIsCurrent() == 0) return useTLSIsCurrent;
@ -1384,6 +1386,17 @@ void GLContext::LoadMoreSymbols(const SymbolLoader& loader) {
fnLoadForFeature(symbols, GLFeature::invalidate_framebuffer);
}
if (IsSupported(GLFeature::multiview)) {
const SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &mSymbols.fFramebufferTextureMultiview, {{
"glFramebufferTextureMultiviewOVR",
"glFramebufferTextureMultiviewLayeredANGLE"
}} },
END_SYMBOLS
};
fnLoadForFeature(symbols, GLFeature::multiview);
}
if (IsSupported(GLFeature::prim_restart)) {
const SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &mSymbols.fPrimitiveRestartIndex, {{ "glPrimitiveRestartIndex", "glPrimitiveRestartIndexNV" }} },

Просмотреть файл

@ -104,6 +104,7 @@ enum class GLFeature {
internalformat_query,
invalidate_framebuffer,
map_buffer_range,
multiview,
occlusion_query,
occlusion_query_boolean,
occlusion_query2,
@ -353,6 +354,7 @@ class GLContext : public GenericAtomicRefCounted,
ANGLE_framebuffer_blit,
ANGLE_framebuffer_multisample,
ANGLE_instanced_arrays,
ANGLE_multiview,
ANGLE_texture_compression_dxt3,
ANGLE_texture_compression_dxt5,
ANGLE_timer_query,
@ -479,6 +481,7 @@ class GLContext : public GenericAtomicRefCounted,
OES_texture_half_float_linear,
OES_texture_npot,
OES_vertex_array_object,
OVR_multiview2,
Extensions_Max,
Extensions_End
};
@ -3300,6 +3303,20 @@ class GLContext : public GenericAtomicRefCounted,
AFTER_GL_CALL;
}
// -----------------------------------------------------------------------------
// multiview
void fFramebufferTextureMultiview(GLenum target, GLenum attachment,
GLuint texture, GLint level,
GLint baseViewIndex,
GLsizei numViews) const {
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fFramebufferTextureMultiview);
mSymbols.fFramebufferTextureMultiview(target, attachment, texture, level,
baseViewIndex, numViews);
AFTER_GL_CALL;
}
#undef BEFORE_GL_CALL
#undef AFTER_GL_CALL
#undef ASSERT_SYMBOL_PRESENT

Просмотреть файл

@ -246,6 +246,12 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLESVersion::ES3,
GLContext::ARB_map_buffer_range,
{GLContext::EXT_map_buffer_range, GLContext::Extensions_End}},
{"multiview",
GLVersion::NONE,
GLESVersion::NONE,
GLContext::Extension_None,
{GLContext::ANGLE_multiview, GLContext::OVR_multiview2,
GLContext::Extensions_End}},
{
"occlusion_query",
GLVersion::GL2,

Просмотреть файл

@ -445,6 +445,13 @@ struct GLContextSymbols final {
// NV_primitive_restart
void(GLAPIENTRY* fPrimitiveRestartIndex)(GLuint);
// OVR_multiview2
void(GLAPIENTRY* fFramebufferTextureMultiview)(GLenum target,
GLenum attachment,
GLuint texture, GLint level,
GLint baseViewIndex,
GLsizei numViews);
};
} // namespace gl

Просмотреть файл

@ -52,6 +52,8 @@ class GLConstHeader:
' * License, v. 2.0. If a copy of the MPL was not distributed with this',
' * file, You can obtain one at http://mozilla.org/MPL/2.0/. */',
'',
'// clang-format off',
'',
'#ifndef GLCONSTS_H_',
'#define GLCONSTS_H_',
'',
@ -62,7 +64,7 @@ class GLConstHeader:
' *',
' * To generate this file, see tutorial in \'GLParseRegistryXML.py\'.',
' */',
''
'',
])
def formatLibBegin(self, lib):
@ -89,7 +91,9 @@ class GLConstHeader:
def formatFileEnd(self):
self.write([
'',
'#endif // GLCONSTS_H_'
'#endif // GLCONSTS_H_',
'',
'// clang-format on',
])

Просмотреть файл

@ -122,7 +122,7 @@ struct ScopedFramebuffer : public ScopedGLWrapper<ScopedFramebuffer> {
public:
explicit ScopedFramebuffer(GLContext* aGL);
GLuint FB() { return mFB; }
const auto& FB() const { return mFB; }
protected:
void UnwrapImpl();

Просмотреть файл

@ -8,11 +8,13 @@
#include <unordered_map>
#include "mozilla/Atomics.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/gfx/Logging.h"
class gfxDWriteFontFileStream;
static mozilla::Atomic<uint64_t> sNextFontFileKey;
static mozilla::StaticMutex sFontFileStreamsMutex;
static uint64_t sNextFontFileKey = 0;
static std::unordered_map<uint64_t, gfxDWriteFontFileStream*> sFontFileStreams;
IDWriteFontFileLoader* gfxDWriteFontFileLoader::mInstance = nullptr;
@ -46,18 +48,22 @@ class gfxDWriteFontFileStream final : public IDWriteFontFileStream {
IFACEMETHOD_(ULONG, AddRef)() {
MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
++mRefCnt;
return mRefCnt;
return ++mRefCnt;
}
IFACEMETHOD_(ULONG, Release)() {
MOZ_ASSERT(0 != mRefCnt, "dup release");
--mRefCnt;
if (mRefCnt == 0) {
uint32_t count = --mRefCnt;
if (count == 0) {
// Avoid locking unless necessary. Verify the refcount hasn't changed
// while locked. Delete within the scope of the lock when zero.
mozilla::StaticMutexAutoLock lock(sFontFileStreamsMutex);
if (0 != mRefCnt) {
return mRefCnt;
}
delete this;
return 0;
}
return mRefCnt;
return count;
}
// IDWriteFontFileStream methods
@ -81,7 +87,7 @@ class gfxDWriteFontFileStream final : public IDWriteFontFileStream {
private:
FallibleTArray<uint8_t> mData;
nsAutoRefCnt mRefCnt;
mozilla::Atomic<uint32_t> mRefCnt;
uint64_t mFontFileKey;
};
@ -134,6 +140,7 @@ HRESULT STDMETHODCALLTYPE gfxDWriteFontFileLoader::CreateStreamFromKey(
return E_POINTER;
}
mozilla::StaticMutexAutoLock lock(sFontFileStreamsMutex);
uint64_t fontFileKey = *static_cast<const uint64_t*>(fontFileReferenceKey);
auto found = sFontFileStreams.find(fontFileKey);
if (found == sFontFileStreams.end()) {
@ -161,10 +168,12 @@ gfxDWriteFontFileLoader::CreateCustomFontFile(
return E_FAIL;
}
sFontFileStreamsMutex.Lock();
uint64_t fontFileKey = sNextFontFileKey++;
RefPtr<gfxDWriteFontFileStream> ffsRef =
new gfxDWriteFontFileStream(aFontData, aLength, fontFileKey);
sFontFileStreams[fontFileKey] = ffsRef;
sFontFileStreamsMutex.Unlock();
RefPtr<IDWriteFontFile> fontFile;
HRESULT hr = factory->CreateCustomFontFileReference(

Просмотреть файл

@ -12,5 +12,8 @@ members = [
debug = true
panic = "abort"
[profile.dev]
panic = "abort"
[patch.crates-io]
serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums10", feature="deserialize_in_place" }

Просмотреть файл

@ -56,3 +56,29 @@ Release mode:
Now the APK at ../target/android-artifacts/app/build/outputs/apk/app-release-unsigned.apk
should be signed and installable (you may need to uninstall the debug APK first if you
have that installed).
Running reftests like a boss:
-----------------------------
First, compile wrench as described above (debug mode).
Then, from the root gecko source dir, run:
./mach python testing/mozharness/scripts/android_emulator_wrench.py --config testing/mozharness/configs/android/wrench.py
This will automatically do the following:
- Download the blessed android AVDs from taskcluster
- Start the emulator (using your ~/.mozbuild/android-sdk-linux emulator binaries)
- Install the debug APK (from gfx/wr/wrench/target/.../app-debug.apk)
- Copy the reftests to the sdcard
- Write an args file to the sdcard
- Run wrench
- Wait for wrench to finish running
- Scrape the logcat for reftest output
Other logs (e.g. full logcat) can be found in your ~/.wrench/logs folder. Note that
this will also leave the android emulator running, so repeating the command will be
even faster the next time around as it won't need to redownload the AVDs or restart
the emulator. It will reinstall the APK and re-push the reftests folder though.
If you want to use a release APK (runs much faster), build it as per the "Release mode"
instructions above and set the WRENCH_APK env var to point to the APK:
to point to it:
export WRENCH_APK=gfx/wr/target/android-artifacts/app/build/outputs/apk/app-release-unsigned.apk
./mach python testing/mozharness/scripts/android_emulator_wrench.py --config testing/mozharness/configs/android/wrench.py

Просмотреть файл

@ -1,2 +1,2 @@
== rounded-rects.yaml rounded-rects-ref.png
skip_on(android) == rounded-rects.yaml rounded-rects-ref.png # Too wide for Android
== aa-dist-bug.yaml aa-dist-bug-ref.yaml

Просмотреть файл

@ -1,15 +1,20 @@
== multiply.yaml multiply-ref.yaml
== multiply-2.yaml multiply-2-ref.yaml
== color_targets(3) alpha_targets(0) multiply-3.yaml multiply-2-ref.yaml
== difference.yaml difference-ref.yaml
fuzzy(1,30000) == difference-transparent.yaml difference-transparent-ref.yaml
== darken.yaml darken-ref.yaml
== lighten.yaml lighten-ref.yaml
# Some tests in this file skipped on debug Android because of panic,
# GL error 502 at blit_framebuffer. These are marked with skip_on(android)
# or skip_on(android,debug). Additionally, the ones marked skip_on(android)
# fail in opt builds.
== repeated-difference.yaml repeated-difference-ref.yaml
skip_on(android,debug) == multiply.yaml multiply-ref.yaml
skip_on(android) == multiply-2.yaml multiply-2-ref.yaml
skip_on(android) == color_targets(3) alpha_targets(0) multiply-3.yaml multiply-2-ref.yaml
skip_on(android) == difference.yaml difference-ref.yaml
skip_on(android) fuzzy(1,30000) == difference-transparent.yaml difference-transparent-ref.yaml
skip_on(android) == darken.yaml darken-ref.yaml
skip_on(android) == lighten.yaml lighten-ref.yaml
skip_on(android,debug) == repeated-difference.yaml repeated-difference-ref.yaml
== isolated.yaml isolated-ref.yaml
== isolated-2.yaml isolated-2-ref.yaml
skip_on(android) == isolated-2.yaml isolated-2-ref.yaml
== isolated-with-filter.yaml isolated-ref.yaml
== isolated-premultiplied.yaml blank.yaml
== isolated-premultiplied-2.yaml isolated-premultiplied-2-ref.yaml
@ -21,4 +26,4 @@ fuzzy(1,30000) == difference-transparent.yaml difference-transparent-ref.yaml
fuzzy(1,2502) == transparent-composite-1.yaml transparent-composite-1-ref.yaml
fuzzy(1,2502) == transparent-composite-2.yaml transparent-composite-2-ref.yaml
== multi-mix-blend-mode.yaml multi-mix-blend-mode-ref.yaml
skip_on(android) == multi-mix-blend-mode.yaml multi-mix-blend-mode-ref.yaml

Просмотреть файл

@ -18,7 +18,7 @@ fuzzy(64,24) == border-ridge-simple.yaml border-ridge-simple-ref.yaml
platform(linux,mac) fuzzy(1,3) == degenerate-curve.yaml degenerate-curve.png
platform(linux,mac) == border-image.yaml border-image-ref.png
== border-image-crash.yaml border-image-crash-ref.yaml
== border-image-fill.yaml border-image-fill-ref.png
skip_on(android) == border-image-fill.yaml border-image-fill-ref.png # fails on Android
== border-no-bogus-line.yaml border-no-bogus-line-ref.png
platform(linux,mac) == dotted-corner-small-radius.yaml dotted-corner-small-radius.png
== overlapping.yaml overlapping.png

Просмотреть файл

@ -15,7 +15,7 @@ platform(linux,mac) == box-shadow-suite-blur.yaml box-shadow-suite-blur.png
== box-shadow-large-blur-radius.yaml box-shadow-large-blur-radius-ref.yaml
fuzzy(1,6388) == rounding.yaml rounding-ref.yaml
platform(linux,mac) == box-shadow-border-radii.yaml box-shadow-border-radii.png
== box-shadow-spread.yaml box-shadow-spread.png
skip_on(android) == box-shadow-spread.yaml box-shadow-spread.png # Too wide for Android
== box-shadow-spread-radii.yaml box-shadow-spread-radii-ref.yaml
== invalid.yaml invalid-ref.yaml
== inset-empty.yaml blank.yaml
@ -23,7 +23,7 @@ platform(linux,mac) == inset-subpx.yaml inset-subpx.png
platform(linux,mac) fuzzy(1,4) == inset-downscale.yaml inset-downscale.png
platform(linux,mac) fuzzy(1,50) == box-shadow-cache.yaml box-shadow-cache.png
platform(linux,mac) fuzzy(1,685) == overlap1.yaml overlap1.png
fuzzy(1,61) == overlap2.yaml overlap2.png
fuzzy(1,134) == overlap2.yaml overlap2.png
platform(linux,mac) fuzzy(1,48) == no-stretch.yaml no-stretch.png
platform(linux,mac) fuzzy(1,9) == box-shadow-stretch-mode-x.yaml box-shadow-stretch-mode-x.png
platform(linux,mac) fuzzy(1,41) == box-shadow-stretch-mode-y.yaml box-shadow-stretch-mode-y.png

Просмотреть файл

@ -11,4 +11,4 @@ platform(linux,mac) == segmentation-with-other-coordinate-system-clip.yaml segme
== segmentation-across-rotation.yaml segmentation-across-rotation-ref.yaml
== color_targets(2) alpha_targets(1) stacking-context-clip.yaml stacking-context-clip-ref.yaml
== snapping.yaml snapping-ref.yaml
fuzzy(65,2400) == clip-and-filter-with-rotation.yaml clip-and-filter-with-rotation-ref.yaml
fuzzy(70,2400) == clip-and-filter-with-rotation.yaml clip-and-filter-with-rotation-ref.yaml

Просмотреть файл

@ -9,13 +9,13 @@ color_targets(1) alpha_targets(0) == opacity-combined.yaml opacity-combined-ref.
== filter-brightness-2.yaml filter-brightness-2-ref.yaml
== filter-brightness-3.yaml filter-brightness-3-ref.yaml
== filter-brightness-4.yaml filter-brightness-4-ref.yaml
== filter-component-transfer.yaml filter-component-transfer-ref.yaml
skip_on(android) == filter-component-transfer.yaml filter-component-transfer-ref.yaml # fails on Android
== filter-color-matrix.yaml filter-color-matrix-ref.yaml
== filter-contrast-gray-alpha-1.yaml filter-contrast-gray-alpha-1-ref.yaml
== filter-invert.yaml filter-invert-ref.yaml
== filter-invert-2.yaml filter-invert-2-ref.yaml
platform(linux,mac) fuzzy(1,133) == filter-large-blur-radius.yaml filter-large-blur-radius.png
== draw_calls(4) color_targets(4) alpha_targets(0) filter-small-blur-radius.yaml filter-small-blur-radius.png
skip_on(android) == draw_calls(4) color_targets(4) alpha_targets(0) filter-small-blur-radius.yaml filter-small-blur-radius.png # fails on Android
== filter-saturate-red-1.yaml filter-saturate-red-1-ref.yaml
== filter-saturate-red-2.yaml filter-saturate-red-2-ref.yaml
== filter-saturate-red-3.yaml filter-saturate-red-3-ref.yaml
@ -30,17 +30,17 @@ platform(linux,mac) fuzzy(1,133) == filter-large-blur-radius.yaml filter-large-b
== filter-saturate-blue-alpha-1.yaml filter-saturate-blue-alpha-1-ref.yaml
== filter-hue-rotate-1.yaml filter-hue-rotate-1-ref.yaml
== filter-hue-rotate-alpha-1.yaml filter-hue-rotate-alpha-1-ref.yaml
fuzzy(1,14) == filter-long-chain.yaml filter-long-chain.png
skip_on(android) fuzzy(1,14) == filter-long-chain.yaml filter-long-chain.png # fails on Android
platform(linux,mac) == filter-drop-shadow.yaml filter-drop-shadow.png
platform(linux,mac) == filter-drop-shadow-on-viewport-edge.yaml filter-drop-shadow-on-viewport-edge.png
platform(linux,mac) == blend-clipped.yaml blend-clipped.png
platform(linux,mac) == filter-drop-shadow-clip.yaml filter-drop-shadow-clip.png
== filter-segments.yaml filter-segments-ref.yaml
== iframe-dropshadow.yaml iframe-dropshadow-ref.yaml
== filter-mix-blend-mode.yaml filter-mix-blend-mode-ref.yaml
skip_on(android) == filter-mix-blend-mode.yaml filter-mix-blend-mode-ref.yaml # Android debug: GL error 502 at blit_framebuffer, Android opt: fails
== fuzzy(3,20000) srgb-to-linear.yaml srgb-to-linear-ref.yaml
!= srgb-to-linear-2.yaml srgb-to-linear-ref.yaml
!= filter-blur-huge.yaml blank.yaml
!= filter-drop-shadow-huge.yaml blank.yaml
== filter-blur-scaled.yaml filter-blur-scaled-ref.yaml
== filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png
skip_on(android) == filter-blur-scaled-xonly.yaml filter-blur-scaled-xonly.png # fails on Android

Просмотреть файл

@ -18,7 +18,7 @@ platform(linux,mac) fuzzy(1,35000) == linear-stops.yaml linear-stops-ref.png
fuzzy(1,20000) == linear.yaml linear-ref.yaml
fuzzy(1,20000) == linear-reverse.yaml linear-ref.yaml
fuzzy(1,15200) == linear-aligned-clip.yaml linear-aligned-clip-ref.yaml
skip_on(android,debug) fuzzy(1,15200) == linear-aligned-clip.yaml linear-aligned-clip-ref.yaml # Android: GL error 502 at blit_framebuffer
platform(linux,mac) fuzzy(1,80000) == radial-circle.yaml radial-circle-ref.png
platform(linux,mac) fuzzy(1,80000) == radial-ellipse.yaml radial-ellipse-ref.png

Просмотреть файл

@ -1,10 +1,15 @@
== tile-size.yaml tile-size-ref.yaml
== very-big.yaml very-big-ref.yaml
# Some tests in this file skipped on debug Android because of panic,
# GL error 502 at tex_sub_image_3d_pbo. These are marked with skip_on(android)
# or skip_on(android,debug). Additionally, the ones marked skip_on(android)
# fail in opt builds.
skip_on(android) == tile-size.yaml tile-size-ref.yaml
skip_on(android) == very-big.yaml very-big-ref.yaml
== very-big-tile-size.yaml very-big-tile-size-ref.yaml
== tile-with-spacing.yaml tile-with-spacing-ref.yaml
fuzzy(1,331264) == tile-repeat-prim-or-decompose.yaml tile-repeat-prim-or-decompose-ref.yaml
skip_on(android,debug) == tile-with-spacing.yaml tile-with-spacing-ref.yaml
skip_on(android) fuzzy(1,331264) == tile-repeat-prim-or-decompose.yaml tile-repeat-prim-or-decompose-ref.yaml
platform(linux,mac) options(allow-mipmaps) == downscale.yaml downscale.png
== segments.yaml segments.png
skip_on(android) == segments.yaml segments.png
platform(linux,mac) == yuv.yaml yuv.png
== tiled-clip-chain.yaml tiled-clip-chain-ref.yaml
== tiled-complex-clip.yaml tiled-complex-clip-ref.yaml
skip_on(android) == tiled-clip-chain.yaml tiled-clip-chain-ref.yaml
skip_on(android) == tiled-complex-clip.yaml tiled-complex-clip-ref.yaml

Просмотреть файл

@ -1,2 +1,5 @@
# Test that a red -> green -> red rect correctly invalidates each frame
dirty([(50,50):256x256]) one-rounded-rect.yaml dirty([(50,50):256x256]) one-rounded-rect-green.yaml dirty([(50,50):256x256]) one-rounded-rect.yaml == one-rounded-rect.yaml
# Skipped on debug Android debug because of panic,
# GL error 502 at blit_framebuffer. It also fails on
# Android release.
skip_on(android) dirty([(50,50):256x256]) one-rounded-rect.yaml dirty([(50,50):256x256]) one-rounded-rect-green.yaml dirty([(50,50):256x256]) one-rounded-rect.yaml == one-rounded-rect.yaml

Просмотреть файл

@ -1,7 +1,7 @@
== mask.yaml mask-ref.yaml
== mask-tiling.yaml mask-ref.yaml
skip_on(android) == mask-tiling.yaml mask-ref.yaml # Android: GL error 502 at tex_sub_image_3d_pbo, fails on opt
== nested-mask.yaml nested-mask-ref.yaml
== nested-mask-tiling.yaml nested-mask-ref.yaml
skip_on(android) == nested-mask-tiling.yaml nested-mask-ref.yaml # Android: GL error 502 at tex_sub_image_3d_pbo, fails on opt
!= mask.yaml green.yaml
== aligned-layer-rect.yaml aligned-layer-rect-ref.yaml
== mask-transformed-to-empty-rect.yaml mask-transformed-to-empty-rect-ref.yaml
@ -10,7 +10,7 @@ platform(linux,mac) == rounded-corners.yaml rounded-corners.png
platform(linux,mac) fuzzy(1,8750) color_targets(2) alpha_targets(1) == mask-atomicity.yaml mask-atomicity-ref.yaml
platform(linux,mac) fuzzy(1,8750) == mask-atomicity-tiling.yaml mask-atomicity-ref.yaml
platform(linux,mac) == mask-perspective.yaml mask-perspective.png
== fuzzy(1,6) mask-perspective-tiling.yaml mask-perspective.yaml
skip_on(android) == fuzzy(1,6) mask-perspective-tiling.yaml mask-perspective.yaml # Android: GL error 502 at tex_sub_image_3d_pbo, fails on opt
platform(linux,mac) == checkerboard.yaml checkerboard.png
== checkerboard.yaml checkerboard-tiling.yaml
skip_on(android) == checkerboard.yaml checkerboard-tiling.yaml # Android: GL error 502 at blit_framebuffer, fails on opt
== missing-mask.yaml missing-mask-ref.yaml

Просмотреть файл

@ -1 +1 @@
== color_targets(1) alpha_targets(0) no-clip-mask.yaml no-clip-mask.png
skip_on(android) == color_targets(1) alpha_targets(0) no-clip-mask.yaml no-clip-mask.png # Too wide for Android

Просмотреть файл

@ -10,7 +10,7 @@ fuzzy(35,200) == nested-coord-systems.yaml nested-coord-systems-ref.yaml
== intermediate-2.yaml intermediate-1-ref.yaml
== split-intersect1.yaml split-intersect1-ref.yaml
== ordering.yaml ordering-ref.yaml
fuzzy(1,20) == near-plane.yaml near-plane.png
skip_on(android) fuzzy(1,20) == near-plane.yaml near-plane.png # Fails on Android
# Note: on windows the image is rendered at a slightly different spot.
# similarly, a lot of tests in "transform" are non-windows. TODO: investigate
platform(linux,mac) fuzzy(1,20) == same-plane.yaml same-plane.png

Просмотреть файл

@ -6,7 +6,7 @@
!= shadow-cover-1.yaml blank.yaml
!= shadow-cover-2.yaml blank.yaml
== shadow.yaml shadow-ref.yaml
skip_on(android) == shadow.yaml shadow-ref.yaml # Fails on Android
== shadow-huge.yaml shadow-huge-ref.yaml
!= shadow-cover-1.yaml shadow-cover-2.yaml
!= shadow-many.yaml shadow.yaml
@ -14,22 +14,24 @@
!= shadow-clipped-text.yaml blank.yaml
!= non-opaque.yaml non-opaque-notref.yaml
== decorations.yaml decorations-ref.yaml
fuzzy(1,173) == decorations-suite.yaml decorations-suite.png
skip_on(android) fuzzy(1,173) == decorations-suite.yaml decorations-suite.png # Fails on Android
== 1658.yaml 1658-ref.yaml
fuzzy(1,5) == split-batch.yaml split-batch-ref.yaml
== shadow-red.yaml shadow-red-ref.yaml
fuzzy(1,735) == shadow-grey.yaml shadow-grey-ref.yaml
fuzzy(1,663) == shadow-grey-transparent.yaml shadow-grey-ref.yaml
skip_on(android,debug) fuzzy(1,5) == split-batch.yaml split-batch-ref.yaml # Android: GL error 502 at blit_framebuffer
# Next 3 tests affected by bug 1548099 on Android
skip_on(android) == shadow-red.yaml shadow-red-ref.yaml
skip_on(android) fuzzy(1,735) == shadow-grey.yaml shadow-grey-ref.yaml
skip_on(android) fuzzy(1,663) == shadow-grey-transparent.yaml shadow-grey-ref.yaml
== subtle-shadow.yaml subtle-shadow-ref.yaml
== shadow-atomic.yaml shadow-atomic-ref.yaml
== shadow-clip-rect.yaml shadow-atomic-ref.yaml
fuzzy(1,1) platform(linux) == shadow-ordering.yaml shadow-ordering-ref.yaml
!= synthetic-bold.yaml synthetic-bold-not-ref.yaml
fuzzy(1,1786) options(disable-subpixel) == synthetic-bold-transparent.yaml synthetic-bold-transparent-ref.yaml
!= synthetic-bold-transparent.yaml synthetic-bold.yaml
!= synthetic-italics.yaml synthetic-italics-ref.yaml
!= synthetic-italics-custom.yaml synthetic-italics-ref.yaml
!= synthetic-italics-custom.yaml synthetic-italics.yaml
# Next 6 tests affected by bug 1548099 on Android
skip_on(android) != synthetic-bold.yaml synthetic-bold-not-ref.yaml
skip_on(android) fuzzy(1,1786) options(disable-subpixel) == synthetic-bold-transparent.yaml synthetic-bold-transparent-ref.yaml
skip_on(android) != synthetic-bold-transparent.yaml synthetic-bold.yaml
skip_on(android) != synthetic-italics.yaml synthetic-italics-ref.yaml
skip_on(android) != synthetic-italics-custom.yaml synthetic-italics-ref.yaml
skip_on(android) != synthetic-italics-custom.yaml synthetic-italics.yaml
options(disable-aa) == ahem.yaml ahem-ref.yaml
platform(linux) == isolated-text.yaml isolated-text.png
platform(mac) skip_on(mac,>=10.14) fuzzy(3,67) == white-opacity.yaml white-opacity.png
@ -56,16 +58,16 @@ platform(linux) == writing-modes.yaml writing-modes-ref.yaml
platform(linux) == blurred-shadow-local-clip-rect.yaml blurred-shadow-local-clip-rect-ref.png
fuzzy(1,1) platform(linux) == two-shadows.yaml two-shadows.png
== shadow-clip.yaml shadow-clip-ref.yaml
== shadow-fast-clip.yaml shadow-fast-clip-ref.yaml
== shadow-partial-glyph.yaml shadow-partial-glyph-ref.yaml
skip_on(android) == shadow-fast-clip.yaml shadow-fast-clip-ref.yaml # Fails on Android
skip_on(android) == shadow-partial-glyph.yaml shadow-partial-glyph-ref.yaml # Fails on Android
fuzzy(1,107) platform(linux) == shadow-transforms.yaml shadow-transforms.png
fuzzy(1,113) platform(linux) == raster-space.yaml raster-space.png
skip_on(mac,>=10.14) != allow-subpixel.yaml allow-subpixel-ref.yaml
skip_on(android,debug) skip_on(mac,>=10.14) != allow-subpixel.yaml allow-subpixel-ref.yaml # Android: GL error 502 at blit_framebuffer
== bg-color.yaml bg-color-ref.yaml
!= large-glyphs.yaml blank.yaml
== snap-text-offset.yaml snap-text-offset-ref.yaml
== shadow-border.yaml shadow-solid-ref.yaml
== shadow-image.yaml shadow-solid-ref.yaml
options(disable-aa) == snap-clip.yaml snap-clip-ref.yaml
skip_on(android) == shadow-image.yaml shadow-solid-ref.yaml # Fails on Android
skip_on(android) options(disable-aa) == snap-clip.yaml snap-clip-ref.yaml # Fails on Android
platform(linux) == perspective-clip.yaml perspective-clip.png
options(disable-subpixel) == raster-space-snap.yaml raster-space-snap-ref.yaml

Просмотреть файл

@ -1,7 +1,7 @@
platform(linux,mac) == local-clip.yaml local-clip.png
platform(linux,mac) == rotated-clip.yaml rotated-clip.png
platform(linux,mac) == rotated-clip-large.yaml rotated-clip-large.png
== image-rotated-clip.yaml image-rotated-clip.png
skip_on(android) == image-rotated-clip.yaml image-rotated-clip.png # Fails on Android
# Something leaks the state: the test passes if only run `reftest reftests/transform`
# but fails when all the tests are run
platform(linux,mac) fuzzy(1,4) == rotated-image.yaml rotated-image.png
@ -23,7 +23,7 @@ platform(linux,mac) == nested-preserve-3d.yaml nested-preserve-3d.png
platform(linux,mac) fuzzy(1,283) == near-plane-clip.yaml near-plane-clip.png
platform(linux,mac) == perspective-mask.yaml perspective-mask.png
rotate-clip.yaml rotate-clip-ref.yaml
clip-translate.yaml clip-translate-ref.yaml
skip_on(android) == clip-translate.yaml clip-translate-ref.yaml # Fails on Android
platform(linux,mac) == perspective-clip.yaml perspective-clip.png
platform(linux,mac) fuzzy(1,2) == perspective-clip-1.yaml perspective-clip-1.png
platform(linux,mac) fuzzy(1,2) == perspective-shadow.yaml perspective-shadow.png

Просмотреть файл

@ -8,12 +8,14 @@
#include "js/JSON.h" // JS_ParseJSON
#include "mozilla/dom/DocumentL10n.h"
#include "mozilla/dom/DocumentL10nBinding.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/L10nUtilsBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/l10n/DOMOverlays.h"
#include "mozilla/intl/LocaleService.h"
#include "nsQueryObject.h"
#include "nsIScriptError.h"
#include "nsISupports.h"
#include "nsImportModule.h"
#include "nsContentUtils.h"
@ -27,6 +29,8 @@
static const char* kObservedPrefs[] = {L10N_PSEUDO_PREF, INTL_UI_DIRECTION_PREF,
nullptr};
using namespace mozilla::intl;
namespace mozilla {
namespace dom {
@ -51,8 +55,26 @@ void PromiseResolver::RejectedCallback(JSContext* aCx,
PromiseResolver::~PromiseResolver() { mPromise = nullptr; }
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DocumentL10n, mDocument, mDOMLocalization,
mContentSink, mReady)
NS_IMPL_CYCLE_COLLECTION_CLASS(DocumentL10n)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DocumentL10n)
tmp->DisconnectMutations();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMutations)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalization)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContentSink)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReady)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoots)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DocumentL10n)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMutations)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalization)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReady)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoots)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(DocumentL10n)
NS_IMPL_CYCLE_COLLECTING_ADDREF(DocumentL10n)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DocumentL10n)
@ -66,6 +88,7 @@ NS_INTERFACE_MAP_END
DocumentL10n::DocumentL10n(Document* aDocument)
: mDocument(aDocument), mState(DocumentL10nState::Initialized) {
mContentSink = do_QueryInterface(aDocument->GetCurrentContentSink());
mMutations = new mozilla::dom::l10n::Mutations(this);
}
DocumentL10n::~DocumentL10n() {
@ -75,15 +98,24 @@ DocumentL10n::~DocumentL10n() {
}
Preferences::RemoveObservers(this, kObservedPrefs);
DisconnectMutations();
}
void DocumentL10n::DisconnectMutations() {
if (mMutations) {
mMutations->Disconnect();
DisconnectRoots();
}
}
bool DocumentL10n::Init(nsTArray<nsString>& aResourceIds) {
nsCOMPtr<mozIDOMLocalizationJSM> jsm =
do_ImportModule("resource://gre/modules/DOMLocalization.jsm");
nsCOMPtr<mozILocalizationJSM> jsm =
do_ImportModule("resource://gre/modules/Localization.jsm");
MOZ_RELEASE_ASSERT(jsm);
Unused << jsm->GetDOMLocalization(getter_AddRefs(mDOMLocalization));
MOZ_RELEASE_ASSERT(mDOMLocalization);
Unused << jsm->GetLocalization(getter_AddRefs(mLocalization));
MOZ_RELEASE_ASSERT(mLocalization);
nsIGlobalObject* global = mDocument->GetScopeObject();
if (!global) {
@ -101,7 +133,7 @@ bool DocumentL10n::Init(nsTArray<nsString>& aResourceIds) {
// resources will be ready by the time the document
// is ready for localization.
uint32_t ret;
if (NS_FAILED(mDOMLocalization->AddResourceIds(aResourceIds, true, &ret))) {
if (NS_FAILED(mLocalization->AddResourceIds(aResourceIds, true, &ret))) {
return false;
}
@ -128,32 +160,19 @@ NS_IMETHODIMP
DocumentL10n::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
if (!strcmp(aTopic, INTL_APP_LOCALES_CHANGED)) {
if (mDOMLocalization) {
mDOMLocalization->OnChange();
}
OnChange();
} else {
MOZ_ASSERT(!strcmp("nsPref:changed", aTopic));
nsDependentString pref(aData);
if (pref.EqualsLiteral(L10N_PSEUDO_PREF) ||
pref.EqualsLiteral(INTL_UI_DIRECTION_PREF)) {
if (mDOMLocalization) {
mDOMLocalization->OnChange();
}
OnChange();
}
}
return NS_OK;
}
void DocumentL10n::Destroy() {
if (mDOMLocalization) {
Element* elem = mDocument->GetDocumentElement();
if (elem) {
mDOMLocalization->DisconnectRoot(elem);
}
}
}
JSObject* DocumentL10n::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return DocumentL10n_Binding::Wrap(aCx, this, aGivenProto);
@ -185,19 +204,19 @@ already_AddRefed<Promise> DocumentL10n::MaybeWrapPromise(
uint32_t DocumentL10n::AddResourceIds(nsTArray<nsString>& aResourceIds) {
uint32_t ret = 0;
mDOMLocalization->AddResourceIds(aResourceIds, false, &ret);
mLocalization->AddResourceIds(aResourceIds, false, &ret);
return ret;
}
uint32_t DocumentL10n::RemoveResourceIds(nsTArray<nsString>& aResourceIds) {
// We need to guard against a scenario where the
// mDOMLocalization has been unlinked, but the elements
// mLocalization has been unlinked, but the elements
// are only now removed from DOM.
if (!mDOMLocalization) {
if (!mLocalization) {
return 0;
}
uint32_t ret = 0;
mDOMLocalization->RemoveResourceIds(aResourceIds, &ret);
mLocalization->RemoveResourceIds(aResourceIds, &ret);
return ret;
}
@ -215,7 +234,7 @@ already_AddRefed<Promise> DocumentL10n::FormatMessages(
}
RefPtr<Promise> promise;
aRv = mDOMLocalization->FormatMessages(jsKeys, getter_AddRefs(promise));
aRv = mLocalization->FormatMessages(jsKeys, getter_AddRefs(promise));
if (aRv.Failed()) {
return nullptr;
}
@ -237,7 +256,7 @@ already_AddRefed<Promise> DocumentL10n::FormatValues(
}
RefPtr<Promise> promise;
aRv = mDOMLocalization->FormatValues(jsKeys, getter_AddRefs(promise));
aRv = mLocalization->FormatValues(jsKeys, getter_AddRefs(promise));
if (aRv.Failed()) {
return nullptr;
}
@ -257,8 +276,7 @@ already_AddRefed<Promise> DocumentL10n::FormatValue(
}
RefPtr<Promise> promise;
nsresult rv =
mDOMLocalization->FormatValue(aId, args, getter_AddRefs(promise));
nsresult rv = mLocalization->FormatValue(aId, args, getter_AddRefs(promise));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
@ -316,7 +334,9 @@ void DocumentL10n::GetAttributes(JSContext* aCx, Element& aElement,
class LocalizationHandler : public PromiseNativeHandler {
public:
explicit LocalizationHandler(nsINode* aNode) { mNode = aNode; };
explicit LocalizationHandler(DocumentL10n* aDocumentL10n) {
mDocumentL10n = aDocumentL10n;
};
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(LocalizationHandler)
@ -331,8 +351,6 @@ class LocalizationHandler : public PromiseNativeHandler {
JS::Handle<JS::Value> aValue) override {
ErrorResult rv;
RefPtr<DocumentL10n> docL10n = mNode->OwnerDoc()->GetL10n();
nsTArray<L10nValue> l10nData;
if (aValue.isObject()) {
JS::ForOfIterator iter(aCx);
@ -375,12 +393,10 @@ class LocalizationHandler : public PromiseNativeHandler {
return;
}
if (docL10n) {
docL10n->PauseObserving(rv);
if (NS_WARN_IF(rv.Failed())) {
mReturnValuePromise->MaybeRejectWithUndefined();
return;
}
mDocumentL10n->PauseObserving(rv);
if (NS_WARN_IF(rv.Failed())) {
mReturnValuePromise->MaybeRejectWithUndefined();
return;
}
nsTArray<DOMOverlaysError> errors;
@ -394,26 +410,15 @@ class LocalizationHandler : public PromiseNativeHandler {
}
}
if (docL10n) {
docL10n->ResumeObserving(rv);
if (NS_WARN_IF(rv.Failed())) {
mReturnValuePromise->MaybeRejectWithUndefined();
return;
}
mDocumentL10n->ResumeObserving(rv);
if (NS_WARN_IF(rv.Failed())) {
mReturnValuePromise->MaybeRejectWithUndefined();
return;
}
nsTArray<JS::Value> jsErrors;
SequenceRooter<JS::Value> rooter(aCx, &jsErrors);
for (auto& error : errors) {
JS::RootedValue jsError(aCx);
if (!ToJSValue(aCx, error, &jsError)) {
mReturnValuePromise->MaybeRejectWithUndefined();
return;
}
jsErrors.AppendElement(jsError);
}
DocumentL10n::ReportDOMOverlaysErrors(mDocumentL10n->GetDocument(), errors);
mReturnValuePromise->MaybeResolve(jsErrors);
mReturnValuePromise->MaybeResolveWithUndefined();
}
virtual void RejectedCallback(JSContext* aCx,
@ -425,7 +430,7 @@ class LocalizationHandler : public PromiseNativeHandler {
~LocalizationHandler() = default;
nsTArray<nsCOMPtr<Element>> mElements;
RefPtr<nsINode> mNode;
RefPtr<DocumentL10n> mDocumentL10n;
RefPtr<Promise> mReturnValuePromise;
};
@ -440,23 +445,28 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(LocalizationHandler)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(LocalizationHandler)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentL10n)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReturnValuePromise)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(LocalizationHandler)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElements)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentL10n)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReturnValuePromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
already_AddRefed<Promise> DocumentL10n::TranslateFragment(JSContext* aCx,
nsINode& aNode,
already_AddRefed<Promise> DocumentL10n::TranslateFragment(nsINode& aNode,
ErrorResult& aRv) {
Sequence<L10nKey> l10nKeys;
SequenceRooter<L10nKey> rooter(aCx, &l10nKeys);
RefPtr<LocalizationHandler> nativeHandler = new LocalizationHandler(&aNode);
nsTArray<nsCOMPtr<Element>>& domElements = nativeHandler->Elements();
Sequence<OwningNonNull<Element>> elements;
GetTranslatables(aNode, elements, aRv);
return TranslateElements(elements, aRv);
}
void DocumentL10n::GetTranslatables(nsINode& aNode,
Sequence<OwningNonNull<Element>>& aElements,
ErrorResult& aRv) {
nsIContent* node =
aNode.IsContent() ? aNode.AsContent() : aNode.GetFirstChild();
for (; node; node = node->GetNextNode(&aNode)) {
@ -470,13 +480,42 @@ already_AddRefed<Promise> DocumentL10n::TranslateFragment(JSContext* aCx,
continue;
}
if (!aElements.AppendElement(*domElement, fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
}
}
already_AddRefed<Promise> DocumentL10n::TranslateElements(
const Sequence<OwningNonNull<Element>>& aElements, ErrorResult& aRv) {
JS::RootingContext* rcx = RootingCx();
Sequence<L10nKey> l10nKeys;
SequenceRooter<L10nKey> rooter(rcx, &l10nKeys);
RefPtr<LocalizationHandler> nativeHandler = new LocalizationHandler(this);
nsTArray<nsCOMPtr<Element>>& domElements = nativeHandler->Elements();
domElements.SetCapacity(aElements.Length());
nsIGlobalObject* global = mDocument->GetScopeObject();
if (!global) {
return nullptr;
}
AutoEntryScript aes(global, "DocumentL10n GetAttributes");
JSContext* cx = aes.cx();
for (auto& domElement : aElements) {
if (!domElement->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nid)) {
continue;
}
L10nKey* key = l10nKeys.AppendElement(fallible);
if (!key) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
GetAttributes(aCx, *domElement, *key, aRv);
GetAttributes(cx, *domElement, *key, aRv);
if (aRv.Failed()) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
@ -488,17 +527,12 @@ already_AddRefed<Promise> DocumentL10n::TranslateFragment(JSContext* aCx,
}
}
nsIGlobalObject* global = mDocument->GetScopeObject();
if (!global) {
return nullptr;
}
RefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
RefPtr<Promise> callbackResult = FormatMessages(aCx, l10nKeys, aRv);
RefPtr<Promise> callbackResult = FormatMessages(cx, l10nKeys, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -509,27 +543,98 @@ already_AddRefed<Promise> DocumentL10n::TranslateFragment(JSContext* aCx,
return MaybeWrapPromise(promise);
}
already_AddRefed<Promise> DocumentL10n::TranslateElements(
const Sequence<OwningNonNull<Element>>& aElements, ErrorResult& aRv) {
AutoTArray<RefPtr<Element>, 10> elements;
elements.SetCapacity(aElements.Length());
for (auto& element : aElements) {
elements.AppendElement(element);
class L10nRootTranslationHandler final : public PromiseNativeHandler {
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(L10nRootTranslationHandler)
explicit L10nRootTranslationHandler(Element* aRoot) : mRoot(aRoot) {}
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
DocumentL10n::SetRootInfo(mRoot);
}
RefPtr<Promise> promise;
aRv = mDOMLocalization->TranslateElements(elements, getter_AddRefs(promise));
if (aRv.Failed()) {
return nullptr;
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
}
private:
~L10nRootTranslationHandler() = default;
RefPtr<Element> mRoot;
};
NS_IMPL_CYCLE_COLLECTION(L10nRootTranslationHandler, mRoot)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(L10nRootTranslationHandler)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(L10nRootTranslationHandler)
NS_IMPL_CYCLE_COLLECTING_RELEASE(L10nRootTranslationHandler)
void DocumentL10n::TranslateRoots() {
ErrorResult rv;
for (auto iter = mRoots.ConstIter(); !iter.Done(); iter.Next()) {
Element* root = iter.Get()->GetKey();
RefPtr<Promise> promise = TranslateFragment(*root, rv);
RefPtr<L10nRootTranslationHandler> nativeHandler =
new L10nRootTranslationHandler(root);
promise->AppendNativeHandler(nativeHandler);
}
return MaybeWrapPromise(promise);
}
void DocumentL10n::PauseObserving(ErrorResult& aRv) {
aRv = mDOMLocalization->PauseObserving();
mMutations->PauseObserving();
}
void DocumentL10n::ResumeObserving(ErrorResult& aRv) {
aRv = mDOMLocalization->ResumeObserving();
mMutations->ResumeObserving();
}
/* static */
void DocumentL10n::ReportDOMOverlaysErrors(
Document* aDocument, nsTArray<mozilla::dom::DOMOverlaysError>& aErrors) {
nsAutoString msg;
for (auto& error : aErrors) {
if (error.mCode.WasPassed()) {
msg = NS_LITERAL_STRING("[fluent-dom] ");
switch (error.mCode.Value()) {
case DOMOverlays_Binding::ERROR_FORBIDDEN_TYPE:
msg += NS_LITERAL_STRING("An element of forbidden type \"") +
error.mTranslatedElementName.Value() +
NS_LITERAL_STRING(
"\" was found in the translation. Only safe text-level "
"elements and elements with data-l10n-name are allowed.");
break;
case DOMOverlays_Binding::ERROR_NAMED_ELEMENT_MISSING:
msg += NS_LITERAL_STRING("An element named \"") +
error.mL10nName.Value() +
NS_LITERAL_STRING("\" wasn't found in the source.");
break;
case DOMOverlays_Binding::ERROR_NAMED_ELEMENT_TYPE_MISMATCH:
msg += NS_LITERAL_STRING("An element named \"") +
error.mL10nName.Value() +
NS_LITERAL_STRING(
"\" was found in the translation but its type ") +
error.mTranslatedElementName.Value() +
NS_LITERAL_STRING(
" didn't match the element found in the source ") +
error.mSourceElementName.Value() + NS_LITERAL_STRING(".");
break;
case DOMOverlays_Binding::ERROR_UNKNOWN:
default:
msg += NS_LITERAL_STRING(
"Unknown error happened while translation of an element.");
break;
}
nsContentUtils::ReportToConsoleNonLocalized(
msg, nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"),
aDocument);
}
}
}
class L10nReadyHandler final : public PromiseNativeHandler {
@ -542,12 +647,12 @@ class L10nReadyHandler final : public PromiseNativeHandler {
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
mDocumentL10n->InitialDocumentTranslationCompleted();
mPromise->MaybeResolveWithClone(aCx, aValue);
mPromise->MaybeResolveWithUndefined();
}
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
mDocumentL10n->InitialDocumentTranslationCompleted();
mPromise->MaybeRejectWithClone(aCx, aValue);
mPromise->MaybeRejectWithUndefined();
}
private:
@ -574,12 +679,18 @@ void DocumentL10n::TriggerInitialDocumentTranslation() {
mState = DocumentL10nState::InitialTranslationTriggered;
Element* elem = mDocument->GetDocumentElement();
if (elem) {
mDOMLocalization->ConnectRoot(elem);
if (!elem) {
return;
}
RefPtr<Promise> promise;
mDOMLocalization->TranslateRoots(getter_AddRefs(promise));
Sequence<OwningNonNull<Element>> elements;
ErrorResult rv;
GetTranslatables(*elem, elements, rv);
ConnectRoot(elem);
RefPtr<Promise> promise = TranslateElements(elements, rv);
if (!promise) {
return;
}
@ -594,6 +705,11 @@ void DocumentL10n::InitialDocumentTranslationCompleted() {
return;
}
Element* documentElement = mDocument->GetDocumentElement();
if (documentElement) {
SetRootInfo(documentElement);
}
mState = DocumentL10nState::InitialTranslationCompleted;
mDocument->InitialDocumentTranslationCompleted();
@ -607,5 +723,70 @@ void DocumentL10n::InitialDocumentTranslationCompleted() {
Promise* DocumentL10n::Ready() { return mReady; }
void DocumentL10n::OnChange() {
if (mLocalization) {
mLocalization->OnChange();
TranslateRoots();
}
}
void DocumentL10n::ConnectRoot(Element* aNode) {
nsCOMPtr<nsIGlobalObject> global = aNode->GetOwnerGlobal();
if (!global) {
return;
}
#ifdef DEBUG
for (auto iter = mRoots.ConstIter(); !iter.Done(); iter.Next()) {
Element* root = iter.Get()->GetKey();
MOZ_ASSERT(
root != aNode && !root->Contains(aNode) && !aNode->Contains(root),
"Cannot add a root that overlaps with existing root.");
}
#endif
mRoots.PutEntry(aNode);
aNode->AddMutationObserverUnlessExists(mMutations);
}
void DocumentL10n::DisconnectRoot(Element* aNode) {
if (mRoots.Contains(aNode)) {
aNode->RemoveMutationObserver(mMutations);
mRoots.RemoveEntry(aNode);
}
}
void DocumentL10n::DisconnectRoots() {
for (auto iter = mRoots.ConstIter(); !iter.Done(); iter.Next()) {
Element* elem = iter.Get()->GetKey();
elem->RemoveMutationObserver(mMutations);
}
mRoots.Clear();
}
/* static */
void DocumentL10n::SetRootInfo(Element* aElement) {
nsAutoCString primaryLocale;
LocaleService::GetInstance()->GetAppLocaleAsBCP47(primaryLocale);
aElement->SetAttr(kNameSpaceID_None, nsGkAtoms::lang,
NS_ConvertUTF8toUTF16(primaryLocale), true);
nsAutoString dir;
if (LocaleService::GetInstance()->IsAppLocaleRTL()) {
nsGkAtoms::rtl->ToString(dir);
} else {
nsGkAtoms::ltr->ToString(dir);
}
uint32_t nameSpace = aElement->GetNameSpaceID();
nsAtom* dirAtom =
nameSpace == kNameSpaceID_XUL ? nsGkAtoms::localedir : nsGkAtoms::dir;
aElement->SetAttr(kNameSpaceID_None, dirAtom, dir, true);
}
} // namespace dom
} // namespace mozilla

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше