xf86-video-intel: src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Aug 1 07:33:01 PDT 2013


 src/sna/sna.h        |   11 +++++++++++
 src/sna/sna_dri.c    |   42 ++++++++++++++++++++++++++++++++----------
 src/sna/sna_driver.c |    8 ++++++++
 3 files changed, 51 insertions(+), 10 deletions(-)

New commits:
commit 3f04b6f33f05f8a24698f934a23462269b84917d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 1 14:49:36 2013 +0100

    sna/dri: Disable TripleBuffering by default for compositors
    
    Ideally, the method of swapping is something that the applications have
    control over, along with how to synchronise to the vertical refresh.
    Whilst triple buffering is good to reduce jitter for games (at the cost of
    an extra frame of latency, usually considered a good tradeoff), it
    prevents the applications from accurately controlling the presentation
    of animations. One vocal critique is Owen Taylor, who demands accurate
    swap control for smooth animations in gnome-shell. For example,
    
    http://blog.fishsoup.net/2012/11/28/avoiding-jitter-in-composited-frame-display/
    
    In lieu of application control, just apply a quirk for the compositor.
    Everyone else will just have to wait for DRI3.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index d0d2de4..abc8c5b 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -107,6 +107,17 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define SNA_CURSOR_X			64
 #define SNA_CURSOR_Y			SNA_CURSOR_X
 
+struct sna_client {
+	int is_compositor; /* only 4 bits used */
+};
+
+extern DevPrivateKeyRec sna_client_key;
+
+pure static inline struct sna_client *sna_client(ClientPtr client)
+{
+	return __get_private(client, sna_client_key);
+}
+
 struct sna_cow {
 	struct kgem_bo *bo;
 	struct list list;
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index a48c8d0..0083b52 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -48,6 +48,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <xf86drm.h>
 #include <i915_drm.h>
 #include <dri2.h>
+#include <compositeext.h>
 
 #if DRI2INFOREC_VERSION <= 2
 #error DRI2 version supported by the Xserver is too old
@@ -61,12 +62,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define COLOR_PREFER_TILING_Y 0
 
 enum frame_event_type {
+	DRI2_WAITMSC = 0,
 	DRI2_SWAP,
 	DRI2_SWAP_WAIT,
 	DRI2_SWAP_THROTTLE,
 	DRI2_FLIP,
 	DRI2_FLIP_THROTTLE,
-	DRI2_WAITMSC,
 };
 
 struct sna_dri_frame_event {
@@ -1118,11 +1119,6 @@ can_flip(struct sna * sna,
 		return false;
 	}
 
-	if (!get_private(front)->scanout) {
-		DBG(("%s: no, DRI2 drawable not attached at time of creation)\n",
-		     __FUNCTION__));
-		return false;
-	}
 	assert(get_private(front)->pixmap == sna->front);
 	assert(sna_pixmap(sna->front)->gpu_bo == get_private(front)->bo);
 
@@ -1685,6 +1681,34 @@ get_current_msc_for_target(struct sna *sna, CARD64 target_msc, int pipe)
 	return ret;
 }
 
+static Bool find(pointer value, XID id, pointer cdata)
+{
+	return TRUE;
+}
+
+static int use_triple_buffer(struct sna *sna, ClientPtr client)
+{
+	struct sna_client *priv;
+
+	if ((sna->flags & SNA_TRIPLE_BUFFER) == 0)
+		return DRI2_FLIP;
+
+	/* Hack: Disable triple buffering for compositors */
+
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
+	priv = sna_client(client);
+	if (priv->is_compositor == 0)
+		priv->is_compositor =
+			LookupClientResourceComplex(client,
+						    CompositeClientWindowType+1,
+						    find, NULL) ? DRI2_FLIP : DRI2_FLIP_THROTTLE;
+
+	return priv->is_compositor;
+#else
+	return DRI2_FLIP_THROTTLE;
+#endif
+}
+
 static bool
 sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw,
 		      DRI2BufferPtr front, DRI2BufferPtr back, int pipe,
@@ -1707,8 +1731,7 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw,
 		DBG(("%s: performing immediate swap on pipe %d, pending? %d, mode: %d\n",
 		     __FUNCTION__, pipe, info != NULL, info ? info->mode : 0));
 
-		if (info &&
-		    info->draw == draw) {
+		if (info && info->draw == draw) {
 			assert(info->type == DRI2_FLIP_THROTTLE);
 			assert(info->front == front);
 			if (info->back != back) {
@@ -1734,8 +1757,7 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw,
 		if (info == NULL)
 			return false;
 
-		info->type = sna->flags & SNA_TRIPLE_BUFFER ? DRI2_FLIP_THROTTLE: DRI2_FLIP;
-
+		info->type = use_triple_buffer(sna, client);
 		info->draw = draw;
 		info->client = client;
 		info->event_complete = func;
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 16dbc91..fc8773b 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -77,6 +77,7 @@ DevPrivateKeyRec sna_pixmap_key;
 DevPrivateKeyRec sna_gc_key;
 DevPrivateKeyRec sna_window_key;
 DevPrivateKeyRec sna_glyph_key;
+DevPrivateKeyRec sna_client_key;
 
 static void
 sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices,
@@ -788,6 +789,10 @@ sna_register_all_privates(void)
 	if (!dixRegisterPrivateKey(&sna_window_key, PRIVATE_WINDOW,
 				   3*sizeof(void *)))
 		return FALSE;
+
+	if (!dixRegisterPrivateKey(&sna_client_key, PRIVATE_CLIENT,
+				   sizeof(struct sna_client)))
+		return FALSE;
 #else
 	if (!dixRequestPrivate(&sna_pixmap_key, 3*sizeof(void *)))
 		return FALSE;
@@ -800,6 +805,9 @@ sna_register_all_privates(void)
 
 	if (!dixRequestPrivate(&sna_window_key, 3*sizeof(void *)))
 		return FALSE;
+
+	if (!dixRequestPrivate(&sna_client_key, sizeof(struct sna_client)))
+		return FALSE;
 #endif
 
 	return TRUE;


More information about the xorg-commit mailing list