diff options
Diffstat (limited to 'src/egl/drivers')
-rw-r--r-- | src/egl/drivers/Makefile.template | 4 | ||||
-rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 178 | ||||
-rw-r--r-- | src/egl/drivers/glx/egl_glx.c | 347 |
3 files changed, 289 insertions, 240 deletions
diff --git a/src/egl/drivers/Makefile.template b/src/egl/drivers/Makefile.template index 08e82c65e9b..47709e3c59f 100644 --- a/src/egl/drivers/Makefile.template +++ b/src/egl/drivers/Makefile.template @@ -24,8 +24,8 @@ $(EGL_DRIVER_PATH): $(EGL_DRIVER) $(EGL_DRIVER): $(EGL_OBJECTS) Makefile $(TOP)/src/egl/drivers/Makefile.template @$(MKLIB) -o $(EGL_DRIVER) -noprefix \ - -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -L$(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + -linker '$(CC)' -ldflags '-L$(TOP)/$(LIB_DIR) $(LDFLAGS)' \ + $(MKLIB_OPTIONS) \ $(EGL_OBJECTS) $(EGL_LIBS) -l$(EGL_LIB) .c.o: diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index d17a2ab88c2..51834d74e3d 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -248,21 +248,20 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, if (double_buffer) return NULL; - if (depth > 0 && depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE)) + if (depth > 0 && depth != base.BufferSize) return NULL; - _eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE); + base.NativeRenderable = EGL_TRUE; - _eglSetConfigKey(&base, EGL_SURFACE_TYPE, surface_type); + base.SurfaceType = surface_type; if (surface_type & (EGL_PIXMAP_BIT | EGL_PBUFFER_BIT)) { - _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb); - if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0) - _eglSetConfigKey(&base, - EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba); + base.BindToTextureRGB = bind_to_texture_rgb; + if (base.AlphaSize > 0) + base.BindToTextureRGBA = bind_to_texture_rgba; } - _eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, disp->ClientAPIsMask); - _eglSetConfigKey(&base, EGL_CONFORMANT, disp->ClientAPIsMask); + base.RenderableType = disp->ClientAPIsMask; + base.Conformant = disp->ClientAPIsMask; if (!_eglValidateConfig(&base, EGL_FALSE)) { _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); @@ -273,7 +272,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, if (conf != NULL) { memcpy(&conf->base, &base, sizeof base); conf->dri_config = dri_config; - _eglAddConfig(disp, &conf->base); + _eglLinkConfig(&conf->base); } return conf; @@ -1161,7 +1160,7 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) (void) drv; - if (_eglIsSurfaceBound(surf)) + if (!_eglPutSurface(surf)) return EGL_TRUE; (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); @@ -1188,15 +1187,17 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf); struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf); struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + _EGLContext *old_ctx; + _EGLSurface *old_dsurf, *old_rsurf; __DRIdrawable *ddraw, *rdraw; __DRIcontext *cctx; - /* bind the new context and return the "orphaned" one */ - if (!_eglBindContext(&ctx, &dsurf, &rsurf)) + /* make new bindings */ + if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) return EGL_FALSE; /* flush before context switch */ - if (ctx && dri2_drv->glFlush) + if (old_ctx && dri2_drv->glFlush) dri2_drv->glFlush(); ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL; @@ -1205,16 +1206,29 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, if ((cctx == NULL && ddraw == NULL && rdraw == NULL) || dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { - if (dsurf && !_eglIsSurfaceLinked(dsurf)) - dri2_destroy_surface(drv, disp, dsurf); - if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(dsurf)) - dri2_destroy_surface(drv, disp, rsurf); - if (ctx != NULL && !_eglIsContextLinked(ctx)) - dri2_dpy->core->unbindContext(dri2_egl_context(ctx)->dri_context); + dri2_destroy_surface(drv, disp, old_dsurf); + dri2_destroy_surface(drv, disp, old_rsurf); + if (old_ctx) { + dri2_dpy->core->unbindContext(dri2_egl_context(old_ctx)->dri_context); + /* no destroy? */ + _eglPutContext(old_ctx); + } return EGL_TRUE; } else { - _eglBindContext(&ctx, &dsurf, &rsurf); + /* undo the previous _eglBindContext */ + _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf); + assert(&dri2_ctx->base == ctx && + &dri2_dsurf->base == dsurf && + &dri2_rsurf->base == rsurf); + + _eglPutSurface(dsurf); + _eglPutSurface(rsurf); + _eglPutContext(ctx); + + _eglPutSurface(old_dsurf); + _eglPutSurface(old_rsurf); + _eglPutContext(old_ctx); return EGL_FALSE; } @@ -1251,8 +1265,7 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, if (type == EGL_PBUFFER_BIT) { dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn); s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); - xcb_create_pixmap(dri2_dpy->conn, - _eglGetConfigKey(conf, EGL_BUFFER_SIZE), + xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, dri2_surf->drawable, s.data->root, dri2_surf->base.Width, dri2_surf->base.Height); } else { @@ -1601,7 +1614,7 @@ dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, return EGL_NO_IMAGE_KHR; } - if (!_eglInitImage(&dri2_img->base, disp, attr_list)) { + if (!_eglInitImage(&dri2_img->base, disp)) { free(buffers_reply); free(geometry_reply); return EGL_NO_IMAGE_KHR; @@ -1644,7 +1657,7 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, return EGL_NO_IMAGE_KHR; } - if (!_eglInitImage(&dri2_img->base, disp, attr_list)) + if (!_eglInitImage(&dri2_img->base, disp)) return EGL_NO_IMAGE_KHR; dri2_img->dri_image = @@ -1661,56 +1674,28 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_image *dri2_img; - EGLint width, height, format, name, stride, pitch, i, err; + EGLint format, name, pitch, err; + _EGLImageAttribs attrs; (void) ctx; name = (EGLint) buffer; - err = EGL_SUCCESS; - width = 0; - height = 0; - format = 0; - stride = 0; - - for (i = 0; attr_list[i] != EGL_NONE; i++) { - EGLint attr = attr_list[i++]; - EGLint val = attr_list[i]; - - switch (attr) { - case EGL_WIDTH: - width = val; - break; - case EGL_HEIGHT: - height = val; - break; - case EGL_DRM_BUFFER_FORMAT_MESA: - format = val; - break; - case EGL_DRM_BUFFER_STRIDE_MESA: - stride = val; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) { - _eglLog(_EGL_WARNING, "bad image attribute 0x%04x", attr); - return NULL; - } - } + err = _eglParseImageAttribList(&attrs, disp, attr_list); + if (err != EGL_SUCCESS) + return NULL; - if (width <= 0 || height <= 0 || stride <= 0) { + if (attrs.Width <= 0 || attrs.Height <= 0 || + attrs.DRMBufferStrideMESA <= 0) { _eglError(EGL_BAD_PARAMETER, "bad width, height or stride"); return NULL; } - switch (format) { + switch (attrs.DRMBufferFormatMESA) { case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: format = __DRI_IMAGE_FORMAT_ARGB8888; - pitch = stride; + pitch = attrs.DRMBufferStrideMESA; break; default: _eglError(EGL_BAD_PARAMETER, @@ -1724,15 +1709,15 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, return NULL; } - if (!_eglInitImage(&dri2_img->base, disp, attr_list)) { + if (!_eglInitImage(&dri2_img->base, disp)) { free(dri2_img); return NULL; } dri2_img->dri_image = dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, - width, - height, + attrs.Width, + attrs.Height, format, name, pitch, @@ -1786,8 +1771,9 @@ dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_image *dri2_img; - int width, height, format, i; - unsigned int use, dri_use, valid_mask; + _EGLImageAttribs attrs; + unsigned int dri_use, valid_mask; + int format; EGLint err = EGL_SUCCESS; (void) drv; @@ -1803,74 +1789,50 @@ dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, goto cleanup_img; } - if (!_eglInitImage(&dri2_img->base, disp, attr_list)) { + if (!_eglInitImage(&dri2_img->base, disp)) { err = EGL_BAD_PARAMETER; goto cleanup_img; } - width = 0; - height = 0; - format = 0; - use = 0; - for (i = 0; attr_list[i] != EGL_NONE; i++) { - EGLint attr = attr_list[i++]; - EGLint val = attr_list[i]; - - switch (attr) { - case EGL_WIDTH: - width = val; - break; - case EGL_HEIGHT: - height = val; - break; - case EGL_DRM_BUFFER_FORMAT_MESA: - format = val; - break; - case EGL_DRM_BUFFER_USE_MESA: - use = val; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) { - _eglLog(_EGL_WARNING, "bad image attribute 0x%04x", attr); - goto cleanup_img; - } - } + err = _eglParseImageAttribList(&attrs, disp, attr_list); + if (err != EGL_SUCCESS) + goto cleanup_img; - if (width <= 0 || height <= 0) { - _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", width, height); + if (attrs.Width <= 0 || attrs.Height <= 0) { + _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", + attrs.Width, attrs.Height); goto cleanup_img; } - switch (format) { + switch (attrs.DRMBufferFormatMESA) { case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: format = __DRI_IMAGE_FORMAT_ARGB8888; break; default: - _eglLog(_EGL_WARNING, "bad image format value 0x%04x", format); + _eglLog(_EGL_WARNING, "bad image format value 0x%04x", + attrs.DRMBufferFormatMESA); goto cleanup_img; } valid_mask = EGL_DRM_BUFFER_USE_SCANOUT_MESA | EGL_DRM_BUFFER_USE_SHARE_MESA; - if (use & ~valid_mask) { - _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", use & ~valid_mask); + if (attrs.DRMBufferUseMESA & ~valid_mask) { + _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", + attrs.DRMBufferUseMESA & ~valid_mask); goto cleanup_img; } dri_use = 0; - if (use & EGL_DRM_BUFFER_USE_SHARE_MESA) + if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA) dri_use |= __DRI_IMAGE_USE_SHARE; - if (use & EGL_DRM_BUFFER_USE_SCANOUT_MESA) + if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SCANOUT_MESA) dri_use |= __DRI_IMAGE_USE_SCANOUT; dri2_img->dri_image = dri2_dpy->image->createImage(dri2_dpy->dri_screen, - width, height, format, dri_use, dri2_img); + attrs.Width, attrs.Height, + format, dri_use, dri2_img); if (dri2_img->dri_image == NULL) { err = EGL_BAD_ALLOC; goto cleanup_img; diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 8a46f9c4a61..8ec7c48c50e 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -132,29 +132,38 @@ static const struct { int egl_attr; } fbconfig_attributes[] = { /* table 3.1 of GLX 1.4 */ - { GLX_BUFFER_SIZE, EGL_BUFFER_SIZE }, - { GLX_LEVEL, EGL_LEVEL }, - { GLX_RED_SIZE, EGL_RED_SIZE }, - { GLX_GREEN_SIZE, EGL_GREEN_SIZE }, - { GLX_BLUE_SIZE, EGL_BLUE_SIZE }, - { GLX_ALPHA_SIZE, EGL_ALPHA_SIZE }, - { GLX_DEPTH_SIZE, EGL_DEPTH_SIZE }, - { GLX_STENCIL_SIZE, EGL_STENCIL_SIZE }, - { GLX_SAMPLE_BUFFERS, EGL_SAMPLE_BUFFERS }, - { GLX_SAMPLES, EGL_SAMPLES }, - { GLX_RENDER_TYPE, EGL_RENDERABLE_TYPE }, - { GLX_X_RENDERABLE, EGL_NATIVE_RENDERABLE }, - { GLX_X_VISUAL_TYPE, EGL_NATIVE_VISUAL_TYPE }, - { GLX_CONFIG_CAVEAT, EGL_CONFIG_CAVEAT }, - { GLX_TRANSPARENT_TYPE, EGL_TRANSPARENT_TYPE }, - { GLX_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_RED_VALUE }, - { GLX_TRANSPARENT_GREEN_VALUE, EGL_TRANSPARENT_GREEN_VALUE }, - { GLX_TRANSPARENT_BLUE_VALUE, EGL_TRANSPARENT_BLUE_VALUE }, - { GLX_MAX_PBUFFER_WIDTH, EGL_MAX_PBUFFER_WIDTH }, - { GLX_MAX_PBUFFER_HEIGHT, EGL_MAX_PBUFFER_HEIGHT }, - { GLX_MAX_PBUFFER_PIXELS, EGL_MAX_PBUFFER_PIXELS }, - { GLX_VISUAL_ID, EGL_NATIVE_VISUAL_ID }, - { GLX_X_VISUAL_TYPE, EGL_NATIVE_VISUAL_TYPE }, + { GLX_FBCONFIG_ID, 0 }, + { GLX_BUFFER_SIZE, EGL_BUFFER_SIZE }, + { GLX_LEVEL, EGL_LEVEL }, + { GLX_DOUBLEBUFFER, 0 }, + { GLX_STEREO, 0 }, + { GLX_AUX_BUFFERS, 0 }, + { GLX_RED_SIZE, EGL_RED_SIZE }, + { GLX_GREEN_SIZE, EGL_GREEN_SIZE }, + { GLX_BLUE_SIZE, EGL_BLUE_SIZE }, + { GLX_ALPHA_SIZE, EGL_ALPHA_SIZE }, + { GLX_DEPTH_SIZE, EGL_DEPTH_SIZE }, + { GLX_STENCIL_SIZE, EGL_STENCIL_SIZE }, + { GLX_ACCUM_RED_SIZE, 0 }, + { GLX_ACCUM_GREEN_SIZE, 0 }, + { GLX_ACCUM_BLUE_SIZE, 0 }, + { GLX_ACCUM_ALPHA_SIZE, 0 }, + { GLX_SAMPLE_BUFFERS, EGL_SAMPLE_BUFFERS }, + { GLX_SAMPLES, EGL_SAMPLES }, + { GLX_RENDER_TYPE, 0 }, + { GLX_DRAWABLE_TYPE, EGL_SURFACE_TYPE }, + { GLX_X_RENDERABLE, EGL_NATIVE_RENDERABLE }, + { GLX_X_VISUAL_TYPE, EGL_NATIVE_VISUAL_TYPE }, + { GLX_CONFIG_CAVEAT, EGL_CONFIG_CAVEAT }, + { GLX_TRANSPARENT_TYPE, EGL_TRANSPARENT_TYPE }, + { GLX_TRANSPARENT_INDEX_VALUE, 0 }, + { GLX_TRANSPARENT_RED_VALUE, EGL_TRANSPARENT_RED_VALUE }, + { GLX_TRANSPARENT_GREEN_VALUE, EGL_TRANSPARENT_GREEN_VALUE }, + { GLX_TRANSPARENT_BLUE_VALUE, EGL_TRANSPARENT_BLUE_VALUE }, + { GLX_MAX_PBUFFER_WIDTH, EGL_MAX_PBUFFER_WIDTH }, + { GLX_MAX_PBUFFER_HEIGHT, EGL_MAX_PBUFFER_HEIGHT }, + { GLX_MAX_PBUFFER_PIXELS, EGL_MAX_PBUFFER_PIXELS }, + { GLX_VISUAL_ID, EGL_NATIVE_VISUAL_ID } }; @@ -162,13 +171,31 @@ static EGLBoolean convert_fbconfig(Display *dpy, GLXFBConfig fbconfig, struct GLX_egl_config *GLX_conf) { - int err = 0, attr, egl_attr, val; + int err, attr, val; unsigned i; - EGLint conformant, config_caveat, surface_type; + + /* must have rgba bit */ + err = glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &val); + if (err || !(val & GLX_RGBA_BIT)) + return EGL_FALSE; + + /* must know whether it is double-buffered */ + err = glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &val); + if (err) + return EGL_FALSE; + GLX_conf->double_buffered = val; + + GLX_conf->Base.RenderableType = EGL_OPENGL_BIT; + GLX_conf->Base.Conformant = EGL_OPENGL_BIT; for (i = 0; i < ARRAY_SIZE(fbconfig_attributes); i++) { + EGLint egl_attr, egl_val; + attr = fbconfig_attributes[i].attr; egl_attr = fbconfig_attributes[i].egl_attr; + if (!egl_attr) + continue; + err = glXGetFBConfigAttrib(dpy, fbconfig, attr, &val); if (err) { if (err == GLX_BAD_ATTRIBUTE) { @@ -178,47 +205,71 @@ convert_fbconfig(Display *dpy, GLXFBConfig fbconfig, break; } - _eglSetConfigKey(&GLX_conf->Base, egl_attr, val); + switch (egl_attr) { + case EGL_SURFACE_TYPE: + egl_val = 0; + if (val & GLX_WINDOW_BIT) + egl_val |= EGL_WINDOW_BIT; + /* pixmap and pbuffer surfaces must be single-buffered in EGL */ + if (!GLX_conf->double_buffered) { + if (val & GLX_PIXMAP_BIT) + egl_val |= EGL_PIXMAP_BIT; + if (val & GLX_PBUFFER_BIT) + egl_val |= EGL_PBUFFER_BIT; + } + break; + case EGL_NATIVE_VISUAL_TYPE: + switch (val) { + case GLX_TRUE_COLOR: + egl_val = TrueColor; + break; + case GLX_DIRECT_COLOR: + egl_val = DirectColor; + break; + case GLX_PSEUDO_COLOR: + egl_val = PseudoColor; + break; + case GLX_STATIC_COLOR: + egl_val = StaticColor; + break; + case GLX_GRAY_SCALE: + egl_val = GrayScale; + break; + case GLX_STATIC_GRAY: + egl_val = StaticGray; + break; + default: + egl_val = EGL_NONE; + break; + } + break; + case EGL_CONFIG_CAVEAT: + egl_val = EGL_NONE; + if (val == GLX_SLOW_CONFIG) { + egl_val = EGL_SLOW_CONFIG; + } + else if (val == GLX_NON_CONFORMANT_CONFIG) { + GLX_conf->Base.Conformant &= ~EGL_OPENGL_BIT; + egl_val = EGL_NONE; + } + break; + case EGL_TRANSPARENT_TYPE: + egl_val = (val == GLX_TRANSPARENT_RGB) ? + EGL_TRANSPARENT_RGB : EGL_NONE; + break; + default: + egl_val = val; + break; + } + + _eglSetConfigKey(&GLX_conf->Base, egl_attr, egl_val); } if (err) return EGL_FALSE; - /* must have rgba bit */ - glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &val); - if (!(val & GLX_RGBA_BIT)) + if (!GLX_conf->Base.SurfaceType) return EGL_FALSE; - conformant = EGL_OPENGL_BIT; - glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &val); - if (val == GLX_SLOW_CONFIG) - config_caveat = EGL_SLOW_CONFIG; - if (val == GLX_NON_CONFORMANT_CONFIG) - conformant &= ~EGL_OPENGL_BIT; - if (!(conformant & EGL_OPENGL_ES_BIT)) - config_caveat = EGL_NON_CONFORMANT_CONFIG; - - _eglSetConfigKey(&GLX_conf->Base, EGL_CONFIG_CAVEAT, config_caveat); - - surface_type = 0; - glXGetFBConfigAttrib(dpy, fbconfig, GLX_DRAWABLE_TYPE, &val); - if (val & GLX_WINDOW_BIT) - surface_type |= EGL_WINDOW_BIT; - if (val & GLX_PIXMAP_BIT) - surface_type |= EGL_PIXMAP_BIT; - if (val & GLX_PBUFFER_BIT) - surface_type |= EGL_PBUFFER_BIT; - - /* pixmap and pbuffer surfaces must be single-buffered in EGL */ - glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &val); - GLX_conf->double_buffered = val; - if (GLX_conf->double_buffered) { - surface_type &= ~(EGL_PIXMAP_BIT | EGL_PBUFFER_BIT); - if (!surface_type) - return EGL_FALSE; - } - - _eglSetConfigKey(&GLX_conf->Base, EGL_SURFACE_TYPE, surface_type); - return EGL_TRUE; } @@ -227,35 +278,69 @@ static const struct { int egl_attr; } visual_attributes[] = { /* table 3.7 of GLX 1.4 */ - /* no GLX_USE_GL */ - { GLX_BUFFER_SIZE, EGL_BUFFER_SIZE }, - { GLX_LEVEL, EGL_LEVEL }, - { GLX_RED_SIZE, EGL_RED_SIZE }, - { GLX_GREEN_SIZE, EGL_GREEN_SIZE }, - { GLX_BLUE_SIZE, EGL_BLUE_SIZE }, - { GLX_ALPHA_SIZE, EGL_ALPHA_SIZE }, - { GLX_DEPTH_SIZE, EGL_DEPTH_SIZE }, - { GLX_STENCIL_SIZE, EGL_STENCIL_SIZE }, - { GLX_SAMPLE_BUFFERS, EGL_SAMPLE_BUFFERS }, - { GLX_SAMPLES, EGL_SAMPLES }, + { GLX_USE_GL, 0 }, + { GLX_BUFFER_SIZE, EGL_BUFFER_SIZE }, + { GLX_LEVEL, EGL_LEVEL }, + { GLX_RGBA, 0 }, + { GLX_DOUBLEBUFFER, 0 }, + { GLX_STEREO, 0 }, + { GLX_AUX_BUFFERS, 0 }, + { GLX_RED_SIZE, EGL_RED_SIZE }, + { GLX_GREEN_SIZE, EGL_GREEN_SIZE }, + { GLX_BLUE_SIZE, EGL_BLUE_SIZE }, + { GLX_ALPHA_SIZE, EGL_ALPHA_SIZE }, + { GLX_DEPTH_SIZE, EGL_DEPTH_SIZE }, + { GLX_STENCIL_SIZE, EGL_STENCIL_SIZE }, + { GLX_ACCUM_RED_SIZE, 0 }, + { GLX_ACCUM_GREEN_SIZE, 0 }, + { GLX_ACCUM_BLUE_SIZE, 0 }, + { GLX_ACCUM_ALPHA_SIZE, 0 }, + { GLX_SAMPLE_BUFFERS, EGL_SAMPLE_BUFFERS }, + { GLX_SAMPLES, EGL_SAMPLES }, + { GLX_FBCONFIG_ID, 0 }, + /* GLX_EXT_visual_rating */ + { GLX_VISUAL_CAVEAT_EXT, EGL_CONFIG_CAVEAT } }; static EGLBoolean convert_visual(Display *dpy, XVisualInfo *vinfo, struct GLX_egl_config *GLX_conf) { - int err, attr, egl_attr, val; + int err, attr, val; unsigned i; - EGLint conformant, config_caveat, surface_type; - /* the visual must support OpenGL */ + /* the visual must support OpenGL and RGBA buffer */ err = glXGetConfig(dpy, vinfo, GLX_USE_GL, &val); + if (!err && val) + err = glXGetConfig(dpy, vinfo, GLX_RGBA, &val); if (err || !val) return EGL_FALSE; + /* must know whether it is double-buffered */ + err = glXGetConfig(dpy, vinfo, GLX_DOUBLEBUFFER, &val); + if (err) + return EGL_FALSE; + GLX_conf->double_buffered = val; + + GLX_conf->Base.RenderableType = EGL_OPENGL_BIT; + GLX_conf->Base.Conformant = EGL_OPENGL_BIT; + GLX_conf->Base.SurfaceType = EGL_WINDOW_BIT; + /* pixmap surfaces must be single-buffered in EGL */ + if (!GLX_conf->double_buffered) + GLX_conf->Base.SurfaceType |= EGL_PIXMAP_BIT; + + GLX_conf->Base.NativeVisualID = vinfo->visualid; + GLX_conf->Base.NativeVisualType = vinfo->class; + GLX_conf->Base.NativeRenderable = EGL_TRUE; + for (i = 0; i < ARRAY_SIZE(visual_attributes); i++) { + EGLint egl_attr, egl_val; + attr = visual_attributes[i].attr; - egl_attr = fbconfig_attributes[i].egl_attr; + egl_attr = visual_attributes[i].egl_attr; + if (!egl_attr) + continue; + err = glXGetConfig(dpy, vinfo, attr, &val); if (err) { if (err == GLX_BAD_ATTRIBUTE) { @@ -265,41 +350,26 @@ convert_visual(Display *dpy, XVisualInfo *vinfo, break; } - _eglSetConfigKey(&GLX_conf->Base, egl_attr, val); + switch (egl_attr) { + case EGL_CONFIG_CAVEAT: + egl_val = EGL_NONE; + if (val == GLX_SLOW_VISUAL_EXT) { + egl_val = EGL_SLOW_CONFIG; + } + else if (val == GLX_NON_CONFORMANT_VISUAL_EXT) { + GLX_conf->Base.Conformant &= ~EGL_OPENGL_BIT; + egl_val = EGL_NONE; + } + break; + break; + default: + egl_val = val; + break; + } + _eglSetConfigKey(&GLX_conf->Base, egl_attr, egl_val); } - if (err) - return EGL_FALSE; - - glXGetConfig(dpy, vinfo, GLX_RGBA, &val); - if (!val) - return EGL_FALSE; - - conformant = EGL_OPENGL_BIT; - glXGetConfig(dpy, vinfo, GLX_VISUAL_CAVEAT_EXT, &val); - if (val == GLX_SLOW_CONFIG) - config_caveat = EGL_SLOW_CONFIG; - if (val == GLX_NON_CONFORMANT_CONFIG) - conformant &= ~EGL_OPENGL_BIT; - if (!(conformant & EGL_OPENGL_ES_BIT)) - config_caveat = EGL_NON_CONFORMANT_CONFIG; - - _eglSetConfigKey(&GLX_conf->Base, EGL_CONFIG_CAVEAT, config_caveat); - _eglSetConfigKey(&GLX_conf->Base, EGL_NATIVE_VISUAL_ID, vinfo->visualid); - _eglSetConfigKey(&GLX_conf->Base, EGL_NATIVE_VISUAL_TYPE, vinfo->class); - - /* pixmap and pbuffer surfaces must be single-buffered in EGL */ - glXGetConfig(dpy, vinfo, GLX_DOUBLEBUFFER, &val); - GLX_conf->double_buffered = val; - surface_type = EGL_WINDOW_BIT; - /* pixmap surfaces must be single-buffered in EGL */ - if (!GLX_conf->double_buffered) - surface_type |= EGL_PIXMAP_BIT; - _eglSetConfigKey(&GLX_conf->Base, EGL_SURFACE_TYPE, surface_type); - - _eglSetConfigKey(&GLX_conf->Base, EGL_NATIVE_RENDERABLE, EGL_TRUE); - - return EGL_TRUE; + return (err) ? EGL_FALSE : EGL_TRUE; } @@ -307,30 +377,31 @@ 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; + conf->SurfaceType &= ~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); + conf->SurfaceType |= EGL_PBUFFER_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); + if (!(conf->SurfaceType & EGL_WINDOW_BIT)) { + conf->NativeVisualID = 0; + conf->NativeVisualType = EGL_NONE; + } + + if (conf->TransparentType != EGL_TRANSPARENT_RGB) { + /* some impls set them to -1 (GLX_DONT_CARE) */ + conf->TransparentRedValue = 0; + conf->TransparentGreenValue = 0; + conf->TransparentBlueValue = 0; } /* 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); + conf->BufferSize = + conf->RedSize + conf->GreenSize + conf->BlueSize + conf->AlphaSize; } @@ -381,7 +452,7 @@ create_configs(_EGLDisplay *dpy, struct GLX_egl_display *GLX_dpy, memcpy(GLX_conf, &template, sizeof(template)); GLX_conf->index = i; - _eglAddConfig(dpy, &GLX_conf->Base); + _eglLinkConfig(&GLX_conf->Base); id++; } } @@ -606,14 +677,16 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, struct GLX_egl_surface *GLX_dsurf = GLX_egl_surface(dsurf); struct GLX_egl_surface *GLX_rsurf = GLX_egl_surface(rsurf); struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx); + _EGLContext *old_ctx; + _EGLSurface *old_dsurf, *old_rsurf; GLXDrawable ddraw, rdraw; GLXContext cctx; EGLBoolean ret = EGL_FALSE; (void) drv; - /* bind the new context and return the "orphaned" one */ - if (!_eglBindContext(&ctx, &dsurf, &rsurf)) + /* make new bindings */ + if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) return EGL_FALSE; ddraw = (GLX_dsurf) ? GLX_dsurf->glx_drawable : None; @@ -626,13 +699,27 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, ret = glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); if (ret) { - if (dsurf && !_eglIsSurfaceLinked(dsurf)) - destroy_surface(disp, dsurf); - if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(rsurf)) - destroy_surface(disp, rsurf); + if (_eglPutSurface(old_dsurf)) + destroy_surface(disp, old_dsurf); + if (_eglPutSurface(old_rsurf)) + destroy_surface(disp, old_rsurf); + /* no destroy? */ + _eglPutContext(old_ctx); } else { - _eglBindContext(&ctx, &dsurf, &rsurf); + /* undo the previous _eglBindContext */ + _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf); + assert(&GLX_ctx->Base == ctx && + &GLX_dsurf->Base == dsurf && + &GLX_rsurf->Base == rsurf); + + _eglPutSurface(dsurf); + _eglPutSurface(rsurf); + _eglPutContext(ctx); + + _eglPutSurface(old_dsurf); + _eglPutSurface(old_rsurf); + _eglPutContext(old_ctx); } return ret; @@ -836,7 +923,7 @@ GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { (void) drv; - if (!_eglIsSurfaceBound(surf)) + if (_eglPutSurface(surf)) destroy_surface(disp, surf); return EGL_TRUE; |