xserver-multidpi/hw/xgl/xglglx.c
2005-12-23 01:13:28 +00:00

4912 lines
115 KiB
C

/*
* Copyright © 2005 Novell, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Novell, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Novell, Inc. makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#ifdef GLXEXT
#include <GL/gl.h>
#include "glxserver.h"
#include "glxdrawable.h"
#include "glxscreens.h"
#include "glxutil.h"
#include "unpack.h"
#include "g_disptab.h"
#include "micmap.h"
#define XGL_MAX_TEXTURE_UNITS 8
#define XGL_TEXTURE_1D_BIT (1 << 0)
#define XGL_TEXTURE_2D_BIT (1 << 1)
#define XGL_TEXTURE_3D_BIT (1 << 2)
#define XGL_TEXTURE_RECTANGLE_BIT (1 << 3)
#define XGL_TEXTURE_CUBE_MAP_BIT (1 << 4)
extern void
GlxSetVisualConfigs (int nconfigs,
__GLXvisualConfig *configs,
void **privates);
extern void
GlxWrapInitVisuals (miInitVisualsProcPtr *);
extern int
GlxInitVisuals (VisualPtr *visualp,
DepthPtr *depthp,
int *nvisualp,
int *ndepthp,
int *rootDepthp,
VisualID *defaultVisp,
unsigned long sizes,
int bitsPerRGB,
int preferredVis);
extern void
__glXFlushContextCache (void);
extern __GLXscreenInfo __glDDXScreenInfo;
extern __glProcTable __glMesaRenderTable;
extern __glProcTableEXT __glMesaRenderTableEXT;
typedef Bool (*GLXScreenProbeProc) (int screen);
typedef __GLinterface *(*GLXCreateContextProc) (__GLimports *imports,
__GLcontextModes *modes,
__GLinterface *shareGC);
typedef void (*GLXCreateBufferProc) (__GLXdrawablePrivate *glxPriv);
typedef GLboolean (*GLXSwapBuffersProc) (__GLXdrawablePrivate *glxPriv);
typedef int (*GLXBindBuffersProc) (__GLXdrawablePrivate *glxPriv,
int buffer);
typedef int (*GLXReleaseBuffersProc) (__GLXdrawablePrivate *glxPriv,
int buffer);
typedef struct _xglGLXScreenInfo {
GLXScreenProbeProc screenProbe;
GLXCreateContextProc createContext;
GLXCreateBufferProc createBuffer;
} xglGLXScreenInfoRec, *xglGLXScreenInfoPtr;
static xglGLXScreenInfoRec screenInfoPriv;
typedef GLboolean (*GLResizeBuffersProc) (__GLdrawableBuffer *buffer,
GLint x,
GLint y,
GLuint width,
GLuint height,
__GLdrawablePrivate *glPriv,
GLuint bufferMask);
typedef void (*GLFreeBuffersProc) (__GLdrawablePrivate *glPriv);
typedef struct _xglGLBuffer {
GLXSwapBuffersProc swapBuffers;
GLXBindBuffersProc bindBuffers;
GLXReleaseBuffersProc releaseBuffers;
GLResizeBuffersProc resizeBuffers;
GLFreeBuffersProc freeBuffers;
ScreenPtr pScreen;
DrawablePtr pDrawable;
glitz_surface_t *backSurface;
PixmapPtr pPixmap;
GCPtr pGC;
RegionRec damage;
void *private;
int xOff, yOff;
int yFlip;
} xglGLBufferRec, *xglGLBufferPtr;
typedef int xglGLXVisualConfigRec, *xglGLXVisualConfigPtr;
typedef struct _xglDisplayList *xglDisplayListPtr;
#define XGL_LIST_OP_CALLS 0
#define XGL_LIST_OP_DRAW 1
#define XGL_LIST_OP_GL 2
#define XGL_LIST_OP_LIST 3
typedef struct _xglGLOp {
void (*glProc) (struct _xglGLOp *pOp);
union {
GLenum enumeration;
GLbitfield bitfield;
GLsizei size;
struct {
GLint x;
GLint y;
GLsizei width;
GLsizei height;
} rect;
struct {
GLenum target;
GLuint texture;
} bind_texture;
struct {
GLenum target;
GLenum pname;
GLint params[4];
} tex_parameter_iv;
struct {
GLenum target;
GLenum pname;
GLfloat params[4];
} tex_parameter_fv;
struct {
GLint x;
GLint y;
GLsizei width;
GLsizei height;
GLenum type;
} copy_pixels;
struct {
GLenum target;
GLint level;
GLenum internalformat;
GLint x;
GLint y;
GLsizei width;
GLint border;
} copy_tex_image_1d;
struct {
GLenum target;
GLint level;
GLenum internalformat;
GLint x;
GLint y;
GLsizei width;
GLsizei height;
GLint border;
} copy_tex_image_2d;
struct {
GLenum target;
GLint level;
GLint xoffset;
GLint x;
GLint y;
GLsizei width;
} copy_tex_sub_image_1d;
struct {
GLenum target;
GLint level;
GLint xoffset;
GLint yoffset;
GLint x;
GLint y;
GLsizei width;
GLsizei height;
} copy_tex_sub_image_2d;
struct {
GLenum target;
GLenum internalformat;
GLint x;
GLint y;
GLsizei width;
} copy_color_table;
struct {
GLenum target;
GLsizei start;
GLint x;
GLint y;
GLsizei width;
} copy_color_sub_table;
struct {
GLenum target;
GLenum internalformat;
GLint x;
GLint y;
GLsizei width;
} copy_convolution_filter_1d;
struct {
GLenum target;
GLenum internalformat;
GLint x;
GLint y;
GLsizei width;
GLsizei height;
} copy_convolution_filter_2d;
struct {
GLenum target;
GLint level;
GLint xoffset;
GLint yoffset;
GLint zoffset;
GLint x;
GLint y;
GLsizei width;
GLsizei height;
} copy_tex_sub_image_3d;
struct {
GLfloat x;
GLfloat y;
GLfloat z;
} window_pos_3f;
} u;
} xglGLOpRec, *xglGLOpPtr;
typedef struct _xglListOp {
int type;
union {
GLuint list;
xglGLOpPtr gl;
} u;
} xglListOpRec, *xglListOpPtr;
typedef struct _xglDisplayList {
xglListOpPtr pOp;
int nOp;
int size;
} xglDisplayListRec;
typedef struct _xglTexObj {
GLuint key;
GLuint name;
PixmapPtr pPixmap;
int refcnt;
} xglTexObjRec, *xglTexObjPtr;
typedef struct _xglTexUnit {
GLbitfield enabled;
xglTexObjPtr p1D;
xglTexObjPtr p2D;
xglTexObjPtr p3D;
xglTexObjPtr pRect;
xglTexObjPtr pCubeMap;
} xglTexUnitRec, *xglTexUnitPtr;
typedef struct _xglGLAttributes {
GLbitfield mask;
GLenum drawBuffer;
GLenum readBuffer;
xRectangle viewport;
xRectangle scissor;
GLboolean scissorTest;
xglTexUnitRec texUnits[XGL_MAX_TEXTURE_UNITS];
} xglGLAttributesRec, *xglGLAttributesPtr;
typedef struct _xglGLContext {
__GLinterface iface;
__GLinterface *mIface;
int refcnt;
struct _xglGLContext *shared;
glitz_context_t *context;
__glProcTableEXT glRenderTableEXT;
PFNGLACTIVETEXTUREARBPROC ActiveTextureARB;
PFNGLWINDOWPOS3FMESAPROC WindowPos3fMESA;
Bool needInit;
xglGLBufferPtr pDrawBuffer;
xglGLBufferPtr pReadBuffer;
int drawXoff, drawYoff;
char *versionString;
GLenum errorValue;
GLboolean doubleBuffer;
GLint depthBits;
GLint stencilBits;
xglHashTablePtr texObjects;
xglHashTablePtr displayLists;
GLuint list;
GLenum listMode;
xglDisplayListPtr pList;
GLuint groupList;
xglGLAttributesRec attrib;
xglGLAttributesPtr pAttribStack;
int nAttribStack;
int activeTexUnit;
GLint maxTexUnits;
GLint maxListNesting;
} xglGLContextRec, *xglGLContextPtr;
static xglGLContextPtr cctx = NULL;
static void
xglSetCurrentContext (xglGLContextPtr pContext);
#define XGL_GLX_INTERSECT_BOX(pBox1, pBox2) \
{ \
if ((pBox1)->x1 < (pBox2)->x1) \
(pBox1)->x1 = (pBox2)->x1; \
if ((pBox1)->y1 < (pBox2)->y1) \
(pBox1)->y1 = (pBox2)->y1; \
if ((pBox1)->x2 > (pBox2)->x2) \
(pBox1)->x2 = (pBox2)->x2; \
if ((pBox1)->y2 > (pBox2)->y2) \
(pBox1)->y2 = (pBox2)->y2; \
}
#define XGL_GLX_SET_SCISSOR_BOX(pBox) \
glScissor ((pBox)->x1, \
cctx->pDrawBuffer->yFlip - (pBox)->y2, \
(pBox)->x2 - (pBox)->x1, \
(pBox)->y2 - (pBox)->y1)
#define XGL_GLX_DRAW_PROLOGUE(pBox, nBox, pScissorBox) \
(pBox) = REGION_RECTS (cctx->pDrawBuffer->pGC->pCompositeClip); \
(nBox) = REGION_NUM_RECTS (cctx->pDrawBuffer->pGC->pCompositeClip); \
(pScissorBox)->x1 = cctx->attrib.scissor.x + cctx->pDrawBuffer->xOff; \
(pScissorBox)->x2 = (pScissorBox)->x1 + cctx->attrib.scissor.width; \
(pScissorBox)->y2 = cctx->attrib.scissor.y + cctx->pDrawBuffer->yOff; \
(pScissorBox)->y2 = cctx->pDrawBuffer->yFlip - (pScissorBox)->y2; \
(pScissorBox)->y1 = (pScissorBox)->y2 - cctx->attrib.scissor.height; \
xglSetupTextures ()
#define XGL_GLX_DRAW_DAMAGE(pBox, pRegion) \
if (cctx->attrib.drawBuffer != GL_BACK && \
cctx->pDrawBuffer->pDrawable && \
cctx->pDrawBuffer->pDrawable->type != DRAWABLE_PIXMAP) \
{ \
REGION_INIT (cctx->pDrawBuffer->pGC->pScreen, pRegion, pBox, 1); \
REGION_UNION (cctx->pDrawBuffer->pGC->pScreen, \
&cctx->pDrawBuffer->damage, \
&cctx->pDrawBuffer->damage, \
pRegion); \
REGION_UNINIT (cctx->pDrawBuffer->pGC->pScreen, pRegion); \
}
static void
xglRecordError (GLenum error)
{
if (cctx->errorValue == GL_NO_ERROR)
cctx->errorValue = error;
}
static xglDisplayListPtr
xglCreateList (void)
{
xglDisplayListPtr pDisplayList;
pDisplayList = xalloc (sizeof (xglDisplayListRec));
if (!pDisplayList)
return NULL;
pDisplayList->pOp = NULL;
pDisplayList->nOp = 0;
pDisplayList->size = 0;
return pDisplayList;
}
static void
xglDestroyList (xglDisplayListPtr pDisplayList)
{
xglListOpPtr pOp = pDisplayList->pOp;
int nOp = pDisplayList->nOp;
while (nOp--)
{
switch (pOp->type) {
case XGL_LIST_OP_CALLS:
case XGL_LIST_OP_DRAW:
glDeleteLists (pOp->u.list, 1);
break;
case XGL_LIST_OP_GL:
xfree (pOp->u.gl);
break;
case XGL_LIST_OP_LIST:
break;
}
pOp++;
}
if (pDisplayList->pOp)
xfree (pDisplayList->pOp);
xfree (pDisplayList);
}
static Bool
xglResizeList (xglDisplayListPtr pDisplayList,
int nOp)
{
if (pDisplayList->size < nOp)
{
int size = pDisplayList->nOp ? pDisplayList->nOp : 4;
while (size < nOp)
size <<= 1;
pDisplayList->pOp = xrealloc (pDisplayList->pOp,
sizeof (xglListOpRec) * size);
if (!pDisplayList->pOp)
return FALSE;
pDisplayList->size = size;
}
return TRUE;
}
static void
xglStartList (int type,
GLenum mode)
{
if (!xglResizeList (cctx->pList, cctx->pList->nOp + 1))
{
xglRecordError (GL_OUT_OF_MEMORY);
return;
}
cctx->pList->pOp[cctx->pList->nOp].type = type;
cctx->pList->pOp[cctx->pList->nOp].u.list = glGenLists (1);
glNewList (cctx->pList->pOp[cctx->pList->nOp].u.list, mode);
cctx->pList->nOp++;
}
static void
xglGLOp (xglGLOpPtr pOp)
{
if (cctx->list)
{
xglGLOpPtr pGLOp;
pGLOp = xalloc (sizeof (xglGLOpRec));
if (!pGLOp)
{
xglRecordError (GL_OUT_OF_MEMORY);
return;
}
if (!xglResizeList (cctx->pList, cctx->pList->nOp + 1))
{
xfree (pGLOp);
xglRecordError (GL_OUT_OF_MEMORY);
return;
}
glEndList ();
*pGLOp = *pOp;
cctx->pList->pOp[cctx->pList->nOp].type = XGL_LIST_OP_GL;
cctx->pList->pOp[cctx->pList->nOp].u.gl = pGLOp;
cctx->pList->nOp++;
if (cctx->listMode == GL_COMPILE_AND_EXECUTE)
(*pOp->glProc) (pOp);
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
else
(*pOp->glProc) (pOp);
}
static void
xglViewportProc (xglGLOpPtr pOp)
{
cctx->attrib.viewport.x = pOp->u.rect.x;
cctx->attrib.viewport.y = pOp->u.rect.y;
cctx->attrib.viewport.width = pOp->u.rect.width;
cctx->attrib.viewport.height = pOp->u.rect.height;
glViewport (pOp->u.rect.x + cctx->pDrawBuffer->xOff,
pOp->u.rect.y + cctx->pDrawBuffer->yOff,
pOp->u.rect.width,
pOp->u.rect.height);
}
static void
xglViewport (GLint x,
GLint y,
GLsizei width,
GLsizei height)
{
xglGLOpRec gl;
gl.glProc = xglViewportProc;
gl.u.rect.x = x;
gl.u.rect.y = y;
gl.u.rect.width = width;
gl.u.rect.height = height;
xglGLOp (&gl);
}
static void
xglScissorProc (xglGLOpPtr pOp)
{
cctx->attrib.scissor.x = pOp->u.rect.x;
cctx->attrib.scissor.y = pOp->u.rect.y;
cctx->attrib.scissor.width = pOp->u.rect.width;
cctx->attrib.scissor.height = pOp->u.rect.height;
}
static void
xglScissor (GLint x,
GLint y,
GLsizei width,
GLsizei height)
{
xglGLOpRec gl;
gl.glProc = xglScissorProc;
gl.u.rect.x = x;
gl.u.rect.y = y;
gl.u.rect.width = width;
gl.u.rect.height = height;
xglGLOp (&gl);
}
static void
xglDrawBufferProc (xglGLOpPtr pOp)
{
switch (pOp->u.enumeration) {
case GL_FRONT:
case GL_FRONT_AND_BACK:
break;
case GL_BACK:
if (!cctx->doubleBuffer)
{
xglRecordError (GL_INVALID_OPERATION);
return;
}
break;
default:
xglRecordError (GL_INVALID_ENUM);
return;
}
cctx->attrib.drawBuffer = pOp->u.enumeration;
glDrawBuffer (pOp->u.enumeration);
}
static void
xglDrawBuffer (GLenum mode)
{
xglGLOpRec gl;
gl.glProc = xglDrawBufferProc;
gl.u.enumeration = mode;
xglGLOp (&gl);
}
static void
xglReadBufferProc (xglGLOpPtr pOp)
{
switch (pOp->u.enumeration) {
case GL_FRONT:
break;
case GL_BACK:
if (!cctx->doubleBuffer)
{
xglRecordError (GL_INVALID_OPERATION);
return;
}
break;
default:
xglRecordError (GL_INVALID_ENUM);
return;
}
cctx->attrib.readBuffer = pOp->u.enumeration;
glReadBuffer (pOp->u.enumeration);
}
static void
xglReadBuffer (GLenum mode)
{
xglGLOpRec gl;
gl.glProc = xglReadBufferProc;
gl.u.enumeration = mode;
xglGLOp (&gl);
}
static void
xglDisableProc (xglGLOpPtr pOp)
{
xglTexUnitPtr pTexUnit = &cctx->attrib.texUnits[cctx->activeTexUnit];
switch (pOp->u.enumeration) {
case GL_SCISSOR_TEST:
cctx->attrib.scissorTest = GL_FALSE;
return;
case GL_TEXTURE_1D:
pTexUnit->enabled &= ~XGL_TEXTURE_1D_BIT;
break;
case GL_TEXTURE_2D:
pTexUnit->enabled &= ~XGL_TEXTURE_2D_BIT;
break;
case GL_TEXTURE_3D:
pTexUnit->enabled &= ~XGL_TEXTURE_3D_BIT;
break;
case GL_TEXTURE_RECTANGLE_NV:
pTexUnit->enabled &= ~XGL_TEXTURE_RECTANGLE_BIT;
break;
case GL_TEXTURE_CUBE_MAP_ARB:
pTexUnit->enabled &= ~XGL_TEXTURE_CUBE_MAP_BIT;
break;
default:
break;
}
glDisable (pOp->u.enumeration);
}
static void
xglDisable (GLenum cap)
{
xglGLOpRec gl;
gl.glProc = xglDisableProc;
gl.u.enumeration = cap;
xglGLOp (&gl);
}
static void
xglEnableProc (xglGLOpPtr pOp)
{
xglTexUnitPtr pTexUnit = &cctx->attrib.texUnits[cctx->activeTexUnit];
switch (pOp->u.enumeration) {
case GL_SCISSOR_TEST:
cctx->attrib.scissorTest = GL_TRUE;
return;
case GL_DEPTH_TEST:
if (!cctx->depthBits)
return;
case GL_STENCIL_TEST:
if (!cctx->stencilBits)
return;
case GL_TEXTURE_1D:
pTexUnit->enabled |= XGL_TEXTURE_1D_BIT;
break;
case GL_TEXTURE_2D:
pTexUnit->enabled |= XGL_TEXTURE_2D_BIT;
break;
case GL_TEXTURE_3D:
pTexUnit->enabled |= XGL_TEXTURE_3D_BIT;
break;
case GL_TEXTURE_RECTANGLE_NV:
pTexUnit->enabled |= XGL_TEXTURE_RECTANGLE_BIT;
break;
case GL_TEXTURE_CUBE_MAP_ARB:
pTexUnit->enabled |= XGL_TEXTURE_CUBE_MAP_BIT;
break;
default:
break;
}
glEnable (pOp->u.enumeration);
}
static void
xglEnable (GLenum cap)
{
xglGLOpRec gl;
gl.glProc = xglEnableProc;
gl.u.enumeration = cap;
xglGLOp (&gl);
}
static void
xglDeleteTexObj (xglTexObjPtr pTexObj)
{
if (pTexObj->pPixmap)
{
ScreenPtr pScreen = pTexObj->pPixmap->drawable.pScreen;
(*pScreen->DestroyPixmap) (pTexObj->pPixmap);
}
if (pTexObj->name)
{
glDeleteTextures (1, &pTexObj->name);
}
pTexObj->key = 0;
pTexObj->name = 0;
pTexObj->pPixmap = NULL;
}
static void
xglRefTexObj (xglTexObjPtr pTexObj)
{
if (!pTexObj)
return;
pTexObj->refcnt++;
}
static void
xglUnrefTexObj (xglTexObjPtr pTexObj)
{
if (!pTexObj)
return;
pTexObj->refcnt--;
if (pTexObj->refcnt)
return;
xglDeleteTexObj (pTexObj);
xfree (pTexObj);
}
static void
xglPushAttribProc (xglGLOpPtr pOp)
{
xglGLAttributesPtr pAttrib;
GLint depth;
glGetIntegerv (GL_MAX_ATTRIB_STACK_DEPTH, &depth);
if (cctx->nAttribStack == depth)
{
xglRecordError (GL_STACK_OVERFLOW);
return;
}
cctx->pAttribStack =
realloc (cctx->pAttribStack,
sizeof (xglGLAttributesRec) * (cctx->nAttribStack + 1));
if (!cctx->pAttribStack)
{
xglRecordError (GL_OUT_OF_MEMORY);
return;
}
pAttrib = &cctx->pAttribStack[cctx->nAttribStack];
pAttrib->mask = pOp->u.bitfield;
*pAttrib = cctx->attrib;
if (pOp->u.bitfield & GL_TEXTURE_BIT)
{
int i;
for (i = 0; i < cctx->maxTexUnits; i++)
{
xglRefTexObj (pAttrib->texUnits[i].p1D);
xglRefTexObj (pAttrib->texUnits[i].p2D);
xglRefTexObj (pAttrib->texUnits[i].p3D);
xglRefTexObj (pAttrib->texUnits[i].pRect);
xglRefTexObj (pAttrib->texUnits[i].pCubeMap);
}
}
cctx->nAttribStack++;
glPushAttrib (pOp->u.bitfield);
}
static void
xglPushAttrib (GLbitfield mask)
{
xglGLOpRec gl;
gl.glProc = xglPushAttribProc;
gl.u.bitfield = mask;
xglGLOp (&gl);
}
static void
xglPopAttribProc (xglGLOpPtr pOp)
{
xglGLAttributesPtr pAttrib;
GLbitfield mask;
if (!cctx->nAttribStack)
{
xglRecordError (GL_STACK_UNDERFLOW);
return;
}
cctx->nAttribStack--;
pAttrib = &cctx->pAttribStack[cctx->nAttribStack];
mask = pAttrib->mask;
if (mask & GL_COLOR_BUFFER_BIT)
xglDrawBuffer (pAttrib->drawBuffer);
if (mask & GL_PIXEL_MODE_BIT)
xglReadBuffer (pAttrib->readBuffer);
if (mask & GL_SCISSOR_BIT)
{
xglScissor (pAttrib->scissor.x,
pAttrib->scissor.y,
pAttrib->scissor.width,
pAttrib->scissor.height);
if (pAttrib->scissorTest)
xglEnable (GL_SCISSOR_TEST);
else
xglDisable (GL_SCISSOR_TEST);
}
else if (mask & GL_ENABLE_BIT)
{
if (pAttrib->scissorTest)
xglEnable (GL_SCISSOR_TEST);
else
xglDisable (GL_SCISSOR_TEST);
}
if (mask & GL_VIEWPORT_BIT)
xglViewport (pAttrib->viewport.x,
pAttrib->viewport.y,
pAttrib->viewport.width,
pAttrib->viewport.height);
if (mask & GL_TEXTURE_BIT)
{
int i;
for (i = 0; i < cctx->maxTexUnits; i++)
{
xglUnrefTexObj (cctx->attrib.texUnits[i].p1D);
xglUnrefTexObj (cctx->attrib.texUnits[i].p2D);
xglUnrefTexObj (cctx->attrib.texUnits[i].p3D);
xglUnrefTexObj (cctx->attrib.texUnits[i].pRect);
xglUnrefTexObj (cctx->attrib.texUnits[i].pCubeMap);
cctx->attrib.texUnits[i] = pAttrib->texUnits[i];
}
}
else if (mask & GL_ENABLE_BIT)
{
int i;
for (i = 0; i < cctx->maxTexUnits; i++)
cctx->attrib.texUnits[i].enabled = pAttrib->texUnits[i].enabled;
}
cctx->pAttribStack =
realloc (cctx->pAttribStack,
sizeof (xglGLAttributesRec) * cctx->nAttribStack);
glPopAttrib ();
}
static void
xglPopAttrib (void)
{
xglGLOpRec gl;
gl.glProc = xglPopAttribProc;
xglGLOp (&gl);
}
static GLuint
xglActiveTextureBinding (GLenum target)
{
xglTexObjPtr pTexObj;
switch (target) {
case GL_TEXTURE_BINDING_1D:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p1D;
break;
case GL_TEXTURE_BINDING_2D:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
break;
case GL_TEXTURE_BINDING_3D:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p3D;
break;
case GL_TEXTURE_BINDING_RECTANGLE_NV:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
break;
case GL_TEXTURE_BINDING_CUBE_MAP_ARB:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pCubeMap;
break;
default:
return 0;
}
if (pTexObj)
return pTexObj->key;
return 0;
}
#define DOUBLE_TO_BOOLEAN(X) ((X) ? GL_TRUE : GL_FALSE)
#define INT_TO_BOOLEAN(I) ((I) ? GL_TRUE : GL_FALSE)
#define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE)
static void
xglGetBooleanv (GLenum pname,
GLboolean *params)
{
switch (pname) {
case GL_CURRENT_RASTER_POSITION:
{
GLdouble v[4];
glGetDoublev (GL_CURRENT_RASTER_POSITION, v);
params[0] = DOUBLE_TO_BOOLEAN (v[0] - (GLdouble) cctx->drawXoff);
params[1] = DOUBLE_TO_BOOLEAN (v[1] - (GLdouble) cctx->drawYoff);
params[2] = DOUBLE_TO_BOOLEAN (v[2]);
params[3] = DOUBLE_TO_BOOLEAN (v[3]);
} break;
case GL_DOUBLEBUFFER:
params[0] = cctx->doubleBuffer;
break;
case GL_DEPTH_BITS:
params[0] = INT_TO_BOOLEAN (cctx->depthBits);
break;
case GL_STENCIL_BITS:
params[0] = INT_TO_BOOLEAN (cctx->stencilBits);
break;
case GL_DRAW_BUFFER:
params[0] = ENUM_TO_BOOLEAN (cctx->attrib.drawBuffer);
break;
case GL_READ_BUFFER:
params[0] = ENUM_TO_BOOLEAN (cctx->attrib.readBuffer);
break;
case GL_SCISSOR_BOX:
params[0] = INT_TO_BOOLEAN (cctx->attrib.scissor.x);
params[1] = INT_TO_BOOLEAN (cctx->attrib.scissor.y);
params[2] = INT_TO_BOOLEAN (cctx->attrib.scissor.width);
params[3] = INT_TO_BOOLEAN (cctx->attrib.scissor.height);
break;
case GL_SCISSOR_TEST:
params[0] = cctx->attrib.scissorTest;
break;
case GL_VIEWPORT:
params[0] = INT_TO_BOOLEAN (cctx->attrib.viewport.x);
params[1] = INT_TO_BOOLEAN (cctx->attrib.viewport.y);
params[2] = INT_TO_BOOLEAN (cctx->attrib.viewport.width);
params[3] = INT_TO_BOOLEAN (cctx->attrib.viewport.height);
break;
case GL_TEXTURE_BINDING_1D:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_3D:
case GL_TEXTURE_RECTANGLE_NV:
/* should be safe to fall-through here */
default:
glGetBooleanv (pname, params);
}
}
#define INT_TO_DOUBLE(I) ((GLdouble) (I))
#define ENUM_TO_DOUBLE(E) ((GLdouble) (E))
#define BOOLEAN_TO_DOUBLE(B) ((B) ? 1.0F : 0.0F)
static void
xglGetDoublev (GLenum pname,
GLdouble *params)
{
switch (pname) {
case GL_CURRENT_RASTER_POSITION:
glGetDoublev (GL_CURRENT_RASTER_POSITION, params);
params[0] -= (GLdouble) cctx->drawXoff;
params[1] -= (GLdouble) cctx->drawYoff;
break;
case GL_DOUBLEBUFFER:
params[0] = BOOLEAN_TO_DOUBLE (cctx->doubleBuffer);
break;
case GL_DEPTH_BITS:
params[0] = INT_TO_DOUBLE (cctx->depthBits);
break;
case GL_STENCIL_BITS:
params[0] = INT_TO_DOUBLE (cctx->stencilBits);
break;
case GL_DRAW_BUFFER:
params[0] = ENUM_TO_DOUBLE (cctx->attrib.drawBuffer);
break;
case GL_READ_BUFFER:
params[0] = ENUM_TO_DOUBLE (cctx->attrib.readBuffer);
break;
case GL_SCISSOR_BOX:
params[0] = cctx->attrib.scissor.x;
params[1] = cctx->attrib.scissor.y;
params[2] = cctx->attrib.scissor.width;
params[3] = cctx->attrib.scissor.height;
break;
case GL_SCISSOR_TEST:
params[0] = BOOLEAN_TO_DOUBLE (cctx->attrib.scissorTest);
break;
case GL_VIEWPORT:
params[0] = cctx->attrib.viewport.x;
params[1] = cctx->attrib.viewport.y;
params[2] = cctx->attrib.viewport.width;
params[3] = cctx->attrib.viewport.height;
break;
case GL_TEXTURE_BINDING_1D:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_3D:
case GL_TEXTURE_RECTANGLE_NV:
params[0] = xglActiveTextureBinding (pname);
break;
case GL_MAX_TEXTURE_UNITS_ARB:
params[0] = cctx->maxTexUnits;
break;
default:
glGetDoublev (pname, params);
}
}
#define INT_TO_FLOAT(I) ((GLfloat) (I))
#define ENUM_TO_FLOAT(E) ((GLfloat) (E))
#define BOOLEAN_TO_FLOAT(B) ((B) ? 1.0F : 0.0F)
static void
xglGetFloatv (GLenum pname,
GLfloat *params)
{
switch (pname) {
case GL_CURRENT_RASTER_POSITION:
glGetFloatv (GL_CURRENT_RASTER_POSITION, params);
params[0] -= (GLfloat) cctx->drawXoff;
params[1] -= (GLfloat) cctx->drawYoff;
break;
case GL_DOUBLEBUFFER:
params[0] = BOOLEAN_TO_FLOAT (cctx->doubleBuffer);
break;
case GL_DEPTH_BITS:
params[0] = INT_TO_FLOAT (cctx->depthBits);
break;
case GL_STENCIL_BITS:
params[0] = INT_TO_FLOAT (cctx->stencilBits);
break;
case GL_DRAW_BUFFER:
params[0] = ENUM_TO_FLOAT (cctx->attrib.drawBuffer);
break;
case GL_READ_BUFFER:
params[0] = ENUM_TO_FLOAT (cctx->attrib.readBuffer);
break;
case GL_SCISSOR_BOX:
params[0] = cctx->attrib.scissor.x;
params[1] = cctx->attrib.scissor.y;
params[2] = cctx->attrib.scissor.width;
params[3] = cctx->attrib.scissor.height;
break;
case GL_SCISSOR_TEST:
params[0] = BOOLEAN_TO_FLOAT (cctx->attrib.scissorTest);
break;
case GL_VIEWPORT:
params[0] = cctx->attrib.viewport.x;
params[1] = cctx->attrib.viewport.y;
params[2] = cctx->attrib.viewport.width;
params[3] = cctx->attrib.viewport.height;
break;
case GL_TEXTURE_BINDING_1D:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_3D:
case GL_TEXTURE_RECTANGLE_NV:
params[0] = xglActiveTextureBinding (pname);
break;
case GL_MAX_TEXTURE_UNITS_ARB:
params[0] = cctx->maxTexUnits;
break;
default:
glGetFloatv (pname, params);
}
}
#define ENUM_TO_INT(E) ((GLint) (E))
#define BOOLEAN_TO_INT(B) ((GLint) (B))
static void
xglGetIntegerv (GLenum pname,
GLint *params)
{
switch (pname) {
case GL_CURRENT_RASTER_POSITION:
glGetIntegerv (GL_CURRENT_RASTER_POSITION, params);
params[0] -= (GLint) cctx->drawXoff;
params[1] -= (GLint) cctx->drawYoff;
break;
case GL_DOUBLEBUFFER:
params[0] = BOOLEAN_TO_INT (cctx->doubleBuffer);
break;
case GL_DEPTH_BITS:
params[0] = cctx->depthBits;
break;
case GL_STENCIL_BITS:
params[0] = cctx->stencilBits;
break;
case GL_DRAW_BUFFER:
params[0] = ENUM_TO_INT (cctx->attrib.drawBuffer);
break;
case GL_READ_BUFFER:
params[0] = ENUM_TO_INT (cctx->attrib.readBuffer);
break;
case GL_SCISSOR_BOX:
params[0] = cctx->attrib.scissor.x;
params[1] = cctx->attrib.scissor.y;
params[2] = cctx->attrib.scissor.width;
params[3] = cctx->attrib.scissor.height;
break;
case GL_SCISSOR_TEST:
params[0] = BOOLEAN_TO_INT (cctx->attrib.scissorTest);
break;
case GL_VIEWPORT:
params[0] = cctx->attrib.viewport.x;
params[1] = cctx->attrib.viewport.y;
params[2] = cctx->attrib.viewport.width;
params[3] = cctx->attrib.viewport.height;
break;
case GL_TEXTURE_BINDING_1D:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_3D:
case GL_TEXTURE_RECTANGLE_NV:
params[0] = xglActiveTextureBinding (pname);
break;
case GL_MAX_TEXTURE_UNITS_ARB:
params[0] = cctx->maxTexUnits;
break;
default:
glGetIntegerv (pname, params);
}
}
static GLboolean
xglIsEnabled (GLenum cap)
{
switch (cap) {
case GL_SCISSOR_TEST:
return cctx->attrib.scissorTest;
default:
return glIsEnabled (cap);
}
}
static GLenum
xglGetError (void)
{
GLenum error = cctx->errorValue;
if (error != GL_NO_ERROR)
{
cctx->errorValue = GL_NO_ERROR;
return error;
}
return glGetError ();
}
static const GLubyte *
xglGetString (GLenum name)
{
switch (name) {
case GL_VERSION:
if (!cctx->versionString)
{
static char *version = "1.2 (%s)";
char *nativeVersion = (char *) glGetString (GL_VERSION);
cctx->versionString = xalloc (strlen (version) +
strlen (nativeVersion));
if (cctx->versionString)
sprintf (cctx->versionString, version, nativeVersion);
}
return (GLubyte *) cctx->versionString;
default:
return glGetString (name);
}
}
static void
xglGenTextures (GLsizei n,
GLuint *textures)
{
xglTexObjPtr pTexObj;
GLuint name;
name = xglHashFindFreeKeyBlock (cctx->shared->texObjects, n);
glGenTextures (n, textures);
while (n--)
{
pTexObj = xalloc (sizeof (xglTexObjRec));
if (pTexObj)
{
pTexObj->key = name;
pTexObj->name = *textures;
pTexObj->pPixmap = NULL;
pTexObj->refcnt = 1;
xglHashInsert (cctx->shared->texObjects, name, pTexObj);
}
else
{
xglRecordError (GL_OUT_OF_MEMORY);
}
*textures++ = name++;
}
}
static void
xglBindTextureProc (xglGLOpPtr pOp)
{
xglTexObjPtr *ppTexObj;
switch (pOp->u.bind_texture.target) {
case GL_TEXTURE_1D:
ppTexObj = &cctx->attrib.texUnits[cctx->activeTexUnit].p1D;
break;
case GL_TEXTURE_2D:
ppTexObj = &cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
break;
case GL_TEXTURE_3D:
ppTexObj = &cctx->attrib.texUnits[cctx->activeTexUnit].p3D;
break;
case GL_TEXTURE_RECTANGLE_NV:
ppTexObj = &cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
break;
case GL_TEXTURE_CUBE_MAP_ARB:
ppTexObj = &cctx->attrib.texUnits[cctx->activeTexUnit].pCubeMap;
break;
default:
xglRecordError (GL_INVALID_ENUM);
return;
}
if (pOp->u.bind_texture.texture)
{
xglTexObjPtr pTexObj;
pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects,
pOp->u.bind_texture.texture);
if (!pTexObj)
{
pTexObj = xalloc (sizeof (xglTexObjRec));
if (!pTexObj)
{
xglRecordError (GL_OUT_OF_MEMORY);
return;
}
pTexObj->key = pOp->u.bind_texture.texture;
pTexObj->pPixmap = NULL;
pTexObj->refcnt = 1;
glGenTextures (1, &pTexObj->name);
xglHashInsert (cctx->shared->texObjects,
pOp->u.bind_texture.texture,
pTexObj);
}
xglRefTexObj (pTexObj);
xglUnrefTexObj (*ppTexObj);
*ppTexObj = pTexObj;
glBindTexture (pOp->u.bind_texture.target, pTexObj->name);
}
else
{
xglUnrefTexObj (*ppTexObj);
*ppTexObj = NULL;
glBindTexture (pOp->u.bind_texture.target, 0);
}
}
static void
xglBindTexture (GLenum target,
GLuint texture)
{
xglGLOpRec gl;
gl.glProc = xglBindTextureProc;
gl.u.bind_texture.target = target;
gl.u.bind_texture.texture = texture;
xglGLOp (&gl);
}
static void
xglSetupTextures (void)
{
xglGLContextPtr pContext = cctx;
xglTexUnitPtr pTexUnit;
xglTexObjPtr pTexObj[XGL_MAX_TEXTURE_UNITS];
int i, activeTexUnit;
for (i = 0; i < pContext->maxTexUnits; i++)
{
pTexObj[i] = NULL;
pTexUnit = &pContext->attrib.texUnits[i];
if (pTexUnit->enabled)
{
if (pTexUnit->enabled & XGL_TEXTURE_RECTANGLE_BIT)
pTexObj[i] = pTexUnit->pRect;
else if (pTexUnit->enabled & XGL_TEXTURE_2D_BIT)
pTexObj[i] = pTexUnit->p2D;
if (pTexObj[i] && pTexObj[i]->pPixmap)
{
if (!xglSyncSurface (&pTexObj[i]->pPixmap->drawable))
pTexObj[i] = NULL;
}
else
pTexObj[i] = NULL;
}
}
if (pContext != cctx)
{
XGL_SCREEN_PRIV (pContext->pDrawBuffer->pGC->pScreen);
glitz_drawable_finish (pScreenPriv->drawable);
xglSetCurrentContext (pContext);
}
activeTexUnit = cctx->activeTexUnit;
for (i = 0; i < pContext->maxTexUnits; i++)
{
if (pTexObj[i])
{
XGL_PIXMAP_PRIV (pTexObj[i]->pPixmap);
activeTexUnit = GL_TEXTURE0_ARB + i;
cctx->ActiveTextureARB (activeTexUnit);
glitz_context_bind_texture (cctx->context, pPixmapPriv->surface);
}
}
if (cctx->activeTexUnit != activeTexUnit)
cctx->ActiveTextureARB (cctx->activeTexUnit);
}
static GLboolean
xglAreTexturesResident (GLsizei n,
const GLuint *textures,
GLboolean *residences)
{
GLboolean allResident = GL_TRUE;
int i, j;
if (n < 0)
{
xglRecordError (GL_INVALID_VALUE);
return GL_FALSE;
}
if (!textures || !residences)
return GL_FALSE;
for (i = 0; i < n; i++)
{
xglTexObjPtr pTexObj;
GLboolean resident;
if (textures[i] == 0)
{
xglRecordError (GL_INVALID_VALUE);
return GL_FALSE;
}
pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects,
textures[i]);
if (!pTexObj)
{
xglRecordError (GL_INVALID_VALUE);
return GL_FALSE;
}
if (pTexObj->name == 0 ||
glAreTexturesResident (1, &pTexObj->name, &resident))
{
if (!allResident)
residences[i] = GL_TRUE;
}
else
{
if (allResident)
{
allResident = GL_FALSE;
for (j = 0; j < i; j++)
residences[j] = GL_TRUE;
}
residences[i] = GL_FALSE;
}
}
return allResident;
}
static void
xglDeleteTextures (GLsizei n,
const GLuint *textures)
{
xglTexObjPtr pTexObj;
while (n--)
{
pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects,
*textures);
if (pTexObj)
{
xglDeleteTexObj (pTexObj);
xglUnrefTexObj (pTexObj);
xglHashRemove (cctx->shared->texObjects, *textures);
}
textures++;
}
}
static GLboolean
xglIsTexture (GLuint texture)
{
xglTexObjPtr pTexObj;
if (!texture)
return GL_FALSE;
pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects, texture);
if (pTexObj)
return GL_TRUE;
return GL_FALSE;
}
static void
xglPrioritizeTextures (GLsizei n,
const GLuint *textures,
const GLclampf *priorities)
{
xglTexObjPtr pTexObj;
int i;
if (n < 0)
{
xglRecordError (GL_INVALID_VALUE);
return;
}
if (!priorities)
return;
for (i = 0; i < n; i++)
{
if (textures[i] <= 0)
continue;
pTexObj = (xglTexObjPtr) xglHashLookup (cctx->shared->texObjects,
textures[i]);
if (pTexObj && pTexObj->name)
glPrioritizeTextures (1, &pTexObj->name, &priorities[i]);
}
}
static void
xglTexParameterfvProc (xglGLOpPtr pOp)
{
xglTexObjPtr pTexObj;
glTexParameterfv (pOp->u.tex_parameter_fv.target,
pOp->u.tex_parameter_fv.pname,
pOp->u.tex_parameter_fv.params);
switch (pOp->u.tex_parameter_fv.target) {
case GL_TEXTURE_2D:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
break;
case GL_TEXTURE_RECTANGLE_NV:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
break;
default:
pTexObj = NULL;
break;
}
if (pTexObj && pTexObj->pPixmap)
{
XGL_PIXMAP_PRIV (pTexObj->pPixmap);
/* texture parameters should eventually go into a
glitz_texture_object_t */
glitz_context_bind_texture (cctx->context, pPixmapPriv->surface);
glTexParameterfv (pOp->u.tex_parameter_fv.target,
pOp->u.tex_parameter_fv.pname,
pOp->u.tex_parameter_fv.params);
glBindTexture (pOp->u.tex_parameter_fv.target, pTexObj->name);
}
}
static void
xglTexParameterfv (GLenum target,
GLenum pname,
const GLfloat *params)
{
xglGLOpRec gl;
gl.glProc = xglTexParameterfvProc;
gl.u.tex_parameter_fv.target = target;
gl.u.tex_parameter_fv.pname = pname;
switch (pname) {
case GL_TEXTURE_BORDER_COLOR:
gl.u.tex_parameter_fv.params[3] = params[3];
gl.u.tex_parameter_fv.params[2] = params[2];
gl.u.tex_parameter_fv.params[1] = params[1];
/* fall-through */
default:
gl.u.tex_parameter_fv.params[0] = params[0];
break;
}
xglGLOp (&gl);
}
static void
xglTexParameterivProc (xglGLOpPtr pOp)
{
xglTexObjPtr pTexObj;
glTexParameteriv (pOp->u.tex_parameter_iv.target,
pOp->u.tex_parameter_iv.pname,
pOp->u.tex_parameter_iv.params);
switch (pOp->u.tex_parameter_iv.target) {
case GL_TEXTURE_2D:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
break;
case GL_TEXTURE_RECTANGLE_NV:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
break;
default:
pTexObj = NULL;
break;
}
if (pTexObj && pTexObj->pPixmap)
{
XGL_PIXMAP_PRIV (pTexObj->pPixmap);
/* texture parameters should eventually go into a
glitz_texture_object_t */
glitz_context_bind_texture (cctx->context, pPixmapPriv->surface);
glTexParameteriv (pOp->u.tex_parameter_iv.target,
pOp->u.tex_parameter_iv.pname,
pOp->u.tex_parameter_iv.params);
glBindTexture (pOp->u.tex_parameter_iv.target, pTexObj->name);
}
}
static void
xglTexParameteriv (GLenum target,
GLenum pname,
const GLint *params)
{
xglGLOpRec gl;
gl.glProc = xglTexParameterivProc;
gl.u.tex_parameter_iv.target = target;
gl.u.tex_parameter_iv.pname = pname;
switch (pname) {
case GL_TEXTURE_BORDER_COLOR:
gl.u.tex_parameter_iv.params[3] = params[3];
gl.u.tex_parameter_iv.params[2] = params[2];
gl.u.tex_parameter_iv.params[1] = params[1];
/* fall-through */
default:
gl.u.tex_parameter_iv.params[0] = params[0];
break;
}
xglGLOp (&gl);
}
static void
xglTexParameterf (GLenum target,
GLenum pname,
GLfloat param)
{
xglTexParameterfv (target, pname, (const GLfloat *) &param);
}
static void
xglTexParameteri (GLenum target,
GLenum pname,
GLint param)
{
xglTexParameteriv (target, pname, (const GLint *) &param);
}
static void
xglGetTexLevelParameterfv (GLenum target,
GLint level,
GLenum pname,
GLfloat *params)
{
xglTexObjPtr pTexObj;
switch (target) {
case GL_TEXTURE_2D:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
break;
case GL_TEXTURE_RECTANGLE_NV:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
break;
default:
pTexObj = NULL;
break;
}
if (pTexObj && pTexObj->pPixmap)
{
XGL_PIXMAP_PRIV (pTexObj->pPixmap);
glitz_context_bind_texture (cctx->context, pPixmapPriv->surface);
glGetTexLevelParameterfv (target, level, pname, params);
glBindTexture (target, pTexObj->name);
}
else
glGetTexLevelParameterfv (target, level, pname, params);
}
static void
xglGetTexLevelParameteriv (GLenum target,
GLint level,
GLenum pname,
GLint *params)
{
xglTexObjPtr pTexObj;
switch (target) {
case GL_TEXTURE_2D:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
break;
case GL_TEXTURE_RECTANGLE_NV:
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
break;
default:
pTexObj = NULL;
break;
}
if (pTexObj && pTexObj->pPixmap)
{
XGL_PIXMAP_PRIV (pTexObj->pPixmap);
glitz_context_bind_texture (cctx->context, pPixmapPriv->surface);
glGetTexLevelParameteriv (target, level, pname, params);
glBindTexture (target, pTexObj->name);
}
else
glGetTexLevelParameteriv (target, level, pname, params);
}
static GLuint
xglGenLists (GLsizei range)
{
xglDisplayListPtr pDisplayList;
GLuint first, name;
first = xglHashFindFreeKeyBlock (cctx->shared->displayLists, range);
name = first;
for (name = first; range--; name++)
{
pDisplayList = xglCreateList ();
if (pDisplayList)
{
xglHashInsert (cctx->shared->displayLists, name, pDisplayList);
}
else
{
xglRecordError (GL_OUT_OF_MEMORY);
}
}
return first;
}
static void
xglNewList (GLuint list,
GLenum mode)
{
if (!list)
{
xglRecordError (GL_INVALID_VALUE);
return;
}
if (cctx->list)
{
xglRecordError (GL_INVALID_OPERATION);
return;
}
cctx->pList = xglCreateList ();
if (!cctx->pList)
{
xglRecordError (GL_OUT_OF_MEMORY);
return;
}
cctx->list = list;
cctx->listMode = mode;
xglStartList (XGL_LIST_OP_CALLS, mode);
}
static void
xglEndList (void)
{
xglDisplayListPtr pDisplayList;
if (!cctx->list)
{
xglRecordError (GL_INVALID_OPERATION);
return;
}
glEndList ();
pDisplayList = (xglDisplayListPtr)
xglHashLookup (cctx->shared->displayLists, cctx->list);
if (pDisplayList)
{
xglHashRemove (cctx->shared->displayLists, cctx->list);
xglDestroyList (pDisplayList);
}
xglHashInsert (cctx->shared->displayLists, cctx->list, cctx->pList);
cctx->list = 0;
}
static void
xglDrawList (GLuint list)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glCallList (list);
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
static void
xglCallDisplayList (GLuint list,
int nesting)
{
if (nesting > cctx->maxListNesting)
return;
if (!list)
{
xglRecordError (GL_INVALID_VALUE);
return;
}
if (cctx->list)
{
if (!xglResizeList (cctx->pList, cctx->pList->nOp + 1))
{
xglRecordError (GL_OUT_OF_MEMORY);
return;
}
cctx->pList->pOp[cctx->pList->nOp].type = XGL_LIST_OP_LIST;
cctx->pList->pOp[cctx->pList->nOp].u.list = list;
cctx->pList->nOp++;
}
else
{
xglDisplayListPtr pDisplayList;
pDisplayList = (xglDisplayListPtr)
xglHashLookup (cctx->shared->displayLists, list);
if (pDisplayList)
{
xglListOpPtr pOp = pDisplayList->pOp;
int nOp = pDisplayList->nOp;
while (nOp--)
{
switch (pOp->type) {
case XGL_LIST_OP_CALLS:
glCallList (pOp->u.list);
break;
case XGL_LIST_OP_DRAW:
xglDrawList (pOp->u.list);
break;
case XGL_LIST_OP_GL:
(*pOp->u.gl->glProc) (pOp->u.gl);
break;
case XGL_LIST_OP_LIST:
xglCallDisplayList (pOp->u.list, nesting + 1);
break;
}
pOp++;
}
}
}
}
static void
xglCallList (GLuint list)
{
xglCallDisplayList (list, 1);
}
static void
xglCallLists (GLsizei n,
GLenum type,
const GLvoid *lists)
{
GLuint list;
GLint base, i;
glGetIntegerv (GL_LIST_BASE, &base);
for (i = 0; i < n; i++)
{
switch (type) {
case GL_BYTE:
list = (GLuint) *(((GLbyte *) lists) + n);
break;
case GL_UNSIGNED_BYTE:
list = (GLuint) *(((GLubyte *) lists) + n);
break;
case GL_SHORT:
list = (GLuint) *(((GLshort *) lists) + n);
break;
case GL_UNSIGNED_SHORT:
list = (GLuint) *(((GLushort *) lists) + n);
break;
case GL_INT:
list = (GLuint) *(((GLint *) lists) + n);
break;
case GL_UNSIGNED_INT:
list = (GLuint) *(((GLuint *) lists) + n);
break;
case GL_FLOAT:
list = (GLuint) *(((GLfloat *) lists) + n);
break;
case GL_2_BYTES:
{
GLubyte *ubptr = ((GLubyte *) lists) + 2 * n;
list = (GLuint) *ubptr * 256 + (GLuint) *(ubptr + 1);
} break;
case GL_3_BYTES:
{
GLubyte *ubptr = ((GLubyte *) lists) + 3 * n;
list = (GLuint) * ubptr * 65536
+ (GLuint) * (ubptr + 1) * 256
+ (GLuint) * (ubptr + 2);
} break;
case GL_4_BYTES:
{
GLubyte *ubptr = ((GLubyte *) lists) + 4 * n;
list = (GLuint) * ubptr * 16777216
+ (GLuint) * (ubptr + 1) * 65536
+ (GLuint) * (ubptr + 2) * 256
+ (GLuint) * (ubptr + 3);
} break;
default:
xglRecordError (GL_INVALID_ENUM);
return;
}
xglCallDisplayList (base + list, 1);
}
}
static void
xglDeleteLists (GLuint list,
GLsizei range)
{
xglDisplayListPtr pDisplayList;
GLint i;
if (range < 0)
{
xglRecordError (GL_INVALID_VALUE);
return;
}
for (i = 0; i < range; i++)
{
pDisplayList = (xglDisplayListPtr)
xglHashLookup (cctx->shared->displayLists, list + i);
if (pDisplayList)
{
xglHashRemove (cctx->shared->displayLists, list + i);
xglDestroyList (pDisplayList);
}
}
}
static GLboolean
xglIsList (GLuint list)
{
xglDisplayListPtr pDisplayList;
if (!list)
return GL_FALSE;
pDisplayList = (xglDisplayListPtr)
xglHashLookup (cctx->shared->displayLists, list);
if (pDisplayList)
return GL_TRUE;
return GL_FALSE;
}
static void
xglFlush (void)
{
glFlush ();
if (cctx->pDrawBuffer->pDrawable)
{
xglGLBufferPtr pBuffer = cctx->pDrawBuffer;
if (REGION_NOTEMPTY (pBuffer->pDrawable->pScreen, &pBuffer->damage))
{
DamageDamageRegion (pBuffer->pDrawable, &pBuffer->damage);
REGION_EMPTY (pBuffer->pDrawable->pScreen, &pBuffer->damage);
}
}
}
static void
xglFinish (void)
{
glFinish ();
if (cctx->pDrawBuffer->pDrawable)
{
xglGLBufferPtr pBuffer = cctx->pDrawBuffer;
if (REGION_NOTEMPTY (pBuffer->pDrawable->pScreen, &pBuffer->damage))
{
DamageDamageRegion (pBuffer->pDrawable, &pBuffer->damage);
REGION_EMPTY (pBuffer->pDrawable->pScreen, &pBuffer->damage);
}
}
}
static void
xglClear (GLbitfield mask)
{
GLenum mode;
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
glClear (mask);
glEndList ();
mode = cctx->listMode;
}
else
mode = GL_COMPILE_AND_EXECUTE;
if (mode == GL_COMPILE_AND_EXECUTE)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glClear (mask);
if (mask & GL_COLOR_BUFFER_BIT)
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
static void
xglAccum (GLenum op,
GLfloat value)
{
if (op == GL_RETURN)
{
GLenum listMode;
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
glAccum (GL_RETURN, value);
glEndList ();
listMode = cctx->listMode;
}
else
listMode = GL_COMPILE_AND_EXECUTE;
if (listMode == GL_COMPILE_AND_EXECUTE)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glAccum (GL_RETURN, value);
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
else
glAccum (op, value);
}
static void
xglDrawArrays (GLenum mode,
GLint first,
GLsizei count)
{
GLenum listMode;
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
glDrawArrays (mode, first, count);
glEndList ();
listMode = cctx->listMode;
}
else
listMode = GL_COMPILE_AND_EXECUTE;
if (listMode == GL_COMPILE_AND_EXECUTE)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glDrawArrays (mode, first, count);
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
static void
xglDrawElements (GLenum mode,
GLsizei count,
GLenum type,
const GLvoid *indices)
{
GLenum listMode;
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
glDrawElements (mode, count, type, indices);
glEndList ();
listMode = cctx->listMode;
}
else
listMode = GL_COMPILE_AND_EXECUTE;
if (listMode == GL_COMPILE_AND_EXECUTE)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glDrawElements (mode, count, type, indices);
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
static void
xglDrawPixels (GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid *pixels)
{
GLenum listMode;
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
glDrawPixels (width, height, format, type, pixels);
glEndList ();
listMode = cctx->listMode;
}
else
listMode = GL_COMPILE_AND_EXECUTE;
if (listMode == GL_COMPILE_AND_EXECUTE)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glDrawPixels (width, height, format, type, pixels);
if (format != GL_STENCIL_INDEX)
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
static void
xglBitmap (GLsizei width,
GLsizei height,
GLfloat xorig,
GLfloat yorig,
GLfloat xmove,
GLfloat ymove,
const GLubyte *bitmap)
{
GLenum listMode;
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
glBitmap (width, height, xorig, yorig, 0, 0, bitmap);
glEndList ();
listMode = cctx->listMode;
}
else
listMode = GL_COMPILE_AND_EXECUTE;
if (listMode == GL_COMPILE_AND_EXECUTE && width && height)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glBitmap (width, height, xorig, yorig, 0, 0, bitmap);
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
glBitmap (0, 0, 0, 0, xmove, ymove, NULL);
}
static void
xglRectdv (const GLdouble *v1,
const GLdouble *v2)
{
GLenum listMode;
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
glRectdv (v1, v2);
glEndList ();
listMode = cctx->listMode;
}
else
listMode = GL_COMPILE_AND_EXECUTE;
if (listMode == GL_COMPILE_AND_EXECUTE)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glRectdv (v1, v2);
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
static void
xglRectfv (const GLfloat *v1,
const GLfloat *v2)
{
GLdouble dv1[2];
GLdouble dv2[2];
dv1[0] = (GLdouble) v1[0];
dv1[1] = (GLdouble) v1[1];
dv2[0] = (GLdouble) v2[0];
dv2[1] = (GLdouble) v2[1];
xglRectdv (dv1, dv2);
}
static void
xglRectiv (const GLint *v1,
const GLint *v2)
{
GLdouble dv1[2];
GLdouble dv2[2];
dv1[0] = (GLdouble) v1[0];
dv1[1] = (GLdouble) v1[1];
dv2[0] = (GLdouble) v2[0];
dv2[1] = (GLdouble) v2[1];
xglRectdv (dv1, dv2);
}
static void
xglRectsv (const GLshort *v1,
const GLshort *v2)
{
GLdouble dv1[2];
GLdouble dv2[2];
dv1[0] = (GLdouble) v1[0];
dv1[1] = (GLdouble) v1[1];
dv2[0] = (GLdouble) v2[0];
dv2[1] = (GLdouble) v2[1];
xglRectdv (dv1, dv2);
}
static void
xglBegin (GLenum mode)
{
if (cctx->list)
{
glEndList ();
xglStartList (XGL_LIST_OP_DRAW, GL_COMPILE);
}
else
{
BoxRec scissor;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
if (nBox == 1)
{
BoxRec box = *pBox;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
XGL_GLX_SET_SCISSOR_BOX (&box);
}
else
{
if (!cctx->groupList)
cctx->groupList = glGenLists (1);
glNewList (cctx->groupList, GL_COMPILE);
}
}
glBegin (mode);
}
static void
xglEnd (void)
{
glEnd ();
if (!cctx->list || cctx->listMode == GL_COMPILE_AND_EXECUTE)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
GLuint list;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
if (cctx->list)
{
list = cctx->pList->pOp[cctx->pList->nOp - 1].u.list;
}
else
{
if (nBox == 1)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
XGL_GLX_DRAW_DAMAGE (&box, &region);
return;
}
list = cctx->groupList;
}
glEndList ();
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glCallList (list);
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
if (cctx->list)
xglStartList (XGL_LIST_OP_CALLS, cctx->listMode);
}
static void
xglCopyPixelsProc (xglGLOpPtr pOp)
{
RegionRec region;
BoxRec scissor, box;
BoxPtr pBox;
int nBox;
XGL_GLX_DRAW_PROLOGUE (pBox, nBox, &scissor);
while (nBox--)
{
box = *pBox++;
if (cctx->attrib.scissorTest)
XGL_GLX_INTERSECT_BOX (&box, &scissor);
if (box.x1 < box.x2 && box.y1 < box.y2)
{
XGL_GLX_SET_SCISSOR_BOX (&box);
glCopyPixels (pOp->u.copy_pixels.x + cctx->pReadBuffer->xOff,
pOp->u.copy_pixels.y + cctx->pReadBuffer->yOff,
pOp->u.copy_pixels.width,
pOp->u.copy_pixels.height,
pOp->u.copy_pixels.type);
if (pOp->u.copy_pixels.type == GL_COLOR)
XGL_GLX_DRAW_DAMAGE (&box, &region);
}
}
}
static void
xglCopyPixels (GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLenum type)
{
xglGLOpRec gl;
gl.glProc = xglCopyPixelsProc;
gl.u.copy_pixels.x = x;
gl.u.copy_pixels.y = y;
gl.u.copy_pixels.width = width;
gl.u.copy_pixels.height = height;
gl.u.copy_pixels.type = type;
xglGLOp (&gl);
}
static void
xglReadPixels (GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
GLvoid *pixels)
{
glReadPixels (x + cctx->pReadBuffer->xOff,
y + cctx->pReadBuffer->yOff,
width, height, format, type, pixels);
}
static void
xglCopyTexImage1DProc (xglGLOpPtr pOp)
{
glCopyTexImage1D (pOp->u.copy_tex_image_1d.target,
pOp->u.copy_tex_image_1d.level,
pOp->u.copy_tex_image_1d.internalformat,
pOp->u.copy_tex_image_1d.x + cctx->pReadBuffer->xOff,
pOp->u.copy_tex_image_1d.y + cctx->pReadBuffer->yOff,
pOp->u.copy_tex_image_1d.width,
pOp->u.copy_tex_image_1d.border);
}
static void
xglCopyTexImage1D (GLenum target,
GLint level,
GLenum internalformat,
GLint x,
GLint y,
GLsizei width,
GLint border)
{
xglGLOpRec gl;
gl.glProc = xglCopyTexImage1DProc;
gl.u.copy_tex_image_1d.target = target;
gl.u.copy_tex_image_1d.level = level;
gl.u.copy_tex_image_1d.internalformat = internalformat;
gl.u.copy_tex_image_1d.x = x;
gl.u.copy_tex_image_1d.y = y;
gl.u.copy_tex_image_1d.width = width;
gl.u.copy_tex_image_1d.border = border;
xglGLOp (&gl);
}
static void
xglCopyTexImage2DProc (xglGLOpPtr pOp)
{
glCopyTexImage2D (pOp->u.copy_tex_image_2d.target,
pOp->u.copy_tex_image_2d.level,
pOp->u.copy_tex_image_2d.internalformat,
pOp->u.copy_tex_image_2d.x + cctx->pReadBuffer->xOff,
pOp->u.copy_tex_image_2d.y + cctx->pReadBuffer->yOff,
pOp->u.copy_tex_image_2d.width,
pOp->u.copy_tex_image_2d.height,
pOp->u.copy_tex_image_2d.border);
}
static void
xglCopyTexImage2D (GLenum target,
GLint level,
GLenum internalformat,
GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLint border)
{
xglGLOpRec gl;
gl.glProc = xglCopyTexImage2DProc;
gl.u.copy_tex_image_2d.target = target;
gl.u.copy_tex_image_2d.level = level;
gl.u.copy_tex_image_2d.internalformat = internalformat;
gl.u.copy_tex_image_2d.x = x;
gl.u.copy_tex_image_2d.y = y;
gl.u.copy_tex_image_2d.width = width;
gl.u.copy_tex_image_2d.height = height;
gl.u.copy_tex_image_2d.border = border;
xglGLOp (&gl);
}
static void
xglCopyTexSubImage1DProc (xglGLOpPtr pOp)
{
glCopyTexSubImage1D (pOp->u.copy_tex_sub_image_1d.target,
pOp->u.copy_tex_sub_image_1d.level,
pOp->u.copy_tex_sub_image_1d.xoffset,
pOp->u.copy_tex_sub_image_1d.x +
cctx->pReadBuffer->xOff,
pOp->u.copy_tex_sub_image_1d.y +
cctx->pReadBuffer->yOff,
pOp->u.copy_tex_sub_image_1d.width);
}
static void
xglCopyTexSubImage1D (GLenum target,
GLint level,
GLint xoffset,
GLint x,
GLint y,
GLsizei width)
{
xglGLOpRec gl;
gl.glProc = xglCopyTexSubImage1DProc;
gl.u.copy_tex_sub_image_1d.target = target;
gl.u.copy_tex_sub_image_1d.level = level;
gl.u.copy_tex_sub_image_1d.xoffset = xoffset;
gl.u.copy_tex_sub_image_1d.x = x;
gl.u.copy_tex_sub_image_1d.y = y;
gl.u.copy_tex_sub_image_1d.width = width;
xglGLOp (&gl);
}
static void
xglCopyTexSubImage2DProc (xglGLOpPtr pOp)
{
glCopyTexSubImage2D (pOp->u.copy_tex_sub_image_2d.target,
pOp->u.copy_tex_sub_image_2d.level,
pOp->u.copy_tex_sub_image_2d.xoffset,
pOp->u.copy_tex_sub_image_2d.yoffset,
pOp->u.copy_tex_sub_image_2d.x +
cctx->pReadBuffer->xOff,
pOp->u.copy_tex_sub_image_2d.y +
cctx->pReadBuffer->yOff,
pOp->u.copy_tex_sub_image_2d.width,
pOp->u.copy_tex_sub_image_2d.height);
}
static void
xglCopyTexSubImage2D (GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint x,
GLint y,
GLsizei width,
GLsizei height)
{
xglGLOpRec gl;
gl.glProc = xglCopyTexSubImage2DProc;
gl.u.copy_tex_sub_image_2d.target = target;
gl.u.copy_tex_sub_image_2d.level = level;
gl.u.copy_tex_sub_image_2d.xoffset = xoffset;
gl.u.copy_tex_sub_image_2d.yoffset = yoffset;
gl.u.copy_tex_sub_image_2d.x = x;
gl.u.copy_tex_sub_image_2d.y = y;
gl.u.copy_tex_sub_image_2d.width = width;
gl.u.copy_tex_sub_image_2d.height = height;
xglGLOp (&gl);
}
static void
xglCopyColorTableProc (xglGLOpPtr pOp)
{
glCopyColorTable (pOp->u.copy_color_table.target,
pOp->u.copy_color_table.internalformat,
pOp->u.copy_color_table.x + cctx->pReadBuffer->xOff,
pOp->u.copy_color_table.y + cctx->pReadBuffer->yOff,
pOp->u.copy_color_table.width);
}
static void
xglCopyColorTable (GLenum target,
GLenum internalformat,
GLint x,
GLint y,
GLsizei width)
{
xglGLOpRec gl;
gl.glProc = xglCopyColorTableProc;
gl.u.copy_color_table.target = target;
gl.u.copy_color_table.internalformat = internalformat;
gl.u.copy_color_table.x = x;
gl.u.copy_color_table.y = y;
gl.u.copy_color_table.width = width;
xglGLOp (&gl);
}
static void
xglCopyColorSubTableProc (xglGLOpPtr pOp)
{
glCopyColorTable (pOp->u.copy_color_sub_table.target,
pOp->u.copy_color_sub_table.start,
pOp->u.copy_color_sub_table.x + cctx->pReadBuffer->xOff,
pOp->u.copy_color_sub_table.y + cctx->pReadBuffer->yOff,
pOp->u.copy_color_sub_table.width);
}
static void
xglCopyColorSubTable (GLenum target,
GLsizei start,
GLint x,
GLint y,
GLsizei width)
{
xglGLOpRec gl;
gl.glProc = xglCopyColorSubTableProc;
gl.u.copy_color_sub_table.target = target;
gl.u.copy_color_sub_table.start = start;
gl.u.copy_color_sub_table.x = x;
gl.u.copy_color_sub_table.y = y;
gl.u.copy_color_sub_table.width = width;
xglGLOp (&gl);
}
static void
xglCopyConvolutionFilter1DProc (xglGLOpPtr pOp)
{
GLenum internalformat = pOp->u.copy_convolution_filter_1d.internalformat;
glCopyConvolutionFilter1D (pOp->u.copy_convolution_filter_1d.target,
internalformat,
pOp->u.copy_convolution_filter_1d.x +
cctx->pReadBuffer->xOff,
pOp->u.copy_convolution_filter_1d.y +
cctx->pReadBuffer->yOff,
pOp->u.copy_convolution_filter_1d.width);
}
static void
xglCopyConvolutionFilter1D (GLenum target,
GLenum internalformat,
GLint x,
GLint y,
GLsizei width)
{
xglGLOpRec gl;
gl.glProc = xglCopyConvolutionFilter1DProc;
gl.u.copy_convolution_filter_1d.target = target;
gl.u.copy_convolution_filter_1d.internalformat = internalformat;
gl.u.copy_convolution_filter_1d.x = x;
gl.u.copy_convolution_filter_1d.y = y;
gl.u.copy_convolution_filter_1d.width = width;
xglGLOp (&gl);
}
static void
xglCopyConvolutionFilter2DProc (xglGLOpPtr pOp)
{
GLenum internalformat = pOp->u.copy_convolution_filter_2d.internalformat;
glCopyConvolutionFilter2D (pOp->u.copy_convolution_filter_2d.target,
internalformat,
pOp->u.copy_convolution_filter_2d.x +
cctx->pReadBuffer->xOff,
pOp->u.copy_convolution_filter_2d.y +
cctx->pReadBuffer->yOff,
pOp->u.copy_convolution_filter_2d.width,
pOp->u.copy_convolution_filter_2d.height);
}
static void
xglCopyConvolutionFilter2D (GLenum target,
GLenum internalformat,
GLint x,
GLint y,
GLsizei width,
GLsizei height)
{
xglGLOpRec gl;
gl.glProc = xglCopyConvolutionFilter2DProc;
gl.u.copy_convolution_filter_2d.target = target;
gl.u.copy_convolution_filter_2d.internalformat = internalformat;
gl.u.copy_convolution_filter_2d.x = x;
gl.u.copy_convolution_filter_2d.y = y;
gl.u.copy_convolution_filter_2d.width = width;
gl.u.copy_convolution_filter_2d.height = height;
xglGLOp (&gl);
}
static void
xglCopyTexSubImage3DProc (xglGLOpPtr pOp)
{
glCopyTexSubImage3D (pOp->u.copy_tex_sub_image_3d.target,
pOp->u.copy_tex_sub_image_3d.level,
pOp->u.copy_tex_sub_image_3d.xoffset,
pOp->u.copy_tex_sub_image_3d.yoffset,
pOp->u.copy_tex_sub_image_3d.zoffset,
pOp->u.copy_tex_sub_image_3d.x +
cctx->pReadBuffer->xOff,
pOp->u.copy_tex_sub_image_3d.y +
cctx->pReadBuffer->yOff,
pOp->u.copy_tex_sub_image_3d.width,
pOp->u.copy_tex_sub_image_3d.height);
}
static void
xglCopyTexSubImage3D (GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLint x,
GLint y,
GLsizei width,
GLsizei height)
{
xglGLOpRec gl;
gl.glProc = xglCopyTexSubImage3DProc;
gl.u.copy_tex_sub_image_3d.target = target;
gl.u.copy_tex_sub_image_3d.level = level;
gl.u.copy_tex_sub_image_3d.xoffset = xoffset;
gl.u.copy_tex_sub_image_3d.yoffset = yoffset;
gl.u.copy_tex_sub_image_3d.zoffset = zoffset;
gl.u.copy_tex_sub_image_3d.x = x;
gl.u.copy_tex_sub_image_3d.y = y;
gl.u.copy_tex_sub_image_3d.width = width;
gl.u.copy_tex_sub_image_3d.height = height;
xglGLOp (&gl);
}
__glProcTable __glNativeRenderTable = {
xglNewList, /* glNewList */
xglEndList, /* glEndList */
xglCallList, /* glCallList */
xglCallLists, /* glCallLists */
xglDeleteLists, /* glDeleteLists */
xglGenLists, /* glGenLists */
glListBase,
xglBegin, /* glBegin */
xglBitmap, /* glBitmap */
glColor3bv,
glColor3dv,
glColor3fv,
glColor3iv,
glColor3sv,
glColor3ubv,
glColor3uiv,
glColor3usv,
glColor4bv,
glColor4dv,
glColor4fv,
glColor4iv,
glColor4sv,
glColor4ubv,
glColor4uiv,
glColor4usv,
glEdgeFlagv,
xglEnd, /* glEnd */
glIndexdv,
glIndexfv,
glIndexiv,
glIndexsv,
glNormal3bv,
glNormal3dv,
glNormal3fv,
glNormal3iv,
glNormal3sv,
glRasterPos2dv,
glRasterPos2fv,
glRasterPos2iv,
glRasterPos2sv,
glRasterPos3dv,
glRasterPos3fv,
glRasterPos3iv,
glRasterPos3sv,
glRasterPos4dv,
glRasterPos4fv,
glRasterPos4iv,
glRasterPos4sv,
xglRectdv, /* glRectdv */
xglRectfv, /* glRectfv */
xglRectiv, /* glRectiv */
xglRectsv, /* glRectsv */
glTexCoord1dv,
glTexCoord1fv,
glTexCoord1iv,
glTexCoord1sv,
glTexCoord2dv,
glTexCoord2fv,
glTexCoord2iv,
glTexCoord2sv,
glTexCoord3dv,
glTexCoord3fv,
glTexCoord3iv,
glTexCoord3sv,
glTexCoord4dv,
glTexCoord4fv,
glTexCoord4iv,
glTexCoord4sv,
glVertex2dv,
glVertex2fv,
glVertex2iv,
glVertex2sv,
glVertex3dv,
glVertex3fv,
glVertex3iv,
glVertex3sv,
glVertex4dv,
glVertex4fv,
glVertex4iv,
glVertex4sv,
glClipPlane,
glColorMaterial,
glCullFace,
glFogf,
glFogfv,
glFogi,
glFogiv,
glFrontFace,
glHint,
glLightf,
glLightfv,
glLighti,
glLightiv,
glLightModelf,
glLightModelfv,
glLightModeli,
glLightModeliv,
glLineStipple,
glLineWidth,
glMaterialf,
glMaterialfv,
glMateriali,
glMaterialiv,
glPointSize,
glPolygonMode,
glPolygonStipple,
xglScissor, /* glScissor */
glShadeModel,
xglTexParameterf, /* glTexParameterf */
xglTexParameterfv, /* glTexParameterfv */
xglTexParameteri, /* glTexParameteri */
xglTexParameteriv, /* glTexParameteriv */
glTexImage1D,
glTexImage2D,
glTexEnvf,
glTexEnvfv,
glTexEnvi,
glTexEnviv,
glTexGend,
glTexGendv,
glTexGenf,
glTexGenfv,
glTexGeni,
glTexGeniv,
glFeedbackBuffer,
glSelectBuffer,
glRenderMode,
glInitNames,
glLoadName,
glPassThrough,
glPopName,
glPushName,
xglDrawBuffer, /* glDrawBuffer */
xglClear, /* glClear */
glClearAccum,
glClearIndex,
glClearColor,
glClearStencil,
glClearDepth,
glStencilMask,
glColorMask,
glDepthMask,
glIndexMask,
xglAccum, /* glAccum */
xglDisable, /* glDisable */
xglEnable, /* glEnable */
xglFinish, /* glFinish */
xglFlush, /* glFlush */
xglPopAttrib, /* glPopAttrib */
xglPushAttrib, /* glPushAttrib */
glMap1d,
glMap1f,
glMap2d,
glMap2f,
glMapGrid1d,
glMapGrid1f,
glMapGrid2d,
glMapGrid2f,
glEvalCoord1dv,
glEvalCoord1fv,
glEvalCoord2dv,
glEvalCoord2fv,
glEvalMesh1,
glEvalPoint1,
glEvalMesh2,
glEvalPoint2,
glAlphaFunc,
glBlendFunc,
glLogicOp,
glStencilFunc,
glStencilOp,
glDepthFunc,
glPixelZoom,
glPixelTransferf,
glPixelTransferi,
glPixelStoref,
glPixelStorei,
glPixelMapfv,
glPixelMapuiv,
glPixelMapusv,
xglReadBuffer, /* glReadBuffer */
xglCopyPixels, /* glCopyPixels */
xglReadPixels, /* glReadPixels */
xglDrawPixels, /* glDrawPixels */
xglGetBooleanv, /* glGetBooleanv */
glGetClipPlane,
xglGetDoublev, /* glGetDoublev */
xglGetError, /* glGetError */
xglGetFloatv, /* glGetFloatv */
xglGetIntegerv, /* glGetIntegerv */
glGetLightfv,
glGetLightiv,
glGetMapdv,
glGetMapfv,
glGetMapiv,
glGetMaterialfv,
glGetMaterialiv,
glGetPixelMapfv,
glGetPixelMapuiv,
glGetPixelMapusv,
glGetPolygonStipple,
xglGetString, /* glGetString */
glGetTexEnvfv,
glGetTexEnviv,
glGetTexGendv,
glGetTexGenfv,
glGetTexGeniv,
glGetTexImage,
glGetTexParameterfv,
glGetTexParameteriv,
xglGetTexLevelParameterfv, /* glGetTexLevelParameterfv */
xglGetTexLevelParameteriv, /* glGetTexLevelParameteriv */
xglIsEnabled, /* glIsEnabled */
xglIsList, /* glIsList */
glDepthRange,
glFrustum,
glLoadIdentity,
glLoadMatrixf,
glLoadMatrixd,
glMatrixMode,
glMultMatrixf,
glMultMatrixd,
glOrtho,
glPopMatrix,
glPushMatrix,
glRotated,
glRotatef,
glScaled,
glScalef,
glTranslated,
glTranslatef,
xglViewport, /* glViewport */
glArrayElement,
xglBindTexture, /* glBindTexture */
glColorPointer,
glDisableClientState,
xglDrawArrays, /* glDrawArrays */
xglDrawElements, /* glDrawElements */
glEdgeFlagPointer,
glEnableClientState,
glIndexPointer,
glIndexubv,
glInterleavedArrays,
glNormalPointer,
glPolygonOffset,
glTexCoordPointer,
glVertexPointer,
xglAreTexturesResident, /* glAreTexturesResident */
xglCopyTexImage1D, /* glCopyTexImage1D */
xglCopyTexImage2D, /* glCopyTexImage2D */
xglCopyTexSubImage1D, /* glCopyTexSubImage1D */
xglCopyTexSubImage2D, /* glCopyTexSubImage2D */
xglDeleteTextures, /* glDeleteTextures */
xglGenTextures, /* glGenTextures */
glGetPointerv,
xglIsTexture, /* glIsTexture */
xglPrioritizeTextures, /* glPrioritizeTextures */
glTexSubImage1D,
glTexSubImage2D,
glPopClientAttrib,
glPushClientAttrib,
glBlendColor,
glBlendEquation,
glColorTable,
glColorTableParameterfv,
glColorTableParameteriv,
xglCopyColorTable, /* glCopyColorTable */
glGetColorTable,
glGetColorTableParameterfv,
glGetColorTableParameteriv,
glColorSubTable,
xglCopyColorSubTable, /* glCopyColorSubTable */
glConvolutionFilter1D,
glConvolutionFilter2D,
glConvolutionParameterf,
glConvolutionParameterfv,
glConvolutionParameteri,
glConvolutionParameteriv,
xglCopyConvolutionFilter1D, /* glCopyConvolutionFilter1D */
xglCopyConvolutionFilter2D, /* glCopyConvolutionFilter2D */
glGetConvolutionFilter,
glGetConvolutionParameterfv,
glGetConvolutionParameteriv,
glGetSeparableFilter,
glSeparableFilter2D,
glGetHistogram,
glGetHistogramParameterfv,
glGetHistogramParameteriv,
glGetMinmax,
glGetMinmaxParameterfv,
glGetMinmaxParameteriv,
glHistogram,
glMinmax,
glResetHistogram,
glResetMinmax,
glTexImage3D,
glTexSubImage3D,
xglCopyTexSubImage3D /* glCopyTexSubImage3D */
};
/* GL_ARB_multitexture */
static void
xglNoOpActiveTextureARB (GLenum texture) {}
static void
xglActiveTextureARBProc (xglGLOpPtr pOp)
{
GLenum texUnit;
texUnit = pOp->u.enumeration - GL_TEXTURE0;
if (texUnit < 0 || texUnit >= cctx->maxTexUnits)
{
xglRecordError (GL_INVALID_ENUM);
}
else
{
cctx->activeTexUnit = texUnit;
(*cctx->ActiveTextureARB) (pOp->u.enumeration);
}
}
static void
xglActiveTextureARB (GLenum texture)
{
xglGLOpRec gl;
gl.glProc = xglActiveTextureARBProc;
gl.u.enumeration = texture;
xglGLOp (&gl);
}
static void
xglNoOpClientActiveTextureARB (GLenum texture) {}
static void
xglNoOpMultiTexCoord1dvARB (GLenum target, const GLdouble *v) {}
static void
xglNoOpMultiTexCoord1fvARB (GLenum target, const GLfloat *v) {}
static void
xglNoOpMultiTexCoord1ivARB (GLenum target, const GLint *v) {}
static void
xglNoOpMultiTexCoord1svARB (GLenum target, const GLshort *v) {}
static void
xglNoOpMultiTexCoord2dvARB (GLenum target, const GLdouble *v) {}
static void
xglNoOpMultiTexCoord2fvARB (GLenum target, const GLfloat *v) {}
static void
xglNoOpMultiTexCoord2ivARB (GLenum target, const GLint *v) {}
static void
xglNoOpMultiTexCoord2svARB (GLenum target, const GLshort *v) {}
static void
xglNoOpMultiTexCoord3dvARB (GLenum target, const GLdouble *v) {}
static void
xglNoOpMultiTexCoord3fvARB (GLenum target, const GLfloat *v) {}
static void
xglNoOpMultiTexCoord3ivARB (GLenum target, const GLint *v) {}
static void
xglNoOpMultiTexCoord3svARB (GLenum target, const GLshort *v) {}
static void
xglNoOpMultiTexCoord4dvARB (GLenum target, const GLdouble *v) {}
static void
xglNoOpMultiTexCoord4fvARB (GLenum target, const GLfloat *v) {}
static void
xglNoOpMultiTexCoord4ivARB (GLenum target, const GLint *v) {}
static void
xglNoOpMultiTexCoord4svARB (GLenum target, const GLshort *v) {}
/* GL_ARB_multisample */
static void
xglNoOpSampleCoverageARB (GLclampf value, GLboolean invert) {}
/* GL_EXT_texture_object */
static GLboolean
xglNoOpAreTexturesResidentEXT (GLsizei n,
const GLuint *textures,
GLboolean *residences)
{
return GL_FALSE;
}
static void
xglNoOpGenTexturesEXT (GLsizei n, GLuint *textures) {}
static GLboolean
xglNoOpIsTextureEXT (GLuint texture)
{
return GL_FALSE;
}
/* GL_SGIS_multisample */
static void
xglNoOpSampleMaskSGIS (GLclampf value, GLboolean invert) {}
static void
xglNoOpSamplePatternSGIS (GLenum pattern) {}
/* GL_EXT_point_parameters */
static void
xglNoOpPointParameterfEXT (GLenum pname, GLfloat param) {}
static void
xglNoOpPointParameterfvEXT (GLenum pname, const GLfloat *params) {}
/* GL_MESA_window_pos */
static void
xglNoOpWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z) {}
static void
xglWindowPos3fMESAProc (xglGLOpPtr pOp)
{
(*cctx->WindowPos3fMESA) (pOp->u.window_pos_3f.x + cctx->pDrawBuffer->xOff,
pOp->u.window_pos_3f.y + cctx->pDrawBuffer->yOff,
pOp->u.window_pos_3f.z);
}
static void
xglWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z)
{
xglGLOpRec gl;
gl.glProc = xglWindowPos3fMESAProc;
gl.u.window_pos_3f.x = x;
gl.u.window_pos_3f.y = y;
gl.u.window_pos_3f.z = z;
xglGLOp (&gl);
}
/* GL_EXT_blend_func_separate */
static void
xglNoOpBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB,
GLenum sfactorAlpha, GLenum dfactorAlpha) {}
/* GL_EXT_fog_coord */
static void
xglNoOpFogCoordfvEXT (const GLfloat *coord) {}
static void
xglNoOpFogCoorddvEXT (const GLdouble *coord) {}
static void
xglNoOpFogCoordPointerEXT (GLenum type, GLsizei stride,
const GLvoid *pointer) {}
/* GL_EXT_secondary_color */
static void
xglNoOpSecondaryColor3bvEXT (const GLbyte *v) {}
static void
xglNoOpSecondaryColor3dvEXT (const GLdouble *v) {}
static void
xglNoOpSecondaryColor3fvEXT (const GLfloat *v) {}
static void
xglNoOpSecondaryColor3ivEXT (const GLint *v) {}
static void
xglNoOpSecondaryColor3svEXT (const GLshort *v) {}
static void
xglNoOpSecondaryColor3ubvEXT (const GLubyte *v) {}
static void
xglNoOpSecondaryColor3uivEXT (const GLuint *v) {}
static void
xglNoOpSecondaryColor3usvEXT (const GLushort *v) {}
static void
xglNoOpSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer) {}
/* GL_NV_point_sprite */
static void
xglNoOpPointParameteriNV (GLenum pname, GLint params) {}
static void
xglNoOpPointParameterivNV (GLenum pname, const GLint *params) {}
/* GL_EXT_stencil_two_side */
static void
xglNoOpActiveStencilFaceEXT (GLenum face) {}
__glProcTableEXT __glNoOpRenderTableEXT = {
xglNoOpActiveTextureARB,
xglNoOpClientActiveTextureARB,
xglNoOpMultiTexCoord1dvARB,
xglNoOpMultiTexCoord1fvARB,
xglNoOpMultiTexCoord1ivARB,
xglNoOpMultiTexCoord1svARB,
xglNoOpMultiTexCoord2dvARB,
xglNoOpMultiTexCoord2fvARB,
xglNoOpMultiTexCoord2ivARB,
xglNoOpMultiTexCoord2svARB,
xglNoOpMultiTexCoord3dvARB,
xglNoOpMultiTexCoord3fvARB,
xglNoOpMultiTexCoord3ivARB,
xglNoOpMultiTexCoord3svARB,
xglNoOpMultiTexCoord4dvARB,
xglNoOpMultiTexCoord4fvARB,
xglNoOpMultiTexCoord4ivARB,
xglNoOpMultiTexCoord4svARB,
xglNoOpSampleCoverageARB,
xglNoOpAreTexturesResidentEXT,
xglNoOpGenTexturesEXT,
xglNoOpIsTextureEXT,
xglNoOpSampleMaskSGIS,
xglNoOpSamplePatternSGIS,
xglNoOpPointParameterfEXT,
xglNoOpPointParameterfvEXT,
xglNoOpWindowPos3fMESA,
xglNoOpBlendFuncSeparateEXT,
xglNoOpFogCoordfvEXT,
xglNoOpFogCoorddvEXT,
xglNoOpFogCoordPointerEXT,
xglNoOpSecondaryColor3bvEXT,
xglNoOpSecondaryColor3dvEXT,
xglNoOpSecondaryColor3fvEXT,
xglNoOpSecondaryColor3ivEXT,
xglNoOpSecondaryColor3svEXT,
xglNoOpSecondaryColor3ubvEXT,
xglNoOpSecondaryColor3uivEXT,
xglNoOpSecondaryColor3usvEXT,
xglNoOpSecondaryColorPointerEXT,
xglNoOpPointParameteriNV,
xglNoOpPointParameterivNV,
xglNoOpActiveStencilFaceEXT
};
static void
xglInitExtensions (xglGLContextPtr pContext)
{
const char *extensions;
pContext->glRenderTableEXT = __glNoOpRenderTableEXT;
extensions = (const char *) glGetString (GL_EXTENSIONS);
if (strstr (extensions, "GL_ARB_multitexture"))
{
pContext->ActiveTextureARB =
(PFNGLACTIVETEXTUREARBPROC)
glitz_context_get_proc_address (pContext->context,
"glActiveTextureARB");
pContext->glRenderTableEXT.ClientActiveTextureARB =
(PFNGLCLIENTACTIVETEXTUREARBPROC)
glitz_context_get_proc_address (pContext->context,
"glClientActiveTextureARB");
pContext->glRenderTableEXT.MultiTexCoord1dvARB =
(PFNGLMULTITEXCOORD1DVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord1dvARB");
pContext->glRenderTableEXT.MultiTexCoord1fvARB =
(PFNGLMULTITEXCOORD1FVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord1fvARB");
pContext->glRenderTableEXT.MultiTexCoord1ivARB =
(PFNGLMULTITEXCOORD1IVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord1ivARB");
pContext->glRenderTableEXT.MultiTexCoord1svARB =
(PFNGLMULTITEXCOORD1SVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord1svARB");
pContext->glRenderTableEXT.MultiTexCoord2dvARB =
(PFNGLMULTITEXCOORD2DVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord2dvARB");
pContext->glRenderTableEXT.MultiTexCoord2fvARB =
(PFNGLMULTITEXCOORD2FVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord2fvARB");
pContext->glRenderTableEXT.MultiTexCoord2ivARB =
(PFNGLMULTITEXCOORD2IVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord2ivARB");
pContext->glRenderTableEXT.MultiTexCoord2svARB =
(PFNGLMULTITEXCOORD2SVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord2svARB");
pContext->glRenderTableEXT.MultiTexCoord3dvARB =
(PFNGLMULTITEXCOORD3DVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord3dvARB");
pContext->glRenderTableEXT.MultiTexCoord3fvARB =
(PFNGLMULTITEXCOORD3FVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord3fvARB");
pContext->glRenderTableEXT.MultiTexCoord3ivARB =
(PFNGLMULTITEXCOORD3IVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord3ivARB");
pContext->glRenderTableEXT.MultiTexCoord3svARB =
(PFNGLMULTITEXCOORD3SVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord3svARB");
pContext->glRenderTableEXT.MultiTexCoord4dvARB =
(PFNGLMULTITEXCOORD4DVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord4dvARB");
pContext->glRenderTableEXT.MultiTexCoord4fvARB =
(PFNGLMULTITEXCOORD4FVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord4fvARB");
pContext->glRenderTableEXT.MultiTexCoord4ivARB =
(PFNGLMULTITEXCOORD4IVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord4ivARB");
pContext->glRenderTableEXT.MultiTexCoord4svARB =
(PFNGLMULTITEXCOORD4SVARBPROC)
glitz_context_get_proc_address (pContext->context,
"glMultiTexCoord4svARB");
glGetIntegerv (GL_MAX_LIST_NESTING, &pContext->maxListNesting);
glGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &pContext->maxTexUnits);
if (pContext->maxTexUnits > XGL_MAX_TEXTURE_UNITS)
pContext->maxTexUnits = XGL_MAX_TEXTURE_UNITS;
pContext->glRenderTableEXT.ActiveTextureARB = xglActiveTextureARB;
}
else
pContext->maxTexUnits = 1;
if (strstr (extensions, "GL_ARB_multisample"))
{
pContext->glRenderTableEXT.SampleCoverageARB =
(PFNGLSAMPLECOVERAGEARBPROC)
glitz_context_get_proc_address (pContext->context,
"glSampleCoverageARB");
}
if (strstr (extensions, "GL_EXT_texture_object"))
{
pContext->glRenderTableEXT.AreTexturesResidentEXT =
xglAreTexturesResident;
pContext->glRenderTableEXT.GenTexturesEXT = xglGenTextures;
pContext->glRenderTableEXT.IsTextureEXT = xglIsTexture;
}
if (strstr (extensions, "GL_SGIS_multisample"))
{
pContext->glRenderTableEXT.SampleMaskSGIS =
(PFNGLSAMPLEMASKSGISPROC)
glitz_context_get_proc_address (pContext->context,
"glSampleMaskSGIS");
pContext->glRenderTableEXT.SamplePatternSGIS =
(PFNGLSAMPLEPATTERNSGISPROC)
glitz_context_get_proc_address (pContext->context,
"glSamplePatternSGIS");
}
if (strstr (extensions, "GL_EXT_point_parameters"))
{
pContext->glRenderTableEXT.PointParameterfEXT =
(PFNGLPOINTPARAMETERFEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glPointParameterfEXT");
pContext->glRenderTableEXT.PointParameterfvEXT =
(PFNGLPOINTPARAMETERFVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glPointParameterfvEXT");
}
if (strstr (extensions, "GL_MESA_window_pos"))
{
pContext->WindowPos3fMESA =
(PFNGLWINDOWPOS3FMESAPROC)
glitz_context_get_proc_address (pContext->context,
"glWindowPos3fMESA");
pContext->glRenderTableEXT.WindowPos3fMESA = xglWindowPos3fMESA;
}
if (strstr (extensions, "GL_EXT_blend_func_separate"))
{
pContext->glRenderTableEXT.BlendFuncSeparateEXT =
(PFNGLBLENDFUNCSEPARATEEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glBlendFuncSeparateEXT");
}
if (strstr (extensions, "GL_EXT_fog_coord"))
{
pContext->glRenderTableEXT.FogCoordfvEXT =
(PFNGLFOGCOORDFVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glFogCoordfvEXT");
pContext->glRenderTableEXT.FogCoorddvEXT =
(PFNGLFOGCOORDDVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glFogCoorddvEXT");
pContext->glRenderTableEXT.FogCoordPointerEXT =
(PFNGLFOGCOORDPOINTEREXTPROC)
glitz_context_get_proc_address (pContext->context,
"glFogCoordPointerEXT");
}
if (strstr (extensions, "GL_EXT_secondary_color"))
{
pContext->glRenderTableEXT.SecondaryColor3bvEXT =
(PFNGLSECONDARYCOLOR3BVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3bvEXT");
pContext->glRenderTableEXT.SecondaryColor3dvEXT =
(PFNGLSECONDARYCOLOR3DVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3dvEXT");
pContext->glRenderTableEXT.SecondaryColor3fvEXT =
(PFNGLSECONDARYCOLOR3FVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3fvEXT");
pContext->glRenderTableEXT.SecondaryColor3ivEXT =
(PFNGLSECONDARYCOLOR3IVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3ivEXT");
pContext->glRenderTableEXT.SecondaryColor3svEXT =
(PFNGLSECONDARYCOLOR3SVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3svEXT");
pContext->glRenderTableEXT.SecondaryColor3ubvEXT =
(PFNGLSECONDARYCOLOR3UBVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3ubvEXT");
pContext->glRenderTableEXT.SecondaryColor3uivEXT =
(PFNGLSECONDARYCOLOR3UIVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3uivEXT");
pContext->glRenderTableEXT.SecondaryColor3usvEXT =
(PFNGLSECONDARYCOLOR3USVEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColor3usvEXT");
pContext->glRenderTableEXT.SecondaryColorPointerEXT =
(PFNGLSECONDARYCOLORPOINTEREXTPROC)
glitz_context_get_proc_address (pContext->context,
"glSecondaryColorPointerEXT");
}
if (strstr (extensions, "GL_NV_point_sprite"))
{
pContext->glRenderTableEXT.PointParameteriNV =
(PFNGLPOINTPARAMETERINVPROC)
glitz_context_get_proc_address (pContext->context,
"glPointParameteriNV");
pContext->glRenderTableEXT.PointParameterivNV =
(PFNGLPOINTPARAMETERIVNVPROC)
glitz_context_get_proc_address (pContext->context,
"glPointParameterivNV");
}
if (strstr (extensions, "GL_EXT_stencil_two_side"))
{
pContext->glRenderTableEXT.ActiveStencilFaceEXT =
(PFNGLACTIVESTENCILFACEEXTPROC)
glitz_context_get_proc_address (pContext->context,
"glActiveStencilFaceEXT");
}
}
static void
xglSetCurrentContext (xglGLContextPtr pContext)
{
XGL_SCREEN_PRIV (pContext->pDrawBuffer->pGC->pScreen);
cctx = pContext;
glitz_context_make_current (cctx->context, pScreenPriv->drawable);
__glRenderTable = &__glNativeRenderTable;
__glRenderTableEXT = &cctx->glRenderTableEXT;
}
static void
xglFreeContext (xglGLContextPtr pContext)
{
int i;
pContext->refcnt--;
if (pContext->shared == pContext)
pContext->refcnt--;
if (pContext->refcnt)
return;
if (pContext->shared != pContext)
xglFreeContext (pContext->shared);
if (pContext->texObjects)
{
xglTexObjPtr pTexObj;
GLuint key;
do {
key = xglHashFirstEntry (pContext->texObjects);
if (key)
{
pTexObj = (xglTexObjPtr) xglHashLookup (pContext->texObjects,
key);
if (pTexObj)
xglUnrefTexObj (pTexObj);
xglHashRemove (pContext->texObjects, key);
}
} while (key);
xglDeleteHashTable (pContext->texObjects);
}
if (pContext->displayLists)
{
xglDisplayListPtr pDisplayList;
GLuint key;
do {
key = xglHashFirstEntry (pContext->displayLists);
if (key)
{
pDisplayList = (xglDisplayListPtr)
xglHashLookup (pContext->displayLists, key);
if (pDisplayList)
xglDestroyList (pDisplayList);
xglHashRemove (pContext->displayLists, key);
}
} while (key);
xglDeleteHashTable (pContext->displayLists);
}
for (i = 0; i < pContext->maxTexUnits; i++)
{
xglUnrefTexObj (pContext->attrib.texUnits[i].p1D);
xglUnrefTexObj (pContext->attrib.texUnits[i].p2D);
xglUnrefTexObj (pContext->attrib.texUnits[i].p3D);
xglUnrefTexObj (pContext->attrib.texUnits[i].pRect);
xglUnrefTexObj (pContext->attrib.texUnits[i].pCubeMap);
}
if (pContext->groupList)
glDeleteLists (pContext->groupList, 1);
if (pContext->pAttribStack)
xfree (pContext->pAttribStack);
if (pContext->context)
glitz_context_destroy (pContext->context);
if (pContext->versionString)
xfree (pContext->versionString);
xfree (pContext);
}
static GLboolean
xglDestroyContext (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
xglFreeContext (pContext);
if (!iface)
return GL_TRUE;
return (*iface->exports.destroyContext) ((__GLcontext *) iface);
}
static GLboolean
xglLoseCurrent (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
__glXFlushContextCache ();
if (!iface)
return GL_TRUE;
return (*iface->exports.loseCurrent) ((__GLcontext *) iface);
}
static GLboolean
xglMakeCurrent (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = &pContext->iface;
__GLinterface *mIface = pContext->mIface;
__GLdrawablePrivate *drawPriv = iface->imports.getDrawablePrivate (gc);
__GLdrawablePrivate *readPriv = iface->imports.getReadablePrivate (gc);
xglGLBufferPtr pDrawBufferPriv = drawPriv->private;
xglGLBufferPtr pReadBufferPriv = readPriv->private;
GLboolean status = GL_TRUE;
if (pReadBufferPriv->pDrawable && pDrawBufferPriv->pDrawable)
{
XID values[2] = { ClipByChildren, 0 };
int status;
#ifdef COMPOSITE
/* XXX: temporary hack for root window drawing using
IncludeInferiors */
if (pDrawBufferPriv->pDrawable->type == DRAWABLE_WINDOW &&
(!((WindowPtr) (pDrawBufferPriv->pDrawable))->parent))
values[0] = IncludeInferiors;
#endif
/* this happens if client previously used this context with a buffer
not supported by the native GL stack */
if (!pContext->context)
return GL_FALSE;
/* XXX: GLX_SGI_make_current_read disabled for now */
if (pDrawBufferPriv != pReadBufferPriv)
return GL_FALSE;
pContext->pReadBuffer = pReadBufferPriv;
pContext->pDrawBuffer = pDrawBufferPriv;
if (!pReadBufferPriv->pGC)
pReadBufferPriv->pGC =
CreateGC (pReadBufferPriv->pDrawable,
GCSubwindowMode | GCGraphicsExposures, values,
&status);
ValidateGC (pReadBufferPriv->pDrawable, pReadBufferPriv->pGC);
if (!pDrawBufferPriv->pGC)
pDrawBufferPriv->pGC =
CreateGC (pDrawBufferPriv->pDrawable,
GCSubwindowMode | GCGraphicsExposures, values,
&status);
ValidateGC (pDrawBufferPriv->pDrawable, pDrawBufferPriv->pGC);
pContext->pReadBuffer = pReadBufferPriv;
pContext->pDrawBuffer = pDrawBufferPriv;
pReadBufferPriv->pPixmap = (PixmapPtr) 0;
pDrawBufferPriv->pPixmap = (PixmapPtr) 0;
/* from now on this context can only be used with native GL stack */
if (mIface)
{
(*mIface->exports.destroyContext) ((__GLcontext *) mIface);
pContext->mIface = NULL;
}
}
else
{
/* this happens if client previously used this context with a buffer
supported by the native GL stack */
if (!mIface)
return GL_FALSE;
drawPriv->private = pDrawBufferPriv->private;
readPriv->private = pReadBufferPriv->private;
status = (*mIface->exports.makeCurrent) ((__GLcontext *) mIface);
drawPriv->private = pDrawBufferPriv;
readPriv->private = pReadBufferPriv;
/* from now on this context can not be used with native GL stack */
if (status == GL_TRUE && pContext->context)
{
glitz_context_destroy (pContext->context);
pContext->context = NULL;
}
}
return status;
}
static GLboolean
xglShareContext (__GLcontext *gc,
__GLcontext *gcShare)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
xglGLContextPtr pContextShare = (xglGLContextPtr) gcShare;
__GLinterface *iface = pContext->mIface;
__GLinterface *ifaceShare = pContextShare->mIface;
if (!iface || !ifaceShare)
return GL_TRUE;
return (*iface->exports.shareContext) ((__GLcontext *) iface,
(__GLcontext *) ifaceShare);
}
static GLboolean
xglCopyContext (__GLcontext *dst,
const __GLcontext *src,
GLuint mask)
{
xglGLContextPtr pDst = (xglGLContextPtr) dst;
xglGLContextPtr pSrc = (xglGLContextPtr) src;
const __GLcontext *srcCtx = (const __GLcontext *) pSrc->mIface;
__GLinterface *dstIface = (__GLinterface *) pDst->mIface;
GLboolean status = GL_TRUE;
if (pSrc->context && pDst->context)
glitz_context_copy (pSrc->context, pDst->context, mask);
else
status = GL_FALSE;
if (dstIface && srcCtx)
status = (*dstIface->exports.copyContext) ((__GLcontext *) dstIface,
srcCtx,
mask);
return status;
}
static GLboolean
xglForceCurrent (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
GLboolean status = GL_TRUE;
if (pContext->context)
{
cctx = pContext;
if (cctx->pReadBuffer->pDrawable && cctx->pDrawBuffer->pDrawable)
{
DrawablePtr pDrawable;
PixmapPtr pReadPixmap, pDrawPixmap;
pDrawable = cctx->pReadBuffer->pDrawable;
if (pDrawable->type != DRAWABLE_PIXMAP)
{
pReadPixmap = XGL_GET_WINDOW_PIXMAP (pDrawable);
cctx->pReadBuffer->xOff = pDrawable->x +
__XGL_OFF_X_WIN (pReadPixmap);
cctx->pReadBuffer->yOff = pReadPixmap->drawable.height -
((pDrawable->y + __XGL_OFF_Y_WIN (pReadPixmap)) +
pDrawable->height);
cctx->pReadBuffer->yFlip = pReadPixmap->drawable.height;
}
else
{
pReadPixmap = (PixmapPtr) pDrawable;
cctx->pReadBuffer->xOff = cctx->pReadBuffer->yOff = 0;
cctx->pReadBuffer->yFlip = pDrawable->height;
}
pDrawable = cctx->pDrawBuffer->pDrawable;
if (pDrawable->type != DRAWABLE_PIXMAP)
{
pDrawPixmap = XGL_GET_WINDOW_PIXMAP (pDrawable);
cctx->pDrawBuffer->xOff = pDrawable->x +
__XGL_OFF_X_WIN (pDrawPixmap);
cctx->pDrawBuffer->yOff = pDrawPixmap->drawable.height -
((pDrawable->y + __XGL_OFF_Y_WIN (pDrawPixmap)) +
pDrawable->height);
cctx->pDrawBuffer->yFlip = pDrawPixmap->drawable.height;
}
else
{
pDrawPixmap = (PixmapPtr) pDrawable;
cctx->pDrawBuffer->xOff = cctx->pDrawBuffer->yOff = 0;
cctx->pDrawBuffer->yFlip = pDrawable->height;
}
/* check if buffers have changed */
if (cctx->pReadBuffer->pPixmap != pReadPixmap ||
cctx->pDrawBuffer->pPixmap != pDrawPixmap)
{
XGL_SCREEN_PRIV (pDrawable->pScreen);
XGL_PIXMAP_PRIV (pDrawPixmap);
if (!xglPrepareTarget (pDrawable))
return FALSE;
/* draw buffer is offscreen */
if (pPixmapPriv->surface != pScreenPriv->surface)
{
/* NYI: framebuffer object setup */
FatalError ("NYI: offscreen GL drawable\n");
}
cctx->pReadBuffer->pPixmap = pReadPixmap;
cctx->pDrawBuffer->pPixmap = pDrawPixmap;
}
}
xglSetCurrentContext (pContext);
if (cctx->needInit)
{
int i;
xglInitExtensions (cctx);
cctx->attrib.scissorTest = GL_FALSE;
cctx->attrib.scissor.x = cctx->attrib.scissor.y = 0;
cctx->attrib.scissor.width = cctx->pDrawBuffer->pDrawable->width;
cctx->attrib.scissor.height = cctx->pDrawBuffer->pDrawable->height;
cctx->attrib.viewport = cctx->attrib.scissor;
cctx->activeTexUnit = 0;
for (i = 0; i < cctx->maxTexUnits; i++)
{
cctx->attrib.texUnits[i].enabled = 0;
cctx->attrib.texUnits[i].p1D = NULL;
cctx->attrib.texUnits[i].p2D = NULL;
cctx->attrib.texUnits[i].p3D = NULL;
cctx->attrib.texUnits[i].pRect = NULL;
cctx->attrib.texUnits[i].pCubeMap = NULL;
}
glEnable (GL_SCISSOR_TEST);
cctx->needInit = FALSE;
}
/* update viewport and raster position */
if (cctx->pDrawBuffer->xOff != cctx->drawXoff ||
cctx->pDrawBuffer->yOff != cctx->drawYoff)
{
glViewport (cctx->attrib.scissor.x + cctx->pDrawBuffer->xOff,
cctx->attrib.scissor.y + cctx->pDrawBuffer->yOff,
cctx->attrib.scissor.width,
cctx->attrib.scissor.height);
glBitmap (0, 0, 0, 0,
cctx->pDrawBuffer->xOff - cctx->drawXoff,
cctx->pDrawBuffer->yOff - cctx->drawYoff,
NULL);
cctx->drawXoff = cctx->pDrawBuffer->xOff;
cctx->drawYoff = cctx->pDrawBuffer->yOff;
}
glDrawBuffer (cctx->attrib.drawBuffer);
glReadBuffer (cctx->attrib.readBuffer);
}
else
{
cctx = NULL;
__glRenderTable = &__glMesaRenderTable;
__glRenderTableEXT = &__glMesaRenderTableEXT;
status = (*iface->exports.forceCurrent) ((__GLcontext *) iface);
}
return status;
}
static GLboolean
xglNotifyResize (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
if (!iface)
return GL_TRUE;
return (*iface->exports.notifyResize) ((__GLcontext *) iface);
}
static void
xglNotifyDestroy (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
if (iface)
(*iface->exports.notifyDestroy) ((__GLcontext *) iface);
}
static void
xglNotifySwapBuffers (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
if (iface)
(*iface->exports.notifySwapBuffers) ((__GLcontext *) iface);
}
static struct __GLdispatchStateRec *
xglDispatchExec (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
if (!iface)
return NULL;
return (*iface->exports.dispatchExec) ((__GLcontext *) iface);
}
static void
xglBeginDispatchOverride (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
if (iface)
(*iface->exports.beginDispatchOverride) ((__GLcontext *) iface);
}
static void
xglEndDispatchOverride (__GLcontext *gc)
{
xglGLContextPtr pContext = (xglGLContextPtr) gc;
__GLinterface *iface = pContext->mIface;
if (iface)
(*iface->exports.endDispatchOverride) ((__GLcontext *) iface);
}
static void
xglLoseCurrentContext (void *closure)
{
cctx = NULL;
__glRenderTable = &__glMesaRenderTable;
__glRenderTableEXT = &__glMesaRenderTableEXT;
__glXFlushContextCache ();
}
static __GLinterface *
xglCreateContext (__GLimports *imports,
__GLcontextModes *modes,
__GLinterface *shareGC)
{
glitz_drawable_format_t *format;
xglGLContextPtr pShareContext = (xglGLContextPtr) shareGC;
xglGLContextPtr pContext;
__GLinterface *shareIface = NULL;
__GLinterface *iface;
__GLXcontext *glxCtx = (__GLXcontext *) imports->other;
XGL_SCREEN_PRIV (glxCtx->pScreen);
format = glitz_drawable_get_format (pScreenPriv->drawable);
pContext = xalloc (sizeof (xglGLContextRec));
if (!pContext)
return NULL;
pContext->context = glitz_context_create (pScreenPriv->drawable, format);
glitz_context_set_user_data (pContext->context, NULL,
xglLoseCurrentContext);
pContext->needInit = TRUE;
pContext->versionString = NULL;
pContext->errorValue = GL_NO_ERROR;
pContext->shared = NULL;
pContext->list = 0;
pContext->groupList = 0;
pContext->pAttribStack = NULL;
pContext->nAttribStack = 0;
pContext->refcnt = 1;
pContext->doubleBuffer = glxCtx->pGlxVisual->doubleBuffer;
pContext->depthBits = glxCtx->pGlxVisual->depthSize;
pContext->stencilBits = glxCtx->pGlxVisual->stencilSize;
pContext->drawXoff = 0;
pContext->drawYoff = 0;
pContext->maxTexUnits = 0;
if (pContext->doubleBuffer)
{
pContext->attrib.drawBuffer = GL_BACK;
pContext->attrib.readBuffer = GL_BACK;
}
else
{
pContext->attrib.drawBuffer = GL_FRONT;
pContext->attrib.readBuffer = GL_FRONT;
}
pContext->attrib.scissorTest = GL_FALSE;
if (shareGC)
{
pContext->texObjects = NULL;
pContext->displayLists = NULL;
pContext->shared = pShareContext->shared;
shareIface = pShareContext->mIface;
}
else
{
pContext->texObjects = xglNewHashTable ();
if (!pContext->texObjects)
{
xglFreeContext (pContext);
return NULL;
}
pContext->displayLists = xglNewHashTable ();
if (!pContext->displayLists)
{
xglFreeContext (pContext);
return NULL;
}
pContext->shared = pContext;
}
pContext->shared->refcnt++;
iface = (*screenInfoPriv.createContext) (imports, modes, shareIface);
if (!iface)
{
xglFreeContext (pContext);
return NULL;
}
pContext->mIface = iface;
pContext->iface.imports = *imports;
pContext->iface.exports.destroyContext = xglDestroyContext;
pContext->iface.exports.loseCurrent = xglLoseCurrent;
pContext->iface.exports.makeCurrent = xglMakeCurrent;
pContext->iface.exports.shareContext = xglShareContext;
pContext->iface.exports.copyContext = xglCopyContext;
pContext->iface.exports.forceCurrent = xglForceCurrent;
pContext->iface.exports.notifyResize = xglNotifyResize;
pContext->iface.exports.notifyDestroy = xglNotifyDestroy;
pContext->iface.exports.notifySwapBuffers = xglNotifySwapBuffers;
pContext->iface.exports.dispatchExec = xglDispatchExec;
pContext->iface.exports.beginDispatchOverride = xglBeginDispatchOverride;
pContext->iface.exports.endDispatchOverride = xglEndDispatchOverride;
return (__GLinterface *) pContext;
}
static GLboolean
xglSwapBuffers (__GLXdrawablePrivate *glxPriv)
{
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
xglGLBufferPtr pBufferPriv = glPriv->private;
DrawablePtr pDrawable = pBufferPriv->pDrawable;
GLboolean status = GL_TRUE;
if (pDrawable)
{
if (glPriv->modes->doubleBufferMode)
{
glitz_surface_t *surface;
int xOff, yOff;
GCPtr pGC = pBufferPriv->pGC;
BoxPtr pBox = REGION_RECTS (pGC->pCompositeClip);
int nBox = REGION_NUM_RECTS (pGC->pCompositeClip);
XGL_SCREEN_PRIV (pGC->pScreen);
if (!xglPrepareTarget (pDrawable))
return GL_FALSE;
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
/* native swap buffers for fullscreen windows */
if (surface == pScreenPriv->surface &&
nBox == 1 &&
pBox->x1 <= 0 &&
pBox->y1 <= 0 &&
pBox->x2 >= pGC->pScreen->width &&
pBox->y2 >= pGC->pScreen->height)
{
glitz_drawable_swap_buffers (pScreenPriv->drawable);
}
else
{
glitz_surface_set_clip_region (surface, xOff, yOff,
(glitz_box_t *) pBox, nBox);
glitz_copy_area (pBufferPriv->backSurface,
surface,
pDrawable->x + xOff,
pDrawable->y + yOff,
pDrawable->width,
pDrawable->height,
pDrawable->x + xOff,
pDrawable->y + yOff);
glitz_surface_set_clip_region (surface, 0, 0, NULL, 0);
}
DamageDamageRegion (pDrawable, pGC->pCompositeClip);
REGION_EMPTY (pGC->pScreen, &pBufferPriv->damage);
}
}
else if (pBufferPriv->private)
{
glPriv->private = pBufferPriv->private;
status = (*pBufferPriv->swapBuffers) (glxPriv);
glPriv->private = pBufferPriv;
}
return status;
}
static GLboolean
xglResizeBuffers (__GLdrawableBuffer *buffer,
GLint x,
GLint y,
GLuint width,
GLuint height,
__GLdrawablePrivate *glPriv,
GLuint bufferMask)
{
xglGLBufferPtr pBufferPriv = glPriv->private;
DrawablePtr pDrawable = pBufferPriv->pDrawable;
GLboolean status = GL_TRUE;
if (pDrawable)
{
if (glPriv->modes->doubleBufferMode)
{
glitz_surface_t *surface = pBufferPriv->backSurface;
XGL_SCREEN_PRIV (pDrawable->pScreen);
/* FIXME: copy color buffer bits, stencil bits and depth bits */
if (surface != pScreenPriv->backSurface &&
(glitz_surface_get_width (surface) != width ||
glitz_surface_get_height (surface) != height))
{
glitz_format_t *format;
format = pScreenPriv->pixmapFormats[pDrawable->depth].format;
glitz_surface_destroy (surface);
pBufferPriv->backSurface =
glitz_surface_create (pScreenPriv->drawable, format,
width, height, 0, NULL);
if (!pBufferPriv->backSurface)
status = GL_FALSE;
}
}
ValidateGC (pDrawable, pBufferPriv->pGC);
}
else if (pBufferPriv->private)
{
glPriv->private = pBufferPriv->private;
status = (*pBufferPriv->resizeBuffers) (buffer,
x, y, width, height,
glPriv,
bufferMask);
glPriv->private = pBufferPriv;
}
return status;
}
static int
xglBindBuffers (__GLXdrawablePrivate *glxPriv,
int buffer)
{
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
xglGLBufferPtr pBufferPriv = glPriv->private;
if (cctx)
{
xglTexUnitPtr pTexUnit = &cctx->attrib.texUnits[cctx->activeTexUnit];
xglTexObjPtr pTexObj = NULL;
DrawablePtr pDrawable;
/* XXX: front left buffer is only supported so far */
if (buffer != GLX_FRONT_LEFT_EXT)
return BadMatch;
/* Must be a GLXpixmap */
if (!glxPriv->pGlxPixmap)
return __glXBadDrawable;
pDrawable = glxPriv->pGlxPixmap->pDraw;
switch (glxPriv->texTarget) {
case GLX_TEXTURE_RECTANGLE_EXT:
pTexObj = pTexUnit->pRect;
break;
case GLX_TEXTURE_2D_EXT:
pTexObj = pTexUnit->p2D;
break;
default:
break;
}
if (pTexObj)
{
XGL_DRAWABLE_PIXMAP (pDrawable);
pPixmap->refcnt++;
if (pTexObj->pPixmap)
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
pTexObj->pPixmap = pPixmap;
return Success;
}
}
else if (pBufferPriv->private)
{
int status;
glPriv->private = pBufferPriv->private;
status = (*pBufferPriv->bindBuffers) (glxPriv, buffer);
glPriv->private = pBufferPriv;
return status;
}
return __glXBadContext;
}
static int
xglReleaseBuffers (__GLXdrawablePrivate *glxPriv,
int buffer)
{
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
xglGLBufferPtr pBufferPriv = glPriv->private;
if (cctx)
{
xglTexObjPtr pTexObj;
/* XXX: front left buffer is only supported so far */
if (buffer != GLX_FRONT_LEFT_EXT)
return BadMatch;
/* Must be a GLXpixmap */
if (glxPriv->pGlxPixmap)
{
DrawablePtr pDrawable = glxPriv->pGlxPixmap->pDraw;
XGL_DRAWABLE_PIXMAP (pDrawable);
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
if (pTexObj && pTexObj->pPixmap == pPixmap)
{
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
pTexObj->pPixmap = NULL;
return Success;
}
else
{
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
if (pTexObj && pTexObj->pPixmap == pPixmap)
{
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
pTexObj->pPixmap = NULL;
return Success;
}
}
}
}
else if (pBufferPriv->private)
{
int status;
glPriv->private = pBufferPriv->private;
status = (*pBufferPriv->releaseBuffers) (glxPriv, buffer);
glPriv->private = pBufferPriv;
return status;
}
return __glXBadContext;
}
static void
xglFreeBuffers (__GLdrawablePrivate *glPriv)
{
xglGLBufferPtr pBufferPriv = glPriv->private;
glPriv->private = pBufferPriv->private;
if (pBufferPriv->freeBuffers)
(*pBufferPriv->freeBuffers) (glPriv);
if (pBufferPriv->pGC)
FreeGC (pBufferPriv->pGC, (GContext) 0);
if (pBufferPriv->backSurface)
glitz_surface_destroy (pBufferPriv->backSurface);
xfree (pBufferPriv);
}
static void
xglCreateBuffer (__GLXdrawablePrivate *glxPriv)
{
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
DrawablePtr pDrawable = glxPriv->pDraw;
ScreenPtr pScreen = pDrawable->pScreen;
xglGLBufferPtr pBufferPriv;
XGL_SCREEN_PRIV (pScreen);
pBufferPriv = xalloc (sizeof (xglGLBufferRec));
if (!pBufferPriv)
FatalError ("xglCreateBuffer: No memory\n");
pBufferPriv->pScreen = pScreen;
pBufferPriv->pDrawable = NULL;
pBufferPriv->pPixmap = NULL;
pBufferPriv->pGC = NULL;
pBufferPriv->backSurface = NULL;
pBufferPriv->swapBuffers = NULL;
pBufferPriv->bindBuffers = NULL;
pBufferPriv->releaseBuffers = NULL;
pBufferPriv->resizeBuffers = NULL;
pBufferPriv->private = NULL;
pBufferPriv->freeBuffers = NULL;
REGION_INIT (pScreen, &pBufferPriv->damage, NullBox, 0);
/* use native back buffer for regular windows */
if (pDrawable->type == DRAWABLE_WINDOW
#ifdef COMPOSITE
/* this is a root window, can't be redirected */
&& (!((WindowPtr) pDrawable)->parent)
#endif
)
{
pBufferPriv->pDrawable = pDrawable;
if (glxPriv->pGlxVisual->doubleBuffer)
{
pBufferPriv->backSurface = pScreenPriv->backSurface;
glitz_surface_reference (pScreenPriv->backSurface);
}
}
else if (0) /* pScreenPriv->features &
GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) */
{
pBufferPriv->pDrawable = pDrawable;
if (glxPriv->pGlxVisual->doubleBuffer)
{
int depth = pDrawable->depth;
pBufferPriv->backSurface =
glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[depth].format,
pDrawable->width, pDrawable->height,
0, NULL);
if (!pBufferPriv->backSurface)
FatalError ("xglCreateBuffer: glitz_surface_create\n");
}
}
else
{
(*screenInfoPriv.createBuffer) (glxPriv);
/* Wrap the swap buffers routine */
pBufferPriv->swapBuffers = glxPriv->swapBuffers;
/* Wrap the render texture routines */
pBufferPriv->bindBuffers = glxPriv->bindBuffers;
pBufferPriv->releaseBuffers = glxPriv->releaseBuffers;
/* Wrap the front buffer's resize routine */
pBufferPriv->resizeBuffers = glPriv->frontBuffer.resize;
/* Save Xgl's private buffer structure */
pBufferPriv->freeBuffers = glPriv->freePrivate;
pBufferPriv->private = glPriv->private;
}
glxPriv->texTarget = GLX_NO_TEXTURE_EXT;
/* We enable render texture for all GLXPixmaps right now. Eventually, this
should only be enabled when fbconfig attribute GLX_RENDER_TEXTURE_RGB or
GLX_RENDER_TEXTURE_RGBA is set to TRUE. */
if (pDrawable->type != DRAWABLE_WINDOW)
{
/* GL_ARB_texture_rectangle is required for sane texture coordinates.
GL_ARB_texture_border_clamp is required right now as glitz will
emulate it when missing, which means a 1 pixel translucent black
border inside textures, that cannot be exposed to clients. */
if (pScreenPriv->features &
(GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK |
GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK))
{
glitz_point_fixed_t point = { 1 << 16 , 1 << 16 };
XGL_DRAWABLE_PIXMAP (pDrawable);
if (xglCreatePixmapSurface (pPixmap))
{
XGL_PIXMAP_PRIV (pPixmap);
/* FIXME: doesn't work for 1x1 textures */
glitz_surface_translate_point (pPixmapPriv->surface,
&point, &point);
if (point.x > (1 << 16) || point.y > (1 << 16))
glxPriv->texTarget = GLX_TEXTURE_RECTANGLE_EXT;
else
glxPriv->texTarget = GLX_TEXTURE_2D_EXT;
}
}
}
glxPriv->swapBuffers = xglSwapBuffers;
glxPriv->bindBuffers = xglBindBuffers;
glxPriv->releaseBuffers = xglReleaseBuffers;
glPriv->frontBuffer.resize = xglResizeBuffers;
glPriv->private = (void *) pBufferPriv;
glPriv->freePrivate = xglFreeBuffers;
}
static Bool
xglScreenProbe (int screen)
{
Bool status;
status = (*screenInfoPriv.screenProbe) (screen);
/* Wrap createBuffer */
if (__glDDXScreenInfo.createBuffer != xglCreateBuffer)
{
screenInfoPriv.createBuffer = __glDDXScreenInfo.createBuffer;
__glDDXScreenInfo.createBuffer = xglCreateBuffer;
}
/* Wrap createContext */
if (__glDDXScreenInfo.createContext != xglCreateContext)
{
screenInfoPriv.createContext = __glDDXScreenInfo.createContext;
__glDDXScreenInfo.createContext = xglCreateContext;
}
return status;
}
static int
xglXWaitX (__GLXclientState *cl, GLbyte *pc)
{
xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
__GLXcontext *cx;
cx = (__GLXcontext *) __glXLookupContextByTag (cl, req->contextTag);
if (cx)
{
xglGLContextPtr pContext = (xglGLContextPtr) cx->gc;
__GLXcontext *glxCtx = (__GLXcontext *)
pContext->iface.imports.other;
XGL_SCREEN_PRIV (glxCtx->pScreen);
glitz_drawable_finish (pScreenPriv->drawable);
return Success;
}
else
{
cl->client->errorValue = req->contextTag;
return __glXBadContextTag;
}
}
static int
xglXSwapWaitX (__GLXclientState *cl, GLbyte *pc)
{
xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
__GLX_DECLARE_SWAP_VARIABLES;
__GLX_SWAP_SHORT (&req->length);
__GLX_SWAP_INT (&req->contextTag);
return xglXWaitX (cl, pc);
}
static Bool
xglDestroyWindow (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
Bool ret;
XGL_SCREEN_PRIV (pScreen);
if (cctx)
{
if (cctx->pDrawBuffer->pDrawable == &pWin->drawable)
cctx->pDrawBuffer->pDrawable = NULL;
if (cctx->pReadBuffer->pDrawable == &pWin->drawable)
cctx->pReadBuffer->pDrawable = NULL;
}
XGL_SCREEN_UNWRAP (DestroyWindow);
ret = (*pScreen->DestroyWindow) (pWin);
XGL_SCREEN_WRAP (DestroyWindow, xglDestroyWindow);
return ret;
}
Bool
xglInitVisualConfigs (ScreenPtr pScreen)
{
miInitVisualsProcPtr initVisualsProc = NULL;
VisualPtr visuals;
int nvisuals;
DepthPtr depths;
int ndepths;
int rootDepth;
VisualID defaultVis;
glitz_drawable_format_t *format;
xglPixelFormatPtr pPixel;
__GLXvisualConfig *pConfig;
xglGLXVisualConfigPtr pConfigPriv, *ppConfigPriv;
XID *installedCmaps;
ColormapPtr installedCmap;
int numInstalledCmaps;
int numConfig = 1;
int depth, bpp, i;
XGL_SCREEN_PRIV (pScreen);
XGL_SCREEN_WRAP (DestroyWindow, xglDestroyWindow);
depth = pScreenPriv->pVisual->pPixel->depth;
bpp = pScreenPriv->pVisual->pPixel->masks.bpp;
format = glitz_drawable_get_format (pScreenPriv->drawable);
pPixel = pScreenPriv->pixmapFormats[depth].pPixel;
if (format->doublebuffer)
{
pScreenPriv->backSurface =
glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[depth].format,
pScreen->width, pScreen->height,
0, NULL);
if (!pScreenPriv->backSurface)
return FALSE;
glitz_surface_attach (pScreenPriv->backSurface,
pScreenPriv->drawable,
GLITZ_DRAWABLE_BUFFER_BACK_COLOR);
numConfig *= 2;
}
pConfig = xcalloc (sizeof (__GLXvisualConfig), numConfig);
if (!pConfig)
return FALSE;
pConfigPriv = xcalloc (sizeof (xglGLXVisualConfigRec), numConfig);
if (!pConfigPriv)
{
xfree (pConfig);
return FALSE;
}
ppConfigPriv = xcalloc (sizeof (xglGLXVisualConfigPtr), numConfig);
if (!ppConfigPriv)
{
xfree (pConfigPriv);
xfree (pConfig);
return FALSE;
}
installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID));
if (!installedCmaps)
{
xfree (ppConfigPriv);
xfree (pConfigPriv);
xfree (pConfig);
return FALSE;
}
for (i = 0; i < numConfig; i++)
{
ppConfigPriv[i] = &pConfigPriv[i];
pConfig[i].vid = (VisualID) (-1);
pConfig[i].class = -1;
pConfig[i].rgba = TRUE;
pConfig[i].redSize = format->color.red_size;
pConfig[i].greenSize = format->color.green_size;
pConfig[i].blueSize = format->color.blue_size;
pConfig[i].redMask = pPixel->masks.red_mask;
pConfig[i].greenMask = pPixel->masks.green_mask;
pConfig[i].blueMask = pPixel->masks.blue_mask;
if (format->color.alpha_size)
{
pConfig[i].alphaSize = format->color.alpha_size;
pConfig[i].alphaMask = pPixel->masks.alpha_mask;
}
else
{
pConfig[i].alphaSize = 0;
pConfig[i].alphaMask = 0;
}
if (i == 1)
{
pConfig[i].doubleBuffer = FALSE;
pConfig[i].depthSize = 0;
pConfig[i].stencilSize = 0;
}
else
{
pConfig[i].doubleBuffer = TRUE;
pConfig[i].depthSize = format->depth_size;
pConfig[i].stencilSize = format->stencil_size;
}
pConfig[i].stereo = FALSE;
if (depth == 16)
pConfig[i].bufferSize = 16;
else
pConfig[i].bufferSize = 32;
pConfig[i].auxBuffers = 0;
pConfig[i].level = 0;
pConfig[i].visualRating = GLX_NONE;
pConfig[i].transparentPixel = GLX_NONE;
pConfig[i].transparentRed = 0;
pConfig[i].transparentGreen = 0;
pConfig[i].transparentBlue = 0;
pConfig[i].transparentAlpha = 0;
pConfig[i].transparentIndex = 0;
}
GlxSetVisualConfigs (numConfig, pConfig, (void **) ppConfigPriv);
/* Wrap screenProbe */
if (__glDDXScreenInfo.screenProbe != xglScreenProbe)
{
screenInfoPriv.screenProbe = __glDDXScreenInfo.screenProbe;
__glDDXScreenInfo.screenProbe = xglScreenProbe;
__glXSingleTable[9] = xglXWaitX;
__glXSwapSingleTable[9] = xglXSwapWaitX;
}
visuals = pScreen->visuals;
nvisuals = pScreen->numVisuals;
depths = pScreen->allowedDepths;
ndepths = pScreen->numDepths;
rootDepth = pScreen->rootDepth;
defaultVis = pScreen->rootVisual;
/* Find installed colormaps */
numInstalledCmaps = (*pScreen->ListInstalledColormaps) (pScreen,
installedCmaps);
GlxWrapInitVisuals (&initVisualsProc);
GlxInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootDepth,
&defaultVis, ((unsigned long) 1 << (bpp - 1)), 8, -1);
/* Fix up any existing installed colormaps. */
for (i = 0; i < numInstalledCmaps; i++)
{
int j;
installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP);
if (!installedCmap)
continue;
j = installedCmap->pVisual - pScreen->visuals;
installedCmap->pVisual = &visuals[j];
}
pScreen->visuals = visuals;
pScreen->numVisuals = nvisuals;
pScreen->allowedDepths = depths;
pScreen->numDepths = ndepths;
pScreen->rootDepth = rootDepth;
pScreen->rootVisual = defaultVis;
xfree (installedCmaps);
xfree (pConfigPriv);
xfree (pConfig);
return TRUE;
}
#endif /* GLXEXT */