mirror of
https://github.com/X11Libre/xserver.git
synced 2026-09-29 21:46:40 +00:00
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:
commit
b633d54b94
44 changed files with 1207 additions and 1881 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
497
GL/glx/glxcmds.c
497
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;
|
||||
__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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in a new issue