+static EGLBoolean
+xdri_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+ EGLint buffer)
+{
+ typedef int (*bind_teximage)(__DRInativeDisplay *dpy,
+ __DRIid surface, __DRIscreen *psc,
+ int buffer, int target, int format,
+ int level, int mipmap);
+
+ bind_teximage egl_dri_bind_teximage;
+
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+
+ struct xdri_egl_context *xdri_ctx = current_context();
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
+
+ __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0;
+
+ __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
+ __DRIscreen *psc = &scrnConf->driScreen;
+
+ /* this call just does error checking */
+ if (!_eglBindTexImage(drv, dpy, surface, buffer)) {
+ return EGL_FALSE;
+ }
+
+ egl_dri_bind_teximage =
+ (bind_teximage) dlsym(NULL, "egl_dri_bind_teximage");
+ if (egl_dri_bind_teximage) {
+ return egl_dri_bind_teximage(disp->Xdpy, dri_surf, psc,
+ buffer,
+ xdri_surf->Base.TextureTarget,
+ xdri_surf->Base.TextureFormat,
+ xdri_surf->Base.MipmapLevel,
+ xdri_surf->Base.MipmapTexture);
+ }
+ else {
+ /* fallback path based on glCopyTexImage() */
+ /* Get/save currently bound 2D texobj name */
+ glGetIntegerv_t glGetIntegerv_func =
+ (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv");
+ GLint curTexObj = 0;
+ if (glGetIntegerv_func) {
+ (*glGetIntegerv_func)(GL_TEXTURE_BINDING_2D, &curTexObj);
+ }
+ xdri_ctx->bound_tex_object = curTexObj;
+ }
+
+ return EGL_FALSE;
+}
+
+
+static EGLBoolean
+xdri_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+ EGLint buffer)
+{
+ typedef int (*release_teximage)(__DRInativeDisplay *dpy,
+ __DRIid surface, __DRIscreen *psc,
+ int buffer, int target, int format,
+ int level, int mipmap);
+ release_teximage egl_dri_release_teximage;
+
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+
+ struct xdri_egl_context *xdri_ctx = current_context();
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
+
+ __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0;
+
+ __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
+ __DRIscreen *psc = &scrnConf->driScreen;
+
+ /* this call just does error checking */
+ if (!_eglReleaseTexImage(drv, dpy, surface, buffer)) {
+ return EGL_FALSE;
+ }
+
+ egl_dri_release_teximage =
+ (release_teximage) dlsym(NULL, "egl_dri_release_teximage");
+ if (egl_dri_release_teximage) {
+ return egl_dri_release_teximage(disp->Xdpy, dri_surf, psc,
+ buffer,
+ xdri_surf->Base.TextureTarget,
+ xdri_surf->Base.TextureFormat,
+ xdri_surf->Base.MipmapLevel,
+ xdri_surf->Base.MipmapTexture);
+ }
+ else {
+ /* fallback path based on glCopyTexImage() */
+ glGetIntegerv_t glGetIntegerv_func =
+ (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv");
+ glBindTexture_t glBindTexture_func =
+ (glBindTexture_t) dlsym(NULL, "glBindTexture");
+ glCopyTexImage2D_t glCopyTexImage2D_func =
+ (glCopyTexImage2D_t) dlsym(NULL, "glCopyTexImage2D");
+ GLint curTexObj;
+ GLenum intFormat;
+ GLint level, width, height;
+
+ if (xdri_surf->Base.TextureFormat == EGL_TEXTURE_RGBA)
+ intFormat = GL_RGBA;
+ else
+ intFormat = GL_RGB;
+ level = xdri_surf->Base.MipmapLevel;
+ width = xdri_surf->Base.Width >> level;
+ height = xdri_surf->Base.Height >> level;
+
+ if (width > 0 && height > 0 &&
+ glGetIntegerv_func && glBindTexture_func && glCopyTexImage2D_func) {
+ glGetIntegerv_func(GL_TEXTURE_BINDING_2D, &curTexObj);
+ /* restore texobj from time of eglBindTexImage() call */
+ if (curTexObj != xdri_ctx->bound_tex_object)
+ glBindTexture_func(GL_TEXTURE_2D, xdri_ctx->bound_tex_object);
+ /* copy pbuffer image to texture */
+ glCopyTexImage2D_func(GL_TEXTURE_2D,
+ level,
+ intFormat,
+ 0, 0, width, height, 0);
+ /* restore current texture */
+ if (curTexObj != xdri_ctx->bound_tex_object)
+ glBindTexture_func(GL_TEXTURE_2D, curTexObj);
+ }
+ xdri_ctx->bound_tex_object = -1;
+ }
+
+ return EGL_FALSE;
+}
+
+