From 454524f5e75fe0c3ce32463239d28d4249e59056 Mon Sep 17 00:00:00 2001 From: Shuang He Date: Mon, 1 Jun 2009 11:16:09 +0800 Subject: [PATCH] glXReleaseTexImageEXT should release reference to storage for the pixmap According to GLX_EXT_texture_from_pixmap spec, "The storage for the GLX pixmap will be freed when it is not current to any client and all color buffers that are bound to a texture object have been released." --- include/GL/internal/dri_interface.h | 8 +++++ src/glx/x11/glxcmds.c | 18 ++++++++++- src/mesa/drivers/dri/intel/intel_screen.c | 2 + src/mesa/drivers/dri/intel/intel_tex.h | 7 ++++ src/mesa/drivers/dri/intel/intel_tex_image.c | 42 ++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 1 deletions(-) diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 910c916..e4cb308 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -245,6 +245,10 @@ struct __DRItexBufferExtensionRec { void (*setTexBuffer)(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *pDraw); + void (*unsetTexBuffer)(__DRIcontext *pDRICtx, + GLint target, + __DRIdrawable *pDraw); + /** * Method to override base texture image with the contents of a @@ -256,6 +260,10 @@ struct __DRItexBufferExtensionRec { GLint target, GLint format, __DRIdrawable *pDraw); + void (*unsetTexBuffer2)(__DRIcontext *pDRICtx, + GLint target, + __DRIdrawable *pDraw); + }; /** diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index ec3e69e..ad54ca5 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -2698,8 +2698,24 @@ static void __glXReleaseTexImageEXT(Display *dpy, return; #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) + if (gc->driContext) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + + if (pdraw != NULL) { + if (pdraw->psc->texBuffer->base.version >= 2 && + pdraw->psc->texBuffer->unsetTexBuffer2 != NULL) { + (*pdraw->psc->texBuffer->unsetTexBuffer2)(gc->__driContext, + pdraw->textureTarget, + pdraw->driDrawable); + } else { + (*pdraw->psc->texBuffer->unsetTexBuffer)(gc->__driContext, + pdraw->textureTarget, + pdraw->driDrawable); + } + } return; + } + #endif opcode = __glXSetupForCommand(dpy); diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 9904e34..05492c6 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -211,7 +211,9 @@ static const __DRItexOffsetExtension intelTexOffsetExtension = { static const __DRItexBufferExtension intelTexBufferExtension = { { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, intelSetTexBuffer, + intelUnsetTexBuffer, intelSetTexBuffer2, + intelUnsetTexBuffer2, }; static const __DRIextension *intelScreenExtensions[] = { diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index f5372d8..f299b72 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -149,9 +149,16 @@ void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); void intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *pDraw); + +void intelUnsetTexBuffer(__DRIcontext *pDRICtx, + GLint target, __DRIdrawable *pDraw); + void intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint format, __DRIdrawable *pDraw); +void intelUnsetTexBuffer2(__DRIcontext *pDRICtx, + GLint target, __DRIdrawable *pDraw); + GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); void intel_tex_map_level_images(struct intel_context *intel, diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index ddbb13e..b17e5ff 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -795,6 +795,42 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, } void +intelUnsetTexBuffer2(__DRIcontext *pDRICtx, GLint target, + __DRIdrawable *dPriv) +{ + struct intel_context *intel = pDRICtx->driverPrivate; + struct intel_texture_object *intelObj; + struct intel_texture_image *intelImage; + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int level = 0; + + texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target); + intelObj = intel_texture_object(texObj); + + if (!intelObj) + return; + + _mesa_lock_texture(&intel->ctx, texObj); + + texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); + intelImage = intel_texture_image(texImage); + + if (intelImage->mt) { + intel_miptree_release(intel, &intelImage->mt); + intelImage->mt = NULL; + } + if (intelObj->mt) { + intel_miptree_release(intel, &intelObj->mt); + intelObj->mt = NULL; + } + + _mesa_unlock_texture(&intel->ctx, texObj); +} + +void intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) { /* The old interface didn't have the format argument, so copy our @@ -802,3 +838,9 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) */ intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); } + +void +intelUnsetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) +{ + intelUnsetTexBuffer2(pDRICtx, target, dPriv); +} -- 1.6.0.3