Exemplo n.º 1
0
static int64_t
dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
                int64_t remainder)
{
    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
    __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy);
    __GLXDRIdisplayPrivate *pdp =
        (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
    int64_t ret;

#ifdef __DRI2_FLUSH
    if (pdraw->psc->f)
        (*pdraw->psc->f->flush)(pdraw->driDrawable);
#endif

    /* Old servers don't send invalidate events */
    if (!pdp->invalidateAvailable)
        dri2InvalidateBuffers(dpyPriv->dpy, pdraw->drawable);

    /* Old servers can't handle swapbuffers */
    if (!pdp->swapAvailable) {
        dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
        return 0;
    }

#ifdef X_DRI2SwapBuffers
    DRI2SwapBuffers(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
                    remainder, &ret);
#endif

    return ret;
}
static void run(Display *dpy, int width, int height,
		unsigned int *attachments, int nattachments,
		const char *name)
{
	Window win;
	XSetWindowAttributes attr;
	int count, loop;
	DRI2Buffer *buffers;

	/* Be nasty and install a fullscreen window on top so that we
	 * can guarantee we do not get clipped by children.
	 */
	attr.override_redirect = 1;
	loop = 100;
	do {
		win = XCreateWindow(dpy, DefaultRootWindow(dpy),
				    0, 0, width, height, 0,
				    DefaultDepth(dpy, DefaultScreen(dpy)),
				    InputOutput,
				    DefaultVisual(dpy, DefaultScreen(dpy)),
				    CWOverrideRedirect, &attr);
		XMapWindow(dpy, win);

		DRI2CreateDrawable(dpy, win);

		buffers = DRI2GetBuffers(dpy, win, &width, &height,
					 attachments, nattachments, &count);
		if (count != nattachments)
			return;

		free(buffers);
		for (count = 0; count < loop; count++)
			DRI2SwapBuffers(dpy, win, 0, 0, 0);
		XDestroyWindow(dpy, win);
	} while (--loop);

	XSync(dpy, 1);
	sleep(2);
	XSync(dpy, 1);
}
Exemplo n.º 3
0
static void
DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc,
              CARD32 sbc)
{
    DrawablePtr pDrawable = data;
    xDRI2BufferSwapComplete2 event = {
        .type = DRI2EventBase + DRI2_BufferSwapComplete,
        .event_type = type,
        .drawable = pDrawable->id,
        .ust_hi = (CARD64) ust >> 32,
        .ust_lo = ust & 0xffffffff,
        .msc_hi = (CARD64) msc >> 32,
        .msc_lo = msc & 0xffffffff,
        .sbc = sbc
    };

    WriteEventsToClient(client, 1, (xEvent *) &event);
}

static int
ProcDRI2SwapBuffers(ClientPtr client)
{
    REQUEST(xDRI2SwapBuffersReq);
    xDRI2SwapBuffersReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0
    };
    DrawablePtr pDrawable;
    CARD64 target_msc, divisor, remainder, swap_target;
    int status;

    REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);

    if (!validDrawable(client, stuff->drawable,
                       DixReadAccess | DixWriteAccess, &pDrawable, &status))
        return status;

    /*
     * Ensures an out of control client can't exhaust our swap queue, and
     * also orders swaps.
     */
    if (DRI2ThrottleClient(client, pDrawable))
        return Success;

    target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
    divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
    remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);

    status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder,
                             &swap_target, DRI2SwapEvent, pDrawable);
    if (status != Success)
        return BadDrawable;

    load_swap_reply(&rep, swap_target);

    WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep);

    return Success;
}

static void
load_msc_reply(xDRI2MSCReply * rep, CARD64 ust, CARD64 msc, CARD64 sbc)
{
    rep->ust_hi = ust >> 32;
    rep->ust_lo = ust & 0xffffffff;
    rep->msc_hi = msc >> 32;
    rep->msc_lo = msc & 0xffffffff;
    rep->sbc_hi = sbc >> 32;
    rep->sbc_lo = sbc & 0xffffffff;
}
Exemplo n.º 4
0
static void run(Display *dpy, int width, int height,
		unsigned int *attachments, int nattachments,
		const char *name)
{
	Window win;
	XSetWindowAttributes attr;
	int count;
	DRI2Buffer *buffers;
	struct timespec start, end;

	/* Be nasty and install a fullscreen window on top so that we
	 * can guarantee we do not get clipped by children.
	 */
	attr.override_redirect = 1;
	win = XCreateWindow(dpy, DefaultRootWindow(dpy),
			 0, 0, width, height, 0,
			 DefaultDepth(dpy, DefaultScreen(dpy)),
			 InputOutput,
			 DefaultVisual(dpy, DefaultScreen(dpy)),
			 CWOverrideRedirect, &attr);
	XMapWindow(dpy, win);
	xsync(dpy, win);

	DRI2CreateDrawable(dpy, win);

	buffers = DRI2GetBuffers(dpy, win, &width, &height,
				 attachments, nattachments, &count);
	if (count != nattachments)
		return;

	xsync(dpy, win);
	clock_gettime(CLOCK_MONOTONIC, &start);
	for (count = 0; count < COUNT; count++)
		DRI2SwapBuffers(dpy, win, 0, 0, 0);
	xsync(dpy, win);
	clock_gettime(CLOCK_MONOTONIC, &end);
	printf("%d %s (%dx%d) swaps in %fs.\n",
	       count, name, width, height, elapsed(&start, &end));

	xsync(dpy, win);
	clock_gettime(CLOCK_MONOTONIC, &start);
	for (count = 0; count < COUNT; count++)
		dri2_copy_swap(dpy, win, width, height, nattachments == 2);
	xsync(dpy, win);
	clock_gettime(CLOCK_MONOTONIC, &end);

	printf("%d %s (%dx%d) blits in %fs.\n",
	       count, name, width, height, elapsed(&start, &end));

	DRI2SwapInterval(dpy, win, 0);

	xsync(dpy, win);
	clock_gettime(CLOCK_MONOTONIC, &start);
	for (count = 0; count < COUNT; count++)
		DRI2SwapBuffers(dpy, win, 0, 0, 0);
	xsync(dpy, win);
	clock_gettime(CLOCK_MONOTONIC, &end);
	printf("%d %s (%dx%d) vblank=0 swaps in %fs.\n",
	       count, name, width, height, elapsed(&start, &end));

	XDestroyWindow(dpy, win);
	free(buffers);

	XSync(dpy, 1);
}