GLX/DRI2: handle swap event swap count wrapping
Create a new GLX drawable struct to track client related info, and add a wrap counter to it drawable and track it as we receive events. This allows us to support the full 64 bits of the event structure we pass to the client even though the server only gives us a 32 bit count. Reviewed-by: Michel Dänzer <michel@daenzer.net> Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
parent
1e39fc784b
commit
4df137691e
|
@ -88,6 +88,7 @@ static Bool
|
||||||
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
|
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
|
||||||
{
|
{
|
||||||
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
|
||||||
|
struct glx_drawable *glxDraw;
|
||||||
|
|
||||||
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
XextCheckExtension(dpy, info, dri2ExtensionName, False);
|
||||||
|
|
||||||
|
@ -98,6 +99,9 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
|
||||||
{
|
{
|
||||||
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
|
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
|
||||||
xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire;
|
xDRI2BufferSwapComplete2 *awire = (xDRI2BufferSwapComplete2 *)wire;
|
||||||
|
__GLXDRIdrawable *pdraw;
|
||||||
|
|
||||||
|
pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable);
|
||||||
|
|
||||||
/* Ignore swap events if we're not looking for them */
|
/* Ignore swap events if we're not looking for them */
|
||||||
aevent->type = dri2GetSwapEventType(dpy, awire->drawable);
|
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->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
|
||||||
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_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;
|
return True;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -396,6 +396,7 @@ CreateDrawable(Display *dpy, struct glx_config *config,
|
||||||
Drawable drawable, const int *attrib_list, CARD8 glxCode)
|
Drawable drawable, const int *attrib_list, CARD8 glxCode)
|
||||||
{
|
{
|
||||||
xGLXCreateWindowReq *req;
|
xGLXCreateWindowReq *req;
|
||||||
|
struct glx_drawable *glxDraw;
|
||||||
CARD32 *data;
|
CARD32 *data;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
CARD8 opcode;
|
CARD8 opcode;
|
||||||
|
@ -411,6 +412,10 @@ CreateDrawable(Display *dpy, struct glx_config *config,
|
||||||
if (!opcode)
|
if (!opcode)
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
|
glxDraw = Xmalloc(sizeof(*glxDraw));
|
||||||
|
if (!glxDraw)
|
||||||
|
return None;
|
||||||
|
|
||||||
LockDisplay(dpy);
|
LockDisplay(dpy);
|
||||||
GetReqExtra(GLXCreateWindow, 8 * i, req);
|
GetReqExtra(GLXCreateWindow, 8 * i, req);
|
||||||
data = (CARD32 *) (req + 1);
|
data = (CARD32 *) (req + 1);
|
||||||
|
@ -429,6 +434,11 @@ CreateDrawable(Display *dpy, struct glx_config *config,
|
||||||
UnlockDisplay(dpy);
|
UnlockDisplay(dpy);
|
||||||
SyncHandle();
|
SyncHandle();
|
||||||
|
|
||||||
|
if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) {
|
||||||
|
free(glxDraw);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
|
if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
|
||||||
if (glxCode == X_GLXCreatePixmap)
|
if (glxCode == X_GLXCreatePixmap)
|
||||||
glxCode = X_GLXDestroyPixmap;
|
glxCode = X_GLXDestroyPixmap;
|
||||||
|
@ -454,6 +464,7 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
|
||||||
|
|
||||||
protocolDestroyDrawable(dpy, drawable, glxCode);
|
protocolDestroyDrawable(dpy, drawable, glxCode);
|
||||||
|
|
||||||
|
DestroyGLXDrawable(dpy, drawable);
|
||||||
DestroyDRIDrawable(dpy, drawable, GL_FALSE);
|
DestroyDRIDrawable(dpy, drawable, GL_FALSE);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -567,6 +567,8 @@ struct glx_display
|
||||||
*/
|
*/
|
||||||
struct glx_screen **screens;
|
struct glx_screen **screens;
|
||||||
|
|
||||||
|
__glxHashTable *glXDrawHash;
|
||||||
|
|
||||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||||
__glxHashTable *drawHash;
|
__glxHashTable *drawHash;
|
||||||
|
|
||||||
|
@ -579,6 +581,14 @@ struct glx_display
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct glx_drawable {
|
||||||
|
XID xDrawable;
|
||||||
|
XID drawable;
|
||||||
|
|
||||||
|
uint32_t lastEventSbc;
|
||||||
|
int64_t eventSbcWrap;
|
||||||
|
};
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
glx_screen_init(struct glx_screen *psc,
|
glx_screen_init(struct glx_screen *psc,
|
||||||
int screen, struct glx_display * priv);
|
int screen, struct glx_display * priv);
|
||||||
|
@ -784,6 +794,12 @@ extern int
|
||||||
applegl_create_display(struct glx_display *display);
|
applegl_create_display(struct glx_display *display);
|
||||||
#endif
|
#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_context dummyContext;
|
||||||
|
|
||||||
extern struct glx_screen *
|
extern struct glx_screen *
|
||||||
|
|
|
@ -90,6 +90,51 @@ GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
|
||||||
|
|
||||||
#endif
|
#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.
|
* 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;
|
return pixmap;
|
||||||
#else
|
#else
|
||||||
xGLXCreateGLXPixmapReq *req;
|
xGLXCreateGLXPixmapReq *req;
|
||||||
|
struct glx_drawable *glxDraw;
|
||||||
GLXPixmap xid;
|
GLXPixmap xid;
|
||||||
CARD8 opcode;
|
CARD8 opcode;
|
||||||
|
|
||||||
|
@ -616,6 +662,10 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glxDraw = Xmalloc(sizeof(*glxDraw));
|
||||||
|
if (!glxDraw)
|
||||||
|
return None;
|
||||||
|
|
||||||
/* Send the glXCreateGLXPixmap request */
|
/* Send the glXCreateGLXPixmap request */
|
||||||
LockDisplay(dpy);
|
LockDisplay(dpy);
|
||||||
GetReq(GLXCreateGLXPixmap, req);
|
GetReq(GLXCreateGLXPixmap, req);
|
||||||
|
@ -628,6 +678,11 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
|
||||||
UnlockDisplay(dpy);
|
UnlockDisplay(dpy);
|
||||||
SyncHandle();
|
SyncHandle();
|
||||||
|
|
||||||
|
if (InitGLXDrawable(dpy, glxDraw, pixmap, req->glxpixmap)) {
|
||||||
|
free(glxDraw);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||||
do {
|
do {
|
||||||
/* FIXME: Maybe delay __DRIdrawable creation until the drawable
|
/* FIXME: Maybe delay __DRIdrawable creation until the drawable
|
||||||
|
@ -700,6 +755,8 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
|
||||||
UnlockDisplay(dpy);
|
UnlockDisplay(dpy);
|
||||||
SyncHandle();
|
SyncHandle();
|
||||||
|
|
||||||
|
DestroyGLXDrawable(dpy, glxpixmap);
|
||||||
|
|
||||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||||
{
|
{
|
||||||
struct glx_display *const priv = __glXInitialize(dpy);
|
struct glx_display *const priv = __glXInitialize(dpy);
|
||||||
|
|
|
@ -134,11 +134,19 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
|
||||||
{
|
{
|
||||||
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
|
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
|
||||||
xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
|
xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
|
||||||
|
struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
|
||||||
aevent->event_type = awire->event_type;
|
aevent->event_type = awire->event_type;
|
||||||
aevent->drawable = awire->drawable;
|
aevent->drawable = awire->drawable;
|
||||||
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
|
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
|
||||||
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_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;
|
return True;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -227,6 +235,8 @@ glx_display_free(struct glx_display *priv)
|
||||||
if (priv->serverGLXversion)
|
if (priv->serverGLXversion)
|
||||||
Xfree((char *) priv->serverGLXversion);
|
Xfree((char *) priv->serverGLXversion);
|
||||||
|
|
||||||
|
__glxHashDestroy(priv->glXDrawHash);
|
||||||
|
|
||||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||||
__glxHashDestroy(priv->drawHash);
|
__glxHashDestroy(priv->drawHash);
|
||||||
|
|
||||||
|
@ -847,6 +857,8 @@ __glXInitialize(Display * dpy)
|
||||||
XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
|
XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
|
||||||
XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
|
XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
|
||||||
|
|
||||||
|
dpyPriv->glXDrawHash = __glxHashCreate();
|
||||||
|
|
||||||
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
|
||||||
glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
|
glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
|
||||||
glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
|
glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
|
||||||
|
|
Loading…
Reference in New Issue