summaryrefslogtreecommitdiffstats
path: root/src/egl/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/drivers')
-rw-r--r--src/egl/drivers/Makefile.template4
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c178
-rw-r--r--src/egl/drivers/glx/egl_glx.c347
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;