Add an Android port

This commit is contained in:
Patrick Walton 2019-03-08 16:52:47 -08:00
parent d5effc35ae
commit 9c404dfdc1
72 changed files with 1676 additions and 133 deletions

262
Cargo.lock generated
View File

@ -5,6 +5,14 @@ name = "adler32"
version = "1.0.3" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aho-corasick"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.6.10" version = "0.6.10"
@ -38,6 +46,11 @@ dependencies = [
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "ascii"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.11" version = "0.2.11"
@ -53,6 +66,28 @@ name = "autocfg"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "backtrace"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace-sys"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.9.3" version = "0.9.3"
@ -77,6 +112,11 @@ name = "cc"
version = "1.0.29" version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cesu8"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.6" version = "0.1.6"
@ -109,6 +149,18 @@ name = "color_quant"
version = "1.0.1" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "combine"
version = "3.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.1.2" version = "1.1.2"
@ -162,13 +214,25 @@ name = "demo"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_demo 0.1.0", "pathfinder_demo 0.1.0",
"pathfinder_geometry 0.3.0", "pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0",
"pathfinder_simd 0.3.0", "pathfinder_simd 0.3.0",
"sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)", "sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)", "sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "egl"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"khronos 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.5.0" version = "1.5.0"
@ -186,6 +250,14 @@ dependencies = [
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "error-chain"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "euclid" name = "euclid"
version = "0.19.5" version = "0.19.5"
@ -350,6 +422,24 @@ dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "jni"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"combine 3.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jni-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "jpeg-decoder" name = "jpeg-decoder"
version = "0.1.15" version = "0.1.15"
@ -359,6 +449,23 @@ dependencies = [
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "khronos"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "khronos_api" name = "khronos_api"
version = "2.2.0" version = "2.2.0"
@ -369,6 +476,11 @@ name = "lazy_static"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.48" version = "0.2.48"
@ -415,6 +527,14 @@ name = "lzw"
version = "0.10.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.2.0" version = "2.2.0"
@ -506,6 +626,19 @@ dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "pathfinder_android_demo"
version = "0.1.0"
dependencies = [
"egl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_demo 0.1.0",
"pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0",
]
[[package]] [[package]]
name = "pathfinder_demo" name = "pathfinder_demo"
version = "0.1.0" version = "0.1.0"
@ -514,7 +647,6 @@ dependencies = [
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_geometry 0.3.0", "pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0", "pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0", "pathfinder_gpu 0.1.0",
@ -548,6 +680,7 @@ dependencies = [
"pathfinder_gpu 0.1.0", "pathfinder_gpu 0.1.0",
"pathfinder_renderer 0.1.0", "pathfinder_renderer 0.1.0",
"pathfinder_simd 0.3.0", "pathfinder_simd 0.3.0",
"rustache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -837,6 +970,18 @@ dependencies = [
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "regex"
version = "0.1.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.1.0" version = "1.1.0"
@ -849,6 +994,11 @@ dependencies = [
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "regex-syntax"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.5" version = "0.6.5"
@ -865,6 +1015,25 @@ dependencies = [
"xmlparser 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "xmlparser 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "rustache"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-demangle"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-serialize"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "0.2.7" version = "0.2.7"
@ -880,6 +1049,14 @@ name = "safemem"
version = "0.3.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "same-file"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "scoped_threadpool" name = "scoped_threadpool"
version = "0.1.9" version = "0.1.9"
@ -1025,6 +1202,23 @@ dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "thread-id"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "thread_local" name = "thread_local"
version = "0.3.6" version = "0.3.6"
@ -1053,6 +1247,14 @@ name = "unicode-xid"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unreachable"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "usvg" name = "usvg"
version = "0.4.0" version = "0.4.0"
@ -1067,6 +1269,11 @@ dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "utf8-ranges"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "utf8-ranges" name = "utf8-ranges"
version = "1.0.2" version = "1.0.2"
@ -1077,6 +1284,26 @@ name = "vec_map"
version = "0.8.1" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "2.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.6" version = "0.3.6"
@ -1086,6 +1313,11 @@ dependencies = [
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "winapi-i686-pc-windows-gnu" name = "winapi-i686-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
@ -1128,26 +1360,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata] [metadata]
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" "checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
"checksum ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5fc969a8ce2c9c0c4b0429bb8431544f6658283c8326ba5ff8c762b75369335"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
"checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4"
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" "checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"
"checksum cesu8 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" "checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
"checksum combine 3.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d2623b3542b48f4427e15ddd4995186decb594ebbd70271463886584b4a114b9"
"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" "checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86" "checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86"
"checksum egl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a373bc9844200b1ff15bd1b245931d1c20d09d06e4ec09f361171f29a4b0752d"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
"checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea" "checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea"
"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15" "checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
@ -1166,15 +1406,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" "checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" "checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3"
"checksum jni 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "294eca097d1dc0bf59de5ab9f7eafa5f77129e9f6464c957ed3ddeb705fb4292"
"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
"checksum jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d" "checksum jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum khronos 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c0711aaa80e6ba6eb1fa8978f1f46bfcb38ceb2f3f33f3736efbff39dac89f50"
"checksum khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554" "checksum khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047"
"checksum libflate 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "54d1ddf9c52870243c5689d7638d888331c1116aa5b398f3ba1acfa7d8758ca1" "checksum libflate 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "54d1ddf9c52870243c5689d7638d888331c1116aa5b398f3ba1acfa7d8758ca1"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum lyon_geom 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2b60eaa9061c87affcd671e88289ce6971324269ec6548b677e02624ef3ef63c" "checksum lyon_geom 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2b60eaa9061c87affcd671e88289ce6971324269ec6548b677e02624ef3ef63c"
"checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98" "checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
@ -1213,12 +1459,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" "checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" "checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" "checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"
"checksum roxmltree 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02660467d0c2da1b6276042501aee6e15ec5b8ff59423243f185b294cd53acf3" "checksum roxmltree 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02660467d0c2da1b6276042501aee6e15ec5b8ff59423243f185b294cd53acf3"
"checksum rustache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86de9443c1a5618e0d51bbd8eb6227ead9916446eb8952575a70d1ef7e00209"
"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
"checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e" "checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e"
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebf85f207d42e4da59fa31fff977be5ff0b224873506c4bd70cc1c94b331593" "checksum sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebf85f207d42e4da59fa31fff977be5ff0b224873506c4bd70cc1c94b331593"
@ -1237,15 +1489,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ebf4d5244ba2e8305caf9de7949377794ecdea5a9e3c84fc5610d78d21f5ee" "checksum usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ebf4d5244ba2e8305caf9de7949377794ecdea5a9e3c84fc5610d78d21f5ee"
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -1,5 +1,6 @@
[workspace] [workspace]
members = [ members = [
"demo/android/rust",
"demo/common", "demo/common",
"demo/native", "demo/native",
"geometry", "geometry",

10
demo/android/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
*.iml
.gradle
/local.properties
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild

1
demo/android/app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,31 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "graphics.pathfinder.pathfinderdemo"
minSdkVersion 21
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters "arm64-v8a"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

21
demo/android/app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@ -0,0 +1,26 @@
package graphics.pathfinder.pathfinderdemo;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("graphics.pathfinder.pathfinderdemo", appContext.getPackageName());
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="graphics.pathfinder.pathfinderdemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".PathfinderActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
android:theme="@style/FullscreenTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>

View File

@ -0,0 +1,185 @@
package graphics.pathfinder.pathfinderdemo;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class PathfinderActivity extends AppCompatActivity {
/**
* Whether or not the system UI should be auto-hidden after
* {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
*/
private static final boolean AUTO_HIDE = true;
/**
* If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
* user interaction before hiding the system UI.
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* Some older devices needs a small delay between UI widget updates
* and a change of the status and navigation bar.
*/
private static final int UI_ANIMATION_DELAY = 300;
private final Handler mHideHandler = new Handler();
private PathfinderDemoSurfaceView mContentView;
private final Runnable mHidePart2Runnable = new Runnable() {
@SuppressLint("InlinedApi")
@Override
public void run() {
// Delayed removal of status and navigation bar
// Note that some of these constants are new as of API 16 (Jelly Bean)
// and API 19 (KitKat). It is safe to use them, as they are inlined
// at compile-time and do nothing on earlier devices.
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
};
private View mControlsView;
private final Runnable mShowPart2Runnable = new Runnable() {
@Override
public void run() {
// Delayed display of UI elements
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.show();
}
mControlsView.setVisibility(View.VISIBLE);
}
};
private boolean mVisible;
private final Runnable mHideRunnable = new Runnable() {
@Override
public void run() {
hide();
}
};
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
String[] perms = new String[1];
perms[0] = Manifest.permission.READ_EXTERNAL_STORAGE;
ActivityCompat.requestPermissions(this, perms,
1);
} else {
init();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (permissions[0] == Manifest.permission.READ_EXTERNAL_STORAGE)
init();
}
private void init() {
setContentView(R.layout.activity_pathfinder);
mVisible = true;
mControlsView = findViewById(R.id.fullscreen_content_controls);
mContentView = findViewById(R.id.fullscreen_content);
// Set up the user interaction to manually show or hide the system UI.
mContentView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toggle();
}
});
mContentView.setEGLContextClientVersion(3);
mContentView.setRenderer(new PathfinderDemoRenderer(getAssets()));
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
delayedHide(100);
}
private void toggle() {
if (mVisible) {
hide();
} else {
show();
}
}
private void hide() {
// Hide UI first
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
mControlsView.setVisibility(View.GONE);
mVisible = false;
// Schedule a runnable to remove the status and navigation bar after a delay
mHideHandler.removeCallbacks(mShowPart2Runnable);
mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
}
@SuppressLint("InlinedApi")
private void show() {
// Show the system bar
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mVisible = true;
// Schedule a runnable to display UI elements after a delay
mHideHandler.removeCallbacks(mHidePart2Runnable);
mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
}
/**
* Schedules a call to hide() in delay milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
}

View File

@ -0,0 +1,40 @@
package graphics.pathfinder.pathfinderdemo;
import android.content.res.AssetManager;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Renderer {
private AssetManager m_assetManager;
private static native void init(PathfinderDemoResourceLoader resourceLoader);
private static native void runOnce();
static {
System.loadLibrary("pathfinder_android_demo");
}
protected PathfinderDemoRenderer() {}
PathfinderDemoRenderer(AssetManager assetManager) {
super();
m_assetManager = assetManager;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
init(new PathfinderDemoResourceLoader(m_assetManager));
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onDrawFrame(GL10 gl) {
runOnce();
}
}

View File

@ -0,0 +1,15 @@
package graphics.pathfinder.pathfinderdemo;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
public class PathfinderDemoSurfaceView extends GLSurfaceView {
public PathfinderDemoSurfaceView(Context context) {
super(context);
}
public PathfinderDemoSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".PathfinderActivity">
<!-- The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView,
TextureView, etc. -->
<graphics.pathfinder.pathfinderdemo.PathfinderDemoSurfaceView
android:id="@+id/fullscreen_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true" />
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:id="@+id/fullscreen_content_controls"
style="?metaButtonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="@color/black_overlay"
android:orientation="horizontal"
tools:ignore="UselessParent">
</LinearLayout>
</FrameLayout>
</FrameLayout>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,12 @@
<resources>
<!-- Declare custom theme attributes that allow changing which styles are
used for button bars depending on the API level.
?android:attr/buttonBarStyle is new as of API 11 so this is
necessary to support previous API levels. -->
<declare-styleable name="ButtonBarContainerTheme">
<attr name="metaButtonBarStyle" format="reference" />
<attr name="metaButtonBarButtonStyle" format="reference" />
</declare-styleable>
</resources>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="black_overlay">#66000000</color>
</resources>

View File

@ -0,0 +1,6 @@
<resources>
<string name="app_name">Pathfinder Demo</string>
<string name="dummy_button">Dummy Button</string>
<string name="dummy_content">DUMMY\nCONTENT</string>
</resources>

View File

@ -0,0 +1,23 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="FullscreenTheme" parent="AppTheme">
<item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">@null</item>
<item name="metaButtonBarStyle">?android:attr/buttonBarStyle</item>
<item name="metaButtonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
</style>
<style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
<item name="android:background">@color/black_overlay</item>
</style>
</resources>

View File

@ -0,0 +1,17 @@
package graphics.pathfinder.pathfinderdemo;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

27
demo/android/build.gradle Normal file
View File

@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,14 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useDeprecatedNdk=true

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Fri Mar 08 12:48:37 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

172
demo/android/gradlew vendored Executable file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
demo/android/gradlew.bat vendored Normal file
View File

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,25 @@
[package]
name = "pathfinder_android_demo"
version = "0.1.0"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
edition = "2018"
[lib]
crate_type = ["cdylib"]
[dependencies]
egl = "0.2"
gl = "0.6"
jni = "0.11"
[dependencies.pathfinder_demo]
path = "../../common"
[dependencies.pathfinder_geometry]
path = "../../../geometry"
[dependencies.pathfinder_gl]
path = "../../../gl"
[dependencies.pathfinder_gpu]
path = "../../../gpu"

View File

@ -0,0 +1,143 @@
// pathfinder/demo/android/rust/src/main.rs
//
// Copyright © 2019 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use jni::{JNIEnv, JavaVM};
use jni::objects::{GlobalRef, JByteBuffer, JClass, JObject, JValue};
use pathfinder_demo::DemoApp;
use pathfinder_demo::window::{Event, Keycode, Window};
use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::ResourceLoader;
use std::cell::RefCell;
use std::io::Error as IOError;
use std::os::raw::c_void;
use std::path::PathBuf;
thread_local! {
static DEMO_APP: RefCell<Option<DemoApp<WindowImpl>>> = RefCell::new(None);
static JAVA_RESOURCE_LOADER: RefCell<Option<JavaResourceLoader>> = RefCell::new(None);
}
static RESOURCE_LOADER: AndroidResourceLoader = AndroidResourceLoader;
#[no_mangle]
pub unsafe extern "system" fn
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_init(env: JNIEnv,
class: JClass,
loader: JObject) {
JAVA_RESOURCE_LOADER.with(|java_resource_loader| {
*java_resource_loader.borrow_mut() = Some(JavaResourceLoader::new(env, loader))
});
DEMO_APP.with(|demo_app| *demo_app.borrow_mut() = Some(DemoApp::<WindowImpl>::new()));
}
#[no_mangle]
pub unsafe extern "system" fn
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_runOnce(env: JNIEnv,
class: JClass) {
DEMO_APP.with(|demo_app| {
if let Some(ref mut demo_app) = *demo_app.borrow_mut() {
demo_app.run_once(vec![]);
}
});
}
#[no_mangle]
pub unsafe extern "system" fn
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDown(env: JNIEnv,
class: JClass,
x: i32,
y: i32) {
}
struct WindowImpl;
impl Window for WindowImpl {
fn new(default_framebuffer_size: Point2DI32) -> WindowImpl {
gl::load_with(|name| egl::get_proc_address(name) as *const c_void);
WindowImpl
}
fn gl_version(&self) -> GLVersion {
GLVersion::GLES3
}
fn size(&self) -> Point2DI32 {
Point2DI32::new(1080, 1920)
}
fn drawable_size(&self) -> Point2DI32 {
Point2DI32::new(1080, 1920)
}
fn mouse_position(&self) -> Point2DI32 {
Point2DI32::new(0, 0)
}
fn present(&self) {}
fn resource_loader(&self) -> &dyn ResourceLoader {
&RESOURCE_LOADER
}
fn create_user_event_id(&self) -> u32 {
0
}
fn push_user_event(message_type: u32, message_data: u32) {
}
fn run_open_dialog(&self, extension: &str) -> Result<PathBuf, ()> {
// TODO(pcwalton)
Err(())
}
fn run_save_dialog(&self, extension: &str) -> Result<PathBuf, ()> {
// TODO(pcwalton)
Err(())
}
}
struct AndroidResourceLoader;
impl ResourceLoader for AndroidResourceLoader {
fn slurp(&self, path: &str) -> Result<Vec<u8>, IOError> {
JAVA_RESOURCE_LOADER.with(|java_resource_loader| {
let java_resource_loader = java_resource_loader.borrow();
let java_resource_loader = java_resource_loader.as_ref().unwrap();
let loader = java_resource_loader.loader.as_obj();
let env = java_resource_loader.vm.get_env().unwrap();
match env.call_method(loader,
"slurp",
"(Ljava/lang/String;)Ljava/nio/ByteBuffer;",
&[JValue::Object(*env.new_string(path).unwrap())]).unwrap() {
JValue::Object(object) => {
let byte_buffer = JByteBuffer::from(object);
Ok(Vec::from(env.get_direct_buffer_address(byte_buffer).unwrap()))
}
_ => panic!("Unexpected return value!"),
}
})
}
}
struct JavaResourceLoader {
loader: GlobalRef,
vm: JavaVM,
}
impl JavaResourceLoader {
fn new(env: JNIEnv, loader: JObject) -> JavaResourceLoader {
JavaResourceLoader {
loader: env.new_global_ref(loader).unwrap(),
vm: env.get_java_vm().unwrap(),
}
}
}

View File

@ -0,0 +1 @@
include ':app'

View File

@ -8,7 +8,6 @@ authors = ["Patrick Walton <pcwalton@mimiga.net>"]
clap = "2.32" clap = "2.32"
gl = "0.6" gl = "0.6"
jemallocator = "0.1" jemallocator = "0.1"
nfd = "0.0.4"
rayon = "1.0" rayon = "1.0"
usvg = "0.4" usvg = "0.4"

View File

@ -11,7 +11,8 @@
//! GPU rendering code specifically for the demo. //! GPU rendering code specifically for the demo.
use crate::GRIDLINE_COUNT; use crate::GRIDLINE_COUNT;
use pathfinder_gpu::{BufferTarget, BufferUploadMode, Device, Resources, VertexAttrType}; use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BufferTarget, BufferUploadMode, Device, VertexAttrType};
pub struct GroundProgram<D> where D: Device { pub struct GroundProgram<D> where D: Device {
pub program: D::Program, pub program: D::Program,
@ -20,7 +21,7 @@ pub struct GroundProgram<D> where D: Device {
} }
impl<D> GroundProgram<D> where D: Device { impl<D> GroundProgram<D> where D: Device {
pub fn new(device: &D, resources: &Resources) -> GroundProgram<D> { pub fn new(device: &D, resources: &dyn ResourceLoader) -> GroundProgram<D> {
let program = device.create_program(resources, "demo_ground"); let program = device.create_program(resources, "demo_ground");
let transform_uniform = device.get_uniform(&program, "Transform"); let transform_uniform = device.get_uniform(&program, "Transform");
let color_uniform = device.get_uniform(&program, "Color"); let color_uniform = device.get_uniform(&program, "Color");

View File

@ -22,8 +22,9 @@ use pathfinder_geometry::basic::transform2d::Transform2DF32;
use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32}; use pathfinder_geometry::basic::transform3d::{Perspective, Transform3DF32};
use pathfinder_geometry::color::ColorU; use pathfinder_geometry::color::ColorU;
use pathfinder_gl::GLDevice; use pathfinder_gl::GLDevice;
use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, Resources}; use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{StencilFunc, StencilState, UniformData}; use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc};
use pathfinder_gpu::{StencilState, UniformData};
use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder}; use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder};
use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::gpu_data::BuiltScene; use pathfinder_renderer::gpu_data::BuiltScene;
@ -34,6 +35,9 @@ use pathfinder_svg::BuiltSVG;
use pathfinder_ui::UIEvent; use pathfinder_ui::UIEvent;
use rayon::ThreadPoolBuilder; use rayon::ThreadPoolBuilder;
use std::f32::consts::FRAC_PI_4; use std::f32::consts::FRAC_PI_4;
use std::ffi::CString;
use std::fs::File;
use std::io::Read;
use std::mem; use std::mem;
use std::panic; use std::panic;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -46,7 +50,7 @@ use usvg::{Options as UsvgOptions, Tree};
#[global_allocator] #[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
static DEFAULT_SVG_FILENAME: &'static str = "Ghostscript_Tiger.svg"; static DEFAULT_SVG_VIRTUAL_PATH: &'static str = "svg/Ghostscript_Tiger.svg";
const MAIN_FRAMEBUFFER_WIDTH: u32 = 1067; const MAIN_FRAMEBUFFER_WIDTH: u32 = 1067;
const MAIN_FRAMEBUFFER_HEIGHT: u32 = 800; const MAIN_FRAMEBUFFER_HEIGHT: u32 = 800;
@ -111,18 +115,18 @@ impl<W> DemoApp<W> where W: Window {
let window = W::new(default_framebuffer_size); let window = W::new(default_framebuffer_size);
let expire_message_event_id = window.create_user_event_id(); let expire_message_event_id = window.create_user_event_id();
let device = GLDevice::new(); let device = GLDevice::new(window.gl_version());
let resources = Resources::locate(); let resources = window.resource_loader();
let options = Options::get(&resources); let options = Options::get(resources);
let (window_size, drawable_size) = (window.size(), window.drawable_size()); let (window_size, drawable_size) = (window.size(), window.drawable_size());
let built_svg = load_scene(&options.input_path); let built_svg = load_scene(resources, &options.input_path);
let message = get_svg_building_message(&built_svg); let message = get_svg_building_message(&built_svg);
let scene_view_box = built_svg.scene.view_box; let scene_view_box = built_svg.scene.view_box;
let scene_is_monochrome = built_svg.scene.is_monochrome(); let scene_is_monochrome = built_svg.scene.is_monochrome();
let renderer = Renderer::new(device, &resources, drawable_size); let renderer = Renderer::new(device, resources, drawable_size);
let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone()); let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone());
scene_thread_proxy.set_drawable_size(window.drawable_size()); scene_thread_proxy.set_drawable_size(window.drawable_size());
@ -132,7 +136,7 @@ impl<W> DemoApp<W> where W: Window {
Camera::new_2d(scene_view_box, drawable_size) Camera::new_2d(scene_view_box, drawable_size)
}; };
let ground_program = GroundProgram::new(&renderer.device, &resources); let ground_program = GroundProgram::new(&renderer.device, resources);
let ground_solid_vertex_array = let ground_solid_vertex_array =
GroundSolidVertexArray::new(&renderer.device, GroundSolidVertexArray::new(&renderer.device,
&ground_program, &ground_program,
@ -140,7 +144,7 @@ impl<W> DemoApp<W> where W: Window {
let ground_line_vertex_array = GroundLineVertexArray::new(&renderer.device, let ground_line_vertex_array = GroundLineVertexArray::new(&renderer.device,
&ground_program); &ground_program);
let mut ui = DemoUI::new(&renderer.device, &resources, options); let mut ui = DemoUI::new(&renderer.device, resources, options);
let mut message_epoch = 0; let mut message_epoch = 0;
emit_message::<W>(&mut ui, &mut message_epoch, expire_message_event_id, message); emit_message::<W>(&mut ui, &mut message_epoch, expire_message_event_id, message);
@ -341,7 +345,10 @@ impl<W> DemoApp<W> where W: Window {
self.ui.show_text_effects = self.scene_is_monochrome; self.ui.show_text_effects = self.scene_is_monochrome;
let mut ui_action = UIAction::None; let mut ui_action = UIAction::None;
self.ui.update(&self.renderer.device, &mut self.renderer.debug_ui, &mut ui_action); self.ui.update(&self.renderer.device,
&self.window,
&mut self.renderer.debug_ui,
&mut ui_action);
ui_event = mem::replace(&mut self.renderer.debug_ui.ui.event, UIEvent::None); ui_event = mem::replace(&mut self.renderer.debug_ui.ui.event, UIEvent::None);
self.handle_ui_action(&mut ui_action); self.handle_ui_action(&mut ui_action);
@ -469,7 +476,7 @@ impl<W> DemoApp<W> where W: Window {
UIAction::None => {} UIAction::None => {}
UIAction::OpenFile(ref path) => { UIAction::OpenFile(ref path) => {
let built_svg = load_scene(&path); let built_svg = load_scene(self.window.resource_loader(), &Some((*path).clone()));
self.ui.message = get_svg_building_message(&built_svg); self.ui.message = get_svg_building_message(&built_svg);
self.scene_view_box = built_svg.scene.view_box; self.scene_view_box = built_svg.scene.view_box;
@ -620,11 +627,11 @@ enum SceneToMainMsg {
pub struct Options { pub struct Options {
jobs: Option<usize>, jobs: Option<usize>,
three_d: bool, three_d: bool,
input_path: PathBuf, input_path: Option<PathBuf>,
} }
impl Options { impl Options {
fn get(resources: &Resources) -> Options { fn get(resources: &dyn ResourceLoader) -> Options {
let matches = App::new("tile-svg") let matches = App::new("tile-svg")
.arg( .arg(
Arg::with_name("jobs") Arg::with_name("jobs")
@ -643,15 +650,7 @@ impl Options {
.map(|string| string.parse().unwrap()); .map(|string| string.parse().unwrap());
let three_d = matches.is_present("3d"); let three_d = matches.is_present("3d");
let input_path = match matches.value_of("INPUT") { let input_path = matches.value_of("INPUT").map(PathBuf::from);
Some(path) => PathBuf::from(path),
None => {
let mut path = resources.resources_directory.clone();
path.push("svg");
path.push(DEFAULT_SVG_FILENAME);
path
}
};
// Set up Rayon. // Set up Rayon.
let mut thread_pool_builder = ThreadPoolBuilder::new(); let mut thread_pool_builder = ThreadPoolBuilder::new();
@ -664,8 +663,21 @@ impl Options {
} }
} }
fn load_scene(input_path: &Path) -> BuiltSVG { fn load_scene(resource_loader: &dyn ResourceLoader, input_path: &Option<PathBuf>) -> BuiltSVG {
BuiltSVG::from_tree(Tree::from_file(input_path, &UsvgOptions::default()).unwrap()) let mut data;
match *input_path {
Some(ref input_path) => {
data = vec![];
let mut file = match File::open(input_path) {
Ok(file) => file,
Err(err) => panic!(),
};
file.read_to_end(&mut data).unwrap();
}
None => data = resource_loader.slurp(DEFAULT_SVG_VIRTUAL_PATH).unwrap(),
}
BuiltSVG::from_tree(Tree::from_data(&data, &UsvgOptions::default()).unwrap())
} }
fn build_scene(scene: &Scene, build_options: BuildOptions, jobs: Option<usize>) -> BuiltScene { fn build_scene(scene: &Scene, build_options: BuildOptions, jobs: Option<usize>) -> BuiltScene {

View File

@ -9,10 +9,11 @@
// except according to those terms. // except according to those terms.
use crate::Options; use crate::Options;
use nfd::Response; use crate::window::Window;
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_geometry::basic::rect::RectI32; use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_gpu::{Device, Resources}; use pathfinder_gpu::Device;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_renderer::gpu::debug::DebugUI; use pathfinder_renderer::gpu::debug::DebugUI;
use pathfinder_ui::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, FONT_ASCENT, PADDING}; use pathfinder_ui::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, FONT_ASCENT, PADDING};
use pathfinder_ui::{SWITCH_SIZE, TEXT_COLOR, TOOLTIP_HEIGHT, WINDOW_COLOR}; use pathfinder_ui::{SWITCH_SIZE, TEXT_COLOR, TOOLTIP_HEIGHT, WINDOW_COLOR};
@ -66,7 +67,7 @@ pub struct DemoUI<D> where D: Device {
} }
impl<D> DemoUI<D> where D: Device { impl<D> DemoUI<D> where D: Device {
pub fn new(device: &D, resources: &Resources, options: Options) -> DemoUI<D> { pub fn new(device: &D, resources: &dyn ResourceLoader, options: Options) -> DemoUI<D> {
let effects_texture = device.create_texture_from_png(resources, EFFECTS_PNG_NAME); let effects_texture = device.create_texture_from_png(resources, EFFECTS_PNG_NAME);
let open_texture = device.create_texture_from_png(resources, OPEN_PNG_NAME); let open_texture = device.create_texture_from_png(resources, OPEN_PNG_NAME);
let rotate_texture = device.create_texture_from_png(resources, ROTATE_PNG_NAME); let rotate_texture = device.create_texture_from_png(resources, ROTATE_PNG_NAME);
@ -104,7 +105,12 @@ impl<D> DemoUI<D> where D: Device {
(self.rotation as f32 / SLIDER_WIDTH as f32 * 2.0 - 1.0) * PI (self.rotation as f32 / SLIDER_WIDTH as f32 * 2.0 - 1.0) * PI
} }
pub fn update(&mut self, device: &D, debug_ui: &mut DebugUI<D>, action: &mut UIAction) { pub fn update<W>(&mut self,
device: &D,
window: &W,
debug_ui: &mut DebugUI<D>,
action: &mut UIAction)
where W: Window {
// Draw message text. // Draw message text.
self.draw_message_text(device, debug_ui); self.draw_message_text(device, debug_ui);
@ -132,8 +138,10 @@ impl<D> DemoUI<D> where D: Device {
// Draw open button. // Draw open button.
if debug_ui.ui.draw_button(device, position, &self.open_texture) { if debug_ui.ui.draw_button(device, position, &self.open_texture) {
if let Ok(Response::Okay(file)) = nfd::open_file_dialog(Some("svg"), None) { // FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
*action = UIAction::OpenFile(PathBuf::from(file)); // the contents of the file.
if let Ok(file) = window.run_open_dialog("svg") {
*action = UIAction::OpenFile(file);
} }
} }
debug_ui.ui.draw_tooltip(device, "Open SVG", RectI32::new(position, button_size)); debug_ui.ui.draw_tooltip(device, "Open SVG", RectI32::new(position, button_size));
@ -141,8 +149,10 @@ impl<D> DemoUI<D> where D: Device {
// Draw screenshot button. // Draw screenshot button.
if debug_ui.ui.draw_button(device, position, &self.screenshot_texture) { if debug_ui.ui.draw_button(device, position, &self.screenshot_texture) {
if let Ok(Response::Okay(file)) = nfd::open_save_dialog(Some("png"), None) { // FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
*action = UIAction::TakeScreenshot(PathBuf::from(file)); // the contents of the file.
if let Ok(file) = window.run_save_dialog("png") {
*action = UIAction::TakeScreenshot(file);
} }
} }
debug_ui.ui.draw_tooltip(device, "Take Screenshot", RectI32::new(position, button_size)); debug_ui.ui.draw_tooltip(device, "Take Screenshot", RectI32::new(position, button_size));

View File

@ -11,15 +11,23 @@
//! A minimal cross-platform windowing layer. //! A minimal cross-platform windowing layer.
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::ResourceLoader;
use std::io::Error;
use std::path::PathBuf;
pub trait Window { pub trait Window {
fn new(initial_size: Point2DI32) -> Self; fn new(initial_size: Point2DI32) -> Self;
fn gl_version(&self) -> GLVersion;
fn size(&self) -> Point2DI32; fn size(&self) -> Point2DI32;
fn drawable_size(&self) -> Point2DI32; fn drawable_size(&self) -> Point2DI32;
fn mouse_position(&self) -> Point2DI32; fn mouse_position(&self) -> Point2DI32;
fn present(&self); fn present(&self);
fn resource_loader(&self) -> &dyn ResourceLoader;
fn create_user_event_id(&self) -> u32; fn create_user_event_id(&self) -> u32;
fn push_user_event(message_type: u32, message_data: u32); fn push_user_event(message_type: u32, message_data: u32);
fn run_open_dialog(&self, extension: &str) -> Result<PathBuf, ()>;
fn run_save_dialog(&self, extension: &str) -> Result<PathBuf, ()>;
} }
pub enum Event { pub enum Event {

View File

@ -9,6 +9,7 @@ pf-no-simd = ["pathfinder_simd/pf-no-simd"]
[dependencies] [dependencies]
gl = "0.6" gl = "0.6"
nfd = "0.0.4"
sdl2 = "0.32" sdl2 = "0.32"
sdl2-sys = "0.32" sdl2-sys = "0.32"
@ -18,5 +19,11 @@ path = "../common"
[dependencies.pathfinder_geometry] [dependencies.pathfinder_geometry]
path = "../../geometry" path = "../../geometry"
[dependencies.pathfinder_gl]
path = "../../gl"
[dependencies.pathfinder_gpu]
path = "../../gpu"
[dependencies.pathfinder_simd] [dependencies.pathfinder_simd]
path = "../../simd" path = "../../simd"

View File

@ -10,14 +10,18 @@
//! A demo app for Pathfinder using SDL 2. //! A demo app for Pathfinder using SDL 2.
use nfd::Response;
use pathfinder_demo::DemoApp; use pathfinder_demo::DemoApp;
use pathfinder_demo::window::{Event, Keycode, Window}; use pathfinder_demo::window::{Event, Keycode, Window};
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
use sdl2::{EventPump, EventSubsystem, Sdl, VideoSubsystem}; use sdl2::{EventPump, EventSubsystem, Sdl, VideoSubsystem};
use sdl2::event::{Event as SDLEvent, WindowEvent}; use sdl2::event::{Event as SDLEvent, WindowEvent};
use sdl2::keyboard::Keycode as SDLKeycode; use sdl2::keyboard::Keycode as SDLKeycode;
use sdl2::video::{GLContext, GLProfile, Window as SDLWindow}; use sdl2::video::{GLContext, GLProfile, Window as SDLWindow};
use sdl2_sys::{SDL_Event, SDL_UserEvent}; use sdl2_sys::{SDL_Event, SDL_UserEvent};
use std::path::PathBuf;
use std::ptr; use std::ptr;
fn main() { fn main() {
@ -42,6 +46,7 @@ struct WindowImpl {
event_pump: EventPump, event_pump: EventPump,
#[allow(dead_code)] #[allow(dead_code)]
gl_context: GLContext, gl_context: GLContext,
resource_loader: FilesystemResourceLoader,
} }
impl Window for WindowImpl { impl Window for WindowImpl {
@ -69,10 +74,16 @@ impl Window for WindowImpl {
event_pump = SDL_CONTEXT.with(|sdl_context| sdl_context.event_pump().unwrap()); event_pump = SDL_CONTEXT.with(|sdl_context| sdl_context.event_pump().unwrap());
WindowImpl { window, event_pump, gl_context } let resource_loader = FilesystemResourceLoader::locate();
WindowImpl { window, event_pump, gl_context, resource_loader }
}) })
} }
fn gl_version(&self) -> GLVersion {
GLVersion::GL3
}
fn size(&self) -> Point2DI32 { fn size(&self) -> Point2DI32 {
let (width, height) = self.window.size(); let (width, height) = self.window.size();
Point2DI32::new(width as i32, height as i32) Point2DI32::new(width as i32, height as i32)
@ -92,6 +103,10 @@ impl Window for WindowImpl {
self.window.gl_swap_window(); self.window.gl_swap_window();
} }
fn resource_loader(&self) -> &dyn ResourceLoader {
&self.resource_loader
}
fn create_user_event_id(&self) -> u32 { fn create_user_event_id(&self) -> u32 {
SDL_EVENT.with(|sdl_event| unsafe { sdl_event.register_event().unwrap() }) SDL_EVENT.with(|sdl_event| unsafe { sdl_event.register_event().unwrap() })
} }
@ -109,6 +124,20 @@ impl Window for WindowImpl {
sdl2_sys::SDL_PushEvent(&mut user_event as *mut SDL_UserEvent as *mut SDL_Event); sdl2_sys::SDL_PushEvent(&mut user_event as *mut SDL_UserEvent as *mut SDL_Event);
} }
} }
fn run_open_dialog(&self, extension: &str) -> Result<PathBuf, ()> {
match nfd::open_file_dialog(Some(extension), None) {
Ok(Response::Okay(file)) => Ok(PathBuf::from(file)),
_ => Err(()),
}
}
fn run_save_dialog(&self, extension: &str) -> Result<PathBuf, ()> {
match nfd::open_save_dialog(Some(extension), None) {
Ok(Response::Okay(file)) => Ok(PathBuf::from(file)),
_ => Err(()),
}
}
} }
impl WindowImpl { impl WindowImpl {

View File

@ -6,6 +6,7 @@ authors = ["Patrick Walton <pcwalton@mimiga.net>"]
[dependencies] [dependencies]
gl = "0.6" gl = "0.6"
rustache = "0.1"
[dependencies.image] [dependencies.image]
version = "0.21" version = "0.21"

View File

@ -10,23 +10,29 @@
//! An OpenGL implementation of the device abstraction. //! An OpenGL implementation of the device abstraction.
use gl::types::{GLboolean, GLchar, GLdouble, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr}; use gl::types::{GLboolean, GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
use gl::types::{GLuint, GLvoid};
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_gpu::{BlendState, BufferTarget, BufferUploadMode, DepthFunc, Device, Primitive}; use pathfinder_gpu::{BlendState, BufferTarget, BufferUploadMode, DepthFunc, Device, Primitive};
use pathfinder_gpu::{RenderState, ShaderKind, StencilFunc, TextureFormat}; use pathfinder_gpu::{RenderState, ShaderKind, StencilFunc, TextureFormat};
use pathfinder_gpu::{UniformData, VertexAttrType}; use pathfinder_gpu::{UniformData, VertexAttrType};
use pathfinder_simd::default::F32x4; use pathfinder_simd::default::F32x4;
use rustache::{HashBuilder, Render};
use std::ffi::CString; use std::ffi::CString;
use std::io::Cursor;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use std::str;
use std::time::Duration; use std::time::Duration;
pub struct GLDevice; pub struct GLDevice {
version: GLVersion,
}
impl GLDevice { impl GLDevice {
#[inline] #[inline]
pub fn new() -> GLDevice { GLDevice } pub fn new(version: GLVersion) -> GLDevice {
GLDevice { version }
}
fn set_texture_parameters(&self, texture: &GLTexture) { fn set_texture_parameters(&self, texture: &GLTexture) {
self.bind_texture(texture, 0); self.bind_texture(texture, 0);
@ -189,7 +195,7 @@ impl Device for GLDevice {
self.bind_texture(&texture, 0); self.bind_texture(&texture, 0);
gl::TexImage2D(gl::TEXTURE_2D, gl::TexImage2D(gl::TEXTURE_2D,
0, 0,
gl::RED as GLint, gl::R8 as GLint,
size.x() as GLsizei, size.x() as GLsizei,
size.y() as GLsizei, size.y() as GLsizei,
0, 0,
@ -203,6 +209,12 @@ impl Device for GLDevice {
} }
fn create_shader_from_source(&self, name: &str, source: &[u8], kind: ShaderKind) -> GLShader { fn create_shader_from_source(&self, name: &str, source: &[u8], kind: ShaderKind) -> GLShader {
let glsl_version_spec = self.version.to_glsl_version_spec();
let template_input = HashBuilder::new().insert("version", glsl_version_spec);
let mut output = Cursor::new(vec![]);
template_input.render(str::from_utf8(source).unwrap(), &mut output).unwrap();
let source = output.into_inner();
let gl_shader_kind = match kind { let gl_shader_kind = match kind {
ShaderKind::Vertex => gl::VERTEX_SHADER, ShaderKind::Vertex => gl::VERTEX_SHADER,
ShaderKind::Fragment => gl::FRAGMENT_SHADER, ShaderKind::Fragment => gl::FRAGMENT_SHADER,
@ -361,7 +373,6 @@ impl Device for GLDevice {
let mut gl_framebuffer = 0; let mut gl_framebuffer = 0;
unsafe { unsafe {
gl::GenFramebuffers(1, &mut gl_framebuffer); ck(); gl::GenFramebuffers(1, &mut gl_framebuffer); ck();
assert_eq!(gl::GetError(), gl::NO_ERROR);
gl::BindFramebuffer(gl::FRAMEBUFFER, gl_framebuffer); ck(); gl::BindFramebuffer(gl::FRAMEBUFFER, gl_framebuffer); ck();
self.bind_texture(&texture, 0); self.bind_texture(&texture, 0);
gl::FramebufferTexture2D(gl::FRAMEBUFFER, gl::FramebufferTexture2D(gl::FRAMEBUFFER,
@ -469,7 +480,7 @@ impl Device for GLDevice {
} }
if let Some(depth) = depth { if let Some(depth) = depth {
gl::DepthMask(gl::TRUE); ck(); gl::DepthMask(gl::TRUE); ck();
gl::ClearDepth(depth as GLdouble); ck(); gl::ClearDepthf(depth as _); ck(); // FIXME(pcwalton): GLES
flags |= gl::DEPTH_BUFFER_BIT; flags |= gl::DEPTH_BUFFER_BIT;
} }
if let Some(stencil) = stencil { if let Some(stencil) = stencil {
@ -797,6 +808,23 @@ impl VertexAttrTypeExt for VertexAttrType {
} }
} }
/// The version/dialect of OpenGL we should render with.
pub enum GLVersion {
/// OpenGL 3.0+, core profile.
GL3,
/// OpenGL ES 3.0+.
GLES3,
}
impl GLVersion {
fn to_glsl_version_spec(&self) -> &'static str {
match *self {
GLVersion::GL3 => "330",
GLVersion::GLES3 => "300 es",
}
}
}
// Error checking // Error checking
#[cfg(debug)] #[cfg(debug)]

View File

@ -10,6 +10,8 @@
//! Minimal abstractions over GPU device capabilities. //! Minimal abstractions over GPU device capabilities.
use crate::resources::ResourceLoader;
use image::ImageFormat;
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_simd::default::F32x4; use pathfinder_simd::default::F32x4;
use std::env; use std::env;
@ -18,6 +20,8 @@ use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::Duration; use std::time::Duration;
pub mod resources;
pub trait Device { pub trait Device {
type Buffer; type Buffer;
type Framebuffer; type Framebuffer;
@ -91,28 +95,22 @@ pub trait Device {
fn bind_framebuffer(&self, framebuffer: &Self::Framebuffer); fn bind_framebuffer(&self, framebuffer: &Self::Framebuffer);
fn bind_texture(&self, texture: &Self::Texture, unit: u32); fn bind_texture(&self, texture: &Self::Texture, unit: u32);
fn create_texture_from_png(&self, resources: &Resources, name: &str) -> Self::Texture { fn create_texture_from_png(&self, resources: &dyn ResourceLoader, name: &str)
let mut path = resources.resources_directory.clone(); -> Self::Texture {
path.push("textures"); let data = resources.slurp(&format!("textures/{}.png", name)).unwrap();
path.push(format!("{}.png", name)); let image = image::load_from_memory_with_format(&data, ImageFormat::PNG).unwrap().to_luma();
let image = image::open(&path).unwrap().to_luma();
let size = Point2DI32::new(image.width() as i32, image.height() as i32); let size = Point2DI32::new(image.width() as i32, image.height() as i32);
self.create_texture_from_data(size, &image) self.create_texture_from_data(size, &image)
} }
fn create_shader(&self, resources: &Resources, name: &str, kind: ShaderKind) -> Self::Shader { fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind)
-> Self::Shader {
let suffix = match kind { ShaderKind::Vertex => 'v', ShaderKind::Fragment => 'f' }; let suffix = match kind { ShaderKind::Vertex => 'v', ShaderKind::Fragment => 'f' };
let mut path = resources.resources_directory.clone(); let source = resources.slurp(&format!("shaders/{}.{}s.glsl", name, suffix)).unwrap();
path.push("shaders");
path.push(format!("{}.{}s.glsl", name, suffix));
let mut source = vec![];
File::open(&path).unwrap().read_to_end(&mut source).unwrap();
self.create_shader_from_source(name, &source, kind) self.create_shader_from_source(name, &source, kind)
} }
fn create_program(&self, resources: &Resources, name: &str) -> Self::Program { fn create_program(&self, resources: &dyn ResourceLoader, name: &str) -> Self::Program {
let vertex_shader = self.create_shader(resources, name, ShaderKind::Vertex); let vertex_shader = self.create_shader(resources, name, ShaderKind::Vertex);
let fragment_shader = self.create_shader(resources, name, ShaderKind::Fragment); let fragment_shader = self.create_shader(resources, name, ShaderKind::Fragment);
self.create_program_from_shaders(name, vertex_shader, fragment_shader) self.create_program_from_shaders(name, vertex_shader, fragment_shader)
@ -243,33 +241,3 @@ impl Default for StencilFunc {
StencilFunc::Always StencilFunc::Always
} }
} }
pub struct Resources {
pub resources_directory: PathBuf,
}
impl Resources {
pub fn locate() -> Resources {
let mut parent_directory = env::current_dir().unwrap();
loop {
// So ugly :(
let mut resources_directory = parent_directory.clone();
resources_directory.push("resources");
if resources_directory.is_dir() {
let mut shaders_directory = resources_directory.clone();
let mut textures_directory = resources_directory.clone();
shaders_directory.push("shaders");
textures_directory.push("textures");
if shaders_directory.is_dir() && textures_directory.is_dir() {
return Resources { resources_directory };
}
}
if !parent_directory.pop() {
break;
}
}
panic!("No suitable `resources/` directory found!");
}
}

70
gpu/src/resources.rs Normal file
View File

@ -0,0 +1,70 @@
// pathfinder/gpu/src/resources.rs
//
// Copyright © 2019 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! An abstraction for reading resources.
//!
//! We can't always count on a filesystem being present.
use crate::ShaderKind;
use std::env;
use std::fs::File;
use std::io::{Error as IOError, Read};
use std::path::PathBuf;
pub trait ResourceLoader {
/// This is deliberately not a `Path`, because these are virtual paths
/// that do not necessarily correspond to real paths on a filesystem.
fn slurp(&self, path: &str) -> Result<Vec<u8>, IOError>;
}
pub struct FilesystemResourceLoader {
pub directory: PathBuf,
}
impl FilesystemResourceLoader {
pub fn new(root: PathBuf) -> FilesystemResourceLoader {
let mut parent_directory = env::current_dir().unwrap();
loop {
// So ugly :(
let mut resources_directory = parent_directory.clone();
resources_directory.push("resources");
if resources_directory.is_dir() {
let mut shaders_directory = resources_directory.clone();
let mut textures_directory = resources_directory.clone();
shaders_directory.push("shaders");
textures_directory.push("textures");
if shaders_directory.is_dir() && textures_directory.is_dir() {
return FilesystemResourceLoader { directory: resources_directory };
}
}
if !parent_directory.pop() {
break;
}
}
panic!("No suitable `resources/` directory found!");
}
pub fn locate() -> FilesystemResourceLoader {
FilesystemResourceLoader::new(env::current_dir().unwrap())
}
}
impl ResourceLoader for FilesystemResourceLoader {
fn slurp(&self, virtual_path: &str) -> Result<Vec<u8>, IOError> {
let mut path = self.directory.clone();
virtual_path.split('/').for_each(|segment| path.push(segment));
let mut data = vec![];
File::open(&path)?.read_to_end(&mut data)?;
Ok(data)
}
}

View File

@ -18,7 +18,8 @@
use crate::gpu_data::Stats; use crate::gpu_data::Stats;
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_geometry::basic::rect::RectI32; use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_gpu::{Device, Resources}; use pathfinder_gpu::Device;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UI, WINDOW_COLOR}; use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UI, WINDOW_COLOR};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::ops::{Add, Div}; use std::ops::{Add, Div};
@ -37,7 +38,8 @@ pub struct DebugUI<D> where D: Device {
} }
impl<D> DebugUI<D> where D: Device { impl<D> DebugUI<D> where D: Device {
pub fn new(device: &D, resources: &Resources, framebuffer_size: Point2DI32) -> DebugUI<D> { pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Point2DI32)
-> DebugUI<D> {
let ui = UI::new(device, resources, framebuffer_size); let ui = UI::new(device, resources, framebuffer_size);
DebugUI { ui, cpu_samples: SampleBuffer::new(), gpu_samples: SampleBuffer::new() } DebugUI { ui, cpu_samples: SampleBuffer::new(), gpu_samples: SampleBuffer::new() }
} }

View File

@ -15,8 +15,9 @@ use crate::scene::ObjectShader;
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32}; use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32};
use pathfinder_geometry::color::ColorU; use pathfinder_geometry::color::ColorU;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendState, BufferTarget, BufferUploadMode, DepthFunc, DepthState, Device}; use pathfinder_gpu::{BlendState, BufferTarget, BufferUploadMode, DepthFunc, DepthState, Device};
use pathfinder_gpu::{Primitive, RenderState, Resources, StencilFunc, StencilState, TextureFormat}; use pathfinder_gpu::{Primitive, RenderState, StencilFunc, StencilState, TextureFormat};
use pathfinder_gpu::{UniformData, VertexAttrType}; use pathfinder_gpu::{UniformData, VertexAttrType};
use pathfinder_simd::default::{F32x4, I32x4}; use pathfinder_simd::default::{F32x4, I32x4};
use std::collections::VecDeque; use std::collections::VecDeque;
@ -73,17 +74,17 @@ pub struct Renderer<D> where D: Device {
} }
impl<D> Renderer<D> where D: Device { impl<D> Renderer<D> where D: Device {
pub fn new(device: D, resources: &Resources, main_framebuffer_size: Point2DI32) pub fn new(device: D, resources: &dyn ResourceLoader, main_framebuffer_size: Point2DI32)
-> Renderer<D> { -> Renderer<D> {
let fill_program = FillProgram::new(&device, &resources); let fill_program = FillProgram::new(&device, resources);
let solid_tile_program = SolidTileProgram::new(&device, &resources); let solid_tile_program = SolidTileProgram::new(&device, resources);
let mask_tile_program = MaskTileProgram::new(&device, &resources); let mask_tile_program = MaskTileProgram::new(&device, resources);
let postprocess_program = PostprocessProgram::new(&device, &resources); let postprocess_program = PostprocessProgram::new(&device, resources);
let stencil_program = StencilProgram::new(&device, &resources); let stencil_program = StencilProgram::new(&device, resources);
let area_lut_texture = device.create_texture_from_png(&resources, "area-lut"); let area_lut_texture = device.create_texture_from_png(resources, "area-lut");
let gamma_lut_texture = device.create_texture_from_png(&resources, "gamma-lut"); let gamma_lut_texture = device.create_texture_from_png(resources, "gamma-lut");
let quad_vertex_positions_buffer = device.create_buffer(); let quad_vertex_positions_buffer = device.create_buffer();
device.upload_to_buffer(&quad_vertex_positions_buffer, device.upload_to_buffer(&quad_vertex_positions_buffer,
@ -115,7 +116,7 @@ impl<D> Renderer<D> where D: Device {
FILL_COLORS_TEXTURE_HEIGHT); FILL_COLORS_TEXTURE_HEIGHT);
let fill_colors_texture = device.create_texture(TextureFormat::RGBA8, fill_colors_size); let fill_colors_texture = device.create_texture(TextureFormat::RGBA8, fill_colors_size);
let debug_ui = DebugUI::new(&device, &resources, main_framebuffer_size); let debug_ui = DebugUI::new(&device, resources, main_framebuffer_size);
Renderer { Renderer {
device, device,
@ -653,7 +654,7 @@ struct FillProgram<D> where D: Device {
} }
impl<D> FillProgram<D> where D: Device { impl<D> FillProgram<D> where D: Device {
fn new(device: &D, resources: &Resources) -> FillProgram<D> { fn new(device: &D, resources: &dyn ResourceLoader) -> FillProgram<D> {
let program = device.create_program(resources, "fill"); let program = device.create_program(resources, "fill");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let tile_size_uniform = device.get_uniform(&program, "TileSize"); let tile_size_uniform = device.get_uniform(&program, "TileSize");
@ -672,7 +673,7 @@ struct SolidTileProgram<D> where D: Device {
} }
impl<D> SolidTileProgram<D> where D: Device { impl<D> SolidTileProgram<D> where D: Device {
fn new(device: &D, resources: &Resources) -> SolidTileProgram<D> { fn new(device: &D, resources: &dyn ResourceLoader) -> SolidTileProgram<D> {
let program = device.create_program(resources, "solid_tile"); let program = device.create_program(resources, "solid_tile");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let tile_size_uniform = device.get_uniform(&program, "TileSize"); let tile_size_uniform = device.get_uniform(&program, "TileSize");
@ -703,7 +704,7 @@ struct MaskTileProgram<D> where D: Device {
} }
impl<D> MaskTileProgram<D> where D: Device { impl<D> MaskTileProgram<D> where D: Device {
fn new(device: &D, resources: &Resources) -> MaskTileProgram<D> { fn new(device: &D, resources: &dyn ResourceLoader) -> MaskTileProgram<D> {
let program = device.create_program(resources, "mask_tile"); let program = device.create_program(resources, "mask_tile");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let tile_size_uniform = device.get_uniform(&program, "TileSize"); let tile_size_uniform = device.get_uniform(&program, "TileSize");
@ -736,7 +737,7 @@ struct PostprocessProgram<D> where D: Device {
} }
impl<D> PostprocessProgram<D> where D: Device { impl<D> PostprocessProgram<D> where D: Device {
fn new(device: &D, resources: &Resources) -> PostprocessProgram<D> { fn new(device: &D, resources: &dyn ResourceLoader) -> PostprocessProgram<D> {
let program = device.create_program(resources, "post"); let program = device.create_program(resources, "post");
let source_uniform = device.get_uniform(&program, "Source"); let source_uniform = device.get_uniform(&program, "Source");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
@ -787,7 +788,7 @@ struct StencilProgram<D> where D: Device {
} }
impl<D> StencilProgram<D> where D: Device { impl<D> StencilProgram<D> where D: Device {
fn new(device: &D, resources: &Resources) -> StencilProgram<D> { fn new(device: &D, resources: &dyn ResourceLoader) -> StencilProgram<D> {
let program = device.create_program(resources, "stencil"); let program = device.create_program(resources, "stencil");
StencilProgram { program } StencilProgram { program }
} }

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/shaders/debug_solid.fs.glsl // pathfinder/demo/shaders/debug_solid.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/shaders/debug_solid.vs.glsl // pathfinder/demo/shaders/debug_solid.vs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/shaders/debug_texture.fs.glsl // pathfinder/demo/shaders/debug_texture.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/shaders/debug_texture.vs.glsl // pathfinder/demo/shaders/debug_texture.vs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/resources/shaders/demo_ground.fs.glsl // pathfinder/demo/resources/shaders/demo_ground.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/resources/shaders/demo_ground.vs.glsl // pathfinder/demo/resources/shaders/demo_ground.vs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo2/stencil.fs.glsl // pathfinder/demo2/stencil.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/fill.vs.glsl // pathfinder/demo/fill.vs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/resources/shaders/mask_tile.fs.glsl // pathfinder/demo/resources/shaders/mask_tile.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/shaders/mask_tile.vs.glsl // pathfinder/demo/shaders/mask_tile.vs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/shaders/post.fs.glsl // pathfinder/demo/shaders/post.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/shaders/post.vs.glsl // pathfinder/demo/shaders/post.vs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo2/opaque.fs.glsl // pathfinder/demo2/opaque.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/demo/resources/shaders/solid_tile.vs.glsl // pathfinder/demo/resources/shaders/solid_tile.vs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/resources/shaders/stencil.fs.glsl // pathfinder/resources/shaders/stencil.fs.glsl
// //

View File

@ -1,4 +1,4 @@
#version 330 #version {{version}}
// pathfinder/resources/shaders/stencil.vs.glsl // pathfinder/resources/shaders/stencil.vs.glsl
// //

View File

@ -16,6 +16,7 @@ pub use crate::scalar as default;
pub use crate::x86 as default; pub use crate::x86 as default;
pub mod scalar; pub mod scalar;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod x86; pub mod x86;
mod extras; mod extras;

View File

@ -20,8 +20,9 @@ use hashbrown::HashMap;
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32}; use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32};
use pathfinder_geometry::basic::rect::RectI32; use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_geometry::color::ColorU; use pathfinder_geometry::color::ColorU;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendState, BufferTarget, BufferUploadMode, Device, Primitive, RenderState}; use pathfinder_gpu::{BlendState, BufferTarget, BufferUploadMode, Device, Primitive, RenderState};
use pathfinder_gpu::{Resources, UniformData, VertexAttrType}; use pathfinder_gpu::{UniformData, VertexAttrType};
use pathfinder_simd::default::F32x4; use pathfinder_simd::default::F32x4;
use serde_json; use serde_json;
use std::fs::File; use std::fs::File;
@ -55,7 +56,7 @@ static OUTLINE_COLOR: ColorU = ColorU { r: 255, g: 255, b: 255, a: 192 };
static INVERTED_TEXT_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 }; static INVERTED_TEXT_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 };
static FONT_JSON_FILENAME: &'static str = "debug-font.json"; static FONT_JSON_VIRTUAL_PATH: &'static str = "debug-fonts/regular.json";
static FONT_PNG_NAME: &'static str = "debug-font"; static FONT_PNG_NAME: &'static str = "debug-font";
static CORNER_FILL_PNG_NAME: &'static str = "debug-corner-fill"; static CORNER_FILL_PNG_NAME: &'static str = "debug-corner-fill";
@ -83,7 +84,7 @@ pub struct UI<D> where D: Device {
} }
impl<D> UI<D> where D: Device { impl<D> UI<D> where D: Device {
pub fn new(device: &D, resources: &Resources, framebuffer_size: Point2DI32) -> UI<D> { pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Point2DI32) -> UI<D> {
let texture_program = DebugTextureProgram::new(device, resources); let texture_program = DebugTextureProgram::new(device, resources);
let texture_vertex_array = DebugTextureVertexArray::new(device, &texture_program); let texture_vertex_array = DebugTextureVertexArray::new(device, &texture_program);
let font = DebugFont::load(resources); let font = DebugFont::load(resources);
@ -509,7 +510,7 @@ struct DebugTextureProgram<D> where D: Device {
} }
impl<D> DebugTextureProgram<D> where D: Device { impl<D> DebugTextureProgram<D> where D: Device {
fn new(device: &D, resources: &Resources) -> DebugTextureProgram<D> { fn new(device: &D, resources: &dyn ResourceLoader) -> DebugTextureProgram<D> {
let program = device.create_program(resources, "debug_texture"); let program = device.create_program(resources, "debug_texture");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let texture_size_uniform = device.get_uniform(&program, "TextureSize"); let texture_size_uniform = device.get_uniform(&program, "TextureSize");
@ -598,7 +599,7 @@ struct DebugSolidProgram<D> where D: Device {
} }
impl<D> DebugSolidProgram<D> where D: Device { impl<D> DebugSolidProgram<D> where D: Device {
fn new(device: &D, resources: &Resources) -> DebugSolidProgram<D> { fn new(device: &D, resources: &dyn ResourceLoader) -> DebugSolidProgram<D> {
let program = device.create_program(resources, "debug_solid"); let program = device.create_program(resources, "debug_solid");
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize"); let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
let color_uniform = device.get_uniform(&program, "Color"); let color_uniform = device.get_uniform(&program, "Color");
@ -727,10 +728,8 @@ struct DebugCharacter {
} }
impl DebugFont { impl DebugFont {
fn load(resources: &Resources) -> DebugFont { #[inline]
let mut path = resources.resources_directory.clone(); fn load(resources: &dyn ResourceLoader) -> DebugFont {
path.push(FONT_JSON_FILENAME); serde_json::from_slice(&resources.slurp(FONT_JSON_VIRTUAL_PATH).unwrap()).unwrap()
serde_json::from_reader(BufReader::new(File::open(path).unwrap())).unwrap()
} }
} }