GLX/DRI2: add INTEL_swap_event support
This allows clients to easily check for swap completion status in their main loop. Reviewed-by: Kristian Høgsberg <krh@bitplanet.net> Reviewed-by: Adam Jackson <ajax@nwnk.net> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
This commit is contained in:
		
							parent
							
								
									04a54f69a8
								
							
						
					
					
						commit
						84956ca43b
					
				|  | @ -755,7 +755,7 @@ XINERAMAPROTO="xineramaproto" | ||||||
| BIGFONTPROTO="xf86bigfontproto >= 1.2.0" | BIGFONTPROTO="xf86bigfontproto >= 1.2.0" | ||||||
| XCALIBRATEPROTO="xcalibrateproto" | XCALIBRATEPROTO="xcalibrateproto" | ||||||
| DGAPROTO="xf86dgaproto >= 2.0.99.1" | DGAPROTO="xf86dgaproto >= 2.0.99.1" | ||||||
| GLPROTO="glproto >= 1.4.9" | GLPROTO="glproto >= 1.4.10" | ||||||
| DMXPROTO="dmxproto >= 2.2.99.1" | DMXPROTO="dmxproto >= 2.2.99.1" | ||||||
| VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1" | VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1" | ||||||
| WINDOWSWMPROTO="windowswmproto" | WINDOWSWMPROTO="windowswmproto" | ||||||
|  |  | ||||||
|  | @ -82,6 +82,7 @@ static const struct extension_info known_glx_extensions[] = { | ||||||
|    { GLX(SGIX_fbconfig),               VER(1,3), Y, }, |    { GLX(SGIX_fbconfig),               VER(1,3), Y, }, | ||||||
|    { GLX(SGIX_pbuffer),                VER(1,3), Y, }, |    { GLX(SGIX_pbuffer),                VER(1,3), Y, }, | ||||||
|    { GLX(SGIX_visual_select_group),    VER(0,0), Y, }, |    { GLX(SGIX_visual_select_group),    VER(0,0), Y, }, | ||||||
|  |    { GLX(INTEL_swap_event),            VER(1,4), N, }, | ||||||
|    { NULL } |    { NULL } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -50,6 +50,7 @@ enum { | ||||||
|    SGIX_fbconfig_bit, |    SGIX_fbconfig_bit, | ||||||
|    SGIX_pbuffer_bit, |    SGIX_pbuffer_bit, | ||||||
|    SGIX_visual_select_group_bit, |    SGIX_visual_select_group_bit, | ||||||
|  |    INTEL_swap_event_bit, | ||||||
|    __NUM_GLX_EXTS, |    __NUM_GLX_EXTS, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -167,6 +167,43 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable) | ||||||
| 		   DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); | 		   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. |  * Copy or flip back to front, honoring the swap interval if possible. | ||||||
|  * |  * | ||||||
|  | @ -184,7 +221,7 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable) | ||||||
| 	(*screen->flush->flushInvalidate)(priv->driDrawable); | 	(*screen->flush->flushInvalidate)(priv->driDrawable); | ||||||
| 
 | 
 | ||||||
|     if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused, |     if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused, | ||||||
| 			NULL, drawable->pDraw) != Success) | 			__glXdriSwapEvent, drawable->pDraw) != Success) | ||||||
| 	return FALSE; | 	return FALSE; | ||||||
| 
 | 
 | ||||||
