parent
f02f834097
commit
9be207f4c5
|
|
@ -34,11 +34,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760038930,
|
"lastModified": 1762363567,
|
||||||
"narHash": "sha256-Oncbh0UmHjSlxO7ErQDM3KM0A5/Znfofj2BSzlHLeVw=",
|
"narHash": "sha256-YRqMDEtSMbitIMj+JLpheSz0pwEr0Rmy5mC7myl17xs=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "0b4defa2584313f3b781240b29d61f6f9f7e0df3",
|
"rev": "ae814fd3904b621d8ab97418f1d0f2eb0d3716f4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -63,11 +63,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760236527,
|
"lastModified": 1762569282,
|
||||||
"narHash": "sha256-h9+WEQtUIZaZMvA1pnbZbMM+5X39OFnW92Q8hNoToD0=",
|
"narHash": "sha256-vINZAJpXQTZd5cfh06Rcw7hesH7sGSvi+Tn+HUieJn8=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "a38dd7f462825c75ce8567816ae38c2e7d826bfa",
|
"rev": "a35a6144b976f70827c2fe2f5c89d16d8f9179d8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -724,20 +724,29 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cef"
|
name = "cef"
|
||||||
version = "140.3.1+140.1.14"
|
version = "141.4.0+141.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "951391894583c255fd60b11f9a80397c9f8e1273d5b3a05531fcfa1365259059"
|
checksum = "e05b0ae455c0cf0693da242b3336586cd0057702c0516731d8ba72962559a625"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ash",
|
||||||
"cef-dll-sys",
|
"cef-dll-sys",
|
||||||
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
|
"metal 0.32.0",
|
||||||
|
"objc",
|
||||||
|
"objc2-io-surface",
|
||||||
|
"thiserror 2.0.16",
|
||||||
|
"tracing",
|
||||||
|
"wgpu",
|
||||||
|
"windows",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cef-dll-sys"
|
name = "cef-dll-sys"
|
||||||
version = "140.3.1+140.1.14"
|
version = "141.6.0+141.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "208b1aa960cedcde7ac7590cb882a107caca0804242ac4060c488db233eef222"
|
checksum = "4c95e419bbb8b2190df8b6eb3934ecc4137533803fcc5ae2b076e591ee789071"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cmake",
|
"cmake",
|
||||||
|
|
@ -1619,6 +1628,12 @@ version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "font-types"
|
name = "font-types"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
@ -1692,7 +1707,7 @@ checksum = "39f97079e1293b8c1e9fb03a2875d328bd2ee8f3b95ce62959c0acc04049c708"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"fontconfig-cache-parser",
|
"fontconfig-cache-parser",
|
||||||
"hashbrown",
|
"hashbrown 0.15.5",
|
||||||
"icu_locid",
|
"icu_locid",
|
||||||
"memmap2",
|
"memmap2",
|
||||||
"objc2",
|
"objc2",
|
||||||
|
|
@ -2031,7 +2046,7 @@ checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.3",
|
"bitflags 2.9.3",
|
||||||
"gpu-descriptor-types",
|
"gpu-descriptor-types",
|
||||||
"hashbrown",
|
"hashbrown 0.15.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2492,7 +2507,16 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"foldhash",
|
"foldhash 0.1.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2900,7 +2924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
|
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown 0.15.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -3493,7 +3517,32 @@ dependencies = [
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
"half",
|
"half",
|
||||||
"hashbrown",
|
"hashbrown 0.15.5",
|
||||||
|
"hexf-parse",
|
||||||
|
"indexmap",
|
||||||
|
"libm",
|
||||||
|
"log",
|
||||||
|
"num-traits",
|
||||||
|
"once_cell",
|
||||||
|
"rustc-hash 1.1.0",
|
||||||
|
"thiserror 2.0.16",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "naga"
|
||||||
|
version = "27.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bit-set",
|
||||||
|
"bitflags 2.9.3",
|
||||||
|
"cfg-if",
|
||||||
|
"cfg_aliases",
|
||||||
|
"codespan-reporting",
|
||||||
|
"half",
|
||||||
|
"hashbrown 0.16.0",
|
||||||
"hexf-parse",
|
"hexf-parse",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"libm",
|
"libm",
|
||||||
|
|
@ -3834,6 +3883,19 @@ dependencies = [
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-io-surface"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.3",
|
||||||
|
"libc",
|
||||||
|
"objc2",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-foundation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-ui-kit"
|
name = "objc2-ui-kit"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
|
@ -4016,7 +4078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13e57638545cf2ba4c3e72cc5715e53b1880b829cc3dbefda3d1700c58efe723"
|
checksum = "13e57638545cf2ba4c3e72cc5715e53b1880b829cc3dbefda3d1700c58efe723"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fontique",
|
"fontique",
|
||||||
"hashbrown",
|
"hashbrown 0.15.5",
|
||||||
"peniko 0.4.0",
|
"peniko 0.4.0",
|
||||||
"skrifa 0.31.3",
|
"skrifa 0.31.3",
|
||||||
"swash",
|
"swash",
|
||||||
|
|
@ -4142,7 +4204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca"
|
checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fixedbitset",
|
"fixedbitset",
|
||||||
"hashbrown",
|
"hashbrown 0.15.5",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -6383,8 +6445,7 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vello"
|
name = "vello"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/linebender/vello#8f2f2564127812362d2c57ded20cad369e3a00fe"
|
||||||
checksum = "71acbd6b5f7f19841425845c113a89a54bbf60556ae39e7d0182a6f80ce37f5b"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"futures-intrusive",
|
"futures-intrusive",
|
||||||
|
|
@ -6402,8 +6463,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vello_encoding"
|
name = "vello_encoding"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/linebender/vello#8f2f2564127812362d2c57ded20cad369e3a00fe"
|
||||||
checksum = "cfd5e0b9fec91df34a09fbcbbed474cec68d05691b590a911c7af83c4860ae42"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"guillotiere",
|
"guillotiere",
|
||||||
|
|
@ -6415,12 +6475,11 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vello_shaders"
|
name = "vello_shaders"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/linebender/vello#8f2f2564127812362d2c57ded20cad369e3a00fe"
|
||||||
checksum = "8c381dde4e7d0d7957df0c0e3f8a7cc0976762d3972d97da5c71464e57ffefd3"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"log",
|
"log",
|
||||||
"naga",
|
"naga 26.0.0",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.16",
|
||||||
"vello_encoding",
|
"vello_encoding",
|
||||||
]
|
]
|
||||||
|
|
@ -6714,19 +6773,19 @@ checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu"
|
name = "wgpu"
|
||||||
version = "26.0.1"
|
version = "27.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "70b6ff82bbf6e9206828e1a3178e851f8c20f1c9028e74dd3a8090741ccd5798"
|
checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags 2.9.3",
|
"bitflags 2.9.3",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"document-features",
|
"document-features",
|
||||||
"hashbrown",
|
"hashbrown 0.16.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"naga",
|
"naga 27.0.3",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
"profiling",
|
"profiling",
|
||||||
|
|
@ -6743,9 +6802,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core"
|
name = "wgpu-core"
|
||||||
version = "26.0.1"
|
version = "27.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d5f62f1053bd28c2268f42916f31588f81f64796e2ff91b81293515017ca8bd9"
|
checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bit-set",
|
"bit-set",
|
||||||
|
|
@ -6754,10 +6813,10 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"document-features",
|
"document-features",
|
||||||
"hashbrown",
|
"hashbrown 0.16.0",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"log",
|
"log",
|
||||||
"naga",
|
"naga 27.0.3",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
|
|
@ -6775,27 +6834,27 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core-deps-apple"
|
name = "wgpu-core-deps-apple"
|
||||||
version = "26.0.0"
|
version = "27.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18ae5fbde6a4cbebae38358aa73fcd6e0f15c6144b67ef5dc91ded0db125dbdf"
|
checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wgpu-hal",
|
"wgpu-hal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core-deps-emscripten"
|
name = "wgpu-core-deps-emscripten"
|
||||||
version = "26.0.0"
|
version = "27.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7670e390f416006f746b4600fdd9136455e3627f5bd763abf9a65daa216dd2d"
|
checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wgpu-hal",
|
"wgpu-hal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core-deps-windows-linux-android"
|
name = "wgpu-core-deps-windows-linux-android"
|
||||||
version = "26.0.0"
|
version = "27.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "720a5cb9d12b3d337c15ff0e24d3e97ed11490ff3f7506e7f3d98c68fa5d6f14"
|
checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wgpu-hal",
|
"wgpu-hal",
|
||||||
]
|
]
|
||||||
|
|
@ -6821,9 +6880,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-hal"
|
name = "wgpu-hal"
|
||||||
version = "26.0.6"
|
version = "27.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8d0e67224cc7305b3b4eb2cc57ca4c4c3afc665c1d1bee162ea806e19c47bdd"
|
checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
|
|
@ -6840,16 +6899,17 @@ dependencies = [
|
||||||
"gpu-alloc",
|
"gpu-alloc",
|
||||||
"gpu-allocator",
|
"gpu-allocator",
|
||||||
"gpu-descriptor",
|
"gpu-descriptor",
|
||||||
"hashbrown",
|
"hashbrown 0.16.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"khronos-egl",
|
"khronos-egl",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
"log",
|
"log",
|
||||||
"metal 0.32.0",
|
"metal 0.32.0",
|
||||||
"naga",
|
"naga 27.0.3",
|
||||||
"ndk-sys",
|
"ndk-sys",
|
||||||
"objc",
|
"objc",
|
||||||
|
"once_cell",
|
||||||
"ordered-float 4.6.0",
|
"ordered-float 4.6.0",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
|
|
@ -6869,9 +6929,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-types"
|
name = "wgpu-types"
|
||||||
version = "26.0.0"
|
version = "27.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eca7a8d8af57c18f57d393601a1fb159ace8b2328f1b6b5f80893f7d672c9ae2"
|
checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.3",
|
"bitflags 2.9.3",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
|
|
||||||
10
Cargo.toml
10
Cargo.toml
|
|
@ -106,7 +106,7 @@ quote = "1.0"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
ron = "0.11"
|
ron = "0.11"
|
||||||
fastnoise-lite = "1.1"
|
fastnoise-lite = "1.1"
|
||||||
wgpu = { version = "26.0", features = [
|
wgpu = { version = "27.0", features = [
|
||||||
# We don't have wgpu on multiple threads (yet) https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md#wgpu-types-now-send-sync-on-wasm
|
# We don't have wgpu on multiple threads (yet) https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md#wgpu-types-now-send-sync-on-wasm
|
||||||
"fragile-send-sync-non-atomic-wasm",
|
"fragile-send-sync-non-atomic-wasm",
|
||||||
"spirv",
|
"spirv",
|
||||||
|
|
@ -138,8 +138,8 @@ winit = { git = "https://github.com/rust-windowing/winit.git" }
|
||||||
keyboard-types = "0.8"
|
keyboard-types = "0.8"
|
||||||
url = "2.5"
|
url = "2.5"
|
||||||
tokio = { version = "1.29", features = ["fs", "macros", "io-std", "rt"] }
|
tokio = { version = "1.29", features = ["fs", "macros", "io-std", "rt"] }
|
||||||
vello = { version = "0.6" }
|
vello = { git = "https://github.com/linebender/vello" }
|
||||||
vello_encoding = { version = "0.6" }
|
vello_encoding = { git = "https://github.com/linebender/vello" }
|
||||||
resvg = "0.45"
|
resvg = "0.45"
|
||||||
usvg = "0.45"
|
usvg = "0.45"
|
||||||
rand = { version = "0.9", default-features = false, features = ["std_rng"] }
|
rand = { version = "0.9", default-features = false, features = ["std_rng"] }
|
||||||
|
|
@ -188,8 +188,8 @@ iai-callgrind = { version = "0.16" }
|
||||||
ndarray = "0.16"
|
ndarray = "0.16"
|
||||||
strum = { version = "0.27", features = ["derive"] }
|
strum = { version = "0.27", features = ["derive"] }
|
||||||
dirs = "6.0"
|
dirs = "6.0"
|
||||||
cef = "140"
|
cef = { version = "141", features = ["accelerated_osr"] }
|
||||||
cef-dll-sys = "140"
|
cef-dll-sys = "141"
|
||||||
include_dir = "0.7"
|
include_dir = "0.7"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,7 @@ mod platform;
|
||||||
mod utility;
|
mod utility;
|
||||||
|
|
||||||
#[cfg(feature = "accelerated_paint")]
|
#[cfg(feature = "accelerated_paint")]
|
||||||
mod texture_import;
|
use cef::osr_texture_import::SharedTextureHandle;
|
||||||
#[cfg(feature = "accelerated_paint")]
|
|
||||||
use texture_import::SharedTextureHandle;
|
|
||||||
|
|
||||||
pub(crate) use context::{CefContext, CefContextBuilder, InitError};
|
pub(crate) use context::{CefContext, CefContextBuilder, InitError};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
|
||||||
|
|
||||||
#[cfg(feature = "accelerated_paint")]
|
#[cfg(feature = "accelerated_paint")]
|
||||||
fn on_accelerated_paint(&self, _browser: Option<&mut Browser>, type_: PaintElementType, _dirty_rect_count: usize, _dirty_rects: Option<&Rect>, info: Option<&cef::AcceleratedPaintInfo>) {
|
fn on_accelerated_paint(&self, _browser: Option<&mut Browser>, type_: PaintElementType, _dirty_rect_count: usize, _dirty_rects: Option<&Rect>, info: Option<&cef::AcceleratedPaintInfo>) {
|
||||||
use crate::cef::texture_import::shared_texture_handle::SharedTextureHandle;
|
use cef::osr_texture_import::SharedTextureHandle;
|
||||||
|
|
||||||
if type_ != PaintElementType::default() {
|
if type_ != PaintElementType::default() {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
//! Common utilities and traits for texture import across platforms
|
|
||||||
|
|
||||||
use crate::cef::texture_import::*;
|
|
||||||
use cef::sys::cef_color_type_t;
|
|
||||||
use wgpu::Device;
|
|
||||||
|
|
||||||
/// Common format conversion utilities
|
|
||||||
pub mod format {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
/// Convert CEF color type to wgpu texture format
|
|
||||||
pub fn cef_to_wgpu(format: cef_color_type_t) -> Result<wgpu::TextureFormat, TextureImportError> {
|
|
||||||
match format {
|
|
||||||
cef_color_type_t::CEF_COLOR_TYPE_BGRA_8888 => Ok(wgpu::TextureFormat::Bgra8UnormSrgb),
|
|
||||||
cef_color_type_t::CEF_COLOR_TYPE_RGBA_8888 => Ok(wgpu::TextureFormat::Rgba8UnormSrgb),
|
|
||||||
_ => Err(TextureImportError::UnsupportedFormat { format }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
|
||||||
/// Convert CEF color type to Vulkan format
|
|
||||||
pub fn cef_to_vulkan(format: cef_color_type_t) -> Result<ash::vk::Format, TextureImportError> {
|
|
||||||
match format {
|
|
||||||
cef_color_type_t::CEF_COLOR_TYPE_BGRA_8888 => Ok(ash::vk::Format::B8G8R8A8_UNORM),
|
|
||||||
cef_color_type_t::CEF_COLOR_TYPE_RGBA_8888 => Ok(ash::vk::Format::R8G8B8A8_UNORM),
|
|
||||||
_ => Err(TextureImportError::UnsupportedFormat { format }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Common texture creation utilities
|
|
||||||
pub mod texture {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
/// Create a fallback CPU texture with the given dimensions and format
|
|
||||||
pub fn create_fallback(device: &Device, width: u32, height: u32, format: cef_color_type_t, label: &str) -> TextureImportResult {
|
|
||||||
let wgpu_format = format::cef_to_wgpu(format)?;
|
|
||||||
|
|
||||||
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
|
||||||
label: Some(label),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: wgpu_format,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
|
||||||
view_formats: &[],
|
|
||||||
});
|
|
||||||
|
|
||||||
tracing::warn!(
|
|
||||||
"Using fallback CPU texture for CEF rendering ({}x{}, {:?}) - hardware acceleration failed or unavailable. Consider checking GPU driver support.",
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
format
|
|
||||||
);
|
|
||||||
Ok(texture)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Common Vulkan utilities
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
|
||||||
pub mod vulkan {
|
|
||||||
use super::*;
|
|
||||||
use ash::vk;
|
|
||||||
|
|
||||||
/// Find a suitable memory type index for Vulkan allocation
|
|
||||||
pub fn find_memory_type_index(type_filter: u32, properties: vk::MemoryPropertyFlags, mem_properties: &vk::PhysicalDeviceMemoryProperties) -> Option<u32> {
|
|
||||||
(0..mem_properties.memory_type_count).find(|&i| (type_filter & (1 << i)) != 0 && mem_properties.memory_types[i as usize].property_flags.contains(properties))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if the wgpu device is using Vulkan backend
|
|
||||||
pub fn is_vulkan_backend(device: &Device) -> bool {
|
|
||||||
use wgpu::hal::api;
|
|
||||||
let mut is_vulkan = false;
|
|
||||||
unsafe {
|
|
||||||
device.as_hal::<api::Vulkan, _, _>(|device| {
|
|
||||||
is_vulkan = device.is_some();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
is_vulkan
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if the wgpu device is using D3D12 backend
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn is_d3d12_backend(device: &Device) -> bool {
|
|
||||||
use wgpu::hal::api;
|
|
||||||
let mut is_d3d12 = false;
|
|
||||||
unsafe {
|
|
||||||
device.as_hal::<api::Dx12, _, _>(|device| {
|
|
||||||
is_d3d12 = device.is_some();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
is_d3d12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,289 +0,0 @@
|
||||||
//! Windows D3D11 shared texture import implementation
|
|
||||||
|
|
||||||
use super::common::{format, texture, vulkan};
|
|
||||||
use super::{TextureImportError, TextureImportResult, TextureImporter};
|
|
||||||
use ash::vk;
|
|
||||||
use cef::{AcceleratedPaintInfo, sys::cef_color_type_t};
|
|
||||||
use std::os::raw::c_void;
|
|
||||||
use wgpu::hal::api;
|
|
||||||
|
|
||||||
pub struct D3D11Importer {
|
|
||||||
pub handle: *mut c_void,
|
|
||||||
pub format: cef_color_type_t,
|
|
||||||
pub width: u32,
|
|
||||||
pub height: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextureImporter for D3D11Importer {
|
|
||||||
fn new(info: &AcceleratedPaintInfo) -> Self {
|
|
||||||
Self {
|
|
||||||
handle: info.shared_texture_handle,
|
|
||||||
format: *info.format.as_ref(),
|
|
||||||
width: info.extra.coded_size.width as u32,
|
|
||||||
height: info.extra.coded_size.height as u32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_to_wgpu(&self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
// Try hardware acceleration first
|
|
||||||
if self.supports_hardware_acceleration(device) {
|
|
||||||
// Try D3D12 first (most efficient on Windows)
|
|
||||||
if vulkan::is_d3d12_backend(device) {
|
|
||||||
match self.import_via_d3d12(device) {
|
|
||||||
Ok(texture) => {
|
|
||||||
tracing::info!("Successfully imported D3D11 shared texture via D3D12");
|
|
||||||
return Ok(texture);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::warn!("Failed to import D3D11 via D3D12: {}, trying Vulkan fallback", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try Vulkan as fallback
|
|
||||||
if vulkan::is_vulkan_backend(device) {
|
|
||||||
match self.import_via_vulkan(device) {
|
|
||||||
Ok(texture) => {
|
|
||||||
tracing::info!("Successfully imported D3D11 shared texture via Vulkan");
|
|
||||||
return Ok(texture);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::warn!("Failed to import D3D11 via Vulkan: {}, falling back to CPU texture", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to CPU texture
|
|
||||||
texture::create_fallback(device, self.width, self.height, self.format, "CEF D3D11 Texture (fallback)")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn supports_hardware_acceleration(&self, device: &wgpu::Device) -> bool {
|
|
||||||
// Check if handle is valid
|
|
||||||
if self.handle.is_null() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if wgpu is using D3D12 or Vulkan backend
|
|
||||||
vulkan::is_d3d12_backend(device) || vulkan::is_vulkan_backend(device)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl D3D11Importer {
|
|
||||||
fn import_via_d3d12(&self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
// Get wgpu's D3D12 device
|
|
||||||
use wgpu::hal::api;
|
|
||||||
let hal_texture = unsafe {
|
|
||||||
device.as_hal::<api::Dx12, _, _>(|device| {
|
|
||||||
let Some(device) = device else {
|
|
||||||
return Err(TextureImportError::HardwareUnavailable {
|
|
||||||
reason: "Device is not using D3D12 backend".to_string(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Import D3D11 shared handle directly into D3D12 resource
|
|
||||||
let d3d12_resource = self.import_d3d11_handle_to_d3d12(device)?;
|
|
||||||
|
|
||||||
// Wrap D3D12 resource in wgpu-hal texture
|
|
||||||
let hal_texture = <api::Dx12 as wgpu::hal::Api>::Device::texture_from_raw(
|
|
||||||
d3d12_resource,
|
|
||||||
format::cef_to_wgpu(self.format)?,
|
|
||||||
wgpu::TextureDimension::D2,
|
|
||||||
wgpu::Extent3d {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
1, // mip_level_count
|
|
||||||
1, // sample_count
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(hal_texture)
|
|
||||||
})
|
|
||||||
}?;
|
|
||||||
|
|
||||||
// Import hal texture into wgpu
|
|
||||||
let texture = unsafe {
|
|
||||||
device.create_texture_from_hal::<api::Dx12>(
|
|
||||||
hal_texture,
|
|
||||||
&wgpu::TextureDescriptor {
|
|
||||||
label: Some("CEF D3D11→D3D12 Shared Texture"),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: format::cef_to_wgpu(self.format)?,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
view_formats: &[],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(texture)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_via_vulkan(&self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
// Get wgpu's Vulkan instance and device
|
|
||||||
use wgpu::{TextureUses, wgc::api::Vulkan};
|
|
||||||
let hal_texture = unsafe {
|
|
||||||
device.as_hal::<api::Vulkan, _, _>(|device| {
|
|
||||||
let Some(device) = device else {
|
|
||||||
return Err(TextureImportError::HardwareUnavailable {
|
|
||||||
reason: "Device is not using Vulkan backend".to_string(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Import D3D11 shared handle into Vulkan
|
|
||||||
let vk_image = self.import_d3d11_handle_to_vulkan(device)?;
|
|
||||||
|
|
||||||
// Wrap VkImage in wgpu-hal texture
|
|
||||||
let hal_texture = <api::Vulkan as wgpu::hal::Api>::Device::texture_from_raw(
|
|
||||||
vk_image,
|
|
||||||
&wgpu::hal::TextureDescriptor {
|
|
||||||
label: Some("CEF D3D11 Shared Texture"),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: format::cef_to_wgpu(self.format)?,
|
|
||||||
usage: TextureUses::COPY_DST | TextureUses::RESOURCE,
|
|
||||||
memory_flags: wgpu::hal::MemoryFlags::empty(),
|
|
||||||
view_formats: vec![],
|
|
||||||
},
|
|
||||||
None, // drop_callback
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(hal_texture)
|
|
||||||
})
|
|
||||||
}?;
|
|
||||||
|
|
||||||
// Import hal texture into wgpu
|
|
||||||
let texture = unsafe {
|
|
||||||
device.create_texture_from_hal::<Vulkan>(
|
|
||||||
hal_texture,
|
|
||||||
&wgpu::TextureDescriptor {
|
|
||||||
label: Some("CEF D3D11 Shared Texture"),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: format::cef_to_wgpu(self.format)?,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
view_formats: &[],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(texture)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_d3d11_handle_to_vulkan(&self, hal_device: &<api::Vulkan as wgpu::hal::Api>::Device) -> Result<vk::Image, TextureImportError> {
|
|
||||||
// Get raw Vulkan handles
|
|
||||||
let device = hal_device.raw_device();
|
|
||||||
let _instance = hal_device.shared_instance().raw_instance();
|
|
||||||
|
|
||||||
// Validate dimensions
|
|
||||||
if self.width == 0 || self.height == 0 {
|
|
||||||
return Err(TextureImportError::InvalidHandle("Invalid D3D11 texture dimensions".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create external memory image info
|
|
||||||
let mut external_memory_info = vk::ExternalMemoryImageCreateInfo::default().handle_types(vk::ExternalMemoryHandleTypeFlags::D3D11_TEXTURE);
|
|
||||||
|
|
||||||
// Create image create info
|
|
||||||
let image_create_info = vk::ImageCreateInfo::default()
|
|
||||||
.image_type(vk::ImageType::TYPE_2D)
|
|
||||||
.format(format::cef_to_vulkan(self.format)?)
|
|
||||||
.extent(vk::Extent3D {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth: 1,
|
|
||||||
})
|
|
||||||
.mip_levels(1)
|
|
||||||
.array_layers(1)
|
|
||||||
.samples(vk::SampleCountFlags::TYPE_1)
|
|
||||||
.tiling(vk::ImageTiling::OPTIMAL)
|
|
||||||
.usage(vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::COLOR_ATTACHMENT)
|
|
||||||
.sharing_mode(vk::SharingMode::EXCLUSIVE)
|
|
||||||
.push_next(&mut external_memory_info);
|
|
||||||
|
|
||||||
// Create the image
|
|
||||||
let image = unsafe {
|
|
||||||
device.create_image(&image_create_info, None).map_err(|e| TextureImportError::VulkanError {
|
|
||||||
operation: format!("Failed to create Vulkan image: {:?}", e),
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get memory requirements
|
|
||||||
let memory_requirements = unsafe { device.get_image_memory_requirements(image) };
|
|
||||||
|
|
||||||
// Import D3D11 handle
|
|
||||||
let mut import_memory_win32 = vk::ImportMemoryWin32HandleInfoKHR::default()
|
|
||||||
.handle_type(vk::ExternalMemoryHandleTypeFlags::D3D11_TEXTURE)
|
|
||||||
.handle(self.handle as isize);
|
|
||||||
|
|
||||||
// Find a suitable memory type
|
|
||||||
let memory_properties = unsafe { hal_device.shared_instance().raw_instance().get_physical_device_memory_properties(hal_device.raw_physical_device()) };
|
|
||||||
|
|
||||||
let memory_type_index =
|
|
||||||
vulkan::find_memory_type_index(memory_requirements.memory_type_bits, vk::MemoryPropertyFlags::empty(), &memory_properties).ok_or_else(|| TextureImportError::VulkanError {
|
|
||||||
operation: "Failed to find suitable memory type for D3D11 texture".to_string(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let allocate_info = vk::MemoryAllocateInfo::default()
|
|
||||||
.allocation_size(memory_requirements.size)
|
|
||||||
.memory_type_index(memory_type_index)
|
|
||||||
.push_next(&mut import_memory_win32);
|
|
||||||
|
|
||||||
let device_memory = unsafe {
|
|
||||||
device.allocate_memory(&allocate_info, None).map_err(|e| TextureImportError::VulkanError {
|
|
||||||
operation: format!("Failed to allocate memory for D3D11 texture: {:?}", e),
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
// Bind memory to image
|
|
||||||
unsafe {
|
|
||||||
device.bind_image_memory(image, device_memory, 0).map_err(|e| TextureImportError::VulkanError {
|
|
||||||
operation: format!("Failed to bind memory to image: {:?}", e),
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(image)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_d3d11_handle_to_d3d12(&self, hal_device: &<wgpu::hal::api::Dx12 as wgpu::hal::Api>::Device) -> Result<windows::Win32::Graphics::Direct3D12::ID3D12Resource, TextureImportError> {
|
|
||||||
use windows::Win32::Graphics::Direct3D12::*;
|
|
||||||
|
|
||||||
// Get D3D12 device from wgpu-hal
|
|
||||||
let d3d12_device = hal_device.raw_device();
|
|
||||||
|
|
||||||
// Validate dimensions
|
|
||||||
if self.width == 0 || self.height == 0 {
|
|
||||||
return Err(TextureImportError::InvalidHandle("Invalid D3D11 texture dimensions".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open D3D11 shared handle on D3D12 device
|
|
||||||
unsafe {
|
|
||||||
let mut shared_resource: Option<ID3D12Resource> = None;
|
|
||||||
d3d12_device
|
|
||||||
.OpenSharedHandle(windows::Win32::Foundation::HANDLE(self.handle), &mut shared_resource)
|
|
||||||
.map_err(|e| TextureImportError::PlatformError {
|
|
||||||
message: format!("Failed to open D3D11 shared handle on D3D12: {:?}", e),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
shared_resource.ok_or_else(|| TextureImportError::InvalidHandle("Failed to get D3D12 resource from shared handle".to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,273 +0,0 @@
|
||||||
//! Linux DMA-BUF texture import implementation
|
|
||||||
|
|
||||||
use super::common::{format, texture, vulkan};
|
|
||||||
use super::{TextureImportError, TextureImportResult, TextureImporter};
|
|
||||||
use ash::vk;
|
|
||||||
use cef::{AcceleratedPaintInfo, sys::cef_color_type_t};
|
|
||||||
use wgpu::hal::api;
|
|
||||||
|
|
||||||
pub(crate) struct DmaBufImporter {
|
|
||||||
fds: Vec<std::os::fd::RawFd>,
|
|
||||||
format: cef_color_type_t,
|
|
||||||
modifier: u64,
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
strides: Vec<u32>,
|
|
||||||
offsets: Vec<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextureImporter for DmaBufImporter {
|
|
||||||
fn new(info: &AcceleratedPaintInfo) -> Self {
|
|
||||||
Self {
|
|
||||||
fds: extract_fds_from_info(info),
|
|
||||||
format: *info.format.as_ref(),
|
|
||||||
modifier: info.modifier,
|
|
||||||
width: info.extra.coded_size.width as u32,
|
|
||||||
height: info.extra.coded_size.height as u32,
|
|
||||||
strides: extract_strides_from_info(info),
|
|
||||||
offsets: extract_offsets_from_info(info),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_to_wgpu(&self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
// Try hardware acceleration first
|
|
||||||
if self.supports_hardware_acceleration(device) {
|
|
||||||
match self.import_via_vulkan(device) {
|
|
||||||
Ok(texture) => {
|
|
||||||
tracing::info!("Successfully imported DMA-BUF texture via Vulkan");
|
|
||||||
return Ok(texture);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::warn!("Failed to import DMA-BUF via Vulkan: {}, falling back to CPU texture", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to CPU texture
|
|
||||||
texture::create_fallback(device, self.width, self.height, self.format, "CEF DMA-BUF Texture (fallback)")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn supports_hardware_acceleration(&self, device: &wgpu::Device) -> bool {
|
|
||||||
// Check if we have valid file descriptors
|
|
||||||
if self.fds.is_empty() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for &fd in &self.fds {
|
|
||||||
if fd < 0 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check if file descriptor is valid
|
|
||||||
let flags = unsafe { libc::fcntl(fd, libc::F_GETFD) };
|
|
||||||
if flags == -1 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if wgpu is using Vulkan backend
|
|
||||||
vulkan::is_vulkan_backend(device)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DmaBufImporter {
|
|
||||||
fn import_via_vulkan(&self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
// Get wgpu's Vulkan instance and device
|
|
||||||
use wgpu::{TextureUses, wgc::api::Vulkan};
|
|
||||||
let hal_texture = unsafe {
|
|
||||||
device.as_hal::<api::Vulkan, _, _>(|device| {
|
|
||||||
let Some(device) = device else {
|
|
||||||
return Err(TextureImportError::HardwareUnavailable {
|
|
||||||
reason: "Device is not using Vulkan backend".to_string(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create VkImage from DMA-BUF using external memory
|
|
||||||
let vk_image = self.create_vulkan_image_from_dmabuf(device)?;
|
|
||||||
|
|
||||||
// Wrap VkImage in wgpu-hal texture
|
|
||||||
let hal_texture = <api::Vulkan as wgpu::hal::Api>::Device::texture_from_raw(
|
|
||||||
vk_image,
|
|
||||||
&wgpu::hal::TextureDescriptor {
|
|
||||||
label: Some("CEF DMA-BUF Texture"),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: format::cef_to_wgpu(self.format)?,
|
|
||||||
usage: TextureUses::COPY_DST | TextureUses::RESOURCE,
|
|
||||||
memory_flags: wgpu::hal::MemoryFlags::empty(),
|
|
||||||
view_formats: vec![],
|
|
||||||
},
|
|
||||||
None, // drop_callback
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(hal_texture)
|
|
||||||
})
|
|
||||||
}?;
|
|
||||||
|
|
||||||
// Import hal texture into wgpu
|
|
||||||
let texture = unsafe {
|
|
||||||
device.create_texture_from_hal::<Vulkan>(
|
|
||||||
hal_texture,
|
|
||||||
&wgpu::TextureDescriptor {
|
|
||||||
label: Some("CEF DMA-BUF Texture"),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: format::cef_to_wgpu(self.format)?,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
view_formats: &[],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(texture)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_vulkan_image_from_dmabuf(&self, hal_device: &<api::Vulkan as wgpu::hal::Api>::Device) -> Result<vk::Image, TextureImportError> {
|
|
||||||
// Get raw Vulkan handles
|
|
||||||
let device = hal_device.raw_device();
|
|
||||||
let _instance = hal_device.shared_instance().raw_instance();
|
|
||||||
|
|
||||||
// Validate dimensions
|
|
||||||
if self.width == 0 || self.height == 0 {
|
|
||||||
return Err(TextureImportError::InvalidHandle("Invalid DMA-BUF dimensions".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create external memory image
|
|
||||||
let image_create_info = vk::ImageCreateInfo::default()
|
|
||||||
.image_type(vk::ImageType::TYPE_2D)
|
|
||||||
.format(format::cef_to_vulkan(self.format)?)
|
|
||||||
.extent(vk::Extent3D {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth: 1,
|
|
||||||
})
|
|
||||||
.mip_levels(1)
|
|
||||||
.array_layers(1)
|
|
||||||
.samples(vk::SampleCountFlags::TYPE_1)
|
|
||||||
.tiling(vk::ImageTiling::DRM_FORMAT_MODIFIER_EXT)
|
|
||||||
.usage(vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::COLOR_ATTACHMENT)
|
|
||||||
.sharing_mode(vk::SharingMode::EXCLUSIVE);
|
|
||||||
|
|
||||||
// Set up DRM format modifier
|
|
||||||
let plane_layouts = self.create_subresource_layouts()?;
|
|
||||||
let mut drm_format_modifier = vk::ImageDrmFormatModifierExplicitCreateInfoEXT::default()
|
|
||||||
.drm_format_modifier(self.modifier)
|
|
||||||
.plane_layouts(&plane_layouts);
|
|
||||||
|
|
||||||
let image_create_info = image_create_info.push_next(&mut drm_format_modifier);
|
|
||||||
|
|
||||||
// Create the image
|
|
||||||
let image = unsafe {
|
|
||||||
device.create_image(&image_create_info, None).map_err(|e| TextureImportError::VulkanError {
|
|
||||||
operation: format!("Failed to create Vulkan image: {e:?}"),
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
// Import memory from DMA-BUF
|
|
||||||
let memory_requirements = unsafe { device.get_image_memory_requirements(image) };
|
|
||||||
|
|
||||||
// Duplicate the file descriptor to avoid ownership issues
|
|
||||||
let dup_fd = unsafe { libc::dup(self.fds[0]) };
|
|
||||||
if dup_fd == -1 {
|
|
||||||
return Err(TextureImportError::PlatformError {
|
|
||||||
message: "Failed to duplicate DMA-BUF file descriptor".to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut import_memory_fd = vk::ImportMemoryFdInfoKHR::default().handle_type(vk::ExternalMemoryHandleTypeFlags::DMA_BUF_EXT).fd(dup_fd);
|
|
||||||
|
|
||||||
// Find a suitable memory type
|
|
||||||
let memory_properties = unsafe { hal_device.shared_instance().raw_instance().get_physical_device_memory_properties(hal_device.raw_physical_device()) };
|
|
||||||
|
|
||||||
let memory_type_index =
|
|
||||||
vulkan::find_memory_type_index(memory_requirements.memory_type_bits, vk::MemoryPropertyFlags::empty(), &memory_properties).ok_or_else(|| TextureImportError::VulkanError {
|
|
||||||
operation: "Failed to find suitable memory type for DMA-BUF".to_string(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let allocate_info = vk::MemoryAllocateInfo::default()
|
|
||||||
.allocation_size(memory_requirements.size)
|
|
||||||
.memory_type_index(memory_type_index)
|
|
||||||
.push_next(&mut import_memory_fd);
|
|
||||||
|
|
||||||
let device_memory = unsafe {
|
|
||||||
device.allocate_memory(&allocate_info, None).map_err(|e| TextureImportError::VulkanError {
|
|
||||||
operation: format!("Failed to allocate memory for DMA-BUF: {e:?}"),
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
// Bind memory to image
|
|
||||||
unsafe {
|
|
||||||
device.bind_image_memory(image, device_memory, 0).map_err(|e| TextureImportError::VulkanError {
|
|
||||||
operation: format!("Failed to bind memory to image: {e:?}"),
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(image)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_subresource_layouts(&self) -> Result<Vec<vk::SubresourceLayout>, TextureImportError> {
|
|
||||||
let mut layouts = Vec::new();
|
|
||||||
|
|
||||||
for i in 0..self.fds.len() {
|
|
||||||
layouts.push(vk::SubresourceLayout {
|
|
||||||
offset: self.offsets.get(i).copied().unwrap_or(0) as u64,
|
|
||||||
size: 0, // Will be calculated by driver
|
|
||||||
row_pitch: self.strides.get(i).copied().unwrap_or(0) as u64,
|
|
||||||
array_pitch: 0,
|
|
||||||
depth_pitch: 0,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(layouts)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_fds_from_info(info: &cef::AcceleratedPaintInfo) -> Vec<std::os::fd::RawFd> {
|
|
||||||
let plane_count = info.plane_count as usize;
|
|
||||||
let mut fds = Vec::with_capacity(plane_count);
|
|
||||||
|
|
||||||
for i in 0..plane_count {
|
|
||||||
if let Some(plane) = info.planes.get(i) {
|
|
||||||
fds.push(plane.fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fds
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_strides_from_info(info: &cef::AcceleratedPaintInfo) -> Vec<u32> {
|
|
||||||
let plane_count = info.plane_count as usize;
|
|
||||||
let mut strides = Vec::with_capacity(plane_count);
|
|
||||||
|
|
||||||
for i in 0..plane_count {
|
|
||||||
if let Some(plane) = info.planes.get(i) {
|
|
||||||
strides.push(plane.stride);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strides
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_offsets_from_info(info: &cef::AcceleratedPaintInfo) -> Vec<u32> {
|
|
||||||
let plane_count = info.plane_count as usize;
|
|
||||||
let mut offsets = Vec::with_capacity(plane_count);
|
|
||||||
|
|
||||||
for i in 0..plane_count {
|
|
||||||
if let Some(plane) = info.planes.get(i) {
|
|
||||||
offsets.push(plane.offset as u32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offsets
|
|
||||||
}
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
//! macOS IOSurface texture import implementation
|
|
||||||
|
|
||||||
use super::common::{format, texture};
|
|
||||||
use super::{TextureImportError, TextureImportResult, TextureImporter};
|
|
||||||
use cef::{AcceleratedPaintInfo, sys::cef_color_type_t};
|
|
||||||
use metal::foreign_types::ForeignType;
|
|
||||||
use metal::{MTLPixelFormat, MTLTextureType, MTLTextureUsage, Texture};
|
|
||||||
use std::os::raw::c_void;
|
|
||||||
use wgpu::hal::api;
|
|
||||||
|
|
||||||
pub struct IOSurfaceImporter {
|
|
||||||
pub handle: *mut c_void,
|
|
||||||
pub format: cef_color_type_t,
|
|
||||||
pub width: u32,
|
|
||||||
pub height: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextureImporter for IOSurfaceImporter {
|
|
||||||
fn new(info: &AcceleratedPaintInfo) -> Self {
|
|
||||||
Self {
|
|
||||||
handle: info.shared_texture_io_surface,
|
|
||||||
format: *info.format.as_ref(),
|
|
||||||
width: info.extra.coded_size.width as u32,
|
|
||||||
height: info.extra.coded_size.height as u32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_to_wgpu(&self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
// Try hardware acceleration first
|
|
||||||
if self.supports_hardware_acceleration(device) {
|
|
||||||
match self.import_via_metal(device) {
|
|
||||||
Ok(texture) => {
|
|
||||||
tracing::trace!("Successfully imported IOSurface texture via Metal");
|
|
||||||
return Ok(texture);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::warn!("Failed to import IOSurface via Metal: {}, falling back to CPU texture", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to CPU texture
|
|
||||||
texture::create_fallback(device, self.width, self.height, self.format, "CEF IOSurface Texture (fallback)")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn supports_hardware_acceleration(&self, device: &wgpu::Device) -> bool {
|
|
||||||
// Check if handle is valid
|
|
||||||
if self.handle.is_null() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if wgpu is using Metal backend
|
|
||||||
self.is_metal_backend(device)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IOSurfaceImporter {
|
|
||||||
fn import_via_metal(&self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
// Get wgpu's Metal device
|
|
||||||
use wgpu::wgc::api::Metal;
|
|
||||||
let hal_texture = unsafe {
|
|
||||||
device.as_hal::<api::Metal, _, _>(|hal_device| {
|
|
||||||
let Some(hal_device) = hal_device else {
|
|
||||||
return Err(TextureImportError::HardwareUnavailable {
|
|
||||||
reason: "Device is not using Metal backend".to_string(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Import IOSurface handle into Metal texture
|
|
||||||
let metal_texture = self.import_iosurface_to_metal_texture(hal_device)?;
|
|
||||||
|
|
||||||
// Wrap Metal texture in wgpu-hal texture
|
|
||||||
// texture_from_raw signature: (texture, format, texture_type, mip_levels, sample_count, copy_extent)
|
|
||||||
let hal_texture = <api::Metal as wgpu::hal::Api>::Device::texture_from_raw(
|
|
||||||
metal_texture,
|
|
||||||
format::cef_to_wgpu(self.format)?,
|
|
||||||
MTLTextureType::D2,
|
|
||||||
1, // mip_level_count
|
|
||||||
1, // sample_count
|
|
||||||
wgpu::hal::CopyExtent {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth: 1,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(hal_texture)
|
|
||||||
})
|
|
||||||
}?;
|
|
||||||
|
|
||||||
// Import hal texture into wgpu
|
|
||||||
let texture = unsafe {
|
|
||||||
device.create_texture_from_hal::<Metal>(
|
|
||||||
hal_texture,
|
|
||||||
&wgpu::TextureDescriptor {
|
|
||||||
label: Some("CEF IOSurface Texture"),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: format::cef_to_wgpu(self.format)?,
|
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
view_formats: &[],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(texture)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_iosurface_to_metal_texture(&self, hal_device: &<api::Metal as wgpu::hal::Api>::Device) -> Result<Texture, TextureImportError> {
|
|
||||||
// Validate dimensions
|
|
||||||
if self.width == 0 || self.height == 0 {
|
|
||||||
return Err(TextureImportError::InvalidHandle("Invalid IOSurface texture dimensions".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the Metal device from wgpu-hal
|
|
||||||
let metal_device = hal_device.raw_device();
|
|
||||||
|
|
||||||
// Convert CEF format to Metal pixel format
|
|
||||||
let metal_format = self.cef_to_metal_format(self.format)?;
|
|
||||||
|
|
||||||
// Create Metal texture from IOSurface using objc runtime
|
|
||||||
// We need to use raw objc because the metal crate doesn't expose IOSurface creation directly
|
|
||||||
#[allow(unexpected_cfgs)] // Suppress objc crate internal cfg warnings
|
|
||||||
unsafe {
|
|
||||||
use objc::runtime::Object;
|
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
|
||||||
|
|
||||||
let iosurface = self.handle;
|
|
||||||
|
|
||||||
// Create texture descriptor using NSObject/Objective-C
|
|
||||||
let descriptor_class = class!(MTLTextureDescriptor);
|
|
||||||
let descriptor: *mut Object = msg_send![descriptor_class, new];
|
|
||||||
|
|
||||||
// Set descriptor properties
|
|
||||||
let _: () = msg_send![descriptor, setTextureType: MTLTextureType::D2];
|
|
||||||
let _: () = msg_send![descriptor, setPixelFormat: metal_format];
|
|
||||||
let _: () = msg_send![descriptor, setWidth: self.width as u64];
|
|
||||||
let _: () = msg_send![descriptor, setHeight: self.height as u64];
|
|
||||||
let _: () = msg_send![descriptor, setDepth: 1u64];
|
|
||||||
let _: () = msg_send![descriptor, setMipmapLevelCount: 1u64];
|
|
||||||
let _: () = msg_send![descriptor, setSampleCount: 1u64];
|
|
||||||
let _: () = msg_send![descriptor, setArrayLength: 1u64];
|
|
||||||
let _: () = msg_send![descriptor, setUsage: MTLTextureUsage::ShaderRead.bits()];
|
|
||||||
|
|
||||||
// Get device pointer
|
|
||||||
let device_ptr = metal_device.lock().as_ptr();
|
|
||||||
|
|
||||||
// Call newTextureWithDescriptor:iosurface:plane:
|
|
||||||
let metal_texture: *mut Object = msg_send![device_ptr, newTextureWithDescriptor:descriptor iosurface:iosurface plane:0u64];
|
|
||||||
|
|
||||||
// Release the descriptor
|
|
||||||
let _: () = msg_send![descriptor, release];
|
|
||||||
|
|
||||||
if metal_texture.is_null() {
|
|
||||||
return Err(TextureImportError::PlatformError {
|
|
||||||
message: "Failed to create Metal texture from IOSurface".to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast to correct type and wrap in metal::Texture
|
|
||||||
let mtl_texture = metal_texture as *mut metal::MTLTexture;
|
|
||||||
Ok(Texture::from_ptr(mtl_texture))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cef_to_metal_format(&self, format: cef_color_type_t) -> Result<MTLPixelFormat, TextureImportError> {
|
|
||||||
match format {
|
|
||||||
cef_color_type_t::CEF_COLOR_TYPE_BGRA_8888 => Ok(MTLPixelFormat::BGRA8Unorm_sRGB),
|
|
||||||
cef_color_type_t::CEF_COLOR_TYPE_RGBA_8888 => Ok(MTLPixelFormat::RGBA8Unorm_sRGB),
|
|
||||||
_ => Err(TextureImportError::UnsupportedFormat { format }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_metal_backend(&self, device: &wgpu::Device) -> bool {
|
|
||||||
use wgpu::hal::api;
|
|
||||||
let mut is_metal = false;
|
|
||||||
unsafe {
|
|
||||||
device.as_hal::<api::Metal, _, _>(|device| {
|
|
||||||
is_metal = device.is_some();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
is_metal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
//! Unified texture import system for CEF hardware acceleration
|
|
||||||
//!
|
|
||||||
//! This module provides a platform-agnostic interface for importing shared textures
|
|
||||||
//! from CEF into wgpu, with automatic fallback to CPU textures when hardware
|
|
||||||
//! acceleration is not available.
|
|
||||||
//!
|
|
||||||
//! # Supported Platforms
|
|
||||||
//!
|
|
||||||
//! - **Linux**: DMA-BUF via Vulkan external memory
|
|
||||||
//! - **Windows**: D3D11 shared textures via Vulkan interop
|
|
||||||
//! - **macOS**: IOSurface via Metal native API
|
|
||||||
//!
|
|
||||||
//! # Features
|
|
||||||
//!
|
|
||||||
//! - `accelerated_paint` - Base feature for texture import
|
|
||||||
//! - `accelerated_paint_dmabuf` - Linux DMA-BUF support
|
|
||||||
//! - `accelerated_paint_d3d11` - Windows D3D11 support
|
|
||||||
//! - `accelerated_paint_iosurface` - macOS IOSurface support
|
|
||||||
|
|
||||||
pub(crate) mod common;
|
|
||||||
|
|
||||||
pub(crate) mod shared_texture_handle;
|
|
||||||
pub(crate) use shared_texture_handle::SharedTextureHandle;
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub(crate) mod dmabuf;
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub(crate) mod d3d11;
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub(crate) mod iosurface;
|
|
||||||
|
|
||||||
/// Result type for texture import operations
|
|
||||||
pub type TextureImportResult = Result<wgpu::Texture, TextureImportError>;
|
|
||||||
|
|
||||||
/// Errors that can occur during texture import
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
|
||||||
pub enum TextureImportError {
|
|
||||||
#[error("Invalid texture handle: {0}")]
|
|
||||||
InvalidHandle(String),
|
|
||||||
|
|
||||||
#[error("Unsupported texture format: {format:?}")]
|
|
||||||
UnsupportedFormat { format: cef::sys::cef_color_type_t },
|
|
||||||
|
|
||||||
#[error("Hardware acceleration not available: {reason}")]
|
|
||||||
HardwareUnavailable { reason: String },
|
|
||||||
|
|
||||||
#[error("Vulkan operation failed: {operation}")]
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
|
||||||
VulkanError { operation: String },
|
|
||||||
|
|
||||||
#[error("Platform-specific error: {message}")]
|
|
||||||
PlatformError { message: String },
|
|
||||||
|
|
||||||
#[error("Unsupported platform for texture import")]
|
|
||||||
UnsupportedPlatform,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait for platform-specific texture importers
|
|
||||||
pub trait TextureImporter {
|
|
||||||
fn new(info: &cef::AcceleratedPaintInfo) -> Self;
|
|
||||||
|
|
||||||
/// Import the texture into wgpu, with automatic fallback to CPU texture
|
|
||||||
fn import_to_wgpu(&self, device: &wgpu::Device) -> TextureImportResult;
|
|
||||||
|
|
||||||
/// Check if hardware acceleration is available for this texture
|
|
||||||
fn supports_hardware_acceleration(&self, device: &wgpu::Device) -> bool;
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
use cef::AcceleratedPaintInfo;
|
|
||||||
|
|
||||||
use super::{TextureImportError, TextureImportResult, TextureImporter};
|
|
||||||
|
|
||||||
pub(crate) enum SharedTextureHandle {
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
DmaBuf(super::dmabuf::DmaBufImporter),
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
D3D11(super::d3d11::D3D11Importer),
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
IOSurface(super::iosurface::IOSurfaceImporter),
|
|
||||||
Unsupported,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SharedTextureHandle {
|
|
||||||
pub(crate) fn new(info: &AcceleratedPaintInfo) -> Self {
|
|
||||||
// Extract DMA-BUF information
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
return Self::DmaBuf(super::dmabuf::DmaBufImporter::new(info));
|
|
||||||
|
|
||||||
// Extract D3D11 shared handle with texture metadata
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
return Self::D3D11(super::d3d11::D3D11Importer::new(info));
|
|
||||||
|
|
||||||
// Extract IOSurface handle with texture metadata
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
return Self::IOSurface(super::iosurface::IOSurfaceImporter::new(info));
|
|
||||||
|
|
||||||
#[allow(unreachable_code)]
|
|
||||||
Self::Unsupported
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Import a texture using the appropriate platform-specific importer
|
|
||||||
pub(crate) fn import_texture(self, device: &wgpu::Device) -> TextureImportResult {
|
|
||||||
match self {
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
SharedTextureHandle::DmaBuf(importer) => importer.import_to_wgpu(device),
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
SharedTextureHandle::D3D11(importer) => importer.import_to_wgpu(device),
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
SharedTextureHandle::IOSurface(importer) => importer.import_to_wgpu(device),
|
|
||||||
SharedTextureHandle::Unsupported => Err(TextureImportError::UnsupportedPlatform),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -250,6 +250,7 @@ impl GraphicsState {
|
||||||
load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.01, g: 0.01, b: 0.01, a: 1.0 }),
|
load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.01, g: 0.01, b: 0.01, a: 1.0 }),
|
||||||
store: wgpu::StoreOp::Store,
|
store: wgpu::StoreOp::Store,
|
||||||
},
|
},
|
||||||
|
depth_slice: None,
|
||||||
})],
|
})],
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
occlusion_query_set: None,
|
occlusion_query_set: None,
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ impl ContextBuilder {
|
||||||
required_limits: adapter.limits(),
|
required_limits: adapter.limits(),
|
||||||
memory_hints: Default::default(),
|
memory_hints: Default::default(),
|
||||||
trace: wgpu::Trace::Off,
|
trace: wgpu::Trace::Off,
|
||||||
|
experimental_features: Default::default(),
|
||||||
};
|
};
|
||||||
adapter.request_device(&device_descriptor).await.ok()
|
adapter.request_device(&device_descriptor).await.ok()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue