[libyuv] Expand WebAssembly SIMD128 and Relaxed SIMD support

Expand WebAssembly SIMD128 (_WASMSIMD) and WebAssembly Relaxed SIMD
(_RELAXEDSIMD) optimizations across compare, rotate, convert, and scale
row functions.

Add a distinct kCpuHasRELAXEDSIMD (0x200) capability flag and runtime
WasmCpuCaps() detection modeled after XNNPACK, probing whether
wasm_i8x16_relaxed_swizzle or wasm_f32x4_relaxed_madd exhibit
hardware-specific Relaxed SIMD behavior at runtime. Support disabling
Relaxed SIMD alone (LIBYUV_DISABLE_RELAXEDSIMD), Wasm SIMD128 alone
(LIBYUV_DISABLE_WASMSIMD), or all Wasm SIMD (LIBYUV_DISABLE_WASM) via
compile-time macros or runtime environment variables.

Compare (6 functions):
C Function        x86        Arm          Wasm
----------------- ---------- ------------ -----------
HammingDistance_C AVX512VNNI NEON_DOTPROD RELAXEDSIMD
SumSquareError_C  AVX512VNNI NEON_DOTPROD WASMSIMD
HashDjb2_C        AVX512BW   NEON         WASMSIMD
Ssim4x4Row_C      AVX512BW   SME          WASMSIMD
SsimWindowRow_C   AVX512BW   SME          WASMSIMD
ARGBDetectRow_C   AVX2       NEON         WASMSIMD
----------------- ---------- ------------ -----------
Count (6)         6/6        6/6          6/6
Percentage        100.0%     100.0%       100.0%

Rotate (7 functions):
C Function        x86      Arm    Wasm
----------------- -------- ------ --------
TransposeWx8_C    AVX2     NEON   WASMSIMD
TransposeWx16_C   AVX512BW NEON   WASMSIMD
TransposeUVWx8_C  AVX2     NEON   WASMSIMD
TransposeUVWx16_C AVX512BW -      WASMSIMD
TransposeWx8_16_C AVX2     SVE2   WASMSIMD
TransposeWxH_32_C AVX2     SME    -
TransposeWx4_32_C AVX2     SVE2   WASMSIMD
----------------- -------- ------ --------
Count (7)         7/7      6/7    6/7
Percentage        100.0%   85.7%  85.7%

Convert (171 functions):
C Function                  x86        Arm          Wasm
--------------------------- ---------- ------------ -----------
ARGBToYMatrixRow_C          AVX512VNNI SME          WASMSIMD
ARGBToUVMatrixRow_C         AVX512VNNI SME          RELAXEDSIMD
RGBToYMatrixRow_C           AVX512BW   NEON_DOTPROD RELAXEDSIMD
RGBToUVMatrixRow_C          AVX512BW   NEON         RELAXEDSIMD
RGBToUV444MatrixRow_C       AVX512BW   NEON         RELAXEDSIMD
RGB565ToYMatrixRow_C        AVX2       NEON         WASMSIMD
ARGB1555ToYMatrixRow_C      AVX2       NEON         WASMSIMD
ARGB1555ToUVMatrixRow_C     AVX2       NEON         WASMSIMD
ARGB4444ToYMatrixRow_C      AVX2       NEON         WASMSIMD
ARGB4444ToUVMatrixRow_C     AVX2       NEON         WASMSIMD
RGB565ToUVMatrixRow_C       AVX2       NEON         WASMSIMD
ARGBToUV444MatrixRow_C      AVX512VNNI NEON_I8MM    RELAXEDSIMD
RGB565ToYRow_C              AVX2       NEON         -
ARGB1555ToYRow_C            AVX2       NEON         -
ARGB4444ToYRow_C            AVX2       NEON         -
RGB565ToUVRow_C             AVX2       NEON         -
ARGB1555ToUVRow_C           AVX2       NEON         -
ARGB4444ToUVRow_C           AVX2       NEON         -
MirrorRow_C                 AVX512BW   NEON         RELAXEDSIMD
MirrorUVRow_C               AVX512BW   NEON         RELAXEDSIMD
MirrorSplitUVRow_C          AVX512BW   NEON         RELAXEDSIMD
MirrorRow_16_C              AVX512BW   NEON         -
ARGBMirrorRow_C             AVX512BW   NEON         WASMSIMD
RGB24MirrorRow_C            AVX512VBMI NEON         RELAXEDSIMD
SplitUVRow_C                AVX512BW   SME          WASMSIMD
DetileRow_C                 AVX2       NEON         WASMSIMD
DetileRow_16_C              AVX2       NEON         WASMSIMD
DetileSplitUVRow_C          AVX2       NEON         WASMSIMD
DetileToYUY2_C              AVX2       NEON         WASMSIMD
UnpackMT2T_C                AVX2       NEON         -
MergeUVRow_C                AVX512BW   SME          WASMSIMD
HalfMergeUVRow_C            AVX512BW   SME          WASMSIMD
SplitRGBRow_C               AVX2       NEON         RELAXEDSIMD
MergeRGBRow_C               AVX512VBMI NEON         RELAXEDSIMD
MergeARGBRow_C              AVX2       NEON         WASMSIMD
SplitARGBRow_C              AVX2       NEON         WASMSIMD
MergeXRGBRow_C              AVX2       NEON         WASMSIMD
SplitXRGBRow_C              AVX2       NEON         WASMSIMD
MergeXR30Row_C              AVX2       NEON         -
MergeAR64Row_C              AVX2       NEON         -
MergeARGB16To8Row_C         AVX2       NEON         -
MergeXR64Row_C              AVX2       NEON         -
MergeXRGB16To8Row_C         AVX2       NEON         -
MergeUVRow_16_C             AVX512BW   SME          WASMSIMD
SplitUVRow_16_C             AVX2       NEON         WASMSIMD
MultiplyRow_16_C            AVX512BW   SME          WASMSIMD
DivideRow_16_C              AVX512BW   SME          WASMSIMD
Convert8To16Row_C           AVX512BW   SME          WASMSIMD
Convert16To8Row_C           AVX512BW   SME          WASMSIMD
HalfRow_C                   AVX2       SME          WASMSIMD
HalfRow_16_C                AVX2       SME          WASMSIMD
HalfRow_16To8_C             AVX512BW   SME          WASMSIMD
HalfWidthRow_16To8_C        AVX512BW   SME          WASMSIMD
HalfWidthRow_16To8_Odd_C    AVX2       NEON         -
Convert8To8Row_C            AVX512BW   SME          WASMSIMD
CopyRow_C                   AVX512BW   SME          WASMSIMD
CopyRow_16_C                AVX2       NEON         WASMSIMD
ARGBCopyAlphaRow_C          AVX2       NEON         WASMSIMD
ARGBExtractAlphaRow_C       AVX512BW   NEON         WASMSIMD
ARGBCopyYToAlphaRow_C       AVX512BW   NEON         RELAXEDSIMD
SetRow_C                    AVX2       NEON         WASMSIMD
ARGBSetRow_C                AVX2       NEON         WASMSIMD
ARGBShuffleRow_C            AVX512BW   NEON         RELAXEDSIMD
RGB24ToARGBRow_C            AVX512BW   SME          RELAXEDSIMD
RAWToARGBRow_C              AVX512BW   SME          RELAXEDSIMD
RAWToRGBARow_C              AVX512VBMI SME          RELAXEDSIMD
RAWToRGB24Row_C             AVX512VBMI SME          RELAXEDSIMD
RGB565ToARGBRow_C           AVX2       NEON         WASMSIMD
ARGB1555ToARGBRow_C         AVX512BW   SME          WASMSIMD
ARGB4444ToARGBRow_C         AVX2       NEON         WASMSIMD
AR30ToARGBRow_C             AVX512BW   NEON         WASMSIMD
AR30ToABGRRow_C             AVX512BW   NEON         WASMSIMD
ARGBToAR30Row_C             AVX512BW   NEON         WASMSIMD
AR30ToAB30Row_C             AVX512BW   NEON         WASMSIMD
ARGBToRGB565DitherRow_C     AVX512BW   SME          WASMSIMD
ARGBToABGRRow_C             -          -            -
ARGBToBGRARow_C             -          -            -
ARGBToRGBARow_C             -          -            -
ARGBToRGB24Row_C            AVX512BW   SME          RELAXEDSIMD
ARGBToRAWRow_C              AVX512BW   SME          RELAXEDSIMD
ARGBToRGB565Row_C           AVX512BW   SME          WASMSIMD
ARGBToARGB1555Row_C         AVX2       NEON         WASMSIMD
ARGBToARGB4444Row_C         AVX2       NEON         WASMSIMD
ABGRToAR30Row_C             AVX512BW   NEON         WASMSIMD
ARGBToAR64Row_C             AVX2       NEON         WASMSIMD
ARGBToAB64Row_C             AVX2       NEON         WASMSIMD
AR64ToARGBRow_C             AVX2       NEON         WASMSIMD
AB64ToARGBRow_C             AVX2       NEON         WASMSIMD
AR64ToAB64Row_C             -          -            -
RGBAToARGBRow_C             -          -            -
AR64ShuffleRow_C            -          -            -
J400ToARGBRow_C             AVX512BW   NEON         RELAXEDSIMD
I444ToARGBRow_C             AVX512BW   SME          WASMSIMD
I444ToRGB24Row_C            AVX512VBMI SME          RELAXEDSIMD
I422ToARGBRow_C             AVX512BW   SME          WASMSIMD
I422ToAR30Row_C             AVX512BW   SME          WASMSIMD
I210ToAR30Row_C             AVX512BW   SME          WASMSIMD
I210ToARGBRow_C             AVX512BW   SME          WASMSIMD
I212ToAR30Row_C             AVX512BW   SME          -
I212ToARGBRow_C             AVX512BW   SME          -
I410ToAR30Row_C             AVX512BW   SME          WASMSIMD
I410ToARGBRow_C             AVX512BW   SME          WASMSIMD
I210AlphaToARGBRow_C        AVX512BW   SME          WASMSIMD
I410AlphaToARGBRow_C        AVX512BW   SME          WASMSIMD
I444AlphaToARGBRow_C        AVX512BW   SME          WASMSIMD
I422AlphaToARGBRow_C        AVX512BW   SME          WASMSIMD
NV12ToARGBRow_C             AVX512BW   SME          WASMSIMD
NV12ToRGB565Row_C           AVX2       NEON         WASMSIMD
NV21ToARGBRow_C             AVX512BW   SME          WASMSIMD
NV12ToRGB24Row_C            AVX512VBMI SME          RELAXEDSIMD
NV21ToRGB24Row_C            AVX512VBMI SME          RELAXEDSIMD
NV21ToYUV24Row_C            AVX512VBMI NEON         -
YUY2ToARGBRow_C             AVX512BW   SME          WASMSIMD
UYVYToARGBRow_C             AVX512BW   SME          WASMSIMD
P210ToARGBRow_C             AVX512BW   SME          -
P410ToARGBRow_C             AVX512BW   SME          -
P210ToAR30Row_C             AVX512BW   SME          -
P410ToAR30Row_C             AVX512BW   SME          -
I422ToRGBARow_C             AVX512BW   SME          WASMSIMD
I422ToRGB24Row_C            AVX512VBMI SME          RELAXEDSIMD
I422ToARGB4444Row_C         AVX512BW   SME          WASMSIMD
I422ToARGB1555Row_C         AVX512BW   SME          WASMSIMD
I422ToRGB565Row_C           AVX512BW   SME          WASMSIMD
I400ToARGBRow_C             AVX512BW   SME          RELAXEDSIMD
ARGBBlendRow_C              AVX512BW   NEON         RELAXEDSIMD
BlendPlaneRow_C             AVX512BW   NEON         WASMSIMD
ARGBMultiplyRow_C           AVX512BW   SME          WASMSIMD
ARGBAddRow_C                AVX2       NEON         WASMSIMD
ARGBSubtractRow_C           AVX2       NEON         WASMSIMD
ARGBOrRow_C                 AVX512BW   SME          WASMSIMD
ARGBAlphaBlendRow_C         AVX512BW   SME          WASMSIMD
YUY2ToYRow_C                AVX512BW   SME          WASMSIMD
YUY2ToUVRow_C               AVX512BW   SME          WASMSIMD
YUY2ToNVUVRow_C             AVX2       NEON         WASMSIMD
YUY2ToUV422Row_C            AVX512BW   NEON         WASMSIMD
UYVYToYRow_C                AVX512BW   SME          WASMSIMD
UYVYToUVRow_C               AVX512BW   SME          WASMSIMD
UYVYToUV422Row_C            AVX512BW   NEON         WASMSIMD
SwapUVRow_C                 AVX512BW   NEON         WASMSIMD
AYUVToYRow_C                AVX512VBMI NEON         WASMSIMD
AYUVToUVRow_C               AVX512VBMI SME          RELAXEDSIMD
AYUVToVURow_C               AVX512VBMI SME          RELAXEDSIMD
I422ToYUY2Row_C             AVX2       NEON         WASMSIMD
I422ToUYVYRow_C             AVX2       NEON         WASMSIMD
ARGBAttenuateRow_C          AVX512BW   NEON         RELAXEDSIMD
ARGBUnattenuateRow_C        AVX2       NEON         -
ARGBGrayRow_C               AVX512VNNI NEON_DOTPROD RELAXEDSIMD
ARGBSepiaRow_C              AVX512VNNI NEON_DOTPROD RELAXEDSIMD
ARGBColorMatrixRow_C        AVX512VNNI NEON_I8MM    WASMSIMD
ARGBColorTableRow_C         AVX2       NEON         -
RGBColorTableRow_C          AVX2       NEON         -
ARGBQuantizeRow_C           AVX2       NEON         WASMSIMD
ARGBShadeRow_C              AVX2       NEON         WASMSIMD
CumulativeSumToAverageRow_C AVX2       NEON         -
ComputeCumulativeSumRow_C   AVX2       NEON         -
ARGBAffineRow_C             AVX2       NEON         -
InterpolateRow_C            AVX512BW   SME          WASMSIMD
InterpolateRow_16_C         AVX512BW   SME          WASMSIMD
SobelXRow_C                 AVX2       NEON         WASMSIMD
SobelYRow_C                 AVX2       NEON         WASMSIMD
SobelRow_C                  AVX2       NEON         RELAXEDSIMD
SobelToPlaneRow_C           AVX2       NEON         WASMSIMD
SobelXYRow_C                AVX2       NEON         WASMSIMD
ARGBPolynomialRow_C         AVX2       NEON         WASMSIMD
HalfFloatRow_C              AVX512BW   SME          WASMSIMD
ByteToFloatRow_C            AVX2       NEON         WASMSIMD
ARGBLumaColorTableRow_C     AVX2       NEON         WASMSIMD
GaussRow_F32_C              AVX2       NEON         -
GaussCol_F32_C              AVX2       NEON         -
GaussRow_C                  AVX2       NEON         -
GaussCol_C                  AVX2       NEON         -
--------------------------- ---------- ------------ -----------
Count (171)                 165/171    165/171      134/171
Percentage                  96.5%      96.5%        78.4%

Scale (86 functions):
C Function                      x86        Arm    Wasm
------------------------------- ---------- ------ -----------
FixedDiv_C                      -          -      -
FixedDiv1_C                     -          -      -
ScaleRowDown2_C                 AVX512BW   SME    WASMSIMD
ScaleRowDown2_16_C              AVX2       SME    -
ScaleRowDown2Linear_C           AVX512BW   SME    WASMSIMD
ScaleRowDown2Linear_16_C        AVX2       SME    -
ScaleRowDown2Box_C              AVX512BW   SME    WASMSIMD
ScaleRowDown2Box_Odd_C          AVX512BW   NEON   WASMSIMD
ScaleRowDown2Box_16_C           AVX2       SME    -
ScaleRowDown4_C                 AVX2       NEON   WASMSIMD
ScaleRowDown4_16_C              -          -      -
ScaleRowDown4Box_C              AVX2       NEON   WASMSIMD
ScaleRowDown4Box_16_C           -          -      -
ScaleRowDown34_C                AVX2       NEON   RELAXEDSIMD
ScaleRowDown34_16_C             -          -      -
ScaleRowDown34_0_Box_C          AVX2       NEON   RELAXEDSIMD
ScaleRowDown34_0_Box_16_C       -          -      -
ScaleRowDown34_1_Box_C          AVX2       NEON   RELAXEDSIMD
ScaleRowDown34_1_Box_16_C       -          -      -
ScaleRowUp2_Linear_C            AVX2       NEON   RELAXEDSIMD
ScaleRowUp2_Bilinear_C          AVX2       NEON   RELAXEDSIMD
ScaleRowUp2_Linear_16_C         AVX2       NEON   -
ScaleRowUp2_Bilinear_16_C       AVX2       NEON   -
ScaleRowUp2_Linear_Any_C        AVX2       NEON   RELAXEDSIMD
ScaleRowUp2_Bilinear_Any_C      AVX2       NEON   RELAXEDSIMD
ScaleRowUp2_Linear_16_Any_C     AVX2       NEON   -
ScaleRowUp2_Bilinear_16_Any_C   AVX2       NEON   -
ScaleCols_C                     -          -      -
ScaleCols_16_C                  -          -      -
ScaleColsUp2_C                  AVX2       -      -
ScaleColsUp2_16_C               -          -      -
ScaleFilterCols_C               AVX2       NEON   WASMSIMD
ScaleFilterCols_16_C            -          -      -
ScaleFilterCols64_C             -          -      -
ScaleFilterCols64_16_C          -          -      -
ScaleRowDown38_C                AVX2       NEON   RELAXEDSIMD
ScaleRowDown38_16_C             -          -      -
ScaleRowDown38_3_Box_C          AVX2       NEON   RELAXEDSIMD
ScaleRowDown38_3_Box_16_C       -          -      -
ScaleRowDown38_2_Box_C          AVX2       NEON   RELAXEDSIMD
ScaleRowDown38_2_Box_16_C       -          -      -
ScaleAddRow_C                   AVX512BW   NEON   WASMSIMD
ScaleAddRow_16_C                -          -      -
ScaleARGBRowDown2_C             AVX2       SME    WASMSIMD
ScaleARGBRowDown2Linear_C       AVX2       SME    WASMSIMD
ScaleARGBRowDown2Box_C          AVX2       SME    WASMSIMD
ScaleARGBRowDownEven_C          AVX2       NEON   WASMSIMD
ScaleARGBRowDownEvenBox_C       AVX2       NEON   WASMSIMD
ScaleARGBCols_C                 AVX2       NEON   WASMSIMD
ScaleARGBCols64_C               -          -      -
ScaleARGBColsUp2_C              AVX2       -      WASMSIMD
ScaleARGBFilterCols_C           AVX2       NEON   WASMSIMD
ScaleARGBFilterCols64_C         -          -      -
ScaleUVRowDown2_C               AVX2       SME    WASMSIMD
ScaleUVRowDown2_16_C            -          -      -
ScaleUVRowDown2Linear_C         AVX2       SME    WASMSIMD
ScaleUVRowDown2Linear_16_C      -          -      -
ScaleUVRowDown2Box_C            AVX2       SME    WASMSIMD
ScaleUVRowDown2Box_16_C         -          -      -
ScaleUVRowDownEven_C            AVX2       NEON   WASMSIMD
ScaleUVRowDownEven_16_C         -          -      -
ScaleUVRowDownEvenBox_C         -          -      -
ScaleUVRowDownEvenBox_16_C      -          -      -
ScaleUVRowUp2_Linear_C          AVX2       NEON   RELAXEDSIMD
ScaleUVRowUp2_Bilinear_C        AVX2       NEON   RELAXEDSIMD
ScaleUVRowUp2_Linear_Any_C      AVX2       NEON   RELAXEDSIMD
ScaleUVRowUp2_Bilinear_Any_C    AVX2       NEON   RELAXEDSIMD
ScaleUVRowUp2_Linear_16_C       AVX2       NEON   -
ScaleUVRowUp2_Bilinear_16_C     AVX2       NEON   -
ScaleUVRowUp2_Linear_16_Any_C   AVX2       NEON   -
ScaleUVRowUp2_Bilinear_16_Any_C AVX2       NEON   -
ScaleUVCols_C                   -          -      -
ScaleUVCols_16_C                -          -      -
ScaleUVCols64_C                 -          -      -
ScaleUVCols64_16_C              -          -      -
ScaleUVColsUp2_C                -          -      -
ScaleUVColsUp2_16_C             -          -      -
ScaleUVFilterCols_C             -          -      -
ScaleUVFilterCols_16_C          -          -      -
ScaleUVFilterCols64_C           -          -      -
ScaleUVFilterCols64_16_C        -          -      -
ScaleUVAddCols3_C               AVX512VBMI SME    WASMSIMD
ScaleUVAddCols3_16_C            -          -      -
ScaleMaxSamples_C               AVX2       NEON   WASMSIMD
ScaleSumSamples_C               AVX2       NEON   WASMSIMD
ScaleSamples_C                  AVX2       NEON   WASMSIMD
------------------------------- ---------- ------ -----------
Count (86)                      50/86      48/86  38/86
Percentage                      58.1%      55.8%  44.2%

Bug: 42280942
Change-Id: I4420a570327a95cc998c6aa023286a0b3552f742
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8724066
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
This commit is contained in:
Frank Barchard 2026-11-04 03:09:42 -08:00
parent d2a6496353
commit d4074c4e18
32 changed files with 7910 additions and 294 deletions

View File

@ -50,7 +50,10 @@ config("libyuv_config") {
defines += [ "LIBYUV_DISABLE_LASX" ]
}
if (current_cpu == "wasm") {
cflags_cc = [ "-msimd128" ]
cflags_cc = [
"-msimd128",
"-mrelaxed-simd",
]
}
}

View File

