X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Fglx_pbuffer.c;h=515099aa0d8767121fb5e7ceda383274d885a2be;hb=396b41095944ea3675d30c0d47ca8c01db2b4c8f;hp=15bfb1591916e1cd0c51a7cd65027e190fb0c3f7;hpb=c356f5867f2c1fad7155df538b9affa8dbdcf869;p=mesa.git diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c index 15bfb159191..515099aa0d8 100644 --- a/src/glx/glx_pbuffer.c +++ b/src/glx/glx_pbuffer.c @@ -39,10 +39,11 @@ #ifdef GLX_USE_APPLEGL #include -#include "apple_glx_drawable.h" -#include "glx_error.h" +#include "apple/apple_glx_drawable.h" #endif +#include "glx_error.h" + #define WARN_ONCE_GLX_1_3(a, b) { \ static int warned=1; \ if(warned) { \ @@ -59,7 +60,7 @@ warn_GLX_1_3(Display * dpy, const char *function_name) { struct glx_display *priv = __glXInitialize(dpy); - if (priv->minorVersion < 3) { + if (priv && priv->minorVersion < 3) { fprintf(stderr, "WARNING: Application calling GLX 1.3 function \"%s\" " "when GLX 1.3 is not supported! This is an application bug!\n", @@ -77,26 +78,23 @@ warn_GLX_1_3(Display * dpy, const char *function_name) * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. - * - * \todo - * This function needs to be modified to work with direct-rendering drivers. */ static void ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, const CARD32 * attribs, size_t num_attribs) { struct glx_display *priv = __glXInitialize(dpy); +#ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw; +#endif CARD32 *output; CARD8 opcode; int i; - if ((dpy == NULL) || (drawable == 0)) { + if ((priv == NULL) || (dpy == NULL) || (drawable == 0)) { return; } - pdraw = GetGLXDRIDrawable(dpy, drawable); - opcode = __glXSetupForCommand(dpy); if (!opcode) return; @@ -106,7 +104,7 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { xGLXChangeDrawableAttributesReq *req; - GetReqExtra(GLXChangeDrawableAttributes, 8 + (8 * num_attribs), req); + GetReqExtra(GLXChangeDrawableAttributes, 8 * num_attribs, req); output = (CARD32 *) (req + 1); req->reqType = opcode; @@ -117,7 +115,7 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, else { xGLXVendorPrivateWithReplyReq *vpreq; - GetReqExtra(GLXVendorPrivateWithReply, 4 + (8 * num_attribs), vpreq); + GetReqExtra(GLXVendorPrivateWithReply, 8 + (8 * num_attribs), vpreq); output = (CARD32 *) (vpreq + 1); vpreq->reqType = opcode; @@ -125,7 +123,8 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX; output[0] = (CARD32) drawable; - output++; + output[1] = num_attribs; + output += 2; } (void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs); @@ -133,6 +132,12 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, UnlockDisplay(dpy); SyncHandle(); +#ifdef GLX_DIRECT_RENDERING + pdraw = GetGLXDRIDrawable(dpy, drawable); + + if (!pdraw) + return; + for (i = 0; i < num_attribs; i++) { switch(attribs[i * 2]) { case GLX_EVENT_MASK: @@ -141,6 +146,7 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, break; } } +#endif return; } @@ -182,7 +188,7 @@ determineTextureFormat(const int *attribs, int numAttribs) return 0; } -static void +static GLboolean CreateDRIDrawable(Display *dpy, struct glx_config *config, XID drawable, XID glxdrawable, const int *attrib_list, size_t num_attribs) @@ -191,24 +197,31 @@ CreateDRIDrawable(Display *dpy, struct glx_config *config, __GLXDRIdrawable *pdraw; struct glx_screen *psc; + if (priv == NULL) { + fprintf(stderr, "failed to create drawable\n"); + return GL_FALSE; + } + psc = priv->screens[config->screen]; if (psc->driScreen == NULL) - return; + return GL_TRUE; pdraw = psc->driScreen->createDrawable(psc, drawable, glxdrawable, config); if (pdraw == NULL) { fprintf(stderr, "failed to create drawable\n"); - return; + return GL_FALSE; } if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) { (*pdraw->destroyDrawable) (pdraw); - return; /* FIXME: Check what we're supposed to do here... */ + return GL_FALSE; } pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs); pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs); + + return GL_TRUE; } static void @@ -216,22 +229,25 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) { struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); + XID xid; - if (pdraw != NULL) { - if (destroy_xdrawable) - XFreePixmap(pdraw->psc->dpy, pdraw->xDrawable); + if (priv != NULL && pdraw != NULL) { + xid = pdraw->xDrawable; (*pdraw->destroyDrawable) (pdraw); __glxHashDelete(priv->drawHash, drawable); + if (destroy_xdrawable) + XFreePixmap(priv->dpy, xid); } } #else -static void +static GLboolean CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig, XID drawable, XID glxdrawable, const int *attrib_list, size_t num_attribs) { + return GL_TRUE; } static void @@ -255,13 +271,10 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) * The number of attributes returned is likely to be small, probably less than * 10. Given that, this routine should try to use an array on the stack to * capture the reply rather than always calling Xmalloc. - * - * \todo - * This function needs to be modified to work with direct-rendering drivers. */ -static int -GetDrawableAttribute(Display * dpy, GLXDrawable drawable, - int attribute, unsigned int *value) +int +__glXGetDrawableAttribute(Display * dpy, GLXDrawable drawable, + int attribute, unsigned int *value) { struct glx_display *priv; xGLXGetDrawableAttributesReply reply; @@ -272,11 +285,27 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable, unsigned int num_attributes; GLboolean use_glx_1_3; - if ((dpy == NULL) || (drawable == 0)) { +#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) + __GLXDRIdrawable *pdraw; +#endif + + if (dpy == NULL) + return 0; + + /* Page 38 (page 52 of the PDF) of glxencode1.3.pdf says: + * + * "If drawable is not a valid GLX drawable, a GLXBadDrawable error is + * generated." + */ + if (drawable == 0) { + __glXSendError(dpy, GLXBadDrawable, 0, X_GLXGetDrawableAttributes, false); return 0; } priv = __glXInitialize(dpy); + if (priv == NULL) + return 0; + use_glx_1_3 = ((priv->majorVersion > 1) || (priv->minorVersion >= 3)); *value = 0; @@ -286,12 +315,42 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable, if (!opcode) return 0; +#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) + pdraw = GetGLXDRIDrawable(dpy, drawable); + + if (attribute == GLX_BACK_BUFFER_AGE_EXT) { + struct glx_context *gc = __glXGetCurrentContext(); + struct glx_screen *psc; + + /* The GLX_EXT_buffer_age spec says: + * + * "If querying GLX_BACK_BUFFER_AGE_EXT and is not bound to + * the calling thread's current context a GLXBadDrawable error is + * generated." + */ + if (pdraw == NULL || gc == &dummyContext || gc->currentDpy != dpy || + (gc->currentDrawable != drawable && + gc->currentReadable != drawable)) { + __glXSendError(dpy, GLXBadDrawable, drawable, + X_GLXGetDrawableAttributes, false); + return 0; + } + + psc = pdraw->psc; + + if (psc->driScreen->getBufferAge != NULL) + *value = psc->driScreen->getBufferAge(pdraw); + + return 0; + } +#endif + LockDisplay(dpy); if (use_glx_1_3) { xGLXGetDrawableAttributesReq *req; - GetReqExtra(GLXGetDrawableAttributes, 4, req); + GetReq(GLXGetDrawableAttributes, req); req->reqType = opcode; req->glxCode = X_GLXGetDrawableAttributes; req->drawable = drawable; @@ -319,7 +378,7 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable, length = reply.length; if (length) { num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2; - data = (CARD32 *) Xmalloc(length * sizeof(CARD32)); + data = malloc(length * sizeof(CARD32)); if (data == NULL) { /* Throw data on the floor */ _XEatData(dpy, length); @@ -338,42 +397,60 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable, } #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - { - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); - - if (pdraw != NULL && !pdraw->textureTarget) + if (pdraw != NULL) { + if (!pdraw->textureTarget) pdraw->textureTarget = determineTextureTarget((const int *) data, num_attributes); - if (pdraw != NULL && !pdraw->textureFormat) + if (!pdraw->textureFormat) pdraw->textureFormat = determineTextureFormat((const int *) data, num_attributes); } #endif - Xfree(data); + free(data); } } UnlockDisplay(dpy); SyncHandle(); - return 0; + return 1; +} + +static void +protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode) +{ + xGLXDestroyPbufferReq *req; + CARD8 opcode; + + opcode = __glXSetupForCommand(dpy); + if (!opcode) + return; + + LockDisplay(dpy); + + GetReq(GLXDestroyPbuffer, req); + req->reqType = opcode; + req->glxCode = glxCode; + req->pbuffer = (GLXPbuffer) drawable; + + UnlockDisplay(dpy); + SyncHandle(); } /** * Create a non-pbuffer GLX drawable. - * - * \todo - * This function needs to be modified to work with direct-rendering drivers. */ static GLXDrawable CreateDrawable(Display *dpy, struct glx_config *config, Drawable drawable, const int *attrib_list, CARD8 glxCode) { xGLXCreateWindowReq *req; + struct glx_drawable *glxDraw; CARD32 *data; unsigned int i; CARD8 opcode; + GLXDrawable xid; i = 0; if (attrib_list) { @@ -385,6 +462,10 @@ CreateDrawable(Display *dpy, struct glx_config *config, if (!opcode) return None; + glxDraw = malloc(sizeof(*glxDraw)); + if (!glxDraw) + return None; + LockDisplay(dpy); GetReqExtra(GLXCreateWindow, 8 * i, req); data = (CARD32 *) (req + 1); @@ -394,7 +475,7 @@ CreateDrawable(Display *dpy, struct glx_config *config, req->screen = config->screen; req->fbconfig = config->fbconfigID; req->window = drawable; - req->glxwindow = XAllocID(dpy); + req->glxwindow = xid = XAllocID(dpy); req->numAttribs = i; if (attrib_list) @@ -403,9 +484,21 @@ CreateDrawable(Display *dpy, struct glx_config *config, UnlockDisplay(dpy); SyncHandle(); - CreateDRIDrawable(dpy, config, drawable, req->glxwindow, attrib_list, i); + if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) { + free(glxDraw); + return None; + } + + if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) { + if (glxCode == X_GLXCreatePixmap) + glxCode = X_GLXDestroyPixmap; + else + glxCode = X_GLXDestroyWindow; + protocolDestroyDrawable(dpy, xid, glxCode); + xid = None; + } - return req->glxwindow; + return xid; } @@ -415,28 +508,13 @@ CreateDrawable(Display *dpy, struct glx_config *config, static void DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) { - xGLXDestroyPbufferReq *req; - CARD8 opcode; - if ((dpy == NULL) || (drawable == 0)) { return; } + protocolDestroyDrawable(dpy, drawable, glxCode); - opcode = __glXSetupForCommand(dpy); - if (!opcode) - return; - - LockDisplay(dpy); - - GetReqExtra(GLXDestroyPbuffer, 4, req); - req->reqType = opcode; - req->glxCode = glxCode; - req->pbuffer = (GLXPbuffer) drawable; - - UnlockDisplay(dpy); - SyncHandle(); - + DestroyGLXDrawable(dpy, drawable); DestroyDRIDrawable(dpy, drawable, GL_FALSE); return; @@ -452,9 +530,6 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) * \note * This function dynamically determines whether to use the SGIX_pbuffer * version of the protocol or the GLX 1.3 version of the protocol. - * - * \todo - * This function needs to be modified to work with direct-rendering drivers. */ static GLXDrawable CreatePbuffer(Display * dpy, struct glx_config *config, @@ -467,6 +542,10 @@ CreatePbuffer(Display * dpy, struct glx_config *config, CARD8 opcode; unsigned int i; Pixmap pixmap; + GLboolean glx_1_3 = GL_FALSE; + + if (priv == NULL) + return None; i = 0; if (attrib_list) { @@ -485,6 +564,8 @@ CreatePbuffer(Display * dpy, struct glx_config *config, xGLXCreatePbufferReq *req; unsigned int extra = (size_in_attribs) ? 0 : 2; + glx_1_3 = GL_TRUE; + GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req); data = (CARD32 *) (req + 1); @@ -529,7 +610,12 @@ CreatePbuffer(Display * dpy, struct glx_config *config, pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen), width, height, config->rgbBits); - CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i); + if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) { + CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX; + XFreePixmap(dpy, pixmap); + protocolDestroyDrawable(dpy, id, o); + id = None; + } return id; } @@ -550,7 +636,7 @@ DestroyPbuffer(Display * dpy, GLXDrawable drawable) struct glx_display *priv = __glXInitialize(dpy); CARD8 opcode; - if ((dpy == NULL) || (drawable == 0)) { + if ((priv == NULL) || (dpy == NULL) || (drawable == 0)) { return; } @@ -593,7 +679,7 @@ DestroyPbuffer(Display * dpy, GLXDrawable drawable) /** * Create a new pbuffer. */ -_X_EXPORT GLXPbufferSGIX +_GLX_PUBLIC GLXPbufferSGIX glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) @@ -608,7 +694,7 @@ glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config, /** * Create a new pbuffer. */ -_X_EXPORT GLXPbuffer +_GLX_PUBLIC GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list) { int i, width, height; @@ -683,7 +769,7 @@ glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list) /** * Destroy an existing pbuffer. */ -_X_EXPORT void +_GLX_PUBLIC void glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) { #ifdef GLX_USE_APPLEGL @@ -699,7 +785,7 @@ glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) /** * Query an attribute of a drawable. */ -_X_EXPORT void +_GLX_PUBLIC void glXQueryDrawable(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { @@ -739,7 +825,7 @@ glXQueryDrawable(Display * dpy, GLXDrawable drawable, } } #else - GetDrawableAttribute(dpy, drawable, attribute, value); + __glXGetDrawableAttribute(dpy, drawable, attribute, value); #endif } @@ -748,18 +834,18 @@ glXQueryDrawable(Display * dpy, GLXDrawable drawable, /** * Query an attribute of a pbuffer. */ -_X_EXPORT int +_GLX_PUBLIC void glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable, int attribute, unsigned int *value) { - return GetDrawableAttribute(dpy, drawable, attribute, value); + __glXGetDrawableAttribute(dpy, drawable, attribute, value); } #endif /** * Select the event mask for a drawable. */ -_X_EXPORT void +_GLX_PUBLIC void glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask) { #ifdef GLX_USE_APPLEGL @@ -792,7 +878,7 @@ glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask) /** * Get the selected event mask for a drawable. */ -_X_EXPORT void +_GLX_PUBLIC void glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask) { #ifdef GLX_USE_APPLEGL @@ -815,7 +901,7 @@ glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask) __glXSendError(dpy, GLXBadDrawable, drawable, X_GLXGetDrawableAttributes, true); #else - unsigned int value; + unsigned int value = 0; /* The non-sense with value is required because on LP64 platforms @@ -823,20 +909,20 @@ glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask) * we could just type-cast the pointer, but why? */ - GetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value); + __glXGetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value); *mask = value; #endif } -_X_EXPORT GLXPixmap +_GLX_PUBLIC GLXPixmap glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list) { WARN_ONCE_GLX_1_3(dpy, __func__); #ifdef GLX_USE_APPLEGL - const struct glx_config *modes = (const __GLcontextModes *) config; + const struct glx_config *modes = (const struct glx_config *) config; if (apple_glx_pixmap_create(dpy, modes->screen, pixmap, modes)) return None; @@ -849,7 +935,7 @@ glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, } -_X_EXPORT GLXWindow +_GLX_PUBLIC GLXWindow glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, const int *attrib_list) { @@ -874,7 +960,7 @@ glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, return None; } - XFree(visinfo); + free(visinfo); return win; #else @@ -884,7 +970,7 @@ glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, } -_X_EXPORT void +_GLX_PUBLIC void glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) { WARN_ONCE_GLX_1_3(dpy, __func__); @@ -897,7 +983,7 @@ glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) } -_X_EXPORT void +_GLX_PUBLIC void glXDestroyWindow(Display * dpy, GLXWindow win) { WARN_ONCE_GLX_1_3(dpy, __func__); @@ -906,20 +992,18 @@ glXDestroyWindow(Display * dpy, GLXWindow win) #endif } -#ifndef GLX_USE_APPLEGL -_X_EXPORT +_GLX_PUBLIC GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX, (Display * dpy, GLXPbufferSGIX pbuf), (dpy, pbuf), glXDestroyPbuffer) -_X_EXPORT +_GLX_PUBLIC GLX_ALIAS_VOID(glXSelectEventSGIX, (Display * dpy, GLXDrawable drawable, unsigned long mask), (dpy, drawable, mask), glXSelectEvent) -_X_EXPORT +_GLX_PUBLIC GLX_ALIAS_VOID(glXGetSelectedEventSGIX, (Display * dpy, GLXDrawable drawable, unsigned long *mask), (dpy, drawable, mask), glXGetSelectedEvent) -#endif