|     return TRUE; |     return TRUE; | ||||||
|  | @ -581,6 +618,10 @@ initializeExtensions(__GLXDRIscreen *screen) | ||||||
| 			 "GLX_MESA_copy_sub_buffer"); | 			 "GLX_MESA_copy_sub_buffer"); | ||||||
|     LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); |     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++) { |     for (i = 0; extensions[i]; i++) { | ||||||
| #ifdef __DRI_READ_DRAWABLE | #ifdef __DRI_READ_DRAWABLE | ||||||
| 	if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { | 	if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { | ||||||
|  |  | ||||||
|  | @ -267,6 +267,7 @@ GLboolean __glXErrorOccured(void) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int __glXErrorBase; | static int __glXErrorBase; | ||||||
|  | int __glXEventBase; | ||||||
| 
 | 
 | ||||||
| int __glXError(int error) | int __glXError(int error) | ||||||
| { | { | ||||||
|  | @ -403,6 +404,7 @@ void GlxExtensionInit(void) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     __glXErrorBase = extEntry->errorBase; |     __glXErrorBase = extEntry->errorBase; | ||||||
|  |     __glXEventBase = extEntry->eventBase; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /************************************************************************/ | /************************************************************************/ | ||||||
|  |  | ||||||
|  | @ -181,6 +181,7 @@ static char GLXServerExtensions[] = | ||||||
| 			"GLX_SGIX_fbconfig " | 			"GLX_SGIX_fbconfig " | ||||||
| 			"GLX_SGIX_pbuffer " | 			"GLX_SGIX_pbuffer " | ||||||
| 			"GLX_MESA_copy_sub_buffer " | 			"GLX_MESA_copy_sub_buffer " | ||||||
|  |                         "GLX_INTEL_swap_event" | ||||||
| 			; | 			; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  |  | ||||||
|  | @ -249,4 +249,6 @@ extern int __glXImageSize(GLenum format, GLenum type, | ||||||
| extern unsigned glxMajorVersion; | extern unsigned glxMajorVersion; | ||||||
| extern unsigned glxMinorVersion; | extern unsigned glxMinorVersion; | ||||||
| 
 | 
 | ||||||
|  | extern int __glXEventBase; | ||||||
|  | 
 | ||||||
| #endif /* !__GLX_server_h__ */ | #endif /* !__GLX_server_h__ */ | ||||||
|  |  | ||||||
|  | @ -169,6 +169,8 @@ typedef struct { | ||||||
|     DRI2ScheduleWaitMSCProcPtr	ScheduleWaitMSC; |     DRI2ScheduleWaitMSCProcPtr	ScheduleWaitMSC; | ||||||
| }  DRI2InfoRec, *DRI2InfoPtr; | }  DRI2InfoRec, *DRI2InfoPtr; | ||||||
| 
 | 
 | ||||||
|  | extern _X_EXPORT int DRI2EventBase; | ||||||
|  | 
 | ||||||
| extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr	pScreen, | extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr	pScreen, | ||||||
| 		    DRI2InfoPtr info); | 		    DRI2InfoPtr info); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -348,6 +348,25 @@ vals_to_card64(CARD32 lo, CARD32 hi) | ||||||
|     return (CARD64)hi << 32 | lo; |     return (CARD64)hi << 32 | lo; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, | ||||||
|  | 	      CARD64 sbc) | ||||||
|  | { | ||||||
|  |     xDRI2BufferSwapComplete event; | ||||||
|  | 
 | ||||||
|  |     event.type = DRI2EventBase + DRI2_BufferSwapComplete; | ||||||
|  |     event.sequenceNumber = client->sequence; | ||||||
|  |     event.event_type = type; | ||||||
|  |     event.ust_hi = (CARD64)ust >> 32; | ||||||
|  |     event.ust_lo = ust & 0xffffffff; | ||||||
|  |     event.msc_hi = (CARD64)msc >> 32; | ||||||
|  |     event.msc_lo = msc & 0xffffffff; | ||||||
|  |     event.sbc_hi = (CARD64)sbc >> 32; | ||||||
|  |     event.sbc_lo = sbc & 0xffffffff; | ||||||
|  | 
 | ||||||
|  |     WriteEventsToClient(client, 1, (xEvent *)&event); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int | static int | ||||||
| ProcDRI2SwapBuffers(ClientPtr client) | ProcDRI2SwapBuffers(ClientPtr client) | ||||||
| { | { | ||||||
|  | @ -368,7 +387,7 @@ ProcDRI2SwapBuffers(ClientPtr client) | ||||||
|     remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); |     remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi); | ||||||
| 
 | 
 | ||||||
|     status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder, |     status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder, | ||||||
| 			     &swap_target, NULL, pDrawable); | 			     &swap_target, DRI2SwapEvent, pDrawable); | ||||||
|     if (status != Success) |     if (status != Success) | ||||||
| 	return BadDrawable; | 	return BadDrawable; | ||||||
| 
 | 
 | ||||||
|  | @ -608,6 +627,8 @@ static int DRI2DrawableGone(pointer p, XID id) | ||||||
|     return Success; |     return Success; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int DRI2EventBase; | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| DRI2ExtensionInit(void) | DRI2ExtensionInit(void) | ||||||
| { | { | ||||||
|  | @ -624,6 +645,7 @@ DRI2ExtensionInit(void) | ||||||
| 				 NULL, | 				 NULL, | ||||||
| 				 StandardMinorOpcode); | 				 StandardMinorOpcode); | ||||||
| 
 | 
 | ||||||
|  |     DRI2EventBase = dri2Extension->eventBase; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| extern Bool noDRI2Extension; | extern Bool noDRI2Extension; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue