Instead of occupying multiple TLS slots, introduce a single type
that stores all the builtin function types in members. Use a macro
to define this struct then, which allows us to use a nice DSL to
define these function types, reducing the boiler plate significantly.
The downside is that we no longer have the ability to easily share
semantically equivalent function types (e.g. for `Round`, `Ceil`
and `Floor` etc.). Doing so would require us to introdue a separate
name for these types, and then use external matching to map the
BuiltinFunctions to the reduced list of types. The performance impact
is minimal though, so this is not done to KISS.
This is rarely used, but using Rc here like elsewhere allows us to
elide a few unneccessary memory allocations when copying such types.
The speed impact is not measurable though. With heaptrack I see that
we get rid of the last ~7600 allocations in my benchmark when cloning
Type.
These are known statically, so let's store them once in thread local
statics and return them from there.
Before:
```
Time (mean ± σ): 1.034 s ± 0.026 s [User: 0.733 s, System: 0.201 s]
Range (min … max): 1.000 s … 1.078 s 10 runs
allocations: 2917476
```
After:
```
Time (mean ± σ): 996.9 ms ± 17.7 ms [User: 708.9 ms, System: 202.9 ms]
Range (min … max): 977.8 ms … 1033.1 ms 10 runs
allocations: 2686677
```
This makes copying such types much cheaper and will allow us to
intern common struct types in the future too. This further
drops the sample cost for langtype.rs from ~6.6% down to 4.0%.
We are now also able to share/intern common struct types.
Before:
```
Time (mean ± σ): 1.073 s ± 0.021 s [User: 0.759 s, System: 0.215 s]
Range (min … max): 1.034 s … 1.105 s 10 runs
allocations: 3074261
```
After:
```
Time (mean ± σ): 1.034 s ± 0.026 s [User: 0.733 s, System: 0.201 s]
Range (min … max): 1.000 s … 1.078 s 10 runs
allocations: 2917476
```
This allows us to cheaply copy the langtype::Type values which
contain such a type. The runtime impact is small and barely noticable
but a sampling profiler shows a clear reduction in samples pointing
at langtype.rs, roughly reducing that from ~8.6% inclusive cost
down to 6.6% inclusive cost.
Furthermore, this allows us to share/intern common types.
Before:
```
Benchmark 1: ./target/release/slint-viewer ../slint-perf/app.slint
Time (mean ± σ): 1.089 s ± 0.026 s [User: 0.771 s, System: 0.216 s]
Range (min … max): 1.046 s … 1.130 s 10 runs
allocations: 3152149
```
After:
```
Time (mean ± σ): 1.073 s ± 0.021 s [User: 0.759 s, System: 0.215 s]
Range (min … max): 1.034 s … 1.105 s 10 runs
allocations: 3074261
```
wasm_demos.yaml uses upload-artifact to archive the demos & examples and strips any common directory prefix. So it used to be top-level gallery, etc. and now it's examples/gallery and demos/printerdemo.
- include the ' ' char that doesn't have a bounding box but need to be
included for the advance_x
- Fix an off by one in rendering where the last pixel was missing
Initially the character map is ordered by glyph index. Maintain that order for glyph embedding, so that we can safely collect() the bitmaps. Just before creating the final BitmapFont data structure, sort by code point for fast lookups at run-time.
Copying potentially thousands of properties for no reason is something
that can be easily optimized away to save a bit of time:
Before:
```
Benchmark 1: ./target/release/slint-viewer ../slint-perf/app.slint
Time (mean ± σ): 1.108 s ± 0.015 s [User: 0.792 s, System: 0.231 s]
Range (min … max): 1.085 s … 1.133 s 10 runs
```
After:
```
Benchmark 1: ./target/release/slint-viewer ../slint-perf/app.slint
Time (mean ± σ): 1.082 s ± 0.019 s [User: 0.773 s, System: 0.214 s]
Range (min … max): 1.054 s … 1.117 s 10 runs
```
Destroy means we need to exit the event loop.
And android_main will be called again from another thread, so we need to
support reseting the proxy
There is also a bug in the timer when exiting the app that this worked
around
Fix#6626