mirror of
https://github.com/RaySollium99/libpicofe.git
synced 2025-09-03 06:17:44 -04:00
add some VideCore/R-pi support code
This commit is contained in:
parent
e54719efea
commit
0d645bc539
5 changed files with 153 additions and 7 deletions
11
gl.c
11
gl.c
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES/gl.h>
|
||||
#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();
|
||||
}
|
||||
|
|
18
gl.h
18
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
|
||||
|
|
120
gl_platform.c
Normal file
120
gl_platform.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
#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
|
2
gl_platform.h
Normal file
2
gl_platform.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
int gl_platform_init(void **display, void **window, int *quirks);
|
||||
void gl_platform_finish(void);
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue