#include #include #include #include #include #include #include #include #include #include /* must set framebuffer to 32 bpp for it to work, add the following to /boot/config.txt. framebuffer_depth=32 framebuffer_ignore_alpha=1 this must be compiled as follows: gcc -fPIC -g -c -Wl,-export-dynamic -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads k_eglGetDisplayCopy.c sudo mv k_eglGetDisplayCopy.o /opt/vc/lib/libegl-unpack cd /opt/vc/lib/libegl-unpack sudo ar x ../libEGL_static.a sudo objcopy --redefine-sym eglGetDisplay=real_eglGetDisplay --redefine-sym eglCreateWindowSurface=real_eglCreateWindowSurface --redefine-sym eglSwapBuffers=real_eglSwapBuffers --redefine-sym eglMakeCurrent=real_eglMakeCurrent egl_client.c.o egl_client-modified.c.o sudo rm -rf egl_client.c.o cd .. sudo gcc -shared -Wl,-soname,libEGL.so -o libEGL.so -L/opt/vc/lib libegl-unpack/*.o -g -lvchiq_arm -lvcos -lbcm_host -lm -lpthread -ldl -lrt -lc -lXext -lX11 libkhrn_static.a sudo ldconfig -v */ #define XSHM 1 #define TRUECOLOR_X 1 static int x11_enabled = 0; Window root; Window window; EGLDisplay *edisplay; int width, height,depth; Display* display; EGLSurface egl_surface; XWindowAttributes *window_attributes_return; static GC eglgc; static XGCValues gcvalues; static XImage *image =0; XImage *img; static unsigned int *buffer; static Screen *screen; /////////////////////////////////// EGLDisplay eglGetDisplay(NativeDisplayType native_display) { display = XOpenDisplay(0); if(display==NULL) // if ( native_display == EGL_DEFAULT_DISPLAY) { x11_enabled=0; return (void *) real_eglGetDisplay(native_display); } x11_enabled=1; bcm_host_init(); root = (void *) DefaultRootWindow(display); edisplay = (void *) real_eglGetDisplay(EGL_DEFAULT_DISPLAY); return edisplay; } /////////////////////// EGLSurface eglCreateWindowSurface(EGLDisplay egldisplay, EGLConfig config, NativeWindowType native_window, EGLint const * attrib_list) { if (x11_enabled == 0) { return (EGLSurface) real_eglCreateWindowSurface(egldisplay,config,native_window,attrib_list); } int blackColor=BlackPixel(display,DefaultScreen(display)); int white=WhitePixel(display,DefaultScreen(display)); window = XCreateSimpleWindow(display,root,0,0,400,400,0,blackColor,blackColor); XSelectInput(display,window,StructureNotifyMask); XMapWindow(display,window); eglgc=XCreateGC(display,(Drawable)window,0,&gcvalues); XSetForeground(display,eglgc,white); for(;;){ XEvent e; XNextEvent(display,&e); if(e.type==MapNotify) break; } XDrawLine(display,window,eglgc,0,0,100,100); XFlush(display); XWindowAttributes window_attributes; XGetWindowAttributes(display,(Drawable) window,&window_attributes); printf("Window Location: %i,%i \n Window Dimensions %i x %i \n Bit depth : %i \n",(void*)window_attributes.x,window_attributes.y,window_attributes.width,window_attributes.height,window_attributes.depth); width=window_attributes.width ; height=window_attributes.height; depth=window_attributes.depth; #if TRUECOLOR_X EGLint attr[] = { // some attributes to set up our egl-interface EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_OPENGL_ES2_BIT, EGL_NONE }; #else // 16bpp X mode?????? apparently this does not work correctly if you want 565 you actuall need set 0,0,0,0 EGLint attr[] = { // some attributes to set up our egl-interface EGL_RED_SIZE, 0, EGL_GREEN_SIZE, 0, EGL_BLUE_SIZE, 0, EGL_ALPHA_SIZE, 0, EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_OPENGL_ES2_BIT, EGL_NONE }; #endif #if XSHM // xshm setup int ignore, major, minor; Bool pixmaps; /* Check for the XShm extension */ if( XQueryExtension(display, "MIT-SHM", &ignore, &ignore, &ignore) ) { if(XShmQueryVersion(display, &major, &minor, &pixmaps) == True) { printf("XShm extention version %d.%d %s shared pixmaps\n", major, minor, (pixmaps==True) ? "with" : "without"); } else return 1; } XShmSegmentInfo shminfo; screen=XDefaultScreenOfDisplay(display); img = XShmCreateImage(display, DefaultVisualOfScreen(screen), DefaultDepthOfScreen(screen), ZPixmap, NULL, &shminfo, width,height ); if(img == NULL) return 1; /* Get the shared memory and check for errors */ shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line*img->height, IPC_CREAT | 0777 ); if(shminfo.shmid < 0) return 1; /* attach, and check for errrors */ shminfo.shmaddr = img->data = (char *)shmat(shminfo.shmid, 0, 0); if(shminfo.shmaddr == (char *) -1) return 1; /* set as read/write, and attach to the display */ shminfo.readOnly = False; XShmAttach(display, &shminfo); buffer = img->data; mlock(img->data,img->bytes_per_line*img->height); XShmPutImage(display, window, eglgc, img, 0, 0, 0, 0, img->width, img->height, False); #else buffer = (unsigned int *)malloc(height * width * 4); #endif EGLConfig ecfg; EGLint num_config; if (!eglChooseConfig(edisplay, attr, &ecfg, 1, &num_config)) { fprintf(stderr, "Failed to choose config (eglError: %s)\n"); return EGL_NO_SURFACE; } #if TRUECOLOR_X EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM; #else EGLint pixel_format = EGL_PIXEL_FORMAT_RGB_565_BRCM; #endif EGLint rt; eglGetConfigAttrib(edisplay, ecfg, EGL_RENDERABLE_TYPE, &rt); if (rt & EGL_OPENGL_ES_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM; } if (rt & EGL_OPENGL_ES2_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM; } if (rt & EGL_OPENVG_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_VG_BRCM; pixel_format |= EGL_PIXEL_FORMAT_VG_IMAGE_BRCM; } if (rt & EGL_OPENGL_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GL_BRCM; } EGLint pixmap[5]; pixmap[0] = 0; pixmap[1] = 0; pixmap[2] = width; pixmap[3] = height; pixmap[4] = pixel_format; eglCreateGlobalImageBRCM(width, height, pixmap[4], 0, width*4, pixmap); egl_surface = eglCreatePixmapSurface(edisplay, ecfg, pixmap, 0); puts("EGL Surface Created"); EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLContext context = eglCreateContext ( edisplay, ecfg, EGL_NO_CONTEXT, ctxattr ); real_eglMakeCurrent(edisplay, egl_surface, egl_surface, context); return egl_surface; } ///////////////////////// #if ! XSHM EGLBoolean eglSwapBuffers(EGLDisplay edisplay, EGLSurface egsurface) { if (x11_enabled == 0) { return real_eglSwapBuffers(edisplay,egsurface); } glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); XImage *img = XCreateImage(display,CopyFromParent,depth,ZPixmap,0,(char *)buffer,width, height, 32, 0); XPutImage(display, (Drawable)window, eglgc, img, 0, 0, 0, 0, width, height); return EGL_TRUE; } #else // towelie says I have no idea whats going on // egl buffers are stored as floats X11 are ints can we actually share buffers without a shit load of conversion? // this does wtf? its so long since i looked at xshm i am not sure this would ever work? EGLBoolean eglSwapBuffers(EGLDisplay edisplay, EGLSurface egsurface) { if (x11_enabled == 0) { return real_eglSwapBuffers(edisplay,egsurface); } buffer=img->data; glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); //img->data=buffer; XShmPutImage(display, window, eglgc, img, 0, 0, 0, 0, width, height, False); glFlush(); return EGL_TRUE; } #endif ///////////////// EGLBoolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context) { real_eglMakeCurrent(display,draw,read,context); return EGL_TRUE; }