ref: 707b65bd160766f22d82c2c9b3dfc74955c3e2df
parent: 2056f7e0d8d3fc4fd05e53d199dc15b8779bcb64
author: Christian Duvivier <cduvivier@google.com>
date: Wed Aug 8 11:47:36 EDT 2012
Partial import of "New RTCD implementation" from master branch. Latest version of all scripts/makefile but rtcd_defs.sh is empty, all existing functions are still selected using the old/current way. Change-Id: Ib92946a48a31d6c8d1d7359eca524bc1d3e66174
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -389,6 +389,7 @@
ASFLAGS = ${ASFLAGS} extralibs = ${extralibs} AS_SFX = ${AS_SFX:-.asm}+RTCD_OPTIONS = ${RTCD_OPTIONS}EOF
if enabled rvct; then cat >> $1 << EOF
@@ -451,8 +452,20 @@
;;
--enable-?*|--disable-?*)
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
- echo "${CMDLINE_SELECT} ${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null || die_unknown $opt- $action $option
+ if echo "${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null; then+ [ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "+ else
+ echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||+ die_unknown $opt
+ fi $action $option
+ ;;
+ --require-?*)
+ eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
+ if echo "${ARCH_EXT_LIST}" none | grep "^ *$option\$" >/dev/null; then+ RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "+ else
+ die_unknown $opt
+ fi
;;
--force-enable-?*|--force-disable-?*)
eval `echo "$opt" | sed 's/--force-/action=/;s/-/ option=/;s/-/_/g'`
--- /dev/null
+++ b/build/make/rtcd.sh
@@ -1,0 +1,356 @@
+#!/bin/sh
+self=$0
+
+usage() {+ cat <<EOF >&2
+Usage: $self [options] FILE
+
+Reads the Run Time CPU Detections definitions from FILE and generates a
+C header file on stdout.
+
+Options:
+ --arch=ARCH Architecture to generate defs for (required)
+ --disable-EXT Disable support for EXT extensions
+ --require-EXT Require support for EXT extensions
+ --sym=SYMBOL Unique symbol to use for RTCD initialization function
+ --config=FILE File with CONFIG_FOO=yes lines to parse
+EOF
+ exit 1
+}
+
+die() {+ echo "$@" >&2
+ exit 1
+}
+
+die_argument_required() {+ die "Option $opt requires argument"
+}
+
+for opt; do
+ optval="${opt#*=}"+ case "$opt" in
+ --arch) die_argument_required;;
+ --arch=*) arch=${optval};;+ --disable-*) eval "disable_${opt#--disable-}=true";;+ --require-*) REQUIRES="${REQUIRES}${opt#--require-} ";;+ --sym) die_argument_required;;
+ --sym=*) symbol=${optval};;+ --config=*) config_file=${optval};;+ -h|--help)
+ usage
+ ;;
+ -*)
+ die "Unrecognized option: ${opt%%=*}"+ ;;
+ *)
+ defs_file="$defs_file $opt"
+ ;;
+ esac
+ shift
+done
+for f in $defs_file; do [ -f "$f" ] || usage; done
+[ -n "$arch" ] || usage
+
+# Import the configuration
+[ -f "$config_file" ] && eval $(grep CONFIG_ "$config_file")
+
+#
+# Routines for the RTCD DSL to call
+#
+prototype() {+ local rtyp
+ case "$1" in
+ unsigned) rtyp="$1 "; shift;;
+ esac
+ rtyp="${rtyp}$1"+ local fn="$2"
+ local args="$3"
+
+ eval "${2}_rtyp='$rtyp'"+ eval "${2}_args='$3'"+ ALL_FUNCS="$ALL_FUNCS $fn"
+ specialize $fn c
+}
+
+specialize() {+ local fn="$1"
+ shift
+ for opt in "$@"; do
+ eval "${fn}_${opt}=${fn}_${opt}"+ done
+}
+
+require() {+ for fn in $ALL_FUNCS; do
+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")+ [ -z "$ofn" ] && continue
+
+ # if we already have a default, then we can disable it, as we know
+ # we can do better.
+ local best=$(eval "echo \$${fn}_default")+ local best_ofn=$(eval "echo \$${best}")+ [ -n "$best" ] && [ "$best_ofn" != "$ofn" ] && eval "${best}_link=false"+ eval "${fn}_default=${fn}_${opt}"+ eval "${fn}_${opt}_link=true"+ done
+ done
+}
+
+forward_decls() {+ ALL_FORWARD_DECLS="$ALL_FORWARD_DECLS $1"
+}
+
+#
+# Include the user's directives
+#
+for f in $defs_file; do
+ . $f
+done
+
+#
+# Process the directives according to the command line
+#
+process_forward_decls() {+ for fn in $ALL_FORWARD_DECLS; do
+ eval $fn
+ done
+}
+
+determine_indirection() {+ [ "$CONFIG_RUNTIME_CPU_DETECT" = "yes" ] || require $ALL_ARCHS
+ for fn in $ALL_FUNCS; do
+ local n=""
+ local rtyp="$(eval "echo \$${fn}_rtyp")"+ local args="$(eval "echo \"\$${fn}_args\"")"+ local dfn="$(eval "echo \$${fn}_default")"+ dfn=$(eval "echo \$${dfn}")+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")+ [ -z "$ofn" ] && continue
+ local link=$(eval "echo \$${fn}_${opt}_link")+ [ "$link" = "false" ] && continue
+ n="${n}x"+ done
+ if [ "$n" = "x" ]; then
+ eval "${fn}_indirect=false"+ else
+ eval "${fn}_indirect=true"+ fi
+ done
+}
+
+declare_function_pointers() {+ for fn in $ALL_FUNCS; do
+ local rtyp="$(eval "echo \$${fn}_rtyp")"+ local args="$(eval "echo \"\$${fn}_args\"")"+ local dfn="$(eval "echo \$${fn}_default")"+ dfn=$(eval "echo \$${dfn}")+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")+ [ -z "$ofn" ] && continue
+ echo "$rtyp ${ofn}($args);"+ done
+ if [ "$(eval "echo \$${fn}_indirect")" = "false" ]; then+ echo "#define ${fn} ${dfn}"+ else
+ echo "RTCD_EXTERN $rtyp (*${fn})($args);"+ fi
+ echo
+ done
+}
+
+set_function_pointers() {+ for fn in $ALL_FUNCS; do
+ local n=""
+ local rtyp="$(eval "echo \$${fn}_rtyp")"+ local args="$(eval "echo \"\$${fn}_args\"")"+ local dfn="$(eval "echo \$${fn}_default")"+ dfn=$(eval "echo \$${dfn}")+ if $(eval "echo \$${fn}_indirect"); then+ echo " $fn = $dfn;"
+ for opt in "$@"; do
+ local ofn=$(eval "echo \$${fn}_${opt}")+ [ -z "$ofn" ] && continue
+ [ "$ofn" = "$dfn" ] && continue;
+ local link=$(eval "echo \$${fn}_${opt}_link")+ [ "$link" = "false" ] && continue
+ local cond="$(eval "echo \$have_${opt}")"+ echo " if (${cond}) $fn = $ofn;"+ done
+ fi
+ echo
+ done
+}
+
+filter() {+ local filtered
+ for opt in "$@"; do
+ [ -z $(eval "echo \$disable_${opt}") ] && filtered="$filtered $opt"+ done
+ echo $filtered
+}
+
+#
+# Helper functions for generating the arch specific RTCD files
+#
+common_top() {+ local outfile_basename=$(basename ${symbol:-rtcd.h})+ local include_guard=$(echo $outfile_basename | tr '[a-z]' '[A-Z]' | tr -c '[A-Z]' _)
+ cat <<EOF
+#ifndef ${include_guard}+#define ${include_guard}+
+#ifdef RTCD_C
+#define RTCD_EXTERN
+#else
+#define RTCD_EXTERN extern
+#endif
+
+$(process_forward_decls)
+
+$(declare_function_pointers c $ALL_ARCHS)
+
+void ${symbol:-rtcd}(void);+EOF
+}
+
+common_bottom() {+ cat <<EOF
+#endif
+EOF
+}
+
+x86() {+ determine_indirection c $ALL_ARCHS
+
+ # Assign the helper variable for each enabled extension
+ for opt in $ALL_ARCHS; do
+ local uc=$(echo $opt | tr '[a-z]' '[A-Z]')
+ eval "have_${opt}=\"flags & HAS_${uc}\""+ done
+
+ cat <<EOF
+$(common_top)
+
+#ifdef RTCD_C
+#include "vpx_ports/x86.h"
+static void setup_rtcd_internal(void)
+{+ int flags = x86_simd_caps();
+
+ (void)flags;
+
+$(set_function_pointers c $ALL_ARCHS)
+}
+#endif
+$(common_bottom)
+EOF
+}
+
+arm() {+ determine_indirection c $ALL_ARCHS
+
+ # Assign the helper variable for each enabled extension
+ for opt in $ALL_ARCHS; do
+ local uc=$(echo $opt | tr '[a-z]' '[A-Z]')
+ eval "have_${opt}=\"flags & HAS_${uc}\""+ done
+
+ cat <<EOF
+$(common_top)
+#include "vpx_config.h"
+
+#ifdef RTCD_C
+#include "vpx_ports/arm.h"
+static void setup_rtcd_internal(void)
+{+ int flags = arm_cpu_caps();
+
+ (void)flags;
+
+$(set_function_pointers c $ALL_ARCHS)
+}
+#endif
+$(common_bottom)
+EOF
+}
+
+
+mips() {+ determine_indirection c $ALL_ARCHS
+ cat <<EOF
+$(common_top)
+#include "vpx_config.h"
+
+#ifdef RTCD_C
+static void setup_rtcd_internal(void)
+{+$(set_function_pointers c $ALL_ARCHS)
+#if HAVE_DSPR2
+void dsputil_static_init();
+dsputil_static_init();
+#endif
+}
+#endif
+$(common_bottom)
+EOF
+}
+
+unoptimized() {+ determine_indirection c
+ cat <<EOF
+$(common_top)
+#include "vpx_config.h"
+
+#ifdef RTCD_C
+static void setup_rtcd_internal(void)
+{+$(set_function_pointers c)
+}
+#endif
+$(common_bottom)
+EOF
+
+}
+#
+# Main Driver
+#
+require c
+case $arch in
+ x86)
+ ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1)
+ x86
+ ;;
+ x86_64)
+ ALL_ARCHS=$(filter mmx sse sse2 sse3 ssse3 sse4_1)
+ REQUIRES=${REQUIRES:-mmx sse sse2}+ require $(filter $REQUIRES)
+ x86
+ ;;
+ mips32)
+ ALL_ARCHS=$(filter mips32)
+ dspr2=$([ -f "$config_file" ] && eval echo $(grep HAVE_DSPR2 "$config_file"))
+ HAVE_DSPR2="${dspr2#*=}"+ if [ "$HAVE_DSPR2" = "yes" ]; then
+ ALL_ARCHS=$(filter mips32 dspr2)
+ fi
+ mips
+ ;;
+ armv5te)
+ ALL_ARCHS=$(filter edsp)
+ arm
+ ;;
+ armv6)
+ ALL_ARCHS=$(filter edsp media)
+ arm
+ ;;
+ armv7)
+ ALL_ARCHS=$(filter edsp media neon)
+ arm
+ ;;
+ *)
+ unoptimized
+ ;;
+esac
--- a/libs.mk
+++ b/libs.mk
@@ -91,6 +91,7 @@
$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_LIBVPX,BUILD_LIBVPX):=yes)
CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh
+CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.sh
CODEC_SRCS-$(BUILD_LIBVPX) += vpx/vpx_integer.h
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/asm_offsets.h
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/vpx_timer.h
@@ -185,6 +186,7 @@
PROJECTS-$(BUILD_LIBVPX) += vpx.vcproj
vpx.vcproj: vpx_config.asm
+vpx.vcproj: vpx_rtcd.h
endif
else
@@ -350,6 +352,18 @@
$(shell $(SRC_PATH_BARE)/build/make/version.sh "$(SRC_PATH_BARE)" $(BUILD_PFX)vpx_version.h)
CLEAN-OBJS += $(BUILD_PFX)vpx_version.h
+
+#
+# Rule to generate runtime cpu detection files
+#
+$(OBJS-yes:.o=.d): vpx_rtcd.h
+vpx_rtcd.h: $(sort $(filter %rtcd_defs.sh,$(CODEC_SRCS)))
+ @echo " [CREATE] $@"
+ $(qexec)$(SRC_PATH_BARE)/build/make/rtcd.sh --arch=$(TGT_ISA) \
+ --sym=vpx_rtcd \
+ --config=$(target)$(if $(FAT_ARCHS),,-$(TOOLCHAIN)).mk \
+ $(RTCD_OPTIONS) $^ > $@
+CLEAN-OBJS += $(BUILD_PFX)vpx_rtcd.h
CODEC_DOC_SRCS += vpx/vpx_codec.h \
vpx/vpx_decoder.h \
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -10,6 +10,7 @@
#include "vpx_ports/config.h"
+#include "vpx_rtcd.h"
#include "vp8/common/g_common.h"
#include "vp8/common/subpixel.h"
#include "vp8/common/loopfilter.h"
@@ -140,4 +141,6 @@
#if ARCH_ARM
vp8_arch_arm_common_init(ctx);
#endif
+
+ vpx_rtcd();
}
--- /dev/null
+++ b/vp8/common/rtcd.c
@@ -1,0 +1,69 @@
+/*
+ * Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE 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.
+ */
+#include "vpx_config.h"
+#define RTCD_C
+#include "vpx_rtcd.h"
+
+#if CONFIG_MULTITHREAD && HAVE_PTHREAD_H
+#include <pthread.h>
+static void once(void (*func)(void))
+{+ static pthread_once_t lock = PTHREAD_ONCE_INIT;
+ pthread_once(&lock, func);
+}
+
+
+#elif CONFIG_MULTITHREAD && defined(_WIN32)
+#include <windows.h>
+static void once(void (*func)(void))
+{+ /* Using a static initializer here rather than InitializeCriticalSection()
+ * since there's no race-free context in which to execute it. Protecting
+ * it with an atomic op like InterlockedCompareExchangePointer introduces
+ * an x86 dependency, and InitOnceExecuteOnce requires Vista.
+ */
+ static CRITICAL_SECTION lock = {(void *)-1, -1, 0, 0, 0, 0};+ static int done;
+
+ EnterCriticalSection(&lock);
+
+ if (!done)
+ {+ func();
+ done = 1;
+ }
+
+ LeaveCriticalSection(&lock);
+}
+
+
+#else
+/* No-op version that performs no synchronization. vpx_rtcd() is idempotent,
+ * so as long as your platform provides atomic loads/stores of pointers
+ * no synchronization is strictly necessary.
+ */
+
+static void once(void (*func)(void))
+{+ static int done;
+
+ if(!done)
+ {+ func();
+ done = 1;
+ }
+}
+#endif
+
+
+void vpx_rtcd()
+{+ once(setup_rtcd_internal);
+}
--- /dev/null
+++ b/vp8/common/rtcd_defs.sh
@@ -1,0 +1,6 @@
+common_forward_decls() {+cat <<EOF
+struct blockd;
+EOF
+}
+forward_decls common_forward_decls
--- a/vp8/vp8_common.mk
+++ b/vp8/vp8_common.mk
@@ -52,6 +52,8 @@
VP8_COMMON_SRCS-yes += common/reconinter.h
VP8_COMMON_SRCS-yes += common/reconintra.h
VP8_COMMON_SRCS-yes += common/reconintra4x4.h
+VP8_COMMON_SRCS-yes += common/rtcd.c
+VP8_COMMON_SRCS-yes += common/rtcd_defs.sh
VP8_COMMON_SRCS-yes += common/seg_common.h
VP8_COMMON_SRCS-yes += common/seg_common.c
VP8_COMMON_SRCS-yes += common/setupintrarecon.h
--
⑨