summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-01 14:49:36 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-01 15:21:04 +0100
commit3f04b6f33f05f8a24698f934a23462269b84917d (patch)
treee314cec9f5429b9a390e20460d9139ec6c454fb8
parent0ae07158c3550b418d3596cacda33a64ee653790 (diff)
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@chris-wilson.co.uk>
-rw-r--r--src/sna/sna.h11
-rw-r--r--src/sna/sna_dri.c42
-rw-r--r--src/sna/sna_driver.c8
3 files changed, 51 insertions, 10 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index d0d2de4f..abc8c5bf 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 a48c8d00..0083b524 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 16dbc91b..fc8773bc 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;