summaryrefslogtreecommitdiff
path: root/GL
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-08-27 14:23:50 -0400
committerKristian Høgsberg <krh@redhat.com>2007-10-12 19:12:26 -0400
commit695eb8b2e88abc9fa3a76d8da48c3214c7dd1f08 (patch)
tree15708e11ab0afd61892e68d60188d266f0e9237d /GL
parent516c181f57367847c3f317f8f8f5cc3211026f4c (diff)
Implement GLX pbuffers.
Diffstat (limited to 'GL')
-rw-r--r--GL/glx/glxcmds.c158
-rw-r--r--GL/glx/glxdrawable.h12
-rw-r--r--GL/glx/glxdri.c4
-rw-r--r--GL/glx/glxext.h5
-rw-r--r--GL/glx/glxglcore.c5
-rw-r--r--GL/glx/glxscreens.h1
-rw-r--r--GL/glx/glxutil.c6
-rw-r--r--GL/glx/glxutil.h2
8 files changed, 134 insertions, 59 deletions
diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 0d576c146..f838f21a6 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -488,7 +488,8 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
}
pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
- pDraw, drawId, modes);
+ pDraw, GLX_DRAWABLE_WINDOW,
+ drawId, modes);
/* since we are creating the drawablePrivate, drawId should be new */
if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
@@ -1127,24 +1128,17 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
static int
DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
- XID drawableId, XID glxDrawableId, int type)
+ DrawablePtr pDraw, XID glxDrawableId, int type)
{
- DrawablePtr pDraw;
ScreenPtr pScreen;
VisualPtr pVisual;
__GLXscreen *pGlxScreen;
__GLXdrawable *pGlxDraw;
__GLcontextModes *modes;
- int i, rc;
+ int i;
LEGAL_NEW_RESOURCE(glxDrawableId, client);
- rc = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess);
- if (rc != Success || pDraw->type != type) {
- client->errorValue = drawableId;
- return type == DRAWABLE_WINDOW ? BadWindow : BadPixmap;
- }
-
/* Check if screen of the fbconfig matches screen of drawable. */
pScreen = pDraw->pScreen;
if (screenNum != pScreen->myNum)
@@ -1169,7 +1163,7 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
/* FIXME: We need to check that the window visual is compatible
* with the specified fbconfig. */
- pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw,
+ pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
glxDrawableId, modes);
if (pGlxDraw == NULL)
return BadAlloc;
@@ -1179,10 +1173,29 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId,
return BadAlloc;
}
- if (type == DRAWABLE_PIXMAP)
+ return Success;
+}
+
+static int
+DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId,
+ XID drawableId, XID glxDrawableId)
+{
+ DrawablePtr pDraw;
+ int err;
+
+ err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess);
+ if (err != Success || pDraw->type != DRAWABLE_PIXMAP) {
+ client->errorValue = drawableId;
+ return BadPixmap;
+ }
+
+ err = DoCreateGLXDrawable(client, screenNum, fbconfigId, pDraw,
+ glxDrawableId, GLX_DRAWABLE_PIXMAP);
+
+ if (err == Success)
((PixmapPtr) pDraw)->refcnt++;
- return Success;
+ return err;
}
static void
@@ -1223,8 +1236,8 @@ int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
- return DoCreateGLXDrawable(cl->client, req->screen, req->visual,
- req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
+ return DoCreateGLXPixmap(cl->client, req->screen, req->visual,
+ req->pixmap, req->glxpixmap);
}
int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
@@ -1232,8 +1245,8 @@ int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
int err;
- err = DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
- req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
+ err = DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
+ req->pixmap, req->glxpixmap);
if (err != Success)
return err;
@@ -1248,8 +1261,8 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
xGLXCreateGLXPixmapWithConfigSGIXReq *req =
(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
- return DoCreateGLXDrawable(cl->client, req->screen, req->fbconfig,
- req->pixmap, req->glxpixmap, DRAWABLE_PIXMAP);
+ return DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig,
+ req->pixmap, req->glxpixmap);
}
@@ -1257,7 +1270,6 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
{
ClientPtr client = cl->client;
__GLXdrawable *pGlxDraw;
- int error;
/*
** Check it's the right type of drawable.
@@ -1265,8 +1277,14 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
pGlxDraw = LookupIDByType(glxdrawable, __glXDrawableRes);
if (pGlxDraw == NULL || pGlxDraw->type != type) {
client->errorValue = glxdrawable;
- error = type == DRAWABLE_WINDOW ? GLXBadWindow : GLXBadDrawable;
- return __glXError(error);
+ switch (type) {
+ case GLX_DRAWABLE_WINDOW:
+ return __glXError(GLXBadWindow);
+ case GLX_DRAWABLE_PIXMAP:
+ return __glXError(GLXBadDrawable);
+ case GLX_DRAWABLE_PBUFFER:
+ return __glXError(GLXBadPbuffer);
+ }
}
FreeResource(glxdrawable, FALSE);
@@ -1277,50 +1295,94 @@ int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
- return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
+ return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
}
int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
- return DoDestroyDrawable(cl, req->glxpixmap, DRAWABLE_PIXMAP);
+ return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
+}
+
+static int
+DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
+ int width, int height, XID glxDrawableId)
+{
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ PixmapPtr pPixmap;
+ int i;
+
+ pScreen = screenInfo.screens[screenNum];
+
+ pVisual = pScreen->visuals;
+ for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+ if (pVisual->vid == fbconfigId)
+ break;
+ }
+ if (i == pScreen->numVisuals)
+ return __glXError(GLXBadFBConfig);
+
+ __glXenterServer(GL_FALSE);
+ pPixmap = (*pScreen->CreatePixmap) (pScreen,
+ width, height, pVisual->nplanes);
+ __glXleaveServer(GL_FALSE);
+
+ return DoCreateGLXDrawable(client, screenNum, fbconfigId,
+ &pPixmap->drawable, glxDrawableId,
+ GLX_DRAWABLE_PBUFFER);
}
int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
{
- xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
+ xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
+ CARD32 *attrs;
+ int width, height, i;
- (void) req;
+ attrs = (CARD32 *) (req + 1);
+ width = 0;
+ height = 0;
- return BadRequest;
+ for (i = 0; i < req->numAttribs; i++) {
+ switch (attrs[i * 2]) {
+ case GLX_PBUFFER_WIDTH:
+ width = attrs[i * 2 + 1];
+ break;
+ case GLX_PBUFFER_HEIGHT:
+ height = attrs[i * 2 + 1];
+ break;
+ case GLX_LARGEST_PBUFFER:
+ case GLX_PRESERVED_CONTENTS:
+ /* FIXME: huh... */
+ break;
+ }
+ }
+
+ return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+ width, height, req->pbuffer);
}
int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
{
xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
- (void) req;
-
- return BadRequest;
+ return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+ req->width, req->height, req->pbuffer);
}
int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
- (void) req;
-
- return BadRequest;
+ return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
}
-__glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
- (void) req;
-
- return BadRequest;
+ return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
}
int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
@@ -1345,18 +1407,26 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
{
- xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
- ClientPtr client = cl->client;
+ xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ int err;
+
+ err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess);
+ if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
+ client->errorValue = req->window;
+ return BadWindow;
+ }
return DoCreateGLXDrawable(client, req->screen, req->fbconfig,
- req->window, req->glxwindow, DRAWABLE_WINDOW);
+ pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
}
int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
{
xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
- return DoDestroyDrawable(cl, req->glxwindow, DRAWABLE_WINDOW);
+ return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
}
@@ -1493,7 +1563,7 @@ int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
return error;
pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
- if (!pGlxDraw || pGlxDraw->type != DRAWABLE_PIXMAP) {
+ if (!pGlxDraw || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
client->errorValue = drawId;
return __glXError(GLXBadPixmap);
}
@@ -1526,7 +1596,7 @@ int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
return error;
pGlxDraw = __glXGetDrawable(NULL, drawId, client, &error);
- if (error != Success || pGlxDraw->type != DRAWABLE_PIXMAP) {
+ if (error != Success || pGlxDraw->type != GLX_DRAWABLE_PIXMAP) {
client->errorValue = drawId;
return error;
}
@@ -1588,7 +1658,7 @@ int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
return error;
if (pGlxDraw == NULL ||
- pGlxDraw->type != DRAWABLE_WINDOW ||
+ pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
pGlxDraw->copySubBuffer == NULL)
return __glXError(GLXBadDrawable);
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index 5fdcf9525..247e7a27c 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -46,6 +46,13 @@
#include <GL/internal/dri_interface.h>
#endif
+/* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */
+enum {
+ GLX_DRAWABLE_WINDOW,
+ GLX_DRAWABLE_PIXMAP,
+ GLX_DRAWABLE_PBUFFER
+};
+
struct __GLXdrawable {
void (*destroy)(__GLXdrawable *private);
GLboolean (*resize)(__GLXdrawable *private);
@@ -63,9 +70,8 @@ struct __GLXdrawable {
XID drawId;
/*
- ** Either DRAWABLE_PIXMAP or DRAWABLE_WINDOW, copied from pDraw above.
- ** Needed by the resource freer because pDraw might already have been
- ** freed.
+ ** Either GLX_DRAWABLE_PIXMAP, GLX_DRAWABLE_WINDOW or
+ ** GLX_DRAWABLE_PBUFFER.
*/
int type;
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 3394e5896..2ded6aa81 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -615,6 +615,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
static __GLXdrawable *
__glXDRIscreenCreateDrawable(__GLXscreen *screen,
DrawablePtr pDraw,
+ int type,
XID drawId,
__GLcontextModes *modes)
{
@@ -629,7 +630,8 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen,
memset(private, 0, sizeof *private);
- if (!__glXDrawableInit(&private->base, screen, pDraw, drawId, modes)) {
+ if (!__glXDrawableInit(&private->base, screen,
+ pDraw, type, drawId, modes)) {
xfree(private);
return NULL;
}
diff --git a/GL/glx/glxext.h b/GL/glx/glxext.h
index 8de643495..601bb2248 100644
--- a/GL/glx/glxext.h
+++ b/GL/glx/glxext.h
@@ -79,11 +79,6 @@ extern int DoGetFBConfigs(__GLXclientState *cl, unsigned screen,
GLboolean do_swap);
extern int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
GLXContextID shareList, VisualID visual, GLuint screen, GLboolean isDirect);
-extern int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
- GLuint screenNum, XID pixmapId, XID glxpixmapId, CARD32 *attribs,
- CARD32 numAttribs);
-extern int DoDestroyPixmap(__GLXclientState *cl, XID glxpixmapId);
-
extern int DoQueryContext(__GLXclientState *cl, GLXContextID gcId);
extern int DoRender(__GLXclientState *cl, GLbyte *pc, int do_swap);
diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c
index 679d55c5d..fd4e57d59 100644
--- a/GL/glx/glxglcore.c
+++ b/GL/glx/glxglcore.c
@@ -118,7 +118,7 @@ __glXMesaDrawableSwapBuffers(__GLXdrawable *base)
static __GLXdrawable *
__glXMesaScreenCreateDrawable(__GLXscreen *screen,
- DrawablePtr pDraw,
+ DrawablePtr pDraw, int type,
XID drawId,
__GLcontextModes *modes)
{
@@ -131,7 +131,8 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen,
memset(glxPriv, 0, sizeof *glxPriv);
- if (!__glXDrawableInit(&glxPriv->base, screen, pDraw, drawId, modes)) {
+ if (!__glXDrawableInit(&glxPriv->base, screen,
+ pDraw, type, drawId, modes)) {
xfree(glxPriv);
return NULL;
}
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index d887beb2a..7b1bbcd58 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -72,6 +72,7 @@ struct __GLXscreen {
__GLXdrawable *(*createDrawable)(__GLXscreen *context,
DrawablePtr pDraw,
+ int type,
XID drawId,
__GLcontextModes *modes);
int (*swapInterval) (__GLXdrawable *drawable,
diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c
index df1cb2abc..9479a5890 100644
--- a/GL/glx/glxutil.c
+++ b/GL/glx/glxutil.c
@@ -139,11 +139,11 @@ __glXUnrefDrawable(__GLXdrawable *glxPriv)
GLboolean
__glXDrawableInit(__GLXdrawable *drawable,
- __GLXscreen *screen, DrawablePtr pDraw, XID drawId,
- __GLcontextModes *modes)
+ __GLXscreen *screen, DrawablePtr pDraw, int type,
+ XID drawId, __GLcontextModes *modes)
{
- drawable->type = pDraw->type;
drawable->pDraw = pDraw;
+ drawable->type = type;
drawable->drawId = drawId;
drawable->refCount = 1;
drawable->modes = modes;
diff --git a/GL/glx/glxutil.h b/GL/glx/glxutil.h
index 1937ef2cf..6534c3f94 100644
--- a/GL/glx/glxutil.h
+++ b/GL/glx/glxutil.h
@@ -50,7 +50,7 @@ extern void __glXUnrefDrawable(__GLXdrawable *glxPriv);
extern GLboolean __glXDrawableInit(__GLXdrawable *drawable,
__GLXscreen *screen,
- DrawablePtr pDraw, XID drawID,
+ DrawablePtr pDraw, int type, XID drawID,
__GLcontextModes *modes);
/* context helper routines */