DRI2/GLX: add INTEL_swap_event support

Add event support for the GLX swap buffers event, along with DRI2 protocol
support for generating GLX swap buffers events in the direct rendered case.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
Jesse Barnes
2009-11-12 16:48:07 +00:00
committed by Jesse Barnes
parent efc82e7c70
commit 7f170573ea
8 changed files with 193 additions and 5 deletions

View File

@@ -186,6 +186,16 @@ typedef XID GLXWindow;
typedef XID GLXPbuffer;
/*
** Events.
** __GLX_NUMBER_EVENTS is set to 17 to account for the BufferClobberSGIX
** event - this helps initialization if the server supports the pbuffer
** extension and the client doesn't.
*/
#define GLX_PbufferClobber 0
#define GLX_BufferSwapComplete 1
#define __GLX_NUMBER_EVENTS 17
extern XVisualInfo* glXChooseVisual( Display *dpy, int screen,
int *attribList );
@@ -507,8 +517,17 @@ typedef struct {
int count; /* if nonzero, at least this many more */
} GLXPbufferClobberEvent;
typedef struct {
int event_type;
GLXDrawable drawable;
int64_t ust;
int64_t msc;
int64_t sbc;
} GLXBufferSwapComplete;
typedef union __GLXEvent {
GLXPbufferClobberEvent glxpbufferclobber;
GLXBufferSwapComplete glxbufferswapcomplete;
long pad[24];
} GLXEvent;

View File

@@ -696,6 +696,14 @@ extern void glXJoinSwapGroupSGIX (Display *, GLXDrawable, GLXDrawable);
typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
#endif
#ifndef GLX_INTEL_swap_event
#define GLX_INTEL_swap_event
#define GLX_BUFFER_SWAP_COMPLETE_MASK 0x10000000
#define GLX_EXCHANGE_COMPLETE 0x8024
#define GLX_BLIT_COMPLETE 0x8025
#define GLX_FLIP_COMPLETE 0x8026
#endif
#ifndef GLX_SGIX_swap_barrier
#define GLX_SGIX_swap_barrier 1
#ifdef GLX_GLXEXT_PROTOTYPES

View File

@@ -41,6 +41,8 @@
#include <X11/extensions/dri2proto.h>
#include "xf86drm.h"
#include "dri2.h"
#include "glxclient.h"
#include "GL/glxext.h"
/* Allow the build to work with an older versions of dri2proto.h and
* dri2tokens.h.
@@ -56,6 +58,11 @@ static char dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo *dri2Info;
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
static Bool
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire);
static Status
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire);
static /* const */ XExtensionHooks dri2ExtensionHooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
@@ -64,8 +71,8 @@ static /* const */ XExtensionHooks dri2ExtensionHooks = {
NULL, /* create_font */
NULL, /* free_font */
DRI2CloseDisplay, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
DRI2WireToEvent, /* wire_to_event */
DRI2EventToWire, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
@@ -76,6 +83,65 @@ static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
&dri2ExtensionHooks,
0, NULL)
static Bool
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
XextCheckExtension(dpy, info, dri2ExtensionName, False);
switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
case DRI2_BufferSwapComplete:
{
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
switch (awire->type) {
case DRI2_EXCHANGE_COMPLETE:
aevent->event_type = GLX_EXCHANGE_COMPLETE;
break;
case DRI2_BLIT_COMPLETE:
aevent->event_type = GLX_BLIT_COMPLETE;
break;
case DRI2_FLIP_COMPLETE:
aevent->event_type = GLX_FLIP_COMPLETE;
break;
default:
/* unknown swap completion type */
return False;
}
aevent->drawable = awire->drawable;
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
return True;
}
default:
/* client doesn't support server event */
break;
}
return False;
}
/* We don't actually support this. It doesn't make sense for clients to
* send each other DRI2 events.
*/
static Status
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
XextCheckExtension(dpy, info, dri2ExtensionName, False);
switch (event->type) {
default:
/* client doesn't support server event */
break;
}
return Success;
}
Bool
DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
{

View File

@@ -394,6 +394,9 @@ dri2BindExtensions(__GLXscreenConfigs *psc)
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
/* FIXME: if DRI2 version supports it... */
__glXEnableDirectExtension(psc, "INTEL_swap_event");
#ifdef __DRI2_FLUSH
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
psc->f = (__DRI2flushExtension *) extensions[i];

View File

@@ -101,6 +101,10 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes)
static
XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
__GLX_NUMBER_ERRORS, error_list)
static Bool
__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
static Status
__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire);
static /* const */ XExtensionHooks __glXExtensionHooks = {
NULL, /* create_gc */
@@ -110,8 +114,8 @@ static /* const */ XExtensionHooks __glXExtensionHooks = {
NULL, /* create_font */
NULL, /* free_font */
__glXCloseDisplay, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
__glXWireToEvent, /* wire_to_event */
__glXEventToWire, /* event_to_wire */
NULL, /* error */
__glXErrorString, /* error_string */
};
@@ -121,6 +125,89 @@ XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
__glXExtensionName, &__glXExtensionHooks,
__GLX_NUMBER_EVENTS, NULL)
/*
* GLX events are a bit funky. We don't stuff the X event code into
* our user exposed (via XNextEvent) structure. Instead we use the GLX
* private event code namespace (and hope it doesn't conflict). Clients
* have to know that bit 15 in the event type field means they're getting
* a GLX event, and then handle the various sub-event types there, rather
* than simply checking the event code and handling it directly.
*/
static Bool
__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = __glXFindDisplay(dpy);
XextCheckExtension(dpy, info, __glXExtensionName, False);
switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
case GLX_PbufferClobber:
{
GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event;
xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire;
aevent->event_type = awire->type;
aevent->serial = awire->sequenceNumber;
aevent->event_type = awire->event_type;
aevent->draw_type = awire->draw_type;
aevent->drawable = awire->drawable;
aevent->buffer_mask = awire->buffer_mask;
aevent->aux_buffer = awire->aux_buffer;
aevent->x = awire->x;
aevent->y = awire->y;
aevent->width = awire->width;
aevent->height = awire->height;
aevent->count = awire->count;
return True;
}
case GLX_BufferSwapComplete:
{
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
xGLXBufferSwapComplete *awire = (xGLXBufferSwapComplete *)wire;
aevent->event_type = awire->event_type;
aevent->drawable = awire->drawable;
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
return True;
}
default:
/* client doesn't support server event */
break;
}
return False;
}
/* We don't actually support this. It doesn't make sense for clients to
* send each other GLX events.
*/
static Status
__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = __glXFindDisplay(dpy);
XextCheckExtension(dpy, info, __glXExtensionName, False);
switch (event->type) {
case GLX_DAMAGED:
break;
case GLX_SAVED:
break;
case GLX_EXCHANGE_COMPLETE:
break;
case GLX_BLIT_COMPLETE:
break;
case GLX_FLIP_COMPLETE:
break;
default:
/* client doesn't support server event */
break;
}
return Success;
}
/************************************************************************/
/*
** Free the per screen configs data as well as the array of

View File

@@ -104,6 +104,7 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(SGIX_swap_group), VER(0,0), N, N, N, N },
{ GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N },
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N },
{ GLX(INTEL_swap_event), VER(1,4), Y, Y, N, N },
{ NULL }
};

View File

@@ -65,7 +65,8 @@ enum
SGIX_swap_barrier_bit,
SGIX_swap_group_bit,
SGIX_visual_select_group_bit,
EXT_texture_from_pixmap_bit
EXT_texture_from_pixmap_bit,
INTEL_swap_event_bit,
};
enum

View File

@@ -1172,6 +1172,9 @@ _glxapi_get_extensions(void)
#endif
#ifdef GLX_EXT_texture_from_pixmap
"GLX_EXT_texture_from_pixmap",
#endif
#ifdef GLX_INTEL_swap_event
"GLX_INTEL_swap_event",
#endif
NULL
};