glx: keep native window glx drawable by driconf option
DRI3 window back buffer is a client resource, so it's destroyed when context switch drawable for native window. But some application like Abaqus may leave a dirty back buffer and reuse it when switch back. So add a driconf option for these kind of app to keep the entire GLX drawable for native window. Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Signed-off-by: Qiang Yu <yuq825@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14926>
This commit is contained in:
parent
4a420c50f2
commit
1dac5454ea
|
@ -49,6 +49,7 @@ DRI_CONF_SECTION_DEBUG
|
|||
DRI_CONF_IGNORE_MAP_UNSYNCHRONIZED(false)
|
||||
DRI_CONF_FORCE_DIRECT_GLX_CONTEXT(false)
|
||||
DRI_CONF_ALLOW_INVALID_GLX_DESTROY_WINDOW(false)
|
||||
DRI_CONF_KEEP_NATIVE_WINDOW_GLX_DRAWABLE(false)
|
||||
DRI_CONF_SECTION_END
|
||||
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
|
|
|
@ -1055,6 +1055,13 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
|||
&invalid_glx_destroy_window) == 0) {
|
||||
psc->base.allow_invalid_glx_destroy_window = invalid_glx_destroy_window;
|
||||
}
|
||||
|
||||
uint8_t keep_native_window_glx_drawable = false;
|
||||
if (psc->config->configQueryb(psc->driScreen,
|
||||
"keep_native_window_glx_drawable",
|
||||
&keep_native_window_glx_drawable) == 0) {
|
||||
psc->base.keep_native_window_glx_drawable = keep_native_window_glx_drawable;
|
||||
}
|
||||
}
|
||||
|
||||
free(driverName);
|
||||
|
|
|
@ -357,6 +357,9 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable)
|
|||
return NULL;
|
||||
|
||||
if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) {
|
||||
/* Resurrected, so remove from the alive-query-set if exist. */
|
||||
_mesa_set_remove_key(priv->zombieGLXDrawable, pdraw);
|
||||
|
||||
pdraw->refcount ++;
|
||||
return pdraw;
|
||||
}
|
||||
|
@ -419,6 +422,46 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable)
|
|||
return pdraw;
|
||||
}
|
||||
|
||||
static int
|
||||
discardGLXBadDrawableHandler(Display *display, xError *err, XExtCodes *codes,
|
||||
int *ret_code)
|
||||
{
|
||||
int code = codes->first_error + GLXBadDrawable;
|
||||
|
||||
/* Only discard error which is expected. */
|
||||
if (err->majorCode == codes->major_opcode &&
|
||||
err->minorCode == X_GLXGetDrawableAttributes &&
|
||||
/* newer xserver use GLXBadDrawable, old one use BadDrawable */
|
||||
(err->errorCode == code || err->errorCode == BadDrawable)) {
|
||||
*ret_code = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
checkServerGLXDrawableAlive(const struct glx_display *priv)
|
||||
{
|
||||
ErrorType old = XESetError(priv->dpy, priv->codes.extension,
|
||||
discardGLXBadDrawableHandler);
|
||||
|
||||
set_foreach(priv->zombieGLXDrawable, entry) {
|
||||
__GLXDRIdrawable *pdraw = (__GLXDRIdrawable *)entry->key;
|
||||
GLXDrawable drawable = pdraw->drawable;
|
||||
unsigned int dummy;
|
||||
|
||||
/* Fail to query, so the window has been closed. Release the GLXDrawable. */
|
||||
if (!__glXGetDrawableAttribute(priv->dpy, drawable, GLX_WIDTH, &dummy)) {
|
||||
pdraw->destroyDrawable(pdraw);
|
||||
__glxHashDelete(priv->drawHash, drawable);
|
||||
_mesa_set_remove(priv->zombieGLXDrawable, entry);
|
||||
}
|
||||
}
|
||||
|
||||
XESetError(priv->dpy, priv->codes.extension, old);
|
||||
}
|
||||
|
||||
static void
|
||||
releaseDrawable(const struct glx_display *priv, GLXDrawable drawable)
|
||||
{
|
||||
|
@ -433,8 +476,13 @@ releaseDrawable(const struct glx_display *priv, GLXDrawable drawable)
|
|||
* hold the last refcount until destroy the GLXPbuffer object.
|
||||
*/
|
||||
if (pdraw->refcount == 0) {
|
||||
pdraw->destroyDrawable(pdraw);
|
||||
__glxHashDelete(priv->drawHash, drawable);
|
||||
if (pdraw->psc->keep_native_window_glx_drawable) {
|
||||
checkServerGLXDrawableAlive(priv);
|
||||
_mesa_set_add(priv->zombieGLXDrawable, pdraw);
|
||||
} else {
|
||||
pdraw->destroyDrawable(pdraw);
|
||||
__glxHashDelete(priv->drawHash, drawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "glxhash.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/u_thread.h"
|
||||
#include "util/set.h"
|
||||
#include "loader.h"
|
||||
#include "glxextensions.h"
|
||||
|
||||
|
@ -524,6 +525,7 @@ struct glx_screen
|
|||
int scr;
|
||||
bool force_direct_context;
|
||||
bool allow_invalid_glx_destroy_window;
|
||||
bool keep_native_window_glx_drawable;
|
||||
|
||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||
/**
|
||||
|
@ -595,6 +597,11 @@ struct glx_display
|
|||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||
__glxHashTable *drawHash;
|
||||
|
||||
/**
|
||||
* GLXDrawable created from native window and about to be released.
|
||||
*/
|
||||
struct set *zombieGLXDrawable;
|
||||
|
||||
/**
|
||||
* Per display direct rendering interface functions and data.
|
||||
*/
|
||||
|
|
|
@ -268,6 +268,16 @@ FreeScreenConfigs(struct glx_display * priv)
|
|||
priv->screens = NULL;
|
||||
}
|
||||
|
||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||
static void
|
||||
free_zombie_glx_drawable(struct set_entry *entry)
|
||||
{
|
||||
__GLXDRIdrawable *pdraw = (__GLXDRIdrawable *)entry->key;
|
||||
|
||||
pdraw->destroyDrawable(pdraw);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
glx_display_free(struct glx_display *priv)
|
||||
{
|
||||
|
@ -279,6 +289,11 @@ glx_display_free(struct glx_display *priv)
|
|||
__glXSetCurrentContextNull();
|
||||
}
|
||||
|
||||
/* Needs to be done before free screen. */
|
||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||
_mesa_set_destroy(priv->zombieGLXDrawable, free_zombie_glx_drawable);
|
||||
#endif
|
||||
|
||||
FreeScreenConfigs(priv);
|
||||
|
||||
__glxHashDestroy(priv->glXDrawHash);
|
||||
|
@ -914,6 +929,8 @@ __glXInitialize(Display * dpy)
|
|||
|
||||
dpyPriv->drawHash = __glxHashCreate();
|
||||
|
||||
dpyPriv->zombieGLXDrawable = _mesa_pointer_set_create(NULL);
|
||||
|
||||
#ifndef GLX_USE_APPLEGL
|
||||
/* Set the logger before the *CreateDisplay functions. */
|
||||
loader_set_logger(glx_message);
|
||||
|
|
|
@ -250,6 +250,10 @@
|
|||
DRI_CONF_OPT_B(allow_invalid_glx_destroy_window, def, \
|
||||
"Allow passing an invalid window into glXDestroyWindow")
|
||||
|
||||
#define DRI_CONF_KEEP_NATIVE_WINDOW_GLX_DRAWABLE(def) \
|
||||
DRI_CONF_OPT_B(keep_native_window_glx_drawable, def, \
|
||||
"Keep GLX drawable created from native window when switch context")
|
||||
|
||||
#define DRI_CONF_OVERRIDE_VRAM_SIZE() \
|
||||
DRI_CONF_OPT_I(override_vram_size, -1, -1, 2147483647, \
|
||||
"Override the VRAM size advertised to the application in MiB (-1 = default)")
|
||||
|
|
Loading…
Reference in New Issue