int X11_GL_LoadLibrary(_THIS, const char *path) { Display *display; void *handle; if (_this->gl_data) { return SDL_SetError("OpenGL context already created"); } /* Load the OpenGL library */ if (path == NULL) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); } if (path == NULL) { path = DEFAULT_OPENGL; } _this->gl_config.dll_handle = GL_LoadObject(path); if (!_this->gl_config.dll_handle) { #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) SDL_SetError("Failed loading %s: %s", path, dlerror()); #endif return -1; } SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); /* Allocate OpenGL memory */ _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData)); if (!_this->gl_data) { return SDL_OutOfMemory(); } /* Load function pointers */ handle = _this->gl_config.dll_handle; _this->gl_data->glXQueryExtension = (Bool (*)(Display *, int *, int *)) GL_LoadFunction(handle, "glXQueryExtension"); _this->gl_data->glXGetProcAddress = (void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB"); _this->gl_data->glXChooseVisual = (XVisualInfo * (*)(Display *, int, int *)) X11_GL_GetProcAddress(_this, "glXChooseVisual"); _this->gl_data->glXCreateContext = (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int)) X11_GL_GetProcAddress(_this, "glXCreateContext"); _this->gl_data->glXDestroyContext = (void (*)(Display *, GLXContext)) X11_GL_GetProcAddress(_this, "glXDestroyContext"); _this->gl_data->glXMakeCurrent = (int (*)(Display *, GLXDrawable, GLXContext)) X11_GL_GetProcAddress(_this, "glXMakeCurrent"); _this->gl_data->glXSwapBuffers = (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(_this, "glXSwapBuffers"); _this->gl_data->glXQueryDrawable = (void (*)(Display*,GLXDrawable,int,unsigned int*)) X11_GL_GetProcAddress(_this, "glXQueryDrawable"); if (!_this->gl_data->glXQueryExtension || !_this->gl_data->glXChooseVisual || !_this->gl_data->glXCreateContext || !_this->gl_data->glXDestroyContext || !_this->gl_data->glXMakeCurrent || !_this->gl_data->glXSwapBuffers) { return SDL_SetError("Could not retrieve OpenGL functions"); } display = ((SDL_VideoData *) _this->driverdata)->display; if (!_this->gl_data->glXQueryExtension(display, &_this->gl_data->errorBase, &_this->gl_data->eventBase)) { return SDL_SetError("GLX is not supported"); } /* Initialize extensions */ X11_GL_InitExtensions(_this); /* If SDL_GL_CONTEXT_EGL has been changed to 1, and there's * no GLX_EXT_create_context_es2_profile extension switch over to X11_GLES functions */ if (_this->gl_config.use_egl == 1) { if (_this->gl_data->HAS_GLX_EXT_create_context_es2_profile) { /* We cheat a little bit here by using GLX instead of EGL * to improve our chances of getting hardware acceleration */ _this->gl_config.use_egl = 0; _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; } else { #if SDL_VIDEO_OPENGL_EGL X11_GL_UnloadLibrary(_this); /* Better avoid conflicts! */ if (_this->gl_config.dll_handle != NULL ) { GL_UnloadObject(_this->gl_config.dll_handle); _this->gl_config.dll_handle = NULL; } _this->GL_LoadLibrary = X11_GLES_LoadLibrary; _this->GL_GetProcAddress = X11_GLES_GetProcAddress; _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; _this->GL_CreateContext = X11_GLES_CreateContext; _this->GL_MakeCurrent = X11_GLES_MakeCurrent; _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; _this->GL_SwapWindow = X11_GLES_SwapWindow; _this->GL_DeleteContext = X11_GLES_DeleteContext; return X11_GLES_LoadLibrary(_this, NULL); #else return SDL_SetError("SDL not configured with EGL support"); #endif } } return 0; }
XVisualInfo * X11_GLES_GetVisual(_THIS, Display * display, int screen) { /* 64 seems nice. */ EGLint attribs[64]; EGLint found_configs = 0; VisualID visual_id; int i; /* load the gl driver from a default path */ if (!_this->gl_config.driver_loaded) { /* no driver has been loaded, use default (ourselves) */ if (X11_GLES_LoadLibrary(_this, NULL) < 0) { return NULL; } } i = 0; attribs[i++] = EGL_RED_SIZE; attribs[i++] = _this->gl_config.red_size; attribs[i++] = EGL_GREEN_SIZE; attribs[i++] = _this->gl_config.green_size; attribs[i++] = EGL_BLUE_SIZE; attribs[i++] = _this->gl_config.blue_size; if (_this->gl_config.alpha_size) { attribs[i++] = EGL_ALPHA_SIZE; attribs[i++] = _this->gl_config.alpha_size; } if (_this->gl_config.buffer_size) { attribs[i++] = EGL_BUFFER_SIZE; attribs[i++] = _this->gl_config.buffer_size; } attribs[i++] = EGL_DEPTH_SIZE; attribs[i++] = _this->gl_config.depth_size; if (_this->gl_config.stencil_size) { attribs[i++] = EGL_STENCIL_SIZE; attribs[i++] = _this->gl_config.stencil_size; } if (_this->gl_config.multisamplebuffers) { attribs[i++] = EGL_SAMPLE_BUFFERS; attribs[i++] = _this->gl_config.multisamplebuffers; } if (_this->gl_config.multisamplesamples) { attribs[i++] = EGL_SAMPLES; attribs[i++] = _this->gl_config.multisamplesamples; } attribs[i++] = EGL_NONE; if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display, attribs, &_this->gles_data->egl_config, 1, &found_configs) == EGL_FALSE || found_configs == 0) { SDL_SetError("Couldn't find matching EGL config"); return NULL; } if (_this->gles_data->eglGetConfigAttrib(_this->gles_data->egl_display, _this->gles_data->egl_config, EGL_NATIVE_VISUAL_ID, (EGLint *) & visual_id) == EGL_FALSE || !visual_id) { /* Use the default visual when all else fails */ XVisualInfo vi_in; int out_count; vi_in.screen = screen; _this->gles_data->egl_visualinfo = XGetVisualInfo(display, VisualScreenMask, &vi_in, &out_count); } else { XVisualInfo vi_in; int out_count; vi_in.screen = screen; vi_in.visualid = visual_id; _this->gles_data->egl_visualinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &vi_in, &out_count); } return _this->gles_data->egl_visualinfo; }
int X11_GL_LoadLibrary(_THIS, const char *path) { void *handle; if (_this->gl_data) { return SDL_SetError("OpenGL context already created"); } /* If SDL_GL_CONTEXT_EGL has been changed to 1, switch over to X11_GLES functions */ if (_this->gl_config.use_egl == 1) { #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 _this->GL_LoadLibrary = X11_GLES_LoadLibrary; _this->GL_GetProcAddress = X11_GLES_GetProcAddress; _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; _this->GL_CreateContext = X11_GLES_CreateContext; _this->GL_MakeCurrent = X11_GLES_MakeCurrent; _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; _this->GL_SwapWindow = X11_GLES_SwapWindow; _this->GL_DeleteContext = X11_GLES_DeleteContext; return X11_GLES_LoadLibrary(_this, path); #else return SDL_SetError("SDL not configured with OpenGL ES/EGL support"); #endif } /* Load the OpenGL library */ if (path == NULL) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); } if (path == NULL) { path = DEFAULT_OPENGL; } _this->gl_config.dll_handle = GL_LoadObject(path); if (!_this->gl_config.dll_handle) { #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) SDL_SetError("Failed loading %s: %s", path, dlerror()); #endif return -1; } SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); /* Allocate OpenGL memory */ _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData)); if (!_this->gl_data) { return SDL_OutOfMemory(); } /* Load function pointers */ handle = _this->gl_config.dll_handle; _this->gl_data->glXGetProcAddress = (void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB"); _this->gl_data->glXChooseVisual = (XVisualInfo * (*)(Display *, int, int *)) X11_GL_GetProcAddress(_this, "glXChooseVisual"); _this->gl_data->glXCreateContext = (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int)) X11_GL_GetProcAddress(_this, "glXCreateContext"); _this->gl_data->glXDestroyContext = (void (*)(Display *, GLXContext)) X11_GL_GetProcAddress(_this, "glXDestroyContext"); _this->gl_data->glXMakeCurrent = (int (*)(Display *, GLXDrawable, GLXContext)) X11_GL_GetProcAddress(_this, "glXMakeCurrent"); _this->gl_data->glXSwapBuffers = (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(_this, "glXSwapBuffers"); _this->gl_data->glXQueryDrawable = (void (*)(Display*,GLXDrawable,int,unsigned int*)) X11_GL_GetProcAddress(_this, "glXQueryDrawable"); if (!_this->gl_data->glXChooseVisual || !_this->gl_data->glXCreateContext || !_this->gl_data->glXDestroyContext || !_this->gl_data->glXMakeCurrent || !_this->gl_data->glXSwapBuffers) { return SDL_SetError("Could not retrieve OpenGL functions"); } /* Initialize extensions */ X11_GL_InitExtensions(_this); return 0; }