diff -Naur Mesa-7.5.1-orig/include/GL/internal/dri_interface.h Mesa-7.5.1/include/GL/internal/dri_interface.h --- Mesa-7.5.1-orig/include/GL/internal/dri_interface.h 2009-08-06 17:44:37.000000000 +0200 +++ Mesa-7.5.1/include/GL/internal/dri_interface.h 2009-09-12 10:30:06.002557293 +0200 @@ -79,6 +79,7 @@ typedef struct __DRIdri2ExtensionRec __DRIdri2Extension; typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension; typedef struct __DRI2flushExtensionRec __DRI2flushExtension; +typedef struct __DRI2postswapbuffersExtensionRec __DRI2postswapbuffersExtension; /*@}*/ @@ -267,6 +268,17 @@ __DRIextension base; void (*flush)(__DRIdrawable *drawable); }; + +/** + * Used by drivers that implement DRI2, called after a SwapBuffers is done + * in case the driver wants to do some throttling. + */ +#define __DRI2_POST_SWAPBUFFERS "DRI2_PostSwapbuffers" +#define __DRI2_POST_SWAPBUFFERS_VERSION 1 +struct __DRI2postswapbuffersExtensionRec { + __DRIextension base; + void (*post_swapbuffers)(__DRIdrawable *drawable); +}; /** diff -Naur Mesa-7.5.1-orig/src/glx/x11/dri2_glx.c Mesa-7.5.1/src/glx/x11/dri2_glx.c --- Mesa-7.5.1-orig/src/glx/x11/dri2_glx.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/glx/x11/dri2_glx.c 2009-09-12 10:31:26.156414523 +0200 @@ -222,6 +222,11 @@ __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); + +#ifdef __DRI2_POSTSWAPBUFFERS + if (pdraw->psc->dri2_postswapbuffers) + (*pdraw->psc->dri2_postswapbuffers->postswapbuffers)(pdraw->driDrawable); +#endif } static void dri2WaitX(__GLXDRIdrawable *pdraw) diff -Naur Mesa-7.5.1-orig/src/glx/x11/dri_common.c Mesa-7.5.1/src/glx/x11/dri_common.c --- Mesa-7.5.1-orig/src/glx/x11/dri_common.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/glx/x11/dri_common.c 2009-09-12 10:32:14.517571624 +0200 @@ -400,6 +400,13 @@ /* internal driver extension, no GL extension exposed */ } #endif + +#ifdef __DRI2_POSTSWAPBUFFERS + if ((strcmp(extensions[i]->name, __DRI2_POSTSWAPBUFFERS) == 0) && dri2) { + psc->f = (__DRI2flushExtension *) extensions[i]; + /* internal driver extension, no GL extension exposed */ + } +#endif /* Ignore unknown extensions */ } diff -Naur Mesa-7.5.1-orig/src/glx/x11/glxclient.h Mesa-7.5.1/src/glx/x11/glxclient.h --- Mesa-7.5.1-orig/src/glx/x11/glxclient.h 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/glx/x11/glxclient.h 2009-09-12 10:33:31.544414481 +0200 @@ -530,6 +530,10 @@ #ifdef __DRI2_FLUSH const __DRI2flushExtension *f; #endif + +#ifdef __DRI2_FLUSH + const __DRI2postswapbuffersExtension *dri2_postswapbuffers; +#endif #endif diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/i915/intel_batchbuffer.c Mesa-7.5.1/src/mesa/drivers/dri/i915/intel_batchbuffer.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/i915/intel_batchbuffer.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/i915/intel_batchbuffer.c 2009-09-12 10:35:04.842378400 +0200 @@ -195,6 +195,14 @@ { struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; + + + if (intel->first_post_swapbuffers_batch == NULL) { + intel->first_post_swapbuffers_batch = intel->batch->buf; + drm_intel_bo_reference(intel->first_post_swapbuffers_batch); + } + + GLboolean was_locked = intel->locked; if (intel->first_post_swapbuffers_batch == NULL) { diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/i915/intel_screen.c Mesa-7.5.1/src/mesa/drivers/dri/i915/intel_screen.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/i915/intel_screen.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/i915/intel_screen.c 2009-09-12 10:37:15.303295289 +0200 @@ -213,6 +213,11 @@ intelSetTexBuffer, intelSetTexBuffer2, }; + +static const __DRI2postswapbuffersExtension intelPostSwapbuffersExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intel_dri2_post_swapbuffers, +}; static const __DRIextension *intelScreenExtensions[] = { &driReadDrawableExtension, @@ -222,6 +227,7 @@ &driMediaStreamCounterExtension.base, &intelTexOffsetExtension.base, &intelTexBufferExtension.base, + &intelPostSwapbuffersExtension.base, NULL }; diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/i915/intel_swapbuffers.c Mesa-7.5.1/src/mesa/drivers/dri/i915/intel_swapbuffers.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/i915/intel_swapbuffers.c 2009-08-06 17:44:38.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/i915/intel_swapbuffers.c 2009-09-12 10:38:17.446545794 +0200 @@ -246,3 +246,24 @@ if (ctx->Driver.DepthRange != NULL) ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); } + +void +intel_dri2_post_swapbuffers(__DRIdrawablePrivate *dPriv) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + + /* Wait for the swapbuffers before the one we just emitted, so we don't + * get too many swaps outstanding for apps that are GPU-heavy but not + * CPU-heavy. + * + * Unfortunately, we don't have a handle to the batch containing the swap, + * and getting our hands on that doesn't seem worth it, so we just us the + * first batch we emitted after the last swap. + */ + if (intel->first_post_swapbuffers_batch != NULL) { + drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch); + drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); + intel->first_post_swapbuffers_batch = NULL; + } +} diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/i965/intel_batchbuffer.c Mesa-7.5.1/src/mesa/drivers/dri/i965/intel_batchbuffer.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/i965/intel_batchbuffer.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/i965/intel_batchbuffer.c 2009-09-12 10:35:04.842378400 +0200 @@ -195,6 +195,14 @@ { struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; + + + if (intel->first_post_swapbuffers_batch == NULL) { + intel->first_post_swapbuffers_batch = intel->batch->buf; + drm_intel_bo_reference(intel->first_post_swapbuffers_batch); + } + + GLboolean was_locked = intel->locked; if (intel->first_post_swapbuffers_batch == NULL) { diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/i965/intel_screen.c Mesa-7.5.1/src/mesa/drivers/dri/i965/intel_screen.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/i965/intel_screen.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/i965/intel_screen.c 2009-09-12 10:37:15.303295289 +0200 @@ -213,6 +213,11 @@ intelSetTexBuffer, intelSetTexBuffer2, }; + +static const __DRI2postswapbuffersExtension intelPostSwapbuffersExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intel_dri2_post_swapbuffers, +}; static const __DRIextension *intelScreenExtensions[] = { &driReadDrawableExtension, @@ -222,6 +227,7 @@ &driMediaStreamCounterExtension.base, &intelTexOffsetExtension.base, &intelTexBufferExtension.base, + &intelPostSwapbuffersExtension.base, NULL }; diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/i965/intel_swapbuffers.c Mesa-7.5.1/src/mesa/drivers/dri/i965/intel_swapbuffers.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/i965/intel_swapbuffers.c 2009-08-06 17:44:38.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/i965/intel_swapbuffers.c 2009-09-12 10:38:17.446545794 +0200 @@ -246,3 +246,24 @@ if (ctx->Driver.DepthRange != NULL) ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); } + +void +intel_dri2_post_swapbuffers(__DRIdrawablePrivate *dPriv) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + + /* Wait for the swapbuffers before the one we just emitted, so we don't + * get too many swaps outstanding for apps that are GPU-heavy but not + * CPU-heavy. + * + * Unfortunately, we don't have a handle to the batch containing the swap, + * and getting our hands on that doesn't seem worth it, so we just us the + * first batch we emitted after the last swap. + */ + if (intel->first_post_swapbuffers_batch != NULL) { + drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch); + drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); + intel->first_post_swapbuffers_batch = NULL; + } +} diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_batchbuffer.c Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_batchbuffer.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_batchbuffer.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_batchbuffer.c 2009-09-12 10:35:04.842378400 +0200 @@ -195,6 +195,14 @@ { struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; + + + if (intel->first_post_swapbuffers_batch == NULL) { + intel->first_post_swapbuffers_batch = intel->batch->buf; + drm_intel_bo_reference(intel->first_post_swapbuffers_batch); + } + + GLboolean was_locked = intel->locked; if (intel->first_post_swapbuffers_batch == NULL) { diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_screen.c Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_screen.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_screen.c 2009-09-01 01:13:07.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_screen.c 2009-09-12 10:37:15.303295289 +0200 @@ -213,6 +213,11 @@ intelSetTexBuffer, intelSetTexBuffer2, }; + +static const __DRI2postswapbuffersExtension intelPostSwapbuffersExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intel_dri2_post_swapbuffers, +}; static const __DRIextension *intelScreenExtensions[] = { &driReadDrawableExtension, @@ -222,6 +227,7 @@ &driMediaStreamCounterExtension.base, &intelTexOffsetExtension.base, &intelTexBufferExtension.base, + &intelPostSwapbuffersExtension.base, NULL }; diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_swapbuffers.c Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_swapbuffers.c --- Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_swapbuffers.c 2009-08-06 17:44:38.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_swapbuffers.c 2009-09-12 10:38:17.446545794 +0200 @@ -246,3 +246,24 @@ if (ctx->Driver.DepthRange != NULL) ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); } + +void +intel_dri2_post_swapbuffers(__DRIdrawablePrivate *dPriv) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + + /* Wait for the swapbuffers before the one we just emitted, so we don't + * get too many swaps outstanding for apps that are GPU-heavy but not + * CPU-heavy. + * + * Unfortunately, we don't have a handle to the batch containing the swap, + * and getting our hands on that doesn't seem worth it, so we just us the + * first batch we emitted after the last swap. + */ + if (intel->first_post_swapbuffers_batch != NULL) { + drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch); + drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); + intel->first_post_swapbuffers_batch = NULL; + } +} diff -Naur Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_swapbuffers.h Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_swapbuffers.h --- Mesa-7.5.1-orig/src/mesa/drivers/dri/intel/intel_swapbuffers.h 2009-08-06 17:44:38.000000000 +0200 +++ Mesa-7.5.1/src/mesa/drivers/dri/intel/intel_swapbuffers.h 2009-09-12 10:38:57.454581970 +0200 @@ -47,6 +47,8 @@ extern void intelWindowMoved(struct intel_context *intel); - + +void +intel_dri2_post_swapbuffers(__DRIdrawablePrivate *dPriv); #endif /* INTEL_SWAPBUFFERS_H */