@ -9,6 +9,8 @@ option( LIBYUV_DISABLE_JPEG "Disable JPEG support" OFF )
option( LIBYUV_DISABLE_ASM "Disable inline assembly" OFF )
option( LIBYUV_DISABLE_LSX "Disable LoongArch LSX" OFF )
option( LIBYUV_DISABLE_LASX "Disable LoongArch LASX" OFF )
option( LIBYUV_DISABLE_WASMSIMD "Disable WebAssembly SIMD128" OFF )
option( LIBYUV_DISABLE_RELAXEDSIMD "Disable WebAssembly Relaxed SIMD" OFF )
if(LIBYUV_DISABLE_ASM)
add_definitions(-DLIBYUV_DISABLE_ASM)
@ -19,6 +21,12 @@ endif()
if(LIBYUV_DISABLE_LASX)
add_definitions(-DLIBYUV_DISABLE_LASX)
endif()
if(LIBYUV_DISABLE_WASMSIMD)
add_definitions(-DLIBYUV_DISABLE_WASMSIMD)
endif()
if(LIBYUV_DISABLE_RELAXEDSIMD)
add_definitions(-DLIBYUV_DISABLE_RELAXEDSIMD)
endif()
include(CheckCSourceCompiles)
@ -208,8 +216,8 @@ int main(void) { return 0; }
endif()
if(arch_lowercase MATCHES "^wasm" OR EMSCRIPTEN)
set(CMAKE_C_FLAGS "-msimd128 ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "-msimd128 ${CMAKE_CXX_FLAGS}")
set(CMAKE_C_FLAGS "-msimd128 -mrelaxed-simd ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "-msimd128 -mrelaxed-simd ${CMAKE_CXX_FLAGS}")
endif()
endif()

View File

@ -1,6 +1,6 @@
Name: libyuv
URL: https://chromium.googlesource.com/libyuv/libyuv/
Version: 1978
Version: 1979
Revision: DEPS
License: BSD-3-Clause
License File: LICENSE

View File

@ -152,7 +152,7 @@ extern "C" {
#endif
// The following are available for WebAssembly SIMD128:
#if !defined(LIBYUV_DISABLE_WASM) && defined(__wasm_simd128__)
#if !defined(LIBYUV_DISABLE_WASMSIMD) && defined(__wasm_simd128__)
#define HAS_HAMMINGDISTANCE_WASMSIMD
#define HAS_SUMSQUAREERROR_WASMSIMD
#define HAS_HASHDJB2_WASMSIMD
@ -161,6 +161,11 @@ extern "C" {
#define HAS_ARGBDETECTROW_WASMSIMD
#endif
// The following are available for WebAssembly Relaxed SIMD:
#if !defined(LIBYUV_DISABLE_RELAXEDSIMD) && defined(__wasm_relaxed_simd__)
#define HAS_HAMMINGDISTANCE_RELAXEDSIMD
#endif
// The following are available for Hexagon HVX:
#if !defined(LIBYUV_DISABLE_HVX) && defined(__HVX__)
#define HAS_HAMMINGDISTANCE_HVX
@ -207,6 +212,9 @@ uint32_t HammingDistance_LASX(const uint8_t* src_a,
uint32_t HammingDistance_WASMSIMD(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_RELAXEDSIMD(const uint8_t* src_a,
const uint8_t* src_b,
int count);
uint32_t HammingDistance_HVX(const uint8_t* src_a,
const uint8_t* src_b,
int count);

View File

@ -74,6 +74,7 @@ static const int kCpuHasLASX = 0x200;
// These flags are only valid on WASM processors.
static const int kCpuHasWASM = 0x40;
static const int kCpuHasWASMSIMD = 0x100;
static const int kCpuHasRELAXEDSIMD = 0x200;
// These flags are only valid on Hexagon processors.
static const int kCpuHasHexagon = 0x80;
@ -102,6 +103,8 @@ LIBYUV_API
int ArmCpuCaps(const char* cpuinfo_name);
LIBYUV_API
int RiscvCpuCaps(const char* cpuinfo_name);
LIBYUV_API
int WasmCpuCaps(void);
#ifdef __linux__
// On Linux, parse AArch64 features from getauxval(AT_HWCAP{,2}).

View File

@ -26,6 +26,15 @@ extern "C" {
#define LIBYUV_DISABLE_NEON
#endif
#if defined(LIBYUV_DISABLE_WASM)
#if !defined(LIBYUV_DISABLE_WASMSIMD)
#define LIBYUV_DISABLE_WASMSIMD
#endif
#if !defined(LIBYUV_DISABLE_RELAXEDSIMD)
#define LIBYUV_DISABLE_RELAXEDSIMD
#endif
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)

View File

@ -136,7 +136,7 @@ extern "C" {
#define HAS_TRANSPOSEWXH_32_RVV
#endif
#if !defined(LIBYUV_DISABLE_WASM) && defined(__wasm_simd128__)
#if !defined(LIBYUV_DISABLE_WASMSIMD) && defined(__wasm_simd128__)
#define HAS_TRANSPOSEWX8_WASMSIMD
#define HAS_TRANSPOSEUVWX8_WASMSIMD
#define HAS_TRANSPOSEWX16_WASMSIMD

File diff suppressed because it is too large Load Diff

View File

@ -232,7 +232,7 @@ extern "C" {
#endif
// The following are available for WebAssembly SIMD128:
#if !defined(LIBYUV_DISABLE_WASM) && defined(__wasm_simd128__)
#if !defined(LIBYUV_DISABLE_WASMSIMD) && defined(__wasm_simd128__)
#define HAS_SCALEADDROW_WASMSIMD
#define HAS_SCALEARGBCOLS_WASMSIMD
#define HAS_SCALEARGBCOLSUP2_WASMSIMD
@ -240,11 +240,32 @@ extern "C" {
#define HAS_SCALEARGBROWDOWN2_WASMSIMD
#define HAS_SCALEARGBROWDOWNEVEN_WASMSIMD
#define HAS_SCALEFILTERCOLS_WASMSIMD
#define HAS_SCALEMAXSAMPLES_WASMSIMD
#define HAS_SCALEROWDOWN2_WASMSIMD
#define HAS_SCALEROWDOWN34_WASMSIMD
#define HAS_SCALEROWDOWN38_WASMSIMD
#define HAS_SCALEROWDOWN4_WASMSIMD
#define HAS_SCALEROWUP2_BILINEAR_WASMSIMD
#define HAS_SCALEROWUP2_LINEAR_WASMSIMD
#define HAS_SCALESAMPLES_WASMSIMD
#define HAS_SCALESUMSAMPLES_WASMSIMD
#define HAS_SCALEUVADDCOLS3_WASMSIMD
#define HAS_SCALEUVROWDOWN2_WASMSIMD
#define HAS_SCALEUVROWDOWN2BOX_WASMSIMD
#define HAS_SCALEUVROWDOWN2LINEAR_WASMSIMD
#define HAS_SCALEUVROWDOWNEVEN_WASMSIMD
#define HAS_SCALEUVROWUP2_BILINEAR_WASMSIMD
#define HAS_SCALEUVROWUP2_LINEAR_WASMSIMD
#endif
// The following are available for WebAssembly Relaxed SIMD:
#if !defined(LIBYUV_DISABLE_RELAXEDSIMD) && defined(__wasm_relaxed_simd__)
#define HAS_SCALEROWDOWN34_RELAXEDSIMD
#define HAS_SCALEROWDOWN38_RELAXEDSIMD
#define HAS_SCALEROWUP2_BILINEAR_RELAXEDSIMD
#define HAS_SCALEROWUP2_LINEAR_RELAXEDSIMD
#define HAS_SCALEUVROWUP2_BILINEAR_RELAXEDSIMD
#define HAS_SCALEUVROWUP2_LINEAR_RELAXEDSIMD
#endif
// The following are available for Hexagon HVX:
@ -2247,6 +2268,164 @@ void ScaleARGBColsUp2_WASMSIMD(uint8_t* dst_argb,
int dst_width,
int x,
int dx);
void ScaleRowDown34_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_0_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_1_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_3_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_2_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_0_Box_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown34_1_Box_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_3_Box_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowDown38_2_Box_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowDown2_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDown2Linear_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDown2Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width);
void ScaleUVRowDown2_Any_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowDown2Linear_Any_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowDown2Box_Any_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowDownEven_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
int src_stepx,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowDownEven_Any_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
int src_stepx,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowUp2_Linear_WASMSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowUp2_Linear_RELAXEDSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowUp2_Linear_Any_WASMSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowUp2_Linear_Any_RELAXEDSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleRowUp2_Bilinear_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleRowUp2_Bilinear_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleRowUp2_Bilinear_Any_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleRowUp2_Bilinear_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleUVRowUp2_Linear_WASMSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowUp2_Linear_RELAXEDSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowUp2_Linear_Any_WASMSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowUp2_Linear_Any_RELAXEDSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width);
void ScaleUVRowUp2_Bilinear_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleUVRowUp2_Bilinear_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleUVRowUp2_Bilinear_Any_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleUVRowUp2_Bilinear_Any_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width);
void ScaleSamples_WASMSIMD(const float* src,
float* dst,
float scale,
int width);
float ScaleSumSamples_WASMSIMD(const float* src,
float* dst,
float scale,
int width);
float ScaleMaxSamples_WASMSIMD(const float* src,
float* dst,
float scale,
int width);
void ScaleAddRow_HVX(const uint8_t* src_ptr, uint16_t* dst_ptr, int src_width);
void ScaleRowDown2_HVX(const uint8_t* src_ptr,

View File

@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1978
#define LIBYUV_VERSION 1979
#endif // INCLUDE_LIBYUV_VERSION_H_

View File

@ -252,6 +252,11 @@ uint64_t ComputeHammingDistance(const uint8_t* src_a,
HammingDistance = HammingDistance_WASMSIMD;
}
#endif
#if defined(HAS_HAMMINGDISTANCE_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
HammingDistance = HammingDistance_RELAXEDSIMD;
}
#endif
#if defined(HAS_HAMMINGDISTANCE_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
HammingDistance = HammingDistance_HVX;

View File

@ -12,7 +12,8 @@
#include "libyuv/row.h"
#include "libyuv/video_common.h"
#if !defined(LIBYUV_DISABLE_WASM) && defined(__wasm_simd128__)
#if (!defined(LIBYUV_DISABLE_WASMSIMD) && defined(__wasm_simd128__)) || \
(!defined(LIBYUV_DISABLE_RELAXEDSIMD) && defined(__wasm_relaxed_simd__))
#include <wasm_simd128.h>
#ifdef __cplusplus
@ -29,15 +30,11 @@ static inline uint32_t SumLanes_WASMSIMD(v128_t sum) {
#if defined(HAS_HAMMINGDISTANCE_WASMSIMD)
// Bit counts of 64 bytes are added as bytes, then accumulated into 32 bit
// lanes using relaxed i8x16 dot product when available or pairwise widening
// adds. Count is a multiple of 64.
// lanes using pairwise widening adds. Count is a multiple of 64.
uint32_t HammingDistance_WASMSIMD(const uint8_t* src_a,
const uint8_t* src_b,
int count) {
v128_t sum = wasm_i32x4_splat(0);
#ifdef __wasm_relaxed_simd__
const v128_t ones = wasm_i8x16_splat(1);
#endif
while (count > 0) {
v128_t c0 = wasm_i8x16_popcnt(
wasm_v128_xor(wasm_v128_load(src_a), wasm_v128_load(src_b)));
@ -48,12 +45,8 @@ uint32_t HammingDistance_WASMSIMD(const uint8_t* src_a,
v128_t c3 = wasm_i8x16_popcnt(
wasm_v128_xor(wasm_v128_load(src_a + 48), wasm_v128_load(src_b + 48)));
v128_t c = wasm_i8x16_add(wasm_i8x16_add(c0, c1), wasm_i8x16_add(c2, c3));
#ifdef __wasm_relaxed_simd__
sum = wasm_i32x4_relaxed_dot_i8x16_i7x16_add(c, ones, sum);
#else
sum = wasm_i32x4_add(sum, wasm_u32x4_extadd_pairwise_u16x8(
wasm_u16x8_extadd_pairwise_u8x16(c)));
#endif
src_a += 64;
src_b += 64;
count -= 64;
@ -62,6 +55,33 @@ uint32_t HammingDistance_WASMSIMD(const uint8_t* src_a,
}
#endif // HAS_HAMMINGDISTANCE_WASMSIMD
#if defined(HAS_HAMMINGDISTANCE_RELAXEDSIMD)
// Bit counts of 64 bytes are added as bytes, then accumulated into 32 bit
// lanes using relaxed i8x16 dot product. Count is a multiple of 64.
uint32_t HammingDistance_RELAXEDSIMD(const uint8_t* src_a,
const uint8_t* src_b,
int count) {
v128_t sum = wasm_i32x4_splat(0);
const v128_t ones = wasm_i8x16_splat(1);
while (count > 0) {
v128_t c0 = wasm_i8x16_popcnt(
wasm_v128_xor(wasm_v128_load(src_a), wasm_v128_load(src_b)));
v128_t c1 = wasm_i8x16_popcnt(
wasm_v128_xor(wasm_v128_load(src_a + 16), wasm_v128_load(src_b + 16)));
v128_t c2 = wasm_i8x16_popcnt(
wasm_v128_xor(wasm_v128_load(src_a + 32), wasm_v128_load(src_b + 32)));
v128_t c3 = wasm_i8x16_popcnt(
wasm_v128_xor(wasm_v128_load(src_a + 48), wasm_v128_load(src_b + 48)));
v128_t c = wasm_i8x16_add(wasm_i8x16_add(c0, c1), wasm_i8x16_add(c2, c3));
sum = wasm_i32x4_relaxed_dot_i8x16_i7x16_add(c, ones, sum);
src_a += 64;
src_b += 64;
count -= 64;
}
return SumLanes_WASMSIMD(sum);
}
#endif // HAS_HAMMINGDISTANCE_RELAXEDSIMD
#if defined(HAS_SUMSQUAREERROR_WASMSIMD)
// Differences are widened to signed 16 bits and squared with i32x4.dot.
// Count is a multiple of 16.

View File

@ -326,6 +326,14 @@ static int I41xToI420(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_CONVERT16TO8ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Convert16To8Row = Convert16To8Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
Convert16To8Row = Convert16To8Row_WASMSIMD;
}
}
#endif
if (IS_ALIGNED(width, 2)) {
#if defined(HAS_HALFWIDTHROW_16TO8_NEON)
@ -371,6 +379,14 @@ static int I41xToI420(const uint16_t* src_y,
if (TestCpuFlag(kCpuHasRVV)) {
HalfWidthRow_16To8 = HalfWidthRow_16To8_RVV;
}
#endif
#if defined(HAS_HALFWIDTHROW_16TO8_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
HalfWidthRow_16To8 = HalfWidthRow_16To8_Any_WASMSIMD;
if (IS_ALIGNED(uv_width, 8)) {
HalfWidthRow_16To8 = HalfWidthRow_16To8_WASMSIMD;
}
}
#endif
} else {
#if defined(HAS_HALFWIDTHROW_16TO8_NEON)
@ -516,6 +532,14 @@ static int I21xToI420(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_CONVERT16TO8ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Convert16To8Row = Convert16To8Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
Convert16To8Row = Convert16To8Row_WASMSIMD;
}
}
#endif
#if defined(HAS_HALFROW_16TO8_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
@ -582,6 +606,14 @@ static int I21xToI420(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_HALFROW_16TO8_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
HalfRow_16To8 = HalfRow_16To8_Any_WASMSIMD;
if (IS_ALIGNED(uv_width, 16)) {
HalfRow_16To8 = HalfRow_16To8_WASMSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
HalfRow_16To8(src_u, src_stride_u, dst_u, scale, uv_width);
@ -1048,6 +1080,14 @@ int I010ToNV12(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_CONVERT16TO8ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Convert16To8Row = Convert16To8Row_Any_WASMSIMD;
if (IS_ALIGNED(halfwidth, 16)) {
Convert16To8Row = Convert16To8Row_WASMSIMD;
}
}
#endif
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
@ -2210,6 +2250,14 @@ static int Px10ToI420(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_CONVERT16TO8ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Convert16To8Row = Convert16To8Row_Any_WASMSIMD;
if (IS_ALIGNED(uv_packed, 16)) {
Convert16To8Row = Convert16To8Row_WASMSIMD;
}
}
#endif
#if defined(HAS_SPLITUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SplitUVRow = SplitUVRow_Any_SSE2;
@ -2275,6 +2323,14 @@ static int Px10ToI420(const uint16_t* src_y,
SplitUVRow = SplitUVRow_HVX;
}
#endif
#if defined(HAS_SPLITUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow = SplitUVRow_Any_WASMSIMD;
if (IS_ALIGNED(src_uv_width, 16)) {
SplitUVRow = SplitUVRow_WASMSIMD;
}
}
#endif
align_buffer_64(row_uv, ((uv_packed + 63) & ~63));
if (!row_uv) {
@ -2340,6 +2396,14 @@ static int Px10ToI420(const uint16_t* src_y,
SplitUVRow_16 = SplitUVRow_16_LASX;
}
}
#endif
#if defined(HAS_SPLITUVROW_16_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow_16 = SplitUVRow_16_Any_WASMSIMD;
if (IS_ALIGNED(src_uv_width, 8)) {
SplitUVRow_16 = SplitUVRow_16_WASMSIMD;
}
}
#endif
if (subsample_x) {
#if defined(HAS_HALFROW_16TO8_NEON)
@ -2406,6 +2470,14 @@ static int Px10ToI420(const uint16_t* src_y,
Half16To8 = HalfRow_16To8_LASX;
}
}
#endif
#if defined(HAS_HALFROW_16TO8_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Half16To8 = HalfRow_16To8_Any_WASMSIMD;
if (IS_ALIGNED(dst_uv_width, 16)) {
Half16To8 = HalfRow_16To8_WASMSIMD;
}
}
#endif
} else if (IS_ALIGNED(width, 2)) {
#if defined(HAS_HALFWIDTHROW_16TO8_NEON)
@ -2451,6 +2523,14 @@ static int Px10ToI420(const uint16_t* src_y,
if (TestCpuFlag(kCpuHasRVV)) {
Half16To8 = HalfWidthRow_16To8_RVV;
}
#endif
#if defined(HAS_HALFWIDTHROW_16TO8_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Half16To8 = HalfWidthRow_16To8_Any_WASMSIMD;
if (IS_ALIGNED(dst_uv_width, 8)) {
Half16To8 = HalfWidthRow_16To8_WASMSIMD;
}
}
#endif
} else {
#if defined(HAS_HALFWIDTHROW_16TO8_NEON)
@ -2721,6 +2801,16 @@ int YUY2ToI420(const uint8_t* src_yuy2,
YUY2ToUVRow = YUY2ToUVRow_HVX;
}
#endif
#if defined(HAS_YUY2TOYROW_WASMSIMD) && defined(HAS_YUY2TOUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
YUY2ToYRow = YUY2ToYRow_Any_WASMSIMD;
YUY2ToUVRow = YUY2ToUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
YUY2ToYRow = YUY2ToYRow_WASMSIMD;
YUY2ToUVRow = YUY2ToUVRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
YUY2ToUVRow(src_yuy2, src_stride_yuy2, dst_u, dst_v, width);
@ -2840,6 +2930,16 @@ int UYVYToI420(const uint8_t* src_uyvy,
UYVYToUVRow = UYVYToUVRow_HVX;
}
#endif
#if defined(HAS_UYVYTOYROW_WASMSIMD) && defined(HAS_UYVYTOUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
UYVYToYRow = UYVYToYRow_Any_WASMSIMD;
UYVYToUVRow = UYVYToUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
UYVYToYRow = UYVYToYRow_WASMSIMD;
UYVYToUVRow = UYVYToUVRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width);
@ -2940,6 +3040,24 @@ int AYUVToNV12(const uint8_t* src_ayuv,
}
}
#endif
#if defined(HAS_AYUVTOYROW_WASMSIMD) && defined(HAS_AYUVTOUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
AYUVToYRow = AYUVToYRow_Any_WASMSIMD;
AYUVToUVRow = AYUVToUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
AYUVToYRow = AYUVToYRow_WASMSIMD;
AYUVToUVRow = AYUVToUVRow_WASMSIMD;
}
}
#endif
#if defined(HAS_AYUVTOUVROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
AYUVToUVRow = AYUVToUVRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
AYUVToUVRow = AYUVToUVRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
AYUVToUVRow(src_ayuv, src_stride_ayuv, dst_uv, width);
@ -3039,6 +3157,24 @@ int AYUVToNV21(const uint8_t* src_ayuv,
}
}
#endif
#if defined(HAS_AYUVTOYROW_WASMSIMD) && defined(HAS_AYUVTOVUROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
AYUVToYRow = AYUVToYRow_Any_WASMSIMD;
AYUVToVURow = AYUVToVURow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
AYUVToYRow = AYUVToYRow_WASMSIMD;
AYUVToVURow = AYUVToVURow_WASMSIMD;
}
}
#endif
#if defined(HAS_AYUVTOVUROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
AYUVToVURow = AYUVToVURow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
AYUVToVURow = AYUVToVURow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
AYUVToVURow(src_ayuv, src_stride_ayuv, dst_vu, width);
@ -3258,6 +3394,14 @@ int ARGBToI420Matrix(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_HVX;
@ -3517,6 +3661,14 @@ int ARGBToI420Alpha(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_HVX;
@ -3769,6 +3921,14 @@ static int AR30ToI420Matrix(const uint8_t* src_ar30,
}
}
#endif
#if defined(HAS_AR30TOARGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
AR30ToARGBRow = AR30ToARGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
AR30ToARGBRow = AR30ToARGBRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOYMATRIXROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
ARGBToYMatrixRow = ARGBToYMatrixRow_Any_SSSE3;
@ -3934,6 +4094,14 @@ static int AR30ToI420Matrix(const uint8_t* src_ar30,
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_HVX;
@ -4119,6 +4287,14 @@ int RGB24ToI420(const uint8_t* src_rgb24,
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_WASMSIMD;
@ -4127,6 +4303,14 @@ int RGB24ToI420(const uint8_t* src_rgb24,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
if (!src_rgb24 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0 ||
height == INT_MIN) {
@ -4277,6 +4461,14 @@ int RGB24ToJ420(const uint8_t* src_rgb24,
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_WASMSIMD;
@ -4285,6 +4477,14 @@ int RGB24ToJ420(const uint8_t* src_rgb24,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
if (!src_rgb24 || !dst_y || !dst_u || !dst_v || width <= 0 || height == 0 ||
height == INT_MIN) {
@ -4424,6 +4624,14 @@ int RAWToI420(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_WASMSIMD;
@ -4432,6 +4640,14 @@ int RAWToI420(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_RVV)
if (TestCpuFlag(kCpuHasRVV)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_RVV;
@ -4582,6 +4798,14 @@ int RAWToJ420(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_WASMSIMD;
@ -4590,6 +4814,14 @@ int RAWToJ420(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_RVV)
if (TestCpuFlag(kCpuHasRVV)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_RVV;
@ -4715,6 +4947,14 @@ static int RAWToI444Matrix(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOUV444MATRIXROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
@ -4758,6 +4998,14 @@ static int RAWToI444Matrix(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOUV444MATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToUV444MatrixRow = RGBToUV444MatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToUV444MatrixRow = RGBToUV444MatrixRow_RELAXEDSIMD;
}
}
#endif
if (!src_raw || !dst_y || !dst_u || !dst_v || !argbconstants || width <= 0 ||
height == 0 || height == INT_MIN) {
@ -5204,6 +5452,14 @@ int RGB24ToJ400(const uint8_t* src_rgb24,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
RGBToYMatrixRow(src_rgb24, dst_yj, width, &kArgbJPEGConstants);
@ -5306,6 +5562,14 @@ int RAWToJ400(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
RGBToYMatrixRow(src_raw, dst_yj, width, &kAbgrJPEGConstants);

File diff suppressed because it is too large Load Diff

View File

@ -414,6 +414,14 @@ int I422ToYUY2(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_I422TOYUY2ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
I422ToYUY2Row = I422ToYUY2Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
I422ToYUY2Row = I422ToYUY2Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width);
@ -490,6 +498,14 @@ int I420ToYUY2(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_I422TOYUY2ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
I422ToYUY2Row = I422ToYUY2Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
I422ToYUY2Row = I422ToYUY2Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width);
@ -579,6 +595,14 @@ int I422ToUYVY(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_I422TOUYVYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
I422ToUYVYRow = I422ToUYVYRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
I422ToUYVYRow = I422ToUYVYRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width);
@ -655,6 +679,14 @@ int I420ToUYVY(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_I422TOUYVYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
I422ToUYVYRow = I422ToUYVYRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
I422ToUYVYRow = I422ToUYVYRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width);
@ -890,6 +922,14 @@ static int I4xxToPxxx(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_MERGEUVROW_16_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
MergeUVRow_16 = MergeUVRow_16_Any_WASMSIMD;
if (IS_ALIGNED(uv_width, 8)) {
MergeUVRow_16 = MergeUVRow_16_WASMSIMD;
}
}
#endif
row_stride = (uv_width + 31) & ~31;
align_buffer_64(row_u, (size_t)row_stride * sizeof(uint16_t) * 2u);

View File

@ -216,6 +216,14 @@ int ARGBToI444Matrix(const uint8_t* src_argb,
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUV444MATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_RELAXEDSIMD;
}
}
#endif
if (!src_argb || !dst_y || !dst_u || !dst_v || !argbconstants || width <= 0 ||
height == 0 || height == INT_MIN) {
@ -446,6 +454,14 @@ int ARGBToI422Matrix(const uint8_t* src_argb,
ARGBToUVMatrixRow = ARGBToUVMatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
if (!src_argb || !dst_y || !dst_u || !dst_v || !argbconstants || width <= 0 ||
height == 0 || height == INT_MIN) {
@ -672,6 +688,14 @@ int ARGBToNV12Matrix(const uint8_t* src_argb,
ARGBToUVMatrixRow = ARGBToUVMatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v,
uint8_t* dst_uv, int width) = MergeUVRow_C;
@ -988,6 +1012,14 @@ int ARGBToNV16Matrix(const uint8_t* src_argb,
ARGBToUVMatrixRow = ARGBToUVMatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v,
uint8_t* dst_uv, int width) = MergeUVRow_C;
@ -1284,6 +1316,14 @@ int ARGBToNV24Matrix(const uint8_t* src_argb,
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUV444MATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_RELAXEDSIMD;
}
}
#endif
void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v,
uint8_t* dst_uv, int width) = MergeUVRow_C;
@ -1582,6 +1622,14 @@ int ARGBToNV21Matrix(const uint8_t* src_argb,
ARGBToUVMatrixRow = ARGBToUVMatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v,
uint8_t* dst_vu, int width) = MergeUVRow_C;
@ -2013,6 +2061,14 @@ int ARGBToYUY2Matrix(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_HVX;
@ -2058,6 +2114,14 @@ int ARGBToYUY2Matrix(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_I422TOYUY2ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
I422ToYUY2Row = I422ToYUY2Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
I422ToYUY2Row = I422ToYUY2Row_WASMSIMD;
}
}
#endif
{
align_buffer_64(row_y, ((width + 63) & ~63) * 2);
@ -2272,6 +2336,14 @@ int ARGBToUYVYMatrix(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_HVX;
@ -2317,6 +2389,14 @@ int ARGBToUYVYMatrix(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_I422TOUYVYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
I422ToUYVYRow = I422ToUYVYRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
I422ToUYVYRow = I422ToUYVYRow_WASMSIMD;
}
}
#endif
{
align_buffer_64(row_y, ((width + 63) & ~63) * 2);
@ -2565,6 +2645,14 @@ int ARGBToP010Matrix(const uint8_t* src_argb,
ARGBToUVMatrixRow = ARGBToUVMatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
// Negative height means invert the image.
if (height < 0) {
@ -3036,6 +3124,14 @@ int ARGBToP210Matrix(const uint8_t* src_argb,
ARGBToUVMatrixRow = ARGBToUVMatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUVMatrixRow = ARGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
// Negative height means invert the image.
if (height < 0) {
@ -3478,6 +3574,14 @@ int ARGBToP410Matrix(const uint8_t* src_argb,
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTOUV444MATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToUV444MatrixRow = ARGBToUV444MatrixRow_RELAXEDSIMD;
}
}
#endif
// Negative height means invert the image.
if (height < 0) {
@ -3939,6 +4043,22 @@ int ARGBToRGB24(const uint8_t* src_argb,
ARGBToRGB24Row = ARGBToRGB24Row_RVV;
}
#endif
#if defined(HAS_ARGBTORGB24ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBToRGB24Row = ARGBToRGB24Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToRGB24Row = ARGBToRGB24Row_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTORGB24ROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToRGB24Row = ARGBToRGB24Row_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToRGB24Row = ARGBToRGB24Row_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToRGB24Row(src_argb, dst_rgb24, width);
@ -4034,6 +4154,22 @@ int ARGBToRAW(const uint8_t* src_argb,
ARGBToRAWRow = ARGBToRAWRow_RVV;
}
#endif
#if defined(HAS_ARGBTORAWROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBToRAWRow = ARGBToRAWRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToRAWRow = ARGBToRAWRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBTORAWROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBToRAWRow = ARGBToRAWRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
ARGBToRAWRow = ARGBToRAWRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToRAWRow(src_argb, dst_raw, width);
@ -4458,6 +4594,14 @@ int ABGRToAR30(const uint8_t* src_abgr,
ABGRToAR30Row = ABGRToAR30Row_LASX;
}
}
#endif
#if defined(HAS_ABGRTOAR30ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ABGRToAR30Row = ABGRToAR30Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ABGRToAR30Row = ABGRToAR30Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ABGRToAR30Row(src_abgr, dst_ar30, width);
@ -4538,6 +4682,14 @@ int ARGBToAR30(const uint8_t* src_argb,
ARGBToAR30Row = ARGBToAR30Row_LASX;
}
}
#endif
#if defined(HAS_ARGBTOAR30ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBToAR30Row = ARGBToAR30Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBToAR30Row = ARGBToAR30Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToAR30Row(src_argb, dst_ar30, width);
@ -4746,6 +4898,14 @@ int ARGBToAR64(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBTOAR64ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBToAR64Row = ARGBToAR64Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 8)) {
ARGBToAR64Row = ARGBToAR64Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToAR64Row(src_argb, dst_ar64, width);
@ -4833,6 +4993,14 @@ int ARGBToAB64(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBTOAB64ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBToAB64Row = ARGBToAB64Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 8)) {
ARGBToAB64Row = ARGBToAB64Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBToAB64Row(src_argb, dst_ab64, width);
@ -4940,6 +5108,14 @@ static int RAWToNVMatrix(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOYMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToYMatrixRow = RGBToYMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToYMatrixRow = RGBToYMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) {
@ -4983,6 +5159,14 @@ static int RAWToNVMatrix(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RGBTOUVMATRIXROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGBToUVMatrixRow = RGBToUVMatrixRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {

View File

@ -221,6 +221,14 @@ static int NV24ToARGB(const uint8_t* src_y,
I444ToARGBRow = I444ToARGBRow_HVX;
}
#endif
#if defined(HAS_I444TOARGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
I444ToARGBRow = I444ToARGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 8)) {
I444ToARGBRow = I444ToARGBRow_WASMSIMD;
}
}
#endif
#if defined(HAS_SPLITUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
@ -287,6 +295,14 @@ static int NV24ToARGB(const uint8_t* src_y,
SplitUVRow = SplitUVRow_HVX;
}
#endif
#if defined(HAS_SPLITUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow = SplitUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_WASMSIMD;
}
}
#endif
align_buffer_64(row_u, width);
align_buffer_64(row_v, width);

View File

@ -126,6 +126,14 @@ static int NV16ToI420(const uint8_t* src_y,
SplitUVRow = SplitUVRow_RVV;
}
#endif
#if defined(HAS_SPLITUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow = SplitUVRow_Any_WASMSIMD;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_WASMSIMD;
}
}
#endif
#if defined(HAS_INTERPOLATEROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
InterpolateRow = InterpolateRow_Any_AVX2;
@ -343,6 +351,14 @@ static int NV24ToI420(const uint8_t* src_y,
ScaleUVRowDown2Linear = ScaleUVRowDown2Linear_HVX;
}
#endif
#if defined(HAS_SCALEUVROWDOWN2_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ScaleUVRowDown2Linear = ScaleUVRowDown2Linear_Any_WASMSIMD;
if (IS_ALIGNED(halfwidth, 8)) {
ScaleUVRowDown2Linear = ScaleUVRowDown2Linear_WASMSIMD;
}
}
#endif
#if defined(HAS_SPLITUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SplitUVRow = SplitUVRow_Any_SSE2;
@ -408,6 +424,14 @@ static int NV24ToI420(const uint8_t* src_y,
SplitUVRow = SplitUVRow_HVX;
}
#endif
#if defined(HAS_SPLITUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow = SplitUVRow_Any_WASMSIMD;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_WASMSIMD;
}
}
#endif
align_buffer_64(row_uv, halfwidth * 6);
if (!row_uv) {

View File

@ -9,6 +9,11 @@
*/
#include "libyuv/cpu_id.h"
#include "libyuv/cpu_support.h"
#if defined(__wasm__) && defined(__wasm_simd128__)
#include <wasm_simd128.h>
#endif
#if defined(_MSC_VER)
#include <intrin.h> // For __cpuidex()
@ -420,6 +425,41 @@ LIBYUV_API SAFEBUFFERS int LoongArchCpuCaps(void) {
return flag;
}
// For WebAssembly, but public to allow testing on any CPU.
LIBYUV_API SAFEBUFFERS int WasmCpuCaps(void) {
int flag = 0;
#if defined(__wasm__)
#if !defined(LIBYUV_DISABLE_WASMSIMD) && defined(__wasm_simd128__)
flag |= kCpuHasWASMSIMD;
#endif
#if !defined(LIBYUV_DISABLE_RELAXEDSIMD) && defined(__wasm_relaxed_simd__)
// Probe whether the runtime executes Relaxed SIMD instructions natively on
// the host CPU:
// - On x86 (SSSE3/AVX2/AVX-512), i8x16.relaxed_swizzle lowers to vpshufb,
// which masks out-of-range index 16 by 0x0f and selects lane 0 (non-zero),
// whereas deterministic i8x16.swizzle zeroes out-of-range indices.
// - On AArch64 (Neon fmla) and x86 (FMA3/AVX2 vfmadd213ps),
// f32x4.relaxed_madd(16777218.f, 3.f, 3.f) computes a single-rounded
// fused multiply-add (50331656.f), whereas unfused mul+add rounds twice
// (50331660.f).
const v128_t kNonZero = wasm_i8x16_splat(1);
const volatile v128_t kIndex16 = wasm_i8x16_splat(16);
const v128_t swizzle_diff =
wasm_v128_xor(wasm_i8x16_relaxed_swizzle(kNonZero, kIndex16),
wasm_i8x16_swizzle(kNonZero, kIndex16));
const volatile v128_t kFmaA = wasm_f32x4_splat(16777218.0f);
const v128_t kFmaB = wasm_f32x4_splat(3.0f);
const v128_t fma_diff =
wasm_v128_xor(wasm_f32x4_relaxed_madd(kFmaA, kFmaB, kFmaB),
wasm_f32x4_add(kFmaB, wasm_f32x4_mul(kFmaA, kFmaB)));
if (wasm_v128_any_true(wasm_v128_or(swizzle_diff, fma_diff))) {
flag |= kCpuHasRELAXEDSIMD;
}
#endif
#endif // defined(__wasm__)
return flag;
}
static SAFEBUFFERS int GetCpuFlags(void) {
int cpu_info = 0;
#if !defined(__pnacl__) && !defined(__CLR_VER) && \
@ -552,10 +592,8 @@ static SAFEBUFFERS int GetCpuFlags(void) {
cpu_info |= kCpuHasRISCV;
#endif // __riscv
#if defined(__wasm__)
cpu_info = kCpuHasWASM;
#if !defined(LIBYUV_DISABLE_WASM) && defined(__wasm_simd128__)
cpu_info |= kCpuHasWASMSIMD;
#endif
cpu_info = WasmCpuCaps();
cpu_info |= kCpuHasWASM;
#endif // __wasm__
#if defined(__hexagon__)
cpu_info = kCpuHasHexagon;

View File

@ -110,6 +110,11 @@ void CopyPlane(const uint8_t* src_y,
CopyRow = CopyRow_HVX;
}
#endif
#if defined(HAS_COPYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
CopyRow = IS_ALIGNED(width, 64) ? CopyRow_WASMSIMD : CopyRow_Any_WASMSIMD;
}
#endif
// Copy plane
for (y = 0; y < height; ++y) {
@ -173,6 +178,12 @@ void CopyPlane_16(const uint16_t* src_y,
CopyRow = CopyRow_16_HVX;
}
#endif
#if defined(HAS_COPYROW_16_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
CopyRow =
IS_ALIGNED(width, 32) ? CopyRow_16_WASMSIMD : CopyRow_16_Any_WASMSIMD;
}
#endif
// Copy plane
for (y = 0; y < height; ++y) {
@ -266,6 +277,14 @@ void Convert16To8Plane(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_CONVERT16TO8ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Convert16To8Row = Convert16To8Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
Convert16To8Row = Convert16To8Row_WASMSIMD;
}
}
#endif
// Convert plane
for (y = 0; y < height; ++y) {
@ -473,6 +492,14 @@ void Convert8To8Plane(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_CONVERT8TO8ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Convert8To8Row = Convert8To8Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
Convert8To8Row = Convert8To8Row_WASMSIMD;
}
}
#endif
// Convert plane
for (y = 0; y < height; ++y) {
@ -844,6 +871,14 @@ void SplitUVPlane(const uint8_t* src_uv,
SplitUVRow = SplitUVRow_HVX;
}
#endif
#if defined(HAS_SPLITUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow = SplitUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
// Copy a row of UV.
@ -1036,6 +1071,14 @@ void SplitUVPlane_16(const uint16_t* src_uv,
}
}
#endif
#if defined(HAS_SPLITUVROW_16_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow_16 = SplitUVRow_16_Any_WASMSIMD;
if (IS_ALIGNED(width, 8)) {
SplitUVRow_16 = SplitUVRow_16_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
// Copy a row of UV.
@ -1125,6 +1168,14 @@ void MergeUVPlane_16(const uint16_t* src_u,
}
}
#endif
#if defined(HAS_MERGEUVROW_16_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
MergeUVRow_16 = MergeUVRow_16_Any_WASMSIMD;
if (IS_ALIGNED(width, 8)) {
MergeUVRow_16 = MergeUVRow_16_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
// Merge a row of U and V into a row of UV.
@ -1315,6 +1366,14 @@ void ConvertToLSBPlane_16(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_DIVIDEROW_16_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
DivideRow = DivideRow_16_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
DivideRow = DivideRow_16_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
DivideRow(src_y, dst_y, scale, width);
@ -1523,6 +1582,14 @@ int DetilePlane(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_DETILEROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
DetileRow = DetileRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
DetileRow = DetileRow_WASMSIMD;
}
}
#endif
// Detile plane
for (y = 0; y < height; ++y) {
@ -1596,6 +1663,14 @@ int DetilePlane_16(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_DETILEROW_16_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
DetileRow_16 = DetileRow_16_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
DetileRow_16 = DetileRow_16_WASMSIMD;
}
}
#endif
// Detile plane
for (y = 0; y < height; ++y) {
@ -1660,6 +1735,14 @@ void DetileSplitUVPlane(const uint8_t* src_uv,
}
}
#endif
#if defined(HAS_DETILESPLITUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
DetileSplitUVRow = DetileSplitUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
DetileSplitUVRow = DetileSplitUVRow_WASMSIMD;
}
}
#endif
// Detile plane
for (y = 0; y < height; ++y) {
@ -1726,6 +1809,14 @@ void DetileToYUY2(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_DETILETOYUY2_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
DetileToYUY2 = DetileToYUY2_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
DetileToYUY2 = DetileToYUY2_WASMSIMD;
}
}
#endif
// Detile plane
for (y = 0; y < height; ++y) {
@ -1819,6 +1910,22 @@ void SplitRGBPlane(const uint8_t* src_rgb,
SplitRGBRow = SplitRGBRow_RVV;
}
#endif
#if defined(HAS_SPLITRGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitRGBRow = SplitRGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SplitRGBRow = SplitRGBRow_WASMSIMD;
}
}
#endif
#if defined(HAS_SPLITRGBROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
SplitRGBRow = SplitRGBRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
SplitRGBRow = SplitRGBRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
// Copy a row of RGB.
@ -1889,6 +1996,22 @@ void MergeRGBPlane(const uint8_t* src_r,
MergeRGBRow = MergeRGBRow_RVV;
}
#endif
#if defined(HAS_MERGERGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
MergeRGBRow = MergeRGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
MergeRGBRow = MergeRGBRow_WASMSIMD;
}
}
#endif
#if defined(HAS_MERGERGBROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
MergeRGBRow = MergeRGBRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
MergeRGBRow = MergeRGBRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
// Merge a row of U and V into a row of RGB.
@ -1990,6 +2113,14 @@ static void SplitARGBPlaneAlpha(const uint8_t* src_argb,
SplitARGBRow = SplitARGBRow_HVX;
}
#endif
#if defined(HAS_SPLITARGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitARGBRow = SplitARGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SplitARGBRow = SplitARGBRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
SplitARGBRow(src_argb, dst_r, dst_g, dst_b, dst_a, width);
@ -2086,6 +2217,14 @@ static void SplitARGBPlaneOpaque(const uint8_t* src_argb,
SplitXRGBRow = SplitXRGBRow_HVX;
}
#endif
#if defined(HAS_SPLITXRGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitXRGBRow = SplitXRGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SplitXRGBRow = SplitXRGBRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
SplitXRGBRow(src_argb, dst_r, dst_g, dst_b, width);
@ -2218,6 +2357,14 @@ static void MergeARGBPlaneAlpha(const uint8_t* src_r,
MergeARGBRow = MergeARGBRow_HVX;
}
#endif
#if defined(HAS_MERGEARGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
MergeARGBRow = MergeARGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
MergeARGBRow = MergeARGBRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
MergeARGBRow(src_r, src_g, src_b, src_a, dst_argb, width);
@ -2306,6 +2453,14 @@ static void MergeARGBPlaneOpaque(const uint8_t* src_r,
MergeXRGBRow = MergeXRGBRow_HVX;
}
#endif
#if defined(HAS_MERGEXRGBROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
MergeXRGBRow = MergeXRGBRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
MergeXRGBRow = MergeXRGBRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
MergeXRGBRow(src_r, src_g, src_b, dst_argb, width);
@ -2830,6 +2985,16 @@ int YUY2ToI422(const uint8_t* src_yuy2,
YUY2ToUV422Row = YUY2ToUV422Row_HVX;
}
#endif
#if defined(HAS_YUY2TOYROW_WASMSIMD) && defined(HAS_YUY2TOUV422ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
YUY2ToYRow = YUY2ToYRow_Any_WASMSIMD;
YUY2ToUV422Row = YUY2ToUV422Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
YUY2ToYRow = YUY2ToYRow_WASMSIMD;
YUY2ToUV422Row = YUY2ToUV422Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width);
@ -2949,6 +3114,16 @@ int UYVYToI422(const uint8_t* src_uyvy,
UYVYToUV422Row = UYVYToUV422Row_HVX;
}
#endif
#if defined(HAS_UYVYTOYROW_WASMSIMD) && defined(HAS_UYVYTOUV422ROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
UYVYToYRow = UYVYToYRow_Any_WASMSIMD;
UYVYToUV422Row = UYVYToUV422Row_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
UYVYToYRow = UYVYToYRow_WASMSIMD;
UYVYToUV422Row = UYVYToUV422Row_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
UYVYToUV422Row(src_uyvy, dst_u, dst_v, width);
@ -3048,6 +3223,14 @@ int YUY2ToY(const uint8_t* src_yuy2,
YUY2ToYRow = YUY2ToYRow_HVX;
}
#endif
#if defined(HAS_YUY2TOYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
YUY2ToYRow = YUY2ToYRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
YUY2ToYRow = YUY2ToYRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
YUY2ToYRow(src_yuy2, dst_y, width);
@ -3144,6 +3327,14 @@ int UYVYToY(const uint8_t* src_uyvy,
UYVYToYRow = UYVYToYRow_HVX;
}
#endif
#if defined(HAS_UYVYTOYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
UYVYToYRow = UYVYToYRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
UYVYToYRow = UYVYToYRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
UYVYToYRow(src_uyvy, dst_y, width);
@ -3226,6 +3417,14 @@ void MirrorPlane(const uint8_t* src_y,
}
}
#endif
#if defined(HAS_MIRRORROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
MirrorRow = MirrorRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
MirrorRow = MirrorRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_MIRRORROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
MirrorRow = MirrorRow_HVX;
@ -3334,6 +3533,17 @@ void MirrorPlane_16(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_MIRRORUVROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
MirrorRow_16 = reinterpret_cast<void (*)(const uint16_t*, uint16_t*, int)>(
MirrorUVRow_Any_RELAXEDSIMD);
if (IS_ALIGNED(width, 8)) {
MirrorRow_16 =
reinterpret_cast<void (*)(const uint16_t*, uint16_t*, int)>(
MirrorUVRow_RELAXEDSIMD);
}
}
#endif
#if defined(HAS_MIRRORROW_16_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
MirrorRow_16 = MirrorRow_16_HVX;
@ -3426,6 +3636,14 @@ void MirrorUVPlane(const uint8_t* src_uv,
}
}
#endif
#if defined(HAS_MIRRORUVROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
MirrorUVRow = MirrorUVRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 8)) {
MirrorUVRow = MirrorUVRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_MIRRORUVROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
MirrorUVRow = MirrorUVRow_HVX;
@ -3696,6 +3914,14 @@ int RGB24Mirror(const uint8_t* src_rgb24,
}
}
#endif
#if defined(HAS_RGB24MIRRORROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RGB24MirrorRow = RGB24MirrorRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RGB24MirrorRow = RGB24MirrorRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_RGB24MIRRORROW_LSX)
if (TestCpuFlag(kCpuHasLSX)) {
RGB24MirrorRow = RGB24MirrorRow_Any_LSX;
@ -3793,6 +4019,11 @@ int ARGBBlend(const uint8_t* src_argb0,
ARGBBlendRow = ARGBBlendRow_WASMSIMD;
}
#endif
#if defined(HAS_ARGBBLENDROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBBlendRow = ARGBBlendRow_RELAXEDSIMD;
}
#endif
#if defined(HAS_ARGBBLENDROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
ARGBBlendRow = ARGBBlendRow_HVX;
@ -4356,6 +4587,14 @@ int ARGBMultiply(const uint8_t* src_argb0,
ARGBMultiplyRow = ARGBMultiplyRow_HVX;
}
#endif
#if defined(HAS_ARGBMULTIPLYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBMultiplyRow = ARGBMultiplyRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBMultiplyRow = ARGBMultiplyRow_WASMSIMD;
}
}
#endif
// Multiply plane
for (y = 0; y < height; ++y) {
@ -4442,6 +4681,14 @@ int ARGBAdd(const uint8_t* src_argb0,
ARGBAddRow = ARGBAddRow_HVX;
}
#endif
#if defined(HAS_ARGBADDROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBAddRow = ARGBAddRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBAddRow = ARGBAddRow_WASMSIMD;
}
}
#endif
// Add plane
for (y = 0; y < height; ++y) {
@ -4528,6 +4775,14 @@ int ARGBSubtract(const uint8_t* src_argb0,
ARGBSubtractRow = ARGBSubtractRow_HVX;
}
#endif
#if defined(HAS_ARGBSUBTRACTROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBSubtractRow = ARGBSubtractRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBSubtractRow = ARGBSubtractRow_WASMSIMD;
}
}
#endif
// Subtract plane
for (y = 0; y < height; ++y) {
@ -4750,6 +5005,14 @@ int RAWToRGB24(const uint8_t* src_raw,
}
}
#endif
#if defined(HAS_RAWTORGB24ROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
RAWToRGB24Row = RAWToRGB24Row_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
RAWToRGB24Row = RAWToRGB24Row_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
RAWToRGB24Row(src_raw, dst_rgb24, width);
@ -4825,6 +5088,14 @@ void SetPlane(uint8_t* dst_y,
SetRow = SetRow_HVX;
}
#endif
#if defined(HAS_SETROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SetRow = SetRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SetRow = SetRow_WASMSIMD;
}
}
#endif
// Set plane
for (y = 0; y < height; ++y) {
@ -4937,6 +5208,14 @@ int ARGBRect(uint8_t* dst_argb,
ARGBSetRow = ARGBSetRow_RVV;
}
#endif
#if defined(HAS_ARGBSETROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBSetRow = ARGBSetRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBSetRow = ARGBSetRow_WASMSIMD;
}
}
#endif
// Set plane
for (y = 0; y < height; ++y) {
@ -5040,6 +5319,22 @@ int ARGBAttenuate(const uint8_t* src_argb,
ARGBAttenuateRow = ARGBAttenuateRow_HVX;
}
#endif
#if defined(HAS_ARGBATTENUATEROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBAttenuateRow = ARGBAttenuateRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBAttenuateRow = ARGBAttenuateRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBATTENUATEROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBAttenuateRow = ARGBAttenuateRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBAttenuateRow = ARGBAttenuateRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBAttenuateRow(src_argb, dst_argb, width);
@ -5183,6 +5478,22 @@ int ARGBGrayTo(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBGRAYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBGrayRow = ARGBGrayRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBGrayRow = ARGBGrayRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBGRAYROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBGrayRow = ARGBGrayRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBGrayRow = ARGBGrayRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBGrayRow(src_argb, dst_argb, width);
@ -5260,6 +5571,22 @@ int ARGBGray(uint8_t* dst_argb,
}
}
#endif
#if defined(HAS_ARGBGRAYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBGrayRow = ARGBGrayRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBGrayRow = ARGBGrayRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBGRAYROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBGrayRow = ARGBGrayRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBGrayRow = ARGBGrayRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBGrayRow(dst, dst, width);
@ -5330,6 +5657,22 @@ int ARGBSepia(uint8_t* dst_argb,
}
}
#endif
#if defined(HAS_ARGBSEPIAROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBSepiaRow = ARGBSepiaRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBSepiaRow = ARGBSepiaRow_WASMSIMD;
}
}
#endif
#if defined(HAS_ARGBSEPIAROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBSepiaRow = ARGBSepiaRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBSepiaRow = ARGBSepiaRow_RELAXEDSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBSepiaRow(dst, width);
@ -5409,6 +5752,14 @@ int ARGBColorMatrix(const uint8_t* src_argb,
ARGBColorMatrixRow = ARGBColorMatrixRow_LASX;
}
}
#endif
#if defined(HAS_ARGBCOLORMATRIXROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBColorMatrixRow = ARGBColorMatrixRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBColorMatrixRow = ARGBColorMatrixRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBColorMatrixRow(src_argb, dst_argb, matrix_argb, width);
@ -5598,6 +5949,14 @@ int ARGBQuantize(uint8_t* dst_argb,
ARGBQuantizeRow = ARGBQuantizeRow_LASX;
}
}
#endif
#if defined(HAS_ARGBQUANTIZEROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBQuantizeRow = ARGBQuantizeRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBQuantizeRow = ARGBQuantizeRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBQuantizeRow(dst, scale, interval_size, interval_offset, width);
@ -5821,6 +6180,14 @@ int ARGBShade(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBSHADEROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBShadeRow = ARGBShadeRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBShadeRow = ARGBShadeRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBShadeRow(src_argb, dst_argb, width, value);
@ -6178,6 +6545,14 @@ int ARGBShuffle(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBSHUFFLEROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBShuffleRow = ARGBShuffleRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBShuffleRow = ARGBShuffleRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_ARGBSHUFFLEROW_RVV)
if (TestCpuFlag(kCpuHasRVV)) {
ARGBShuffleRow = ARGBShuffleRow_RVV;
@ -6275,6 +6650,14 @@ int AR64Shuffle(const uint16_t* src_ar64,
}
}
#endif
#if defined(HAS_ARGBSHUFFLEROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
AR64ShuffleRow = ARGBShuffleRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 4)) {
AR64ShuffleRow = ARGBShuffleRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_ARGBSHUFFLEROW_RVV)
if (TestCpuFlag(kCpuHasRVV)) {
AR64ShuffleRow = ARGBShuffleRow_RVV;
@ -6509,6 +6892,11 @@ static int ARGBSobelize(const uint8_t* src_argb,
SobelYRow = SobelYRow_NEON;
}
#endif
#if defined(HAS_SOBELYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SobelYRow = SobelYRow_WASMSIMD;
}
#endif
#if defined(HAS_SOBELXROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
SobelXRow = SobelXRow_AVX2;
@ -6518,6 +6906,11 @@ static int ARGBSobelize(const uint8_t* src_argb,
if (TestCpuFlag(kCpuHasNEON)) {
SobelXRow = SobelXRow_NEON;
}
#endif
#if defined(HAS_SOBELXROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SobelXRow = SobelXRow_WASMSIMD;
}
#endif
{
// 3 rows with edges before/after.
@ -6610,6 +7003,22 @@ int ARGBSobel(const uint8_t* src_argb,
SobelRow = SobelRow_LASX;
}
}
#endif
#if defined(HAS_SOBELROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SobelRow = SobelRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SobelRow = SobelRow_WASMSIMD;
}
}
#endif
#if defined(HAS_SOBELROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
SobelRow = SobelRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
SobelRow = SobelRow_RELAXEDSIMD;
}
}
#endif
return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
width, height, SobelRow);
@ -6656,6 +7065,14 @@ int ARGBSobelToPlane(const uint8_t* src_argb,
SobelToPlaneRow = SobelToPlaneRow_LASX;
}
}
#endif
#if defined(HAS_SOBELTOPLANEROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SobelToPlaneRow = SobelToPlaneRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SobelToPlaneRow = SobelToPlaneRow_WASMSIMD;
}
}
#endif
return ARGBSobelize(src_argb, src_stride_argb, dst_y, dst_stride_y, width,
height, SobelToPlaneRow);
@ -6703,6 +7120,14 @@ int ARGBSobelXY(const uint8_t* src_argb,
SobelXYRow = SobelXYRow_LASX;
}
}
#endif
#if defined(HAS_SOBELXYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SobelXYRow = SobelXYRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
SobelXYRow = SobelXYRow_WASMSIMD;
}
}
#endif
return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
width, height, SobelXYRow);
@ -6761,6 +7186,14 @@ int ARGBPolynomial(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBPOLYNOMIALROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBPolynomialRow = ARGBPolynomialRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBPolynomialRow = ARGBPolynomialRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBPolynomialRow(src_argb, dst_argb, poly, width);
@ -6865,6 +7298,14 @@ int HalfFloatPlane(const uint16_t* src_y,
}
}
#endif
#if defined(HAS_HALFFLOATROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
HalfFloatRow = HalfFloatRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
HalfFloatRow = HalfFloatRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
HalfFloatRow(src_y, dst_y, scale, width);
@ -6898,6 +7339,14 @@ int ByteToFloat(const uint8_t* src_y, float* dst_y, float scale, int width) {
}
}
#endif
#if defined(HAS_BYTETOFLOATROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ByteToFloatRow = ByteToFloatRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
ByteToFloatRow = ByteToFloatRow_WASMSIMD;
}
}
#endif
ByteToFloatRow(src_y, dst_y, scale, width);
return 0;
@ -6946,6 +7395,14 @@ int ARGBLumaColorTable(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBLUMACOLORTABLEROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBLumaColorTableRow = ARGBLumaColorTableRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 4)) {
ARGBLumaColorTableRow = ARGBLumaColorTableRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBLumaColorTableRow(src_argb, dst_argb, width, luma, 0x00264b0f);
@ -7028,6 +7485,14 @@ int ARGBCopyAlpha(const uint8_t* src_argb,
}
}
#endif
#if defined(HAS_ARGBCOPYALPHAROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ARGBCopyAlphaRow = ARGBCopyAlphaRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 8)) {
ARGBCopyAlphaRow = ARGBCopyAlphaRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height; ++y) {
ARGBCopyAlphaRow(src_argb, dst_argb, width);
@ -7185,6 +7650,13 @@ int ARGBCopyYToAlpha(const uint8_t* src_y,
: ARGBCopyYToAlphaRow_Any_WASMSIMD;
}
#endif
#if defined(HAS_ARGBCOPYYTOALPHAROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ARGBCopyYToAlphaRow = IS_ALIGNED(width, 16)
? ARGBCopyYToAlphaRow_RELAXEDSIMD
: ARGBCopyYToAlphaRow_Any_RELAXEDSIMD;
}
#endif
#if defined(HAS_ARGBCOPYYTOALPHAROW_RVV)
if (TestCpuFlag(kCpuHasRVV)) {
ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_RVV;
@ -7305,6 +7777,14 @@ int YUY2ToNV12(const uint8_t* src_yuy2,
YUY2ToYRow = YUY2ToYRow_HVX;
}
#endif
#if defined(HAS_YUY2TOYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
YUY2ToYRow = YUY2ToYRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
YUY2ToYRow = YUY2ToYRow_WASMSIMD;
}
}
#endif
#if defined(HAS_YUY2TONVUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
@ -7347,6 +7827,14 @@ int YUY2ToNV12(const uint8_t* src_yuy2,
}
}
#endif
#if defined(HAS_YUY2TONVUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
YUY2ToNVUVRow = YUY2ToNVUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
YUY2ToNVUVRow = YUY2ToNVUVRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
YUY2ToYRow(src_yuy2, dst_y, width);
@ -7459,6 +7947,14 @@ int UYVYToNV12(const uint8_t* src_uyvy,
SplitUVRow = SplitUVRow_HVX;
}
#endif
#if defined(HAS_SPLITUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
SplitUVRow = SplitUVRow_Any_WASMSIMD;
if (IS_ALIGNED(awidth, 16)) {
SplitUVRow = SplitUVRow_WASMSIMD;
}
}
#endif
#if defined(HAS_INTERPOLATEROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
@ -7637,6 +8133,14 @@ void HalfMergeUVPlane(const uint8_t* src_u,
}
}
#endif
#if defined(HAS_HALFMERGEUVROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
HalfMergeUVRow = HalfMergeUVRow_Any_WASMSIMD;
if (IS_ALIGNED(width, 16)) {
HalfMergeUVRow = HalfMergeUVRow_WASMSIMD;
}
}
#endif
for (y = 0; y < height - 1; y += 2) {
// Merge a row of U and V into a row of UV.

View File

@ -290,6 +290,14 @@ void RotatePlane180(const uint8_t* src,
}
}
#endif
#if defined(HAS_MIRRORROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
MirrorRow = MirrorRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
MirrorRow = MirrorRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_MIRRORROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
MirrorRow = MirrorRow_HVX;
@ -350,6 +358,11 @@ void RotatePlane180(const uint8_t* src,
CopyRow = IS_ALIGNED(width, 32) ? CopyRow_LASX : CopyRow_Any_LASX;
}
#endif
#if defined(HAS_COPYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
CopyRow = IS_ALIGNED(width, 32) ? CopyRow_WASMSIMD : CopyRow_Any_WASMSIMD;
}
#endif
// Odd height will harmlessly mirror the middle row twice.
for (y = 0; y < half_height; ++y) {
@ -633,6 +646,14 @@ void SplitRotateUV180(const uint8_t* src,
}
}
#endif
#if defined(HAS_MIRRORSPLITUVROW_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
MirrorSplitUVRow = MirrorSplitUVRow_Any_RELAXEDSIMD;
if (IS_ALIGNED(width, 16)) {
MirrorSplitUVRow = MirrorSplitUVRow_RELAXEDSIMD;
}
}
#endif
#if defined(HAS_MIRRORSPLITUVROW_HVX)
if (TestCpuFlag(kCpuHasHVX)) {
MirrorSplitUVRow = MirrorSplitUVRow_HVX;

View File

@ -11,7 +11,7 @@
#include "libyuv/rotate_row.h"
#include "libyuv/row.h"
#if !defined(LIBYUV_DISABLE_WASM) && defined(__wasm_simd128__)
#if !defined(LIBYUV_DISABLE_WASMSIMD) && defined(__wasm_simd128__)
#include <wasm_simd128.h>
#ifdef __cplusplus

View File

@ -68,6 +68,9 @@ ANY41(MergeARGBRow_Any_LSX, MergeARGBRow_LSX, 0, 0, 4, 15)
#ifdef HAS_MERGEARGBROW_LASX
ANY41(MergeARGBRow_Any_LASX, MergeARGBRow_LASX, 0, 0, 4, 15)
#endif
#ifdef HAS_MERGEARGBROW_WASMSIMD
ANY41(MergeARGBRow_Any_WASMSIMD, MergeARGBRow_WASMSIMD, 0, 0, 4, 15)
#endif
// Note that odd width replication includes 444 due to implementation
// on arm that subsamples 444 to 422 internally.
@ -126,6 +129,12 @@ ANY41C(I422AlphaToARGBRow_Any_LSX, I422AlphaToARGBRow_LSX, 1, 0, 4, 7)
#ifdef HAS_I422ALPHATOARGBROW_LASX
ANY41C(I422AlphaToARGBRow_Any_LASX, I422AlphaToARGBRow_LASX, 1, 0, 4, 15)
#endif
#ifdef HAS_I444ALPHATOARGBROW_WASMSIMD
ANY41C(I444AlphaToARGBRow_Any_WASMSIMD, I444AlphaToARGBRow_WASMSIMD, 0, 0, 4, 7)
#endif
#ifdef HAS_I422ALPHATOARGBROW_WASMSIMD
ANY41C(I422AlphaToARGBRow_Any_WASMSIMD, I422AlphaToARGBRow_WASMSIMD, 1, 0, 4, 7)
#endif
#undef ANY41C
// Any 4 planes to 1 plane of 8 bit with yuvconstants
@ -220,6 +229,27 @@ ANY41CT(I410AlphaToARGBRow_Any_AVX2,
15)
#endif
#ifdef HAS_I210ALPHATOARGBROW_WASMSIMD
ANY41CT(I210AlphaToARGBRow_Any_WASMSIMD,
I210AlphaToARGBRow_WASMSIMD,
1,
0,
uint16_t,
2,
4,
7)
#endif
#ifdef HAS_I410ALPHATOARGBROW_WASMSIMD
ANY41CT(I410AlphaToARGBRow_Any_WASMSIMD,
I410AlphaToARGBRow_WASMSIMD,
0,
0,
uint16_t,
2,
4,
7)
#endif
#undef ANY41CT
// Any 4 planes to 1 plane with parameter
@ -367,6 +397,21 @@ ANY31(BlendPlaneRow_Any_LASX, BlendPlaneRow_LASX, 0, 0, 1, 31)
#ifdef HAS_BLENDPLANEROW_WASMSIMD
ANY31(BlendPlaneRow_Any_WASMSIMD, BlendPlaneRow_WASMSIMD, 0, 0, 1, 15)
#endif
#ifdef HAS_MERGERGBROW_WASMSIMD
ANY31(MergeRGBRow_Any_WASMSIMD, MergeRGBRow_WASMSIMD, 0, 0, 3, 15)
#endif
#ifdef HAS_MERGERGBROW_RELAXEDSIMD
ANY31(MergeRGBRow_Any_RELAXEDSIMD, MergeRGBRow_RELAXEDSIMD, 0, 0, 3, 15)
#endif
#ifdef HAS_MERGEXRGBROW_WASMSIMD
ANY31(MergeXRGBRow_Any_WASMSIMD, MergeXRGBRow_WASMSIMD, 0, 0, 4, 15)
#endif
#ifdef HAS_I422TOYUY2ROW_WASMSIMD
ANY31(I422ToYUY2Row_Any_WASMSIMD, I422ToYUY2Row_WASMSIMD, 1, 1, 4, 15)
#endif
#ifdef HAS_I422TOUYVYROW_WASMSIMD
ANY31(I422ToUYVYRow_Any_WASMSIMD, I422ToUYVYRow_WASMSIMD, 1, 1, 4, 15)
#endif
#undef ANY31
// Note that odd width replication includes 444 due to implementation
@ -509,6 +554,21 @@ ANY31C(I422ToARGB1555Row_Any_WASMSIMD, I422ToARGB1555Row_WASMSIMD, 1, 0, 2, 7)
#ifdef HAS_I422TOARGB4444ROW_WASMSIMD
ANY31C(I422ToARGB4444Row_Any_WASMSIMD, I422ToARGB4444Row_WASMSIMD, 1, 0, 2, 7)
#endif
#ifdef HAS_I422TORGBAROW_WASMSIMD
ANY31C(I422ToRGBARow_Any_WASMSIMD, I422ToRGBARow_WASMSIMD, 1, 0, 4, 7)
#endif
#ifdef HAS_I444TOARGBROW_WASMSIMD
ANY31C(I444ToARGBRow_Any_WASMSIMD, I444ToARGBRow_WASMSIMD, 0, 0, 4, 7)
#endif
#ifdef HAS_I444TORGB24ROW_WASMSIMD
ANY31C(I444ToRGB24Row_Any_WASMSIMD, I444ToRGB24Row_WASMSIMD, 0, 0, 3, 15)
#endif
#ifdef HAS_I444TORGB24ROW_RELAXEDSIMD
ANY31C(I444ToRGB24Row_Any_RELAXEDSIMD, I444ToRGB24Row_RELAXEDSIMD, 0, 0, 3, 15)
#endif
#ifdef HAS_I422TORGB24ROW_RELAXEDSIMD
ANY31C(I422ToRGB24Row_Any_RELAXEDSIMD, I422ToRGB24Row_RELAXEDSIMD, 1, 0, 3, 15)
#endif
#undef ANY31C
// Any 3 planes of 16 bit to 1 with yuvconstants
@ -592,6 +652,46 @@ ANY31CT(I212ToARGBRow_Any_NEON, I212ToARGBRow_NEON, 1, 0, uint16_t, 2, 4, 7)
#ifdef HAS_I212TOAR30ROW_NEON
ANY31CT(I212ToAR30Row_Any_NEON, I212ToAR30Row_NEON, 1, 0, uint16_t, 2, 4, 7)
#endif
#ifdef HAS_I210TOARGBROW_WASMSIMD
ANY31CT(I210ToARGBRow_Any_WASMSIMD,
I210ToARGBRow_WASMSIMD,
1,
0,
uint16_t,
2,
4,
7)
#endif
#ifdef HAS_I410TOARGBROW_WASMSIMD
ANY31CT(I410ToARGBRow_Any_WASMSIMD,
I410ToARGBRow_WASMSIMD,
0,
0,
uint16_t,
2,
4,
7)
#endif
#ifdef HAS_I210TOAR30ROW_WASMSIMD
ANY31CT(I210ToAR30Row_Any_WASMSIMD,
I210ToAR30Row_WASMSIMD,
1,
0,
uint16_t,
2,
4,
7)
#endif
#ifdef HAS_I410TOAR30ROW_WASMSIMD
ANY31CT(I410ToAR30Row_Any_WASMSIMD,
I410ToAR30Row_WASMSIMD,
0,
0,
uint16_t,
2,
4,
7)
#endif
#undef ANY31CT
// Any 3 planes to 1 plane with parameter
@ -823,6 +923,33 @@ ANY21(SobelXYRow_Any_LASX, SobelXYRow_LASX, 0, 1, 1, 4, 15)
#ifdef HAS_MERGEUVROW_WASMSIMD
ANY21(MergeUVRow_Any_WASMSIMD, MergeUVRow_WASMSIMD, 0, 1, 1, 2, 15)
#endif
#ifdef HAS_ARGBBLENDROW_WASMSIMD
ANY21(ARGBBlendRow_Any_WASMSIMD, ARGBBlendRow_WASMSIMD, 0, 4, 4, 4, 3)
#endif
#ifdef HAS_ARGBBLENDROW_RELAXEDSIMD
ANY21(ARGBBlendRow_Any_RELAXEDSIMD, ARGBBlendRow_RELAXEDSIMD, 0, 4, 4, 4, 3)
#endif
#ifdef HAS_ARGBMULTIPLYROW_WASMSIMD
ANY21(ARGBMultiplyRow_Any_WASMSIMD, ARGBMultiplyRow_WASMSIMD, 0, 4, 4, 4, 3)
#endif
#ifdef HAS_ARGBADDROW_WASMSIMD
ANY21(ARGBAddRow_Any_WASMSIMD, ARGBAddRow_WASMSIMD, 0, 4, 4, 4, 3)
#endif
#ifdef HAS_ARGBSUBTRACTROW_WASMSIMD
ANY21(ARGBSubtractRow_Any_WASMSIMD, ARGBSubtractRow_WASMSIMD, 0, 4, 4, 4, 3)
#endif
#ifdef HAS_SOBELROW_WASMSIMD
ANY21(SobelRow_Any_WASMSIMD, SobelRow_WASMSIMD, 0, 1, 1, 4, 15)
#endif
#ifdef HAS_SOBELROW_RELAXEDSIMD
ANY21(SobelRow_Any_RELAXEDSIMD, SobelRow_RELAXEDSIMD, 0, 1, 1, 4, 15)
#endif
#ifdef HAS_SOBELTOPLANEROW_WASMSIMD
ANY21(SobelToPlaneRow_Any_WASMSIMD, SobelToPlaneRow_WASMSIMD, 0, 1, 1, 1, 15)
#endif
#ifdef HAS_SOBELXYROW_WASMSIMD
ANY21(SobelXYRow_Any_WASMSIMD, SobelXYRow_WASMSIMD, 0, 1, 1, 4, 15)
#endif
#undef ANY21
// Any 2 planes to 1 with stride
@ -863,6 +990,9 @@ ANY21S(YUY2ToNVUVRow_Any_LSX, YUY2ToNVUVRow_LSX, 4, 2, 7)
#ifdef HAS_YUY2TONVUVROW_LASX
ANY21S(YUY2ToNVUVRow_Any_LASX, YUY2ToNVUVRow_LASX, 4, 2, 15)
#endif
#ifdef HAS_YUY2TONVUVROW_WASMSIMD
ANY21S(YUY2ToNVUVRow_Any_WASMSIMD, YUY2ToNVUVRow_WASMSIMD, 4, 2, 7)
#endif
#undef ANY21S
// Any 2 planes to 1 half-size merged UV row with stride (2 rows of U and V).
@ -911,6 +1041,9 @@ ANY21HMS(HalfMergeUVRow_Any_LSX, HalfMergeUVRow_LSX, 15)
#ifdef HAS_HALFMERGEUVROW_LASX
ANY21HMS(HalfMergeUVRow_Any_LASX, HalfMergeUVRow_LASX, 31)
#endif
#ifdef HAS_HALFMERGEUVROW_WASMSIMD
ANY21HMS(HalfMergeUVRow_Any_WASMSIMD, HalfMergeUVRow_WASMSIMD, 15)
#endif
#undef ANY21HMS
// Any 2 planes to 1 with yuvconstants
@ -1012,6 +1145,30 @@ ANY21C(NV21ToARGBRow_Any_WASMSIMD, NV21ToARGBRow_WASMSIMD, 1, 1, 2, 4, 7)
#ifdef HAS_NV12TORGB565ROW_WASMSIMD
ANY21C(NV12ToRGB565Row_Any_WASMSIMD, NV12ToRGB565Row_WASMSIMD, 1, 1, 2, 2, 7)
#endif
#ifdef HAS_NV12TORGB24ROW_WASMSIMD
ANY21C(NV12ToRGB24Row_Any_WASMSIMD, NV12ToRGB24Row_WASMSIMD, 1, 1, 2, 3, 15)
#endif
#ifdef HAS_NV12TORGB24ROW_RELAXEDSIMD
ANY21C(NV12ToRGB24Row_Any_RELAXEDSIMD,
NV12ToRGB24Row_RELAXEDSIMD,
1,
1,
2,
3,
15)
#endif
#ifdef HAS_NV21TORGB24ROW_WASMSIMD
ANY21C(NV21ToRGB24Row_Any_WASMSIMD, NV21ToRGB24Row_WASMSIMD, 1, 1, 2, 3, 15)
#endif
#ifdef HAS_NV21TORGB24ROW_RELAXEDSIMD
ANY21C(NV21ToRGB24Row_Any_RELAXEDSIMD,
NV21ToRGB24Row_RELAXEDSIMD,
1,
1,
2,
3,
15)
#endif
#undef ANY21C
// Any 2 planes of 16 bit to 1 with yuvconstants
@ -1113,6 +1270,9 @@ ANY21PT(MergeUVRow_16_Any_LSX, MergeUVRow_16_LSX, uint16_t, 2, 7)
#ifdef HAS_MERGEUVROW_16_LASX
ANY21PT(MergeUVRow_16_Any_LASX, MergeUVRow_16_LASX, uint16_t, 2, 15)
#endif
#ifdef HAS_MERGEUVROW_16_WASMSIMD
ANY21PT(MergeUVRow_16_Any_WASMSIMD, MergeUVRow_16_WASMSIMD, uint16_t, 2, 7)
#endif
#undef ANY21CT
@ -1549,6 +1709,80 @@ ANY11(ARGBGrayRow_Any_LSX, ARGBGrayRow_LSX, 0, 4, 4, 7)
#ifdef HAS_ARGBGRAYROW_LASX
ANY11(ARGBGrayRow_Any_LASX, ARGBGrayRow_LASX, 0, 4, 4, 15)
#endif
#ifdef HAS_COPYROW_WASMSIMD
ANY11(CopyRow_Any_WASMSIMD, CopyRow_WASMSIMD, 0, 1, 1, 63)
#endif
#ifdef HAS_ARGBTORGB24ROW_WASMSIMD
ANY11(ARGBToRGB24Row_Any_WASMSIMD, ARGBToRGB24Row_WASMSIMD, 0, 4, 3, 15)
#endif
#ifdef HAS_ARGBTORGB24ROW_RELAXEDSIMD
ANY11(ARGBToRGB24Row_Any_RELAXEDSIMD, ARGBToRGB24Row_RELAXEDSIMD, 0, 4, 3, 15)
#endif
#ifdef HAS_ARGBTORAWROW_WASMSIMD
ANY11(ARGBToRAWRow_Any_WASMSIMD, ARGBToRAWRow_WASMSIMD, 0, 4, 3, 15)
#endif
#ifdef HAS_ARGBTORAWROW_RELAXEDSIMD
ANY11(ARGBToRAWRow_Any_RELAXEDSIMD, ARGBToRAWRow_RELAXEDSIMD, 0, 4, 3, 15)
#endif
#ifdef HAS_RAWTORGBAROW_WASMSIMD
ANY11(RAWToRGBARow_Any_WASMSIMD, RAWToRGBARow_WASMSIMD, 0, 3, 4, 15)
#endif
#ifdef HAS_RAWTORGBAROW_RELAXEDSIMD
ANY11(RAWToRGBARow_Any_RELAXEDSIMD, RAWToRGBARow_RELAXEDSIMD, 0, 3, 4, 15)
#endif
#ifdef HAS_RAWTOARGBROW_RELAXEDSIMD
ANY11(RAWToARGBRow_Any_RELAXEDSIMD, RAWToARGBRow_RELAXEDSIMD, 0, 3, 4, 15)
#endif
#ifdef HAS_RGB24TOARGBROW_RELAXEDSIMD
ANY11(RGB24ToARGBRow_Any_RELAXEDSIMD, RGB24ToARGBRow_RELAXEDSIMD, 0, 3, 4, 15)
#endif
#ifdef HAS_RAWTORGB24ROW_RELAXEDSIMD
ANY11(RAWToRGB24Row_Any_RELAXEDSIMD, RAWToRGB24Row_RELAXEDSIMD, 0, 3, 3, 15)
#endif
#ifdef HAS_J400TOARGBROW_RELAXEDSIMD
ANY11(J400ToARGBRow_Any_RELAXEDSIMD, J400ToARGBRow_RELAXEDSIMD, 0, 1, 4, 15)
#endif
#ifdef HAS_AR30TOARGBROW_WASMSIMD
ANY11(AR30ToARGBRow_Any_WASMSIMD, AR30ToARGBRow_WASMSIMD, 0, 4, 4, 3)
#endif
#ifdef HAS_AR30TOABGRROW_WASMSIMD
ANY11(AR30ToABGRRow_Any_WASMSIMD, AR30ToABGRRow_WASMSIMD, 0, 4, 4, 3)
#endif
#ifdef HAS_AR30TOAB30ROW_WASMSIMD
ANY11(AR30ToAB30Row_Any_WASMSIMD, AR30ToAB30Row_WASMSIMD, 0, 4, 4, 3)
#endif
#ifdef HAS_ARGBTOAR30ROW_WASMSIMD
ANY11(ARGBToAR30Row_Any_WASMSIMD, ARGBToAR30Row_WASMSIMD, 0, 4, 4, 3)
#endif
#ifdef HAS_ABGRTOAR30ROW_WASMSIMD
ANY11(ABGRToAR30Row_Any_WASMSIMD, ABGRToAR30Row_WASMSIMD, 0, 4, 4, 3)
#endif
#ifdef HAS_YUY2TOYROW_WASMSIMD
ANY11(YUY2ToYRow_Any_WASMSIMD, YUY2ToYRow_WASMSIMD, 1, 4, 1, 15)
#endif
#ifdef HAS_UYVYTOYROW_WASMSIMD
ANY11(UYVYToYRow_Any_WASMSIMD, UYVYToYRow_WASMSIMD, 1, 4, 1, 15)
#endif
#ifdef HAS_AYUVTOYROW_WASMSIMD
ANY11(AYUVToYRow_Any_WASMSIMD, AYUVToYRow_WASMSIMD, 0, 4, 1, 15)
#endif
#ifdef HAS_ARGBATTENUATEROW_WASMSIMD
ANY11(ARGBAttenuateRow_Any_WASMSIMD, ARGBAttenuateRow_WASMSIMD, 0, 4, 4, 3)
#endif
#ifdef HAS_ARGBATTENUATEROW_RELAXEDSIMD
ANY11(ARGBAttenuateRow_Any_RELAXEDSIMD,
ARGBAttenuateRow_RELAXEDSIMD,
0,
4,
4,
3)
#endif
#ifdef HAS_ARGBGRAYROW_WASMSIMD
ANY11(ARGBGrayRow_Any_WASMSIMD, ARGBGrayRow_WASMSIMD, 0, 4, 4, 3)
#endif
#ifdef HAS_ARGBGRAYROW_RELAXEDSIMD
ANY11(ARGBGrayRow_Any_RELAXEDSIMD, ARGBGrayRow_RELAXEDSIMD, 0, 4, 4, 3)
#endif
#undef ANY11
// Any 1 to 1 blended. Destination is read, modify, write.
@ -1611,6 +1845,17 @@ ANY11B(ARGBCopyYToAlphaRow_Any_WASMSIMD,
4,
15)
#endif
#ifdef HAS_ARGBCOPYYTOALPHAROW_RELAXEDSIMD
ANY11B(ARGBCopyYToAlphaRow_Any_RELAXEDSIMD,
ARGBCopyYToAlphaRow_RELAXEDSIMD,
0,
1,
4,
15)
#endif
#ifdef HAS_ARGBCOPYALPHAROW_WASMSIMD
ANY11B(ARGBCopyAlphaRow_Any_WASMSIMD, ARGBCopyAlphaRow_WASMSIMD, 0, 4, 4, 7)
#endif
#undef ANY11B
// Any 1 to 1 with parameter.
@ -1809,6 +2054,46 @@ ANY11P(ARGBColorMatrixRow_Any_LASX,
4,
7)
#endif
#ifdef HAS_I400TOARGBROW_WASMSIMD
ANY11P(I400ToARGBRow_Any_WASMSIMD,
I400ToARGBRow_WASMSIMD,
const struct YuvConstants*,
1,
4,
15)
#endif
#ifdef HAS_I400TOARGBROW_RELAXEDSIMD
ANY11P(I400ToARGBRow_Any_RELAXEDSIMD,
I400ToARGBRow_RELAXEDSIMD,
const struct YuvConstants*,
1,
4,
15)
#endif
#ifdef HAS_ARGBSHUFFLEROW_RELAXEDSIMD
ANY11P(ARGBShuffleRow_Any_RELAXEDSIMD,
ARGBShuffleRow_RELAXEDSIMD,
const uint8_t*,
4,
4,
3)
#endif
#ifdef HAS_ARGBPOLYNOMIALROW_WASMSIMD
ANY11P(ARGBPolynomialRow_Any_WASMSIMD,
ARGBPolynomialRow_WASMSIMD,
const float*,
4,
4,
3)
#endif
#ifdef HAS_ARGBCOLORMATRIXROW_WASMSIMD
ANY11P(ARGBColorMatrixRow_Any_WASMSIMD,
ARGBColorMatrixRow_WASMSIMD,
const int8_t*,
4,
4,
3)
#endif
#undef ANY11P
// Any 1 in-place.
@ -1839,6 +2124,12 @@ ANY1I(ARGBSepiaRow_Any_LSX, ARGBSepiaRow_LSX, 4, 7)
#ifdef HAS_ARGBSEPIAROW_LASX
ANY1I(ARGBSepiaRow_Any_LASX, ARGBSepiaRow_LASX, 4, 15)
#endif
#ifdef HAS_ARGBSEPIAROW_WASMSIMD
ANY1I(ARGBSepiaRow_Any_WASMSIMD, ARGBSepiaRow_WASMSIMD, 4, 3)
#endif
#ifdef HAS_ARGBSEPIAROW_RELAXEDSIMD
ANY1I(ARGBSepiaRow_Any_RELAXEDSIMD, ARGBSepiaRow_RELAXEDSIMD, 4, 3)
#endif
#undef ANY1I
// Any 1 in-place with 3 int parameters.
@ -1866,6 +2157,9 @@ ANY1I3(ARGBQuantizeRow_Any_LSX, ARGBQuantizeRow_LSX, 4, 3)
#ifdef HAS_ARGBQUANTIZEROW_LASX
ANY1I3(ARGBQuantizeRow_Any_LASX, ARGBQuantizeRow_LASX, 4, 7)
#endif
#ifdef HAS_ARGBQUANTIZEROW_WASMSIMD
ANY1I3(ARGBQuantizeRow_Any_WASMSIMD, ARGBQuantizeRow_WASMSIMD, 4, 3)
#endif
#undef ANY1I3
// Any 1 to 1 with trailing parameter.
@ -1895,6 +2189,9 @@ ANY11PT(ARGBShadeRow_Any_LSX, ARGBShadeRow_LSX, uint32_t, 4, 4, 3)
#ifdef HAS_ARGBSHADEROW_LASX
ANY11PT(ARGBShadeRow_Any_LASX, ARGBShadeRow_LASX, uint32_t, 4, 4, 7)
#endif
#ifdef HAS_ARGBSHADEROW_WASMSIMD
ANY11PT(ARGBShadeRow_Any_WASMSIMD, ARGBShadeRow_WASMSIMD, uint32_t, 4, 4, 3)
#endif
#undef ANY11PT
#ifdef HAS_ARGBLUMACOLORTABLEROW_NEON
@ -1918,6 +2215,27 @@ void ARGBLumaColorTableRow_Any_NEON(const uint8_t* src_argb,
memcpy(dst_argb + np * 4, vout, r * 4);
}
#endif
#ifdef HAS_ARGBLUMACOLORTABLEROW_WASMSIMD
void ARGBLumaColorTableRow_Any_WASMSIMD(const uint8_t* src_argb,
uint8_t* dst_argb,
int width,
const uint8_t* luma,
const uint32_t lumacoeff) {
SIMD_ALIGNED(uint8_t vin[4 * 4]);
SIMD_ALIGNED(uint8_t vout[4 * 4]);
MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */
MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */
int r = width & 3;
int n = width & ~3;
if (n > 0) {
ARGBLumaColorTableRow_WASMSIMD(src_argb, dst_argb, n, luma, lumacoeff);
}
ptrdiff_t np = n;
memcpy(vin, src_argb + np * 4, r * 4);
ARGBLumaColorTableRow_WASMSIMD(vin, vout, 4, luma, lumacoeff);
memcpy(dst_argb + np * 4, vout, r * 4);
}
#endif
// Any 1 to 1 with type
#define ANY11T(NAMEANY, ANY_SIMD, SBPP, BPP, STYPE, DTYPE, MASK) \
@ -2021,6 +2339,51 @@ ANY11T(CopyRow_16_Any_LSX, CopyRow_16_LSX, 2, 2, uint16_t, uint16_t, 15)
#ifdef HAS_COPYROW_16_LASX
ANY11T(CopyRow_16_Any_LASX, CopyRow_16_LASX, 2, 2, uint16_t, uint16_t, 31)
#endif
#ifdef HAS_ARGBTOAR64ROW_WASMSIMD
ANY11T(ARGBToAR64Row_Any_WASMSIMD,
ARGBToAR64Row_WASMSIMD,
4,
8,
uint8_t,
uint16_t,
7)
#endif
#ifdef HAS_ARGBTOAB64ROW_WASMSIMD
ANY11T(ARGBToAB64Row_Any_WASMSIMD,
ARGBToAB64Row_WASMSIMD,
4,
8,
uint8_t,
uint16_t,
7)
#endif
#ifdef HAS_AR64TOARGBROW_WASMSIMD
ANY11T(AR64ToARGBRow_Any_WASMSIMD,
AR64ToARGBRow_WASMSIMD,
8,
4,
uint16_t,
uint8_t,
7)
#endif
#ifdef HAS_AB64TOARGBROW_WASMSIMD
ANY11T(AB64ToARGBRow_Any_WASMSIMD,
AB64ToARGBRow_WASMSIMD,
8,
4,
uint16_t,
uint8_t,
7)
#endif
#ifdef HAS_COPYROW_16_WASMSIMD
ANY11T(CopyRow_16_Any_WASMSIMD,
CopyRow_16_WASMSIMD,
2,
2,
uint16_t,
uint16_t,
31)
#endif
#undef ANY11T
@ -2200,6 +2563,24 @@ ANY11C(MultiplyRow_16_Any_WASMSIMD,
uint16_t,
15)
#endif
#ifdef HAS_CONVERT16TO8ROW_WASMSIMD
ANY11C(Convert16To8Row_Any_WASMSIMD,
Convert16To8Row_WASMSIMD,
2,
1,
uint16_t,
uint8_t,
15)
#endif
#ifdef HAS_DIVIDEROW_16_WASMSIMD
ANY11C(DivideRow_16_Any_WASMSIMD,
DivideRow_16_WASMSIMD,
2,
2,
uint16_t,
uint16_t,
15)
#endif
#undef ANY11C
// Any 1 to 1 with parameter and shorts. BPP measures in shorts.
@ -2259,6 +2640,15 @@ ANY11SB(Convert8To8Row_Any_LASX,
uint8_t,
31)
#endif
#ifdef HAS_CONVERT8TO8ROW_WASMSIMD
ANY11SB(Convert8To8Row_Any_WASMSIMD,
Convert8To8Row_WASMSIMD,
1,
1,
uint8_t,
uint8_t,
15)
#endif
#undef ANY11B
// Any 1 to 1 with parameter and shorts to byte. BPP measures in shorts.
@ -2309,6 +2699,24 @@ ANY11P16(HalfFloatRow_Any_LSX, HalfFloatRow_LSX, uint16_t, uint16_t, 2, 2, 7)
#ifdef HAS_HALFFLOATROW_LASX
ANY11P16(HalfFloatRow_Any_LASX, HalfFloatRow_LASX, uint16_t, uint16_t, 2, 2, 15)
#endif
#ifdef HAS_HALFFLOATROW_WASMSIMD
ANY11P16(HalfFloatRow_Any_WASMSIMD,
HalfFloatRow_WASMSIMD,
uint16_t,
uint16_t,
2,
2,
15)
#endif
#ifdef HAS_BYTETOFLOATROW_WASMSIMD
ANY11P16(ByteToFloatRow_Any_WASMSIMD,
ByteToFloatRow_WASMSIMD,
uint8_t,
float,
1,
4,
15)
#endif
#undef ANY11P16
// Any 1 to 1 with yuvconstants
@ -2353,6 +2761,10 @@ ANY11C(UYVYToARGBRow_Any_LSX, UYVYToARGBRow_LSX, 1, 4, 4, 7)
ANY11C(YUY2ToARGBRow_Any_LASX, YUY2ToARGBRow_LASX, 1, 4, 4, 15)
ANY11C(UYVYToARGBRow_Any_LASX, UYVYToARGBRow_LASX, 1, 4, 4, 15)
#endif
#if defined(HAS_YUY2TOARGBROW_WASMSIMD)
ANY11C(YUY2ToARGBRow_Any_WASMSIMD, YUY2ToARGBRow_WASMSIMD, 1, 4, 4, 7)
ANY11C(UYVYToARGBRow_Any_WASMSIMD, UYVYToARGBRow_WASMSIMD, 1, 4, 4, 7)
#endif
#undef ANY11C
// Any 1 to 1 interpolate. Takes 2 rows of source via stride.
@ -2493,6 +2905,12 @@ ANY11H(HalfRow_16_Any_LSX, HalfRow_16_LSX, uint16_t, 7)
#ifdef HAS_HALFROW_16_LASX
ANY11H(HalfRow_16_Any_LASX, HalfRow_16_LASX, uint16_t, 15)
#endif
#ifdef HAS_HALFROW_WASMSIMD
ANY11H(HalfRow_Any_WASMSIMD, HalfRow_WASMSIMD, uint8_t, 15)
#endif
#ifdef HAS_HALFROW_16_WASMSIMD
ANY11H(HalfRow_16_Any_WASMSIMD, HalfRow_16_WASMSIMD, uint16_t, 7)
#endif
#undef ANY11H
@ -2535,6 +2953,13 @@ ANY11HS(HalfRow_16To8_Any_LSX, HalfRow_16To8_LSX, uint16_t, uint8_t, 15)
#ifdef HAS_HALFROW_16TO8_LASX
ANY11HS(HalfRow_16To8_Any_LASX, HalfRow_16To8_LASX, uint16_t, uint8_t, 31)
#endif
#ifdef HAS_HALFROW_16TO8_WASMSIMD
ANY11HS(HalfRow_16To8_Any_WASMSIMD,
HalfRow_16To8_WASMSIMD,
uint16_t,
uint8_t,
15)
#endif
#undef ANY11HS
@ -2602,6 +3027,13 @@ void HalfWidthRow_16To8_Odd_NEON(const uint16_t* src_uv,
dst_uv[0] = (uint8_t)((avg * (uint32_t)scale) >> 17);
}
#endif
#ifdef HAS_HALFWIDTHROW_16TO8_WASMSIMD
ANY11HWS(HalfWidthRow_16To8_Any_WASMSIMD,
HalfWidthRow_16To8_WASMSIMD,
uint16_t,
uint8_t,
7)
#endif
#undef ANY11HWS
@ -2697,6 +3129,15 @@ ANY11M(ARGBMirrorRow_Any_WASMSIMD, ARGBMirrorRow_WASMSIMD, 4, 3)
#ifdef HAS_RGB24MIRRORROW_WASMSIMD
ANY11M(RGB24MirrorRow_Any_WASMSIMD, RGB24MirrorRow_WASMSIMD, 3, 15)
#endif
#ifdef HAS_MIRRORROW_RELAXEDSIMD
ANY11M(MirrorRow_Any_RELAXEDSIMD, MirrorRow_RELAXEDSIMD, 1, 15)
#endif
#ifdef HAS_MIRRORUVROW_RELAXEDSIMD
ANY11M(MirrorUVRow_Any_RELAXEDSIMD, MirrorUVRow_RELAXEDSIMD, 2, 7)
#endif
#ifdef HAS_RGB24MIRRORROW_RELAXEDSIMD
ANY11M(RGB24MirrorRow_Any_RELAXEDSIMD, RGB24MirrorRow_RELAXEDSIMD, 3, 15)
#endif
#undef ANY11M
// Any 1 to 1 mirror with type.
@ -2764,6 +3205,9 @@ ANY12MR(MirrorSplitUVRow_Any_LASX, MirrorSplitUVRow_LASX, 31)
#ifdef HAS_MIRRORSPLITUVROW_WASMSIMD
ANY12MR(MirrorSplitUVRow_Any_WASMSIMD, MirrorSplitUVRow_WASMSIMD, 15)
#endif
#ifdef HAS_MIRRORSPLITUVROW_RELAXEDSIMD
ANY12MR(MirrorSplitUVRow_Any_RELAXEDSIMD, MirrorSplitUVRow_RELAXEDSIMD, 15)
#endif
#undef ANY12MR
// Any 1 plane. (memset)
@ -2794,6 +3238,9 @@ ANY1(SetRow_Any_LSX, SetRow_LSX, uint8_t, 1, 15)
#ifdef HAS_SETROW_LASX
ANY1(SetRow_Any_LASX, SetRow_LASX, uint8_t, 1, 31)
#endif
#ifdef HAS_SETROW_WASMSIMD
ANY1(SetRow_Any_WASMSIMD, SetRow_WASMSIMD, uint8_t, 1, 15)
#endif
#ifdef HAS_ARGBSETROW_AVX2
ANY1(ARGBSetRow_Any_AVX2, ARGBSetRow_AVX2, uint32_t, 4, 7)
#endif
@ -2806,6 +3253,9 @@ ANY1(ARGBSetRow_Any_LSX, ARGBSetRow_LSX, uint32_t, 4, 3)
#ifdef HAS_ARGBSETROW_LASX
ANY1(ARGBSetRow_Any_LASX, ARGBSetRow_LASX, uint32_t, 4, 7)
#endif
#ifdef HAS_ARGBSETROW_WASMSIMD
ANY1(ARGBSetRow_Any_WASMSIMD, ARGBSetRow_WASMSIMD, uint32_t, 4, 3)
#endif
#undef ANY1
// Any 1 to 2. Outputs UV planes.
@ -2869,6 +3319,15 @@ ANY12(UYVYToUV422Row_Any_LSX, UYVYToUV422Row_LSX, 1, 4, 1, 15)
ANY12(YUY2ToUV422Row_Any_LASX, YUY2ToUV422Row_LASX, 1, 4, 1, 31)
ANY12(UYVYToUV422Row_Any_LASX, UYVYToUV422Row_LASX, 1, 4, 1, 31)
#endif
#ifdef HAS_SPLITUVROW_WASMSIMD
ANY12(SplitUVRow_Any_WASMSIMD, SplitUVRow_WASMSIMD, 0, 2, 0, 15)
#endif
#ifdef HAS_YUY2TOUV422ROW_WASMSIMD
ANY12(YUY2ToUV422Row_Any_WASMSIMD, YUY2ToUV422Row_WASMSIMD, 1, 4, 1, 15)
#endif
#ifdef HAS_UYVYTOUV422ROW_WASMSIMD
ANY12(UYVYToUV422Row_Any_WASMSIMD, UYVYToUV422Row_WASMSIMD, 1, 4, 1, 15)
#endif
#undef ANY12
// Any 2 16 bit planes with parameter to 1
@ -2907,6 +3366,9 @@ ANY12PT(SplitUVRow_16_Any_LSX, SplitUVRow_16_LSX, uint16_t, 2, 7)
#ifdef HAS_SPLITUVROW_16_LASX
ANY12PT(SplitUVRow_16_Any_LASX, SplitUVRow_16_LASX, uint16_t, 2, 15)
#endif
#ifdef HAS_SPLITUVROW_16_WASMSIMD
ANY12PT(SplitUVRow_16_Any_WASMSIMD, SplitUVRow_16_WASMSIMD, uint16_t, 2, 7)
#endif
#undef ANY21CT
@ -2961,6 +3423,15 @@ ANY13(SplitXRGBRow_Any_LSX, SplitXRGBRow_LSX, 4, 15)
#ifdef HAS_SPLITXRGBROW_LASX
ANY13(SplitXRGBRow_Any_LASX, SplitXRGBRow_LASX, 4, 15)
#endif
#ifdef HAS_SPLITRGBROW_WASMSIMD
ANY13(SplitRGBRow_Any_WASMSIMD, SplitRGBRow_WASMSIMD, 3, 15)
#endif
#ifdef HAS_SPLITRGBROW_RELAXEDSIMD
ANY13(SplitRGBRow_Any_RELAXEDSIMD, SplitRGBRow_RELAXEDSIMD, 3, 15)
#endif
#ifdef HAS_SPLITXRGBROW_WASMSIMD
ANY13(SplitXRGBRow_Any_WASMSIMD, SplitXRGBRow_WASMSIMD, 4, 15)
#endif
// Any 1 to 4. Outputs ARGB planes.
#define ANY14(NAMEANY, ANY_SIMD, BPP, MASK) \
@ -3004,6 +3475,9 @@ ANY14(SplitARGBRow_Any_LSX, SplitARGBRow_LSX, 4, 15)
#ifdef HAS_SPLITARGBROW_LASX
ANY14(SplitARGBRow_Any_LASX, SplitARGBRow_LASX, 4, 15)
#endif
#ifdef HAS_SPLITARGBROW_WASMSIMD
ANY14(SplitARGBRow_Any_WASMSIMD, SplitARGBRow_WASMSIMD, 4, 15)
#endif
// Any 1 to 2 with source stride (2 rows of source). Outputs UV planes.
// 128 byte row allows for 32 avx ARGB pixels.
@ -3179,6 +3653,32 @@ ANY12M(ARGBToUV444MatrixRow_Any_WASMSIMD, ARGBToUV444MatrixRow_WASMSIMD, 4, 15)
#ifdef HAS_RGBTOUV444MATRIXROW_WASMSIMD
ANY12M(RGBToUV444MatrixRow_Any_WASMSIMD, RGBToUV444MatrixRow_WASMSIMD, 3, 15)
#endif
#ifdef HAS_ARGBTOUVMATRIXROW_RELAXEDSIMD
ANY12MS(ARGBToUVMatrixRow_Any_RELAXEDSIMD,
ARGBToUVMatrixRow_RELAXEDSIMD,
0,
4,
15)
#endif
#ifdef HAS_RGBTOUVMATRIXROW_RELAXEDSIMD
ANY12MS(RGBToUVMatrixRow_Any_RELAXEDSIMD,
RGBToUVMatrixRow_RELAXEDSIMD,
0,
3,
15)
#endif
#ifdef HAS_ARGBTOUV444MATRIXROW_RELAXEDSIMD
ANY12M(ARGBToUV444MatrixRow_Any_RELAXEDSIMD,
ARGBToUV444MatrixRow_RELAXEDSIMD,
4,
15)
#endif
#ifdef HAS_RGBTOUV444MATRIXROW_RELAXEDSIMD
ANY12M(RGBToUV444MatrixRow_Any_RELAXEDSIMD,
RGBToUV444MatrixRow_RELAXEDSIMD,
3,
15)
#endif
#define ANY11MC(NAMEANY, ANY_SIMD, BPP, MASK) \
void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, int width, \
@ -3261,6 +3761,9 @@ ANY11MC(ARGB1555ToYMatrixRow_Any_WASMSIMD, ARGB1555ToYMatrixRow_WASMSIMD, 2, 15)
#ifdef HAS_ARGB4444TOYMATRIXROW_WASMSIMD
ANY11MC(ARGB4444ToYMatrixRow_Any_WASMSIMD, ARGB4444ToYMatrixRow_WASMSIMD, 2, 15)
#endif
#ifdef HAS_RGBTOYMATRIXROW_RELAXEDSIMD
ANY11MC(RGBToYMatrixRow_Any_RELAXEDSIMD, RGBToYMatrixRow_RELAXEDSIMD, 3, 15)
#endif
#undef ANY11MC
#ifdef HAS_YUY2TOUVROW_AVX2
@ -3340,6 +3843,12 @@ ANY12S(UYVYToUVRow_Any_LSX, UYVYToUVRow_LSX, 1, 4, 15)
#ifdef HAS_UYVYTOUVROW_LASX
ANY12S(UYVYToUVRow_Any_LASX, UYVYToUVRow_LASX, 1, 4, 31)
#endif
#ifdef HAS_YUY2TOUVROW_WASMSIMD
ANY12S(YUY2ToUVRow_Any_WASMSIMD, YUY2ToUVRow_WASMSIMD, 1, 4, 15)
#endif
#ifdef HAS_UYVYTOUVROW_WASMSIMD
ANY12S(UYVYToUVRow_Any_WASMSIMD, UYVYToUVRow_WASMSIMD, 1, 4, 15)
#endif
#undef ANY12S
// Any 1 to 1 with source stride (2 rows of source). Outputs UV plane.
@ -3396,6 +3905,18 @@ ANY11S(AYUVToVURow_Any_LSX, AYUVToVURow_LSX, 0, 4, 15)
#ifdef HAS_AYUVTOVUROW_LASX
ANY11S(AYUVToVURow_Any_LASX, AYUVToVURow_LASX, 0, 4, 15)
#endif
#ifdef HAS_AYUVTOUVROW_WASMSIMD
ANY11S(AYUVToUVRow_Any_WASMSIMD, AYUVToUVRow_WASMSIMD, 0, 4, 15)
#endif
#ifdef HAS_AYUVTOUVROW_RELAXEDSIMD
ANY11S(AYUVToUVRow_Any_RELAXEDSIMD, AYUVToUVRow_RELAXEDSIMD, 0, 4, 15)
#endif
#ifdef HAS_AYUVTOVUROW_WASMSIMD
ANY11S(AYUVToVURow_Any_WASMSIMD, AYUVToVURow_WASMSIMD, 0, 4, 15)
#endif
#ifdef HAS_AYUVTOVUROW_RELAXEDSIMD
ANY11S(AYUVToVURow_Any_RELAXEDSIMD, AYUVToVURow_RELAXEDSIMD, 0, 4, 15)
#endif
#undef ANY11S
#define ANYDETILE(NAMEANY, ANY_SIMD, T, BPP, MASK) \
@ -3441,6 +3962,12 @@ ANYDETILE(DetileRow_16_Any_LSX, DetileRow_16_LSX, uint16_t, 2, 15)
#ifdef HAS_DETILEROW_16_LASX
ANYDETILE(DetileRow_16_Any_LASX, DetileRow_16_LASX, uint16_t, 2, 15)
#endif
#ifdef HAS_DETILEROW_WASMSIMD
ANYDETILE(DetileRow_Any_WASMSIMD, DetileRow_WASMSIMD, uint8_t, 1, 15)
#endif
#ifdef HAS_DETILEROW_16_WASMSIMD
ANYDETILE(DetileRow_16_Any_WASMSIMD, DetileRow_16_WASMSIMD, uint16_t, 2, 15)
#endif
// DetileSplitUVRow width is in bytes
#define ANYDETILESPLITUV(NAMEANY, ANY_SIMD, MASK) \
@ -3471,6 +3998,9 @@ ANYDETILESPLITUV(DetileSplitUVRow_Any_NEON, DetileSplitUVRow_NEON, 15)
#ifdef HAS_DETILESPLITUVROW_AVX2
ANYDETILESPLITUV(DetileSplitUVRow_Any_AVX2, DetileSplitUVRow_AVX2, 15)
#endif
#ifdef HAS_DETILESPLITUVROW_WASMSIMD
ANYDETILESPLITUV(DetileSplitUVRow_Any_WASMSIMD, DetileSplitUVRow_WASMSIMD, 15)
#endif
#define ANYDETILEMERGE(NAMEANY, ANY_SIMD, MASK) \
void NAMEANY(const uint8_t* src_y, ptrdiff_t src_y_tile_stride, \
@ -3508,6 +4038,10 @@ ANYDETILEMERGE(DetileToYUY2_Any_NEON, DetileToYUY2_NEON, 15)
ANYDETILEMERGE(DetileToYUY2_Any_AVX2, DetileToYUY2_AVX2, 31)
#endif
#ifdef HAS_DETILETOYUY2_WASMSIMD
ANYDETILEMERGE(DetileToYUY2_Any_WASMSIMD, DetileToYUY2_WASMSIMD, 15)
#endif
#undef ANYDETILEMERGE
#undef MSAN_MEMSET

File diff suppressed because it is too large Load Diff

View File

@ -546,6 +546,27 @@ static void ScalePlaneDown34(int src_width,
}
}
#endif
#if defined(HAS_SCALEROWDOWN34_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
if (dst_width % 24 == 0) {
if (!filtering) {
ScaleRowDown34_0 = ScaleRowDown34_RELAXEDSIMD;
ScaleRowDown34_1 = ScaleRowDown34_RELAXEDSIMD;
} else {
ScaleRowDown34_0 = ScaleRowDown34_0_Box_RELAXEDSIMD;
ScaleRowDown34_1 = ScaleRowDown34_1_Box_RELAXEDSIMD;
}
} else {
if (!filtering) {
ScaleRowDown34_0 = ScaleRowDown34_Any_RELAXEDSIMD;
ScaleRowDown34_1 = ScaleRowDown34_Any_RELAXEDSIMD;
} else {
ScaleRowDown34_0 = ScaleRowDown34_0_Box_Any_RELAXEDSIMD;
ScaleRowDown34_1 = ScaleRowDown34_1_Box_Any_RELAXEDSIMD;
}
}
}
#endif
for (y = 0; y < dst_height - 2; y += 3) {
ScaleRowDown34_0(src_ptr, filter_stride, dst_ptr, dst_width);
@ -771,6 +792,26 @@ static void ScalePlaneDown38(int src_width,
}
}
#endif
#if defined(HAS_SCALEROWDOWN38_RELAXEDSIMD)
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
if (!filtering) {
ScaleRowDown38_3 = ScaleRowDown38_Any_RELAXEDSIMD;
ScaleRowDown38_2 = ScaleRowDown38_Any_RELAXEDSIMD;
} else {
ScaleRowDown38_3 = ScaleRowDown38_3_Box_Any_RELAXEDSIMD;
ScaleRowDown38_2 = ScaleRowDown38_2_Box_Any_RELAXEDSIMD;
}
if (dst_width % 12 == 0) {
if (!filtering) {
ScaleRowDown38_3 = ScaleRowDown38_RELAXEDSIMD;
ScaleRowDown38_2 = ScaleRowDown38_RELAXEDSIMD;
} else {
ScaleRowDown38_3 = ScaleRowDown38_3_Box_RELAXEDSIMD;
ScaleRowDown38_2 = ScaleRowDown38_2_Box_RELAXEDSIMD;
}
}
}
#endif
for (y = 0; y < dst_height - 2; y += 3) {
ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width);
@ -1675,6 +1716,16 @@ static void ScalePlaneUp2_Linear(int src_width,
ScaleRowUp = ScaleRowUp2_Linear_RVV;
}
#endif
#ifdef HAS_SCALEROWUP2_LINEAR_WASMSIMD
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ScaleRowUp = ScaleRowUp2_Linear_Any_WASMSIMD;
}
#endif
#ifdef HAS_SCALEROWUP2_LINEAR_RELAXEDSIMD
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ScaleRowUp = ScaleRowUp2_Linear_Any_RELAXEDSIMD;
}
#endif
if (dst_height == 1) {
ScaleRowUp(src_ptr + ((src_height - 1) / 2) * src_stride, dst_ptr,
@ -1741,6 +1792,16 @@ static void ScalePlaneUp2_Bilinear(int src_width,
Scale2RowUp = ScaleRowUp2_Bilinear_RVV;
}
#endif
#ifdef HAS_SCALEROWUP2_BILINEAR_WASMSIMD
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Scale2RowUp = ScaleRowUp2_Bilinear_Any_WASMSIMD;
}
#endif
#ifdef HAS_SCALEROWUP2_BILINEAR_RELAXEDSIMD
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
Scale2RowUp = ScaleRowUp2_Bilinear_Any_RELAXEDSIMD;
}
#endif
Scale2RowUp(src_ptr, 0, dst_ptr, 0, dst_width);
dst_ptr += dst_stride;

