-
Notifications
You must be signed in to change notification settings - Fork 621
Description
Summary
Enable AVX2 SIMD optimizations in libwebp for improved WebP encoding/decoding performance on modern x86/x64 CPUs.
Background
libwebp 1.6.0 added AVX2 optimizations in two new source files:
src/dsp/lossless_avx2.csrc/dsp/lossless_enc_avx2.c
Upstream commit: webmproject/libwebp@f2b3f527
During the libwebp 1.3.2 → 1.6.0 update (#3461), we had to disable AVX2 to fix Windows build failures. This issue tracks re-enabling it properly.
Current Workaround
We disabled AVX2 using -mno-avx2 compiler flag in third_party/libwebp/BUILD.gn:
config("libwebp_no_avx2") {
if (current_cpu == "x86" || current_cpu == "x64") {
cflags = [ "-mno-avx2" ]
}
}This prevents the compiler from defining __AVX2__, which would otherwise trigger AVX2 code paths.
Why Windows Failed (and others did not)
The AVX2 code path is enabled via preprocessor macros in src/dsp/cpu.h:
// Lines 59-62: MSVC-compatible compilers trigger this
#if defined(_MSC_VER) && _MSC_VER >= 1700 && \
(defined(_M_X64) || defined(_M_IX86))
#define WEBP_MSC_AVX2
#endif
// Lines 88-95: This enables the AVX2 code path
#if (defined(__AVX2__) || defined(WEBP_MSC_AVX2)) && \
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_AVX2))
#define WEBP_USE_AVX2
#endifWhy Windows fails: SkiaSharp uses clang-cl on Windows, which defines _MSC_VER for MSVC compatibility. This triggers WEBP_MSC_AVX2 → WEBP_HAVE_AVX2, causing lossless.c and lossless_enc.c to call VP8LDspInitAVX2() and VP8LEncDspInitAVX2(). But these functions are defined in the AVX2 source files which are not compiled → linker error.
Why macOS/Linux x64 works: Native Clang/GCC does not define _MSC_VER, and does not define __AVX2__ by default, so AVX2 is not enabled.
Why ARM works: AVX2 is an x86 instruction set, ARM platforms have no AVX2 code paths.
How to Enable AVX2
Add a new AVX2 target following the existing SSE4.1 pattern:
third_party("libwebp_avx2") {
public_include_dirs = [
"../externals/libwebp/src",
"../externals/libwebp",
]
configs = [ ":libwebp_defines" ]
sources = [
"../externals/libwebp/src/dsp/lossless_avx2.c",
"../externals/libwebp/src/dsp/lossless_enc_avx2.c",
]
# Enable AVX2 compilation on x86/x64
if (current_cpu == "x86" || current_cpu == "x64") {
if (is_win && !is_clang) {
# MSVC
cflags_c = [ "/arch:AVX2" ]
} else {
# Clang (macOS, Linux, Windows clang-cl)
cflags_c = [ "-mavx2" ]
}
}
}
third_party("libwebp") {
# ...
deps = [ ":libwebp_sse41", ":libwebp_avx2" ] # Add AVX2 dependency
# ...
}Then remove the config("libwebp_no_avx2") workaround.
Compiler Flags Summary
| Platform | Compiler | Flag to enable AVX2 |
|---|---|---|
| Windows (MSVC) | cl.exe | /arch:AVX2 |
| Windows (clang-cl) | clang-cl | -mavx2 |
| macOS | clang | -mavx2 |
| Linux | clang/gcc | -mavx2 |
Safety: Runtime CPU Detection
libwebp has runtime CPU detection - the AVX2 code only runs on CPUs that support it:
// src/dsp/lossless.c lines 658-661
#if defined(WEBP_HAVE_AVX2)
if (VP8GetCPUInfo(kAVX2)) { // Runtime check!
VP8LDspInitAVX2();
}
#endifSo even on older CPUs without AVX2 support, the code safely falls back to SSE/C implementations.
What AVX2 Does
AVX2 (Advanced Vector Extensions 2) is a SIMD instruction set that processes 256 bits at once (vs 128 bits for SSE). This provides faster:
- Lossless WebP encoding
- Lossless WebP decoding
- Color space conversions
Available on: Intel Haswell (2013+), AMD Excavator (2015+), and newer CPUs.
Files to Modify
externals/skia/third_party/libwebp/BUILD.gn- Add AVX2 target, remove-mno-avx2workaround
References
- libwebp AVX2 commit - Original upstream commit adding AVX2 support
- libwebp 1.6.0 release
- PR #3461 - libwebp 1.6.0 update
Metadata
Metadata
Assignees
Labels
Type
Projects
Status