Skip to content
Permalink
Browse files

Chrome's Native Client backend implementation

  • Loading branch information
gabomdq committed Jun 6, 2014
1 parent 04a0836 commit 1e352d7929be2cec7976139d449c9b3e53252abc
@@ -0,0 +1,60 @@
================================================================================
Simple DirectMedia Layer for Native Client
================================================================================

Requirements:

* Native Client SDK (https://developer.chrome.com/native-client),
(tested with Pepper version 33 or higher).

The SDL backend for Chrome's Native Client has been tested only with the PNaCl
toolchain, which generates binaries designed to run on ARM and x86_32/64
platforms. This does not mean it won't work with the other toolchains!

================================================================================
Building SDL for NaCl
================================================================================

Set up the right environment variables (see naclbuild.sh), then configure SDL with:

configure --host=pnacl --prefix some/install/destination

Then "make".

As an example of how to create a deployable app a Makefile project is provided
in test/nacl/Makefile, which includes some monkey patching of the common.mk file
provided by NaCl, without which linking properly to SDL won't work (the search
path can't be modified externally, so the linker won't find SDL's binaries unless
you dump them into the SDK path, which is inconvenient).
Also provided in test/nacl is the required support file, such as index.html,
manifest.json, etc.


================================================================================
Running tests
================================================================================

Due to the nature of NaCl programs, building and running SDL tests is not as
straightforward as one would hope. The script naclbuild.sh in build-scripts
automates the process and should serve as a guide for users of SDL trying to build
their own applications.

Basic usage:

./naclbuild.sh path/to/pepper/toolchain (i.e. ~/naclsdk/pepper_35)

This will build testgles2.c by default.

If you want to build a different test, for example testrendercopyex.c:

SOURCES=~/sdl/SDL/test/testrendercopyex.c ./naclbuild.sh ~/naclsdk/pepper_35

Once the build finishes, you have to serve the contents with a web server (the
script will give you instructions on how to do that with Python).

================================================================================
TODO - Known Issues
================================================================================
* Audio backend is not usable yet.
* Testing of all systems with a real application (something other than SDL's tests)

@@ -9,6 +9,7 @@ General:
* Added an event SDL_RENDER_DEVICE_RESET that is sent from the D3D renderers
when the D3D device is lost, and from Android's event loop when the GLES
context had to be re created.
* Native Client backend

---------------------------------------------------------------------------
2.0.3:
@@ -359,6 +359,19 @@ case $basic_machine in
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
nacl64*)
basic_machine=x86_64-pc
os=-nacl
;;
nacl*)
basic_machine=i686-pc
os=-nacl
;;
pnacl*)
# le32-unknown-pnacl comes from http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi
basic_machine=le32-unknown
os=-pnacl
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
@@ -843,6 +856,10 @@ case $basic_machine in
basic_machine=le32-unknown
os=-nacl
;;
pnacl)
basic_machine=le32-unknown
os=-pnacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -1384,6 +1401,12 @@ case $os in
;;
esac
;;
-nacl*)
os=-nacl
;;
-pnacl*)
os=-pnacl
;;
-nto-qnx*)
;;
-nto*)
@@ -1506,6 +1529,10 @@ case $os in
os=-dicos
;;
-nacl*)
os=-nacl
;;
-pnacl*)
os=-pnacl
;;
-none)
;;
@@ -0,0 +1,105 @@
#!/bin/bash
if [ -z "$1" ] && [ -z "$NACL_SDK_ROOT" ]; then
echo "Usage: ./naclbuild ~/nacl/pepper_33"
echo "This will build SDL for Native Client, and testgles2.c as a demo"
echo "You can set env vars CC, AR, LD and RANLIB to override the default PNaCl toolchain used"
echo "You can set env var SOURCES to select a different source file than testgles2.c"
exit 1
fi

if [ -n "$1" ]; then
NACL_SDK_ROOT="$1"
fi

CC=""

if [ -n "$2" ]; then
CC="$2"
fi

echo "Using SDK at $NACL_SDK_ROOT"

export NACL_SDK_ROOT="$NACL_SDK_ROOT"
export CFLAGS="$CFLAGS -I$NACL_SDK_ROOT/include"

NCPUS="1"
case "$OSTYPE" in
darwin*)
NCPU=`sysctl -n hw.ncpu`
;;
linux*)
if [ -n `which nproc` ]; then
NCPUS=`nproc`
fi
;;
*);;
esac

CURDIR=`pwd -P`
SDLPATH="$( cd "$(dirname "$0")/.." ; pwd -P )"
BUILDPATH="$SDLPATH/build/nacl"
TESTBUILDPATH="$BUILDPATH/test"
SDL2_STATIC="$BUILDPATH/build/.libs/libSDL2.a"
mkdir -p $BUILDPATH
mkdir -p $TESTBUILDPATH

if [ -z "$CC" ]; then
export CC="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-clang"
fi
if [ -z "$AR" ]; then
export AR="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-ar"
fi
if [ -z "$LD" ]; then
export LD="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-ar"
fi
if [ -z "$RANLIB" ]; then
export RANLIB="$NACL_SDK_ROOT/toolchain/linux_pnacl/bin/pnacl-ranlib"
fi

if [ -z "$SOURCES" ]; then
export SOURCES="$SDLPATH/test/testgles2.c"
fi

if [ ! -f "$CC" ]; then
echo "Could not find compiler at $CC"
exit 1
fi




cd $BUILDPATH
$SDLPATH/configure --host=pnacl --prefix $TESTBUILDPATH
make -j$NCPUS CFLAGS="$CFLAGS -I./include"
make install

