glx: Prepare __glXGetDrawable for no-config contexts

Any proper (GLX 1.3) drawable will already have a bound config, but if
we're doing the GLX 1.2 thing of making a Window current, we need to
infer the config from the window's Visual.

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Adam Jackson 2017-11-14 15:15:02 -05:00
parent 5d667df6ea
commit f0fffa926a

View File

@ -474,6 +474,18 @@ StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc)
glxc->currentClient = cl->client;
}
static __GLXconfig *
inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin)
{
int i, vid = wVisual(pWin);
for (i = 0; i < pGlxScreen->numVisuals; i++)
if (pGlxScreen->visuals[i]->visualID == vid)
return pGlxScreen->visuals[i];
return NULL;
}
/**
* This is a helper function to handle the legacy (pre GLX 1.3) cases
* where passing an X window to glXMakeCurrent is valid. Given a
@ -486,11 +498,15 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
{
DrawablePtr pDraw;
__GLXdrawable *pGlxDraw;
__GLXconfig *config;
__GLXscreen *pGlxScreen;
int rc;
if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
DixWriteAccess, &pGlxDraw, &rc)) {
if (glxc != NULL && pGlxDraw->config != glxc->config) {
if (glxc != NULL &&
glxc->config != NULL &&
glxc->config != pGlxDraw->config) {
client->errorValue = drawId;
*error = BadMatch;
return NULL;
@ -518,19 +534,35 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
return NULL;
}
if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
pGlxScreen = glxc->pGlxScreen;
if (pDraw->pScreen != pGlxScreen->pScreen) {
client->errorValue = pDraw->pScreen->myNum;
*error = BadMatch;
return NULL;
}
if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
config = glxc->config;
if (!config)
config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw);
if (!config) {
/*
* If we get here, we've tried to bind a no-config context to a
* window without a corresponding fbconfig, presumably because
* we don't support GL on it (PseudoColor perhaps). From GLX Section
* 3.3.7 "Rendering Contexts":
*
* "If draw or read are not compatible with ctx a BadMatch error
* is generated."
*/
*error = BadMatch;
return NULL;
}
if (!validGlxFBConfigForWindow(client, config, pDraw, error))
return NULL;
pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
pDraw, drawId,
GLX_DRAWABLE_WINDOW,
drawId, glxc->config);
pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId,
GLX_DRAWABLE_WINDOW, drawId, config);
if (!pGlxDraw) {
*error = BadAlloc;
return NULL;