summaryrefslogtreecommitdiffstats
path: root/src/glx
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/dri2.c12
-rw-r--r--src/glx/glx_pbuffer.c11
-rw-r--r--src/glx/glxclient.h16
-rw-r--r--src/glx/glxcmds.c57
-rw-r--r--src/glx/glxext.c14
5 files changed, 108 insertions, 2 deletions
diff --git a/src/glx/dri2.c b/src/glx/dri2.c
index 8654a37688f..229840d6919 100644
--- a/src/glx/dri2.c
+++ b/src/glx/dri2.c
@@ -88,6 +88,7 @@ static Bool
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ struct glx_drawable *glxDraw;
XextCheckExtension(dpy, info, dri2ExtensionName, False);
@@ -98,6 +99,9 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire;
+ __GLXDRIdrawable *pdraw;
+
+ pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable);
/* Ignore swap events if we're not looking for them */
aevent->type = dri2GetSwapEventType(dpy, awire->drawable);
@@ -124,7 +128,13 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
}
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
- aevent->sbc = awire->sbc;
+
+ glxDraw = GetGLXDrawable(dpy, pdraw->drawable);
+ if (awire->sbc < glxDraw->lastEventSbc)
+ glxDraw->eventSbcWrap += 0x100000000;
+ glxDraw->lastEventSbc = awire->sbc;
+ aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
+
return True;
}
#endif
diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index 0e74e7ccd0e..6738252a31d 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -396,6 +396,7 @@ CreateDrawable(Display *dpy, struct glx_config *config,
Drawable drawable, const int *attrib_list, CARD8 glxCode)
{
xGLXCreateWindowReq *req;
+ struct glx_drawable *glxDraw;
CARD32 *data;
unsigned int i;
CARD8 opcode;
@@ -411,6 +412,10 @@ CreateDrawable(Display *dpy, struct glx_config *config,
if (!opcode)
return None;
+ glxDraw = Xmalloc(sizeof(*glxDraw));
+ if (!glxDraw)
+ return None;
+
LockDisplay(dpy);
GetReqExtra(GLXCreateWindow, 8 * i, req);
data = (CARD32 *) (req + 1);
@@ -429,6 +434,11 @@ CreateDrawable(Display *dpy, struct glx_config *config,
UnlockDisplay(dpy);
SyncHandle();
+ if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) {
+ free(glxDraw);
+ return None;
+ }
+
if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
if (glxCode == X_GLXCreatePixmap)
glxCode = X_GLXDestroyPixmap;
@@ -454,6 +464,7 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
protocolDestroyDrawable(dpy, drawable, glxCode);
+ DestroyGLXDrawable(dpy, drawable);
DestroyDRIDrawable(dpy, drawable, GL_FALSE);
return;
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 06415288165..f9154266101 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -567,6 +567,8 @@ struct glx_display
*/
struct glx_screen **screens;
+ __glxHashTable *glXDrawHash;
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
__glxHashTable *drawHash;
@@ -579,6 +581,14 @@ struct glx_display
#endif
};
+struct glx_drawable {
+ XID xDrawable;
+ XID drawable;
+
+ uint32_t lastEventSbc;
+ int64_t eventSbcWrap;
+};
+
extern int
glx_screen_init(struct glx_screen *psc,
int screen, struct glx_display * priv);
@@ -784,6 +794,12 @@ extern int
applegl_create_display(struct glx_display *display);
#endif
+
+extern struct glx_drawable *GetGLXDrawable(Display *dpy, GLXDrawable drawable);
+extern int InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw,
+ XID xDrawable, GLXDrawable drawable);
+extern void DestroyGLXDrawable(Display *dpy, GLXDrawable drawable);
+
extern struct glx_context dummyContext;
extern struct glx_screen *
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 191b321ce32..fc0a07901a7 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -90,6 +90,51 @@ GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
#endif
+_X_HIDDEN struct glx_drawable *
+GetGLXDrawable(Display *dpy, GLXDrawable drawable)
+{
+ struct glx_display *priv = __glXInitialize(dpy);
+ struct glx_drawable *glxDraw;
+
+ if (priv == NULL)
+ return NULL;
+
+ if (__glxHashLookup(priv->glXDrawHash, drawable, (void *) &glxDraw) == 0)
+ return glxDraw;
+
+ return NULL;
+}
+
+_X_HIDDEN int
+InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
+ GLXDrawable drawable)
+{
+ struct glx_display *priv = __glXInitialize(dpy);
+
+ if (!priv)
+ return -1;
+
+ glxDraw->xDrawable = xDrawable;
+ glxDraw->drawable = drawable;
+ glxDraw->lastEventSbc = 0;
+ glxDraw->eventSbcWrap = 0;
+
+ return __glxHashInsert(priv->glXDrawHash, drawable, glxDraw);
+}
+
+_X_HIDDEN void
+DestroyGLXDrawable(Display *dpy, GLXDrawable drawable)
+{
+ struct glx_display *priv = __glXInitialize(dpy);
+ struct glx_drawable *glxDraw;
+
+ if (!priv)
+ return;
+
+ glxDraw = GetGLXDrawable(dpy, drawable);
+ __glxHashDelete(priv->glXDrawHash, drawable);
+ free(glxDraw);
+}
/**
* Get the GLX per-screen data structure associated with a GLX context.
@@ -608,6 +653,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
return pixmap;
#else
xGLXCreateGLXPixmapReq *req;
+ struct glx_drawable *glxDraw;
GLXPixmap xid;
CARD8 opcode;
@@ -616,6 +662,10 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
return None;
}
+ glxDraw = Xmalloc(sizeof(*glxDraw));
+ if (!glxDraw)
+ return None;
+
/* Send the glXCreateGLXPixmap request */
LockDisplay(dpy);
GetReq(GLXCreateGLXPixmap, req);
@@ -628,6 +678,11 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
UnlockDisplay(dpy);
SyncHandle();
+ if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
+ free(glxDraw);
+ return None;
+ }
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
do {
/* FIXME: Maybe delay __DRIdrawable creation until the drawable
@@ -700,6 +755,8 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
UnlockDisplay(dpy);
SyncHandle();
+ DestroyGLXDrawable(dpy, glxpixmap);
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
{
struct glx_display *const priv = __glXInitialize(dpy);
diff --git a/src/glx/glxext.c b/src/glx/glxext.c
index 40a06a8612b..8704c484f96 100644
--- a/src/glx/glxext.c
+++ b/src/glx/glxext.c
@@ -134,11 +134,19 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
+ struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
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 = awire->sbc;
+
+ if (!glxDraw)
+ return False;
+
+ if (awire->sbc < glxDraw->lastEventSbc)
+ glxDraw->eventSbcWrap += 0x100000000;
+ glxDraw->lastEventSbc = awire->sbc;
+ aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
return True;
}
default:
@@ -227,6 +235,8 @@ glx_display_free(struct glx_display *priv)
if (priv->serverGLXversion)
Xfree((char *) priv->serverGLXversion);
+ __glxHashDestroy(priv->glXDrawHash);
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
__glxHashDestroy(priv->drawHash);
@@ -847,6 +857,8 @@ __glXInitialize(Display * dpy)
XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
+ dpyPriv->glXDrawHash = __glxHashCreate();
+
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);