diff --git a/Cargo.lock b/Cargo.lock index 8ce1063b..9f2e16cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if 1.0.0", "getrandom", @@ -29,6 +29,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "algorithms" version = "0.1.0" @@ -36,6 +45,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -46,10 +61,58 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.68" +name = "anstream" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "autocfg" @@ -59,9 +122,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -74,9 +137,9 @@ dependencies = [ [[package]] name = "bincode" -version = "2.0.0-rc.2" +version = "2.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb50c5a2ef4b9b1e7ae73e3a73b52ea24b20312d629f9c4df28260b7ad2c3c4" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" dependencies = [ "bincode_derive", "serde", @@ -84,9 +147,9 @@ dependencies = [ [[package]] name = "bincode_derive" -version = "2.0.0-rc.2" +version = "2.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a45a23389446d2dd25dc8e73a7a3b3c43522b630cac068927f0649d43d719d2" +checksum = "7e30759b3b99a1b802a7a3aa21c85c3ded5c28e1c83170d82d70f08bbf7f3e4c" dependencies = [ "virtue", ] @@ -98,10 +161,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bstr" -version = "1.1.0" +name = "bitflags" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bstr" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" dependencies = [ "memchr", "serde", @@ -109,21 +178,24 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -139,125 +211,79 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", - "time", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] name = "clap" -version = "4.0.32" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "is-terminal", - "once_cell", "strsim", - "termcolor", "terminal_size", ] [[package]] name = "clap_complete" -version = "4.0.7" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b" +checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.0.21" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "colorchoice" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cxx" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "default-config" @@ -271,73 +297,63 @@ dependencies = [ [[package]] name = "dirs" -version = "4.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.3.7" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", - "winapi", + "windows-sys", ] [[package]] name = "errno" -version = "0.2.8" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", "libc", + "windows-sys", ] [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-macro", @@ -349,35 +365,26 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "humantime" @@ -387,48 +394,25 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows-core", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "is-terminal" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" -dependencies = [ - "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys", + "cc", ] [[package]] @@ -446,7 +430,7 @@ dependencies = [ "anyhow", "backtrace", "bincode", - "bitflags", + "bitflags 2.4.1", "bstr", "byteorder", "chrono", @@ -482,9 +466,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -497,40 +481,31 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if 1.0.0", - "winapi", -] - -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", + "windows-sys", ] [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -538,78 +513,65 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "num-derive" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", + "syn 2.0.38", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] -name = "os_str_bytes" -version = "6.4.1" +name = "option-ext" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "parking_lot" @@ -623,42 +585,42 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "smallvec", - "windows-sys", + "windows-targets", ] [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -672,44 +634,20 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -750,7 +688,16 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", ] [[package]] @@ -760,24 +707,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "regex" -version = "1.7.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "repc" @@ -796,19 +757,18 @@ checksum = "9e110b7d5a1335c2e801176c42a626a905c23eecdee104d9bdfbd6ea5f0b8368" [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.36.6" +version = "0.38.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" +checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" dependencies = [ - "bitflags", + "bitflags 2.4.1", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys", @@ -816,36 +776,44 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scratch" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] [[package]] name = "slab" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "strsim" @@ -855,9 +823,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -865,19 +833,21 @@ dependencies = [ ] [[package]] -name = "termcolor" -version = "1.1.3" +name = "syn" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ - "winapi-util", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "terminal_size" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb20089a8ba2b69debd491f8d2d023761cbf196e999218c591fa1e7e15a21907" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ "rustix", "windows-sys", @@ -885,33 +855,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", + "syn 2.0.38", ] [[package]] @@ -937,20 +896,20 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn", + "syn 1.0.109", ] [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "unicode-width" -version = "0.1.10" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "version_check" @@ -960,15 +919,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "virtue" -version = "0.0.8" +version = "0.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b60dcd6a64dd45abf9bd426970c9843726da7fc08f44cd6fcebf68c21220a63" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" [[package]] name = "wasi" @@ -978,9 +931,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -988,24 +941,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.38", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1013,59 +966,46 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-targets", ] -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -1078,42 +1018,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index 4941e2f5..1077ef70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,9 +20,9 @@ ahash = "0.8.2" log = { version = "0.4.16", features = ["std"] } futures-util = "0.3.19" num-traits = "0.2.14" -num-derive = "0.3.3" -bitflags = "1.3.2" -libloading = "0.7.2" +num-derive = "0.4.1" +bitflags = "2.4.1" +libloading = "0.8.1" bstr = { version = "1.1.0", default-features = false, features = ["std"] } isnt = "0.1.0" once_cell = "1.9.0" @@ -37,7 +37,7 @@ pin-project = "1.0.10" clap = { version = "4.0.29", features = ["derive", "wrap_help"] } clap_complete = "4.0.6" humantime = "2.1.0" -dirs = "4.0.0" +dirs = "5.0.1" backtrace = "0.3.64" chrono = "0.4.19" parking_lot = "0.12.1" diff --git a/jay-config/src/_private.rs b/jay-config/src/_private.rs index d39e9674..9502e65b 100644 --- a/jay-config/src/_private.rs +++ b/jay-config/src/_private.rs @@ -31,7 +31,6 @@ pub fn bincode_ops() -> impl bincode::config::Config { .with_fixed_int_encoding() .with_little_endian() .with_no_limit() - .skip_fixed_array_length() } pub trait Config { diff --git a/src/backend.rs b/src/backend.rs index 0d1a7a5d..6666cedf 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -2,8 +2,8 @@ use { crate::{ async_engine::SpawnedFuture, fixed::Fixed, + gfx_api::GfxFramebuffer, ifs::wl_seat::wl_pointer::{CONTINUOUS, FINGER, HORIZONTAL_SCROLL, VERTICAL_SCROLL, WHEEL}, - render::Framebuffer, video::drm::{ConnectorType, DrmError, DrmVersion}, }, std::{ @@ -95,7 +95,7 @@ pub enum ConnectorEvent { pub trait HardwareCursor: Debug { fn set_enabled(&self, enabled: bool); - fn get_buffer(&self) -> Rc; + fn get_buffer(&self) -> Rc; fn set_position(&self, x: i32, y: i32); fn swap_buffer(&self); fn commit(&self); diff --git a/src/backends/metal.rs b/src/backends/metal.rs index a1ebe46d..58cd22b9 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -11,6 +11,7 @@ use { }, backends::metal::video::{MetalDrmDeviceData, MetalRenderContext, PendingDrmDevice}, dbus::{DbusError, SignalHandler}, + gfx_api::GfxError, libinput::{ consts::{ AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE, @@ -23,7 +24,6 @@ use { LibInput, LibInputAdapter, LibInputError, }, logind::{LogindError, Session}, - render::RenderError, state::State, time::now_usec, udev::{Udev, UdevError, UdevMonitor}, @@ -75,7 +75,7 @@ pub enum MetalError { #[error("Could not update the drm properties")] UpdateProperties(#[source] DrmError), #[error("Could not create a render context")] - CreateRenderContex(#[source] RenderError), + CreateRenderContex(#[source] GfxError), #[error("Cannot initialize connector because no CRTC is available")] NoCrtcForConnector, #[error("Cannot initialize connector because no primary plane is available")] @@ -86,12 +86,12 @@ pub enum MetalError { ScanoutBuffer(#[source] GbmError), #[error("addfb2 failed")] Framebuffer(#[source] DrmError), - #[error("Could not import a framebuffer into EGL")] - ImportFb(#[source] RenderError), - #[error("Could not import a texture into EGL")] - ImportTexture(#[source] RenderError), - #[error("Could not import an image into EGL")] - ImportImage(#[source] RenderError), + #[error("Could not import a framebuffer into the graphics API")] + ImportFb(#[source] GfxError), + #[error("Could not import a texture into the graphics API")] + ImportTexture(#[source] GfxError), + #[error("Could not import an image into the graphics API")] + ImportImage(#[source] GfxError), #[error("Could not perform modeset")] Modeset(#[source] DrmError), #[error("Could not enable atomic modesetting")] diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index d7ce00f8..978a5c9f 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -8,8 +8,10 @@ use { backends::metal::{MetalBackend, MetalError}, edid::Descriptor, format::{Format, ARGB8888, XRGB8888}, + gfx_api::{GfxContext, GfxFramebuffer, GfxTexture}, + gfx_apis::create_gfx_context, ifs::wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC}, - render::{Framebuffer, RenderContext, RenderResult, Texture}, + renderer::RenderResult, state::State, udev::UdevDevice, utils::{ @@ -51,7 +53,7 @@ pub struct PendingDrmDevice { #[derive(Debug)] pub struct MetalRenderContext { pub dev_id: DrmDeviceId, - pub egl: Rc, + pub gfx: Rc, } #[derive(Debug)] @@ -213,7 +215,7 @@ impl HardwareCursor for MetalHardwareCursor { } } - fn get_buffer(&self) -> Rc { + fn get_buffer(&self) -> Rc { let buffer = (self.connector.cursor_front_buffer.get() + 1) % 2; self.cursor_buffers[buffer].render_fb() } @@ -374,7 +376,7 @@ impl MetalConnector { fr.send_done(); let _ = fr.client.remove_obj(&*fr); } - node.perform_screencopies(&render_fb, &buffer.render_tex); + node.perform_screencopies(&*render_fb, &buffer.render_tex); } changes.change_object(plane.id, |c| { c.change(plane.fb_id, buffer.drm.id().0 as _); @@ -882,9 +884,9 @@ impl MetalBackend { None => return false, }; if let Some(r) = ctx - .egl + .gfx .reset_status() - .or_else(|| dev.ctx.egl.reset_status()) + .or_else(|| dev.ctx.gfx.reset_status()) { fatal!("EGL context has been reset: {:?}", r); } @@ -1089,13 +1091,13 @@ impl MetalBackend { } } - let egl = match RenderContext::from_drm_device(master) { - Ok(r) => Rc::new(r), + let gfx = match create_gfx_context(master) { + Ok(r) => r, Err(e) => return Err(MetalError::CreateRenderContex(e)), }; let ctx = Rc::new(MetalRenderContext { dev_id: pending.id, - egl, + gfx, }); let gbm = match GbmDevice::new(master) { @@ -1420,7 +1422,7 @@ impl MetalBackend { return true; } } - self.state.set_render_ctx(Some(&dev.ctx.egl)); + self.state.set_render_ctx(Some(dev.ctx.gfx.clone())); self.ctx.set(Some(dev.ctx.clone())); let mut preserve = Preserve::default(); for dev in self.device_holder.drm_devices.lock().values() { @@ -1600,11 +1602,11 @@ impl MetalBackend { Ok(fb) => Rc::new(fb), Err(e) => return Err(MetalError::Framebuffer(e)), }; - let dev_img = match dev.ctx.egl.dmabuf_img(dev_bo.dmabuf()) { + let dev_img = match dev.ctx.gfx.clone().dmabuf_img(dev_bo.dmabuf()) { Ok(img) => img, Err(e) => return Err(MetalError::ImportImage(e)), }; - let dev_fb = match dev_img.to_framebuffer() { + let dev_fb = match dev_img.clone().to_framebuffer() { Ok(fb) => fb, Err(e) => return Err(MetalError::ImportFb(e)), }; @@ -1618,16 +1620,16 @@ impl MetalBackend { } else { // Create a _bridge_ BO in the render device usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR; - let render_bo = render_ctx.egl.gbm.create_bo(width, height, format, usage); + let render_bo = render_ctx.gfx.gbm().create_bo(width, height, format, usage); let render_bo = match render_bo { Ok(b) => b, Err(e) => return Err(MetalError::ScanoutBuffer(e)), }; - let render_img = match render_ctx.egl.dmabuf_img(render_bo.dmabuf()) { + let render_img = match render_ctx.gfx.clone().dmabuf_img(render_bo.dmabuf()) { Ok(img) => img, Err(e) => return Err(MetalError::ImportImage(e)), }; - let render_fb = match render_img.to_framebuffer() { + let render_fb = match render_img.clone().to_framebuffer() { Ok(fb) => fb, Err(e) => return Err(MetalError::ImportFb(e)), }; @@ -1638,7 +1640,7 @@ impl MetalBackend { }; // Import the bridge BO into the current device - let dev_img = match dev.ctx.egl.dmabuf_img(render_bo.dmabuf()) { + let dev_img = match dev.ctx.gfx.clone().dmabuf_img(render_bo.dmabuf()) { Ok(img) => img, Err(e) => return Err(MetalError::ImportImage(e)), }; @@ -1832,20 +1834,20 @@ pub struct RenderBuffer { drm: Rc, // ctx = dev // buffer location = dev - dev_fb: Rc, + dev_fb: Rc, // ctx = dev // buffer location = render - dev_tex: Option>, + dev_tex: Option>, // ctx = render // buffer location = render - render_tex: Rc, + render_tex: Rc, // ctx = render // buffer location = render - render_fb: Option>, + render_fb: Option>, } impl RenderBuffer { - fn render_fb(&self) -> Rc { + fn render_fb(&self) -> Rc { self.render_fb .clone() .unwrap_or_else(|| self.dev_fb.clone()) diff --git a/src/backends/x.rs b/src/backends/x.rs index e746be61..db9943ff 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -9,7 +9,9 @@ use { }, fixed::Fixed, format::XRGB8888, - render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture}, + gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture}, + gfx_apis::create_gfx_context, + renderer::RenderResult, state::State, time::now_usec, utils::{ @@ -88,14 +90,14 @@ pub enum XBackendError { GbmError(#[from] GbmError), #[error("Could not import a dma-buf")] ImportBuffer(#[source] XconError), - #[error("Could not create an EGL context")] - CreateEgl(#[source] RenderError), - #[error("Could not create an EGL image from a dma-buf")] - CreateImage(#[source] RenderError), - #[error("Could not create a framebuffer from an EGL image")] - CreateFramebuffer(#[source] RenderError), - #[error("Could not create a texture from an EGL image")] - CreateTexture(#[source] RenderError), + #[error("Could not create a graphics API context")] + CreateEgl(#[source] GfxError), + #[error("Could not create an graphics API image from a dma-buf")] + CreateImage(#[source] GfxError), + #[error("Could not create a framebuffer from a graphics API image")] + CreateFramebuffer(#[source] GfxError), + #[error("Could not create a texture from an graphics API image")] + CreateTexture(#[source] GfxError), #[error("Could not select input events")] CannotSelectInputEvents(#[source] XconError), #[error("Could not select present events")] @@ -177,8 +179,8 @@ pub async fn create(state: &Rc) -> Result, XBackendError> { Err(e) => return Err(XBackendError::DrmDeviceFstat(e)), }; let gbm = GbmDevice::new(&drm)?; - let ctx = match RenderContext::from_drm_device(&drm) { - Ok(r) => Rc::new(r), + let ctx = match create_gfx_context(&drm) { + Ok(r) => r, Err(e) => return Err(XBackendError::CreateEgl(e)), }; let cursor = { @@ -265,7 +267,7 @@ pub struct XBackend { outputs: CopyHashMap>, seats: CopyHashMap>, mouse_seats: CopyHashMap>, - ctx: Rc, + ctx: Rc, gbm: GbmDevice, cursor: u32, root: u32, @@ -287,7 +289,7 @@ impl XBackend { .eng .spawn2(Phase::Present, self.clone().present_handler()); - self.state.set_render_ctx(Some(&self.ctx)); + self.state.set_render_ctx(Some(self.ctx.clone())); self.state .backend_events .push(BackendEvent::NewDrmDevice(Rc::new(XDrmDevice { @@ -387,11 +389,11 @@ impl XBackend { assert!(dma.planes.len() == 1); let plane = dma.planes.first().unwrap(); let size = plane.stride * dma.height as u32; - let img = match self.ctx.dmabuf_img(dma) { + let img = match self.ctx.clone().dmabuf_img(dma) { Ok(f) => f, Err(e) => return Err(XBackendError::CreateImage(e)), }; - let fb = match img.to_framebuffer() { + let fb = match img.clone().to_framebuffer() { Ok(f) => f, Err(e) => return Err(XBackendError::CreateFramebuffer(e)), }; @@ -734,7 +736,7 @@ impl XBackend { fr.send_done(); let _ = fr.client.remove_obj(&*fr); } - node.perform_screencopies(&fb, &image.tex.get()); + node.perform_screencopies(&*fb, &image.tex.get()); } let pp = PresentPixmap { @@ -988,8 +990,8 @@ struct XOutput { struct XImage { pixmap: Cell, - fb: CloneCell>, - tex: CloneCell>, + fb: CloneCell>, + tex: CloneCell>, idle: Cell, render_on_idle: Cell, last_serial: Cell, diff --git a/src/compositor.rs b/src/compositor.rs index 85205aba..d201ba7d 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -20,7 +20,6 @@ use { io_uring::{IoUring, IoUringError}, leaks, logger::Logger, - render::{self, RenderError}, scale::Scale, sighand::{self, SighandError}, state::{ConnectorData, IdleState, ScreenlockState, State, XWaylandState}, @@ -86,8 +85,6 @@ pub enum CompositorError { ClientmemError(#[from] ClientMemError), #[error("The timer subsystem caused an error")] WheelError(#[from] WheelError), - #[error("The render backend caused an error")] - RenderError(#[from] RenderError), #[error("Could not create an io-uring")] IoUringError(#[from] IoUringError), } @@ -112,7 +109,6 @@ fn start_compositor2( log::info!("pid = {}", uapi::getpid()); init_fd_limit(); leaks::init(); - render::init()?; clientmem::init()?; let xkb_ctx = XkbContext::new().unwrap(); let xkb_keymap = xkb_ctx.keymap_from_str(include_str!("keymap.xkb")).unwrap(); diff --git a/src/cursor.rs b/src/cursor.rs index 2bcd8651..9c3dd279 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -2,8 +2,9 @@ use { crate::{ fixed::Fixed, format::ARGB8888, + gfx_api::{GfxContext, GfxError, GfxTexture}, rect::Rect, - render::{RenderContext, RenderError, Renderer, Texture}, + renderer::Renderer, scale::Scale, state::State, time::Time, @@ -86,7 +87,7 @@ pub enum KnownCursor { } impl ServerCursors { - pub fn load(ctx: &Rc, state: &State) -> Result, CursorError> { + pub fn load(ctx: &Rc, state: &State) -> Result, CursorError> { let paths = find_cursor_paths(); log::debug!("Trying to load cursors from paths {:?}", paths); let sizes = state.cursor_sizes.to_vec(); @@ -134,7 +135,7 @@ impl ServerCursorTemplate { scales: &[Scale], sizes: &[u32], paths: &[BString], - ctx: &Rc, + ctx: &Rc, ) -> Result { match open_cursor(name, theme, scales, sizes, paths) { Ok(cs) => { @@ -214,7 +215,7 @@ impl ServerCursorTemplate { struct CursorImageScaled { extents: Rect, - tex: Rc, + tex: Rc, } struct CursorImage { @@ -229,7 +230,7 @@ struct InstantiatedCursorImage { impl CursorImageScaled { fn from_bytes( - ctx: &Rc, + ctx: &Rc, data: &[Cell], width: i32, height: i32, @@ -238,7 +239,9 @@ impl CursorImageScaled { ) -> Result, CursorError> { Ok(Rc::new(Self { extents: Rect::new_sized(-xhot, -yhot, width, height).unwrap(), - tex: ctx.shmem_texture(data, ARGB8888, width, height, width * 4)?, + tex: ctx + .clone() + .shmem_texture(data, ARGB8888, width, height, width * 4)?, })) } } @@ -295,6 +298,8 @@ fn render_img(image: &InstantiatedCursorImage, renderer: &mut Renderer, x: Fixed None, None, scale, + i32::MAX, + i32::MAX, ); } } @@ -306,9 +311,17 @@ impl Cursor for StaticCursor { fn render_hardware_cursor(&self, renderer: &mut Renderer) { if let Some(img) = self.image.scales.get(&renderer.scale()) { - renderer - .base - .render_texture(&img.tex, 0, 0, ARGB8888, None, None, renderer.scale()); + renderer.base.render_texture( + &img.tex, + 0, + 0, + ARGB8888, + None, + None, + renderer.scale(), + i32::MAX, + i32::MAX, + ); } } @@ -336,9 +349,17 @@ impl Cursor for AnimatedCursor { fn render_hardware_cursor(&self, renderer: &mut Renderer) { let img = &self.images[self.idx.get()]; if let Some(img) = img.scales.get(&renderer.scale()) { - renderer - .base - .render_texture(&img.tex, 0, 0, ARGB8888, None, None, renderer.scale()); + renderer.base.render_texture( + &img.tex, + 0, + 0, + ARGB8888, + None, + None, + renderer.scale(), + i32::MAX, + i32::MAX, + ); } } @@ -517,7 +538,7 @@ pub enum CursorError { #[error("The requested cursor could not be found")] NotFound, #[error("Could not import the cursor as a texture")] - ImportError(#[from] RenderError), + ImportError(#[from] GfxError), } #[derive(Default, Clone)] diff --git a/src/format.rs b/src/format.rs index c5530b76..1d1f9bd0 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,10 +1,10 @@ use { crate::{ + gfx_apis::gl::sys::{GLint, GL_BGRA_EXT, GL_RGBA, GL_UNSIGNED_BYTE}, pipewire::pw_pod::{ SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SpaVideoFormat, SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_NV12, SPA_VIDEO_FORMAT_RGBA, }, - render::sys::{GLint, GL_BGRA_EXT, GL_RGBA, GL_UNSIGNED_BYTE}, utils::debug_fn::debug_fn, }, ahash::AHashMap, diff --git a/src/gfx_api.rs b/src/gfx_api.rs new file mode 100644 index 00000000..00e8971f --- /dev/null +++ b/src/gfx_api.rs @@ -0,0 +1,218 @@ +use { + crate::{ + cursor::Cursor, + format::Format, + rect::Rect, + renderer::{renderer_base::RendererBase, RenderResult}, + scale::Scale, + state::State, + theme::Color, + tree::Node, + video::{dmabuf::DmaBuf, gbm::GbmDevice}, + }, + ahash::AHashMap, + std::{ + any::Any, + cell::Cell, + error::Error, + ffi::CString, + fmt::{Debug, Formatter}, + rc::Rc, + }, + thiserror::Error, +}; + +pub enum GfxApiOpt { + Sync, + Clear(Clear), + FillRect(FillRect), + CopyTexture(CopyTexture), +} + +#[derive(Default, Debug, Copy, Clone)] +pub struct BufferPoint { + pub x: f32, + pub y: f32, +} + +impl BufferPoint { + pub fn is_leq_1(&self) -> bool { + self.x <= 1.0 && self.y <= 1.0 + } +} + +#[derive(Default, Debug, Copy, Clone)] +pub struct BufferPoints { + pub top_left: BufferPoint, + pub top_right: BufferPoint, + pub bottom_left: BufferPoint, + pub bottom_right: BufferPoint, +} + +impl BufferPoints { + pub fn norm(&self, width: f32, height: f32) -> Self { + Self { + top_left: BufferPoint { + x: self.top_left.x / width, + y: self.top_left.y / height, + }, + top_right: BufferPoint { + x: self.top_right.x / width, + y: self.top_right.y / height, + }, + bottom_left: BufferPoint { + x: self.bottom_left.x / width, + y: self.bottom_left.y / height, + }, + bottom_right: BufferPoint { + x: self.bottom_right.x / width, + y: self.bottom_right.y / height, + }, + } + } + + pub fn is_leq_1(&self) -> bool { + self.top_left.is_leq_1() + && self.top_right.is_leq_1() + && self.bottom_left.is_leq_1() + && self.bottom_right.is_leq_1() + } +} + +pub struct AbsoluteRect { + pub x1: f32, + pub x2: f32, + pub y1: f32, + pub y2: f32, +} + +pub struct Clear { + pub color: Color, +} + +pub struct FillRect { + pub rect: AbsoluteRect, + pub color: Color, +} + +pub struct CopyTexture { + pub tex: Rc, + pub format: &'static Format, + pub source: BufferPoints, + pub target: AbsoluteRect, +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ResetStatus { + Guilty, + Innocent, + Unknown, + Other(u32), +} + +pub trait GfxFramebuffer: Debug { + fn as_any(&self) -> &dyn Any; + + fn clear(&self); + + fn clear_with(&self, r: f32, g: f32, b: f32, a: f32); + + fn copy_texture( + &self, + state: &State, + texture: &Rc, + x: i32, + y: i32, + alpha: bool, + ); + + fn copy_to_shm( + &self, + x: i32, + y: i32, + width: i32, + height: i32, + format: &Format, + shm: &[Cell], + ); + + fn render_custom(&self, scale: Scale, f: &mut dyn FnMut(&mut RendererBase)); + + fn render( + &self, + node: &dyn Node, + state: &State, + cursor_rect: Option, + on_output: bool, + result: &mut RenderResult, + scale: Scale, + render_hardware_cursor: bool, + ); + + fn render_hardware_cursor(&self, cursor: &dyn Cursor, state: &State, scale: Scale); +} + +pub trait GfxImage { + fn to_framebuffer(self: Rc) -> Result, GfxError>; + + fn to_texture(self: Rc) -> Result, GfxError>; + + fn width(&self) -> i32; + fn height(&self) -> i32; +} + +pub trait GfxTexture: Debug { + fn width(&self) -> i32; + fn height(&self) -> i32; + fn as_any(&self) -> &dyn Any; +} + +pub trait GfxContext: Debug { + fn take_render_ops(&self) -> Vec; + + fn reset_status(&self) -> Option; + + fn supports_external_texture(&self) -> bool; + + fn render_node(&self) -> Rc; + + fn formats(&self) -> Rc>; + + fn dmabuf_fb(self: Rc, buf: &DmaBuf) -> Result, GfxError>; + + fn dmabuf_img(self: Rc, buf: &DmaBuf) -> Result, GfxError>; + + fn shmem_texture( + self: Rc, + data: &[Cell], + format: &'static Format, + width: i32, + height: i32, + stride: i32, + ) -> Result, GfxError>; + + fn gbm(&self) -> &GbmDevice; +} + +#[derive(Debug)] +pub struct GfxFormat { + pub format: &'static Format, + pub implicit_external_only: bool, + pub modifiers: AHashMap, +} + +#[derive(Debug)] +pub struct GfxModifier { + pub modifier: u64, + pub external_only: bool, +} + +#[derive(Error)] +#[error(transparent)] +pub struct GfxError(pub Box); + +impl Debug for GfxError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&self.0, f) + } +} diff --git a/src/gfx_apis.rs b/src/gfx_apis.rs new file mode 100644 index 00000000..d6450911 --- /dev/null +++ b/src/gfx_apis.rs @@ -0,0 +1,13 @@ +use { + crate::{ + gfx_api::{GfxContext, GfxError}, + video::drm::Drm, + }, + std::rc::Rc, +}; + +pub mod gl; + +pub fn create_gfx_context(drm: &Drm) -> Result, GfxError> { + gl::create_gfx_context(drm) +} diff --git a/src/gfx_apis/gl.rs b/src/gfx_apis/gl.rs new file mode 100644 index 00000000..f8423ead --- /dev/null +++ b/src/gfx_apis/gl.rs @@ -0,0 +1,358 @@ +macro_rules! egl_transparent { + ($name:ident) => { + #[derive(Copy, Clone, Debug, Eq, PartialEq)] + #[repr(transparent)] + pub struct $name(pub *mut u8); + + impl $name { + #[allow(dead_code)] + pub const fn none() -> Self { + Self(std::ptr::null_mut()) + } + + #[allow(dead_code)] + pub fn is_none(self) -> bool { + self.0.is_null() + } + } + }; +} + +use { + crate::{ + format::Format, + gfx_api::{ + BufferPoints, CopyTexture, FillRect, GfxApiOpt, GfxContext, GfxError, GfxTexture, + }, + gfx_apis::gl::{ + gl::texture::image_target, + renderer::{context::GlRenderContext, framebuffer::Framebuffer, texture::Texture}, + sys::{ + glActiveTexture, glBindTexture, glClear, glClearColor, glDisable, + glDisableVertexAttribArray, glDrawArrays, glEnable, glEnableVertexAttribArray, + glTexParameteri, glUniform1i, glUniform4f, glUseProgram, glVertexAttribPointer, + GL_BLEND, GL_COLOR_BUFFER_BIT, GL_FALSE, GL_FLOAT, GL_LINEAR, GL_TEXTURE0, + GL_TEXTURE_MIN_FILTER, GL_TRIANGLES, GL_TRIANGLE_STRIP, + }, + }, + theme::Color, + utils::{rc_eq::rc_eq, vecstorage::VecStorage}, + video::{ + drm::{Drm, DrmError}, + gbm::GbmError, + }, + }, + isnt::std_1::vec::IsntVecExt, + once_cell::sync::Lazy, + std::{cell::RefCell, rc::Rc, sync::Arc}, + thiserror::Error, +}; + +mod egl; +mod ext; +mod gl; +mod proc; +mod renderer; + +pub mod sys { + pub use super::{egl::sys::*, gl::sys::*}; +} + +static INIT: Lazy>> = Lazy::new(|| egl::init().map_err(Arc::new)); + +pub(super) fn create_gfx_context(drm: &Drm) -> Result, GfxError> { + if let Err(e) = &*INIT { + return Err(GfxError(Box::new(e.clone()))); + } + GlRenderContext::from_drm_device(drm) + .map(|v| Rc::new(v) as Rc) + .map_err(|e| e.into()) +} + +#[derive(Debug, Error)] +enum RenderError { + #[error("EGL library does not support `EGL_EXT_platform_base`")] + ExtPlatformBase, + #[error("Could not compile a shader")] + ShaderCompileFailed, + #[error("Could not link a program")] + ProgramLink, + #[error("Could not bind to `EGL_OPENGL_ES_API`")] + BindFailed, + #[error("EGL library does not support the GBM platform")] + GbmExt, + #[error("Could not create a GBM device")] + Gbm(#[source] GbmError), + #[error("`eglCreateContext` failed")] + CreateContext, + #[error("`eglMakeCurrent` failed")] + MakeCurrent, + #[error("`eglCreateImageKHR` failed")] + CreateImage, + #[error("Image buffer is too small")] + SmallImageBuffer, + #[error("Binding a renderbuffer to a framebuffer failed")] + CreateFramebuffer, + #[error("`eglGetPlatformDisplayEXT` failed")] + GetDisplay, + #[error("`eglInitialize` failed")] + Initialize, + #[error("EGL display does not support `EGL_EXT_image_dma_buf_import_modifiers`")] + DmaBufImport, + #[error("GLES driver does not support `GL_OES_EGL_image`")] + OesEglImage, + #[error("EGL display does not support `EGL_KHR_image_base`")] + ImageBase, + #[error( + "EGL display does not support `EGL_KHR_no_config_context` or `EGL_MESA_configless_context`" + )] + ConfiglessContext, + #[error("EGL display does not support `EGL_KHR_surfaceless_context`")] + SurfacelessContext, + #[error("`eglQueryDmaBufFormatsEXT` failed")] + QueryDmaBufFormats, + #[error("`eglQueryDmaBufModifiersEXT` failed")] + QueryDmaBufModifiers, + #[error(transparent)] + DrmError(#[from] DrmError), + #[error("The GLES driver does not support the XRGB8888 format")] + XRGB888, + #[error("The DRM device does not have a render node")] + NoRenderNode, + #[error("The requested format is not supported")] + UnsupportedFormat, + #[error("The requested modifier is not supported")] + UnsupportedModifier, + #[error("Image is external only and cannot be rendered to")] + ExternalOnly, + #[error("OpenGL context does not support external textures")] + ExternalUnsupported, +} + +#[derive(Default)] +struct GfxGlState { + triangles: RefCell>, + fill_rect: VecStorage<&'static FillRect>, + copy_tex: VecStorage<&'static CopyTexture>, +} + +fn run_ops(fb: &Framebuffer, ops: &[GfxApiOpt]) { + let mut state = fb.ctx.gl_state.borrow_mut(); + let state = &mut *state; + let mut fill_rect = state.fill_rect.take(); + let fill_rect = &mut *fill_rect; + let mut copy_tex = state.copy_tex.take(); + let copy_tex = &mut *copy_tex; + let mut triangles = state.triangles.borrow_mut(); + let triangles = &mut *triangles; + let width = fb.gl.width as f32; + let height = fb.gl.height as f32; + let mut i = 0; + while i < ops.len() { + macro_rules! has_ops { + () => { + fill_rect.is_not_empty() || copy_tex.is_not_empty() + }; + } + fill_rect.clear(); + copy_tex.clear(); + while i < ops.len() { + match &ops[i] { + GfxApiOpt::Sync => { + i += 1; + if has_ops!() { + break; + } + } + GfxApiOpt::Clear(c) => { + if has_ops!() { + break; + } + clear(&c.color); + i += 1; + } + GfxApiOpt::FillRect(f) => { + fill_rect.push(f); + i += 1; + } + GfxApiOpt::CopyTexture(c) => { + copy_tex.push(c); + i += 1; + } + } + } + if fill_rect.is_not_empty() { + fill_rect.sort_unstable_by_key(|f| f.color); + let mut i = 0; + while i < fill_rect.len() { + triangles.clear(); + let mut color = None; + while i < fill_rect.len() { + let fr = fill_rect[i]; + match color { + None => color = Some(fr.color), + Some(c) if c == fr.color => {} + _ => break, + } + let x1 = 2.0 * (fr.rect.x1 / width) - 1.0; + let x2 = 2.0 * (fr.rect.x2 / width) - 1.0; + let y1 = 2.0 * (fr.rect.y1 / height) - 1.0; + let y2 = 2.0 * (fr.rect.y2 / height) - 1.0; + triangles.extend_from_slice(&[ + // triangle 1 + x2, y1, // top right + x1, y1, // top left + x1, y2, // bottom left + // triangle 2 + x2, y1, // top right + x1, y2, // bottom left + x2, y2, // bottom right + ]); + i += 1; + } + if let Some(color) = color { + fill_boxes3(&fb.ctx, triangles, &color); + } + } + } + for tex in &*copy_tex { + let x1 = 2.0 * (tex.target.x1 / width) - 1.0; + let y1 = 2.0 * (tex.target.y1 / height) - 1.0; + let x2 = 2.0 * (tex.target.x2 / width) - 1.0; + let y2 = 2.0 * (tex.target.y2 / height) - 1.0; + render_texture( + &fb.ctx, + &tex.tex.as_gl(), + tex.format, + x1, + y1, + x2, + y2, + &tex.source, + ) + } + } +} + +fn clear(c: &Color) { + unsafe { + glClearColor(c.r, c.g, c.b, c.a); + glClear(GL_COLOR_BUFFER_BIT); + } +} + +fn fill_boxes3(ctx: &GlRenderContext, boxes: &[f32], color: &Color) { + unsafe { + glUseProgram(ctx.fill_prog.prog); + glUniform4f(ctx.fill_prog_color, color.r, color.g, color.b, color.a); + glVertexAttribPointer( + ctx.fill_prog_pos as _, + 2, + GL_FLOAT, + GL_FALSE, + 0, + boxes.as_ptr() as _, + ); + glEnableVertexAttribArray(ctx.fill_prog_pos as _); + glDrawArrays(GL_TRIANGLES, 0, (boxes.len() / 2) as _); + glDisableVertexAttribArray(ctx.fill_prog_pos as _); + } +} + +fn render_texture( + ctx: &GlRenderContext, + texture: &Texture, + format: &Format, + x1: f32, + y1: f32, + x2: f32, + y2: f32, + src: &BufferPoints, +) { + assert!(rc_eq(&ctx.ctx, &texture.ctx.ctx)); + unsafe { + glActiveTexture(GL_TEXTURE0); + + let target = image_target(texture.gl.external_only); + + glBindTexture(target, texture.gl.tex); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + let progs = match texture.gl.external_only { + true => match &ctx.tex_external { + Some(p) => p, + _ => { + log::error!("Trying to render an external-only texture but context does not support the required extension"); + return; + } + }, + false => &ctx.tex_internal, + }; + let prog = match format.has_alpha { + true => { + glEnable(GL_BLEND); + &progs.alpha + } + false => { + glDisable(GL_BLEND); + &progs.solid + } + }; + + glUseProgram(prog.prog.prog); + + glUniform1i(prog.tex, 0); + + let texcoord = [ + src.top_right.x, + src.top_right.y, + src.top_left.x, + src.top_left.y, + src.bottom_right.x, + src.bottom_right.y, + src.bottom_left.x, + src.bottom_left.y, + ]; + + let pos = [ + x2, y1, // top right + x1, y1, // top left + x2, y2, // bottom right + x1, y2, // bottom left + ]; + + glVertexAttribPointer( + prog.texcoord as _, + 2, + GL_FLOAT, + GL_FALSE, + 0, + texcoord.as_ptr() as _, + ); + glVertexAttribPointer(prog.pos as _, 2, GL_FLOAT, GL_FALSE, 0, pos.as_ptr() as _); + + glEnableVertexAttribArray(prog.texcoord as _); + glEnableVertexAttribArray(prog.pos as _); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(prog.texcoord as _); + glDisableVertexAttribArray(prog.pos as _); + + glBindTexture(target, 0); + } +} + +impl dyn GfxTexture { + fn as_gl(&self) -> &Texture { + self.as_any() + .downcast_ref() + .expect("Non-gl texture passed into gl") + } +} + +impl From for GfxError { + fn from(value: RenderError) -> Self { + Self(Box::new(value)) + } +} diff --git a/src/render/egl.rs b/src/gfx_apis/gl/egl.rs similarity index 93% rename from src/render/egl.rs rename to src/gfx_apis/gl/egl.rs index 2108e95b..a24affc5 100644 --- a/src/render/egl.rs +++ b/src/gfx_apis/gl/egl.rs @@ -1,5 +1,5 @@ use { - crate::render::{ + crate::gfx_apis::gl::{ egl::sys::{ eglBindAPI, EGLAttrib, EGLLabelKHR, EGLenum, EGLint, EGL_DEBUG_MSG_CRITICAL_KHR, EGL_DEBUG_MSG_ERROR_KHR, EGL_DEBUG_MSG_INFO_KHR, EGL_DEBUG_MSG_WARN_KHR, EGL_NONE, @@ -27,11 +27,11 @@ pub mod display; pub mod image; pub mod sys; -pub(super) static PROCS: Lazy = Lazy::new(ExtProc::load); +pub(crate) static PROCS: Lazy = Lazy::new(ExtProc::load); -pub(super) static EXTS: Lazy = Lazy::new(get_client_ext); +pub(crate) static EXTS: Lazy = Lazy::new(get_client_ext); -pub fn init() -> Result<(), RenderError> { +pub(in crate::gfx_apis::gl) fn init() -> Result<(), RenderError> { if !EXTS.contains(ClientExt::EXT_PLATFORM_BASE) { return Err(RenderError::ExtPlatformBase); } diff --git a/src/render/egl/context.rs b/src/gfx_apis/gl/egl/context.rs similarity index 77% rename from src/render/egl/context.rs rename to src/gfx_apis/gl/egl/context.rs index 3e895cd7..c71f7176 100644 --- a/src/render/egl/context.rs +++ b/src/gfx_apis/gl/egl/context.rs @@ -1,16 +1,21 @@ use { - crate::render::{ - egl::{ - display::EglDisplay, - sys::{eglDestroyContext, eglMakeCurrent, EGLContext, EGLSurface, EGL_FALSE, EGL_TRUE}, - PROCS, + crate::{ + gfx_api::ResetStatus, + gfx_apis::gl::{ + egl::{ + display::EglDisplay, + sys::{ + eglDestroyContext, eglMakeCurrent, EGLContext, EGLSurface, EGL_FALSE, EGL_TRUE, + }, + PROCS, + }, + ext::{DisplayExt, GlExt}, + sys::{ + GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB, + GL_UNKNOWN_CONTEXT_RESET_ARB, + }, + RenderError, }, - ext::{DisplayExt, GlExt}, - sys::{ - GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB, - GL_UNKNOWN_CONTEXT_RESET_ARB, - }, - RenderError, ResetStatus, }, std::rc::Rc, }; @@ -58,7 +63,7 @@ impl EglContext { } #[inline] - pub fn with_current Result>( + pub(in crate::gfx_apis::gl) fn with_current Result>( &self, f: F, ) -> Result { diff --git a/src/render/egl/display.rs b/src/gfx_apis/gl/egl/display.rs similarity index 93% rename from src/render/egl/display.rs rename to src/gfx_apis/gl/egl/display.rs index 04520929..95681b63 100644 --- a/src/render/egl/display.rs +++ b/src/gfx_apis/gl/egl/display.rs @@ -1,7 +1,8 @@ use { crate::{ format::{formats, Format}, - render::{ + gfx_api::{GfxFormat, GfxModifier}, + gfx_apis::gl::{ egl::{ context::EglContext, image::EglImage, @@ -35,29 +36,16 @@ use { std::{ptr, rc::Rc}, }; -#[derive(Debug)] -pub struct EglFormat { - pub format: &'static Format, - pub implicit_external_only: bool, - pub modifiers: AHashMap, -} - -#[derive(Debug)] -pub struct EglModifier { - pub modifier: u64, - pub external_only: bool, -} - #[derive(Debug)] pub struct EglDisplay { pub exts: DisplayExt, - pub formats: Rc>, + pub formats: Rc>, pub gbm: Rc, pub dpy: EGLDisplay, } impl EglDisplay { - pub fn create(drm: &Drm) -> Result, RenderError> { + pub(in crate::gfx_apis::gl) fn create(drm: &Drm) -> Result, RenderError> { unsafe { let gbm = match GbmDevice::new(drm) { Ok(gbm) => gbm, @@ -107,7 +95,9 @@ impl EglDisplay { } } - pub fn create_context(self: &Rc) -> Result, RenderError> { + pub(in crate::gfx_apis::gl) fn create_context( + self: &Rc, + ) -> Result, RenderError> { let mut attrib = vec![EGL_CONTEXT_CLIENT_VERSION, 2]; if self .exts @@ -142,7 +132,10 @@ impl EglDisplay { } } - pub fn import_dmabuf(self: &Rc, buf: &DmaBuf) -> Result, RenderError> { + pub(in crate::gfx_apis::gl) fn import_dmabuf( + self: &Rc, + buf: &DmaBuf, + ) -> Result, RenderError> { let format = match self.formats.get(&buf.format.drm) { Some(fmt) => match fmt.modifiers.get(&buf.modifier) { Some(fmt) => fmt, @@ -235,7 +228,7 @@ impl Drop for EglDisplay { } } -unsafe fn query_formats(dpy: EGLDisplay) -> Result, RenderError> { +unsafe fn query_formats(dpy: EGLDisplay) -> Result, RenderError> { let mut vec = vec![]; let mut num = 0; let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num); @@ -255,7 +248,7 @@ unsafe fn query_formats(dpy: EGLDisplay) -> Result, Ren let (modifiers, external_only) = query_modifiers(dpy, fmt, format)?; res.insert( format.drm, - EglFormat { + GfxFormat { format, implicit_external_only: external_only, modifiers, @@ -270,7 +263,7 @@ unsafe fn query_modifiers( dpy: EGLDisplay, gl_format: EGLint, format: &'static Format, -) -> Result<(AHashMap, bool), RenderError> { +) -> Result<(AHashMap, bool), RenderError> { let mut mods = vec![]; let mut ext_only = vec![]; let mut num = 0; @@ -304,7 +297,7 @@ unsafe fn query_modifiers( for (modifier, ext_only) in mods.iter().copied().zip(ext_only.iter().copied()) { res.insert( modifier as _, - EglModifier { + GfxModifier { modifier: modifier as _, external_only: ext_only == EGL_TRUE, }, @@ -316,7 +309,7 @@ unsafe fn query_modifiers( } res.insert( INVALID_MODIFIER, - EglModifier { + GfxModifier { modifier: INVALID_MODIFIER, external_only, }, diff --git a/src/render/egl/image.rs b/src/gfx_apis/gl/egl/image.rs similarity index 94% rename from src/render/egl/image.rs rename to src/gfx_apis/gl/egl/image.rs index 4746e9db..ff7a1c0d 100644 --- a/src/render/egl/image.rs +++ b/src/gfx_apis/gl/egl/image.rs @@ -1,5 +1,5 @@ use { - crate::render::egl::{ + crate::gfx_apis::gl::egl::{ display::EglDisplay, sys::{EGLImageKHR, EGL_FALSE}, PROCS, diff --git a/src/render/egl/sys.rs b/src/gfx_apis/gl/egl/sys.rs similarity index 98% rename from src/render/egl/sys.rs rename to src/gfx_apis/gl/egl/sys.rs index 087c06a5..8282eb48 100644 --- a/src/render/egl/sys.rs +++ b/src/gfx_apis/gl/egl/sys.rs @@ -1,4 +1,4 @@ -use {crate::render::sys::GLenum, uapi::c}; +use {crate::gfx_apis::gl::sys::GLenum, uapi::c}; pub type EGLint = i32; pub type EGLenum = c::c_uint; diff --git a/src/render/ext.rs b/src/gfx_apis/gl/ext.rs similarity index 95% rename from src/render/ext.rs rename to src/gfx_apis/gl/ext.rs index f42c3c74..02fac8cd 100644 --- a/src/render/ext.rs +++ b/src/gfx_apis/gl/ext.rs @@ -1,6 +1,6 @@ use { crate::{ - render::{ + gfx_apis::gl::{ egl::sys::{eglQueryString, EGLDisplay, EGL_EXTENSIONS}, gl::sys::{glGetString, GL_EXTENSIONS}, }, @@ -47,6 +47,7 @@ where } bitflags::bitflags! { + #[derive(Copy, Clone, Debug)] pub struct ClientExt: u32 { const EXT_CLIENT_EXTENSION = 1 << 0; const EXT_PLATFORM_BASE = 1 << 1; @@ -68,6 +69,7 @@ pub fn get_client_ext() -> ClientExt { } bitflags::bitflags! { + #[derive(Copy, Clone, Debug)] pub struct DisplayExt: u32 { const KHR_IMAGE_BASE = 1 << 0; const EXT_IMAGE_DMA_BUF_IMPORT = 1 << 1; @@ -80,7 +82,7 @@ bitflags::bitflags! { } } -pub(super) unsafe fn get_display_ext(dpy: EGLDisplay) -> DisplayExt { +pub(crate) unsafe fn get_display_ext(dpy: EGLDisplay) -> DisplayExt { let map = [ ("EGL_KHR_image_base", DisplayExt::KHR_IMAGE_BASE), ( @@ -116,6 +118,7 @@ pub(super) unsafe fn get_display_ext(dpy: EGLDisplay) -> DisplayExt { } bitflags::bitflags! { + #[derive(Copy, Clone, Debug)] pub struct GlExt: u32 { const GL_OES_EGL_IMAGE = 1 << 0; const GL_OES_EGL_IMAGE_EXTERNAL = 1 << 1; diff --git a/src/render/gl.rs b/src/gfx_apis/gl/gl.rs similarity index 100% rename from src/render/gl.rs rename to src/gfx_apis/gl/gl.rs diff --git a/src/gfx_apis/gl/gl/frame_buffer.rs b/src/gfx_apis/gl/gl/frame_buffer.rs new file mode 100644 index 00000000..70d289a0 --- /dev/null +++ b/src/gfx_apis/gl/gl/frame_buffer.rs @@ -0,0 +1,31 @@ +use { + crate::gfx_apis::gl::{ + egl::context::EglContext, + gl::{ + render_buffer::GlRenderBuffer, + sys::{glDeleteFramebuffers, GLuint}, + texture::GlTexture, + }, + }, + std::rc::Rc, +}; + +pub struct GlFrameBuffer { + pub _rb: Option>, + pub _tex: Option>, + pub ctx: Rc, + pub width: i32, + pub height: i32, + pub fbo: GLuint, +} + +impl Drop for GlFrameBuffer { + fn drop(&mut self) { + let _ = self.ctx.with_current(|| { + unsafe { + glDeleteFramebuffers(1, &self.fbo); + } + Ok(()) + }); + } +} diff --git a/src/render/gl/program.rs b/src/gfx_apis/gl/gl/program.rs similarity index 89% rename from src/render/gl/program.rs rename to src/gfx_apis/gl/gl/program.rs index 759d7a81..a2c523f8 100644 --- a/src/render/gl/program.rs +++ b/src/gfx_apis/gl/gl/program.rs @@ -1,5 +1,5 @@ use { - crate::render::{ + crate::gfx_apis::gl::{ egl::context::EglContext, gl::{ shader::GlShader, @@ -21,7 +21,7 @@ pub struct GlProgram { } impl GlProgram { - pub unsafe fn from_shaders( + pub(in crate::gfx_apis::gl) unsafe fn from_shaders( ctx: &Rc, vert: &str, frag: &str, @@ -31,7 +31,10 @@ impl GlProgram { Self::link(&vert, &frag) } - pub unsafe fn link(vert: &GlShader, frag: &GlShader) -> Result { + pub(in crate::gfx_apis::gl) unsafe fn link( + vert: &GlShader, + frag: &GlShader, + ) -> Result { let res = GlProgram { _ctx: vert.ctx.clone(), prog: glCreateProgram(), diff --git a/src/render/gl/render_buffer.rs b/src/gfx_apis/gl/gl/render_buffer.rs similarity index 91% rename from src/render/gl/render_buffer.rs rename to src/gfx_apis/gl/gl/render_buffer.rs index 7e45eec2..a1cee485 100644 --- a/src/render/gl/render_buffer.rs +++ b/src/gfx_apis/gl/gl/render_buffer.rs @@ -1,5 +1,5 @@ use { - crate::render::{ + crate::gfx_apis::gl::{ egl::{context::EglContext, image::EglImage, PROCS}, gl::{ frame_buffer::GlFrameBuffer, @@ -22,7 +22,7 @@ pub struct GlRenderBuffer { } impl GlRenderBuffer { - pub unsafe fn from_image( + pub(in crate::gfx_apis::gl) unsafe fn from_image( img: &Rc, ctx: &Rc, ) -> Result, RenderError> { @@ -41,7 +41,9 @@ impl GlRenderBuffer { })) } - pub unsafe fn create_framebuffer(self: &Rc) -> Result { + pub(in crate::gfx_apis::gl) unsafe fn create_framebuffer( + self: &Rc, + ) -> Result { let mut fbo = 0; glGenFramebuffers(1, &mut fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); diff --git a/src/render/gl/shader.rs b/src/gfx_apis/gl/gl/shader.rs similarity index 93% rename from src/render/gl/shader.rs rename to src/gfx_apis/gl/gl/shader.rs index 037ef79c..40386ea1 100644 --- a/src/render/gl/shader.rs +++ b/src/gfx_apis/gl/gl/shader.rs @@ -1,5 +1,5 @@ use { - crate::render::{ + crate::gfx_apis::gl::{ egl::context::EglContext, gl::sys::{ glCompileShader, glCreateShader, glDeleteShader, glGetShaderiv, glShaderSource, GLenum, @@ -17,7 +17,7 @@ pub struct GlShader { } impl GlShader { - pub unsafe fn compile( + pub(in crate::gfx_apis::gl) unsafe fn compile( ctx: &Rc, ty: GLenum, src: &str, diff --git a/src/render/gl/sys.rs b/src/gfx_apis/gl/gl/sys.rs similarity index 97% rename from src/render/gl/sys.rs rename to src/gfx_apis/gl/gl/sys.rs index 7c04973e..54bf0754 100644 --- a/src/render/gl/sys.rs +++ b/src/gfx_apis/gl/gl/sys.rs @@ -28,7 +28,6 @@ pub const GL_FRAMEBUFFER: GLenum = 0x8D40; pub const GL_LINEAR: GLint = 0x2601; pub const GL_LINK_STATUS: GLenum = 0x8B82; pub const GL_RENDERBUFFER: GLenum = 0x8D41; -pub const GL_SCISSOR_TEST: GLenum = 0x0C11; pub const GL_TEXTURE0: GLenum = 0x84C0; pub const GL_TEXTURE_2D: GLenum = 0x0DE1; pub const GL_TEXTURE_EXTERNAL_OES: GLenum = 0x8D65; @@ -106,7 +105,6 @@ extern "C" { pixels: *const c::c_void, ); - pub fn glScissor(x: GLint, y: GLint, width: GLsizei, height: GLsizei); pub fn glEnable(cap: GLenum); pub fn glDisable(cap: GLenum); pub fn glViewport(x: GLint, y: GLint, width: GLsizei, height: GLsizei); diff --git a/src/render/gl/texture.rs b/src/gfx_apis/gl/gl/texture.rs similarity index 92% rename from src/render/gl/texture.rs rename to src/gfx_apis/gl/gl/texture.rs index e488eac2..58db32d6 100644 --- a/src/render/gl/texture.rs +++ b/src/gfx_apis/gl/gl/texture.rs @@ -1,7 +1,7 @@ use { crate::{ format::Format, - render::{ + gfx_apis::gl::{ egl::{context::EglContext, image::EglImage, PROCS}, ext::GlExt, gl::sys::{ @@ -17,7 +17,7 @@ use { }; pub struct GlTexture { - pub(super) ctx: Rc, + pub(crate) ctx: Rc, pub img: Option>, pub tex: GLuint, pub width: i32, @@ -33,7 +33,10 @@ pub fn image_target(external_only: bool) -> GLenum { } impl GlTexture { - pub fn import_img(ctx: &Rc, img: &Rc) -> Result { + pub(in crate::gfx_apis::gl) fn import_img( + ctx: &Rc, + img: &Rc, + ) -> Result { if !ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE_EXTERNAL) { return Err(RenderError::ExternalUnsupported); } @@ -58,7 +61,7 @@ impl GlTexture { }) } - pub fn import_shm( + pub(in crate::gfx_apis::gl) fn import_shm( ctx: &Rc, data: &[Cell], format: &'static Format, diff --git a/src/render/proc.rs b/src/gfx_apis/gl/proc.rs similarity index 100% rename from src/render/proc.rs rename to src/gfx_apis/gl/proc.rs diff --git a/src/gfx_apis/gl/renderer.rs b/src/gfx_apis/gl/renderer.rs new file mode 100644 index 00000000..eaa9bc1d --- /dev/null +++ b/src/gfx_apis/gl/renderer.rs @@ -0,0 +1,4 @@ +pub(super) mod context; +pub(super) mod framebuffer; +pub(super) mod image; +pub(super) mod texture; diff --git a/src/render/renderer/context.rs b/src/gfx_apis/gl/renderer/context.rs similarity index 62% rename from src/render/renderer/context.rs rename to src/gfx_apis/gl/renderer/context.rs index 0be13b30..55674b08 100644 --- a/src/render/renderer/context.rs +++ b/src/gfx_apis/gl/renderer/context.rs @@ -1,17 +1,18 @@ use { crate::{ format::{Format, XRGB8888}, - render::{ - egl::{ - context::EglContext, - display::{EglDisplay, EglFormat}, - }, + gfx_api::{ + GfxApiOpt, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxTexture, + ResetStatus, + }, + gfx_apis::gl::{ + egl::{context::EglContext, display::EglDisplay}, ext::GlExt, gl::{ program::GlProgram, render_buffer::GlRenderBuffer, sys::GLint, texture::GlTexture, }, renderer::{framebuffer::Framebuffer, image::Image}, - RenderError, Texture, + GfxGlState, RenderError, Texture, }, video::{ dmabuf::DmaBuf, @@ -21,19 +22,20 @@ use { }, ahash::AHashMap, std::{ - cell::Cell, + cell::{Cell, RefCell}, ffi::CString, fmt::{Debug, Formatter}, + mem, rc::Rc, }, uapi::ustr, }; -pub(super) struct TexProg { - pub(super) prog: GlProgram, - pub(super) pos: GLint, - pub(super) texcoord: GLint, - pub(super) tex: GLint, +pub(crate) struct TexProg { + pub(crate) prog: GlProgram, + pub(crate) pos: GLint, + pub(crate) texcoord: GLint, + pub(crate) tex: GLint, } impl TexProg { @@ -47,40 +49,35 @@ impl TexProg { } } -pub(super) struct TexProgs { +pub(crate) struct TexProgs { pub alpha: TexProg, pub solid: TexProg, } -pub struct RenderContext { - pub(super) ctx: Rc, +pub(in crate::gfx_apis::gl) struct GlRenderContext { + pub(crate) ctx: Rc, pub gbm: Rc, - pub(super) render_node: Rc, + pub(crate) render_node: Rc, - pub(super) tex_internal: TexProgs, - pub(super) tex_external: Option, + pub(crate) tex_internal: TexProgs, + pub(crate) tex_external: Option, - pub(super) fill_prog: GlProgram, - pub(super) fill_prog_pos: GLint, - pub(super) fill_prog_color: GLint, + pub(crate) fill_prog: GlProgram, + pub(crate) fill_prog_pos: GLint, + pub(crate) fill_prog_color: GLint, + + pub(crate) gfx_ops: RefCell>, + pub(in crate::gfx_apis::gl) gl_state: RefCell, } -impl Debug for RenderContext { +impl Debug for GlRenderContext { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("RenderContext").finish_non_exhaustive() } } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum ResetStatus { - Guilty, - Innocent, - Unknown, - Other(u32), -} - -impl RenderContext { +impl GlRenderContext { pub fn reset_status(&self) -> Option { self.ctx.reset_status() } @@ -89,7 +86,7 @@ impl RenderContext { self.ctx.ext.contains(GlExt::GL_OES_EGL_IMAGE_EXTERNAL) } - pub fn from_drm_device(drm: &Drm) -> Result { + pub(in crate::gfx_apis::gl) fn from_drm_device(drm: &Drm) -> Result { let nodes = drm.get_nodes()?; let node = match nodes .get(&NodeType::Render) @@ -153,6 +150,9 @@ impl RenderContext { fill_prog_pos: fill_prog.get_attrib_location(ustr!("pos")), fill_prog_color: fill_prog.get_uniform_location(ustr!("color")), fill_prog, + + gfx_ops: Default::default(), + gl_state: Default::default(), }) } @@ -160,11 +160,11 @@ impl RenderContext { self.render_node.clone() } - pub fn formats(&self) -> Rc> { + pub fn formats(&self) -> Rc> { self.ctx.dpy.formats.clone() } - pub fn dmabuf_fb(self: &Rc, buf: &DmaBuf) -> Result, RenderError> { + fn dmabuf_fb(self: &Rc, buf: &DmaBuf) -> Result, RenderError> { self.ctx.with_current(|| unsafe { let img = self.ctx.dpy.import_dmabuf(buf)?; let rb = GlRenderBuffer::from_image(&img, &self.ctx)?; @@ -176,7 +176,7 @@ impl RenderContext { }) } - pub fn dmabuf_img(self: &Rc, buf: &DmaBuf) -> Result, RenderError> { + fn dmabuf_img(self: &Rc, buf: &DmaBuf) -> Result, RenderError> { self.ctx.with_current(|| { let img = self.ctx.dpy.import_dmabuf(buf)?; Ok(Rc::new(Image { @@ -186,7 +186,7 @@ impl RenderContext { }) } - pub fn shmem_texture( + fn shmem_texture( self: &Rc, data: &[Cell], format: &'static Format, @@ -201,3 +201,57 @@ impl RenderContext { })) } } + +impl GfxContext for GlRenderContext { + fn take_render_ops(&self) -> Vec { + mem::take(&mut self.gfx_ops.borrow_mut()) + } + + fn reset_status(&self) -> Option { + self.reset_status() + } + + fn supports_external_texture(&self) -> bool { + self.supports_external_texture() + } + + fn render_node(&self) -> Rc { + self.render_node() + } + + fn formats(&self) -> Rc> { + self.formats() + } + + fn dmabuf_fb(self: Rc, buf: &DmaBuf) -> Result, GfxError> { + (&self) + .dmabuf_fb(buf) + .map(|w| w as Rc) + .map_err(|e| e.into()) + } + + fn dmabuf_img(self: Rc, buf: &DmaBuf) -> Result, GfxError> { + (&self) + .dmabuf_img(buf) + .map(|w| w as Rc) + .map_err(|e| e.into()) + } + + fn shmem_texture( + self: Rc, + data: &[Cell], + format: &'static Format, + width: i32, + height: i32, + stride: i32, + ) -> Result, GfxError> { + (&self) + .shmem_texture(data, format, width, height, stride) + .map(|w| w as Rc) + .map_err(|e| e.into()) + } + + fn gbm(&self) -> &GbmDevice { + &self.gbm + } +} diff --git a/src/gfx_apis/gl/renderer/framebuffer.rs b/src/gfx_apis/gl/renderer/framebuffer.rs new file mode 100644 index 00000000..8ffb32a0 --- /dev/null +++ b/src/gfx_apis/gl/renderer/framebuffer.rs @@ -0,0 +1,331 @@ +use { + crate::{ + cursor::Cursor, + fixed::Fixed, + format::{Format, ARGB8888, XRGB8888}, + gfx_api::{GfxFramebuffer, GfxTexture}, + gfx_apis::gl::{ + gl::{ + frame_buffer::GlFrameBuffer, + sys::{ + glBindFramebuffer, glClear, glClearColor, glViewport, GL_COLOR_BUFFER_BIT, + GL_FRAMEBUFFER, + }, + }, + renderer::context::GlRenderContext, + run_ops, + sys::{glBlendFunc, glFlush, glReadnPixels, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, + }, + rect::Rect, + renderer::{renderer_base::RendererBase, RenderResult, Renderer}, + scale::Scale, + state::State, + tree::Node, + }, + std::{ + any::Any, + cell::Cell, + fmt::{Debug, Formatter}, + rc::Rc, + }, +}; + +pub struct Framebuffer { + pub(in crate::gfx_apis::gl) ctx: Rc, + pub(in crate::gfx_apis::gl) gl: GlFrameBuffer, +} + +impl Debug for Framebuffer { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Framebuffer").finish_non_exhaustive() + } +} + +impl Framebuffer { + pub fn clear(&self) { + self.clear_with(0.0, 0.0, 0.0, 0.0); + } + + pub fn clear_with(&self, r: f32, g: f32, b: f32, a: f32) { + let _ = self.ctx.ctx.with_current(|| { + unsafe { + glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); + glViewport(0, 0, self.gl.width, self.gl.height); + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT); + } + Ok(()) + }); + } + + pub fn copy_texture( + &self, + state: &State, + texture: &Rc, + x: i32, + y: i32, + alpha: bool, + ) { + let mut ops = self.ctx.gfx_ops.borrow_mut(); + ops.clear(); + let scale = Scale::from_int(1); + let extents = Rect::new_sized(0, 0, self.gl.width, self.gl.height).unwrap(); + let mut renderer = Renderer { + base: RendererBase { + ops: &mut ops, + scaled: false, + scale, + scalef: 1.0, + }, + state, + on_output: false, + result: &mut RenderResult::default(), + logical_extents: extents, + physical_extents: extents, + }; + let format = match alpha { + true => ARGB8888, + false => XRGB8888, + }; + renderer + .base + .render_texture(texture, x, y, format, None, None, scale, i32::MAX, i32::MAX); + let _ = self.ctx.ctx.with_current(|| { + unsafe { + glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); + glViewport(0, 0, self.gl.width, self.gl.height); + if alpha { + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + } + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + run_ops(self, &ops); + unsafe { + glFlush(); + } + Ok(()) + }); + } + + pub fn copy_to_shm( + &self, + x: i32, + y: i32, + width: i32, + height: i32, + format: &Format, + shm: &[Cell], + ) { + let y = self.gl.height - y - height; + let _ = self.ctx.ctx.with_current(|| { + unsafe { + glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); + glViewport(0, 0, self.gl.width, self.gl.height); + glReadnPixels( + x, + y, + width, + height, + format.gl_format as _, + format.gl_type as _, + shm.len() as _, + shm.as_ptr() as _, + ); + } + Ok(()) + }); + } + + pub fn render_custom(&self, scale: Scale, f: &mut dyn FnMut(&mut RendererBase)) { + let mut ops = self.ctx.gfx_ops.borrow_mut(); + ops.clear(); + let mut renderer = RendererBase { + ops: &mut ops, + scaled: scale != 1, + scale, + scalef: scale.to_f64(), + }; + f(&mut renderer); + let _ = self.ctx.ctx.with_current(|| { + unsafe { + glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); + glViewport(0, 0, self.gl.width, self.gl.height); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + run_ops(self, &ops); + unsafe { + glFlush(); + } + Ok(()) + }); + } + + pub fn render( + &self, + node: &dyn Node, + state: &State, + cursor_rect: Option, + on_output: bool, + result: &mut RenderResult, + scale: Scale, + render_hardware_cursor: bool, + ) { + let mut ops = self.ctx.gfx_ops.borrow_mut(); + ops.clear(); + let mut renderer = Renderer { + base: RendererBase { + ops: &mut ops, + scaled: scale != 1, + scale, + scalef: scale.to_f64(), + }, + state, + on_output, + result, + logical_extents: node.node_absolute_position().at_point(0, 0), + physical_extents: Rect::new(0, 0, self.gl.width, self.gl.height).unwrap(), + }; + node.node_render(&mut renderer, 0, 0, i32::MAX, i32::MAX); + if let Some(rect) = cursor_rect { + let seats = state.globals.lock_seats(); + for seat in seats.values() { + if !render_hardware_cursor && seat.hardware_cursor() { + continue; + } + if let Some(cursor) = seat.get_cursor() { + let (mut x, mut y) = seat.get_position(); + if let Some(dnd_icon) = seat.dnd_icon() { + let extents = dnd_icon.extents.get().move_( + x.round_down() + dnd_icon.buf_x.get(), + y.round_down() + dnd_icon.buf_y.get(), + ); + if extents.intersects(&rect) { + let (x, y) = rect.translate(extents.x1(), extents.y1()); + renderer.render_surface(&dnd_icon, x, y, i32::MAX, i32::MAX); + } + } + cursor.tick(); + x -= Fixed::from_int(rect.x1()); + y -= Fixed::from_int(rect.y1()); + cursor.render(&mut renderer, x, y); + } + } + } + let _ = self.ctx.ctx.with_current(|| { + let c = state.theme.colors.background.get(); + unsafe { + glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); + glViewport(0, 0, self.gl.width, self.gl.height); + glClearColor(c.r, c.g, c.b, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + run_ops(self, &ops); + unsafe { + glFlush(); + } + Ok(()) + }); + } + + pub fn render_hardware_cursor(&self, cursor: &dyn Cursor, state: &State, scale: Scale) { + let mut ops = self.ctx.gfx_ops.borrow_mut(); + ops.clear(); + let mut res = RenderResult::default(); + let mut renderer = Renderer { + base: RendererBase { + ops: &mut ops, + scaled: scale != 1, + scale, + scalef: scale.to_f64(), + }, + state, + on_output: false, + result: &mut res, + logical_extents: Rect::new_empty(0, 0), + physical_extents: Rect::new(0, 0, self.gl.width, self.gl.height).unwrap(), + }; + cursor.render_hardware_cursor(&mut renderer); + let _ = self.ctx.ctx.with_current(|| { + unsafe { + glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); + glViewport(0, 0, self.gl.width, self.gl.height); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + run_ops(self, &ops); + unsafe { + glFlush(); + } + Ok(()) + }); + } +} + +impl GfxFramebuffer for Framebuffer { + fn as_any(&self) -> &dyn Any { + self + } + + fn clear(&self) { + self.clear() + } + + fn clear_with(&self, r: f32, g: f32, b: f32, a: f32) { + self.clear_with(r, g, b, a) + } + + fn copy_texture( + &self, + state: &State, + texture: &Rc, + x: i32, + y: i32, + alpha: bool, + ) { + self.copy_texture(state, texture, x, y, alpha) + } + + fn copy_to_shm( + &self, + x: i32, + y: i32, + width: i32, + height: i32, + format: &Format, + shm: &[Cell], + ) { + self.copy_to_shm(x, y, width, height, format, shm) + } + + fn render_custom(&self, scale: Scale, f: &mut dyn FnMut(&mut RendererBase)) { + self.render_custom(scale, f) + } + + fn render( + &self, + node: &dyn Node, + state: &State, + cursor_rect: Option, + on_output: bool, + result: &mut RenderResult, + scale: Scale, + render_hardware_cursor: bool, + ) { + self.render( + node, + state, + cursor_rect, + on_output, + result, + scale, + render_hardware_cursor, + ) + } + + fn render_hardware_cursor(&self, cursor: &dyn Cursor, state: &State, scale: Scale) { + self.render_hardware_cursor(cursor, state, scale) + } +} diff --git a/src/gfx_apis/gl/renderer/image.rs b/src/gfx_apis/gl/renderer/image.rs new file mode 100644 index 00000000..a586f271 --- /dev/null +++ b/src/gfx_apis/gl/renderer/image.rs @@ -0,0 +1,68 @@ +use { + crate::{ + gfx_api::{GfxError, GfxFramebuffer, GfxImage, GfxTexture}, + gfx_apis::gl::{ + egl::image::EglImage, + gl::{render_buffer::GlRenderBuffer, texture::GlTexture}, + Framebuffer, GlRenderContext, RenderError, Texture, + }, + }, + std::rc::Rc, +}; + +pub struct Image { + pub(in crate::gfx_apis::gl) ctx: Rc, + pub(in crate::gfx_apis::gl) gl: Rc, +} + +impl Image { + pub fn width(&self) -> i32 { + self.gl.width + } + + pub fn height(&self) -> i32 { + self.gl.height + } + + fn to_texture(self: &Rc) -> Result, RenderError> { + Ok(Rc::new(Texture { + ctx: self.ctx.clone(), + gl: GlTexture::import_img(&self.ctx.ctx, &self.gl)?, + })) + } + + fn to_framebuffer(&self) -> Result, RenderError> { + self.ctx.ctx.with_current(|| unsafe { + let rb = GlRenderBuffer::from_image(&self.gl, &self.ctx.ctx)?; + let fb = rb.create_framebuffer()?; + Ok(Rc::new(Framebuffer { + ctx: self.ctx.clone(), + gl: fb, + })) + }) + } +} + +impl GfxImage for Image { + fn to_framebuffer(self: Rc) -> Result, GfxError> { + (*self) + .to_framebuffer() + .map(|v| v as Rc) + .map_err(|e| e.into()) + } + + fn to_texture(self: Rc) -> Result, GfxError> { + (&self) + .to_texture() + .map(|v| v as Rc) + .map_err(|e| e.into()) + } + + fn width(&self) -> i32 { + self.width() + } + + fn height(&self) -> i32 { + self.height() + } +} diff --git a/src/gfx_apis/gl/renderer/texture.rs b/src/gfx_apis/gl/renderer/texture.rs new file mode 100644 index 00000000..0eb73dd8 --- /dev/null +++ b/src/gfx_apis/gl/renderer/texture.rs @@ -0,0 +1,46 @@ +use { + crate::{ + gfx_api::GfxTexture, + gfx_apis::gl::{gl::texture::GlTexture, renderer::context::GlRenderContext}, + }, + std::{ + any::Any, + fmt::{Debug, Formatter}, + rc::Rc, + }, +}; + +pub struct Texture { + pub(in crate::gfx_apis::gl) ctx: Rc, + pub(in crate::gfx_apis::gl) gl: GlTexture, +} + +impl Debug for Texture { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Texture").finish_non_exhaustive() + } +} + +impl Texture { + pub fn width(&self) -> i32 { + self.gl.width + } + + pub fn height(&self) -> i32 { + self.gl.height + } +} + +impl GfxTexture for Texture { + fn width(&self) -> i32 { + self.width() + } + + fn height(&self) -> i32 { + self.height() + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/src/render/shaders/fill.frag.glsl b/src/gfx_apis/gl/shaders/fill.frag.glsl similarity index 100% rename from src/render/shaders/fill.frag.glsl rename to src/gfx_apis/gl/shaders/fill.frag.glsl diff --git a/src/render/shaders/fill.vert.glsl b/src/gfx_apis/gl/shaders/fill.vert.glsl similarity index 100% rename from src/render/shaders/fill.vert.glsl rename to src/gfx_apis/gl/shaders/fill.vert.glsl diff --git a/src/render/shaders/tex-alpha.frag.glsl b/src/gfx_apis/gl/shaders/tex-alpha.frag.glsl similarity index 100% rename from src/render/shaders/tex-alpha.frag.glsl rename to src/gfx_apis/gl/shaders/tex-alpha.frag.glsl diff --git a/src/render/shaders/tex-external-alpha.frag.glsl b/src/gfx_apis/gl/shaders/tex-external-alpha.frag.glsl similarity index 100% rename from src/render/shaders/tex-external-alpha.frag.glsl rename to src/gfx_apis/gl/shaders/tex-external-alpha.frag.glsl diff --git a/src/render/shaders/tex-external.frag.glsl b/src/gfx_apis/gl/shaders/tex-external.frag.glsl similarity index 100% rename from src/render/shaders/tex-external.frag.glsl rename to src/gfx_apis/gl/shaders/tex-external.frag.glsl diff --git a/src/render/shaders/tex.frag.glsl b/src/gfx_apis/gl/shaders/tex.frag.glsl similarity index 100% rename from src/render/shaders/tex.frag.glsl rename to src/gfx_apis/gl/shaders/tex.frag.glsl diff --git a/src/render/shaders/tex.vert.glsl b/src/gfx_apis/gl/shaders/tex.vert.glsl similarity index 100% rename from src/render/shaders/tex.vert.glsl rename to src/gfx_apis/gl/shaders/tex.vert.glsl diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index 87a446d6..2794d7e2 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -277,7 +277,7 @@ impl JayCompositor { .render_ctx_watchers .set((self.client.id, req.id), ctx.clone()); let rctx = self.client.state.render_ctx.get(); - ctx.send_render_ctx(rctx.as_ref()); + ctx.send_render_ctx(rctx); Ok(()) } diff --git a/src/ifs/jay_render_ctx.rs b/src/ifs/jay_render_ctx.rs index 73e8374b..3b58c2a0 100644 --- a/src/ifs/jay_render_ctx.rs +++ b/src/ifs/jay_render_ctx.rs @@ -1,9 +1,9 @@ use { crate::{ client::{Client, ClientError}, + gfx_api::GfxContext, leaks::Tracker, object::Object, - render::RenderContext, utils::{ buffd::{MsgParser, MsgParserError}, errorfmt::ErrorFmt, @@ -21,10 +21,10 @@ pub struct JayRenderCtx { } impl JayRenderCtx { - pub fn send_render_ctx(&self, ctx: Option<&Rc>) { + pub fn send_render_ctx(&self, ctx: Option>) { let mut fd = None; if let Some(ctx) = ctx { - match ctx.gbm.drm.dup_render() { + match ctx.gbm().drm.dup_render() { Ok(d) => fd = Some(d.fd().clone()), Err(e) => { log::error!("Could not dup drm fd: {}", ErrorFmt(e)); diff --git a/src/ifs/jay_screencast.rs b/src/ifs/jay_screencast.rs index dc368237..951a12c4 100644 --- a/src/ifs/jay_screencast.rs +++ b/src/ifs/jay_screencast.rs @@ -2,10 +2,10 @@ use { crate::{ client::{Client, ClientError}, format::XRGB8888, + gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture}, ifs::jay_output::JayOutput, leaks::Tracker, object::Object, - render::{Framebuffer, RenderContext, RenderError, Texture}, tree::{OutputNode, WorkspaceNodeId}, utils::{ buffd::{MsgParser, MsgParserError}, @@ -60,7 +60,7 @@ struct Pending { struct ScreencastBuffer { dmabuf: DmaBuf, - fb: Rc, + fb: Rc, free: bool, } @@ -147,7 +147,7 @@ impl JayScreencast { }); } - pub fn copy_texture(&self, on: &OutputNode, texture: &Texture) { + pub fn copy_texture(&self, on: &OutputNode, texture: &Rc) { if !self.running.get() { return; } @@ -193,7 +193,7 @@ impl JayScreencast { self.client.event(Destroyed { self_id: self.id }); } - pub fn realloc(&self, ctx: &Rc) -> Result<(), JayScreencastError> { + pub fn realloc(&self, ctx: &Rc) -> Result<(), JayScreencastError> { let mut buffers = vec![]; if let Some(output) = self.output.get() { let mode = output.global.mode.get(); @@ -207,8 +207,10 @@ impl JayScreencast { if self.linear.get() { flags |= GBM_BO_USE_LINEAR; } - let buffer = ctx.gbm.create_bo(mode.width, mode.height, &format, flags)?; - let fb = ctx.dmabuf_img(buffer.dmabuf())?.to_framebuffer()?; + let buffer = ctx + .gbm() + .create_bo(mode.width, mode.height, &format, flags)?; + let fb = ctx.clone().dmabuf_img(buffer.dmabuf())?.to_framebuffer()?; buffers.push(ScreencastBuffer { dmabuf: buffer.dmabuf().clone(), fb, @@ -444,7 +446,7 @@ pub enum JayScreencastError { #[error(transparent)] GbmError(#[from] GbmError), #[error(transparent)] - RenderError(#[from] RenderError), + GfxError(#[from] GfxError), } efrom!(JayScreencastError, MsgParserError); efrom!(JayScreencastError, ClientError); diff --git a/src/ifs/wl_buffer.rs b/src/ifs/wl_buffer.rs index cba05ae0..0e4c7139 100644 --- a/src/ifs/wl_buffer.rs +++ b/src/ifs/wl_buffer.rs @@ -3,10 +3,10 @@ use { client::{Client, ClientError}, clientmem::{ClientMem, ClientMemError, ClientMemOffset}, format::Format, + gfx_api::{GfxError, GfxFramebuffer, GfxImage, GfxTexture}, leaks::Tracker, object::Object, rect::Rect, - render::{Framebuffer, Image, RenderError, Texture}, utils::{ buffd::{MsgParser, MsgParserError}, clonecell::CloneCell, @@ -25,7 +25,7 @@ use { pub enum WlBufferStorage { Shm { mem: ClientMemOffset, stride: i32 }, - Dmabuf(Rc), + Dmabuf(Rc), } pub struct WlBuffer { @@ -37,8 +37,8 @@ pub struct WlBuffer { dmabuf: Option, render_ctx_version: Cell, pub storage: RefCell>, - pub texture: CloneCell>>, - pub famebuffer: CloneCell>>, + pub texture: CloneCell>>, + pub famebuffer: CloneCell>>, width: i32, height: i32, pub tracker: Tracker, @@ -55,7 +55,7 @@ impl WlBuffer { client: &Rc, format: &'static Format, dmabuf: DmaBuf, - img: &Rc, + img: &Rc, ) -> Self { let width = img.width(); let height = img.height(); @@ -165,7 +165,7 @@ impl WlBuffer { } WlBufferStorage::Dmabuf(img) => { if self.texture.get().is_none() { - self.texture.set(Some(img.to_texture()?)); + self.texture.set(Some(img.clone().to_texture()?)); } } } @@ -184,7 +184,7 @@ impl WlBuffer { } WlBufferStorage::Dmabuf(img) => { if self.famebuffer.get().is_none() { - self.famebuffer.set(Some(img.to_framebuffer()?)); + self.famebuffer.set(Some(img.clone().to_framebuffer()?)); } } } @@ -225,14 +225,13 @@ pub enum WlBufferError { StrideTooSmall, #[error("Could not access the client memory")] ClientMemError(#[source] Box), - #[error("GLES could not import the client image")] - RenderError(#[source] Box), + #[error("The graphics library could not import the client image")] + GfxError(#[from] GfxError), #[error("Parsing failed")] MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(WlBufferError, ClientMemError); -efrom!(WlBufferError, RenderError); efrom!(WlBufferError, MsgParserError); efrom!(WlBufferError, ClientError); diff --git a/src/ifs/wl_drm.rs b/src/ifs/wl_drm.rs index 8842b8ee..bc791506 100644 --- a/src/ifs/wl_drm.rs +++ b/src/ifs/wl_drm.rs @@ -1,11 +1,11 @@ use { crate::{ client::{Client, ClientError}, + gfx_api::GfxError, globals::{Global, GlobalName}, ifs::wl_buffer::WlBuffer, leaks::Tracker, object::Object, - render::RenderError, utils::buffd::{MsgParser, MsgParserError}, video::{ dmabuf::{DmaBuf, DmaBufPlane}, @@ -190,7 +190,7 @@ pub enum WlDrmError { #[error("The format {0} is not supported")] InvalidFormat(u32), #[error("Could not import the buffer")] - ImportError(#[from] RenderError), + ImportError(#[from] GfxError), } efrom!(WlDrmError, ClientError); efrom!(WlDrmError, MsgParserError); diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index efa9c4a6..9085f62b 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -3,6 +3,7 @@ use { backend, client::{Client, ClientError, ClientId}, format::XRGB8888, + gfx_api::{GfxFramebuffer, GfxTexture}, globals::{Global, GlobalName}, ifs::{ wl_buffer::WlBufferStorage, wl_surface::WlSurface, @@ -11,7 +12,6 @@ use { leaks::Tracker, object::Object, rect::Rect, - render::{Framebuffer, Texture}, state::{ConnectorData, State}, time::Time, tree::OutputNode, @@ -199,7 +199,7 @@ impl WlOutputGlobal { Ok(()) } - pub fn perform_screencopies(&self, fb: &Framebuffer, tex: &Texture) { + pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc) { if self.pending_captures.is_empty() { return; } diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 04aab5b0..a0e04b53 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -887,7 +887,7 @@ impl WlSeatGlobal { } { let mut bindings = self.bindings.borrow_mut(); - let bindings = bindings.entry(client.id).or_insert_with(Default::default); + let bindings = bindings.entry(client.id).or_default(); bindings.insert(id, obj.clone()); } Ok(()) diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index ce7b85e1..ad6d493e 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -15,6 +15,7 @@ use { backend::KeyState, client::{Client, ClientError, RequestParser}, fixed::Fixed, + gfx_api::{BufferPoint, BufferPoints}, ifs::{ wl_buffer::WlBuffer, wl_callback::WlCallback, @@ -38,7 +39,7 @@ use { leaks::Tracker, object::Object, rect::{Rect, Region}, - render::Renderer, + renderer::Renderer, tree::{ FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, NodeVisitorBase, OutputNode, ToplevelNode, @@ -101,20 +102,6 @@ impl Transform { } } -#[derive(Default, Debug)] -struct BufferPoint { - x: f32, - y: f32, -} - -#[derive(Default, Debug)] -struct BufferPoints { - top_right: BufferPoint, - top_left: BufferPoint, - bottom_right: BufferPoint, - bottom_left: BufferPoint, -} - impl Transform { fn apply_inv_sized(self, x1: f32, y1: f32, width: f32, height: f32) -> BufferPoints { let x2 = x1 + width; @@ -237,7 +224,7 @@ pub struct WlSurface { input_region: Cell>>, opaque_region: Cell>>, buffer_points: RefCell, - pub buffer_points_norm: RefCell<[f32; 8]>, + pub buffer_points_norm: RefCell, buffer_transform: Cell, buffer_scale: Cell, src_rect: Cell>, @@ -817,35 +804,12 @@ impl WlSurface { .buffer_transform .get() .apply_inv_sized(0.0, 0.0, 1.0, 1.0); - let points = &*buffer_points; - *buffer_points_norm = [ - points.top_right.x, - points.top_right.y, - points.top_left.x, - points.top_left.y, - points.bottom_right.x, - points.bottom_right.y, - points.bottom_left.x, - points.bottom_left.y, - ]; + *buffer_points_norm = *buffer_points; } else { - let width = buffer.rect.width() as f32; - let height = buffer.rect.height() as f32; - let points = &*buffer_points; - *buffer_points_norm = [ - points.top_right.x / width, - points.top_right.y / height, - points.top_left.x / width, - points.top_left.y / height, - points.bottom_right.x / width, - points.bottom_right.y / height, - points.bottom_left.x / width, - points.bottom_left.y / height, - ]; - for &v in buffer_points_norm.iter() { - if v > 1.0 { - return Err(WlSurfaceError::ViewportOutsideBuffer); - } + *buffer_points_norm = buffer_points + .norm(buffer.rect.width() as f32, buffer.rect.height() as f32); + if !buffer_points_norm.is_leq_1() { + return Err(WlSurfaceError::ViewportOutsideBuffer); } } } @@ -1134,8 +1098,15 @@ impl Node for WlSurface { } } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { - renderer.render_surface(self, x, y); + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + max_width: i32, + max_height: i32, + ) { + renderer.render_surface(self, x, y, max_width, max_height); } fn node_client(&self) -> Option> { diff --git a/src/ifs/wl_surface/cursor.rs b/src/ifs/wl_surface/cursor.rs index f42d8d0c..99df51df 100644 --- a/src/ifs/wl_surface/cursor.rs +++ b/src/ifs/wl_surface/cursor.rs @@ -5,7 +5,7 @@ use { ifs::{wl_seat::WlSeatGlobal, wl_surface::WlSurface}, leaks::Tracker, rect::Rect, - render::Renderer, + renderer::Renderer, scale::Scale, tree::{Node, NodeVisitorBase, OutputNode}, }, @@ -76,16 +76,28 @@ impl Cursor for CursorSurface { let (hot_x, hot_y) = (Fixed::from_int(hot_x), Fixed::from_int(hot_y)); let x = ((x - hot_x).to_f64() * scale).round() as _; let y = ((y - hot_y).to_f64() * scale).round() as _; - renderer.render_surface_scaled(&self.surface, x, y, None); + renderer.render_surface_scaled(&self.surface, x, y, None, i32::MAX, i32::MAX); } else { - renderer.render_surface(&self.surface, x_int - hot_x, y_int - hot_y); + renderer.render_surface( + &self.surface, + x_int - hot_x, + y_int - hot_y, + i32::MAX, + i32::MAX, + ); } } } fn render_hardware_cursor(&self, renderer: &mut Renderer) { let extents = self.surface.extents.get(); - renderer.render_surface(&self.surface, -extents.x1(), -extents.y1()); + renderer.render_surface( + &self.surface, + -extents.x1(), + -extents.y1(), + i32::MAX, + i32::MAX, + ); struct FrameRequests; impl NodeVisitorBase for FrameRequests { diff --git a/src/ifs/wl_surface/x_surface/xwindow.rs b/src/ifs/wl_surface/x_surface/xwindow.rs index 256b086b..fe092165 100644 --- a/src/ifs/wl_surface/x_surface/xwindow.rs +++ b/src/ifs/wl_surface/x_surface/xwindow.rs @@ -8,7 +8,7 @@ use { wl_surface::{x_surface::XSurface, WlSurface, WlSurfaceError}, }, rect::Rect, - render::Renderer, + renderer::Renderer, state::State, tree::{ Direction, FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, StackedNode, @@ -334,8 +334,15 @@ impl Node for Xwindow { FindTreeResult::Other } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { - renderer.render_surface(&self.x.surface, x, y) + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + max_width: i32, + max_height: i32, + ) { + renderer.render_surface(&self.x.surface, x, y, max_width, max_height) } fn node_client(&self) -> Option> { diff --git a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs index 29380b4a..a24498b9 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs @@ -11,7 +11,7 @@ use { leaks::Tracker, object::Object, rect::Rect, - render::Renderer, + renderer::Renderer, tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, StackedNode, WorkspaceNode}, utils::{ buffd::{MsgParser, MsgParserError}, @@ -308,8 +308,15 @@ impl Node for XdgPopup { self.xdg.find_tree_at(x, y, tree) } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { - renderer.render_xdg_surface(&self.xdg, x, y) + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + max_width: i32, + max_height: i32, + ) { + renderer.render_xdg_surface(&self.xdg, x, y, max_width, max_height) } fn node_client(&self) -> Option> { diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 0965db63..830c7556 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -12,7 +12,7 @@ use { leaks::Tracker, object::Object, rect::Rect, - render::Renderer, + renderer::Renderer, state::State, tree::{ Direction, FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, ToplevelData, @@ -425,8 +425,15 @@ impl Node for XdgToplevel { self.xdg.find_tree_at(x, y, tree) } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { - renderer.render_xdg_surface(&self.xdg, x, y) + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + max_width: i32, + max_height: i32, + ) { + renderer.render_xdg_surface(&self.xdg, x, y, max_width, max_height) } fn node_client(&self) -> Option> { diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index ecedd8ee..924e473e 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -11,7 +11,7 @@ use { leaks::Tracker, object::Object, rect::Rect, - render::Renderer, + renderer::Renderer, tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, utils::{ bitflags::BitflagsExt, @@ -394,7 +394,14 @@ impl Node for ZwlrLayerSurfaceV1 { self.surface.find_tree_at_(x, y, tree) } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + _max_width: i32, + _max_height: i32, + ) { renderer.render_layer_surface(self, x, y); } } diff --git a/src/ifs/xdg_positioner.rs b/src/ifs/xdg_positioner.rs index 2275e43c..b2115d16 100644 --- a/src/ifs/xdg_positioner.rs +++ b/src/ifs/xdg_positioner.rs @@ -25,7 +25,7 @@ const TOP_RIGHT: u32 = 7; const BOTTOM_RIGHT: u32 = 8; bitflags::bitflags! { - #[derive(Default)] + #[derive(Copy, Clone, Default, Debug)] pub struct Edge: u32 { const TOP = 1 << 0; const BOTTOM = 1 << 1; @@ -53,7 +53,7 @@ impl Edge { } bitflags::bitflags! { - #[derive(Default)] + #[derive(Copy, Clone, Default, Debug)] pub struct CA: u32 { const NONE = 0; const SLIDE_X = 1; diff --git a/src/ifs/zwp_linux_buffer_params_v1.rs b/src/ifs/zwp_linux_buffer_params_v1.rs index 6feb0213..f75d66d0 100644 --- a/src/ifs/zwp_linux_buffer_params_v1.rs +++ b/src/ifs/zwp_linux_buffer_params_v1.rs @@ -1,10 +1,10 @@ use { crate::{ client::ClientError, + gfx_api::GfxError, ifs::{wl_buffer::WlBuffer, zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1}, leaks::Tracker, object::Object, - render::RenderError, utils::{ buffd::{MsgParser, MsgParserError}, errorfmt::ErrorFmt, @@ -228,7 +228,7 @@ pub enum ZwpLinuxBufferParamsV1Error { #[error("Plane {0} was not set")] MissingPlane(usize), #[error("Could not import the buffer")] - ImportError(#[from] RenderError), + ImportError(#[from] GfxError), } efrom!(ZwpLinuxBufferParamsV1Error, ClientError); efrom!(ZwpLinuxBufferParamsV1Error, MsgParserError); diff --git a/src/it/test_backend.rs b/src/it/test_backend.rs index df1ffbba..6d2bfa3b 100644 --- a/src/it/test_backend.rs +++ b/src/it/test_backend.rs @@ -9,8 +9,9 @@ use { }, compositor::TestFuture, fixed::Fixed, + gfx_api::GfxError, + gfx_apis::create_gfx_context, it::test_error::TestResult, - render::{RenderContext, RenderError}, state::State, time::now_usec, utils::{ @@ -33,7 +34,7 @@ pub enum TestBackendError { #[error("Could not open drm node {0}")] OpenDrmNode(String, #[source] OsError), #[error("Could not create a render context")] - RenderContext(#[source] RenderError), + RenderContext(#[source] GfxError), } pub struct TestBackend { @@ -177,11 +178,11 @@ impl TestBackend { } }; let drm = Drm::open_existing(file); - let ctx = match RenderContext::from_drm_device(&drm) { + let ctx = match create_gfx_context(&drm) { Ok(ctx) => ctx, Err(e) => return Err(TestBackendError::RenderContext(e)), }; - self.state.set_render_ctx(Some(&Rc::new(ctx))); + self.state.set_render_ctx(Some(ctx)); Ok(()) } } diff --git a/src/logind.rs b/src/logind.rs index aa2e796b..5e73f11c 100644 --- a/src/logind.rs +++ b/src/logind.rs @@ -110,7 +110,7 @@ impl Session { LOGIND_NAME, &self.session_path, org::freedesktop::login1::session::TakeDevice { major, minor }, - move |r| f(r), + f, ); } @@ -122,7 +122,7 @@ impl Session { .handle_signal::( Some(LOGIND_NAME), Some(&self.session_path), - move |v| f(v), + f, ) } @@ -154,7 +154,7 @@ impl Session { LOGIND_NAME, &self.seat, org::freedesktop::login1::seat::SwitchTo { vtnr }, - |r| f(r), + f, ); } } diff --git a/src/main.rs b/src/main.rs index 9246f5ae..bd871451 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,6 +62,8 @@ mod edid; mod fixed; mod forker; mod format; +mod gfx_api; +mod gfx_apis; mod globals; mod ifs; mod io_uring; @@ -75,7 +77,7 @@ mod pango; mod pipewire; mod portal; mod rect; -mod render; +mod renderer; mod scale; mod screenshoter; mod sighand; diff --git a/src/pipewire/pw_ifs/pw_client_node.rs b/src/pipewire/pw_ifs/pw_client_node.rs index 083832d4..d4ea482b 100644 --- a/src/pipewire/pw_ifs/pw_client_node.rs +++ b/src/pipewire/pw_ifs/pw_client_node.rs @@ -271,7 +271,7 @@ impl PwClientNode { f.write_int(-1); // n_buffers f.write_uint(buffers.len() as _); - for buffer in buffers.deref() { + for buffer in buffers { // n_datas f.write_uint(buffer.planes.len() as _); for plane in &buffer.planes { diff --git a/src/portal/ptl_display.rs b/src/portal/ptl_display.rs index f012d715..d1cd8861 100644 --- a/src/portal/ptl_display.rs +++ b/src/portal/ptl_display.rs @@ -1,11 +1,11 @@ use { crate::{ + gfx_apis::create_gfx_context, ifs::wl_seat::POINTER, portal::{ ptl_render_ctx::PortalRenderCtx, ptl_screencast::ScreencastSession, ptr_gui::WindowData, PortalState, }, - render::RenderContext, utils::{ bitflags::BitflagsExt, clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, oserror::OsError, @@ -169,7 +169,7 @@ impl UsrJayRenderCtxOwner for PortalDisplay { } if self.render_ctx.get().is_none() { let drm = Drm::open_existing(fd); - let ctx = match RenderContext::from_drm_device(&drm) { + let ctx = match create_gfx_context(&drm) { Ok(c) => c, Err(e) => { log::error!( @@ -179,10 +179,7 @@ impl UsrJayRenderCtxOwner for PortalDisplay { return; } }; - let ctx = Rc::new(PortalRenderCtx { - dev_id, - ctx: Rc::new(ctx), - }); + let ctx = Rc::new(PortalRenderCtx { dev_id, ctx }); self.render_ctx.set(Some(ctx.clone())); self.state.render_ctxs.set(dev_id, Rc::downgrade(&ctx)); } diff --git a/src/portal/ptl_render_ctx.rs b/src/portal/ptl_render_ctx.rs index f4589fdf..03fd115a 100644 --- a/src/portal/ptl_render_ctx.rs +++ b/src/portal/ptl_render_ctx.rs @@ -1,6 +1,6 @@ -use {crate::render::RenderContext, std::rc::Rc, uapi::c}; +use {crate::gfx_api::GfxContext, std::rc::Rc, uapi::c}; pub struct PortalRenderCtx { pub dev_id: c::dev_t, - pub ctx: Rc, + pub ctx: Rc, } diff --git a/src/portal/ptr_gui.rs b/src/portal/ptr_gui.rs index 19f4a9bf..b97cdd77 100644 --- a/src/portal/ptr_gui.rs +++ b/src/portal/ptr_gui.rs @@ -4,9 +4,10 @@ use { cursor::KnownCursor, fixed::Fixed, format::ARGB8888, + gfx_api::{GfxContext, GfxFramebuffer, GfxTexture}, ifs::zwlr_layer_shell_v1::OVERLAY, portal::ptl_display::{PortalDisplay, PortalOutput, PortalSeat}, - render::{Framebuffer, RenderContext, RendererBase, Texture}, + renderer::renderer_base::RendererBase, scale::Scale, text::{self, TextMeasurement}, theme::Color, @@ -49,7 +50,7 @@ pub trait GuiElement { fn data(&self) -> &GuiElementData; fn layout( &self, - ctx: &Rc, + ctx: &Rc, scale: f32, max_width: f32, max_height: f32, @@ -117,7 +118,7 @@ pub struct Button { pub bg_hover_color: Cell, pub text: RefCell, pub font: RefCell>, - pub tex: CloneCell>>, + pub tex: CloneCell>>, pub owner: CloneCell>>, } @@ -156,7 +157,7 @@ impl GuiElement for Button { fn layout( &self, - ctx: &Rc, + ctx: &Rc, scale: f32, _max_width: f32, _max_height: f32, @@ -219,6 +220,8 @@ impl GuiElement for Button { None, None, r.scale(), + i32::MAX, + i32::MAX, ); } } @@ -257,7 +260,7 @@ pub struct Label { pub data: GuiElementData, pub font: RefCell>, pub text: RefCell, - pub tex: CloneCell>>, + pub tex: CloneCell>>, } impl Default for Label { @@ -278,7 +281,7 @@ impl GuiElement for Label { fn layout( &self, - ctx: &Rc, + ctx: &Rc, scale: f32, _max_width: f32, _max_height: f32, @@ -315,6 +318,8 @@ impl GuiElement for Label { None, None, r.scale(), + i32::MAX, + i32::MAX, ); } } @@ -359,7 +364,7 @@ impl GuiElement for Flow { fn layout( &self, - ctx: &Rc, + ctx: &Rc, scale: f32, max_width: f32, max_height: f32, @@ -633,7 +638,7 @@ impl WindowData { self.have_frame.set(false); buf.free.set(false); - buf.fb.render_custom(self.scale.get(), |r| { + buf.fb.render_custom(self.scale.get(), &mut |r| { r.clear(&Color::from_gray(0)); if let Some(content) = self.content.get() { content.render_at(r, 0.0, 0.0) @@ -695,7 +700,7 @@ impl WindowData { }; let bo = match ctx .ctx - .gbm + .gbm() .create_bo(width, height, &format, GBM_BO_USE_RENDERING) { Ok(b) => b, @@ -704,7 +709,7 @@ impl WindowData { return; } }; - let img = match ctx.ctx.dmabuf_img(bo.dmabuf()) { + let img = match ctx.ctx.clone().dmabuf_img(bo.dmabuf()) { Ok(b) => b, Err(e) => { log::error!("Could not import dmabuf into EGL: {}", ErrorFmt(e)); @@ -809,14 +814,14 @@ impl WindowData { pub struct GuiBuffer { pub wl: Rc, pub window: Rc, - pub fb: Rc, + pub fb: Rc, pub free: Cell, pub size: (i32, i32), } struct GuiBufferPending { pub window: Rc, - pub fb: Rc, + pub fb: Rc, pub params: Rc, pub size: (i32, i32), } diff --git a/src/render.rs b/src/render.rs deleted file mode 100644 index 92ee0b2f..00000000 --- a/src/render.rs +++ /dev/null @@ -1,99 +0,0 @@ -macro_rules! egl_transparent { - ($name:ident) => { - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - #[repr(transparent)] - pub struct $name(pub *mut u8); - - impl $name { - #[allow(dead_code)] - pub const fn none() -> Self { - Self(std::ptr::null_mut()) - } - - #[allow(dead_code)] - pub fn is_none(self) -> bool { - self.0.is_null() - } - } - }; -} - -pub use renderer::*; -use { - crate::video::{drm::DrmError, gbm::GbmError}, - thiserror::Error, -}; - -mod egl; -mod ext; -mod gl; -mod proc; -mod renderer; - -pub mod sys { - pub use super::{egl::sys::*, gl::sys::*}; -} - -pub fn init() -> Result<(), RenderError> { - egl::init() -} - -#[derive(Debug, Error)] -pub enum RenderError { - #[error("EGL library does not support `EGL_EXT_platform_base`")] - ExtPlatformBase, - #[error("Could not compile a shader")] - ShaderCompileFailed, - #[error("Could not link a program")] - ProgramLink, - #[error("Could not bind to `EGL_OPENGL_ES_API`")] - BindFailed, - #[error("EGL library does not support the GBM platform")] - GbmExt, - #[error("Could not create a GBM device")] - Gbm(#[source] GbmError), - #[error("`eglCreateContext` failed")] - CreateContext, - #[error("`eglMakeCurrent` failed")] - MakeCurrent, - #[error("`eglCreateImageKHR` failed")] - CreateImage, - #[error("Image buffer is too small")] - SmallImageBuffer, - #[error("Binding a renderbuffer to a framebuffer failed")] - CreateFramebuffer, - #[error("`eglGetPlatformDisplayEXT` failed")] - GetDisplay, - #[error("`eglInitialize` failed")] - Initialize, - #[error("EGL display does not support `EGL_EXT_image_dma_buf_import_modifiers`")] - DmaBufImport, - #[error("GLES driver does not support `GL_OES_EGL_image`")] - OesEglImage, - #[error("EGL display does not support `EGL_KHR_image_base`")] - ImageBase, - #[error( - "EGL display does not support `EGL_KHR_no_config_context` or `EGL_MESA_configless_context`" - )] - ConfiglessContext, - #[error("EGL display does not support `EGL_KHR_surfaceless_context`")] - SurfacelessContext, - #[error("`eglQueryDmaBufFormatsEXT` failed")] - QueryDmaBufFormats, - #[error("`eglQueryDmaBufModifiersEXT` failed")] - QueryDmaBufModifiers, - #[error(transparent)] - DrmError(#[from] DrmError), - #[error("The GLES driver does not support the XRGB8888 format")] - XRGB888, - #[error("The DRM device does not have a render node")] - NoRenderNode, - #[error("The requested format is not supported")] - UnsupportedFormat, - #[error("The requested modifier is not supported")] - UnsupportedModifier, - #[error("Image is external only and cannot be rendered to")] - ExternalOnly, - #[error("OpenGL context does not support external textures")] - ExternalUnsupported, -} diff --git a/src/render/gl/frame_buffer.rs b/src/render/gl/frame_buffer.rs deleted file mode 100644 index 7c5cad83..00000000 --- a/src/render/gl/frame_buffer.rs +++ /dev/null @@ -1,62 +0,0 @@ -use { - crate::{ - rect::Rect, - render::{ - egl::context::EglContext, - gl::{ - render_buffer::GlRenderBuffer, - sys::{glDeleteFramebuffers, GLuint}, - texture::GlTexture, - }, - sys::{glDisable, glEnable, glScissor, GL_SCISSOR_TEST}, - }, - utils::ptr_ext::PtrExt, - }, - std::{ptr, rc::Rc}, -}; - -pub struct GlFrameBuffer { - pub _rb: Option>, - pub _tex: Option>, - pub ctx: Rc, - pub width: i32, - pub height: i32, - pub fbo: GLuint, -} - -impl Drop for GlFrameBuffer { - fn drop(&mut self) { - let _ = self.ctx.with_current(|| { - unsafe { - glDeleteFramebuffers(1, &self.fbo); - } - Ok(()) - }); - } -} - -pub unsafe fn with_scissor T>(scissor: &Rect, f: F) -> T { - #[thread_local] - static mut SCISSOR: *const Rect = ptr::null(); - - let prev = SCISSOR; - if prev.is_null() { - glEnable(GL_SCISSOR_TEST); - } - glScissor( - scissor.x1(), - scissor.y1(), - scissor.width(), - scissor.height(), - ); - SCISSOR = scissor; - let res = f(); - if prev.is_null() { - glDisable(GL_SCISSOR_TEST); - } else { - let prev = prev.deref(); - glScissor(prev.x1(), prev.y1(), prev.width(), prev.height()); - } - SCISSOR = prev; - res -} diff --git a/src/render/renderer.rs b/src/render/renderer.rs deleted file mode 100644 index a1e4320f..00000000 --- a/src/render/renderer.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub use {context::*, framebuffer::*, image::*, renderer::*, renderer_base::*, texture::*}; - -mod context; -mod framebuffer; -mod image; -mod renderer; -mod renderer_base; -mod texture; diff --git a/src/render/renderer/framebuffer.rs b/src/render/renderer/framebuffer.rs deleted file mode 100644 index af163016..00000000 --- a/src/render/renderer/framebuffer.rs +++ /dev/null @@ -1,243 +0,0 @@ -use { - crate::{ - cursor::Cursor, - fixed::Fixed, - format::{Format, ARGB8888, XRGB8888}, - rect::Rect, - render::{ - gl::{ - frame_buffer::GlFrameBuffer, - sys::{ - glBindFramebuffer, glClear, glClearColor, glViewport, GL_COLOR_BUFFER_BIT, - GL_FRAMEBUFFER, - }, - }, - renderer::{context::RenderContext, renderer::Renderer, renderer_base::RendererBase}, - sys::{glBlendFunc, glFlush, glReadnPixels, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, - RenderResult, Texture, - }, - scale::Scale, - state::State, - tree::Node, - }, - std::{ - cell::Cell, - fmt::{Debug, Formatter}, - rc::Rc, - }, -}; - -pub struct Framebuffer { - pub(super) ctx: Rc, - pub(super) gl: GlFrameBuffer, -} - -impl Debug for Framebuffer { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Framebuffer").finish_non_exhaustive() - } -} - -impl Framebuffer { - pub fn clear(&self) { - self.clear_with(0.0, 0.0, 0.0, 0.0); - } - - pub fn clear_with(&self, r: f32, g: f32, b: f32, a: f32) { - let _ = self.ctx.ctx.with_current(|| { - unsafe { - glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); - glViewport(0, 0, self.gl.width, self.gl.height); - glClearColor(r, g, b, a); - glClear(GL_COLOR_BUFFER_BIT); - } - Ok(()) - }); - } - - pub fn copy_texture(&self, state: &State, texture: &Texture, x: i32, y: i32, alpha: bool) { - let _ = self.ctx.ctx.with_current(|| { - unsafe { - glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); - glViewport(0, 0, self.gl.width, self.gl.height); - if alpha { - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - } - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - let scale = Scale::from_int(1); - let mut renderer = Renderer { - base: RendererBase { - ctx: &self.ctx, - fb: &self.gl, - scaled: false, - scale, - scalef: 1.0, - }, - state, - on_output: false, - result: &mut RenderResult::default(), - logical_extents: Rect::new_sized(0, 0, self.gl.width, self.gl.height).unwrap(), - }; - let format = match alpha { - true => ARGB8888, - false => XRGB8888, - }; - renderer - .base - .render_texture(texture, x, y, format, None, None, scale); - unsafe { - glFlush(); - } - Ok(()) - }); - } - - pub fn copy_to_shm( - &self, - x: i32, - y: i32, - width: i32, - height: i32, - format: &Format, - shm: &[Cell], - ) { - let y = self.gl.height - y - height; - let _ = self.ctx.ctx.with_current(|| { - unsafe { - glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); - glViewport(0, 0, self.gl.width, self.gl.height); - glReadnPixels( - x, - y, - width, - height, - format.gl_format as _, - format.gl_type as _, - shm.len() as _, - shm.as_ptr() as _, - ); - } - Ok(()) - }); - } - - pub fn render_custom(&self, scale: Scale, f: impl FnOnce(&mut RendererBase)) { - let _ = self.ctx.ctx.with_current(|| { - unsafe { - glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); - glViewport(0, 0, self.gl.width, self.gl.height); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - let mut renderer = RendererBase { - ctx: &self.ctx, - fb: &self.gl, - scaled: scale != 1, - scale, - scalef: scale.to_f64(), - }; - f(&mut renderer); - unsafe { - glFlush(); - } - Ok(()) - }); - } - - pub fn render( - &self, - node: &dyn Node, - state: &State, - cursor_rect: Option, - on_output: bool, - result: &mut RenderResult, - scale: Scale, - render_hardware_cursor: bool, - ) { - let _ = self.ctx.ctx.with_current(|| { - let c = state.theme.colors.background.get(); - unsafe { - glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); - glViewport(0, 0, self.gl.width, self.gl.height); - glClearColor(c.r, c.g, c.b, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - let mut renderer = Renderer { - base: RendererBase { - ctx: &self.ctx, - fb: &self.gl, - scaled: scale != 1, - scale, - scalef: scale.to_f64(), - }, - state, - on_output, - result, - logical_extents: node.node_absolute_position().at_point(0, 0), - }; - node.node_render(&mut renderer, 0, 0); - if let Some(rect) = cursor_rect { - let seats = state.globals.lock_seats(); - for seat in seats.values() { - if !render_hardware_cursor && seat.hardware_cursor() { - continue; - } - if let Some(cursor) = seat.get_cursor() { - let (mut x, mut y) = seat.get_position(); - if let Some(dnd_icon) = seat.dnd_icon() { - let extents = dnd_icon.extents.get().move_( - x.round_down() + dnd_icon.buf_x.get(), - y.round_down() + dnd_icon.buf_y.get(), - ); - if extents.intersects(&rect) { - let (x, y) = rect.translate(extents.x1(), extents.y1()); - renderer.render_surface(&dnd_icon, x, y); - } - } - cursor.tick(); - x -= Fixed::from_int(rect.x1()); - y -= Fixed::from_int(rect.y1()); - cursor.render(&mut renderer, x, y); - } - } - } - unsafe { - glFlush(); - } - Ok(()) - }); - } - - pub fn render_hardware_cursor(&self, cursor: &dyn Cursor, state: &State, scale: Scale) { - let _ = self.ctx.ctx.with_current(|| { - unsafe { - glBindFramebuffer(GL_FRAMEBUFFER, self.gl.fbo); - glViewport(0, 0, self.gl.width, self.gl.height); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - let mut res = RenderResult::default(); - let mut renderer = Renderer { - base: RendererBase { - ctx: &self.ctx, - fb: &self.gl, - scaled: scale != 1, - scale, - scalef: scale.to_f64(), - }, - state, - on_output: false, - result: &mut res, - logical_extents: Rect::new_empty(0, 0), - }; - cursor.render_hardware_cursor(&mut renderer); - unsafe { - glFlush(); - } - Ok(()) - }); - } -} diff --git a/src/render/renderer/image.rs b/src/render/renderer/image.rs deleted file mode 100644 index 6156fbea..00000000 --- a/src/render/renderer/image.rs +++ /dev/null @@ -1,41 +0,0 @@ -use { - crate::render::{ - egl::image::EglImage, - gl::{render_buffer::GlRenderBuffer, texture::GlTexture}, - Framebuffer, RenderContext, RenderError, Texture, - }, - std::rc::Rc, -}; - -pub struct Image { - pub(super) ctx: Rc, - pub(super) gl: Rc, -} - -impl Image { - pub fn width(&self) -> i32 { - self.gl.width - } - - pub fn height(&self) -> i32 { - self.gl.height - } - - pub fn to_texture(self: &Rc) -> Result, RenderError> { - Ok(Rc::new(Texture { - ctx: self.ctx.clone(), - gl: GlTexture::import_img(&self.ctx.ctx, &self.gl)?, - })) - } - - pub fn to_framebuffer(&self) -> Result, RenderError> { - self.ctx.ctx.with_current(|| unsafe { - let rb = GlRenderBuffer::from_image(&self.gl, &self.ctx.ctx)?; - let fb = rb.create_framebuffer()?; - Ok(Rc::new(Framebuffer { - ctx: self.ctx.clone(), - gl: fb, - })) - }) - } -} diff --git a/src/render/renderer/renderer_base.rs b/src/render/renderer/renderer_base.rs deleted file mode 100644 index 5d04396f..00000000 --- a/src/render/renderer/renderer_base.rs +++ /dev/null @@ -1,282 +0,0 @@ -use { - crate::{ - format::Format, - rect::Rect, - render::{ - gl::{ - frame_buffer::GlFrameBuffer, - sys::{ - glActiveTexture, glBindTexture, glDisableVertexAttribArray, glDrawArrays, - glEnableVertexAttribArray, glTexParameteri, glUniform1i, glUniform4f, - glUseProgram, glVertexAttribPointer, GL_FALSE, GL_FLOAT, GL_LINEAR, - GL_TEXTURE0, GL_TEXTURE_MIN_FILTER, GL_TRIANGLES, GL_TRIANGLE_STRIP, - }, - texture::image_target, - }, - renderer::context::RenderContext, - sys::{glClear, glClearColor, glDisable, glEnable, GL_BLEND, GL_COLOR_BUFFER_BIT}, - Texture, - }, - scale::Scale, - theme::Color, - utils::rc_eq::rc_eq, - }, - std::rc::Rc, -}; - -pub struct RendererBase<'a> { - pub(super) ctx: &'a Rc, - pub(super) fb: &'a GlFrameBuffer, - pub(super) scaled: bool, - pub(super) scale: Scale, - pub(super) scalef: f64, -} - -impl RendererBase<'_> { - pub fn scale(&self) -> Scale { - self.scale - } - - pub fn physical_extents(&self) -> Rect { - Rect::new_sized(0, 0, self.fb.width, self.fb.height).unwrap() - } - - pub fn scale_point(&self, mut x: i32, mut y: i32) -> (i32, i32) { - if self.scaled { - x = (x as f64 * self.scalef).round() as _; - y = (y as f64 * self.scalef).round() as _; - } - (x, y) - } - - pub fn scale_point_f(&self, mut x: f32, mut y: f32) -> (f32, f32) { - if self.scaled { - x = (x as f64 * self.scalef) as _; - y = (y as f64 * self.scalef) as _; - } - (x, y) - } - - pub fn scale_rect(&self, mut rect: Rect) -> Rect { - if self.scaled { - let x1 = (rect.x1() as f64 * self.scalef).round() as _; - let y1 = (rect.y1() as f64 * self.scalef).round() as _; - let x2 = (rect.x2() as f64 * self.scalef).round() as _; - let y2 = (rect.y2() as f64 * self.scalef).round() as _; - rect = Rect::new(x1, y1, x2, y2).unwrap(); - } - rect - } - - pub fn scale_rect_f(&self, mut rect: (f32, f32, f32, f32)) -> (f32, f32, f32, f32) { - if self.scaled { - let x1 = (rect.0 as f64 * self.scalef).round() as _; - let y1 = (rect.1 as f64 * self.scalef).round() as _; - let x2 = (rect.2 as f64 * self.scalef).round() as _; - let y2 = (rect.3 as f64 * self.scalef).round() as _; - rect = (x1, y1, x2, y2) - } - rect - } - - fn xf_to_f(&self, x: f32) -> f32 { - 2.0 * (x / self.fb.width as f32) - 1.0 - } - - fn yf_to_f(&self, y: f32) -> f32 { - 2.0 * (y / self.fb.height as f32) - 1.0 - } - - fn x_to_f(&self, x: i32) -> f32 { - 2.0 * (x as f32 / self.fb.width as f32) - 1.0 - } - - fn y_to_f(&self, y: i32) -> f32 { - 2.0 * (y as f32 / self.fb.height as f32) - 1.0 - } - - pub fn clear(&self, c: &Color) { - unsafe { - glClearColor(c.r, c.g, c.b, c.a); - glClear(GL_COLOR_BUFFER_BIT); - } - } - - pub fn fill_boxes(&self, boxes: &[Rect], color: &Color) { - self.fill_boxes2(boxes, color, 0, 0); - } - - pub fn fill_boxes2(&self, boxes: &[Rect], color: &Color, dx: i32, dy: i32) { - if boxes.is_empty() { - return; - } - let (dx, dy) = self.scale_point(dx, dy); - let mut pos = Vec::with_capacity(boxes.len() * 12); - for bx in boxes { - let bx = self.scale_rect(*bx); - let x1 = self.x_to_f(bx.x1() + dx); - let y1 = self.y_to_f(bx.y1() + dy); - let x2 = self.x_to_f(bx.x2() + dx); - let y2 = self.y_to_f(bx.y2() + dy); - pos.extend_from_slice(&[ - // triangle 1 - x2, y1, // top right - x1, y1, // top left - x1, y2, // bottom left - // triangle 2 - x2, y1, // top right - x1, y2, // bottom left - x2, y2, // bottom right - ]); - } - self.fill_boxes3(&pos, color) - } - - pub fn fill_boxes_f(&self, boxes: &[(f32, f32, f32, f32)], color: &Color) { - self.fill_boxes2_f(boxes, color, 0.0, 0.0); - } - - pub fn fill_boxes2_f(&self, boxes: &[(f32, f32, f32, f32)], color: &Color, dx: f32, dy: f32) { - if boxes.is_empty() { - return; - } - let (dx, dy) = self.scale_point_f(dx, dy); - let mut pos = Vec::with_capacity(boxes.len() * 12); - for bx in boxes { - let (x1, y1, x2, y2) = self.scale_rect_f(*bx); - let x1 = self.xf_to_f(x1 + dx); - let y1 = self.yf_to_f(y1 + dy); - let x2 = self.xf_to_f(x2 + dx); - let y2 = self.yf_to_f(y2 + dy); - pos.extend_from_slice(&[ - // triangle 1 - x2, y1, // top right - x1, y1, // top left - x1, y2, // bottom left - // triangle 2 - x2, y1, // top right - x1, y2, // bottom left - x2, y2, // bottom right - ]); - } - self.fill_boxes3(&pos, color) - } - - fn fill_boxes3(&self, boxes: &[f32], color: &Color) { - unsafe { - glUseProgram(self.ctx.fill_prog.prog); - glUniform4f(self.ctx.fill_prog_color, color.r, color.g, color.b, color.a); - glVertexAttribPointer( - self.ctx.fill_prog_pos as _, - 2, - GL_FLOAT, - GL_FALSE, - 0, - boxes.as_ptr() as _, - ); - glEnableVertexAttribArray(self.ctx.fill_prog_pos as _); - glDrawArrays(GL_TRIANGLES, 0, (boxes.len() / 2) as _); - glDisableVertexAttribArray(self.ctx.fill_prog_pos as _); - } - } - - pub fn render_texture( - &mut self, - texture: &Texture, - x: i32, - y: i32, - format: &Format, - tpoints: Option<&[f32; 8]>, - tsize: Option<(i32, i32)>, - tscale: Scale, - ) { - assert!(rc_eq(&self.ctx.ctx, &texture.ctx.ctx)); - unsafe { - glActiveTexture(GL_TEXTURE0); - - let target = image_target(texture.gl.external_only); - - glBindTexture(target, texture.gl.tex); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - let progs = match texture.gl.external_only { - true => match &self.ctx.tex_external { - Some(p) => p, - _ => { - log::error!("Trying to render an external-only texture but context does not support the required extension"); - return; - } - }, - false => &self.ctx.tex_internal, - }; - let prog = match format.has_alpha { - true => { - glEnable(GL_BLEND); - &progs.alpha - } - false => { - glDisable(GL_BLEND); - &progs.solid - } - }; - - glUseProgram(prog.prog.prog); - - glUniform1i(prog.tex, 0); - - static DEFAULT_TEXCOORD: [f32; 8] = [1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0]; - - let texcoord: &[f32; 8] = match tpoints { - None => &DEFAULT_TEXCOORD, - Some(tp) => tp, - }; - - let f_width = self.fb.width as f32; - let f_height = self.fb.height as f32; - - let (twidth, theight) = if let Some(size) = tsize { - size - } else { - let (mut w, mut h) = (texture.gl.width, texture.gl.height); - if tscale != self.scale { - let tscale = tscale.to_f64(); - w = (w as f64 * self.scalef / tscale).round() as _; - h = (h as f64 * self.scalef / tscale).round() as _; - } - (w, h) - }; - - let x1 = 2.0 * (x as f32 / f_width) - 1.0; - let y1 = 2.0 * (y as f32 / f_height) - 1.0; - let x2 = 2.0 * ((x + twidth) as f32 / f_width) - 1.0; - let y2 = 2.0 * ((y + theight) as f32 / f_height) - 1.0; - - let pos: [f32; 8] = [ - x2, y1, // top right - x1, y1, // top left - x2, y2, // bottom right - x1, y2, // bottom left - ]; - - glVertexAttribPointer( - prog.texcoord as _, - 2, - GL_FLOAT, - GL_FALSE, - 0, - texcoord.as_ptr() as _, - ); - glVertexAttribPointer(prog.pos as _, 2, GL_FLOAT, GL_FALSE, 0, pos.as_ptr() as _); - - glEnableVertexAttribArray(prog.texcoord as _); - glEnableVertexAttribArray(prog.pos as _); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glDisableVertexAttribArray(prog.texcoord as _); - glDisableVertexAttribArray(prog.pos as _); - - glBindTexture(target, 0); - } - } -} diff --git a/src/render/renderer/texture.rs b/src/render/renderer/texture.rs deleted file mode 100644 index 9ac815f2..00000000 --- a/src/render/renderer/texture.rs +++ /dev/null @@ -1,28 +0,0 @@ -use { - crate::render::{gl::texture::GlTexture, renderer::context::RenderContext}, - std::{ - fmt::{Debug, Formatter}, - rc::Rc, - }, -}; - -pub struct Texture { - pub(super) ctx: Rc, - pub(super) gl: GlTexture, -} - -impl Debug for Texture { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Texture").finish_non_exhaustive() - } -} - -impl Texture { - pub fn width(&self) -> i32 { - self.gl.width - } - - pub fn height(&self) -> i32 { - self.gl.height - } -} diff --git a/src/render/renderer/renderer.rs b/src/renderer.rs similarity index 77% rename from src/render/renderer/renderer.rs rename to src/renderer.rs index 2a29e6e6..69f9a0b6 100644 --- a/src/render/renderer/renderer.rs +++ b/src/renderer.rs @@ -1,6 +1,7 @@ use { crate::{ format::ARGB8888, + gfx_api::{BufferPoints, GfxApiOpt}, ifs::{ wl_buffer::WlBuffer, wl_callback::WlCallback, @@ -10,7 +11,7 @@ use { wp_presentation_feedback::WpPresentationFeedback, }, rect::Rect, - render::{gl::frame_buffer::with_scissor, renderer::renderer_base::RendererBase}, + renderer::renderer_base::RendererBase, scale::Scale, state::State, theme::Color, @@ -27,6 +28,8 @@ use { }, }; +pub mod renderer_base; + #[derive(Default)] pub struct RenderResult { pub frame_requests: Vec>, @@ -41,10 +44,11 @@ impl Debug for RenderResult { pub struct Renderer<'a> { pub base: RendererBase<'a>, - pub(super) state: &'a State, - pub(super) on_output: bool, - pub(super) result: &'a mut RenderResult, - pub(super) logical_extents: Rect, + pub state: &'a State, + pub on_output: bool, + pub result: &'a mut RenderResult, + pub logical_extents: Rect, + pub physical_extents: Rect, } impl Renderer<'_> { @@ -53,7 +57,7 @@ impl Renderer<'_> { } pub fn physical_extents(&self) -> Rect { - self.base.physical_extents() + self.physical_extents } pub fn logical_extents(&self) -> Rect { @@ -74,7 +78,7 @@ impl Renderer<'_> { if self.state.lock.locked.get() { if let Some(surface) = output.lock_surface.get() { if surface.surface.buffer.get().is_some() { - self.render_surface(&surface.surface, x, y); + self.render_surface(&surface.surface, x, y, i32::MAX, i32::MAX); } } return; @@ -94,7 +98,7 @@ impl Renderer<'_> { } if let Some(ws) = output.workspace.get() { if let Some(fs) = ws.fullscreen.get() { - fs.tl_as_node().node_render(self, x, y); + fs.tl_as_node().node_render(self, x, y, i32::MAX, i32::MAX); render_layer!(output.layers[2]); render_layer!(output.layers[3]); return; @@ -136,13 +140,31 @@ impl Renderer<'_> { let scale = output.preferred_scale.get(); for title in &rd.titles { let (x, y) = self.base.scale_point(x + title.tex_x, y + title.tex_y); - self.base - .render_texture(&title.tex, x, y, ARGB8888, None, None, scale); + self.base.render_texture( + &title.tex, + x, + y, + ARGB8888, + None, + None, + scale, + i32::MAX, + i32::MAX, + ); } if let Some(status) = &rd.status { let (x, y) = self.base.scale_point(x + status.tex_x, y + status.tex_y); - self.base - .render_texture(&status.tex, x, y, ARGB8888, None, None, scale); + self.base.render_texture( + &status.tex, + x, + y, + ARGB8888, + None, + None, + scale, + i32::MAX, + i32::MAX, + ); } } if let Some(ws) = output.workspace.get() { @@ -150,10 +172,11 @@ impl Renderer<'_> { } for stacked in self.state.root.stacked.iter() { if stacked.node_visible() { + self.base.ops.push(GfxApiOpt::Sync); let pos = stacked.node_absolute_position(); if pos.intersects(&opos) { let (x, y) = opos.translate(pos.x1(), pos.y1()); - stacked.node_render(self, x, y); + stacked.node_render(self, x, y, i32::MAX, i32::MAX); } } } @@ -176,8 +199,17 @@ impl Renderer<'_> { if let Some(tex) = placeholder.textures.get(&self.base.scale) { let x = x + (pos.width() - tex.width()) / 2; let y = y + (pos.height() - tex.height()) / 2; - self.base - .render_texture(&tex, x, y, ARGB8888, None, None, self.base.scale); + self.base.render_texture( + &tex, + x, + y, + ARGB8888, + None, + None, + self.base.scale, + i32::MAX, + i32::MAX, + ); } } @@ -212,21 +244,23 @@ impl Renderer<'_> { None, None, self.base.scale, + i32::MAX, + i32::MAX, ); } } } if let Some(child) = container.mono_child.get() { - unsafe { - let body = container.mono_body.get().move_(x, y); - let body = self.base.scale_rect(body); - with_scissor(&body, || { - let content = container.mono_content.get(); - child - .node - .node_render(self, x + content.x1(), y + content.y1()); - }); - } + let body = container.mono_body.get().move_(x, y); + let body = self.base.scale_rect(body); + let content = container.mono_content.get(); + child.node.node_render( + self, + x + content.x1(), + y + content.y1(), + body.width(), + body.height(), + ); } else { for child in container.children.iter() { let body = child.body.get(); @@ -235,31 +269,45 @@ impl Renderer<'_> { } let body = body.move_(x, y); let body = self.base.scale_rect(body); - unsafe { - with_scissor(&body, || { - let content = child.content.get(); - child - .node - .node_render(self, x + content.x1(), y + content.y1()); - }); - } + let content = child.content.get(); + child.node.node_render( + self, + x + content.x1(), + y + content.y1(), + body.width(), + body.height(), + ); } } } - pub fn render_xdg_surface(&mut self, xdg: &XdgSurface, mut x: i32, mut y: i32) { + pub fn render_xdg_surface( + &mut self, + xdg: &XdgSurface, + mut x: i32, + mut y: i32, + max_width: i32, + max_height: i32, + ) { let surface = &xdg.surface; if let Some(geo) = xdg.geometry() { let (xt, yt) = geo.translate(x, y); x = xt; y = yt; } - self.render_surface(surface, x, y); + self.render_surface(surface, x, y, max_width, max_height); } - pub fn render_surface(&mut self, surface: &WlSurface, x: i32, y: i32) { + pub fn render_surface( + &mut self, + surface: &WlSurface, + x: i32, + y: i32, + max_width: i32, + max_height: i32, + ) { let (x, y) = self.base.scale_point(x, y); - self.render_surface_scaled(surface, x, y, None); + self.render_surface_scaled(surface, x, y, None, max_width, max_height); } pub fn render_surface_scaled( @@ -268,6 +316,8 @@ impl Renderer<'_> { x: i32, y: i32, pos_rel: Option<(i32, i32)>, + max_width: i32, + max_height: i32, ) { let children = surface.children.borrow(); let buffer = match surface.buffer.get() { @@ -302,15 +352,17 @@ impl Renderer<'_> { x + x1, y + y1, Some((pos.x1(), pos.y1())), + max_width, + max_height, ); } }; } render!(&children.below); - self.render_buffer(&buffer, x, y, &tpoints, size); + self.render_buffer(&buffer, x, y, *tpoints, size, max_width, max_height); render!(&children.above); } else { - self.render_buffer(&buffer, x, y, &tpoints, size); + self.render_buffer(&buffer, x, y, *tpoints, size, max_width, max_height); } if self.on_output { { @@ -329,8 +381,10 @@ impl Renderer<'_> { buffer: &WlBuffer, x: i32, y: i32, - tpoints: &[f32; 8], + tpoints: BufferPoints, tsize: (i32, i32), + max_width: i32, + max_height: i32, ) { if let Some(tex) = buffer.texture.get() { self.base.render_texture( @@ -341,6 +395,8 @@ impl Renderer<'_> { Some(tpoints), Some(tsize), self.base.scale, + max_width, + max_height, ); } } @@ -374,8 +430,17 @@ impl Renderer<'_> { self.base.fill_boxes(&title_underline, &uc); if let Some(title) = floating.title_textures.get(&self.base.scale) { let (x, y) = self.base.scale_point(x + bw, y + bw); - self.base - .render_texture(&title, x, y, ARGB8888, None, None, self.base.scale); + self.base.render_texture( + &title, + x, + y, + ARGB8888, + None, + None, + self.base.scale, + i32::MAX, + i32::MAX, + ); } let body = Rect::new_sized( x + bw, @@ -385,20 +450,18 @@ impl Renderer<'_> { ) .unwrap(); let scissor_body = self.base.scale_rect(body); - unsafe { - with_scissor(&scissor_body, || { - child.node_render(self, body.x1(), body.y1()); - }); - } + child.node_render( + self, + body.x1(), + body.y1(), + scissor_body.width(), + scissor_body.height(), + ); } pub fn render_layer_surface(&mut self, surface: &ZwlrLayerSurfaceV1, x: i32, y: i32) { - unsafe { - let body = surface.position().at_point(x, y); - let body = self.base.scale_rect(body); - with_scissor(&body, || { - self.render_surface(&surface.surface, x, y); - }); - } + let body = surface.position().at_point(x, y); + let body = self.base.scale_rect(body); + self.render_surface(&surface.surface, x, y, body.width(), body.height()); } } diff --git a/src/renderer/renderer_base.rs b/src/renderer/renderer_base.rs new file mode 100644 index 00000000..6d022d30 --- /dev/null +++ b/src/renderer/renderer_base.rs @@ -0,0 +1,199 @@ +use { + crate::{ + format::Format, + gfx_api::{ + AbsoluteRect, BufferPoint, BufferPoints, Clear, CopyTexture, FillRect, GfxApiOpt, + GfxTexture, + }, + rect::Rect, + scale::Scale, + theme::Color, + }, + std::rc::Rc, +}; + +pub struct RendererBase<'a> { + pub ops: &'a mut Vec, + pub scaled: bool, + pub scale: Scale, + pub scalef: f64, +} + +impl RendererBase<'_> { + pub fn scale(&self) -> Scale { + self.scale + } + + pub fn scale_point(&self, mut x: i32, mut y: i32) -> (i32, i32) { + if self.scaled { + x = (x as f64 * self.scalef).round() as _; + y = (y as f64 * self.scalef).round() as _; + } + (x, y) + } + + pub fn scale_point_f(&self, mut x: f32, mut y: f32) -> (f32, f32) { + if self.scaled { + x = (x as f64 * self.scalef) as _; + y = (y as f64 * self.scalef) as _; + } + (x, y) + } + + pub fn scale_rect(&self, mut rect: Rect) -> Rect { + if self.scaled { + let x1 = (rect.x1() as f64 * self.scalef).round() as _; + let y1 = (rect.y1() as f64 * self.scalef).round() as _; + let x2 = (rect.x2() as f64 * self.scalef).round() as _; + let y2 = (rect.y2() as f64 * self.scalef).round() as _; + rect = Rect::new(x1, y1, x2, y2).unwrap(); + } + rect + } + + pub fn scale_rect_f(&self, mut rect: (f32, f32, f32, f32)) -> (f32, f32, f32, f32) { + if self.scaled { + let x1 = (rect.0 as f64 * self.scalef).round() as _; + let y1 = (rect.1 as f64 * self.scalef).round() as _; + let x2 = (rect.2 as f64 * self.scalef).round() as _; + let y2 = (rect.3 as f64 * self.scalef).round() as _; + rect = (x1, y1, x2, y2) + } + rect + } + + pub fn clear(&mut self, c: &Color) { + self.ops.push(GfxApiOpt::Clear(Clear { color: *c })) + } + + pub fn fill_boxes(&mut self, boxes: &[Rect], color: &Color) { + self.fill_boxes2(boxes, color, 0, 0); + } + + pub fn fill_boxes2(&mut self, boxes: &[Rect], color: &Color, dx: i32, dy: i32) { + if boxes.is_empty() { + return; + } + let (dx, dy) = self.scale_point(dx, dy); + for bx in boxes { + let bx = self.scale_rect(*bx); + self.ops.push(GfxApiOpt::FillRect(FillRect { + rect: AbsoluteRect { + x1: (bx.x1() + dx) as f32, + y1: (bx.y1() + dy) as f32, + x2: (bx.x2() + dx) as f32, + y2: (bx.y2() + dy) as f32, + }, + color: *color, + })); + } + } + + pub fn fill_boxes_f(&mut self, boxes: &[(f32, f32, f32, f32)], color: &Color) { + self.fill_boxes2_f(boxes, color, 0.0, 0.0); + } + + pub fn fill_boxes2_f( + &mut self, + boxes: &[(f32, f32, f32, f32)], + color: &Color, + dx: f32, + dy: f32, + ) { + if boxes.is_empty() { + return; + } + let (dx, dy) = self.scale_point_f(dx, dy); + for bx in boxes { + let (x1, y1, x2, y2) = self.scale_rect_f(*bx); + self.ops.push(GfxApiOpt::FillRect(FillRect { + rect: AbsoluteRect { + x1: x1 + dx, + y1: y1 + dy, + x2: x2 + dx, + y2: y2 + dy, + }, + color: *color, + })); + } + } + + pub fn render_texture( + &mut self, + texture: &Rc, + x: i32, + y: i32, + format: &'static Format, + tpoints: Option, + tsize: Option<(i32, i32)>, + tscale: Scale, + max_width: i32, + max_height: i32, + ) { + let mut texcoord = tpoints.unwrap_or(BufferPoints { + top_left: BufferPoint { x: 0.0, y: 0.0 }, + top_right: BufferPoint { x: 1.0, y: 0.0 }, + bottom_left: BufferPoint { x: 0.0, y: 1.0 }, + bottom_right: BufferPoint { x: 1.0, y: 1.0 }, + }); + + let (twidth, theight) = if let Some(size) = tsize { + size + } else { + let (mut w, mut h) = (texture.width(), texture.height()); + if tscale != self.scale { + let tscale = tscale.to_f64(); + w = (w as f64 * self.scalef / tscale).round() as _; + h = (h as f64 * self.scalef / tscale).round() as _; + } + (w, h) + }; + + macro_rules! clamp { + ($desired:ident, $max:ident, $([$far:ident, $near:ident]),*) => { + if $desired > $max { + let $desired = $desired as f32; + let $max = $max as f32; + let factor = $max / $desired; + $( + let dx = (texcoord.$far.x - texcoord.$near.x) * factor; + texcoord.$far.x = texcoord.$near.x + dx; + let dy = (texcoord.$far.y - texcoord.$near.y) * factor; + texcoord.$far.y = texcoord.$near.y + dy; + )* + $max + } else { + $desired as f32 + } + }; + } + + let twidth = clamp!( + twidth, + max_width, + [top_right, top_left], + [bottom_right, bottom_left] + ); + let theight = clamp!( + theight, + max_height, + [bottom_left, top_left], + [bottom_right, top_right] + ); + + let x = x as f32; + let y = y as f32; + + self.ops.push(GfxApiOpt::CopyTexture(CopyTexture { + tex: texture.clone(), + format, + source: texcoord, + target: AbsoluteRect { + x1: x, + y1: y, + x2: x + twidth, + y2: y + theight, + }, + })); + } +} diff --git a/src/screenshoter.rs b/src/screenshoter.rs index c1c740ac..2fea0a97 100644 --- a/src/screenshoter.rs +++ b/src/screenshoter.rs @@ -1,7 +1,7 @@ use { crate::{ format::XRGB8888, - render::RenderError, + gfx_api::GfxError, scale::Scale, state::State, video::{ @@ -24,7 +24,7 @@ pub enum ScreenshooterError { #[error(transparent)] GbmError(#[from] GbmError), #[error(transparent)] - RenderError(#[from] RenderError), + RenderError(#[from] GfxError), #[error(transparent)] DrmError(#[from] DrmError), } @@ -47,13 +47,14 @@ pub fn take_screenshot(state: &State) -> Result format: XRGB8888, modifier: INVALID_MODIFIER, }; - let bo = ctx.gbm.create_bo( + let gbm = ctx.gbm(); + let bo = gbm.create_bo( extents.width(), extents.height(), &format, GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR, )?; - let fb = ctx.dmabuf_fb(bo.dmabuf())?; + let fb = ctx.clone().dmabuf_fb(bo.dmabuf())?; fb.render( state.root.deref(), state, @@ -63,6 +64,6 @@ pub fn take_screenshot(state: &State) -> Result Scale::from_int(1), true, ); - let drm = ctx.gbm.drm.dup_render()?.fd().clone(); + let drm = gbm.drm.dup_render()?.fd().clone(); Ok(Screenshot { drm, bo }) } diff --git a/src/state.rs b/src/state.rs index e4979dfa..da830015 100644 --- a/src/state.rs +++ b/src/state.rs @@ -13,6 +13,7 @@ use { cursor::{Cursor, ServerCursors}, dbus::Dbus, forker::ForkerProxy, + gfx_api::GfxContext, globals::{Globals, GlobalsError, WaylandGlobal}, ifs::{ ext_session_lock_v1::ExtSessionLockV1, @@ -31,7 +32,6 @@ use { leaks::Tracker, logger::Logger, rect::Rect, - render::RenderContext, scale::Scale, theme::Theme, tree::{ @@ -69,7 +69,7 @@ pub struct State { pub forker: CloneCell>>, pub default_keymap: Rc, pub eng: Rc, - pub render_ctx: CloneCell>>, + pub render_ctx: CloneCell>>, pub render_ctx_version: NumCell, pub render_ctx_ever_initialized: Cell, pub cursors: CloneCell>>, @@ -305,8 +305,8 @@ impl State { } } - pub fn set_render_ctx(&self, ctx: Option<&Rc>) { - self.render_ctx.set(ctx.cloned()); + pub fn set_render_ctx(&self, ctx: Option>) { + self.render_ctx.set(ctx.clone()); self.render_ctx_version.fetch_add(1); self.cursors.set(None); @@ -364,7 +364,7 @@ impl State { } for watcher in self.render_ctx_watchers.lock().values() { - watcher.send_render_ctx(ctx); + watcher.send_render_ctx(ctx.clone()); } let mut scs = vec![]; diff --git a/src/text.rs b/src/text.rs index 3b9a1da2..9913641e 100644 --- a/src/text.rs +++ b/src/text.rs @@ -1,6 +1,7 @@ use { crate::{ format::ARGB8888, + gfx_api::{GfxContext, GfxError, GfxTexture}, pango::{ consts::{ CAIRO_FORMAT_ARGB32, CAIRO_OPERATOR_SOURCE, PANGO_ELLIPSIZE_END, PANGO_SCALE, @@ -9,7 +10,6 @@ use { PangoLayout, }, rect::Rect, - render::{RenderContext, RenderError, Texture}, theme::Color, }, std::{ops::Neg, rc::Rc}, @@ -27,7 +27,7 @@ pub enum TextError { #[error("Could not create a pango layout")] CreateLayout(#[source] PangoError), #[error("Could not import the rendered text")] - RenderError(#[source] RenderError), + RenderError(#[source] GfxError), #[error("Could not access the cairo image data")] ImageData(#[source] PangoError), } @@ -94,21 +94,21 @@ pub fn measure( } pub fn render( - ctx: &Rc, + ctx: &Rc, width: i32, height: i32, font: &str, text: &str, color: Color, scale: Option, -) -> Result, TextError> { +) -> Result, TextError> { render2( ctx, 1, None, width, height, 1, font, text, color, true, false, scale, ) } fn render2( - ctx: &Rc, + ctx: &Rc, x: i32, y: Option, width: i32, @@ -120,7 +120,7 @@ fn render2( ellipsize: bool, markup: bool, scale: Option, -) -> Result, TextError> { +) -> Result, TextError> { let data = create_data(font, width, height, scale)?; if ellipsize { data.layout @@ -144,21 +144,24 @@ fn render2( Ok(d) => d, Err(e) => return Err(TextError::ImageData(e)), }; - match ctx.shmem_texture(bytes, ARGB8888, width, height, data.image.stride()) { + match ctx + .clone() + .shmem_texture(bytes, ARGB8888, width, height, data.image.stride()) + { Ok(t) => Ok(t), Err(e) => Err(TextError::RenderError(e)), } } pub fn render_fitting( - ctx: &Rc, + ctx: &Rc, height: Option, font: &str, text: &str, color: Color, markup: bool, scale: Option, -) -> Result, TextError> { +) -> Result, TextError> { render_fitting2(ctx, height, font, text, color, markup, scale, false).map(|(a, _)| a) } @@ -170,7 +173,7 @@ pub struct TextMeasurement { } pub fn render_fitting2( - ctx: &Rc, + ctx: &Rc, height: Option, font: &str, text: &str, @@ -178,7 +181,7 @@ pub fn render_fitting2( markup: bool, scale: Option, include_measurements: bool, -) -> Result<(Rc, TextMeasurement), TextError> { +) -> Result<(Rc, TextMeasurement), TextError> { let measurement = measure(font, text, markup, scale, include_measurements)?; let y = match height { Some(_) => None, diff --git a/src/theme.rs b/src/theme.rs index 8df6861f..f018cf63 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -1,6 +1,9 @@ -use std::cell::{Cell, RefCell}; +use std::{ + cell::{Cell, RefCell}, + cmp::Ordering, +}; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq)] pub struct Color { pub r: f32, pub g: f32, @@ -8,6 +11,24 @@ pub struct Color { pub a: f32, } +impl Eq for Color {} + +impl Ord for Color { + fn cmp(&self, other: &Self) -> Ordering { + self.r + .total_cmp(&other.r) + .then_with(|| self.g.total_cmp(&other.g)) + .then_with(|| self.b.total_cmp(&other.b)) + .then_with(|| self.a.total_cmp(&other.a)) + } +} + +impl PartialOrd for Color { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + fn to_f32(c: u8) -> f32 { c as f32 / 255f32 } diff --git a/src/tree.rs b/src/tree.rs index 6e31beb6..0ea96811 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -8,7 +8,7 @@ use { wl_surface::WlSurface, }, rect::Rect, - render::Renderer, + renderer::Renderer, utils::numcell::NumCell, xkbcommon::ModifierState, }, @@ -137,10 +137,19 @@ pub trait Node: 'static { let _ = (child, active, depth); } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + max_width: i32, + max_height: i32, + ) { let _ = renderer; let _ = x; let _ = y; + let _ = max_width; + let _ = max_height; } fn node_client(&self) -> Option> { diff --git a/src/tree/container.rs b/src/tree/container.rs index b2a9ebd4..eaff7a3c 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -3,12 +3,13 @@ use { backend::KeyState, cursor::KnownCursor, fixed::Fixed, + gfx_api::GfxTexture, ifs::wl_seat::{ collect_kb_foci, collect_kb_foci2, wl_pointer::PendingScroll, NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT, }, rect::Rect, - render::{Renderer, Texture}, + renderer::Renderer, scale::Scale, state::State, text, @@ -76,7 +77,7 @@ tree_id!(ContainerNodeId); pub struct ContainerTitle { pub x: i32, pub y: i32, - pub tex: Rc, + pub tex: Rc, } #[derive(Default)] @@ -736,7 +737,6 @@ impl ContainerNode { child.node.tl_set_visible(true); // log::info!("activate_child2"); self.schedule_layout(); - } else { } } @@ -1086,7 +1086,14 @@ impl Node for ContainerNode { .node_child_active_changed(self.deref(), active, depth + 1); } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + _max_width: i32, + _max_height: i32, + ) { renderer.render_container(self, x, y); } diff --git a/src/tree/display.rs b/src/tree/display.rs index ab655681..a60ca10f 100644 --- a/src/tree/display.rs +++ b/src/tree/display.rs @@ -4,7 +4,7 @@ use { cursor::KnownCursor, ifs::wl_seat::{NodeSeatState, WlSeatGlobal}, rect::Rect, - render::Renderer, + renderer::Renderer, tree::{ walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, OutputNode, StackedNode, }, @@ -111,7 +111,14 @@ impl Node for DisplayNode { FindTreeResult::AcceptsInput } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + _max_width: i32, + _max_height: i32, + ) { renderer.render_display(self, x, y); } diff --git a/src/tree/float.rs b/src/tree/float.rs index 68c3c282..525e6ff6 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -3,9 +3,10 @@ use { backend::KeyState, cursor::KnownCursor, fixed::Fixed, + gfx_api::GfxTexture, ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT}, rect::Rect, - render::{Renderer, Texture}, + renderer::Renderer, scale::Scale, state::State, text, @@ -43,7 +44,7 @@ pub struct FloatNode { pub layout_scheduled: Cell, pub render_titles_scheduled: Cell, pub title: RefCell, - pub title_textures: CopyHashMap>, + pub title_textures: CopyHashMap>, seats: RefCell>, } @@ -420,7 +421,14 @@ impl Node for FloatNode { } } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + _max_width: i32, + _max_height: i32, + ) { renderer.render_floating(self, x, y) } diff --git a/src/tree/output.rs b/src/tree/output.rs index 3c86881f..53379c43 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -4,6 +4,7 @@ use { client::ClientId, cursor::KnownCursor, fixed::Fixed, + gfx_api::{GfxFramebuffer, GfxTexture}, ifs::{ jay_output::JayOutput, jay_screencast::JayScreencast, @@ -19,7 +20,7 @@ use { zwlr_layer_shell_v1::{BACKGROUND, BOTTOM, OVERLAY, TOP}, }, rect::Rect, - render::{Framebuffer, Renderer, Texture}, + renderer::Renderer, scale::Scale, state::State, text, @@ -77,7 +78,7 @@ pub async fn output_render_data(state: Rc) { } impl OutputNode { - pub fn perform_screencopies(&self, fb: &Framebuffer, tex: &Texture) { + pub fn perform_screencopies(&self, fb: &dyn GfxFramebuffer, tex: &Rc) { if let Some(workspace) = self.workspace.get() { if !workspace.capture.get() { return; @@ -464,14 +465,14 @@ pub struct OutputTitle { pub x2: i32, pub tex_x: i32, pub tex_y: i32, - pub tex: Rc, + pub tex: Rc, pub ws: Rc, } pub struct OutputStatus { pub tex_x: i32, pub tex_y: i32, - pub tex: Rc, + pub tex: Rc, } #[derive(Copy, Clone)] @@ -620,7 +621,14 @@ impl Node for OutputNode { FindTreeResult::AcceptsInput } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + _max_width: i32, + _max_height: i32, + ) { renderer.render_output(self, x, y); } diff --git a/src/tree/placeholder.rs b/src/tree/placeholder.rs index bf882ffb..72c3635b 100644 --- a/src/tree/placeholder.rs +++ b/src/tree/placeholder.rs @@ -3,9 +3,10 @@ use { client::Client, cursor::KnownCursor, fixed::Fixed, + gfx_api::GfxTexture, ifs::wl_seat::{NodeSeatState, WlSeatGlobal}, rect::Rect, - render::{Renderer, Texture}, + renderer::Renderer, scale::Scale, state::State, text, @@ -24,7 +25,7 @@ pub struct PlaceholderNode { id: PlaceholderNodeId, toplevel: ToplevelData, destroyed: Cell, - pub textures: SmallMap, 2>, + pub textures: SmallMap, 2>, } impl PlaceholderNode { @@ -122,7 +123,14 @@ impl Node for PlaceholderNode { FindTreeResult::AcceptsInput } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + _max_width: i32, + _max_height: i32, + ) { renderer.render_placeholder(self, x, y); } diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index b3f8cf56..00c11353 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -9,7 +9,7 @@ use { wl_surface::WlSurface, }, rect::Rect, - render::Renderer, + renderer::Renderer, tree::{ container::ContainerNode, walker::NodeVisitor, ContainingNode, Direction, FindTreeResult, FoundNode, Node, NodeId, NodeVisitorBase, OutputNode, StackedNode, @@ -170,7 +170,14 @@ impl Node for WorkspaceNode { FindTreeResult::AcceptsInput } - fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32) { + fn node_render( + &self, + renderer: &mut Renderer, + x: i32, + y: i32, + _max_width: i32, + _max_height: i32, + ) { renderer.render_workspace(self, x, y); } diff --git a/src/video/drm/sys.rs b/src/video/drm/sys.rs index 7acbcb92..35c4dd03 100644 --- a/src/video/drm/sys.rs +++ b/src/video/drm/sys.rs @@ -814,7 +814,7 @@ pub fn mode_getconnector( modes: modes.into_iter().map(|m| m.into()).collect(), props: props .into_iter() - .zip(prop_values.into_iter()) + .zip(prop_values) .map(|(id, value)| DrmPropertyValue { id: DrmProperty(id), value,