sna/dri: Eradicate the DRI2 name exchange mechanism

Thinking about the compositor <-> server <-> client inter-exchange
demonstrates that we cannot prevent the client rendering into the
source texture being show by the compositor. That is a subject for DRI3.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-02-21 19:37:51 +00:00
parent 6172ff3e35
commit b0c83b77d0
1 changed files with 4 additions and 145 deletions

View File

@ -62,7 +62,6 @@ enum frame_event_type {
DRI2_SWAP,
DRI2_SWAP_WAIT,
DRI2_SWAP_THROTTLE,
DRI2_XCHG_THROTTLE,
DRI2_FLIP,
DRI2_FLIP_THROTTLE,
DRI2_WAITMSC,
@ -1259,80 +1258,6 @@ can_flip(struct sna * sna,
return true;
}
static bool
can_exchange(struct sna * sna,
DrawablePtr draw,
DRI2BufferPtr front,
DRI2BufferPtr back)
{
WindowPtr win = (WindowPtr)draw;
PixmapPtr pixmap;
/* XXX There is an inherent race between the DRI2 client and the DRI2
* compositor which is only masked if we force a blit and serialise
* the operations through the kernel command queue. Hopeless.
*/
return false;
if (front->format != back->format) {
DBG(("%s: no, format mismatch, front = %d, back = %d\n",
__FUNCTION__, front->format, back->format));
return false;
}
if (draw->type == DRAWABLE_PIXMAP)
return true;
pixmap = get_window_pixmap(win);
if (pixmap == sna->front) {
DBG(("%s: no, window is attached to the front buffer\n",
__FUNCTION__));
return false;
}
if (pixmap->drawable.width != win->drawable.width ||
pixmap->drawable.height != win->drawable.height) {
DBG(("%s: no, window has been reparented, window size %dx%d, parent %dx%d\n",
__FUNCTION__,
win->drawable.width,
win->drawable.height,
pixmap->drawable.width,
pixmap->drawable.height));
return false;
}
if (sna_pixmap_get_buffer(pixmap) != front) {
DBG(("%s: no, DRI2 drawable is no longer attached\n",
__FUNCTION__));
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);
if (!get_private(back)->scanout) {
DBG(("%s: no, DRI2 drawable was too small at time of creation)\n",
__FUNCTION__));
return false;
}
assert(get_private(back)->size == get_private(front)->size);
/* prevent an implicit tiling mode change */
if (get_private(front)->bo->tiling != get_private(back)->bo->tiling) {
DBG(("%s -- no, tiling mismatch: front %d, back=%d\n",
__FUNCTION__,
get_private(front)->bo->tiling,
get_private(back)->bo->tiling));
return false;
}
return true;
}
inline static uint32_t pipe_select(int pipe)
{
/* The third pipe was introduced with IvyBridge long after
@ -1402,19 +1327,13 @@ static void chain_swap(struct sna *sna,
assert(chain == sna_dri_window_get_chain((WindowPtr)draw));
DBG(("%s: chaining type=%d\n", __FUNCTION__, chain->type));
switch (chain->type) {
case DRI2_XCHG_THROTTLE:
case DRI2_SWAP_THROTTLE:
break;
default:
return;
}
if (chain->type == DRI2_XCHG_THROTTLE &&
can_exchange(sna, draw, chain->front, chain->back)) {
DBG(("%s: performing chained exchange\n", __FUNCTION__));
sna_dri_exchange_buffers(draw, chain->front, chain->back);
type = DRI2_EXCHANGE_COMPLETE;
} else if (can_blit(sna, draw, chain->front, chain->back)) {
if (can_blit(sna, draw, chain->front, chain->back)) {
DBG(("%s: emitting chained vsync'ed blit\n", __FUNCTION__));
chain->bo = sna_dri_copy_to_front(sna, draw, NULL,
@ -1515,10 +1434,6 @@ void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event)
event->sequence, event->tv_sec, event->tv_usec));
break;
case DRI2_XCHG_THROTTLE:
DBG(("%s: xchg throttle\n", __FUNCTION__));
break;
case DRI2_WAITMSC:
DRI2WaitMSCComplete(info->client, draw,
event->sequence,
@ -1794,52 +1709,6 @@ sna_dri_page_flip_handler(struct sna *sna,
sna_dri_flip_event(sna, info);
}
static void
sna_dri_immediate_xchg(struct sna *sna,
DrawablePtr draw,
struct sna_dri_frame_event *info,
bool sync)
{
drmVBlank vbl;
if (sna->flags & SNA_NO_WAIT)
sync = false;
DBG(("%s: emitting immediate exchange, throttling client, synced? %d\n",
__FUNCTION__, sync));
VG_CLEAR(vbl);
if (sync) {
info->type = DRI2_XCHG_THROTTLE;
if (sna_dri_window_get_chain((WindowPtr)draw) == info) {
DBG(("%s: no pending xchg, starting chain\n",
__FUNCTION__));
sna_dri_exchange_buffers(draw, info->front, info->back);
DRI2SwapComplete(info->client, draw, 0, 0, 0,
DRI2_EXCHANGE_COMPLETE,
info->event_complete,
info->event_data);
vbl.request.type =
DRM_VBLANK_RELATIVE |
DRM_VBLANK_NEXTONMISS |
DRM_VBLANK_EVENT |
pipe_select(info->pipe);
vbl.request.sequence = 0;
vbl.request.signal = (unsigned long)info;
if (sna_wait_vblank(sna, &vbl))
sna_dri_frame_event_info_free(sna, draw, info);
}
} else {
sna_dri_exchange_buffers(draw, info->front, info->back);
DRI2SwapComplete(info->client, draw, 0, 0, 0,
DRI2_EXCHANGE_COMPLETE,
info->event_complete,
info->event_data);
sna_dri_frame_event_info_free(sna, draw, info);
}
}
static void
sna_dri_immediate_blit(struct sna *sna,
DrawablePtr draw,
@ -2190,9 +2059,7 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
if (divisor == 0 && current_msc >= *target_msc - 1) {
bool sync = current_msc < *target_msc;
if (can_exchange(sna, draw, front, back)) {
sna_dri_immediate_xchg(sna, draw, info, sync);
} else if (can_blit(sna, draw, front, back)) {
if (can_blit(sna, draw, front, back)) {
sna_dri_immediate_blit(sna, draw, info, sync);
} else {
DRI2SwapComplete(client, draw, 0, 0, 0,
@ -2270,11 +2137,7 @@ sna_dri_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
blit:
pipe = DRI2_BLIT_COMPLETE;
if (can_exchange(sna, draw, front, back)) {
DBG(("%s -- xchg\n", __FUNCTION__));
sna_dri_exchange_buffers(draw, front, back);
pipe = DRI2_EXCHANGE_COMPLETE;
} else if (can_blit(sna, draw, front, back)) {
if (can_blit(sna, draw, front, back)) {
DBG(("%s -- blit\n", __FUNCTION__));
sna_dri_copy_to_front(sna, draw, NULL,
get_private(front)->bo,
@ -2306,11 +2169,7 @@ sna_dri_async_swap(ClientPtr client, DrawablePtr draw,
!sna_dri_schedule_flip(client, draw, front, back, pipe,
&target_msc, 0, 0, func, data)) {
pipe = DRI2_BLIT_COMPLETE;
if (can_exchange(sna, draw, front, back)) {
DBG(("%s: unable to flip, so xchg\n", __FUNCTION__));
sna_dri_exchange_buffers(draw, front, back);
pipe = DRI2_EXCHANGE_COMPLETE;
} else if (can_blit(sna, draw, front, back)) {
if (can_blit(sna, draw, front, back)) {
DBG(("%s: unable to flip, so blit\n", __FUNCTION__));
sna_dri_copy_to_front(sna, draw, NULL,
get_private(front)->bo,