Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Initial support for Raspberry Pi
  • Loading branch information
andoma committed Jan 17, 2013
1 parent 02192c3 commit 12ac85d
Show file tree
Hide file tree
Showing 4 changed files with 352 additions and 1 deletion.
78 changes: 78 additions & 0 deletions configure.rpi
@@ -0,0 +1,78 @@
#!/bin/bash

OS="rpi"
DEFAULT_UI="glw"
CONFIGURE_POSTFIX="rpi"

source support/configure.inc

show_help(){
common_help
exit 1
}

for opt do
optval="${opt#*=}"
case "$opt" in
--help) show_help
;;
--toolchain=*) TOOLCHAIN="$optval"
;;
--vcroot=*) VCROOT="$optval"
;;
*)
common_opt $opt $optval
esac
done

[ -z "$TOOLCHAIN" ] && die_cause "--toolchain not specified"
[ -z "$VCROOT" ] && die_cause "--vcroot not specified"

setup_env "$@"


enable sqlite_internal
enable spidermonkey
enable glw_backend_opengl_es
enable glw
enable polarssl
enable librtmp
enable httpserver
enable dvd
enable libfreetype
enable stdin

zlib_setup
bzip2_setup
freetype_setup --host=arm-linux-gnueabihf

LIBAV_CFLAGS="-mfpu=vfp -I${BUILDDIR}/zlib/install/include"
LIBAV_LDFLAGS="-L${BUILDDIR}/zlib/install/lib"
LIBAV_ARCH_FLAGS="--cross-prefix=${TOOLCHAIN} --enable-cross-compile --arch=arm --cpu=arm1176jzf-s --target-os=linux --disable-armv5te --disable-neon --enable-armv6t2 --enable-armv6 --enable-armvfp"

libav_setup

cat >> ${CONFIG_MAK} <<EOF
CC=${TOOLCHAIN}cc
STRIP=${TOOLCHAIN}strip
OBJDUMP=${TOOLCHAIN}objdump
OBJCOPY=${TOOLCHAIN}objcopy
CFLAGS_cfg += -mfpu=vfp
CFLAGS_cfg += -I${VCROOT}/include
CFLAGS_cfg += -I${VCROOT}/include/IL
CFLAGS_cfg += -I${VCROOT}/include/interface/vcos/pthreads/
CFLAGS_cfg += -I${VCROOT}/include/interface/vmcs_host/linux
LDFLAGS_cfg += -L${VCROOT}/lib
LDFLAGS_cfg += -lopenmaxil -lGLESv2 -lEGL -lvcos -lbcm_host -lvchiq_arm
LDFLAGS_cfg += -lpthread -lrt -ldl
EOF

finalize

echo
echo "NOTE: Support for Raspberry Pi is still experimental"
echo "NOTE: Audio/Video playback does not work yet"
echo "NOTE: A lot of other things are probably broken as well"
echo "NOTE: You have been warned"
echo
255 changes: 255 additions & 0 deletions src/arch/rpi/rpi_main.c
@@ -0,0 +1,255 @@
/*
* Showtime mediacenter
* Copyright (C) 2007-2012 Andreas Öman
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>

#include <bcm_host.h>

#include <EGL/egl.h>
#include <GLES2/gl2.h>

#include "showtime.h"
#include "arch/arch.h"
#include "arch/posix/posix.h"

#include "arch/linux/linux.h"
#include "prop/prop.h"
#include "ui/glw/glw.h"
#include "navigator.h"

static uint32_t screen_width, screen_height;
static EGLDisplay display;
static EGLContext context;
static EGLSurface surface;


/**
*
*/
int64_t
showtime_get_avtime(void)
{
return showtime_get_ts();
}


#define check() assert(glGetError() == 0)