View File

@ -588,6 +588,26 @@ SDANY(ScaleRowDown34_1_Box_Any_WASMSIMD,
1,
23)
#endif
#ifdef HAS_SCALEROWDOWN34_RELAXEDSIMD
SDANY(ScaleRowDown34_Any_RELAXEDSIMD,
ScaleRowDown34_RELAXEDSIMD,
ScaleRowDown34_C,
4 / 3,
1,
23)
SDANY(ScaleRowDown34_0_Box_Any_RELAXEDSIMD,
ScaleRowDown34_0_Box_RELAXEDSIMD,
ScaleRowDown34_0_Box_C,
4 / 3,
1,
23)
SDANY(ScaleRowDown34_1_Box_Any_RELAXEDSIMD,
ScaleRowDown34_1_Box_RELAXEDSIMD,
ScaleRowDown34_1_Box_C,
4 / 3,
1,
23)
#endif
#ifdef HAS_SCALEROWDOWN38_WASMSIMD
SDANY(ScaleRowDown38_Any_WASMSIMD,
ScaleRowDown38_WASMSIMD,
@ -608,6 +628,50 @@ SDANY(ScaleRowDown38_2_Box_Any_WASMSIMD,
1,
11)
#endif
#ifdef HAS_SCALEROWDOWN38_RELAXEDSIMD
SDANY(ScaleRowDown38_Any_RELAXEDSIMD,
ScaleRowDown38_RELAXEDSIMD,
ScaleRowDown38_C,
8 / 3,
1,
11)
SDANY(ScaleRowDown38_3_Box_Any_RELAXEDSIMD,
ScaleRowDown38_3_Box_RELAXEDSIMD,
ScaleRowDown38_3_Box_C,
8 / 3,
1,
11)
SDANY(ScaleRowDown38_2_Box_Any_RELAXEDSIMD,
ScaleRowDown38_2_Box_RELAXEDSIMD,
ScaleRowDown38_2_Box_C,
8 / 3,
1,
11)
#endif
#ifdef HAS_SCALEUVROWDOWN2_WASMSIMD
SDANY(ScaleUVRowDown2_Any_WASMSIMD,
ScaleUVRowDown2_WASMSIMD,
ScaleUVRowDown2_C,
2,
2,
7)
#endif
#ifdef HAS_SCALEUVROWDOWN2LINEAR_WASMSIMD
SDANY(ScaleUVRowDown2Linear_Any_WASMSIMD,
ScaleUVRowDown2Linear_WASMSIMD,
ScaleUVRowDown2Linear_C,
2,
2,
7)
#endif
#ifdef HAS_SCALEUVROWDOWN2BOX_WASMSIMD
SDANY(ScaleUVRowDown2Box_Any_WASMSIMD,
ScaleUVRowDown2Box_WASMSIMD,
ScaleUVRowDown2Box_C,
2,
2,
7)
#endif
#ifdef HAS_SCALEARGBROWDOWN2_WASMSIMD
SDANY(ScaleARGBRowDown2_Any_WASMSIMD,
ScaleARGBRowDown2_WASMSIMD,
@ -708,6 +772,13 @@ SDAANY(ScaleUVRowDownEven_Any_NEON,
2,
3)
#endif
#ifdef HAS_SCALEUVROWDOWNEVEN_WASMSIMD
SDAANY(ScaleUVRowDownEven_Any_WASMSIMD,
ScaleUVRowDownEven_WASMSIMD,
ScaleUVRowDownEven_C,
2,
3)
#endif
#ifdef HAS_SCALEARGBROWDOWNEVEN_WASMSIMD
SDAANY(ScaleARGBRowDownEven_Any_WASMSIMD,
ScaleARGBRowDownEven_WASMSIMD,
@ -997,6 +1068,22 @@ SUH2LANY(ScaleRowUp2_Linear_16_Any_NEON,
uint16_t)
#endif
#ifdef HAS_SCALEROWUP2_LINEAR_WASMSIMD
SUH2LANY(ScaleRowUp2_Linear_Any_WASMSIMD,
ScaleRowUp2_Linear_WASMSIMD,
ScaleRowUp2_Linear_C,
15,
uint8_t)
#endif
#ifdef HAS_SCALEROWUP2_LINEAR_RELAXEDSIMD
SUH2LANY(ScaleRowUp2_Linear_Any_RELAXEDSIMD,
ScaleRowUp2_Linear_RELAXEDSIMD,
ScaleRowUp2_Linear_C,
15,
uint8_t)
#endif
#undef SUH2LANY
// Scale up 2 times using bilinear filter.
@ -1117,6 +1204,22 @@ SU2BLANY(ScaleRowUp2_Bilinear_16_Any_NEON,
uint16_t)
#endif
#ifdef HAS_SCALEROWUP2_BILINEAR_WASMSIMD
SU2BLANY(ScaleRowUp2_Bilinear_Any_WASMSIMD,
ScaleRowUp2_Bilinear_WASMSIMD,
ScaleRowUp2_Bilinear_C,
15,
uint8_t)
#endif
#ifdef HAS_SCALEROWUP2_BILINEAR_RELAXEDSIMD
SU2BLANY(ScaleRowUp2_Bilinear_Any_RELAXEDSIMD,
ScaleRowUp2_Bilinear_RELAXEDSIMD,
ScaleRowUp2_Bilinear_C,
15,
uint8_t)
#endif
#undef SU2BLANY
// Scale bi-planar plane up horizontally 2 times using linear filter.
@ -1198,6 +1301,22 @@ SBUH2LANY(ScaleUVRowUp2_Linear_16_Any_NEON,
uint16_t)
#endif
#ifdef HAS_SCALEUVROWUP2_LINEAR_WASMSIMD
SBUH2LANY(ScaleUVRowUp2_Linear_Any_WASMSIMD,
ScaleUVRowUp2_Linear_WASMSIMD,
ScaleUVRowUp2_Linear_C,
7,
uint8_t)
#endif
#ifdef HAS_SCALEUVROWUP2_LINEAR_RELAXEDSIMD
SBUH2LANY(ScaleUVRowUp2_Linear_Any_RELAXEDSIMD,
ScaleUVRowUp2_Linear_RELAXEDSIMD,
ScaleUVRowUp2_Linear_C,
7,
uint8_t)
#endif
#undef SBUH2LANY
// Scale bi-planar plane up 2 times using bilinear filter.
@ -1297,6 +1416,22 @@ SBU2BLANY(ScaleUVRowUp2_Bilinear_16_Any_NEON,
uint16_t)
#endif
#ifdef HAS_SCALEUVROWUP2_BILINEAR_WASMSIMD
SBU2BLANY(ScaleUVRowUp2_Bilinear_Any_WASMSIMD,
ScaleUVRowUp2_Bilinear_WASMSIMD,
ScaleUVRowUp2_Bilinear_C,
7,
uint8_t)
#endif
#ifdef HAS_SCALEUVROWUP2_BILINEAR_RELAXEDSIMD
SBU2BLANY(ScaleUVRowUp2_Bilinear_Any_RELAXEDSIMD,
ScaleUVRowUp2_Bilinear_RELAXEDSIMD,
ScaleUVRowUp2_Bilinear_C,
7,
uint8_t)
#endif
#undef SBU2BLANY
// Scale UV columns by 3 box filter.

View File

@ -147,6 +147,22 @@ static void ScaleUVDown2(int src_width,
: ScaleUVRowDown2Box_HVX);
}
#endif
#if defined(HAS_SCALEUVROWDOWN2_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ScaleUVRowDown2 =
filtering == kFilterNone
? ScaleUVRowDown2_Any_WASMSIMD
: (filtering == kFilterLinear ? ScaleUVRowDown2Linear_Any_WASMSIMD
: ScaleUVRowDown2Box_Any_WASMSIMD);
if (IS_ALIGNED(dst_width, 8)) {
ScaleUVRowDown2 =
filtering == kFilterNone
? ScaleUVRowDown2_WASMSIMD
: (filtering == kFilterLinear ? ScaleUVRowDown2Linear_WASMSIMD
: ScaleUVRowDown2Box_WASMSIMD);
}
}
#endif
if (filtering == kFilterLinear) {
src_stride = 0;
@ -267,6 +283,14 @@ static int ScaleUVDown4Box(int src_width,
ScaleUVRowDown2 = ScaleUVRowDown2Box_HVX;
}
#endif
#if defined(HAS_SCALEUVROWDOWN2BOX_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ScaleUVRowDown2 = ScaleUVRowDown2Box_Any_WASMSIMD;
if (IS_ALIGNED(dst_width, 8)) {
ScaleUVRowDown2 = ScaleUVRowDown2Box_WASMSIMD;
}
}
#endif
for (j = 0; j < dst_height; ++j) {
ScaleUVRowDown2(src_uv, src_stride, row, dst_width * 2);
@ -740,6 +764,14 @@ static void ScaleUVDownEven(int src_width,
#endif
}
#endif
#if defined(HAS_SCALEUVROWDOWNEVEN_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD) && !filtering) {
ScaleUVRowDownEven = ScaleUVRowDownEven_Any_WASMSIMD;
if (IS_ALIGNED(dst_width, 4)) {
ScaleUVRowDownEven = ScaleUVRowDownEven_WASMSIMD;
}
}
#endif
if (filtering == kFilterLinear) {
src_stride = 0;
@ -1400,6 +1432,18 @@ static void ScaleUVLinearUp2(int src_width,
}
#endif
#ifdef HAS_SCALEUVROWUP2_LINEAR_WASMSIMD
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ScaleRowUp = ScaleUVRowUp2_Linear_Any_WASMSIMD;
}
#endif
#ifdef HAS_SCALEUVROWUP2_LINEAR_RELAXEDSIMD
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
ScaleRowUp = ScaleUVRowUp2_Linear_Any_RELAXEDSIMD;
}
#endif
if (dst_height == 1) {
ScaleRowUp(src_uv + ((src_height - 1) / 2) * src_stride, dst_uv, dst_width);
} else {
@ -1460,6 +1504,18 @@ static void ScaleUVBilinearUp2(int src_width,
}
#endif
#ifdef HAS_SCALEUVROWUP2_BILINEAR_WASMSIMD
if (TestCpuFlag(kCpuHasWASMSIMD)) {
Scale2RowUp = ScaleUVRowUp2_Bilinear_Any_WASMSIMD;
}
#endif
#ifdef HAS_SCALEUVROWUP2_BILINEAR_RELAXEDSIMD
if (TestCpuFlag(kCpuHasRELAXEDSIMD)) {
Scale2RowUp = ScaleUVRowUp2_Bilinear_Any_RELAXEDSIMD;
}
#endif
Scale2RowUp(src_ptr, 0, dst_ptr, 0, dst_width);
dst_ptr += dst_stride;
for (x = 0; x < src_height - 1; ++x) {

View File

@ -11,22 +11,27 @@
#include "libyuv/row.h"
#include "libyuv/scale_row.h"
#if !defined(LIBYUV_DISABLE_WASM) && defined(__wasm_simd128__)
#if (!defined(LIBYUV_DISABLE_WASMSIMD) || \
!defined(LIBYUV_DISABLE_RELAXEDSIMD)) && \
defined(__wasm_simd128__)
#include <wasm_simd128.h>
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Arbitrary i8x16.shuffle masks are rematerialized on every use by V8, so
// shuffles that do not map to a single instruction use swizzle with masks
// loaded before the loop. Mask indices of 128 produce 0.
template <bool kRelaxed>
static inline v128_t WasmSwizzle(v128_t a, v128_t b) {
#ifdef __wasm_relaxed_simd__
#define LIBYUV_WASM_SWIZZLE wasm_i8x16_relaxed_swizzle
#else
#define LIBYUV_WASM_SWIZZLE wasm_i8x16_swizzle
if (kRelaxed) {
return wasm_i8x16_relaxed_swizzle(a, b);
}
#endif
return wasm_i8x16_swizzle(a, b);
}
// Load a constant vector. The empty asm hides the address so the compiler
// keeps the vector in a local instead of sinking a v128.const into the loop.
@ -148,7 +153,8 @@ void ScaleRowDown4Box_WASMSIMD(const uint8_t* src_ptr,
}
#endif // HAS_SCALEROWDOWN4_WASMSIMD
#ifdef HAS_SCALEROWDOWN34_WASMSIMD
#if defined(HAS_SCALEROWDOWN34_WASMSIMD) || \
defined(HAS_SCALEROWDOWN34_RELAXEDSIMD)
static const uint8_t kShuf34[8][16] = {
// ScaleRowDown34: 16 bytes from a, then b, then 8 bytes from b.
{0, 1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 128, 128, 128, 128},
@ -164,10 +170,11 @@ static const uint8_t kShuf34[8][16] = {
};
// Point sample 32 pixels to 24, keeping pixels 0, 1 and 3 of every 4.
void ScaleRowDown34_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
template <bool kRelaxed>
static inline void ScaleRowDown34_Wasm(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
const v128_t m0 = LoadConst(kShuf34[0]);
const v128_t m1 = LoadConst(kShuf34[1]);
const v128_t m2 = LoadConst(kShuf34[2]);
@ -175,9 +182,9 @@ void ScaleRowDown34_WASMSIMD(const uint8_t* src_ptr,
while (dst_width > 0) {
v128_t a = wasm_v128_load(src_ptr);
v128_t b = wasm_v128_load(src_ptr + 16);
wasm_v128_store(dst_ptr, wasm_v128_or(LIBYUV_WASM_SWIZZLE(a, m0),
LIBYUV_WASM_SWIZZLE(b, m1)));
wasm_v128_store64_lane(dst_ptr + 16, LIBYUV_WASM_SWIZZLE(b, m2), 0);
wasm_v128_store(dst_ptr, wasm_v128_or(WasmSwizzle<kRelaxed>(a, m0),
WasmSwizzle<kRelaxed>(b, m1)));
wasm_v128_store64_lane(dst_ptr + 16, WasmSwizzle<kRelaxed>(b, m2), 0);
src_ptr += 32;
dst_ptr += 24;
dst_width -= 24;
@ -194,18 +201,20 @@ static inline v128_t AvgFloor(v128_t a, v128_t b) {
// Horizontal 4 to 3 filter of 16 pixels. Result bytes 4n+0..2 are
// (3 * s0 + s1 + 2) >> 2, (s1 + s2 + 1) >> 1, (s2 + 3 * s3 + 2) >> 2
// using (3 * a + b + 2) >> 2 == avgr(a, (a + b) >> 1). Byte 4n+3 is unused.
template <bool kRelaxed>
static inline v128_t Filter34(v128_t s, v128_t mp, v128_t ma) {
v128_t p = LIBYUV_WASM_SWIZZLE(s, mp); // s0 s1 s3
v128_t a = LIBYUV_WASM_SWIZZLE(s, ma); // s0 s2 s2
v128_t b = wasm_u32x4_shr(s, 8); // s1 s2 s3
v128_t p = WasmSwizzle<kRelaxed>(s, mp); // s0 s1 s3
v128_t a = WasmSwizzle<kRelaxed>(s, ma); // s0 s2 s2
v128_t b = wasm_u32x4_shr(s, 8); // s1 s2 s3
return wasm_u8x16_avgr(p, AvgFloor(a, b));
}
// Filter rows 1 and 2 together, 1 : 1
void ScaleRowDown34_1_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
template <bool kRelaxed>
static inline void ScaleRowDown34_1_Box_Wasm(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
const uint8_t* t = src_ptr + src_stride;
const v128_t mp = LoadConst(kShuf34[3]);
const v128_t ma = LoadConst(kShuf34[4]);
@ -213,13 +222,15 @@ void ScaleRowDown34_1_Box_WASMSIMD(const uint8_t* src_ptr,
const v128_t m1 = LoadConst(kShuf34[6]);
const v128_t m2 = LoadConst(kShuf34[7]);
while (dst_width > 0) {
v128_t a = wasm_u8x16_avgr(Filter34(wasm_v128_load(src_ptr), mp, ma),
Filter34(wasm_v128_load(t), mp, ma));
v128_t b = wasm_u8x16_avgr(Filter34(wasm_v128_load(src_ptr + 16), mp, ma),
Filter34(wasm_v128_load(t + 16), mp, ma));
wasm_v128_store(dst_ptr, wasm_v128_or(LIBYUV_WASM_SWIZZLE(a, m0),
LIBYUV_WASM_SWIZZLE(b, m1)));
wasm_v128_store64_lane(dst_ptr + 16, LIBYUV_WASM_SWIZZLE(b, m2), 0);
v128_t a =
wasm_u8x16_avgr(Filter34<kRelaxed>(wasm_v128_load(src_ptr), mp, ma),
Filter34<kRelaxed>(wasm_v128_load(t), mp, ma));
v128_t b = wasm_u8x16_avgr(
Filter34<kRelaxed>(wasm_v128_load(src_ptr + 16), mp, ma),
Filter34<kRelaxed>(wasm_v128_load(t + 16), mp, ma));
wasm_v128_store(dst_ptr, wasm_v128_or(WasmSwizzle<kRelaxed>(a, m0),
WasmSwizzle<kRelaxed>(b, m1)));
wasm_v128_store64_lane(dst_ptr + 16, WasmSwizzle<kRelaxed>(b, m2), 0);
src_ptr += 32;
t += 32;
dst_ptr += 24;
@ -228,10 +239,11 @@ void ScaleRowDown34_1_Box_WASMSIMD(const uint8_t* src_ptr,
}
// Filter rows 0 and 1 together, 3 : 1
void ScaleRowDown34_0_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
template <bool kRelaxed>
static inline void ScaleRowDown34_0_Box_Wasm(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
const uint8_t* t = src_ptr + src_stride;
const v128_t mp = LoadConst(kShuf34[3]);
const v128_t ma = LoadConst(kShuf34[4]);
@ -239,24 +251,67 @@ void ScaleRowDown34_0_Box_WASMSIMD(const uint8_t* src_ptr,
const v128_t m1 = LoadConst(kShuf34[6]);
const v128_t m2 = LoadConst(kShuf34[7]);
while (dst_width > 0) {
v128_t a0 = Filter34(wasm_v128_load(src_ptr), mp, ma);
v128_t b0 = Filter34(wasm_v128_load(src_ptr + 16), mp, ma);
v128_t a1 = Filter34(wasm_v128_load(t), mp, ma);
v128_t b1 = Filter34(wasm_v128_load(t + 16), mp, ma);
v128_t a0 = Filter34<kRelaxed>(wasm_v128_load(src_ptr), mp, ma);
v128_t b0 = Filter34<kRelaxed>(wasm_v128_load(src_ptr + 16), mp, ma);
v128_t a1 = Filter34<kRelaxed>(wasm_v128_load(t), mp, ma);
v128_t b1 = Filter34<kRelaxed>(wasm_v128_load(t + 16), mp, ma);
v128_t a = wasm_u8x16_avgr(a0, AvgFloor(a0, a1));
v128_t b = wasm_u8x16_avgr(b0, AvgFloor(b0, b1));
wasm_v128_store(dst_ptr, wasm_v128_or(LIBYUV_WASM_SWIZZLE(a, m0),
LIBYUV_WASM_SWIZZLE(b, m1)));
wasm_v128_store64_lane(dst_ptr + 16, LIBYUV_WASM_SWIZZLE(b, m2), 0);
wasm_v128_store(dst_ptr, wasm_v128_or(WasmSwizzle<kRelaxed>(a, m0),
WasmSwizzle<kRelaxed>(b, m1)));
wasm_v128_store64_lane(dst_ptr + 16, WasmSwizzle<kRelaxed>(b, m2), 0);
src_ptr += 32;
t += 32;
dst_ptr += 24;
dst_width -= 24;
}
}
#ifdef HAS_SCALEROWDOWN34_WASMSIMD
void ScaleRowDown34_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown34_Wasm<false>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown34_1_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown34_1_Box_Wasm<false>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown34_0_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown34_0_Box_Wasm<false>(src_ptr, src_stride, dst_ptr, dst_width);
}
#endif // HAS_SCALEROWDOWN34_WASMSIMD
#ifdef HAS_SCALEROWDOWN38_WASMSIMD
#ifdef HAS_SCALEROWDOWN34_RELAXEDSIMD
void ScaleRowDown34_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown34_Wasm<true>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown34_1_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown34_1_Box_Wasm<true>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown34_0_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown34_0_Box_Wasm<true>(src_ptr, src_stride, dst_ptr, dst_width);
}
#endif // HAS_SCALEROWDOWN34_RELAXEDSIMD
#endif // HAS_SCALEROWDOWN34_WASMSIMD || HAS_SCALEROWDOWN34_RELAXEDSIMD
#if defined(HAS_SCALEROWDOWN38_WASMSIMD) || \
defined(HAS_SCALEROWDOWN38_RELAXEDSIMD)
static const uint8_t kShuf38[3][16] = {
// ScaleRowDown38: 6 bytes from a, then 6 bytes from b.
{0, 3, 6, 8, 11, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128},
@ -266,17 +321,18 @@ static const uint8_t kShuf38[3][16] = {
};
// Point sample 32 pixels to 12, keeping pixels 0, 3 and 6 of every 8.
void ScaleRowDown38_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
template <bool kRelaxed>
static inline void ScaleRowDown38_Wasm(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
const v128_t m0 = LoadConst(kShuf38[0]);
const v128_t m1 = LoadConst(kShuf38[1]);
(void)src_stride;
while (dst_width > 0) {
v128_t d =
wasm_v128_or(LIBYUV_WASM_SWIZZLE(wasm_v128_load(src_ptr), m0),
LIBYUV_WASM_SWIZZLE(wasm_v128_load(src_ptr + 16), m1));
wasm_v128_or(WasmSwizzle<kRelaxed>(wasm_v128_load(src_ptr), m0),
WasmSwizzle<kRelaxed>(wasm_v128_load(src_ptr + 16), m1));
wasm_v128_store64_lane(dst_ptr, d, 0);
wasm_v128_store32_lane(dst_ptr + 8, d, 2);
src_ptr += 32;
@ -299,6 +355,7 @@ static inline v128_t Sum38(v128_t s, v128_t k) {
}
// Pack 12 results from Sum38 and store them.
template <bool kRelaxed>
static inline void Store38(uint8_t* dst_ptr,
v128_t m,
v128_t a,
@ -307,16 +364,17 @@ static inline void Store38(uint8_t* dst_ptr,
v128_t d) {
v128_t r = wasm_u8x16_narrow_i16x8(wasm_u16x8_narrow_i32x4(a, b),
wasm_u16x8_narrow_i32x4(c, d));
r = LIBYUV_WASM_SWIZZLE(r, m);
r = WasmSwizzle<kRelaxed>(r, m);
wasm_v128_store64_lane(dst_ptr, r, 0);
wasm_v128_store32_lane(dst_ptr + 8, r, 2);
}
// 8x3 -> 3x1
void ScaleRowDown38_3_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
template <bool kRelaxed>
static inline void ScaleRowDown38_3_Box_Wasm(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
const v128_t k =
wasm_i16x8_const(65536 / 9, 0, 0, 65536 / 9, 0, 0, 65536 / 6, 0);
const v128_t m = LoadConst(kShuf38[2]);
@ -328,8 +386,8 @@ void ScaleRowDown38_3_Box_WASMSIMD(const uint8_t* src_ptr,
wasm_u16x8_load8x8(p + src_stride)),
wasm_u16x8_load8x8(p + src_stride * 2));
}
Store38(dst_ptr, m, Sum38(s[0], k), Sum38(s[1], k), Sum38(s[2], k),
Sum38(s[3], k));
Store38<kRelaxed>(dst_ptr, m, Sum38(s[0], k), Sum38(s[1], k),
Sum38(s[2], k), Sum38(s[3], k));
src_ptr += 32;
dst_ptr += 12;
dst_width -= 12;
@ -337,10 +395,11 @@ void ScaleRowDown38_3_Box_WASMSIMD(const uint8_t* src_ptr,
}
// 8x2 -> 3x1
void ScaleRowDown38_2_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
template <bool kRelaxed>
static inline void ScaleRowDown38_2_Box_Wasm(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
const v128_t k =
wasm_i16x8_const(65536 / 6, 0, 0, 65536 / 6, 0, 0, 65536 / 4, 0);
const v128_t m = LoadConst(kShuf38[2]);
@ -351,15 +410,57 @@ void ScaleRowDown38_2_Box_WASMSIMD(const uint8_t* src_ptr,
s[i] = wasm_i16x8_add(wasm_u16x8_load8x8(p),
wasm_u16x8_load8x8(p + src_stride));
}
Store38(dst_ptr, m, Sum38(s[0], k), Sum38(s[1], k), Sum38(s[2], k),
Sum38(s[3], k));
Store38<kRelaxed>(dst_ptr, m, Sum38(s[0], k), Sum38(s[1], k),
Sum38(s[2], k), Sum38(s[3], k));
src_ptr += 32;
dst_ptr += 12;
dst_width -= 12;
}
}
#ifdef HAS_SCALEROWDOWN38_WASMSIMD
void ScaleRowDown38_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown38_Wasm<false>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown38_3_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown38_3_Box_Wasm<false>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown38_2_Box_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown38_2_Box_Wasm<false>(src_ptr, src_stride, dst_ptr, dst_width);
}
#endif // HAS_SCALEROWDOWN38_WASMSIMD
#ifdef HAS_SCALEROWDOWN38_RELAXEDSIMD
void ScaleRowDown38_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown38_Wasm<true>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown38_3_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown38_3_Box_Wasm<true>(src_ptr, src_stride, dst_ptr, dst_width);
}
void ScaleRowDown38_2_Box_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
int dst_width) {
ScaleRowDown38_2_Box_Wasm<true>(src_ptr, src_stride, dst_ptr, dst_width);
}
#endif // HAS_SCALEROWDOWN38_RELAXEDSIMD
#endif // HAS_SCALEROWDOWN38_WASMSIMD || HAS_SCALEROWDOWN38_RELAXEDSIMD
#ifdef HAS_SCALEFILTERCOLS_WASMSIMD
// Bilinear column filtering with 7 bit fractions, matching ScaleFilterCols_C:
// a + ((f * (b - a) + 64) >> 7). 8 pixels per loop. The fraction
@ -705,8 +806,492 @@ void ScaleUVAddCols3_WASMSIMD(int dst_width,
}
#endif // HAS_SCALEUVADDCOLS3_WASMSIMD
#ifdef HAS_SCALEUVROWDOWN2_WASMSIMD
void ScaleUVRowDown2_WASMSIMD(const uint8_t* src_uv,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width) {
int x;
(void)src_stride;
for (x = 0; x < dst_width - 7; x += 8) {
const v128_t s0 = wasm_v128_load(src_uv);
const v128_t s1 = wasm_v128_load(src_uv + 16);
src_uv += 32;
const v128_t d = wasm_i16x8_shuffle(s0, s1, 1, 3, 5, 7, 9, 11, 13, 15);
wasm_v128_store(dst_uv, d);
dst_uv += 16;
}
}
#endif // HAS_SCALEUVROWDOWN2_WASMSIMD
#ifdef HAS_SCALEUVROWDOWN2LINEAR_WASMSIMD
void ScaleUVRowDown2Linear_WASMSIMD(const uint8_t* src_uv,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width) {
int x;
(void)src_stride;
for (x = 0; x < dst_width - 7; x += 8) {
const v128_t s0 = wasm_v128_load(src_uv);
const v128_t s1 = wasm_v128_load(src_uv + 16);
src_uv += 32;
const v128_t even = wasm_i16x8_shuffle(s0, s1, 0, 2, 4, 6, 8, 10, 12, 14);
const v128_t odd = wasm_i16x8_shuffle(s0, s1, 1, 3, 5, 7, 9, 11, 13, 15);
wasm_v128_store(dst_uv, wasm_u8x16_avgr(even, odd));
dst_uv += 16;
}
}
#endif // HAS_SCALEUVROWDOWN2LINEAR_WASMSIMD
#ifdef HAS_SCALEUVROWDOWN2BOX_WASMSIMD
void ScaleUVRowDown2Box_WASMSIMD(const uint8_t* src_uv,
ptrdiff_t src_stride,
uint8_t* dst_uv,
int dst_width) {
int x;
const uint8_t* t_uv = src_uv + src_stride;
const v128_t kTwo = wasm_i16x8_splat(2);
for (x = 0; x < dst_width - 7; x += 8) {
const v128_t s0 = wasm_v128_load(src_uv);
const v128_t s1 = wasm_v128_load(src_uv + 16);
const v128_t t0 = wasm_v128_load(t_uv);
const v128_t t1 = wasm_v128_load(t_uv + 16);
src_uv += 32;
t_uv += 32;
const v128_t s_even = wasm_i16x8_shuffle(s0, s1, 0, 2, 4, 6, 8, 10, 12, 14);
const v128_t s_odd = wasm_i16x8_shuffle(s0, s1, 1, 3, 5, 7, 9, 11, 13, 15);
const v128_t t_even = wasm_i16x8_shuffle(t0, t1, 0, 2, 4, 6, 8, 10, 12, 14);
const v128_t t_odd = wasm_i16x8_shuffle(t0, t1, 1, 3, 5, 7, 9, 11, 13, 15);
const v128_t sum_lo =
wasm_i16x8_add(wasm_i16x8_add(wasm_u16x8_extend_low_u8x16(s_even),
wasm_u16x8_extend_low_u8x16(s_odd)),
wasm_i16x8_add(wasm_u16x8_extend_low_u8x16(t_even),
wasm_u16x8_extend_low_u8x16(t_odd)));
const v128_t sum_hi =
wasm_i16x8_add(wasm_i16x8_add(wasm_u16x8_extend_high_u8x16(s_even),
wasm_u16x8_extend_high_u8x16(s_odd)),
wasm_i16x8_add(wasm_u16x8_extend_high_u8x16(t_even),
wasm_u16x8_extend_high_u8x16(t_odd)));
const v128_t avg_lo = wasm_u16x8_shr(wasm_i16x8_add(sum_lo, kTwo), 2);
const v128_t avg_hi = wasm_u16x8_shr(wasm_i16x8_add(sum_hi, kTwo), 2);
wasm_v128_store(dst_uv, wasm_u8x16_narrow_i16x8(avg_lo, avg_hi));
dst_uv += 16;
}
}
#endif // HAS_SCALEUVROWDOWN2BOX_WASMSIMD
#ifdef HAS_SCALEUVROWDOWNEVEN_WASMSIMD
void ScaleUVRowDownEven_WASMSIMD(const uint8_t* src_uv,
ptrdiff_t src_stride,
int src_stepx,
uint8_t* dst_uv,
int dst_width) {
int x;
const ptrdiff_t step = (ptrdiff_t)src_stepx * 2;
(void)src_stride;
v128_t v = wasm_i32x4_splat(0);
for (x = 0; x < dst_width - 3; x += 4) {
v = wasm_v128_load16_lane(src_uv, v, 0);
v = wasm_v128_load16_lane(src_uv + step, v, 1);
v = wasm_v128_load16_lane(src_uv + step * 2, v, 2);
v = wasm_v128_load16_lane(src_uv + step * 3, v, 3);
wasm_v128_store64_lane(dst_uv, v, 0);
src_uv += step * 4;
dst_uv += 8;
}
}
#endif // HAS_SCALEUVROWDOWNEVEN_WASMSIMD
#if defined(HAS_SCALEROWUP2_LINEAR_WASMSIMD) || \
defined(HAS_SCALEROWUP2_BILINEAR_WASMSIMD)
static inline void ScaleRowUp2Madd31_Wasm(const uint8_t* src,
v128_t* out_lo,
v128_t* out_hi) {
const v128_t s0 = wasm_u16x8_load8x8(src);
const v128_t s1 = wasm_u16x8_load8x8(src + 1);
const v128_t near_lo = wasm_i16x8_shuffle(s0, s1, 0, 8, 1, 9, 2, 10, 3, 11);
const v128_t far_lo = wasm_i16x8_shuffle(s0, s1, 8, 0, 9, 1, 10, 2, 11, 3);
const v128_t near_hi = wasm_i16x8_shuffle(s0, s1, 4, 12, 5, 13, 6, 14, 7, 15);
const v128_t far_hi = wasm_i16x8_shuffle(s0, s1, 12, 4, 13, 5, 14, 6, 15, 7);
*out_lo = wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(near_lo, 1), near_lo),
far_lo);
*out_hi = wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(near_hi, 1), near_hi),
far_hi);
}
#endif // HAS_SCALEROWUP2_LINEAR_WASMSIMD || HAS_SCALEROWUP2_BILINEAR_WASMSIMD
#if defined(HAS_SCALEROWUP2_LINEAR_RELAXEDSIMD) || \
defined(HAS_SCALEROWUP2_BILINEAR_RELAXEDSIMD)
static inline void ScaleRowUp2Madd31_Relaxed(const uint8_t* src,
v128_t* out_lo,
v128_t* out_hi) {
const v128_t kBias80 = wasm_i8x16_splat(-128);
const v128_t kMadd31 =
wasm_i8x16_const(3, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 3);
const v128_t s0 = wasm_v128_xor(wasm_v128_load64_zero(src), kBias80);
const v128_t s1 = wasm_v128_xor(wasm_v128_load64_zero(src + 1), kBias80);
const v128_t lo = wasm_i8x16_shuffle(s0, s1, 0, 16, 0, 16, 1, 17, 1, 17, 2,
18, 2, 18, 3, 19, 3, 19);
const v128_t hi = wasm_i8x16_shuffle(s0, s1, 4, 20, 4, 20, 5, 21, 5, 21, 6,
22, 6, 22, 7, 23, 7, 23);
*out_lo = wasm_i16x8_relaxed_dot_i8x16_i7x16(lo, kMadd31);
*out_hi = wasm_i16x8_relaxed_dot_i8x16_i7x16(hi, kMadd31);
}
#endif // HAS_SCALEROWUP2_LINEAR_RELAXEDSIMD ||
// HAS_SCALEROWUP2_BILINEAR_RELAXEDSIMD
#ifdef HAS_SCALEROWUP2_LINEAR_WASMSIMD
void ScaleRowUp2_Linear_WASMSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width) {
int x;
const v128_t kTwo = wasm_i16x8_splat(2);
for (x = 0; x < dst_width - 15; x += 16) {
v128_t lo, hi;
ScaleRowUp2Madd31_Wasm(src_ptr, &lo, &hi);
src_ptr += 8;
lo = wasm_u16x8_shr(wasm_i16x8_add(lo, kTwo), 2);
hi = wasm_u16x8_shr(wasm_i16x8_add(hi, kTwo), 2);
wasm_v128_store(dst_ptr, wasm_u8x16_narrow_i16x8(lo, hi));
dst_ptr += 16;
}
}
#endif // HAS_SCALEROWUP2_LINEAR_WASMSIMD
#ifdef HAS_SCALEROWUP2_LINEAR_RELAXEDSIMD
void ScaleRowUp2_Linear_RELAXEDSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width) {
int x;
const v128_t kBias514 = wasm_i16x8_splat(512 + 2);
for (x = 0; x < dst_width - 15; x += 16) {
v128_t lo, hi;
ScaleRowUp2Madd31_Relaxed(src_ptr, &lo, &hi);
src_ptr += 8;
lo = wasm_u16x8_shr(wasm_i16x8_add(lo, kBias514), 2);
hi = wasm_u16x8_shr(wasm_i16x8_add(hi, kBias514), 2);
wasm_v128_store(dst_ptr, wasm_u8x16_narrow_i16x8(lo, hi));
dst_ptr += 16;
}
}
#endif // HAS_SCALEROWUP2_LINEAR_RELAXEDSIMD
#ifdef HAS_SCALEROWUP2_BILINEAR_WASMSIMD
void ScaleRowUp2_Bilinear_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width) {
int x;
const uint8_t* s = src_ptr;
const uint8_t* t = src_ptr + src_stride;
uint8_t* d = dst_ptr;
uint8_t* e = dst_ptr + dst_stride;
const v128_t kEight = wasm_i16x8_splat(8);
for (x = 0; x < dst_width - 15; x += 16) {
v128_t s_lo, s_hi, t_lo, t_hi;
ScaleRowUp2Madd31_Wasm(s, &s_lo, &s_hi);
ScaleRowUp2Madd31_Wasm(t, &t_lo, &t_hi);
s += 8;
t += 8;
const v128_t d_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_lo, 1), s_lo),
wasm_i16x8_add(t_lo, kEight)),
4);
const v128_t d_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_hi, 1), s_hi),
wasm_i16x8_add(t_hi, kEight)),
4);
const v128_t e_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_lo, 1), t_lo),
wasm_i16x8_add(s_lo, kEight)),
4);
const v128_t e_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_hi, 1), t_hi),
wasm_i16x8_add(s_hi, kEight)),
4);
wasm_v128_store(d, wasm_u8x16_narrow_i16x8(d_lo, d_hi));
wasm_v128_store(e, wasm_u8x16_narrow_i16x8(e_lo, e_hi));
d += 16;
e += 16;
}
}
#endif // HAS_SCALEROWUP2_BILINEAR_WASMSIMD
#ifdef HAS_SCALEROWUP2_BILINEAR_RELAXEDSIMD
void ScaleRowUp2_Bilinear_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width) {
int x;
const uint8_t* s = src_ptr;
const uint8_t* t = src_ptr + src_stride;
uint8_t* d = dst_ptr;
uint8_t* e = dst_ptr + dst_stride;
const v128_t kBias2056 = wasm_i16x8_splat(2048 + 8);
for (x = 0; x < dst_width - 15; x += 16) {
v128_t s_lo, s_hi, t_lo, t_hi;
ScaleRowUp2Madd31_Relaxed(s, &s_lo, &s_hi);
ScaleRowUp2Madd31_Relaxed(t, &t_lo, &t_hi);
s += 8;
t += 8;
const v128_t d_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_lo, 1), s_lo),
wasm_i16x8_add(t_lo, kBias2056)),
4);
const v128_t d_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_hi, 1), s_hi),
wasm_i16x8_add(t_hi, kBias2056)),
4);
const v128_t e_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_lo, 1), t_lo),
wasm_i16x8_add(s_lo, kBias2056)),
4);
const v128_t e_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_hi, 1), t_hi),
wasm_i16x8_add(s_hi, kBias2056)),
4);
wasm_v128_store(d, wasm_u8x16_narrow_i16x8(d_lo, d_hi));
wasm_v128_store(e, wasm_u8x16_narrow_i16x8(e_lo, e_hi));
d += 16;
e += 16;
}
}
#endif // HAS_SCALEROWUP2_BILINEAR_RELAXEDSIMD
#if defined(HAS_SCALEUVROWUP2_LINEAR_WASMSIMD) || \
defined(HAS_SCALEUVROWUP2_BILINEAR_WASMSIMD)
static inline void ScaleUVRowUp2Madd31_Wasm(const uint8_t* src,
v128_t* out_lo,
v128_t* out_hi) {
const v128_t s0 = wasm_u16x8_load8x8(src);
const v128_t s1 = wasm_u16x8_load8x8(src + 2);
const v128_t near_lo = wasm_i16x8_shuffle(s0, s1, 0, 1, 8, 9, 2, 3, 10, 11);
const v128_t far_lo = wasm_i16x8_shuffle(s0, s1, 8, 9, 0, 1, 10, 11, 2, 3);
const v128_t near_hi = wasm_i16x8_shuffle(s0, s1, 4, 5, 12, 13, 6, 7, 14, 15);
const v128_t far_hi = wasm_i16x8_shuffle(s0, s1, 12, 13, 4, 5, 14, 15, 6, 7);
*out_lo = wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(near_lo, 1), near_lo),
far_lo);
*out_hi = wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(near_hi, 1), near_hi),
far_hi);
}
#endif // HAS_SCALEUVROWUP2_LINEAR_WASMSIMD ||
// HAS_SCALEUVROWUP2_BILINEAR_WASMSIMD
#if defined(HAS_SCALEUVROWUP2_LINEAR_RELAXEDSIMD) || \
defined(HAS_SCALEUVROWUP2_BILINEAR_RELAXEDSIMD)
static inline void ScaleUVRowUp2Madd31_Relaxed(const uint8_t* src,
v128_t* out_lo,
v128_t* out_hi) {
const v128_t kBias80 = wasm_i8x16_splat(-128);
const v128_t kUVMadd31 =
wasm_i8x16_const(3, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1, 3, 1, 3);
const v128_t s0 = wasm_v128_xor(wasm_v128_load64_zero(src), kBias80);
const v128_t s1 = wasm_v128_xor(wasm_v128_load64_zero(src + 2), kBias80);
const v128_t lo = wasm_i8x16_shuffle(s0, s1, 0, 16, 1, 17, 0, 16, 1, 17, 2,
18, 3, 19, 2, 18, 3, 19);
const v128_t hi = wasm_i8x16_shuffle(s0, s1, 4, 20, 5, 21, 4, 20, 5, 21, 6,
22, 7, 23, 6, 22, 7, 23);
*out_lo = wasm_i16x8_relaxed_dot_i8x16_i7x16(lo, kUVMadd31);
*out_hi = wasm_i16x8_relaxed_dot_i8x16_i7x16(hi, kUVMadd31);
}
#endif // HAS_SCALEUVROWUP2_LINEAR_RELAXEDSIMD ||
// HAS_SCALEUVROWUP2_BILINEAR_RELAXEDSIMD
#ifdef HAS_SCALEUVROWUP2_LINEAR_WASMSIMD
void ScaleUVRowUp2_Linear_WASMSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width) {
int x;
const v128_t kTwo = wasm_i16x8_splat(2);
for (x = 0; x < dst_width - 7; x += 8) {
v128_t lo, hi;
ScaleUVRowUp2Madd31_Wasm(src_ptr, &lo, &hi);
src_ptr += 8;
lo = wasm_u16x8_shr(wasm_i16x8_add(lo, kTwo), 2);
hi = wasm_u16x8_shr(wasm_i16x8_add(hi, kTwo), 2);
wasm_v128_store(dst_ptr, wasm_u8x16_narrow_i16x8(lo, hi));
dst_ptr += 16;
}
}
#endif // HAS_SCALEUVROWUP2_LINEAR_WASMSIMD
#ifdef HAS_SCALEUVROWUP2_LINEAR_RELAXEDSIMD
void ScaleUVRowUp2_Linear_RELAXEDSIMD(const uint8_t* src_ptr,
uint8_t* dst_ptr,
int dst_width) {
int x;
const v128_t kBias514 = wasm_i16x8_splat(512 + 2);
for (x = 0; x < dst_width - 7; x += 8) {
v128_t lo, hi;
ScaleUVRowUp2Madd31_Relaxed(src_ptr, &lo, &hi);
src_ptr += 8;
lo = wasm_u16x8_shr(wasm_i16x8_add(lo, kBias514), 2);
hi = wasm_u16x8_shr(wasm_i16x8_add(hi, kBias514), 2);
wasm_v128_store(dst_ptr, wasm_u8x16_narrow_i16x8(lo, hi));
dst_ptr += 16;
}
}
#endif // HAS_SCALEUVROWUP2_LINEAR_RELAXEDSIMD
#ifdef HAS_SCALEUVROWUP2_BILINEAR_WASMSIMD
void ScaleUVRowUp2_Bilinear_WASMSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width) {
int x;
const uint8_t* s = src_ptr;
const uint8_t* t = src_ptr + src_stride;
uint8_t* d = dst_ptr;
uint8_t* e = dst_ptr + dst_stride;
const v128_t kEight = wasm_i16x8_splat(8);
for (x = 0; x < dst_width - 7; x += 8) {
v128_t s_lo, s_hi, t_lo, t_hi;
ScaleUVRowUp2Madd31_Wasm(s, &s_lo, &s_hi);
ScaleUVRowUp2Madd31_Wasm(t, &t_lo, &t_hi);
s += 8;
t += 8;
const v128_t d_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_lo, 1), s_lo),
wasm_i16x8_add(t_lo, kEight)),
4);
const v128_t d_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_hi, 1), s_hi),
wasm_i16x8_add(t_hi, kEight)),
4);
const v128_t e_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_lo, 1), t_lo),
wasm_i16x8_add(s_lo, kEight)),
4);
const v128_t e_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_hi, 1), t_hi),
wasm_i16x8_add(s_hi, kEight)),
4);
wasm_v128_store(d, wasm_u8x16_narrow_i16x8(d_lo, d_hi));
wasm_v128_store(e, wasm_u8x16_narrow_i16x8(e_lo, e_hi));
d += 16;
e += 16;
}
}
#endif // HAS_SCALEUVROWUP2_BILINEAR_WASMSIMD
#ifdef HAS_SCALEUVROWUP2_BILINEAR_RELAXEDSIMD
void ScaleUVRowUp2_Bilinear_RELAXEDSIMD(const uint8_t* src_ptr,
ptrdiff_t src_stride,
uint8_t* dst_ptr,
ptrdiff_t dst_stride,
int dst_width) {
int x;
const uint8_t* s = src_ptr;
const uint8_t* t = src_ptr + src_stride;
uint8_t* d = dst_ptr;
uint8_t* e = dst_ptr + dst_stride;
const v128_t kBias2056 = wasm_i16x8_splat(2048 + 8);
for (x = 0; x < dst_width - 7; x += 8) {
v128_t s_lo, s_hi, t_lo, t_hi;
ScaleUVRowUp2Madd31_Relaxed(s, &s_lo, &s_hi);
ScaleUVRowUp2Madd31_Relaxed(t, &t_lo, &t_hi);
s += 8;
t += 8;
const v128_t d_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_lo, 1), s_lo),
wasm_i16x8_add(t_lo, kBias2056)),
4);
const v128_t d_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(s_hi, 1), s_hi),
wasm_i16x8_add(t_hi, kBias2056)),
4);
const v128_t e_lo = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_lo, 1), t_lo),
wasm_i16x8_add(s_lo, kBias2056)),
4);
const v128_t e_hi = wasm_u16x8_shr(
wasm_i16x8_add(wasm_i16x8_add(wasm_i16x8_shl(t_hi, 1), t_hi),
wasm_i16x8_add(s_hi, kBias2056)),
4);
wasm_v128_store(d, wasm_u8x16_narrow_i16x8(d_lo, d_hi));
wasm_v128_store(e, wasm_u8x16_narrow_i16x8(e_lo, e_hi));
d += 16;
e += 16;
}
}
#endif // HAS_SCALEUVROWUP2_BILINEAR_RELAXEDSIMD
#ifdef HAS_SCALESAMPLES_WASMSIMD
void ScaleSamples_WASMSIMD(const float* src,
float* dst,
float scale,
int width) {
const v128_t vscale = wasm_f32x4_splat(scale);
for (; width >= 4; width -= 4) {
const v128_t v = wasm_v128_load(src);
src += 4;
wasm_v128_store(dst, wasm_f32x4_mul(v, vscale));
dst += 4;
}
for (; width > 0; --width) {
*dst++ = *src++ * scale;
}
}
#endif // HAS_SCALESAMPLES_WASMSIMD
#ifdef HAS_SCALESUMSAMPLES_WASMSIMD
float ScaleSumSamples_WASMSIMD(const float* src,
float* dst,
float scale,
int width) {
v128_t vsum = wasm_f32x4_splat(0.f);
const v128_t vscale = wasm_f32x4_splat(scale);
for (; width >= 4; width -= 4) {
const v128_t v = wasm_v128_load(src);
src += 4;
vsum = wasm_f32x4_add(vsum, wasm_f32x4_mul(v, v));
wasm_v128_store(dst, wasm_f32x4_mul(v, vscale));
dst += 4;
}
vsum = wasm_f32x4_add(vsum, wasm_i32x4_shuffle(vsum, vsum, 2, 3, 0, 1));
vsum = wasm_f32x4_add(vsum, wasm_i32x4_shuffle(vsum, vsum, 1, 0, 3, 2));
float fsum = wasm_f32x4_extract_lane(vsum, 0);
for (; width > 0; --width) {
const float v = *src++;
fsum += v * v;
*dst++ = v * scale;
}
return fsum;
}
#endif // HAS_SCALESUMSAMPLES_WASMSIMD
#ifdef HAS_SCALEMAXSAMPLES_WASMSIMD
float ScaleMaxSamples_WASMSIMD(const float* src,
float* dst,
float scale,
int width) {
v128_t vmax = wasm_f32x4_splat(0.f);
const v128_t vscale = wasm_f32x4_splat(scale);
for (; width >= 4; width -= 4) {
const v128_t v = wasm_v128_load(src);
src += 4;
vmax = wasm_f32x4_pmax(vmax, v);
wasm_v128_store(dst, wasm_f32x4_mul(v, vscale));
dst += 4;
}
vmax = wasm_f32x4_pmax(vmax, wasm_i32x4_shuffle(vmax, vmax, 2, 3, 0, 1));
vmax = wasm_f32x4_pmax(vmax, wasm_i32x4_shuffle(vmax, vmax, 1, 0, 3, 2));
float fmax = wasm_f32x4_extract_lane(vmax, 0);
for (; width > 0; --width) {
const float v = *src++;
if (v > fmax) {
fmax = v;
}
*dst++ = v * scale;
}
return fmax;
}
#endif // HAS_SCALEMAXSAMPLES_WASMSIMD
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif

View File

@ -167,8 +167,10 @@ TEST_F(LibYUVBaseTest, TestCpuHas) {
int has_wasm = TestCpuFlag(kCpuHasWASM);
if (has_wasm) {
int has_wasm_simd = TestCpuFlag(kCpuHasWASMSIMD);
int has_relaxed_simd = TestCpuFlag(kCpuHasRELAXEDSIMD);
printf("Has WASM 0x%x\n", has_wasm);
printf("Has WASM SIMD 0x%x\n", has_wasm_simd);
printf("Has RELAXED SIMD 0x%x\n", has_relaxed_simd);
}
#endif // defined(__wasm__)
@ -325,6 +327,9 @@ TEST_F(LibYUVBaseTest, TestCompilerMacros) {
#ifdef __wasm_simd128__
printf("__wasm_simd128__ %d\n", __wasm_simd128__);
#endif
#ifdef __wasm_relaxed_simd__
printf("__wasm_relaxed_simd__ %d\n", __wasm_relaxed_simd__);
#endif
#ifdef __hexagon__
printf("__hexagon__ %d\n", __hexagon__);
#endif
@ -472,6 +477,11 @@ TEST_F(LibYUVBaseTest, MAYBE_TestSetCpuFlags) {
SetCpuFlags(cpu_flags);
ASSERT_EQ(cpu_flags, TestCpuFlag(-1));
cpu_flags =
kCpuHasWASM | kCpuHasWASMSIMD | kCpuHasRELAXEDSIMD | kCpuInitialized;
SetCpuFlags(cpu_flags);
ASSERT_EQ(cpu_flags, TestCpuFlag(-1));
// Test that setting 0 turns auto-init back on.
SetCpuFlags(0);
ASSERT_EQ(original_cpu_flags, TestCpuFlag(-1));

View File

@ -4890,6 +4890,16 @@ float TestScaleMaxSamples(int benchmark_width,
reinterpret_cast<float*>(dst_opt), scale,
kPixels);
}
#elif defined(HAS_SCALEMAXSAMPLES_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
max_opt = ScaleMaxSamples_WASMSIMD(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt),
scale, kPixels);
} else {
max_opt = ScaleMaxSamples_C(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt), scale,
kPixels);
}
#else
max_opt =
ScaleMaxSamples_C(reinterpret_cast<float*>(orig_y),
@ -4997,6 +5007,16 @@ float TestScaleSumSamples(int benchmark_width,
reinterpret_cast<float*>(dst_opt), scale,
kPixels);
}
#elif defined(HAS_SCALESUMSAMPLES_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
sum_opt = ScaleSumSamples_WASMSIMD(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt),
scale, kPixels);
} else {
sum_opt = ScaleSumSamples_C(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt), scale,
kPixels);
}
#else
sum_opt =
ScaleSumSamples_C(reinterpret_cast<float*>(orig_y),
@ -5107,6 +5127,15 @@ float TestScaleSamples(int benchmark_width,
ScaleSamples_C(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt), scale, kPixels);
}
#elif defined(HAS_SCALESAMPLES_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
ScaleSamples_WASMSIMD(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt), scale,
kPixels);
} else {
ScaleSamples_C(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt), scale, kPixels);
}
#else
ScaleSamples_C(reinterpret_cast<float*>(orig_y),
reinterpret_cast<float*>(dst_opt), scale, kPixels);
@ -5176,6 +5205,12 @@ float TestCopySamples(int benchmark_width,
} else {
CopyRow_C(orig_y, dst_opt, kPixels * 4);
}
#elif defined(HAS_COPYROW_WASMSIMD)
if (TestCpuFlag(kCpuHasWASMSIMD)) {
CopyRow_WASMSIMD(orig_y, dst_opt, kPixels * 4);
} else {
CopyRow_C(orig_y, dst_opt, kPixels * 4);
}
#else
CopyRow_C(orig_y, dst_opt, kPixels * 4);
#endif

View File

@ -135,8 +135,14 @@ static int TestCpuEnv(int cpu_info) {
#endif
#if defined(__wasm__)
if (TestEnv("LIBYUV_DISABLE_WASM")) {
cpu_info &= ~(libyuv::kCpuHasWASMSIMD | libyuv::kCpuHasRELAXEDSIMD);
}
if (TestEnv("LIBYUV_DISABLE_WASMSIMD")) {
cpu_info &= ~libyuv::kCpuHasWASMSIMD;
}
if (TestEnv("LIBYUV_DISABLE_RELAXEDSIMD")) {
cpu_info &= ~libyuv::kCpuHasRELAXEDSIMD;
}
#endif
#if defined(__hexagon__)
if (TestEnv("LIBYUV_DISABLE_HVX")) {

View File

@ -140,8 +140,10 @@ int main(int argc, const char* argv[]) {
int has_wasm = TestCpuFlag(kCpuHasWASM);
if (has_wasm) {
int has_wasm_simd = TestCpuFlag(kCpuHasWASMSIMD);
int has_relaxed_simd = TestCpuFlag(kCpuHasRELAXEDSIMD);
printf("Has WASM 0x%x\n", has_wasm);
printf("Has WASM SIMD 0x%x\n", has_wasm_simd);
printf("Has RELAXED SIMD 0x%x\n", has_relaxed_simd);
}
#endif // defined(__wasm__)