diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-01 14:49:36 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-08-01 15:21:04 +0100 |
commit | 3f04b6f33f05f8a24698f934a23462269b84917d (patch) | |
tree | e314cec9f5429b9a390e20460d9139ec6c454fb8 | |
parent | 0ae07158c3550b418d3596cacda33a64ee653790 (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.h | 11 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 42 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 8 |
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; |