summaryrefslogtreecommitdiffstats
path: root/src/glx
diff options
context:
space:
mode:
authorJesse Barnes <[email protected]>2009-11-12 16:48:07 +0000
committerJesse Barnes <[email protected]>2010-01-08 12:37:43 -0500
commit7f170573ea486f2f2dd474c2590346f1a0110773 (patch)
tree7fdda10cc6a9aef6bfa2d8d9e7ea5597d357e454 /src/glx
parentefc82e7c703f9160cfdbe6d97e166ca6f5e75d86 (diff)
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 <[email protected]>
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/x11/dri2.c70
-rw-r--r--src/glx/x11/dri_common.c3
-rw-r--r--src/glx/x11/glxext.c91
-rw-r--r--src/glx/x11/glxextensions.c1
-rw-r--r--src/glx/x11/glxextensions.h3
5 files changed, 163 insertions, 5 deletions
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
index 9ce633c40d4..2cb5d3463af 100644
--- a/src/glx/x11/dri2.c
+++ b/src/glx/x11/dri2.c
@@ -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)
{
diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c
index d1b77f308dd..e4034161bb3 100644
--- a/src/glx/x11/dri_common.c
+++ b/src/glx/x11/dri_common.c
@@ -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];
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 5633a3e4a29..fe65216c411 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -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
diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c
index 6852128e2ae..25a5c492930 100644
--- a/src/glx/x11/glxextensions.c
+++ b/src/glx/x11/glxextensions.c
@@ -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 }
};
diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h
index 652c5db1c81..f556b1239c9 100644
--- a/src/glx/x11/glxextensions.h
+++ b/src/glx/x11/glxextensions.h
@@ -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