mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-10-28 18:07:12 +08:00
Implement RAWToRGB24Row_WASMSIMD and RAWToRGB24Row_Any_WASMSIMD in source/row_wasm.cc for RGB24ToRAW and RAWToRGB24 conversions: - Process 16 pixels (48 bytes) per loop iteration using three 128-bit loads, three byte-wise shuffles, and four 2-way blends. - Use wasm_i8x16_relaxed_swizzle when __wasm_relaxed_simd__ is enabled (compiling to a single vpshufb on x86 without bounds-checking overhead) and fall back to wasm_i8x16_swizzle for baseline SIMD128. - Add kCpuHasWASM (0x100) and kCpuHasWASMSIMD (0x101) CPU feature flags and enable -msimd128 in BUILD.bazel, BUILD.gn, and CMakeLists.txt for WebAssembly targets. Performance (RAWToRGB24_Opt, 1280x720, V8 d8): CPU WASM C SIMD128 Relaxed SIMD Spd Rlx Spd ------------------------------------------------------------------- AMD Zen 4 595.0 us 137.0 us 84.0 us 4.34x 7.08x AMD Zen 3 708.0 us 148.0 us 107.0 us 4.78x 6.62x AMD Zen 5 375.0 us 107.0 us 67.0 us 3.50x 5.60x ARM Neoverse-V2 638.0 us 118.0 us 116.0 us 5.41x 5.50x ARM Neoverse-N1 1046.0 us 294.0 us 294.0 us 3.56x 3.56x Intel Ice Lake 707.0 us 209.0 us 220.0 us 3.38x 3.21x Intel Haswell 1110.0 us 344.0 us 360.0 us 3.23x 3.08x Intel Emerald Rapids 519.0 us 207.0 us 208.0 us 2.51x 2.50x Intel Sapphire Rapids 551.0 us 220.0 us 255.0 us 2.50x 2.16x ARM Cortex-A53 14440.0 us 8660.0us 6920.0us 1.67x 2.09x Intel Granite Rapids 453.0 us 225.0 us 221.0 us 2.01x 2.05x Bug: 42271072 Test: libyuv_test --gunit_filter=*RAWToRGB24*:*RGB24ToRAW*:*Cpu* Change-Id: Id902668263a2ab70aa300eeeea18851490c917b5 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8515581 Reviewed-by: richard winterton <rrwinterton@gmail.com> Commit-Queue: Frank Barchard <fbarchard@google.com>
288 lines
7.4 KiB
Python
288 lines
7.4 KiB
Python
# Copyright 2026 The LibYuv Project Authors. All rights reserved.
|
|
#
|
|
# Description:
|
|
# The libyuv package provides implementation yuv image conversion, rotation
|
|
# and scaling.
|
|
|
|
load("@bazel_skylib//lib:selects.bzl", "selects")
|
|
load(":libyuv.bzl", "libyuv_hdrs", "libyuv_neon_srcs", "libyuv_rvv_srcs", "libyuv_srcs", "libyuv_sve_srcs", "libyuv_test_srcs")
|
|
|
|
# Detect if we are in Google's internal repository (where source files are
|
|
# under files/) or open source (where source files are at the root).
|
|
PREFIX = "files/" if len(native.glob(["files/source/*.cc"])) > 0 else ""
|
|
|
|
# We support NEON for all arm processors, as we only support ARMv7a+.
|
|
SUPPORTS_NEON_COPTS = [
|
|
"-DLIBYUV_NEON",
|
|
]
|
|
|
|
# ARMv7a requires that we explicitly enable NEON. arm64 enables it implicitly.
|
|
ENABLE_NEON_COPTS = [
|
|
"-mfpu=neon",
|
|
]
|
|
|
|
ENABLE_NEON64_COPTS = [
|
|
"-march=armv8-a+dotprod+i8mm",
|
|
]
|
|
|
|
NEON_COPTS = select({
|
|
"@platforms//cpu:armv7": ENABLE_NEON_COPTS + SUPPORTS_NEON_COPTS,
|
|
"@platforms//cpu:aarch64": ENABLE_NEON64_COPTS + SUPPORTS_NEON_COPTS,
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
SUPPORTS_SVE_COPTS = [
|
|
"-DLIBYUV_SVE",
|
|
]
|
|
|
|
ENABLE_SVE_COPTS = [
|
|
"-march=armv8.5-a+i8mm+sve2",
|
|
]
|
|
|
|
SVE_COPTS = select({
|
|
"@platforms//cpu:aarch64": ENABLE_SVE_COPTS + SUPPORTS_SVE_COPTS,
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
SUPPORTS_RVV_COPTS = [
|
|
"-DLIBYUV_RVV",
|
|
"-fno-tree-vectorize",
|
|
"-fno-tree-slp-vectorize",
|
|
]
|
|
|
|
ENABLE_RVV_COPTS = [
|
|
"-march=rv32gcv",
|
|
]
|
|
|
|
ENABLE_RVV64_COPTS = [
|
|
"-march=rv64gcv",
|
|
]
|
|
|
|
RVV_COPTS = select({
|
|
"@platforms//cpu:riscv32": ENABLE_RVV_COPTS + SUPPORTS_RVV_COPTS,
|
|
"@platforms//cpu:riscv64": ENABLE_RVV64_COPTS + SUPPORTS_RVV_COPTS,
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
ARCH_SUPPORT_COPTS = select({
|
|
"@platforms//cpu:armv7": SUPPORTS_NEON_COPTS,
|
|
"@platforms//cpu:aarch64": SUPPORTS_NEON_COPTS + SUPPORTS_SVE_COPTS,
|
|
"@platforms//cpu:riscv32": SUPPORTS_RVV_COPTS,
|
|
"@platforms//cpu:riscv64": SUPPORTS_RVV_COPTS,
|
|
"@platforms//cpu:wasm32": ["-msimd128"],
|
|
"@platforms//cpu:wasm64": ["-msimd128"],
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
PLATFORM_COPTS = select({
|
|
"@platforms//os:android": ["-DHAVE_JPEG"],
|
|
"@platforms//os:linux": ["-DHAVE_JPEG"],
|
|
"@platforms//os:windows": ["-DHAVE_JPEG"],
|
|
"@platforms//os:macos": ["-DHAVE_JPEG"],
|
|
"//conditions:default": [],
|
|
}) + [
|
|
"-DLIBYUV_DISABLE_SME",
|
|
"-DLIBYUV_USE_ABSL_FLAGS",
|
|
"-DGOOGLE_COMMANDLINEFLAGS_FULL_API",
|
|
]
|
|
|
|
ALL_COPTS = PLATFORM_COPTS + ARCH_SUPPORT_COPTS
|
|
|
|
ALL_NEON_COPTS = NEON_COPTS + PLATFORM_COPTS
|
|
|
|
ALL_SVE_COPTS = SVE_COPTS + PLATFORM_COPTS
|
|
|
|
ALL_RVV_COPTS = RVV_COPTS + PLATFORM_COPTS
|
|
|
|
NEON_DEPS = select({
|
|
"@platforms//cpu:armv7": [":libyuv_neon_impl"],
|
|
"@platforms//cpu:aarch64": [":libyuv_neon_impl"],
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
SVE_DEPS = select({
|
|
"@platforms//cpu:aarch64": [":libyuv_sve_impl"],
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
RVV_DEPS = select({
|
|
"@platforms//cpu:riscv32": [":libyuv_rvv_impl"],
|
|
"@platforms//cpu:riscv64": [":libyuv_rvv_impl"],
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
PLATFORM_DEPS = select({
|
|
"@platforms//os:android": ["@libjpeg_turbo//:jpeg"],
|
|
"@platforms//os:linux": ["@libjpeg_turbo//:jpeg"],
|
|
"@platforms//os:windows": ["@libjpeg_turbo//:jpeg"],
|
|
"@platforms//os:macos": ["@libjpeg_turbo//:jpeg"],
|
|
"//conditions:default": [],
|
|
})
|
|
|
|
ALL_DEPS = NEON_DEPS + SVE_DEPS + RVV_DEPS + PLATFORM_DEPS
|
|
|
|
cc_library(
|
|
name = "libyuv",
|
|
hdrs = [
|
|
PREFIX + "include/libyuv.h",
|
|
# Headers included by libyuv.h.
|
|
PREFIX + "include/libyuv/basic_types.h",
|
|
PREFIX + "include/libyuv/compare.h",
|
|
PREFIX + "include/libyuv/convert.h",
|
|
PREFIX + "include/libyuv/convert_argb.h",
|
|
PREFIX + "include/libyuv/convert_from.h",
|
|
PREFIX + "include/libyuv/convert_from_argb.h",
|
|
PREFIX + "include/libyuv/cpu_id.h",
|
|
PREFIX + "include/libyuv/mjpeg_decoder.h",
|
|
PREFIX + "include/libyuv/planar_functions.h",
|
|
PREFIX + "include/libyuv/rotate.h",
|
|
PREFIX + "include/libyuv/rotate_argb.h",
|
|
PREFIX + "include/libyuv/row.h", # Bug 553148013: Should be private.
|
|
PREFIX + "include/libyuv/scale.h",
|
|
PREFIX + "include/libyuv/scale_argb.h",
|
|
PREFIX + "include/libyuv/scale_rgb.h",
|
|
PREFIX + "include/libyuv/scale_uv.h",
|
|
PREFIX + "include/libyuv/version.h",
|
|
PREFIX + "include/libyuv/video_common.h",
|
|
# Headers included by libyuv/row.h.
|
|
PREFIX + "include/libyuv/cpu_support.h", # Bug 553148013: Should be private.
|
|
],
|
|
strip_include_prefix = PREFIX + "include",
|
|
visibility = ["//visibility:public"],
|
|
deps = [":libyuv_impl"],
|
|
)
|
|
|
|
cc_library(
|
|
name = "libyuv_impl",
|
|
srcs = libyuv_srcs(PREFIX),
|
|
hdrs = libyuv_hdrs(PREFIX),
|
|
copts = ALL_COPTS + selects.with_or({
|
|
(
|
|
"@platforms//os:android",
|
|
"@platforms//os:ios",
|
|
"@platforms//os:tvos",
|
|
"@platforms//os:windows",
|
|
"@platforms//os:macos",
|
|
): [],
|
|
"//conditions:default": [
|
|
"-fomit-frame-pointer",
|
|
],
|
|
}) + selects.with_or({
|
|
(
|
|
"@platforms//os:android",
|
|
"@platforms//os:ios",
|
|
"@platforms//os:tvos",
|
|
): ["-O2"],
|
|
"//conditions:default": [],
|
|
}),
|
|
includes = [PREFIX + "include"],
|
|
deps = ALL_DEPS,
|
|
alwayslink = 1,
|
|
)
|
|
|
|
cc_library(
|
|
name = "libyuv_neon_impl",
|
|
srcs = libyuv_neon_srcs(PREFIX),
|
|
copts = ALL_NEON_COPTS,
|
|
includes = [PREFIX + "include"],
|
|
visibility = ["//visibility:private"],
|
|
alwayslink = 1,
|
|
)
|
|
|
|
cc_library(
|
|
name = "libyuv_sve_impl",
|
|
srcs = libyuv_sve_srcs(PREFIX),
|
|
copts = ALL_SVE_COPTS,
|
|
includes = [PREFIX + "include"],
|
|
visibility = ["//visibility:private"],
|
|
alwayslink = 1,
|
|
)
|
|
|
|
cc_library(
|
|
name = "libyuv_rvv_impl",
|
|
srcs = libyuv_rvv_srcs(PREFIX),
|
|
copts = ALL_RVV_COPTS,
|
|
includes = [PREFIX + "include"],
|
|
visibility = ["//visibility:private"],
|
|
alwayslink = 1,
|
|
)
|
|
|
|
cc_test(
|
|
name = "libyuv_test",
|
|
srcs = libyuv_test_srcs(PREFIX),
|
|
copts = ALL_COPTS + [
|
|
"-Wno-unused-variable",
|
|
],
|
|
visibility = ["//visibility:public"],
|
|
deps = [
|
|
":libyuv",
|
|
"@com_google_googletest//:gtest_main",
|
|
"@com_google_absl//absl/flags:flag",
|
|
"@com_google_absl//absl/flags:parse",
|
|
],
|
|
)
|
|
|
|
cc_library(
|
|
name = "psnr_lib",
|
|
srcs = [PREFIX + "util/psnr.cc"],
|
|
hdrs = [PREFIX + "util/psnr.h"],
|
|
copts = PLATFORM_COPTS,
|
|
visibility = ["//visibility:private"],
|
|
)
|
|
|
|
cc_library(
|
|
name = "ssim_lib",
|
|
srcs = [PREFIX + "util/ssim.cc"],
|
|
hdrs = [PREFIX + "util/ssim.h"],
|
|
visibility = ["//visibility:private"],
|
|
)
|
|
|
|
cc_binary(
|
|
name = "psnr",
|
|
srcs = [PREFIX + "util/psnr_main.cc"],
|
|
copts = PLATFORM_COPTS + [
|
|
"-Wframe-larger-than=64000",
|
|
],
|
|
deps = [
|
|
":libyuv",
|
|
":psnr_lib",
|
|
":ssim_lib",
|
|
],
|
|
)
|
|
|
|
cc_binary(
|
|
name = "i444tonv12_eg",
|
|
srcs = [PREFIX + "util/i444tonv12_eg.cc"],
|
|
visibility = ["//visibility:public"],
|
|
deps = [
|
|
":libyuv",
|
|
],
|
|
)
|
|
|
|
cc_binary(
|
|
name = "cpuid",
|
|
srcs = [PREFIX + "util/cpuid.c"],
|
|
visibility = ["//visibility:public"],
|
|
deps = [
|
|
":libyuv",
|
|
],
|
|
)
|
|
|
|
cc_binary(
|
|
name = "yuvconstants",
|
|
srcs = [PREFIX + "util/yuvconstants.c"],
|
|
visibility = ["//visibility:public"],
|
|
deps = [
|
|
":libyuv",
|
|
],
|
|
)
|
|
|
|
cc_binary(
|
|
name = "yuvconvert",
|
|
srcs = [PREFIX + "util/yuvconvert.cc"],
|
|
visibility = ["//visibility:public"],
|
|
deps = [
|
|
":libyuv",
|
|
],
|
|
)
|