add dec_wasm.c

stub + basic cmake support for targeting native code generation using
portable intrinsics / wasm (WebAssembly). integrating this into the
webp_js path will be left until the implementation is more complete.

Change-Id: I3e751b511f6d671da5ba8afc88ca412f31f097b0
This commit is contained in:
James Zern 2017-06-22 16:22:44 -07:00
parent 3b62347b0f
commit 4b21971337
8 changed files with 76 additions and 7 deletions

View File

@ -4,6 +4,7 @@ project(libwebp C)
# Options for coder / decoder executables. # Options for coder / decoder executables.
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON) option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON)
option(WEBP_ENABLE_WASM "Enable WebAssembly optimizations." OFF)
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF) option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF)
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF) option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF)
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF) option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
@ -13,7 +14,7 @@ option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF) option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF)
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF) option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF)
if(WEBP_BUILD_WEBP_JS) if(WEBP_BUILD_WEBP_JS OR WEBP_ENABLE_WASM)
set(WEBP_ENABLE_SIMD OFF) set(WEBP_ENABLE_SIMD OFF)
endif() endif()
@ -37,6 +38,9 @@ string(REGEX MATCH "[0-9.]+" WEBP_VERSION ${SOURCE_FILE})
if(WEBP_ENABLE_SWAP_16BIT_CSP) if(WEBP_ENABLE_SWAP_16BIT_CSP)
add_definitions(-DWEBP_SWAP_16BIT_CSP) add_definitions(-DWEBP_SWAP_16BIT_CSP)
endif() endif()
if(WEBP_ENABLE_WASM)
add_definitions(-DWEBP_USE_WASM)
endif()
################################################################################ ################################################################################
# Android only. # Android only.
@ -162,9 +166,11 @@ math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE}) foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE) list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG) list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
if(NOT ${SIMD_COMPILE_FLAG} STREQUAL "NOTFOUND")
set_source_files_properties(${FILE} PROPERTIES set_source_files_properties(${FILE} PROPERTIES
COMPILE_FLAGS ${SIMD_COMPILE_FLAG} COMPILE_FLAGS ${SIMD_COMPILE_FLAG}
) )
endif()
endforeach() endforeach()
# Build the executables if asked for. # Build the executables if asked for.

View File

@ -31,6 +31,11 @@ using Emscripten and CMake.
- that's it! Upon completion, you should have the webp.js and - that's it! Upon completion, you should have the webp.js and
webp.js.mem files generated. webp.js.mem files generated.
- Note this generates both webp_js and webp_wasm without any SIMD enabled due
to bugs with this toolchain associated with the SSE2 code.
-DWEBP_ENABLE_WASM is currently meant to generate native (x86, arm)
executables (dwebp, cwebp) and is incompatible with -DWEBP_BUILD_WEBP_JS.
The callable JavaScript function is WebPToSDL(), which decodes a raw WebP The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
bitstream into a canvas. See webp_js/index.html for a simple usage sample. bitstream into a canvas. See webp_js/index.html for a simple usage sample.

View File

@ -116,3 +116,13 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
endif() endif()
endif() endif()
endforeach() endforeach()
## Add *_wasm.c files if enabled.
if(WEBP_ENABLE_WASM)
file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
"src/dsp/*_wasm.c"
)
foreach(FILE ${SIMD_FILES})
list(APPEND WEBP_SIMD_FILES_TO_INCLUDE ${FILE})
endforeach()
endif()

View File

@ -3,6 +3,7 @@ noinst_LTLIBRARIES += libwebpdsp_sse2.la libwebpdspdecode_sse2.la
noinst_LTLIBRARIES += libwebpdsp_sse41.la libwebpdspdecode_sse41.la noinst_LTLIBRARIES += libwebpdsp_sse41.la libwebpdspdecode_sse41.la
noinst_LTLIBRARIES += libwebpdsp_neon.la libwebpdspdecode_neon.la noinst_LTLIBRARIES += libwebpdsp_neon.la libwebpdspdecode_neon.la
noinst_LTLIBRARIES += libwebpdsp_msa.la libwebpdspdecode_msa.la noinst_LTLIBRARIES += libwebpdsp_msa.la libwebpdspdecode_msa.la
noinst_LTLIBRARIES += libwebpdspdecode_wasm.la
if BUILD_LIBWEBPDECODER if BUILD_LIBWEBPDECODER
noinst_LTLIBRARIES += libwebpdspdecode.la noinst_LTLIBRARIES += libwebpdspdecode.la
@ -96,6 +97,10 @@ libwebpdspdecode_msa_la_SOURCES += upsampling_msa.c
libwebpdspdecode_msa_la_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS) libwebpdspdecode_msa_la_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS)
libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS) libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS)
# WASM is not fully integrated into configure; the addition here keeps source
# extraction by cmake simple.
libwebpdspdecode_wasm_la_SOURCES = dec_wasm.c
libwebpdsp_sse2_la_SOURCES = libwebpdsp_sse2_la_SOURCES =
libwebpdsp_sse2_la_SOURCES += argb_sse2.c libwebpdsp_sse2_la_SOURCES += argb_sse2.c
libwebpdsp_sse2_la_SOURCES += cost_sse2.c libwebpdsp_sse2_la_SOURCES += cost_sse2.c

View File

@ -217,6 +217,12 @@ static int mipsCPUInfo(CPUFeature feature) {
} }
VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo; VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo;
#elif defined(WEBP_USE_WASM)
static int wasmCPUInfo(CPUFeature feature) {
if (feature != kWASM) return 0;
return 1;
}
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
#else #else
VP8CPUInfo VP8GetCPUInfo = NULL; VP8CPUInfo VP8GetCPUInfo = NULL;
#endif #endif

View File

@ -700,6 +700,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 VP8DspInitWASM(void);
static volatile VP8CPUInfo dec_last_cpuinfo_used = static volatile VP8CPUInfo dec_last_cpuinfo_used =
(VP8CPUInfo)&dec_last_cpuinfo_used; (VP8CPUInfo)&dec_last_cpuinfo_used;
@ -789,6 +790,11 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
if (VP8GetCPUInfo(kMSA)) { if (VP8GetCPUInfo(kMSA)) {
VP8DspInitMSA(); VP8DspInitMSA();
} }
#endif
#if defined(WEBP_USE_WASM)
if (VP8GetCPUInfo(kWASM)) {
VP8DspInitWASM();
}
#endif #endif
} }
dec_last_cpuinfo_used = VP8GetCPUInfo; dec_last_cpuinfo_used = VP8GetCPUInfo;

29
src/dsp/dec_wasm.c Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2017 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.
//
#include "./dsp.h"
#if defined(WEBP_USE_WASM)
//------------------------------------------------------------------------------
// Entry point
extern void VP8DspInitWASM(void);
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitWASM(void) {
}
#else // !WEBP_USE_WASM
WEBP_DSP_INIT_STUB(VP8DspInitWASM)
#endif // WEBP_USE_WASM

View File

@ -42,8 +42,9 @@ 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 // For now, none of the optimizations below are available in emscripten.
#if !defined(EMSCRIPTEN) // WebAssembly overrides native optimizations.
#if !(defined(EMSCRIPTEN) || defined(WEBP_USE_WASM))
#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))
@ -144,7 +145,8 @@ typedef enum {
kNEON, kNEON,
kMIPS32, kMIPS32,
kMIPSdspR2, kMIPSdspR2,
kMSA kMSA,
kWASM
} 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);