From c83ef201a1683864f7e18e3cd00db4ae6e33fc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 25 Sep 2024 11:00:02 +0200 Subject: [PATCH] wip: target emscripten for rust poc --- docker/devenv/Dockerfile | 10 + docker/devenv/files/bashrc | 1 + frontend/renderer/rs/Cargo.lock | 657 ++++++++++++++++++ frontend/renderer/rs/Cargo.toml | 21 + frontend/renderer/rs/src/main.rs | 134 ++++ frontend/src/app/main/data/workspace.cljs | 3 + .../src/app/main/ui/workspace/viewport.cljs | 19 +- 7 files changed, 838 insertions(+), 7 deletions(-) create mode 100644 frontend/renderer/rs/Cargo.lock create mode 100644 frontend/renderer/rs/Cargo.toml create mode 100644 frontend/renderer/rs/src/main.rs diff --git a/docker/devenv/Dockerfile b/docker/devenv/Dockerfile index 042e16d0e..dc6e52512 100644 --- a/docker/devenv/Dockerfile +++ b/docker/devenv/Dockerfile @@ -265,6 +265,16 @@ RUN set -eux; \ rm rustup-init; \ chmod -R a+w $RUSTUP_HOME $CARGO_HOME; +WORKDIR /usr/local + +# Install emscripten SDK and activate it +RUN set -eux; \ + git clone https://github.com/emscripten-core/emsdk.git; \ + cd emsdk; \ + ./emsdk install latest; \ + ./emsdk activate latest; \ + rustup target add wasm32-unknown-emscripten; + WORKDIR /home COPY files/nginx.conf /etc/nginx/nginx.conf diff --git a/docker/devenv/files/bashrc b/docker/devenv/files/bashrc index dca37aadb..821966554 100644 --- a/docker/devenv/files/bashrc +++ b/docker/devenv/files/bashrc @@ -11,6 +11,7 @@ alias lsf='ls -h *(.)' # init Cargo / Rust env . "/usr/local/cargo/env" +EMSDK_QUIET=1 . "/usr/local/emsdk/emsdk_env.sh" # include .bashrc if it exists if [ -f "$HOME/.bashrc.local" ]; then diff --git a/frontend/renderer/rs/Cargo.lock b/frontend/renderer/rs/Cargo.lock new file mode 100644 index 000000000..c75359ed2 --- /dev/null +++ b/frontend/renderer/rs/Cargo.lock @@ -0,0 +1,657 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "cc" +version = "1.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +dependencies = [ + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "flate2" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "gl" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[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.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "prettyplease" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "renderer" +version = "0.1.0" +dependencies = [ + "gl", + "skia-safe", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "skia-bindings" +version = "0.78.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ac1da945f92ee2c5ae7999bc679d682fd976ef524b09cc80b5aae971d3e557" +dependencies = [ + "bindgen", + "cc", + "flate2", + "heck", + "lazy_static", + "regex", + "serde_json", + "tar", + "toml", +] + +[[package]] +name = "skia-safe" +version = "0.78.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80a2993ab98e8f01c874fc35cfec9a8d216d968b80f7e9b1cb9ac1bf4f6a2f3a" +dependencies = [ + "bitflags", + "lazy_static", + "skia-bindings", +] + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tar" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "xml-rs" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" diff --git a/frontend/renderer/rs/Cargo.toml b/frontend/renderer/rs/Cargo.toml new file mode 100644 index 000000000..f0c811830 --- /dev/null +++ b/frontend/renderer/rs/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "renderer" +version = "0.1.0" +edition = "2021" +repository = "https://github.com/penpot/penpot" +license-file = "../../../../LICENSE" +description = "Wasm-based canvas renderer for Penpot" + +[features] +default = ["skia-safe/gl"] + +[[bin]] +name = "renderer_v2" +path = "src/main.rs" + +[dependencies] +gl = "0.14.0" +skia-safe = "0.78.0" + +[profile.release] +opt-level = "s" diff --git a/frontend/renderer/rs/src/main.rs b/frontend/renderer/rs/src/main.rs new file mode 100644 index 000000000..9322d9cc0 --- /dev/null +++ b/frontend/renderer/rs/src/main.rs @@ -0,0 +1,134 @@ +use std::boxed::Box; + +use skia_safe::{ + gpu::{self, gl::FramebufferInfo, DirectContext}, + Color, Paint, PaintStyle, Surface, Rect +}; + +extern "C" { + pub fn emscripten_GetProcAddress( + name: *const ::std::os::raw::c_char, + ) -> *const ::std::os::raw::c_void; +} + +struct GpuState { + context: DirectContext, + framebuffer_info: FramebufferInfo, +} + +/// This struct holds the state of the Rust application between JS calls. +/// +/// It is created by [init] and passed to the other exported functions. Note that rust-skia data +/// structures are not thread safe, so a state must not be shared between different Web Workers. +pub struct State { + gpu_state: GpuState, + surface: Surface, +} + +impl State { + fn new(gpu_state: GpuState, surface: Surface) -> Self { + State { gpu_state, surface } + } + + fn set_surface(&mut self, surface: Surface) { + self.surface = surface; + } +} + +#[no_mangle] +pub fn add(left: f32, right: f32) -> f32 { + println!("left-> {}", left); + println!("right-> {}", right); + left + right +} + +fn init_gl() { + unsafe { + gl::load_with(|addr| { + let addr = std::ffi::CString::new(addr).unwrap(); + emscripten_GetProcAddress(addr.into_raw() as *const _) as *const _ + }); + } +} + +/// This needs to be done once per WebGL context. +fn create_gpu_state() -> GpuState { + let interface = skia_safe::gpu::gl::Interface::new_native().unwrap(); + let context = skia_safe::gpu::direct_contexts::make_gl(interface, None).unwrap(); + let framebuffer_info = { + let mut fboid: gl::types::GLint = 0; + unsafe { gl::GetIntegerv(gl::FRAMEBUFFER_BINDING, &mut fboid) }; + + FramebufferInfo { + fboid: fboid.try_into().unwrap(), + format: skia_safe::gpu::gl::Format::RGBA8.into(), + protected: skia_safe::gpu::Protected::No, + } + }; + + GpuState { + context, + framebuffer_info, + } +} + +/// Create the Skia surface that will be used for rendering. +fn create_surface(gpu_state: &mut GpuState, width: i32, height: i32) -> Surface { + let backend_render_target = + gpu::backend_render_targets::make_gl((width, height), 1, 8, gpu_state.framebuffer_info); + + gpu::surfaces::wrap_backend_render_target( + &mut gpu_state.context, + &backend_render_target, + skia_safe::gpu::SurfaceOrigin::BottomLeft, + skia_safe::ColorType::RGBA8888, + None, + None, + ) + .unwrap() +} + +fn render_rect(surface: &mut Surface, left: f32, top: f32, right: f32, bottom: f32) { + let mut paint = Paint::default(); + paint.set_style(PaintStyle::Fill); + paint.set_color(Color::BLACK); + paint.set_anti_alias(true); + surface.canvas().draw_rect(Rect::new(left, top, right, bottom), &paint); +} + +/// This is called from JS after the WebGL context has been created. +#[no_mangle] +pub extern "C" fn init(width: i32, height: i32) -> Box { + let mut gpu_state = create_gpu_state(); + let surface = create_surface(&mut gpu_state, width, height); + let state = State::new(gpu_state, surface); + Box::new(state) +} + +/// Draw a black rect at the specified coordinates. +/// # Safety +#[no_mangle] +pub unsafe extern "C" fn draw_rect(state: *mut State, left: i32, right: i32, top: i32, bottom: i32) { + let state = unsafe { state.as_mut() }.expect("got an invalid state pointer"); + //state.surface.canvas().clear(Color::WHITE); + render_rect(&mut state.surface, left as f32, right as f32, top as f32, bottom as f32); + state + .gpu_state + .context + .flush_and_submit_surface(&mut state.surface, None); +} + +fn main() { + init_gl(); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} \ No newline at end of file diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index ee253d7ef..ee8c898ff 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -75,6 +75,7 @@ [app.main.streams :as ms] [app.main.worker :as uw] [app.renderer.cpp :as renderer-cpp] + [app.renderer.rs :as renderer-rs] [app.util.dom :as dom] [app.util.globals :as ug] [app.util.http :as http] @@ -356,6 +357,8 @@ (when (contains? cf/flags :renderer-v2-cpp) (rx/of (renderer-cpp/init))) + (when (contains? cf/flags :renderer-v2-rs) + (rx/of (renderer-rs/init))) (->> stream (rx/filter dch/commit?) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 7d14532e4..1e4b75561 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -49,6 +49,7 @@ [app.main.ui.workspace.viewport.viewport-ref :refer [create-viewport-ref]] [app.main.ui.workspace.viewport.widgets :as widgets] [app.renderer.cpp :as renderer-cpp] + [app.renderer.rs :as renderer-rs] [app.util.debug :as dbg] [beicon.v2.core :as rx] [rumext.v2 :as mf])) @@ -133,6 +134,7 @@ ;; REFS [viewport-ref on-viewport-ref] (create-viewport-ref) + canvas-ref (mf/use-ref nil) ;; VARS disable-paste (mf/use-var false) @@ -268,10 +270,12 @@ rule-area-size (/ rulers/ruler-area-size zoom)] (mf/with-effect - [canvas-ref] - ;; FIXME: - (let [canvas (mf/ref-val canvas-ref)] - (renderer-cpp/set-canvas canvas))) + [canvas-ref] + (let [canvas (mf/ref-val canvas-ref)] + (when (contains? cf/flags :renderer-v2-cpp) + (renderer-cpp/set-canvas canvas)) + (when (contains? cf/flags :renderer-v2-rs) + (renderer-rs/set-canvas canvas)))) (hooks/setup-dom-events zoom disable-paste in-viewport? workspace-read-only? drawing-tool drawing-path?) (hooks/setup-viewport-size vport viewport-ref) @@ -314,7 +318,8 @@ :layout layout :viewport-ref viewport-ref}])] - (if (contains? cf/flags :renderer-v2-cpp) + (if (or (contains? cf/flags :renderer-v2-cpp) + (contains? cf/flags :renderer-v2-rs)) [:canvas {:id "render" :ref canvas-ref :class (stl/css :render-shapes) @@ -354,7 +359,7 @@ (when (dbg/enabled? :show-export-metadata) [:& use/export-page {:page page}]) - ;; We need a "real" background shape so layer transforms work properly in firefox + ;; We need a "real" background shape so layer transforms work properly in firefox [:rect {:width (:width vbox 0) :height (:height vbox 0) :x (:x vbox 0) @@ -363,7 +368,7 @@ [:& (mf/provider ctx/current-vbox) {:value vbox'} [:& (mf/provider use/include-metadata-ctx) {:value (dbg/enabled? :show-export-metadata)} - ;; Render root shape + ;; Render root shape [:& shapes/root-shape {:key page-id :objects base-objects :active-frames @active-frames}]]]])