Skip to content

Instantly share code, notes, and snippets.

@lethean
Last active August 29, 2015 14:15
Show Gist options
  • Save lethean/ac21450495dddc597f79 to your computer and use it in GitHub Desktop.
Save lethean/ac21450495dddc597f79 to your computer and use it in GitHub Desktop.
EGL + X11 on Raspberry Pi... and incompleted Cogl patch...
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index c36985b..ea51796 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -696,7 +696,7 @@ Cogl_2_0_gir_LIBS += $(top_builddir)/test-fixtures/libtest-fixtures.la
endif
Cogl_2_0_gir_FILES = $(cogl_experimental_h) $(cogl_additional_experimental_h) cogl-enum-types.h
-Cogl_1_0_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) -UCOGL_ENABLE_EXPERIMENTAL_API -UCOGL_ENABLE_EXPERIMENTAL_2_0_API -UCOGL_COMPILATION -D__COGL_H_INSIDE__ -D__COGL_XLIB_H_INSIDE__ -D__COGL_EGL_H_INSIDE__ -D__COGL_GLX_H_INSIDE__ -DCOGL_GIR_SCANNING
+Cogl_1_0_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) -UCOGL_ENABLE_EXPERIMENTAL_API -UCOGL_ENABLE_EXPERIMENTAL_2_0_API -UCOGL_COMPILATION -D__COGL_H_INSIDE__ -D__COGL_XLIB_H_INSIDE__ -D__COGL_EGL_H_INSIDE__ -D__COGL_GLX_H_INSIDE__ -DCOGL_GIR_SCANNING -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux
Cogl_1_0_gir_INCLUDES = GL-1.0 GObject-2.0
Cogl_1_0_gir_EXPORT_PACKAGES = cogl-1.0
Cogl_1_0_gir_SCANNERFLAGS = --warn-all --c-include='cogl/cogl.h'
diff --git a/cogl/cogl.c b/cogl/cogl.c
index d269bc4..2ac76c6 100644
--- a/cogl/cogl.c
+++ b/cogl/cogl.c
@@ -34,6 +34,8 @@
#include <math.h>
#include <stdlib.h>
+#include <bcm_host.h>
+
#define COGL_VERSION_MIN_REQUIRED COGL_VERSION_1_4
#include "cogl-i18n-private.h"
@@ -767,6 +769,8 @@ _cogl_init (void)
_cogl_config_read ();
_cogl_debug_check_environment ();
initialized = TRUE;
+
+ bcm_host_init ();
}
}
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
index 793b10b..52c1b00 100644
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -239,6 +239,7 @@ _cogl_framebuffer_gl_flush_front_face_winding_state (CoglFramebuffer *framebuffe
static void
_cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
{
+#if 0
CoglContext *ctx = framebuffer->context;
GLenum draw_buffer = GL_BACK;
@@ -267,6 +268,7 @@ _cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
GE (ctx, glDrawBuffer (draw_buffer));
ctx->current_gl_draw_buffer = draw_buffer;
}
+#endif
}
void
diff --git a/cogl/winsys/cogl-winsys-egl-null.c b/cogl/winsys/cogl-winsys-egl-null.c
index 962d6d1..e2ea34f 100644
--- a/cogl/winsys/cogl-winsys-egl-null.c
+++ b/cogl/winsys/cogl-winsys-egl-null.c
@@ -35,6 +35,7 @@
#include "config.h"
#endif
+#include <bcm_host.h>
#include "cogl-winsys-egl-null-private.h"
#include "cogl-winsys-egl-private.h"
#include "cogl-renderer-private.h"
@@ -93,10 +94,50 @@ _cogl_winsys_egl_context_created (CoglDisplay *display,
CoglDisplayNull *null_display = egl_display->platform;
const char *error_message;
+ 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;
+ uint32_t screen_width;
+ uint32_t screen_height;
+ int success;
+
+ success = graphics_get_display_size (0 /* LCD */, &screen_width, &screen_height);
+ if (success < 0)
+ {
+ error_message = "graphics_get_display_size() failed";
+ goto fail;
+ }
+
+ 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 );
+
egl_display->egl_surface =
eglCreateWindowSurface (egl_renderer->edpy,
egl_display->egl_config,
- (EGLNativeWindowType) NULL,
+ &nativewindow,
NULL);
if (egl_display->egl_surface == EGL_NO_SURFACE)
{
@@ -113,6 +154,9 @@ _cogl_winsys_egl_context_created (CoglDisplay *display,
goto fail;
}
+ null_display->egl_surface_width = screen_width;
+ null_display->egl_surface_height = screen_height;
+
eglQuerySurface (egl_renderer->edpy,
egl_display->egl_surface,
EGL_WIDTH,
diff --git a/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/winsys/cogl-winsys-egl-x11.c
index 0e55d41..21f572c 100644
--- a/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/winsys/cogl-winsys-egl-x11.c
@@ -277,8 +277,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
if (!_cogl_xlib_renderer_connect (renderer, error))
goto error;
- egl_renderer->edpy =
- eglGetDisplay ((EGLNativeDisplayType) xlib_renderer->xdpy);
+ egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
goto error;
@@ -420,56 +419,50 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
_cogl_xlib_renderer_trap_errors (display->renderer, &state);
xvisinfo = get_visual_info (display, egl_config);
- if (xvisinfo == NULL)
- {
- _cogl_set_error (error, COGL_WINSYS_ERROR,
- COGL_WINSYS_ERROR_CREATE_ONSCREEN,
- "Unable to retrieve the X11 visual of context's "
- "fbconfig");
- return FALSE;
- }
/* window attributes */
xattr.background_pixel =
- WhitePixel (xlib_renderer->xdpy,
- DefaultScreen (xlib_renderer->xdpy));
+ WhitePixel (xlib_renderer->xdpy,
+ DefaultScreen (xlib_renderer->xdpy));
xattr.border_pixel = 0;
/* XXX: is this an X resource that we are leaking‽... */
- xattr.colormap =
- XCreateColormap (xlib_renderer->xdpy,
- DefaultRootWindow (xlib_renderer->xdpy),
- xvisinfo->visual,
- AllocNone);
+ xattr.colormap = xvisinfo ?
+ XCreateColormap (xlib_renderer->xdpy,
+ DefaultRootWindow (xlib_renderer->xdpy),
+ xvisinfo->visual,
+ AllocNone)
+ : NULL;
xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
- mask = CWBorderPixel | CWColormap | CWEventMask;
+ mask = CWBorderPixel | CWEventMask | (xvisinfo ? CWColormap : 0);
xwin = XCreateWindow (xlib_renderer->xdpy,
- DefaultRootWindow (xlib_renderer->xdpy),
- 0, 0,
- width, height,
- 0,
- xvisinfo->depth,
- InputOutput,
- xvisinfo->visual,
- mask, &xattr);
-
- XFree (xvisinfo);
+ DefaultRootWindow (xlib_renderer->xdpy),
+ 0, 0,
+ width, height,
+ 0,
+ xvisinfo ? xvisinfo->depth : CopyFromParent,
+ InputOutput,
+ xvisinfo ? xvisinfo->visual : CopyFromParent,
+ mask, &xattr);
+
+ if (xvisinfo)
+ XFree (xvisinfo);
XSync (xlib_renderer->xdpy, False);
xerror =
- _cogl_xlib_renderer_untrap_errors (display->renderer, &state);
+ _cogl_xlib_renderer_untrap_errors (display->renderer, &state);
if (xerror)
- {
- char message[1000];
- XGetErrorText (xlib_renderer->xdpy, xerror,
- message, sizeof (message));
- _cogl_set_error (error, COGL_WINSYS_ERROR,
- COGL_WINSYS_ERROR_CREATE_ONSCREEN,
- "X error while creating Window for CoglOnscreen: %s",
- message);
- return FALSE;
- }
+ {
+ char message[1000];
+ XGetErrorText (xlib_renderer->xdpy, xerror,
+ message, sizeof (message));
+ _cogl_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+ "X error while creating Window for CoglOnscreen: %s",
+ message);
+ return FALSE;
+ }
}
xlib_onscreen = g_slice_new (CoglOnscreenXlib);
@@ -478,11 +471,48 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
xlib_onscreen->xwin = xwin;
xlib_onscreen->is_foreign_xwin = onscreen->foreign_xid ? TRUE : FALSE;
+ {
+ 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;
+ uint32_t screen_width;
+ uint32_t screen_height;
+ int success;
+
+ success = graphics_get_display_size (0 /* LCD */, &screen_width, &screen_height);
+
+ 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 );
+
egl_onscreen->egl_surface =
eglCreateWindowSurface (egl_renderer->edpy,
egl_config,
- (EGLNativeWindowType) xlib_onscreen->xwin,
+ &nativewindow,
NULL);
+ }
return TRUE;
}
@@ -600,48 +630,61 @@ _cogl_winsys_egl_context_created (CoglDisplay *display,
xvisinfo = get_visual_info (display, egl_display->egl_config);
if (xvisinfo == NULL)
{
- error_message = "Unable to find suitable X visual";
- goto fail;
- }
-
- attrs.override_redirect = True;
- attrs.colormap = XCreateColormap (xlib_renderer->xdpy,
- DefaultRootWindow (xlib_renderer->xdpy),
- xvisinfo->visual,
- AllocNone);
- attrs.border_pixel = 0;
-
- if ((egl_renderer->private_features &
- COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0)
- {
- xlib_display->dummy_xwin =
- XCreateWindow (xlib_renderer->xdpy,
- DefaultRootWindow (xlib_renderer->xdpy),
- -100, -100, 1, 1,
- 0,
- xvisinfo->depth,
- CopyFromParent,
- xvisinfo->visual,
- CWOverrideRedirect |
- CWColormap |
- CWBorderPixel,
- &attrs);
-
egl_display->dummy_surface =
eglCreateWindowSurface (egl_renderer->edpy,
egl_display->egl_config,
- (EGLNativeWindowType) xlib_display->dummy_xwin,
+ //(EGLNativeWindowType) DefaultRootWindow (xlib_renderer->xdpy),
+ NULL,
NULL);
if (egl_display->dummy_surface == EGL_NO_SURFACE)
{
error_message = "Unable to create an EGL surface";
- XFree (xvisinfo);
goto fail;
}
}
-
- XFree (xvisinfo);
+ else
+ {
+ attrs.override_redirect = True;
+ attrs.colormap = XCreateColormap (xlib_renderer->xdpy,
+ DefaultRootWindow (xlib_renderer->xdpy),
+ xvisinfo->visual,
+ AllocNone);
+ attrs.border_pixel = 0;
+
+ if ((egl_renderer->private_features &
+ COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0)
+ {
+ xlib_display->dummy_xwin =
+ XCreateWindow (xlib_renderer->xdpy,
+ DefaultRootWindow (xlib_renderer->xdpy),
+ -100, -100, 1, 1,
+ 0,
+ xvisinfo->depth,
+ CopyFromParent,
+ xvisinfo->visual,
+ CWOverrideRedirect |
+ CWColormap |
+ CWBorderPixel,
+ &attrs);
+
+ egl_display->dummy_surface =
+ eglCreateWindowSurface (egl_renderer->edpy,
+ egl_display->egl_config,
+ (EGLNativeWindowType) xlib_display->dummy_xwin,
+ NULL);
+
+ if (egl_display->dummy_surface == EGL_NO_SURFACE)
+ {
+ error_message = "Unable to create an EGL surface";
+ XFree (xvisinfo);
+ goto fail;
+ }
+ }
+
+ if (xvisinfo)
+ XFree (xvisinfo);
+ }
if (!_cogl_winsys_egl_make_current (display,
egl_display->dummy_surface,
#!/bin/sh
#
# Excerpt from http://www.raspberrypi.org/forums/viewtopic.php?t=89065&p=625499
#
set -x
# Install base libraries
#sudo apt-get install autoconf libtool automake libgudev-1.0-dev libxkbcommon-dev libudev-dev libmtdev-dev libev-dev gobject-introspection libgirepository1.0-dev python-gi-cairo
# Define some variables !!!
export CPPFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux"
export CFLAGS="-std=c99 -g -DHAVE_LIBOPENMAX=2 -DOMX -DOMX_SKIP64BIT -DUSE_EXTERNAL_OMX -DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000"
export LDFLAGS="-g -L/opt/vc/lib -lbcm_host"
export LIBS="-lGLESv2 -lEGL -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt -lm"
export LD_LIBRARY_PATH="/opt/vc/lib"
#./autogen.sh
./configure --prefix=/usr \
--libdir=/usr/lib/arm-linux-gnueabihf \
--disable-gtk-doc \
--enable-gdk-pixbuf \
--enable-cogl-pango \
--enable-introspection=no \
--disable-glibtest \
--disable-gl \
--disable-glx \
--enable-gles2 \
--enable-xlib-egl-platform \
--enable-null-egl-platform \
--with-default-driver=gles2
make && sudo make install
#!/bin/sh -x
set -x
cd /opt/vc/lib/
mkdir -p libegl-unpack
cd libegl-unpack
ar x ../libEGL_static.a
objcopy \
--redefine-sym eglGetDisplay=egl_realGetDisplay \
--redefine-sym eglCreateWindowSurface=egl_realCreateWindowSurface \
egl_client.c.o egl_client-hacked.c.o
rm egl_client.c.o
cat > egl_client_override.c << EOF
#include <EGL/egl.h>
#include <assert.h>
#include <unistd.h>
#include "bcm_host.h"
EGLDisplay eglGetDisplay(NativeDisplayType native_display)
{
bcm_host_init();
return (EGLDisplay) egl_realGetDisplay(EGL_DEFAULT_DISPLAY);
}
EGLSurface eglCreateWindowSurface(EGLDisplay display, EGLConfig config, NativeWindowType native_window, EGLint const * attrib_list)
{
uint32_t screen_width;
uint32_t screen_height;
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;
int32_t success;
success = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
assert( success >= 0 );
dst_rect.x = 800/2;
dst_rect.y = 600/2;
dst_rect.width = 800;
dst_rect.height = 600;
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = 800<<16;
src_rect.height = 600<<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 );
return egl_realCreateWindowSurface(display, config, &nativewindow, attrib_list);
}
EOF
gcc -g \
-I/opt/vc/include \
-I/opt/vc/include/interface/vcos/pthreads \
-I/opt/vc/include/interface/vmcs_host/linux \
-c egl_client_override.c && \
gcc -g -shared \
-o libEGL.so \
*.o /opt/vc/lib/libkhrn_static.a \
-L/opt/vc/lib -lbcm_host -lvchiq_arm -lvcos && \
mv /opt/vc/lib/libEGL.so /opt/vc/lib/libEGL.so.orig && \
cp -v libEGL.so /opt/vc/lib/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment