From 0d645bc539fdc073f20c4dea9f4a4e218cebec0e Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 22 Dec 2012 03:10:53 +0200 Subject: [PATCH] add some VideCore/R-pi support code --- gl.c | 11 ++++- gl.h | 18 ++++++-- gl_platform.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++ gl_platform.h | 2 + plat_sdl.c | 9 +++- 5 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 gl_platform.c create mode 100644 gl_platform.h diff --git a/gl.c b/gl.c index 92b39f7..44e0dd5 100644 --- a/gl.c +++ b/gl.c @@ -3,6 +3,7 @@ #include #include +#include "gl_platform.h" #include "gl.h" static EGLDisplay edpy; @@ -29,7 +30,7 @@ static int gles_have_error(const char *name) return 0; } -int gl_init(void *display, void *window) +int gl_init(void *display, void *window, int *quirks) { EGLConfig ecfg = NULL; GLuint texture_name = 0; @@ -42,6 +43,12 @@ int gl_init(void *display, void *window) EGL_NONE }; + ret = gl_platform_init(&display, &window, quirks); + if (ret != 0) { + fprintf(stderr, "gl_platform_init failed with %d\n", ret); + goto out; + } + tmp_texture_mem = calloc(1, 1024 * 512 * 2); if (tmp_texture_mem == NULL) { fprintf(stderr, "OOM\n"); @@ -177,4 +184,6 @@ void gl_finish(void) esfc = EGL_NO_SURFACE; eglTerminate(edpy); edpy = EGL_NO_DISPLAY; + + gl_platform_finish(); } diff --git a/gl.h b/gl.h index 9925dac..83b9e41 100644 --- a/gl.h +++ b/gl.h @@ -1,13 +1,23 @@ #ifdef HAVE_GLES -int gl_init(void *display, void *window); +int gl_init(void *display, void *window, int *quirks); int gl_flip(const void *fb, int w, int h); void gl_finish(void); #else -static __inline int gl_init(void *display, void *window) { return -1; } -static __inline int gl_flip(const void *fb, int w, int h) { return -1; } -static __inline void gl_finish(void) {} +static __inline int gl_init(void *display, void *window, int *quirks) +{ + return -1; +} +static __inline int gl_flip(const void *fb, int w, int h) +{ + return -1; +} +static __inline void gl_finish(void) +{ +} #endif + +#define GL_QUIRK_ACTIVATE_RECREATE 1 diff --git a/gl_platform.c b/gl_platform.c new file mode 100644 index 0000000..74eea8f --- /dev/null +++ b/gl_platform.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include + +#include "gl.h" +#include "gl_platform.h" + +#ifdef VCOS_VERSION + +/* + * hacks for Broadcom VideoCore / Raspberry Pi.. + * Why do I have to do this proprietary API stuff, + * couldn't they implement EGL properly? D: + */ +#include +#include + +static Display *x11display; +static Window x11window; +static DISPMANX_DISPLAY_HANDLE_T m_dispmanDisplay; +static EGL_DISPMANX_WINDOW_T m_nativeWindow; + +static void get_window_rect(VC_RECT_T *rect) +{ + XWindowAttributes xattrs_root; + uint32_t disp_w = 0, disp_h = 0; + int dx = 0, dy = 0; + unsigned int dw = 0, dh = 0, dummy; + Window root, dummyw; + + graphics_get_display_size(0, &disp_w, &disp_h); + if (disp_w == 0 || disp_h == 0) + fprintf(stderr, "ERROR: graphics_get_display_size is broken\n"); + + // default to fullscreen + rect->x = rect->y = 0; + rect->width = disp_w; + rect->height = disp_h; + + if (x11display == NULL || x11window == 0) + return; // use fullscreen + + XGetGeometry(x11display, x11window, &root, &dx, &dy, &dw, &dh, + &dummy, &dummy); + XGetWindowAttributes(x11display, root, &xattrs_root); + + if (dw == xattrs_root.width && dh == xattrs_root.height) + return; // use fullscreen + + XTranslateCoordinates(x11display, x11window, root, + dx, dy, &dx, &dy, &dummyw); + + // how to deal with that weird centering thing? + // this is not quite right.. + dx += (disp_w - xattrs_root.width) / 2; + dy += (disp_h - xattrs_root.height) / 2; + + rect->x = dx; + rect->y = dy; + rect->width = dw; + rect->height = dh; +} + +static void submit_rect(void) +{ + DISPMANX_UPDATE_HANDLE_T m_dispmanUpdate; + DISPMANX_ELEMENT_HANDLE_T m_dispmanElement; + VC_RECT_T srcRect = { 0, }; // unused, but we segfault without passing it?? + VC_RECT_T dstRect; + + get_window_rect(&dstRect); + + m_dispmanDisplay = vc_dispmanx_display_open(0); + m_dispmanUpdate = vc_dispmanx_update_start(0); + + m_dispmanElement = vc_dispmanx_element_add(m_dispmanUpdate, + m_dispmanDisplay, 0, &dstRect, 0, &srcRect, + DISPMANX_PROTECTION_NONE, 0, 0, DISPMANX_NO_ROTATE); + + m_nativeWindow.element = m_dispmanElement; + m_nativeWindow.width = dstRect.width; + m_nativeWindow.height = dstRect.height; + + vc_dispmanx_update_submit_sync(m_dispmanUpdate); +} + +int gl_platform_init(void **display, void **window, int *quirks) +{ + x11display = *display; + x11window = (Window)*window; + + bcm_host_init(); + submit_rect(); + + *display = EGL_DEFAULT_DISPLAY; + *window = &m_nativeWindow; + *quirks |= GL_QUIRK_ACTIVATE_RECREATE; + + return 0; +} + +void gl_platform_finish(void) +{ + vc_dispmanx_display_close(m_dispmanDisplay); + bcm_host_deinit(); +} + +#else + +int gl_platform_init(void **display, void **window, int *quirks) +{ + return 0; +} + +void gl_platform_finish(void) +{ +} + +#endif diff --git a/gl_platform.h b/gl_platform.h new file mode 100644 index 0000000..3e0bbb1 --- /dev/null +++ b/gl_platform.h @@ -0,0 +1,2 @@ +int gl_platform_init(void **display, void **window, int *quirks); +void gl_platform_finish(void); diff --git a/plat_sdl.c b/plat_sdl.c index 609d267..2508d1c 100644 --- a/plat_sdl.c +++ b/plat_sdl.c @@ -30,6 +30,7 @@ static int fs_w, fs_h; static int old_fullscreen; static int vout_mode_overlay = -1, vout_mode_gl = -1; static void *display, *window; +static int gl_quirks; /* w, h is layer resolution */ int plat_sdl_change_video_mode(int w, int h, int force) @@ -96,7 +97,7 @@ int plat_sdl_change_video_mode(int w, int h, int force) } } else if (plat_target.vout_method == vout_mode_gl) { - plat_sdl_gl_active = (gl_init(display, window) == 0); + plat_sdl_gl_active = (gl_init(display, window, &gl_quirks) == 0); if (!plat_sdl_gl_active) { fprintf(stderr, "warning: could not init GL.\n"); plat_target.vout_method = 0; @@ -139,6 +140,10 @@ void plat_sdl_event_handler(void *event_) SDL_DisplayYUVOverlay(plat_sdl_overlay, &dstrect); } else if (plat_sdl_gl_active) { + if (gl_quirks & GL_QUIRK_ACTIVATE_RECREATE) { + gl_finish(); + plat_sdl_gl_active = (gl_init(display, window, &gl_quirks) == 0); + } gl_flip(NULL, 0, 0); } // else SDL takes care of it @@ -220,7 +225,7 @@ int plat_sdl_init(void) display = wminfo.info.x11.display; window = (void *)wminfo.info.x11.window; - ret = gl_init(display, window); + ret = gl_init(display, window, &gl_quirks); if (ret == 0) { gl_works = 1; gl_finish(); -- 2.39.2