Skip to content

Add new rust-based coder implementation#4

Open
Lolle2000la wants to merge 83 commits intomihonapp:mainfrom
Lolle2000la:rewrite-in-rust
Open

Add new rust-based coder implementation#4
Lolle2000la wants to merge 83 commits intomihonapp:mainfrom
Lolle2000la:rewrite-in-rust

Conversation

@Lolle2000la
Copy link

Adds a new fully-compatible drop-in compatible (once enabled) backend written in Rust. It can be integrated into Mihon and forks without any changes except adding a way to enable it. Note that the existing C++ based backend remains fully available and enabled by default. Without the consumer enabling it, this new backend will not affect existing behavior (requiring WIP PR #3048).

Aside from superior performance with up-to-date libraries that are easier to update due to Cargo, the main reason I even implemented is that it implements a much-superior Catmull-Rom bicubic filter. This should help with all the complaints surrounding moire. As can be seen from the benchmarks below, the performance is still at the worst equal, usually better than the C++ implementation despite using a higher quality filter.

Benchmarks

These benchmarks were done on a S24 Ultra with a Snapdragon processor. They compare the C++ implementation against the new rust implementation. The benchmarks are also included.

Benchmark results on a S24 Ultra (Snapdragon)

Why a rewrite to Rust?

When I went to see what might be necessary to implement better filtering, I noticed that:

  1. I hate C++ and am not sure if I can do this safely
  2. Actually, that C++ part is surprisingly small

Rust, aside from being a lot saner, has the nice plus of being a lot more approachable, meaning that its much easier to make changes. I found that it was much easier for me to implement the filter (with a nice crate that provided a lot of juicy SIMD uplift) and then optimize the rest of the decoders with more confidence.

… out while developing and use the same AGP version as mihon
Since the Rust compiler also needs to see it, its a bit of a weird setup
Resolves `unresolved link` errors
…mproving readability and reducing code duplication
…anicking when the output buffer is different from what it expects before scaling

Since it doesn't take into account the size after scaling, we need to go around it.

(also add back the test I accidentally deleted)
…dling

Using an iterator allows evading a lot of unsafe indexing on potentially uninitialized memory
…e pixel conversion

Using an iterator gets us around some of the indexing stuff
…ckend-to-choose C++ lib

The benchmark code has renames of the jni methods so that the benchmark code can use both. In case of the prod code, the libraries are transparently switchable, so no rename necessary.

BUT this approach breaks the bench, so that needs a separate name.
Otherwise this will accidentally test C++ against C++
… v3 API for cropping and respecting MCU alignment
…heif

Basically, the prior impl. reads a bit better but since it loses what the final size will be and needs to do some copying etc., it can not optimize as much (same as before with the heif decoder).
`lib.rs` in particular is about the usage of a pointer without proper (un)safety markings
…nder way, satisfying clippy.

It is factually equivalent but does provide a bit more safety by only setting the size on the vector once it has actually been filled.
The case where AVIFs don't have an alphachannel leads to the `*4` and `/4` calculation to be off. Specifically the division will cause the an unreasonable number to be passed for avif 3 channel pictures.
It was there in an initial design matching the C++ design, but handling color transformations inside the decoders yields more performance as specific optimizations can be done.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant