summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;