summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-07-17 15:01:06 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-07-17 15:20:05 +0100
commit129656e4a82d4bf799e5c1d75d0dcb4480f6eb09 (patch)
tree2346c9594aed58b0186eec0d08951f2ea90d0f69
parenta45b2ea11c15f35c36330ff27cb45854a29c2e2c (diff)
sna/dri2: Disable SwapLimit buffers with buggy prime implementations
If there is a GPU screen, we have to assume that the DRI2 code may pass around the wrong pointers to ReuseBufferNotify until the fix is released: commit 4d92fab39c4225e89f2d157a1f559cb0618a6eaa Author: Chris Wilson <chris@chris-wilson.co.uk> Date: Wed Jun 18 11:14:43 2014 +0100 dri2: Use the PrimeScreen when creating/reusing buffers Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_dri2.c66
1 files changed, 39 insertions, 27 deletions
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index be5d8141..286be66b 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -239,10 +239,21 @@ inline static void *dri2_window_get_front(WindowPtr win) { return NULL; }
#endif
#if DRI2INFOREC_VERSION < 6
-#define XORG_CAN_TRIPLE_BUFFER 0
+
+#define xorg_can_triple_buffer(ptr) 0
#define swap_limit(d, l) false
+
+#else
+
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,904,0)
+#define xorg_can_triple_buffer(ptr) 1
#else
-#define XORG_CAN_TRIPLE_BUFFER 1
+inline static bool xorg_can_triple_buffer(struct sna *sna)
+{
+ return screenInfo.numGPUScreens == 0;
+}
+#endif
+
static Bool
sna_dri2_swap_limit_validate(DrawablePtr draw, int swap_limit)
{
@@ -2164,14 +2175,14 @@ void sna_dri2_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
__FUNCTION__, info->type,
event->sequence, event->tv_sec, event->tv_usec));
-#if XORG_CAN_TRIPLE_BUFFER
- if (!sna_dri2_blit_complete(sna, info))
- return;
+ if (xorg_can_triple_buffer(sna)) {
+ if (!sna_dri2_blit_complete(sna, info))
+ return;
- DBG(("%s: triple buffer swap complete, unblocking client (frame=%d, tv=%d.%06d)\n", __FUNCTION__,
- event->sequence, event->tv_sec, event->tv_usec));
- frame_swap_complete(sna, info, DRI2_BLIT_COMPLETE);
-#endif
+ DBG(("%s: triple buffer swap complete, unblocking client (frame=%d, tv=%d.%06d)\n", __FUNCTION__,
+ event->sequence, event->tv_sec, event->tv_usec));
+ frame_swap_complete(sna, info, DRI2_BLIT_COMPLETE);
+ }
break;
case WAITMSC:
@@ -2283,7 +2294,7 @@ sna_dri2_flip_continue(struct sna *sna, struct sna_dri2_event *info)
if (!sna_dri2_flip(sna, info))
return false;
- if (!XORG_CAN_TRIPLE_BUFFER) {
+ if (!xorg_can_triple_buffer(sna)) {
sna_dri2_get_back(sna, info->draw, info->back, info);
DBG(("%s: fake triple buffering, unblocking client\n", __FUNCTION__));
frame_swap_complete(sna, info, DRI2_FLIP_COMPLETE);
@@ -2321,7 +2332,7 @@ static void chain_flip(struct sna *sna)
chain->back, chain->front,
true);
- if (XORG_CAN_TRIPLE_BUFFER) {
+ if (xorg_can_triple_buffer(sna)) {
union drm_wait_vblank vbl;
VG_CLEAR(vbl);
@@ -2414,7 +2425,7 @@ get_current_msc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc)
return draw_current_msc(draw, crtc, ret);
}
-#if !XORG_CAN_TRIPLE_BUFFER && XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
static Bool find(pointer value, XID id, pointer cdata)
{
return TRUE;
@@ -2434,10 +2445,12 @@ static int use_triple_buffer(struct sna *sna, ClientPtr client, bool async)
return sna->flags & SNA_HAS_ASYNC_FLIP ? FLIP_ASYNC : FLIP_COMPLETE;
}
-#if XORG_CAN_TRIPLE_BUFFER
- DBG(("%s: triple buffer enabled, using FLIP_THROTTLE\n", __FUNCTION__));
- return FLIP_THROTTLE;
-#elif XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
+ if (xorg_can_triple_buffer(sna)) {
+ DBG(("%s: triple buffer enabled, using FLIP_THROTTLE\n", __FUNCTION__));
+ return FLIP_THROTTLE;
+ }
+
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
/* Hack: Disable triple buffering for compositors */
{
struct sna_client *priv = sna_client(client);
@@ -2522,11 +2535,10 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
} else {
DBG(("%s: chaining flip\n", __FUNCTION__));
type = FLIP_THROTTLE;
-#if XORG_CAN_TRIPLE_BUFFER
- info->mode = -type;
-#else
- info->mode = -FLIP_COMPLETE;
-#endif
+ if (xorg_can_triple_buffer(sna))
+ info->mode = -type;
+ else
+ info->mode = -FLIP_COMPLETE;
goto out;
}
}
@@ -2564,7 +2576,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
swap_limit(draw, 1 + (type == FLIP_THROTTLE));
if (type >= FLIP_COMPLETE) {
new_back:
- if (!XORG_CAN_TRIPLE_BUFFER)
+ if (!xorg_can_triple_buffer(sna))
sna_dri2_get_back(sna, draw, back, info);
DBG(("%s: fake triple buffering, unblocking client\n", __FUNCTION__));
frame_swap_complete(sna, info, DRI2_EXCHANGE_COMPLETE);
@@ -3244,11 +3256,11 @@ bool sna_dri2_open(struct sna *sna, ScreenPtr screen)
driverNames[1] = info.driverName;
#endif
-#if XORG_CAN_TRIPLE_BUFFER
- info.version = 6;
- info.SwapLimitValidate = sna_dri2_swap_limit_validate;
- info.ReuseBufferNotify = sna_dri2_reuse_buffer;
-#endif
+ if (xorg_can_triple_buffer(sna)) {
+ info.version = 6;
+ info.SwapLimitValidate = sna_dri2_swap_limit_validate;
+ info.ReuseBufferNotify = sna_dri2_reuse_buffer;
+ }
#if USE_ASYNC_SWAP
info.version = 10;