diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2007-10-25 12:19:30 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil> | 2007-10-25 12:19:30 -0400 |
commit | b633d54b94d746d26e13014634d9f63bbb7e8f7d (patch) | |
tree | 4832d035672164284ff8698d5875e9d5435f494a | |
parent | 4b05f19cb9e42d8c8eff5ca4e463f5bc2a05433d (diff) | |
parent | 48ca5961caee62f2980017a6bdc96a1b4c747727 (diff) |
Merge branch 'master' into XACE-SELINUX
Conflicts:
GL/glx/glxscreens.c
hw/xnest/Screen.c
render/glyph.c
render/glyphstr.h
render/render.c
44 files changed, 1207 insertions, 1881 deletions
diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am index 7c1730e39..8eda1531e 100644 --- a/GL/glx/Makefile.am +++ b/GL/glx/Makefile.am @@ -53,7 +53,6 @@ libglx_la_SOURCES = \ glxserver.h \ glxutil.c \ glxutil.h \ - glxvisuals.c \ indirect_dispatch.c \ indirect_dispatch.h \ indirect_dispatch_swap.c \ diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index f6e032193..992ddbce5 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -59,16 +59,91 @@ #include "indirect_table.h" #include "indirect_util.h" -/************************************************************************/ - void GlxSetRenderTables (struct _glapi_table *table) { _glapi_set_dispatch (table); } +static int +validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) +{ + /* + ** Check if screen exists. + */ + if (screen >= screenInfo.numScreens) { + client->errorValue = screen; + *err = BadValue; + return FALSE; + } + *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); -/************************************************************************/ + return TRUE; +} + +static int +validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, + __GLcontextModes **config, int *err) +{ + __GLcontextModes *m; + + for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) + if (m->fbconfigID == id) { + *config = m; + return TRUE; + } + + client->errorValue = id; + *err = __glXError(GLXBadFBConfig); + + return FALSE; +} + +static int +validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, + __GLcontextModes **config, int *err) +{ + int i; + + for (i = 0; i < pGlxScreen->numVisuals; i++) + if (pGlxScreen->visuals[i]->visualID == id) { + *config = pGlxScreen->visuals[i]; + return TRUE; + } + + client->errorValue = id; + *err = BadValue; + + return FALSE; +} + +static int +validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config, + DrawablePtr pDraw, int *err) +{ + ScreenPtr pScreen = pDraw->pScreen; + VisualPtr pVisual = NULL; + XID vid; + int i; + + vid = wVisual((WindowPtr)pDraw); + for (i = 0; i < pScreen->numVisuals; i++) { + if (pScreen->visuals[i].vid == vid) { + pVisual = &pScreen->visuals[i]; + break; + } + } + + /* FIXME: What exactly should we check here... */ + if (pVisual->class != _gl_convert_to_x_visual_type(config->visualType) || + !(config->drawableType & GLX_WINDOW_BIT)) { + client->errorValue = pDraw->id; + *err = BadMatch; + return FALSE; + } + + return TRUE; +} void __glXContextDestroy(__GLXcontext *context) @@ -111,58 +186,14 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, static int DoCreateContext(__GLXclientState *cl, GLXContextID gcId, - GLXContextID shareList, VisualID visual, - GLuint screen, GLboolean isDirect) + GLXContextID shareList, __GLcontextModes *config, + __GLXscreen *pGlxScreen, GLboolean isDirect) { ClientPtr client = cl->client; VisualPtr pVisual; - ScreenPtr pScreen; __GLXcontext *glxc, *shareglxc; - __GLcontextModes *modes; - __GLXscreen *pGlxScreen; - GLint i; LEGAL_NEW_RESOURCE(gcId, client); - - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return BadValue; - } - pScreen = screenInfo.screens[screen]; - pGlxScreen = glxGetScreen(pScreen); - - /* - ** Check if the visual ID is valid for this screen. - */ - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == visual) { - break; - } - } - if (i == pScreen->numVisuals) { - client->errorValue = visual; - return BadValue; - } - - /* - ** Get configuration of the visual. This assumes that the - ** glxScreen structure contains visual configurations only for the - ** subset of Visuals that are supported by this implementation of the - ** OpenGL. - */ - - modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual ); - if (modes == NULL) { - /* - ** Visual not support on this screen by this OpenGL implementation. - */ - client->errorValue = visual; - return BadValue; - } /* ** Find the display list space that we want to share. @@ -206,9 +237,9 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, ** Allocate memory for the new context */ if (!isDirect) - glxc = pGlxScreen->createContext(pGlxScreen, modes, shareglxc); + glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc); else - glxc = __glXdirectContextCreate(pGlxScreen, modes, shareglxc); + glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc); if (!glxc) { return BadAlloc; } @@ -217,10 +248,10 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, ** Initially, setup the part of the context that could be used by ** a GL core that needs windowing information (e.g., Mesa). */ - glxc->pScreen = pScreen; + glxc->pScreen = pGlxScreen->pScreen; glxc->pGlxScreen = pGlxScreen; glxc->pVisual = pVisual; - glxc->modes = modes; + glxc->modes = config; /* ** Register this context as a resource. @@ -245,34 +276,54 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, return Success; } - int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - return DoCreateContext( cl, req->context, req->shareList, req->visual, - req->screen, req->isDirect ); -} + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; + + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) + return err; + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; - return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, - req->screen, req->isDirect ); -} + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; - return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, - req->screen, req->isDirect ); -} + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; -/* -** Destroy a GL context as an X resource. -*/ + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; @@ -407,9 +458,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, int *error) { DrawablePtr pDraw; - __GLcontextModes *modes; __GLXdrawable *pGlxDraw; - VisualID vid; int rc; /* This is the GLX 1.3 case - the client passes in a GLXWindow or @@ -446,21 +495,17 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, return NULL; } - vid = wVisual((WindowPtr)pDraw); - modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, vid); - /* We're binding an X Window for the first time and need to create - * a GLX drawable for it. First check that the drawable screen - * and fbconfig matches the context ditto. */ - if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) { - client->errorValue = drawId; - *error = BadMatch; + * a GLX drawable for it. Check that the drawable screen matches + * the context screen and that the context fbconfig is compatible + * with the window visual. */ + if (pDraw->pScreen != glxc->pScreen || + !validGlxFBConfigForWindow(client, glxc->modes, pDraw, error)) return NULL; - } pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, pDraw, GLX_DRAWABLE_WINDOW, - drawId, modes); + drawId, glxc->modes); /* since we are creating the drawablePrivate, drawId should be new */ if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { @@ -830,29 +875,24 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc) } -static int -DoGetVisualConfigs(__GLXclientState *cl, unsigned screen) +int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) { + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; ClientPtr client = cl->client; xGLXGetVisualConfigsReply reply; __GLXscreen *pGlxScreen; __GLcontextModes *modes; CARD32 buf[__GLX_TOTAL_CONFIG]; - int p; + int p, i, err; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - if (screen >= screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; - reply.numVisuals = pGlxScreen->numUsableVisuals; + reply.numVisuals = pGlxScreen->numVisuals; reply.numProps = __GLX_TOTAL_CONFIG; - reply.length = (pGlxScreen->numUsableVisuals * __GLX_SIZE_CARD32 * - __GLX_TOTAL_CONFIG) >> 2; + reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG) >> 2; reply.type = X_Reply; reply.sequenceNumber = client->sequence; @@ -865,11 +905,9 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen) WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); - for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { - if (modes->visualID == 0) { - /* not a usable visual */ - continue; - } + for (i = 0; i < pGlxScreen->numVisuals; i++) { + modes = pGlxScreen->visuals[i]; + p = 0; buf[p++] = modes->visualID; buf[p++] = _gl_convert_to_x_visual_type( modes->visualType ); @@ -919,93 +957,6 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen) return Success; } -int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; - return DoGetVisualConfigs(cl, req->screen); -} - - -/* Composite adds a 32 bit ARGB visual after glxvisuals.c have created - * the context modes for the screens. This visual is useful for GLX - * pixmaps, so we create a single mode for this visual with no extra - * buffers. */ -static void -__glXCreateARGBConfig(__GLXscreen *screen) -{ - __GLcontextModes *modes; - VisualPtr visual; - int i; - - /* search for a 32-bit visual */ - visual = NULL; - for (i = 0; i < screen->pScreen->numVisuals; i++) - if (screen->pScreen->visuals[i].nplanes == 32) { - visual = &screen->pScreen->visuals[i]; - break; - } - - if (visual == NULL || visual->class != TrueColor) - return; - - /* Stop now if we already added the mode. */ - if (_gl_context_modes_find_visual (screen->modes, visual->vid)) - return; - - modes = _gl_context_modes_create(1, sizeof(__GLcontextModes)); - if (modes == NULL) - return; - - /* Insert this new mode at the TAIL of the linked list. - * Previously, the mode was incorrectly inserted at the head of the - * list, causing find_mesa_visual() to be off by one. This would - * GLX clients to blow up if they attempted to use the last mode - * in the list! - */ - { - __GLcontextModes *prev = NULL, *m; - for (m = screen->modes; m; m = m->next) - prev = m; - if (prev) - prev->next = modes; - else - screen->modes = modes; - } - - screen->numUsableVisuals++; - screen->numVisuals++; - - modes->visualID = visual->vid; - modes->fbconfigID = visual->vid; - modes->visualType = GLX_TRUE_COLOR; - modes->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; - modes->renderType = GLX_RGBA_BIT; - modes->xRenderable = GL_TRUE; - modes->rgbMode = TRUE; - modes->colorIndexMode = FALSE; - modes->doubleBufferMode = FALSE; - modes->stereoMode = FALSE; - modes->haveAccumBuffer = FALSE; - - modes->redBits = visual->bitsPerRGBValue;; - modes->greenBits = visual->bitsPerRGBValue; - modes->blueBits = visual->bitsPerRGBValue; - modes->alphaBits = visual->bitsPerRGBValue; - - modes->rgbBits = 4 * visual->bitsPerRGBValue; - modes->indexBits = 0; - modes->level = 0; - modes->numAuxBuffers = 0; - - modes->haveDepthBuffer = FALSE; - modes->depthBits = 0; - modes->haveStencilBuffer = FALSE; - modes->stencilBits = 0; - - modes->visualRating = GLX_NON_CONFORMANT_CONFIG; -} - - #define __GLX_TOTAL_FBCONFIG_ATTRIBS (28) #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) /** @@ -1025,25 +976,15 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) xGLXGetFBConfigsReply reply; __GLXscreen *pGlxScreen; CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; - int p; + int p, err; __GLcontextModes *modes; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err)) + return err; - if (screen >= screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - - /* Create the "extra" 32bpp ARGB visual, if not already added. - * XXX This is questionable place to do so! Re-examine this someday. - */ - __glXCreateARGBConfig(pGlxScreen); - - reply.numFBConfigs = pGlxScreen->numUsableVisuals; + reply.numFBConfigs = pGlxScreen->numFBConfigs; reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS; reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs); reply.type = X_Reply; @@ -1058,18 +999,14 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); - for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { - if (modes->visualID == 0) { - /* not a usable visual */ - continue; - } + for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) { p = 0; #define WRITE_PAIR(tag,value) \ do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) WRITE_PAIR( GLX_VISUAL_ID, modes->visualID ); - WRITE_PAIR( GLX_FBCONFIG_ID, modes->visualID ); + WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID ); WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE ); WRITE_PAIR( GLX_RGBA, modes->rgbMode ); @@ -1089,12 +1026,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits ); WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits ); WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits ); - WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType ); - - /* - ** Add token/value pairs for extensions. - */ WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating ); WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel ); WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed ); @@ -1127,44 +1059,18 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) } static int -DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId, +DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, DrawablePtr pDraw, XID glxDrawableId, int type) { - ScreenPtr pScreen; - VisualPtr pVisual; - __GLXscreen *pGlxScreen; __GLXdrawable *pGlxDraw; - __GLcontextModes *modes; - int i; LEGAL_NEW_RESOURCE(glxDrawableId, client); - /* Check if screen of the fbconfig matches screen of drawable. */ - pScreen = pDraw->pScreen; - if (screenNum != pScreen->myNum) + if (pGlxScreen->pScreen != pDraw->pScreen) return BadMatch; - /* If this fbconfig has a corresponding VisualRec the number of - * planes must match the drawable depth. */ - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == fbconfigId && pVisual->nplanes != pDraw->depth) - return BadMatch; - } - - /* Get configuration of the visual. */ - pGlxScreen = glxGetScreen(pScreen); - modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId); - if (modes == NULL) { - /* Visual not support on this screen by this OpenGL implementation. */ - client->errorValue = fbconfigId; - return BadValue; - } - - /* FIXME: We need to check that the window visual is compatible - * with the specified fbconfig. */ pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type, - glxDrawableId, modes); + glxDrawableId, config); if (pGlxDraw == NULL) return BadAlloc; @@ -1177,7 +1083,7 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId, } static int -DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId, +DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, XID drawableId, XID glxDrawableId) { DrawablePtr pDraw; @@ -1189,7 +1095,7 @@ DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId, return BadPixmap; } - err = DoCreateGLXDrawable(client, screenNum, fbconfigId, pDraw, + err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, glxDrawableId, GLX_DRAWABLE_PIXMAP); if (err == Success) @@ -1235,17 +1141,32 @@ determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs) int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; - return DoCreateGLXPixmap(cl->client, req->screen, req->visual, + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) + return err; + + return DoCreateGLXPixmap(cl->client, pGlxScreen, config, req->pixmap, req->glxpixmap); } int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; int err; - err = DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig, + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + err = DoCreateGLXPixmap(cl->client, pGlxScreen, config, req->pixmap, req->glxpixmap); if (err != Success) return err; @@ -1260,9 +1181,17 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapWithConfigSGIXReq *req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; - return DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig, - req->pixmap, req->glxpixmap); + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateGLXPixmap(cl->client, pGlxScreen, + config, req->pixmap, req->glxpixmap); } @@ -1286,6 +1215,11 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type) return __glXError(GLXBadPbuffer); } } + + if (type == GLX_DRAWABLE_PIXMAP) { + ((PixmapPtr) pGlxDraw->pDraw)->refcnt--; + } + FreeResource(glxdrawable, FALSE); return Success; @@ -1309,29 +1243,23 @@ 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]; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + PixmapPtr pPixmap; + int err; - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == fbconfigId) - break; - } - if (i == pScreen->numVisuals) - return __glXError(GLXBadFBConfig); + if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) + return err; __glXenterServer(GL_FALSE); - pPixmap = (*pScreen->CreatePixmap) (pScreen, - width, height, pVisual->nplanes); + pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen, + width, height, config->rgbBits); __glXleaveServer(GL_FALSE); - return DoCreateGLXDrawable(client, screenNum, fbconfigId, - &pPixmap->drawable, glxDrawableId, - GLX_DRAWABLE_PBUFFER); + return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, + glxDrawableId, GLX_DRAWABLE_PBUFFER); } int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) @@ -1428,17 +1356,27 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) { xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; ClientPtr client = cl->client; DrawablePtr pDraw; int err; + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) + return 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, + if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) + return err; + + return DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW); } @@ -2338,23 +2276,15 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) ClientPtr client = cl->client; xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; xGLXQueryExtensionsStringReply reply; - GLuint screen; + __GLXscreen *pGlxScreen; size_t n, length; - const char *ptr; char *buf; + int err; - screen = req->screen; - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return BadValue; - } - - ptr = glxGetScreen(screenInfo.screens[screen])->GLXextensions; + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; - n = strlen(ptr) + 1; + n = strlen(pGlxScreen->GLXextensions) + 1; length = __GLX_PAD(n) >> 2; reply.type = X_Reply; reply.sequenceNumber = client->sequence; @@ -2365,7 +2295,7 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) buf = (char *) xalloc(length << 2); if (buf == NULL) return BadAlloc; - memcpy(buf, ptr, n); + memcpy(buf, pGlxScreen->GLXextensions, n); if (client->swapped) { glxSwapQueryExtensionsStringReply(client, &reply, buf); @@ -2383,25 +2313,16 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc) ClientPtr client = cl->client; xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; xGLXQueryServerStringReply reply; - int name; - GLuint screen; size_t n, length; const char *ptr; char *buf; __GLXscreen *pGlxScreen; + int err; - name = req->name; - screen = req->screen; - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return BadValue; - } - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; - switch(name) { + switch(req->name) { case GLX_VENDOR: ptr = pGlxScreen->GLXvendor; break; diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h index 858bbb35b..f62d1ee34 100644 --- a/GL/glx/glxdrawable.h +++ b/GL/glx/glxdrawable.h @@ -42,10 +42,6 @@ #include <damage.h> -#ifdef XF86DRI -#include <GL/internal/dri_interface.h> -#endif - /* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */ enum { GLX_DRAWABLE_WINDOW, diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index 2ded6aa81..3688d50a8 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -658,64 +658,6 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, return &private->base; } - -static unsigned -filter_modes(__GLcontextModes **server_modes, - const __GLcontextModes *driver_modes) -{ - __GLcontextModes * m; - __GLcontextModes ** prev_next; - const __GLcontextModes * check; - unsigned modes_count = 0; - - if ( driver_modes == NULL ) { - LogMessage(X_WARNING, - "AIGLX: 3D driver returned no fbconfigs.\n"); - return 0; - } - - /* For each mode in server_modes, check to see if a matching mode exists - * in driver_modes. If not, then the mode is not available. - */ - - prev_next = server_modes; - for ( m = *prev_next ; m != NULL ; m = *prev_next ) { - GLboolean do_delete = GL_TRUE; - - for ( check = driver_modes ; check != NULL ; check = check->next ) { - if ( _gl_context_modes_are_same( m, check ) ) { - do_delete = GL_FALSE; - break; - } - } - - /* The 3D has to support all the modes that match the GLX visuals - * sent from the X server. - */ - if ( do_delete && (m->visualID != 0) ) { - do_delete = GL_FALSE; - - LogMessage(X_WARNING, - "AIGLX: 3D driver claims to not support " - "visual 0x%02x\n", m->visualID); - } - - if ( do_delete ) { - *prev_next = m->next; - - m->next = NULL; - _gl_context_modes_destroy( m ); - } - else { - modes_count++; - prev_next = & m->next; - } - } - - return modes_count; -} - - static GLboolean getDrawableInfo(__DRIdrawable *driDrawable, unsigned int *index, unsigned int *stamp, @@ -923,7 +865,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) char *driverName; drm_handle_t hFB; int junk; - __GLcontextModes * driver_modes; __GLXDRIscreen *screen; void *dev_priv = NULL; char filename[128]; @@ -1073,7 +1014,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - driver_modes = NULL; screen->driScreen.private = (*createNewScreen)(pScreen->myNum, &screen->driScreen, @@ -1085,7 +1025,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) fd, api_ver, &interface_methods, - &driver_modes); + &screen->base.fbconfigs); if (screen->driScreen.private == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); @@ -1110,10 +1050,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) screen->base.GLXextensions); } - - filter_modes(&screen->base.modes, driver_modes); - _gl_context_modes_destroy(driver_modes); - __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer); screen->enterVT = pScrn->EnterVT; diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c index 55463c7cf..60dc090ac 100644 --- a/GL/glx/glxext.c +++ b/GL/glx/glxext.c @@ -392,7 +392,7 @@ void glxSuspendClients(void) int i; for (i = 1; i < currentMaxClients; i++) { - if (glxGetClient(clients[i])->inUse) + if (clients[i] && glxGetClient(clients[i])->inUse) IgnoreClient(clients[i]); } @@ -407,7 +407,7 @@ void glxResumeClients(void) glxBlockClients = FALSE; for (i = 1; i < currentMaxClients; i++) { - if (glxGetClient(clients[i])->inUse) + if (clients[i] && glxGetClient(clients[i])->inUse) AttendClient(clients[i]); } diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index fd4e57d59..6aa4e7f5c 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -70,7 +70,7 @@ struct __GLXMESAdrawable { XMesaBuffer xm_buf; }; -static XMesaVisual find_mesa_visual(__GLXscreen *screen, VisualID vid); +static XMesaVisual find_mesa_visual(__GLXscreen *screen, XID fbconfigID); static void @@ -141,7 +141,7 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen, glxPriv->base.resize = __glXMesaDrawableResize; glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers; - xm_vis = find_mesa_visual(screen, modes->visualID); + xm_vis = find_mesa_visual(screen, modes->fbconfigID); if (xm_vis == NULL) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", modes->visualID); @@ -155,6 +155,11 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen, glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0); } + if (glxPriv->xm_buf == NULL) { + xfree(glxPriv); + return NULL; + } + return &glxPriv->base; } @@ -235,7 +240,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen, context->base.copy = __glXMesaContextCopy; context->base.forceCurrent = __glXMesaContextForceCurrent; - xm_vis = find_mesa_visual(screen, modes->visualID); + xm_vis = find_mesa_visual(screen, modes->fbconfigID); if (!xm_vis) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", modes->visualID); @@ -274,107 +279,122 @@ __glXMesaScreenDestroy(__GLXscreen *screen) } static XMesaVisual -find_mesa_visual(__GLXscreen *screen, VisualID vid) +find_mesa_visual(__GLXscreen *screen, XID fbconfigID) { __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen; const __GLcontextModes *modes; unsigned i = 0; - for ( modes = screen->modes ; modes != NULL ; modes = modes->next ) { - if ( modes->visualID == vid ) { - break; - } - + for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) { + if (modes->fbconfigID == fbconfigID) + return mesaScreen->xm_vis[i]; i++; } - return (modes != NULL) ? mesaScreen->xm_vis[i] : NULL; + return NULL; } -static void init_screen_visuals(__GLXMESAscreen *screen) +const static int numBack = 2; +const static int numDepth = 2; +const static int numStencil = 2; + +static __GLcontextModes * +createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, + VisualPtr visual, __GLcontextModes *config) { - ScreenPtr pScreen = screen->base.pScreen; - __GLcontextModes *modes; - XMesaVisual *pXMesaVisual; - int *used; - int num_vis, j, size; - - /* Alloc space for the list of XMesa visuals */ - size = screen->base.numVisuals * sizeof(XMesaVisual); - pXMesaVisual = (XMesaVisual *) xalloc(size); - memset(pXMesaVisual, 0, size); - - /* FIXME: Change 'used' to be a array of bits (rather than of ints), - * FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less - * FIXME: than 64 or 128 the stack array can be used instead of calling - * FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to - * FIXME: array of bytes instead of ints! - */ - used = (int *) xalloc(pScreen->numVisuals * sizeof(int)); - memset(used, 0, pScreen->numVisuals * sizeof(int)); - - num_vis = 0; - for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) { - const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); - const int nplanes = (modes->rgbBits - modes->alphaBits); - const VisualPtr pVis = pScreen->visuals; - - for (j = 0; j < pScreen->numVisuals; j++) { - if (pVis[j].class == vis_class && - pVis[j].nplanes == nplanes && - pVis[j].redMask == modes->redMask && - pVis[j].greenMask == modes->greenMask && - pVis[j].blueMask == modes->blueMask && - !used[j]) { - - /* Create the XMesa visual */ - assert(num_vis < screen->base.numVisuals); - pXMesaVisual[num_vis] = - XMesaCreateVisual(pScreen, - &pVis[j], - modes->rgbMode, - (modes->alphaBits > 0), - modes->doubleBufferMode, - modes->stereoMode, - GL_TRUE, /* ximage_flag */ - modes->depthBits, - modes->stencilBits, - modes->accumRedBits, - modes->accumGreenBits, - modes->accumBlueBits, - modes->accumAlphaBits, - modes->samples, - modes->level, - modes->visualRating); - /* Set the VisualID */ - modes->visualID = pVis[j].vid; - - /* Mark this visual used */ - used[j] = 1; - break; + int back, depth, stencil; + + /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ + + for (back = numBack - 1; back >= 0; back--) + for (depth = 0; depth < numDepth; depth++) + for (stencil = 0; stencil < numStencil; stencil++) { + config->visualType = _gl_convert_from_x_visual_type(visual->class); + config->xRenderable = GL_TRUE; + config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; + config->rgbMode = (visual->class >= TrueColor); + config->colorIndexMode = !config->rgbMode; + config->renderType = + (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + config->doubleBufferMode = back; + config->haveDepthBuffer = depth; + config->depthBits = depth ? visual->nplanes : 0; + config->haveStencilBuffer = stencil; + config->stencilBits = stencil ? visual->bitsPerRGBValue : 0; + config->haveAccumBuffer = 0; + + config->redBits = Ones(visual->redMask); + config->greenBits = Ones(visual->greenMask); + config->blueBits = Ones(visual->blueMask); + config->alphaBits = 0; + config->redMask = visual->redMask; + config->greenMask = visual->greenMask; + config->blueMask = visual->blueMask; + config->alphaMask = 0; + config->rgbBits = config->rgbMode ? visual->nplanes : 0; + config->indexBits = config->colorIndexMode ? visual->nplanes : 0; + config = config->next; } - } - if ( j == pScreen->numVisuals ) { - ErrorF("No matching visual for __GLcontextMode with " - "visual class = %d (%d), nplanes = %u\n", - vis_class, - modes->visualType, - (modes->rgbBits - modes->alphaBits) ); - } - else if ( modes->visualID == -1 ) { - FatalError( "Matching visual found, but visualID still -1!\n" ); - } + return config; +} - num_vis++; - } +static void +createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen) +{ + __GLcontextModes *configs; + int i; - xfree(used); + /* We assume here that each existing visual correspond to a + * different visual class. Note, this runs before COMPOSITE adds + * its visual, so it's not entirely crazy. */ + pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil; + pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs, + sizeof *configs); + + configs = pGlxScreen->fbconfigs; + for (i = 0; i < pScreen->numVisuals; i++) + configs = createFBConfigsForVisual(pGlxScreen, pScreen, + &pScreen->visuals[i], configs); +} - screen->num_vis = num_vis; - screen->xm_vis = pXMesaVisual; +static void +createMesaVisuals(__GLXMESAscreen *pMesaScreen) +{ + __GLcontextModes *config; + ScreenPtr pScreen; + VisualPtr visual; + int i, j; + + i = 0; + pScreen = pMesaScreen->base.pScreen; + pMesaScreen->xm_vis = + xcalloc(pMesaScreen->base.numFBConfigs, sizeof (XMesaVisual)); + for (config = pMesaScreen->base.fbconfigs; config != NULL; config = config->next) { + for (j = 0; j < pScreen->numVisuals; j++) + if (pScreen->visuals[j].vid == config->visualID) { + visual = &pScreen->visuals[j]; + break; + } - assert(screen->num_vis <= screen->base.numVisuals); + pMesaScreen->xm_vis[i++] = + XMesaCreateVisual(pScreen, + visual, + config->rgbMode, + (config->alphaBits > 0), + config->doubleBufferMode, + config->stereoMode, + GL_TRUE, /* ximage_flag */ + config->depthBits, + config->stencilBits, + config->accumRedBits, + config->accumGreenBits, + config->accumBlueBits, + config->accumAlphaBits, + config->samples, + config->level, + config->visualRating); + } } static __GLXscreen * @@ -386,19 +406,22 @@ __glXMesaScreenProbe(ScreenPtr pScreen) if (screen == NULL) return NULL; + /* + * Find the GLX visuals that are supported by this screen and create + * XMesa's visuals. + */ + createFBConfigs(&screen->base, pScreen); + __glXScreenInit(&screen->base, pScreen); + /* Now that GLX has created the corresponding X visual, create the mesa visuals. */ + createMesaVisuals(screen); + screen->base.destroy = __glXMesaScreenDestroy; screen->base.createContext = __glXMesaScreenCreateContext; screen->base.createDrawable = __glXMesaScreenCreateDrawable; screen->base.pScreen = pScreen; - /* - * Find the GLX visuals that are supported by this screen and create - * XMesa's visuals. - */ - init_screen_visuals(screen); - return &screen->base; } diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 6e4d497f5..2dc9d2f10 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -40,11 +40,13 @@ #include <string.h> #include <windowstr.h> #include <os.h> +#include <colormapst.h> #include "privates.h" #include "glxserver.h" #include "glxutil.h" #include "glxext.h" +#include "glcontextmodes.h" static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKey; @@ -282,23 +284,252 @@ glxGetScreen(ScreenPtr pScreen) return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey); } -void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) +void GlxSetVisualConfigs(int nconfigs, + __GLXvisualConfig *configs, void **privates) { - glxScreen->pScreen = pScreen; - glxScreen->GLextensions = xstrdup(GLServerExtensions); - glxScreen->GLXvendor = xstrdup(GLXServerVendorName); - glxScreen->GLXversion = xstrdup(GLXServerVersion); - glxScreen->GLXextensions = xstrdup(GLXServerExtensions); + /* We keep this stub around for the DDX drivers that still + * call it. */ +} + +static XID +findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m) +{ + int i; + + for (i = 0; i < pScreen->numVisuals; i++) { + if (_gl_convert_to_x_visual_type(m->visualType) == pScreen->visuals[i].class) + return pScreen->visuals[i].vid; + } + + return 0; +} + +/* This code inspired by composite/compinit.c. We could move this to + * mi/ and share it with composite.*/ + +static VisualPtr +AddScreenVisuals(ScreenPtr pScreen, int count, int d) +{ + XID *installedCmaps, *vids, vid; + int numInstalledCmaps, numVisuals, i, j; + VisualPtr visuals; + ColormapPtr installedCmap; + DepthPtr depth; + + depth = NULL; + for (i = 0; i < pScreen->numDepths; i++) { + if (pScreen->allowedDepths[i].depth == d) { + depth = &pScreen->allowedDepths[i]; + break; + } + } + if (depth == NULL) + return NULL; + + /* Find the installed colormaps */ + installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID)); + if (!installedCmaps) + return NULL; + + numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen, installedCmaps); + + /* realloc the visual array to fit the new one in place */ + numVisuals = pScreen->numVisuals; + visuals = xrealloc(pScreen->visuals, (numVisuals + count) * sizeof(VisualRec)); + if (!visuals) { + xfree(installedCmaps); + return NULL; + } + + vids = xrealloc(depth->vids, (depth->numVids + count) * sizeof(XID)); + if (vids == NULL) { + xfree(installedCmaps); + xfree(visuals); + return NULL; + } - glxScreen->PositionWindow = pScreen->PositionWindow; + /* + * Fix up any existing installed colormaps -- we'll assume that + * the only ones created so far have been installed. If this + * isn't true, we'll have to walk the resource database looking + * for all colormaps. + */ + for (i = 0; i < numInstalledCmaps; i++) { + installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP); + if (!installedCmap) + continue; + j = installedCmap->pVisual - pScreen->visuals; + installedCmap->pVisual = &visuals[j]; + } + + xfree(installedCmaps); + + for (i = 0; i < count; i++) { + vid = FakeClientID(0); + visuals[pScreen->numVisuals + i].vid = vid; + vids[depth->numVids + i] = vid; + } + + pScreen->visuals = visuals; + pScreen->numVisuals += count; + depth->vids = vids; + depth->numVids += count; + + /* Return a pointer to the first of the added visuals. */ + return pScreen->visuals + pScreen->numVisuals - count; +} + +static int +findFirstSet(unsigned int v) +{ + int i; + + for (i = 0; i < 32; i++) + if (v & (1 << i)) + return i; + + return -1; +} + +static void +initGlxVisual(VisualPtr visual, __GLcontextModes *config) +{ + config->visualID = visual->vid; + visual->class = _gl_convert_to_x_visual_type(config->visualType); + visual->bitsPerRGBValue = config->redBits; + visual->ColormapEntries = 1 << config->redBits; + visual->nplanes = config->redBits + config->greenBits + config->blueBits; + + visual->redMask = config->redMask; + visual->greenMask = config->greenMask; + visual->blueMask = config->blueMask; + visual->offsetRed = findFirstSet(config->redMask); + visual->offsetGreen = findFirstSet(config->greenMask); + visual->offsetBlue = findFirstSet(config->blueMask); +} + +static void +addMinimalSet(__GLXscreen *pGlxScreen) +{ + __GLcontextModes *config; + VisualPtr visuals; + int depth; + + for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { + if (config->visualRating != GLX_NONE) + continue; + if (config->doubleBufferMode && config->depthBits > 0) + break; + } + if (config == NULL) + config = pGlxScreen->fbconfigs; + + pGlxScreen->visuals = xcalloc(1, sizeof (__GLcontextModes *)); + if (pGlxScreen->visuals == NULL) { + ErrorF("Failed to allocate for minimal set of GLX visuals\n"); + return; + } + + depth = config->redBits + config->greenBits + config->blueBits; + visuals = AddScreenVisuals(pGlxScreen->pScreen, 1, depth); + if (visuals == NULL) { + xfree(pGlxScreen->visuals); + return; + } + + pGlxScreen->numVisuals = 1; + pGlxScreen->visuals[0] = config; + initGlxVisual(&visuals[0], config); +} + +static void +addTypicalSet(__GLXscreen *pGlxScreen) +{ + addMinimalSet(pGlxScreen); +} + +static void +addFullSet(__GLXscreen *pGlxScreen) +{ + __GLcontextModes *config; + VisualPtr visuals; + int i, depth; + + pGlxScreen->visuals = + xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLcontextModes *)); + if (pGlxScreen->visuals == NULL) { + ErrorF("Failed to allocate for full set of GLX visuals\n"); + return; + } + + config = pGlxScreen->fbconfigs; + depth = config->redBits + config->greenBits + config->blueBits; + visuals = AddScreenVisuals(pGlxScreen->pScreen, pGlxScreen->numFBConfigs, depth); + if (visuals == NULL) { + xfree(pGlxScreen->visuals); + return; + } + + pGlxScreen->numVisuals = pGlxScreen->numFBConfigs; + for (i = 0, config = pGlxScreen->fbconfigs; config; config = config->next, i++) { + pGlxScreen->visuals[i] = config; + initGlxVisual(&visuals[i], config); + } +} + +static int glxVisualConfig = GLX_ALL_VISUALS; + +void GlxSetVisualConfig(int config) +{ + glxVisualConfig = config; +} + +void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) +{ + __GLcontextModes *m; + int i; + + pGlxScreen->pScreen = pScreen; + pGlxScreen->GLextensions = xstrdup(GLServerExtensions); + pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); + pGlxScreen->GLXversion = xstrdup(GLXServerVersion); + pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); + + pGlxScreen->PositionWindow = pScreen->PositionWindow; pScreen->PositionWindow = glxPositionWindow; - glxScreen->CloseScreen = pScreen->CloseScreen; + pGlxScreen->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = glxCloseScreen; - __glXScreenInitVisuals(glxScreen); + i = 0; + for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { + m->fbconfigID = FakeClientID(0); + m->visualID = findVisualForConfig(pScreen, m); + ErrorF("mapping fbconfig id 0x%02lx to visual id 0x%02lx\n", + m->fbconfigID, m->visualID); + i++; + } + pGlxScreen->numFBConfigs = i; + + /* Select a subset of fbconfigs that we send to the client when it + * asks for the glx visuals. All the fbconfigs here have a valid + * value for visual ID and each visual ID is only present once. + * This runs before composite adds its extra visual so we have to + * remember the number of visuals here.*/ + + switch (glxVisualConfig) { + case GLX_MINIMAL_VISUALS: + addMinimalSet(pGlxScreen); + break; + case GLX_TYPICAL_VISUALS: + addTypicalSet(pGlxScreen); + break; + case GLX_ALL_VISUALS: + addFullSet(pGlxScreen); + break; + } - dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, glxScreen); + dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen); } void __glXScreenDestroy(__GLXscreen *screen) diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h index 7b1bbcd58..f1eef912c 100644 --- a/GL/glx/glxscreens.h +++ b/GL/glx/glxscreens.h @@ -83,14 +83,13 @@ struct __GLXscreen { ScreenPtr pScreen; - /** - * Linked list of valid context modes for this screen. - */ - __GLcontextModes *modes; + /* Linked list of valid fbconfigs for this screen. */ + __GLcontextModes *fbconfigs; + int numFBConfigs; - void **pVisualPriv; + /* Subset of fbconfigs that are exposed as GLX visuals. */ + __GLcontextModes **visuals; GLint numVisuals; - GLint numUsableVisuals; char *GLextensions; diff --git a/GL/glx/glxserver.h b/GL/glx/glxserver.h index 45de8e794..518868981 100644 --- a/GL/glx/glxserver.h +++ b/GL/glx/glxserver.h @@ -95,6 +95,8 @@ extern __GLXclientState *glxGetClient(ClientPtr pClient); /************************************************************************/ +void GlxExtensionInit(void); + void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **privates); @@ -132,6 +134,14 @@ struct __GLXprovider { void GlxPushProvider(__GLXprovider *provider); +enum { + GLX_MINIMAL_VISUALS, + GLX_TYPICAL_VISUALS, + GLX_ALL_VISUALS +}; + +void GlxSetVisualConfig(int config); + void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean), void (*leave)(GLboolean)); void __glXenterServer(GLboolean rendering); diff --git a/GL/glx/glxvisuals.c b/GL/glx/glxvisuals.c deleted file mode 100644 index 46b380b3d..000000000 --- a/GL/glx/glxvisuals.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright © 2006 Red Hat, Inc. - * (C) Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * RED HAT, INC, OR PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Brian Paul <brian@precisioninsight.com> - * Kristian Høgsberg <krh@redhat.com> - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <assert.h> -#include <string.h> -#include <regionstr.h> -#include <resource.h> -#include <GL/gl.h> -#include <GL/glxint.h> -#include <GL/glxtokens.h> -#include <GL/internal/glcore.h> -#include <scrnintstr.h> -#include <config.h> -#include <glxserver.h> -#include <glxscreens.h> -#include <glxdrawable.h> -#include <glxcontext.h> -#include <glxext.h> -#include <glxutil.h> -#include <micmap.h> - -void GlxWrapInitVisuals(miInitVisualsProcPtr *); - -extern Bool noGlxVisualInit; -#include "glcontextmodes.h" - -struct ScreenVisualsRec { - int num_vis; - void *private; - __GLcontextModes *modes; -}; -typedef struct ScreenVisualsRec ScreenVisuals; - -static ScreenVisuals screenVisuals[MAXSCREENS]; - -static int numConfigs = 0; -static __GLXvisualConfig *visualConfigs = NULL; -static void **visualPrivates = NULL; - -static int count_bits(unsigned int n) -{ - int bits = 0; - - while (n > 0) { - if (n & 1) bits++; - n >>= 1; - } - return bits; -} - -/* - * In the case the driver defines no GLX visuals we'll use these. - * Note that for TrueColor and DirectColor visuals, bufferSize is the - * sum of redSize, greenSize, blueSize and alphaSize, which may be larger - * than the nplanes/rootDepth of the server's X11 visuals - */ -#define NUM_FALLBACK_CONFIGS 5 -static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = { - /* [0] = RGB, double buffered, Z */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 0, /* rgba sizes */ - -1, -1, -1, 0, /* rgba masks */ - 0, 0, 0, 0, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 0, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [1] = RGB, double buffered, Z, stencil, accum */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 0, /* rgba sizes */ - -1, -1, -1, 0, /* rgba masks */ - 16, 16, 16, 0, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 8, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [2] = RGB+Alpha, double buffered, Z, stencil, accum */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 8, /* rgba sizes */ - -1, -1, -1, -1, /* rgba masks */ - 16, 16, 16, 16, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 8, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [3] = RGB+Alpha, single buffered, Z, stencil, accum */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 8, /* rgba sizes */ - -1, -1, -1, -1, /* rgba masks */ - 16, 16, 16, 16, /* rgba accum sizes */ - False, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 8, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [4] = CI, double buffered, Z */ - { - -1, /* vid */ - -1, /* class */ - False, /* rgba? (false = color index) */ - -1, -1, -1, 0, /* rgba sizes */ - -1, -1, -1, 0, /* rgba masks */ - 0, 0, 0, 0, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 0, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, -}; - - -static Bool init_visuals(int *nvisualp, VisualPtr *visualp, - VisualID *defaultVisp, - int ndepth, DepthPtr pdepth, - int rootDepth) -{ - int numRGBconfigs; - int numCIconfigs; - int numVisuals = *nvisualp; - int numNewVisuals; - int numNewConfigs; - VisualPtr pVisual = *visualp; - VisualPtr pVisualNew = NULL; - VisualID *orig_vid = NULL; - __GLcontextModes *modes; - __GLXvisualConfig *pNewVisualConfigs = NULL; - void **glXVisualPriv; - void **pNewVisualPriv; - int found_default; - int i, j, k; - - if (numConfigs > 0) - numNewConfigs = numConfigs; - else - numNewConfigs = NUM_FALLBACK_CONFIGS; - - /* Alloc space for the list of new GLX visuals */ - pNewVisualConfigs = (__GLXvisualConfig *) - xalloc(numNewConfigs * sizeof(__GLXvisualConfig)); - if (!pNewVisualConfigs) { - return FALSE; - } - - /* Alloc space for the list of new GLX visual privates */ - pNewVisualPriv = (void **) xalloc(numNewConfigs * sizeof(void *)); - if (!pNewVisualPriv) { - xfree(pNewVisualConfigs); - return FALSE; - } - - /* - ** If SetVisualConfigs was not called, then use default GLX - ** visual configs. - */ - if (numConfigs == 0) { - memcpy(pNewVisualConfigs, FallbackConfigs, - NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig)); - memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *)); - } - else { - /* copy driver's visual config info */ - for (i = 0; i < numConfigs; i++) { - pNewVisualConfigs[i] = visualConfigs[i]; - pNewVisualPriv[i] = visualPrivates[i]; - } - } - - /* Count the number of RGB and CI visual configs */ - numRGBconfigs = 0; - numCIconfigs = 0; - for (i = 0; i < numNewConfigs; i++) { - if (pNewVisualConfigs[i].rgba) - numRGBconfigs++; - else - numCIconfigs++; - } - - /* Count the total number of visuals to compute */ - numNewVisuals = 0; - for (i = 0; i < numVisuals; i++) { - numNewVisuals += - (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor) - ? numRGBconfigs : numCIconfigs; - } - - /* Reset variables for use with the next screen/driver's visual configs */ - visualConfigs = NULL; - numConfigs = 0; - - /* Alloc temp space for the list of orig VisualIDs for each new visual */ - orig_vid = (VisualID *) xalloc(numNewVisuals * sizeof(VisualID)); - if (!orig_vid) { - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Alloc space for the list of glXVisuals */ - modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes)); - if (modes == NULL) { - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Alloc space for the list of glXVisualPrivates */ - glXVisualPriv = (void **)xalloc(numNewVisuals * sizeof(void *)); - if (!glXVisualPriv) { - _gl_context_modes_destroy( modes ); - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Alloc space for the new list of the X server's visuals */ - pVisualNew = (VisualPtr)xalloc(numNewVisuals * sizeof(VisualRec)); - if (!pVisualNew) { - xfree(glXVisualPriv); - _gl_context_modes_destroy( modes ); - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Initialize the new visuals */ - found_default = FALSE; - screenVisuals[screenInfo.numScreens-1].modes = modes; - for (i = j = 0; i < numVisuals; i++) { - int is_rgb = (pVisual[i].class == TrueColor || - pVisual[i].class == DirectColor); - - for (k = 0; k < numNewConfigs; k++) { - if (pNewVisualConfigs[k].rgba != is_rgb) - continue; - - assert( modes != NULL ); - - /* Initialize the new visual */ - pVisualNew[j] = pVisual[i]; - pVisualNew[j].vid = FakeClientID(0); - - /* Check for the default visual */ - if (!found_default && pVisual[i].vid == *defaultVisp) { - *defaultVisp = pVisualNew[j].vid; - found_default = TRUE; - } - - /* Save the old VisualID */ - orig_vid[j] = pVisual[i].vid; - - /* Initialize the glXVisual */ - _gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] ); - modes->visualID = pVisualNew[j].vid; - if (modes->fbconfigID == GLX_DONT_CARE) - modes->fbconfigID = modes->visualID; - - /* - * If the class is -1, then assume the X visual information - * is identical to what GLX needs, and take them from the X - * visual. NOTE: if class != -1, then all other fields MUST - * be initialized. - */ - if (modes->visualType == GLX_NONE) { - modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class ); - modes->redBits = count_bits(pVisual[i].redMask); - modes->greenBits = count_bits(pVisual[i].greenMask); - modes->blueBits = count_bits(pVisual[i].blueMask); - modes->alphaBits = modes->alphaBits; - modes->redMask = pVisual[i].redMask; - modes->greenMask = pVisual[i].greenMask; - modes->blueMask = pVisual[i].blueMask; - modes->alphaMask = modes->alphaMask; - modes->rgbBits = (is_rgb) - ? (modes->redBits + modes->greenBits + - modes->blueBits + modes->alphaBits) - : rootDepth; - } - - /* Save the device-dependent private for this visual */ - glXVisualPriv[j] = pNewVisualPriv[k]; - - j++; - modes = modes->next; - } - } - - assert(j <= numNewVisuals); - - /* Save the GLX visuals in the screen structure */ - screenVisuals[screenInfo.numScreens-1].num_vis = numNewVisuals; - screenVisuals[screenInfo.numScreens-1].private = glXVisualPriv; - - /* Set up depth's VisualIDs */ - for (i = 0; i < ndepth; i++) { - int numVids = 0; - VisualID *pVids = NULL; - int k, n = 0; - - /* Count the new number of VisualIDs at this depth */ - for (j = 0; j < pdepth[i].numVids; j++) - for (k = 0; k < numNewVisuals; k++) - if (pdepth[i].vids[j] == orig_vid[k]) - numVids++; - - /* Allocate a new list of VisualIDs for this depth */ - pVids = (VisualID *)xalloc(numVids * sizeof(VisualID)); - - /* Initialize the new list of VisualIDs for this depth */ - for (j = 0; j < pdepth[i].numVids; j++) - for (k = 0; k < numNewVisuals; k++) - if (pdepth[i].vids[j] == orig_vid[k]) - pVids[n++] = pVisualNew[k].vid; - - /* Update this depth's list of VisualIDs */ - xfree(pdepth[i].vids); - pdepth[i].vids = pVids; - pdepth[i].numVids = numVids; - } - - /* Update the X server's visuals */ - *nvisualp = numNewVisuals; - *visualp = pVisualNew; - - /* Free the old list of the X server's visuals */ - xfree(pVisual); - - /* Clean up temporary allocations */ - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - - /* Free the private list created by DDX HW driver */ - if (visualPrivates) - xfree(visualPrivates); - visualPrivates = NULL; - - return TRUE; -} - -void GlxSetVisualConfigs(int nconfigs, - __GLXvisualConfig *configs, void **privates) -{ - numConfigs = nconfigs; - visualConfigs = configs; - visualPrivates = privates; -} - -static miInitVisualsProcPtr saveInitVisualsProc; - -Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp, - int *nvisualp, int *ndepthp, - int *rootDepthp, VisualID *defaultVisp, - unsigned long sizes, int bitsPerRGB, - int preferredVis) -{ - Bool ret; - - if (saveInitVisualsProc) { - ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp, - rootDepthp, defaultVisp, sizes, bitsPerRGB, - preferredVis); - if (!ret) - return False; - } - - /* - * Setup the visuals supported by this particular screen. - */ - if (!noGlxVisualInit) { - init_visuals(nvisualp, visualp, defaultVisp, - *ndepthp, *depthp, *rootDepthp); - } - - - return True; -} - -/************************************************************************/ - - -void -GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc) -{ - saveInitVisualsProc = *initVisProc; - *initVisProc = GlxInitVisuals; -} - -static void fixup_visuals(int screen) -{ - ScreenPtr pScreen = screenInfo.screens[screen]; - ScreenVisuals *psv = &screenVisuals[screen]; - int j; - __GLcontextModes *modes; - - for ( modes = psv->modes ; modes != NULL ; modes = modes->next ) { - const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); - const int nplanes = (modes->rgbBits - modes->alphaBits); - const VisualPtr pVis = pScreen->visuals; - - /* Find a visual that matches the GLX visual's class and size */ - for (j = 0; j < pScreen->numVisuals; j++) { - if (pVis[j].class == vis_class && - pVis[j].nplanes == nplanes) { - - /* Fixup the masks */ - modes->redMask = pVis[j].redMask; - modes->greenMask = pVis[j].greenMask; - modes->blueMask = pVis[j].blueMask; - - /* Recalc the sizes */ - modes->redBits = count_bits(modes->redMask); - modes->greenBits = count_bits(modes->greenMask); - modes->blueBits = count_bits(modes->blueMask); - } - } - } -} - -void __glXScreenInitVisuals(__GLXscreen *screen) -{ - int index = screen->pScreen->myNum; - - screen->modes = screenVisuals[index].modes; - screen->pVisualPriv = screenVisuals[index].private; - screen->numVisuals = screenVisuals[index].num_vis; - screen->numUsableVisuals = screenVisuals[index].num_vis; - - /* - * The ordering of the rgb compenents might have been changed by the - * driver after mi initialized them. - */ - fixup_visuals(index); -} diff --git a/configure.ac b/configure.ac index d224185be..417aca1d7 100644 --- a/configure.ac +++ b/configure.ac @@ -464,6 +464,10 @@ APPLE_APPLICATIONS_DIR="${bindir}/Applications" AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: ${bindir}/Applications)]), [ APPLE_APPLICATIONS_DIR="${withval}" ]. [ APPLE_APPLICATIONS_DIR="${bindir}/Applications" ]) +AC_ARG_WITH(pci-txt-ids-dir, AS_HELP_STRING([--with-pci-txt-ids-dir=PATH], +[Path to pci id directory (default: ${datadir}/X11/pci)]), + [ PCI_TXT_IDS_DIR="$withval" ], + [ PCI_TXT_IDS_DIR="${datadir}/X11/pci" ]) AC_ARG_ENABLE(builddocs, AS_HELP_STRING([--enable-builddocs], [Build docs (default: disabled)]), [BUILDDOCS=$enableval], [BUILDDOCS=no]) @@ -1022,6 +1026,7 @@ fi AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path]) AC_DEFINE_DIR(RGB_DB, RGBPATH, [Default RGB path]) +AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path]) AC_DEFINE_DIR(SERVERCONFIGdir, SERVERCONFIG, [Server config path]) AC_DEFINE_DIR(BASE_FONT_PATH, FONTDIR, [Default base font path]) AC_DEFINE_DIR(DRI_DRIVER_PATH, DRI_DRIVER_PATH, [Default DRI driver path]) @@ -1101,7 +1106,7 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) # XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" XSERVER_LIBS="$DIX_LIB $CONFIG_LIB $MI_LIB $OS_LIB" -XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}" +XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS} -lcrypto" AC_SUBST([XSERVER_LIBS]) AC_SUBST([XSERVER_SYS_LIBS]) @@ -1902,7 +1907,7 @@ if test "$KDRIVE" = yes; then KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB" - KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS $XV_LIBS" + KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $XV_LIBS" # check if we can build Xephyr PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) @@ -290,7 +290,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) pExaPixmap->fb_ptr = NULL; } else { pExaPixmap->driverPriv = NULL; - /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */ + /* Scratch pixmaps may have w/h equal to zero, and may not be + * migrated. + */ if (!w || !h) pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; else @@ -695,7 +697,6 @@ exaCloseScreen(int i, ScreenPtr pScreen) #ifdef RENDER if (ps) { ps->Composite = pExaScr->SavedComposite; - ps->Glyphs = pExaScr->SavedGlyphs; ps->Trapezoids = pExaScr->SavedTrapezoids; } #endif @@ -858,9 +859,6 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->SavedTriangles = ps->Triangles; ps->Triangles = exaTriangles; - pExaScr->SavedGlyphs = ps->Glyphs; - ps->Glyphs = exaGlyphs; - pExaScr->SavedTrapezoids = ps->Trapezoids; ps->Trapezoids = exaTrapezoids; } diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 8bbf036e4..5fb72d71b 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -152,6 +152,9 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int bpp = pDrawable->bitsPerPixel; Bool access_prepared = FALSE; + if (pExaPixmap->accel_blocked) + return FALSE; + /* Don't bother with under 8bpp, XYPixmaps. */ if (format != ZPixmap || bpp < 8) return FALSE; @@ -655,7 +658,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, x1 = ppt[0].x; y1 = ppt[0].y; /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < npt; i++) { + for (i = 0; i < npt - 1; i++) { if (mode == CoordModePrevious) { x2 = x1 + ppt[i + 1].x; y2 = y1 + ppt[i + 1].y; diff --git a/exa/exa_migration.c b/exa/exa_migration.c index 7968521c5..d69526b7f 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -299,6 +299,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate) if (pPixmap->drawable.bitsPerPixel < 8) return; + if (pExaPixmap->accel_blocked) + return; + if (pExaPixmap->area == NULL) { pExaPixmap->area = exaOffscreenAlloc (pScreen, pExaPixmap->fb_size, diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 582ddcaa6..6439954d6 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -53,6 +53,7 @@ #include "fboverlay.h" #ifdef RENDER #include "fbpict.h" +#include "glyphstr.h" #endif #include "damage.h" diff --git a/exa/exa_render.c b/exa/exa_render.c index 2ad53041a..6a9e53f3e 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -247,10 +247,24 @@ exaTryDriverSolidFill(PicturePtr pSrc, int nbox; int dst_off_x, dst_off_y; PixmapPtr pSrcPix, pDstPix; + ExaPixmapPrivPtr pSrcExaPix, pDstExaPix; CARD32 pixel; CARD16 red, green, blue, alpha; ExaMigrationRec pixmaps[1]; + pDstPix = exaGetDrawablePixmap (pDst->pDrawable); + pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); + + pSrcExaPix = ExaGetPixmapPriv(pSrcPix); + pDstExaPix = ExaGetPixmapPriv(pDstPix); + + /* Check whether the accelerator can use these pixmaps. + */ + if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked) + { + return -1; + } + xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; @@ -261,12 +275,10 @@ exaTryDriverSolidFill(PicturePtr pSrc, width, height)) return 1; - pDstPix = exaGetDrawablePixmap (pDst->pDrawable); exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); - pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); pixel = exaGetPixmapFirstPixel (pSrcPix); pixmaps[0].as_dst = TRUE; @@ -985,355 +997,3 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); } } - -/** - * Returns TRUE if the glyphs in the lists intersect. Only checks based on - * bounding box, which appears to be good enough to catch most cases at least. - */ -static Bool -exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) -{ - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - BoxRec extents; - Bool first = TRUE; - - x = 0; - y = 0; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) { - glyph = *glyphs++; - - if (glyph->info.width == 0 || glyph->info.height == 0) { - x += glyph->info.xOff; - y += glyph->info.yOff; - continue; - } - - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - - if (first) { - extents.x1 = x1; - extents.y1 = y1; - extents.x2 = x2; - extents.y2 = y2; - first = FALSE; - } else { - if (x1 < extents.x2 && x2 > extents.x1 && - y1 < extents.y2 && y2 > extents.y1) - { - return TRUE; - } - - if (x1 < extents.x1) - extents.x1 = x1; - if (x2 > extents.x2) - extents.x2 = x2; - if (y1 < extents.y1) - extents.y1 = y1; - if (y2 > extents.y2) - extents.y2 = y2; - } - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } - - return FALSE; -} - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The - * issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to - * migrate these pixmaps. So, instead we create a pixmap at the beginning of - * the loop and upload each glyph into the pixmap before compositing. - * - * This is now used even when Composite can't be accelerated for better - * migration control. - */ -void -exaGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - ExaScreenPriv (pDst->pDrawable->pScreen); - PixmapPtr pPixmap = NULL; - PicturePtr pPicture; - PixmapPtr pMaskPixmap = NULL; - PicturePtr pMask; - ScreenPtr pScreen = pDst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y, x1, y1; - int xDst = list->xOff, yDst = list->yOff; - int n; - int error; - BoxRec extents; - CARD32 component_alpha; - - /* If we have a mask format but it's the same as all the glyphs and - * the glyphs don't intersect, we can avoid accumulating the glyphs in the - * temporary picture. - */ - if (maskFormat != NULL) { - Bool sameFormat = TRUE; - int i; - - for (i = 0; i < nlist; i++) { - if (maskFormat->format != list[i].format->format) { - sameFormat = FALSE; - break; - } - } - if (sameFormat) { - if (!exaGlyphsIntersect(nlist, list, glyphs)) { - maskFormat = NULL; - } - } - } - - if (maskFormat) - { - GCPtr pGC; - xRectangle rect; - - miGlyphExtents (nlist, list, glyphs, &extents); - - extents.x1 = max(extents.x1, 0); - extents.y1 = max(extents.y1, 0); - extents.x2 = min(extents.x2, pDst->pDrawable->width); - extents.y2 = min(extents.y2, pDst->pDrawable->height); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, - maskFormat->depth); - if (!pMaskPixmap) - return; - component_alpha = NeedsComponent(maskFormat->format); - pMask = CreatePicture (0, &pMaskPixmap->drawable, - maskFormat, CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pMaskPixmap); - return; - } - ValidatePicture(pMask); - pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); - ValidateGC (&pMaskPixmap->drawable, pGC); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect); - if (pExaScr->info->PrepareComposite) - (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); - else - exaPixmapDirty(pMaskPixmap, 0, 0, width, height); - FreeScratchGC (pGC); - x = -extents.x1; - y = -extents.y1; - } - else - { - pMask = pDst; - x = 0; - y = 0; - } - - while (nlist--) - { - GCPtr pGC = NULL; - int maxwidth = 0, maxheight = 0, i; - ExaMigrationRec pixmaps[1]; - PixmapPtr pScratchPixmap = NULL; - - x += list->xOff; - y += list->yOff; - n = list->len; - for (i = 0; i < n; i++) { - if (glyphs[i]->info.width > maxwidth) - maxwidth = glyphs[i]->info.width; - if (glyphs[i]->info.height > maxheight) - maxheight = glyphs[i]->info.height; - } - if (maxwidth == 0 || maxheight == 0) { - while (n--) - { - GlyphPtr glyph; - - glyph = *glyphs++; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - continue; - } - - /* Create the (real) temporary pixmap to store the current glyph in */ - pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight, - list->format->depth); - if (!pPixmap) - return; - - /* Create a temporary picture to wrap the temporary pixmap, so it can be - * used as a source for Composite. - */ - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) { - (*pScreen->DestroyPixmap) (pPixmap); - return; - } - ValidatePicture(pPicture); - - /* Give the temporary pixmap an initial kick towards the screen, so - * it'll stick there. - */ - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = NULL; - exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL); - - while (n--) - { - GlyphPtr glyph = *glyphs++; - pointer glyphdata = (pointer) (glyph + 1); - DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable; - - x1 = x - glyph->info.x; - y1 = y - glyph->info.y; - - if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height || - (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) - goto nextglyph; - - (*pScreen->ModifyPixmapHeader) (pScratchPixmap, - glyph->info.width, - glyph->info.height, - 0, 0, -1, glyphdata); - - /* Copy the glyph data into the proper pixmap instead of a fake. - * First we try to use UploadToScreen, if we can, then we fall back - * to a plain exaCopyArea in case of failure. - */ - if (pExaScr->info->UploadToScreen && - exaPixmapIsOffscreen(pPixmap) && - (*pExaScr->info->UploadToScreen) (pPixmap, 0, 0, - glyph->info.width, - glyph->info.height, - glyphdata, - PixmapBytePad(glyph->info.width, - list->format->depth))) - { - exaMarkSync (pScreen); - } else { - /* Set up the scratch pixmap/GC for doing a CopyArea. */ - if (pScratchPixmap == NULL) { - /* Get a scratch pixmap to wrap the original glyph data */ - pScratchPixmap = GetScratchPixmapHeader (pScreen, - glyph->info.width, - glyph->info.height, - list->format->depth, - list->format->depth, - -1, glyphdata); - if (!pScratchPixmap) { - FreePicture(pPicture, 0); - (*pScreen->DestroyPixmap) (pPixmap); - return; - } - - /* Get a scratch GC with which to copy the glyph data from - * scratch to temporary - */ - pGC = GetScratchGC (list->format->depth, pScreen); - ValidateGC (&pPixmap->drawable, pGC); - } else { - (*pScreen->ModifyPixmapHeader) (pScratchPixmap, - glyph->info.width, - glyph->info.height, - 0, 0, -1, glyphdata); - pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - } - -#ifdef MITSHM - if (pExaScr->info->PrepareComposite) - exaShmPutImage(&pPixmap->drawable, pGC, - pPixmap->drawable.depth, ZPixmap, - glyph->info.width, glyph->info.height, 0, 0, - glyph->info.width, glyph->info.height, 0, 0, - glyphdata); - else -#endif - exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC, - 0, 0, glyph->info.width, glyph->info.height, 0, 0); - } - - exaPixmapDirty (pPixmap, 0, 0, - glyph->info.width, glyph->info.height); - - if (maskFormat) - { - exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0, - x1, y1, glyph->info.width, glyph->info.height); - exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width, - y1 + glyph->info.height); - } - else - { - exaComposite (op, pSrc, pPicture, pDst, - xSrc + x1 - xDst, ySrc + y1 - yDst, - 0, 0, x1, y1, glyph->info.width, - glyph->info.height); - } -nextglyph: - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - if (pGC != NULL) - FreeScratchGC (pGC); - FreePicture ((pointer) pPicture, 0); - (*pScreen->DestroyPixmap) (pPixmap); - if (pScratchPixmap != NULL) - FreeScratchPixmapHeader (pScratchPixmap); - } - if (maskFormat) - { - x = extents.x1; - y = extents.y1; - exaComposite (op, pSrc, pMask, pDst, xSrc + x - xDst, ySrc + y - yDst, - 0, 0, x, y, width, height); - FreePicture ((pointer) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } -} diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index a6bfc0190..c5998bfb8 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -329,6 +329,11 @@ autoConfigDevice(GDevPtr preconf_device) return ptr; } +#ifdef __linux__ +/* This function is used to provide a workaround for binary drivers that + * don't export their PCI ID's properly. If distros don't end up using this + * feature it can and should be removed because the symbol-based resolution + * scheme should be the primary one */ static void matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip) { @@ -341,9 +346,10 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip char path_name[256], vendor_str[5], chip_str[5]; uint16_t vendor, chip; int i, j; - idsdir = opendir("/usr/share/xserver-xorg/pci"); + idsdir = opendir(PCI_TXT_IDS_PATH); if (idsdir) { + xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH); direntry = readdir(idsdir); /* Read the directory */ while (direntry) { @@ -355,15 +361,20 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip /* A tiny bit of sanity checking. We should probably do better */ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { /* We need the full path name to open the file */ - strncpy(path_name, "/usr/share/xserver-xorg/pci/", 256); - strncat(path_name, direntry->d_name, (256 - strlen(path_name))); + strncpy(path_name, PCI_TXT_IDS_PATH, 256); + strncat(path_name, "/", 1); + strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1)); fp = fopen(path_name, "r"); if (fp == NULL) { xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name); goto end; } /* Read the file */ + #ifdef __GLIBC__ while ((read = getline(&line, &len, fp)) != -1) { + #else + while ((line = fgetln(fp, &len)) != (char *)NULL) { + #endif /* __GLIBC __ */ xchomp(line); if (isdigit(line[0])) { strncpy(vendor_str, line, 4); @@ -405,8 +416,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip matches[i][j] = direntry->d_name[j]; } } - xf86Msg(X_INFO, "Matched %s from file name %s in autoconfig\n", matches[i], direntry->d_name); - + xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name); } } else { /* TODO Handle driver overrides here */ @@ -421,6 +431,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip xfree(line); closedir(idsdir); } +#endif /* __linux__ */ char* chooseVideoDriver(void) @@ -448,24 +459,27 @@ chooseVideoDriver(void) ErrorF("Primary device is not PCI\n"); } +#ifdef __linux__ matchDriverFromFiles(matches, info->vendor_id, info->device_id); +#endif /* __linux__ */ /* TODO Handle multiple drivers claiming to support the same PCI ID */ if (matches[0]) { chosen_driver = matches[0]; } else { - chosen_driver = videoPtrToDriverName(info); - #if 0 /* Save for later */ - #if defined __i386__ || defined __amd64__ || defined __hurd__ - chosen_driver = "vesa"; - #elif defined __alpha__ - chosen_driver = "vga"; - #elif defined __sparc__ - chosen_driver = "sunffb"; - #else - chosen_driver = "fbdev"; - #endif - #endif + if (info != NULL) + chosen_driver = videoPtrToDriverName(info); + if (chosen_driver == NULL) { +#if defined __i386__ || defined __amd64__ || defined __hurd__ + chosen_driver = "vesa"; +#elif defined __alpha__ + chosen_driver = "vga"; +#elif defined __sparc__ + chosen_driver = "sunffb"; +#else + chosen_driver = "fbdev"; +#endif + } } xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver); diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 96fadc9dd..35b62a244 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -792,6 +792,7 @@ typedef enum { FLAG_USE_DEFAULT_FONT_PATH, FLAG_AUTO_ADD_DEVICES, FLAG_AUTO_ENABLE_DEVICES, + FLAG_GLX_VISUALS, } FlagValues; static OptionInfoRec FlagOptions[] = { @@ -873,6 +874,8 @@ static OptionInfoRec FlagOptions[] = { {0}, TRUE }, { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN, {0}, TRUE }, + { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING, + {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE }, }; @@ -904,6 +907,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) Pix24Flags pix24 = Pix24DontCare; Bool value; MessageType from; + const char *s; /* * Merge the ServerLayout and ServerFlags options. The former have @@ -1021,7 +1025,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value)) xf86Info.pmFlag = !value; { - const char *s; if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) { if (!xf86NameCmp(s,"flush")) { xf86Msg(X_CONFIG, "Flushing logfile enabled\n"); @@ -1040,8 +1043,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) #ifdef RENDER { - const char *s; - if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){ int policy = PictureParseCmapPolicy (s); if (policy == PictureCmapPolicyInvalid) @@ -1055,7 +1056,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) } #endif { - const char *s; if ((s = xf86GetOptValString(FlagOptions, FLAG_HANDLE_SPECIAL_KEYS))) { if (!xf86NameCmp(s,"always")) { xf86Msg(X_CONFIG, "Always handling special keys in DDX\n"); @@ -1093,6 +1093,27 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) xf86Info.aiglxFrom = X_CONFIG; } +#ifdef GLXEXT + xf86Info.glxVisuals = XF86_GlxVisualsAll; + xf86Info.glxVisualsFrom = X_DEFAULT; + if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) { + if (!xf86NameCmp(s, "minimal")) { + xf86Info.glxVisuals = XF86_GlxVisualsMinimal; + } else if (!xf86NameCmp(s, "typical")) { + xf86Info.glxVisuals = XF86_GlxVisualsTypical; + } else if (!xf86NameCmp(s, "all")) { + xf86Info.glxVisuals = XF86_GlxVisualsAll; + } else { + xf86Msg(X_WARNING,"Unknown HandleSpecialKeys option\n"); + } + } + + if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) { + xf86Info.aiglx = value; + xf86Info.aiglxFrom = X_CONFIG; + } +#endif + xf86Info.allowEmptyInput = FALSE; if (xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &value)) xf86Info.allowEmptyInput = TRUE; diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h index 75d497471..92a6305a0 100644 --- a/hw/xfree86/common/xf86Privstr.h +++ b/hw/xfree86/common/xf86Privstr.h @@ -60,6 +60,12 @@ typedef enum { SKAlways } SpecialKeysInDDX; +typedef enum { + XF86_GlxVisualsMinimal, + XF86_GlxVisualsTypical, + XF86_GlxVisualsAll, +} XF86_GlxVisuals; + /* * xf86InfoRec contains global parameters which the video drivers never * need to access. Global parameters which the video drivers do need @@ -120,6 +126,9 @@ typedef struct { MessageType randRFrom; Bool aiglx; MessageType aiglxFrom; + XF86_GlxVisuals glxVisuals; + MessageType glxVisualsFrom; + Bool useDefaultFontPath; MessageType useDefaultFontPathFrom; Bool ignoreABI; diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c index 5384f434b..847f0d4a2 100644 --- a/hw/xfree86/dixmods/glxmodule.c +++ b/hw/xfree86/dixmods/glxmodule.c @@ -41,18 +41,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "colormap.h" #include "micmap.h" #include "globals.h" - -typedef struct __GLXscreen __GLXscreen; -typedef struct __GLXprovider __GLXprovider; -struct __GLXprovider { - __GLXscreen *(*screenProbe)(ScreenPtr pScreen); - const char *name; - __GLXprovider *next; -}; - -extern void GlxPushProvider(__GLXprovider *provider); -extern void GlxExtensionInit(void); -extern void GlxWrapInitVisuals(miInitVisualsProcPtr *); +#include "glxserver.h" static MODULESETUPPROTO(glxSetup); @@ -114,7 +103,6 @@ static __GLXprovider __glXMesaProxyProvider = { NULL }; - static pointer glxSetup(pointer module, pointer opts, int *errmaj, int *errmin) { @@ -139,12 +127,22 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin) GlxPushProvider(provider); } + switch (xf86Info.glxVisuals) { + case XF86_GlxVisualsMinimal: + GlxSetVisualConfig(GLX_MINIMAL_VISUALS); + xf86Msg(xf86Info.aiglxFrom, "Exporting only minimal set of GLX visuals\n"); + break; + case XF86_GlxVisualsTypical: + GlxSetVisualConfig(GLX_TYPICAL_VISUALS); + xf86Msg(xf86Info.aiglxFrom, "Exporting typical set of GLX visuals\n"); + break; + case XF86_GlxVisualsAll: + GlxSetVisualConfig(GLX_ALL_VISUALS); + xf86Msg(xf86Info.aiglxFrom, "Exporting all GLX visuals\n"); + break; + } + LoadExtension(&GLXExt, FALSE); - /* Wrap the init visuals routine in micmap.c */ - GlxWrapInitVisuals(&miInitVisualsProc); - /* Make sure this gets wrapped each time InitVisualWrap is called */ - miHookInitVisuals(NULL, GlxWrapInitVisuals); - bail: return module; } diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre index 54d8eaa87..4064ef6d8 100644 --- a/hw/xfree86/doc/man/xorg.conf.man.pre +++ b/hw/xfree86/doc/man/xorg.conf.man.pre @@ -700,6 +700,17 @@ the builtin handler will be used. .BI "Option \*qAIGLX\*q \*q" boolean \*q enable or disable AIGLX. AIGLX is enabled by default. .TP 7 +.BI "Option \*qGlxVisuals\*q \*q" string \*q +This option controls how many GLX visuals the GLX modules sets up. +The default value is +.BR "typical" , +which will setup up a typical subset of +the GLXFBConfigs provided by the driver as GLX visuals. Other options are +.BR "minimal" , +which will set up the minimal set allowed by the GLX specification and +.BR "all" +which will setup GLX visuals for all GLXFBConfigs. +.TP 7 .BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q Include the default font path even if other paths are specified in xorg.conf. If enabled, other font paths are included as well. Enabled by diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index c35386354..b736c6ae0 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -67,7 +67,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dristruct.h" #include "xf86.h" #include "xf86drm.h" -#include "glxserver.h" #include "mi.h" #include "mipointer.h" #include "xf86_OSproc.h" @@ -953,24 +952,8 @@ static Bool DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - __GLXscreen *pGLXScreen = glxGetScreen(pScreen); - __GLcontextModes *modes = pGLXScreen->modes; - void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; - VisualPtr visual; - int visNum; - - visual = pScreen->visuals; - - /* Find the X visual that corresponds the the first GLX visual */ - for (visNum = 0; - visNum < pScreen->numVisuals; - visNum++, visual++) { - if (modes->visualID == visual->vid) - break; - } - if (visNum == pScreen->numVisuals) return FALSE; if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, @@ -980,9 +963,9 @@ DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) contextStore = DRIGetContextStore(pDRIContextPriv); if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) { - if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, visual, + if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL, pDRIPriv->pSAREA->dummy_context, - *pVisualConfigPriv, + NULL, (DRIContextType)(long)contextStore)) { DRIDestroyContextPriv(pDRIContextPriv); return FALSE; @@ -1017,9 +1000,6 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, XID context, drm_context_t * pHWContext) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - __GLXscreen *pGLXScreen = glxGetScreen(pScreen); - __GLcontextModes *modes = pGLXScreen->modes; - void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; @@ -1031,26 +1011,14 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, } } - /* Find the GLX visual associated with the one requested */ - for (modes = pGLXScreen->modes; modes != NULL; modes = modes->next) { - if (modes->visualID == visual->vid) - break; - pVisualConfigPriv++; - } - - if (modes == NULL) { - /* No matching GLX visual found */ - return FALSE; - } - if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) { return FALSE; } contextStore = DRIGetContextStore(pDRIContextPriv); if (pDRIPriv->pDriverInfo->CreateContext) { - if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, visual, - *pHWContext, *pVisualConfigPriv, + if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL, + *pHWContext, NULL, (DRIContextType)(long)contextStore))) { DRIDestroyContextPriv(pDRIContextPriv); return FALSE; diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c index c658421e8..e01d6d9be 100644 --- a/hw/xfree86/dri/xf86dri.c +++ b/hw/xfree86/dri/xf86dri.c @@ -373,19 +373,9 @@ ProcXF86DRICreateContext( rep.sequenceNumber = client->sequence; pScreen = screenInfo.screens[stuff->screen]; - visual = pScreen->visuals; - - /* Find the requested X visual */ - for (i = 0; i < pScreen->numVisuals; i++, visual++) - if (visual->vid == stuff->visual) - break; - if (i == pScreen->numVisuals) { - /* No visual found */ - return BadValue; - } if (!DRICreateContext( pScreen, - visual, + NULL, stuff->context, (drm_context_t *)&rep.hHWContext)) { return BadValue; diff --git a/hw/xfree86/loader/misym.c b/hw/xfree86/loader/misym.c index e87d35408..aa712c03a 100644 --- a/hw/xfree86/loader/misym.c +++ b/hw/xfree86/loader/misym.c @@ -205,9 +205,6 @@ _X_HIDDEN void *miLookupTab[] = { SYMVAR(miPointerScreenKey) SYMVAR(miInstalledMaps) SYMVAR(miInitVisualsProc) -#ifdef RENDER - SYMFUNC(miGlyphExtents) -#endif #ifdef DAMAGE SYMFUNC(DamageDamageRegion) #endif diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 0a48d5bd3..bb416fddc 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1417,9 +1417,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) output->probed_modes = mode; } mode->type |= (M_T_PREFERRED|M_T_USERPREF); + break; } - else - mode->type &= ~M_T_PREFERRED; } } diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 9fa5fef9e..2f26a6450 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -64,6 +64,8 @@ typedef enum { * maximum size and use that. */ DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5, + /* Monitor forgot to set the first detailed is preferred bit. */ + DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6, } ddc_quirk_t; static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) @@ -147,6 +149,16 @@ static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC) return FALSE; } +static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC) +{ + /* Philips 107p5 CRT. Reported on xorg@ with pastebin. */ + if (memcmp (DDC->vendor.name, "PHL", 4) == 0 && + DDC->vendor.prod_id == 57364) + return TRUE; + + return FALSE; +} + typedef struct { Bool (*detect) (int scrnIndex, xf86MonPtr DDC); ddc_quirk_t quirk; @@ -178,6 +190,10 @@ static const ddc_quirk_map_t ddc_quirks[] = { quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE, "Detailed timings give sizes in cm." }, + { + quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED, + "First detailed timing was not marked as preferred." + }, { NULL, DDC_QUIRK_NONE, "No known quirks" @@ -257,7 +273,7 @@ DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing, */ static DisplayModePtr DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, - int preferred, ddc_quirk_t quirks) + Bool preferred, ddc_quirk_t quirks) { DisplayModePtr Mode; @@ -470,9 +486,10 @@ xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes, _X_EXPORT DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) { - int preferred, i; + int i; DisplayModePtr Modes = NULL, Mode; ddc_quirk_t quirks; + Bool preferred; xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", DDC->vendor.name, DDC->vendor.prod_id); @@ -480,8 +497,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE); preferred = PREFERRED_TIMING_MODE(DDC->features.msc); - if (quirks & DDC_QUIRK_PREFER_LARGE_60) - preferred = 0; + if (quirks & DDC_QUIRK_FIRST_DETAILED_PREFERRED) + preferred = TRUE; + if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75)) + preferred = FALSE; for (i = 0; i < DET_TIMINGS; i++) { struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; @@ -492,7 +511,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) &det_mon->section.d_timings, preferred, quirks); - preferred = 0; + preferred = FALSE; Modes = xf86ModesAdd(Modes, Mode); break; case DS_STD_TIMINGS: diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index d58cc7070..2c0dc3120 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -426,8 +426,18 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen) xf86OutputPtr output = config->output[config->compat_output]; xf86CrtcPtr crtc = output->crtc; - if (crtc && crtc->mode.HDisplay && - output->mm_width && output->mm_height) + if (output->conf_monitor && + (output->conf_monitor->mon_width > 0 && + output->conf_monitor->mon_height > 0)) + { + /* + * Prefer user configured DisplaySize + */ + mmWidth = output->conf_monitor->mon_width; + mmHeight = output->conf_monitor->mon_height; + } + else if (crtc && crtc->mode.HDisplay && + output->mm_width && output->mm_height) { /* * If the output has a mode and a declared size, use that diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c index 024e6ef09..bb975cc5d 100644 --- a/hw/xfree86/os-support/linux/lnx_acpi.c +++ b/hw/xfree86/os-support/linux/lnx_acpi.c @@ -23,11 +23,11 @@ #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 -#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 -#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 -#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 -#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 -#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 +#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 +#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 +#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 +#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 +#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) #define ACPI_VIDEO_HEAD_END (~0u) @@ -69,9 +69,11 @@ lnxACPIGetEventFromOs(int fd, pmEvent *events, int num) TimerSet(NULL, 0, ACPI_REOPEN_DELAY, lnxACPIReopen, NULL); return 0; } + /* FIXME: this only processes the first read ACPI event & might break + * with interrupted reads. */ /* Check that we have a video event */ - if (strstr(ev, "video") == ev) { + if (!strncmp(ev, "video", 5)) { char *video = NULL; char *GFX = NULL; char *notify = NULL; @@ -97,26 +99,19 @@ lnxACPIGetEventFromOs(int fd, pmEvent *events, int num) ErrorF("data: 0x%lx\n",data_l); #endif - /* We currently don't differentiate between any event */ + /* Differentiate between events */ switch (notify_l) { case ACPI_VIDEO_NOTIFY_SWITCH: - break; - case ACPI_VIDEO_NOTIFY_PROBE: - break; case ACPI_VIDEO_NOTIFY_CYCLE: - break; case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: - break; case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: - break; + events[0] = XF86_APM_CAPABILITY_CHANGED; + return 1; + case ACPI_VIDEO_NOTIFY_PROBE: + return 0; default: - break; + return 0; } - - /* Deal with all ACPI events as a capability change */ - events[0] = XF86_APM_CAPABILITY_CHANGED; - - return 1; } return 0; diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c index 83590bced..61a325f3c 100644 --- a/hw/xnest/Screen.c +++ b/hw/xnest/Screen.c @@ -45,10 +45,6 @@ is" without express or implied warranty. Window xnestDefaultWindows[MAXSCREENS]; Window xnestScreenSaverWindows[MAXSCREENS]; -#ifdef GLXEXT -extern void GlxWrapInitVisuals(miInitVisualsProcPtr *); -#endif - ScreenPtr xnestScreen(Window window) { @@ -220,17 +216,6 @@ xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[]) defaultVisual = visuals[xnestDefaultVisualIndex].vid; rootDepth = visuals[xnestDefaultVisualIndex].nplanes; -#ifdef GLXEXT - { - miInitVisualsProcPtr proc = NULL; - - GlxWrapInitVisuals(&proc); - /* GlxInitVisuals ignores the last three arguments. */ - proc(&visuals, &depths, &numVisuals, &numDepths, - &rootDepth, &defaultVisual, 0, 0, 0); - } -#endif - if (xnestParentWindow != 0) { XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes); xnestWidth = gattributes.width; diff --git a/include/os.h b/include/os.h index ac61992fe..40e89da24 100644 --- a/include/os.h +++ b/include/os.h @@ -517,7 +517,7 @@ __attribute((noreturn)) #ifdef DEBUG #define DebugF ErrorF #else -#define DebugF(x, ...) /* */ +#define DebugF(...) /* */ #endif extern void VErrorF(const char *f, va_list args); diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in index 97d53a2ee..b91ea9260 100644 --- a/include/xorg-config.h.in +++ b/include/xorg-config.h.in @@ -112,4 +112,7 @@ /* Have execinfo.h */ #undef HAVE_EXECINFO_H +/* Path to text files containing PCI IDs */ +#undef PCI_TXT_IDS_PATH + #endif /* _XORG_CONFIG_H_ */ diff --git a/mi/miinitext.c b/mi/miinitext.c index 2540975ac..c1ed6e74a 100644 --- a/mi/miinitext.c +++ b/mi/miinitext.c @@ -352,7 +352,6 @@ extern void DarwinGlxWrapInitVisuals(miInitVisualsProcPtr *); extern __GLXprovider __glXMesaProvider; extern void GlxPushProvider(__GLXprovider *impl); extern void GlxExtensionInit(INITARGS); -extern void GlxWrapInitVisuals(miInitVisualsProcPtr *); #endif // INXDARWINAPP #endif // GLXEXT #ifdef XF86DRI @@ -678,9 +677,7 @@ InitVisualWrap() { miResetInitVisuals(); #ifdef GLXEXT -#ifndef __DARWIN__ - GlxWrapInitVisuals(&miInitVisualsProc); -#else +#ifdef __DARWIN__ DarwinGlxWrapInitVisuals(&miInitVisualsProc); #endif #endif diff --git a/miext/cw/cw.h b/miext/cw/cw.h index 47c4ee3b8..145f3492c 100644 --- a/miext/cw/cw.h +++ b/miext/cw/cw.h @@ -99,7 +99,6 @@ typedef struct { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; CompositeRectsProcPtr CompositeRects; TrapezoidsProcPtr Trapezoids; diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c index 35416beb7..6e0c727c2 100644 --- a/miext/cw/cw_render.c +++ b/miext/cw/cw_render.c @@ -280,34 +280,6 @@ cwComposite (CARD8 op, } static void -cwGlyphs (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlists, - GlyphListPtr lists, - GlyphPtr *glyphs) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - - cwPsUnwrap(Glyphs); - if (nlists) - { - lists->xOff += dst_picture_x_off; - lists->yOff += dst_picture_y_off; - } - (*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - nlists, lists, glyphs); - cwPsWrap(Glyphs, cwGlyphs); -} - -static void cwCompositeRects (CARD8 op, PicturePtr pDstPicture, xRenderColor *color, @@ -470,7 +442,6 @@ cwInitializeRender (ScreenPtr pScreen) cwPsWrap(ChangePicture, cwChangePicture); cwPsWrap(ValidatePicture, cwValidatePicture); cwPsWrap(Composite, cwComposite); - cwPsWrap(Glyphs, cwGlyphs); cwPsWrap(CompositeRects, cwCompositeRects); cwPsWrap(Trapezoids, cwTrapezoids); cwPsWrap(Triangles, cwTriangles); @@ -491,7 +462,6 @@ cwFiniRender (ScreenPtr pScreen) cwPsUnwrap(ChangePicture); cwPsUnwrap(ValidatePicture); cwPsUnwrap(Composite); - cwPsUnwrap(Glyphs); cwPsUnwrap(CompositeRects); cwPsUnwrap(Trapezoids); cwPsUnwrap(Triangles); diff --git a/render/Makefile.am b/render/Makefile.am index 830778a92..e53c7c746 100644 --- a/render/Makefile.am +++ b/render/Makefile.am @@ -6,7 +6,6 @@ librender_la_SOURCES = \ animcur.c \ filter.c \ glyph.c \ - miglyph.c \ miindex.c \ mipict.c \ mirect.c \ diff --git a/render/glyph.c b/render/glyph.c index cb1534d6e..bb7c880d3 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -26,6 +26,9 @@ #include <dix-config.h> #endif +#include <stddef.h> +#include <openssl/sha.h> + #include "misc.h" #include "scrnintstr.h" #include "os.h" @@ -41,6 +44,7 @@ #include "servermd.h" #include "picturestr.h" #include "glyphstr.h" +#include "mipict.h" /* * From Knuth -- a good choice for hash/rehash values is p, p-2 where @@ -93,6 +97,7 @@ FreeGlyphPrivates (GlyphPtr glyph) } dixFreePrivates(glyph->devPrivates); + glyph->devPrivates = NULL; } void @@ -114,7 +119,6 @@ GlyphUninit (ScreenPtr pScreen) { (*ps->UnrealizeGlyph) (pScreen, glyph); FreeGlyphPrivates(glyph); - glyph->devPrivates = NULL; } } } @@ -141,7 +145,10 @@ FindGlyphHashSet (CARD32 filled) } GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]) { CARD32 elt, step, s; GlyphPtr glyph; @@ -172,7 +179,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) } else if (s == signature && (!match || - memcmp (&compare->info, &glyph->info, compare->size) == 0)) + memcmp (glyph->sha1, sha1, 20) == 0)) { break; } @@ -189,17 +196,47 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) return gr; } -CARD32 -HashGlyph (GlyphPtr glyph) +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]) { - CARD32 *bits = (CARD32 *) &(glyph->info); - CARD32 hash; - int n = glyph->size / sizeof (CARD32); - - hash = 0; - while (n--) - hash ^= *bits++; - return hash; + SHA_CTX ctx; + int success; + + success = SHA1_Init (&ctx); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo)); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, bits, size); + if (! success) + return BadAlloc; + + success = SHA1_Final (sha1, &ctx); + if (! success) + return BadAlloc; + + return Success; +} + +GlyphPtr +FindGlyphByHash (unsigned char sha1[20], int format) +{ + GlyphRefPtr gr; + CARD32 signature = *(CARD32 *) sha1; + + gr = FindGlyphRef (&globalGlyphs[format], + signature, TRUE, sha1); + + if (gr->glyph && gr->glyph != DeletedGlyph) + return gr->glyph; + else + return NULL; } #ifdef CHECK_DUPLICATES @@ -240,6 +277,7 @@ FreeGlyph (GlyphPtr glyph, int format) GlyphRefPtr gr; int i; int first; + CARD32 signature; first = -1; for (i = 0; i < globalGlyphs[format].hashSet->size; i++) @@ -250,8 +288,9 @@ FreeGlyph (GlyphPtr glyph, int format) first = i; } - gr = FindGlyphRef (&globalGlyphs[format], - HashGlyph (glyph), TRUE, glyph); + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[format], signature, + TRUE, glyph->sha1); if (gr - globalGlyphs[format].table != first) DuplicateRef (glyph, "Found wrong one"); if (gr->glyph && gr->glyph != DeletedGlyph) @@ -263,9 +302,13 @@ FreeGlyph (GlyphPtr glyph, int format) for (i = 0; i < screenInfo.numScreens; i++) { - ps = GetPictureScreenIfSet (screenInfo.screens[i]); + ScreenPtr pScreen = screenInfo.screens[i]; + + FreePicture ((pointer) GlyphPicture (glyph)[i], 0); + + ps = GetPictureScreenIfSet (pScreen); if (ps) - (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + (*ps->UnrealizeGlyph) (pScreen, glyph); } FreeGlyphPrivates(glyph); @@ -277,13 +320,14 @@ void AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) { GlyphRefPtr gr; - CARD32 hash; + CARD32 signature; CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); /* Locate existing matching glyph */ - hash = HashGlyph (glyph); - gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); - if (gr->glyph && gr->glyph != DeletedGlyph) + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); + if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { PictureScreenPtr ps; int i; @@ -298,10 +342,10 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) xfree (glyph); glyph = gr->glyph; } - else + else if (gr->glyph != glyph) { gr->glyph = glyph; - gr->signature = hash; + gr->signature = signature; globalGlyphs[glyphSet->fdepth].tableEntries++; } @@ -354,7 +398,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) GlyphPtr glyph; int i; - size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]); + size = screenInfo.numScreens * sizeof (PicturePtr); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); if (!glyph) return 0; @@ -366,25 +410,27 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) for (i = 0; i < screenInfo.numScreens; i++) { ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) { if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) - { - while (i--) - { - ps = GetPictureScreenIfSet (screenInfo.screens[i]); - if (ps) - (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); - } - - FreeGlyphPrivates(glyph); - xfree (glyph); - return 0; - } + goto bail; } } return glyph; + +bail: + while (i--) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + + FreeGlyphPrivates(glyph); + xfree (glyph); + return 0; } Bool @@ -428,7 +474,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global) if (glyph && glyph != DeletedGlyph) { s = hash->table[i].signature; - gr = FindGlyphRef (&newHash, s, global, glyph); + gr = FindGlyphRef (&newHash, s, global, glyph->sha1); gr->signature = s; gr->glyph = glyph; ++newHash.tableEntries; @@ -510,3 +556,215 @@ FreeGlyphSet (pointer value, } return Success; } + +static void +GlyphExtents (int nlist, + GlyphListPtr list, + GlyphPtr *glyphs, + BoxPtr extents) +{ + int x1, x2, y1, y2; + int n; + GlyphPtr glyph; + int x, y; + + x = 0; + y = 0; + extents->x1 = MAXSHORT; + extents->x2 = MINSHORT; + extents->y1 = MAXSHORT; + extents->y2 = MINSHORT; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) + { + glyph = *glyphs++; + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + if (x1 < extents->x1) + extents->x1 = x1; + if (x2 > extents->x2) + extents->x2 = x2; + if (y1 < extents->y1) + extents->y1 = y1; + if (y2 > extents->y2) + extents->y2 = y2; + x += glyph->info.xOff; + y += glyph->info.yOff; + } + } +} + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +/* Stub ABI compatibility for mi*Glyph, should go away */ +_X_EXPORT void +miGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + CompositeGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, + glyphs); +} + +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ + return TRUE; +} + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ +} + +_X_EXPORT void +CompositeGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + PicturePtr pPicture; + PixmapPtr pMaskPixmap = 0; + PicturePtr pMask; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int xDst = list->xOff, yDst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = {0, 0, 0, 0}; + CARD32 component_alpha; + + ValidatePicture (pSrc); + ValidatePicture (pDst); + + if (maskFormat) + { + GCPtr pGC; + xRectangle rect; + + GlyphExtents (nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + maskFormat->depth); + if (!pMaskPixmap) + return; + component_alpha = NeedsComponent(maskFormat->format); + pMask = CreatePicture (0, &pMaskPixmap->drawable, + maskFormat, CPComponentAlpha, &component_alpha, + serverClient, &error); + if (!pMask) + { + (*pScreen->DestroyPixmap) (pMaskPixmap); + return; + } + pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); + ValidateGC (&pMaskPixmap->drawable, pGC); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); + FreeScratchGC (pGC); + x = -extents.x1; + y = -extents.y1; + } + else + { + pMask = pDst; + x = 0; + y = 0; + } + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) + { + glyph = *glyphs++; + pPicture = GlyphPicture (glyph)[pScreen->myNum]; + + if (maskFormat) + { + CompositePicture (PictOpAdd, + pPicture, + None, + pMask, + 0, 0, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + else + { + CompositePicture (op, + pSrc, + pPicture, + pDst, + xSrc + (x - glyph->info.x) - xDst, + ySrc + (y - glyph->info.y) - yDst, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + if (maskFormat) + { + x = extents.x1; + y = extents.y1; + CompositePicture (op, + pSrc, + pMask, + pDst, + xSrc + x - xDst, + ySrc + y - yDst, + 0, 0, + x, y, + width, height); + FreePicture ((pointer) pMask, (XID) 0); + (*pScreen->DestroyPixmap) (pMaskPixmap); + } +} diff --git a/render/glyphstr.h b/render/glyphstr.h index e89f34e59..67b21fe63 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -40,13 +40,16 @@ #define GlyphFormatNum 5 typedef struct _Glyph { - CARD32 refcnt; + CARD32 refcnt; PrivateRec *devPrivates; - CARD32 size; /* info + bitmap */ - xGlyphInfo info; - /* bits follow */ + unsigned char sha1[20]; + CARD32 size; /* info + bitmap */ + xGlyphInfo info; + /* per-screen pixmaps follow */ } GlyphRec, *GlyphPtr; +#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1)) + typedef struct _GlyphRef { CARD32 signature; GlyphPtr glyph; @@ -98,10 +101,19 @@ GlyphHashSetPtr FindGlyphHashSet (CARD32 filled); GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]); -CARD32 -HashGlyph (GlyphPtr glyph); +GlyphPtr +FindGlyphByHash (unsigned char sha1[20], int format); + +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]); void FreeGlyph (GlyphPtr glyph, int format); diff --git a/render/miglyph.c b/render/miglyph.c deleted file mode 100644 index 7968c90ea..000000000 --- a/render/miglyph.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * - * Copyright © 2000 SuSE, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "mi.h" -#include "picturestr.h" -#include "mipict.h" - -Bool -miRealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ - return TRUE; -} - -void -miUnrealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ -} - -_X_EXPORT void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents) -{ - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - - x = 0; - y = 0; - extents->x1 = MAXSHORT; - extents->x2 = MINSHORT; - extents->y1 = MAXSHORT; - extents->y2 = MINSHORT; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) - { - glyph = *glyphs++; - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - if (x1 < extents->x1) - extents->x1 = x1; - if (x2 > extents->x2) - extents->x2 = x2; - if (y1 < extents->y1) - extents->y1 = y1; - if (y2 > extents->y2) - extents->y2 = y2; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } -} - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -_X_EXPORT void -miGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - PixmapPtr pPixmap = 0; - PicturePtr pPicture; - PixmapPtr pMaskPixmap = 0; - PicturePtr pMask; - ScreenPtr pScreen = pDst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y; - int xDst = list->xOff, yDst = list->yOff; - int n; - GlyphPtr glyph; - int error; - BoxRec extents; - CARD32 component_alpha; - - if (maskFormat) - { - GCPtr pGC; - xRectangle rect; - - miGlyphExtents (nlist, list, glyphs, &extents); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth); - if (!pMaskPixmap) - return; - component_alpha = NeedsComponent(maskFormat->format); - pMask = CreatePicture (0, &pMaskPixmap->drawable, - maskFormat, CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pMaskPixmap); - return; - } - pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); - ValidateGC (&pMaskPixmap->drawable, pGC); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); - FreeScratchGC (pGC); - x = -extents.x1; - y = -extents.y1; - } - else - { - pMask = pDst; - x = 0; - y = 0; - } - pPicture = 0; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - while (n--) - { - glyph = *glyphs++; - if (!pPicture) - { - pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, - list->format->depth, - list->format->depth, - 0, (pointer) (glyph + 1)); - if (!pPixmap) - return; - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) - { - FreeScratchPixmapHeader (pPixmap); - return; - } - } - (*pScreen->ModifyPixmapHeader) (pPixmap, - glyph->info.width, glyph->info.height, - 0, 0, -1, (pointer) (glyph + 1)); - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - if (maskFormat) - { - CompositePicture (PictOpAdd, - pPicture, - None, - pMask, - 0, 0, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - else - { - CompositePicture (op, - pSrc, - pPicture, - pDst, - xSrc + (x - glyph->info.x) - xDst, - ySrc + (y - glyph->info.y) - yDst, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - if (pPicture) - { - FreeScratchPixmapHeader (pPixmap); - FreePicture ((pointer) pPicture, 0); - pPicture = 0; - pPixmap = 0; - } - } - if (maskFormat) - { - x = extents.x1; - y = extents.y1; - CompositePicture (op, - pSrc, - pMask, - pDst, - xSrc + x - xDst, - ySrc + y - yDst, - 0, 0, - x, y, - width, height); - FreePicture ((pointer) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } -} diff --git a/render/mipict.c b/render/mipict.c index 87dccbbda..5aad676f5 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -636,7 +636,7 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) /* MI rendering routines */ ps->Composite = 0; /* requires DDX support */ - ps->Glyphs = miGlyphs; + ps->Glyphs = NULL; ps->CompositeRects = miCompositeRects; ps->Trapezoids = miTrapezoids; ps->Triangles = miTriangles; diff --git a/render/mipict.h b/render/mipict.h index bd7c23f4b..60baf7f66 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -120,12 +120,6 @@ miUnrealizeGlyph (ScreenPtr pScreen, GlyphPtr glyph); void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents); - -void miGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst, diff --git a/render/picture.c b/render/picture.c index 049274e9f..35e2a28b3 100644 --- a/render/picture.c +++ b/render/picture.c @@ -1673,24 +1673,6 @@ CompositePicture (CARD8 op, } void -CompositeGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr lists, - GlyphPtr *glyphs) -{ - PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); - - ValidatePicture (pSrc); - ValidatePicture (pDst); - (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); -} - -void CompositeRects (CARD8 op, PicturePtr pDst, xRenderColor *color, diff --git a/render/picture.h b/render/picture.h index 563a81b43..e8a098cd9 100644 --- a/render/picture.h +++ b/render/picture.h @@ -115,7 +115,7 @@ typedef enum _PictFormatShort { /* 1bpp formats */ PICT_a1 = PIXMAN_a1, - PICT_g1 = PIXMAN_g1, + PICT_g1 = PIXMAN_g1 } PictFormatShort; /* diff --git a/render/picturestr.h b/render/picturestr.h index 5444e519c..4dfa94402 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -342,7 +342,7 @@ typedef struct _PictureScreen { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; + GlyphsProcPtr Glyphs; /* unused */ CompositeRectsProcPtr CompositeRects; DestroyWindowProcPtr DestroyWindow; diff --git a/render/render.c b/render/render.c index fe50dd28e..b9ac45e96 100644 --- a/render/render.c +++ b/render/render.c @@ -1170,24 +1170,31 @@ ProcRenderFreeGlyphSet (ClientPtr client) } typedef struct _GlyphNew { - Glyph id; - GlyphPtr glyph; + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; } GlyphNewRec, *GlyphNewPtr; +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + static int ProcRenderAddGlyphs (ClientPtr client) { GlyphSetPtr glyphSet; REQUEST(xRenderAddGlyphsReq); GlyphNewRec glyphsLocal[NLOCALGLYPH]; - GlyphNewPtr glyphsBase, glyphs; - GlyphPtr glyph; + GlyphNewPtr glyphsBase, glyphs, glyph_new; int remain, nglyphs; CARD32 *gids; xGlyphInfo *gi; CARD8 *bits; int size; int err; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); err = dixLookupResource((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, @@ -1203,11 +1210,15 @@ ProcRenderAddGlyphs (ClientPtr client) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) return BadAlloc; - if (nglyphs <= NLOCALGLYPH) + component_alpha = NeedsComponent (glyphSet->format->format); + + if (nglyphs <= NLOCALGLYPH) { + memset (glyphsLocal, 0, sizeof (glyphsLocal)); glyphsBase = glyphsLocal; + } else { - glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec)); + glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec)); if (!glyphsBase) return BadAlloc; } @@ -1220,58 +1231,133 @@ ProcRenderAddGlyphs (ClientPtr client) gi = (xGlyphInfo *) (gids + nglyphs); bits = (CARD8 *) (gi + nglyphs); remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; - while (remain >= 0 && nglyphs) + for (i = 0; i < nglyphs; i++) { - glyph = AllocateGlyph (gi, glyphSet->fdepth); - if (!glyph) - { - err = BadAlloc; - goto bail; - } - - glyphs->glyph = glyph; - glyphs->id = *gids; - - size = glyph->size - sizeof (xGlyphInfo); + glyph_new = &glyphs[i]; + size = gi[i].height * PixmapBytePad (gi[i].width, + glyphSet->format->depth); if (remain < size) break; - memcpy ((CARD8 *) (glyph + 1), bits, size); + + err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; + + glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, + glyphSet->fdepth); + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) + { + glyph_new->found = TRUE; + } + else + { + GlyphPtr glyph; + + glyph_new->found = FALSE; + glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); + if (! glyph) + { + err = BadAlloc; + goto bail; + } + + for (screen = 0; screen < screenInfo.numScreens; screen++) + { + int width = gi[i].width; + int height = gi[i].height; + int depth = glyphSet->format->depth; + ScreenPtr pScreen; + int error; + + pScreen = screenInfo.screens[screen]; + pSrcPix = GetScratchPixmapHeader (pScreen, + width, height, + depth, depth, + -1, bits); + if (! pSrcPix) + { + err = BadAlloc; + goto bail; + } + + pSrc = CreatePicture (0, &pSrcPix->drawable, + glyphSet->format, 0, NULL, + serverClient, &error); + if (! pSrc) + { + err = BadAlloc; + goto bail; + } + + pDstPix = (pScreen->CreatePixmap) (pScreen, + width, height, depth); + + GlyphPicture (glyph)[screen] = pDst = + CreatePicture (0, &pDstPix->drawable, + glyphSet->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + /* The picture takes a reference to the pixmap, so we + drop ours. */ + (pScreen->DestroyPixmap) (pDstPix); + + if (! pDst) + { + err = BadAlloc; + goto bail; + } + + CompositePicture (PictOpSrc, + pSrc, + None, + pDst, + 0, 0, + 0, 0, + 0, 0, + width, height); + + FreePicture ((pointer) pSrc, 0); + pSrc = NULL; + FreeScratchPixmapHeader (pSrcPix); + pSrcPix = NULL; + } + + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); + } + + glyph_new->id = gids[i]; if (size & 3) size += 4 - (size & 3); bits += size; remain -= size; - gi++; - gids++; - glyphs++; - nglyphs--; } - if (nglyphs || remain) + if (remain || i < nglyphs) { err = BadLength; goto bail; } - nglyphs = stuff->nglyphs; if (!ResizeGlyphSet (glyphSet, nglyphs)) { err = BadAlloc; goto bail; } - glyphs = glyphsBase; - while (nglyphs--) { - AddGlyph (glyphSet, glyphs->glyph, glyphs->id); - glyphs++; - } + for (i = 0; i < nglyphs; i++) + AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); return client->noClientException; bail: - while (glyphs != glyphsBase) - { - --glyphs; - xfree (glyphs->glyph); - } + if (pSrc) + FreePicture ((pointer) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader (pSrcPix); + for (i = 0; i < nglyphs; i++) + if (glyphs[i].glyph && ! glyphs[i].found) + xfree (glyphs[i].glyph); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); return err; |