#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
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+#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 <bcm_host.h>
+#include <X11/Xlib.h>
+
+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
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)
}
}
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;
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
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();