xf86-video-intel: 6 commits - src/intel_options.c src/intel_options.h src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_threads.c
Chris Wilson
ickle at kemper.freedesktop.org
Thu May 8 06:23:02 PDT 2014
src/intel_options.c | 1
src/intel_options.h | 1
src/sna/sna.h | 1
src/sna/sna_display.c | 41 +++++++--
src/sna/sna_dri.c | 221 ++++++++++++++++++++++++++++++++++++--------------
src/sna/sna_driver.c | 3
src/sna/sna_threads.c | 13 ++
7 files changed, 212 insertions(+), 69 deletions(-)
New commits:
commit ad01e1c8700caeaf0288b72450646d7ebe7cce93
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu May 8 13:02:15 2014 +0100
sna: Fix another assignment inside an assert
Another recent introduction, spotted by Rinat Ibragimov.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 51b4db6..eda6c5b 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3014,7 +3014,7 @@ static void sort_randr_outputs(struct sna *sna, ScreenPtr screen)
rrScrPriv(screen);
int i;
- assert(pScrPriv->numOutputs = config->num_output);
+ assert(pScrPriv->numOutputs == config->num_output);
for (i = 0; i < config->num_output; i++) {
assert(config->output[i]->randr_output);
pScrPriv->outputs[i] = config->output[i]->randr_output;
commit e78a00c5da922024ac64270fae0797d98d1d6e57
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu May 8 06:45:43 2014 +0100
sna: Add an xorg.conf option for removing unused outputs
Clients are not yet ready for outputs that disappear at runtime, often
unexpectedly dieing with asynchronous BadOutput errors. A simple
workaround is to not remove any output just yet - but allow users to opt
in via xorg.conf, i.e.
Section "Device"
Option "DeleteUnusedDP12Displays" "true"
EndSection
The name chosen is to be consistent with the nvidia driver, which did
MST first and encountered all of these issues first, and has also been
adopted for -modesetting. If this is combined with persistent output
naming (i.e. based on DisplayPort branch topology), the number of
outputs presented to the user should be static.
Instead of removing the outputs, we have to mark them detached instead
to avoid throwing errors from the kernel.
Based on the patch for -modesetting by Dave Airlie.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/intel_options.c b/src/intel_options.c
index 02a4ae1..51d5462 100644
--- a/src/intel_options.c
+++ b/src/intel_options.c
@@ -20,6 +20,7 @@ const OptionInfoRec intel_options[] = {
{OPTION_PREFER_OVERLAY, "XvPreferOverlay", OPTV_BOOLEAN, {0}, 0},
{OPTION_HOTPLUG, "HotPlug", OPTV_BOOLEAN, {0}, 1},
{OPTION_REPROBE, "ReprobeOutputs", OPTV_BOOLEAN, {0}, 0},
+ {OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, 0},
#ifdef INTEL_XVMC
{OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, 1},
#endif
diff --git a/src/intel_options.h b/src/intel_options.h
index 77f0c45..6873a6d 100644
--- a/src/intel_options.h
+++ b/src/intel_options.h
@@ -27,6 +27,7 @@ enum intel_options {
OPTION_PREFER_OVERLAY,
OPTION_HOTPLUG,
OPTION_REPROBE,
+ OPTION_DELETE_DP12,
#if defined(XvMCExtension) && defined(ENABLE_XVMC)
OPTION_XVMC,
#define INTEL_XVMC 1
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 75a0e36..3a45924 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -244,6 +244,7 @@ struct sna {
#define SNA_IS_HOSTED 0x80
#define SNA_PERFORMANCE 0x100
#define SNA_POWERSAVE 0x200
+#define SNA_REMOVE_OUTPUTS 0x400
#define SNA_REDISCOVER 0x40000000
#define SNA_REPROBE 0x80000000
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index af71f11..51b4db6 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -172,6 +172,8 @@ static inline struct sna_output *to_sna_output(xf86OutputPtr output)
static inline int to_connector_id(xf86OutputPtr output)
{
+ assert(to_sna_output(output));
+ assert(to_sna_output(output)->id);
return to_sna_output(output)->id;
}
@@ -1904,7 +1906,10 @@ sna_output_detect(xf86OutputPtr output)
struct sna_output *sna_output = output->driver_private;
union compat_mode_get_connector compat_conn;
- DBG(("%s(%s)\n", __FUNCTION__, output->name));
+ DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
+
+ if (!sna_output->id)
+ return XF86OutputStatusDisconnected;
VG_CLEAR(compat_conn);
compat_conn.conn.connector_id = sna_output->id;
@@ -2134,7 +2139,8 @@ sna_output_get_modes(xf86OutputPtr output)
DisplayModePtr Modes = NULL, Mode, current = NULL;
int i;
- DBG(("%s(%s)\n", __FUNCTION__, output->name));
+ DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
+ assert(sna_output->id);
sna_output_attach_edid(output);
@@ -2245,7 +2251,7 @@ sna_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode)
if (!sna_output->backlight.iface)
return;
- DBG(("%s(%s) -- %d -> %d\n", __FUNCTION__, output->name, oldmode, mode));
+ DBG(("%s(%s:%d) -- %d -> %d\n", __FUNCTION__, output->name, sna_output->id, oldmode, mode));
if (mode == DPMSModeOn) {
/* If we're going from off->on we may need to turn on the backlight. */
@@ -2266,11 +2272,14 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
struct sna *sna = to_sna(output->scrn);
struct sna_output *sna_output = output->driver_private;
- DBG(("%s(%s): dpms=%d (current: %d), active? %d\n",
- __FUNCTION__, output->name,
+ DBG(("%s(%s:%d): dpms=%d (current: %d), active? %d\n",
+ __FUNCTION__, output->name, sna_output->id,
dpms, sna_output->dpms_mode,
output->crtc != NULL));
+ if (!sna_output->id)
+ return;
+
if (sna_output->dpms_mode == dpms)
return;
@@ -2465,6 +2474,9 @@ sna_output_set_property(xf86OutputPtr output, Atom property,
return TRUE;
}
+ if (!sna_output->id)
+ return TRUE;
+
for (i = 0; i < sna_output->num_props; i++) {
struct sna_property *p = &sna_output->props[i];
@@ -2725,8 +2737,13 @@ sna_mode_compute_possible_outputs(struct sna *sna)
assert(sna_output);
- output->possible_clones = sna_output->possible_encoders;
- encoder_mask[i] = sna_output->attached_encoders;
+ if (sna_output->id) {
+ output->possible_clones = sna_output->possible_encoders;
+ encoder_mask[i] = sna_output->attached_encoders;
+ } else {
+ output->possible_clones = 0;
+ encoder_mask[i] = 0;
+ }
}
/* Convert from encoder numbering to output numbering */
@@ -3045,7 +3062,12 @@ void sna_mode_discover(struct sna *sna)
for (i = 0; i < sna->mode.num_real_output; i++) {
xf86OutputPtr output = config->output[i];
if (to_sna_output(output)->serial != serial) {
- sna_output_del(output); i--;
+ if (sna->flags & SNA_REMOVE_OUTPUTS) {
+ sna_output_del(output); i--;
+ } else {
+ to_sna_output(output)->id = 0;
+ output->crtc = NULL;
+ }
changed = true;
}
}
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index f1a30dc..58e5cbc 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -564,6 +564,9 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE))
sna->tiling &= ~SNA_TILING_FB;
+ if (xf86ReturnOptValBool(sna->Options, OPTION_DELETE_DP12, FALSE))
+ sna->flags |= SNA_REMOVE_OUTPUTS;
+
if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE))
sna->flags |= SNA_NO_WAIT;
DBG(("%s: swapbuffer wait? %s\n", __FUNCTION__, sna->flags & SNA_NO_WAIT ? "disabled" : "enabled"));
commit a93157587a82c699e7df76fb482c49569f0686b9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed May 7 21:20:56 2014 +0100
sna: Tidy thread handling under valgrind
If valgrind is running, keep it simple and avoid using unknown
instructions (causing valgrind to die with SIGILL).
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_threads.c b/src/sna/sna_threads.c
index 1310972..f263d24 100644
--- a/src/sna/sna_threads.c
+++ b/src/sna/sna_threads.c
@@ -35,6 +35,13 @@
#include <pthread.h>
#include <signal.h>
+#ifdef HAVE_VALGRIND
+#include <valgrind.h>
+static inline bool valgrind_active(void) { return RUNNING_ON_VALGRIND; }
+#else
+static inline bool valgrind_active(void) { return false; }
+#endif
+
static int max_threads = -1;
static struct thread {
@@ -131,6 +138,9 @@ void sna_threads_init(void)
if (max_threads != -1)
return;
+ if (valgrind_active())
+ goto bail;
+
max_threads = num_cores();
if (max_threads == 0)
max_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2;
@@ -182,6 +192,9 @@ void sna_threads_trap(int sig)
pthread_t t = pthread_self();
int n;
+ if (max_threads == 0)
+ return;
+
if (t == threads[0].thread)
return;
commit efd9e9c3eeb83b9e5725fa642066925d608c059d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed May 7 21:19:57 2014 +0100
sna/dri: Use move-area-to-gpu to handle clipped regions more efficiently
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index f30770f..9b882a7 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -747,14 +747,10 @@ __sna_dri_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
unsigned int flags;
flags = MOVE_WRITE | __MOVE_FORCE;
- if (clip.data ||
- clip.extents.x1 > 0 ||
- clip.extents.x2 < pixmap->drawable.width ||
- clip.extents.y1 > 0 ||
- clip.extents.y2 < pixmap->drawable.height)
+ if (clip.data)
flags |= MOVE_READ;
- priv = sna_pixmap_move_to_gpu(pixmap, flags);
+ priv = sna_pixmap_move_area_to_gpu(pixmap, &clip.extents, flags);
if (priv) {
damage(pixmap, priv, region);
dst_bo = priv->gpu_bo;
commit 1385ca9eeb26b0b82b623da619a65036830ccceb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed May 7 21:19:32 2014 +0100
sna: Initialize value read through ioctl to please valgrind
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index df80f1e..af71f11 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -3890,6 +3890,7 @@ sna_cursor_pre_init(struct sna *sna)
sna->cursor.max_size = 64;
+ cap.value = 0;
cap.name = DRM_CAP_CURSOR_WIDTH;
if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0)
sna->cursor.max_size = cap.value;
commit 7d516589ba9d0325e57e08d41becff64f81e2d00
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed May 7 17:49:15 2014 +0100
sna/dri: Implement TripleBuffering using DRI2SwapLimit
An addition to DRI2 that was overlooked at the time, was the support
added for having multiple outstanding swap requests in the core. The
importance of this is that we can then send the SwapComplete reply after
the pageflip is completed and not before as we currently do to fake
triple buffering - in clear violation of OML_sync_control.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 89d707a..f30770f 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -55,6 +55,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#error DRI2 version supported by the Xserver is too old
#endif
+#if DRI2INFOREC_VERSION < 6
+#define XORG_CAN_TRIPLE_BUFFER 0
+#else
+#define XORG_CAN_TRIPLE_BUFFER 1
+static Bool
+sna_dri_swap_limit_validate(DrawablePtr draw, int swap_limit)
+{
+ return swap_limit >= 1;
+}
+#endif
+
#if DRI2INFOREC_VERSION < 10
#undef USE_ASYNC_SWAP
#define USE_ASYNC_SWAP 0
@@ -969,6 +980,7 @@ sna_dri_window_set_chain(WindowPtr win,
{
DBG(("%s: head now %p\n", __FUNCTION__, chain));
assert(win->drawable.type == DRAWABLE_WINDOW);
+ assert(sna_dri_window_get_chain(win) != chain);
((void **)__get_private(win, sna_window_key))[1] = chain;
}
@@ -1121,6 +1133,11 @@ sna_dri_page_flip(struct sna *sna, struct sna_dri_frame_event *info)
get_private(info->back)->bo = tmp.bo;
sna->dri.flip_pending = info;
+
+#if XORG_CAN_TRIPLE_BUFFER
+ DRI2SwapLimit(info->draw, 1 + (info->type == DRI2_FLIP_THROTTLE));
+#endif
+
return true;
}
@@ -1304,48 +1321,53 @@ static void chain_swap(struct sna *sna,
DBG(("%s: chaining type=%d\n", __FUNCTION__, chain->type));
switch (chain->type) {
case DRI2_SWAP_THROTTLE:
- break;
- default:
- return;
- }
-
- DBG(("%s: emitting chained vsync'ed blit\n", __FUNCTION__));
-
- if (sna->mode.shadow_flip && !sna->mode.shadow_damage) {
- /* recursed from wait_for_shadow(), simply requeue */
- DBG(("%s -- recursed from wait_for_shadow(), requeuing\n", __FUNCTION__));
- chain->type = DRI2_SWAP;
+ DBG(("%s: emitting chained vsync'ed blit\n", __FUNCTION__));
+ if (sna->mode.shadow_flip && !sna->mode.shadow_damage) {
+ /* recursed from wait_for_shadow(), simply requeue */
+ DBG(("%s -- recursed from wait_for_shadow(), requeuing\n", __FUNCTION__));
+ chain->type = DRI2_SWAP;
- VG_CLEAR(vbl);
- vbl.request.type =
- DRM_VBLANK_RELATIVE |
- DRM_VBLANK_EVENT;
- vbl.request.sequence = 1;
- vbl.request.signal = (unsigned long)chain;
+ VG_CLEAR(vbl);
+ vbl.request.type =
+ DRM_VBLANK_RELATIVE |
+ DRM_VBLANK_EVENT;
+ vbl.request.sequence = 1;
+ vbl.request.signal = (unsigned long)chain;
- if (!sna_wait_vblank(sna, &vbl, chain->pipe))
- return;
+ if (!sna_wait_vblank(sna, &vbl, chain->pipe))
+ return;
- DBG(("%s -- requeue failed, errno=%d\n", __FUNCTION__, errno));
- } else {
- chain->bo = __sna_dri_copy_region(sna, draw, NULL,
- chain->back, chain->front, true);
+ DBG(("%s -- requeue failed, errno=%d\n", __FUNCTION__, errno));
+ } else {
+ chain->bo = __sna_dri_copy_region(sna, draw, NULL,
+ chain->back, chain->front, true);
+ }
+ case DRI2_SWAP:
+ break;
+ default:
+ return;
}
- DRI2SwapComplete(chain->client, draw,
- frame, tv_sec, tv_usec,
- DRI2_BLIT_COMPLETE,
- chain->client ? chain->event_complete : NULL, chain->event_data);
-
VG_CLEAR(vbl);
vbl.request.type =
DRM_VBLANK_RELATIVE |
- DRM_VBLANK_NEXTONMISS |
DRM_VBLANK_EVENT;
- vbl.request.sequence = 0;
+ vbl.request.sequence = 1;
vbl.request.signal = (unsigned long)chain;
- if (sna_wait_vblank(sna, &vbl, chain->pipe))
+ if (sna_wait_vblank(sna, &vbl, chain->pipe)) {
+ DRI2SwapComplete(chain->client, draw,
+ frame, tv_sec, tv_usec,
+ DRI2_BLIT_COMPLETE,
+ chain->client ? chain->event_complete : NULL, chain->event_data);
sna_dri_frame_event_info_free(sna, draw, chain);
+ } else {
+#if !XORG_CAN_TRIPLE_BUFFER
+ DRI2SwapComplete(chain->client, draw,
+ frame, tv_sec, tv_usec,
+ DRI2_BLIT_COMPLETE,
+ chain->client ? chain->event_complete : NULL, chain->event_data);
+#endif
+ }
}
static bool sna_dri_blit_complete(struct sna *sna,
@@ -1432,6 +1454,18 @@ void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
DBG(("%s: %d complete, frame=%d tv=%d.%06d\n",
__FUNCTION__, info->type,
event->sequence, event->tv_sec, event->tv_usec));
+
+#if XORG_CAN_TRIPLE_BUFFER
+ if (!sna_dri_blit_complete(sna, info))
+ return;
+
+ DRI2SwapComplete(info->client,
+ draw, event->sequence,
+ event->tv_sec, event->tv_usec,
+ DRI2_BLIT_COMPLETE,
+ info->client ? info->event_complete : NULL,
+ info->event_data);
+#endif
break;
case DRI2_WAITMSC:
@@ -1448,6 +1482,7 @@ void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
}
if (info->chain) {
+ assert(info->chain != info);
sna_dri_remove_frame_event((WindowPtr)draw, info);
chain_swap(sna, draw,
event->sequence, event->tv_sec, event->tv_usec,
@@ -1475,10 +1510,7 @@ sna_dri_immediate_blit(struct sna *sna,
event));
if (sync) {
- info->type = DRI2_SWAP_THROTTLE;
if (sna_dri_window_get_chain((WindowPtr)draw) == info) {
- drmVBlank vbl;
-
DBG(("%s: no pending blit, starting chain\n",
__FUNCTION__));
@@ -1487,24 +1519,59 @@ sna_dri_immediate_blit(struct sna *sna,
info->front,
true);
if (event) {
- DRI2SwapComplete(info->client, draw, 0, 0, 0,
- DRI2_BLIT_COMPLETE,
- info->event_complete,
- info->event_data);
+ drmVBlank vbl;
+
+ info->type = DRI2_SWAP_THROTTLE;
VG_CLEAR(vbl);
vbl.request.type =
DRM_VBLANK_RELATIVE |
- DRM_VBLANK_NEXTONMISS |
DRM_VBLANK_EVENT;
- vbl.request.sequence = 0;
+ vbl.request.sequence = 1;
vbl.request.signal = (unsigned long)info;
ret = !sna_wait_vblank(sna, &vbl, info->pipe);
+#if XORG_CAN_TRIPLE_BUFFER
+ if (ret)
+ DRI2SwapLimit(draw, 2);
+#endif
+ if (!XORG_CAN_TRIPLE_BUFFER || !ret)
+ DRI2SwapComplete(info->client, draw, 0, 0, 0,
+ DRI2_BLIT_COMPLETE,
+ info->event_complete,
+ info->event_data);
}
} else {
DBG(("%s: pending blit, chained\n", __FUNCTION__));
ret = true;
}
+#if XORG_CAN_TRIPLE_BUFFER
+ } else if (event) {
+ if (sna_dri_window_get_chain((WindowPtr)draw) == info) {
+ drmVBlank vbl;
+
+ info->type = DRI2_SWAP_THROTTLE;
+ info->bo = __sna_dri_copy_region(sna, draw, NULL,
+ info->back, info->front, false);
+
+ VG_CLEAR(vbl);
+ vbl.request.type =
+ DRM_VBLANK_RELATIVE |
+ DRM_VBLANK_EVENT;
+ vbl.request.sequence = 1;
+ vbl.request.signal = (unsigned long)info;
+ ret = !sna_wait_vblank(sna, &vbl, info->pipe);
+ if (ret)
+ DRI2SwapLimit(draw, 2);
+ else
+ DRI2SwapComplete(info->client, draw, 0, 0, 0,
+ DRI2_BLIT_COMPLETE,
+ info->event_complete,
+ info->event_data);
+ } else {
+ DBG(("%s: pending blit, chained\n", __FUNCTION__));
+ ret = true;
+ }
+#endif
} else {
DBG(("%s: immediate blit\n", __FUNCTION__));
info->bo = __sna_dri_copy_region(sna, draw, NULL,
@@ -1618,11 +1685,13 @@ sna_dri_flip_continue(struct sna *sna, struct sna_dri_frame_event *info)
return false;
sna_dri_flip_get_back(sna, info);
+#if !XORG_CAN_TRIPLE_BUFFER
DRI2SwapComplete(info->client, info->draw,
0, 0, 0,
DRI2_FLIP_COMPLETE,
info->client ? info->event_complete : NULL,
info->event_data);
+#endif
}
info->mode = 0;
@@ -1653,6 +1722,23 @@ static void chain_flip(struct sna *sna)
chain->bo = __sna_dri_copy_region(sna, chain->draw, NULL,
chain->back, chain->front,
true);
+#if XORG_CAN_TRIPLE_BUFFER
+ {
+ drmVBlank vbl;
+
+ VG_CLEAR(vbl);
+
+ chain->type = DRI2_SWAP_WAIT;
+ vbl.request.type =
+ DRM_VBLANK_RELATIVE |
+ DRM_VBLANK_EVENT;
+ vbl.request.sequence = 1;
+ vbl.request.signal = (unsigned long)chain;
+
+ if (!sna_wait_vblank(sna, &vbl, chain->pipe))
+ return;
+ }
+#endif
DRI2SwapComplete(chain->client, chain->draw, 0, 0, 0,
DRI2_BLIT_COMPLETE, chain->client ? chain->event_complete : NULL, chain->event_data);
sna_dri_frame_event_info_free(sna, chain->draw, chain);
@@ -1729,6 +1815,16 @@ static void sna_dri_flip_event(struct sna *sna,
break;
case DRI2_FLIP_THROTTLE:
+#if XORG_CAN_TRIPLE_BUFFER
+ if (flip->draw)
+ DRI2SwapComplete(flip->client, flip->draw,
+ flip->fe_frame,
+ flip->fe_tv_sec,
+ flip->fe_tv_usec,
+ DRI2_FLIP_COMPLETE,
+ flip->client ? flip->event_complete : NULL,
+ flip->event_data);
+#endif
if (sna->dri.flip_pending) {
sna_dri_frame_event_info_free(sna, flip->draw, flip);
chain_flip(sna);
@@ -1804,29 +1900,32 @@ get_current_msc_for_target(struct sna *sna, CARD64 target_msc, int pipe)
return ret;
}
+#if !XORG_CAN_TRIPLE_BUFFER && XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
static Bool find(pointer value, XID id, pointer cdata)
{
return TRUE;
}
+#endif
static int use_triple_buffer(struct sna *sna, ClientPtr client)
{
- struct sna_client *priv;
-
if ((sna->flags & SNA_TRIPLE_BUFFER) == 0)
return DRI2_FLIP;
+#if XORG_CAN_TRIPLE_BUFFER
+ return DRI2_FLIP_THROTTLE;
+#elif XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
/* Hack: Disable triple buffering for compositors */
+ {
+ struct sna_client *priv = sna_client(client);
+ if (priv->is_compositor == 0)
+ priv->is_compositor =
+ LookupClientResourceComplex(client,
+ CompositeClientWindowType+1,
+ find, NULL) ? DRI2_FLIP : DRI2_FLIP_THROTTLE;
-#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;
+ return priv->is_compositor;
+ }
#else
return DRI2_FLIP_THROTTLE;
#endif
@@ -1919,9 +2018,11 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw,
if (info->type != DRI2_FLIP) {
new_back:
sna_dri_flip_get_back(sna, info);
+#if !XORG_CAN_TRIPLE_BUFFER
DRI2SwapComplete(client, draw, 0, 0, 0,
DRI2_EXCHANGE_COMPLETE,
func, data);
+#endif
}
out:
DBG(("%s: target_msc=%lu\n", __FUNCTION__, (unsigned long)current_msc));
@@ -2010,6 +2111,10 @@ out:
return false;
}
+#if XORG_CAN_TRIPLE_BUFFER
+ DRI2SwapLimit(draw, 1);
+#endif
+
return true;
}
@@ -2345,10 +2450,10 @@ sna_dri_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc,
vbl.request.sequence += divisor;
}
+ DBG(("%s: waiting until MSC=%llu\n", __FUNCTION__, (long long)vbl.request.sequence));
if (sna_wait_vblank(sna, &vbl, pipe))
goto out_free_info;
- DBG(("%s: waiting until MSC=%llu\n", __FUNCTION__, (long long)vbl.request.sequence));
DRI2BlockClient(client, draw);
return TRUE;
@@ -2506,9 +2611,9 @@ bool sna_dri_open(struct sna *sna, ScreenPtr screen)
driverNames[1] = info.driverName;
#endif
-#if DRI2INFOREC_VERSION >= 6
+#if XORG_CAN_TRIPLE_BUFFER
info.version = 6;
- info.SwapLimitValidate = NULL;
+ info.SwapLimitValidate = sna_dri_swap_limit_validate;
info.ReuseBufferNotify = NULL;
#endif
More information about the xorg-commit
mailing list