Couple of fixes to allow SIMD on Emscripten

- Add `-msimd128` to flags to actually enable WebAssembly SIMD
   when performing SIMD detection. It's currently required in
   addition to `-msse*` / `-mfpu=neon` flags which only perform
   translation of corresponding intrinsics to Wasm SIMD ones.
   See a discussion at emscripten-core/emscripten#12714 for
   automating this and making easier in the future.
 - Remove compilation branch that prevented definitions of
   `WEBP_USE_SSE` and `WEBP_USE_NEON` on Emscripten even when
   SIMD support was detected at compile-time.
 - Add an implementation of `VP8GetCPUInfo` for Emscripten which
   uses static `WEBP_USE_*` flags to determine if a corresponding
   SIMD instruction is supported. This is because Wasm doesn't
   have proper feature detection (yet) and requires making separate
   build for SIMD version anyway.

Change-Id: I77592081b91fd0e4cbc9242f5600ce905184f506
This commit is contained in:
Ingvar Stepanyan 2020-11-11 17:46:17 +00:00 committed by Pascal Massimino
parent 17fd4ba820
commit 52273943c6
4 changed files with 34 additions and 7 deletions

View File

@ -3,7 +3,13 @@ cmake_minimum_required(VERSION 3.5)
project(WebP C) project(WebP C)
# Options for coder / decoder executables. # Options for coder / decoder executables.
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON) if(NOT EMSCRIPTEN)
# Disable SIMD on Emscripten by default, as it's a new unstable Wasm feature.
# Users can still explicitly opt-in to make a SIMD-enabled build.
set(WEBP_ENABLE_SIMD_DEFAULT ON)
endif()
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
${WEBP_ENABLE_SIMD_DEFAULT})
option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON) option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON) option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON)
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON) option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON)
@ -26,7 +32,6 @@ if(WIN32)
endif() endif()
if(WEBP_BUILD_WEBP_JS) if(WEBP_BUILD_WEBP_JS)
set(WEBP_ENABLE_SIMD OFF)
set(WEBP_BUILD_ANIM_UTILS OFF) set(WEBP_BUILD_ANIM_UTILS OFF)
set(WEBP_BUILD_CWEBP OFF) set(WEBP_BUILD_CWEBP OFF)
set(WEBP_BUILD_DWEBP OFF) set(WEBP_BUILD_DWEBP OFF)

View File

@ -70,6 +70,9 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD}) webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG}) if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG) list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
if(EMSCRIPTEN)
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
endif()
set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG}) set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD}) webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
else() else()

View File

@ -179,6 +179,30 @@ static int AndroidCPUInfo(CPUFeature feature) {
return 0; return 0;
} }
VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo; VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
#elif defined(EMSCRIPTEN) // also needs to be before generic NEON test
// Use compile flags as an indicator of SIMD support instead of a runtime check.
static int wasmCPUInfo(CPUFeature feature) {
switch (feature) {
#ifdef WEBP_USE_SSE2
case kSSE2:
return 1;
#endif
#ifdef WEBP_USE_SSE41
case kSSE3:
case kSlowSSSE3:
case kSSE4_1:
return 1;
#endif
#ifdef WEBP_USE_NEON
case kNEON:
return 1;
#endif
default:
break;
}
return 0;
}
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
#elif defined(WEBP_USE_NEON) #elif defined(WEBP_USE_NEON)
// define a dummy function to enable turning off NEON at runtime by setting // define a dummy function to enable turning off NEON at runtime by setting
// VP8DecGetCPUInfo = NULL // VP8DecGetCPUInfo = NULL

View File

@ -51,9 +51,6 @@ extern "C" {
# define __has_builtin(x) 0 # define __has_builtin(x) 0
#endif #endif
// for now, none of the optimizations below are available in emscripten
#if !defined(EMSCRIPTEN)
#if defined(_MSC_VER) && _MSC_VER > 1310 && \ #if defined(_MSC_VER) && _MSC_VER > 1310 && \
(defined(_M_X64) || defined(_M_IX86)) (defined(_M_X64) || defined(_M_IX86))
#define WEBP_MSC_SSE2 // Visual C++ SSE2 targets #define WEBP_MSC_SSE2 // Visual C++ SSE2 targets
@ -110,8 +107,6 @@ extern "C" {
#define WEBP_USE_MSA #define WEBP_USE_MSA
#endif #endif
#endif /* EMSCRIPTEN */
#ifndef WEBP_DSP_OMIT_C_CODE #ifndef WEBP_DSP_OMIT_C_CODE
#define WEBP_DSP_OMIT_C_CODE 1 #define WEBP_DSP_OMIT_C_CODE 1
#endif #endif