if [ ! -f "$SDL2_STATIC" ]; then
echo "Build failed! $SDL2_STATIC"
exit 1
fi

echo "Building test"
cp -f $SDLPATH/test/nacl/* $TESTBUILDPATH
# Some tests need these resource files
cp -f $SDLPATH/test/*.bmp $TESTBUILDPATH
cp -f $SDLPATH/test/*.wav $TESTBUILDPATH
cp -f $SDL2_STATIC $TESTBUILDPATH

# Copy user sources
_SOURCES=($SOURCES)
for src in "${_SOURCES[@]}"
do
cp $src $TESTBUILDPATH
done
export SOURCES="$SOURCES"

cd $TESTBUILDPATH
make -j$NCPUS CONFIG="Release" CFLAGS="$CFLAGS -I$TESTBUILDPATH/include/SDL2 -I$SDLPATH/include"
make -j$NCPUS CONFIG="Debug" CFLAGS="$CFLAGS -I$TESTBUILDPATH/include/SDL2 -I$SDLPATH/include"

echo
echo "Run the test with: "
echo "cd $TESTBUILDPATH;python -m SimpleHTTPServer"
echo "Then visit http://localhost:8000 with Chrome"

cd $CURDIR
fi
}

CheckNativeClient()
{
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */

#if !defined(__native_client__)
#error "NO NACL"
#endif

int
main ()
{


;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

$as_echo "#define SDL_VIDEO_DRIVER_NACL 1" >>confdefs.h

$as_echo "#define SDL_AUDIO_DRIVER_NACL 1" >>confdefs.h


$as_echo "#define HAVE_POW 1" >>confdefs.h


$as_echo "#define HAVE_OPENGLES2 1" >>confdefs.h


$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h


$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h


SDL_LIBS="-lppapi_simple -lppapi_gles2 $SDL_LIBS"

SDLMAIN_SOURCES="$srcdir/src/main/nacl/*.c"
SOURCES="$SOURCES $srcdir/src/audio/nacl/*.c"
SUMMARY_audio="${SUMMARY_audio} nacl"
SOURCES="$SOURCES $srcdir/src/video/nacl/*.c"
SUMMARY_video="${SUMMARY_video} nacl opengles2"

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
}


CheckX11()
{
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit"
fi
;;
*-nacl|*-pnacl)
ARCH=nacl
CheckNativeClient
CheckDummyAudio
CheckDummyVideo
CheckInputEvents
# Set up files for the timer library
if test x$enable_timers = xyes; then
$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h

SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes
fi
CheckPTHREAD
;;
*)
as_fn_error $? "
*** Unsupported host: Please add to configure.in
@@ -1317,6 +1317,32 @@ AC_HELP_STRING([--enable-mir-shared], [dynamically load Mir support [[default=ma
fi
}

dnl Check for Native Client stuff
CheckNativeClient()
{
AC_TRY_COMPILE([
#if !defined(__native_client__)
#error "NO NACL"
#endif
],[
],[
AC_DEFINE(SDL_VIDEO_DRIVER_NACL)
AC_DEFINE(SDL_AUDIO_DRIVER_NACL)
AC_DEFINE(HAVE_POW, 1, [ ])
AC_DEFINE(HAVE_OPENGLES2, 1, [ ])
AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ])
AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES2, 1, [ ])

SDL_LIBS="-lppapi_simple -lppapi_gles2 $SDL_LIBS"

SDLMAIN_SOURCES="$srcdir/src/main/nacl/*.c"
SOURCES="$SOURCES $srcdir/src/audio/nacl/*.c"
SUMMARY_audio="${SUMMARY_audio} nacl"
SOURCES="$SOURCES $srcdir/src/video/nacl/*.c"
SUMMARY_video="${SUMMARY_video} nacl opengles2"
])
}


dnl Find the X11 include and library directories
CheckX11()
@@ -3119,6 +3145,20 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit"
fi
;;
*-nacl|*-pnacl)
ARCH=nacl
CheckNativeClient
CheckDummyAudio
CheckDummyVideo
CheckInputEvents
# Set up files for the timer library
if test x$enable_timers = xyes; then
AC_DEFINE(SDL_TIMER_UNIX)
SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes
fi
CheckPTHREAD
;;
*)
AC_MSG_ERROR([
*** Unsupported host: Please add to configure.in
@@ -51,7 +51,7 @@ assert can have unique static variables associated with it.
/* Don't include intrin.h here because it contains C++ code */
extern void __cdecl __debugbreak(void);
#define SDL_TriggerBreakpoint() __debugbreak()
#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
#elif (!defined(__NACL__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
#elif defined(HAVE_SIGNAL_H)
#include <signal.h>
@@ -208,6 +208,7 @@
#undef SDL_AUDIO_DRIVER_DSOUND
#undef SDL_AUDIO_DRIVER_ESD
#undef SDL_AUDIO_DRIVER_ESD_DYNAMIC
#undef SDL_AUDIO_DRIVER_NACL
#undef SDL_AUDIO_DRIVER_NAS
#undef SDL_AUDIO_DRIVER_NAS_DYNAMIC
#undef SDL_AUDIO_DRIVER_SNDIO
@@ -297,6 +298,7 @@
#undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XDATA32
#undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY
#undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
#undef SDL_VIDEO_DRIVER_NACL

#undef SDL_VIDEO_RENDER_D3D
#undef SDL_VIDEO_RENDER_D3D11

0 comments on commit 1e352d7

Please sign in to comment.