forked from enlightenment/efl
303 lines
8.0 KiB
C
303 lines
8.0 KiB
C
#include <Eina.h>
|
|
#include <Ecore.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <dlfcn.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
#define SYM(lib, xx) \
|
|
do { \
|
|
sym_ ## xx = dlsym(lib, #xx); \
|
|
if (!(sym_ ## xx)) { \
|
|
fail = 1; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define GLX_DRAWABLE_TYPE 0x8010
|
|
#define GLX_WINDOW_BIT 0x00000001
|
|
#define GLX_RENDER_TYPE 0x8011
|
|
#define GLX_RGBA_BIT 0x00000001
|
|
#define GLX_DOUBLEBUFFER 5
|
|
#define GLX_RED_SIZE 8
|
|
#define GLX_GREEN_SIZE 9
|
|
#define GLX_BLUE_SIZE 10
|
|
#define GLX_RGBA_TYPE 0x8014
|
|
typedef struct __GLXFBConfigRec *GLXFBConfig;
|
|
|
|
typedef struct
|
|
{
|
|
void *visual;
|
|
long visualid;
|
|
int screen;
|
|
int depth;
|
|
int c_class;
|
|
unsigned long red_mask;
|
|
unsigned long green_mask;
|
|
unsigned long blue_mask;
|
|
int colormap_size;
|
|
int bits_per_rgb;
|
|
} XVisualInfo;
|
|
|
|
typedef struct
|
|
{
|
|
long background_pixmap;
|
|
unsigned long background_pixel;
|
|
long border_pixmap;
|
|
unsigned long border_pixel;
|
|
int bit_gravity;
|
|
int win_gravity;
|
|
int backing_store;
|
|
unsigned long backing_planes;
|
|
unsigned long backing_pixel;
|
|
int save_under;
|
|
long event_mask;
|
|
long do_not_propagate_mask;
|
|
int override_redirect;
|
|
long colormap;
|
|
long cursor;
|
|
} XSetWindowAttributes;
|
|
|
|
typedef struct {
|
|
void *ext_data;
|
|
void *display;
|
|
long root;
|
|
int width, height;
|
|
int mwidth, mheight;
|
|
int ndepths;
|
|
void *depths;
|
|
int root_depth;
|
|
void *root_visual;
|
|
long default_gc;
|
|
long cmap;
|
|
unsigned long white_pixel;
|
|
unsigned long black_pixel;
|
|
int max_maps, min_maps;
|
|
int backing_store;
|
|
int save_unders;
|
|
long root_input_mask;
|
|
} Screen;
|
|
|
|
typedef struct
|
|
{
|
|
void *ext_data;
|
|
void *private1;
|
|
int fd;
|
|
int private2;
|
|
int proto_major_version;
|
|
int proto_minor_version;
|
|
char *vendor;
|
|
long private3;
|
|
long private4;
|
|
long private5;
|
|
int private6;
|
|
long (*resource_alloc)(void *);
|
|
int byte_order;
|
|
int bitmap_unit;
|
|
int bitmap_pad;
|
|
int bitmap_bit_order;
|
|
int nformats;
|
|
void *pixmap_format;
|
|
int private8;
|
|
int release;
|
|
void *private9, *private10;
|
|
int qlen;
|
|
unsigned long last_request_read;
|
|
unsigned long request;
|
|
char *private11;
|
|
char *private12;
|
|
char *private13;
|
|
char *private14;
|
|
unsigned max_request_size;
|
|
void *db;
|
|
int (*private15)(void *);
|
|
char *display_name;
|
|
int default_screen;
|
|
int nscreens;
|
|
Screen *screens;
|
|
unsigned long motion_buffer;
|
|
unsigned long private16;
|
|
int min_keycode;
|
|
int max_keycode;
|
|
char *private17;
|
|
char *private18;
|
|
int private19;
|
|
char *xdefaults;
|
|
} *_XPrivDisplay;
|
|
|
|
#define InputOutput 1
|
|
#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root)
|
|
#define ScreenOfDisplay(dpy, scr) (&((_XPrivDisplay)dpy)->screens[scr])
|
|
#define CWBorderPixel (1L<<3)
|
|
#define CWColormap (1L<<13)
|
|
#define CWOverrideRedirect (1L<<9)
|
|
#define AllocNone 0
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static const char *lib_x11_files[] =
|
|
{
|
|
"libX11.so.6",
|
|
"libX11.so.5",
|
|
"libX11.so.4",
|
|
"libX11.so",
|
|
NULL
|
|
};
|
|
static void *lib_x11 = NULL;
|
|
static void * (*sym_XOpenDisplay) (char *name) = NULL;
|
|
static long (*sym_XCreateColormap) (void *d, long w, void *vis, int alloc) = NULL;
|
|
static long (*sym_XCreateWindow) (void *d, long par, int x, int y, unsigned int w, unsigned int h, unsigned int bd, int depth, unsigned int clas, void *vis, unsigned long valmask, void *attr) = NULL;
|
|
static int (*sym_XCloseDisplay) (void *d) = NULL;
|
|
//static void * (*sym_) () = NULL;
|
|
|
|
static const char *lib_gl_files[] =
|
|
{
|
|
"libGL.so.9",
|
|
"libGL.so.8",
|
|
"libGL.so.7",
|
|
"libGL.so.6",
|
|
"libGL.so.5",
|
|
"libGL.so.4",
|
|
"libGL.so.3",
|
|
"libGL.so.2",
|
|
"libGL.so.1",
|
|
"libGL.so",
|
|
NULL
|
|
};
|
|
static void *lib_gl = NULL;
|
|
static GLXFBConfig * (*sym_glXChooseFBConfig) (void *d, int sc, const int *att, int *n) = NULL;
|
|
static void * (*sym_glXGetVisualFromFBConfig) (void *d, GLXFBConfig fbconfig) = NULL;
|
|
static void *(*sym_glXCreateNewContext) (void *d, GLXFBConfig config, int rtype, void *shr, int direct) = NULL;
|
|
static long (*sym_glXCreateWindow) (void *d, GLXFBConfig config, long win, const int *attr) = NULL;
|
|
static int (*sym_glXMakeContextCurrent) (void *d, long draw, long draw2, void *context) = NULL;
|
|
static void (*sym_glXSwapBuffers) (void *d, long draw) = NULL;
|
|
static const char * (*sym_glXQueryExtensionsString) (void *d, int ival) = NULL;
|
|
static void * (*sym_glXGetProcAddressARB) (const char *sym) = NULL;
|
|
static int (*sym_glXGetVideoSyncSGI) (unsigned int *cnt) = NULL;
|
|
static int (*sym_glXWaitVideoSyncSGI) (int divisor, int remainder, unsigned int *cnt) = NULL;
|
|
//static void * (*sym_) () = NULL;
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
static void *disp = NULL;
|
|
static long gwin = 0;
|
|
static void *context = NULL;
|
|
|
|
static void *
|
|
lib_load(const char *files[])
|
|
{
|
|
int i;
|
|
void *lib = NULL;
|
|
|
|
for (i = 0; files[i]; i++)
|
|
{
|
|
lib = dlopen(files[i], RTLD_LOCAL | RTLD_LAZY);
|
|
if (lib) return lib;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
_vsync_init_glx(void)
|
|
{
|
|
int fail = 0;
|
|
GLXFBConfig *fbconfigs;
|
|
int num = 0;
|
|
int attr[] =
|
|
{
|
|
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
|
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
|
GLX_DOUBLEBUFFER, 1,
|
|
GLX_RED_SIZE, 1,
|
|
GLX_GREEN_SIZE, 1,
|
|
GLX_BLUE_SIZE, 1,
|
|
0
|
|
};
|
|
XVisualInfo *vi;
|
|
XSetWindowAttributes wa;
|
|
long win;
|
|
const char *extns;
|
|
|
|
/*---------------------------*/
|
|
lib_x11 = lib_load(lib_x11_files);
|
|
if (!lib_x11) goto err;
|
|
|
|
SYM(lib_x11, XOpenDisplay);
|
|
SYM(lib_x11, XCreateColormap);
|
|
SYM(lib_x11, XCreateWindow);
|
|
SYM(lib_x11, XCloseDisplay);
|
|
if (fail) goto err;
|
|
|
|
/*---------------------------*/
|
|
lib_gl = lib_load(lib_gl_files);
|
|
if (!lib_gl)
|
|
{
|
|
dlclose(lib_x11);
|
|
return 0;
|
|
}
|
|
|
|
SYM(lib_gl, glXChooseFBConfig);
|
|
SYM(lib_gl, glXGetVisualFromFBConfig);
|
|
SYM(lib_gl, glXCreateNewContext);
|
|
SYM(lib_gl, glXCreateWindow);
|
|
SYM(lib_gl, glXMakeContextCurrent);
|
|
SYM(lib_gl, glXSwapBuffers);
|
|
SYM(lib_gl, glXQueryExtensionsString);
|
|
SYM(lib_gl, glXGetProcAddressARB);
|
|
if (fail) goto err;
|
|
|
|
/*---------------------------*/
|
|
disp = sym_XOpenDisplay(NULL);
|
|
if (!disp) goto err;
|
|
fbconfigs = sym_glXChooseFBConfig(disp, 0, attr, &num);
|
|
if (!fbconfigs) goto err;
|
|
vi = sym_glXGetVisualFromFBConfig(disp, fbconfigs[0]);
|
|
if (!vi) goto err;
|
|
wa.override_redirect = 1;
|
|
wa.border_pixel = 0;
|
|
wa.colormap = sym_XCreateColormap(disp, RootWindow(disp, vi->screen),
|
|
vi->visual, AllocNone);
|
|
if (!wa.colormap) goto err;
|
|
win = sym_XCreateWindow(disp, RootWindow(disp, vi->screen),
|
|
-77, -777, 1, 1, 0, vi->depth, InputOutput,
|
|
vi->visual,
|
|
CWBorderPixel | CWColormap | CWOverrideRedirect, &wa);
|
|
if (!win) goto err;
|
|
context = sym_glXCreateNewContext(disp, fbconfigs[0], GLX_RGBA_TYPE,
|
|
NULL, 1);
|
|
if (!context) goto err;
|
|
gwin = sym_glXCreateWindow(disp, fbconfigs[0], win, NULL);
|
|
if (!gwin) goto err;
|
|
extns = sym_glXQueryExtensionsString(disp, 0);
|
|
if (!extns) goto err;
|
|
if (!strstr(extns, "GLX_SGI_swap_control")) goto err;
|
|
sym_glXGetVideoSyncSGI = sym_glXGetProcAddressARB("glXGetVideoSyncSGI");
|
|
sym_glXWaitVideoSyncSGI = sym_glXGetProcAddressARB("glXWaitVideoSyncSGI");
|
|
if ((!sym_glXGetVideoSyncSGI) || (!sym_glXWaitVideoSyncSGI)) goto err;
|
|
|
|
return 1;
|
|
err:
|
|
if (disp) sym_XCloseDisplay(disp);
|
|
if (lib_gl) dlclose(lib_gl);
|
|
if (lib_x11) dlclose(lib_x11);
|
|
return 0;
|
|
}
|
|
|
|
double
|
|
_vsync_wait_glx(void)
|
|
{
|
|
double t;
|
|
unsigned int rc = 0;
|
|
|
|
sym_glXMakeContextCurrent(disp, gwin, gwin, context);
|
|
sym_glXGetVideoSyncSGI(&rc);
|
|
sym_glXWaitVideoSyncSGI(1, 0, &rc);
|
|
t = ecore_time_get();
|
|
return t;
|
|
}
|