static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc, XID xDrawable, GLXDrawable drawable, const __GLcontextModes *modes) { __GLXDRIdrawablePrivate *pdraw; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; pdraw = Xmalloc(sizeof(*pdraw)); if (!pdraw) return NULL; pdraw->base.destroyDrawable = dri2DestroyDrawable; pdraw->base.xDrawable = xDrawable; pdraw->base.drawable = drawable; pdraw->base.psc = psc; pdraw->bufferCount = 0; DRI2CreateDrawable(psc->dpy, xDrawable); /* Create a new drawable */ pdraw->base.driDrawable = (*psc->dri2->createNewDrawable)(psc->__driScreen, config->driConfig, pdraw); if (!pdraw->base.driDrawable) { DRI2DestroyDrawable(psc->dpy, drawable); Xfree(pdraw); return NULL; } return &pdraw->base; }
/** * Create/Destroy the DRI drawable. */ void x11_drawable_enable_dri2(struct x11_screen *xscr, Drawable drawable, boolean on) { if (on) DRI2CreateDrawable(xscr->dpy, drawable); else DRI2DestroyDrawable(xscr->dpy, drawable); }
static __GLXDRIdrawable * dri2CreateDrawable(__GLXscreenConfigs * psc, XID xDrawable, GLXDrawable drawable, const __GLcontextModes * modes) { __GLXDRIdrawablePrivate *pdraw; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; __GLXdisplayPrivate *dpyPriv; __GLXDRIdisplayPrivate *pdp; pdraw = Xmalloc(sizeof(*pdraw)); if (!pdraw) return NULL; pdraw->base.destroyDrawable = dri2DestroyDrawable; pdraw->base.xDrawable = xDrawable; pdraw->base.drawable = drawable; pdraw->base.psc = psc; pdraw->bufferCount = 0; pdraw->swap_interval = 1; pdraw->have_back = 0; DRI2CreateDrawable(psc->dpy, xDrawable); dpyPriv = __glXInitialize(psc->dpy); pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;; /* Create a new drawable */ pdraw->base.driDrawable = (*psc->dri2->createNewDrawable) (psc->__driScreen, config->driConfig, pdraw); if (!pdraw->base.driDrawable) { DRI2DestroyDrawable(psc->dpy, xDrawable); Xfree(pdraw); return NULL; } #ifdef X_DRI2SwapInterval /* * Make sure server has the same swap interval we do for the new * drawable. */ if (pdp->swapAvailable) DRI2SwapInterval(psc->dpy, xDrawable, pdraw->swap_interval); #endif return &pdraw->base; }
static int ProcDRI2CreateDrawable(ClientPtr client) { REQUEST(xDRI2CreateDrawableReq); DrawablePtr pDrawable; int status; REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); if (!validDrawable(client, stuff->drawable, DixAddAccess, &pDrawable, &status)) return status; status = DRI2CreateDrawable(client, pDrawable, stuff->drawable, DRI2InvalidateBuffersEvent, client); if (status != Success) return status; return Success; }
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); }
static int ProcDRI2QueryVersion(ClientPtr client) { REQUEST(xDRI2QueryVersionReq); xDRI2QueryVersionReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .majorVersion = dri2_major, .minorVersion = dri2_minor }; if (client->swapped) swaps(&stuff->length); REQUEST_SIZE_MATCH(xDRI2QueryVersionReq); if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.majorVersion); swapl(&rep.minorVersion); } WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep); return Success; } static int ProcDRI2Connect(ClientPtr client) { REQUEST(xDRI2ConnectReq); xDRI2ConnectReply rep = { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .driverNameLength = 0, .deviceNameLength = 0 }; DrawablePtr pDraw; int fd, status; const char *driverName; const char *deviceName; REQUEST_SIZE_MATCH(xDRI2ConnectReq); if (!validDrawable(client, stuff->window, DixGetAttrAccess, &pDraw, &status)) return status; if (!DRI2Connect(client, pDraw->pScreen, stuff->driverType, &fd, &driverName, &deviceName)) goto fail; rep.driverNameLength = strlen(driverName); rep.deviceNameLength = strlen(deviceName); rep.length = (rep.driverNameLength + 3) / 4 + (rep.deviceNameLength + 3) / 4; fail: WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); WriteToClient(client, rep.driverNameLength, driverName); WriteToClient(client, rep.deviceNameLength, deviceName); return Success; } static int ProcDRI2Authenticate(ClientPtr client) { REQUEST(xDRI2AuthenticateReq); xDRI2AuthenticateReply rep; DrawablePtr pDraw; int status; REQUEST_SIZE_MATCH(xDRI2AuthenticateReq); if (!validDrawable(client, stuff->window, DixGetAttrAccess, &pDraw, &status)) return status; rep = (xDRI2AuthenticateReply) { .type = X_Reply, .sequenceNumber = client->sequence, .length = 0, .authenticated = DRI2Authenticate(client, pDraw->pScreen, stuff->magic) }; WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep); return Success; } static void DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id) { ClientPtr client = priv; xDRI2InvalidateBuffers event = { .type = DRI2EventBase + DRI2_InvalidateBuffers, .drawable = id }; WriteEventsToClient(client, 1, (xEvent *) &event); } static int ProcDRI2CreateDrawable(ClientPtr client) { REQUEST(xDRI2CreateDrawableReq); DrawablePtr pDrawable; int status; REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); if (!validDrawable(client, stuff->drawable, DixAddAccess, &pDrawable, &status)) return status; status = DRI2CreateDrawable(client, pDrawable, stuff->drawable, DRI2InvalidateBuffersEvent, client); if (status != Success) return status; return Success; }
int ephyrDRI2CreateDrawable(XID drawable) { Display *dpy = hostx_get_display () ; DRI2CreateDrawable(dpy, drawable); return Success ; }
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); }