зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
c7c661056f
|
@ -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": {
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче