From: Christian Duvivier Date: Wed, 8 Aug 2012 22:47:36 +0000 (-0700) Subject: Partial import of "New RTCD implementation" from master branch. X-Git-Tag: v1.3.0~1217^2~327^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=707b65bd160766f22d82c2c9b3dfc74955c3e2df;p=libvpx 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 --- diff --git a/build/make/configure.sh b/build/make/configure.sh index 552f8c188..be3477823 100755 --- a/build/make/configure.sh +++ b/build/make/configure.sh @@ -389,6 +389,7 @@ LDFLAGS = ${LDFLAGS} 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 @@ process_common_cmdline() { ;; --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'` diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh new file mode 100755 index 000000000..ddf9e09a4 --- /dev/null +++ b/build/make/rtcd.sh @@ -0,0 +1,356 @@ +#!/bin/sh +self=$0 + +usage() { + cat <&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 < $@ +CLEAN-OBJS += $(BUILD_PFX)vpx_rtcd.h + CODEC_DOC_SRCS += vpx/vpx_codec.h \ vpx/vpx_decoder.h \ vpx/vpx_encoder.h \ diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c index 1798e6524..b71ef750d 100644 --- 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 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) { #if ARCH_ARM vp8_arch_arm_common_init(ctx); #endif + + vpx_rtcd(); } diff --git a/vp8/common/rtcd.c b/vp8/common/rtcd.c new file mode 100644 index 000000000..4980f48ad --- /dev/null +++ b/vp8/common/rtcd.c @@ -0,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 +static void once(void (*func)(void)) +{ + static pthread_once_t lock = PTHREAD_ONCE_INIT; + pthread_once(&lock, func); +} + + +#elif CONFIG_MULTITHREAD && defined(_WIN32) +#include +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); +} diff --git a/vp8/common/rtcd_defs.sh b/vp8/common/rtcd_defs.sh new file mode 100644 index 000000000..95148c86f --- /dev/null +++ b/vp8/common/rtcd_defs.sh @@ -0,0 +1,6 @@ +common_forward_decls() { +cat <