summaryrefslogtreecommitdiff
path: root/src/glx
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2008-08-13 11:46:25 -0400
committerKristian Høgsberg <krh@redhat.com>2008-08-29 12:13:14 -0400
commitf56b569e9af356c11869ee49a4669bb01b75397e (patch)
tree5fd52ee856b106c8b97027061737d366de2d1c2b /src/glx
parent7a2ab6d05573508389b38f8f1fa261ba56062865 (diff)
DRI2: Drop sarea, implement swap buffers in the X server.
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/x11/dri2.c113
-rw-r--r--src/glx/x11/dri2.h23
-rw-r--r--src/glx/x11/dri2_glx.c128
-rw-r--r--src/glx/x11/dri_glx.c6
-rw-r--r--src/glx/x11/glxclient.h5
-rw-r--r--src/glx/x11/glxcmds.c3
6 files changed, 174 insertions, 104 deletions
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
index e7044ab424..dc60af90c1 100644
--- a/src/glx/x11/dri2.c
+++ b/src/glx/x11/dri2.c
@@ -122,7 +122,11 @@ Bool DRI2Connect(Display *dpy, int screen,
return False;
}
- *sareaHandle = rep.sareaHandle;
+ if (rep.driverNameLength == 0 && rep.busIdLength == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
*driverName = Xmalloc(rep.driverNameLength + 1);
if (*driverName == NULL) {
@@ -150,7 +154,7 @@ Bool DRI2Connect(Display *dpy, int screen,
UnlockDisplay(dpy);
SyncHandle();
- return rep.sareaHandle != 0;
+ return True;
}
Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic)
@@ -179,74 +183,119 @@ Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic)
return rep.authenticated;
}
-Bool DRI2CreateDrawable(Display *dpy, XID drawable,
- unsigned int *handle, unsigned int *head)
+void DRI2CreateDrawable(Display *dpy, XID drawable)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2CreateDrawableReply rep;
xDRI2CreateDrawableReq *req;
- XextCheckExtension (dpy, info, dri2ExtensionName, False);
+ XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
LockDisplay(dpy);
GetReq(DRI2CreateDrawable, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2CreateDrawable;
req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetBuffersReply rep;
+ xDRI2GetBuffersReq *req;
+ DRI2Buffer *buffers;
+ xDRI2Buffer repBuffer;
+ CARD32 *p;
+ int i;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReqExtra(DRI2GetBuffers, count * 4, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetBuffers;
+ req->drawable = drawable;
+ req->count = count;
+ p = (CARD32 *) &req[1];
+ for (i = 0; i < count; i++)
+ p[i] = attachments[i];
+
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
- return False;
+ return NULL;
+ }
+
+ *width = rep.width;
+ *height = rep.height;
+ *outCount = rep.count;
+
+ buffers = Xmalloc(count * sizeof buffers[0]);
+ if (buffers == NULL) {
+ _XEatData(dpy, rep.count * sizeof repBuffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ for (i = 0; i < rep.count; i++) {
+ _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
+ buffers[i].attachment = repBuffer.attachment;
+ buffers[i].name = repBuffer.name;
+ buffers[i].pitch = repBuffer.pitch;
+ buffers[i].cpp = repBuffer.cpp;
+ buffers[i].flags = repBuffer.flags;
}
+
UnlockDisplay(dpy);
SyncHandle();
- *handle = rep.handle;
- *head = rep.head;
-
- return True;
+ return buffers;
}
-void DRI2DestroyDrawable(Display *dpy, XID drawable)
+void DRI2SwapBuffers(Display *dpy, XID drawable,
+ int x, int y, int width, int height)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2DestroyDrawableReq *req;
+ xDRI2SwapBuffersReq *req;
+ xDRI2SwapBuffersReply rep;
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
- XSync(dpy, GL_FALSE);
-
LockDisplay(dpy);
- GetReq(DRI2DestroyDrawable, req);
+ GetReq(DRI2SwapBuffers, req);
req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2DestroyDrawable;
+ req->dri2ReqType = X_DRI2SwapBuffers;
req->drawable = drawable;
+ req->x = x;
+ req->y = y;
+ req->width = width;
+ req->height = height;
+
+ _XReply(dpy, (xReply *)&rep, 0, xFalse);
+
UnlockDisplay(dpy);
SyncHandle();
}
-Bool DRI2ReemitDrawableInfo(Display *dpy, XID drawable, unsigned int *head)
+void DRI2DestroyDrawable(Display *dpy, XID drawable)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2ReemitDrawableInfoReply rep;
- xDRI2ReemitDrawableInfoReq *req;
+ xDRI2DestroyDrawableReq *req;
- XextCheckExtension (dpy, info, dri2ExtensionName, False);
+ XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+
+ XSync(dpy, GL_FALSE);
LockDisplay(dpy);
- GetReq(DRI2ReemitDrawableInfo, req);
+ GetReq(DRI2DestroyDrawable, req);
req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2ReemitDrawableInfo;
+ req->dri2ReqType = X_DRI2DestroyDrawable;
req->drawable = drawable;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
UnlockDisplay(dpy);
SyncHandle();
-
- *head = rep.head;
-
- return True;
}
diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h
index 1dfd0448b2..e57c4ce644 100644
--- a/src/glx/x11/dri2.h
+++ b/src/glx/x11/dri2.h
@@ -33,6 +33,14 @@
#ifndef _DRI2_H_
#define _DRI2_H_
+typedef struct {
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
+} DRI2Buffer;
+
extern Bool
DRI2QueryExtension(Display *display, int *eventBase, int *errorBase);
extern Bool
@@ -42,12 +50,17 @@ DRI2Connect(Display *display, int screen,
char **driverName, char **busId, unsigned int *sareaHandle);
extern Bool
DRI2AuthConnection(Display *display, int screen, drm_magic_t magic);
-extern Bool
-DRI2CreateDrawable(Display *display, XID drawable,
- unsigned int *handle, unsigned int *head);
+extern void
+DRI2CreateDrawable(Display *display, XID drawable);
extern void
DRI2DestroyDrawable(Display *display, XID handle);
-extern Bool
-DRI2ReemitDrawableInfo(Display *dpy, XID handle, unsigned int *head);
+extern DRI2Buffer *
+DRI2GetBuffers(Display *dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount);
+extern void
+DRI2SwapBuffers(Display *dpy, XID drawable,
+ int x, int y, int width, int height);
#endif
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index 0be65bce62..c56adfa558 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -49,6 +49,7 @@
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
+typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
struct __GLXDRIdisplayPrivateRec {
__GLXDRIdisplay base;
@@ -67,6 +68,13 @@ struct __GLXDRIcontextPrivateRec {
__GLXscreenConfigs *psc;
};
+struct __GLXDRIdrawablePrivateRec {
+ __GLXDRIdrawable base;
+ __DRIbuffer buffers[5];
+ int bufferCount;
+ int width, height;
+};
+
static void dri2DestroyContext(__GLXDRIcontext *context,
__GLXscreenConfigs *psc, Display *dpy)
{
@@ -104,7 +112,6 @@ static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc,
{
__GLXDRIcontextPrivate *pcp, *pcp_shared;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
- const __DRIcoreExtension *core = psc->core;
__DRIcontext *shared = NULL;
if (shareList) {
@@ -118,8 +125,8 @@ static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc,
pcp->psc = psc;
pcp->driContext =
- (*core->createNewContext)(psc->__driScreen,
- config->driConfig, shared, pcp);
+ (*psc->dri2->createNewContext)(psc->__driScreen,
+ config->driConfig, shared, pcp);
gc->__driContext = pcp->driContext;
if (pcp->driContext == NULL) {
@@ -148,45 +155,40 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc,
GLXDrawable drawable,
const __GLcontextModes *modes)
{
- __GLXDRIdrawable *pdraw;
+ __GLXDRIdrawablePrivate *pdraw;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
- unsigned int handle, head;
- const __DRIcoreExtension *core = psc->core;
pdraw = Xmalloc(sizeof(*pdraw));
if (!pdraw)
return NULL;
- pdraw->destroyDrawable = dri2DestroyDrawable;
- pdraw->xDrawable = xDrawable;
- pdraw->drawable = drawable;
- pdraw->psc = psc;
-
- fprintf(stderr, "calling DRI2CreateDrawable, XID 0x%lx, GLX ID 0x%lx\n",
- xDrawable, drawable);
-
- if (!DRI2CreateDrawable(psc->dpy, xDrawable, &handle, &head)) {
- Xfree(pdraw);
- return NULL;
- }
+ pdraw->base.destroyDrawable = dri2DestroyDrawable;
+ pdraw->base.xDrawable = xDrawable;
+ pdraw->base.drawable = drawable;
+ pdraw->base.psc = psc;
- fprintf(stderr, "success, head 0x%x, handle 0x%x\n", head, handle);
+ DRI2CreateDrawable(psc->dpy, xDrawable);
/* Create a new drawable */
- pdraw->driDrawable =
- (*core->createNewDrawable)(psc->__driScreen,
- config->driConfig,
- handle,
- head,
- pdraw);
-
- if (!pdraw->driDrawable) {
+ 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;
+ return &pdraw->base;
+}
+
+static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
+{
+ __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+
+ DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable,
+ 0, 0, priv->width, priv->height);
}
static void dri2DestroyScreen(__GLXscreenConfigs *psc)
@@ -197,46 +199,39 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc)
psc->__driScreen = NULL;
}
-
-static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail,
- void *loaderPrivate)
+static __DRIbuffer *
+dri2GetBuffers(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
{
- __GLXDRIdrawable *pdraw = loaderPrivate;
-
- DRI2ReemitDrawableInfo(pdraw->psc->dpy, pdraw->drawable, tail);
-}
-
-static void dri2PostDamage(__DRIdrawable *draw,
- struct drm_clip_rect *rects,
- int numRects, void *loaderPrivate)
-{
- XRectangle *xrects;
- XserverRegion region;
- __GLXDRIdrawable *glxDraw = loaderPrivate;
- __GLXscreenConfigs *psc = glxDraw->psc;
- Display *dpy = psc->dpy;
+ __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+ DRI2Buffer *buffers;
int i;
- xrects = malloc(sizeof(XRectangle) * numRects);
- if (xrects == NULL)
- return;
-
- for (i = 0; i < numRects; i++) {
- xrects[i].x = rects[i].x1;
- xrects[i].y = rects[i].y1;
- xrects[i].width = rects[i].x2 - rects[i].x1;
- xrects[i].height = rects[i].y2 - rects[i].y1;
+ buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
+ width, height, attachments, count, out_count);
+ pdraw->width = *width;
+ pdraw->height = *height;
+
+ /* This assumes the DRI2 buffer attachment tokens matches the
+ * __DRIbuffer tokens. */
+ for (i = 0; i < *out_count; i++) {
+ pdraw->buffers[i].attachment = buffers[i].attachment;
+ pdraw->buffers[i].name = buffers[i].name;
+ pdraw->buffers[i].pitch = buffers[i].pitch;
+ pdraw->buffers[i].cpp = buffers[i].cpp;
+ pdraw->buffers[i].flags = buffers[i].flags;
}
- region = XFixesCreateRegion(dpy, xrects, numRects);
- free(xrects);
- XDamageAdd(dpy, glxDraw->xDrawable, region);
- XFixesDestroyRegion(dpy, region);
+
+ Xfree(buffers);
+
+ return pdraw->buffers;
}
-static const __DRIloaderExtension dri2LoaderExtension = {
- { __DRI_LOADER, __DRI_LOADER_VERSION },
- dri2ReemitDrawableInfo,
- dri2PostDamage
+static const __DRIdri2LoaderExtension dri2LoaderExtension = {
+ { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
+ dri2GetBuffers,
};
static const __DRIextension *loader_extensions[] = {
@@ -279,10 +274,12 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
psc->core = (__DRIcoreExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
+ psc->dri2 = (__DRIdri2Extension *) extensions[i];
}
- if (psc->core == NULL) {
- ErrorMessageF("core dri extension not found\n");
+ if (psc->core == NULL || psc->dri2 == NULL) {
+ ErrorMessageF("core dri or dri2 extension not found\n");
goto handle_error;
}
@@ -301,7 +298,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
}
psc->__driScreen =
- psc->core->createNewScreen(screen, psc->fd, sareaHandle,
+ psc->dri2->createNewScreen(screen, psc->fd,
loader_extensions, &driver_configs, psc);
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
@@ -316,6 +313,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
psp->destroyScreen = dri2DestroyScreen;
psp->createContext = dri2CreateContext;
psp->createDrawable = dri2CreateDrawable;
+ psp->swapBuffers = dri2SwapBuffers;
Xfree(driverName);
Xfree(busID);
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index 08c83a2310..39bf6c430b 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -570,6 +570,11 @@ static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
return pdraw;
}
+static void driSwapBuffers(__GLXDRIdrawable *pdraw)
+{
+ (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
+}
+
static void driDestroyScreen(__GLXscreenConfigs *psc)
{
/* Free the direct rendering per screen data */
@@ -641,6 +646,7 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
psp->createDrawable = driCreateDrawable;
+ psp->swapBuffers = driSwapBuffers;
return psp;
}
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index e2b4218200..412511247e 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -123,6 +123,8 @@ struct __GLXDRIscreenRec {
XID drawable,
GLXDrawable glxDrawable,
const __GLcontextModes *modes);
+
+ void (*swapBuffers)(__GLXDRIdrawable *pdraw);
};
struct __GLXDRIcontextRec {
@@ -141,8 +143,8 @@ struct __GLXDRIdrawableRec {
XID xDrawable;
XID drawable;
__GLXscreenConfigs *psc;
- __DRIdrawable *driDrawable;
GLenum textureTarget;
+ __DRIdrawable *driDrawable;
};
/*
@@ -469,6 +471,7 @@ struct __GLXscreenConfigsRec {
const __DRIcoreExtension *core;
const __DRIlegacyExtension *legacy;
const __DRIswrastExtension *swrast;
+ const __DRIdri2Extension *dri2;
__glxHashTable *drawHash;
Display *dpy;
int scr, fd;
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index 0f0cb6233a..9197130dca 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -855,7 +855,8 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
if (pdraw != NULL) {
- (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
+ glFlush();
+ (*pdraw->psc->driScreen->swapBuffers)(pdraw);
return;
}
#endif