diff options
author | Kristian Høgsberg <krh@redhat.com> | 2007-08-27 14:23:50 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2007-10-12 19:12:26 -0400 |
commit | 695eb8b2e88abc9fa3a76d8da48c3214c7dd1f08 (patch) | |
tree | 15708e11ab0afd61892e68d60188d266f0e9237d /GL | |
parent | 516c181f57367847c3f317f8f8f5cc3211026f4c (diff) |
Implement GLX pbuffers.
Diffstat (limited to 'GL')
-rw-r--r-- | GL/glx/glxcmds.c | 158 | ||||
-rw-r--r-- | GL/glx/glxdrawable.h | 12 | ||||
-rw-r--r-- | GL/glx/glxdri.c | 4 | ||||
-rw-r--r-- | GL/glx/glxext.h | 5 | ||||
-rw-r--r-- | GL/glx/glxglcore.c | 5 | ||||
-rw-r--r-- | GL/glx/glxscreens.h | 1 | ||||
-rw-r--r-- | GL/glx/glxutil.c | 6 | ||||
-rw-r--r-- | GL/glx/glxutil.h | 2 |
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 */ |