/**
*
*/
static void
egl_init(void)
{
int32_t success = 0;
EGLBoolean result;
EGLint num_config;

static EGL_DISPMANX_WINDOW_T nativewindow;

DISPMANX_ELEMENT_HANDLE_T dispman_element;
DISPMANX_DISPLAY_HANDLE_T dispman_display;
DISPMANX_UPDATE_HANDLE_T dispman_update;
VC_RECT_T dst_rect;
VC_RECT_T src_rect;

static const EGLint attribute_list[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};

static const EGLint context_attributes[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLConfig config;

// get an EGL display connection
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(display!=EGL_NO_DISPLAY);
check();

// initialize the EGL display connection
result = eglInitialize(display, NULL, NULL);
assert(EGL_FALSE != result);
check();

// get an appropriate EGL frame buffer configuration
result = eglChooseConfig(display, attribute_list, &config, 1, &num_config);
assert(EGL_FALSE != result);
check();

// get an appropriate EGL frame buffer configuration
result = eglBindAPI(EGL_OPENGL_ES_API);
assert(EGL_FALSE != result);
check();

// create an EGL rendering context
context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
assert(context!=EGL_NO_CONTEXT);
check();

// create an EGL window surface
success = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
assert( success >= 0 );

dst_rect.x = 0;
dst_rect.y = 0;
dst_rect.width = screen_width;
dst_rect.height = screen_height;

src_rect.x = 0;
src_rect.y = 0;
src_rect.width = screen_width << 16;
src_rect.height = screen_height << 16;

dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
dispman_update = vc_dispmanx_update_start( 0 );

dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
0/*layer*/, &dst_rect, 0/*src*/,
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

nativewindow.element = dispman_element;
nativewindow.width = screen_width;
nativewindow.height = screen_height;
vc_dispmanx_update_submit_sync( dispman_update );

check();

surface = eglCreateWindowSurface( display, config, &nativewindow, NULL );
assert(surface != EGL_NO_SURFACE);
check();

// connect the context to the surface
result = eglMakeCurrent(display, surface, surface, context);
assert(EGL_FALSE != result);
check();

// Set background color and clear buffers
glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
glClear( GL_COLOR_BUFFER_BIT );

check();
}


/**
*
*/
static void
run(void)
{
glw_root_t *gr = calloc(1, sizeof(glw_root_t));
gr->gr_prop_ui = prop_create_root("ui");
gr->gr_prop_nav = nav_spawn();
gr->gr_width = screen_width;
gr->gr_height = screen_height;

if(glw_init(gr)) {
TRACE(TRACE_ERROR, "GLW", "Unable to init GLW");
exit(1);
}

glw_load_universe(gr);
glw_opengl_init_context(gr);

glClearColor(0,0,0,0);

while(!gr->gr_stop) {

glw_lock(gr);

glViewport(0, 0, gr->gr_width, gr->gr_height);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

glw_prepare_frame(gr, 0);

glw_rctx_t rc;
glw_rctx_init(&rc, gr->gr_width, gr->gr_height, 1);
glw_layout0(gr->gr_universe, &rc);
glw_render0(gr->gr_universe, &rc);

glw_unlock(gr);
glw_post_scene(gr);

eglSwapBuffers(display, surface);
}
}


/**
* Linux main
*/
int
main(int argc, char **argv)
{
bcm_host_init();

gconf.binary = argv[0];

posix_init();

parse_opts(argc, argv);

gconf.concurrency = 1;

trap_init();

showtime_init();

linux_init_monitors();

egl_init();

run();

showtime_fini();

arch_exit();
}


/**
*
*/
void
arch_exit(void)
{
exit(gconf.exit_code);
}


#include "audio2/audio.h"

static audio_class_t dummy_audio_class = {
.ac_alloc_size = 1024,
};


audio_class_t *
audio_driver_init(void)
{
return &dummy_audio_class;
}

1 change: 0 additions & 1 deletion support/configure.inc
Expand Up @@ -493,5 +493,4 @@ EOF
rm -f ${CONFIG_H} ${CONFIG_MAK}

cleanup
exit 0
}
19 changes: 19 additions & 0 deletions support/rpi.mk
@@ -0,0 +1,19 @@
.DEFAULT_GOAL := ${PROG}.bundle

SRCS += src/arch/rpi/rpi_main.c

SRCS += src/arch/linux/linux_misc.c \
src/arch/linux/linux_trap.c \
src/arch/posix/posix.c \
src/arch/posix/posix_threads.c \
src/networking/net_posix.c \

#
# OS specific sources and flags
#
DVDCSS_CFLAGS = -DHAVE_LINUX_DVD_STRUCT -DDVD_STRUCT_IN_LINUX_CDROM_H -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE

${PROG}.stripped: ${PROG}.bundle
${STRIP} -o $@ $<

stripped: ${PROG}.stripped

0 comments on commit 12ac85d

Please sign in to comment.