From 4899c4e9a60fcec6a911799373d37018272ecb1e Mon Sep 17 00:00:00 2001 From: JohannesItten Date: Thu, 9 Jul 2026 23:43:58 +0300 Subject: [PATCH] pip perf fix --- shared/V210.hpp | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/shared/V210.hpp b/shared/V210.hpp index 241cdb9..7b00ef6 100644 --- a/shared/V210.hpp +++ b/shared/V210.hpp @@ -220,6 +220,30 @@ inline void scale_and_overlay( const float inv_pip_w = static_cast(inset_w) / pip_w; const float inv_pip_cw = static_cast(inset_w / 2) / (pip_w / 2); + // Precompute horizontal source positions once — they are the same for every row. + // thread_local avoids heap allocation on repeated calls with the same dimensions. + struct XS { int x0, x1; float fx, ifx; }; + static thread_local std::vector y_xs, c_xs; + static thread_local int cached_pip_w = 0, cached_inset_w = 0; + if (pip_w != cached_pip_w || inset_w != cached_inset_w) { + y_xs.resize(pip_w); + for (int dx = 0; dx < pip_w; ++dx) { + const float sx = (dx + 0.5f) * inv_pip_w - 0.5f; + const int x0 = std::max(0, static_cast(sx)); + const float fx = sx - static_cast(x0); + y_xs[dx] = { x0, std::min(inset_w - 1, x0 + 1), fx, 1.0f - fx }; + } + c_xs.resize(pip_w / 2); + for (int cx = 0; cx < pip_w / 2; ++cx) { + const float sx = (cx + 0.5f) * inv_pip_cw - 0.5f; + const int x0 = std::max(0, static_cast(sx)); + const float fx = sx - static_cast(x0); + c_xs[cx] = { x0, std::min(inset_w / 2 - 1, x0 + 1), fx, 1.0f - fx }; + } + cached_pip_w = pip_w; + cached_inset_w = inset_w; + } + int cur_row0 = -1, cur_row1 = -1; for (int dy = 0; dy < pip_h; ++dy) { @@ -227,6 +251,8 @@ inline void scale_and_overlay( const int sy0 = std::max(0, static_cast(sy)); const int sy1 = std::min(inset_h - 1, sy0 + 1); const float fy = sy - static_cast(sy0); + const float w0 = 1.0f - fy; + const float w1 = fy; if (sy0 != cur_row0) { unpack_row(inset + static_cast(sy0) * inset_stride, inset_w, @@ -246,25 +272,19 @@ inline void scale_and_overlay( uint16_t Y[6], Cb[3], Cr[3]; for (int i = 0; i < 6; ++i) { - const float sx = (bx + i + 0.5f) * inv_pip_w - 0.5f; - const int sx0 = std::max(0, static_cast(sx)); - const int sx1 = std::min(inset_w - 1, sx0 + 1); - const float fx = sx - static_cast(sx0); + const XS& xs = y_xs[bx + i]; Y[i] = static_cast( - Y0_buf[sx0] * (1-fx) * (1-fy) + Y0_buf[sx1] * fx * (1-fy) + - Y1_buf[sx0] * (1-fx) * fy + Y1_buf[sx1] * fx * fy + 0.5f); + (Y0_buf[xs.x0] * xs.ifx + Y0_buf[xs.x1] * xs.fx) * w0 + + (Y1_buf[xs.x0] * xs.ifx + Y1_buf[xs.x1] * xs.fx) * w1 + 0.5f); } for (int i = 0; i < 3; ++i) { - const float cx = (b * 3 + i + 0.5f) * inv_pip_cw - 0.5f; - const int cx0 = std::max(0, static_cast(cx)); - const int cx1 = std::min(inset_w / 2 - 1, cx0 + 1); - const float cfx = cx - static_cast(cx0); + const XS& cs = c_xs[b * 3 + i]; Cb[i] = static_cast( - Cb0_buf[cx0]*(1-cfx)*(1-fy) + Cb0_buf[cx1]*cfx*(1-fy) + - Cb1_buf[cx0]*(1-cfx)* fy + Cb1_buf[cx1]*cfx* fy + 0.5f); + (Cb0_buf[cs.x0] * cs.ifx + Cb0_buf[cs.x1] * cs.fx) * w0 + + (Cb1_buf[cs.x0] * cs.ifx + Cb1_buf[cs.x1] * cs.fx) * w1 + 0.5f); Cr[i] = static_cast( - Cr0_buf[cx0]*(1-cfx)*(1-fy) + Cr0_buf[cx1]*cfx*(1-fy) + - Cr1_buf[cx0]*(1-cfx)* fy + Cr1_buf[cx1]*cfx* fy + 0.5f); + (Cr0_buf[cs.x0] * cs.ifx + Cr0_buf[cs.x1] * cs.fx) * w0 + + (Cr1_buf[cs.x0] * cs.ifx + Cr1_buf[cs.x1] * cs.fx) * w1 + 0.5f); } pack_block(dst_row + b * 16,