summaryrefslogtreecommitdiffstats
path: root/src/egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl')
-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
-rw-r--r--src/egl/main/Makefile1
-rw-r--r--src/egl/main/SConscript1
-rw-r--r--src/egl/main/eglapi.c35
-rw-r--r--src/egl/main/eglconfig.c255
-rw-r--r--src/egl/main/eglconfig.h167
-rw-r--r--src/egl/main/eglcontext.c158
-rw-r--r--src/egl/main/eglcontext.h57
-rw-r--r--src/egl/main/egldisplay.c53
-rw-r--r--src/egl/main/egldisplay.h15
-rw-r--r--src/egl/main/egldriver.c79
-rw-r--r--src/egl/main/egldriver.h1
-rw-r--r--src/egl/main/eglfallbacks.c99
-rw-r--r--src/egl/main/eglimage.c75
-rw-r--r--src/egl/main/eglimage.h68
-rw-r--r--src/egl/main/eglmisc.c29
-rw-r--r--src/egl/main/eglmisc.h8
-rw-r--r--src/egl/main/eglmode.c60
-rw-r--r--src/egl/main/eglmode.h5
-rw-r--r--src/egl/main/eglscreen.c161
-rw-r--r--src/egl/main/eglscreen.h45
-rw-r--r--src/egl/main/eglsurface.c135
-rw-r--r--src/egl/main/eglsurface.h75
-rw-r--r--src/egl/main/eglsync.c36
-rw-r--r--src/egl/main/eglsync.h57
-rw-r--r--src/egl/main/egltypedefs.h2
28 files changed, 946 insertions, 1260 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;
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 19085a31f18..b4ca20c094a 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -36,6 +36,7 @@ SOURCES = \
eglcurrent.c \
egldisplay.c \
egldriver.c \
+ eglfallbacks.c \
eglglobals.c \
eglimage.c \
egllog.c \
diff --git a/src/egl/main/SConscript b/src/egl/main/SConscript
index 45d40e26502..8ade85b3572 100644
--- a/src/egl/main/SConscript
+++ b/src/egl/main/SConscript
@@ -28,6 +28,7 @@ if env['platform'] != 'winddk':
'eglcurrent.c',
'egldisplay.c',
'egldriver.c',
+ 'eglfallbacks.c',
'eglglobals.c',
'eglimage.c',
'egllog.c',
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index e8f856f6beb..efa9e97346b 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -416,7 +416,7 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
- ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT;
+ ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
RETURN_EGL_EVAL(disp, ret);
}
@@ -515,7 +515,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
@@ -536,7 +536,7 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
@@ -555,7 +555,7 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
@@ -648,11 +648,12 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
- if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp)
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ ctx->Resource.Display != disp)
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
surf = ctx->DrawSurface;
- if (!_eglIsSurfaceLinked(surf))
+ if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
ret = drv->API.SwapInterval(drv, disp, surf, interval);
@@ -673,7 +674,8 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
/* surface must be bound to current context in EGL 1.4 */
- if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ surf != ctx->DrawSurface)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
ret = drv->API.SwapBuffers(drv, disp, surf);
@@ -714,7 +716,8 @@ eglWaitClient(void)
_eglLockMutex(&disp->Mutex);
/* let bad current context imply bad current surface */
- if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
/* a valid current context implies an initialized current display */
@@ -763,7 +766,8 @@ eglWaitNative(EGLint engine)
_eglLockMutex(&disp->Mutex);
/* let bad current context imply bad current surface */
- if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface))
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
/* a valid current context implies an initialized current display */
@@ -1043,7 +1047,7 @@ eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
@@ -1235,7 +1239,7 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
conf, attrib_list);
- ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
+ ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
RETURN_EGL_EVAL(disp, ret);
}
@@ -1298,7 +1302,7 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
img = drv->API.CreateImageKHR(drv,
disp, context, target, buffer, attr_list);
- ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
+ ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
RETURN_EGL_EVAL(disp, ret);
}
@@ -1344,7 +1348,7 @@ eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
- ret = (sync) ? _eglLinkSync(sync, disp) : EGL_NO_SYNC_KHR;
+ ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
RETURN_EGL_EVAL(disp, ret);
}
@@ -1437,7 +1441,8 @@ eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
RETURN_EGL_EVAL(disp, EGL_FALSE);
/* surface must be bound to current context in EGL 1.4 */
- if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface)
+ if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+ surf != ctx->DrawSurface)
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
@@ -1463,7 +1468,7 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
- ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR;
+ ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
RETURN_EGL_EVAL(disp, ret);
}
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 01e7144d40a..fec94fb20cd 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -24,34 +24,34 @@
* IDs are from 1 to N respectively.
*/
void
-_eglInitConfig(_EGLConfig *config, _EGLDisplay *dpy, EGLint id)
+_eglInitConfig(_EGLConfig *conf, _EGLDisplay *dpy, EGLint id)
{
- memset(config, 0, sizeof(*config));
+ memset(conf, 0, sizeof(*conf));
- config->Display = dpy;
+ conf->Display = dpy;
/* some attributes take non-zero default values */
- SET_CONFIG_ATTRIB(config, EGL_CONFIG_ID, id);
- SET_CONFIG_ATTRIB(config, EGL_CONFIG_CAVEAT, EGL_NONE);
- SET_CONFIG_ATTRIB(config, EGL_TRANSPARENT_TYPE, EGL_NONE);
- SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, EGL_NONE);
-#ifdef EGL_VERSION_1_2
- SET_CONFIG_ATTRIB(config, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
-#endif /* EGL_VERSION_1_2 */
+ conf->ConfigID = id;
+ conf->ConfigCaveat = EGL_NONE;
+ conf->TransparentType = EGL_NONE;
+ conf->NativeVisualType = EGL_NONE;
+ conf->ColorBufferType = EGL_RGB_BUFFER;
}
/**
- * Link a config to a display and return the handle of the link.
+ * Link a config to its display and return the handle of the link.
* The handle can be passed to client directly.
*
* Note that we just save the ptr to the config (we don't copy the config).
*/
-EGLConfig
-_eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf)
+PUBLIC EGLConfig
+_eglLinkConfig(_EGLConfig *conf)
{
+ _EGLDisplay *dpy = conf->Display;
+
/* sanity check */
- assert(GET_CONFIG_ATTRIB(conf, EGL_CONFIG_ID) > 0);
+ assert(dpy && conf->ConfigID > 0);
if (!dpy->Configs) {
dpy->Configs = _eglCreateArray("Config", 16);
@@ -59,23 +59,29 @@ _eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf)
return (EGLConfig) NULL;
}
- conf->Display = dpy;
_eglAppendArray(dpy->Configs, (void *) conf);
return (EGLConfig) conf;
}
-EGLBoolean
-_eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy)
+/**
+ * Lookup a handle to find the linked config.
+ * Return NULL if the handle has no corresponding linked config.
+ */
+_EGLConfig *
+_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy)
{
_EGLConfig *conf;
+ if (!dpy)
+ return NULL;
+
conf = (_EGLConfig *) _eglFindArray(dpy->Configs, (void *) config);
if (conf)
assert(conf->Display == dpy);
- return (conf != NULL);
+ return conf;
}
@@ -104,6 +110,7 @@ static const struct {
EGLint default_value;
} _eglValidationTable[] =
{
+ /* core */
{ EGL_BUFFER_SIZE, ATTRIB_TYPE_INTEGER,
ATTRIB_CRITERION_ATLEAST,
0 },
@@ -200,22 +207,13 @@ static const struct {
{ EGL_TRANSPARENT_BLUE_VALUE, ATTRIB_TYPE_INTEGER,
ATTRIB_CRITERION_EXACT,
EGL_DONT_CARE },
- /* these are not real attributes */
{ EGL_MATCH_NATIVE_PIXMAP, ATTRIB_TYPE_PSEUDO,
ATTRIB_CRITERION_SPECIAL,
EGL_NONE },
- /* there is a gap before EGL_SAMPLES */
- { 0x3030, ATTRIB_TYPE_PSEUDO,
- ATTRIB_CRITERION_IGNORE,
- 0 },
- { EGL_NONE, ATTRIB_TYPE_PSEUDO,
- ATTRIB_CRITERION_IGNORE,
- 0 },
-
+ /* extensions */
{ EGL_Y_INVERTED_NOK, ATTRIB_TYPE_BOOLEAN,
ATTRIB_CRITERION_EXACT,
- EGL_DONT_CARE },
-
+ EGL_DONT_CARE }
};
@@ -232,18 +230,13 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
{
EGLint i, attr, val;
EGLBoolean valid = EGL_TRUE;
- EGLint red_size = 0, green_size = 0, blue_size = 0, luminance_size = 0;
- EGLint alpha_size = 0, buffer_size = 0;
-
- /* all attributes should have been listed */
- assert(ARRAY_SIZE(_eglValidationTable) == _EGL_CONFIG_NUM_ATTRIBS);
/* check attributes by their types */
for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
EGLint mask;
attr = _eglValidationTable[i].attr;
- val = GET_CONFIG_ATTRIB(conf, attr);
+ val = _eglGetConfigKey(conf, attr);
switch (_eglValidationTable[i].type) {
case ATTRIB_TYPE_INTEGER:
@@ -255,30 +248,14 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
break;
case EGL_SAMPLE_BUFFERS:
/* there can be at most 1 sample buffer */
- if (val > 1)
+ if (val > 1 || val < 0)
valid = EGL_FALSE;
break;
- case EGL_RED_SIZE:
- red_size = val;
- break;
- case EGL_GREEN_SIZE:
- green_size = val;
- break;
- case EGL_BLUE_SIZE:
- blue_size = val;
- break;
- case EGL_LUMINANCE_SIZE:
- luminance_size = val;
- break;
- case EGL_ALPHA_SIZE:
- alpha_size = val;
- break;
- case EGL_BUFFER_SIZE:
- buffer_size = val;
+ default:
+ if (val < 0)
+ valid = EGL_FALSE;
break;
}
- if (val < 0)
- valid = EGL_FALSE;
break;
case ATTRIB_TYPE_BOOLEAN:
if (val != EGL_TRUE && val != EGL_FALSE)
@@ -366,17 +343,18 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
/* now check for conflicting attribute values */
- switch (GET_CONFIG_ATTRIB(conf, EGL_COLOR_BUFFER_TYPE)) {
+ switch (conf->ColorBufferType) {
case EGL_RGB_BUFFER:
- if (luminance_size)
+ if (conf->LuminanceSize)
valid = EGL_FALSE;
- if (red_size + green_size + blue_size + alpha_size != buffer_size)
+ if (conf->RedSize + conf->GreenSize +
+ conf->BlueSize + conf->AlphaSize != conf->BufferSize)
valid = EGL_FALSE;
break;
case EGL_LUMINANCE_BUFFER:
- if (red_size || green_size || blue_size)
+ if (conf->RedSize || conf->GreenSize || conf->BlueSize)
valid = EGL_FALSE;
- if (luminance_size + alpha_size != buffer_size)
+ if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize)
valid = EGL_FALSE;
break;
}
@@ -385,23 +363,19 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
return EGL_FALSE;
}
- val = GET_CONFIG_ATTRIB(conf, EGL_SAMPLE_BUFFERS);
- if (!val && GET_CONFIG_ATTRIB(conf, EGL_SAMPLES))
+ if (!conf->SampleBuffers && conf->Samples)
valid = EGL_FALSE;
if (!valid) {
_eglLog(_EGL_DEBUG, "conflicting samples and sample buffers");
return EGL_FALSE;
}
- val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
- if (!(val & EGL_WINDOW_BIT)) {
- if (GET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_ID) != 0 ||
- GET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE) != EGL_NONE)
+ if (!(conf->SurfaceType & EGL_WINDOW_BIT)) {
+ if (conf->NativeVisualID != 0 || conf->NativeVisualType != EGL_NONE)
valid = EGL_FALSE;
}
- if (!(val & EGL_PBUFFER_BIT)) {
- if (GET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB) ||
- GET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA))
+ if (!(conf->SurfaceType & EGL_PBUFFER_BIT)) {
+ if (conf->BindToTextureRGB || conf->BindToTextureRGBA)
valid = EGL_FALSE;
}
if (!valid) {
@@ -433,11 +407,11 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
continue;
attr = _eglValidationTable[i].attr;
- cmp = GET_CONFIG_ATTRIB(criteria, attr);
+ cmp = _eglGetConfigKey(criteria, attr);
if (cmp == EGL_DONT_CARE)
continue;
- val = GET_CONFIG_ATTRIB(conf, attr);
+ val = _eglGetConfigKey(conf, attr);
switch (_eglValidationTable[i].criterion) {
case ATTRIB_CRITERION_EXACT:
if (val != cmp)
@@ -478,16 +452,11 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
static INLINE EGLBoolean
_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
{
- if (_eglIndexConfig(conf, attr) < 0)
+ if (_eglOffsetOfConfig(attr) < 0)
return EGL_FALSE;
- /* there are some holes in the range */
switch (attr) {
- case 0x3030 /* a gap before EGL_SAMPLES */:
- case EGL_NONE:
-#ifdef EGL_VERSION_1_4
case EGL_MATCH_NATIVE_PIXMAP:
-#endif
return EGL_FALSE;
case EGL_Y_INVERTED_NOK:
return conf->Display->Extensions.NOK_texture_from_pixmap;
@@ -503,18 +472,18 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
* Return EGL_FALSE if any of the attribute is invalid.
*/
EGLBoolean
-_eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list)
+_eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy,
+ const EGLint *attrib_list)
{
EGLint attr, val, i;
- EGLint config_id = 0, level = 0;
- EGLBoolean has_native_visual_type = EGL_FALSE;
- EGLBoolean has_transparent_color = EGL_FALSE;
+
+ _eglInitConfig(conf, dpy, EGL_DONT_CARE);
/* reset to default values */
for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
attr = _eglValidationTable[i].attr;
val = _eglValidationTable[i].default_value;
- SET_CONFIG_ATTRIB(conf, attr, val);
+ _eglSetConfigKey(conf, attr, val);
}
/* parse the list */
@@ -524,59 +493,33 @@ _eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list)
if (!_eglIsConfigAttribValid(conf, attr))
return EGL_FALSE;
-
- SET_CONFIG_ATTRIB(conf, attr, val);
- /* rememeber some attributes for post-processing */
- switch (attr) {
- case EGL_CONFIG_ID:
- config_id = val;
- break;
- case EGL_LEVEL:
- level = val;
- break;
- case EGL_NATIVE_VISUAL_TYPE:
- has_native_visual_type = EGL_TRUE;
- break;
- case EGL_TRANSPARENT_RED_VALUE:
- case EGL_TRANSPARENT_GREEN_VALUE:
- case EGL_TRANSPARENT_BLUE_VALUE:
- has_transparent_color = EGL_TRUE;
- break;
- default:
- break;
- }
+ _eglSetConfigKey(conf, attr, val);
}
if (!_eglValidateConfig(conf, EGL_TRUE))
return EGL_FALSE;
/* the spec says that EGL_LEVEL cannot be EGL_DONT_CARE */
- if (level == EGL_DONT_CARE)
+ if (conf->Level == EGL_DONT_CARE)
return EGL_FALSE;
/* ignore other attributes when EGL_CONFIG_ID is given */
- if (config_id > 0) {
- _eglResetConfigKeys(conf, EGL_DONT_CARE);
- SET_CONFIG_ATTRIB(conf, EGL_CONFIG_ID, config_id);
+ if (conf->ConfigID != EGL_DONT_CARE) {
+ for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
+ attr = _eglValidationTable[i].attr;
+ if (attr != EGL_CONFIG_ID)
+ _eglSetConfigKey(conf, attr, EGL_DONT_CARE);
+ }
}
else {
- if (has_native_visual_type) {
- val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
- if (!(val & EGL_WINDOW_BIT))
- SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE);
- }
+ if (!(conf->SurfaceType & EGL_WINDOW_BIT))
+ conf->NativeVisualType = EGL_DONT_CARE;
- if (has_transparent_color) {
- val = GET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_TYPE);
- if (val == EGL_NONE) {
- SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_RED_VALUE,
- EGL_DONT_CARE);
- SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_GREEN_VALUE,
- EGL_DONT_CARE);
- SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_BLUE_VALUE,
- EGL_DONT_CARE);
- }
+ if (conf->TransparentType == EGL_NONE) {
+ conf->TransparentRedValue = EGL_DONT_CARE;
+ conf->TransparentGreenValue = EGL_DONT_CARE;
+ conf->TransparentBlueValue = EGL_DONT_CARE;
}
}
@@ -610,7 +553,6 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
EGL_ALPHA_MASK_SIZE,
};
EGLint val1, val2;
- EGLBoolean rgb_buffer;
EGLint i;
if (conf1 == conf2)
@@ -619,44 +561,41 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
/* the enum values have the desired ordering */
assert(EGL_NONE < EGL_SLOW_CONFIG);
assert(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
- val1 = GET_CONFIG_ATTRIB(conf1, EGL_CONFIG_CAVEAT);
- val2 = GET_CONFIG_ATTRIB(conf2, EGL_CONFIG_CAVEAT);
- if (val1 != val2)
- return (val1 - val2);
+ val1 = conf1->ConfigCaveat - conf2->ConfigCaveat;
+ if (val1)
+ return val1;
/* the enum values have the desired ordering */
assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
- val1 = GET_CONFIG_ATTRIB(conf1, EGL_COLOR_BUFFER_TYPE);
- val2 = GET_CONFIG_ATTRIB(conf2, EGL_COLOR_BUFFER_TYPE);
- if (val1 != val2)
- return (val1 - val2);
- rgb_buffer = (val1 == EGL_RGB_BUFFER);
+ val1 = conf1->ColorBufferType - conf2->ColorBufferType;
+ if (val1)
+ return val1;
if (criteria) {
val1 = val2 = 0;
- if (rgb_buffer) {
- if (GET_CONFIG_ATTRIB(criteria, EGL_RED_SIZE) > 0) {
- val1 += GET_CONFIG_ATTRIB(conf1, EGL_RED_SIZE);
- val2 += GET_CONFIG_ATTRIB(conf2, EGL_RED_SIZE);
+ if (conf1->ColorBufferType == EGL_RGB_BUFFER) {
+ if (criteria->RedSize > 0) {
+ val1 += conf1->RedSize;
+ val2 += conf2->RedSize;
}
- if (GET_CONFIG_ATTRIB(criteria, EGL_GREEN_SIZE) > 0) {
- val1 += GET_CONFIG_ATTRIB(conf1, EGL_GREEN_SIZE);
- val2 += GET_CONFIG_ATTRIB(conf2, EGL_GREEN_SIZE);
+ if (criteria->GreenSize > 0) {
+ val1 += conf1->GreenSize;
+ val2 += conf2->GreenSize;
}
- if (GET_CONFIG_ATTRIB(criteria, EGL_BLUE_SIZE) > 0) {
- val1 += GET_CONFIG_ATTRIB(conf1, EGL_BLUE_SIZE);
- val2 += GET_CONFIG_ATTRIB(conf2, EGL_BLUE_SIZE);
+ if (criteria->BlueSize > 0) {
+ val1 += conf1->BlueSize;
+ val2 += conf2->BlueSize;
}
}
else {
- if (GET_CONFIG_ATTRIB(criteria, EGL_LUMINANCE_SIZE) > 0) {
- val1 += GET_CONFIG_ATTRIB(conf1, EGL_LUMINANCE_SIZE);
- val2 += GET_CONFIG_ATTRIB(conf2, EGL_LUMINANCE_SIZE);
+ if (criteria->LuminanceSize > 0) {
+ val1 += conf1->LuminanceSize;
+ val2 += conf2->LuminanceSize;
}
}
- if (GET_CONFIG_ATTRIB(criteria, EGL_ALPHA_SIZE) > 0) {
- val1 += GET_CONFIG_ATTRIB(conf1, EGL_ALPHA_SIZE);
- val2 += GET_CONFIG_ATTRIB(conf2, EGL_ALPHA_SIZE);
+ if (criteria->AlphaSize > 0) {
+ val1 += conf1->AlphaSize;
+ val2 += conf2->AlphaSize;
}
}
else {
@@ -669,24 +608,15 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
return (val2 - val1);
for (i = 0; i < ARRAY_SIZE(compare_attribs); i++) {
- val1 = GET_CONFIG_ATTRIB(conf1, compare_attribs[i]);
- val2 = GET_CONFIG_ATTRIB(conf2, compare_attribs[i]);
+ val1 = _eglGetConfigKey(conf1, compare_attribs[i]);
+ val2 = _eglGetConfigKey(conf2, compare_attribs[i]);
if (val1 != val2)
return (val1 - val2);
}
/* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
- if (compare_id) {
- val1 = GET_CONFIG_ATTRIB(conf1, EGL_CONFIG_ID);
- val2 = GET_CONFIG_ATTRIB(conf2, EGL_CONFIG_ID);
- assert(val1 != val2);
- }
- else {
- val1 = val2 = 0;
- }
-
- return (val1 - val2);
+ return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0;
}
@@ -764,8 +694,7 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
if (!num_configs)
return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs");
- _eglInitConfig(&criteria, disp, 0);
- if (!_eglParseConfigAttribList(&criteria, attrib_list))
+ if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
configList = (_EGLConfig **) _eglFilterArray(disp->Configs, &count,
@@ -802,7 +731,7 @@ _eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
if (!value)
return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib");
- *value = GET_CONFIG_ATTRIB(conf, attribute);
+ *value = _eglGetConfigKey(conf, attribute);
return EGL_TRUE;
}
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index 0ad58cf473d..3457670bfa5 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -6,51 +6,97 @@
#include "egltypedefs.h"
-#define _EGL_CONFIG_FIRST_ATTRIB EGL_BUFFER_SIZE
-#define _EGL_CONFIG_LAST_ATTRIB EGL_CONFORMANT
-#define _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS \
- (_EGL_CONFIG_LAST_ATTRIB - _EGL_CONFIG_FIRST_ATTRIB + 1)
-
-/* Attributes outside the contiguous block:
- *
- * EGL_Y_INVERTED_NOK
- */
-#define _EGL_CONFIG_FIRST_EXTRA_ATTRIB _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS
-#define _EGL_CONFIG_NUM_EXTRA_ATTRIBS 1
-
-#define _EGL_CONFIG_NUM_ATTRIBS \
- _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS + _EGL_CONFIG_NUM_EXTRA_ATTRIBS
-
-
+/* update _eglValidationTable and _eglOffsetOfConfig before updating this
+ * struct */
struct _egl_config
{
_EGLDisplay *Display;
- EGLint Storage[_EGL_CONFIG_NUM_ATTRIBS];
-};
-
-/**
- * Macros for source level compatibility.
- */
-#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) _eglSetConfigKey(CONF, ATTR, VAL)
-#define GET_CONFIG_ATTRIB(CONF, ATTR) _eglGetConfigKey(CONF, ATTR)
+ /* core */
+ EGLint BufferSize;
+ EGLint AlphaSize;
+ EGLint BlueSize;
+ EGLint GreenSize;
+ EGLint RedSize;
+ EGLint DepthSize;
+ EGLint StencilSize;
+ EGLint ConfigCaveat;
+ EGLint ConfigID;
+ EGLint Level;
+ EGLint MaxPbufferHeight;
+ EGLint MaxPbufferPixels;
+ EGLint MaxPbufferWidth;
+ EGLint NativeRenderable;
+ EGLint NativeVisualID;
+ EGLint NativeVisualType;
+ EGLint Samples;
+ EGLint SampleBuffers;
+ EGLint SurfaceType;
+ EGLint TransparentType;
+ EGLint TransparentBlueValue;
+ EGLint TransparentGreenValue;
+ EGLint TransparentRedValue;
+ EGLint BindToTextureRGB;
+ EGLint BindToTextureRGBA;
+ EGLint MinSwapInterval;
+ EGLint MaxSwapInterval;
+ EGLint LuminanceSize;
+ EGLint AlphaMaskSize;
+ EGLint ColorBufferType;
+ EGLint RenderableType;
+ EGLint MatchNativePixmap;
+ EGLint Conformant;
+
+ /* extensions */
+ EGLint YInvertedNOK;
+};
/**
- * Given a key, return an index into the storage of the config.
- * Return -1 if the key is invalid.
+ * Map an EGL attribute enum to the offset of the member in _EGLConfig.
*/
static INLINE EGLint
-_eglIndexConfig(const _EGLConfig *conf, EGLint key)
+_eglOffsetOfConfig(EGLint attr)
{
- (void) conf;
- if (key >= _EGL_CONFIG_FIRST_ATTRIB &&
- key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS)
- return key - _EGL_CONFIG_FIRST_ATTRIB;
-
- switch (key) {
- case EGL_Y_INVERTED_NOK:
- return _EGL_CONFIG_FIRST_EXTRA_ATTRIB;
+ switch (attr) {
+#define ATTRIB_MAP(attr, memb) case attr: return offsetof(_EGLConfig, memb)
+ /* core */
+ ATTRIB_MAP(EGL_BUFFER_SIZE, BufferSize);
+ ATTRIB_MAP(EGL_ALPHA_SIZE, AlphaSize);
+ ATTRIB_MAP(EGL_BLUE_SIZE, BlueSize);
+ ATTRIB_MAP(EGL_GREEN_SIZE, GreenSize);
+ ATTRIB_MAP(EGL_RED_SIZE, RedSize);
+ ATTRIB_MAP(EGL_DEPTH_SIZE, DepthSize);
+ ATTRIB_MAP(EGL_STENCIL_SIZE, StencilSize);
+ ATTRIB_MAP(EGL_CONFIG_CAVEAT, ConfigCaveat);
+ ATTRIB_MAP(EGL_CONFIG_ID, ConfigID);
+ ATTRIB_MAP(EGL_LEVEL, Level);
+ ATTRIB_MAP(EGL_MAX_PBUFFER_HEIGHT, MaxPbufferHeight);
+ ATTRIB_MAP(EGL_MAX_PBUFFER_PIXELS, MaxPbufferPixels);
+ ATTRIB_MAP(EGL_MAX_PBUFFER_WIDTH, MaxPbufferWidth);
+ ATTRIB_MAP(EGL_NATIVE_RENDERABLE, NativeRenderable);
+ ATTRIB_MAP(EGL_NATIVE_VISUAL_ID, NativeVisualID);
+ ATTRIB_MAP(EGL_NATIVE_VISUAL_TYPE, NativeVisualType);
+ ATTRIB_MAP(EGL_SAMPLES, Samples);
+ ATTRIB_MAP(EGL_SAMPLE_BUFFERS, SampleBuffers);
+ ATTRIB_MAP(EGL_SURFACE_TYPE, SurfaceType);
+ ATTRIB_MAP(EGL_TRANSPARENT_TYPE, TransparentType);
+ ATTRIB_MAP(EGL_TRANSPARENT_BLUE_VALUE, TransparentBlueValue);
+ ATTRIB_MAP(EGL_TRANSPARENT_GREEN_VALUE, TransparentGreenValue);
+ ATTRIB_MAP(EGL_TRANSPARENT_RED_VALUE, TransparentRedValue);
+ ATTRIB_MAP(EGL_BIND_TO_TEXTURE_RGB, BindToTextureRGB);
+ ATTRIB_MAP(EGL_BIND_TO_TEXTURE_RGBA, BindToTextureRGBA);
+ ATTRIB_MAP(EGL_MIN_SWAP_INTERVAL, MinSwapInterval);
+ ATTRIB_MAP(EGL_MAX_SWAP_INTERVAL, MaxSwapInterval);
+ ATTRIB_MAP(EGL_LUMINANCE_SIZE, LuminanceSize);
+ ATTRIB_MAP(EGL_ALPHA_MASK_SIZE, AlphaMaskSize);
+ ATTRIB_MAP(EGL_COLOR_BUFFER_TYPE, ColorBufferType);
+ ATTRIB_MAP(EGL_RENDERABLE_TYPE, RenderableType);
+ ATTRIB_MAP(EGL_MATCH_NATIVE_PIXMAP, MatchNativePixmap);
+ ATTRIB_MAP(EGL_CONFORMANT, Conformant);
+ /* extensions */
+ ATTRIB_MAP(EGL_Y_INVERTED_NOK, YInvertedNOK);
+#undef ATTRIB_MAP
default:
return -1;
}
@@ -58,18 +104,6 @@ _eglIndexConfig(const _EGLConfig *conf, EGLint key)
/**
- * Reset all keys in the config to a given value.
- */
-static INLINE void
-_eglResetConfigKeys(_EGLConfig *conf, EGLint val)
-{
- EGLint i;
- for (i = 0; i < _EGL_CONFIG_NUM_ATTRIBS; i++)
- conf->Storage[i] = val;
-}
-
-
-/**
* Update a config for a given key.
*
* Note that a valid key is not necessarily a valid attribute. There are gaps
@@ -79,9 +113,9 @@ _eglResetConfigKeys(_EGLConfig *conf, EGLint val)
static INLINE void
_eglSetConfigKey(_EGLConfig *conf, EGLint key, EGLint val)
{
- EGLint idx = _eglIndexConfig(conf, key);
- assert(idx >= 0);
- conf->Storage[idx] = val;
+ EGLint offset = _eglOffsetOfConfig(key);
+ assert(offset >= 0);
+ *((EGLint *) ((char *) conf + offset)) = val;
}
@@ -91,9 +125,9 @@ _eglSetConfigKey(_EGLConfig *conf, EGLint key, EGLint val)
static INLINE EGLint
_eglGetConfigKey(const _EGLConfig *conf, EGLint key)
{
- EGLint idx = _eglIndexConfig(conf, key);
- assert(idx >= 0);
- return conf->Storage[idx];
+ EGLint offset = _eglOffsetOfConfig(key);
+ assert(offset >= 0);
+ return *((EGLint *) ((char *) conf + offset));
}
@@ -102,34 +136,20 @@ _eglInitConfig(_EGLConfig *config, _EGLDisplay *dpy, EGLint id);
PUBLIC EGLConfig
-_eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf);
-
-
-extern EGLBoolean
-_eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy);
+_eglLinkConfig(_EGLConfig *conf);
-/**
- * Lookup a handle to find the linked config.
- * Return NULL if the handle has no corresponding linked config.
- */
-static INLINE _EGLConfig *
-_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy)
-{
- _EGLConfig *conf = (_EGLConfig *) config;
- if (!dpy || !_eglCheckConfigHandle(config, dpy))
- conf = NULL;
- return conf;
-}
+extern _EGLConfig *
+_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy);
/**
- * Return the handle of a linked config, or NULL.
+ * Return the handle of a linked config.
*/
static INLINE EGLConfig
_eglGetConfigHandle(_EGLConfig *conf)
{
- return (EGLConfig) ((conf && conf->Display) ? conf : NULL);
+ return (EGLConfig) conf;
}
@@ -142,7 +162,8 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria);
PUBLIC EGLBoolean
-_eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list);
+_eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy,
+ const EGLint *attrib_list);
PUBLIC EGLint
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index bc22913d401..33dcfa68756 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -103,8 +103,7 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
return EGL_FALSE;
}
- memset(ctx, 0, sizeof(_EGLContext));
- ctx->Resource.Display = dpy;
+ _eglInitResource(&ctx->Resource, sizeof(*ctx), dpy);
ctx->ClientAPI = api;
ctx->Config = conf;
ctx->WindowRenderBuffer = EGL_NONE;
@@ -113,13 +112,12 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
err = _eglParseContextAttribList(ctx, attrib_list);
if (err == EGL_SUCCESS && ctx->Config) {
- EGLint renderable_type, api_bit;
+ EGLint api_bit;
- renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE);
api_bit = _eglGetContextAPIBit(ctx);
- if (!(renderable_type & api_bit)) {
+ if (!(ctx->Config->RenderableType & api_bit)) {
_eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
- api_bit, renderable_type);
+ api_bit, ctx->Config->RenderableType);
err = EGL_BAD_CONFIG;
}
}
@@ -130,29 +128,6 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
}
-/**
- * Just a placeholder/demo function. Real driver will never use this!
- */
-_EGLContext *
-_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- _EGLContext *share_list, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Default fallback routine - drivers should usually override this.
- */
-EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
-{
- if (!_eglIsContextBound(ctx))
- free(ctx);
- return EGL_TRUE;
-}
-
-
#ifdef EGL_VERSION_1_2
static EGLint
_eglQueryContextRenderBuffer(_EGLContext *ctx)
@@ -183,7 +158,9 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
switch (attribute) {
case EGL_CONFIG_ID:
- *value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID);
+ if (!c->Config)
+ return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
+ *value = c->Config->ConfigID;
break;
case EGL_CONTEXT_CLIENT_VERSION:
*value = c->ClientVersion;
@@ -272,10 +249,6 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
if (!surfaceless && (draw == NULL || read == NULL))
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- /* context stealing from another thread is not allowed */
- if (ctx->Binding && ctx->Binding != t)
- return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
-
/*
* The spec says
*
@@ -283,16 +256,23 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
* bound to contexts in another thread, an EGL_BAD_ACCESS error is
* generated."
*
- * But it also says
+ * and
*
* "at most one context may be bound to a particular surface at a given
* time"
- *
- * The latter is more restrictive so we can check only the latter case.
*/
- if ((draw && draw->CurrentContext && draw->CurrentContext != ctx) ||
- (read && read->CurrentContext && read->CurrentContext != ctx))
+ if (ctx->Binding && ctx->Binding != t)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+ if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
+ if (draw->CurrentContext->Binding != t ||
+ draw->CurrentContext->ClientAPI != ctx->ClientAPI)
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+ }
+ if (read && read->CurrentContext && read->CurrentContext != ctx) {
+ if (read->CurrentContext->Binding != t ||
+ read->CurrentContext->ClientAPI != ctx->ClientAPI)
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+ }
/* simply require the configs to be equal */
if ((draw && draw->Config != ctx->Config) ||
@@ -323,79 +303,65 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
/**
* Bind the context to the current thread and given surfaces. Return the
- * "orphaned" context and surfaces. Each argument is both input and output.
+ * previous bound context and surfaces. The caller should unreference the
+ * returned context and surfaces.
+ *
+ * Making a second call with the resources returned by the first call
+ * unsurprisingly undoes the first call, except for the resouce reference
+ * counts.
*/
EGLBoolean
-_eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read)
+_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read,
+ _EGLContext **old_ctx,
+ _EGLSurface **old_draw, _EGLSurface **old_read)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
- _EGLContext *newCtx = *ctx, *oldCtx;
- _EGLSurface *newDraw = *draw, *newRead = *read;
+ _EGLContext *prev_ctx;
+ _EGLSurface *prev_draw, *prev_read;
- if (!_eglCheckMakeCurrent(newCtx, newDraw, newRead))
+ if (!_eglCheckMakeCurrent(ctx, draw, read))
return EGL_FALSE;
+ /* increment refcounts before binding */
+ _eglGetContext(ctx);
+ _eglGetSurface(draw);
+ _eglGetSurface(read);
+
/* bind the new context */
- oldCtx = _eglBindContextToThread(newCtx, t);
+ prev_ctx = _eglBindContextToThread(ctx, t);
- /* break old bindings */
- if (oldCtx) {
- *ctx = oldCtx;
- *draw = oldCtx->DrawSurface;
- *read = oldCtx->ReadSurface;
+ /* break previous bindings */
+ if (prev_ctx) {
+ prev_draw = prev_ctx->DrawSurface;
+ prev_read = prev_ctx->ReadSurface;
- if (*draw)
- (*draw)->CurrentContext = NULL;
- if (*read)
- (*read)->CurrentContext = NULL;
+ if (prev_draw)
+ prev_draw->CurrentContext = NULL;
+ if (prev_read)
+ prev_read->CurrentContext = NULL;
- oldCtx->DrawSurface = NULL;
- oldCtx->ReadSurface = NULL;
+ prev_ctx->DrawSurface = NULL;
+ prev_ctx->ReadSurface = NULL;
+ }
+ else {
+ prev_draw = prev_read = NULL;
}
/* establish new bindings */
- if (newCtx) {
- if (newDraw)
- newDraw->CurrentContext = newCtx;
- if (newRead)
- newRead->CurrentContext = newCtx;
-
- newCtx->DrawSurface = newDraw;
- newCtx->ReadSurface = newRead;
+ if (ctx) {
+ if (draw)
+ draw->CurrentContext = ctx;
+ if (read)
+ read->CurrentContext = ctx;
+
+ ctx->DrawSurface = draw;
+ ctx->ReadSurface = read;
}
- /* an old context or surface is not orphaned if it is still bound */
- if (*ctx == newCtx)
- *ctx = NULL;
- if (*draw == newDraw || *draw == newRead)
- *draw = NULL;
- if (*read == newDraw || *read == newRead)
- *read = NULL;
+ assert(old_ctx && old_draw && old_read);
+ *old_ctx = prev_ctx;
+ *old_draw = prev_draw;
+ *old_read = prev_read;
return EGL_TRUE;
}
-
-
-/**
- * Just a placeholder/demo function. Drivers should override this.
- */
-EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw,
- _EGLSurface *read, _EGLContext *ctx)
-{
- return EGL_FALSE;
-}
-
-
-/**
- * This is defined by the EGL_MESA_copy_context extension.
- */
-EGLBoolean
-_eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source,
- EGLContext dest, EGLint mask)
-{
- /* This function will always have to be overridden/implemented in the
- * device driver. If the driver is based on Mesa, use _mesa_copy_context().
- */
- return EGL_FALSE;
-}
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index cfe92dd9f5c..8cd0df17313 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -34,51 +34,46 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy,
_EGLConfig *config, const EGLint *attrib_list);
-extern _EGLContext *
-_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
-
-
-extern EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
-
-
extern EGLBoolean
_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
PUBLIC EGLBoolean
-_eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read);
-
-
-extern EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
+_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read,
+ _EGLContext **old_ctx,
+ _EGLSurface **old_draw, _EGLSurface **old_read);
-extern EGLBoolean
-_eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
+/**
+ * Increment reference count for the context.
+ */
+static INLINE _EGLContext *
+_eglGetContext(_EGLContext *ctx)
+{
+ if (ctx)
+ _eglGetResource(&ctx->Resource);
+ return ctx;
+}
/**
- * Return true if the context is bound to a thread.
- *
- * The binding is considered a reference to the context. Drivers should not
- * destroy a context when it is bound.
+ * Decrement reference count for the context.
*/
static INLINE EGLBoolean
-_eglIsContextBound(_EGLContext *ctx)
+_eglPutContext(_EGLContext *ctx)
{
- return (ctx->Binding != NULL);
+ return (ctx) ? _eglPutResource(&ctx->Resource) : EGL_FALSE;
}
/**
- * Link a context to a display and return the handle of the link.
+ * Link a context to its display and return the handle of the link.
* The handle can be passed to client directly.
*/
static INLINE EGLContext
-_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy)
+_eglLinkContext(_EGLContext *ctx)
{
- _eglLinkResource(&ctx->Resource, _EGL_RESOURCE_CONTEXT, dpy);
+ _eglLinkResource(&ctx->Resource, _EGL_RESOURCE_CONTEXT);
return (EGLContext) ctx;
}
@@ -120,18 +115,4 @@ _eglGetContextHandle(_EGLContext *ctx)
}
-/**
- * Return true if the context is linked to a display.
- *
- * The link is considered a reference to the context (the display is owning the
- * context). Drivers should not destroy a context when it is linked.
- */
-static INLINE EGLBoolean
-_eglIsContextLinked(_EGLContext *ctx)
-{
- _EGLResource *res = (_EGLResource *) ctx;
- return (res && _eglIsResourceLinked(res));
-}
-
-
#endif /* EGLCONTEXT_INCLUDED */
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index cc0f03e01ba..565e44d2d23 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -233,17 +233,53 @@ _eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy)
/**
- * Link a resource to a display.
+ * Initialize a display resource.
*/
void
-_eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy)
+_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *dpy)
{
- assert(!res->Display || res->Display == dpy);
-
+ memset(res, 0, size);
res->Display = dpy;
+ res->RefCount = 1;
+}
+
+
+/**
+ * Increment reference count for the resource.
+ */
+void
+_eglGetResource(_EGLResource *res)
+{
+ assert(res && res->RefCount > 0);
+ /* hopefully a resource is always manipulated with its display locked */
+ res->RefCount++;
+}
+
+
+/**
+ * Decrement reference count for the resource.
+ */
+EGLBoolean
+_eglPutResource(_EGLResource *res)
+{
+ assert(res && res->RefCount > 0);
+ res->RefCount--;
+ return (!res->RefCount);
+}
+
+
+/**
+ * Link a resource to its display.
+ */
+void
+_eglLinkResource(_EGLResource *res, _EGLResourceType type)
+{
+ assert(res->Display);
+
res->IsLinked = EGL_TRUE;
- res->Next = dpy->ResourceLists[type];
- dpy->ResourceLists[type] = res;
+ res->Next = res->Display->ResourceLists[type];
+ res->Display->ResourceLists[type] = res;
+ _eglGetResource(res);
}
@@ -270,6 +306,9 @@ _eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
}
res->Next = NULL;
- /* do not reset res->Display */
res->IsLinked = EGL_FALSE;
+ _eglPutResource(res);
+
+ /* We always unlink before destroy. The driver still owns a reference */
+ assert(res->RefCount);
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 3863cce0108..bcba05480a8 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -40,6 +40,7 @@ struct _egl_resource
/* which display the resource belongs to */
_EGLDisplay *Display;
EGLBoolean IsLinked;
+ EGLint RefCount;
/* used to link resources of the same type */
_EGLResource *Next;
@@ -162,7 +163,19 @@ _eglGetDisplayHandle(_EGLDisplay *dpy)
extern void
-_eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy);
+_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *dpy);
+
+
+PUBLIC void
+_eglGetResource(_EGLResource *res);
+
+
+PUBLIC EGLBoolean
+_eglPutResource(_EGLResource *res);
+
+
+extern void
+_eglLinkResource(_EGLResource *res, _EGLResourceType type);
extern void
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index a4ff6911be6..2359253ff13 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -9,18 +9,10 @@
#include <stdlib.h>
#include "eglstring.h"
-#include "eglconfig.h"
-#include "eglcontext.h"
#include "egldefines.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "egllog.h"
-#include "eglmisc.h"
-#include "eglmode.h"
-#include "eglscreen.h"
-#include "eglsurface.h"
-#include "eglimage.h"
-#include "eglsync.h"
#include "eglmutex.h"
#if defined(_EGL_OS_UNIX)
@@ -663,77 +655,6 @@ _eglUnloadDrivers(void)
/**
- * Plug all the available fallback routines into the given driver's
- * dispatch table.
- */
-void
-_eglInitDriverFallbacks(_EGLDriver *drv)
-{
- /* If a pointer is set to NULL, then the device driver _really_ has
- * to implement it.
- */
- drv->API.Initialize = NULL;
- drv->API.Terminate = NULL;
-
- drv->API.GetConfigs = _eglGetConfigs;
- drv->API.ChooseConfig = _eglChooseConfig;
- drv->API.GetConfigAttrib = _eglGetConfigAttrib;
-
- drv->API.CreateContext = _eglCreateContext;
- drv->API.DestroyContext = _eglDestroyContext;
- drv->API.MakeCurrent = _eglMakeCurrent;
- drv->API.QueryContext = _eglQueryContext;
-
- drv->API.CreateWindowSurface = _eglCreateWindowSurface;
- drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
- drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
- drv->API.DestroySurface = _eglDestroySurface;
- drv->API.QuerySurface = _eglQuerySurface;
- drv->API.SurfaceAttrib = _eglSurfaceAttrib;
- drv->API.BindTexImage = _eglBindTexImage;
- drv->API.ReleaseTexImage = _eglReleaseTexImage;
- drv->API.SwapInterval = _eglSwapInterval;
- drv->API.SwapBuffers = _eglSwapBuffers;
- drv->API.CopyBuffers = _eglCopyBuffers;
-
- drv->API.QueryString = _eglQueryString;
- drv->API.WaitClient = _eglWaitClient;
- drv->API.WaitNative = _eglWaitNative;
-
-#ifdef EGL_MESA_screen_surface
- drv->API.ChooseModeMESA = _eglChooseModeMESA;
- drv->API.GetModesMESA = _eglGetModesMESA;
- drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
- drv->API.GetScreensMESA = _eglGetScreensMESA;
- drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
- drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
- drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
- drv->API.QueryScreenMESA = _eglQueryScreenMESA;
- drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
- drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
- drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
-#endif /* EGL_MESA_screen_surface */
-
-#ifdef EGL_VERSION_1_2
- drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
-#endif /* EGL_VERSION_1_2 */
-
-#ifdef EGL_KHR_image_base
- drv->API.CreateImageKHR = _eglCreateImageKHR;
- drv->API.DestroyImageKHR = _eglDestroyImageKHR;
-#endif /* EGL_KHR_image_base */
-
-#ifdef EGL_KHR_reusable_sync
- drv->API.CreateSyncKHR = _eglCreateSyncKHR;
- drv->API.DestroySyncKHR = _eglDestroySyncKHR;
- drv->API.ClientWaitSyncKHR = _eglClientWaitSyncKHR;
- drv->API.SignalSyncKHR = _eglSignalSyncKHR;
- drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR;
-#endif /* EGL_KHR_reusable_sync */
-}
-
-
-/**
* Invoke a callback function on each EGL search path.
*
* The first argument of the callback function is the name of the search path.
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index c618feb6b02..1ca7c6cd936 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -80,6 +80,7 @@ extern void
_eglUnloadDrivers(void);
+/* defined in eglfallbacks.c */
PUBLIC void
_eglInitDriverFallbacks(_EGLDriver *drv);
diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c
new file mode 100644
index 00000000000..7c93adb76aa
--- /dev/null
+++ b/src/egl/main/eglfallbacks.c
@@ -0,0 +1,99 @@
+#include <string.h>
+#include "egltypedefs.h"
+#include "egldriver.h"
+#include "eglconfig.h"
+#include "eglcontext.h"
+#include "eglsurface.h"
+#include "eglmisc.h"
+#include "eglscreen.h"
+#include "eglmode.h"
+#include "eglsync.h"
+
+
+static EGLBoolean
+_eglReturnFalse(void)
+{
+ return EGL_FALSE;
+}
+
+
+/**
+ * Plug all the available fallback routines into the given driver's
+ * dispatch table.
+ */
+void
+_eglInitDriverFallbacks(_EGLDriver *drv)
+{
+ memset(&drv->API, 0, sizeof(drv->API));
+
+ /* the driver has to implement these */
+ drv->API.Initialize = NULL;
+ drv->API.Terminate = NULL;
+
+ drv->API.GetConfigs = _eglGetConfigs;
+ drv->API.ChooseConfig = _eglChooseConfig;
+ drv->API.GetConfigAttrib = _eglGetConfigAttrib;
+
+ drv->API.CreateContext = (CreateContext_t) _eglReturnFalse;
+ drv->API.DestroyContext = (DestroyContext_t) _eglReturnFalse;
+ drv->API.MakeCurrent = (MakeCurrent_t) _eglReturnFalse;
+ drv->API.QueryContext = _eglQueryContext;
+
+ drv->API.CreateWindowSurface = (CreateWindowSurface_t) _eglReturnFalse;
+ drv->API.CreatePixmapSurface = (CreatePixmapSurface_t) _eglReturnFalse;
+ drv->API.CreatePbufferSurface = (CreatePbufferSurface_t) _eglReturnFalse;
+ drv->API.CreatePbufferFromClientBuffer =
+ (CreatePbufferFromClientBuffer_t) _eglReturnFalse;
+ drv->API.DestroySurface = (DestroySurface_t) _eglReturnFalse;
+ drv->API.QuerySurface = _eglQuerySurface;
+ drv->API.SurfaceAttrib = _eglSurfaceAttrib;
+
+ drv->API.BindTexImage = (BindTexImage_t) _eglReturnFalse;
+ drv->API.ReleaseTexImage = (ReleaseTexImage_t) _eglReturnFalse;
+ drv->API.CopyBuffers = (CopyBuffers_t) _eglReturnFalse;
+ drv->API.SwapBuffers = (SwapBuffers_t) _eglReturnFalse;
+ drv->API.SwapInterval = _eglSwapInterval;
+
+ drv->API.WaitClient = (WaitClient_t) _eglReturnFalse;
+ drv->API.WaitNative = (WaitNative_t) _eglReturnFalse;
+ drv->API.GetProcAddress = (GetProcAddress_t) _eglReturnFalse;
+ drv->API.QueryString = _eglQueryString;
+
+#ifdef EGL_MESA_screen_surface
+ drv->API.CopyContextMESA = (CopyContextMESA_t) _eglReturnFalse;
+ drv->API.CreateScreenSurfaceMESA =
+ (CreateScreenSurfaceMESA_t) _eglReturnFalse;
+ drv->API.ShowScreenSurfaceMESA = (ShowScreenSurfaceMESA_t) _eglReturnFalse;
+ drv->API.ChooseModeMESA = _eglChooseModeMESA;
+ drv->API.GetModesMESA = _eglGetModesMESA;
+ drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
+ drv->API.GetScreensMESA = _eglGetScreensMESA;
+ drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
+ drv->API.QueryScreenMESA = _eglQueryScreenMESA;
+ drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
+ drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
+ drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
+#endif /* EGL_MESA_screen_surface */
+
+#ifdef EGL_KHR_image_base
+ drv->API.CreateImageKHR = NULL;
+ drv->API.DestroyImageKHR = NULL;
+#endif /* EGL_KHR_image_base */
+
+#ifdef EGL_KHR_reusable_sync
+ drv->API.CreateSyncKHR = NULL;
+ drv->API.DestroySyncKHR = NULL;
+ drv->API.ClientWaitSyncKHR = NULL;
+ drv->API.SignalSyncKHR = NULL;
+ drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR;
+#endif /* EGL_KHR_reusable_sync */
+
+#ifdef EGL_MESA_drm_image
+ drv->API.CreateDRMImageMESA = NULL;
+ drv->API.ExportDRMImageMESA = NULL;
+#endif
+
+#ifdef EGL_NOK_swap_region
+ drv->API.SwapBuffersRegionNOK = NULL;
+#endif
+}
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 5732ef35ecd..6d4ee4e08b9 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -2,7 +2,6 @@
#include <string.h>
#include "eglimage.h"
-#include "eglcurrent.h"
#include "egllog.h"
@@ -12,28 +11,57 @@
/**
* Parse the list of image attributes and return the proper error code.
*/
-static EGLint
-_eglParseImageAttribList(_EGLImage *img, const EGLint *attrib_list)
+EGLint
+_eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
+ const EGLint *attrib_list)
{
EGLint i, err = EGL_SUCCESS;
+ (void) dpy;
+
+ memset(attrs, 0, sizeof(attrs));
+ attrs->ImagePreserved = EGL_FALSE;
+ attrs->GLTextureLevel = 0;
+ attrs->GLTextureZOffset = 0;
+
if (!attrib_list)
- return EGL_SUCCESS;
+ return err;
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
EGLint attr = attrib_list[i++];
EGLint val = attrib_list[i];
switch (attr) {
+ /* EGL_KHR_image_base */
case EGL_IMAGE_PRESERVED_KHR:
- img->Preserved = val;
+ attrs->ImagePreserved = val;
break;
+
+ /* EGL_KHR_gl_image */
case EGL_GL_TEXTURE_LEVEL_KHR:
- img->GLTextureLevel = val;
+ attrs->GLTextureLevel = val;
break;
case EGL_GL_TEXTURE_ZOFFSET_KHR:
- img->GLTextureZOffset = val;
+ attrs->GLTextureZOffset = val;
+ break;
+
+ /* EGL_MESA_drm_image */
+ case EGL_WIDTH:
+ attrs->Width = val;
+ break;
+ case EGL_HEIGHT:
+ attrs->Height = val;
break;
+ case EGL_DRM_BUFFER_FORMAT_MESA:
+ attrs->DRMBufferFormatMESA = val;
+ break;
+ case EGL_DRM_BUFFER_USE_MESA:
+ attrs->DRMBufferUseMESA = val;
+ break;
+ case EGL_DRM_BUFFER_STRIDE_MESA:
+ attrs->DRMBufferStrideMESA = val;
+ break;
+
default:
/* unknown attrs are ignored */
break;
@@ -50,41 +78,12 @@ _eglParseImageAttribList(_EGLImage *img, const EGLint *attrib_list)
EGLBoolean
-_eglInitImage(_EGLImage *img, _EGLDisplay *dpy, const EGLint *attrib_list)
+_eglInitImage(_EGLImage *img, _EGLDisplay *dpy)
{
- EGLint err;
-
- memset(img, 0, sizeof(_EGLImage));
- img->Resource.Display = dpy;
-
- img->Preserved = EGL_FALSE;
- img->GLTextureLevel = 0;
- img->GLTextureZOffset = 0;
-
- err = _eglParseImageAttribList(img, attrib_list);
- if (err != EGL_SUCCESS)
- return _eglError(err, "eglCreateImageKHR");
+ _eglInitResource(&img->Resource, sizeof(*img), dpy);
return EGL_TRUE;
}
-_EGLImage *
-_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
- EGLenum target, EGLClientBuffer buffer,
- const EGLint *attr_list)
-{
- /* driver should override this function */
- return NULL;
-}
-
-
-EGLBoolean
-_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image)
-{
- /* driver should override this function */
- return EGL_FALSE;
-}
-
-
#endif /* EGL_KHR_image_base */
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 2c0fb16d1d3..adb939a9e02 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -6,6 +6,23 @@
#include "egldisplay.h"
+struct _egl_image_attribs
+{
+ /* EGL_KHR_image_base */
+ EGLBoolean ImagePreserved;
+
+ /* EGL_KHR_gl_image */
+ EGLint GLTextureLevel;
+ EGLint GLTextureZOffset;
+
+ /* EGL_MESA_drm_image */
+ EGLint Width;
+ EGLint Height;
+ EGLint DRMBufferFormatMESA;
+ EGLint DRMBufferUseMESA;
+ EGLint DRMBufferStrideMESA;
+};
+
/**
* "Base" class for device driver images.
*/
@@ -13,34 +30,48 @@ struct _egl_image
{
/* An image is a display resource */
_EGLResource Resource;
-
- EGLBoolean Preserved;
- EGLint GLTextureLevel;
- EGLint GLTextureZOffset;
};
+PUBLIC EGLint
+_eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
+ const EGLint *attrib_list);
+
+
PUBLIC EGLBoolean
-_eglInitImage(_EGLImage *img, _EGLDisplay *dpy, const EGLint *attrib_list);
+_eglInitImage(_EGLImage *img, _EGLDisplay *dpy);
-extern _EGLImage *
-_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
- EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list);
+/**
+ * Increment reference count for the image.
+ */
+static INLINE _EGLImage *
+_eglGetImage(_EGLImage *img)
+{
+ if (img)
+ _eglGetResource(&img->Resource);
+ return img;
+}
-extern EGLBoolean
-_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
+/**
+ * Decrement reference count for the image.
+ */
+static INLINE EGLBoolean
+_eglPutImage(_EGLImage *img)
+{
+ return (img) ? _eglPutResource(&img->Resource) : EGL_FALSE;
+}
/**
- * Link an image to a display and return the handle of the link.
+ * Link an image to its display and return the handle of the link.
* The handle can be passed to client directly.
*/
static INLINE EGLImageKHR
-_eglLinkImage(_EGLImage *img, _EGLDisplay *dpy)
+_eglLinkImage(_EGLImage *img)
{
- _eglLinkResource(&img->Resource, _EGL_RESOURCE_IMAGE, dpy);
+ _eglLinkResource(&img->Resource, _EGL_RESOURCE_IMAGE);
return (EGLImageKHR) img;
}
@@ -82,15 +113,4 @@ _eglGetImageHandle(_EGLImage *img)
}
-/**
- * Return true if the image is linked to a display.
- */
-static INLINE EGLBoolean
-_eglIsImageLinked(_EGLImage *img)
-{
- _EGLResource *res = (_EGLResource *) img;
- return (res && _eglIsResourceLinked(res));
-}
-
-
#endif /* EGLIMAGE_INCLUDED */
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index eb3dde1fb48..bbb96a908e4 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -158,32 +158,3 @@ _eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name)
return NULL;
}
}
-
-
-EGLBoolean
-_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
-{
- /* just a placeholder */
- (void) drv;
- (void) dpy;
- (void) ctx;
- return EGL_TRUE;
-}
-
-
-EGLBoolean
-_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
-{
- /* just a placeholder */
- (void) drv;
- (void) dpy;
- switch (engine) {
- case EGL_CORE_NATIVE_ENGINE:
- break;
- default:
- _eglError(EGL_BAD_PARAMETER, "eglWaitNative(engine)");
- return EGL_FALSE;
- }
-
- return EGL_TRUE;
-}
diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h
index 5e6a2d41df6..a753307a14b 100644
--- a/src/egl/main/eglmisc.h
+++ b/src/egl/main/eglmisc.h
@@ -37,12 +37,4 @@ extern const char *
_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name);
-extern EGLBoolean
-_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
-
-
-extern EGLBoolean
-_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
-
-
#endif /* EGLMISC_INCLUDED */
diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c
index ed107d5d7a7..a9653496c32 100644
--- a/src/egl/main/eglmode.c
+++ b/src/egl/main/eglmode.c
@@ -3,11 +3,9 @@
#include <string.h>
#include "egldisplay.h"
-#include "egldriver.h"
#include "eglmode.h"
#include "eglcurrent.h"
#include "eglscreen.h"
-#include "eglstring.h"
#ifdef EGL_MESA_screen_surface
@@ -31,56 +29,24 @@ _eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
/* loop over all screens on the display */
for (scrnum = 0; scrnum < disp->Screens->Size; scrnum++) {
const _EGLScreen *scrn = disp->Screens->Elements[scrnum];
- EGLint i;
- /* search list of modes for handle */
- for (i = 0; i < scrn->NumModes; i++) {
- if (scrn->Modes[i].Handle == mode) {
- return scrn->Modes + i;
- }
- }
- }
+ EGLint idx;
- return NULL;
-}
+ /*
+ * the mode ids of a screen ranges from scrn->Handle to scrn->Handle +
+ * scrn->NumModes
+ */
+ if (mode >= scrn->Handle &&
+ mode < scrn->Handle + _EGL_SCREEN_MAX_MODES) {
+ idx = mode - scrn->Handle;
+ assert(idx < scrn->NumModes && scrn->Modes[idx].Handle == mode);
-/**
- * Add a new mode with the given attributes (width, height, depth, refreshRate)
- * to the given screen.
- * Assign a new mode ID/handle to the mode as well.
- * \return pointer to the new _EGLMode
- */
-_EGLMode *
-_eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
- EGLint refreshRate, const char *name)
-{
- EGLint n;
- _EGLMode *newModes;
-
- assert(screen);
- assert(width > 0);
- assert(height > 0);
- assert(refreshRate > 0);
-
- n = screen->NumModes;
- newModes = (_EGLMode *) realloc(screen->Modes, (n+1) * sizeof(_EGLMode));
- if (newModes) {
- screen->Modes = newModes;
- screen->Modes[n].Handle = n + 1;
- screen->Modes[n].Width = width;
- screen->Modes[n].Height = height;
- screen->Modes[n].RefreshRate = refreshRate;
- screen->Modes[n].Optimal = EGL_FALSE;
- screen->Modes[n].Interlaced = EGL_FALSE;
- screen->Modes[n].Name = _eglstrdup(name);
- screen->NumModes++;
- return screen->Modes + n;
- }
- else {
- return NULL;
+ return &scrn->Modes[idx];
+ }
}
-}
+ return NULL;
+}
/**
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
index 9167cbc4b9b..ed4eb2c34af 100644
--- a/src/egl/main/eglmode.h
+++ b/src/egl/main/eglmode.h
@@ -32,11 +32,6 @@ extern _EGLMode *
_eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy);
-PUBLIC _EGLMode *
-_eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
- EGLint refreshRate, const char *name);
-
-
extern EGLBoolean
_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
const EGLint *attrib_list, EGLModeMESA *modes,
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
index 9e39335cc7a..3abe85ff22f 100644
--- a/src/egl/main/eglscreen.c
+++ b/src/egl/main/eglscreen.c
@@ -18,7 +18,6 @@
#include "egldisplay.h"
#include "eglcurrent.h"
#include "eglmode.h"
-#include "eglconfig.h"
#include "eglsurface.h"
#include "eglscreen.h"
#include "eglmutex.h"
@@ -42,7 +41,8 @@ _eglAllocScreenHandle(void)
EGLScreenMESA s;
_eglLockMutex(&_eglNextScreenHandleMutex);
- s = _eglNextScreenHandle++;
+ s = _eglNextScreenHandle;
+ _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
_eglUnlockMutex(&_eglNextScreenHandleMutex);
return s;
@@ -53,60 +53,80 @@ _eglAllocScreenHandle(void)
* Initialize an _EGLScreen object to default values.
*/
void
-_eglInitScreen(_EGLScreen *screen)
+_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes)
{
memset(screen, 0, sizeof(_EGLScreen));
+
+ screen->Display = dpy;
+ screen->NumModes = num_modes;
screen->StepX = 1;
screen->StepY = 1;
+
+ if (num_modes > _EGL_SCREEN_MAX_MODES)
+ num_modes = _EGL_SCREEN_MAX_MODES;
+ screen->Modes = (_EGLMode *) calloc(num_modes, sizeof(*screen->Modes));
+ screen->NumModes = (screen->Modes) ? num_modes : 0;
}
/**
- * Given a public screen handle, return the internal _EGLScreen object.
+ * Link a screen to its display and return the handle of the link.
+ * The handle can be passed to client directly.
*/
-_EGLScreen *
-_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
+EGLScreenMESA
+_eglLinkScreen(_EGLScreen *screen)
{
+ _EGLDisplay *display;
EGLint i;
- if (!display || !display->Screens)
- return NULL;
+ assert(screen && screen->Display);
+ display = screen->Display;
- for (i = 0; i < display->Screens->Size; i++) {
- _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
- if (scr->Handle == screen)
- return scr;
+ if (!display->Screens) {
+ display->Screens = _eglCreateArray("Screen", 4);
+ if (!display->Screens)
+ return (EGLScreenMESA) 0;
}
- return NULL;
+
+ screen->Handle = _eglAllocScreenHandle();
+ for (i = 0; i < screen->NumModes; i++)
+ screen->Modes[i].Handle = screen->Handle + i;
+
+ _eglAppendArray(display->Screens, (void *) screen);
+
+ return screen->Handle;
}
/**
- * Add the given _EGLScreen to the display's list of screens.
+ * Lookup a handle to find the linked config.
+ * Return NULL if the handle has no corresponding linked config.
*/
-void
-_eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
+_EGLScreen *
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
{
- assert(display);
- assert(screen);
+ EGLint i;
- if (!display->Screens) {
- display->Screens = _eglCreateArray("Screen", 4);
- if (!display->Screens)
- return;
+ if (!display || !display->Screens)
+ return NULL;
+
+ for (i = 0; i < display->Screens->Size; i++) {
+ _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
+ if (scr->Handle == screen) {
+ assert(scr->Display == display);
+ return scr;
+ }
}
- screen->Handle = _eglAllocScreenHandle();
- _eglAppendArray(display->Screens, (void *) screen);
+ return NULL;
}
-
static EGLBoolean
_eglFlattenScreen(void *elem, void *buffer)
{
_EGLScreen *scr = (_EGLScreen *) elem;
EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
- *handle = scr->Handle;
+ *handle = _eglGetScreenHandle(scr);
return EGL_TRUE;
}
@@ -123,66 +143,6 @@ _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens
/**
- * Drivers should do a proper implementation.
- */
-_EGLSurface *
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Show the given surface on the named screen.
- * If surface is EGL_NO_SURFACE, disable the screen's output.
- *
- * This is just a placeholder function; drivers will always override
- * this with code that _really_ shows the surface.
- */
-EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLScreen *scrn, _EGLSurface *surf,
- _EGLMode *mode)
-{
- if (!surf) {
- scrn->CurrentSurface = NULL;
- }
- else {
- if (surf->Type != EGL_SCREEN_BIT_MESA) {
- _eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
- return EGL_FALSE;
- }
- if (surf->Width < mode->Width || surf->Height < mode->Height) {
- _eglError(EGL_BAD_SURFACE,
- "eglShowSurfaceMESA(surface smaller than screen size)");
- return EGL_FALSE;
- }
-
- scrn->CurrentSurface = surf;
- scrn->CurrentMode = mode;
- }
- return EGL_TRUE;
-}
-
-
-/**
- * Set a screen's current display mode.
- * Note: mode = EGL_NO_MODE is valid (turns off the screen)
- *
- * This is just a placeholder function; drivers will always override
- * this with code that _really_ sets the mode.
- */
-EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
- _EGLMode *m)
-{
- scrn->CurrentMode = m;
- return EGL_TRUE;
-}
-
-
-/**
* Set a screen's surface origin.
*/
EGLBoolean
@@ -242,33 +202,4 @@ _eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
}
-/**
- * Delete the modes associated with given screen.
- */
-void
-_eglDestroyScreenModes(_EGLScreen *scrn)
-{
- EGLint i;
- for (i = 0; i < scrn->NumModes; i++) {
- if (scrn->Modes[i].Name)
- free((char *) scrn->Modes[i].Name); /* cast away const */
- }
- if (scrn->Modes)
- free(scrn->Modes);
- scrn->Modes = NULL;
- scrn->NumModes = 0;
-}
-
-
-/**
- * Default fallback routine - drivers should usually override this.
- */
-void
-_eglDestroyScreen(_EGLScreen *scrn)
-{
- _eglDestroyScreenModes(scrn);
- free(scrn);
-}
-
-
#endif /* EGL_MESA_screen_surface */
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
index 3db20478ad6..2a99f23c50a 100644
--- a/src/egl/main/eglscreen.h
+++ b/src/egl/main/eglscreen.h
@@ -8,6 +8,9 @@
#ifdef EGL_MESA_screen_surface
+#define _EGL_SCREEN_MAX_MODES 16
+
+
/**
* Per-screen information.
* Note that an EGL screen doesn't have a size. A screen may be set to
@@ -19,6 +22,8 @@
*/
struct _egl_screen
{
+ _EGLDisplay *Display;
+
EGLScreenMESA Handle; /* The public/opaque handle which names this object */
_EGLMode *CurrentMode;
@@ -33,42 +38,36 @@ struct _egl_screen
PUBLIC void
-_eglInitScreen(_EGLScreen *screen);
+_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes);
+
+
+PUBLIC EGLScreenMESA
+_eglLinkScreen(_EGLScreen *screen);
extern _EGLScreen *
_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy);
-PUBLIC void
-_eglAddScreen(_EGLDisplay *display, _EGLScreen *screen);
+/**
+ * Return the handle of a linked screen.
+ */
+static INLINE EGLScreenMESA
+_eglGetScreenHandle(_EGLScreen *screen)
+{
+ return (screen) ? screen->Handle : (EGLScreenMESA) 0;
+}
extern EGLBoolean
_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-extern _EGLSurface *
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
-
-
-extern EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLSurface *surf, _EGLMode *m);
-
-
-extern EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode *m);
-
-
extern EGLBoolean
_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint x, EGLint y);
extern EGLBoolean
-_eglQueryDisplayMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLint attribute, EGLint *value);
-
-
-extern EGLBoolean
_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLScreen *scrn, _EGLSurface **surface);
@@ -81,14 +80,6 @@ extern EGLBoolean
_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value);
-extern void
-_eglDestroyScreenModes(_EGLScreen *scrn);
-
-
-PUBLIC void
-_eglDestroyScreen(_EGLScreen *scrn);
-
-
#endif /* EGL_MESA_screen_surface */
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 52f5c240c65..cc505045e12 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -17,12 +17,12 @@
static void
_eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
{
- EGLint bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MAX_SWAP_INTERVAL);
+ EGLint bound = surf->Config->MaxSwapInterval;
if (interval >= bound) {
interval = bound;
}
else {
- bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MIN_SWAP_INTERVAL);
+ bound = surf->Config->MinSwapInterval;
if (interval < bound)
interval = bound;
}
@@ -263,14 +263,13 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
return EGL_FALSE;
}
- if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) {
+ if ((conf->SurfaceType & type) == 0) {
/* The config can't be used to create a surface of this type */
_eglError(EGL_BAD_CONFIG, func);
return EGL_FALSE;
}
- memset(surf, 0, sizeof(_EGLSurface));
- surf->Resource.Display = dpy;
+ _eglInitResource(&surf->Resource, sizeof(*surf), dpy);
surf->Type = type;
surf->Config = conf;
@@ -304,24 +303,6 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
-{
- /* Drivers have to do the actual buffer swap. */
- return EGL_TRUE;
-}
-
-
-EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- EGLNativePixmapType target)
-{
- /* copy surface to native pixmap */
- /* All implementation burdon for this is in the device driver */
- return EGL_FALSE;
-}
-
-
-EGLBoolean
_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint *value)
{
@@ -333,7 +314,7 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
*value = surface->Height;
break;
case EGL_CONFIG_ID:
- *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
+ *value = surface->Config->ConfigID;
break;
case EGL_LARGEST_PBUFFER:
*value = surface->LargestPbuffer;
@@ -389,51 +370,6 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
/**
- * Drivers should do a proper implementation.
- */
-_EGLSurface *
-_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- EGLNativeWindowType window, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Drivers should do a proper implementation.
- */
-_EGLSurface *
-_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- EGLNativePixmapType pixmap, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Drivers should do a proper implementation.
- */
-_EGLSurface *
-_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Default fallback routine - drivers should usually override this.
- */
-EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
-{
- if (!_eglIsSurfaceBound(surf))
- free(surf);
- return EGL_TRUE;
-}
-
-
-/**
* Default fallback routine - drivers might override this.
*/
EGLBoolean
@@ -445,7 +381,7 @@ _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
switch (attribute) {
case EGL_MIPMAP_LEVEL:
- confval = GET_CONFIG_ATTRIB(surface->Config, EGL_RENDERABLE_TYPE);
+ confval = surface->Config->RenderableType;
if (!(confval & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT))) {
err = EGL_BAD_PARAMETER;
break;
@@ -457,7 +393,7 @@ _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
break;
case EGL_MULTISAMPLE_RESOLVE_BOX:
- confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE);
+ confval = surface->Config->SurfaceType;
if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
err = EGL_BAD_MATCH;
break;
@@ -474,7 +410,7 @@ _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
case EGL_BUFFER_DESTROYED:
break;
case EGL_BUFFER_PRESERVED:
- confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE);
+ confval = surface->Config->SurfaceType;
if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
err = EGL_BAD_MATCH;
break;
@@ -537,64 +473,9 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
- EGLint buffer)
-{
- /* Just do basic error checking and return success/fail.
- * Drivers must implement the real stuff.
- */
-
- if (surface->Type != EGL_PBUFFER_BIT) {
- _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
- return EGL_FALSE;
- }
-
- if (surface->TextureFormat == EGL_NO_TEXTURE) {
- _eglError(EGL_BAD_MATCH, "eglBindTexImage");
- return EGL_FALSE;
- }
-
- if (buffer != EGL_BACK_BUFFER) {
- _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
- return EGL_FALSE;
- }
-
- if (!surface->BoundToTexture) {
- _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
- return EGL_FALSE;
- }
-
- surface->BoundToTexture = EGL_FALSE;
-
- return EGL_TRUE;
-}
-
-
-EGLBoolean
_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLint interval)
{
_eglClampSwapInterval(surf, interval);
return EGL_TRUE;
}
-
-
-#ifdef EGL_VERSION_1_2
-
-/**
- * Example function - drivers should do a proper implementation.
- */
-_EGLSurface *
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLenum buftype, EGLClientBuffer buffer,
- _EGLConfig *conf, const EGLint *attrib_list)
-{
- if (buftype != EGL_OPENVG_IMAGE) {
- _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
- return NULL;
- }
-
- return NULL;
-}
-
-#endif /* EGL_VERSION_1_2 */
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 8f520dcdf65..ef01b32ede3 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -52,33 +52,9 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
extern EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
-
-
-extern EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLNativePixmapType target);
-
-
-extern EGLBoolean
_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint *value);
-extern _EGLSurface *
-_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list);
-
-
-extern _EGLSurface *
-_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLNativePixmapType pixmap, const EGLint *attrib_list);
-
-
-extern _EGLSurface *
-_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
-
-
-extern EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
-
-
extern EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value);
@@ -88,44 +64,39 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint bu
extern EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
-
-
-extern EGLBoolean
_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval);
-#ifdef EGL_VERSION_1_2
-
-extern _EGLSurface *
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLenum buftype, EGLClientBuffer buffer,
- _EGLConfig *conf, const EGLint *attrib_list);
-
-#endif /* EGL_VERSION_1_2 */
+/**
+ * Increment reference count for the surface.
+ */
+static INLINE _EGLSurface *
+_eglGetSurface(_EGLSurface *surf)
+{
+ if (surf)
+ _eglGetResource(&surf->Resource);
+ return surf;
+}
/**
- * Return true if there is a context bound to the surface.
- *
- * The binding is considered a reference to the surface. Drivers should not
- * destroy a surface when it is bound.
+ * Decrement reference count for the surface.
*/
static INLINE EGLBoolean
-_eglIsSurfaceBound(_EGLSurface *surf)
+_eglPutSurface(_EGLSurface *surf)
{
- return (surf->CurrentContext != NULL);
+ return (surf) ? _eglPutResource(&surf->Resource) : EGL_FALSE;
}
/**
- * Link a surface to a display and return the handle of the link.
+ * Link a surface to its display and return the handle of the link.
* The handle can be passed to client directly.
*/
static INLINE EGLSurface
-_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy)
+_eglLinkSurface(_EGLSurface *surf)
{
- _eglLinkResource(&surf->Resource, _EGL_RESOURCE_SURFACE, dpy);
+ _eglLinkResource(&surf->Resource, _EGL_RESOURCE_SURFACE);
return (EGLSurface) surf;
}
@@ -167,18 +138,4 @@ _eglGetSurfaceHandle(_EGLSurface *surf)
}
-/**
- * Return true if the surface is linked to a display.
- *
- * The link is considered a reference to the surface (the display is owning the
- * surface). Drivers should not destroy a surface when it is linked.
- */
-static INLINE EGLBoolean
-_eglIsSurfaceLinked(_EGLSurface *surf)
-{
- _EGLResource *res = (_EGLResource *) surf;
- return (res && _eglIsResourceLinked(res));
-}
-
-
#endif /* EGLSURFACE_INCLUDED */
diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c
index b6c62d0087d..95e97c73542 100644
--- a/src/egl/main/eglsync.c
+++ b/src/egl/main/eglsync.c
@@ -50,10 +50,7 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
!(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync))
return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
- memset(sync, 0, sizeof(*sync));
-
- sync->Resource.Display = dpy;
-
+ _eglInitResource(&sync->Resource, sizeof(*sync), dpy);
sync->Type = type;
sync->SyncStatus = EGL_UNSIGNALED_KHR;
sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
@@ -66,37 +63,6 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
}
-_EGLSync *
-_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLenum type, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-EGLBoolean
-_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
-{
- return EGL_TRUE;
-}
-
-
-EGLint
-_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
- EGLint flags, EGLTimeKHR timeout)
-{
- return EGL_FALSE;
-}
-
-
-EGLBoolean
-_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
- EGLenum mode)
-{
- return EGL_FALSE;
-}
-
-
EGLBoolean
_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
EGLint attribute, EGLint *value)
diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h
index 25c467175e9..a0025237e7a 100644
--- a/src/egl/main/eglsync.h
+++ b/src/egl/main/eglsync.h
@@ -28,38 +28,41 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
const EGLint *attrib_list);
-extern _EGLSync *
-_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLenum type, const EGLint *attrib_list);
-
-
extern EGLBoolean
-_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
-
-
-extern EGLint
-_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
- EGLint flags, EGLTimeKHR timeout);
+_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLint attribute, EGLint *value);
-extern EGLBoolean
-_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
- EGLenum mode);
+/**
+ * Increment reference count for the sync.
+ */
+static INLINE _EGLSync *
+_eglGetSync(_EGLSync *sync)
+{
+ if (sync)
+ _eglGetResource(&sync->Resource);
+ return sync;
+}
-extern EGLBoolean
-_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
- EGLint attribute, EGLint *value);
+/**
+ * Decrement reference count for the sync.
+ */
+static INLINE EGLBoolean
+_eglPutSync(_EGLSync *sync)
+{
+ return (sync) ? _eglPutResource(&sync->Resource) : EGL_FALSE;
+}
/**
- * Link a sync to a display and return the handle of the link.
+ * Link a sync to its display and return the handle of the link.
* The handle can be passed to client directly.
*/
static INLINE EGLSyncKHR
-_eglLinkSync(_EGLSync *sync, _EGLDisplay *dpy)
+_eglLinkSync(_EGLSync *sync)
{
- _eglLinkResource(&sync->Resource, _EGL_RESOURCE_SYNC, dpy);
+ _eglLinkResource(&sync->Resource, _EGL_RESOURCE_SYNC);
return (EGLSyncKHR) sync;
}
@@ -100,20 +103,6 @@ _eglGetSyncHandle(_EGLSync *sync)
}
-/**
- * Return true if the sync is linked to a display.
- *
- * The link is considered a reference to the sync (the display is owning the
- * sync). Drivers should not destroy a sync when it is linked.
- */
-static INLINE EGLBoolean
-_eglIsSyncLinked(_EGLSync *sync)
-{
- _EGLResource *res = (_EGLResource *) sync;
- return (res && _eglIsResourceLinked(res));
-}
-
-
#endif /* EGL_KHR_reusable_sync */
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index b65f3b72ae5..20b67b28bc6 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -24,6 +24,8 @@ typedef struct _egl_extensions _EGLExtensions;
typedef struct _egl_image _EGLImage;
+typedef struct _egl_image_attribs _EGLImageAttribs;
+
typedef struct _egl_mode _EGLMode;
typedef struct _egl_resource _EGLResource;