|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
[PATCH 0/7] egl_glx: big cleanupHi,
This patch series cleans up egl_glx driver. There are mainly four changes. First, fbconfigs and visuals are now carefully parsed, and fixed, to make sure all resulting EGLConfigs are valid. And there are some quirk fixes to workaround GLX bugs. For example, there may be no config that reports pbuffer support. Or, binding a drawable from glXCreateWindow to a direct context causes a BadDrawable error. Pixmap and pbuffer surface support is added to GLX < 1.3. Extensions are now detected, so that the right function calls are issued. The limitation that context must be direct is removed. And there is now support for eglWaitNative and eglWaitClient, which wrap glXWaitX and glXWaitGL. The last patch updates xeglgears to support pixmap and pbuffer surfaces. Pbuffer is partially supported because it uses eglCopyBuffers which is not implemented by any driver. This is tested with xserver 1.6.3 (GLX 1.2) and xserver git master (GLX 1.4), with i915 driver. It works with NVIDIA GL/GLX driver too. IMHO, EGL should wrap GLX, like this driver does, when the native window system is X. With these cleanups in place, egl_glx should be in a good shape. -- Regards, olv >From 20a51a1584959d3599c41e6a8bee43edace6f71b Mon Sep 17 00:00:00 2001 From: Chia-I Wu <olvaffe@...> Date: Fri, 16 Oct 2009 12:18:25 +0800 Subject: [PATCH 1/7] egl: Correct conversion of native visual type. Signed-off-by: Chia-I Wu <olvaffe@...> --- src/egl/main/eglconfigutil.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/src/egl/main/eglconfigutil.c b/src/egl/main/eglconfigutil.c index a5fcdcd..36e94f0 100644 --- a/src/egl/main/eglconfigutil.c +++ b/src/egl/main/eglconfigutil.c @@ -102,7 +102,12 @@ _eglConfigFromContextModesRec(_EGLConfig *conf, const __GLcontextModes *m, SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, m->xRenderable); SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_ID, m->visualID); - SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE, m->visualType); + + if (m->visualType != GLX_NONE) + SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE, m->visualType); + else + SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); + SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, renderable_type); SET_CONFIG_ATTRIB(conf, EGL_SAMPLE_BUFFERS, m->sampleBuffers); SET_CONFIG_ATTRIB(conf, EGL_SAMPLES, m->samples); -- 1.6.3.3 >From 3b0196363ce93c652e125edf8f1be5a980ebce76 Mon Sep 17 00:00:00 2001 From: Chia-I Wu <olvaffe@...> Date: Thu, 1 Oct 2009 18:16:10 +0800 Subject: [PATCH 2/7] egl_glx: Clean up the initialization code. Proper detection of GLX extensions. Convert fbconfigs or visuals in a more unified way and validate the resulting configs. Signed-off-by: Chia-I Wu <olvaffe@...> --- src/egl/drivers/glx/egl_glx.c | 658 +++++++++++++++++++++++------------------ 1 files changed, 371 insertions(+), 287 deletions(-) diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 4685f60..404c998 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -40,16 +40,14 @@ */ -#include <assert.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include "dlfcn.h" +#include <stdlib.h> +#include <string.h> #include <X11/Xlib.h> -#include <GL/gl.h> +#include <dlfcn.h> + #include "glxclient.h" +#include "eglconfigutil.h" #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" @@ -58,46 +56,19 @@ #include "egllog.h" #include "eglsurface.h" -#include <GL/gl.h> - #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -static const EGLint all_apis = (EGL_OPENGL_ES_BIT - | EGL_OPENGL_ES2_BIT - | EGL_OPENVG_BIT - /* | EGL_OPENGL_BIT */); /* can't do */ +#ifndef GLX_VERSION_1_4 +#error "GL/glx.h must be equal to or greater than GLX 1.4" +#endif + +/* + * report OpenGL ES bits because apps usually forget to specify + * EGL_RENDERABLE_TYPE when choosing configs + */ +#define GLX_EGL_APIS (EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT) -struct visual_attribs -{ - /* X visual attribs */ - int id; - int klass; - int depth; - int redMask, greenMask, blueMask; - int colormapSize; - int bitsPerRGB; - - /* GL visual attribs */ - int supportsGL; - int transparentType; - int transparentRedValue; - int transparentGreenValue; - int transparentBlueValue; - int transparentAlphaValue; - int transparentIndexValue; - int bufferSize; - int level; - int render_type; - int doubleBuffer; - int stereo; - int auxBuffers; - int redSize, greenSize, blueSize, alphaSize; - int depthSize; - int stencilSize; - int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize; - int numSamples, numMultisample; - int visualCaveat; -}; /** subclass of _EGLDriver */ struct GLX_egl_driver @@ -114,6 +85,21 @@ struct GLX_egl_display GLXFBConfig *fbconfigs; int glx_maj, glx_min; + + const char *extensions; + EGLBoolean have_1_3; + EGLBoolean have_make_current_read; + EGLBoolean have_fbconfig; + EGLBoolean have_pbuffer; + + /* GLX_SGIX_pbuffer */ + PFNGLXCREATEGLXPBUFFERSGIXPROC glXCreateGLXPbufferSGIX; + PFNGLXDESTROYGLXPBUFFERSGIXPROC glXDestroyGLXPbufferSGIX; + + /* workaround quirks of different GLX implementations */ + EGLBoolean single_buffered_quirk; + EGLBoolean glx_window_quirk; + }; @@ -139,6 +125,7 @@ struct GLX_egl_surface struct GLX_egl_config { _EGLConfig Base; /**< base class */ + EGLBoolean double_buffered; int index; }; @@ -173,288 +160,369 @@ GLX_egl_config_index(_EGLConfig *conf) return ((struct GLX_egl_config *) conf)->index; } -static GLboolean -get_visual_attribs(Display *dpy, XVisualInfo *vInfo, - struct visual_attribs *attribs) -{ - const char *ext = glXQueryExtensionsString(dpy, vInfo->screen); - int rgba; - memset(attribs, 0, sizeof(struct visual_attribs)); +#define MAP_ATTRIB(attr, memb) \ + { attr, offsetof(__GLcontextModes, memb) } + + +static const struct { + int attr; + int offset; +} fbconfig_attributes[] = { + /* table 3.1 of GLX 1.4 */ + MAP_ATTRIB(GLX_FBCONFIG_ID, fbconfigID), + MAP_ATTRIB(GLX_BUFFER_SIZE, rgbBits), + MAP_ATTRIB(GLX_LEVEL, level), + MAP_ATTRIB(GLX_DOUBLEBUFFER, doubleBufferMode), + MAP_ATTRIB(GLX_STEREO, stereoMode), + MAP_ATTRIB(GLX_AUX_BUFFERS, numAuxBuffers), + MAP_ATTRIB(GLX_RED_SIZE, redBits), + MAP_ATTRIB(GLX_GREEN_SIZE, greenBits), + MAP_ATTRIB(GLX_BLUE_SIZE, blueBits), + MAP_ATTRIB(GLX_ALPHA_SIZE, alphaBits), + MAP_ATTRIB(GLX_DEPTH_SIZE, depthBits), + MAP_ATTRIB(GLX_STENCIL_SIZE, stencilBits), + MAP_ATTRIB(GLX_ACCUM_RED_SIZE, accumRedBits), + MAP_ATTRIB(GLX_ACCUM_GREEN_SIZE, accumGreenBits), + MAP_ATTRIB(GLX_ACCUM_BLUE_SIZE, accumBlueBits), + MAP_ATTRIB(GLX_ACCUM_ALPHA_SIZE, accumAlphaBits), + MAP_ATTRIB(GLX_SAMPLE_BUFFERS, sampleBuffers), + MAP_ATTRIB(GLX_SAMPLES, samples), + MAP_ATTRIB(GLX_RENDER_TYPE, renderType), + MAP_ATTRIB(GLX_DRAWABLE_TYPE, drawableType), + MAP_ATTRIB(GLX_X_RENDERABLE, xRenderable), + MAP_ATTRIB(GLX_X_VISUAL_TYPE, visualType), + MAP_ATTRIB(GLX_CONFIG_CAVEAT, visualRating), + MAP_ATTRIB(GLX_TRANSPARENT_TYPE, transparentPixel), + MAP_ATTRIB(GLX_TRANSPARENT_INDEX_VALUE, transparentIndex), + MAP_ATTRIB(GLX_TRANSPARENT_RED_VALUE, transparentRed), + MAP_ATTRIB(GLX_TRANSPARENT_GREEN_VALUE, transparentGreen), + MAP_ATTRIB(GLX_TRANSPARENT_BLUE_VALUE, transparentBlue), + MAP_ATTRIB(GLX_TRANSPARENT_ALPHA_VALUE, transparentAlpha), + MAP_ATTRIB(GLX_MAX_PBUFFER_WIDTH, maxPbufferWidth), + MAP_ATTRIB(GLX_MAX_PBUFFER_HEIGHT, maxPbufferHeight), + MAP_ATTRIB(GLX_MAX_PBUFFER_PIXELS, maxPbufferPixels), + MAP_ATTRIB(GLX_VISUAL_ID, visualID), +}; - attribs->id = vInfo->visualid; -#if defined(__cplusplus) || defined(c_plusplus) - attribs->klass = vInfo->c_class; -#else - attribs->klass = vInfo->class; -#endif - attribs->depth = vInfo->depth; - attribs->redMask = vInfo->red_mask; - attribs->greenMask = vInfo->green_mask; - attribs->blueMask = vInfo->blue_mask; - attribs->colormapSize = vInfo->colormap_size; - attribs->bitsPerRGB = vInfo->bits_per_rgb; - - if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0 || - !attribs->supportsGL) - return GL_FALSE; - glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize); - glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level); - glXGetConfig(dpy, vInfo, GLX_RGBA, &rgba); - if (!rgba) - return GL_FALSE; - attribs->render_type = GLX_RGBA_BIT; - - glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer); - if (!attribs->doubleBuffer) - return GL_FALSE; - - glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo); - glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers); - glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize); - glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize); - glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize); - glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize); - glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize); - glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize); - glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize); - glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize); - glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize); - glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize); - - /* get transparent pixel stuff */ - glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType); - if (attribs->transparentType == GLX_TRANSPARENT_RGB) { - glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue); - glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue); - glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue); - glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue); - } - else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) { - glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue); - } - /* multisample attribs */ -#ifdef GLX_ARB_multisample - if (ext && strstr(ext, "GLX_ARB_multisample")) { - glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample); - glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples); - } -#endif - else { - attribs->numSamples = 0; - attribs->numMultisample = 0; +static EGLBoolean +convert_fbconfig(Display *dpy, GLXFBConfig fbconfig, + struct GLX_egl_config *GLX_conf) +{ + __GLcontextModes mode; + int err = 0, attr, val, i; + + memset(&mode, 0, sizeof(mode)); + + for (i = 0; i < ARRAY_SIZE(fbconfig_attributes); i++) { + int offset = fbconfig_attributes[i].offset; + attr = fbconfig_attributes[i].attr; + err = glXGetFBConfigAttrib(dpy, fbconfig, attr, &val); + if (err) { + if (err == GLX_BAD_ATTRIBUTE) { + err = 0; + continue; + } + break; + } + *((int *) ((char *) &mode + offset)) = val; } + if (err) + return EGL_FALSE; -#if defined(GLX_EXT_visual_rating) - if (ext && strstr(ext, "GLX_EXT_visual_rating")) { - glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat); - } - else { - attribs->visualCaveat = GLX_NONE_EXT; + /* must have rgba bit */ + if (!(mode.renderType & GLX_RGBA_BIT)) + return EGL_FALSE; + + /* pixmap and pbuffer surfaces must be single-buffered in EGL */ + if (mode.doubleBufferMode) { + mode.drawableType &= ~(GLX_PIXMAP_BIT | GLX_PBUFFER_BIT); + if (!mode.drawableType) + return EGL_FALSE; } -#else - attribs->visualCaveat = 0; -#endif - return GL_TRUE; + mode.rgbMode = GL_TRUE; + mode.haveAccumBuffer = (mode.accumRedBits + + mode.accumGreenBits + + mode.accumBlueBits + + mode.accumAlphaBits > 0); + mode.haveDepthBuffer = (mode.depthBits > 0); + mode.haveStencilBuffer = (mode.stencilBits > 0); + + GLX_conf->double_buffered = (mode.doubleBufferMode != 0); + return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode, + GLX_EGL_APIS, GLX_EGL_APIS); } -#ifdef GLX_VERSION_1_3 + +static const struct { + int attr; + int offset; +} visual_attributes[] = { + /* table 3.7 of GLX 1.4 */ + /* no GLX_USE_GL */ + MAP_ATTRIB(GLX_BUFFER_SIZE, rgbBits), + MAP_ATTRIB(GLX_LEVEL, level), + MAP_ATTRIB(GLX_RGBA, rgbMode), + MAP_ATTRIB(GLX_DOUBLEBUFFER, doubleBufferMode), + MAP_ATTRIB(GLX_STEREO, stereoMode), + MAP_ATTRIB(GLX_AUX_BUFFERS, numAuxBuffers), + MAP_ATTRIB(GLX_RED_SIZE, redBits), + MAP_ATTRIB(GLX_GREEN_SIZE, greenBits), + MAP_ATTRIB(GLX_BLUE_SIZE, blueBits), + MAP_ATTRIB(GLX_ALPHA_SIZE, alphaBits), + MAP_ATTRIB(GLX_DEPTH_SIZE, depthBits), + MAP_ATTRIB(GLX_STENCIL_SIZE, stencilBits), + MAP_ATTRIB(GLX_ACCUM_RED_SIZE, accumRedBits), + MAP_ATTRIB(GLX_ACCUM_GREEN_SIZE, accumGreenBits), + MAP_ATTRIB(GLX_ACCUM_BLUE_SIZE, accumBlueBits), + MAP_ATTRIB(GLX_ACCUM_ALPHA_SIZE, accumAlphaBits), + MAP_ATTRIB(GLX_SAMPLE_BUFFERS, sampleBuffers), + MAP_ATTRIB(GLX_SAMPLES, samples), + MAP_ATTRIB(GLX_FBCONFIG_ID, fbconfigID), + /* GLX_EXT_visual_rating */ + MAP_ATTRIB(GLX_VISUAL_CAVEAT_EXT, visualRating), +}; + static int -glx_token_to_visual_class(int visual_type) -{ - switch (visual_type) { - case GLX_TRUE_COLOR: - return TrueColor; - case GLX_DIRECT_COLOR: - return DirectColor; - case GLX_PSEUDO_COLOR: - return PseudoColor; - case GLX_STATIC_COLOR: - return StaticColor; - case GLX_GRAY_SCALE: - return GrayScale; - case GLX_STATIC_GRAY: - return StaticGray; - case GLX_NONE: +get_visual_type(const XVisualInfo *vis) +{ + int klass; + +#if defined(__cplusplus) || defined(c_plusplus) + klass = vis->c_class; +#else + klass = vis->class; +#endif + + switch (klass) { + case TrueColor: + return GLX_TRUE_COLOR; + case DirectColor: + return GLX_DIRECT_COLOR; + case PseudoColor: + return GLX_PSEUDO_COLOR; + case StaticColor: + return GLX_STATIC_COLOR; + case GrayScale: + return GLX_GRAY_SCALE; + case StaticGray: + return GLX_STATIC_GRAY; default: - return None; + return GLX_NONE; } } -static int -get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig, - struct visual_attribs *attribs) -{ - int visual_type; - int fbconfig_id; - memset(attribs, 0, sizeof(struct visual_attribs)); +static EGLBoolean +convert_visual(Display *dpy, XVisualInfo *vinfo, + struct GLX_egl_config *GLX_conf) +{ + __GLcontextModes mode; + int err, attr, val, i; - glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &fbconfig_id); + /* the visual must support OpenGL */ + err = glXGetConfig(dpy, vinfo, GLX_USE_GL, &val); + if (err || !val) + return EGL_FALSE; - glXGetFBConfigAttrib(dpy, fbconfig, GLX_VISUAL_ID, &attribs->id); + memset(&mode, 0, sizeof(mode)); + + for (i = 0; i < ARRAY_SIZE(visual_attributes); i++) { + int offset = visual_attributes[i].offset; + attr = visual_attributes[i].attr; + err = glXGetConfig(dpy, vinfo, attr, &val); + if (err) { + if (err == GLX_BAD_ATTRIBUTE) { + err = 0; + continue; + } + break; + } + *((int *) ((char *) &mode + offset)) = val; + } + if (err) + return EGL_FALSE; -#if 0 - attribs->depth = vInfo->depth; - attribs->redMask = vInfo->red_mask; - attribs->greenMask = vInfo->green_mask; - attribs->blueMask = vInfo->blue_mask; - attribs->colormapSize = vInfo->colormap_size; - attribs->bitsPerRGB = vInfo->bits_per_rgb; -#endif + /* must be RGB mode */ + if (!mode.rgbMode) + return EGL_FALSE; - glXGetFBConfigAttrib(dpy, fbconfig, GLX_X_VISUAL_TYPE, &visual_type); - attribs->klass = glx_token_to_visual_class(visual_type); - - glXGetFBConfigAttrib(dpy, fbconfig, GLX_BUFFER_SIZE, &attribs->bufferSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type); - if (!(attribs->render_type & GLX_RGBA_BIT)) - return 0; - - glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer); - if (!attribs->doubleBuffer) - return 0; - - glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers); - - glXGetFBConfigAttrib(dpy, fbconfig, GLX_RED_SIZE, &attribs->redSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_GREEN_SIZE, &attribs->greenSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_BLUE_SIZE, &attribs->blueSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_ALPHA_SIZE, &attribs->alphaSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_DEPTH_SIZE, &attribs->depthSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_STENCIL_SIZE, &attribs->stencilSize); - - glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize); - - /* get transparent pixel stuff */ - glXGetFBConfigAttrib(dpy, fbconfig,GLX_TRANSPARENT_TYPE, &attribs->transparentType); - if (attribs->transparentType == GLX_TRANSPARENT_RGB) { - glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue); - } - else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) { - glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue); - } + mode.visualID = vinfo->visualid; + mode.visualType = get_visual_type(vinfo); + mode.redMask = vinfo->red_mask; + mode.greenMask = vinfo->green_mask; + mode.blueMask = vinfo->blue_mask; + + mode.drawableType = GLX_WINDOW_BIT; + /* pixmap surfaces must be single-buffered in EGL */ + if (!mode.doubleBufferMode) + mode.drawableType |= GLX_PIXMAP_BIT; + + mode.renderType = GLX_RGBA_BIT; + mode.xRenderable = GL_TRUE; + mode.haveAccumBuffer = (mode.accumRedBits + + mode.accumGreenBits + + mode.accumBlueBits + + mode.accumAlphaBits > 0); + mode.haveDepthBuffer = (mode.depthBits > 0); + mode.haveStencilBuffer = (mode.stencilBits > 0); + + GLX_conf->double_buffered = (mode.doubleBufferMode != 0); + return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode, + GLX_EGL_APIS, GLX_EGL_APIS); +} - glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLE_BUFFERS, &attribs->numMultisample); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples); - glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat); +static void +fix_config(struct GLX_egl_display *GLX_dpy, struct GLX_egl_config *GLX_conf) +{ + _EGLConfig *conf = &GLX_conf->Base; + EGLint surface_type, r, g, b, a; + + surface_type = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE); + if (!GLX_conf->double_buffered && GLX_dpy->single_buffered_quirk) { + /* some GLX impls do not like single-buffered window surface */ + surface_type &= ~EGL_WINDOW_BIT; + /* pbuffer bit is usually not set */ + if (GLX_dpy->have_pbuffer) + surface_type |= EGL_PBUFFER_BIT; + SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, surface_type); + } - if (attribs->id == 0) { - attribs->id = fbconfig_id; - return EGL_PBUFFER_BIT | EGL_PIXMAP_BIT; + /* no visual attribs unless window bit is set */ + if (!(surface_type & EGL_WINDOW_BIT)) { + SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_ID, 0); + SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); } - return EGL_WINDOW_BIT; + /* make sure buffer size is set correctly */ + r = GET_CONFIG_ATTRIB(conf, EGL_RED_SIZE); + g = GET_CONFIG_ATTRIB(conf, EGL_GREEN_SIZE); + b = GET_CONFIG_ATTRIB(conf, EGL_BLUE_SIZE); + a = GET_CONFIG_ATTRIB(conf, EGL_ALPHA_SIZE); + SET_CONFIG_ATTRIB(conf, EGL_BUFFER_SIZE, r + g + b + a); } -#endif static EGLBoolean -create_configs(_EGLDisplay *disp, struct GLX_egl_display *GLX_dpy) +create_configs(_EGLDisplay *dpy, struct GLX_egl_display *GLX_dpy, + EGLint screen) { - XVisualInfo theTemplate; - int numVisuals; - long mask; - int i; - struct visual_attribs attribs; + EGLint num_configs = 0, i; + EGLint id = 1; - GLX_dpy->fbconfigs = NULL; - -#ifdef GLX_VERSION_1_3 - /* get list of all fbconfigs on this screen */ - GLX_dpy->fbconfigs = glXGetFBConfigs(GLX_dpy->dpy, DefaultScreen(GLX_dpy->dpy), &numVisuals); + if (GLX_dpy->have_fbconfig) { + GLX_dpy->fbconfigs = glXGetFBConfigs(GLX_dpy->dpy, screen, &num_configs); + } + else { + XVisualInfo vinfo_template; + long mask; - if (numVisuals == 0) { - GLX_dpy->fbconfigs = NULL; - goto xvisual; + vinfo_template.screen = screen; + mask = VisualScreenMask; + GLX_dpy->visuals = XGetVisualInfo(GLX_dpy->dpy, mask, &vinfo_template, + &num_configs); } - for (i = 0; i < numVisuals; i++) { - struct GLX_egl_config *config; - int bit; + if (!num_configs) + return EGL_FALSE; - bit = get_fbconfig_attribs(GLX_dpy->dpy, GLX_dpy->fbconfigs[i], &attribs); - if (!bit) + for (i = 0; i < num_configs; i++) { + struct GLX_egl_config *GLX_conf, template; + EGLBoolean ok; + + memset(&template, 0, sizeof(template)); + _eglInitConfig(&template.Base, id); + if (GLX_dpy->have_fbconfig) + ok = convert_fbconfig(GLX_dpy->dpy, GLX_dpy->fbconfigs[i], &template); + else + ok = convert_visual(GLX_dpy->dpy, &GLX_dpy->visuals[i], &template); + if (!ok) + continue; + + fix_config(GLX_dpy, &template); + if (!_eglValidateConfig(&template.Base, EGL_FALSE)) { + _eglLog(_EGL_DEBUG, "GLX: failed to validate config %d", i); continue; + } + + GLX_conf = CALLOC_STRUCT(GLX_egl_config); + if (GLX_conf) { + memcpy(GLX_conf, &template, sizeof(template)); + GLX_conf->index = i; - config = CALLOC_STRUCT(GLX_egl_config); - - config->index = i; - _eglInitConfig(&config->Base, (i+1)); - SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id); - SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, attribs.redSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_GREEN_SIZE, attribs.greenSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_BLUE_SIZE, attribs.blueSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_ALPHA_SIZE, attribs.alphaSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_DEPTH_SIZE, attribs.depthSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_STENCIL_SIZE, attribs.stencilSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLES, attribs.numSamples); - SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLE_BUFFERS, attribs.numMultisample); - SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis); - SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis); - SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, bit); - - /* XXX possibly other things to init... */ - - _eglAddConfig(disp, &config->Base); + _eglAddConfig(dpy, &GLX_conf->Base); + id++; + } } - goto end; -#endif + return EGL_TRUE; +} + + +static void +check_extensions(struct GLX_egl_display *GLX_dpy, EGLint screen) +{ + GLX_dpy->extensions = + glXQueryExtensionsString(GLX_dpy->dpy, screen); + if (GLX_dpy->extensions) { + /* glXGetProcAddress is assumed */ + + if (strstr(GLX_dpy->extensions, "GLX_SGI_make_current_read")) { + /* GLX 1.3 entry points are used */ + GLX_dpy->have_make_current_read = EGL_TRUE; + } -xvisual: - /* get list of all visuals on this screen */ - theTemplate.screen = DefaultScreen(GLX_dpy->dpy); - mask = VisualScreenMask; - GLX_dpy->visuals = XGetVisualInfo(GLX_dpy->dpy, mask, &theTemplate, &numVisuals); - - for (i = 0; i < numVisuals; i++) { - struct GLX_egl_config *config; - - if (!get_visual_attribs(GLX_dpy->dpy, &GLX_dpy->visuals[i], &attribs)) - continue; - - config = CALLOC_STRUCT(GLX_egl_config); - - config->index = i; - _eglInitConfig(&config->Base, (i+1)); - SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id); - SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_RED_SIZE, attribs.redSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_GREEN_SIZE, attribs.greenSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_BLUE_SIZE, attribs.blueSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_ALPHA_SIZE, attribs.alphaSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_DEPTH_SIZE, attribs.depthSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_STENCIL_SIZE, attribs.stencilSize); - SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLES, attribs.numSamples); - SET_CONFIG_ATTRIB(&config->Base, EGL_SAMPLE_BUFFERS, attribs.numMultisample); - SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis); - SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis); - SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, - (EGL_WINDOW_BIT /*| EGL_PBUFFER_BIT | EGL_PIXMAP_BIT*/)); - - /* XXX possibly other things to init... */ - - _eglAddConfig(disp, &config->Base); + if (strstr(GLX_dpy->extensions, "GLX_SGIX_fbconfig")) { + /* GLX 1.3 entry points are used */ + GLX_dpy->have_fbconfig = EGL_TRUE; + } + + if (strstr(GLX_dpy->extensions, "GLX_SGIX_pbuffer")) { + GLX_dpy->glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC) + glXGetProcAddress((const GLubyte *) "glXCreateGLXPbufferSGIX"); + GLX_dpy->glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC) + glXGetProcAddress((const GLubyte *) "glXDestroyGLXPbufferSGIX"); + + if (GLX_dpy->glXCreateGLXPbufferSGIX && + GLX_dpy->glXDestroyGLXPbufferSGIX && + GLX_dpy->have_fbconfig) + GLX_dpy->have_pbuffer = EGL_TRUE; + } } -end: - return EGL_TRUE; + if (GLX_dpy->glx_maj == 1 && GLX_dpy->glx_min >= 3) { + GLX_dpy->have_1_3 = EGL_TRUE; + GLX_dpy->have_make_current_read = EGL_TRUE; + GLX_dpy->have_fbconfig = EGL_TRUE; + GLX_dpy->have_pbuffer = EGL_TRUE; + } +} + + +static void +check_quirks(struct GLX_egl_display *GLX_dpy, EGLint screen) +{ + const char *vendor; + + GLX_dpy->single_buffered_quirk = EGL_TRUE; + GLX_dpy->glx_window_quirk = EGL_TRUE; + + vendor = glXGetClientString(GLX_dpy->dpy, GLX_VENDOR); + if (vendor && strstr(vendor, "NVIDIA")) { + vendor = glXQueryServerString(GLX_dpy->dpy, screen, GLX_VENDOR); + if (vendor && strstr(vendor, "NVIDIA")) { + _eglLog(_EGL_DEBUG, "disable quirks"); + GLX_dpy->single_buffered_quirk = EGL_FALSE; + GLX_dpy->glx_window_quirk = EGL_FALSE; + } + } } + /** * Called via eglInitialize(), GLX_drv->API.Initialize(). */ @@ -478,17 +546,33 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp, } } - disp->DriverData = (void *) GLX_dpy; - disp->ClientAPIsMask = all_apis; + if (!glXQueryVersion(GLX_dpy->dpy, &GLX_dpy->glx_maj, &GLX_dpy->glx_min)) { + _eglLog(_EGL_WARNING, "GLX: glXQueryVersion failed"); + if (!disp->NativeDisplay) + XCloseDisplay(GLX_dpy->dpy); + free(GLX_dpy); + return EGL_FALSE; + } - glXQueryVersion(GLX_dpy->dpy, &GLX_dpy->glx_maj, &GLX_dpy->glx_min); + check_extensions(GLX_dpy, DefaultScreen(GLX_dpy->dpy)); + check_quirks(GLX_dpy, DefaultScreen(GLX_dpy->dpy)); + + create_configs(disp, GLX_dpy, DefaultScreen(GLX_dpy->dpy)); + if (!disp->NumConfigs) { + _eglLog(_EGL_WARNING, "GLX: failed to create any config"); + if (!disp->NativeDisplay) + XCloseDisplay(GLX_dpy->dpy); + free(GLX_dpy); + return EGL_FALSE; + } + + disp->DriverData = (void *) GLX_dpy; + disp->ClientAPIsMask = GLX_EGL_APIS; /* we're supporting EGL 1.4 */ *major = 1; *minor = 4; - create_configs(disp, GLX_dpy); - return EGL_TRUE; } -- 1.6.3.3 >From 4a9d38c787cafd1636c7763606af9662de97d5e1 Mon Sep 17 00:00:00 2001 From: Chia-I Wu <olvaffe@...> Date: Thu, 1 Oct 2009 18:22:33 +0800 Subject: [PATCH 3/7] egl_glx: Clean up surface functions. Separete Drawable and GLXDrawable. Add support for pbuffer and pixmap surfaces on GLX <= 1.3. Remove surface binding code that will never work. Signed-off-by: Chia-I Wu <olvaffe@...> --- src/egl/drivers/glx/egl_glx.c | 205 +++++++++++++++++++++-------------------- 1 files changed, 106 insertions(+), 99 deletions(-) diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 404c998..e09cbe7 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -33,20 +33,12 @@ * Authors: Alan Hourihane <alanh@...> */ -/* - * TODO: - * - * test eglBind/ReleaseTexImage - */ - - #include <stdlib.h> #include <string.h> #include <X11/Xlib.h> +#include <GL/glx.h> #include <dlfcn.h> -#include "glxclient.h" - #include "eglconfigutil.h" #include "eglconfig.h" #include "eglcontext.h" @@ -117,7 +109,8 @@ struct GLX_egl_surface { _EGLSurface Base; /**< base class */ - GLXDrawable drawable; + Drawable drawable; + GLXDrawable glx_drawable; }; @@ -673,8 +666,8 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx)) return EGL_FALSE; - ddraw = (GLX_dsurf) ? GLX_dsurf->drawable : None; - rdraw = (GLX_rsurf) ? GLX_rsurf->drawable : None; + ddraw = (GLX_dsurf) ? GLX_dsurf->glx_drawable : None; + rdraw = (GLX_rsurf) ? GLX_rsurf->glx_drawable : None; cctx = (GLX_ctx) ? GLX_ctx->context : NULL; #ifdef GLX_VERSION_1_3 @@ -726,6 +719,20 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, } GLX_surf->drawable = window; + + if (GLX_dpy->have_1_3 && !GLX_dpy->glx_window_quirk) + GLX_surf->glx_drawable = + glXCreateWindow(GLX_dpy->dpy, + GLX_dpy->fbconfigs[GLX_egl_config_index(conf)], + GLX_surf->drawable, NULL); + else + GLX_surf->glx_drawable = GLX_surf->drawable; + + if (!GLX_surf->glx_drawable) { + free(GLX_surf); + return NULL; + } + get_drawable_size(GLX_dpy->dpy, window, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; @@ -733,18 +740,13 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return &GLX_surf->Base; } -#ifdef GLX_VERSION_1_3 static _EGLSurface * GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; - int i; - - /* GLX must >= 1.3 */ - if (!(GLX_dpy->glx_maj == 1 && GLX_dpy->glx_min >= 3)) - return NULL; + uint width, height; GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) { @@ -758,25 +760,39 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs at this time */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface"); - free(GLX_surf); - return NULL; + GLX_surf->drawable = pixmap; + + if (GLX_dpy->have_1_3) { + GLX_surf->glx_drawable = + glXCreatePixmap(GLX_dpy->dpy, + GLX_dpy->fbconfigs[GLX_egl_config_index(conf)], + GLX_surf->drawable, NULL); + } + else if (GLX_dpy->have_fbconfig) { + GLXFBConfig fbconfig = GLX_dpy->fbconfigs[GLX_egl_config_index(conf)]; + XVisualInfo *vinfo = glXGetVisualFromFBConfig(GLX_dpy->dpy, fbconfig); + if (vinfo) { + GLX_surf->glx_drawable = + glXCreateGLXPixmap(GLX_dpy->dpy, vinfo, GLX_surf->drawable); + XFree(vinfo); } } + else { + GLX_surf->glx_drawable = + glXCreateGLXPixmap(GLX_dpy->dpy, + &GLX_dpy->visuals[GLX_egl_config_index(conf)], + GLX_surf->drawable); + } - GLX_surf->drawable = - glXCreatePixmap(GLX_dpy->dpy, - GLX_dpy->fbconfigs[GLX_egl_config_index(conf)], - pixmap, NULL); - if (!GLX_surf->drawable) { + if (!GLX_surf->glx_drawable) { free(GLX_surf); return NULL; } + get_drawable_size(GLX_dpy->dpy, pixmap, &width, &height); + GLX_surf->Base.Width = width; + GLX_surf->Base.Height = height; + return &GLX_surf->Base; } @@ -787,11 +803,7 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; int attribs[5]; - int i = 0, j = 0; - - /* GLX must >= 1.3 */ - if (!(GLX_dpy->glx_maj == 1 && GLX_dpy->glx_min >= 3)) - return NULL; + int i; GLX_surf = CALLOC_STRUCT(GLX_egl_surface); if (!GLX_surf) { @@ -805,33 +817,44 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } - while(attrib_list[i] != EGL_NONE) { - switch (attrib_list[i]) { - case EGL_WIDTH: - attribs[j++] = GLX_PBUFFER_WIDTH; - attribs[j++] = attrib_list[i+1]; - break; - case EGL_HEIGHT: - attribs[j++] = GLX_PBUFFER_HEIGHT; - attribs[j++] = attrib_list[i+1]; - break; + i = 0; + attribs[i] = None; + + GLX_surf->drawable = None; + + if (GLX_dpy->have_1_3) { + /* put geometry in attribs */ + if (GLX_surf->Base.Width) { + attribs[i++] = GLX_PBUFFER_WIDTH; + attribs[i++] = GLX_surf->Base.Width; + } + if (GLX_surf->Base.Height) { + attribs[i++] = GLX_PBUFFER_HEIGHT; + attribs[i++] = GLX_surf->Base.Height; } - i++; + attribs[i] = None; + + GLX_surf->glx_drawable = + glXCreatePbuffer(GLX_dpy->dpy, + GLX_dpy->fbconfigs[GLX_egl_config_index(conf)], + attribs); + } + else if (GLX_dpy->have_pbuffer) { + GLX_surf->glx_drawable = GLX_dpy->glXCreateGLXPbufferSGIX( + GLX_dpy->dpy, + GLX_dpy->fbconfigs[GLX_egl_config_index(conf)], + GLX_surf->Base.Width, + GLX_surf->Base.Height, + attribs); } - attribs[j++] = 0; - GLX_surf->drawable = - glXCreatePbuffer(GLX_dpy->dpy, - GLX_dpy->fbconfigs[GLX_egl_config_index(conf)], - attribs); - if (!GLX_surf->drawable) { + if (!GLX_surf->glx_drawable) { free(GLX_surf); return NULL; } return &GLX_surf->Base; } -#endif static EGLBoolean GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) @@ -839,15 +862,35 @@ GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); if (!_eglIsSurfaceBound(surf)) { struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); - switch (surf->Type) { - case EGL_PBUFFER_BIT: - glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->drawable); - break; - case EGL_PIXMAP_BIT: - glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->drawable); - break; - default: - break; + + if (GLX_dpy->have_1_3) { + switch (surf->Type) { + case EGL_WINDOW_BIT: + if (!GLX_dpy->glx_window_quirk) + glXDestroyWindow(GLX_dpy->dpy, GLX_surf->glx_drawable); + break; + case EGL_PBUFFER_BIT: + glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->glx_drawable); + break; + case EGL_PIXMAP_BIT: + glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); + break; + default: + break; + } + } + else { + switch (surf->Type) { + case EGL_PBUFFER_BIT: + GLX_dpy->glXDestroyGLXPbufferSGIX(GLX_dpy->dpy, + GLX_surf->glx_drawable); + break; + case EGL_PIXMAP_BIT: + glXDestroyGLXPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); + break; + default: + break; + } } free(surf); } @@ -857,44 +900,12 @@ GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) static EGLBoolean -GLX_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, - EGLint buffer) -{ - struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); - struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); - - /* buffer ?? */ - glXBindTexImageEXT(GLX_dpy->dpy, GLX_surf->drawable, - GLX_FRONT_LEFT_EXT, NULL); - - return EGL_TRUE; -} - - -static EGLBoolean -GLX_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, - EGLint buffer) -{ - struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); - struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); - - /* buffer ?? */ - glXReleaseTexImageEXT(GLX_dpy->dpy, GLX_surf->drawable, - GLX_FRONT_LEFT_EXT); - - return EGL_TRUE; -} - - -static EGLBoolean GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf = GLX_egl_surface(draw); - _eglLog(_EGL_DEBUG, "GLX: EGL SwapBuffers 0x%x",draw); - - glXSwapBuffers(GLX_dpy->dpy, GLX_surf->drawable); + glXSwapBuffers(GLX_dpy->dpy, GLX_surf->glx_drawable); return EGL_TRUE; } @@ -949,13 +960,9 @@ _eglMain(const char *args) GLX_drv->Base.API.CreateContext = GLX_eglCreateContext; GLX_drv->Base.API.MakeCurrent = GLX_eglMakeCurrent; GLX_drv->Base.API.CreateWindowSurface = GLX_eglCreateWindowSurface; -#ifdef GLX_VERSION_1_3 GLX_drv->Base.API.CreatePixmapSurface = GLX_eglCreatePixmapSurface; GLX_drv->Base.API.CreatePbufferSurface = GLX_eglCreatePbufferSurface; -#endif GLX_drv->Base.API.DestroySurface = GLX_eglDestroySurface; - GLX_drv->Base.API.BindTexImage = GLX_eglBindTexImage; - GLX_drv->Base.API.ReleaseTexImage = GLX_eglReleaseTexImage; GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers; GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress; -- 1.6.3.3 >From 5243ef5aa688add39948b149c745d00a8dd0d3b9 Mon Sep 17 00:00:00 2001 From: Chia-I Wu <olvaffe@...> Date: Thu, 1 Oct 2009 18:23:41 +0800 Subject: [PATCH 4/7] egl_glx: Clean up context functions. This lifts the requirement that a context must be direct. Signed-off-by: Chia-I Wu <olvaffe@...> --- src/egl/drivers/glx/egl_glx.c | 24 +++++------------------- 1 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index e09cbe7..aa0c8c8 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -616,8 +616,7 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } -#ifdef GLX_VERSION_1_3 - if (GLX_dpy->fbconfigs) + if (GLX_dpy->have_fbconfig) GLX_ctx->context = glXCreateNewContext(GLX_dpy->dpy, GLX_dpy->fbconfigs[GLX_egl_config_index(conf)], @@ -625,7 +624,6 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE); else -#endif GLX_ctx->context = glXCreateContext(GLX_dpy->dpy, &GLX_dpy->visuals[GLX_egl_config_index(conf)], @@ -636,15 +634,6 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } -#if 1 - /* (maybe?) need to have a direct rendering context */ - if (!glXIsDirect(GLX_dpy->dpy, GLX_ctx->context)) { - glXDestroyContext(GLX_dpy->dpy, GLX_ctx->context); - free(GLX_ctx); - return NULL; - } -#endif - return &GLX_ctx->Base; } @@ -670,13 +659,10 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, rdraw = (GLX_rsurf) ? GLX_rsurf->glx_drawable : None; cctx = (GLX_ctx) ? GLX_ctx->context : NULL; -#ifdef GLX_VERSION_1_3 - if (glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx)) - return EGL_TRUE; -#endif - - if (ddraw == rdraw && glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx)) - return EGL_TRUE; + if (GLX_dpy->have_make_current_read) + return glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx); + else if (ddraw == rdraw) + return glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); return EGL_FALSE; } -- 1.6.3.3 >From 1dfa7c54742201d1ebabe73e41f7a0ed2281f35c Mon Sep 17 00:00:00 2001 From: Chia-I Wu <olvaffe@...> Date: Thu, 1 Oct 2009 18:23:58 +0800 Subject: [PATCH 5/7] egl_glx: Clean up eglGetProcAddress. Signed-off-by: Chia-I Wu <olvaffe@...> --- src/egl/drivers/glx/egl_glx.c | 17 +---------------- 1 files changed, 1 insertions(+), 16 deletions(-) diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index aa0c8c8..71b2618 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -37,7 +37,6 @@ #include <string.h> #include <X11/Xlib.h> #include <GL/glx.h> -#include <dlfcn.h> #include "eglconfigutil.h" #include "eglconfig.h" @@ -902,21 +901,7 @@ GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) static _EGLProc GLX_eglGetProcAddress(const char *procname) { - /* This is a bit of a hack to get at the gallium/Mesa state tracker - * function st_get_proc_address(). This will probably change at - * some point. - */ - _EGLProc (*get_proc_addr)(const char *procname); - _EGLProc proc_addr; - get_proc_addr = dlsym(NULL, "st_get_proc_address"); - if (get_proc_addr) - return get_proc_addr(procname); - - proc_addr = glXGetProcAddress((const GLubyte *)procname); - if (proc_addr) - return proc_addr; - - return (_EGLProc)dlsym(NULL, procname); + return (_EGLProc) glXGetProcAddress((const GLubyte *) procname); } -- 1.6.3.3 >From 07c32b70c515333240bf09a8b35007d46cb421f9 Mon Sep 17 00:00:00 2001 From: Chia-I Wu <olvaffe@...> Date: Fri, 2 Oct 2009 10:38:14 +0800 Subject: [PATCH 6/7] egl_glx: Add support for eglWaitClient and eglWaitNative. Signed-off-by: Chia-I Wu <olvaffe@...> --- src/egl/drivers/glx/egl_glx.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 71b2618..96292b0 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -904,6 +904,21 @@ GLX_eglGetProcAddress(const char *procname) return (_EGLProc) glXGetProcAddress((const GLubyte *) procname); } +static EGLBoolean +GLX_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + glXWaitGL(); + return EGL_TRUE; +} + +static EGLBoolean +GLX_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine) +{ + if (engine != EGL_CORE_NATIVE_ENGINE) + return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); + glXWaitX(); + return EGL_TRUE; +} static void GLX_Unload(_EGLDriver *drv) @@ -936,6 +951,8 @@ _eglMain(const char *args) GLX_drv->Base.API.DestroySurface = GLX_eglDestroySurface; GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers; GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress; + GLX_drv->Base.API.WaitClient = GLX_eglWaitClient; + GLX_drv->Base.API.WaitNative = GLX_eglWaitNative; GLX_drv->Base.Name = "GLX"; GLX_drv->Base.Unload = GLX_Unload; -- 1.6.3.3 >From 3de558aa75f95d2c8baae11f506afef57f7ac3c7 Mon Sep 17 00:00:00 2001 From: Chia-I Wu <olvaffe@...> Date: Sun, 18 Oct 2009 13:15:30 +0800 Subject: [PATCH 7/7] progs/egl: Add support for pixmap and pbuffer surface to xeglgears. Signed-off-by: Chia-I Wu <olvaffe@...> --- progs/egl/xeglgears.c | 399 +++++++++++++++++++++++++++++++++++-------------- 1 files changed, 289 insertions(+), 110 deletions(-) diff --git a/progs/egl/xeglgears.c b/progs/egl/xeglgears.c index 72ed005..614a625 100644 --- a/progs/egl/xeglgears.c +++ b/progs/egl/xeglgears.c @@ -95,9 +95,6 @@ static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; static GLint gear1, gear2, gear3; static GLfloat angle = 0.0; -static GLboolean fullscreen = GL_FALSE; /* Create a single fullscreen window */ - - /* * * Draw a gear wheel. You'll probably want to call this function when @@ -327,122 +324,235 @@ init(void) } -/* - * Create an RGB, double-buffered X window. - * Return the window and context handles. - */ -static void -make_x_window(Display *x_dpy, EGLDisplay egl_dpy, - const char *name, - int x, int y, int width, int height, - Window *winRet, - EGLContext *ctxRet, - EGLSurface *surfRet) -{ - static const EGLint attribs[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - /*EGL_DOUBLEBUFFER,*/ - EGL_DEPTH_SIZE, 1, - EGL_NONE - }; +struct egl_manager { + EGLNativeDisplayType xdpy; + EGLNativeWindowType xwin; + EGLNativePixmapType xpix; - int scrnum; - XSetWindowAttributes attr; - unsigned long mask; - Window root; - Window win; - XVisualInfo *visInfo, visTemplate; - int num_visuals; + EGLDisplay dpy; + EGLConfig conf; EGLContext ctx; - EGLConfig config; - EGLint num_configs, vid; - scrnum = DefaultScreen( x_dpy ); - root = RootWindow( x_dpy, scrnum ); + EGLSurface win; + EGLSurface pix; + EGLSurface pbuf; - if (fullscreen) { - x = 0; y = 0; - width = DisplayWidth( x_dpy, scrnum ); - height = DisplayHeight( x_dpy, scrnum ); + EGLBoolean verbose; + EGLint major, minor; +}; + +static struct egl_manager * +egl_manager_new(EGLNativeDisplayType xdpy, const EGLint *attrib_list, + EGLBoolean verbose) +{ + struct egl_manager *eman; + const char *ver; + EGLint num_conf; + + eman = calloc(1, sizeof(*eman)); + if (!eman) + return NULL; + + eman->verbose = verbose; + eman->xdpy = xdpy; + + eman->dpy = eglGetDisplay(eman->xdpy); + if (eman->dpy == EGL_NO_DISPLAY) { + printf("eglGetDisplay() failed\n"); + free(eman); + return NULL; } - if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { - printf("Error: couldn't get an EGL visual config\n"); - exit(1); + if (!eglInitialize(eman->dpy, &eman->major, &eman->minor)) { + printf("eglInitialize() failed\n"); + free(eman); + return NULL; } - if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { - printf("Error: eglGetConfigAttrib() failed\n"); - exit(1); + ver = eglQueryString(eman->dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", ver); + + if (!eglChooseConfig(eman->dpy, attrib_list, &eman->conf, 1, &num_conf) || + !num_conf) { + printf("eglChooseConfig() failed\n"); + eglTerminate(eman->dpy); + free(eman); + return NULL; } - /* The X window visual must match the EGL config */ - visTemplate.visualid = vid; - visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); - if (!visInfo) { - printf("Error: couldn't get X visual\n"); - exit(1); + eman->ctx = eglCreateContext(eman->dpy, eman->conf, EGL_NO_CONTEXT, NULL); + if (eman->ctx == EGL_NO_CONTEXT) { + printf("eglCreateContext() failed\n"); + eglTerminate(eman->dpy); + free(eman); + return NULL; + } + + return eman; +} + +static EGLBoolean +egl_manager_create_window(struct egl_manager *eman, const char *name, + EGLint w, EGLint h, EGLBoolean need_surface, + EGLBoolean fullscreen, const EGLint *attrib_list) +{ + XVisualInfo vinfo_template, *vinfo = NULL; + EGLint val, num_vinfo; + Window root; + XSetWindowAttributes attrs; + unsigned long mask; + EGLint x = 0, y = 0; + + if (!eglGetConfigAttrib(eman->dpy, eman->conf, + EGL_NATIVE_VISUAL_ID, &val)) { + printf("eglGetConfigAttrib() failed\n"); + return EGL_FALSE; + } + if (val) { + vinfo_template.visualid = (VisualID) val; + vinfo = XGetVisualInfo(eman->xdpy, VisualIDMask, &vinfo_template, &num_vinfo); + } + /* try harder if window surface is not needed */ + if (!vinfo && !need_surface && + eglGetConfigAttrib(eman->dpy, eman->conf, EGL_BUFFER_SIZE, &val)) { + if (val == 32) + val = 24; + vinfo_template.depth = val; + vinfo = XGetVisualInfo(eman->xdpy, VisualDepthMask, &vinfo_template, &num_vinfo); + } + + if (!vinfo) { + printf("XGetVisualInfo() failed\n"); + return EGL_FALSE; + } + + root = DefaultRootWindow(eman->xdpy); + if (fullscreen) { + x = y = 0; + w = DisplayWidth(eman->xdpy, DefaultScreen(eman->xdpy)); + h = DisplayHeight(eman->xdpy, DefaultScreen(eman->xdpy)); } /* window attributes */ - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; - attr.override_redirect = fullscreen; + attrs.background_pixel = 0; + attrs.border_pixel = 0; + attrs.colormap = XCreateColormap(eman->xdpy, root, vinfo->visual, AllocNone); + attrs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + attrs.override_redirect = fullscreen; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect; - win = XCreateWindow( x_dpy, root, 0, 0, width, height, - 0, visInfo->depth, InputOutput, - visInfo->visual, mask, &attr ); + eman->xwin = XCreateWindow(eman->xdpy, root, x, y, w, h, + 0, vinfo->depth, InputOutput, + vinfo->visual, mask, &attrs); + XFree(vinfo); /* set hints and properties */ { XSizeHints sizehints; sizehints.x = x; sizehints.y = y; - sizehints.width = width; - sizehints.height = height; + sizehints.width = w; + sizehints.height = h; sizehints.flags = USSize | USPosition; - XSetNormalHints(x_dpy, win, &sizehints); - XSetStandardProperties(x_dpy, win, name, name, - None, (char **)NULL, 0, &sizehints); + XSetNormalHints(eman->xdpy, eman->xwin, &sizehints); + XSetStandardProperties(eman->xdpy, eman->xwin, name, name, + None, (char **)NULL, 0, &sizehints); } - eglBindAPI(EGL_OPENGL_API); + if (need_surface) { + eman->win = eglCreateWindowSurface(eman->dpy, eman->conf, + eman->xwin, attrib_list); + if (eman->win == EGL_NO_SURFACE) { + printf("eglCreateWindowSurface() failed\n"); + XDestroyWindow(eman->xdpy, eman->xwin); + eman->xwin = None; + return EGL_FALSE; + } + } + + XMapWindow(eman->xdpy, eman->xwin); + + return EGL_TRUE; +} - ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); - if (!ctx) { - printf("Error: glXCreateContext failed\n"); - exit(1); +static EGLBoolean +egl_manager_create_pixmap(struct egl_manager *eman, EGLNativeWindowType xwin, + EGLBoolean need_surface, const EGLint *attrib_list) +{ + XWindowAttributes attrs; + + if (!XGetWindowAttributes(eman->xdpy, xwin, &attrs)) { + printf("XGetWindowAttributes() failed\n"); + return EGL_FALSE; + } + + eman->xpix = XCreatePixmap(eman->xdpy, xwin, + attrs.width, attrs.height, attrs.depth); + + if (need_surface) { + eman->pix = eglCreatePixmapSurface(eman->dpy, eman->conf, + eman->xpix, attrib_list); + if (eman->pix == EGL_NO_SURFACE) { + printf("eglCreatePixmapSurface() failed\n"); + XFreePixmap(eman->xdpy, eman->xpix); + eman->xpix = None; + return EGL_FALSE; + } } - *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + return EGL_TRUE; +} - XFree(visInfo); +static EGLBoolean +egl_manager_create_pbuffer(struct egl_manager *eman, const EGLint *attrib_list) +{ + eman->pbuf = eglCreatePbufferSurface(eman->dpy, eman->conf, attrib_list); + if (eman->pbuf == EGL_NO_SURFACE) { + printf("eglCreatePbufferSurface() failed\n"); + return EGL_FALSE; + } - *winRet = win; - *ctxRet = ctx; + return EGL_TRUE; } +static void +egl_manager_destroy(struct egl_manager *eman) +{ + eglMakeCurrent(eman->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglTerminate(eman->dpy); + + if (eman->xwin != None) + XDestroyWindow(eman->xdpy, eman->xwin); + if (eman->xpix != None) + XFreePixmap(eman->xdpy, eman->xpix); + + free(eman); +} static void -event_loop(Display *dpy, Window win, - EGLDisplay egl_dpy, EGLSurface egl_surf) +event_loop(struct egl_manager *eman, EGLint surface_type, EGLint w, EGLint h) { + GC gc = XCreateGC(eman->xdpy, eman->xwin, 0, NULL); + EGLint orig_w = w, orig_h = h; + + if (surface_type == EGL_PBUFFER_BIT) + printf("there will be no screen update if " + "eglCopyBuffers() is not implemented\n"); + while (1) { - while (XPending(dpy) > 0) { + while (XPending(eman->xdpy) > 0) { XEvent event; - XNextEvent(dpy, &event); + XNextEvent(eman->xdpy, &event); switch (event.type) { - case Expose: + case Expose: /* we'll redraw below */ - break; - case ConfigureNotify: - reshape(event.xconfigure.width, event.xconfigure.height); - break; + break; + case ConfigureNotify: + w = event.xconfigure.width; + h = event.xconfigure.height; + if (surface_type == EGL_WINDOW_BIT) + reshape(w, h); + break; case KeyPress: { char buffer[10]; @@ -476,6 +586,7 @@ event_loop(Display *dpy, Window win, static int frames = 0; static double tRot0 = -1.0, tRate0 = -1.0; double dt, t = current_time(); + int x, y; if (tRot0 < 0.0) tRot0 = t; dt = t - tRot0; @@ -487,7 +598,25 @@ event_loop(Display *dpy, Window win, angle -= 3600.0; draw(); - eglSwapBuffers(egl_dpy, egl_surf); + switch (surface_type) { + case EGL_WINDOW_BIT: + eglSwapBuffers(eman->dpy, eman->win); + break; + case EGL_PBUFFER_BIT: + eglWaitClient(); + if (!eglCopyBuffers(eman->xdpy, eman->pbuf, eman->xpix)) + break; + /* fall through */ + case EGL_PIXMAP_BIT: + eglWaitClient(); + for (x = 0; x < w; x += orig_w) { + for (y = 0; y < h; y += orig_h) { + XCopyArea(eman->xdpy, eman->xpix, eman->xwin, gc, + 0, 0, orig_w, orig_h, x, y); + } + } + break; + } frames++; @@ -503,6 +632,8 @@ event_loop(Display *dpy, Window win, } } } + + XFreeGC(eman->xdpy, gc); } @@ -513,6 +644,8 @@ usage(void) printf(" -display <displayname> set the display to run on\n"); printf(" -fullscreen run in fullscreen mode\n"); printf(" -info display OpenGL renderer info\n"); + printf(" -pixmap use pixmap surface\n"); + printf(" -pbuffer use pbuffer surface\n"); } @@ -521,15 +654,23 @@ main(int argc, char *argv[]) { const int winWidth = 300, winHeight = 300; Display *x_dpy; - Window win; - EGLSurface egl_surf; - EGLContext egl_ctx; - EGLDisplay egl_dpy; char *dpyName = NULL; + struct egl_manager *eman; + EGLint attribs[] = { + EGL_SURFACE_TYPE, 0, /* filled later */ + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_NONE + }; + char win_title[] = "xeglgears (window/pixmap/pbuffer)"; + EGLint surface_type = EGL_WINDOW_BIT; GLboolean printInfo = GL_FALSE; - EGLint egl_major, egl_minor; + GLboolean fullscreen = GL_FALSE; + EGLBoolean ret; int i; - const char *s; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-display") == 0) { @@ -542,12 +683,21 @@ main(int argc, char *argv[]) else if (strcmp(argv[i], "-fullscreen") == 0) { fullscreen = GL_TRUE; } + else if (strcmp(argv[i], "-pixmap") == 0) { + surface_type = EGL_PIXMAP_BIT; + } + else if (strcmp(argv[i], "-pbuffer") == 0) { + surface_type = EGL_PBUFFER_BIT; + } else { usage(); return -1; } } + /* set surface type */ + attribs[1] = surface_type; + x_dpy = XOpenDisplay(dpyName); if (!x_dpy) { printf("Error: couldn't open display %s\n", @@ -555,26 +705,60 @@ main(int argc, char *argv[]) return -1; } - egl_dpy = eglGetDisplay(x_dpy); - if (!egl_dpy) { - printf("Error: eglGetDisplay() failed\n"); - return -1; - } + eglBindAPI(EGL_OPENGL_API); - if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { - printf("Error: eglInitialize() failed\n"); + eman = egl_manager_new(x_dpy, attribs, printInfo); + if (!eman) { + XCloseDisplay(x_dpy); return -1; } - s = eglQueryString(egl_dpy, EGL_VERSION); - printf("EGL_VERSION = %s\n", s); - - make_x_window(x_dpy, egl_dpy, - "glxgears", 0, 0, winWidth, winHeight, - &win, &egl_ctx, &egl_surf); + snprintf(win_title, sizeof(win_title), "xeglgears (%s)", + (surface_type == EGL_WINDOW_BIT) ? "window" : + (surface_type == EGL_PIXMAP_BIT) ? "pixmap" : "pbuffer"); + + /* create surface(s) */ + switch (surface_type) { + case EGL_WINDOW_BIT: + ret = egl_manager_create_window(eman, win_title, winWidth, winHeight, + EGL_TRUE, fullscreen, NULL); + if (ret) + ret = eglMakeCurrent(eman->dpy, eman->win, eman->win, eman->ctx); + break; + case EGL_PIXMAP_BIT: + ret = (egl_manager_create_window(eman, win_title, winWidth, winHeight, + EGL_FALSE, fullscreen, NULL) && + egl_manager_create_pixmap(eman, eman->xwin, + EGL_TRUE, NULL)); + if (ret) + ret = eglMakeCurrent(eman->dpy, eman->pix, eman->pix, eman->ctx); + break; + case EGL_PBUFFER_BIT: + { + EGLint pbuf_attribs[] = { + EGL_WIDTH, winWidth, + EGL_HEIGHT, winHeight, + EGL_NONE + }; + ret = (egl_manager_create_window(eman, win_title, winWidth, winHeight, + EGL_FALSE, fullscreen, NULL) && + egl_manager_create_pixmap(eman, eman->xwin, + EGL_FALSE, NULL) && + egl_manager_create_pbuffer(eman, pbuf_attribs)); + if (ret) + ret = eglMakeCurrent(eman->dpy, eman->pbuf, eman->pbuf, eman->ctx); + } + break; + default: + ret = EGL_FALSE; + break; + } - XMapWindow(x_dpy, win); - eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx); + if (!ret) { + egl_manager_destroy(eman); + XCloseDisplay(x_dpy); + return -1; + } if (printInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); @@ -590,18 +774,13 @@ main(int argc, char *argv[]) */ reshape(winWidth, winHeight); - event_loop(x_dpy, win, egl_dpy, egl_surf); + event_loop(eman, surface_type, winWidth, winHeight); glDeleteLists(gear1, 1); glDeleteLists(gear2, 1); glDeleteLists(gear3, 1); - eglDestroyContext(egl_dpy, egl_ctx); - eglDestroySurface(egl_dpy, egl_surf); - eglTerminate(egl_dpy); - - - XDestroyWindow(x_dpy, win); + egl_manager_destroy(eman); XCloseDisplay(x_dpy); return 0; -- 1.6.3.3 ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@... https://lists.sourceforge.net/lists/listinfo/mesa3d-dev |
|
|
Re: [PATCH 0/7] egl_glx: big cleanupChia-I Wu wrote:
> Hi, > > This patch series cleans up egl_glx driver. There are mainly four > changes. > > First, fbconfigs and visuals are now carefully parsed, and fixed, to > make sure all resulting EGLConfigs are valid. And there are some quirk > fixes to workaround GLX bugs. For example, there may be no config that > reports pbuffer support. Or, binding a drawable from glXCreateWindow to > a direct context causes a BadDrawable error. > > Pixmap and pbuffer surface support is added to GLX < 1.3. Extensions > are now detected, so that the right function calls are issued. > > The limitation that context must be direct is removed. And there is now > support for eglWaitNative and eglWaitClient, which wrap glXWaitX and > glXWaitGL. > > The last patch updates xeglgears to support pixmap and pbuffer surfaces. > Pbuffer is partially supported because it uses eglCopyBuffers which is > not implemented by any driver. > > This is tested with xserver 1.6.3 (GLX 1.2) and xserver git master (GLX > 1.4), with i915 driver. It works with NVIDIA GL/GLX driver too. IMHO, > EGL should wrap GLX, like this driver does, when the native window > system is X. With these cleanups in place, egl_glx should be in a good > shape. Committed. Thanks. -Brian ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@... https://lists.sourceforge.net/lists/listinfo/mesa3d-dev |
| Free embeddable forum powered by Nabble | Forum Help |