dri3: Fix dri3_open API change by adding new dri3_open_client

Xwayland will eventually need the current client in dri3_open. Simply
changing that API is not an option though as other drivers that
implement DRI3 will not have a matching function signature and will
crash when called.

Add a new dri3_open_client function pointer and bump
DRI3_SCREEN_INFO_VERSION so that drivers can be aware of the new
function which will be used in preference to the old function when
available.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Eric Anhole <eric@anholt.net>
This commit is contained in:
Keith Packard 2014-04-04 16:28:43 -07:00
parent 901fbfbbbd
commit 6ec04a75de
3 changed files with 31 additions and 11 deletions

View File

@ -30,13 +30,17 @@
#include <X11/extensions/dri3proto.h> #include <X11/extensions/dri3proto.h>
#include <randrstr.h> #include <randrstr.h>
#define DRI3_SCREEN_INFO_VERSION 0 #define DRI3_SCREEN_INFO_VERSION 1
typedef int (*dri3_open_proc)(ClientPtr client, typedef int (*dri3_open_proc)(ScreenPtr screen,
ScreenPtr screen,
RRProviderPtr provider, RRProviderPtr provider,
int *fd); int *fd);
typedef int (*dri3_open_client_proc)(ClientPtr client,
ScreenPtr screen,
RRProviderPtr provider,
int *fd);
typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen, typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen,
int fd, int fd,
CARD16 width, CARD16 width,
@ -56,6 +60,10 @@ typedef struct dri3_screen_info {
dri3_open_proc open; dri3_open_proc open;
dri3_pixmap_from_fd_proc pixmap_from_fd; dri3_pixmap_from_fd_proc pixmap_from_fd;
dri3_fd_from_pixmap_proc fd_from_pixmap; dri3_fd_from_pixmap_proc fd_from_pixmap;
/* Version 1 */
dri3_open_client_proc open_client;
} dri3_screen_info_rec, *dri3_screen_info_ptr; } dri3_screen_info_rec, *dri3_screen_info_ptr;
extern _X_EXPORT Bool extern _X_EXPORT Bool

View File

@ -30,6 +30,14 @@
#include <misyncshm.h> #include <misyncshm.h>
#include <randrstr.h> #include <randrstr.h>
static inline Bool has_open(dri3_screen_info_ptr info) {
if (info == NULL)
return FALSE;
return info->open != NULL ||
(info->version >= 1 && info->open_client != NULL);
}
int int
dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd) dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd)
{ {
@ -37,10 +45,14 @@ dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd)
dri3_screen_info_ptr info = ds->info; dri3_screen_info_ptr info = ds->info;
int rc; int rc;
if (!info || !info->open) if (!has_open(info))
return BadMatch; return BadMatch;
rc = (*info->open) (client, screen, provider, fd); if (info->version >= 1 && info->open_client != NULL)
rc = (*info->open_client) (client, screen, provider, fd);
else
rc = (*info->open) (screen, provider, fd);
if (rc != Success) if (rc != Success)
return rc; return rc;

View File

@ -608,10 +608,10 @@ glamor_egl_close_screen(ScreenPtr screen)
} }
static int static int
glamor_dri3_open(ClientPtr client, glamor_dri3_open_client(ClientPtr client,
ScreenPtr screen, ScreenPtr screen,
RRProviderPtr provider, RRProviderPtr provider,
int *fdp) int *fdp)
{ {
ScrnInfoPtr scrn = xf86ScreenToScrn(screen); ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_egl_screen_private *glamor_egl = struct glamor_egl_screen_private *glamor_egl =
@ -658,8 +658,8 @@ glamor_dri3_open(ClientPtr client,
} }
static dri3_screen_info_rec glamor_dri3_info = { static dri3_screen_info_rec glamor_dri3_info = {
.version = 0, .version = 1,
.open = glamor_dri3_open, .open_client = glamor_dri3_open_client,
.pixmap_from_fd = glamor_pixmap_from_fd, .pixmap_from_fd = glamor_pixmap_from_fd,
.fd_from_pixmap = glamor_fd_from_pixmap, .fd_from_pixmap = glamor_fd_from_pixmap,
}; };