Commit 451428c4 authored by Gwenole Beauchesne's avatar Gwenole Beauchesne Committed by Jean-Paul Saman

x11: create alternate X connections (MT-safe).

Make sure VA/X11 and VA/GLX backends can be used independently from
the user-provided master X display. Create alternate thread-local X
connections for VA-specific purposes.

This allows for async VA initialization without the need for the
program to explicitly call XInitThreads() beforehand.
Signed-off-by: default avatarGwenole Beauchesne <gwenole.beauchesne@intel.com>
parent b1bc8cf8
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#include "va_glx_private.h" #include "va_glx_private.h"
#include "va_glx_impl.h" #include "va_glx_impl.h"
#include "va_backend_x11.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
...@@ -192,6 +193,7 @@ static int check_extension(const char *name, const char *ext) ...@@ -192,6 +193,7 @@ static int check_extension(const char *name, const char *ext)
static int check_tfp_extensions(VADriverContextP ctx) static int check_tfp_extensions(VADriverContextP ctx)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
const char *gl_extensions; const char *gl_extensions;
const char *glx_extensions; const char *glx_extensions;
...@@ -199,7 +201,7 @@ static int check_tfp_extensions(VADriverContextP ctx) ...@@ -199,7 +201,7 @@ static int check_tfp_extensions(VADriverContextP ctx)
if (!check_extension("GL_ARB_texture_non_power_of_two", gl_extensions)) if (!check_extension("GL_ARB_texture_non_power_of_two", gl_extensions))
return 0; return 0;
glx_extensions = glXQueryExtensionsString(ctx->native_dpy, ctx->x11_screen); glx_extensions = glXQueryExtensionsString(x11_dpy, ctx->x11_screen);
if (!check_extension("GLX_EXT_texture_from_pixmap", glx_extensions)) if (!check_extension("GLX_EXT_texture_from_pixmap", glx_extensions))
return 0; return 0;
return 1; return 1;
...@@ -321,6 +323,7 @@ gl_destroy_context(OpenGLContextStateP cs) ...@@ -321,6 +323,7 @@ gl_destroy_context(OpenGLContextStateP cs)
static OpenGLContextStateP static OpenGLContextStateP
gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent) gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
OpenGLContextStateP cs; OpenGLContextStateP cs;
GLXFBConfig *fbconfigs = NULL; GLXFBConfig *fbconfigs = NULL;
int fbconfig_id, val, n, n_fbconfigs; int fbconfig_id, val, n, n_fbconfigs;
...@@ -340,7 +343,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent) ...@@ -340,7 +343,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
if (!cs) if (!cs)
goto error; goto error;
cs->display = ctx->native_dpy; cs->display = x11_dpy;
cs->window = parent ? parent->window : None; cs->window = parent ? parent->window : None;
cs->context = NULL; cs->context = NULL;
...@@ -357,7 +360,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent) ...@@ -357,7 +360,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
goto choose_fbconfig; goto choose_fbconfig;
fbconfigs = glXGetFBConfigs( fbconfigs = glXGetFBConfigs(
ctx->native_dpy, x11_dpy,
ctx->x11_screen, ctx->x11_screen,
&n_fbconfigs &n_fbconfigs
); );
...@@ -367,7 +370,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent) ...@@ -367,7 +370,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
/* Find out a GLXFBConfig compatible with the parent context */ /* Find out a GLXFBConfig compatible with the parent context */
for (n = 0; n < n_fbconfigs; n++) { for (n = 0; n < n_fbconfigs; n++) {
status = glXGetFBConfigAttrib( status = glXGetFBConfigAttrib(
ctx->native_dpy, x11_dpy,
fbconfigs[n], fbconfigs[n],
GLX_FBCONFIG_ID, &val GLX_FBCONFIG_ID, &val
); );
...@@ -380,7 +383,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent) ...@@ -380,7 +383,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
else { else {
choose_fbconfig: choose_fbconfig:
fbconfigs = glXChooseFBConfig( fbconfigs = glXChooseFBConfig(
ctx->native_dpy, x11_dpy,
ctx->x11_screen, ctx->x11_screen,
fbconfig_attrs, &n_fbconfigs fbconfig_attrs, &n_fbconfigs
); );
...@@ -392,7 +395,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent) ...@@ -392,7 +395,7 @@ gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
} }
cs->context = glXCreateNewContext( cs->context = glXCreateNewContext(
ctx->native_dpy, x11_dpy,
fbconfigs[n], fbconfigs[n],
GLX_RGBA_TYPE, GLX_RGBA_TYPE,
parent ? parent->context : NULL, parent ? parent->context : NULL,
...@@ -459,6 +462,7 @@ struct VASurfaceGLX { ...@@ -459,6 +462,7 @@ struct VASurfaceGLX {
// Create Pixmaps for GLX texture-from-pixmap extension // Create Pixmaps for GLX texture-from-pixmap extension
static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx); VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx);
const unsigned int width = pSurfaceGLX->width; const unsigned int width = pSurfaceGLX->width;
const unsigned int height = pSurfaceGLX->height; const unsigned int height = pSurfaceGLX->height;
...@@ -470,12 +474,12 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -470,12 +474,12 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
int *attrib; int *attrib;
int n_fbconfig_attrs; int n_fbconfig_attrs;
root_window = RootWindow(ctx->native_dpy, ctx->x11_screen); root_window = RootWindow(x11_dpy, ctx->x11_screen);
XGetWindowAttributes(ctx->native_dpy, root_window, &wattr); XGetWindowAttributes(x11_dpy, root_window, &wattr);
if (wattr.depth != 24 && wattr.depth != 32) if (wattr.depth != 24 && wattr.depth != 32)
return 0; return 0;
pixmap = XCreatePixmap( pixmap = XCreatePixmap(
ctx->native_dpy, x11_dpy,
root_window, root_window,
width, width,
height, height,
...@@ -509,7 +513,7 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -509,7 +513,7 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
*attrib++ = GL_NONE; *attrib++ = GL_NONE;
fbconfig = glXChooseFBConfig( fbconfig = glXChooseFBConfig(
ctx->native_dpy, x11_dpy,
ctx->x11_screen, ctx->x11_screen,
fbconfig_attrs, fbconfig_attrs,
&n_fbconfig_attrs &n_fbconfig_attrs
...@@ -533,7 +537,7 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -533,7 +537,7 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
x11_trap_errors(); x11_trap_errors();
glx_pixmap = pOpenGLVTable->glx_create_pixmap( glx_pixmap = pOpenGLVTable->glx_create_pixmap(
ctx->native_dpy, x11_dpy,
fbconfig[0], fbconfig[0],
pixmap, pixmap,
pixmap_attrs pixmap_attrs
...@@ -553,6 +557,7 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -553,6 +557,7 @@ static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
// Destroy Pixmaps used for TFP // Destroy Pixmaps used for TFP
static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx); VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx);
if (pSurfaceGLX->pix_texture) { if (pSurfaceGLX->pix_texture) {
...@@ -561,12 +566,12 @@ static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -561,12 +566,12 @@ static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
} }
if (pSurfaceGLX->glx_pixmap) { if (pSurfaceGLX->glx_pixmap) {
pOpenGLVTable->glx_destroy_pixmap(ctx->native_dpy, pSurfaceGLX->glx_pixmap); pOpenGLVTable->glx_destroy_pixmap(x11_dpy, pSurfaceGLX->glx_pixmap);
pSurfaceGLX->glx_pixmap = None; pSurfaceGLX->glx_pixmap = None;
} }
if (pSurfaceGLX->pixmap) { if (pSurfaceGLX->pixmap) {
XFreePixmap(ctx->native_dpy, pSurfaceGLX->pixmap); XFreePixmap(x11_dpy, pSurfaceGLX->pixmap);
pSurfaceGLX->pixmap = None; pSurfaceGLX->pixmap = None;
} }
} }
...@@ -574,6 +579,7 @@ static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -574,6 +579,7 @@ static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
// Bind GLX Pixmap to texture // Bind GLX Pixmap to texture
static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
if (pSurfaceGLX->is_bound) if (pSurfaceGLX->is_bound)
...@@ -583,12 +589,12 @@ static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -583,12 +589,12 @@ static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
x11_trap_errors(); x11_trap_errors();
pOpenGLVTable->glx_bind_tex_image( pOpenGLVTable->glx_bind_tex_image(
ctx->native_dpy, x11_dpy,
pSurfaceGLX->glx_pixmap, pSurfaceGLX->glx_pixmap,
GLX_FRONT_LEFT_EXT, GLX_FRONT_LEFT_EXT,
NULL NULL
); );
XSync(ctx->native_dpy, False); XSync(x11_dpy, False);
if (x11_untrap_errors() != 0) { if (x11_untrap_errors() != 0) {
va_glx_error_message("failed to bind pixmap\n"); va_glx_error_message("failed to bind pixmap\n");
return 0; return 0;
...@@ -601,6 +607,7 @@ static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -601,6 +607,7 @@ static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
// Release GLX Pixmap from texture // Release GLX Pixmap from texture
static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx); VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
if (!pSurfaceGLX->is_bound) if (!pSurfaceGLX->is_bound)
...@@ -608,11 +615,11 @@ static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX) ...@@ -608,11 +615,11 @@ static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
x11_trap_errors(); x11_trap_errors();
pOpenGLVTable->glx_release_tex_image( pOpenGLVTable->glx_release_tex_image(
ctx->native_dpy, x11_dpy,
pSurfaceGLX->glx_pixmap, pSurfaceGLX->glx_pixmap,
GLX_FRONT_LEFT_EXT GLX_FRONT_LEFT_EXT
); );
XSync(ctx->native_dpy, False); XSync(x11_dpy, False);
if (x11_untrap_errors() != 0) { if (x11_untrap_errors() != 0) {
va_glx_error_message("failed to release pixmap\n"); va_glx_error_message("failed to release pixmap\n");
return 0; return 0;
...@@ -928,6 +935,7 @@ associate_surface( ...@@ -928,6 +935,7 @@ associate_surface(
unsigned int flags unsigned int flags
) )
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
VAStatus status; VAStatus status;
/* XXX: optimise case where we are associating the same VA surface /* XXX: optimise case where we are associating the same VA surface
...@@ -946,7 +954,7 @@ associate_surface( ...@@ -946,7 +954,7 @@ associate_surface(
NULL, 0, NULL, 0,
flags flags
); );
XSync(ctx->native_dpy, False); XSync(x11_dpy, False);
if (x11_untrap_errors() != 0) if (x11_untrap_errors() != 0)
return VA_STATUS_ERROR_OPERATION_FAILED; return VA_STATUS_ERROR_OPERATION_FAILED;
if (status != VA_STATUS_SUCCESS) if (status != VA_STATUS_SUCCESS)
...@@ -1051,6 +1059,7 @@ vaCopySurfaceGLX_impl_libva( ...@@ -1051,6 +1059,7 @@ vaCopySurfaceGLX_impl_libva(
// Initialize GLX driver context // Initialize GLX driver context
VAStatus va_glx_init_context(VADriverContextP ctx) VAStatus va_glx_init_context(VADriverContextP ctx)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
VADriverContextGLXP glx_ctx = VA_DRIVER_CONTEXT_GLX(ctx); VADriverContextGLXP glx_ctx = VA_DRIVER_CONTEXT_GLX(ctx);
VADriverVTableGLXP vtable = &glx_ctx->vtable; VADriverVTableGLXP vtable = &glx_ctx->vtable;
int glx_major, glx_minor; int glx_major, glx_minor;
...@@ -1068,7 +1077,7 @@ VAStatus va_glx_init_context(VADriverContextP ctx) ...@@ -1068,7 +1077,7 @@ VAStatus va_glx_init_context(VADriverContextP ctx)
vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_libva; vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_libva;
vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_libva; vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_libva;
if (!glXQueryVersion(ctx->native_dpy, &glx_major, &glx_minor)) if (!glXQueryVersion(x11_dpy, &glx_major, &glx_minor))
return VA_STATUS_ERROR_UNIMPLEMENTED; return VA_STATUS_ERROR_UNIMPLEMENTED;
if (!check_tfp_extensions(ctx) || !load_tfp_extensions(ctx)) if (!check_tfp_extensions(ctx) || !load_tfp_extensions(ctx))
......
...@@ -433,8 +433,9 @@ struct VADriverContext ...@@ -433,8 +433,9 @@ struct VADriverContext
void *dri_state; void *dri_state;
void *glx; /* opaque for GLX code */ void *glx; /* opaque for GLX code */
void *tls_state; /* opaque for thread-local data */
unsigned long reserved[45]; /* reserve for future add-ins, decrease the subscript accordingly */ unsigned long reserved[44]; /* reserve for future add-ins, decrease the subscript accordingly */
}; };
#define VA_DISPLAY_MAGIC 0x56414430 /* VAD0 */ #define VA_DISPLAY_MAGIC 0x56414430 /* VAD0 */
......
...@@ -34,6 +34,7 @@ source_c = \ ...@@ -34,6 +34,7 @@ source_c = \
$(NULL) $(NULL)
source_h = \ source_h = \
va_backend_x11.h \
va_dri.h \ va_dri.h \
va_dri2.h \ va_dri2.h \
va_dricommon.h \ va_dricommon.h \
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "X11/Xlib.h" #include "X11/Xlib.h"
#include "va.h" #include "va.h"
#include "va_backend.h" #include "va_backend.h"
#include "va_backend_x11.h"
#include "va_dri.h" #include "va_dri.h"
#include "va_dricommon.h" #include "va_dricommon.h"
...@@ -60,19 +61,21 @@ static void ...@@ -60,19 +61,21 @@ static void
dri1Close(VADriverContextP ctx) dri1Close(VADriverContextP ctx)
{ {
struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
Display * const x11_dpy = va_x11_get_display(ctx);
free_drawable_hashtable(ctx); free_drawable_hashtable(ctx);
VA_DRIDestroyContext(ctx->native_dpy, ctx->x11_screen, dri_state->hwContextID); VA_DRIDestroyContext(x11_dpy, ctx->x11_screen, dri_state->hwContextID);
assert(dri_state->pSAREA != MAP_FAILED); assert(dri_state->pSAREA != MAP_FAILED);
drmUnmap(dri_state->pSAREA, SAREA_MAX); drmUnmap(dri_state->pSAREA, SAREA_MAX);
assert(dri_state->fd >= 0); assert(dri_state->fd >= 0);
drmCloseOnce(dri_state->fd); drmCloseOnce(dri_state->fd);
VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen); VA_DRICloseConnection(x11_dpy, ctx->x11_screen);
} }
Bool Bool
isDRI1Connected(VADriverContextP ctx, char **driver_name) isDRI1Connected(VADriverContextP ctx, char **driver_name)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
int direct_capable; int direct_capable;
int driver_major; int driver_major;
...@@ -87,7 +90,7 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name) ...@@ -87,7 +90,7 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name)
dri_state->pSAREA = MAP_FAILED; dri_state->pSAREA = MAP_FAILED;
dri_state->driConnectedFlag = VA_NONE; dri_state->driConnectedFlag = VA_NONE;
if (!VA_DRIQueryDirectRenderingCapable(ctx->native_dpy, if (!VA_DRIQueryDirectRenderingCapable(x11_dpy,
ctx->x11_screen, ctx->x11_screen,
&direct_capable)) &direct_capable))
goto err_out0; goto err_out0;
...@@ -95,12 +98,12 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name) ...@@ -95,12 +98,12 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name)
if (!direct_capable) if (!direct_capable)
goto err_out0; goto err_out0;
if (!VA_DRIGetClientDriverName(ctx->native_dpy, ctx->x11_screen, if (!VA_DRIGetClientDriverName(x11_dpy, ctx->x11_screen,
&driver_major, &driver_minor, &driver_major, &driver_minor,
&driver_patch, driver_name)) &driver_patch, driver_name))
goto err_out0; goto err_out0;
if (!VA_DRIOpenConnection(ctx->native_dpy, ctx->x11_screen, if (!VA_DRIOpenConnection(x11_dpy, ctx->x11_screen,
&dri_state->hSAREA, &BusID)) &dri_state->hSAREA, &BusID))
goto err_out0; goto err_out0;
...@@ -115,14 +118,14 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name) ...@@ -115,14 +118,14 @@ isDRI1Connected(VADriverContextP ctx, char **driver_name)
if (drmGetMagic(dri_state->fd, &magic)) if (drmGetMagic(dri_state->fd, &magic))
goto err_out1; goto err_out1;
if (newlyopened && !VA_DRIAuthConnection(ctx->native_dpy, ctx->x11_screen, magic)) if (newlyopened && !VA_DRIAuthConnection(x11_dpy, ctx->x11_screen, magic))
goto err_out1; goto err_out1;
if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA)) if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
goto err_out1; goto err_out1;
if (!VA_DRICreateContext(ctx->native_dpy, ctx->x11_screen, if (!VA_DRICreateContext(x11_dpy, ctx->x11_screen,
DefaultVisual(ctx->native_dpy, ctx->x11_screen), DefaultVisual(x11_dpy, ctx->x11_screen),
&dri_state->hwContextID, &dri_state->hwContext)) &dri_state->hwContextID, &dri_state->hwContext))
goto err_out1; goto err_out1;
...@@ -142,7 +145,7 @@ err_out1: ...@@ -142,7 +145,7 @@ err_out1:
if (dri_state->fd >= 0) if (dri_state->fd >= 0)
drmCloseOnce(dri_state->fd); drmCloseOnce(dri_state->fd);
VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen); VA_DRICloseConnection(x11_dpy, ctx->x11_screen);
err_out0: err_out0:
if (*driver_name) if (*driver_name)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include "va.h" #include "va.h"
#include "va_backend.h" #include "va_backend.h"
#include "va_backend_x11.h"
#include "va_dri2.h" #include "va_dri2.h"
#include "va_dri2tokens.h" #include "va_dri2tokens.h"
...@@ -40,6 +41,7 @@ static int gsDRI2SwapAvailable; ...@@ -40,6 +41,7 @@ static int gsDRI2SwapAvailable;
static struct dri_drawable * static struct dri_drawable *
dri2CreateDrawable(VADriverContextP ctx, XID x_drawable) dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
struct dri2_drawable *dri2_drawable; struct dri2_drawable *dri2_drawable;
dri2_drawable = calloc(1, sizeof(*dri2_drawable)); dri2_drawable = calloc(1, sizeof(*dri2_drawable));
...@@ -50,7 +52,7 @@ dri2CreateDrawable(VADriverContextP ctx, XID x_drawable) ...@@ -50,7 +52,7 @@ dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
dri2_drawable->base.x_drawable = x_drawable; dri2_drawable->base.x_drawable = x_drawable;
dri2_drawable->base.x = 0; dri2_drawable->base.x = 0;
dri2_drawable->base.y = 0; dri2_drawable->base.y = 0;
VA_DRI2CreateDrawable(ctx->native_dpy, x_drawable); VA_DRI2CreateDrawable(x11_dpy, x_drawable);
return &dri2_drawable->base; return &dri2_drawable->base;
} }
...@@ -58,13 +60,16 @@ dri2CreateDrawable(VADriverContextP ctx, XID x_drawable) ...@@ -58,13 +60,16 @@ dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
static void static void
dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable) dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{ {
VA_DRI2DestroyDrawable(ctx->native_dpy, dri_drawable->x_drawable); Display * const x11_dpy = va_x11_get_display(ctx);
VA_DRI2DestroyDrawable(x11_dpy, dri_drawable->x_drawable);
free(dri_drawable); free(dri_drawable);
} }
static void static void
dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable; struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
XRectangle xrect; XRectangle xrect;
XserverRegion region; XserverRegion region;
...@@ -72,7 +77,7 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) ...@@ -72,7 +77,7 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
if (dri2_drawable->has_backbuffer) { if (dri2_drawable->has_backbuffer) {
if (gsDRI2SwapAvailable) { if (gsDRI2SwapAvailable) {
CARD64 ret; CARD64 ret;
VA_DRI2SwapBuffers(ctx->native_dpy, dri_drawable->x_drawable, 0, 0, VA_DRI2SwapBuffers(x11_dpy, dri_drawable->x_drawable, 0, 0,
0, &ret); 0, &ret);
} else { } else {
xrect.x = 0; xrect.x = 0;
...@@ -80,10 +85,10 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) ...@@ -80,10 +85,10 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
xrect.width = dri2_drawable->width; xrect.width = dri2_drawable->width;
xrect.height = dri2_drawable->height; xrect.height = dri2_drawable->height;
region = XFixesCreateRegion(ctx->native_dpy, &xrect, 1); region = XFixesCreateRegion(x11_dpy, &xrect, 1);
VA_DRI2CopyRegion(ctx->native_dpy, dri_drawable->x_drawable, region, VA_DRI2CopyRegion(x11_dpy, dri_drawable->x_drawable, region,
DRI2BufferFrontLeft, DRI2BufferBackLeft); DRI2BufferFrontLeft, DRI2BufferBackLeft);
XFixesDestroyRegion(ctx->native_dpy, region); XFixesDestroyRegion(x11_dpy, region);
} }
} }
} }
...@@ -91,6 +96,7 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) ...@@ -91,6 +96,7 @@ dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
static union dri_buffer * static union dri_buffer *
dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable; struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
int i; int i;
int count; int count;
...@@ -103,7 +109,7 @@ dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) ...@@ -103,7 +109,7 @@ dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
else else
attachments[i++] = __DRI_BUFFER_FRONT_LEFT; attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
buffers = VA_DRI2GetBuffers(ctx->native_dpy, dri_drawable->x_drawable, buffers = VA_DRI2GetBuffers(x11_dpy, dri_drawable->x_drawable,
&dri2_drawable->width, &dri2_drawable->height, &dri2_drawable->width, &dri2_drawable->height,
attachments, i, &count); attachments, i, &count);
assert(buffers); assert(buffers);
...@@ -152,6 +158,7 @@ dri2Close(VADriverContextP ctx) ...@@ -152,6 +158,7 @@ dri2Close(VADriverContextP ctx)
Bool Bool
isDRI2Connected(VADriverContextP ctx, char **driver_name) isDRI2Connected(VADriverContextP ctx, char **driver_name)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
int major, minor; int major, minor;
int error_base; int error_base;
...@@ -161,14 +168,14 @@ isDRI2Connected(VADriverContextP ctx, char **driver_name) ...@@ -161,14 +168,14 @@ isDRI2Connected(VADriverContextP ctx, char **driver_name)
*driver_name = NULL; *driver_name = NULL;
dri_state->fd = -1; dri_state->fd = -1;
dri_state->driConnectedFlag = VA_NONE; dri_state->driConnectedFlag = VA_NONE;
if (!VA_DRI2QueryExtension(ctx->native_dpy, &event_base, &error_base)) if (!VA_DRI2QueryExtension(x11_dpy, &event_base, &error_base))
goto err_out; goto err_out;
if (!VA_DRI2QueryVersion(ctx->native_dpy, &major, &minor)) if (!VA_DRI2QueryVersion(x11_dpy, &major, &minor))
goto err_out; goto err_out;
if (!VA_DRI2Connect(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen), if (!VA_DRI2Connect(x11_dpy, RootWindow(x11_dpy, ctx->x11_screen),
driver_name, &device_name)) driver_name, &device_name))
goto err_out; goto err_out;
...@@ -181,7 +188,7 @@ isDRI2Connected(VADriverContextP ctx, char **driver_name) ...@@ -181,7 +188,7 @@ isDRI2Connected(VADriverContextP ctx, char **driver_name)
if (drmGetMagic(dri_state->fd, &magic)) if (drmGetMagic(dri_state->fd, &magic))
goto err_out; goto err_out;
if (!VA_DRI2Authenticate(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen), if (!VA_DRI2Authenticate(x11_dpy, RootWindow(x11_dpy, ctx->x11_screen),
magic)) magic))
goto err_out; goto err_out;
......
/*
* Copyright (C) 2011 Intel Corporation. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef VA_BACKEND_X11_H
#define VA_BACKEND_X11_H
/**
* Return thread-local X11 display
*
* @param[in] ctx the VA driver context
* @return X11 Display if successful, or NULL if none was found
*/
Display *
va_x11_get_display(VADriverContextP ctx);
#endif /* VA_BACKEND_X11_H */
#include "va_dricommon.h" #include "va_dricommon.h"
#include "va_backend_x11.h"
// X error trap // X error trap
static int x11_error_code = 0; static int x11_error_code = 0;
...@@ -38,6 +39,7 @@ is_window(Display *dpy, Drawable drawable) ...@@ -38,6 +39,7 @@ is_window(Display *dpy, Drawable drawable)
static struct dri_drawable * static struct dri_drawable *
do_drawable_hash(VADriverContextP ctx, XID drawable) do_drawable_hash(VADriverContextP ctx, XID drawable)
{ {
Display * const x11_dpy = va_x11_get_display(ctx);
struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
int index = drawable % DRAWABLE_HASH_SZ; int index = drawable % DRAWABLE_HASH_SZ;
struct dri_drawable *dri_drawable = dri_state->drawable_hash[index]; struct dri_drawable *dri_drawable = dri_state->drawable_hash[index];
...@@ -50,7 +52,7 @@ do_drawable_hash(VADriverContextP ctx, XID drawable) ...@@ -50,7 +52,7 @@ do_drawable_hash(VADriverContextP ctx, XID drawable)
dri_drawable = dri_state->createDrawable(ctx, drawable); dri_drawable = dri_state->createDrawable(ctx, drawable);
dri_drawable->x_drawable = drawable; dri_drawable->x_drawable = drawable;
dri_drawable->is_window = is_window(ctx->native_dpy, drawable); dri_drawable->is_window = is_window(x11_dpy, drawable);
dri_drawable->next = dri_state->drawable_hash[index]; dri_drawable->next = dri_state->drawable_hash[index];
dri_state->drawable_hash[index] = dri_drawable; dri_state->drawable_hash[index] = dri_drawable;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "sysdeps.h" #include "sysdeps.h"
#include "va.h" #include "va.h"
#include "va_backend.h" #include "va_backend.h"
#include "va_backend_x11.h"
#include "va_trace.h" #include "va_trace.h"
#include "va_fool.h" #include "va_fool.h"
#include "va_x11.h" #include "va_x11.h"
...@@ -39,11 +40,124 @@ ...@@ -39,11 +40,124 @@
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
typedef struct {
pthread_key_t tls_key;
} ThreadLocalState;
typedef struct {
Display *dpy;
} ThreadLocalStateX11;
#define USE_TLS_DATA_AS_KEY \
(sizeof(pthread_key_t) <= sizeof(((VADriverContextP)0)->tls_state))
static void
destroy_tls_state_x11(void *arg)
{
ThreadLocalStateX11 * const state = arg;
if (!state)
return;
if (state->dpy) {
XCloseDisplay(state->dpy);
state->dpy = NULL;
}
free(state);
}
ThreadLocalStateX11 *
create_tls_state_x11(Display *dpy)
{
ThreadLocalStateX11 *tls_state;
tls_state = calloc(1, sizeof(*tls_state));
if (!tls_state)
return NULL;
tls_state->dpy = XOpenDisplay(DisplayString(dpy));
if (!tls_state->dpy)
goto error;
return tls_state;
error:
destroy_tls_state_x11(tls_state);
return NULL;
}
static void
destroy_tls_state(void **tls_state_ptr)
{
ThreadLocalState *tls_state = *tls_state_ptr;
ThreadLocalStateX11 *tls_state_x11;
pthread_key_t tls_key;
tls_key = USE_TLS_DATA_AS_KEY ? (uintptr_t)tls_state : tls_state->tls_key;
/* XXX: it seems the destructor is not implicitly called */
tls_state_x11 = pthread_getspecific(tls_key);
if (tls_state_x11) {
destroy_tls_state_x11(tls_state_x11);
pthread_setspecific(tls_key, NULL);
}
pthread_key_delete(tls_key);
if (!USE_TLS_DATA_AS_KEY)
free(tls_state);
*tls_state_ptr = NULL;
}
static Bool
create_tls_state(void **tls_state_ptr, Display *dpy)
{
ThreadLocalState *tls_state = NULL;
pthread_key_t tls_key;
if (pthread_key_create(&tls_key, destroy_tls_state_x11) != 0)
return False;
if (USE_TLS_DATA_AS_KEY)
tls_state = (void *)(uintptr_t)tls_key;
else {
tls_state = malloc(sizeof(*tls_state));
if (!tls_state)
goto error;
tls_state->tls_key = tls_key;
}
*tls_state_ptr = tls_state;
return True;
error:
destroy_tls_state((void **)&tls_state);
*tls_state_ptr = NULL;
return False;
}
Display *
va_x11_get_display(VADriverContextP ctx)
{
ThreadLocalState * const tls_state = ctx->tls_state;
ThreadLocalStateX11 *tls_state_x11;
pthread_key_t tls_key;
tls_key = USE_TLS_DATA_AS_KEY ? (uintptr_t)tls_state : tls_state->tls_key;
tls_state_x11 = pthread_getspecific(tls_key);
if (!tls_state_x11) {
tls_state_x11 = create_tls_state_x11(ctx->native_dpy);
if (!tls_state_x11)
return NULL;
pthread_setspecific(tls_key, tls_state_x11);
}
return tls_state_x11->dpy;
}
static int va_DisplayContextIsValid ( static int va_DisplayContextIsValid (
VADisplayContextP pDisplayContext VADisplayContextP pDisplayContext
) )
...@@ -68,6 +182,7 @@ static void va_DisplayContextDestroy ( ...@@ -68,6 +182,7 @@ static void va_DisplayContextDestroy (
if (dri_state && dri_state->close) if (dri_state && dri_state->close)
dri_state->close(ctx); dri_state->close(ctx);
destroy_tls_state(&pDisplayContext->pDriverContext->tls_state);
free(pDisplayContext->pDriverContext->dri_state); free(pDisplayContext->pDriverContext->dri_state);
free(pDisplayContext->pDriverContext); free(pDisplayContext->pDriverContext);
free(pDisplayContext); free(pDisplayContext);
...@@ -106,15 +221,16 @@ static VAStatus va_NVCTRL_GetDriverName ( ...@@ -106,15 +221,16 @@ static VAStatus va_NVCTRL_GetDriverName (
) )
{ {
VADriverContextP ctx = pDisplayContext->pDriverContext; VADriverContextP ctx = pDisplayContext->pDriverContext;
Display * const x11_dpy = va_x11_get_display(ctx);
int direct_capable, driver_major, driver_minor, driver_patch; int direct_capable, driver_major, driver_minor, driver_patch;
Bool result; Bool result;
result = VA_NVCTRLQueryDirectRenderingCapable(ctx->native_dpy, ctx->x11_screen, result = VA_NVCTRLQueryDirectRenderingCapable(x11_dpy, ctx->x11_screen,
&direct_capable); &direct_capable);
if (!result || !direct_capable) if (!result || !direct_capable)
return VA_STATUS_ERROR_UNKNOWN; return VA_STATUS_ERROR_UNKNOWN;
result = VA_NVCTRLGetClientDriverName(ctx->native_dpy, ctx->x11_screen, result = VA_NVCTRLGetClientDriverName(x11_dpy, ctx->x11_screen,
&driver_major, &driver_minor, &driver_major, &driver_minor,
&driver_patch, driver_name); &driver_patch, driver_name);
if (!result) if (!result)
...@@ -129,10 +245,11 @@ static VAStatus va_FGLRX_GetDriverName ( ...@@ -129,10 +245,11 @@ static VAStatus va_FGLRX_GetDriverName (
) )
{ {
VADriverContextP ctx = pDisplayContext->pDriverContext; VADriverContextP ctx = pDisplayContext->pDriverContext;
Display * const x11_dpy = va_x11_get_display(ctx);
int driver_major, driver_minor, driver_patch; int driver_major, driver_minor, driver_patch;
Bool result; Bool result;
result = VA_FGLRXGetClientDriverName(ctx->native_dpy, ctx->x11_screen, result = VA_FGLRXGetClientDriverName(x11_dpy, ctx->x11_screen,
&driver_major, &driver_minor, &driver_major, &driver_minor,
&driver_patch, driver_name); &driver_patch, driver_name);
if (!result) if (!result)
...@@ -177,20 +294,24 @@ VADisplay vaGetDisplay ( ...@@ -177,20 +294,24 @@ VADisplay vaGetDisplay (
/* create new entry */ /* create new entry */
VADriverContextP pDriverContext; VADriverContextP pDriverContext;
struct dri_state *dri_state; struct dri_state *dri_state;
void *tls_state;
Bool tls_state_ok;
pDisplayContext = calloc(1, sizeof(*pDisplayContext)); pDisplayContext = calloc(1, sizeof(*pDisplayContext));
pDriverContext = calloc(1, sizeof(*pDriverContext)); pDriverContext = calloc(1, sizeof(*pDriverContext));
dri_state = calloc(1, sizeof(*dri_state)); dri_state = calloc(1, sizeof(*dri_state));
if (pDisplayContext && pDriverContext && dri_state) tls_state_ok = create_tls_state(&tls_state, native_dpy);
if (pDisplayContext && pDriverContext && dri_state && tls_state_ok)
{ {
pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC; pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;
pDriverContext->native_dpy = (void *)native_dpy; pDriverContext->native_dpy = native_dpy;
pDisplayContext->pDriverContext = pDriverContext; pDisplayContext->pDriverContext = pDriverContext;
pDisplayContext->vaIsValid = va_DisplayContextIsValid; pDisplayContext->vaIsValid = va_DisplayContextIsValid;
pDisplayContext->vaDestroy = va_DisplayContextDestroy; pDisplayContext->vaDestroy = va_DisplayContextDestroy;
pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName; pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
pDisplayContext->opaque = NULL; pDisplayContext->opaque = NULL;
pDriverContext->dri_state = dri_state; pDriverContext->dri_state = dri_state;
pDriverContext->tls_state = tls_state;
dpy = (VADisplay)pDisplayContext; dpy = (VADisplay)pDisplayContext;
} }
else else
...@@ -201,6 +322,8 @@ VADisplay vaGetDisplay ( ...@@ -201,6 +322,8 @@ VADisplay vaGetDisplay (
free(pDriverContext); free(pDriverContext);
if (dri_state) if (dri_state)
free(dri_state); free(dri_state);
if (tls_state_ok)
destroy_tls_state(&tls_state);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment