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:

committed by
Jesse Barnes

parent
efc82e7c70
commit
7f170573ea
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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];
|
||||
|
@@ -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
|
||||
|
@@ -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 }
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
};
|
||||
|
Reference in New Issue
Block a user