diff options
Diffstat (limited to 'xorg-server/glx')
-rw-r--r-- | xorg-server/glx/extension_string.c | 1 | ||||
-rw-r--r-- | xorg-server/glx/extension_string.h | 1 | ||||
-rw-r--r-- | xorg-server/glx/glxcmds.c | 2 | ||||
-rw-r--r-- | xorg-server/glx/glxcontext.h | 4 | ||||
-rw-r--r-- | xorg-server/glx/glxdrawable.h | 2 | ||||
-rw-r--r-- | xorg-server/glx/glxdri.c | 2 | ||||
-rw-r--r-- | xorg-server/glx/glxdri2.c | 102 | ||||
-rw-r--r-- | xorg-server/glx/glxdriswrast.c | 2 | ||||
-rw-r--r-- | xorg-server/glx/glxext.c | 5 | ||||
-rw-r--r-- | xorg-server/glx/glxscreens.c | 1 | ||||
-rw-r--r-- | xorg-server/glx/glxserver.h | 20 | ||||
-rw-r--r-- | xorg-server/glx/swap_interval.c | 7 |
12 files changed, 121 insertions, 28 deletions
diff --git a/xorg-server/glx/extension_string.c b/xorg-server/glx/extension_string.c index 9d110cf98..7721cb056 100644 --- a/xorg-server/glx/extension_string.c +++ b/xorg-server/glx/extension_string.c @@ -82,6 +82,7 @@ static const struct extension_info known_glx_extensions[] = { { GLX(SGIX_fbconfig), VER(1,3), Y, }, { GLX(SGIX_pbuffer), VER(1,3), Y, }, { GLX(SGIX_visual_select_group), VER(0,0), Y, }, + { GLX(INTEL_swap_event), VER(1,4), N, }, { NULL } }; diff --git a/xorg-server/glx/extension_string.h b/xorg-server/glx/extension_string.h index 98e91bc18..912534a04 100644 --- a/xorg-server/glx/extension_string.h +++ b/xorg-server/glx/extension_string.h @@ -50,6 +50,7 @@ enum { SGIX_fbconfig_bit, SGIX_pbuffer_bit, SGIX_visual_select_group_bit, + INTEL_swap_event_bit, __NUM_GLX_EXTS, }; diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index 72487a841..6c469b8f8 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/glx/glxcmds.c @@ -1485,7 +1485,7 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc) return error;
if (pGlxDraw->type == DRAWABLE_WINDOW &&
- (*pGlxDraw->swapBuffers)(pGlxDraw) == GL_FALSE)
+ (*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE)
return __glXError(GLXBadDrawable);
return Success;
diff --git a/xorg-server/glx/glxcontext.h b/xorg-server/glx/glxcontext.h index 70a14115d..79bc083a8 100644 --- a/xorg-server/glx/glxcontext.h +++ b/xorg-server/glx/glxcontext.h @@ -55,6 +55,10 @@ struct __GLXcontext { unsigned long mask); int (*forceCurrent) (__GLXcontext *context); + Bool (*wait) (__GLXcontext *context, + __GLXclientState *cl, + int *error); + __GLXtextureFromPixmap *textureFromPixmap; /* diff --git a/xorg-server/glx/glxdrawable.h b/xorg-server/glx/glxdrawable.h index 3f165ed4f..2a365c505 100644 --- a/xorg-server/glx/glxdrawable.h +++ b/xorg-server/glx/glxdrawable.h @@ -45,7 +45,7 @@ enum { struct __GLXdrawable { void (*destroy)(__GLXdrawable *private); - GLboolean (*swapBuffers)(__GLXdrawable *); + GLboolean (*swapBuffers)(ClientPtr client, __GLXdrawable *); void (*copySubBuffer)(__GLXdrawable *drawable, int x, int y, int w, int h); void (*waitX)(__GLXdrawable *); diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c index e4f061c54..910eb464e 100644 --- a/xorg-server/glx/glxdri.c +++ b/xorg-server/glx/glxdri.c @@ -248,7 +248,7 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable) }
static GLboolean
-__glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *basePrivate)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
__GLXDRIscreen *screen =
diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c index ed7dc80ba..69fd39b3b 100644 --- a/xorg-server/glx/glxdri2.c +++ b/xorg-server/glx/glxdri2.c @@ -70,6 +70,7 @@ struct __GLXDRIscreen { const __DRIcoreExtension *core; const __DRIdri2Extension *dri2; + const __DRI2flushExtension *flush; const __DRIcopySubBufferExtension *copySubBuffer; const __DRIswapControlExtension *swapControl; const __DRItexBufferExtension *texBuffer; @@ -132,17 +133,6 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable, DRI2BufferFrontLeft, DRI2BufferBackLeft); } -static GLboolean -__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) -{ - __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - - __glXDRIdrawableCopySubBuffer(drawable, 0, 0, - private->width, private->height); - - return TRUE; -} - static void __glXDRIdrawableWaitX(__GLXdrawable *drawable) { @@ -177,9 +167,74 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable) DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); } +static void +__glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust, + CARD64 msc, CARD64 sbc) +{ + __GLXdrawable *drawable = data; + xGLXBufferSwapComplete wire; + + if (!drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK) + return; + + wire.type = __glXEventBase + GLX_BufferSwapComplete; + switch (type) { + case DRI2_EXCHANGE_COMPLETE: + wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL; + break; + case DRI2_BLIT_COMPLETE: + wire.event_type = GLX_BLIT_COMPLETE_INTEL; + break; + case DRI2_FLIP_COMPLETE: + wire.event_type = GLX_FLIP_COMPLETE_INTEL; + break; + default: + /* unknown swap completion type */ + break; + } + wire.sequenceNumber = client->sequence; + wire.drawable = drawable->drawId; + wire.ust_hi = ust >> 32; + wire.ust_lo = ust & 0xffffffff; + wire.msc_hi = msc >> 32; + wire.msc_lo = msc & 0xffffffff; + wire.sbc_hi = sbc >> 32; + wire.sbc_lo = sbc & 0xffffffff; + + WriteEventsToClient(client, 1, (xEvent *) &wire); +} + +/* + * Copy or flip back to front, honoring the swap interval if possible. + * + * If the kernel supports it, we request an event for the frame when the + * swap should happen, then perform the copy when we receive it. + */ +static GLboolean +__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable) +{ + __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable; + __GLXDRIscreen *screen = priv->screen; + CARD64 unused; + + if (screen->flush) + (*screen->flush->flushInvalidate)(priv->driDrawable); + + if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused, + __glXdriSwapEvent, drawable->pDraw) != Success) + return FALSE; + + return TRUE; +} + static int __glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval) { + if (interval <= 0) /* || interval > BIGNUM? */ + return GLX_BAD_VALUE; + + DRI2SwapInterval(drawable->pDraw, interval); + return 0; } @@ -241,6 +296,18 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) read->driDrawable); } +static Bool +__glXDRIcontextWait(__GLXcontext *baseContext, + __GLXclientState *cl, int *error) +{ + if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) { + *error = cl->client->noClientException; + return TRUE; + } + + return FALSE; +} + #ifdef __DRI_TEX_BUFFER static int @@ -346,6 +413,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, context->base.copy = __glXDRIcontextCopy; context->base.forceCurrent = __glXDRIcontextForceCurrent; context->base.textureFromPixmap = &__glXDRItextureFromPixmap; + context->base.wait = __glXDRIcontextWait; context->driContext = (*screen->dri2->createNewContext)(screen->driScreen, @@ -550,6 +618,10 @@ initializeExtensions(__GLXDRIscreen *screen) "GLX_MESA_copy_sub_buffer"); LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); + /* FIXME: only if DDX supports it */ + __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event"); + LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n"); + for (i = 0; extensions[i]; i++) { #ifdef __DRI_READ_DRAWABLE if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { @@ -581,6 +653,14 @@ initializeExtensions(__GLXDRIscreen *screen) LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); } #endif + +#ifdef __DRI2_FLUSH + if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 && + extensions[i]->version >= __DRI2_FLUSH_VERSION) { + screen->flush = (__DRI2flushExtension *) extensions[i]; + } +#endif + /* Ignore unknown extensions */ } } diff --git a/xorg-server/glx/glxdriswrast.c b/xorg-server/glx/glxdriswrast.c index ece3426a3..cf6c5ada9 100644 --- a/xorg-server/glx/glxdriswrast.c +++ b/xorg-server/glx/glxdriswrast.c @@ -116,7 +116,7 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable) }
static GLboolean
-__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
const __DRIcoreExtension *core = private->screen->core;
diff --git a/xorg-server/glx/glxext.c b/xorg-server/glx/glxext.c index a3b5b62dd..c1fedf3b9 100644 --- a/xorg-server/glx/glxext.c +++ b/xorg-server/glx/glxext.c @@ -273,6 +273,7 @@ GLboolean __glXErrorOccured(void) } static int __glXErrorBase; +int __glXEventBase; int __glXError(int error) { @@ -409,6 +410,7 @@ void GlxExtensionInit(void) } __glXErrorBase = extEntry->errorBase; + __glXEventBase = extEntry->eventBase; } /************************************************************************/ @@ -452,6 +454,9 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag, } } + if (cx->wait && (*cx->wait)(cx, cl, error)) + return NULL; + if (cx == __glXLastContext) { /* No need to re-bind */ return cx; diff --git a/xorg-server/glx/glxscreens.c b/xorg-server/glx/glxscreens.c index 2f6d39efa..b2d1f8741 100644 --- a/xorg-server/glx/glxscreens.c +++ b/xorg-server/glx/glxscreens.c @@ -185,6 +185,7 @@ static char GLXServerExtensions[] = "GLX_SGIX_fbconfig "
"GLX_SGIX_pbuffer "
"GLX_MESA_copy_sub_buffer "
+ "GLX_INTEL_swap_event"
;
/*
diff --git a/xorg-server/glx/glxserver.h b/xorg-server/glx/glxserver.h index 7f2f2dd76..296d453eb 100644 --- a/xorg-server/glx/glxserver.h +++ b/xorg-server/glx/glxserver.h @@ -57,7 +57,14 @@ #include <GL/glext.h>
#include <GL/glxproto.h>
-/* For glxscreens.h */
+/*
+** GLX resources.
+*/
+typedef XID GLXContextID;
+typedef XID GLXPixmap;
+typedef XID GLXDrawable;
+
+typedef struct __GLXclientStateRec __GLXclientState;
typedef struct __GLXdrawable __GLXdrawable;
typedef struct __GLXcontext __GLXcontext;
@@ -72,15 +79,6 @@ typedef struct __GLXcontext __GLXcontext; #define False 0
#endif
-/*
-** GLX resources.
-*/
-typedef XID GLXContextID;
-typedef XID GLXPixmap;
-typedef XID GLXDrawable;
-
-typedef struct __GLXclientStateRec __GLXclientState;
-
extern __GLXscreen *glxGetScreen(ScreenPtr pScreen);
extern __GLXclientState *glxGetClient(ClientPtr pClient);
@@ -252,4 +250,6 @@ extern int __glXImageSize(GLenum format, GLenum type, extern unsigned glxMajorVersion;
extern unsigned glxMinorVersion;
+extern int __glXEventBase;
+
#endif /* !__GLX_server_h__ */
diff --git a/xorg-server/glx/swap_interval.c b/xorg-server/glx/swap_interval.c index 03f83cb89..d8b4ab2b6 100644 --- a/xorg-server/glx/swap_interval.c +++ b/xorg-server/glx/swap_interval.c @@ -57,8 +57,6 @@ int DoSwapInterval(__GLXclientState *cl, GLbyte *pc, int do_swap) cx = __glXLookupContextByTag(cl, tag); - LogMessage(X_ERROR, "%s: cx = %p, GLX screen = %p\n", __FUNCTION__ , - cx, (cx == NULL) ? NULL : cx->pGlxScreen); if ((cx == NULL) || (cx->pGlxScreen == NULL)) { client->errorValue = tag; return __glXError(GLXBadContext); @@ -72,7 +70,7 @@ int DoSwapInterval(__GLXclientState *cl, GLbyte *pc, int do_swap) if (cx->drawPriv == NULL) { client->errorValue = tag; - return __glXError(GLXBadDrawable); + return BadValue; } pc += __GLX_VENDPRIV_HDR_SIZE; @@ -80,6 +78,9 @@ int DoSwapInterval(__GLXclientState *cl, GLbyte *pc, int do_swap) ? bswap_32(*(int *)(pc + 0)) : *(int *)(pc + 0); + if (interval <= 0) + return BadValue; + (void) (*cx->pGlxScreen->swapInterval)(cx->drawPriv, interval); return Success; } |