diff options
Diffstat (limited to 'src/egl')
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; |