examples: Update to glutin 0.32 / winit 0.30

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1661>
This commit is contained in:
Sebastian Dröge 2025-03-03 15:24:01 +02:00
parent 21a564d762
commit 2f23f55cd5
5 changed files with 434 additions and 221 deletions

347
Cargo.lock generated
View file

@ -23,9 +23,9 @@ dependencies = [
[[package]]
name = "android-activity"
version = "0.5.2"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289"
checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046"
dependencies = [
"android-properties",
"bitflags 2.9.0",
@ -117,22 +117,12 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]]
name = "block-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7"
dependencies = [
"objc-sys",
]
[[package]]
name = "block2"
version = "0.3.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68"
checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
dependencies = [
"block-sys",
"objc2",
]
@ -189,9 +179,9 @@ dependencies = [
[[package]]
name = "calloop"
version = "0.12.4"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298"
checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec"
dependencies = [
"bitflags 2.9.0",
"log",
@ -203,9 +193,9 @@ dependencies = [
[[package]]
name = "calloop-wayland-source"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02"
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
dependencies = [
"calloop",
"rustix",
@ -248,9 +238,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.1.1"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "cgl"
@ -453,6 +443,12 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]]
name = "dpi"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
[[package]]
name = "either"
version = "1.14.0"
@ -805,9 +801,9 @@ dependencies = [
[[package]]
name = "glutin"
version = "0.31.3"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746"
checksum = "03642b8b0cce622392deb0ee3e88511f75df2daac806102597905c3ea1974848"
dependencies = [
"bitflags 2.9.0",
"cfg_aliases",
@ -817,21 +813,22 @@ dependencies = [
"glutin_egl_sys",
"glutin_glx_sys",
"glutin_wgl_sys",
"icrate",
"libloading",
"objc2",
"objc2-app-kit",
"objc2-foundation",
"once_cell",
"raw-window-handle",
"wayland-sys",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
"x11-dl",
]
[[package]]
name = "glutin-winit"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735"
checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f"
dependencies = [
"cfg_aliases",
"glutin",
@ -841,19 +838,19 @@ dependencies = [
[[package]]
name = "glutin_egl_sys"
version = "0.6.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd"
checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2"
dependencies = [
"gl_generator",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
name = "glutin_glx_sys"
version = "0.5.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f"
checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185"
dependencies = [
"gl_generator",
"x11-dl",
@ -861,9 +858,9 @@ dependencies = [
[[package]]
name = "glutin_wgl_sys"
version = "0.5.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead"
checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e"
dependencies = [
"gl_generator",
]
@ -1611,17 +1608,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]]
name = "icrate"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319"
dependencies = [
"block2",
"dispatch",
"objc2",
]
[[package]]
name = "image"
version = "0.25.5"
@ -1807,9 +1793,9 @@ checksum = "956787520e75e9bd233246045d19f42fb73242759cc57fba9611d940ae96d4b0"
[[package]]
name = "ndk"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7"
checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
dependencies = [
"bitflags 2.9.0",
"jni-sys",
@ -1828,9 +1814,9 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
[[package]]
name = "ndk-sys"
version = "0.5.0+25.2.9519653"
version = "0.6.0+11769913"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691"
checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873"
dependencies = [
"jni-sys",
]
@ -1908,19 +1894,200 @@ checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
[[package]]
name = "objc2"
version = "0.4.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d"
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [
"objc-sys",
"objc2-encode",
]
[[package]]
name = "objc2-encode"
version = "3.0.0"
name = "objc2-app-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666"
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.9.0",
"block2",
"libc",
"objc2",
"objc2-core-data",
"objc2-core-image",
"objc2-foundation",
"objc2-quartz-core",
]
[[package]]
name = "objc2-cloud-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-core-location",
"objc2-foundation",
]
[[package]]
name = "objc2-contacts"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
dependencies = [
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-core-data"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-core-image"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
dependencies = [
"block2",
"objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]]
name = "objc2-core-location"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
dependencies = [
"block2",
"objc2",
"objc2-contacts",
"objc2-foundation",
]
[[package]]
name = "objc2-encode"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
[[package]]
name = "objc2-foundation"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.9.0",
"block2",
"dispatch",
"libc",
"objc2",
]
[[package]]
name = "objc2-link-presentation"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
dependencies = [
"block2",
"objc2",
"objc2-app-kit",
"objc2-foundation",
]
[[package]]
name = "objc2-metal"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-quartz-core"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]]
name = "objc2-symbols"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc"
dependencies = [
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-ui-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-cloud-kit",
"objc2-core-data",
"objc2-core-image",
"objc2-core-location",
"objc2-foundation",
"objc2-link-presentation",
"objc2-quartz-core",
"objc2-symbols",
"objc2-uniform-type-identifiers",
"objc2-user-notifications",
]
[[package]]
name = "objc2-uniform-type-identifiers"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
dependencies = [
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-user-notifications"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-core-location",
"objc2-foundation",
]
[[package]]
name = "once_cell"
@ -2010,6 +2177,26 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pin-project"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.2.16"
@ -2094,15 +2281,15 @@ dependencies = [
[[package]]
name = "raw-window-handle"
version = "0.5.2"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
[[package]]
name = "redox_syscall"
version = "0.3.5"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
@ -2259,9 +2446,9 @@ checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
[[package]]
name = "smithay-client-toolkit"
version = "0.18.1"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a"
checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016"
dependencies = [
"bitflags 2.9.0",
"calloop",
@ -2648,9 +2835,9 @@ dependencies = [
[[package]]
name = "wayland-protocols"
version = "0.31.2"
version = "0.32.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4"
checksum = "0781cf46869b37e36928f7b432273c0995aa8aed9552c556fb18754420541efc"
dependencies = [
"bitflags 2.9.0",
"wayland-backend",
@ -2660,9 +2847,9 @@ dependencies = [
[[package]]
name = "wayland-protocols-plasma"
version = "0.2.0"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479"
checksum = "7ccaacc76703fefd6763022ac565b590fcade92202492381c95b2edfdf7d46b3"
dependencies = [
"bitflags 2.9.0",
"wayland-backend",
@ -2673,9 +2860,9 @@ dependencies = [
[[package]]
name = "wayland-protocols-wlr"
version = "0.2.0"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6"
checksum = "248a02e6f595aad796561fa82d25601bd2c8c3b145b1c7453fc8f94c1a58f8b2"
dependencies = [
"bitflags 2.9.0",
"wayland-backend",
@ -2719,9 +2906,9 @@ dependencies = [
[[package]]
name = "web-time"
version = "0.2.4"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
@ -2848,11 +3035,11 @@ dependencies = [
[[package]]
name = "windows-sys"
version = "0.48.0"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.48.5",
"windows-targets 0.52.6",
]
[[package]]
@ -3044,36 +3231,40 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winit"
version = "0.29.15"
version = "0.30.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca"
checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0"
dependencies = [
"ahash",
"android-activity",
"atomic-waker",
"bitflags 2.9.0",
"block2",
"bytemuck",
"calloop",
"cfg_aliases",
"concurrent-queue",
"core-foundation 0.9.4",
"core-graphics 0.23.2",
"cursor-icon",
"icrate",
"dpi",
"js-sys",
"libc",
"log",
"memmap2",
"ndk",
"ndk-sys",
"objc2",
"once_cell",
"objc2-app-kit",
"objc2-foundation",
"objc2-ui-kit",
"orbclient",
"percent-encoding",
"pin-project",
"raw-window-handle",
"redox_syscall 0.3.5",
"redox_syscall 0.4.1",
"rustix",
"smithay-client-toolkit",
"smol_str",
"tracing",
"unicode-segmentation",
"wasm-bindgen",
"wasm-bindgen-futures",
@ -3083,7 +3274,7 @@ dependencies = [
"wayland-protocols-plasma",
"web-sys",
"web-time",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
"x11-dl",
"x11rb",
"xkbcommon-dl",

View file

@ -31,16 +31,16 @@ cairo-rs = { workspace = true, features=["use_glib"], optional = true }
derive_more = { version = "2", features = ["display", "error"] }
futures = "0.3"
# Since there's nothing Windows-specific to enable on gstreamer-rs, unconditionally enable glutin's WGL backend
glutin = { version = "0.31", optional = true, default-features = false, features = ["wgl"] }
glutin-winit = { version = "0.4", optional = true, default-features = false, features = ["wgl"] }
glutin = { version = "0.32", optional = true, default-features = false }
glutin-winit = { version = "0.5", optional = true, default-features = false }
image = { version = "0.25", optional = true, default-features = false, features = ["png", "jpeg"] }
memfd = { version = "0.6", optional = true }
memmap2 = { version = "0.9", optional = true }
pango = { workspace = true, optional = true }
pangocairo = { workspace = true, optional = true }
raw-window-handle = { version = "0.5", optional = true }
raw-window-handle = { version = "0.6", optional = true }
uds = { version = "0.4", optional = true }
winit = { version = "0.29", optional = true, default-features = false, features = ["rwh_05"] }
winit = { version = "0.30", optional = true, default-features = false } #, features = ["rwh_05"] }
atomic_refcell = "0.1"
data-encoding = "2.0"
@ -51,6 +51,8 @@ windows = { version = "0.60", features=["Win32_Graphics_Direct3D11",
"Win32_Graphics_Direct2D_Common", "Win32_Graphics_DirectWrite",
"Win32_Graphics_Imaging", "Win32_System_Com", "Foundation_Numerics"], optional = true }
windows-numerics = "0.1"
glutin = { version = "0.32", features = ["wgl"] }
glutin-winit = { version = "0.5", features = ["wgl"] }
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.26"

View file

@ -166,7 +166,9 @@ mod mirror {
fn example_main() -> Result<()> {
gst::init().unwrap();
let glfilter = mirror::GLMirrorFilter::new(Some("Mirror filter"));
App::new(Some(glfilter.as_ref())).and_then(main_loop)
let app = App::new(Some(glfilter.as_ref()))?;
app.run()
}
fn main() -> Result<()> {

View file

@ -10,7 +10,8 @@ use glupload::*;
pub mod examples_common;
fn example_main() -> Result<()> {
App::new(None).and_then(main_loop)
let app = App::new(None)?;
app.run()
}
fn main() -> Result<()> {

View file

@ -23,7 +23,7 @@ use glutin::{
use glutin_winit::GlWindow as _;
use gst::{element_error, PadProbeReturn, PadProbeType, QueryViewMut};
use gst_gl::prelude::*;
use raw_window_handle::HasRawWindowHandle as _;
use raw_window_handle::HasWindowHandle as _;
#[rustfmt::skip]
static VERTICES: [f32; 20] = [
@ -314,7 +314,7 @@ fn load(gl_display: &impl glutin::display::GlDisplay) -> Gl {
}
#[derive(Debug)]
enum Message {
pub(crate) enum Message {
Frame(gst_video::VideoInfo, gst::Buffer),
BusMessage(gst::Message),
}
@ -322,33 +322,39 @@ enum Message {
pub(crate) struct App {
pipeline: gst::Pipeline,
appsink: gst_app::AppSink,
event_loop: winit::event_loop::EventLoop<Message>,
event_loop: Option<winit::event_loop::EventLoop<Message>>,
window: Option<winit::window::Window>,
not_current_gl_context: Option<glutin::context::NotCurrentContext>,
glutin_context: gst_gl::GLContext,
curr_frame: Option<gst_gl::GLVideoFrame<gst_gl::gl_video_frame::Readable>>,
running_state: Option<(
Gl,
glutin::context::PossiblyCurrentContext,
glutin::surface::Surface<glutin::surface::WindowSurface>,
)>,
}
impl App {
pub(crate) fn new(gl_element: Option<&gst::Element>) -> Result<App> {
gst::init()?;
let event_loop = winit::event_loop::EventLoop::with_user_event().build()?;
let (pipeline, appsink) = App::create_pipeline(gl_element)?;
let bus = pipeline
.bus()
.context("Pipeline without bus. Shouldn't happen!")?;
let event_loop = winit::event_loop::EventLoopBuilder::with_user_event().build()?;
// Only Windows requires the window to be present before creating a `glutin::Display`. Other
// platforms don't really need one (and on Android, none exists until `Event::Resumed`).
let window_builder = cfg!(windows).then(|| {
winit::window::WindowBuilder::new()
let window_attributes = cfg!(windows).then(|| {
winit::window::Window::default_attributes()
.with_transparent(true)
.with_title("GL rendering")
});
let display_builder =
glutin_winit::DisplayBuilder::new().with_window_builder(window_builder);
glutin_winit::DisplayBuilder::new().with_window_attributes(window_attributes);
// XXX on macOS/cgl only one config can be queried at a time. If transparency is needed,
// add .with_transparency(true) to ConfigTemplateBuilder. EGL on X11 doesn't support
// transparency at all.
@ -385,19 +391,21 @@ impl App {
println!("Using raw display connection {:?}", raw_gl_display);
let raw_window_handle = window.as_ref().map(|window| window.raw_window_handle());
let window_handle = window
.as_ref()
.map(|window| window.window_handle().unwrap());
// The context creation part. It can be created before surface and that's how
// it's expected in multithreaded + multiwindow operation mode, since you
// can send NotCurrentContext, but not Surface.
let context_attributes =
glutin::context::ContextAttributesBuilder::new().build(raw_window_handle);
let context_attributes = glutin::context::ContextAttributesBuilder::new()
.build(window_handle.map(|h| h.as_raw()));
// Since glutin by default tries to create OpenGL core context, which may not be
// present we should try gles.
let fallback_context_attributes = glutin::context::ContextAttributesBuilder::new()
.with_context_api(glutin::context::ContextApi::Gles(None))
.build(raw_window_handle);
.build(window_handle.map(|h| h.as_raw()));
// There are also some old devices that support neither modern OpenGL nor GLES.
// To support these we can try and create a 2.1 context.
@ -405,7 +413,7 @@ impl App {
.with_context_api(glutin::context::ContextApi::OpenGl(Some(
glutin::context::Version::new(2, 1),
)))
.build(raw_window_handle);
.build(window_handle.map(|h| h.as_raw()));
let not_current_gl_context = unsafe {
gl_display
@ -530,17 +538,24 @@ impl App {
gst::BusSyncReply::Drop
});
Ok(App {
let app = App {
pipeline,
appsink,
event_loop,
event_loop: Some(event_loop),
window,
not_current_gl_context: Some(not_current_gl_context),
glutin_context,
})
curr_frame: None,
running_state: None,
};
app.setup()?;
Ok(app)
}
fn setup(&self, event_loop: &winit::event_loop::EventLoop<Message>) -> Result<()> {
fn setup(&self) -> Result<()> {
let event_loop = self.event_loop.as_ref().unwrap();
let event_proxy = event_loop.create_proxy();
self.appsink.set_callbacks(
gst_app::AppSinkCallbacks::builder()
@ -685,91 +700,49 @@ impl App {
panic!("Received error from {src}: {error} (debug: {debug:?})");
}
}
}
pub(crate) fn main_loop(app: App) -> Result<()> {
app.setup(&app.event_loop)?;
let App {
pipeline,
event_loop,
mut window,
mut not_current_gl_context,
glutin_context,
..
} = app;
let mut curr_frame: Option<gst_gl::GLVideoFrame<gst_gl::gl_video_frame::Readable>> = None;
let mut running_state = None::<(
Gl,
glutin::context::PossiblyCurrentContext,
glutin::surface::Surface<glutin::surface::WindowSurface>,
)>;
Ok(event_loop.run(move |event, window_target| {
window_target.set_control_flow(winit::event_loop::ControlFlow::Wait);
let mut needs_redraw = false;
match event {
winit::event::Event::LoopExiting => {
pipeline.send_event(gst::event::Eos::new());
pipeline.set_state(gst::State::Null).unwrap();
}
winit::event::Event::WindowEvent { event, .. } => match event {
winit::event::WindowEvent::CloseRequested
| winit::event::WindowEvent::KeyboardInput {
event:
winit::event::KeyEvent {
state: winit::event::ElementState::Released,
logical_key:
winit::keyboard::Key::Named(winit::keyboard::NamedKey::Escape),
..
},
..
} => window_target.exit(),
winit::event::WindowEvent::Resized(size) => {
// Some platforms like EGL require resizing GL surface to update the size
// Notable platforms here are Wayland and macOS, other don't require it
// and the function is no-op, but it's wise to resize it for portability
// reasons.
if let Some((gl, gl_context, gl_surface)) = &running_state {
gl_surface.resize(
gl_context,
// XXX Ignore minimizing
NonZeroU32::new(size.width).unwrap(),
NonZeroU32::new(size.height).unwrap(),
);
gl.resize(size);
/// Should be called from within the event loop
fn redraw(&self) {
if let Some((gl, gl_context, gl_surface)) = &self.running_state {
if let Some(frame) = self.curr_frame.as_ref() {
let sync_meta = frame.buffer().meta::<gst_gl::GLSyncMeta>().unwrap();
sync_meta.wait(&self.glutin_context);
if let Ok(texture) = frame.texture_id(0) {
gl.draw_frame(texture as gl::types::GLuint);
}
}
winit::event::WindowEvent::RedrawRequested => needs_redraw = true,
_ => (),
},
// Receive a frame
winit::event::Event::UserEvent(Message::Frame(info, buffer)) => {
if let Ok(frame) = gst_gl::GLVideoFrame::from_buffer_readable(buffer, &info) {
curr_frame = Some(frame);
needs_redraw = true;
gl_surface.swap_buffers(gl_context).unwrap();
}
}
// Handle all pending messages when we are awaken by set_sync_handler
winit::event::Event::UserEvent(Message::BusMessage(msg)) => App::handle_message(msg),
winit::event::Event::Resumed => {
let not_current_gl_context = not_current_gl_context
pub fn run(mut self) -> Result<()> {
let Some(event_loop) = self.event_loop.take() else {
return Ok(());
};
event_loop.run_app(&mut self)?;
Ok(())
}
}
impl winit::application::ApplicationHandler<Message> for App {
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
let not_current_gl_context = self
.not_current_gl_context
.take()
.expect("There must be a NotCurrentContext prior to Event::Resumed");
let gl_config = not_current_gl_context.config();
let gl_display = gl_config.display();
let window = window.get_or_insert_with(|| {
let window_builder = winit::window::WindowBuilder::new().with_transparent(true);
glutin_winit::finalize_window(window_target, window_builder, &gl_config)
.unwrap()
let window = self.window.get_or_insert_with(|| {
let window_attributes =
winit::window::Window::default_attributes().with_transparent(true);
glutin_winit::finalize_window(event_loop, window_attributes, &gl_config).unwrap()
});
let attrs = window.build_surface_attributes(<_>::default());
let attrs = window.build_surface_attributes(<_>::default()).unwrap();
let gl_surface = unsafe {
gl_config
.display()
@ -782,9 +755,9 @@ pub(crate) fn main_loop(app: App) -> Result<()> {
// Tell GStreamer that the context has been made current (for borrowed contexts,
// this does not try to make it current again)
glutin_context.activate(true).unwrap();
self.glutin_context.activate(true).unwrap();
glutin_context
self.glutin_context
.fill_info()
.expect("Couldn't fill context info");
@ -800,27 +773,71 @@ pub(crate) fn main_loop(app: App) -> Result<()> {
eprintln!("Error setting vsync: {res:?}");
}
pipeline.set_state(gst::State::Playing).unwrap();
self.pipeline.set_state(gst::State::Playing).unwrap();
assert!(running_state
assert!(self
.running_state
.replace((gl, gl_context, gl_surface))
.is_none());
}
fn window_event(
&mut self,
event_loop: &winit::event_loop::ActiveEventLoop,
_window_id: winit::window::WindowId,
event: winit::event::WindowEvent,
) {
event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait);
match event {
winit::event::WindowEvent::CloseRequested
| winit::event::WindowEvent::KeyboardInput {
event:
winit::event::KeyEvent {
state: winit::event::ElementState::Released,
logical_key: winit::keyboard::Key::Named(winit::keyboard::NamedKey::Escape),
..
},
..
} => {
self.curr_frame = None;
self.pipeline.send_event(gst::event::Eos::new());
self.pipeline.set_state(gst::State::Null).unwrap();
event_loop.exit();
}
winit::event::WindowEvent::Resized(size) => {
// Some platforms like EGL require resizing GL surface to update the size
// Notable platforms here are Wayland and macOS, other don't require it
// and the function is no-op, but it's wise to resize it for portability
// reasons.
if let Some((gl, gl_context, gl_surface)) = &self.running_state {
gl_surface.resize(
gl_context,
// XXX Ignore minimizing
NonZeroU32::new(size.width).unwrap(),
NonZeroU32::new(size.height).unwrap(),
);
gl.resize(size);
}
}
winit::event::WindowEvent::RedrawRequested => {
self.redraw();
}
_ => (),
}
if needs_redraw {
if let Some((gl, gl_context, gl_surface)) = &running_state {
if let Some(frame) = curr_frame.as_ref() {
let sync_meta = frame.buffer().meta::<gst_gl::GLSyncMeta>().unwrap();
sync_meta.wait(&glutin_context);
if let Ok(texture) = frame.texture_id(0) {
gl.draw_frame(texture as gl::types::GLuint);
}
}
gl_surface.swap_buffers(gl_context).unwrap();
fn user_event(&mut self, _event_loop: &winit::event_loop::ActiveEventLoop, event: Message) {
match event {
// Receive a frame
Message::Frame(info, buffer) => {
if let Ok(frame) = gst_gl::GLVideoFrame::from_buffer_readable(buffer, &info) {
self.curr_frame = Some(frame);
self.redraw();
}
}
// Handle all pending messages when we are awaken by set_sync_handler
Message::BusMessage(msg) => App::handle_message(msg),
}
}
})?)
}