render: Improve performance of round_to_i32
This patch improves performance of matrix::round_to_i32() by using f32::round_ties_even(), which has been stable since 1.77.0, instead of a custom algorithm.
This commit is contained in:
parent
6ad4bc4999
commit
b99bdadb8f
|
@ -1,5 +1,7 @@
|
|||
use swf::{Fixed16, Point, PointDelta, Rectangle, Twips};
|
||||
|
||||
/// TODO: Consider using portable SIMD when it's stable (https://doc.rust-lang.org/std/simd/index.html).
|
||||
|
||||
/// The transformation matrix used by Flash display objects.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Matrix {
|
||||
|
@ -286,18 +288,11 @@ impl From<Matrix> for swf::Matrix {
|
|||
/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule.
|
||||
/// (e.g., both 1.5 and 2.5 will round to 2).
|
||||
/// This is the rounding method used by Flash for the above transforms.
|
||||
/// Although this is easy to do on most architectures, Rust provides no standard
|
||||
/// way to round in this manner (`f32::round` always rounds away from zero).
|
||||
/// For more info and the below code snippet, see: https://github.com/rust-lang/rust/issues/55107
|
||||
/// This also clamps out-of-range values and NaN to `i32::MIN`.
|
||||
/// TODO: Investigate using SSE/wasm intrinsics for this.
|
||||
fn round_to_i32(f: f32) -> i32 {
|
||||
if f.is_finite() {
|
||||
let a = f.abs();
|
||||
if f < 2_147_483_648.0_f32 {
|
||||
let k = 1.0 / f32::EPSILON;
|
||||
let out = if a < k { ((a + k) - k).copysign(f) } else { f };
|
||||
out as i32
|
||||
f.round_ties_even() as i32
|
||||
} else {
|
||||
// Out-of-range clamps to MIN.
|
||||
i32::MIN
|
||||
|
|
Loading…
Reference in New Issue