diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 9a61c14b..8226fd85 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", diff --git a/tools/virtual.c b/tools/virtual.c index 160d6a1d..5452f456 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 { @@ -260,6 +262,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; @@ -1098,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) @@ -1109,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; @@ -1149,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) @@ -1353,8 +1354,18 @@ 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)) { + 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; @@ -1456,16 +1467,29 @@ static int record_mouse(struct context *ctx) static int bad_visual(Visual *visual, int depth) { + 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 || - 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; + 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 1; } } @@ -2318,24 +2342,42 @@ 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); } +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;