mirror of
https://github.com/webmproject/libwebp.git
synced 2025-04-21 08:16:46 +02:00
Add preliminary support of targeting Wasm
This builds on the work on portable-intrinsics branch: - define WEBP_ENABLE_WASM_SIMD to enable WebAssembly optimizations, this defines a constant (WEBP_USE_WASM_SIMD) that we can use in the future to enable Wasm SIMD intrinsics - build dwebp with JS build - add a placeholder dec_wasm.c file, we don't do any special initialization so it will fall back to c functions - add Wasm to cpu checks, it needs to come before all checks since the Emscripten toolchain will emulate x86 systems Change-Id: I12de720304ff19fff82c8d100defbc60353787a9
This commit is contained in:
parent
6b1d18c362
commit
ed665a15e8
@ -22,6 +22,9 @@ if(NOT EMSCRIPTEN)
|
|||||||
endif()
|
endif()
|
||||||
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
|
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
|
||||||
${WEBP_ENABLE_SIMD_DEFAULT})
|
${WEBP_ENABLE_SIMD_DEFAULT})
|
||||||
|
# Emscripten supports SSE builds using its compatibility headers, by default it
|
||||||
|
# will use SSE4 if WEBP_ENABLE_WASM_SIMD is OFF and WEBP_ENABLE_SIMD is ON.
|
||||||
|
option(WEBP_ENABLE_WASM_SIMD "Enable WebAssembly SIMD optimizations" OFF)
|
||||||
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)
|
||||||
@ -48,7 +51,6 @@ endif()
|
|||||||
if(WEBP_BUILD_WEBP_JS)
|
if(WEBP_BUILD_WEBP_JS)
|
||||||
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_GIF2WEBP OFF)
|
set(WEBP_BUILD_GIF2WEBP OFF)
|
||||||
set(WEBP_BUILD_IMG2WEBP OFF)
|
set(WEBP_BUILD_IMG2WEBP OFF)
|
||||||
set(WEBP_BUILD_VWEBP OFF)
|
set(WEBP_BUILD_VWEBP OFF)
|
||||||
@ -80,6 +82,9 @@ include(GNUInstallDirs)
|
|||||||
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
||||||
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
||||||
endif()
|
endif()
|
||||||
|
if(WEBP_ENABLE_WASM_SIMD)
|
||||||
|
add_definitions(-DWEBP_ENABLE_WASM_SIMD)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT WEBP_BITTRACE STREQUAL "0")
|
if(NOT WEBP_BITTRACE STREQUAL "0")
|
||||||
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
|
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
|
||||||
|
@ -108,6 +108,9 @@
|
|||||||
/* Set to 1 if JPEG library is installed */
|
/* Set to 1 if JPEG library is installed */
|
||||||
#cmakedefine WEBP_HAVE_JPEG 1
|
#cmakedefine WEBP_HAVE_JPEG 1
|
||||||
|
|
||||||
|
/* Set to 1 if Wasm SIMD is supported */
|
||||||
|
#cmakedefine WEBP_HAVE_WASM_SIMD
|
||||||
|
|
||||||
/* Set to 1 if NEON is supported */
|
/* Set to 1 if NEON is supported */
|
||||||
#cmakedefine WEBP_HAVE_NEON
|
#cmakedefine WEBP_HAVE_NEON
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# those are included in the names of WEBP_USE_* in c++ code.
|
# those are included in the names of WEBP_USE_* in c++ code.
|
||||||
set(WEBP_SIMD_FLAGS "SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
set(WEBP_SIMD_FLAGS "WASM_SIMD;SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
||||||
set(WEBP_SIMD_FILE_EXTENSIONS
|
set(WEBP_SIMD_FILE_EXTENSIONS
|
||||||
"_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
"_wasm.c;_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
||||||
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||||
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
|
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
|
||||||
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
|
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
|
||||||
@ -53,9 +53,9 @@ if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
|||||||
set(SIMD_DISABLE_FLAGS)
|
set(SIMD_DISABLE_FLAGS)
|
||||||
else()
|
else()
|
||||||
set(SIMD_ENABLE_FLAGS
|
set(SIMD_ENABLE_FLAGS
|
||||||
"-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
"-msimd128;-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
||||||
set(SIMD_DISABLE_FLAGS
|
set(SIMD_DISABLE_FLAGS
|
||||||
"-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
|
"-mno-simd128;-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
|
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
|
||||||
@ -77,7 +77,12 @@ math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
|
|||||||
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||||
# With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
|
# With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
|
||||||
# source will fail to compile.
|
# source will fail to compile.
|
||||||
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
|
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 5)
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
# Emscripten supports SSE via compat headers, if WEBP_ENABLED_WASM_SIMD is
|
||||||
|
# specified skip testing those (because it will succeed).
|
||||||
|
if (EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 1 AND ${WEBP_ENABLE_WASM_SIMD})
|
||||||
break()
|
break()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -91,6 +96,7 @@ 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)
|
||||||
|
# This enables using Emscripten's SSE compatibility headers.
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
|
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -13,6 +13,7 @@ noinst_LTLIBRARIES += libwebpdsp_mips32.la
|
|||||||
noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
|
noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
|
||||||
noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
|
noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
|
noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
|
||||||
|
noinst_LTLIBRARIES += libwebpdspdecode_wasm.la
|
||||||
|
|
||||||
if BUILD_LIBWEBPDECODER
|
if BUILD_LIBWEBPDECODER
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode.la
|
noinst_LTLIBRARIES += libwebpdspdecode.la
|
||||||
@ -106,6 +107,8 @@ libwebpdspdecode_mips_dsp_r2_la_SOURCES += yuv_mips_dsp_r2.c
|
|||||||
libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS)
|
libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS)
|
||||||
libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
|
libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
|
||||||
|
|
||||||
|
libwebpdspdecode_wasm_la_SOURCES = dec_wasm.c
|
||||||
|
|
||||||
libwebpdsp_sse2_la_SOURCES =
|
libwebpdsp_sse2_la_SOURCES =
|
||||||
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
||||||
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
||||||
|
@ -26,8 +26,10 @@
|
|||||||
// SSE2 detection.
|
// SSE2 detection.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Skip SSE detection if using Wasm SIMD build.
|
||||||
|
#if defined(WEBP_USE_WASM_SIMD)
|
||||||
// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
|
// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
|
||||||
#if (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
#elif (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
||||||
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"mov %%ebx, %%edi\n"
|
"mov %%ebx, %%edi\n"
|
||||||
@ -69,8 +71,10 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Skip xgetbv definition if using Wasm SIMD build.
|
||||||
|
#if defined(WEBP_USE_WASM_SIMD)
|
||||||
// NaCl has no support for xgetbv or the raw opcode.
|
// NaCl has no support for xgetbv or the raw opcode.
|
||||||
#if !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
#elif !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
static WEBP_INLINE uint64_t xgetbv(void) {
|
static WEBP_INLINE uint64_t xgetbv(void) {
|
||||||
const uint32_t ecx = 0;
|
const uint32_t ecx = 0;
|
||||||
uint32_t eax, edx;
|
uint32_t eax, edx;
|
||||||
@ -100,7 +104,13 @@ static WEBP_INLINE uint64_t xgetbv(void) {
|
|||||||
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
|
#if defined(WEBP_USE_WASM_SIMD)
|
||||||
|
static int wasmCPUInfo(CPUFeature feature) {
|
||||||
|
if (feature != kWasmSIMD) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
||||||
|
#elif defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
|
||||||
|
|
||||||
// helper function for run-time detection of slow SSSE3 platforms
|
// helper function for run-time detection of slow SSSE3 platforms
|
||||||
static int CheckSlowModel(int info) {
|
static int CheckSlowModel(int info) {
|
||||||
|
@ -740,6 +740,7 @@ extern void VP8DspInitNEON(void);
|
|||||||
extern void VP8DspInitMIPS32(void);
|
extern void VP8DspInitMIPS32(void);
|
||||||
extern void VP8DspInitMIPSdspR2(void);
|
extern void VP8DspInitMIPSdspR2(void);
|
||||||
extern void VP8DspInitMSA(void);
|
extern void VP8DspInitMSA(void);
|
||||||
|
extern void VP8DspInitWasmSIMD(void);
|
||||||
|
|
||||||
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||||
VP8InitClipTables();
|
VP8InitClipTables();
|
||||||
@ -831,6 +832,11 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
|||||||
if (VP8GetCPUInfo(kMSA)) {
|
if (VP8GetCPUInfo(kMSA)) {
|
||||||
VP8DspInitMSA();
|
VP8DspInitMSA();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(WEBP_USE_WASM_SIMD)
|
||||||
|
if (VP8GetCPUInfo(kWasmSIMD)) {
|
||||||
|
VP8DspInitWasmSIMD();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
src/dsp/dec_wasm.c
Normal file
32
src/dsp/dec_wasm.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2021 Google Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license
|
||||||
|
// that can be found in the COPYING file in the root of the source
|
||||||
|
// tree. An additional intellectual property rights grant can be found
|
||||||
|
// in the file PATENTS. All contributing project authors may
|
||||||
|
// be found in the AUTHORS file in the root of the source tree.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// WebAssembly (Wasm) version of some decoding functions.
|
||||||
|
//
|
||||||
|
// This will contain Wasm implementation of some decoding functions.
|
||||||
|
|
||||||
|
#include "./dsp.h"
|
||||||
|
|
||||||
|
#if defined(WEBP_USE_WASM_SIMD)
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Entry point
|
||||||
|
|
||||||
|
extern void VP8DspInitWasmSIMD(void);
|
||||||
|
|
||||||
|
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitWasmSIMD(void) {
|
||||||
|
// TODO(crbug.com/v8/12371): No special implementation for Wasm yet, will be
|
||||||
|
// added later.
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
WEBP_DSP_INIT_STUB(VP8DspInitWasmSIMD)
|
||||||
|
|
||||||
|
#endif // WEBP_USE_WASM_SIMD
|
@ -80,6 +80,11 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined(EMSCRIPTEN) || defined(WEBP_HAVE_WASM_SIMD)) && \
|
||||||
|
defined(__wasm_simd128__) && defined(WEBP_ENABLE_WASM_SIMD)
|
||||||
|
#define WEBP_USE_WASM_SIMD
|
||||||
|
#endif
|
||||||
|
|
||||||
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
||||||
// files without intrinsics, allowing the corresponding Init() to be called.
|
// files without intrinsics, allowing the corresponding Init() to be called.
|
||||||
// Files containing intrinsics will need to be built targeting the instruction
|
// Files containing intrinsics will need to be built targeting the instruction
|
||||||
@ -257,7 +262,8 @@ typedef enum {
|
|||||||
kNEON,
|
kNEON,
|
||||||
kMIPS32,
|
kMIPS32,
|
||||||
kMIPSdspR2,
|
kMIPSdspR2,
|
||||||
kMSA
|
kMSA,
|
||||||
|
kWasmSIMD
|
||||||
} CPUFeature;
|
} CPUFeature;
|
||||||
// returns true if the CPU supports the feature.
|
// returns true if the CPU supports the feature.
|
||||||
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user