mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Vendor the current version of WebRender
This is a step toward upgrading WebRender, which will be upgraded and patched in the `third_party` directory. This change vendors the current private branch of WebRender that we use and adds a `patches` directory which tracks the changes on top of the upstream WebRender commit described by third_party/webrender/patches/head.
This commit is contained in:
parent
c19eb800de
commit
49277f5c3f
1215 changed files with 185677 additions and 34 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -4396,7 +4396,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peek-poke"
|
name = "peek-poke"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/jdm/webrender?branch=crash-backtrace#415b9ba32648667313f6f4ce7965752285bf0b26"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid",
|
"euclid",
|
||||||
"peek-poke-derive",
|
"peek-poke-derive",
|
||||||
|
@ -4405,7 +4404,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peek-poke-derive"
|
name = "peek-poke-derive"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "git+https://github.com/jdm/webrender?branch=crash-backtrace#415b9ba32648667313f6f4ce7965752285bf0b26"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -6990,7 +6988,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender"
|
name = "webrender"
|
||||||
version = "0.61.0"
|
version = "0.61.0"
|
||||||
source = "git+https://github.com/jdm/webrender?branch=crash-backtrace#415b9ba32648667313f6f4ce7965752285bf0b26"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"base64 0.10.1",
|
"base64 0.10.1",
|
||||||
|
@ -7034,7 +7031,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender_api"
|
name = "webrender_api"
|
||||||
version = "0.61.0"
|
version = "0.61.0"
|
||||||
source = "git+https://github.com/jdm/webrender?branch=crash-backtrace#415b9ba32648667313f6f4ce7965752285bf0b26"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -7055,7 +7051,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webrender_build"
|
name = "webrender_build"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/jdm/webrender?branch=crash-backtrace#415b9ba32648667313f6f4ce7965752285bf0b26"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -7320,7 +7315,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wr_malloc_size_of"
|
name = "wr_malloc_size_of"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/jdm/webrender?branch=crash-backtrace#415b9ba32648667313f6f4ce7965752285bf0b26"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"euclid",
|
"euclid",
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -78,6 +78,8 @@ unicode-script = "0.5"
|
||||||
url = "2.0"
|
url = "2.0"
|
||||||
uuid = { version = "1.3.4", features = ["v4"] }
|
uuid = { version = "1.3.4", features = ["v4"] }
|
||||||
webdriver = "0.48.0"
|
webdriver = "0.48.0"
|
||||||
|
webrender = { git = "https://github.com/servo/webrender", features = ["capture"] }
|
||||||
|
webrender_api = { git = "https://github.com/servo/webrender" }
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
xi-unicode = "0.1.0"
|
xi-unicode = "0.1.0"
|
||||||
xml5ever = "0.17"
|
xml5ever = "0.17"
|
||||||
|
@ -104,7 +106,9 @@ mio = { git = "https://github.com/servo/mio.git", branch = "servo-mio-0.6.22" }
|
||||||
# fork that bumps crates since the original repo is archived.
|
# fork that bumps crates since the original repo is archived.
|
||||||
immeta = { git = "https://github.com/fabricedesre/immeta.git" }
|
immeta = { git = "https://github.com/fabricedesre/immeta.git" }
|
||||||
|
|
||||||
# https://github.com/servo/servo/issues/27515#issuecomment-671474054
|
|
||||||
|
# This is required because we want all dependencies that use WebRender to
|
||||||
|
# use our vendored version.
|
||||||
[patch."https://github.com/servo/webrender"]
|
[patch."https://github.com/servo/webrender"]
|
||||||
webrender = { git = "https://github.com/jdm/webrender", branch = "crash-backtrace" }
|
webrender = { path = "third_party/webrender/webrender" }
|
||||||
webrender_api = { git = "https://github.com/jdm/webrender", branch = "crash-backtrace" }
|
webrender_api = { path = "third_party/webrender/webrender_api" }
|
||||||
|
|
|
@ -44,8 +44,8 @@ surfman = { workspace = true, features = ["sm-angle","sm-angle-default"] }
|
||||||
surfman-chains = { workspace = true }
|
surfman-chains = { workspace = true }
|
||||||
surfman-chains-api = { workspace = true }
|
surfman-chains-api = { workspace = true }
|
||||||
time = { workspace = true, optional = true }
|
time = { workspace = true, optional = true }
|
||||||
webrender = { git = "https://github.com/servo/webrender" }
|
webrender = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webrender_surfman = { path = "../webrender_surfman" }
|
webrender_surfman = { path = "../webrender_surfman" }
|
||||||
webrender_traits = { path = "../webrender_traits" }
|
webrender_traits = { path = "../webrender_traits" }
|
||||||
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
||||||
|
|
|
@ -29,5 +29,5 @@ servo_config = { path = "../config" }
|
||||||
sparkle = { workspace = true }
|
sparkle = { workspace = true }
|
||||||
style = { path = "../style" }
|
style = { path = "../style" }
|
||||||
time = { workspace = true, optional = true }
|
time = { workspace = true, optional = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
||||||
|
|
|
@ -39,8 +39,8 @@ servo_geometry = { path = "../geometry" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
style_traits = { path = "../style_traits" }
|
style_traits = { path = "../style_traits" }
|
||||||
time = { workspace = true }
|
time = { workspace = true }
|
||||||
webrender = { git = "https://github.com/servo/webrender", features = ["capture"] }
|
webrender = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webrender_surfman = { path = "../webrender_surfman" }
|
webrender_surfman = { path = "../webrender_surfman" }
|
||||||
webxr = { git = "https://github.com/servo/webxr" }
|
webxr = { git = "https://github.com/servo/webxr" }
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ servo_remutex = { path = "../remutex" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
style_traits = { path = "../style_traits" }
|
style_traits = { path = "../style_traits" }
|
||||||
webgpu = { path = "../webgpu" }
|
webgpu = { path = "../webgpu" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webrender_traits = { path = "../webrender_traits" }
|
webrender_traits = { path = "../webrender_traits" }
|
||||||
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
||||||
|
|
||||||
|
|
|
@ -21,5 +21,5 @@ num-derive = "0.3"
|
||||||
num-traits = { workspace = true }
|
num-traits = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
||||||
|
|
|
@ -38,7 +38,7 @@ time = { workspace = true }
|
||||||
ucd = "0.1.1"
|
ucd = "0.1.1"
|
||||||
unicode-bidi = { workspace = true, features = ["with_serde"] }
|
unicode-bidi = { workspace = true, features = ["with_serde"] }
|
||||||
unicode-script = { workspace = true }
|
unicode-script = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
xi-unicode = { workspace = true }
|
xi-unicode = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
|
|
@ -15,4 +15,4 @@ malloc_size_of = { path = "../malloc_size_of" }
|
||||||
malloc_size_of_derive = { workspace = true }
|
malloc_size_of_derive = { workspace = true }
|
||||||
range = { path = "../range" }
|
range = { path = "../range" }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
|
@ -49,7 +49,7 @@ style = { path = "../style", features = ["servo", "servo-layout-2013"] }
|
||||||
style_traits = { path = "../style_traits" }
|
style_traits = { path = "../style_traits" }
|
||||||
unicode-bidi = { workspace = true, features = ["with_serde"] }
|
unicode-bidi = { workspace = true, features = ["with_serde"] }
|
||||||
unicode-script = { workspace = true }
|
unicode-script = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
xi-unicode = { workspace = true }
|
xi-unicode = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -44,7 +44,7 @@ servo_url = { path = "../url" }
|
||||||
style = { path = "../style", features = ["servo", "servo-layout-2020"] }
|
style = { path = "../style", features = ["servo", "servo-layout-2020"] }
|
||||||
style_traits = { path = "../style_traits" }
|
style_traits = { path = "../style_traits" }
|
||||||
unicode-script = { workspace = true }
|
unicode-script = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
lazy_static = { workspace = true }
|
lazy_static = { workspace = true }
|
||||||
|
|
|
@ -49,4 +49,4 @@ servo_url = { path = "../url" }
|
||||||
style = { path = "../style" }
|
style = { path = "../style" }
|
||||||
style_traits = { path = "../style_traits" }
|
style_traits = { path = "../style_traits" }
|
||||||
time = { workspace = true }
|
time = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
|
@ -45,4 +45,4 @@ servo_config = { path = "../config" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
style = { path = "../style" }
|
style = { path = "../style" }
|
||||||
style_traits = { path = "../style_traits" }
|
style_traits = { path = "../style_traits" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
|
@ -20,4 +20,4 @@ net_traits = { path = "../net_traits" }
|
||||||
profile_traits = { path = "../profile_traits" }
|
profile_traits = { path = "../profile_traits" }
|
||||||
script_traits = { path = "../script_traits" }
|
script_traits = { path = "../script_traits" }
|
||||||
servo_url = { path = "../url" }
|
servo_url = { path = "../url" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
|
@ -49,5 +49,5 @@ tokio = { workspace = true }
|
||||||
url = { workspace = true, optional = true }
|
url = { workspace = true, optional = true }
|
||||||
uuid = { workspace = true, optional = true }
|
uuid = { workspace = true, optional = true }
|
||||||
void = "1.0.2"
|
void = "1.0.2"
|
||||||
webrender_api = { git = "https://github.com/servo/webrender", optional = true }
|
webrender_api = { workspace = true, optional = true }
|
||||||
xml5ever = { workspace = true, optional = true }
|
xml5ever = { workspace = true, optional = true }
|
||||||
|
|
|
@ -19,5 +19,5 @@ log = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
servo-media = { git = "https://github.com/servo/media" }
|
servo-media = { git = "https://github.com/servo/media" }
|
||||||
servo_config = { path = "../config" }
|
servo_config = { path = "../config" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webrender_traits = { path = "../webrender_traits" }
|
webrender_traits = { path = "../webrender_traits" }
|
||||||
|
|
|
@ -19,7 +19,7 @@ malloc_size_of = { path = "../malloc_size_of" }
|
||||||
malloc_size_of_derive = { workspace = true }
|
malloc_size_of_derive = { workspace = true }
|
||||||
parking_lot = { workspace = true }
|
parking_lot = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
size_of_test = { path = "../size_of_test" }
|
size_of_test = { path = "../size_of_test" }
|
||||||
|
|
|
@ -65,7 +65,7 @@ tokio-stream = "0.1"
|
||||||
tungstenite = "0.19"
|
tungstenite = "0.19"
|
||||||
url = { workspace = true }
|
url = { workspace = true }
|
||||||
uuid = { workspace = true }
|
uuid = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
futures = {version = "0.3", features = ["compat"]}
|
futures = {version = "0.3", features = ["compat"]}
|
||||||
|
|
|
@ -117,7 +117,7 @@ utf-8 = "0.7"
|
||||||
uuid = { workspace = true, features = ["serde"] }
|
uuid = { workspace = true, features = ["serde"] }
|
||||||
webdriver = { workspace = true }
|
webdriver = { workspace = true }
|
||||||
webgpu = { path = "../webgpu" }
|
webgpu = { path = "../webgpu" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
||||||
xml5ever = { workspace = true }
|
xml5ever = { workspace = true }
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ time = { workspace = true }
|
||||||
uuid = { workspace = true }
|
uuid = { workspace = true }
|
||||||
webdriver = { workspace = true }
|
webdriver = { workspace = true }
|
||||||
webgpu = { path = "../webgpu" }
|
webgpu = { path = "../webgpu" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -81,8 +81,8 @@ style_traits = { path = "../style_traits", features = ["servo"] }
|
||||||
surfman = { workspace = true }
|
surfman = { workspace = true }
|
||||||
webdriver_server = { path = "../webdriver_server", optional = true }
|
webdriver_server = { path = "../webdriver_server", optional = true }
|
||||||
webgpu = { path = "../webgpu" }
|
webgpu = { path = "../webgpu" }
|
||||||
webrender = { git = "https://github.com/servo/webrender" }
|
webrender = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webrender_surfman = { path = "../webrender_surfman" }
|
webrender_surfman = { path = "../webrender_surfman" }
|
||||||
webrender_traits = { path = "../webrender_traits" }
|
webrender_traits = { path = "../webrender_traits" }
|
||||||
webxr = { git = "https://github.com/servo/webxr" }
|
webxr = { git = "https://github.com/servo/webxr" }
|
||||||
|
|
|
@ -29,4 +29,4 @@ servo_atoms = { path = "../atoms", optional = true }
|
||||||
servo_url = { path = "../url", optional = true }
|
servo_url = { path = "../url", optional = true }
|
||||||
to_shmem = { path = "../to_shmem" }
|
to_shmem = { path = "../to_shmem" }
|
||||||
to_shmem_derive = { path = "../to_shmem_derive" }
|
to_shmem_derive = { path = "../to_shmem_derive" }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender", optional = true }
|
webrender_api = { workspace = true, optional = true }
|
||||||
|
|
|
@ -20,7 +20,7 @@ msg = { path = "../msg" }
|
||||||
serde = { workspace = true, features = ["serde_derive"] }
|
serde = { workspace = true, features = ["serde_derive"] }
|
||||||
servo_config = { path = "../config" }
|
servo_config = { path = "../config" }
|
||||||
smallvec = { workspace = true, features = ["serde"] }
|
smallvec = { workspace = true, features = ["serde"] }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
webrender_traits = { path = "../webrender_traits" }
|
webrender_traits = { path = "../webrender_traits" }
|
||||||
wgpu-core = { version = "0.6.0", git = "https://github.com/gfx-rs/wgpu", features = ["replay", "trace", "serial-pass"], rev = "e72724a6e393503c73f37e86aa9317a5c62e32b8" }
|
wgpu-core = { version = "0.6.0", git = "https://github.com/gfx-rs/wgpu", features = ["replay", "trace", "serial-pass"], rev = "e72724a6e393503c73f37e86aa9317a5c62e32b8" }
|
||||||
wgpu-types = { version = "0.6.0", git = "https://github.com/gfx-rs/wgpu", features = ["replay", "trace"], rev = "e72724a6e393503c73f37e86aa9317a5c62e32b8" }
|
wgpu-types = { version = "0.6.0", git = "https://github.com/gfx-rs/wgpu", features = ["replay", "trace"], rev = "e72724a6e393503c73f37e86aa9317a5c62e32b8" }
|
||||||
|
|
|
@ -12,5 +12,5 @@ path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
euclid = { workspace = true }
|
euclid = { workspace = true }
|
||||||
webrender_api = { git = "https://github.com/servo/webrender" }
|
webrender_api = { workspace = true }
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
match_block_trailing_comma = true
|
match_block_trailing_comma = true
|
||||||
binop_separator = "Back"
|
binop_separator = "Back"
|
||||||
reorder_imports = true
|
reorder_imports = true
|
||||||
|
ignore = [ "third_party" ]
|
||||||
|
|
27
third_party/webrender/.gitignore
vendored
Normal file
27
third_party/webrender/.gitignore
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
target/
|
||||||
|
*~
|
||||||
|
*#
|
||||||
|
|
||||||
|
# WR internals
|
||||||
|
captures
|
||||||
|
wrench/json_frames
|
||||||
|
wrench/ron_frames
|
||||||
|
|
||||||
|
# Editors
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.gradle
|
||||||
|
|
||||||
|
# VSCode
|
||||||
|
.vscode
|
||||||
|
.vs
|
||||||
|
|
||||||
|
# System
|
||||||
|
.fuse_hidden*
|
176
third_party/webrender/.taskcluster.yml
vendored
Normal file
176
third_party/webrender/.taskcluster.yml
vendored
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
# This file specifies the configuration needed to test WebRender using the
|
||||||
|
# Taskcluster infrastructure. Most of this should be relatively
|
||||||
|
# self-explanatory; this file was originally generated by using the
|
||||||
|
# Taskcluster-GitHub integration quickstart tool which no longer exists.
|
||||||
|
#
|
||||||
|
# See https://community-tc.services.mozilla.com/docs
|
||||||
|
version: 1
|
||||||
|
policy:
|
||||||
|
pullRequests: public
|
||||||
|
|
||||||
|
# This file triggers a set of tasks; the ones targeting Linux are run in a docker
|
||||||
|
# container using docker-worker (which is a worker type provided by TaskCluster).
|
||||||
|
# The OS X ones are run in a custom worker type, for which we have worker
|
||||||
|
# instances configured and running.
|
||||||
|
tasks:
|
||||||
|
$if: 'tasks_for in ["github-push", "github-pull-request"]'
|
||||||
|
then:
|
||||||
|
$let:
|
||||||
|
should_run:
|
||||||
|
$if: 'tasks_for == "github-push"'
|
||||||
|
# for pushes, run on any branch but master
|
||||||
|
then: {$eval: 'event.ref != "refs/heads/master"'}
|
||||||
|
# for PRs, run for opened and synchronized events
|
||||||
|
else: {$eval: 'event.action in ["opened", "synchronize"]'}
|
||||||
|
repo_url:
|
||||||
|
$if: 'tasks_for == "github-push"'
|
||||||
|
then: ${event.repository.clone_url}
|
||||||
|
else: ${event.pull_request.head.repo.clone_url}
|
||||||
|
sha:
|
||||||
|
$if: 'tasks_for == "github-push"'
|
||||||
|
then: ${event.after}
|
||||||
|
else: ${event.pull_request.head.sha}
|
||||||
|
login: ${event.sender.login}
|
||||||
|
branch:
|
||||||
|
$if: 'tasks_for == "github-push"'
|
||||||
|
then:
|
||||||
|
$if: 'event.ref[:11] == "refs/heads/"'
|
||||||
|
then: ${event.ref[11:]}
|
||||||
|
else: ${event.ref}
|
||||||
|
else: ${event.pull_request.head.ref}
|
||||||
|
in:
|
||||||
|
$if: should_run
|
||||||
|
then:
|
||||||
|
# For the docker-worker tasks, the Docker image used
|
||||||
|
# (staktrace/webrender-test:debian-v6) was created using the Dockerfile in
|
||||||
|
# ci-scripts/docker-image.
|
||||||
|
#
|
||||||
|
# The docker image may need to be updated over time if the set of required
|
||||||
|
# packages increases. Note in particular that rust/cargo are not part of the
|
||||||
|
# docker image, and are re-installed using rustup on each CI run. This ensures
|
||||||
|
# the latest stable rust compiler is always used.
|
||||||
|
# CI runs will be triggered on opening PRs, updating PRs, and pushes to the
|
||||||
|
# repository.
|
||||||
|
- metadata:
|
||||||
|
name: Linux release tests
|
||||||
|
description: Runs release-mode WebRender CI stuff on a Linux TC worker
|
||||||
|
owner: noreply@mozilla.com
|
||||||
|
source: ${repo_url}
|
||||||
|
provisionerId: proj-webrender
|
||||||
|
workerType: ci-linux
|
||||||
|
deadline: {$fromNow: '1 day'}
|
||||||
|
payload:
|
||||||
|
maxRunTime: 7200
|
||||||
|
image: 'staktrace/webrender-test:debian-v6'
|
||||||
|
env:
|
||||||
|
RUST_BACKTRACE: 'full'
|
||||||
|
RUSTFLAGS: '--deny warnings'
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- '--login'
|
||||||
|
- '-c'
|
||||||
|
- >-
|
||||||
|
curl https://sh.rustup.rs -sSf | sh -s -- -y &&
|
||||||
|
source $HOME/.cargo/env &&
|
||||||
|
git clone ${repo_url} webrender && cd webrender &&
|
||||||
|
git checkout ${sha} &&
|
||||||
|
servo-tidy &&
|
||||||
|
ci-scripts/linux-release-tests.sh
|
||||||
|
routes:
|
||||||
|
- "index.project.webrender.ci.${login}.${branch}.linux-release"
|
||||||
|
- metadata:
|
||||||
|
name: Linux debug tests
|
||||||
|
description: Runs debug-mode WebRender CI stuff on a Linux TC worker
|
||||||
|
owner: noreply@mozilla.com
|
||||||
|
source: ${repo_url}
|
||||||
|
provisionerId: proj-webrender
|
||||||
|
workerType: ci-linux
|
||||||
|
deadline: {$fromNow: '1 day'}
|
||||||
|
payload:
|
||||||
|
maxRunTime: 7200
|
||||||
|
image: 'staktrace/webrender-test:debian-v6'
|
||||||
|
env:
|
||||||
|
RUST_BACKTRACE: 'full'
|
||||||
|
RUSTFLAGS: '--deny warnings'
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- '--login'
|
||||||
|
- '-c'
|
||||||
|
- >-
|
||||||
|
curl https://sh.rustup.rs -sSf | sh -s -- -y &&
|
||||||
|
source $HOME/.cargo/env &&
|
||||||
|
git clone ${repo_url} webrender && cd webrender &&
|
||||||
|
git checkout ${sha} &&
|
||||||
|
servo-tidy &&
|
||||||
|
ci-scripts/linux-debug-tests.sh
|
||||||
|
routes:
|
||||||
|
- "index.project.webrender.ci.${login}.${branch}.linux-debug"
|
||||||
|
# For the OS X jobs we use a pool of machines that we are managing, because
|
||||||
|
# Mozilla releng doesn't have any spare OS X machines for us at this time.
|
||||||
|
# Talk to :kats or :jrmuizel if you need more details about this. The machines
|
||||||
|
# are hooked up to taskcluster using taskcluster-worker; they use a workerpool
|
||||||
|
# of proj-webrender/ci-macos. They are set up with all the dependencies needed
|
||||||
|
# to build and test webrender, including Rust (currently 1.41.1), servo-tidy,
|
||||||
|
# mako, zlib, etc. Note that unlike the docker-worker used for Linux, these
|
||||||
|
# machines WILL persist state from one run to the next, so any cleanup needs
|
||||||
|
# to be handled explicitly.
|
||||||
|
|
||||||
|
# macOS tasks currently disabled, see bug 1639217.
|
||||||
|
# - metadata:
|
||||||
|
# name: OS X release tests
|
||||||
|
# description: Runs release-mode WebRender CI stuff on a OS X TC worker
|
||||||
|
# owner: noreply@mozilla.com
|
||||||
|
# source: ${repo_url}
|
||||||
|
# provisionerId: 'proj-webrender'
|
||||||
|
# workerType: 'ci-macos'
|
||||||
|
# deadline: {$fromNow: '1 day'}
|
||||||
|
# payload:
|
||||||
|
# maxRunTime: 3600
|
||||||
|
# command:
|
||||||
|
# - - /bin/bash
|
||||||
|
# - '--login'
|
||||||
|
# - '-vec'
|
||||||
|
# - |
|
||||||
|
# git clone ${repo_url} webrender
|
||||||
|
# cd webrender
|
||||||
|
# git checkout ${sha}
|
||||||
|
# source $HOME/servotidy-venv/bin/activate
|
||||||
|
# servo-tidy
|
||||||
|
# export RUST_BACKTRACE=full
|
||||||
|
# export RUSTFLAGS='--deny warnings'
|
||||||
|
# export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
|
# echo 'exec make -j1 "$@"' > $HOME/make # See #2638
|
||||||
|
# chmod +x $HOME/make
|
||||||
|
# export MAKE="$HOME/make"
|
||||||
|
# ci-scripts/macos-release-tests.sh
|
||||||
|
# routes:
|
||||||
|
# - "index.project.webrender.ci.${login}.${branch}.osx-release"
|
||||||
|
# - metadata:
|
||||||
|
# name: OS X debug tests
|
||||||
|
# description: Runs debug-mode WebRender CI stuff on a OS X TC worker
|
||||||
|
# owner: noreply@mozilla.com
|
||||||
|
# source: ${repo_url}
|
||||||
|
# provisionerId: 'proj-webrender'
|
||||||
|
# workerType: 'ci-macos'
|
||||||
|
# deadline: {$fromNow: '1 day'}
|
||||||
|
# payload:
|
||||||
|
# maxRunTime: 3600
|
||||||
|
# command:
|
||||||
|
# - - /bin/bash
|
||||||
|
# - '--login'
|
||||||
|
# - '-vec'
|
||||||
|
# - |
|
||||||
|
# git clone ${repo_url} webrender
|
||||||
|
# cd webrender
|
||||||
|
# git checkout ${sha}
|
||||||
|
# source $HOME/servotidy-venv/bin/activate
|
||||||
|
# servo-tidy
|
||||||
|
# export RUST_BACKTRACE=full
|
||||||
|
# export RUSTFLAGS='--deny warnings'
|
||||||
|
# export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
|
# echo 'exec make -j1 "$@"' > $HOME/make # See #2638
|
||||||
|
# chmod +x $HOME/make
|
||||||
|
# export MAKE="$HOME/make"
|
||||||
|
# ci-scripts/macos-debug-tests.sh
|
||||||
|
# routes:
|
||||||
|
# - "index.project.webrender.ci.${login}.${branch}.osx-debug"
|
2267
third_party/webrender/Cargo.lock
generated
vendored
Normal file
2267
third_party/webrender/Cargo.lock
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
25
third_party/webrender/Cargo.toml
vendored
Normal file
25
third_party/webrender/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"direct-composition",
|
||||||
|
"examples",
|
||||||
|
"webrender",
|
||||||
|
"webrender_api",
|
||||||
|
"wrench",
|
||||||
|
"example-compositor/compositor",
|
||||||
|
"tileview",
|
||||||
|
]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
# Running wrench on android built with master cargo-apk results in a crash
|
||||||
|
# due to a mismatched version of android_glue (a dependency of winit).
|
||||||
|
# Override it to use a suitable version of android_glue.
|
||||||
|
# See https://github.com/rust-windowing/android-rs-glue/issues/239.
|
||||||
|
# This can be removed once a new version of android_glue is published to crates.io.
|
||||||
|
[patch.crates-io]
|
||||||
|
android_glue = { git = "https://github.com/rust-windowing/android-rs-glue.git", rev = "e3ac6edea5814e1faca0c31ea8fac6877cb929ea" }
|
374
third_party/webrender/LICENSE
vendored
Normal file
374
third_party/webrender/LICENSE
vendored
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
Mozilla Public License Version 2.0
|
||||||
|
==================================
|
||||||
|
|
||||||
|
1. Definitions
|
||||||
|
--------------
|
||||||
|
|
||||||
|
1.1. "Contributor"
|
||||||
|
means each individual or legal entity that creates, contributes to
|
||||||
|
the creation of, or owns Covered Software.
|
||||||
|
|
||||||
|
1.2. "Contributor Version"
|
||||||
|
means the combination of the Contributions of others (if any) used
|
||||||
|
by a Contributor and that particular Contributor's Contribution.
|
||||||
|
|
||||||
|
1.3. "Contribution"
|
||||||
|
means Covered Software of a particular Contributor.
|
||||||
|
|
||||||
|
1.4. "Covered Software"
|
||||||
|
means Source Code Form to which the initial Contributor has attached
|
||||||
|
the notice in Exhibit A, the Executable Form of such Source Code
|
||||||
|
Form, and Modifications of such Source Code Form, in each case
|
||||||
|
including portions thereof.
|
||||||
|
|
||||||
|
1.5. "Incompatible With Secondary Licenses"
|
||||||
|
means
|
||||||
|
|
||||||
|
(a) that the initial Contributor has attached the notice described
|
||||||
|
in Exhibit B to the Covered Software; or
|
||||||
|
|
||||||
|
(b) that the Covered Software was made available under the terms of
|
||||||
|
version 1.1 or earlier of the License, but not also under the
|
||||||
|
terms of a Secondary License.
|
||||||
|
|
||||||
|
1.6. "Executable Form"
|
||||||
|
means any form of the work other than Source Code Form.
|
||||||
|
|
||||||
|
1.7. "Larger Work"
|
||||||
|
means a work that combines Covered Software with other material, in
|
||||||
|
a separate file or files, that is not Covered Software.
|
||||||
|
|
||||||
|
1.8. "License"
|
||||||
|
means this document.
|
||||||
|
|
||||||
|
1.9. "Licensable"
|
||||||
|
means having the right to grant, to the maximum extent possible,
|
||||||
|
whether at the time of the initial grant or subsequently, any and
|
||||||
|
all of the rights conveyed by this License.
|
||||||
|
|
||||||
|
1.10. "Modifications"
|
||||||
|
means any of the following:
|
||||||
|
|
||||||
|
(a) any file in Source Code Form that results from an addition to,
|
||||||
|
deletion from, or modification of the contents of Covered
|
||||||
|
Software; or
|
||||||
|
|
||||||
|
(b) any new file in Source Code Form that contains any Covered
|
||||||
|
Software.
|
||||||
|
|
||||||
|
1.11. "Patent Claims" of a Contributor
|
||||||
|
means any patent claim(s), including without limitation, method,
|
||||||
|
process, and apparatus claims, in any patent Licensable by such
|
||||||
|
Contributor that would be infringed, but for the grant of the
|
||||||
|
License, by the making, using, selling, offering for sale, having
|
||||||
|
made, import, or transfer of either its Contributions or its
|
||||||
|
Contributor Version.
|
||||||
|
|
||||||
|
1.12. "Secondary License"
|
||||||
|
means either the GNU General Public License, Version 2.0, the GNU
|
||||||
|
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||||
|
Public License, Version 3.0, or any later versions of those
|
||||||
|
licenses.
|
||||||
|
|
||||||
|
1.13. "Source Code Form"
|
||||||
|
means the form of the work preferred for making modifications.
|
||||||
|
|
||||||
|
1.14. "You" (or "Your")
|
||||||
|
means an individual or a legal entity exercising rights under this
|
||||||
|
License. For legal entities, "You" includes any entity that
|
||||||
|
controls, is controlled by, or is under common control with You. For
|
||||||
|
purposes of this definition, "control" means (a) the power, direct
|
||||||
|
or indirect, to cause the direction or management of such entity,
|
||||||
|
whether by contract or otherwise, or (b) ownership of more than
|
||||||
|
fifty percent (50%) of the outstanding shares or beneficial
|
||||||
|
ownership of such entity.
|
||||||
|
|
||||||
|
2. License Grants and Conditions
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
2.1. Grants
|
||||||
|
|
||||||
|
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||||
|
non-exclusive license:
|
||||||
|
|
||||||
|
(a) under intellectual property rights (other than patent or trademark)
|
||||||
|
Licensable by such Contributor to use, reproduce, make available,
|
||||||
|
modify, display, perform, distribute, and otherwise exploit its
|
||||||
|
Contributions, either on an unmodified basis, with Modifications, or
|
||||||
|
as part of a Larger Work; and
|
||||||
|
|
||||||
|
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||||
|
for sale, have made, import, and otherwise transfer either its
|
||||||
|
Contributions or its Contributor Version.
|
||||||
|
|
||||||
|
2.2. Effective Date
|
||||||
|
|
||||||
|
The licenses granted in Section 2.1 with respect to any Contribution
|
||||||
|
become effective for each Contribution on the date the Contributor first
|
||||||
|
distributes such Contribution.
|
||||||
|
|
||||||
|
2.3. Limitations on Grant Scope
|
||||||
|
|
||||||
|
The licenses granted in this Section 2 are the only rights granted under
|
||||||
|
this License. No additional rights or licenses will be implied from the
|
||||||
|
distribution or licensing of Covered Software under this License.
|
||||||
|
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||||
|
Contributor:
|
||||||
|
|
||||||
|
(a) for any code that a Contributor has removed from Covered Software;
|
||||||
|
or
|
||||||
|
|
||||||
|
(b) for infringements caused by: (i) Your and any other third party's
|
||||||
|
modifications of Covered Software, or (ii) the combination of its
|
||||||
|
Contributions with other software (except as part of its Contributor
|
||||||
|
Version); or
|
||||||
|
|
||||||
|
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||||
|
its Contributions.
|
||||||
|
|
||||||
|
This License does not grant any rights in the trademarks, service marks,
|
||||||
|
or logos of any Contributor (except as may be necessary to comply with
|
||||||
|
the notice requirements in Section 3.4).
|
||||||
|
|
||||||
|
2.4. Subsequent Licenses
|
||||||
|
|
||||||
|
No Contributor makes additional grants as a result of Your choice to
|
||||||
|
distribute the Covered Software under a subsequent version of this
|
||||||
|
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||||
|
permitted under the terms of Section 3.3).
|
||||||
|
|
||||||
|
2.5. Representation
|
||||||
|
|
||||||
|
Each Contributor represents that the Contributor believes its
|
||||||
|
Contributions are its original creation(s) or it has sufficient rights
|
||||||
|
to grant the rights to its Contributions conveyed by this License.
|
||||||
|
|
||||||
|
2.6. Fair Use
|
||||||
|
|
||||||
|
This License is not intended to limit any rights You have under
|
||||||
|
applicable copyright doctrines of fair use, fair dealing, or other
|
||||||
|
equivalents.
|
||||||
|
|
||||||
|
2.7. Conditions
|
||||||
|
|
||||||
|
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||||
|
in Section 2.1.
|
||||||
|
|
||||||
|
3. Responsibilities
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
3.1. Distribution of Source Form
|
||||||
|
|
||||||
|
All distribution of Covered Software in Source Code Form, including any
|
||||||
|
Modifications that You create or to which You contribute, must be under
|
||||||
|
the terms of this License. You must inform recipients that the Source
|
||||||
|
Code Form of the Covered Software is governed by the terms of this
|
||||||
|
License, and how they can obtain a copy of this License. You may not
|
||||||
|
attempt to alter or restrict the recipients' rights in the Source Code
|
||||||
|
Form.
|
||||||
|
|
||||||
|
3.2. Distribution of Executable Form
|
||||||
|
|
||||||
|
If You distribute Covered Software in Executable Form then:
|
||||||
|
|
||||||
|
(a) such Covered Software must also be made available in Source Code
|
||||||
|
Form, as described in Section 3.1, and You must inform recipients of
|
||||||
|
the Executable Form how they can obtain a copy of such Source Code
|
||||||
|
Form by reasonable means in a timely manner, at a charge no more
|
||||||
|
than the cost of distribution to the recipient; and
|
||||||
|
|
||||||
|
(b) You may distribute such Executable Form under the terms of this
|
||||||
|
License, or sublicense it under different terms, provided that the
|
||||||
|
license for the Executable Form does not attempt to limit or alter
|
||||||
|
the recipients' rights in the Source Code Form under this License.
|
||||||
|
|
||||||
|
3.3. Distribution of a Larger Work
|
||||||
|
|
||||||
|
You may create and distribute a Larger Work under terms of Your choice,
|
||||||
|
provided that You also comply with the requirements of this License for
|
||||||
|
the Covered Software. If the Larger Work is a combination of Covered
|
||||||
|
Software with a work governed by one or more Secondary Licenses, and the
|
||||||
|
Covered Software is not Incompatible With Secondary Licenses, this
|
||||||
|
License permits You to additionally distribute such Covered Software
|
||||||
|
under the terms of such Secondary License(s), so that the recipient of
|
||||||
|
the Larger Work may, at their option, further distribute the Covered
|
||||||
|
Software under the terms of either this License or such Secondary
|
||||||
|
License(s).
|
||||||
|
|
||||||
|
3.4. Notices
|
||||||
|
|
||||||
|
You may not remove or alter the substance of any license notices
|
||||||
|
(including copyright notices, patent notices, disclaimers of warranty,
|
||||||
|
or limitations of liability) contained within the Source Code Form of
|
||||||
|
the Covered Software, except that You may alter any license notices to
|
||||||
|
the extent required to remedy known factual inaccuracies.
|
||||||
|
|
||||||
|
3.5. Application of Additional Terms
|
||||||
|
|
||||||
|
You may choose to offer, and to charge a fee for, warranty, support,
|
||||||
|
indemnity or liability obligations to one or more recipients of Covered
|
||||||
|
Software. However, You may do so only on Your own behalf, and not on
|
||||||
|
behalf of any Contributor. You must make it absolutely clear that any
|
||||||
|
such warranty, support, indemnity, or liability obligation is offered by
|
||||||
|
You alone, and You hereby agree to indemnify every Contributor for any
|
||||||
|
liability incurred by such Contributor as a result of warranty, support,
|
||||||
|
indemnity or liability terms You offer. You may include additional
|
||||||
|
disclaimers of warranty and limitations of liability specific to any
|
||||||
|
jurisdiction.
|
||||||
|
|
||||||
|
4. Inability to Comply Due to Statute or Regulation
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
If it is impossible for You to comply with any of the terms of this
|
||||||
|
License with respect to some or all of the Covered Software due to
|
||||||
|
statute, judicial order, or regulation then You must: (a) comply with
|
||||||
|
the terms of this License to the maximum extent possible; and (b)
|
||||||
|
describe the limitations and the code they affect. Such description must
|
||||||
|
be placed in a text file included with all distributions of the Covered
|
||||||
|
Software under this License. Except to the extent prohibited by statute
|
||||||
|
or regulation, such description must be sufficiently detailed for a
|
||||||
|
recipient of ordinary skill to be able to understand it.
|
||||||
|
|
||||||
|
5. Termination
|
||||||
|
--------------
|
||||||
|
|
||||||
|
5.1. The rights granted under this License will terminate automatically
|
||||||
|
if You fail to comply with any of its terms. However, if You become
|
||||||
|
compliant, then the rights granted under this License from a particular
|
||||||
|
Contributor are reinstated (a) provisionally, unless and until such
|
||||||
|
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||||
|
ongoing basis, if such Contributor fails to notify You of the
|
||||||
|
non-compliance by some reasonable means prior to 60 days after You have
|
||||||
|
come back into compliance. Moreover, Your grants from a particular
|
||||||
|
Contributor are reinstated on an ongoing basis if such Contributor
|
||||||
|
notifies You of the non-compliance by some reasonable means, this is the
|
||||||
|
first time You have received notice of non-compliance with this License
|
||||||
|
from such Contributor, and You become compliant prior to 30 days after
|
||||||
|
Your receipt of the notice.
|
||||||
|
|
||||||
|
5.2. If You initiate litigation against any entity by asserting a patent
|
||||||
|
infringement claim (excluding declaratory judgment actions,
|
||||||
|
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||||
|
directly or indirectly infringes any patent, then the rights granted to
|
||||||
|
You by any and all Contributors for the Covered Software under Section
|
||||||
|
2.1 of this License shall terminate.
|
||||||
|
|
||||||
|
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||||
|
end user license agreements (excluding distributors and resellers) which
|
||||||
|
have been validly granted by You or Your distributors under this License
|
||||||
|
prior to termination shall survive termination.
|
||||||
|
|
||||||
|
************************************************************************
|
||||||
|
* *
|
||||||
|
* 6. Disclaimer of Warranty *
|
||||||
|
* ------------------------- *
|
||||||
|
* *
|
||||||
|
* Covered Software is provided under this License on an "as is" *
|
||||||
|
* basis, without warranty of any kind, either expressed, implied, or *
|
||||||
|
* statutory, including, without limitation, warranties that the *
|
||||||
|
* Covered Software is free of defects, merchantable, fit for a *
|
||||||
|
* particular purpose or non-infringing. The entire risk as to the *
|
||||||
|
* quality and performance of the Covered Software is with You. *
|
||||||
|
* Should any Covered Software prove defective in any respect, You *
|
||||||
|
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||||
|
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||||
|
* essential part of this License. No use of any Covered Software is *
|
||||||
|
* authorized under this License except under this disclaimer. *
|
||||||
|
* *
|
||||||
|
************************************************************************
|
||||||
|
|
||||||
|
************************************************************************
|
||||||
|
* *
|
||||||
|
* 7. Limitation of Liability *
|
||||||
|
* -------------------------- *
|
||||||
|
* *
|
||||||
|
* Under no circumstances and under no legal theory, whether tort *
|
||||||
|
* (including negligence), contract, or otherwise, shall any *
|
||||||
|
* Contributor, or anyone who distributes Covered Software as *
|
||||||
|
* permitted above, be liable to You for any direct, indirect, *
|
||||||
|
* special, incidental, or consequential damages of any character *
|
||||||
|
* including, without limitation, damages for lost profits, loss of *
|
||||||
|
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||||
|
* and all other commercial damages or losses, even if such party *
|
||||||
|
* shall have been informed of the possibility of such damages. This *
|
||||||
|
* limitation of liability shall not apply to liability for death or *
|
||||||
|
* personal injury resulting from such party's negligence to the *
|
||||||
|
* extent applicable law prohibits such limitation. Some *
|
||||||
|
* jurisdictions do not allow the exclusion or limitation of *
|
||||||
|
* incidental or consequential damages, so this exclusion and *
|
||||||
|
* limitation may not apply to You. *
|
||||||
|
* *
|
||||||
|
************************************************************************
|
||||||
|
|
||||||
|
8. Litigation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Any litigation relating to this License may be brought only in the
|
||||||
|
courts of a jurisdiction where the defendant maintains its principal
|
||||||
|
place of business and such litigation shall be governed by laws of that
|
||||||
|
jurisdiction, without reference to its conflict-of-law provisions.
|
||||||
|
Nothing in this Section shall prevent a party's ability to bring
|
||||||
|
cross-claims or counter-claims.
|
||||||
|
|
||||||
|
9. Miscellaneous
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This License represents the complete agreement concerning the subject
|
||||||
|
matter hereof. If any provision of this License is held to be
|
||||||
|
unenforceable, such provision shall be reformed only to the extent
|
||||||
|
necessary to make it enforceable. Any law or regulation which provides
|
||||||
|
that the language of a contract shall be construed against the drafter
|
||||||
|
shall not be used to construe this License against a Contributor.
|
||||||
|
|
||||||
|
10. Versions of the License
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
10.1. New Versions
|
||||||
|
|
||||||
|
Mozilla Foundation is the license steward. Except as provided in Section
|
||||||
|
10.3, no one other than the license steward has the right to modify or
|
||||||
|
publish new versions of this License. Each version will be given a
|
||||||
|
distinguishing version number.
|
||||||
|
|
||||||
|
10.2. Effect of New Versions
|
||||||
|
|
||||||
|
You may distribute the Covered Software under the terms of the version
|
||||||
|
of the License under which You originally received the Covered Software,
|
||||||
|
or under the terms of any subsequent version published by the license
|
||||||
|
steward.
|
||||||
|
|
||||||
|
10.3. Modified Versions
|
||||||
|
|
||||||
|
If you create software not governed by this License, and you want to
|
||||||
|
create a new license for such software, you may create and use a
|
||||||
|
modified version of this License if you rename the license and remove
|
||||||
|
any references to the name of the license steward (except to note that
|
||||||
|
such modified license differs from this License).
|
||||||
|
|
||||||
|
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||||
|
Licenses
|
||||||
|
|
||||||
|
If You choose to distribute Source Code Form that is Incompatible With
|
||||||
|
Secondary Licenses under the terms of this version of the License, the
|
||||||
|
notice described in Exhibit B of this License must be attached.
|
||||||
|
|
||||||
|
Exhibit A - Source Code Form License Notice
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
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/.
|
||||||
|
|
||||||
|
If it is not possible or desirable to put the notice in a particular
|
||||||
|
file, then You may include the notice in a location (such as a LICENSE
|
||||||
|
file in a relevant directory) where a recipient would be likely to look
|
||||||
|
for such a notice.
|
||||||
|
|
||||||
|
You may add additional accurate notices of copyright ownership.
|
||||||
|
|
||||||
|
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
|
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||||
|
defined by the Mozilla Public License, v. 2.0.
|
||||||
|
|
53
third_party/webrender/README.md
vendored
Normal file
53
third_party/webrender/README.md
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# WebRender
|
||||||
|
|
||||||
|
[](https://crates.io/crates/webrender)
|
||||||
|
|
||||||
|
WebRender is a GPU-based 2D rendering engine written in [Rust](https://www.rust-lang.org/). [Firefox](https://www.mozilla.org/firefox), the research web browser [Servo](https://github.com/servo/servo), and other GUI frameworks draw with it. It currently uses the OpenGL API internally.
|
||||||
|
|
||||||
|
Note that the canonical home for this code is in gfx/wr folder of the
|
||||||
|
mozilla-central repository at https://hg.mozilla.org/mozilla-central. The
|
||||||
|
Github repository at https://github.com/servo/webrender should be considered
|
||||||
|
a downstream mirror, although it contains additional metadata (such as Github
|
||||||
|
wiki pages) that do not exist in mozilla-central. Pull requests against the
|
||||||
|
Github repository are still being accepted, although once reviewed, they will
|
||||||
|
be landed on mozilla-central first and then mirrored back. If you are familiar
|
||||||
|
with the mozilla-central contribution workflow, filing bugs in
|
||||||
|
[Bugzilla](https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&component=Graphics%3A%20WebRender)
|
||||||
|
and submitting patches there would be preferred.
|
||||||
|
|
||||||
|
## Update as a Dependency
|
||||||
|
After updating shaders in WebRender, go to servo and:
|
||||||
|
|
||||||
|
* Go to the servo directory and do ./mach update-cargo -p webrender
|
||||||
|
* Create a pull request to servo
|
||||||
|
|
||||||
|
|
||||||
|
## Use WebRender with Servo
|
||||||
|
To use a local copy of WebRender with servo, go to your servo build directory and:
|
||||||
|
|
||||||
|
* Edit Cargo.toml
|
||||||
|
* Add at the end of the file:
|
||||||
|
|
||||||
|
```
|
||||||
|
[patch."https://github.com/servo/webrender"]
|
||||||
|
"webrender" = { path = "<path>/webrender" }
|
||||||
|
"webrender_api" = { path = "<path>/webrender_api" }
|
||||||
|
```
|
||||||
|
|
||||||
|
where `<path>` is the path to your local copy of WebRender.
|
||||||
|
|
||||||
|
* Build as normal
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
The Wiki has a [few pages](https://github.com/servo/webrender/wiki/) describing the internals and conventions of WebRender.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Tests run using OSMesa to get consistent rendering across platforms.
|
||||||
|
|
||||||
|
Still there may be differences depending on font libraries on your system, for
|
||||||
|
example.
|
||||||
|
|
||||||
|
See [this gist](https://gist.github.com/finalfantasia/129cae811e02bf4551ac) for
|
||||||
|
how to make the text tests useful in Fedora, for example.
|
12
third_party/webrender/ci-scripts/docker-image/Dockerfile
vendored
Normal file
12
third_party/webrender/ci-scripts/docker-image/Dockerfile
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
FROM debian:buster-20200422
|
||||||
|
|
||||||
|
# Debian 10 doesn't have openjdk-8, so add the Debian 9 repository, which contains it.
|
||||||
|
RUN sed s/buster/stretch/ /etc/apt/sources.list | tee /etc/apt/sources.list.d/stretch.list
|
||||||
|
|
||||||
|
COPY setup.sh /root
|
||||||
|
RUN cd /root && ./setup.sh
|
||||||
|
|
||||||
|
RUN useradd -d /home/worker -s /bin/bash -m worker
|
||||||
|
USER worker
|
||||||
|
WORKDIR /home/worker
|
||||||
|
CMD /bin/bash
|
37
third_party/webrender/ci-scripts/docker-image/setup.sh
vendored
Executable file
37
third_party/webrender/ci-scripts/docker-image/setup.sh
vendored
Executable file
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# 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/. */
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
set -o xtrace
|
||||||
|
|
||||||
|
test "$(whoami)" == 'root'
|
||||||
|
|
||||||
|
# Install stuff we need
|
||||||
|
apt-get -y update
|
||||||
|
apt-get install -y \
|
||||||
|
bzip2 \
|
||||||
|
cmake \
|
||||||
|
curl \
|
||||||
|
gcc \
|
||||||
|
git \
|
||||||
|
g++ \
|
||||||
|
libfontconfig1-dev \
|
||||||
|
libgl1-mesa-dev \
|
||||||
|
libx11-dev \
|
||||||
|
openjdk-8-jdk \
|
||||||
|
pkg-config \
|
||||||
|
python \
|
||||||
|
python-mako \
|
||||||
|
python-pip \
|
||||||
|
python-setuptools \
|
||||||
|
python-voluptuous \
|
||||||
|
python-yaml \
|
||||||
|
software-properties-common
|
||||||
|
|
||||||
|
# Other stuff we need
|
||||||
|
pip install servo-tidy==0.3.0
|
36
third_party/webrender/ci-scripts/linux-debug-tests.sh
vendored
Executable file
36
third_party/webrender/ci-scripts/linux-debug-tests.sh
vendored
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# 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/. */
|
||||||
|
|
||||||
|
# This must be run from the root webrender directory!
|
||||||
|
# Users may set the CARGOFLAGS environment variable to pass
|
||||||
|
# additional flags to cargo if desired.
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
set -o xtrace
|
||||||
|
|
||||||
|
CARGOFLAGS=${CARGOFLAGS:-"--verbose"} # default to --verbose if not set
|
||||||
|
|
||||||
|
pushd webrender
|
||||||
|
cargo build ${CARGOFLAGS} --no-default-features
|
||||||
|
cargo build ${CARGOFLAGS} --no-default-features --features capture
|
||||||
|
cargo build ${CARGOFLAGS} --features capture,profiler
|
||||||
|
cargo build ${CARGOFLAGS} --features replay
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd wrench
|
||||||
|
cargo build ${CARGOFLAGS} --features env_logger
|
||||||
|
OPTIMIZED=0 python script/headless.py reftest
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd examples
|
||||||
|
cargo build ${CARGOFLAGS}
|
||||||
|
popd
|
||||||
|
|
||||||
|
cargo test ${CARGOFLAGS} \
|
||||||
|
--all --exclude compositor-windows --exclude compositor \
|
||||||
|
--exclude glsl-to-cxx --exclude swgl
|
22
third_party/webrender/ci-scripts/linux-release-tests.sh
vendored
Executable file
22
third_party/webrender/ci-scripts/linux-release-tests.sh
vendored
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# 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/. */
|
||||||
|
|
||||||
|
# This must be run from the root webrender directory!
|
||||||
|
# Users may set the CARGOFLAGS environment variable to pass
|
||||||
|
# additional flags to cargo if desired.
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
set -o xtrace
|
||||||
|
|
||||||
|
CARGOFLAGS=${CARGOFLAGS:-""} # default to empty if not set
|
||||||
|
|
||||||
|
pushd wrench
|
||||||
|
python script/headless.py reftest
|
||||||
|
python script/headless.py rawtest
|
||||||
|
cargo build ${CARGOFLAGS} --release
|
||||||
|
popd
|
42
third_party/webrender/ci-scripts/macos-debug-tests.sh
vendored
Executable file
42
third_party/webrender/ci-scripts/macos-debug-tests.sh
vendored
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# 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/. */
|
||||||
|
|
||||||
|
# This must be run from the root webrender directory!
|
||||||
|
# Users may set the CARGOFLAGS environment variable to pass
|
||||||
|
# additional flags to cargo if desired.
|
||||||
|
|
||||||
|
# Note that this script is run in a special cross-compiling configuration,
|
||||||
|
# where CARGOTESTFLAGS includes `--no-run`, and the binaries produced by
|
||||||
|
# `cargo test` are run on a different machine. When making changes to this
|
||||||
|
# file, please ensure any such binaries produced by `cargo test` are not
|
||||||
|
# deleted, or they may not get run as expected.
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
set -o xtrace
|
||||||
|
|
||||||
|
CARGOFLAGS=${CARGOFLAGS:-"--verbose"} # default to --verbose if not set
|
||||||
|
CARGOTESTFLAGS=${CARGOTESTFLAGS:-""}
|
||||||
|
|
||||||
|
pushd webrender
|
||||||
|
cargo check ${CARGOFLAGS} --no-default-features
|
||||||
|
cargo check ${CARGOFLAGS} --no-default-features --features capture
|
||||||
|
cargo check ${CARGOFLAGS} --features capture,profiler
|
||||||
|
cargo check ${CARGOFLAGS} --features replay
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd wrench
|
||||||
|
cargo check ${CARGOFLAGS} --features env_logger
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd examples
|
||||||
|
cargo check ${CARGOFLAGS}
|
||||||
|
popd
|
||||||
|
|
||||||
|
cargo test ${CARGOFLAGS} ${CARGOTESTFLAGS} \
|
||||||
|
--all --exclude compositor-windows --exclude compositor \
|
||||||
|
--exclude glsl-to-cxx --exclude swgl
|
29
third_party/webrender/ci-scripts/macos-release-tests.sh
vendored
Executable file
29
third_party/webrender/ci-scripts/macos-release-tests.sh
vendored
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# 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/. */
|
||||||
|
|
||||||
|
# This must be run from the root webrender directory!
|
||||||
|
# Users may set the CARGOFLAGS environment variable to pass
|
||||||
|
# additional flags to cargo if desired.
|
||||||
|
# The WRENCH_BINARY environment variable, if set, is used to run
|
||||||
|
# the precached reftest.
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
set -o xtrace
|
||||||
|
|
||||||
|
CARGOFLAGS=${CARGOFLAGS:-""} # default to empty if not set
|
||||||
|
WRENCH_BINARY=${WRENCH_BINARY:-""}
|
||||||
|
|
||||||
|
pushd wrench
|
||||||
|
python script/headless.py reftest
|
||||||
|
if [[ -z "${WRENCH_BINARY}" ]]; then
|
||||||
|
cargo build ${CARGOFLAGS} --release
|
||||||
|
WRENCH_BINARY="../target/release/wrench"
|
||||||
|
fi
|
||||||
|
"${WRENCH_BINARY}" --precache \
|
||||||
|
reftest reftests/clip/fixed-position-clipping.yaml
|
||||||
|
popd
|
124
third_party/webrender/ci-scripts/set-screenresolution.ps1
vendored
Normal file
124
third_party/webrender/ci-scripts/set-screenresolution.ps1
vendored
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
# http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/07/hey-scripting-guy-how-can-i-change-my-desktop-monitor-resolution-via-windows-powershell.aspx
|
||||||
|
|
||||||
|
Function Set-ScreenResolution {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$true,
|
||||||
|
Position = 0)]
|
||||||
|
[int]
|
||||||
|
$Width,
|
||||||
|
[Parameter(Mandatory=$true,
|
||||||
|
Position = 1)]
|
||||||
|
[int]
|
||||||
|
$Height
|
||||||
|
)
|
||||||
|
$pinvokeCode = @"
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
namespace Resolution
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct DEVMODE1
|
||||||
|
{
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||||
|
public string dmDeviceName;
|
||||||
|
public short dmSpecVersion;
|
||||||
|
public short dmDriverVersion;
|
||||||
|
public short dmSize;
|
||||||
|
public short dmDriverExtra;
|
||||||
|
public int dmFields;
|
||||||
|
public short dmOrientation;
|
||||||
|
public short dmPaperSize;
|
||||||
|
public short dmPaperLength;
|
||||||
|
public short dmPaperWidth;
|
||||||
|
public short dmScale;
|
||||||
|
public short dmCopies;
|
||||||
|
public short dmDefaultSource;
|
||||||
|
public short dmPrintQuality;
|
||||||
|
public short dmColor;
|
||||||
|
public short dmDuplex;
|
||||||
|
public short dmYResolution;
|
||||||
|
public short dmTTOption;
|
||||||
|
public short dmCollate;
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||||
|
public string dmFormName;
|
||||||
|
public short dmLogPixels;
|
||||||
|
public short dmBitsPerPel;
|
||||||
|
public int dmPelsWidth;
|
||||||
|
public int dmPelsHeight;
|
||||||
|
public int dmDisplayFlags;
|
||||||
|
public int dmDisplayFrequency;
|
||||||
|
public int dmICMMethod;
|
||||||
|
public int dmICMIntent;
|
||||||
|
public int dmMediaType;
|
||||||
|
public int dmDitherType;
|
||||||
|
public int dmReserved1;
|
||||||
|
public int dmReserved2;
|
||||||
|
public int dmPanningWidth;
|
||||||
|
public int dmPanningHeight;
|
||||||
|
};
|
||||||
|
class User_32
|
||||||
|
{
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags);
|
||||||
|
public const int ENUM_CURRENT_SETTINGS = -1;
|
||||||
|
public const int CDS_UPDATEREGISTRY = 0x01;
|
||||||
|
public const int CDS_TEST = 0x02;
|
||||||
|
public const int DISP_CHANGE_SUCCESSFUL = 0;
|
||||||
|
public const int DISP_CHANGE_RESTART = 1;
|
||||||
|
public const int DISP_CHANGE_FAILED = -1;
|
||||||
|
}
|
||||||
|
public class PrmaryScreenResolution
|
||||||
|
{
|
||||||
|
static public string ChangeResolution(int width, int height)
|
||||||
|
{
|
||||||
|
DEVMODE1 dm = GetDevMode1();
|
||||||
|
if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm))
|
||||||
|
{
|
||||||
|
dm.dmPelsWidth = width;
|
||||||
|
dm.dmPelsHeight = height;
|
||||||
|
int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST);
|
||||||
|
if (iRet == User_32.DISP_CHANGE_FAILED)
|
||||||
|
{
|
||||||
|
return "Unable To Process Your Request. Sorry For This Inconvenience.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY);
|
||||||
|
switch (iRet)
|
||||||
|
{
|
||||||
|
case User_32.DISP_CHANGE_SUCCESSFUL:
|
||||||
|
{
|
||||||
|
return "Success";
|
||||||
|
}
|
||||||
|
case User_32.DISP_CHANGE_RESTART:
|
||||||
|
{
|
||||||
|
return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.";
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return "Failed To Change The Resolution";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "Failed To Change The Resolution.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static DEVMODE1 GetDevMode1()
|
||||||
|
{
|
||||||
|
DEVMODE1 dm = new DEVMODE1();
|
||||||
|
dm.dmDeviceName = new String(new char[32]);
|
||||||
|
dm.dmFormName = new String(new char[32]);
|
||||||
|
dm.dmSize = (short)Marshal.SizeOf(dm);
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
Add-Type $pinvokeCode -ErrorAction SilentlyContinue
|
||||||
|
[Resolution.PrmaryScreenResolution]::ChangeResolution($width,$height)
|
||||||
|
}
|
36
third_party/webrender/ci-scripts/windows-tests.cmd
vendored
Executable file
36
third_party/webrender/ci-scripts/windows-tests.cmd
vendored
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
:: 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/. */
|
||||||
|
|
||||||
|
:: This must be run from the root webrender directory!
|
||||||
|
:: Users may set the CARGOFLAGS environment variable to pass
|
||||||
|
:: additional flags to cargo if desired.
|
||||||
|
|
||||||
|
if NOT DEFINED CARGOFLAGS SET CARGOFLAGS=--verbose
|
||||||
|
|
||||||
|
pushd webrender_api
|
||||||
|
cargo test %CARGOFLAGS%
|
||||||
|
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd webrender
|
||||||
|
cargo test %CARGOFLAGS%
|
||||||
|
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd wrench
|
||||||
|
cargo test --verbose
|
||||||
|
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||||
|
cargo run --release -- --angle reftest
|
||||||
|
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd examples
|
||||||
|
cargo check --verbose
|
||||||
|
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd direct-composition
|
||||||
|
cargo check --verbose
|
||||||
|
if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
|
||||||
|
popd
|
6
third_party/webrender/debugger/.babelrc
vendored
Normal file
6
third_party/webrender/debugger/.babelrc
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
["env", { "modules": false }],
|
||||||
|
"stage-3"
|
||||||
|
]
|
||||||
|
}
|
11
third_party/webrender/debugger/.gitignore
vendored
Normal file
11
third_party/webrender/debugger/.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
23
third_party/webrender/debugger/README.md
vendored
Normal file
23
third_party/webrender/debugger/README.md
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# WebRender Debugger
|
||||||
|
A web based debugger for WebRender.
|
||||||
|
|
||||||
|
## Using the debugger
|
||||||
|
Build your application with the debugger feature enabled, for example in wrench:
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo build --features=debugger
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, open your browser and open the debugger/index.html file. Click Connect and
|
||||||
|
the debugger will attempt to connect to WR via websocket.
|
||||||
|
|
||||||
|
## Using the debugger with Gecko
|
||||||
|
|
||||||
|
In the Gecko source tree, open ```gfx/webrender_bindings/Cargo.toml``` in a text editor.
|
||||||
|
|
||||||
|
Add ```features = ['debugger']``` to the end of the file (in the ```dependencies.webrender``` section).
|
||||||
|
|
||||||
|
Vendor the rust dependencies locally for the debugger (we don't want these committed to the repo):
|
||||||
|
```./mach vendor rust```
|
||||||
|
|
||||||
|
Now, build and run as usual, and the debugger will be available.
|
13
third_party/webrender/debugger/dist/build.js
vendored
Normal file
13
third_party/webrender/debugger/dist/build.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
third_party/webrender/debugger/dist/build.js.map
vendored
Normal file
1
third_party/webrender/debugger/dist/build.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
11
third_party/webrender/debugger/index.html
vendored
Normal file
11
third_party/webrender/debugger/index.html
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebRender Debugger</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script src="dist/build.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
7606
third_party/webrender/debugger/package-lock.json
generated
vendored
Normal file
7606
third_party/webrender/debugger/package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
36
third_party/webrender/debugger/package.json
vendored
Normal file
36
third_party/webrender/debugger/package.json
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "debugger",
|
||||||
|
"description": "WebRender Debugger",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": "Glenn Watson <github@intuitionlibrary.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
|
||||||
|
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"buefy": "^0.6.7",
|
||||||
|
"vue": "^2.5.11",
|
||||||
|
"vue-material-design-icons": "^0.8.2",
|
||||||
|
"vuex": "^3.0.1"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not ie <= 8"
|
||||||
|
],
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-core": "^6.26.0",
|
||||||
|
"babel-loader": "^7.1.2",
|
||||||
|
"babel-preset-env": "^1.6.0",
|
||||||
|
"babel-preset-stage-3": "^6.24.1",
|
||||||
|
"cross-env": "^5.0.5",
|
||||||
|
"css-loader": "^0.28.7",
|
||||||
|
"file-loader": "^1.1.4",
|
||||||
|
"vue-loader": "^13.0.5",
|
||||||
|
"vue-template-compiler": "^2.4.4",
|
||||||
|
"webpack": "^3.6.0",
|
||||||
|
"webpack-dev-server": "^2.9.1"
|
||||||
|
}
|
||||||
|
}
|
55
third_party/webrender/debugger/src/App.vue
vendored
Normal file
55
third_party/webrender/debugger/src/App.vue
vendored
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<app-navbar></app-navbar>
|
||||||
|
<div class="section">
|
||||||
|
<div class="container">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-3">
|
||||||
|
<app-navmenu></app-navmenu>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<app-options v-if="page == 'options'"></app-options>
|
||||||
|
<app-passview v-if="page == 'passes'"></app-passview>
|
||||||
|
<app-rendertaskview v-if="page == 'render_tasks'"></app-rendertaskview>
|
||||||
|
<app-documentview v-if="page == 'documents'"></app-documentview>
|
||||||
|
<app-clipscrolltreeview v-if="page == 'clip_scroll_tree'"></app-clipscrolltreeview>
|
||||||
|
<app-screenshotview v-if="page == 'screenshot'"></app-screenshotview>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import NavBar from './components/NavBar.vue'
|
||||||
|
import NavMenu from './components/NavMenu.vue'
|
||||||
|
import OptionsPage from './components/OptionsPage.vue'
|
||||||
|
import PassViewPage from './components/PassViewPage.vue'
|
||||||
|
import RenderTaskViewPage from './components/RenderTaskViewPage.vue'
|
||||||
|
import DocumentViewPage from './components/DocumentViewPage.vue'
|
||||||
|
import ClipScrollTreeViewPage from './components/ClipScrollTreeViewPage.vue'
|
||||||
|
import ScreenshotPage from './components/ScreenshotPage.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'app',
|
||||||
|
components: {
|
||||||
|
'app-navbar': NavBar,
|
||||||
|
'app-navmenu': NavMenu,
|
||||||
|
'app-options': OptionsPage,
|
||||||
|
'app-passview': PassViewPage,
|
||||||
|
'app-rendertaskview': RenderTaskViewPage,
|
||||||
|
'app-documentview': DocumentViewPage,
|
||||||
|
'app-clipscrolltreeview': ClipScrollTreeViewPage,
|
||||||
|
'app-screenshotview': ScreenshotPage,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
page() {
|
||||||
|
return this.$store.state.page;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
37
third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/ClipScrollTreeViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<h1 class="title">Clip-Scroll Tree <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||||
|
<hr/>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<app-treeview :model=clip_scroll_tree></app-treeview>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TreeView from './TreeView.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
'app-treeview': TreeView,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetch: function() {
|
||||||
|
this.$store.dispatch('sendMessage', "fetch_clip_scroll_tree");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
disabled() {
|
||||||
|
return !this.$store.state.connected
|
||||||
|
},
|
||||||
|
clip_scroll_tree() {
|
||||||
|
return this.$store.state.clip_scroll_tree
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
37
third_party/webrender/debugger/src/components/DocumentViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/DocumentViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<h1 class="title">Documents <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||||
|
<hr/>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<app-treeview :model=documents></app-treeview>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TreeView from './TreeView.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
'app-treeview': TreeView,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetch: function() {
|
||||||
|
this.$store.dispatch('sendMessage', "fetch_documents");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
disabled() {
|
||||||
|
return !this.$store.state.connected
|
||||||
|
},
|
||||||
|
documents() {
|
||||||
|
return this.$store.state.documents
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
41
third_party/webrender/debugger/src/components/NavBar.vue
vendored
Normal file
41
third_party/webrender/debugger/src/components/NavBar.vue
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<nav class="navbar has-shadow">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item" href="#">WebRender Debugger</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="navbar-menu">
|
||||||
|
<div class="navbar-start"></div>
|
||||||
|
|
||||||
|
<div class="navbar-end">
|
||||||
|
<div class="navbar-item">
|
||||||
|
<p class="control">
|
||||||
|
<button v-if="isConnected" @click="disconnect" class="button is-danger">Disconnect</button>
|
||||||
|
<button v-else @click="connect" class="button is-success">Connect</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
isConnected() {
|
||||||
|
return this.$store.state.connected;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
connect() {
|
||||||
|
this.$store.dispatch('connect');
|
||||||
|
},
|
||||||
|
disconnect() {
|
||||||
|
this.$store.dispatch('disconnect');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
33
third_party/webrender/debugger/src/components/NavMenu.vue
vendored
Normal file
33
third_party/webrender/debugger/src/components/NavMenu.vue
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<template>
|
||||||
|
<aside class="menu">
|
||||||
|
<p class="menu-label">
|
||||||
|
Pages
|
||||||
|
</p>
|
||||||
|
<ul class="menu-list">
|
||||||
|
<li><a @click="setPage('options')" :class="{ 'is-active': page == 'options' }">Debug Options</a></li>
|
||||||
|
<li><a @click="setPage('passes')" :class="{ 'is-active': page == 'passes' }">Passes</a></li>
|
||||||
|
<li><a @click="setPage('render_tasks')" :class="{ 'is-active': page == 'render_tasks' }">Render Tasks</a></li>
|
||||||
|
<li><a @click="setPage('documents')" :class="{ 'is-active': page == 'documents' }">Documents</a></li>
|
||||||
|
<li><a @click="setPage('clip_scroll_tree')" v-bind:class="{ 'is-active': page == 'clip_scroll_tree' }">Clip-Scroll Tree</a></li>
|
||||||
|
<li><a @click="setPage('screenshot')" v-bind:class="{ 'is-active': page == 'screenshot' }">Screenshot</a></li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
setPage(name) {
|
||||||
|
this.$store.commit('setPage', name);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
page() {
|
||||||
|
return this.$store.state.page;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
162
third_party/webrender/debugger/src/components/OptionsPage.vue
vendored
Normal file
162
third_party/webrender/debugger/src/components/OptionsPage.vue
vendored
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setProfiler($event.target.checked)">
|
||||||
|
Profiler
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setTextureCacheDebugger($event.target.checked)">
|
||||||
|
Texture cache debugger
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setRenderTargetDebugger($event.target.checked)">
|
||||||
|
Render target debugger
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setAlphaRectsDebugger($event.target.checked)">
|
||||||
|
Alpha primitive rects debugger
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setGpuTimeQueries($event.target.checked)">
|
||||||
|
Enable GPU time queries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setGpuSampleQueries($event.target.checked)">
|
||||||
|
Enable GPU sample queries
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setOpaquePass(!$event.target.checked)">
|
||||||
|
Disable opaque pass
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setAlphaPass(!$event.target.checked)">
|
||||||
|
Disable alpha pass
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setClipMasks(!$event.target.checked)">
|
||||||
|
Disable clip masks
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setTextPrims(!$event.target.checked)">
|
||||||
|
Disable text primitives
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" :disabled="disabled" v-on:click="setGradientPrims(!$event.target.checked)">
|
||||||
|
Disable gradient primitives
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
disabled() {
|
||||||
|
return !this.$store.state.connected
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setProfiler(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_profiler");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_profiler");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setTextureCacheDebugger(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_texture_cache_debug");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_texture_cache_debug");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setRenderTargetDebugger(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_render_target_debug");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_render_target_debug");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setAlphaRectsDebugger(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_alpha_rects_debug");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_alpha_rects_debug");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setGpuTimeQueries(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_gpu_time_queries");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_gpu_time_queries");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setGpuSampleQueries(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_gpu_sample_queries");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_gpu_sample_queries");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setOpaquePass(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_opaque_pass");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_opaque_pass");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setAlphaPass(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_alpha_pass");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_alpha_pass");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setClipMasks(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_clip_masks");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_clip_masks");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setTextPrims(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_text_prims");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_text_prims");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setGradientPrims(enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
this.$store.dispatch('sendMessage', "enable_gradient_prims");
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('sendMessage', "disable_gradient_prims");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
37
third_party/webrender/debugger/src/components/PassViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/PassViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<h1 class="title">Passes <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||||
|
<hr/>
|
||||||
|
<div v-for="(pass, pass_index) in passes">
|
||||||
|
<p class="has-text-black-bis">Pass {{pass_index}}</p>
|
||||||
|
<div v-for="(target, target_index) in pass.targets">
|
||||||
|
<p style="text-indent: 2em;" class="has-text-grey-dark">Target {{target_index}} ({{target.kind}})</p>
|
||||||
|
<div v-for="(batch, batch_index) in target.batches">
|
||||||
|
<p style="text-indent: 4em;" class="has-text-grey">Batch {{batch_index}} ({{batch.description}}, {{batch.kind}}, {{batch.count}} instances)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
fetch: function() {
|
||||||
|
this.$store.dispatch('sendMessage', "fetch_passes");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
disabled() {
|
||||||
|
return !this.$store.state.connected
|
||||||
|
},
|
||||||
|
passes() {
|
||||||
|
return this.$store.state.passes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
37
third_party/webrender/debugger/src/components/RenderTaskViewPage.vue
vendored
Normal file
37
third_party/webrender/debugger/src/components/RenderTaskViewPage.vue
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<h1 class="title">Render Tasks <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||||
|
<hr/>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<app-treeview :model=render_tasks></app-treeview>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TreeView from './TreeView.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
'app-treeview': TreeView,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetch: function() {
|
||||||
|
this.$store.dispatch('sendMessage', "fetch_render_tasks");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
disabled() {
|
||||||
|
return !this.$store.state.connected
|
||||||
|
},
|
||||||
|
render_tasks() {
|
||||||
|
return this.$store.state.render_tasks
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
32
third_party/webrender/debugger/src/components/ScreenshotPage.vue
vendored
Normal file
32
third_party/webrender/debugger/src/components/ScreenshotPage.vue
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<h1 class="title">Screenshot <a :disabled="disabled" v-on:click="fetch" class="button is-info">Refresh</a></h1>
|
||||||
|
<hr/>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<img v-if="screenshot.length > 0" style="transform: scaleY(-1); width: 1024px; height:768px" :src="'data:image/png;base64,' + screenshot" />
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
disabled() {
|
||||||
|
return !this.$store.state.connected
|
||||||
|
},
|
||||||
|
screenshot() {
|
||||||
|
return this.$store.state.screenshot
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetch: function() {
|
||||||
|
this.$store.dispatch('sendMessage', "fetch_screenshot");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
40
third_party/webrender/debugger/src/components/TreeView.vue
vendored
Normal file
40
third_party/webrender/debugger/src/components/TreeView.vue
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<template>
|
||||||
|
<li>
|
||||||
|
<div v-on:click="toggle">
|
||||||
|
<span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
|
||||||
|
{{model.description}}
|
||||||
|
</div>
|
||||||
|
<ul style="padding-left: 1em; line-height: 1.5em;" v-show="open" v-if="isFolder">
|
||||||
|
<treeview v-for="model in model.children" :model="model"></treeview>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'treeview',
|
||||||
|
props: [
|
||||||
|
'model',
|
||||||
|
],
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
open: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isFolder: function () {
|
||||||
|
return this.model.children && this.model.children.length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle: function () {
|
||||||
|
if (this.isFolder) {
|
||||||
|
this.open = !this.open
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
14
third_party/webrender/debugger/src/main.js
vendored
Normal file
14
third_party/webrender/debugger/src/main.js
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Buefy from 'buefy';
|
||||||
|
import 'buefy/dist/buefy.css';
|
||||||
|
import "vue-material-design-icons/styles.css";
|
||||||
|
import App from './App.vue';
|
||||||
|
import store from './store';
|
||||||
|
|
||||||
|
Vue.use(Buefy);
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
store,
|
||||||
|
render: h => h(App)
|
||||||
|
})
|
105
third_party/webrender/debugger/src/store/index.js
vendored
Normal file
105
third_party/webrender/debugger/src/store/index.js
vendored
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
class Connection {
|
||||||
|
constructor() {
|
||||||
|
this.ws = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(context) {
|
||||||
|
var ws = new WebSocket("ws://127.0.0.1:3583");
|
||||||
|
|
||||||
|
ws.onopen = function() {
|
||||||
|
context.commit('setConnected', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.onmessage = function(evt) {
|
||||||
|
var json = JSON.parse(evt.data);
|
||||||
|
if (json['kind'] == "passes") {
|
||||||
|
context.commit('setPasses', json['passes']);
|
||||||
|
} else if (json['kind'] == "render_tasks") {
|
||||||
|
context.commit('setRenderTasks', json['root']);
|
||||||
|
} else if (json['kind'] == "documents") {
|
||||||
|
context.commit('setDocuments', json['root']);
|
||||||
|
} else if (json['kind'] == "clip_scroll_tree") {
|
||||||
|
context.commit('setClipScrollTree', json['root']);
|
||||||
|
} else if (json['kind'] == "screenshot") {
|
||||||
|
context.commit('setScreenshot', json['data']);
|
||||||
|
} else {
|
||||||
|
console.warn("unknown message kind: " + json['kind']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.onclose = function() {
|
||||||
|
context.commit('setConnected', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ws = ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
send(msg) {
|
||||||
|
if (this.ws !== null) {
|
||||||
|
this.ws.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
if (this.ws !== null) {
|
||||||
|
this.ws.close();
|
||||||
|
this.ws = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var connection = new Connection();
|
||||||
|
|
||||||
|
const store = new Vuex.Store({
|
||||||
|
strict: true,
|
||||||
|
state: {
|
||||||
|
connected: false,
|
||||||
|
page: 'options',
|
||||||
|
passes: [],
|
||||||
|
render_tasks: [],
|
||||||
|
documents: [],
|
||||||
|
clip_scroll_tree: [],
|
||||||
|
screenshot: [],
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setConnected(state, connected) {
|
||||||
|
state.connected = connected;
|
||||||
|
},
|
||||||
|
setPage(state, name) {
|
||||||
|
state.page = name;
|
||||||
|
},
|
||||||
|
setPasses(state, passes) {
|
||||||
|
state.passes = passes;
|
||||||
|
},
|
||||||
|
setRenderTasks(state, render_tasks) {
|
||||||
|
state.render_tasks = render_tasks;
|
||||||
|
},
|
||||||
|
setDocuments(state, documents) {
|
||||||
|
state.documents = documents;
|
||||||
|
},
|
||||||
|
setClipScrollTree(state, clip_scroll_tree) {
|
||||||
|
state.clip_scroll_tree = clip_scroll_tree;
|
||||||
|
},
|
||||||
|
setScreenshot(state, screenshot) {
|
||||||
|
state.screenshot = screenshot;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
connect(context) {
|
||||||
|
connection.connect(context);
|
||||||
|
},
|
||||||
|
disconnect(context) {
|
||||||
|
connection.disconnect();
|
||||||
|
},
|
||||||
|
sendMessage(context, msg) {
|
||||||
|
connection.send(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default store;
|
81
third_party/webrender/debugger/webpack.config.js
vendored
Normal file
81
third_party/webrender/debugger/webpack.config.js
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
var path = require('path')
|
||||||
|
var webpack = require('webpack')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './src/main.js',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, './dist'),
|
||||||
|
publicPath: '/dist/',
|
||||||
|
filename: 'build.js'
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [
|
||||||
|
'vue-style-loader',
|
||||||
|
'css-loader'
|
||||||
|
],
|
||||||
|
}, {
|
||||||
|
test: /\.vue$/,
|
||||||
|
loader: 'vue-loader',
|
||||||
|
options: {
|
||||||
|
loaders: {
|
||||||
|
}
|
||||||
|
// other vue-loader options go here
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpg|gif|svg)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]?[hash]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'vue$': 'vue/dist/vue.esm.js'
|
||||||
|
},
|
||||||
|
alias : {
|
||||||
|
"icons": path.resolve(__dirname, "node_modules/vue-material-design-icons")
|
||||||
|
},
|
||||||
|
extensions: ['*', '.js', '.vue', '.json']
|
||||||
|
},
|
||||||
|
devServer: {
|
||||||
|
historyApiFallback: true,
|
||||||
|
noInfo: true,
|
||||||
|
overlay: true
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
hints: false
|
||||||
|
},
|
||||||
|
devtool: '#eval-source-map'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
module.exports.devtool = '#source-map'
|
||||||
|
// http://vue-loader.vuejs.org/en/workflow/production.html
|
||||||
|
module.exports.plugins = (module.exports.plugins || []).concat([
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env': {
|
||||||
|
NODE_ENV: '"production"'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
|
sourceMap: true,
|
||||||
|
compress: {
|
||||||
|
warnings: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
14
third_party/webrender/direct-composition/Cargo.toml
vendored
Normal file
14
third_party/webrender/direct-composition/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "direct-composition"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
|
||||||
|
license = "MPL-2.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
euclid = "0.22"
|
||||||
|
gleam = "0.12"
|
||||||
|
mozangle = {version = "0.3.1", features = ["egl"]}
|
||||||
|
webrender = {path = "../webrender"}
|
||||||
|
winapi = {version = "0.3", features = ["winerror", "d3d11", "dcomp"]}
|
||||||
|
winit = "0.19"
|
112
third_party/webrender/direct-composition/src/com.rs
vendored
Normal file
112
third_party/webrender/direct-composition/src/com.rs
vendored
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
use std::ops;
|
||||||
|
use std::ptr;
|
||||||
|
use winapi::Interface;
|
||||||
|
use winapi::ctypes::c_void;
|
||||||
|
use winapi::shared::guiddef::GUID;
|
||||||
|
use winapi::shared::winerror::HRESULT;
|
||||||
|
use winapi::shared::winerror::SUCCEEDED;
|
||||||
|
use winapi::um::unknwnbase::IUnknown;
|
||||||
|
|
||||||
|
pub fn as_ptr<T>(x: &T) -> *mut T {
|
||||||
|
x as *const T as _
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait CheckHResult {
|
||||||
|
fn check_hresult(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CheckHResult for HRESULT {
|
||||||
|
fn check_hresult(self) {
|
||||||
|
if !SUCCEEDED(self) {
|
||||||
|
panic_com(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn panic_com(hresult: HRESULT) -> ! {
|
||||||
|
panic!("COM error 0x{:08X}", hresult as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Forked from <https://github.com/retep998/wio-rs/blob/44093f7db8/src/com.rs>
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub struct ComPtr<T>(*mut T) where T: Interface;
|
||||||
|
|
||||||
|
impl<T> ComPtr<T> where T: Interface {
|
||||||
|
/// Creates a `ComPtr` to wrap a raw pointer.
|
||||||
|
/// It takes ownership over the pointer which means it does __not__ call `AddRef`.
|
||||||
|
/// `T` __must__ be a COM interface that inherits from `IUnknown`.
|
||||||
|
pub unsafe fn from_raw(ptr: *mut T) -> ComPtr<T> {
|
||||||
|
assert!(!ptr.is_null());
|
||||||
|
ComPtr(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For use with APIs that take an interface UUID and
|
||||||
|
/// "return" a new COM object through a `*mut *mut c_void` out-parameter.
|
||||||
|
pub unsafe fn new_with_uuid<F>(f: F) -> Self
|
||||||
|
where F: FnOnce(&GUID, *mut *mut c_void) -> HRESULT
|
||||||
|
{
|
||||||
|
Self::new_with(|ptr| f(&T::uuidof(), ptr as _))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For use with APIs that "return" a new COM object through a `*mut *mut T` out-parameter.
|
||||||
|
pub unsafe fn new_with<F>(f: F) -> Self
|
||||||
|
where F: FnOnce(*mut *mut T) -> HRESULT
|
||||||
|
{
|
||||||
|
let mut ptr = ptr::null_mut();
|
||||||
|
let hresult = f(&mut ptr);
|
||||||
|
if SUCCEEDED(hresult) {
|
||||||
|
ComPtr::from_raw(ptr)
|
||||||
|
} else {
|
||||||
|
if !ptr.is_null() {
|
||||||
|
let ptr = ptr as *mut IUnknown;
|
||||||
|
(*ptr).Release();
|
||||||
|
}
|
||||||
|
panic_com(hresult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_raw(&self) -> *mut T {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_unknown(&self) -> &IUnknown {
|
||||||
|
unsafe {
|
||||||
|
&*(self.0 as *mut IUnknown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs QueryInterface fun.
|
||||||
|
pub fn cast<U>(&self) -> ComPtr<U> where U: Interface {
|
||||||
|
unsafe {
|
||||||
|
ComPtr::<U>::new_with_uuid(|uuid, ptr| self.as_unknown().QueryInterface(uuid, ptr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ops::Deref for ComPtr<T> where T: Interface {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
unsafe { &*self.0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Clone for ComPtr<T> where T: Interface {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
unsafe {
|
||||||
|
self.as_unknown().AddRef();
|
||||||
|
ComPtr(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Drop for ComPtr<T> where T: Interface {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
self.as_unknown().Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
174
third_party/webrender/direct-composition/src/egl.rs
vendored
Normal file
174
third_party/webrender/direct-composition/src/egl.rs
vendored
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
use mozangle::egl::ffi::*;
|
||||||
|
use std::os::raw::c_void;
|
||||||
|
use std::ptr;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use winapi::um::d3d11::ID3D11Device;
|
||||||
|
use winapi::um::d3d11::ID3D11Texture2D;
|
||||||
|
|
||||||
|
pub use mozangle::egl::get_proc_address;
|
||||||
|
|
||||||
|
pub struct SharedEglThings {
|
||||||
|
device: EGLDeviceEXT,
|
||||||
|
display: types::EGLDisplay,
|
||||||
|
config: types::EGLConfig,
|
||||||
|
context: types::EGLContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cast_attributes(slice: &[types::EGLenum]) -> &EGLint {
|
||||||
|
unsafe {
|
||||||
|
&*(slice.as_ptr() as *const EGLint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! attributes {
|
||||||
|
($( $key: expr => $value: expr, )*) => {
|
||||||
|
cast_attributes(&[
|
||||||
|
$( $key, $value, )*
|
||||||
|
NONE,
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SharedEglThings {
|
||||||
|
pub unsafe fn new(d3d_device: *mut ID3D11Device) -> Rc<Self> {
|
||||||
|
let device = eglCreateDeviceANGLE(
|
||||||
|
D3D11_DEVICE_ANGLE,
|
||||||
|
d3d_device as *mut c_void,
|
||||||
|
ptr::null(),
|
||||||
|
).check();
|
||||||
|
let display = GetPlatformDisplayEXT(
|
||||||
|
PLATFORM_DEVICE_EXT,
|
||||||
|
device,
|
||||||
|
attributes! [
|
||||||
|
EXPERIMENTAL_PRESENT_PATH_ANGLE => EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
|
||||||
|
],
|
||||||
|
).check();
|
||||||
|
Initialize(display, ptr::null_mut(), ptr::null_mut()).check();
|
||||||
|
|
||||||
|
// Adapted from
|
||||||
|
// https://searchfox.org/mozilla-central/rev/056a4057/gfx/gl/GLContextProviderEGL.cpp#635
|
||||||
|
let mut configs = [ptr::null(); 64];
|
||||||
|
let mut num_configs = 0;
|
||||||
|
ChooseConfig(
|
||||||
|
display,
|
||||||
|
attributes! [
|
||||||
|
SURFACE_TYPE => WINDOW_BIT,
|
||||||
|
RENDERABLE_TYPE => OPENGL_ES2_BIT,
|
||||||
|
RED_SIZE => 8,
|
||||||
|
GREEN_SIZE => 8,
|
||||||
|
BLUE_SIZE => 8,
|
||||||
|
ALPHA_SIZE => 8,
|
||||||
|
],
|
||||||
|
configs.as_mut_ptr(),
|
||||||
|
configs.len() as i32,
|
||||||
|
&mut num_configs,
|
||||||
|
).check();
|
||||||
|
let config = pick_config(&configs[..num_configs as usize]);
|
||||||
|
|
||||||
|
let context = CreateContext(
|
||||||
|
display, config, NO_CONTEXT,
|
||||||
|
attributes![
|
||||||
|
CONTEXT_CLIENT_VERSION => 3,
|
||||||
|
]
|
||||||
|
).check();
|
||||||
|
MakeCurrent(display, NO_SURFACE, NO_SURFACE, context).check();
|
||||||
|
|
||||||
|
Rc::new(SharedEglThings { device, display, config, context })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pick_config(configs: &[types::EGLConfig]) -> types::EGLConfig {
|
||||||
|
// FIXME: better criteria to make this choice?
|
||||||
|
// Firefox uses GetConfigAttrib to find a config that has the requested r/g/b/a sizes
|
||||||
|
// https://searchfox.org/mozilla-central/rev/056a4057/gfx/gl/GLContextProviderEGL.cpp#662-685
|
||||||
|
|
||||||
|
configs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for SharedEglThings {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
// FIXME does EGLDisplay or EGLConfig need clean up? How?
|
||||||
|
DestroyContext(self.display, self.context).check();
|
||||||
|
eglReleaseDeviceANGLE(self.device).check();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PerVisualEglThings {
|
||||||
|
shared: Rc<SharedEglThings>,
|
||||||
|
surface: types::EGLSurface,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PerVisualEglThings {
|
||||||
|
pub unsafe fn new(shared: Rc<SharedEglThings>, buffer: *const ID3D11Texture2D,
|
||||||
|
width: u32, height: u32)
|
||||||
|
-> Self {
|
||||||
|
let surface = CreatePbufferFromClientBuffer(
|
||||||
|
shared.display,
|
||||||
|
D3D_TEXTURE_ANGLE,
|
||||||
|
buffer as types::EGLClientBuffer,
|
||||||
|
shared.config,
|
||||||
|
attributes! [
|
||||||
|
WIDTH => width,
|
||||||
|
HEIGHT => height,
|
||||||
|
FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE => TRUE,
|
||||||
|
],
|
||||||
|
).check();
|
||||||
|
|
||||||
|
PerVisualEglThings { shared, surface }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_current(&self) {
|
||||||
|
unsafe {
|
||||||
|
MakeCurrent(self.shared.display, self.surface, self.surface, self.shared.context).check();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for PerVisualEglThings {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
DestroySurface(self.shared.display, self.surface).check();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_error() {
|
||||||
|
unsafe {
|
||||||
|
let error = GetError() as types::EGLenum;
|
||||||
|
assert_eq!(error, SUCCESS, "0x{:x} != 0x{:x}", error, SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Check {
|
||||||
|
fn check(self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Check for *const c_void {
|
||||||
|
fn check(self) -> Self {
|
||||||
|
check_error();
|
||||||
|
assert!(!self.is_null());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Check for *mut c_void {
|
||||||
|
fn check(self) -> Self {
|
||||||
|
check_error();
|
||||||
|
assert!(!self.is_null());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Check for types::EGLBoolean {
|
||||||
|
fn check(self) -> Self {
|
||||||
|
check_error();
|
||||||
|
assert_eq!(self, TRUE);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
179
third_party/webrender/direct-composition/src/lib.rs
vendored
Normal file
179
third_party/webrender/direct-composition/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#![cfg(windows)]
|
||||||
|
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate mozangle;
|
||||||
|
extern crate winapi;
|
||||||
|
|
||||||
|
use com::{ComPtr, CheckHResult, as_ptr};
|
||||||
|
use std::ptr;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use winapi::shared::dxgi1_2::DXGI_SWAP_CHAIN_DESC1;
|
||||||
|
use winapi::shared::dxgi1_2::IDXGIFactory2;
|
||||||
|
use winapi::shared::minwindef::{TRUE, FALSE};
|
||||||
|
use winapi::shared::windef::HWND;
|
||||||
|
use winapi::um::d3d11::ID3D11Device;
|
||||||
|
use winapi::um::dcomp::IDCompositionDevice;
|
||||||
|
use winapi::um::dcomp::IDCompositionTarget;
|
||||||
|
use winapi::um::dcomp::IDCompositionVisual;
|
||||||
|
|
||||||
|
mod com;
|
||||||
|
mod egl;
|
||||||
|
|
||||||
|
pub struct DirectComposition {
|
||||||
|
d3d_device: ComPtr<ID3D11Device>,
|
||||||
|
dxgi_factory: ComPtr<IDXGIFactory2>,
|
||||||
|
|
||||||
|
egl: Rc<egl::SharedEglThings>,
|
||||||
|
pub gleam: Rc<dyn gleam::gl::Gl>,
|
||||||
|
|
||||||
|
composition_device: ComPtr<IDCompositionDevice>,
|
||||||
|
root_visual: ComPtr<IDCompositionVisual>,
|
||||||
|
|
||||||
|
#[allow(unused)] // Needs to be kept alive
|
||||||
|
composition_target: ComPtr<IDCompositionTarget>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DirectComposition {
|
||||||
|
/// Initialize DirectComposition in the given window
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `hwnd` must be a valid handle to a window.
|
||||||
|
pub unsafe fn new(hwnd: HWND) -> Self {
|
||||||
|
let d3d_device = ComPtr::new_with(|ptr_ptr| winapi::um::d3d11::D3D11CreateDevice(
|
||||||
|
ptr::null_mut(),
|
||||||
|
winapi::um::d3dcommon::D3D_DRIVER_TYPE_HARDWARE,
|
||||||
|
ptr::null_mut(),
|
||||||
|
winapi::um::d3d11::D3D11_CREATE_DEVICE_BGRA_SUPPORT |
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
winapi::um::d3d11::D3D11_CREATE_DEVICE_DEBUG
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
},
|
||||||
|
ptr::null_mut(),
|
||||||
|
0,
|
||||||
|
winapi::um::d3d11::D3D11_SDK_VERSION,
|
||||||
|
ptr_ptr,
|
||||||
|
&mut 0,
|
||||||
|
ptr::null_mut(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let egl = egl::SharedEglThings::new(d3d_device.as_raw());
|
||||||
|
let gleam = gleam::gl::GlesFns::load_with(egl::get_proc_address);
|
||||||
|
|
||||||
|
let dxgi_device = d3d_device.cast::<winapi::shared::dxgi::IDXGIDevice>();
|
||||||
|
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh404556(v=vs.85).aspx#code-snippet-1
|
||||||
|
// “Because you can create a Direct3D device without creating a swap chain,
|
||||||
|
// you might need to retrieve the factory that is used to create the device
|
||||||
|
// in order to create a swap chain.”
|
||||||
|
let adapter = ComPtr::new_with(|ptr_ptr| dxgi_device.GetAdapter(ptr_ptr));
|
||||||
|
let dxgi_factory = ComPtr::<IDXGIFactory2>::new_with_uuid(|uuid, ptr_ptr| {
|
||||||
|
adapter.GetParent(uuid, ptr_ptr)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create the DirectComposition device object.
|
||||||
|
let composition_device = ComPtr::<IDCompositionDevice>::new_with_uuid(|uuid, ptr_ptr| {
|
||||||
|
winapi::um::dcomp::DCompositionCreateDevice(&*dxgi_device, uuid, ptr_ptr)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create the composition target object based on the
|
||||||
|
// specified application window.
|
||||||
|
let composition_target = ComPtr::new_with(|ptr_ptr| {
|
||||||
|
composition_device.CreateTargetForHwnd(hwnd, TRUE, ptr_ptr)
|
||||||
|
});
|
||||||
|
|
||||||
|
let root_visual = ComPtr::new_with(|ptr_ptr| composition_device.CreateVisual(ptr_ptr));
|
||||||
|
composition_target.SetRoot(&*root_visual).check_hresult();
|
||||||
|
|
||||||
|
DirectComposition {
|
||||||
|
d3d_device, dxgi_factory,
|
||||||
|
egl, gleam,
|
||||||
|
composition_device, composition_target, root_visual,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute changes to the DirectComposition scene.
|
||||||
|
pub fn commit(&self) {
|
||||||
|
unsafe {
|
||||||
|
self.composition_device.Commit().check_hresult()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_angle_visual(&self, width: u32, height: u32) -> AngleVisual {
|
||||||
|
unsafe {
|
||||||
|
let desc = DXGI_SWAP_CHAIN_DESC1 {
|
||||||
|
Width: width,
|
||||||
|
Height: height,
|
||||||
|
Format: winapi::shared::dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
Stereo: FALSE,
|
||||||
|
SampleDesc: winapi::shared::dxgitype::DXGI_SAMPLE_DESC {
|
||||||
|
Count: 1,
|
||||||
|
Quality: 0,
|
||||||
|
},
|
||||||
|
BufferUsage: winapi::shared::dxgitype::DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||||
|
BufferCount: 2,
|
||||||
|
Scaling: winapi::shared::dxgi1_2::DXGI_SCALING_STRETCH,
|
||||||
|
SwapEffect: winapi::shared::dxgi::DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
|
||||||
|
AlphaMode: winapi::shared::dxgi1_2::DXGI_ALPHA_MODE_PREMULTIPLIED,
|
||||||
|
Flags: 0,
|
||||||
|
};
|
||||||
|
let swap_chain = ComPtr::<winapi::shared::dxgi1_2::IDXGISwapChain1>::new_with(|ptr_ptr| {
|
||||||
|
self.dxgi_factory.CreateSwapChainForComposition(
|
||||||
|
as_ptr(&self.d3d_device),
|
||||||
|
&desc,
|
||||||
|
ptr::null_mut(),
|
||||||
|
ptr_ptr,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
let back_buffer = ComPtr::<winapi::um::d3d11::ID3D11Texture2D>::new_with_uuid(|uuid, ptr_ptr| {
|
||||||
|
swap_chain.GetBuffer(0, uuid, ptr_ptr)
|
||||||
|
});
|
||||||
|
let egl = egl::PerVisualEglThings::new(self.egl.clone(), &*back_buffer, width, height);
|
||||||
|
let gleam = self.gleam.clone();
|
||||||
|
|
||||||
|
let visual = ComPtr::new_with(|ptr_ptr| self.composition_device.CreateVisual(ptr_ptr));
|
||||||
|
visual.SetContent(&*****swap_chain).check_hresult();
|
||||||
|
self.root_visual.AddVisual(&*visual, FALSE, ptr::null_mut()).check_hresult();
|
||||||
|
|
||||||
|
AngleVisual { visual, swap_chain, egl, gleam }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A DirectComposition "visual" configured for rendering with Direct3D.
|
||||||
|
pub struct AngleVisual {
|
||||||
|
visual: ComPtr<IDCompositionVisual>,
|
||||||
|
swap_chain: ComPtr<winapi::shared::dxgi1_2::IDXGISwapChain1>,
|
||||||
|
egl: egl::PerVisualEglThings,
|
||||||
|
pub gleam: Rc<dyn gleam::gl::Gl>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AngleVisual {
|
||||||
|
pub fn set_offset_x(&self, offset_x: f32) {
|
||||||
|
unsafe {
|
||||||
|
self.visual.SetOffsetX_1(offset_x).check_hresult()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_offset_y(&self, offset_y: f32) {
|
||||||
|
unsafe {
|
||||||
|
self.visual.SetOffsetY_1(offset_y).check_hresult()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_current(&self) {
|
||||||
|
self.egl.make_current()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn present(&self) {
|
||||||
|
self.gleam.finish();
|
||||||
|
unsafe {
|
||||||
|
self.swap_chain.Present(0, 0).check_hresult()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
third_party/webrender/direct-composition/src/main.rs
vendored
Normal file
11
third_party/webrender/direct-composition/src/main.rs
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn main() {
|
||||||
|
println!("This demo only runs on Windows.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
include!("main_windows.rs");
|
212
third_party/webrender/direct-composition/src/main_windows.rs
vendored
Normal file
212
third_party/webrender/direct-composition/src/main_windows.rs
vendored
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate direct_composition;
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
use euclid::size2;
|
||||||
|
use direct_composition::DirectComposition;
|
||||||
|
use std::sync::mpsc;
|
||||||
|
use webrender::api;
|
||||||
|
use winit::os::windows::{WindowExt, WindowBuilderExt};
|
||||||
|
use winit::dpi::LogicalSize;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut events_loop = winit::EventsLoop::new();
|
||||||
|
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let notifier = Box::new(Notifier { events_proxy: events_loop.create_proxy(), tx });
|
||||||
|
|
||||||
|
let window = winit::WindowBuilder::new()
|
||||||
|
.with_title("WebRender + ANGLE + DirectComposition")
|
||||||
|
.with_dimensions(LogicalSize::new(1024., 768.))
|
||||||
|
.with_decorations(true)
|
||||||
|
.with_transparency(true)
|
||||||
|
.with_no_redirection_bitmap(true)
|
||||||
|
.build(&events_loop)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let composition = direct_composition_from_window(&window);
|
||||||
|
let factor = window.get_hidpi_factor() as f32;
|
||||||
|
|
||||||
|
let mut clicks: usize = 0;
|
||||||
|
let mut offset_y = 100.;
|
||||||
|
let mut rects = [
|
||||||
|
Rectangle::new(&composition, ¬ifier, factor, size2(300, 200), 0., 0.2, 0.4, 1.),
|
||||||
|
Rectangle::new(&composition, ¬ifier, factor, size2(400, 300), 0., 0.5, 0., 0.5),
|
||||||
|
];
|
||||||
|
rects[0].render(factor, &rx);
|
||||||
|
rects[1].render(factor, &rx);
|
||||||
|
|
||||||
|
rects[0].visual.set_offset_x(100.);
|
||||||
|
rects[0].visual.set_offset_y(50.);
|
||||||
|
|
||||||
|
rects[1].visual.set_offset_x(200.);
|
||||||
|
rects[1].visual.set_offset_y(offset_y);
|
||||||
|
|
||||||
|
composition.commit();
|
||||||
|
|
||||||
|
events_loop.run_forever(|event| {
|
||||||
|
if let winit::Event::WindowEvent { event, .. } = event {
|
||||||
|
match event {
|
||||||
|
winit::WindowEvent::CloseRequested => {
|
||||||
|
return winit::ControlFlow::Break
|
||||||
|
}
|
||||||
|
winit::WindowEvent::MouseWheel { delta, .. } => {
|
||||||
|
let dy = match delta {
|
||||||
|
winit::MouseScrollDelta::LineDelta(_, dy) => dy,
|
||||||
|
winit::MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
||||||
|
};
|
||||||
|
offset_y = (offset_y - 10. * dy).max(0.).min(468.);
|
||||||
|
|
||||||
|
rects[1].visual.set_offset_y(offset_y);
|
||||||
|
composition.commit();
|
||||||
|
}
|
||||||
|
winit::WindowEvent::MouseInput {
|
||||||
|
button: winit::MouseButton::Left,
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
clicks += 1;
|
||||||
|
let rect = &mut rects[clicks % 2];
|
||||||
|
rect.color.g += 0.1;
|
||||||
|
rect.color.g %= 1.;
|
||||||
|
rect.render(factor, &rx)
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
winit::ControlFlow::Continue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
|
||||||
|
unsafe {
|
||||||
|
DirectComposition::new(window.get_hwnd() as _)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Rectangle {
|
||||||
|
visual: direct_composition::AngleVisual,
|
||||||
|
renderer: Option<webrender::Renderer>,
|
||||||
|
api: api::RenderApi,
|
||||||
|
document_id: api::DocumentId,
|
||||||
|
size: api::units::DeviceIntSize,
|
||||||
|
color: api::ColorF,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rectangle {
|
||||||
|
fn new(composition: &DirectComposition, notifier: &Box<Notifier>,
|
||||||
|
device_pixel_ratio: f32, size: api::units::DeviceIntSize, r: f32, g: f32, b: f32, a: f32)
|
||||||
|
-> Self {
|
||||||
|
let visual = composition.create_angle_visual(size.width as u32, size.height as u32);
|
||||||
|
visual.make_current();
|
||||||
|
|
||||||
|
let (renderer, sender) = webrender::Renderer::new(
|
||||||
|
composition.gleam.clone(),
|
||||||
|
notifier.clone(),
|
||||||
|
webrender::RendererOptions {
|
||||||
|
clear_color: Some(api::ColorF::new(0., 0., 0., 0.)),
|
||||||
|
device_pixel_ratio,
|
||||||
|
..webrender::RendererOptions::default()
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
size,
|
||||||
|
).unwrap();
|
||||||
|
let api = sender.create_api();
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visual,
|
||||||
|
renderer: Some(renderer),
|
||||||
|
document_id: api.add_document(size, 0),
|
||||||
|
api,
|
||||||
|
size,
|
||||||
|
color: api::ColorF { r, g, b, a },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, device_pixel_ratio: f32, rx: &mpsc::Receiver<()>) {
|
||||||
|
self.visual.make_current();
|
||||||
|
|
||||||
|
let pipeline_id = api::PipelineId(0, 0);
|
||||||
|
let layout_size = self.size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||||
|
let mut builder = api::DisplayListBuilder::new(pipeline_id, layout_size);
|
||||||
|
|
||||||
|
let rect = euclid::Rect::new(euclid::Point2D::zero(), layout_size);
|
||||||
|
|
||||||
|
let region = api::ComplexClipRegion::new(
|
||||||
|
rect,
|
||||||
|
api::BorderRadius::uniform(20.),
|
||||||
|
api::ClipMode::Clip
|
||||||
|
);
|
||||||
|
let clip_id = builder.define_clip_rounded_rect(
|
||||||
|
&api::SpaceAndClipInfo::root_scroll(pipeline_id),
|
||||||
|
region,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_rect(
|
||||||
|
&api::CommonItemProperties::new(
|
||||||
|
rect,
|
||||||
|
api::SpaceAndClipInfo {
|
||||||
|
spatial_id: api::SpatialId::root_scroll_node(pipeline_id),
|
||||||
|
clip_id,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
rect,
|
||||||
|
self.color,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut transaction = api::Transaction::new();
|
||||||
|
transaction.set_display_list(
|
||||||
|
api::Epoch(0),
|
||||||
|
None,
|
||||||
|
layout_size,
|
||||||
|
builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
transaction.set_root_pipeline(pipeline_id);
|
||||||
|
transaction.generate_frame();
|
||||||
|
self.api.send_transaction(self.document_id, transaction);
|
||||||
|
rx.recv().unwrap();
|
||||||
|
let renderer = self.renderer.as_mut().unwrap();
|
||||||
|
renderer.update();
|
||||||
|
renderer.render(self.size).unwrap();
|
||||||
|
let _ = renderer.flush_pipeline_info();
|
||||||
|
self.visual.present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Rectangle {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.renderer.take().unwrap().deinit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Notifier {
|
||||||
|
events_proxy: winit::EventsLoopProxy,
|
||||||
|
tx: mpsc::Sender<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl api::RenderNotifier for Notifier {
|
||||||
|
fn clone(&self) -> Box<dyn api::RenderNotifier> {
|
||||||
|
Box::new(Clone::clone(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake_up(&self) {
|
||||||
|
self.tx.send(()).unwrap();
|
||||||
|
let _ = self.events_proxy.wakeup();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_frame_ready(&self,
|
||||||
|
_: api::DocumentId,
|
||||||
|
_: bool,
|
||||||
|
_: bool,
|
||||||
|
_: Option<u64>) {
|
||||||
|
self.wake_up();
|
||||||
|
}
|
||||||
|
}
|
9
third_party/webrender/example-compositor/compositor-windows/Cargo.toml
vendored
Normal file
9
third_party/webrender/example-compositor/compositor-windows/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "compositor-windows"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cc = "1.0"
|
25
third_party/webrender/example-compositor/compositor-windows/build.rs
vendored
Normal file
25
third_party/webrender/example-compositor/compositor-windows/build.rs
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// HACK - This build script relies on Gecko having been built, so that the ANGLE libraries
|
||||||
|
// have already been compiled. It also assumes they are being built with an in-tree
|
||||||
|
// x86_64 object directory.
|
||||||
|
|
||||||
|
cc::Build::new()
|
||||||
|
.file("src/lib.cpp")
|
||||||
|
.include("../../../angle/checkout/include")
|
||||||
|
.compile("windows");
|
||||||
|
|
||||||
|
// Set up linker paths for ANGLE that is built by Gecko
|
||||||
|
println!("cargo:rustc-link-search=../../obj-x86_64-pc-mingw32/gfx/angle/targets/libEGL");
|
||||||
|
println!("cargo:rustc-link-search=../../obj-x86_64-pc-mingw32/gfx/angle/targets/libGLESv2");
|
||||||
|
|
||||||
|
// Link to libEGL and libGLESv2 (ANGLE) and D3D11 + DirectComposition
|
||||||
|
println!("cargo:rustc-link-lib=libEGL");
|
||||||
|
println!("cargo:rustc-link-lib=libGLESv2");
|
||||||
|
println!("cargo:rustc-link-lib=dcomp");
|
||||||
|
println!("cargo:rustc-link-lib=d3d11");
|
||||||
|
println!("cargo:rustc-link-lib=dwmapi");
|
||||||
|
}
|
802
third_party/webrender/example-compositor/compositor-windows/src/lib.cpp
vendored
Normal file
802
third_party/webrender/example-compositor/compositor-windows/src/lib.cpp
vendored
Normal file
|
@ -0,0 +1,802 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#define UNICODE
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <dcomp.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <dwmapi.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#define EGL_EGL_PROTOTYPES 1
|
||||||
|
#define EGL_EGLEXT_PROTOTYPES 1
|
||||||
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
|
#include "EGL/egl.h"
|
||||||
|
#include "EGL/eglext.h"
|
||||||
|
#include "EGL/eglext_angle.h"
|
||||||
|
#include "GL/gl.h"
|
||||||
|
#include "GLES/gl.h"
|
||||||
|
#include "GLES/glext.h"
|
||||||
|
#include "GLES3/gl3.h"
|
||||||
|
|
||||||
|
#define NUM_QUERIES 2
|
||||||
|
|
||||||
|
#define USE_VIRTUAL_SURFACES
|
||||||
|
#define VIRTUAL_OFFSET 512 * 1024
|
||||||
|
|
||||||
|
enum SyncMode {
|
||||||
|
None = 0,
|
||||||
|
Swap = 1,
|
||||||
|
Commit = 2,
|
||||||
|
Flush = 3,
|
||||||
|
Query = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// The OS compositor representation of a picture cache tile.
|
||||||
|
struct Tile {
|
||||||
|
#ifndef USE_VIRTUAL_SURFACES
|
||||||
|
// Represents the underlying DirectComposition surface texture that gets drawn into.
|
||||||
|
IDCompositionSurface *pSurface;
|
||||||
|
// Represents the node in the visual tree that defines the properties of this tile (clip, position etc).
|
||||||
|
IDCompositionVisual2 *pVisual;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TileKey {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
TileKey(int ax, int ay) : x(ax), y(ay) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const TileKey &k0, const TileKey &k1) {
|
||||||
|
return k0.x == k1.x && k0.y == k1.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TileKeyHasher {
|
||||||
|
size_t operator()(const TileKey &key) const {
|
||||||
|
return key.x ^ key.y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Surface {
|
||||||
|
int tile_width;
|
||||||
|
int tile_height;
|
||||||
|
bool is_opaque;
|
||||||
|
std::unordered_map<TileKey, Tile, TileKeyHasher> tiles;
|
||||||
|
IDCompositionVisual2 *pVisual;
|
||||||
|
#ifdef USE_VIRTUAL_SURFACES
|
||||||
|
IDCompositionVirtualSurface *pVirtualSurface;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CachedFrameBuffer {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
GLuint fboId;
|
||||||
|
GLuint depthRboId;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Window {
|
||||||
|
// Win32 window details
|
||||||
|
HWND hWnd;
|
||||||
|
HINSTANCE hInstance;
|
||||||
|
bool enable_compositor;
|
||||||
|
RECT client_rect;
|
||||||
|
SyncMode sync_mode;
|
||||||
|
|
||||||
|
// Main interfaces to D3D11 and DirectComposition
|
||||||
|
ID3D11Device *pD3D11Device;
|
||||||
|
IDCompositionDesktopDevice *pDCompDevice;
|
||||||
|
IDCompositionTarget *pDCompTarget;
|
||||||
|
IDXGIDevice *pDXGIDevice;
|
||||||
|
ID3D11Query *pQueries[NUM_QUERIES];
|
||||||
|
int current_query;
|
||||||
|
|
||||||
|
// ANGLE interfaces that wrap the D3D device
|
||||||
|
EGLDeviceEXT EGLDevice;
|
||||||
|
EGLDisplay EGLDisplay;
|
||||||
|
EGLContext EGLContext;
|
||||||
|
EGLConfig config;
|
||||||
|
// Framebuffer surface for debug mode when we are not using DC
|
||||||
|
EGLSurface fb_surface;
|
||||||
|
|
||||||
|
// The currently bound surface, valid during bind() and unbind()
|
||||||
|
IDCompositionSurface *pCurrentSurface;
|
||||||
|
EGLImage mEGLImage;
|
||||||
|
GLuint mColorRBO;
|
||||||
|
|
||||||
|
// The root of the DC visual tree. Nothing is drawn on this, but
|
||||||
|
// all child tiles are parented to here.
|
||||||
|
IDCompositionVisual2 *pRoot;
|
||||||
|
IDCompositionVisualDebug *pVisualDebug;
|
||||||
|
std::vector<CachedFrameBuffer> mFrameBuffers;
|
||||||
|
|
||||||
|
// Maintain list of layer state between frames to avoid visual tree rebuild.
|
||||||
|
std::vector<uint64_t> mCurrentLayers;
|
||||||
|
std::vector<uint64_t> mPrevLayers;
|
||||||
|
|
||||||
|
// Maps WR surface IDs to each OS surface
|
||||||
|
std::unordered_map<uint64_t, Surface> surfaces;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const wchar_t *CLASS_NAME = L"WR DirectComposite";
|
||||||
|
|
||||||
|
static GLuint GetOrCreateFbo(Window *window, int aWidth, int aHeight) {
|
||||||
|
GLuint fboId = 0;
|
||||||
|
|
||||||
|
// Check if we have a cached FBO with matching dimensions
|
||||||
|
for (auto it = window->mFrameBuffers.begin(); it != window->mFrameBuffers.end(); ++it) {
|
||||||
|
if (it->width == aWidth && it->height == aHeight) {
|
||||||
|
fboId = it->fboId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not, create a new FBO with attached depth buffer
|
||||||
|
if (fboId == 0) {
|
||||||
|
// Create the depth buffer
|
||||||
|
GLuint depthRboId;
|
||||||
|
glGenRenderbuffers(1, &depthRboId);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, depthRboId);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
|
||||||
|
aWidth, aHeight);
|
||||||
|
|
||||||
|
// Create the framebuffer and attach the depth buffer to it
|
||||||
|
glGenFramebuffers(1, &fboId);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
|
||||||
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
|
||||||
|
GL_DEPTH_ATTACHMENT,
|
||||||
|
GL_RENDERBUFFER, depthRboId);
|
||||||
|
|
||||||
|
// Store this in the cache for future calls.
|
||||||
|
CachedFrameBuffer frame_buffer_info;
|
||||||
|
frame_buffer_info.width = aWidth;
|
||||||
|
frame_buffer_info.height = aHeight;
|
||||||
|
frame_buffer_info.fboId = fboId;
|
||||||
|
frame_buffer_info.depthRboId = depthRboId;
|
||||||
|
window->mFrameBuffers.push_back(frame_buffer_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fboId;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK WndProc(
|
||||||
|
HWND hwnd,
|
||||||
|
UINT message,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam
|
||||||
|
) {
|
||||||
|
switch (message) {
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
Window *com_dc_create_window(int width, int height, bool enable_compositor, SyncMode sync_mode) {
|
||||||
|
// Create a simple Win32 window
|
||||||
|
Window *window = new Window;
|
||||||
|
window->hInstance = GetModuleHandle(NULL);
|
||||||
|
window->enable_compositor = enable_compositor;
|
||||||
|
window->mEGLImage = EGL_NO_IMAGE;
|
||||||
|
window->sync_mode = sync_mode;
|
||||||
|
|
||||||
|
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
|
||||||
|
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wcex.lpfnWndProc = WndProc;
|
||||||
|
wcex.cbClsExtra = 0;
|
||||||
|
wcex.cbWndExtra = 0;
|
||||||
|
wcex.hInstance = window->hInstance;
|
||||||
|
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);;
|
||||||
|
wcex.lpszMenuName = nullptr;
|
||||||
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wcex.lpszClassName = CLASS_NAME;
|
||||||
|
RegisterClassEx(&wcex);
|
||||||
|
|
||||||
|
int dpiX = 0;
|
||||||
|
int dpiY = 0;
|
||||||
|
HDC hdc = GetDC(NULL);
|
||||||
|
if (hdc) {
|
||||||
|
dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||||
|
dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||||
|
ReleaseDC(NULL, hdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT window_rect = { 0, 0, width, height };
|
||||||
|
AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
|
UINT window_width = static_cast<UINT>(ceil(float(window_rect.right - window_rect.left) * dpiX / 96.f));
|
||||||
|
UINT window_height = static_cast<UINT>(ceil(float(window_rect.bottom - window_rect.top) * dpiY / 96.f));
|
||||||
|
|
||||||
|
LPCWSTR name;
|
||||||
|
DWORD style;
|
||||||
|
if (enable_compositor) {
|
||||||
|
name = L"example-compositor (DirectComposition)";
|
||||||
|
style = WS_EX_NOREDIRECTIONBITMAP;
|
||||||
|
} else {
|
||||||
|
name = L"example-compositor (Simple)";
|
||||||
|
style = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->hWnd = CreateWindowEx(
|
||||||
|
style,
|
||||||
|
CLASS_NAME,
|
||||||
|
name,
|
||||||
|
WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
window_width,
|
||||||
|
window_height,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
window->hInstance,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
ShowWindow(window->hWnd, SW_SHOWNORMAL);
|
||||||
|
UpdateWindow(window->hWnd);
|
||||||
|
GetClientRect(window->hWnd, &window->client_rect);
|
||||||
|
|
||||||
|
// Create a D3D11 device
|
||||||
|
D3D_FEATURE_LEVEL featureLevelSupported;
|
||||||
|
HRESULT hr = D3D11CreateDevice(
|
||||||
|
nullptr,
|
||||||
|
D3D_DRIVER_TYPE_HARDWARE,
|
||||||
|
NULL,
|
||||||
|
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
D3D11_SDK_VERSION,
|
||||||
|
&window->pD3D11Device,
|
||||||
|
&featureLevelSupported,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
D3D11_QUERY_DESC query_desc;
|
||||||
|
memset(&query_desc, 0, sizeof(query_desc));
|
||||||
|
query_desc.Query = D3D11_QUERY_EVENT;
|
||||||
|
for (int i=0 ; i < NUM_QUERIES ; ++i) {
|
||||||
|
hr = window->pD3D11Device->CreateQuery(&query_desc, &window->pQueries[i]);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
}
|
||||||
|
window->current_query = 0;
|
||||||
|
|
||||||
|
hr = window->pD3D11Device->QueryInterface(&window->pDXGIDevice);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Create a DirectComposition device
|
||||||
|
hr = DCompositionCreateDevice2(
|
||||||
|
window->pDXGIDevice,
|
||||||
|
__uuidof(IDCompositionDesktopDevice),
|
||||||
|
(void **) &window->pDCompDevice
|
||||||
|
);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Create a DirectComposition target for a Win32 window handle
|
||||||
|
hr = window->pDCompDevice->CreateTargetForHwnd(
|
||||||
|
window->hWnd,
|
||||||
|
TRUE,
|
||||||
|
&window->pDCompTarget
|
||||||
|
);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Create an ANGLE EGL device that wraps D3D11
|
||||||
|
window->EGLDevice = eglCreateDeviceANGLE(
|
||||||
|
EGL_D3D11_DEVICE_ANGLE,
|
||||||
|
window->pD3D11Device,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
EGLint display_attribs[] = {
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
window->EGLDisplay = eglGetPlatformDisplayEXT(
|
||||||
|
EGL_PLATFORM_DEVICE_EXT,
|
||||||
|
window->EGLDevice,
|
||||||
|
display_attribs
|
||||||
|
);
|
||||||
|
|
||||||
|
eglInitialize(
|
||||||
|
window->EGLDisplay,
|
||||||
|
nullptr,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
EGLint num_configs = 0;
|
||||||
|
EGLint cfg_attribs[] = {
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
EGL_DEPTH_SIZE, 24,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
EGLConfig configs[32];
|
||||||
|
|
||||||
|
eglChooseConfig(
|
||||||
|
window->EGLDisplay,
|
||||||
|
cfg_attribs,
|
||||||
|
configs,
|
||||||
|
sizeof(configs) / sizeof(EGLConfig),
|
||||||
|
&num_configs
|
||||||
|
);
|
||||||
|
assert(num_configs > 0);
|
||||||
|
window->config = configs[0];
|
||||||
|
|
||||||
|
if (window->enable_compositor) {
|
||||||
|
window->fb_surface = EGL_NO_SURFACE;
|
||||||
|
} else {
|
||||||
|
window->fb_surface = eglCreateWindowSurface(
|
||||||
|
window->EGLDisplay,
|
||||||
|
window->config,
|
||||||
|
window->hWnd,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
assert(window->fb_surface != EGL_NO_SURFACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLint ctx_attribs[] = {
|
||||||
|
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an EGL context that can be used for drawing
|
||||||
|
window->EGLContext = eglCreateContext(
|
||||||
|
window->EGLDisplay,
|
||||||
|
window->config,
|
||||||
|
EGL_NO_CONTEXT,
|
||||||
|
ctx_attribs
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create the root of the DirectComposition visual tree
|
||||||
|
hr = window->pDCompDevice->CreateVisual(&window->pRoot);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
hr = window->pDCompTarget->SetRoot(window->pRoot);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
hr = window->pRoot->QueryInterface(
|
||||||
|
__uuidof(IDCompositionVisualDebug),
|
||||||
|
(void **) &window->pVisualDebug
|
||||||
|
);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Uncomment this to see redraw regions during composite
|
||||||
|
// window->pVisualDebug->EnableRedrawRegions();
|
||||||
|
|
||||||
|
EGLBoolean ok = eglMakeCurrent(
|
||||||
|
window->EGLDisplay,
|
||||||
|
window->fb_surface,
|
||||||
|
window->fb_surface,
|
||||||
|
window->EGLContext
|
||||||
|
);
|
||||||
|
assert(ok);
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void com_dc_destroy_window(Window *window) {
|
||||||
|
for (auto surface_it=window->surfaces.begin() ; surface_it != window->surfaces.end() ; ++surface_it) {
|
||||||
|
Surface &surface = surface_it->second;
|
||||||
|
|
||||||
|
#ifndef USE_VIRTUAL_SURFACES
|
||||||
|
for (auto tile_it=surface.tiles.begin() ; tile_it != surface.tiles.end() ; ++tile_it) {
|
||||||
|
tile_it->second.pSurface->Release();
|
||||||
|
tile_it->second.pVisual->Release();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
surface.pVisual->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->fb_surface != EGL_NO_SURFACE) {
|
||||||
|
eglDestroySurface(window->EGLDisplay, window->fb_surface);
|
||||||
|
}
|
||||||
|
eglDestroyContext(window->EGLDisplay, window->EGLContext);
|
||||||
|
eglTerminate(window->EGLDisplay);
|
||||||
|
eglReleaseDeviceANGLE(window->EGLDevice);
|
||||||
|
|
||||||
|
for (int i=0 ; i < NUM_QUERIES ; ++i) {
|
||||||
|
window->pQueries[i]->Release();
|
||||||
|
}
|
||||||
|
window->pRoot->Release();
|
||||||
|
window->pVisualDebug->Release();
|
||||||
|
window->pD3D11Device->Release();
|
||||||
|
window->pDXGIDevice->Release();
|
||||||
|
window->pDCompDevice->Release();
|
||||||
|
window->pDCompTarget->Release();
|
||||||
|
|
||||||
|
CloseWindow(window->hWnd);
|
||||||
|
UnregisterClass(CLASS_NAME, window->hInstance);
|
||||||
|
|
||||||
|
delete window;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool com_dc_tick(Window *) {
|
||||||
|
// Check and dispatch the windows event loop
|
||||||
|
MSG msg;
|
||||||
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
if (msg.message == WM_QUIT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void com_dc_swap_buffers(Window *window) {
|
||||||
|
// If not using DC mode, then do a normal EGL swap buffers.
|
||||||
|
if (window->fb_surface != EGL_NO_SURFACE) {
|
||||||
|
switch (window->sync_mode) {
|
||||||
|
case SyncMode::None:
|
||||||
|
eglSwapInterval(window->EGLDisplay, 0);
|
||||||
|
break;
|
||||||
|
case SyncMode::Swap:
|
||||||
|
eglSwapInterval(window->EGLDisplay, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false); // unexpected vsync mode for simple compositor.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
eglSwapBuffers(window->EGLDisplay, window->fb_surface);
|
||||||
|
} else {
|
||||||
|
switch (window->sync_mode) {
|
||||||
|
case SyncMode::None:
|
||||||
|
break;
|
||||||
|
case SyncMode::Commit:
|
||||||
|
window->pDCompDevice->WaitForCommitCompletion();
|
||||||
|
break;
|
||||||
|
case SyncMode::Flush:
|
||||||
|
DwmFlush();
|
||||||
|
break;
|
||||||
|
case SyncMode::Query:
|
||||||
|
// todo!!!!
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false); // unexpected vsync mode for native compositor
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new DC surface
|
||||||
|
void com_dc_create_surface(
|
||||||
|
Window *window,
|
||||||
|
uint64_t id,
|
||||||
|
int tile_width,
|
||||||
|
int tile_height,
|
||||||
|
bool is_opaque
|
||||||
|
) {
|
||||||
|
assert(window->surfaces.count(id) == 0);
|
||||||
|
|
||||||
|
Surface surface;
|
||||||
|
surface.tile_width = tile_width;
|
||||||
|
surface.tile_height = tile_height;
|
||||||
|
surface.is_opaque = is_opaque;
|
||||||
|
|
||||||
|
// Create the visual node in the DC tree that stores properties
|
||||||
|
HRESULT hr = window->pDCompDevice->CreateVisual(&surface.pVisual);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
#ifdef USE_VIRTUAL_SURFACES
|
||||||
|
DXGI_ALPHA_MODE alpha_mode = surface.is_opaque ? DXGI_ALPHA_MODE_IGNORE : DXGI_ALPHA_MODE_PREMULTIPLIED;
|
||||||
|
|
||||||
|
hr = window->pDCompDevice->CreateVirtualSurface(
|
||||||
|
VIRTUAL_OFFSET * 2,
|
||||||
|
VIRTUAL_OFFSET * 2,
|
||||||
|
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
alpha_mode,
|
||||||
|
&surface.pVirtualSurface
|
||||||
|
);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Bind the surface memory to this visual
|
||||||
|
hr = surface.pVisual->SetContent(surface.pVirtualSurface);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
window->surfaces[id] = surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void com_dc_create_tile(
|
||||||
|
Window *window,
|
||||||
|
uint64_t id,
|
||||||
|
int x,
|
||||||
|
int y
|
||||||
|
) {
|
||||||
|
assert(window->surfaces.count(id) == 1);
|
||||||
|
Surface &surface = window->surfaces[id];
|
||||||
|
|
||||||
|
TileKey key(x, y);
|
||||||
|
assert(surface.tiles.count(key) == 0);
|
||||||
|
|
||||||
|
Tile tile;
|
||||||
|
|
||||||
|
#ifndef USE_VIRTUAL_SURFACES
|
||||||
|
// Create the video memory surface.
|
||||||
|
DXGI_ALPHA_MODE alpha_mode = surface.is_opaque ? DXGI_ALPHA_MODE_IGNORE : DXGI_ALPHA_MODE_PREMULTIPLIED;
|
||||||
|
HRESULT hr = window->pDCompDevice->CreateSurface(
|
||||||
|
surface.tile_width,
|
||||||
|
surface.tile_height,
|
||||||
|
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
|
alpha_mode,
|
||||||
|
&tile.pSurface
|
||||||
|
);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Create the visual node in the DC tree that stores properties
|
||||||
|
hr = window->pDCompDevice->CreateVisual(&tile.pVisual);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Bind the surface memory to this visual
|
||||||
|
hr = tile.pVisual->SetContent(tile.pSurface);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// Place the visual in local-space of this surface
|
||||||
|
float offset_x = (float) (x * surface.tile_width);
|
||||||
|
float offset_y = (float) (y * surface.tile_height);
|
||||||
|
tile.pVisual->SetOffsetX(offset_x);
|
||||||
|
tile.pVisual->SetOffsetY(offset_y);
|
||||||
|
|
||||||
|
surface.pVisual->AddVisual(
|
||||||
|
tile.pVisual,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
surface.tiles[key] = tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void com_dc_destroy_tile(
|
||||||
|
Window *window,
|
||||||
|
uint64_t id,
|
||||||
|
int x,
|
||||||
|
int y
|
||||||
|
) {
|
||||||
|
assert(window->surfaces.count(id) == 1);
|
||||||
|
Surface &surface = window->surfaces[id];
|
||||||
|
|
||||||
|
TileKey key(x, y);
|
||||||
|
assert(surface.tiles.count(key) == 1);
|
||||||
|
Tile &tile = surface.tiles[key];
|
||||||
|
|
||||||
|
#ifndef USE_VIRTUAL_SURFACES
|
||||||
|
surface.pVisual->RemoveVisual(tile.pVisual);
|
||||||
|
|
||||||
|
tile.pVisual->Release();
|
||||||
|
tile.pSurface->Release();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
surface.tiles.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void com_dc_destroy_surface(
|
||||||
|
Window *window,
|
||||||
|
uint64_t id
|
||||||
|
) {
|
||||||
|
assert(window->surfaces.count(id) == 1);
|
||||||
|
Surface &surface = window->surfaces[id];
|
||||||
|
|
||||||
|
window->pRoot->RemoveVisual(surface.pVisual);
|
||||||
|
|
||||||
|
#ifdef USE_VIRTUAL_SURFACES
|
||||||
|
surface.pVirtualSurface->Release();
|
||||||
|
#else
|
||||||
|
// Release the video memory and visual in the tree
|
||||||
|
for (auto tile_it=surface.tiles.begin() ; tile_it != surface.tiles.end() ; ++tile_it) {
|
||||||
|
tile_it->second.pSurface->Release();
|
||||||
|
tile_it->second.pVisual->Release();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
surface.pVisual->Release();
|
||||||
|
window->surfaces.erase(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind a DC surface to allow issuing GL commands to it
|
||||||
|
GLuint com_dc_bind_surface(
|
||||||
|
Window *window,
|
||||||
|
uint64_t surface_id,
|
||||||
|
int tile_x,
|
||||||
|
int tile_y,
|
||||||
|
int *x_offset,
|
||||||
|
int *y_offset,
|
||||||
|
int dirty_x0,
|
||||||
|
int dirty_y0,
|
||||||
|
int dirty_width,
|
||||||
|
int dirty_height
|
||||||
|
) {
|
||||||
|
assert(window->surfaces.count(surface_id) == 1);
|
||||||
|
Surface &surface = window->surfaces[surface_id];
|
||||||
|
|
||||||
|
TileKey key(tile_x, tile_y);
|
||||||
|
assert(surface.tiles.count(key) == 1);
|
||||||
|
Tile &tile = surface.tiles[key];
|
||||||
|
|
||||||
|
// Inform DC that we want to draw on this surface. DC uses texture
|
||||||
|
// atlases when the tiles are small. It returns an offset where the
|
||||||
|
// client code must draw into this surface when this happens.
|
||||||
|
RECT update_rect;
|
||||||
|
update_rect.left = dirty_x0;
|
||||||
|
update_rect.top = dirty_y0;
|
||||||
|
update_rect.right = dirty_x0 + dirty_width;
|
||||||
|
update_rect.bottom = dirty_y0 + dirty_height;
|
||||||
|
POINT offset;
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
ID3D11Texture2D *pTexture;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
// Store the current surface for unbinding later
|
||||||
|
#ifdef USE_VIRTUAL_SURFACES
|
||||||
|
LONG tile_offset_x = VIRTUAL_OFFSET + tile_x * surface.tile_width;
|
||||||
|
LONG tile_offset_y = VIRTUAL_OFFSET + tile_y * surface.tile_height;
|
||||||
|
|
||||||
|
update_rect.left += tile_offset_x;
|
||||||
|
update_rect.top += tile_offset_y;
|
||||||
|
update_rect.right += tile_offset_x;
|
||||||
|
update_rect.bottom += tile_offset_y;
|
||||||
|
|
||||||
|
hr = surface.pVirtualSurface->BeginDraw(
|
||||||
|
&update_rect,
|
||||||
|
__uuidof(ID3D11Texture2D),
|
||||||
|
(void **) &pTexture,
|
||||||
|
&offset
|
||||||
|
);
|
||||||
|
window->pCurrentSurface = surface.pVirtualSurface;
|
||||||
|
#else
|
||||||
|
hr = tile.pSurface->BeginDraw(
|
||||||
|
&update_rect,
|
||||||
|
__uuidof(ID3D11Texture2D),
|
||||||
|
(void **) &pTexture,
|
||||||
|
&offset
|
||||||
|
);
|
||||||
|
window->pCurrentSurface = tile.pSurface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DC includes the origin of the dirty / update rect in the draw offset,
|
||||||
|
// undo that here since WR expects it to be an absolute offset.
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
offset.x -= dirty_x0;
|
||||||
|
offset.y -= dirty_y0;
|
||||||
|
pTexture->GetDesc(&desc);
|
||||||
|
*x_offset = offset.x;
|
||||||
|
*y_offset = offset.y;
|
||||||
|
|
||||||
|
// Construct an EGLImage wrapper around the D3D texture for ANGLE.
|
||||||
|
const EGLAttrib attribs[] = { EGL_NONE };
|
||||||
|
window->mEGLImage = eglCreateImage(
|
||||||
|
window->EGLDisplay,
|
||||||
|
EGL_NO_CONTEXT,
|
||||||
|
EGL_D3D11_TEXTURE_ANGLE,
|
||||||
|
static_cast<EGLClientBuffer>(pTexture),
|
||||||
|
attribs
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the current FBO and RBO id, so we can restore them later
|
||||||
|
GLint currentFboId, currentRboId;
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤tFboId);
|
||||||
|
glGetIntegerv(GL_RENDERBUFFER_BINDING, ¤tRboId);
|
||||||
|
|
||||||
|
// Create a render buffer object that is backed by the EGL image.
|
||||||
|
glGenRenderbuffers(1, &window->mColorRBO);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, window->mColorRBO);
|
||||||
|
glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, window->mEGLImage);
|
||||||
|
|
||||||
|
// Get or create an FBO for the specified dimensions
|
||||||
|
GLuint fboId = GetOrCreateFbo(window, desc.Width, desc.Height);
|
||||||
|
|
||||||
|
// Attach the new renderbuffer to the FBO
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
|
||||||
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
|
||||||
|
GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_RENDERBUFFER,
|
||||||
|
window->mColorRBO);
|
||||||
|
|
||||||
|
// Restore previous FBO and RBO bindings
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFboId);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, currentRboId);
|
||||||
|
|
||||||
|
return fboId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind a currently bound DC surface
|
||||||
|
void com_dc_unbind_surface(Window *window) {
|
||||||
|
HRESULT hr = window->pCurrentSurface->EndDraw();
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
glDeleteRenderbuffers(1, &window->mColorRBO);
|
||||||
|
window->mColorRBO = 0;
|
||||||
|
|
||||||
|
eglDestroyImage(window->EGLDisplay, window->mEGLImage);
|
||||||
|
window->mEGLImage = EGL_NO_IMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void com_dc_begin_transaction(Window *) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a DC surface to the visual tree. Called per-frame to build the composition.
|
||||||
|
void com_dc_add_surface(
|
||||||
|
Window *window,
|
||||||
|
uint64_t id,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int clip_x,
|
||||||
|
int clip_y,
|
||||||
|
int clip_w,
|
||||||
|
int clip_h
|
||||||
|
) {
|
||||||
|
Surface surface = window->surfaces[id];
|
||||||
|
window->mCurrentLayers.push_back(id);
|
||||||
|
|
||||||
|
// Place the visual - this changes frame to frame based on scroll position
|
||||||
|
// of the slice.
|
||||||
|
float offset_x = (float) (x + window->client_rect.left);
|
||||||
|
float offset_y = (float) (y + window->client_rect.top);
|
||||||
|
#ifdef USE_VIRTUAL_SURFACES
|
||||||
|
offset_x -= VIRTUAL_OFFSET;
|
||||||
|
offset_y -= VIRTUAL_OFFSET;
|
||||||
|
#endif
|
||||||
|
surface.pVisual->SetOffsetX(offset_x);
|
||||||
|
surface.pVisual->SetOffsetY(offset_y);
|
||||||
|
|
||||||
|
// Set the clip rect - converting from world space to the pre-offset space
|
||||||
|
// that DC requires for rectangle clips.
|
||||||
|
D2D_RECT_F clip_rect;
|
||||||
|
clip_rect.left = clip_x - offset_x;
|
||||||
|
clip_rect.top = clip_y - offset_y;
|
||||||
|
clip_rect.right = clip_rect.left + clip_w;
|
||||||
|
clip_rect.bottom = clip_rect.top + clip_h;
|
||||||
|
surface.pVisual->SetClip(clip_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish the composition transaction, telling DC to composite
|
||||||
|
void com_dc_end_transaction(Window *window) {
|
||||||
|
bool same = window->mPrevLayers == window->mCurrentLayers;
|
||||||
|
|
||||||
|
if (!same) {
|
||||||
|
HRESULT hr = window->pRoot->RemoveAllVisuals();
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
for (auto it = window->mCurrentLayers.begin(); it != window->mCurrentLayers.end(); ++it) {
|
||||||
|
Surface &surface = window->surfaces[*it];
|
||||||
|
|
||||||
|
// Add this visual as the last element in the visual tree (z-order is implicit,
|
||||||
|
// based on the order tiles are added).
|
||||||
|
hr = window->pRoot->AddVisual(
|
||||||
|
surface.pVisual,
|
||||||
|
FALSE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window->mPrevLayers.swap(window->mCurrentLayers);
|
||||||
|
window->mCurrentLayers.clear();
|
||||||
|
|
||||||
|
HRESULT hr = window->pDCompDevice->Commit();
|
||||||
|
assert(SUCCEEDED(hr));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a pointer to an EGL symbol
|
||||||
|
void *com_dc_get_proc_address(const char *name) {
|
||||||
|
return eglGetProcAddress(name);
|
||||||
|
}
|
||||||
|
}
|
261
third_party/webrender/example-compositor/compositor-windows/src/lib.rs
vendored
Normal file
261
third_party/webrender/example-compositor/compositor-windows/src/lib.rs
vendored
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
use std::os::raw::{c_void, c_char};
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This is a very simple (and unsafe!) rust wrapper for the DirectComposite / D3D11 / ANGLE
|
||||||
|
implementation in lib.cpp.
|
||||||
|
|
||||||
|
It just proxies the calls from the Compositor impl to the C99 code. This is very
|
||||||
|
hacky and not suitable for production!
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Opaque wrapper for the Window type in lib.cpp
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Window {
|
||||||
|
_unused: [u8; 0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// C99 functions that do the compositor work
|
||||||
|
extern {
|
||||||
|
fn com_dc_create_window(
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
enable_compositor: bool,
|
||||||
|
sync_mode: i32,
|
||||||
|
) -> *mut Window;
|
||||||
|
fn com_dc_destroy_window(window: *mut Window);
|
||||||
|
fn com_dc_tick(window: *mut Window) -> bool;
|
||||||
|
fn com_dc_get_proc_address(name: *const c_char) -> *const c_void;
|
||||||
|
fn com_dc_swap_buffers(window: *mut Window);
|
||||||
|
|
||||||
|
fn com_dc_create_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
tile_width: i32,
|
||||||
|
tile_height: i32,
|
||||||
|
is_opaque: bool,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn com_dc_create_tile(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn com_dc_destroy_tile(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn com_dc_destroy_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn com_dc_bind_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
surface_id: u64,
|
||||||
|
tile_x: i32,
|
||||||
|
tile_y: i32,
|
||||||
|
x_offset: &mut i32,
|
||||||
|
y_offset: &mut i32,
|
||||||
|
dirty_x0: i32,
|
||||||
|
dirty_y0: i32,
|
||||||
|
dirty_width: i32,
|
||||||
|
dirty_height: i32,
|
||||||
|
) -> u32;
|
||||||
|
fn com_dc_unbind_surface(window: *mut Window);
|
||||||
|
|
||||||
|
fn com_dc_begin_transaction(window: *mut Window);
|
||||||
|
|
||||||
|
fn com_dc_add_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
clip_x: i32,
|
||||||
|
clip_y: i32,
|
||||||
|
clip_w: i32,
|
||||||
|
clip_h: i32,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn com_dc_end_transaction(window: *mut Window);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_window(
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
enable_compositor: bool,
|
||||||
|
sync_mode: i32,
|
||||||
|
) -> *mut Window {
|
||||||
|
unsafe {
|
||||||
|
com_dc_create_window(width, height, enable_compositor, sync_mode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy_window(window: *mut Window) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_destroy_window(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick(window: *mut Window) -> bool {
|
||||||
|
unsafe {
|
||||||
|
com_dc_tick(window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_proc_address(name: *const c_char) -> *const c_void {
|
||||||
|
unsafe {
|
||||||
|
com_dc_get_proc_address(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
tile_width: i32,
|
||||||
|
tile_height: i32,
|
||||||
|
is_opaque: bool,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_create_surface(
|
||||||
|
window,
|
||||||
|
id,
|
||||||
|
tile_width,
|
||||||
|
tile_height,
|
||||||
|
is_opaque,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_tile(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_create_tile(
|
||||||
|
window,
|
||||||
|
id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy_tile(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_destroy_tile(
|
||||||
|
window,
|
||||||
|
id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_destroy_surface(
|
||||||
|
window,
|
||||||
|
id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
surface_id: u64,
|
||||||
|
tile_x: i32,
|
||||||
|
tile_y: i32,
|
||||||
|
dirty_x0: i32,
|
||||||
|
dirty_y0: i32,
|
||||||
|
dirty_width: i32,
|
||||||
|
dirty_height: i32,
|
||||||
|
) -> (u32, i32, i32) {
|
||||||
|
unsafe {
|
||||||
|
let mut x_offset = 0;
|
||||||
|
let mut y_offset = 0;
|
||||||
|
|
||||||
|
let fbo_id = com_dc_bind_surface(
|
||||||
|
window,
|
||||||
|
surface_id,
|
||||||
|
tile_x,
|
||||||
|
tile_y,
|
||||||
|
&mut x_offset,
|
||||||
|
&mut y_offset,
|
||||||
|
dirty_x0,
|
||||||
|
dirty_y0,
|
||||||
|
dirty_width,
|
||||||
|
dirty_height,
|
||||||
|
);
|
||||||
|
|
||||||
|
(fbo_id, x_offset, y_offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_surface(
|
||||||
|
window: *mut Window,
|
||||||
|
id: u64,
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
clip_x: i32,
|
||||||
|
clip_y: i32,
|
||||||
|
clip_w: i32,
|
||||||
|
clip_h: i32,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_add_surface(
|
||||||
|
window,
|
||||||
|
id,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
clip_x,
|
||||||
|
clip_y,
|
||||||
|
clip_w,
|
||||||
|
clip_h,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn begin_transaction(window: *mut Window) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_begin_transaction(window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbind_surface(window: *mut Window) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_unbind_surface(window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end_transaction(window: *mut Window) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_end_transaction(window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn swap_buffers(window: *mut Window) {
|
||||||
|
unsafe {
|
||||||
|
com_dc_swap_buffers(window);
|
||||||
|
}
|
||||||
|
}
|
13
third_party/webrender/example-compositor/compositor/Cargo.toml
vendored
Normal file
13
third_party/webrender/example-compositor/compositor/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "compositor"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
webrender = { path = "../../webrender" }
|
||||||
|
gleam = "0.12.0"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
compositor-windows = { path = "../compositor-windows" }
|
484
third_party/webrender/example-compositor/compositor/src/main.rs
vendored
Normal file
484
third_party/webrender/example-compositor/compositor/src/main.rs
vendored
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
An example of how to implement the Compositor trait that
|
||||||
|
allows picture caching surfaces to be composited by the operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
The current example supports DirectComposite on Windows only.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
use euclid::Angle;
|
||||||
|
use gleam::gl;
|
||||||
|
use std::ffi::CString;
|
||||||
|
use std::sync::mpsc;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use compositor_windows as compositor;
|
||||||
|
use std::{env, f32, process};
|
||||||
|
|
||||||
|
// A very hacky integration with DirectComposite. It proxies calls from the compositor
|
||||||
|
// interface to a simple C99 library which does the DirectComposition / D3D11 / ANGLE
|
||||||
|
// interfacing. This is a very unsafe impl due to the way the window pointer is passed
|
||||||
|
// around!
|
||||||
|
struct DirectCompositeInterface {
|
||||||
|
window: *mut compositor::Window,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DirectCompositeInterface {
|
||||||
|
fn new(window: *mut compositor::Window) -> Self {
|
||||||
|
DirectCompositeInterface {
|
||||||
|
window,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl webrender::Compositor for DirectCompositeInterface {
|
||||||
|
fn create_surface(
|
||||||
|
&mut self,
|
||||||
|
id: webrender::NativeSurfaceId,
|
||||||
|
tile_size: DeviceIntSize,
|
||||||
|
is_opaque: bool,
|
||||||
|
) {
|
||||||
|
compositor::create_surface(
|
||||||
|
self.window,
|
||||||
|
id.0,
|
||||||
|
tile_size.width,
|
||||||
|
tile_size.height,
|
||||||
|
is_opaque,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy_surface(
|
||||||
|
&mut self,
|
||||||
|
id: webrender::NativeSurfaceId,
|
||||||
|
) {
|
||||||
|
compositor::destroy_surface(self.window, id.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_tile(
|
||||||
|
&mut self,
|
||||||
|
id: webrender::NativeTileId,
|
||||||
|
) {
|
||||||
|
compositor::create_tile(
|
||||||
|
self.window,
|
||||||
|
id.surface_id.0,
|
||||||
|
id.x,
|
||||||
|
id.y,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy_tile(
|
||||||
|
&mut self,
|
||||||
|
id: webrender::NativeTileId,
|
||||||
|
) {
|
||||||
|
compositor::destroy_tile(
|
||||||
|
self.window,
|
||||||
|
id.surface_id.0,
|
||||||
|
id.x,
|
||||||
|
id.y,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind(
|
||||||
|
&mut self,
|
||||||
|
id: webrender::NativeTileId,
|
||||||
|
dirty_rect: DeviceIntRect,
|
||||||
|
) -> webrender::NativeSurfaceInfo {
|
||||||
|
let (fbo_id, x, y) = compositor::bind_surface(
|
||||||
|
self.window,
|
||||||
|
id.surface_id.0,
|
||||||
|
id.x,
|
||||||
|
id.y,
|
||||||
|
dirty_rect.origin.x,
|
||||||
|
dirty_rect.origin.y,
|
||||||
|
dirty_rect.size.width,
|
||||||
|
dirty_rect.size.height,
|
||||||
|
);
|
||||||
|
|
||||||
|
webrender::NativeSurfaceInfo {
|
||||||
|
origin: DeviceIntPoint::new(x, y),
|
||||||
|
fbo_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unbind(&mut self) {
|
||||||
|
compositor::unbind_surface(self.window);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn begin_frame(&mut self) {
|
||||||
|
compositor::begin_transaction(self.window);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_surface(
|
||||||
|
&mut self,
|
||||||
|
id: webrender::NativeSurfaceId,
|
||||||
|
position: DeviceIntPoint,
|
||||||
|
clip_rect: DeviceIntRect,
|
||||||
|
) {
|
||||||
|
compositor::add_surface(
|
||||||
|
self.window,
|
||||||
|
id.0,
|
||||||
|
position.x,
|
||||||
|
position.y,
|
||||||
|
clip_rect.origin.x,
|
||||||
|
clip_rect.origin.y,
|
||||||
|
clip_rect.size.width,
|
||||||
|
clip_rect.size.height,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_frame(&mut self) {
|
||||||
|
compositor::end_transaction(self.window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simplisitic implementation of the WR notifier interface to know when a frame
|
||||||
|
// has been prepared and can be rendered.
|
||||||
|
struct Notifier {
|
||||||
|
tx: mpsc::Sender<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Notifier {
|
||||||
|
fn new(tx: mpsc::Sender<()>) -> Self {
|
||||||
|
Notifier {
|
||||||
|
tx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderNotifier for Notifier {
|
||||||
|
fn clone(&self) -> Box<dyn RenderNotifier> {
|
||||||
|
Box::new(Notifier {
|
||||||
|
tx: self.tx.clone()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake_up(&self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_frame_ready(&self,
|
||||||
|
_: DocumentId,
|
||||||
|
_scrolled: bool,
|
||||||
|
_composite_needed: bool,
|
||||||
|
_render_time: Option<u64>) {
|
||||||
|
self.tx.send(()).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_rotated_rect(
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
rect: LayoutRect,
|
||||||
|
color: ColorF,
|
||||||
|
spatial_id: SpatialId,
|
||||||
|
root_pipeline_id: PipelineId,
|
||||||
|
angle: f32,
|
||||||
|
time: f32,
|
||||||
|
) {
|
||||||
|
let color = color.scale_rgb(time);
|
||||||
|
let rotation = LayoutTransform::create_rotation(
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
Angle::radians(2.0 * std::f32::consts::PI * angle),
|
||||||
|
);
|
||||||
|
let transform_origin = LayoutVector3D::new(
|
||||||
|
rect.origin.x + rect.size.width * 0.5,
|
||||||
|
rect.origin.y + rect.size.height * 0.5,
|
||||||
|
0.0,
|
||||||
|
);
|
||||||
|
let transform = rotation
|
||||||
|
.pre_translate(-transform_origin)
|
||||||
|
.post_translate(transform_origin);
|
||||||
|
let spatial_id = builder.push_reference_frame(
|
||||||
|
LayoutPoint::zero(),
|
||||||
|
spatial_id,
|
||||||
|
TransformStyle::Flat,
|
||||||
|
PropertyBinding::Value(transform),
|
||||||
|
ReferenceFrameKind::Transform,
|
||||||
|
);
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
rect,
|
||||||
|
SpaceAndClipInfo {
|
||||||
|
spatial_id,
|
||||||
|
clip_id: ClipId::root(root_pipeline_id),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
rect,
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_display_list(
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
scroll_id: ExternalScrollId,
|
||||||
|
root_pipeline_id: PipelineId,
|
||||||
|
layout_size: LayoutSize,
|
||||||
|
time: f32,
|
||||||
|
invalidations: Invalidations,
|
||||||
|
) {
|
||||||
|
let size_factor = match invalidations {
|
||||||
|
Invalidations::Small => 0.1,
|
||||||
|
Invalidations::Large | Invalidations::Scrolling => 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let fixed_space_info = SpaceAndClipInfo {
|
||||||
|
spatial_id: SpatialId::root_scroll_node(root_pipeline_id),
|
||||||
|
clip_id: ClipId::root(root_pipeline_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
let scroll_space_info = builder.define_scroll_frame(
|
||||||
|
&fixed_space_info,
|
||||||
|
Some(scroll_id),
|
||||||
|
LayoutRect::new(LayoutPoint::zero(), layout_size),
|
||||||
|
LayoutRect::new(LayoutPoint::zero(), layout_size),
|
||||||
|
ScrollSensitivity::Script,
|
||||||
|
LayoutVector2D::zero(),
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::zero(), layout_size).inflate(-10.0, -10.0),
|
||||||
|
fixed_space_info,
|
||||||
|
),
|
||||||
|
LayoutRect::new(LayoutPoint::zero(), layout_size).inflate(-10.0, -10.0),
|
||||||
|
ColorF::new(0.8, 0.8, 0.8, 1.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
push_rotated_rect(
|
||||||
|
builder,
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(100.0, 100.0),
|
||||||
|
LayoutSize::new(size_factor * 400.0, size_factor * 400.0),
|
||||||
|
),
|
||||||
|
ColorF::new(1.0, 0.0, 0.0, 1.0),
|
||||||
|
scroll_space_info.spatial_id,
|
||||||
|
root_pipeline_id,
|
||||||
|
time,
|
||||||
|
time,
|
||||||
|
);
|
||||||
|
|
||||||
|
push_rotated_rect(
|
||||||
|
builder,
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(800.0, 100.0),
|
||||||
|
LayoutSize::new(size_factor * 100.0, size_factor * 600.0),
|
||||||
|
),
|
||||||
|
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||||
|
fixed_space_info.spatial_id,
|
||||||
|
root_pipeline_id,
|
||||||
|
0.2,
|
||||||
|
time,
|
||||||
|
);
|
||||||
|
|
||||||
|
push_rotated_rect(
|
||||||
|
builder,
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(700.0, 200.0),
|
||||||
|
LayoutSize::new(size_factor * 300.0, size_factor * 300.0),
|
||||||
|
),
|
||||||
|
ColorF::new(0.0, 0.0, 1.0, 1.0),
|
||||||
|
scroll_space_info.spatial_id,
|
||||||
|
root_pipeline_id,
|
||||||
|
0.1,
|
||||||
|
time,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
enum Invalidations {
|
||||||
|
Large,
|
||||||
|
Small,
|
||||||
|
Scrolling,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
enum Sync {
|
||||||
|
None = 0,
|
||||||
|
Swap = 1,
|
||||||
|
Commit = 2,
|
||||||
|
Flush = 3,
|
||||||
|
Query = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
if args.len() != 6 {
|
||||||
|
println!("USAGE: compositor [native|none] [small|large|scroll] [none|swap|commit|flush|query] width height");
|
||||||
|
process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let enable_compositor = match args[1].parse::<String>().unwrap().as_str() {
|
||||||
|
"native" => true,
|
||||||
|
"none" => false,
|
||||||
|
_ => panic!("invalid compositor [native, none]"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let inv_mode = match args[2].parse::<String>().unwrap().as_str() {
|
||||||
|
"small" => Invalidations::Small,
|
||||||
|
"large" => Invalidations::Large,
|
||||||
|
"scroll" => Invalidations::Scrolling,
|
||||||
|
_ => panic!("invalid invalidations [small, large, scroll]"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let sync_mode = match args[3].parse::<String>().unwrap().as_str() {
|
||||||
|
"none" => Sync::None,
|
||||||
|
"swap" => Sync::Swap,
|
||||||
|
"commit" => Sync::Commit,
|
||||||
|
"flush" => Sync::Flush,
|
||||||
|
"query" => Sync::Query,
|
||||||
|
_ => panic!("invalid sync mode [none, swap, commit, flush, query]"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let width = args[4].parse().unwrap();
|
||||||
|
let height = args[5].parse().unwrap();
|
||||||
|
let device_size = DeviceIntSize::new(width, height);
|
||||||
|
|
||||||
|
// Load GL, construct WR and the native compositor interface.
|
||||||
|
let window = compositor::create_window(
|
||||||
|
device_size.width,
|
||||||
|
device_size.height,
|
||||||
|
enable_compositor,
|
||||||
|
sync_mode as i32,
|
||||||
|
);
|
||||||
|
let debug_flags = DebugFlags::empty();
|
||||||
|
let compositor_config = if enable_compositor {
|
||||||
|
webrender::CompositorConfig::Native {
|
||||||
|
max_update_rects: 1,
|
||||||
|
compositor: Box::new(DirectCompositeInterface::new(window)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
webrender::CompositorConfig::Draw {
|
||||||
|
max_partial_present_rects: 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let opts = webrender::RendererOptions {
|
||||||
|
clear_color: Some(ColorF::new(1.0, 1.0, 1.0, 1.0)),
|
||||||
|
debug_flags,
|
||||||
|
enable_picture_caching: true,
|
||||||
|
compositor_config,
|
||||||
|
..webrender::RendererOptions::default()
|
||||||
|
};
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let notifier = Box::new(Notifier::new(tx));
|
||||||
|
let gl = unsafe {
|
||||||
|
gl::GlesFns::load_with(
|
||||||
|
|symbol| {
|
||||||
|
let symbol = CString::new(symbol).unwrap();
|
||||||
|
let ptr = compositor::get_proc_address(symbol.as_ptr());
|
||||||
|
ptr
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let (mut renderer, sender) = webrender::Renderer::new(
|
||||||
|
gl.clone(),
|
||||||
|
notifier,
|
||||||
|
opts,
|
||||||
|
None,
|
||||||
|
device_size,
|
||||||
|
).unwrap();
|
||||||
|
let api = sender.create_api();
|
||||||
|
let document_id = api.add_document(device_size, 0);
|
||||||
|
let device_pixel_ratio = 1.0;
|
||||||
|
let mut current_epoch = Epoch(0);
|
||||||
|
let root_pipeline_id = PipelineId(0, 0);
|
||||||
|
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||||
|
let mut time = 0.0;
|
||||||
|
let scroll_id = ExternalScrollId(3, root_pipeline_id);
|
||||||
|
|
||||||
|
// Kick off first transaction which will mean we get a notify below to build the DL and render.
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
txn.set_root_pipeline(root_pipeline_id);
|
||||||
|
|
||||||
|
if let Invalidations::Scrolling = inv_mode {
|
||||||
|
let mut root_builder = DisplayListBuilder::new(root_pipeline_id, layout_size);
|
||||||
|
|
||||||
|
build_display_list(
|
||||||
|
&mut root_builder,
|
||||||
|
scroll_id,
|
||||||
|
root_pipeline_id,
|
||||||
|
layout_size,
|
||||||
|
1.0,
|
||||||
|
inv_mode,
|
||||||
|
);
|
||||||
|
|
||||||
|
txn.set_display_list(
|
||||||
|
current_epoch,
|
||||||
|
None,
|
||||||
|
layout_size,
|
||||||
|
root_builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
// Tick the compositor (in this sample, we don't block on UI events)
|
||||||
|
while compositor::tick(window) {
|
||||||
|
// If there is a new frame ready to draw
|
||||||
|
if let Ok(..) = rx.try_recv() {
|
||||||
|
// Update and render. This will invoke the native compositor interface implemented above
|
||||||
|
// as required.
|
||||||
|
renderer.update();
|
||||||
|
renderer.render(device_size).unwrap();
|
||||||
|
let _ = renderer.flush_pipeline_info();
|
||||||
|
|
||||||
|
// Construct a simple display list that can be drawn and composited by DC.
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
|
||||||
|
match inv_mode {
|
||||||
|
Invalidations::Small | Invalidations::Large => {
|
||||||
|
let mut root_builder = DisplayListBuilder::new(root_pipeline_id, layout_size);
|
||||||
|
|
||||||
|
build_display_list(
|
||||||
|
&mut root_builder,
|
||||||
|
scroll_id,
|
||||||
|
root_pipeline_id,
|
||||||
|
layout_size,
|
||||||
|
time,
|
||||||
|
inv_mode,
|
||||||
|
);
|
||||||
|
|
||||||
|
txn.set_display_list(
|
||||||
|
current_epoch,
|
||||||
|
None,
|
||||||
|
layout_size,
|
||||||
|
root_builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Invalidations::Scrolling => {
|
||||||
|
let d = 0.5 - 0.5 * (2.0 * f32::consts::PI * 5.0 * time).cos();
|
||||||
|
txn.scroll_node_with_id(
|
||||||
|
LayoutPoint::new(0.0, (d * 100.0).round()),
|
||||||
|
scroll_id,
|
||||||
|
ScrollClamping::NoClamping,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
current_epoch.0 += 1;
|
||||||
|
time += 0.001;
|
||||||
|
if time > 1.0 {
|
||||||
|
time = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This does nothing when native compositor is enabled
|
||||||
|
compositor::swap_buffers(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.deinit();
|
||||||
|
compositor::destroy_window(window);
|
||||||
|
}
|
71
third_party/webrender/examples/Cargo.toml
vendored
Normal file
71
third_party/webrender/examples/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
[package]
|
||||||
|
name = "webrender-examples"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
|
||||||
|
license = "MPL-2.0"
|
||||||
|
repository = "https://github.com/servo/webrender"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "alpha_perf"
|
||||||
|
path = "alpha_perf.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "animation"
|
||||||
|
path = "animation.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "basic"
|
||||||
|
path = "basic.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "blob"
|
||||||
|
path = "blob.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "document"
|
||||||
|
path = "document.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "frame_output"
|
||||||
|
path = "frame_output.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "iframe"
|
||||||
|
path = "iframe.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "image_resize"
|
||||||
|
path = "image_resize.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "multiwindow"
|
||||||
|
path = "multiwindow.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "scrolling"
|
||||||
|
path = "scrolling.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "texture_cache_stress"
|
||||||
|
path = "texture_cache_stress.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "yuv"
|
||||||
|
path = "yuv.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
debug = ["webrender/capture", "webrender/debugger", "webrender/profiler"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
app_units = "0.7"
|
||||||
|
env_logger = "0.5"
|
||||||
|
euclid = "0.22"
|
||||||
|
gleam = "0.12"
|
||||||
|
glutin = "0.21"
|
||||||
|
rayon = "1"
|
||||||
|
webrender = { path = "../webrender" }
|
||||||
|
winit = "0.19"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
core-foundation = "0.7"
|
8
third_party/webrender/examples/README.md
vendored
Normal file
8
third_party/webrender/examples/README.md
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
This directory contains a collection of examples which uses the WebRender API.
|
||||||
|
|
||||||
|
To run an example e.g. `basic`, try:
|
||||||
|
```
|
||||||
|
cargo run --bin basic
|
||||||
|
```
|
93
third_party/webrender/examples/alpha_perf.rs
vendored
Normal file
93
third_party/webrender/examples/alpha_perf.rs
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use std::cmp;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::DeviceIntSize;
|
||||||
|
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
rect_count: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
_txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let bounds = (0, 0).to(1920, 1080);
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
for _ in 0 .. self.rect_count {
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(bounds, space_and_clip),
|
||||||
|
bounds,
|
||||||
|
ColorF::new(1.0, 1.0, 1.0, 0.05)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(
|
||||||
|
&mut self,
|
||||||
|
event: winit::WindowEvent,
|
||||||
|
_api: &mut RenderApi,
|
||||||
|
_document_id: DocumentId
|
||||||
|
) -> bool {
|
||||||
|
match event {
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(key),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
match key {
|
||||||
|
winit::VirtualKeyCode::Right => {
|
||||||
|
self.rect_count += 1;
|
||||||
|
println!("rects = {}", self.rect_count);
|
||||||
|
}
|
||||||
|
winit::VirtualKeyCode::Left => {
|
||||||
|
self.rect_count = cmp::max(self.rect_count, 1) - 1;
|
||||||
|
println!("rects = {}", self.rect_count);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
rect_count: 1,
|
||||||
|
};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
219
third_party/webrender/examples/animation.rs
vendored
Normal file
219
third_party/webrender/examples/animation.rs
vendored
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
//! This example creates a 200x200 white rect and allows the user to move it
|
||||||
|
//! around by using the arrow keys and rotate with '<'/'>'.
|
||||||
|
//! It does this by using the animation API.
|
||||||
|
|
||||||
|
//! The example also features seamless opaque/transparent split of a
|
||||||
|
//! rounded cornered rectangle, which is done automatically during the
|
||||||
|
//! scene building for render optimization.
|
||||||
|
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use euclid::Angle;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
property_key0: PropertyBindingKey<LayoutTransform>,
|
||||||
|
property_key1: PropertyBindingKey<LayoutTransform>,
|
||||||
|
property_key2: PropertyBindingKey<LayoutTransform>,
|
||||||
|
opacity_key: PropertyBindingKey<f32>,
|
||||||
|
opacity: f32,
|
||||||
|
angle0: f32,
|
||||||
|
angle1: f32,
|
||||||
|
angle2: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
fn add_rounded_rect(
|
||||||
|
&mut self,
|
||||||
|
bounds: LayoutRect,
|
||||||
|
color: ColorF,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
property_key: PropertyBindingKey<LayoutTransform>,
|
||||||
|
opacity_key: Option<PropertyBindingKey<f32>>,
|
||||||
|
) {
|
||||||
|
let filters = match opacity_key {
|
||||||
|
Some(opacity_key) => {
|
||||||
|
vec![
|
||||||
|
FilterOp::Opacity(PropertyBinding::Binding(opacity_key, self.opacity), self.opacity),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let spatial_id = builder.push_reference_frame(
|
||||||
|
bounds.origin,
|
||||||
|
SpatialId::root_scroll_node(pipeline_id),
|
||||||
|
TransformStyle::Flat,
|
||||||
|
PropertyBinding::Binding(property_key, LayoutTransform::identity()),
|
||||||
|
ReferenceFrameKind::Transform,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context_with_filters(
|
||||||
|
LayoutPoint::zero(),
|
||||||
|
spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
&filters,
|
||||||
|
&[],
|
||||||
|
&[]
|
||||||
|
);
|
||||||
|
|
||||||
|
let space_and_clip = SpaceAndClipInfo {
|
||||||
|
spatial_id,
|
||||||
|
clip_id: ClipId::root(pipeline_id),
|
||||||
|
};
|
||||||
|
let clip_bounds = LayoutRect::new(LayoutPoint::zero(), bounds.size);
|
||||||
|
let complex_clip = ComplexClipRegion {
|
||||||
|
rect: clip_bounds,
|
||||||
|
radii: BorderRadius::uniform(30.0),
|
||||||
|
mode: ClipMode::Clip,
|
||||||
|
};
|
||||||
|
let clip_id = builder.define_clip_rounded_rect(
|
||||||
|
&space_and_clip,
|
||||||
|
complex_clip,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fill it with a white rect
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::zero(), bounds.size),
|
||||||
|
SpaceAndClipInfo {
|
||||||
|
spatial_id,
|
||||||
|
clip_id,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
LayoutRect::new(LayoutPoint::zero(), bounds.size),
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
builder.pop_reference_frame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
const WIDTH: u32 = 2048;
|
||||||
|
const HEIGHT: u32 = 1536;
|
||||||
|
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
_txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let opacity_key = self.opacity_key;
|
||||||
|
|
||||||
|
let bounds = (150, 150).to(250, 250);
|
||||||
|
let key0 = self.property_key0;
|
||||||
|
self.add_rounded_rect(bounds, ColorF::new(1.0, 0.0, 0.0, 0.5), builder, pipeline_id, key0, Some(opacity_key));
|
||||||
|
|
||||||
|
let bounds = (400, 400).to(600, 600);
|
||||||
|
let key1 = self.property_key1;
|
||||||
|
self.add_rounded_rect(bounds, ColorF::new(0.0, 1.0, 0.0, 0.5), builder, pipeline_id, key1, None);
|
||||||
|
|
||||||
|
let bounds = (200, 500).to(350, 580);
|
||||||
|
let key2 = self.property_key2;
|
||||||
|
self.add_rounded_rect(bounds, ColorF::new(0.0, 0.0, 1.0, 0.5), builder, pipeline_id, key2, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(&mut self, win_event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||||
|
let mut rebuild_display_list = false;
|
||||||
|
|
||||||
|
match win_event {
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(key),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let (delta_angle, delta_opacity) = match key {
|
||||||
|
winit::VirtualKeyCode::Down => (0.0, -0.1),
|
||||||
|
winit::VirtualKeyCode::Up => (0.0, 0.1),
|
||||||
|
winit::VirtualKeyCode::Right => (1.0, 0.0),
|
||||||
|
winit::VirtualKeyCode::Left => (-1.0, 0.0),
|
||||||
|
winit::VirtualKeyCode::R => {
|
||||||
|
rebuild_display_list = true;
|
||||||
|
(0.0, 0.0)
|
||||||
|
}
|
||||||
|
_ => return false,
|
||||||
|
};
|
||||||
|
// Update the transform based on the keyboard input and push it to
|
||||||
|
// webrender using the generate_frame API. This will recomposite with
|
||||||
|
// the updated transform.
|
||||||
|
self.opacity += delta_opacity;
|
||||||
|
self.angle0 += delta_angle * 0.1;
|
||||||
|
self.angle1 += delta_angle * 0.2;
|
||||||
|
self.angle2 -= delta_angle * 0.15;
|
||||||
|
let xf0 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle0));
|
||||||
|
let xf1 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle1));
|
||||||
|
let xf2 = LayoutTransform::rotation(0.0, 0.0, 1.0, Angle::radians(self.angle2));
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
txn.update_dynamic_properties(
|
||||||
|
DynamicProperties {
|
||||||
|
transforms: vec![
|
||||||
|
PropertyValue {
|
||||||
|
key: self.property_key0,
|
||||||
|
value: xf0,
|
||||||
|
},
|
||||||
|
PropertyValue {
|
||||||
|
key: self.property_key1,
|
||||||
|
value: xf1,
|
||||||
|
},
|
||||||
|
PropertyValue {
|
||||||
|
key: self.property_key2,
|
||||||
|
value: xf2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
floats: vec![
|
||||||
|
PropertyValue {
|
||||||
|
key: self.opacity_key,
|
||||||
|
value: self.opacity,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
colors: vec![],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
rebuild_display_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
property_key0: PropertyBindingKey::new(42), // arbitrary magic number
|
||||||
|
property_key1: PropertyBindingKey::new(44), // arbitrary magic number
|
||||||
|
property_key2: PropertyBindingKey::new(45), // arbitrary magic number
|
||||||
|
opacity_key: PropertyBindingKey::new(43),
|
||||||
|
opacity: 0.5,
|
||||||
|
angle0: 0.0,
|
||||||
|
angle1: 0.0,
|
||||||
|
angle2: 0.0,
|
||||||
|
};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
321
third_party/webrender/examples/basic.rs
vendored
Normal file
321
third_party/webrender/examples/basic.rs
vendored
Normal file
|
@ -0,0 +1,321 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use euclid::vec2;
|
||||||
|
use winit::TouchPhase;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use webrender::ShaderPrecacheFlags;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Gesture {
|
||||||
|
None,
|
||||||
|
Pan,
|
||||||
|
Zoom,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Touch {
|
||||||
|
id: u64,
|
||||||
|
start_x: f32,
|
||||||
|
start_y: f32,
|
||||||
|
current_x: f32,
|
||||||
|
current_y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dist(x0: f32, y0: f32, x1: f32, y1: f32) -> f32 {
|
||||||
|
let dx = x0 - x1;
|
||||||
|
let dy = y0 - y1;
|
||||||
|
((dx * dx) + (dy * dy)).sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Touch {
|
||||||
|
fn distance_from_start(&self) -> f32 {
|
||||||
|
dist(self.start_x, self.start_y, self.current_x, self.current_y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initial_distance_from_other(&self, other: &Touch) -> f32 {
|
||||||
|
dist(self.start_x, self.start_y, other.start_x, other.start_y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_distance_from_other(&self, other: &Touch) -> f32 {
|
||||||
|
dist(
|
||||||
|
self.current_x,
|
||||||
|
self.current_y,
|
||||||
|
other.current_x,
|
||||||
|
other.current_y,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TouchState {
|
||||||
|
active_touches: HashMap<u64, Touch>,
|
||||||
|
current_gesture: Gesture,
|
||||||
|
start_zoom: f32,
|
||||||
|
current_zoom: f32,
|
||||||
|
start_pan: DeviceIntPoint,
|
||||||
|
current_pan: DeviceIntPoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TouchResult {
|
||||||
|
None,
|
||||||
|
Pan(DeviceIntPoint),
|
||||||
|
Zoom(f32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TouchState {
|
||||||
|
fn new() -> TouchState {
|
||||||
|
TouchState {
|
||||||
|
active_touches: HashMap::new(),
|
||||||
|
current_gesture: Gesture::None,
|
||||||
|
start_zoom: 1.0,
|
||||||
|
current_zoom: 1.0,
|
||||||
|
start_pan: DeviceIntPoint::zero(),
|
||||||
|
current_pan: DeviceIntPoint::zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_event(&mut self, touch: winit::Touch) -> TouchResult {
|
||||||
|
match touch.phase {
|
||||||
|
TouchPhase::Started => {
|
||||||
|
debug_assert!(!self.active_touches.contains_key(&touch.id));
|
||||||
|
self.active_touches.insert(
|
||||||
|
touch.id,
|
||||||
|
Touch {
|
||||||
|
id: touch.id,
|
||||||
|
start_x: touch.location.x as f32,
|
||||||
|
start_y: touch.location.y as f32,
|
||||||
|
current_x: touch.location.x as f32,
|
||||||
|
current_y: touch.location.y as f32,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self.current_gesture = Gesture::None;
|
||||||
|
}
|
||||||
|
TouchPhase::Moved => {
|
||||||
|
match self.active_touches.get_mut(&touch.id) {
|
||||||
|
Some(active_touch) => {
|
||||||
|
active_touch.current_x = touch.location.x as f32;
|
||||||
|
active_touch.current_y = touch.location.y as f32;
|
||||||
|
}
|
||||||
|
None => panic!("move touch event with unknown touch id!"),
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.current_gesture {
|
||||||
|
Gesture::None => {
|
||||||
|
let mut over_threshold_count = 0;
|
||||||
|
let active_touch_count = self.active_touches.len();
|
||||||
|
|
||||||
|
for (_, touch) in &self.active_touches {
|
||||||
|
if touch.distance_from_start() > 8.0 {
|
||||||
|
over_threshold_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if active_touch_count == over_threshold_count {
|
||||||
|
if active_touch_count == 1 {
|
||||||
|
self.start_pan = self.current_pan;
|
||||||
|
self.current_gesture = Gesture::Pan;
|
||||||
|
} else if active_touch_count == 2 {
|
||||||
|
self.start_zoom = self.current_zoom;
|
||||||
|
self.current_gesture = Gesture::Zoom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gesture::Pan => {
|
||||||
|
let keys: Vec<u64> = self.active_touches.keys().cloned().collect();
|
||||||
|
debug_assert!(keys.len() == 1);
|
||||||
|
let active_touch = &self.active_touches[&keys[0]];
|
||||||
|
let x = active_touch.current_x - active_touch.start_x;
|
||||||
|
let y = active_touch.current_y - active_touch.start_y;
|
||||||
|
self.current_pan.x = self.start_pan.x + x.round() as i32;
|
||||||
|
self.current_pan.y = self.start_pan.y + y.round() as i32;
|
||||||
|
return TouchResult::Pan(self.current_pan);
|
||||||
|
}
|
||||||
|
Gesture::Zoom => {
|
||||||
|
let keys: Vec<u64> = self.active_touches.keys().cloned().collect();
|
||||||
|
debug_assert!(keys.len() == 2);
|
||||||
|
let touch0 = &self.active_touches[&keys[0]];
|
||||||
|
let touch1 = &self.active_touches[&keys[1]];
|
||||||
|
let initial_distance = touch0.initial_distance_from_other(touch1);
|
||||||
|
let current_distance = touch0.current_distance_from_other(touch1);
|
||||||
|
self.current_zoom = self.start_zoom * current_distance / initial_distance;
|
||||||
|
return TouchResult::Zoom(self.current_zoom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TouchPhase::Ended | TouchPhase::Cancelled => {
|
||||||
|
self.active_touches.remove(&touch.id).unwrap();
|
||||||
|
self.current_gesture = Gesture::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchResult::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
touch_state: TouchState::new(),
|
||||||
|
};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
touch_state: TouchState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
// Make this the only example to test all shaders for compile errors.
|
||||||
|
const PRECACHE_SHADER_FLAGS: ShaderPrecacheFlags = ShaderPrecacheFlags::FULL_COMPILE;
|
||||||
|
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
txn: &mut Transaction,
|
||||||
|
_: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let content_bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||||
|
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
let spatial_id = root_space_and_clip.spatial_id;
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
content_bounds.origin,
|
||||||
|
spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
let image_mask_key = api.generate_image_key();
|
||||||
|
txn.add_image(
|
||||||
|
image_mask_key,
|
||||||
|
ImageDescriptor::new(2, 2, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::new(vec![0, 80, 180, 255]),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let mask = ImageMask {
|
||||||
|
image: image_mask_key,
|
||||||
|
rect: (75, 75).by(100, 100),
|
||||||
|
repeat: false,
|
||||||
|
};
|
||||||
|
let complex = ComplexClipRegion::new(
|
||||||
|
(50, 50).to(150, 150),
|
||||||
|
BorderRadius::uniform(20.0),
|
||||||
|
ClipMode::Clip
|
||||||
|
);
|
||||||
|
let mask_clip_id = builder.define_clip_image_mask(
|
||||||
|
&root_space_and_clip,
|
||||||
|
mask,
|
||||||
|
);
|
||||||
|
let clip_id = builder.define_clip_rounded_rect(
|
||||||
|
&SpaceAndClipInfo {
|
||||||
|
spatial_id: root_space_and_clip.spatial_id,
|
||||||
|
clip_id: mask_clip_id,
|
||||||
|
},
|
||||||
|
complex,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
(100, 100).to(200, 200),
|
||||||
|
SpaceAndClipInfo { spatial_id, clip_id },
|
||||||
|
),
|
||||||
|
(100, 100).to(200, 200),
|
||||||
|
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
(250, 100).to(350, 200),
|
||||||
|
SpaceAndClipInfo { spatial_id, clip_id },
|
||||||
|
),
|
||||||
|
(250, 100).to(350, 200),
|
||||||
|
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||||
|
);
|
||||||
|
let border_side = BorderSide {
|
||||||
|
color: ColorF::new(0.0, 0.0, 1.0, 1.0),
|
||||||
|
style: BorderStyle::Groove,
|
||||||
|
};
|
||||||
|
let border_widths = LayoutSideOffsets::new_all_same(10.0);
|
||||||
|
let border_details = BorderDetails::Normal(NormalBorder {
|
||||||
|
top: border_side,
|
||||||
|
right: border_side,
|
||||||
|
bottom: border_side,
|
||||||
|
left: border_side,
|
||||||
|
radius: BorderRadius::uniform(20.0),
|
||||||
|
do_aa: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
let bounds = (100, 100).to(200, 200);
|
||||||
|
builder.push_border(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
bounds,
|
||||||
|
SpaceAndClipInfo { spatial_id, clip_id },
|
||||||
|
),
|
||||||
|
bounds,
|
||||||
|
border_widths,
|
||||||
|
border_details,
|
||||||
|
);
|
||||||
|
|
||||||
|
if false {
|
||||||
|
// draw box shadow?
|
||||||
|
let simple_box_bounds = (20, 200).by(50, 50);
|
||||||
|
let offset = vec2(10.0, 10.0);
|
||||||
|
let color = ColorF::new(1.0, 1.0, 1.0, 1.0);
|
||||||
|
let blur_radius = 0.0;
|
||||||
|
let spread_radius = 0.0;
|
||||||
|
let simple_border_radius = 8.0;
|
||||||
|
let box_shadow_type = BoxShadowClipMode::Inset;
|
||||||
|
|
||||||
|
builder.push_box_shadow(
|
||||||
|
&CommonItemProperties::new(content_bounds, root_space_and_clip),
|
||||||
|
simple_box_bounds,
|
||||||
|
offset,
|
||||||
|
color,
|
||||||
|
blur_radius,
|
||||||
|
spread_radius,
|
||||||
|
BorderRadius::uniform(simple_border_radius),
|
||||||
|
box_shadow_type,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(&mut self, event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
match event {
|
||||||
|
winit::WindowEvent::Touch(touch) => match self.touch_state.handle_event(touch) {
|
||||||
|
TouchResult::Pan(pan) => {
|
||||||
|
txn.set_pan(pan);
|
||||||
|
}
|
||||||
|
TouchResult::Zoom(zoom) => {
|
||||||
|
txn.set_pinch_zoom(ZoomFactor::new(zoom));
|
||||||
|
}
|
||||||
|
TouchResult::None => {}
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !txn.is_empty() {
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
289
third_party/webrender/examples/blob.rs
vendored
Normal file
289
third_party/webrender/examples/blob.rs
vendored
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate rayon;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use rayon::{ThreadPool, ThreadPoolBuilder};
|
||||||
|
use rayon::prelude::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use webrender::api::{self, DisplayListBuilder, DocumentId, PipelineId, PrimitiveFlags, RenderApi, Transaction};
|
||||||
|
use webrender::api::{ColorF, CommonItemProperties, SpaceAndClipInfo, ImageDescriptorFlags};
|
||||||
|
use webrender::api::units::*;
|
||||||
|
use webrender::euclid::size2;
|
||||||
|
|
||||||
|
// This example shows how to implement a very basic BlobImageHandler that can only render
|
||||||
|
// a checkerboard pattern.
|
||||||
|
|
||||||
|
// The deserialized command list internally used by this example is just a color.
|
||||||
|
type ImageRenderingCommands = api::ColorU;
|
||||||
|
|
||||||
|
// Serialize/deserialize the blob.
|
||||||
|
// For real usecases you should probably use serde rather than doing it by hand.
|
||||||
|
|
||||||
|
fn serialize_blob(color: api::ColorU) -> Arc<Vec<u8>> {
|
||||||
|
Arc::new(vec![color.r, color.g, color.b, color.a])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_blob(blob: &[u8]) -> Result<ImageRenderingCommands, ()> {
|
||||||
|
let mut iter = blob.iter();
|
||||||
|
return match (iter.next(), iter.next(), iter.next(), iter.next()) {
|
||||||
|
(Some(&r), Some(&g), Some(&b), Some(&a)) => Ok(api::ColorU::new(r, g, b, a)),
|
||||||
|
(Some(&a), None, None, None) => Ok(api::ColorU::new(a, a, a, a)),
|
||||||
|
_ => Err(()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the function that applies the deserialized drawing commands and generates
|
||||||
|
// actual image data.
|
||||||
|
fn render_blob(
|
||||||
|
commands: Arc<ImageRenderingCommands>,
|
||||||
|
descriptor: &api::BlobImageDescriptor,
|
||||||
|
tile: TileOffset,
|
||||||
|
) -> api::BlobImageResult {
|
||||||
|
let color = *commands;
|
||||||
|
|
||||||
|
// Note: This implementation ignores the dirty rect which isn't incorrect
|
||||||
|
// but is a missed optimization.
|
||||||
|
|
||||||
|
// Allocate storage for the result. Right now the resource cache expects the
|
||||||
|
// tiles to have have no stride or offset.
|
||||||
|
let bpp = 4;
|
||||||
|
let mut texels = Vec::with_capacity((descriptor.rect.size.area() * bpp) as usize);
|
||||||
|
|
||||||
|
// Generate a per-tile pattern to see it in the demo. For a real use case it would not
|
||||||
|
// make sense for the rendered content to depend on its tile.
|
||||||
|
let tile_checker = (tile.x % 2 == 0) != (tile.y % 2 == 0);
|
||||||
|
|
||||||
|
let [w, h] = descriptor.rect.size.to_array();
|
||||||
|
let offset = descriptor.rect.origin;
|
||||||
|
|
||||||
|
for y in 0..h {
|
||||||
|
for x in 0..w {
|
||||||
|
// Apply the tile's offset. This is important: all drawing commands should be
|
||||||
|
// translated by this offset to give correct results with tiled blob images.
|
||||||
|
let x2 = x + offset.x;
|
||||||
|
let y2 = y + offset.y;
|
||||||
|
|
||||||
|
// Render a simple checkerboard pattern
|
||||||
|
let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
// ..nested in the per-tile checkerboard pattern
|
||||||
|
let tc = if tile_checker { 0 } else { (1 - checker) * 40 };
|
||||||
|
|
||||||
|
match descriptor.format {
|
||||||
|
api::ImageFormat::BGRA8 => {
|
||||||
|
texels.push(color.b * checker + tc);
|
||||||
|
texels.push(color.g * checker + tc);
|
||||||
|
texels.push(color.r * checker + tc);
|
||||||
|
texels.push(color.a * checker + tc);
|
||||||
|
}
|
||||||
|
api::ImageFormat::R8 => {
|
||||||
|
texels.push(color.a * checker + tc);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(api::BlobImageError::Other(
|
||||||
|
format!("Unsupported image format"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(api::RasterizedBlobImage {
|
||||||
|
data: Arc::new(texels),
|
||||||
|
rasterized_rect: size2(w, h).into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CheckerboardRenderer {
|
||||||
|
// We are going to defer the rendering work to worker threads.
|
||||||
|
// Using a pre-built Arc<ThreadPool> rather than creating our own threads
|
||||||
|
// makes it possible to share the same thread pool as the glyph renderer (if we
|
||||||
|
// want to).
|
||||||
|
workers: Arc<ThreadPool>,
|
||||||
|
|
||||||
|
// The deserialized drawing commands.
|
||||||
|
// In this example we store them in Arcs. This isn't necessary since in this simplified
|
||||||
|
// case the command list is a simple 32 bits value and would be cheap to clone before sending
|
||||||
|
// to the workers. But in a more realistic scenario the commands would typically be bigger
|
||||||
|
// and more expensive to clone, so let's pretend it is also the case here.
|
||||||
|
image_cmds: HashMap<api::BlobImageKey, Arc<ImageRenderingCommands>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CheckerboardRenderer {
|
||||||
|
fn new(workers: Arc<ThreadPool>) -> Self {
|
||||||
|
CheckerboardRenderer {
|
||||||
|
image_cmds: HashMap::new(),
|
||||||
|
workers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl api::BlobImageHandler for CheckerboardRenderer {
|
||||||
|
fn create_similar(&self) -> Box<dyn api::BlobImageHandler> {
|
||||||
|
Box::new(CheckerboardRenderer::new(Arc::clone(&self.workers)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self, key: api::BlobImageKey, cmds: Arc<api::BlobImageData>,
|
||||||
|
_visible_rect: &DeviceIntRect, _: api::TileSize) {
|
||||||
|
self.image_cmds
|
||||||
|
.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, key: api::BlobImageKey, cmds: Arc<api::BlobImageData>,
|
||||||
|
_visible_rect: &DeviceIntRect, _dirty_rect: &BlobDirtyRect) {
|
||||||
|
// Here, updating is just replacing the current version of the commands with
|
||||||
|
// the new one (no incremental updates).
|
||||||
|
self.image_cmds
|
||||||
|
.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete(&mut self, key: api::BlobImageKey) {
|
||||||
|
self.image_cmds.remove(&key);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_resources(
|
||||||
|
&mut self,
|
||||||
|
_services: &dyn api::BlobImageResources,
|
||||||
|
_requests: &[api::BlobImageParams],
|
||||||
|
) {}
|
||||||
|
|
||||||
|
fn enable_multithreading(&mut self, _: bool) {}
|
||||||
|
fn delete_font(&mut self, _font: api::FontKey) {}
|
||||||
|
fn delete_font_instance(&mut self, _instance: api::FontInstanceKey) {}
|
||||||
|
fn clear_namespace(&mut self, _namespace: api::IdNamespace) {}
|
||||||
|
fn create_blob_rasterizer(&mut self) -> Box<dyn api::AsyncBlobImageRasterizer> {
|
||||||
|
Box::new(Rasterizer {
|
||||||
|
workers: Arc::clone(&self.workers),
|
||||||
|
image_cmds: self.image_cmds.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Rasterizer {
|
||||||
|
workers: Arc<ThreadPool>,
|
||||||
|
image_cmds: HashMap<api::BlobImageKey, Arc<ImageRenderingCommands>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl api::AsyncBlobImageRasterizer for Rasterizer {
|
||||||
|
fn rasterize(
|
||||||
|
&mut self,
|
||||||
|
requests: &[api::BlobImageParams],
|
||||||
|
_low_priority: bool
|
||||||
|
) -> Vec<(api::BlobImageRequest, api::BlobImageResult)> {
|
||||||
|
let requests: Vec<(&api::BlobImageParams, Arc<ImageRenderingCommands>)> = requests.into_iter().map(|params| {
|
||||||
|
(params, Arc::clone(&self.image_cmds[¶ms.request.key]))
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
self.workers.install(|| {
|
||||||
|
requests.into_par_iter().map(|(params, commands)| {
|
||||||
|
(params.request, render_blob(commands, ¶ms.descriptor, params.request.tile))
|
||||||
|
}).collect()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
LayoutPoint::zero(),
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
let size1 = DeviceIntSize::new(500, 500);
|
||||||
|
let blob_img1 = api.generate_blob_image_key();
|
||||||
|
txn.add_blob_image(
|
||||||
|
blob_img1,
|
||||||
|
api::ImageDescriptor::new(
|
||||||
|
size1.width,
|
||||||
|
size1.height,
|
||||||
|
api::ImageFormat::BGRA8,
|
||||||
|
ImageDescriptorFlags::IS_OPAQUE,
|
||||||
|
),
|
||||||
|
serialize_blob(api::ColorU::new(50, 50, 150, 255)),
|
||||||
|
size1.into(),
|
||||||
|
Some(128),
|
||||||
|
);
|
||||||
|
let bounds = (30, 30).by(size1.width, size1.height);
|
||||||
|
builder.push_image(
|
||||||
|
&CommonItemProperties::new(bounds, space_and_clip),
|
||||||
|
bounds,
|
||||||
|
api::ImageRendering::Auto,
|
||||||
|
api::AlphaType::PremultipliedAlpha,
|
||||||
|
blob_img1.as_image(),
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
|
||||||
|
let size2 = DeviceIntSize::new(256, 256);
|
||||||
|
let blob_img2 = api.generate_blob_image_key();
|
||||||
|
txn.add_blob_image(
|
||||||
|
blob_img2,
|
||||||
|
api::ImageDescriptor::new(
|
||||||
|
size2.width,
|
||||||
|
size2.height,
|
||||||
|
api::ImageFormat::BGRA8,
|
||||||
|
ImageDescriptorFlags::IS_OPAQUE,
|
||||||
|
),
|
||||||
|
serialize_blob(api::ColorU::new(50, 150, 50, 255)),
|
||||||
|
size2.into(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let bounds = (600, 600).by(size2.width, size2.height);
|
||||||
|
builder.push_image(
|
||||||
|
&CommonItemProperties::new(bounds, space_and_clip),
|
||||||
|
bounds,
|
||||||
|
api::ImageRendering::Auto,
|
||||||
|
api::AlphaType::PremultipliedAlpha,
|
||||||
|
blob_img2.as_image(),
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let workers =
|
||||||
|
ThreadPoolBuilder::new().thread_name(|idx| format!("WebRender:Worker#{}", idx))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let workers = Arc::new(workers.unwrap());
|
||||||
|
|
||||||
|
let opts = webrender::RendererOptions {
|
||||||
|
workers: Some(Arc::clone(&workers)),
|
||||||
|
// Register our blob renderer, so that WebRender integrates it in the resource cache..
|
||||||
|
// Share the same pool of worker threads between WebRender and our blob renderer.
|
||||||
|
blob_image_handler: Some(Box::new(CheckerboardRenderer::new(Arc::clone(&workers)))),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut app = App {};
|
||||||
|
|
||||||
|
boilerplate::main_wrapper(&mut app, Some(opts));
|
||||||
|
}
|
338
third_party/webrender/examples/common/boilerplate.rs
vendored
Normal file
338
third_party/webrender/examples/common/boilerplate.rs
vendored
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
use gleam::gl;
|
||||||
|
use glutin;
|
||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use webrender;
|
||||||
|
use winit;
|
||||||
|
use webrender::{DebugFlags, ShaderPrecacheFlags};
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
struct Notifier {
|
||||||
|
events_proxy: winit::EventsLoopProxy,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Notifier {
|
||||||
|
fn new(events_proxy: winit::EventsLoopProxy) -> Notifier {
|
||||||
|
Notifier { events_proxy }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderNotifier for Notifier {
|
||||||
|
fn clone(&self) -> Box<dyn RenderNotifier> {
|
||||||
|
Box::new(Notifier {
|
||||||
|
events_proxy: self.events_proxy.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake_up(&self) {
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
let _ = self.events_proxy.wakeup();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_frame_ready(&self,
|
||||||
|
_: DocumentId,
|
||||||
|
_scrolled: bool,
|
||||||
|
_composite_needed: bool,
|
||||||
|
_render_time: Option<u64>) {
|
||||||
|
self.wake_up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait HandyDandyRectBuilder {
|
||||||
|
fn to(&self, x2: i32, y2: i32) -> LayoutRect;
|
||||||
|
fn by(&self, w: i32, h: i32) -> LayoutRect;
|
||||||
|
}
|
||||||
|
// Allows doing `(x, y).to(x2, y2)` or `(x, y).by(width, height)` with i32
|
||||||
|
// values to build a f32 LayoutRect
|
||||||
|
impl HandyDandyRectBuilder for (i32, i32) {
|
||||||
|
fn to(&self, x2: i32, y2: i32) -> LayoutRect {
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(self.0 as f32, self.1 as f32),
|
||||||
|
LayoutSize::new((x2 - self.0) as f32, (y2 - self.1) as f32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn by(&self, w: i32, h: i32) -> LayoutRect {
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(self.0 as f32, self.1 as f32),
|
||||||
|
LayoutSize::new(w as f32, h as f32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Example {
|
||||||
|
const TITLE: &'static str = "WebRender Sample App";
|
||||||
|
const PRECACHE_SHADER_FLAGS: ShaderPrecacheFlags = ShaderPrecacheFlags::EMPTY;
|
||||||
|
const WIDTH: u32 = 1920;
|
||||||
|
const HEIGHT: u32 = 1080;
|
||||||
|
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
txn: &mut Transaction,
|
||||||
|
device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
document_id: DocumentId,
|
||||||
|
);
|
||||||
|
fn on_event(
|
||||||
|
&mut self,
|
||||||
|
_: winit::WindowEvent,
|
||||||
|
_: &mut RenderApi,
|
||||||
|
_: DocumentId,
|
||||||
|
) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn get_image_handlers(
|
||||||
|
&mut self,
|
||||||
|
_gl: &dyn gl::Gl,
|
||||||
|
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||||
|
Option<Box<dyn OutputImageHandler>>) {
|
||||||
|
(None, None)
|
||||||
|
}
|
||||||
|
fn draw_custom(&mut self, _gl: &dyn gl::Gl) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main_wrapper<E: Example>(
|
||||||
|
example: &mut E,
|
||||||
|
options: Option<webrender::RendererOptions>,
|
||||||
|
) {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
{
|
||||||
|
use core_foundation::{self as cf, base::TCFType};
|
||||||
|
let i = cf::bundle::CFBundle::main_bundle().info_dictionary();
|
||||||
|
let mut i = unsafe { i.to_mutable() };
|
||||||
|
i.set(
|
||||||
|
cf::string::CFString::new("NSSupportsAutomaticGraphicsSwitching"),
|
||||||
|
cf::boolean::CFBoolean::true_value().into_CFType(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let res_path = if args.len() > 1 {
|
||||||
|
Some(PathBuf::from(&args[1]))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut events_loop = winit::EventsLoop::new();
|
||||||
|
let window_builder = winit::WindowBuilder::new()
|
||||||
|
.with_title(E::TITLE)
|
||||||
|
.with_multitouch()
|
||||||
|
.with_dimensions(winit::dpi::LogicalSize::new(E::WIDTH as f64, E::HEIGHT as f64));
|
||||||
|
let windowed_context = glutin::ContextBuilder::new()
|
||||||
|
.with_gl(glutin::GlRequest::GlThenGles {
|
||||||
|
opengl_version: (3, 2),
|
||||||
|
opengles_version: (3, 0),
|
||||||
|
})
|
||||||
|
.build_windowed(window_builder, &events_loop)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let windowed_context = unsafe { windowed_context.make_current().unwrap() };
|
||||||
|
|
||||||
|
let gl = match windowed_context.get_api() {
|
||||||
|
glutin::Api::OpenGl => unsafe {
|
||||||
|
gl::GlFns::load_with(
|
||||||
|
|symbol| windowed_context.get_proc_address(symbol) as *const _
|
||||||
|
)
|
||||||
|
},
|
||||||
|
glutin::Api::OpenGlEs => unsafe {
|
||||||
|
gl::GlesFns::load_with(
|
||||||
|
|symbol| windowed_context.get_proc_address(symbol) as *const _
|
||||||
|
)
|
||||||
|
},
|
||||||
|
glutin::Api::WebGl => unimplemented!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("OpenGL version {}", gl.get_string(gl::VERSION));
|
||||||
|
println!("Shader resource path: {:?}", res_path);
|
||||||
|
let device_pixel_ratio = windowed_context.window().get_hidpi_factor() as f32;
|
||||||
|
println!("Device pixel ratio: {}", device_pixel_ratio);
|
||||||
|
|
||||||
|
println!("Loading shaders...");
|
||||||
|
let mut debug_flags = DebugFlags::ECHO_DRIVER_MESSAGES | DebugFlags::TEXTURE_CACHE_DBG;
|
||||||
|
let opts = webrender::RendererOptions {
|
||||||
|
resource_override_path: res_path,
|
||||||
|
precache_flags: E::PRECACHE_SHADER_FLAGS,
|
||||||
|
device_pixel_ratio,
|
||||||
|
clear_color: Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
|
||||||
|
debug_flags,
|
||||||
|
//allow_texture_swizzling: false,
|
||||||
|
..options.unwrap_or(webrender::RendererOptions::default())
|
||||||
|
};
|
||||||
|
|
||||||
|
let device_size = {
|
||||||
|
let size = windowed_context
|
||||||
|
.window()
|
||||||
|
.get_inner_size()
|
||||||
|
.unwrap()
|
||||||
|
.to_physical(device_pixel_ratio as f64);
|
||||||
|
DeviceIntSize::new(size.width as i32, size.height as i32)
|
||||||
|
};
|
||||||
|
let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
|
||||||
|
let (mut renderer, sender) = webrender::Renderer::new(
|
||||||
|
gl.clone(),
|
||||||
|
notifier,
|
||||||
|
opts,
|
||||||
|
None,
|
||||||
|
device_size,
|
||||||
|
).unwrap();
|
||||||
|
let mut api = sender.create_api();
|
||||||
|
let document_id = api.add_document(device_size, 0);
|
||||||
|
|
||||||
|
let (external, output) = example.get_image_handlers(&*gl);
|
||||||
|
|
||||||
|
if let Some(output_image_handler) = output {
|
||||||
|
renderer.set_output_image_handler(output_image_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(external_image_handler) = external {
|
||||||
|
renderer.set_external_image_handler(external_image_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
let epoch = Epoch(0);
|
||||||
|
let pipeline_id = PipelineId(0, 0);
|
||||||
|
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||||
|
let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
|
||||||
|
example.render(
|
||||||
|
&mut api,
|
||||||
|
&mut builder,
|
||||||
|
&mut txn,
|
||||||
|
device_size,
|
||||||
|
pipeline_id,
|
||||||
|
document_id,
|
||||||
|
);
|
||||||
|
txn.set_display_list(
|
||||||
|
epoch,
|
||||||
|
Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
|
||||||
|
layout_size,
|
||||||
|
builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
txn.set_root_pipeline(pipeline_id);
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
println!("Entering event loop");
|
||||||
|
events_loop.run_forever(|global_event| {
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
let mut custom_event = true;
|
||||||
|
|
||||||
|
let old_flags = debug_flags;
|
||||||
|
let win_event = match global_event {
|
||||||
|
winit::Event::WindowEvent { event, .. } => event,
|
||||||
|
_ => return winit::ControlFlow::Continue,
|
||||||
|
};
|
||||||
|
match win_event {
|
||||||
|
winit::WindowEvent::CloseRequested => return winit::ControlFlow::Break,
|
||||||
|
winit::WindowEvent::AxisMotion { .. } |
|
||||||
|
winit::WindowEvent::CursorMoved { .. } => {
|
||||||
|
custom_event = example.on_event(
|
||||||
|
win_event,
|
||||||
|
&mut api,
|
||||||
|
document_id,
|
||||||
|
);
|
||||||
|
// skip high-frequency events from triggering a frame draw.
|
||||||
|
if !custom_event {
|
||||||
|
return winit::ControlFlow::Continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(key),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => match key {
|
||||||
|
winit::VirtualKeyCode::Escape => return winit::ControlFlow::Break,
|
||||||
|
winit::VirtualKeyCode::P => debug_flags.toggle(DebugFlags::PROFILER_DBG),
|
||||||
|
winit::VirtualKeyCode::O => debug_flags.toggle(DebugFlags::RENDER_TARGET_DBG),
|
||||||
|
winit::VirtualKeyCode::I => debug_flags.toggle(DebugFlags::TEXTURE_CACHE_DBG),
|
||||||
|
winit::VirtualKeyCode::S => debug_flags.toggle(DebugFlags::COMPACT_PROFILER),
|
||||||
|
winit::VirtualKeyCode::T => debug_flags.toggle(DebugFlags::PICTURE_CACHING_DBG),
|
||||||
|
winit::VirtualKeyCode::Q => debug_flags.toggle(
|
||||||
|
DebugFlags::GPU_TIME_QUERIES | DebugFlags::GPU_SAMPLE_QUERIES
|
||||||
|
),
|
||||||
|
winit::VirtualKeyCode::F => debug_flags.toggle(
|
||||||
|
DebugFlags::NEW_FRAME_INDICATOR | DebugFlags::NEW_SCENE_INDICATOR
|
||||||
|
),
|
||||||
|
winit::VirtualKeyCode::G => debug_flags.toggle(DebugFlags::GPU_CACHE_DBG),
|
||||||
|
winit::VirtualKeyCode::Key1 => txn.set_document_view(
|
||||||
|
device_size.into(),
|
||||||
|
1.0
|
||||||
|
),
|
||||||
|
winit::VirtualKeyCode::Key2 => txn.set_document_view(
|
||||||
|
device_size.into(),
|
||||||
|
2.0
|
||||||
|
),
|
||||||
|
winit::VirtualKeyCode::M => api.notify_memory_pressure(),
|
||||||
|
winit::VirtualKeyCode::C => {
|
||||||
|
let path: PathBuf = "../captures/example".into();
|
||||||
|
//TODO: switch between SCENE/FRAME capture types
|
||||||
|
// based on "shift" modifier, when `glutin` is updated.
|
||||||
|
let bits = CaptureBits::all();
|
||||||
|
api.save_capture(path, bits);
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
custom_event = example.on_event(
|
||||||
|
win_event,
|
||||||
|
&mut api,
|
||||||
|
document_id,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
other => custom_event = example.on_event(
|
||||||
|
other,
|
||||||
|
&mut api,
|
||||||
|
document_id,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
if debug_flags != old_flags {
|
||||||
|
api.send_debug_cmd(DebugCommand::SetFlags(debug_flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
if custom_event {
|
||||||
|
let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
|
||||||
|
|
||||||
|
example.render(
|
||||||
|
&mut api,
|
||||||
|
&mut builder,
|
||||||
|
&mut txn,
|
||||||
|
device_size,
|
||||||
|
pipeline_id,
|
||||||
|
document_id,
|
||||||
|
);
|
||||||
|
txn.set_display_list(
|
||||||
|
epoch,
|
||||||
|
Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
|
||||||
|
layout_size,
|
||||||
|
builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
txn.generate_frame();
|
||||||
|
}
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
renderer.update();
|
||||||
|
renderer.render(device_size).unwrap();
|
||||||
|
let _ = renderer.flush_pipeline_info();
|
||||||
|
example.draw_custom(&*gl);
|
||||||
|
windowed_context.swap_buffers().ok();
|
||||||
|
|
||||||
|
winit::ControlFlow::Continue
|
||||||
|
});
|
||||||
|
|
||||||
|
renderer.deinit();
|
||||||
|
}
|
19
third_party/webrender/examples/common/image_helper.rs
vendored
Normal file
19
third_party/webrender/examples/common/image_helper.rs
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
use webrender::api::{ImageData, ImageDescriptor, ImageFormat, ImageDescriptorFlags};
|
||||||
|
|
||||||
|
pub fn make_checkerboard(width: u32, height: u32) -> (ImageDescriptor, ImageData) {
|
||||||
|
let mut image_data = Vec::new();
|
||||||
|
for y in 0 .. height {
|
||||||
|
for x in 0 .. width {
|
||||||
|
let lum = 255 * (((x & 8) == 0) ^ ((y & 8) == 0)) as u8;
|
||||||
|
image_data.extend_from_slice(&[lum, lum, lum, 0xff]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(
|
||||||
|
ImageDescriptor::new(width as i32, height as i32, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::new(image_data)
|
||||||
|
)
|
||||||
|
}
|
149
third_party/webrender/examples/document.rs
vendored
Normal file
149
third_party/webrender/examples/document.rs
vendored
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::Example;
|
||||||
|
use euclid::Scale;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
// This example creates multiple documents overlapping each other with
|
||||||
|
// specified layer indices.
|
||||||
|
|
||||||
|
struct Document {
|
||||||
|
id: DocumentId,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
content_rect: LayoutRect,
|
||||||
|
color: ColorF,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
documents: Vec<Document>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
fn init(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
device_pixel_ratio: f32,
|
||||||
|
) {
|
||||||
|
let init_data = vec![
|
||||||
|
(
|
||||||
|
PipelineId(1, 0),
|
||||||
|
-2,
|
||||||
|
ColorF::new(0.0, 1.0, 0.0, 1.0),
|
||||||
|
DeviceIntPoint::new(0, 0),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
PipelineId(2, 0),
|
||||||
|
-1,
|
||||||
|
ColorF::new(1.0, 1.0, 0.0, 1.0),
|
||||||
|
DeviceIntPoint::new(200, 0),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
PipelineId(3, 0),
|
||||||
|
0,
|
||||||
|
ColorF::new(1.0, 0.0, 0.0, 1.0),
|
||||||
|
DeviceIntPoint::new(200, 200),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
PipelineId(4, 0),
|
||||||
|
1,
|
||||||
|
ColorF::new(1.0, 0.0, 1.0, 1.0),
|
||||||
|
DeviceIntPoint::new(0, 200),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (pipeline_id, layer, color, offset) in init_data {
|
||||||
|
let size = DeviceIntSize::new(250, 250);
|
||||||
|
let bounds = DeviceIntRect::new(offset, size);
|
||||||
|
|
||||||
|
let document_id = api.add_document(size, layer);
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
txn.set_document_view(bounds, device_pixel_ratio);
|
||||||
|
txn.set_root_pipeline(pipeline_id);
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
self.documents.push(Document {
|
||||||
|
id: document_id,
|
||||||
|
pipeline_id,
|
||||||
|
content_rect: LayoutRect::new(
|
||||||
|
LayoutPoint::origin(),
|
||||||
|
bounds.size.to_f32() / Scale::new(device_pixel_ratio),
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
base_builder: &mut DisplayListBuilder,
|
||||||
|
_txn: &mut Transaction,
|
||||||
|
device_size: DeviceIntSize,
|
||||||
|
_pipeline_id: PipelineId,
|
||||||
|
_: DocumentId,
|
||||||
|
) {
|
||||||
|
if self.documents.is_empty() {
|
||||||
|
let device_pixel_ratio = device_size.width as f32 /
|
||||||
|
base_builder.content_size().width;
|
||||||
|
// this is the first run, hack around the boilerplate,
|
||||||
|
// which assumes an example only needs one document
|
||||||
|
self.init(api, device_pixel_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
for doc in &self.documents {
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(doc.pipeline_id);
|
||||||
|
let mut builder = DisplayListBuilder::new(
|
||||||
|
doc.pipeline_id,
|
||||||
|
doc.content_rect.size,
|
||||||
|
);
|
||||||
|
let local_rect = LayoutRect::new(
|
||||||
|
LayoutPoint::zero(),
|
||||||
|
doc.content_rect.size,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
doc.content_rect.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(local_rect, space_and_clip),
|
||||||
|
local_rect,
|
||||||
|
doc.color,
|
||||||
|
);
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
txn.set_display_list(
|
||||||
|
Epoch(0),
|
||||||
|
None,
|
||||||
|
doc.content_rect.size,
|
||||||
|
builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(doc.id, txn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
documents: Vec::new(),
|
||||||
|
};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
238
third_party/webrender/examples/frame_output.rs
vendored
Normal file
238
third_party/webrender/examples/frame_output.rs
vendored
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use euclid::Scale;
|
||||||
|
use gleam::gl;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
|
||||||
|
// This example demonstrates using the frame output feature to copy
|
||||||
|
// the output of a WR framebuffer to a custom texture.
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Document {
|
||||||
|
id: DocumentId,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
content_rect: LayoutRect,
|
||||||
|
color: ColorF,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
external_image_key: Option<ImageKey>,
|
||||||
|
output_document: Option<Document>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OutputHandler {
|
||||||
|
texture_id: gl::GLuint
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ExternalHandler {
|
||||||
|
texture_id: gl::GLuint
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputImageHandler for OutputHandler {
|
||||||
|
fn lock(&mut self, _id: PipelineId) -> Option<(u32, FramebufferIntSize)> {
|
||||||
|
Some((self.texture_id, FramebufferIntSize::new(500, 500)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unlock(&mut self, _id: PipelineId) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalImageHandler for ExternalHandler {
|
||||||
|
fn lock(
|
||||||
|
&mut self,
|
||||||
|
_key: ExternalImageId,
|
||||||
|
_channel_index: u8,
|
||||||
|
_rendering: ImageRendering
|
||||||
|
) -> ExternalImage {
|
||||||
|
ExternalImage {
|
||||||
|
uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
|
||||||
|
source: ExternalImageSource::NativeTexture(self.texture_id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
fn init_output_document(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
device_size: DeviceIntSize,
|
||||||
|
device_pixel_ratio: f32,
|
||||||
|
) {
|
||||||
|
// Generate the external image key that will be used to render the output document to the root document.
|
||||||
|
self.external_image_key = Some(api.generate_image_key());
|
||||||
|
|
||||||
|
let pipeline_id = PipelineId(1, 0);
|
||||||
|
let layer = 1;
|
||||||
|
let color = ColorF::new(1., 1., 0., 1.);
|
||||||
|
let document_id = api.add_document(device_size, layer);
|
||||||
|
api.enable_frame_output(document_id, pipeline_id, true);
|
||||||
|
api.set_document_view(
|
||||||
|
document_id,
|
||||||
|
device_size.into(),
|
||||||
|
device_pixel_ratio,
|
||||||
|
);
|
||||||
|
|
||||||
|
let document = Document {
|
||||||
|
id: document_id,
|
||||||
|
pipeline_id,
|
||||||
|
content_rect: LayoutRect::new(
|
||||||
|
LayoutPoint::zero(),
|
||||||
|
device_size.to_f32() / Scale::new(device_pixel_ratio),
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
|
||||||
|
txn.add_image(
|
||||||
|
self.external_image_key.unwrap(),
|
||||||
|
ImageDescriptor::new(100, 100, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::External(ExternalImageData {
|
||||||
|
id: ExternalImageId(0),
|
||||||
|
channel_index: 0,
|
||||||
|
image_type: ExternalImageType::TextureHandle(TextureTarget::Default),
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
let mut builder = DisplayListBuilder::new(
|
||||||
|
document.pipeline_id,
|
||||||
|
document.content_rect.size,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
document.content_rect.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(document.content_rect, space_and_clip),
|
||||||
|
document.content_rect,
|
||||||
|
ColorF::new(1.0, 1.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
|
||||||
|
txn.set_root_pipeline(pipeline_id);
|
||||||
|
txn.set_display_list(
|
||||||
|
Epoch(0),
|
||||||
|
Some(document.color),
|
||||||
|
document.content_rect.size,
|
||||||
|
builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(document.id, txn);
|
||||||
|
self.output_document = Some(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
_txn: &mut Transaction,
|
||||||
|
device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
if self.output_document.is_none() {
|
||||||
|
let device_pixel_ratio = device_size.width as f32 /
|
||||||
|
builder.content_size().width;
|
||||||
|
self.init_output_document(api, DeviceIntSize::new(200, 200), device_pixel_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
let bounds = (100, 100).to(200, 200);
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_image(
|
||||||
|
&CommonItemProperties::new(bounds, space_and_clip),
|
||||||
|
bounds,
|
||||||
|
ImageRendering::Auto,
|
||||||
|
AlphaType::PremultipliedAlpha,
|
||||||
|
self.external_image_key.unwrap(),
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_image_handlers(
|
||||||
|
&mut self,
|
||||||
|
gl: &dyn gl::Gl,
|
||||||
|
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||||
|
Option<Box<dyn OutputImageHandler>>) {
|
||||||
|
let texture_id = gl.gen_textures(1)[0];
|
||||||
|
|
||||||
|
gl.bind_texture(gl::TEXTURE_2D, texture_id);
|
||||||
|
gl.tex_parameter_i(
|
||||||
|
gl::TEXTURE_2D,
|
||||||
|
gl::TEXTURE_MAG_FILTER,
|
||||||
|
gl::LINEAR as gl::GLint,
|
||||||
|
);
|
||||||
|
gl.tex_parameter_i(
|
||||||
|
gl::TEXTURE_2D,
|
||||||
|
gl::TEXTURE_MIN_FILTER,
|
||||||
|
gl::LINEAR as gl::GLint,
|
||||||
|
);
|
||||||
|
gl.tex_parameter_i(
|
||||||
|
gl::TEXTURE_2D,
|
||||||
|
gl::TEXTURE_WRAP_S,
|
||||||
|
gl::CLAMP_TO_EDGE as gl::GLint,
|
||||||
|
);
|
||||||
|
gl.tex_parameter_i(
|
||||||
|
gl::TEXTURE_2D,
|
||||||
|
gl::TEXTURE_WRAP_T,
|
||||||
|
gl::CLAMP_TO_EDGE as gl::GLint,
|
||||||
|
);
|
||||||
|
gl.tex_image_2d(
|
||||||
|
gl::TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl::RGBA as gl::GLint,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
0,
|
||||||
|
gl::BGRA,
|
||||||
|
gl::UNSIGNED_BYTE,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
gl.bind_texture(gl::TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
(
|
||||||
|
Some(Box::new(ExternalHandler { texture_id })),
|
||||||
|
Some(Box::new(OutputHandler { texture_id }))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
external_image_key: None,
|
||||||
|
output_document: None
|
||||||
|
};
|
||||||
|
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
95
third_party/webrender/examples/iframe.rs
vendored
Normal file
95
third_party/webrender/examples/iframe.rs
vendored
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
// This example uses the push_iframe API to nest a second pipeline's displaylist
|
||||||
|
// inside the root pipeline's display list. When it works, a green square is
|
||||||
|
// shown. If it fails, a red square is shown.
|
||||||
|
|
||||||
|
struct App {}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
_txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
// All the sub_* things are for the nested pipeline
|
||||||
|
let sub_size = DeviceIntSize::new(100, 100);
|
||||||
|
let sub_bounds = (0, 0).to(sub_size.width as i32, sub_size.height as i32);
|
||||||
|
|
||||||
|
let sub_pipeline_id = PipelineId(pipeline_id.0, 42);
|
||||||
|
let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id, sub_bounds.size);
|
||||||
|
let mut space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
|
||||||
|
sub_builder.push_simple_stacking_context(
|
||||||
|
sub_bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
// green rect visible == success
|
||||||
|
sub_builder.push_rect(
|
||||||
|
&CommonItemProperties::new(sub_bounds, space_and_clip),
|
||||||
|
sub_bounds,
|
||||||
|
ColorF::new(0.0, 1.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
sub_builder.pop_stacking_context();
|
||||||
|
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
txn.set_display_list(
|
||||||
|
Epoch(0),
|
||||||
|
None,
|
||||||
|
sub_bounds.size,
|
||||||
|
sub_builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
space_and_clip.spatial_id = builder.push_reference_frame(
|
||||||
|
sub_bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
TransformStyle::Flat,
|
||||||
|
PropertyBinding::Binding(PropertyBindingKey::new(42), LayoutTransform::identity()),
|
||||||
|
ReferenceFrameKind::Transform,
|
||||||
|
);
|
||||||
|
|
||||||
|
// And this is for the root pipeline
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
sub_bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
// red rect under the iframe: if this is visible, things have gone wrong
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(sub_bounds, space_and_clip),
|
||||||
|
sub_bounds,
|
||||||
|
ColorF::new(1.0, 0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
builder.push_iframe(sub_bounds, sub_bounds, &space_and_clip, sub_pipeline_id, false);
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
builder.pop_reference_frame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
121
third_party/webrender/examples/image_resize.rs
vendored
Normal file
121
third_party/webrender/examples/image_resize.rs
vendored
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
#[path = "common/image_helper.rs"]
|
||||||
|
mod image_helper;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
image_key: ImageKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let (image_descriptor, image_data) = image_helper::make_checkerboard(32, 32);
|
||||||
|
txn.add_image(
|
||||||
|
self.image_key,
|
||||||
|
image_descriptor,
|
||||||
|
image_data,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
let bounds = (0, 0).to(512, 512);
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
let image_size = LayoutSize::new(100.0, 100.0);
|
||||||
|
|
||||||
|
builder.push_image(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
|
||||||
|
space_and_clip,
|
||||||
|
),
|
||||||
|
bounds,
|
||||||
|
ImageRendering::Auto,
|
||||||
|
AlphaType::PremultipliedAlpha,
|
||||||
|
self.image_key,
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_image(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size),
|
||||||
|
space_and_clip,
|
||||||
|
),
|
||||||
|
bounds,
|
||||||
|
ImageRendering::Pixelated,
|
||||||
|
AlphaType::PremultipliedAlpha,
|
||||||
|
self.image_key,
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(&mut self, event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||||
|
match event {
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(winit::VirtualKeyCode::Space),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let mut image_data = Vec::new();
|
||||||
|
for y in 0 .. 64 {
|
||||||
|
for x in 0 .. 64 {
|
||||||
|
let r = 255 * ((y & 32) == 0) as u8;
|
||||||
|
let g = 255 * ((x & 32) == 0) as u8;
|
||||||
|
image_data.extend_from_slice(&[0, g, r, 0xff]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
txn.update_image(
|
||||||
|
self.image_key,
|
||||||
|
ImageDescriptor::new(64, 64, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::new(image_data),
|
||||||
|
&DirtyRect::All,
|
||||||
|
);
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
image_key: ImageKey(IdNamespace(0), 0),
|
||||||
|
};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
326
third_party/webrender/examples/multiwindow.rs
vendored
Normal file
326
third_party/webrender/examples/multiwindow.rs
vendored
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
use gleam::gl;
|
||||||
|
use glutin::NotCurrent;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
use webrender::DebugFlags;
|
||||||
|
use winit::dpi::LogicalSize;
|
||||||
|
|
||||||
|
struct Notifier {
|
||||||
|
events_proxy: winit::EventsLoopProxy,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Notifier {
|
||||||
|
fn new(events_proxy: winit::EventsLoopProxy) -> Notifier {
|
||||||
|
Notifier { events_proxy }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderNotifier for Notifier {
|
||||||
|
fn clone(&self) -> Box<dyn RenderNotifier> {
|
||||||
|
Box::new(Notifier {
|
||||||
|
events_proxy: self.events_proxy.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wake_up(&self) {
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
let _ = self.events_proxy.wakeup();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_frame_ready(&self,
|
||||||
|
_: DocumentId,
|
||||||
|
_scrolled: bool,
|
||||||
|
_composite_needed: bool,
|
||||||
|
_render_time: Option<u64>) {
|
||||||
|
self.wake_up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Window {
|
||||||
|
events_loop: winit::EventsLoop, //TODO: share events loop?
|
||||||
|
context: Option<glutin::WindowedContext<NotCurrent>>,
|
||||||
|
renderer: webrender::Renderer,
|
||||||
|
name: &'static str,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
document_id: DocumentId,
|
||||||
|
epoch: Epoch,
|
||||||
|
api: RenderApi,
|
||||||
|
font_instance_key: FontInstanceKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Window {
|
||||||
|
fn new(name: &'static str, clear_color: ColorF) -> Self {
|
||||||
|
let events_loop = winit::EventsLoop::new();
|
||||||
|
let window_builder = winit::WindowBuilder::new()
|
||||||
|
.with_title(name)
|
||||||
|
.with_multitouch()
|
||||||
|
.with_dimensions(LogicalSize::new(800., 600.));
|
||||||
|
let context = glutin::ContextBuilder::new()
|
||||||
|
.with_gl(glutin::GlRequest::GlThenGles {
|
||||||
|
opengl_version: (3, 2),
|
||||||
|
opengles_version: (3, 0),
|
||||||
|
})
|
||||||
|
.build_windowed(window_builder, &events_loop)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let context = unsafe { context.make_current().unwrap() };
|
||||||
|
|
||||||
|
let gl = match context.get_api() {
|
||||||
|
glutin::Api::OpenGl => unsafe {
|
||||||
|
gl::GlFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
|
||||||
|
},
|
||||||
|
glutin::Api::OpenGlEs => unsafe {
|
||||||
|
gl::GlesFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
|
||||||
|
},
|
||||||
|
glutin::Api::WebGl => unimplemented!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let device_pixel_ratio = context.window().get_hidpi_factor() as f32;
|
||||||
|
|
||||||
|
let opts = webrender::RendererOptions {
|
||||||
|
device_pixel_ratio,
|
||||||
|
clear_color: Some(clear_color),
|
||||||
|
..webrender::RendererOptions::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let device_size = {
|
||||||
|
let size = context
|
||||||
|
.window()
|
||||||
|
.get_inner_size()
|
||||||
|
.unwrap()
|
||||||
|
.to_physical(device_pixel_ratio as f64);
|
||||||
|
DeviceIntSize::new(size.width as i32, size.height as i32)
|
||||||
|
};
|
||||||
|
let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
|
||||||
|
let (renderer, sender) = webrender::Renderer::new(gl.clone(), notifier, opts, None, device_size).unwrap();
|
||||||
|
let mut api = sender.create_api();
|
||||||
|
let document_id = api.add_document(device_size, 0);
|
||||||
|
|
||||||
|
let epoch = Epoch(0);
|
||||||
|
let pipeline_id = PipelineId(0, 0);
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
|
||||||
|
let font_key = api.generate_font_key();
|
||||||
|
let font_bytes = load_file("../wrench/reftests/text/FreeSans.ttf");
|
||||||
|
txn.add_raw_font(font_key, font_bytes, 0);
|
||||||
|
|
||||||
|
let font_instance_key = api.generate_font_instance_key();
|
||||||
|
txn.add_font_instance(font_instance_key, font_key, 32.0, None, None, Vec::new());
|
||||||
|
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
Window {
|
||||||
|
events_loop,
|
||||||
|
context: Some(unsafe { context.make_not_current().unwrap() }),
|
||||||
|
renderer,
|
||||||
|
name,
|
||||||
|
epoch,
|
||||||
|
pipeline_id,
|
||||||
|
document_id,
|
||||||
|
api,
|
||||||
|
font_instance_key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tick(&mut self) -> bool {
|
||||||
|
let mut do_exit = false;
|
||||||
|
let my_name = &self.name;
|
||||||
|
let renderer = &mut self.renderer;
|
||||||
|
let api = &mut self.api;
|
||||||
|
|
||||||
|
self.events_loop.poll_events(|global_event| match global_event {
|
||||||
|
winit::Event::WindowEvent { event, .. } => match event {
|
||||||
|
winit::WindowEvent::CloseRequested |
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
virtual_keycode: Some(winit::VirtualKeyCode::Escape),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
do_exit = true
|
||||||
|
}
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(winit::VirtualKeyCode::P),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
println!("set flags {}", my_name);
|
||||||
|
api.send_debug_cmd(DebugCommand::SetFlags(DebugFlags::PROFILER_DBG))
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
});
|
||||||
|
if do_exit {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let context = unsafe { self.context.take().unwrap().make_current().unwrap() };
|
||||||
|
let device_pixel_ratio = context.window().get_hidpi_factor() as f32;
|
||||||
|
let device_size = {
|
||||||
|
let size = context
|
||||||
|
.window()
|
||||||
|
.get_inner_size()
|
||||||
|
.unwrap()
|
||||||
|
.to_physical(device_pixel_ratio as f64);
|
||||||
|
DeviceIntSize::new(size.width as i32, size.height as i32)
|
||||||
|
};
|
||||||
|
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
let mut builder = DisplayListBuilder::new(self.pipeline_id, layout_size);
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(self.pipeline_id);
|
||||||
|
|
||||||
|
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_rect(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(100.0, 200.0),
|
||||||
|
LayoutSize::new(100.0, 200.0),
|
||||||
|
),
|
||||||
|
space_and_clip,
|
||||||
|
),
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(100.0, 200.0),
|
||||||
|
LayoutSize::new(100.0, 200.0),
|
||||||
|
),
|
||||||
|
ColorF::new(0.0, 1.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
let text_bounds = LayoutRect::new(
|
||||||
|
LayoutPoint::new(100.0, 50.0),
|
||||||
|
LayoutSize::new(700.0, 200.0)
|
||||||
|
);
|
||||||
|
let glyphs = vec![
|
||||||
|
GlyphInstance {
|
||||||
|
index: 48,
|
||||||
|
point: LayoutPoint::new(100.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 68,
|
||||||
|
point: LayoutPoint::new(150.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 80,
|
||||||
|
point: LayoutPoint::new(200.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 82,
|
||||||
|
point: LayoutPoint::new(250.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 81,
|
||||||
|
point: LayoutPoint::new(300.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 3,
|
||||||
|
point: LayoutPoint::new(350.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 86,
|
||||||
|
point: LayoutPoint::new(400.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 79,
|
||||||
|
point: LayoutPoint::new(450.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 72,
|
||||||
|
point: LayoutPoint::new(500.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 83,
|
||||||
|
point: LayoutPoint::new(550.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 87,
|
||||||
|
point: LayoutPoint::new(600.0, 100.0),
|
||||||
|
},
|
||||||
|
GlyphInstance {
|
||||||
|
index: 17,
|
||||||
|
point: LayoutPoint::new(650.0, 100.0),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
builder.push_text(
|
||||||
|
&CommonItemProperties::new(
|
||||||
|
text_bounds,
|
||||||
|
space_and_clip,
|
||||||
|
),
|
||||||
|
text_bounds,
|
||||||
|
&glyphs,
|
||||||
|
self.font_instance_key,
|
||||||
|
ColorF::new(1.0, 1.0, 0.0, 1.0),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
|
||||||
|
txn.set_display_list(
|
||||||
|
self.epoch,
|
||||||
|
None,
|
||||||
|
layout_size,
|
||||||
|
builder.finalize(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
txn.set_root_pipeline(self.pipeline_id);
|
||||||
|
txn.generate_frame();
|
||||||
|
api.send_transaction(self.document_id, txn);
|
||||||
|
|
||||||
|
renderer.update();
|
||||||
|
renderer.render(device_size).unwrap();
|
||||||
|
context.swap_buffers().ok();
|
||||||
|
|
||||||
|
self.context = Some(unsafe { context.make_not_current().unwrap() });
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self) {
|
||||||
|
self.renderer.deinit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut win1 = Window::new("window1", ColorF::new(0.3, 0.0, 0.0, 1.0));
|
||||||
|
let mut win2 = Window::new("window2", ColorF::new(0.0, 0.3, 0.0, 1.0));
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if win1.tick() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if win2.tick() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
win1.deinit();
|
||||||
|
win2.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_file(name: &str) -> Vec<u8> {
|
||||||
|
let mut file = File::open(name).unwrap();
|
||||||
|
let mut buffer = vec![];
|
||||||
|
file.read_to_end(&mut buffer).unwrap();
|
||||||
|
buffer
|
||||||
|
}
|
231
third_party/webrender/examples/scrolling.rs
vendored
Normal file
231
third_party/webrender/examples/scrolling.rs
vendored
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate euclid;
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use euclid::SideOffsets2D;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
use winit::dpi::LogicalPosition;
|
||||||
|
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
cursor_position: WorldPoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
_api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
_txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
LayoutPoint::zero(),
|
||||||
|
root_space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
if true {
|
||||||
|
// scrolling and clips stuff
|
||||||
|
// let's make a scrollbox
|
||||||
|
let scrollbox = (0, 0).to(300, 400);
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
LayoutPoint::new(10., 10.),
|
||||||
|
root_space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
// set the scrolling clip
|
||||||
|
let space_and_clip1 = builder.define_scroll_frame(
|
||||||
|
&root_space_and_clip,
|
||||||
|
None,
|
||||||
|
(0, 0).by(1000, 1000),
|
||||||
|
scrollbox,
|
||||||
|
ScrollSensitivity::ScriptAndInputEvents,
|
||||||
|
LayoutVector2D::zero(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// now put some content into it.
|
||||||
|
// start with a white background
|
||||||
|
let mut info = CommonItemProperties::new((0, 0).to(1000, 1000), space_and_clip1);
|
||||||
|
info.hit_info = Some((0, 1));
|
||||||
|
builder.push_rect(&info, info.clip_rect, ColorF::new(1.0, 1.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
// let's make a 50x50 blue square as a visual reference
|
||||||
|
let mut info = CommonItemProperties::new((0, 0).to(50, 50), space_and_clip1);
|
||||||
|
info.hit_info = Some((0, 2));
|
||||||
|
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 0.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
// and a 50x50 green square next to it with an offset clip
|
||||||
|
// to see what that looks like
|
||||||
|
let mut info = CommonItemProperties::new(
|
||||||
|
(50, 0).to(100, 50).intersection(&(60, 10).to(110, 60)).unwrap(),
|
||||||
|
space_and_clip1,
|
||||||
|
);
|
||||||
|
info.hit_info = Some((0, 3));
|
||||||
|
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 1.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
// Below the above rectangles, set up a nested scrollbox. It's still in
|
||||||
|
// the same stacking context, so note that the rects passed in need to
|
||||||
|
// be relative to the stacking context.
|
||||||
|
let space_and_clip2 = builder.define_scroll_frame(
|
||||||
|
&space_and_clip1,
|
||||||
|
None,
|
||||||
|
(0, 100).to(300, 1000),
|
||||||
|
(0, 100).to(200, 300),
|
||||||
|
ScrollSensitivity::ScriptAndInputEvents,
|
||||||
|
LayoutVector2D::zero(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// give it a giant gray background just to distinguish it and to easily
|
||||||
|
// visually identify the nested scrollbox
|
||||||
|
let mut info = CommonItemProperties::new(
|
||||||
|
(-1000, -1000).to(5000, 5000),
|
||||||
|
space_and_clip2,
|
||||||
|
);
|
||||||
|
info.hit_info = Some((0, 4));
|
||||||
|
builder.push_rect(&info, info.clip_rect, ColorF::new(0.5, 0.5, 0.5, 1.0));
|
||||||
|
|
||||||
|
// add a teal square to visualize the scrolling/clipping behaviour
|
||||||
|
// as you scroll the nested scrollbox
|
||||||
|
let mut info = CommonItemProperties::new((0, 200).to(50, 250), space_and_clip2);
|
||||||
|
info.hit_info = Some((0, 5));
|
||||||
|
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 1.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
// Add a sticky frame. It will "stick" twice while scrolling, once
|
||||||
|
// at a margin of 10px from the bottom, for 40 pixels of scrolling,
|
||||||
|
// and once at a margin of 10px from the top, for 60 pixels of
|
||||||
|
// scrolling.
|
||||||
|
let sticky_id = builder.define_sticky_frame(
|
||||||
|
space_and_clip2.spatial_id,
|
||||||
|
(50, 350).by(50, 50),
|
||||||
|
SideOffsets2D::new(Some(10.0), None, Some(10.0), None),
|
||||||
|
StickyOffsetBounds::new(-40.0, 60.0),
|
||||||
|
StickyOffsetBounds::new(0.0, 0.0),
|
||||||
|
LayoutVector2D::new(0.0, 0.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut info = CommonItemProperties::new(
|
||||||
|
(50, 350).by(50, 50),
|
||||||
|
SpaceAndClipInfo {
|
||||||
|
spatial_id: sticky_id,
|
||||||
|
clip_id: space_and_clip2.clip_id,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
info.hit_info = Some((0, 6));
|
||||||
|
builder.push_rect(
|
||||||
|
&info,
|
||||||
|
info.clip_rect,
|
||||||
|
ColorF::new(0.5, 0.5, 1.0, 1.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
// just for good measure add another teal square further down and to
|
||||||
|
// the right, which can be scrolled into view by the user
|
||||||
|
let mut info = CommonItemProperties::new(
|
||||||
|
(250, 350).to(300, 400),
|
||||||
|
space_and_clip2,
|
||||||
|
);
|
||||||
|
info.hit_info = Some((0, 7));
|
||||||
|
builder.push_rect(&info, info.clip_rect, ColorF::new(0.0, 1.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(&mut self, event: winit::WindowEvent, api: &mut RenderApi, document_id: DocumentId) -> bool {
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
match event {
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(key),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let offset = match key {
|
||||||
|
winit::VirtualKeyCode::Down => Some((0.0, -10.0)),
|
||||||
|
winit::VirtualKeyCode::Up => Some((0.0, 10.0)),
|
||||||
|
winit::VirtualKeyCode::Right => Some((-10.0, 0.0)),
|
||||||
|
winit::VirtualKeyCode::Left => Some((10.0, 0.0)),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let zoom = match key {
|
||||||
|
winit::VirtualKeyCode::Key0 => Some(1.0),
|
||||||
|
winit::VirtualKeyCode::Minus => Some(0.8),
|
||||||
|
winit::VirtualKeyCode::Equals => Some(1.25),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(offset) = offset {
|
||||||
|
txn.scroll(
|
||||||
|
ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)),
|
||||||
|
self.cursor_position,
|
||||||
|
);
|
||||||
|
txn.generate_frame();
|
||||||
|
}
|
||||||
|
if let Some(zoom) = zoom {
|
||||||
|
txn.set_pinch_zoom(ZoomFactor::new(zoom));
|
||||||
|
txn.generate_frame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
winit::WindowEvent::CursorMoved { position: LogicalPosition { x, y }, .. } => {
|
||||||
|
self.cursor_position = WorldPoint::new(x as f32, y as f32);
|
||||||
|
}
|
||||||
|
winit::WindowEvent::MouseWheel { delta, .. } => {
|
||||||
|
const LINE_HEIGHT: f32 = 38.0;
|
||||||
|
let (dx, dy) = match delta {
|
||||||
|
winit::MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT),
|
||||||
|
winit::MouseScrollDelta::PixelDelta(pos) => (pos.x as f32, pos.y as f32),
|
||||||
|
};
|
||||||
|
|
||||||
|
txn.scroll(
|
||||||
|
ScrollLocation::Delta(LayoutVector2D::new(dx, dy)),
|
||||||
|
self.cursor_position,
|
||||||
|
);
|
||||||
|
txn.generate_frame();
|
||||||
|
}
|
||||||
|
winit::WindowEvent::MouseInput { .. } => {
|
||||||
|
let results = api.hit_test(
|
||||||
|
document_id,
|
||||||
|
None,
|
||||||
|
self.cursor_position,
|
||||||
|
HitTestFlags::FIND_ALL
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("Hit test results:");
|
||||||
|
for item in &results.items {
|
||||||
|
println!(" • {:?}", item);
|
||||||
|
}
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
cursor_position: WorldPoint::zero(),
|
||||||
|
};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
322
third_party/webrender/examples/texture_cache_stress.rs
vendored
Normal file
322
third_party/webrender/examples/texture_cache_stress.rs
vendored
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::{Example, HandyDandyRectBuilder};
|
||||||
|
use gleam::gl;
|
||||||
|
use std::mem;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
|
||||||
|
struct ImageGenerator {
|
||||||
|
patterns: [[u8; 3]; 6],
|
||||||
|
next_pattern: usize,
|
||||||
|
current_image: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImageGenerator {
|
||||||
|
fn new() -> Self {
|
||||||
|
ImageGenerator {
|
||||||
|
next_pattern: 0,
|
||||||
|
patterns: [
|
||||||
|
[1, 0, 0],
|
||||||
|
[0, 1, 0],
|
||||||
|
[0, 0, 1],
|
||||||
|
[1, 1, 0],
|
||||||
|
[0, 1, 1],
|
||||||
|
[1, 0, 1],
|
||||||
|
],
|
||||||
|
current_image: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_image(&mut self, size: i32) {
|
||||||
|
let pattern = &self.patterns[self.next_pattern];
|
||||||
|
self.current_image.clear();
|
||||||
|
for y in 0 .. size {
|
||||||
|
for x in 0 .. size {
|
||||||
|
let lum = 255 * (1 - (((x & 8) == 0) ^ ((y & 8) == 0)) as u8);
|
||||||
|
self.current_image.extend_from_slice(&[
|
||||||
|
lum * pattern[0],
|
||||||
|
lum * pattern[1],
|
||||||
|
lum * pattern[2],
|
||||||
|
0xff,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.next_pattern = (self.next_pattern + 1) % self.patterns.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn take(&mut self) -> Vec<u8> {
|
||||||
|
mem::replace(&mut self.current_image, Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalImageHandler for ImageGenerator {
|
||||||
|
fn lock(
|
||||||
|
&mut self,
|
||||||
|
_key: ExternalImageId,
|
||||||
|
channel_index: u8,
|
||||||
|
_rendering: ImageRendering
|
||||||
|
) -> ExternalImage {
|
||||||
|
self.generate_image(channel_index as i32);
|
||||||
|
ExternalImage {
|
||||||
|
uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
|
||||||
|
source: ExternalImageSource::RawData(&self.current_image),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
stress_keys: Vec<ImageKey>,
|
||||||
|
image_key: Option<ImageKey>,
|
||||||
|
image_generator: ImageGenerator,
|
||||||
|
swap_keys: Vec<ImageKey>,
|
||||||
|
swap_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let bounds = (0, 0).to(512, 512);
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
let x0 = 50.0;
|
||||||
|
let y0 = 50.0;
|
||||||
|
let image_size = LayoutSize::new(4.0, 4.0);
|
||||||
|
|
||||||
|
if self.swap_keys.is_empty() {
|
||||||
|
let key0 = api.generate_image_key();
|
||||||
|
let key1 = api.generate_image_key();
|
||||||
|
|
||||||
|
self.image_generator.generate_image(128);
|
||||||
|
txn.add_image(
|
||||||
|
key0,
|
||||||
|
ImageDescriptor::new(128, 128, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::new(self.image_generator.take()),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.image_generator.generate_image(128);
|
||||||
|
txn.add_image(
|
||||||
|
key1,
|
||||||
|
ImageDescriptor::new(128, 128, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::new(self.image_generator.take()),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.swap_keys.push(key0);
|
||||||
|
self.swap_keys.push(key1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, key) in self.stress_keys.iter().enumerate() {
|
||||||
|
let x = (i % 128) as f32;
|
||||||
|
let y = (i / 128) as f32;
|
||||||
|
let info = CommonItemProperties::new(
|
||||||
|
LayoutRect::new(
|
||||||
|
LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y),
|
||||||
|
image_size,
|
||||||
|
),
|
||||||
|
space_and_clip,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.push_image(
|
||||||
|
&info,
|
||||||
|
bounds,
|
||||||
|
ImageRendering::Auto,
|
||||||
|
AlphaType::PremultipliedAlpha,
|
||||||
|
*key,
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(image_key) = self.image_key {
|
||||||
|
let image_size = LayoutSize::new(100.0, 100.0);
|
||||||
|
let info = CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
|
||||||
|
space_and_clip,
|
||||||
|
);
|
||||||
|
builder.push_image(
|
||||||
|
&info,
|
||||||
|
bounds,
|
||||||
|
ImageRendering::Auto,
|
||||||
|
AlphaType::PremultipliedAlpha,
|
||||||
|
image_key,
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let swap_key = self.swap_keys[self.swap_index];
|
||||||
|
let image_size = LayoutSize::new(64.0, 64.0);
|
||||||
|
let info = CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::new(100.0, 400.0), image_size),
|
||||||
|
space_and_clip,
|
||||||
|
);
|
||||||
|
builder.push_image(
|
||||||
|
&info,
|
||||||
|
bounds,
|
||||||
|
ImageRendering::Auto,
|
||||||
|
AlphaType::PremultipliedAlpha,
|
||||||
|
swap_key,
|
||||||
|
ColorF::WHITE,
|
||||||
|
);
|
||||||
|
self.swap_index = 1 - self.swap_index;
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(
|
||||||
|
&mut self,
|
||||||
|
event: winit::WindowEvent,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
document_id: DocumentId,
|
||||||
|
) -> bool {
|
||||||
|
match event {
|
||||||
|
winit::WindowEvent::KeyboardInput {
|
||||||
|
input: winit::KeyboardInput {
|
||||||
|
state: winit::ElementState::Pressed,
|
||||||
|
virtual_keycode: Some(key),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let mut txn = Transaction::new();
|
||||||
|
|
||||||
|
match key {
|
||||||
|
winit::VirtualKeyCode::S => {
|
||||||
|
self.stress_keys.clear();
|
||||||
|
|
||||||
|
for _ in 0 .. 16 {
|
||||||
|
for _ in 0 .. 16 {
|
||||||
|
let size = 4;
|
||||||
|
|
||||||
|
let image_key = api.generate_image_key();
|
||||||
|
|
||||||
|
self.image_generator.generate_image(size);
|
||||||
|
|
||||||
|
txn.add_image(
|
||||||
|
image_key,
|
||||||
|
ImageDescriptor::new(
|
||||||
|
size,
|
||||||
|
size,
|
||||||
|
ImageFormat::BGRA8,
|
||||||
|
ImageDescriptorFlags::IS_OPAQUE,
|
||||||
|
),
|
||||||
|
ImageData::new(self.image_generator.take()),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.stress_keys.push(image_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
winit::VirtualKeyCode::D => if let Some(image_key) = self.image_key.take() {
|
||||||
|
txn.delete_image(image_key);
|
||||||
|
},
|
||||||
|
winit::VirtualKeyCode::U => if let Some(image_key) = self.image_key {
|
||||||
|
let size = 128;
|
||||||
|
self.image_generator.generate_image(size);
|
||||||
|
|
||||||
|
txn.update_image(
|
||||||
|
image_key,
|
||||||
|
ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::new(self.image_generator.take()),
|
||||||
|
&DirtyRect::All,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
winit::VirtualKeyCode::E => {
|
||||||
|
if let Some(image_key) = self.image_key.take() {
|
||||||
|
txn.delete_image(image_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let size = 32;
|
||||||
|
let image_key = api.generate_image_key();
|
||||||
|
|
||||||
|
let image_data = ExternalImageData {
|
||||||
|
id: ExternalImageId(0),
|
||||||
|
channel_index: size as u8,
|
||||||
|
image_type: ExternalImageType::Buffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
txn.add_image(
|
||||||
|
image_key,
|
||||||
|
ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::External(image_data),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.image_key = Some(image_key);
|
||||||
|
}
|
||||||
|
winit::VirtualKeyCode::R => {
|
||||||
|
if let Some(image_key) = self.image_key.take() {
|
||||||
|
txn.delete_image(image_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let image_key = api.generate_image_key();
|
||||||
|
let size = 32;
|
||||||
|
self.image_generator.generate_image(size);
|
||||||
|
|
||||||
|
txn.add_image(
|
||||||
|
image_key,
|
||||||
|
ImageDescriptor::new(size, size, ImageFormat::BGRA8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::new(self.image_generator.take()),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.image_key = Some(image_key);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
api.send_transaction(document_id, txn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_image_handlers(
|
||||||
|
&mut self,
|
||||||
|
_gl: &dyn gl::Gl,
|
||||||
|
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||||
|
Option<Box<dyn OutputImageHandler>>) {
|
||||||
|
(Some(Box::new(ImageGenerator::new())), None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
image_key: None,
|
||||||
|
stress_keys: Vec::new(),
|
||||||
|
image_generator: ImageGenerator::new(),
|
||||||
|
swap_keys: Vec::new(),
|
||||||
|
swap_index: 0,
|
||||||
|
};
|
||||||
|
boilerplate::main_wrapper(&mut app, None);
|
||||||
|
}
|
226
third_party/webrender/examples/yuv.rs
vendored
Normal file
226
third_party/webrender/examples/yuv.rs
vendored
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
extern crate gleam;
|
||||||
|
extern crate glutin;
|
||||||
|
extern crate webrender;
|
||||||
|
extern crate winit;
|
||||||
|
|
||||||
|
#[path = "common/boilerplate.rs"]
|
||||||
|
mod boilerplate;
|
||||||
|
|
||||||
|
use crate::boilerplate::Example;
|
||||||
|
use gleam::gl;
|
||||||
|
use webrender::api::*;
|
||||||
|
use webrender::api::units::*;
|
||||||
|
|
||||||
|
|
||||||
|
fn init_gl_texture(
|
||||||
|
id: gl::GLuint,
|
||||||
|
internal: gl::GLenum,
|
||||||
|
external: gl::GLenum,
|
||||||
|
bytes: &[u8],
|
||||||
|
gl: &dyn gl::Gl,
|
||||||
|
) {
|
||||||
|
gl.bind_texture(gl::TEXTURE_2D, id);
|
||||||
|
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as gl::GLint);
|
||||||
|
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as gl::GLint);
|
||||||
|
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint);
|
||||||
|
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint);
|
||||||
|
gl.tex_image_2d(
|
||||||
|
gl::TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
internal as gl::GLint,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
0,
|
||||||
|
external,
|
||||||
|
gl::UNSIGNED_BYTE,
|
||||||
|
Some(bytes),
|
||||||
|
);
|
||||||
|
gl.bind_texture(gl::TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct YuvImageProvider {
|
||||||
|
texture_ids: Vec<gl::GLuint>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl YuvImageProvider {
|
||||||
|
fn new(gl: &dyn gl::Gl) -> Self {
|
||||||
|
let texture_ids = gl.gen_textures(4);
|
||||||
|
|
||||||
|
init_gl_texture(texture_ids[0], gl::RED, gl::RED, &[127; 100 * 100], gl);
|
||||||
|
init_gl_texture(texture_ids[1], gl::RG8, gl::RG, &[0; 100 * 100 * 2], gl);
|
||||||
|
init_gl_texture(texture_ids[2], gl::RED, gl::RED, &[127; 100 * 100], gl);
|
||||||
|
init_gl_texture(texture_ids[3], gl::RED, gl::RED, &[127; 100 * 100], gl);
|
||||||
|
|
||||||
|
YuvImageProvider {
|
||||||
|
texture_ids
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalImageHandler for YuvImageProvider {
|
||||||
|
fn lock(
|
||||||
|
&mut self,
|
||||||
|
key: ExternalImageId,
|
||||||
|
_channel_index: u8,
|
||||||
|
_rendering: ImageRendering
|
||||||
|
) -> ExternalImage {
|
||||||
|
let id = self.texture_ids[key.0 as usize];
|
||||||
|
ExternalImage {
|
||||||
|
uv: TexelRect::new(0.0, 0.0, 1.0, 1.0),
|
||||||
|
source: ExternalImageSource::NativeTexture(id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
texture_id: gl::GLuint,
|
||||||
|
current_value: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Example for App {
|
||||||
|
fn render(
|
||||||
|
&mut self,
|
||||||
|
api: &mut RenderApi,
|
||||||
|
builder: &mut DisplayListBuilder,
|
||||||
|
txn: &mut Transaction,
|
||||||
|
_device_size: DeviceIntSize,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
||||||
|
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
|
||||||
|
|
||||||
|
builder.push_simple_stacking_context(
|
||||||
|
bounds.origin,
|
||||||
|
space_and_clip.spatial_id,
|
||||||
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
||||||
|
);
|
||||||
|
|
||||||
|
let yuv_chanel1 = api.generate_image_key();
|
||||||
|
let yuv_chanel2 = api.generate_image_key();
|
||||||
|
let yuv_chanel2_1 = api.generate_image_key();
|
||||||
|
let yuv_chanel3 = api.generate_image_key();
|
||||||
|
txn.add_image(
|
||||||
|
yuv_chanel1,
|
||||||
|
ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::External(ExternalImageData {
|
||||||
|
id: ExternalImageId(0),
|
||||||
|
channel_index: 0,
|
||||||
|
image_type: ExternalImageType::TextureHandle(
|
||||||
|
TextureTarget::Default,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
txn.add_image(
|
||||||
|
yuv_chanel2,
|
||||||
|
ImageDescriptor::new(100, 100, ImageFormat::RG8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::External(ExternalImageData {
|
||||||
|
id: ExternalImageId(1),
|
||||||
|
channel_index: 0,
|
||||||
|
image_type: ExternalImageType::TextureHandle(
|
||||||
|
TextureTarget::Default,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
txn.add_image(
|
||||||
|
yuv_chanel2_1,
|
||||||
|
ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::External(ExternalImageData {
|
||||||
|
id: ExternalImageId(2),
|
||||||
|
channel_index: 0,
|
||||||
|
image_type: ExternalImageType::TextureHandle(
|
||||||
|
TextureTarget::Default,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
txn.add_image(
|
||||||
|
yuv_chanel3,
|
||||||
|
ImageDescriptor::new(100, 100, ImageFormat::R8, ImageDescriptorFlags::IS_OPAQUE),
|
||||||
|
ImageData::External(ExternalImageData {
|
||||||
|
id: ExternalImageId(3),
|
||||||
|
channel_index: 0,
|
||||||
|
image_type: ExternalImageType::TextureHandle(
|
||||||
|
TextureTarget::Default,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
let info = CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)),
|
||||||
|
space_and_clip,
|
||||||
|
);
|
||||||
|
builder.push_yuv_image(
|
||||||
|
&info,
|
||||||
|
bounds,
|
||||||
|
YuvData::NV12(yuv_chanel1, yuv_chanel2),
|
||||||
|
ColorDepth::Color8,
|
||||||
|
YuvColorSpace::Rec601,
|
||||||
|
ColorRange::Limited,
|
||||||
|
ImageRendering::Auto,
|
||||||
|
);
|
||||||
|
|
||||||
|
let info = CommonItemProperties::new(
|
||||||
|
LayoutRect::new(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)),
|
||||||
|
space_and_clip,
|
||||||
|
);
|
||||||
|
builder.push_yuv_image(
|
||||||
|
&info,
|
||||||
|
bounds,
|
||||||
|
YuvData::PlanarYCbCr(yuv_chanel1, yuv_chanel2_1, yuv_chanel3),
|
||||||
|
ColorDepth::Color8,
|
||||||
|
YuvColorSpace::Rec601,
|
||||||
|
ColorRange::Limited,
|
||||||
|
ImageRendering::Auto,
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.pop_stacking_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_event(
|
||||||
|
&mut self,
|
||||||
|
_event: winit::WindowEvent,
|
||||||
|
_api: &mut RenderApi,
|
||||||
|
_document_id: DocumentId,
|
||||||
|
) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_image_handlers(
|
||||||
|
&mut self,
|
||||||
|
gl: &dyn gl::Gl,
|
||||||
|
) -> (Option<Box<dyn ExternalImageHandler>>,
|
||||||
|
Option<Box<dyn OutputImageHandler>>) {
|
||||||
|
let provider = YuvImageProvider::new(gl);
|
||||||
|
self.texture_id = provider.texture_ids[0];
|
||||||
|
(Some(Box::new(provider)), None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_custom(&mut self, gl: &dyn gl::Gl) {
|
||||||
|
init_gl_texture(self.texture_id, gl::RED, gl::RED, &[self.current_value; 100 * 100], gl);
|
||||||
|
self.current_value = self.current_value.wrapping_add(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App {
|
||||||
|
texture_id: 0,
|
||||||
|
current_value: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let opts = webrender::RendererOptions {
|
||||||
|
debug_flags: webrender::DebugFlags::NEW_FRAME_INDICATOR | webrender::DebugFlags::NEW_SCENE_INDICATOR,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
boilerplate::main_wrapper(&mut app, Some(opts));
|
||||||
|
}
|
11
third_party/webrender/glsl-to-cxx/Cargo.toml
vendored
Normal file
11
third_party/webrender/glsl-to-cxx/Cargo.toml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "glsl-to-cxx"
|
||||||
|
version = "0.1.0"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
authors = ["The Mozilla Project Developers"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
glsl = "4.0"
|
3
third_party/webrender/glsl-to-cxx/README.md
vendored
Normal file
3
third_party/webrender/glsl-to-cxx/README.md
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
A GLSL to C++ translator.
|
||||||
|
|
||||||
|
Translates GLSL to vectorized C++. Intended for use with WebRender software backend.
|
3856
third_party/webrender/glsl-to-cxx/src/hir.rs
vendored
Normal file
3856
third_party/webrender/glsl-to-cxx/src/hir.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
3706
third_party/webrender/glsl-to-cxx/src/lib.rs
vendored
Normal file
3706
third_party/webrender/glsl-to-cxx/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
8
third_party/webrender/glsl-to-cxx/src/main.rs
vendored
Normal file
8
third_party/webrender/glsl-to-cxx/src/main.rs
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
use glsl_to_cxx::translate;
|
||||||
|
fn main() {
|
||||||
|
println!("{}", translate(&mut std::env::args()));
|
||||||
|
}
|
226
third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
vendored
Normal file
226
third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
vendored
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
From 34d968adeda2e06b057a13d14a88df5766b38eda Mon Sep 17 00:00:00 2001
|
||||||
|
From: Josh Matthews <josh@joshmatthews.net>
|
||||||
|
Date: Mon, 6 Jul 2020 14:37:42 -0400
|
||||||
|
Subject: [PATCH] Add signal handler to catch segfault in build script.
|
||||||
|
|
||||||
|
---
|
||||||
|
Cargo.lock | 11 +++++
|
||||||
|
webrender/Cargo.toml | 5 ++
|
||||||
|
webrender/backtrace.rs | 103 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
webrender/build.rs | 30 ++++++++++++
|
||||||
|
4 files changed, 149 insertions(+)
|
||||||
|
create mode 100644 webrender/backtrace.rs
|
||||||
|
|
||||||
|
diff --git a/Cargo.lock b/Cargo.lock
|
||||||
|
index afdd336ae..cf91162d5 100644
|
||||||
|
--- a/Cargo.lock
|
||||||
|
+++ b/Cargo.lock
|
||||||
|
@@ -1477,6 +1477,14 @@ dependencies = [
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
+[[package]]
|
||||||
|
+name = "sig"
|
||||||
|
+version = "1.0.0"
|
||||||
|
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
+dependencies = [
|
||||||
|
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+]
|
||||||
|
+
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.2"
|
||||||
|
@@ -1750,6 +1758,7 @@ dependencies = [
|
||||||
|
name = "webrender"
|
||||||
|
version = "0.61.0"
|
||||||
|
dependencies = [
|
||||||
|
+ "backtrace 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -1780,6 +1789,7 @@ dependencies = [
|
||||||
|
"ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"svg_fmt 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -2178,6 +2188,7 @@ dependencies = [
|
||||||
|
"checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
|
||||||
|
"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||||
|
"checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
|
||||||
|
+"checksum sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6567e29578f9bfade6a5d94a32b9a4256348358d2a3f448cab0021f9a02614a2"
|
||||||
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
|
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
|
||||||
|
"checksum smallvec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a"
|
||||||
|
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||||
|
index dcf26d913..f7679da57 100644
|
||||||
|
--- a/webrender/Cargo.toml
|
||||||
|
+++ b/webrender/Cargo.toml
|
||||||
|
@@ -59,6 +59,11 @@ tracy-rs = { version = "0.1" }
|
||||||
|
mozangle = "0.3.1"
|
||||||
|
rand = "0.4"
|
||||||
|
|
||||||
|
+[target.'cfg(any(target_os = "macos", target_os = "linux"))'.build-dependencies]
|
||||||
|
+backtrace = "0.3"
|
||||||
|
+sig = "1.0"
|
||||||
|
+libc = "0.2"
|
||||||
|
+
|
||||||
|
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
|
||||||
|
freetype = { version = "0.4", default-features = false }
|
||||||
|
libc = "0.2"
|
||||||
|
diff --git a/webrender/backtrace.rs b/webrender/backtrace.rs
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..aa6bb6b32
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/webrender/backtrace.rs
|
||||||
|
@@ -0,0 +1,103 @@
|
||||||
|
+/* 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 https://mozilla.org/MPL/2.0/. */
|
||||||
|
+
|
||||||
|
+//! Similar to `println!("{:?}", Backtrace::new())`, but doesn’t allocate.
|
||||||
|
+//!
|
||||||
|
+//! Seems to fix some deadlocks: https://github.com/servo/servo/issues/24881
|
||||||
|
+//!
|
||||||
|
+//! FIXME: if/when a future version of the `backtrace` crate has
|
||||||
|
+//! https://github.com/rust-lang/backtrace-rs/pull/265, use that instead.
|
||||||
|
+
|
||||||
|
+use std::fmt::{self, Write};
|
||||||
|
+use backtrace::{BytesOrWideString, PrintFmt};
|
||||||
|
+
|
||||||
|
+#[inline(never)]
|
||||||
|
+pub(crate) fn print(w: &mut dyn std::io::Write) -> Result<(), std::io::Error> {
|
||||||
|
+ write!(w, "{:?}", Print {
|
||||||
|
+ print_fn_address: print as usize,
|
||||||
|
+ })
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct Print {
|
||||||
|
+ print_fn_address: usize,
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+impl fmt::Debug for Print {
|
||||||
|
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
+ // Safety: we’re in a signal handler that is about to call `libc::_exit`.
|
||||||
|
+ // Potential data races from using `*_unsynchronized` functions are perhaps
|
||||||
|
+ // less bad than potential deadlocks?
|
||||||
|
+ unsafe {
|
||||||
|
+ let mut print_fn_frame = 0;
|
||||||
|
+ let mut frame_count = 0;
|
||||||
|
+ backtrace::trace_unsynchronized(|frame| {
|
||||||
|
+ let found = frame.symbol_address() as usize == self.print_fn_address;
|
||||||
|
+ if found {
|
||||||
|
+ print_fn_frame = frame_count;
|
||||||
|
+ }
|
||||||
|
+ frame_count += 1;
|
||||||
|
+ !found
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ let mode = PrintFmt::Short;
|
||||||
|
+ let mut p = print_path;
|
||||||
|
+ let mut f = backtrace::BacktraceFmt::new(fmt, mode, &mut p);
|
||||||
|
+ f.add_context()?;
|
||||||
|
+ let mut result = Ok(());
|
||||||
|
+ let mut frame_count = 0;
|
||||||
|
+ backtrace::trace_unsynchronized(|frame| {
|
||||||
|
+ let skip = frame_count < print_fn_frame;
|
||||||
|
+ frame_count += 1;
|
||||||
|
+ if skip {
|
||||||
|
+ return true
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ let mut frame_fmt = f.frame();
|
||||||
|
+ let mut any_symbol = false;
|
||||||
|
+ backtrace::resolve_frame_unsynchronized(frame, |symbol| {
|
||||||
|
+ any_symbol = true;
|
||||||
|
+ if let Err(e) = frame_fmt.symbol(frame, symbol) {
|
||||||
|
+ result = Err(e)
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ if !any_symbol {
|
||||||
|
+ if let Err(e) = frame_fmt.print_raw(frame.ip(), None, None, None) {
|
||||||
|
+ result = Err(e)
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ result.is_ok()
|
||||||
|
+ });
|
||||||
|
+ result?;
|
||||||
|
+ f.finish()
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+fn print_path(fmt: &mut fmt::Formatter, path: BytesOrWideString) -> fmt::Result {
|
||||||
|
+ match path {
|
||||||
|
+ BytesOrWideString::Bytes(mut bytes) => {
|
||||||
|
+ loop {
|
||||||
|
+ match std::str::from_utf8(bytes) {
|
||||||
|
+ Ok(s) => {
|
||||||
|
+ fmt.write_str(s)?;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ Err(err) => {
|
||||||
|
+ fmt.write_char(std::char::REPLACEMENT_CHARACTER)?;
|
||||||
|
+ match err.error_len() {
|
||||||
|
+ Some(len) => bytes = &bytes[err.valid_up_to() + len..],
|
||||||
|
+ None => break,
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ BytesOrWideString::Wide(wide) => {
|
||||||
|
+ for c in std::char::decode_utf16(wide.iter().cloned()) {
|
||||||
|
+ fmt.write_char(c.unwrap_or(std::char::REPLACEMENT_CHARACTER))?
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ Ok(())
|
||||||
|
+}
|
||||||
|
diff --git a/webrender/build.rs b/webrender/build.rs
|
||||||
|
index 3521d1342..36a7f17a8 100644
|
||||||
|
--- a/webrender/build.rs
|
||||||
|
+++ b/webrender/build.rs
|
||||||
|
@@ -244,7 +244,37 @@ fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
+#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
|
+mod backtrace;
|
||||||
|
+
|
||||||
|
+#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
|
+extern "C" fn handler(sig: i32) {
|
||||||
|
+ use std::sync::atomic;
|
||||||
|
+ static BEEN_HERE_BEFORE: atomic::AtomicBool = atomic::AtomicBool::new(false);
|
||||||
|
+ if !BEEN_HERE_BEFORE.swap(true, atomic::Ordering::SeqCst) {
|
||||||
|
+ let stdout = std::io::stdout();
|
||||||
|
+ let mut stdout = stdout.lock();
|
||||||
|
+ let _ = write!(&mut stdout, "Stack trace");
|
||||||
|
+ if let Some(name) = std::thread::current().name() {
|
||||||
|
+ let _ = write!(&mut stdout, " for thread \"{}\"", name);
|
||||||
|
+ }
|
||||||
|
+ let _ = write!(&mut stdout, "\n");
|
||||||
|
+ let _ = backtrace::print(&mut stdout);
|
||||||
|
+ }
|
||||||
|
+ unsafe {
|
||||||
|
+ libc::_exit(sig);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
fn main() -> Result<(), std::io::Error> {
|
||||||
|
+ #[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
|
+ {
|
||||||
|
+ sig::signal!(sig::ffi::Sig::SEGV, handler); // handle segfaults
|
||||||
|
+ sig::signal!(sig::ffi::Sig::ILL, handler); // handle stack overflow and unsupported CPUs
|
||||||
|
+ sig::signal!(sig::ffi::Sig::IOT, handler); // handle double panics
|
||||||
|
+ sig::signal!(sig::ffi::Sig::BUS, handler); // handle invalid memory access
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
let out_dir = env::var("OUT_DIR").unwrap_or("out".to_owned());
|
||||||
|
|
||||||
|
let shaders_file_path = Path::new(&out_dir).join("shaders.rs");
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
174
third_party/webrender/patches/0002-Bug-1646741-Update-gleam-to-0.12.-r-kvark.patch
vendored
Normal file
174
third_party/webrender/patches/0002-Bug-1646741-Update-gleam-to-0.12.-r-kvark.patch
vendored
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
From 299c4db222eb9f0acd9623b66b8f3d0a8a8f77f2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||||
|
Date: Fri, 19 Jun 2020 04:10:02 +0000
|
||||||
|
Subject: [PATCH 2/6] Bug 1646741 - Update gleam to 0.12. r=kvark
|
||||||
|
|
||||||
|
For stride calculation and SSBOs
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D80191
|
||||||
|
|
||||||
|
[ghsync] From https://hg.mozilla.org/mozilla-central/rev/ef8485a16d099e24f4832178664c5a93a28396ec
|
||||||
|
---
|
||||||
|
Cargo.lock | 16 ++++++++--------
|
||||||
|
direct-composition/Cargo.toml | 2 +-
|
||||||
|
example-compositor/compositor/Cargo.toml | 2 +-
|
||||||
|
examples/Cargo.toml | 2 +-
|
||||||
|
swgl/Cargo.toml | 2 +-
|
||||||
|
webrender/Cargo.toml | 2 +-
|
||||||
|
wrench/Cargo.toml | 2 +-
|
||||||
|
7 files changed, 14 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Cargo.lock b/Cargo.lock
|
||||||
|
index cf91162d5..3eb484f26 100644
|
||||||
|
--- a/Cargo.lock
|
||||||
|
+++ b/Cargo.lock
|
||||||
|
@@ -257,7 +257,7 @@ name = "compositor"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"compositor-windows 0.1.0",
|
||||||
|
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"webrender 0.61.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
@@ -435,7 +435,7 @@ name = "direct-composition"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mozangle 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"webrender 0.61.0",
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -617,7 +617,7 @@ dependencies = [
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gleam"
|
||||||
|
-version = "0.11.0"
|
||||||
|
+version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -1545,7 +1545,7 @@ name = "swgl"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glsl-to-cxx 0.1.0",
|
||||||
|
"webrender_build 0.0.1",
|
||||||
|
]
|
||||||
|
@@ -1773,7 +1773,7 @@ dependencies = [
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -1808,7 +1808,7 @@ dependencies = [
|
||||||
|
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"webrender 0.61.0",
|
||||||
|
@@ -1938,7 +1938,7 @@ dependencies = [
|
||||||
|
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -2087,7 +2087,7 @@ dependencies = [
|
||||||
|
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||||
|
"checksum gl_generator 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ca98bbde17256e02d17336a6bdb5a50f7d0ccacee502e191d3e3d0ec2f96f84a"
|
||||||
|
"checksum gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d"
|
||||||
|
-"checksum gleam 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9a13b5bb12ab457c15400b43cbba5971df5c1898b6a9c30cc8c52cb01baa112"
|
||||||
|
+"checksum gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8d023b0b00c16960f0f82816f2f546dabe937e75b25c7d6ce09a63e6a52d71e"
|
||||||
|
"checksum gleam 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cae10d7c99d0e77b4766e850a60898a17c1abaf01075531f1066f03dc7dc5fc5"
|
||||||
|
"checksum glsl 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "766443890761b3c4edcce86cafaac97971b200662fbdd0446eb7c6b99b4401ea"
|
||||||
|
"checksum glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f22b383fcf6f85c4a268af39a0758ec40970e5f9f8fe9809e4415d48409b8379"
|
||||||
|
diff --git a/direct-composition/Cargo.toml b/direct-composition/Cargo.toml
|
||||||
|
index d099402d8..3506aec02 100644
|
||||||
|
--- a/direct-composition/Cargo.toml
|
||||||
|
+++ b/direct-composition/Cargo.toml
|
||||||
|
@@ -7,7 +7,7 @@ edition = "2018"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
euclid = "0.20"
|
||||||
|
-gleam = "0.11"
|
||||||
|
+gleam = "0.12"
|
||||||
|
mozangle = {version = "0.3.1", features = ["egl"]}
|
||||||
|
webrender = {path = "../webrender"}
|
||||||
|
winapi = {version = "0.3", features = ["winerror", "d3d11", "dcomp"]}
|
||||||
|
diff --git a/example-compositor/compositor/Cargo.toml b/example-compositor/compositor/Cargo.toml
|
||||||
|
index ce4d61928..d505e9ad2 100644
|
||||||
|
--- a/example-compositor/compositor/Cargo.toml
|
||||||
|
+++ b/example-compositor/compositor/Cargo.toml
|
||||||
|
@@ -7,7 +7,7 @@ license = "MPL-2.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
webrender = { path = "../../webrender" }
|
||||||
|
-gleam = "0.11.0"
|
||||||
|
+gleam = "0.12.0"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
compositor-windows = { path = "../compositor-windows" }
|
||||||
|
diff --git a/examples/Cargo.toml b/examples/Cargo.toml
|
||||||
|
index 31c695f98..09e658ca2 100644
|
||||||
|
--- a/examples/Cargo.toml
|
||||||
|
+++ b/examples/Cargo.toml
|
||||||
|
@@ -61,7 +61,7 @@ debug = ["webrender/capture", "webrender/debugger", "webrender/profiler"]
|
||||||
|
app_units = "0.7"
|
||||||
|
env_logger = "0.5"
|
||||||
|
euclid = "0.20"
|
||||||
|
-gleam = "0.11"
|
||||||
|
+gleam = "0.12"
|
||||||
|
glutin = "0.21"
|
||||||
|
rayon = "1"
|
||||||
|
webrender = { path = "../webrender" }
|
||||||
|
diff --git a/swgl/Cargo.toml b/swgl/Cargo.toml
|
||||||
|
index 3d57edbab..bc5a04b0a 100644
|
||||||
|
--- a/swgl/Cargo.toml
|
||||||
|
+++ b/swgl/Cargo.toml
|
||||||
|
@@ -12,4 +12,4 @@ glsl-to-cxx = { path = "../glsl-to-cxx" }
|
||||||
|
webrender_build = { path = "../webrender_build" }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
-gleam = "0.11.0"
|
||||||
|
+gleam = "0.12.0"
|
||||||
|
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||||
|
index f7679da57..2b0ab14fb 100644
|
||||||
|
--- a/webrender/Cargo.toml
|
||||||
|
+++ b/webrender/Cargo.toml
|
||||||
|
@@ -34,7 +34,7 @@ cfg-if = "0.1.2"
|
||||||
|
cstr = "0.1.2"
|
||||||
|
euclid = { version = "0.20.0", features = ["serde"] }
|
||||||
|
fxhash = "0.2.1"
|
||||||
|
-gleam = "0.11.0"
|
||||||
|
+gleam = "0.12.0"
|
||||||
|
image_loader = { optional = true, version = "0.23", package = "image", default-features = false, features = ["png"] }
|
||||||
|
lazy_static = "1"
|
||||||
|
log = "0.4"
|
||||||
|
diff --git a/wrench/Cargo.toml b/wrench/Cargo.toml
|
||||||
|
index 988e2537a..4ba95e4c4 100644
|
||||||
|
--- a/wrench/Cargo.toml
|
||||||
|
+++ b/wrench/Cargo.toml
|
||||||
|
@@ -12,7 +12,7 @@ bincode = "1.0"
|
||||||
|
byteorder = "1.0"
|
||||||
|
env_logger = { version = "0.5", optional = true }
|
||||||
|
euclid = "0.20"
|
||||||
|
-gleam = "0.11"
|
||||||
|
+gleam = "0.12"
|
||||||
|
glutin = "0.21"
|
||||||
|
app_units = "0.7"
|
||||||
|
clap = { version = "2", features = ["yaml"] }
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
107
third_party/webrender/patches/0003-Bug-1651889.-Update-to-gleam-0.12.1.-r-kvark.patch
vendored
Normal file
107
third_party/webrender/patches/0003-Bug-1651889.-Update-to-gleam-0.12.1.-r-kvark.patch
vendored
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
From 3767bd8938b5b849bc23bb7ac490cb0c27655560 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||||
|
Date: Sat, 11 Jul 2020 09:42:33 +0000
|
||||||
|
Subject: [PATCH 3/6] Bug 1651889. Update to gleam 0.12.1. r=kvark
|
||||||
|
|
||||||
|
This should fix a crash caused by an unexpected pixel type.
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D83167
|
||||||
|
|
||||||
|
[ghsync] From https://hg.mozilla.org/mozilla-central/rev/b850773b54e129888b8fb2f1e3bc68f528aeccbf
|
||||||
|
---
|
||||||
|
Cargo.lock | 16 ++++++++--------
|
||||||
|
webrender/Cargo.toml | 2 +-
|
||||||
|
2 files changed, 9 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Cargo.lock b/Cargo.lock
|
||||||
|
index 3eb484f26..24f92084c 100644
|
||||||
|
--- a/Cargo.lock
|
||||||
|
+++ b/Cargo.lock
|
||||||
|
@@ -257,7 +257,7 @@ name = "compositor"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"compositor-windows 0.1.0",
|
||||||
|
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"webrender 0.61.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
@@ -435,7 +435,7 @@ name = "direct-composition"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mozangle 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"webrender 0.61.0",
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -617,7 +617,7 @@ dependencies = [
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gleam"
|
||||||
|
-version = "0.12.0"
|
||||||
|
+version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -1545,7 +1545,7 @@ name = "swgl"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glsl-to-cxx 0.1.0",
|
||||||
|
"webrender_build 0.0.1",
|
||||||
|
]
|
||||||
|
@@ -1773,7 +1773,7 @@ dependencies = [
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -1808,7 +1808,7 @@ dependencies = [
|
||||||
|
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"webrender 0.61.0",
|
||||||
|
@@ -1938,7 +1938,7 @@ dependencies = [
|
||||||
|
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -2087,7 +2087,7 @@ dependencies = [
|
||||||
|
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||||
|
"checksum gl_generator 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ca98bbde17256e02d17336a6bdb5a50f7d0ccacee502e191d3e3d0ec2f96f84a"
|
||||||
|
"checksum gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d"
|
||||||
|
-"checksum gleam 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8d023b0b00c16960f0f82816f2f546dabe937e75b25c7d6ce09a63e6a52d71e"
|
||||||
|
+"checksum gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fdef5b9df6d3a261b80a5ac55e13bf93945725df2463c1b0a2e5a527dce0d37"
|
||||||
|
"checksum gleam 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cae10d7c99d0e77b4766e850a60898a17c1abaf01075531f1066f03dc7dc5fc5"
|
||||||
|
"checksum glsl 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "766443890761b3c4edcce86cafaac97971b200662fbdd0446eb7c6b99b4401ea"
|
||||||
|
"checksum glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f22b383fcf6f85c4a268af39a0758ec40970e5f9f8fe9809e4415d48409b8379"
|
||||||
|
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||||
|
index 2b0ab14fb..3fa6630bd 100644
|
||||||
|
--- a/webrender/Cargo.toml
|
||||||
|
+++ b/webrender/Cargo.toml
|
||||||
|
@@ -34,7 +34,7 @@ cfg-if = "0.1.2"
|
||||||
|
cstr = "0.1.2"
|
||||||
|
euclid = { version = "0.20.0", features = ["serde"] }
|
||||||
|
fxhash = "0.2.1"
|
||||||
|
-gleam = "0.12.0"
|
||||||
|
+gleam = "0.12.1"
|
||||||
|
image_loader = { optional = true, version = "0.23", package = "image", default-features = false, features = ["png"] }
|
||||||
|
lazy_static = "1"
|
||||||
|
log = "0.4"
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
328
third_party/webrender/patches/0004-Bug-1654699.-Update-core-foundation-core-graphics.-r.patch
vendored
Normal file
328
third_party/webrender/patches/0004-Bug-1654699.-Update-core-foundation-core-graphics.-r.patch
vendored
Normal file
|
@ -0,0 +1,328 @@
|
||||||
|
From 920168aff79a7cf52980b0c90965a591f2f4204a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||||
|
Date: Fri, 24 Jul 2020 09:54:10 +0000
|
||||||
|
Subject: [PATCH 4/6] Bug 1654699. Update core-foundation/core-graphics.
|
||||||
|
r=kvark,keeler,chunmin
|
||||||
|
|
||||||
|
This includes updates to authenticator, cubeb-coreaudio,
|
||||||
|
metal, gfx-backend-vulkan, gfx-backend-metal, freetype
|
||||||
|
|
||||||
|
libloading is duplicated because of ash
|
||||||
|
|
||||||
|
Differential Revision: https://phabricator.services.mozilla.com/D84688
|
||||||
|
|
||||||
|
[ghsync] From https://hg.mozilla.org/mozilla-central/rev/45fc4a780b2b4a9e047eceba73b39b988f719c58
|
||||||
|
---
|
||||||
|
Cargo.lock | 110 +++++++++++++++++++++++++--------------
|
||||||
|
webrender/Cargo.toml | 10 ++--
|
||||||
|
webrender_api/Cargo.toml | 4 +-
|
||||||
|
wrench/Cargo.toml | 6 +--
|
||||||
|
4 files changed, 80 insertions(+), 50 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Cargo.lock b/Cargo.lock
|
||||||
|
index 24f92084c..617092292 100644
|
||||||
|
--- a/Cargo.lock
|
||||||
|
+++ b/Cargo.lock
|
||||||
|
@@ -286,6 +286,15 @@ dependencies = [
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
+[[package]]
|
||||||
|
+name = "core-foundation"
|
||||||
|
+version = "0.9.0"
|
||||||
|
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
+dependencies = [
|
||||||
|
+ "core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+]
|
||||||
|
+
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.6.2"
|
||||||
|
@@ -296,6 +305,11 @@ name = "core-foundation-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
+[[package]]
|
||||||
|
+name = "core-foundation-sys"
|
||||||
|
+version = "0.8.0"
|
||||||
|
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
+
|
||||||
|
[[package]]
|
||||||
|
name = "core-graphics"
|
||||||
|
version = "0.17.3"
|
||||||
|
@@ -309,22 +323,34 @@ dependencies = [
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-graphics"
|
||||||
|
-version = "0.19.0"
|
||||||
|
+version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-graphics-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+]
|
||||||
|
+
|
||||||
|
+[[package]]
|
||||||
|
+name = "core-graphics-types"
|
||||||
|
+version = "0.1.0"
|
||||||
|
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
+dependencies = [
|
||||||
|
+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-text"
|
||||||
|
-version = "15.0.0"
|
||||||
|
+version = "19.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
@@ -510,13 +536,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "font-loader"
|
||||||
|
-version = "0.9.0"
|
||||||
|
+version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-text 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "servo-fontconfig 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
@@ -535,11 +561,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freetype"
|
||||||
|
-version = "0.4.1"
|
||||||
|
+version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
+ "freetype-sys 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+]
|
||||||
|
+
|
||||||
|
+[[package]]
|
||||||
|
+name = "freetype-sys"
|
||||||
|
+version = "0.13.1"
|
||||||
|
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
+dependencies = [
|
||||||
|
+ "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
@@ -1431,29 +1467,20 @@ dependencies = [
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "servo-fontconfig"
|
||||||
|
-version = "0.4.0"
|
||||||
|
+version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "servo-fontconfig-sys 4.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "servo-fontconfig-sys 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "servo-fontconfig-sys"
|
||||||
|
-version = "4.0.9"
|
||||||
|
+version = "5.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
-]
|
||||||
|
-
|
||||||
|
-[[package]]
|
||||||
|
-name = "servo-freetype-sys"
|
||||||
|
-version = "4.0.5"
|
||||||
|
-source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
-dependencies = [
|
||||||
|
- "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "freetype-sys 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
@@ -1765,13 +1792,13 @@ dependencies = [
|
||||||
|
"build-parallel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-text 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cstr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "freetype 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glslopt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -1822,8 +1849,8 @@ dependencies = [
|
||||||
|
"app_units 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"derive_more 0.99.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"malloc_size_of_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -1931,13 +1958,13 @@ dependencies = [
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"dwrote 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "font-loader 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gleam 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glutin 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@@ -2051,11 +2078,14 @@ dependencies = [
|
||||||
|
"checksum cocoa 0.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1706996401131526e36b3b49f0c4d912639ce110996f3ca144d78946727bce54"
|
||||||
|
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
|
||||||
|
"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
|
||||||
|
+"checksum core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb"
|
||||||
|
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
|
||||||
|
"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
|
||||||
|
+"checksum core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
|
||||||
|
"checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9"
|
||||||
|
-"checksum core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59e78b2e0aaf43f08e7ae0d6bc96895ef72ff0921c7d4ff4762201b2dba376dd"
|
||||||
|
-"checksum core-text 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "131b3fd1f8bd5db9f2b398fa4fdb6008c64afc04d447c306ac2c7e98fba2a61d"
|
||||||
|
+"checksum core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6082396a349fa49674ba1bda4077332a18bf150e8fa75745ece07085e29a113"
|
||||||
|
+"checksum core-graphics-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e92f5d519093a4178296707dbaa3880eae85a5ef5386675f361a1cf25376e93c"
|
||||||
|
+"checksum core-text 19.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04dfae50af11e72657fe7174cddb1ecddc5398037f7f6f39533ad69207c9a4e2"
|
||||||
|
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||||
|
"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be"
|
||||||
|
"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||||
|
@@ -2075,10 +2105,11 @@ dependencies = [
|
||||||
|
"checksum euclid 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6a5b0c779cd0b744c73a1d2083faf181080d696903cdad99a3b03d015d7030"
|
||||||
|
"checksum expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
|
||||||
|
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
-"checksum font-loader 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "933a61458662fbc8e3cd22cdb8331edbd78545fc044e1e2cd3d742f6ce06aa41"
|
||||||
|
+"checksum font-loader 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c49d6b4c11dca1a1dd931a34a9f397e2da91abe3de4110505f3530a80e560b52"
|
||||||
|
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||||
|
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||||
|
-"checksum freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "11926b2b410b469d0e9399eca4cbbe237a9ef02176c485803b29216307e8e028"
|
||||||
|
+"checksum freetype 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6"
|
||||||
|
+"checksum freetype-sys 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a"
|
||||||
|
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
|
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
|
@@ -2183,9 +2214,8 @@ dependencies = [
|
||||||
|
"checksum serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "325a073952621257820e7a3469f55ba4726d8b28657e7e36653d1c36dc2c84ae"
|
||||||
|
"checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
|
||||||
|
"checksum serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)" = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9"
|
||||||
|
-"checksum servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9"
|
||||||
|
-"checksum servo-fontconfig-sys 4.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "62b3e166450f523f4db06c14f02a2d39e76d49b5d8cbd224338d93e3595c156c"
|
||||||
|
-"checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
|
||||||
|
+"checksum servo-fontconfig 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c"
|
||||||
|
+"checksum servo-fontconfig-sys 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388"
|
||||||
|
"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||||
|
"checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
|
||||||
|
"checksum sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6567e29578f9bfade6a5d94a32b9a4256348358d2a3f448cab0021f9a02614a2"
|
||||||
|
diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
|
||||||
|
index 3fa6630bd..d05cf5979 100644
|
||||||
|
--- a/webrender/Cargo.toml
|
||||||
|
+++ b/webrender/Cargo.toml
|
||||||
|
@@ -10,7 +10,7 @@ edition = "2018"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["freetype-lib"]
|
||||||
|
-freetype-lib = ["freetype/servo-freetype-sys"]
|
||||||
|
+freetype-lib = ["freetype/freetype-sys"]
|
||||||
|
profiler = ["tracy-rs/enable_profiler"]
|
||||||
|
debugger = ["ws", "serde_json", "serde", "image_loader", "base64"]
|
||||||
|
capture = ["api/serialize", "ron", "serde", "smallvec/serde"]
|
||||||
|
@@ -65,13 +65,13 @@ sig = "1.0"
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
|
[target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
|
||||||
|
-freetype = { version = "0.4", default-features = false }
|
||||||
|
+freetype = { version = "0.7", default-features = false }
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
dwrote = "0.11"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
-core-foundation = "0.7"
|
||||||
|
-core-graphics = "0.19"
|
||||||
|
-core-text = { version = "15", default-features = false }
|
||||||
|
+core-foundation = "0.9"
|
||||||
|
+core-graphics = "0.22"
|
||||||
|
+core-text = { version = "19", default-features = false }
|
||||||
|
diff --git a/webrender_api/Cargo.toml b/webrender_api/Cargo.toml
|
||||||
|
index 6b8b1e5f2..4ed7ce8e2 100644
|
||||||
|
--- a/webrender_api/Cargo.toml
|
||||||
|
+++ b/webrender_api/Cargo.toml
|
||||||
|
@@ -28,5 +28,5 @@ malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of", package = "
|
||||||
|
peek-poke = { version = "0.2", path = "../peek-poke", features = ["extras"] }
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
-core-foundation = "0.7"
|
||||||
|
-core-graphics = "0.19"
|
||||||
|
+core-foundation = "0.9"
|
||||||
|
+core-graphics = "0.22"
|
||||||
|
diff --git a/wrench/Cargo.toml b/wrench/Cargo.toml
|
||||||
|
index 4ba95e4c4..33679485a 100644
|
||||||
|
--- a/wrench/Cargo.toml
|
||||||
|
+++ b/wrench/Cargo.toml
|
||||||
|
@@ -38,8 +38,8 @@ default-features = false
|
||||||
|
features = ["png"]
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
-core-graphics = "0.19"
|
||||||
|
-core-foundation = "0.7"
|
||||||
|
+core-graphics = "0.22"
|
||||||
|
+core-foundation = "0.9"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "env_logger" ]
|
||||||
|
@@ -51,7 +51,7 @@ dwrote = "0.11"
|
||||||
|
mozangle = {version = "0.3.1", features = ["egl"]}
|
||||||
|
|
||||||
|
[target.'cfg(all(unix, not(target_os = "android")))'.dependencies]
|
||||||
|
-font-loader = "0.9"
|
||||||
|
+font-loader = "0.11"
|
||||||
|
|
||||||
|
# Configuration information used when building wrench as an APK.
|
||||||
|
[package.metadata.android]
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
9059
third_party/webrender/patches/0005-Bug-1656236-Update-to-euclid-0.22.-r-kvark.patch
vendored
Normal file
9059
third_party/webrender/patches/0005-Bug-1656236-Update-to-euclid-0.22.-r-kvark.patch
vendored
Normal file
File diff suppressed because it is too large
Load diff
53
third_party/webrender/patches/0006-Bump-procedural-masquerade-to-0.1.7.patch
vendored
Normal file
53
third_party/webrender/patches/0006-Bump-procedural-masquerade-to-0.1.7.patch
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
From 415b9ba32648667313f6f4ce7965752285bf0b26 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Martin Robinson <mrobinson@igalia.com>
|
||||||
|
Date: Thu, 12 Jan 2023 12:35:31 +0100
|
||||||
|
Subject: [PATCH 2/2] Bump procedural-masquerade to 0.1.7
|
||||||
|
|
||||||
|
This fixes a build issue in this branch.
|
||||||
|
---
|
||||||
|
Cargo.lock | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Cargo.lock b/Cargo.lock
|
||||||
|
index b6085604cae8e18de3273bcddac43fa0a7e1abd1..b7055733e57fcd0acff07881ef72369b560c2abe 100644
|
||||||
|
--- a/Cargo.lock
|
||||||
|
+++ b/Cargo.lock
|
||||||
|
@@ -417,7 +417,7 @@ version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cstr-macros 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
- "procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "procedural-masquerade 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
@@ -425,7 +425,7 @@ name = "cstr-macros"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
- "procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
+ "procedural-masquerade 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
@@ -1212,7 +1212,7 @@ dependencies = [
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "procedural-masquerade"
|
||||||
|
-version = "0.1.6"
|
||||||
|
+version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
@@ -2182,7 +2182,7 @@ dependencies = [
|
||||||
|
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||||
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
|
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
||||||
|
-"checksum procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9a1574a51c3fd37b26d2c0032b649d08a7d51d4cca9c41bbc5bf7118fa4509d0"
|
||||||
|
+"checksum procedural-masquerade 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1383dff4092fe903ac180e391a8d4121cc48f08ccf850614b0290c6673b69d"
|
||||||
|
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
|
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
1
third_party/webrender/patches/head
vendored
Normal file
1
third_party/webrender/patches/head
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1175acad2d4f49fa712e105c84149ac7f394261d
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue