Merge branch 'master' into XACE-SELINUX

Conflicts:

	GL/glx/glxscreens.c
	hw/xnest/Screen.c
	render/glyph.c
	render/glyphstr.h
	render/render.c
This commit is contained in:
Eamon Walsh 2007-10-25 12:19:30 -04:00 • committed by Eamon Walsh
commit b633d54b94
44 changed files with 1207 additions and 1881 deletions

View file

@ -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 \

View file

@ -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;
__GLcontextModes *config;
__GLXscreen *pGlxScreen;
PixmapPtr pPixmap;
int err;
pScreen = screenInfo.screens[screenNum];
pVisual = pScreen->visuals;
for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
if (pVisual->vid == fbconfigId)
break;
}
if (i == pScreen->numVisuals)
return __glXError(GLXBadFBConfig);
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;
}
if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
return err;
ptr = glxGetScreen(screenInfo.screens[screen])->GLXextensions;
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;

View file

@ -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,

View file

@ -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;

View file

@ -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]);
}

View file

@ -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;
int back, depth, stencil;
/* Alloc space for the list of XMesa visuals */
size = screen->base.numVisuals * sizeof(XMesaVisual);
pXMesaVisual = (XMesaVisual *) xalloc(size);
memset(pXMesaVisual, 0, size);
/* FIXME: Ok, I'm making all this up... anybody has a better idea? */
/* 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));
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;
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;
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;
}
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]) {
return config;
}
/* 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;
static void
createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
{
__GLcontextModes *configs;
int i;
/* Mark this visual used */
used[j] = 1;
/* 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);
}
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;
}
}
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" );
}
num_vis++;
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);
}
xfree(used);
screen->num_vis = num_vis;
screen->xm_vis = pXMesaVisual;
assert(screen->num_vis <= screen->base.numVisuals);
}
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;
}

View file

@ -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. */
}
glxScreen->PositionWindow = pScreen->PositionWindow;
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;
}
/*
* 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;
dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, glxScreen);
/* 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, pGlxScreen);
}
void __glXScreenDestroy(__GLXscreen *screen)

View file

@ -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;

View file

@ -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);

View file

@ -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);
}