diff --git a/Cargo.lock b/Cargo.lock index 1a2423eaa..daee43054 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,6 +149,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "allocator-api2" version = "0.2.16" @@ -215,6 +221,21 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + [[package]] name = "arboard" version = "3.4.0" @@ -230,6 +251,17 @@ dependencies = [ "x11rb", ] +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -470,6 +502,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + [[package]] name = "backtrace" version = "0.3.69" @@ -530,6 +585,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -545,6 +606,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b81e1519b0d82120d2fd469d5bfb2919a9361c48b02d82d04befc1cdd2002452" + [[package]] name = "block" version = "0.1.6" @@ -582,6 +649,12 @@ dependencies = [ "piper", ] +[[package]] +name = "built" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" + [[package]] name = "bumpalo" version = "3.14.0" @@ -614,6 +687,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.5.0" @@ -753,7 +832,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" dependencies = [ "ciborium-io", - "half", + "half 1.8.2", ] [[package]] @@ -796,6 +875,12 @@ dependencies = [ "error-code", ] +[[package]] +name = "clipline" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aa02ab3f9d7d7dd389014f64b681a1bd0c0fd88b17373a2b438bb9cafb4dc31" + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -946,7 +1031,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -965,7 +1050,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -1003,6 +1088,12 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1097,6 +1188,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "digest" version = "0.10.7" @@ -1272,6 +1383,19 @@ dependencies = [ "winit", ] +[[package]] +name = "egui_cpu" +version = "0.28.1" +dependencies = [ + "bytemuck", + "derive_more", + "egui", + "egui_extras", + "euc", + "image", + "vek", +] + [[package]] name = "egui_demo_app" version = "0.28.1" @@ -1503,6 +1627,17 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc" +[[package]] +name = "euc" +version = "0.6.0" +source = "git+https://github.com/zesterer/euc#658c8fd5b66599919f64aa8223c78a6ce1893f57" +dependencies = [ + "clipline", + "fxhash", + "image", + "vek", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1541,6 +1676,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half 2.4.1", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fancy-regex" version = "0.11.0" @@ -1600,6 +1751,15 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1719,6 +1879,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "gdk-pixbuf-sys" version = "0.18.0" @@ -2007,6 +2176,16 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -2139,13 +2318,30 @@ dependencies = [ "bytemuck", "byteorder", "color_quant", + "exr", "gif", + "image-webp", "num-traits", "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", "zune-core", "zune-jpeg", ] +[[package]] +name = "image-webp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" +dependencies = [ + "byteorder-lite", + "quick-error", +] + [[package]] name = "images" version = "0.1.0" @@ -2162,6 +2358,12 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + [[package]] name = "immutable-chunkmap" version = "2.0.5" @@ -2190,6 +2392,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -2221,6 +2434,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -2258,6 +2480,12 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.70" @@ -2301,12 +2529,29 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libloading" version = "0.8.0" @@ -2374,6 +2619,15 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "lz4_flex" version = "0.11.1" @@ -2389,6 +2643,16 @@ dependencies = [ "libc", ] +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.6.3" @@ -2543,6 +2807,12 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nix" version = "0.26.4" @@ -2571,6 +2841,55 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.16" @@ -3119,6 +3438,19 @@ name = "profiling" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0f7f43585c34e4fdd7497d746bc32e14458cf11c69341cc0587b1d825dde42" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +dependencies = [ + "quote", + "syn 2.0.48", +] [[package]] name = "puffin" @@ -3160,6 +3492,21 @@ dependencies = [ "puffin_http", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.31.0" @@ -3217,6 +3564,56 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.12.1", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -3419,6 +3816,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.37.25" @@ -3527,6 +3933,12 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" version = "1.0.188" @@ -3613,6 +4025,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "simplecss" version = "0.2.1" @@ -3712,6 +4133,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spirv" @@ -3892,6 +4316,17 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.30" @@ -4207,6 +4642,30 @@ dependencies = [ "tiny-skia-path", ] +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "vek" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86dce3b89992dbfee9b6f46d8a98a4a5ecf79f93f3b077fad3cc2759ebe92214" +dependencies = [ + "approx", + "num-integer", + "num-traits", + "rustc_version", + "serde", +] + [[package]] name = "version-compare" version = "0.1.1" @@ -5131,6 +5590,15 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + [[package]] name = "zune-jpeg" version = "0.4.11" diff --git a/Cargo.toml b/Cargo.toml index b8e02f3fd..8dd8a553e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ members = [ "examples/*", "tests/*", - "xtask", + "xtask", "crates/egui_cpu", ] [workspace.package] diff --git a/crates/egui_cpu/Cargo.toml b/crates/egui_cpu/Cargo.toml new file mode 100644 index 000000000..6f081b64b --- /dev/null +++ b/crates/egui_cpu/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "egui_cpu" +edition.workspace = true +license.workspace = true +rust-version.workspace = true +version.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +euc = { git = "https://github.com/zesterer/euc" } +egui = { workspace = true, features = ["bytemuck"] } +image = { workspace = true, default-features = false } +derive_more = { version = "1", features = ["add", "mul"] } +vek = "0.17.1" +bytemuck = "1" + +[dev-dependencies] +egui = { workspace = true, features = ["default_fonts"] } +egui_extras = { workspace = true, features = ["all_loaders"] } + +[lints] +workspace = true diff --git a/crates/egui_cpu/examples/cpu_renderer.rs b/crates/egui_cpu/examples/cpu_renderer.rs new file mode 100644 index 000000000..93f496850 --- /dev/null +++ b/crates/egui_cpu/examples/cpu_renderer.rs @@ -0,0 +1,67 @@ +use egui::load::SizedTexture; +use egui::{include_image, ColorImage, ImageSource, Pos2, RawInput, Stroke, TextureId, Vec2}; + +fn main() { + let ctx = egui::Context::default(); + + let mut input = RawInput { + screen_rect: Some(egui::Rect::from_min_size( + Default::default(), + Vec2::new(400.0, 200.0), + )), + ..Default::default() + }; + input + .viewports + .get_mut(&input.viewport_id) + .unwrap() + .native_pixels_per_point = Some(2.0); + let output = ctx.run(input, |ctx| { + egui::CentralPanel::default().show(ctx, |ui| { + ui.group(|ui| { + ui.label("Hello World!"); + ui.button("Click me!"); + ui.checkbox(&mut true, "Check me!"); + ui.heading("Heading"); + }); + // ui.image(SizedTexture::new( + // TextureId::default(), + // Vec2::new(2048.0, 128.0), + // )); + ui.image(include_image!("../../../media/rerun_io_logo.png")); + }); + + // ctx.debug_painter().rect_filled( + // egui::Rect::from_min_size(Pos2::new(0.0, 0.0), Vec2::new(100.0, 100.0)), + // 10.0, + // egui::Color32::from_rgba_premultiplied(255, 0, 0, 255), + // ); + // ctx.debug_painter().rect_filled( + // egui::Rect::from_min_size(Pos2::new(100.0, 0.0), Vec2::new(100.0, 100.0)), + // 10.0, + // egui::Color32::from_rgba_premultiplied(0, 255, 0, 255), + // ); + // + // ctx.debug_painter().rect_stroke( + // egui::Rect::from_min_size(Pos2::new(200.0, 0.0), Vec2::new(100.0, 100.0)), + // 10.0, + // Stroke::new(10.0, egui::Color32::from_rgba_premultiplied(0, 0, 255, 255)), + // ); + }); + + let primitives = ctx.tessellate(output.shapes, ctx.pixels_per_point()); + + let mut cpu_renderer = egui_cpu::Renderer::default(); + + cpu_renderer.update_textures(output.textures_delta); + + dbg!(ctx.screen_rect()); + + let image = cpu_renderer.render( + &primitives, + ctx.screen_rect().size(), + ctx.pixels_per_point(), + ); + + image.save("output.png").unwrap(); +} diff --git a/crates/egui_cpu/src/lib.rs b/crates/egui_cpu/src/lib.rs new file mode 100644 index 000000000..8f9b0f4c3 --- /dev/null +++ b/crates/egui_cpu/src/lib.rs @@ -0,0 +1,134 @@ +mod pipeline; + +use egui::ahash::HashMap; +use egui::epaint::Primitive; +use egui::{ClippedPrimitive, ColorImage, ImageData, TextureId, TexturesDelta, Vec2}; +use euc::buffer::Buffer2d; +use euc::{IndexedVertices, Pipeline, Sampler, Texture}; +use image::{DynamicImage, ImageBuffer, Pixel, RgbaImage}; +use std::ops::Deref; +use vek::Rgba; + +#[derive(Debug, Default)] +pub struct Renderer { + textures: HashMap>>, +} + +impl Renderer { + pub fn update_textures(&mut self, delta: TexturesDelta) { + for (id, delta) in delta.set { + dbg!(delta.image.size()); + let image = match delta.image { + ImageData::Color(color) => RgbaImage::from_raw( + color.width() as u32, + color.height() as u32, + Vec::from(color.deref().as_raw()), + ) + .unwrap(), + ImageData::Font(font) => { + let color_image = ColorImage { + size: font.size, + pixels: font.srgba_pixels(None).collect(), + }; + + RgbaImage::from_raw( + font.width() as u32, + font.height() as u32, + Vec::from(color_image.as_raw()), + ) + .unwrap() + } + }; + + let buffer = Buffer2d::from_texture(&DynamicImage::from(image).to_rgba8()); + self.textures.insert(id, buffer); + + if delta.pos.is_some() { + unimplemented!() + } + } + } + + pub fn render( + &self, + primitives: &[ClippedPrimitive], + resolution: Vec2, + dpi: f32, + ) -> ImageBuffer, Vec> { + let width = (resolution.x * dpi) as usize; + let height = (resolution.y * dpi) as usize; + + dbg!(width, height); + + let mut output = Buffer2d::fill([width, height], 0x000000); + let mut depth = Buffer2d::fill([width, height], 1.0); + + for ClippedPrimitive { + primitive, + clip_rect, + } in primitives + { + match primitive { + Primitive::Mesh(mesh) => { + let texture = self.textures.get(&mesh.texture_id).unwrap(); + + let sampler = texture + .map(|pixel| Rgba::from(pixel.0).map(|e: u8| e as f32)) + .linear(); + // let sampler = DebugSampler { + // texture: Buffer2d::fill([1, 1], 0.0), + // }; + + // let sampler = |pos| Rgba::new(0, 0, 0, 0); + + let mut pipeline = pipeline::EguiPipeline { + screen_size: vek::Vec2::new(width as f32, height as f32) / dpi, + scissor_rect: Default::default(), + sampler: &sampler, + }; + + pipeline.scissor_rect = vek::Rect::new( + clip_rect.min.x, + clip_rect.min.y, + clip_rect.width(), + clip_rect.height(), + ); + + pipeline.render( + mesh.indices.iter().map(|&i| mesh.vertices[i as usize]), + &mut output, + &mut depth, + ); + } + Primitive::Callback(_) => { + println!("Callback not implemented"); + } + } + } + + let raw = output.raw(); + let raw = Vec::from(bytemuck::cast_slice(&raw)); + let image = RgbaImage::from_raw(width as u32, height as u32, raw).unwrap(); + image + } +} + +struct DebugSampler { + texture: Buffer2d, +} +impl Sampler<2> for DebugSampler { + type Index = f32; + type Sample = Rgba; + type Texture = Buffer2d; + + fn raw_texture(&self) -> &Self::Texture { + &self.texture + } + + fn sample(&self, index: [Self::Index; 2]) -> Self::Sample { + if index[0] != 0.0 || index[1] != 0.0 { + dbg!(index); + } + Rgba::new(0.0, 0.0, 0.0, 0.0) + } +} diff --git a/crates/egui_cpu/src/pipeline.rs b/crates/egui_cpu/src/pipeline.rs new file mode 100644 index 000000000..98b579ca7 --- /dev/null +++ b/crates/egui_cpu/src/pipeline.rs @@ -0,0 +1,117 @@ +use derive_more::{Add, Mul}; +use euc::primitives::PrimitiveKind; +use euc::rasterizer::{Rasterizer, Triangles}; +use euc::{ + AaMode, CoordinateMode, CullMode, DepthMode, Pipeline, PixelMode, Sampler, Texture, + TriangleList, +}; +use vek::{Rgba, Vec2, Vec4}; + +pub(crate) struct EguiPipeline { + pub screen_size: Vec2, + pub scissor_rect: vek::Rect, + pub sampler: S, +} + +#[derive(Debug, Clone, Add, Mul)] +pub(crate) struct VertexData { + text_coord: Vec2, + color: Rgba, +} + +impl<'r, S: Sampler<2, Index = f32, Sample = Rgba>> Pipeline<'r> for EguiPipeline { + type Vertex = egui::epaint::Vertex; + type VertexData = VertexData; + type Primitives = TriangleList; + type Fragment = Rgba; + type Pixel = u32; + + fn coordinate_mode(&self) -> CoordinateMode { + CoordinateMode::VULKAN + } + + fn pixel_mode(&self) -> PixelMode { + PixelMode::WRITE + } + + fn vertex(&self, vertex: &Self::Vertex) -> ([f32; 4], Self::VertexData) { + let position = + position_from_screen(Vec2::new(vertex.pos.x, vertex.pos.y), self.screen_size); + let text_coord = Vec2::new(vertex.uv.x, vertex.uv.y); + let color = Rgba::new( + vertex.color.r() as f32 / 255.0, + vertex.color.g() as f32 / 255.0, + vertex.color.b() as f32 / 255.0, + vertex.color.a() as f32 / 255.0, + ); + (position.into_array(), VertexData { text_coord, color }) + } + + fn fragment(&self, vs_out: Self::VertexData) -> Self::Fragment { + vs_out.color * self.sampler.sample(vs_out.text_coord.into_array()) + } + + fn blend(&self, old: Self::Pixel, new: Self::Fragment) -> Self::Pixel { + //Source over + let source = new; + let dest = Rgba::from(old.to_le_bytes()).map(|c: u8| c as f32); + + let source_alpha = source.a / 255.0; + let inv_source_alpha = 1.0 - source_alpha; + + let r = source.r + dest.r * inv_source_alpha; + let g = source.g + dest.g * inv_source_alpha; + let b = source.b + dest.b * inv_source_alpha; + let a = source.a + dest.a * inv_source_alpha; + u32::from_le_bytes(Rgba::new(r, g, b, a).map(|c| (c) as u8).into_array()) + + // u32::from_le_bytes(new.map(|c| c as u8).into_array()) + } + + fn rasterizer_config( + &self, + ) -> <>::Rasterizer as Rasterizer>::Config + { + CullMode::None + } + + fn aa_mode(&self) -> AaMode { + AaMode::None + } +} + +// From wgsl shader: +// fn unpack_color(color: u32) -> vec4 { +// return vec4( +// f32(color & 255u), +// f32((color >> 8u) & 255u), +// f32((color >> 16u) & 255u), +// f32((color >> 24u) & 255u), +// ) / 255.0; +// } +// fn unpack_color(color: [u8; 4]) -> Vec4 { +// Vec4::new( +// (color & 255u32) as f32, +// ((color >> 8u32) & 255u32) as f32, +// ((color >> 16u32) & 255u32) as f32, +// ((color >> 24u32) & 255u32) as f32, +// ) / 255.0 +// } + +// From wgsl shader: +// fn position_from_screen(screen_pos: vec2) -> vec4 { +// return vec4( +// 2.0 * screen_pos.x / r_locals.screen_size.x - 1.0, +// 1.0 - 2.0 * screen_pos.y / r_locals.screen_size.y, +// 0.0, +// 1.0, +// ); +// } +fn position_from_screen(screen_pos: Vec2, screen_size: Vec2) -> Vec4 { + Vec4::new( + 2.0 * screen_pos.x / screen_size.x - 1.0, + 1.0 - 2.0 * screen_pos.y / screen_size.y, + 0.0, + 1.0, + ) +} diff --git a/output.png b/output.png new file mode 100644 index 000000000..71ed3ece7 Binary files /dev/null and b/output.png differ diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index 871f56248..000000000 --- a/rust-toolchain +++ /dev/null @@ -1,10 +0,0 @@ -# If you see this, run "rustup self update" to get rustup 1.23 or newer. - -# NOTE: above comment is for older `rustup` (before TOML support was added), -# which will treat the first line as the toolchain name, and therefore show it -# to the user in the error, instead of "error: invalid channel name '[toolchain]'". - -[toolchain] -channel = "1.76.0" -components = ["rustfmt", "clippy"] -targets = ["wasm32-unknown-unknown"]