From 84d667b94a97ad5fde68d730d57a19e1f4241ed5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 08:53:55 +0000 Subject: [PATCH 1/9] sna: Always schedule upload buffers for retirement after use Even if they are multiply referenced due to cached references. Signed-off-by: Chris Wilson --- src/sna/kgem.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 5a540e42..a87b2a52 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1590,10 +1590,15 @@ kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo) static void kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo) { + assert(bo->refcnt); + assert(bo->proxy == NULL); + bo->exec = kgem_add_handle(kgem, bo); bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring); list_move_tail(&bo->request, &kgem->next_request->buffers); + if (bo->io && !list_is_empty(&bo->list)) + list_move(&bo->list, &kgem->batch_buffers); /* XXX is it worth working around gcc here? */ kgem->flush |= bo->flush; @@ -2073,17 +2078,18 @@ static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo) static void kgem_buffer_release(struct kgem *kgem, struct kgem_buffer *bo) { + assert(bo->base.io); while (!list_is_empty(&bo->base.vma)) { struct kgem_bo *cached; cached = list_first_entry(&bo->base.vma, struct kgem_bo, vma); assert(cached->proxy == &bo->base); + assert(cached != &bo->base); list_del(&cached->vma); assert(*(struct kgem_bo **)cached->map__gtt == cached); *(struct kgem_bo **)cached->map__gtt = NULL; cached->map__gtt = NULL; - assert(cached->map__cpu == NULL); kgem_bo_destroy(kgem, cached); } @@ -2285,7 +2291,7 @@ bool kgem_retire(struct kgem *kgem) { bool retired = false; - DBG(("%s\n", __FUNCTION__)); + DBG(("%s, need_retire?=%d\n", __FUNCTION__, kgem->need_retire)); kgem->need_retire = false; @@ -2460,11 +2466,9 @@ static void kgem_finish_buffers(struct kgem *kgem) DBG(("%s: retaining upload buffer (%d/%d): used=%d, refcnt=%d\n", __FUNCTION__, bo->used, bytes(&bo->base), used, bo->base.refcnt)); bo->used = used; - if (bo->base.refcnt == 1) { - list_move(&bo->base.list, - &kgem->active_buffers); - kgem->need_retire = true; - } + list_move(&bo->base.list, + &kgem->active_buffers); + kgem->need_retire = true; continue; } DBG(("%s: discarding mmapped buffer, used=%d, map type=%d\n", From ea4f99c333b181eb21012b5bee60251695e93c8b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 12:30:21 +0000 Subject: [PATCH 2/9] intel-virtual-output: Add some DBG for bad_visual() Signed-off-by: Chris Wilson --- tools/virtual.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/virtual.c b/tools/virtual.c index 160d6a1d..226f86d4 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -1456,15 +1456,23 @@ static int record_mouse(struct context *ctx) static int bad_visual(Visual *visual, int depth) { + DBG(("%s? depth=%d, visual: bits_per_rgb=%d, red_mask=%08x, green_mask=%08x, blue_mask=%08\n", + __func__, depth, + visual->bits_per_rgb, + visual->red_mask, + visual->green_mask, + visual->blue_mask)); switch (depth) { - case 16: return (visual->bits_per_rgb != 6 || - visual->red_mask != 0x1f << 11 || - visual->green_mask != 0x3f << 5 || - visual->blue_mask != 0x1f << 0); - case 24: return (visual->bits_per_rgb != 8 || - visual->red_mask != 0xff << 16 || - visual->green_mask != 0xff << 8 || - visual->blue_mask != 0xff << 0); + case 16: return (visual->bits_per_rgb != 6 || + visual->red_mask != 0x1f << 11 || + visual->green_mask != 0x3f << 5 || + visual->blue_mask != 0x1f << 0); + + case 24: return (visual->bits_per_rgb != 8 || + visual->red_mask != 0xff << 16 || + visual->green_mask != 0xff << 8 || + visual->blue_mask != 0xff << 0); + default: return 0; } } From e0075ccee2e7bbe46ecbf717817d468cc9248cc4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 12:46:08 +0000 Subject: [PATCH 3/9] intel-virtual-output: Check for pending events before skipping draw Make sure we check if the destination display has caught up before skipping a frame. Signed-off-by: Chris Wilson --- tools/virtual.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/virtual.c b/tools/virtual.c index 226f86d4..71d18f5a 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -260,6 +260,8 @@ can_use_shm(Display *dpy, if (codes) { XShmCompletionEvent e; + memset(&e, 0, sizeof(e)); + e.type = codes->first_event; e.send_event = 1; e.serial = 1; @@ -1353,8 +1355,13 @@ static int clone_paint(struct clone *c) DBG(("%s-%s is damaged, last SHM serial: %ld, now %ld\n", DisplayString(c->dst.dpy), c->dst.name, (long)c->dst.serial, (long)LastKnownRequestProcessed(c->dst.dpy))); - if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) - return EAGAIN; + if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) { + while (XPending(c->dst.dpy)) + ; + + if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) + return EAGAIN; + } if (FORCE_FULL_REDRAW) { c->damaged.x1 = c->src.x; @@ -2326,14 +2333,12 @@ static void display_flush_send(struct display *display) return; } + memset(&e, 0, sizeof(e)); e.type = display->shm_event; e.send_event = 1; - e.serial = 0; e.drawable = display->root; e.major_code = display->shm_opcode; e.minor_code = X_ShmPutImage; - e.shmseg = 0; - e.offset = 0; XSendEvent(display->dpy, display->root, False, 0, (XEvent *)&e); display_mark_flush(display); From 969b064f74e0058a49afa17287184005d1e11402 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 12:54:01 +0000 Subject: [PATCH 4/9] intel-virtual-output: Perform an explicit sync If we fail to track rendering using ShmCompletionEvents and begin to drop frames, insert an explicit XSync. Signed-off-by: Chris Wilson --- tools/virtual.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/virtual.c b/tools/virtual.c index 71d18f5a..74a03e81 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -1359,8 +1359,14 @@ static int clone_paint(struct clone *c) while (XPending(c->dst.dpy)) ; - if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) - return EAGAIN; + if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) { + if (c->dst.display->send++ == 0) + return EAGAIN; + + XSync(c->dst.dpy, False); + c->dst.display->flush = 0; + c->dst.display->send = 0; + } } if (FORCE_FULL_REDRAW) { From 8b10c528044840d6c2a6244034fc6c2555476b8e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 12:58:06 +0000 Subject: [PATCH 5/9] intel-virtual-output: Add DBG for the latest XSync Signed-off-by: Chris Wilson --- tools/virtual.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/virtual.c b/tools/virtual.c index 74a03e81..b1527dff 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -1363,6 +1363,9 @@ static int clone_paint(struct clone *c) if (c->dst.display->send++ == 0) return EAGAIN; + DBG(("%s-%s forcing sync (last SHM serial: %ld, now %ld)\n", + DisplayString(c->dst.dpy), c->dst.name, + (long)c->dst.serial, (long)LastKnownRequestProcessed(c->dst.dpy))); XSync(c->dst.dpy, False); c->dst.display->flush = 0; c->dst.display->send = 0; From 83c33a1f436c947ab3d9289a9c57d92f964e9541 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 13:00:11 +0000 Subject: [PATCH 6/9] intel-virtual-output: Disable event tracking after a failure Signed-off-by: Chris Wilson --- tools/virtual.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/virtual.c b/tools/virtual.c index b1527dff..b03a14db 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -1369,6 +1369,9 @@ static int clone_paint(struct clone *c) XSync(c->dst.dpy, False); c->dst.display->flush = 0; c->dst.display->send = 0; + + /* Event tracking proven unreliable, disable */ + c->dst.display->shm_event = 0; } } From fa40286e2f12a4757d1b9bcbe1f1d7c5170bd7da Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 13:53:48 +0000 Subject: [PATCH 7/9] intel-virtual-output: Tighten bad_visual() checks Signed-off-by: Chris Wilson --- tools/virtual.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/virtual.c b/tools/virtual.c index b03a14db..8049d2f2 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -1475,24 +1475,29 @@ static int record_mouse(struct context *ctx) static int bad_visual(Visual *visual, int depth) { - DBG(("%s? depth=%d, visual: bits_per_rgb=%d, red_mask=%08x, green_mask=%08x, blue_mask=%08\n", + DBG(("%s? depth=%d, visual: class=%d, bits_per_rgb=%d, red_mask=%08x, green_mask=%08x, blue_mask=%08x\n", __func__, depth, + visual->class, visual->bits_per_rgb, visual->red_mask, visual->green_mask, visual->blue_mask)); + + if (!(visual->class == TrueColor || visual->class == DirectColor)) + return 1; + switch (depth) { - case 16: return (visual->bits_per_rgb != 6 || + case 16: return (/* visual->bits_per_rgb != 6 || */ visual->red_mask != 0x1f << 11 || visual->green_mask != 0x3f << 5 || visual->blue_mask != 0x1f << 0); - case 24: return (visual->bits_per_rgb != 8 || + case 24: return (/* visual->bits_per_rgb != 8 || */ visual->red_mask != 0xff << 16 || visual->green_mask != 0xff << 8 || visual->blue_mask != 0xff << 0); - default: return 0; + default: return 1; } } From b46d0d327140a1b17066e473d6d61798ffb9871a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 14:04:32 +0000 Subject: [PATCH 8/9] intel-virtual-output: Fix forced synchronisation of clones Signed-off-by: Chris Wilson --- tools/virtual.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/tools/virtual.c b/tools/virtual.c index 8049d2f2..beff3d68 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -111,6 +111,8 @@ struct display { int flush; int send; + int skip_clone; + int skip_frame; }; struct output { @@ -1360,21 +1362,14 @@ static int clone_paint(struct clone *c) ; if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) { - if (c->dst.display->send++ == 0) - return EAGAIN; - - DBG(("%s-%s forcing sync (last SHM serial: %ld, now %ld)\n", - DisplayString(c->dst.dpy), c->dst.name, - (long)c->dst.serial, (long)LastKnownRequestProcessed(c->dst.dpy))); - XSync(c->dst.dpy, False); - c->dst.display->flush = 0; - c->dst.display->send = 0; - - /* Event tracking proven unreliable, disable */ - c->dst.display->shm_event = 0; + c->dst.display->skip_clone++; + return EAGAIN; } } + c->dst.display->skip_clone = 0; + c->dst.display->skip_frame = 0; + if (FORCE_FULL_REDRAW) { c->damaged.x1 = c->src.x; c->damaged.y1 = c->src.y; @@ -2361,11 +2356,31 @@ static void display_flush_send(struct display *display) display_mark_flush(display); } +static void display_sync(struct display *display) +{ + if (display->skip_clone == 0) + return; + + if (display->skip_frame++ < 2) + return; + + DBG(("%s forcing sync\n", DisplayString(display->dpy))); + XSync(display->dpy, False); + + display->flush = 0; + display->send = 0; + + /* Event tracking proven unreliable, disable */ + display->shm_event = 0; +} + static void display_flush(struct display *display) { display_flush_cursor(display); display_flush_send(display); + display_sync(display); + if (!display->flush) return; From abf1a16914d993cc150005879375d4bb17fdccf3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 Nov 2013 17:09:35 +0000 Subject: [PATCH 9/9] intel-virtual-output: Only track the most recent visibility status of the cursor Signed-off-by: Chris Wilson --- tools/virtual.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/virtual.c b/tools/virtual.c index beff3d68..5452f456 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -1102,10 +1102,8 @@ static void display_load_visible_cursor(struct display *display, XFixesCursorIma DBG(("%s marking cursor changed\n", DisplayString(display->dpy))); display->cursor_moved++; - if (display->cursor != display->invisible_cursor) { - display->cursor_visible++; + if (display->cursor != display->invisible_cursor) context_enable_timer(display->ctx); - } } static void display_cursor_move(struct display *display, int x, int y, int visible) @@ -1113,7 +1111,7 @@ static void display_cursor_move(struct display *display, int x, int y, int visib DBG(("%s cursor moved (visible=%d, (%d, %d))\n", DisplayString(display->dpy), visible, x, y)); display->cursor_moved++; - display->cursor_visible += visible; + display->cursor_visible = visible; if (visible) { display->cursor_x = x; display->cursor_y = y; @@ -1153,7 +1151,6 @@ static void display_flush_cursor(struct display *display) display_mark_flush(display); display->cursor_moved = 0; - display->cursor_visible = 0; } static void clone_move_cursor(struct clone *c, int x, int y)