Commit 844a4094 authored by Reinhard Tartler's avatar Reinhard Tartler

Imported nx-X11-3.1.0-3.tar.gz

Summary: Imported nx-X11-3.1.0-3.tar.gz Keywords: Imported nx-X11-3.1.0-3.tar.gz into Git repository
parent f4092abd
ChangeLog:
nx-X11-3.1.0-3
- Moved a variable definition placed in _mesa_make_current().
nx-X11-3.1.0-2
- Fixed TR10E01924. A crash could occur in _mesa_make_current().
- Initialized after_ret variable in _XcmsGetProperty().
nx-X11-3.1.0-1
- Opened the 3.1.0 branch based on nx-X11-3.0.0-37.
......
ChangeLog:
nx-X11-3.1.0-3
- Moved a variable definition placed in _mesa_make_current().
nx-X11-3.1.0-2
- Fixed TR10E01924. A crash could occur in _mesa_make_current().
- Initialized after_ret variable in _XcmsGetProperty().
nx-X11-3.1.0-1
- Opened the 3.1.0 branch based on nx-X11-3.0.0-37.
nx-X11-3.0.0-37
- Changed the Xserver Imakefile to link against Xcomposite on the
......
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXAGENT, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
typedef struct _WSDrawBufferRec {
GLframebuffer *DrawBuffer;
struct _WSDrawBufferRec *next;
} WSDrawBufferRec, *WSDrawBufferPtr;
WSDrawBufferPtr pWSDrawBuffer;
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXAGENT, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
typedef struct _WSDrawBufferRec {
GLframebuffer *DrawBuffer;
struct _WSDrawBufferRec *next;
} WSDrawBufferRec, *WSDrawBufferPtr;
WSDrawBufferPtr pWSDrawBuffer;
......@@ -131,6 +131,10 @@
#endif
#include "shaderobjects.h"
#ifdef NXAGENT_SERVER
#include "WSDrawBuffer.h"
#endif
#ifdef USE_SPARC_ASM
#include "sparc/sparc.h"
#endif
......@@ -143,6 +147,47 @@ int MESA_VERBOSE = 0;
int MESA_DEBUG_FLAGS = 0;
#endif
#ifdef NXAGENT_SERVER
extern WSDrawBufferPtr pWSDrawBuffer;
int IsWSDrawBuffer(GLframebuffer *mesa_buffer)
{
WSDrawBufferPtr p = pWSDrawBuffer;
while (p != NULL) {
if (p -> DrawBuffer == mesa_buffer) {
return 1;
}
p = p -> next;
}
return 0;
}
void FreeWSDrawBuffer(GLframebuffer *mesa_buffer)
{
WSDrawBufferPtr p = pWSDrawBuffer;
WSDrawBufferPtr pOld = NULL;
if (p == NULL)
return;
if (p -> DrawBuffer == mesa_buffer) {
pWSDrawBuffer = p -> next;
free(p);
return;
}
while (p -> next != NULL) {
if (p -> next -> DrawBuffer == mesa_buffer) {
pOld = p -> next;
p -> next = p -> next -> next;
free(pOld);
return;
}
p = p -> next;
}
}
#endif
/* ubyte -> float conversion */
GLfloat _mesa_ubyte_to_float_color_tab[256];
......@@ -1520,6 +1565,10 @@ void
_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
#ifdef NXAGENT_SERVER
int flag;
#endif
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(newCtx, "_mesa_make_current()\n");
......@@ -1558,11 +1607,30 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
ASSERT(readBuffer->Name == 0);
newCtx->WinSysDrawBuffer = drawBuffer;
newCtx->WinSysReadBuffer = readBuffer;
#ifdef NXAGENT_SERVER
flag = 0;
if (newCtx->DrawBuffer) {
if (!IsWSDrawBuffer(newCtx->DrawBuffer)) {
if (newCtx->DrawBuffer->Name == 0) {
flag = 1;
}
FreeWSDrawBuffer(newCtx->DrawBuffer);
}
else flag = 1;
}
if (!newCtx->DrawBuffer || flag) {
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
}
#else
/* don't replace user-buffer bindings with window system buffer */
if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
}
#endif
newCtx->NewState |= _NEW_BUFFERS;
......
/**
* \file context.c
* Mesa context/visual/framebuffer management functions.
* \author Brian Paul
*/
/*
* Mesa 3-D graphics library
* Version: 6.4
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \mainpage Mesa Main Module
*
* \section MainIntroduction Introduction
*
* The Mesa Main module consists of all the files in the main/ directory.
* Among the features of this module are:
* <UL>
* <LI> Structures to represent most GL state </LI>
* <LI> State set/get functions </LI>
* <LI> Display lists </LI>
* <LI> Texture unit, object and image handling </LI>
* <LI> Matrix and attribute stacks </LI>
* </UL>
*
* Other modules are responsible for API dispatch, vertex transformation,
* point/line/triangle setup, rasterization, vertex array caching,
* vertex/fragment programs/shaders, etc.
*
*
* \section AboutDoxygen About Doxygen
*
* If you're viewing this information as Doxygen-generated HTML you'll
* see the documentation index at the top of this page.
*
* The first line lists the Mesa source code modules.
* The second line lists the indexes available for viewing the documentation
* for each module.
*
* Selecting the <b>Main page</b> link will display a summary of the module
* (this page).
*
* Selecting <b>Data Structures</b> will list all C structures.
*
* Selecting the <b>File List</b> link will list all the source files in
* the module.
* Selecting a filename will show a list of all functions defined in that file.
*
* Selecting the <b>Data Fields</b> link will display a list of all
* documented structure members.
*
* Selecting the <b>Globals</b> link will display a list
* of all functions, structures, global variables and macros in the module.
*
*/
#include "glheader.h"
#include "imports.h"
#include "accum.h"
#include "attrib.h"
#include "blend.h"
#include "buffers.h"
#include "bufferobj.h"
#include "colortab.h"
#include "context.h"
#include "debug.h"
#include "depth.h"
#include "dlist.h"
#include "eval.h"
#include "enums.h"
#include "extensions.h"
#include "fbobject.h"
#include "feedback.h"
#include "fog.h"
#include "get.h"
#include "glthread.h"
#include "glapioffsets.h"
#include "histogram.h"
#include "hint.h"
#include "hash.h"
#include "light.h"
#include "lines.h"
#include "macros.h"
#include "matrix.h"
#include "occlude.h"
#include "pixel.h"
#include "points.h"
#include "polygon.h"
#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
#include "program.h"
#endif
#include "rastpos.h"
#include "simple_list.h"
#include "state.h"
#include "stencil.h"
#include "texcompress.h"
#include "teximage.h"
#include "texobj.h"
#include "texstate.h"
#include "mtypes.h"
#include "varray.h"
#include "version.h"
#include "vtxfmt.h"
#if _HAVE_FULL_GL
#include "math/m_translate.h"
#include "math/m_matrix.h"
#include "math/m_xform.h"
#include "math/mathmod.h"
#endif
#include "shaderobjects.h"
#ifdef NXAGENT_SERVER
#include "WSDrawBuffer.h"
#endif
#ifdef USE_SPARC_ASM
#include "sparc/sparc.h"
#endif
#ifndef MESA_VERBOSE
int MESA_VERBOSE = 0;
#endif
#ifndef MESA_DEBUG_FLAGS
int MESA_DEBUG_FLAGS = 0;
#endif
#ifdef NXAGENT_SERVER
extern WSDrawBufferPtr pWSDrawBuffer;
int IsWSDrawBuffer(GLframebuffer *mesa_buffer)
{
WSDrawBufferPtr p = pWSDrawBuffer;
while (p != NULL) {
if (p -> DrawBuffer == mesa_buffer) {
return 1;
}
p = p -> next;
}
return 0;
}
void FreeWSDrawBuffer(GLframebuffer *mesa_buffer)
{
WSDrawBufferPtr p = pWSDrawBuffer;
WSDrawBufferPtr pOld = NULL;
if (p == NULL)
return;
if (p -> DrawBuffer == mesa_buffer) {
pWSDrawBuffer = p -> next;
free(p);
return;
}
while (p -> next != NULL) {
if (p -> next -> DrawBuffer == mesa_buffer) {
pOld = p -> next;
p -> next = p -> next -> next;
free(pOld);
return;
}
p = p -> next;
}
}
#endif
/* ubyte -> float conversion */
GLfloat _mesa_ubyte_to_float_color_tab[256];
static void
free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
/**********************************************************************/
/** \name OpenGL SI-style interface (new in Mesa 3.5)
*
* \if subset
* \note Most of these functions are never called in the Mesa subset.
* \endif
*/
/*@{*/
/**
* Destroy context callback.
*
* \param gc context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::destroyCurrent) when
* the rendering context is to be destroyed.
* \endif
*
* Frees the context data and the context structure.
*/
GLboolean
_mesa_destroyContext(__GLcontext *gc)
{
if (gc) {
_mesa_free_context_data(gc);
_mesa_free(gc);
}
return GL_TRUE;
}
/**
* Unbind context callback.
*
* \param gc context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::loseCurrent)
* when the rendering context is made non-current.
* \endif
*
* No-op
*/
GLboolean
_mesa_loseCurrent(__GLcontext *gc)
{
/* XXX unbind context from thread */
(void) gc;
return GL_TRUE;
}
/**
* Bind context callback.
*
* \param gc context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::makeCurrent)
* when the rendering context is made current.
* \endif
*
* No-op
*/
GLboolean
_mesa_makeCurrent(__GLcontext *gc)
{
/* XXX bind context to thread */
(void) gc;
return GL_TRUE;
}
/**
* Share context callback.
*
* \param gc context.
* \param gcShare shared context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::shareContext)
* \endif
*
* Update the shared context reference count, gl_shared_state::RefCount.
*/
GLboolean
_mesa_shareContext(__GLcontext *gc, __GLcontext *gcShare)
{
if (gc && gcShare && gc->Shared && gcShare->Shared) {
gc->Shared->RefCount--;
if (gc->Shared->RefCount == 0) {
free_shared_state(gc, gc->Shared);
}
gc->Shared = gcShare->Shared;
gc->Shared->RefCount++;
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
#if _HAVE_FULL_GL
/**
* Copy context callback.
*/
GLboolean
_mesa_copyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask)
{
if (dst && src) {
_mesa_copy_context( src, dst, mask );
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
#endif
/** No-op */
GLboolean
_mesa_forceCurrent(__GLcontext *gc)
{
(void) gc;
return GL_TRUE;
}
/**
* Windows/buffer resizing notification callback.
*
* \param gc GL context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*/
GLboolean
_mesa_notifyResize(__GLcontext *gc)
{
GLint x, y;
GLuint width, height;
__GLdrawablePrivate *d = gc->imports.getDrawablePrivate(gc);
if (!d || !d->getDrawableSize)
return GL_FALSE;
d->getDrawableSize( d, &x, &y, &width, &height );
/* update viewport, resize software buffers, etc. */
return GL_TRUE;
}
/**
* Window/buffer destruction notification callback.
*
* \param gc GL context.
*
* Called when the context's window/buffer is going to be destroyed.
*
* No-op
*/
void
_mesa_notifyDestroy(__GLcontext *gc)
{
/* Unbind from it. */
(void) gc;
}
/**
* Swap buffers notification callback.
*
* \param gc GL context.
*
* Called by window system just before swapping buffers.
* We have to finish any pending rendering.
*/
void
_mesa_notifySwapBuffers(__GLcontext *gc)
{
FLUSH_VERTICES( gc, 0 );
}
/** No-op */
struct __GLdispatchStateRec *
_mesa_dispatchExec(__GLcontext *gc)
{
(void) gc;
return NULL;
}
/** No-op */
void
_mesa_beginDispatchOverride(__GLcontext *gc)
{
(void) gc;
}
/** No-op */
void
_mesa_endDispatchOverride(__GLcontext *gc)
{
(void) gc;
}
/**
* \ifnot subset
* Setup the exports.
*
* The window system will call these functions when it needs Mesa to do
* something.
*
* \note Device drivers should override these functions! For example,
* the Xlib driver should plug in the XMesa*-style functions into this
* structure. The XMesa-style functions should then call the _mesa_*
* version of these functions. This is an approximation to OO design
* (inheritance and virtual functions).
* \endif
*
* \if subset
* No-op.
*
* \endif
*/
static void
_mesa_init_default_exports(__GLexports *exports)
{
#if _HAVE_FULL_GL
exports->destroyContext = _mesa_destroyContext;
exports->loseCurrent = _mesa_loseCurrent;
exports->makeCurrent = _mesa_makeCurrent;
exports->shareContext = _mesa_shareContext;
exports->copyContext = _mesa_copyContext;
exports->forceCurrent = _mesa_forceCurrent;
exports->notifyResize = _mesa_notifyResize;
exports->notifyDestroy = _mesa_notifyDestroy;
exports->notifySwapBuffers = _mesa_notifySwapBuffers;
exports->dispatchExec = _mesa_dispatchExec;
exports->beginDispatchOverride = _mesa_beginDispatchOverride;
exports->endDispatchOverride = _mesa_endDispatchOverride;
#else
(void) exports;
#endif
}
/**
* Exported OpenGL SI interface.
*/
__GLcontext *
__glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes)
{
GLcontext *ctx;
ctx = (GLcontext *) (*imports->calloc)(NULL, 1, sizeof(GLcontext));
if (ctx == NULL) {
return NULL;
}
/* XXX doesn't work at this time */
_mesa_initialize_context(ctx, modes, NULL, NULL, NULL);
ctx->imports = *imports;
return ctx;
}
/**
* Exported OpenGL SI interface.
*/
void
__glCoreNopDispatch(void)
{
#if 0
/* SI */
__gl_dispatch = __glNopDispatchState;
#else
/* Mesa */
_glapi_set_dispatch(NULL);
#endif
}
/*@}*/
/**********************************************************************/
/** \name GL Visual allocation/destruction */
/**********************************************************************/
/*@{*/
/**
* Allocates a GLvisual structure and initializes it via
* _mesa_initialize_visual().
*
* \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
* \param dbFlag double buffering
* \param stereoFlag stereo buffer
* \param depthBits requested bits per depth buffer value. Any value in [0, 32]
* is acceptable but the actual depth type will be GLushort or GLuint as
* needed.
* \param stencilBits requested minimum bits per stencil buffer value
* \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
* \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
* \param redBits number of bits per color component in frame buffer for RGB(A)
* mode. We always use 8 in core Mesa though.
* \param greenBits same as above.
* \param blueBits same as above.
* \param alphaBits same as above.
* \param numSamples not really used.
*
* \return pointer to new GLvisual or NULL if requested parameters can't be
* met.
*
* \note Need to add params for level and numAuxBuffers (at least)
*/
GLvisual *
_mesa_create_visual( GLboolean rgbFlag,
GLboolean dbFlag,
GLboolean stereoFlag,
GLint redBits,
GLint greenBits,
GLint blueBits,
GLint alphaBits,
GLint indexBits,
GLint depthBits,
GLint stencilBits,
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
GLint accumAlphaBits,
GLint numSamples )
{
GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
if (vis) {
if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
redBits, greenBits, blueBits, alphaBits,
indexBits, depthBits, stencilBits,
accumRedBits, accumGreenBits,
accumBlueBits, accumAlphaBits,
numSamples)) {
FREE(vis);
return NULL;
}
}
return vis;
}
/**
* Makes some sanity checks and fills in the fields of the
* GLvisual object with the given parameters. If the caller needs
* to set additional fields, he should just probably init the whole GLvisual
* object himself.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \sa _mesa_create_visual() above for the parameter description.
*/
GLboolean
_mesa_initialize_visual( GLvisual *vis,
GLboolean rgbFlag,
GLboolean dbFlag,
GLboolean stereoFlag,
GLint redBits,
GLint greenBits,
GLint blueBits,
GLint alphaBits,
GLint indexBits,
GLint depthBits,
GLint stencilBits,
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
GLint accumAlphaBits,
GLint numSamples )
{
assert(vis);
if (depthBits < 0 || depthBits > 32) {
return GL_FALSE;
}
if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
return GL_FALSE;
}
if (accumRedBits < 0 || accumRedBits > ACCUM_BITS) {
return GL_FALSE;
}
if (accumGreenBits < 0 || accumGreenBits > ACCUM_BITS) {
return GL_FALSE;
}
if (accumBlueBits < 0 || accumBlueBits > ACCUM_BITS) {
return GL_FALSE;
}
if (accumAlphaBits < 0 || accumAlphaBits > ACCUM_BITS) {
return GL_FALSE;
}
vis->rgbMode = rgbFlag;
vis->doubleBufferMode = dbFlag;
vis->stereoMode = stereoFlag;
vis->redBits = redBits;
vis->greenBits = greenBits;
vis->blueBits = blueBits;
vis->alphaBits = alphaBits;
vis->rgbBits = redBits + greenBits + blueBits;
vis->indexBits = indexBits;
vis->depthBits = depthBits;
vis->stencilBits = stencilBits;
vis->accumRedBits = accumRedBits;
vis->accumGreenBits = accumGreenBits;
vis->accumBlueBits = accumBlueBits;
vis->accumAlphaBits = accumAlphaBits;
vis->haveAccumBuffer = accumRedBits > 0;
vis->haveDepthBuffer = depthBits > 0;
vis->haveStencilBuffer = stencilBits > 0;
vis->numAuxBuffers = 0;
vis->level = 0;
vis->pixmapMode = 0;
vis->sampleBuffers = numSamples > 0 ? 1 : 0;
vis->samples = numSamples;
return GL_TRUE;
}
/**
* Destroy a visual and free its memory.
*
* \param vis visual.
*
* Frees the visual structure.
*/
void
_mesa_destroy_visual( GLvisual *vis )
{
FREE(vis);
}
/*@}*/
/**********************************************************************/
/** \name Context allocation, initialization, destroying
*
* The purpose of the most initialization functions here is to provide the
* default state values according to the OpenGL specification.
*/
/**********************************************************************/
/*@{*/
/**
* One-time initialization mutex lock.
*
* \sa Used by one_time_init().
*/
_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
/**
* Calls all the various one-time-init functions in Mesa.
*
* While holding a global mutex lock, calls several initialization functions,
* and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
* defined.
*
* \sa _mesa_init_lists(), _math_init().
*/
static void
one_time_init( GLcontext *ctx )
{
static GLboolean alreadyCalled = GL_FALSE;
(void) ctx;
_glthread_LOCK_MUTEX(OneTimeLock);
if (!alreadyCalled) {
GLuint i;
/* do some implementation tests */
assert( sizeof(GLbyte) == 1 );
assert( sizeof(GLubyte) == 1 );
assert( sizeof(GLshort) == 2 );
assert( sizeof(GLushort) == 2 );
assert( sizeof(GLint) == 4 );
assert( sizeof(GLuint) == 4 );
_mesa_init_lists();
#if _HAVE_FULL_GL
_math_init();
for (i = 0; i < 256; i++) {
_mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
}
#endif
#ifdef USE_SPARC_ASM
_mesa_init_sparc_glapi_relocs();
#endif
if (_mesa_getenv("MESA_DEBUG")) {
_glapi_noop_enable_warnings(GL_TRUE);
_glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
}
else {
_glapi_noop_enable_warnings(GL_FALSE);
}
#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
_mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
MESA_VERSION_STRING, __DATE__, __TIME__);
#endif
alreadyCalled = GL_TRUE;
}
_glthread_UNLOCK_MUTEX(OneTimeLock);
}
/**
* Allocate and initialize a shared context state structure.
* Initializes the display list, texture objects and vertex programs hash
* tables, allocates the texture objects. If it runs out of memory, frees
* everything already allocated before returning NULL.
*
* \return pointer to a gl_shared_state structure on success, or NULL on
* failure.
*/
static GLboolean
alloc_shared_state( GLcontext *ctx )
{
struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
if (!ss)
return GL_FALSE;
ctx->Shared = ss;
_glthread_INIT_MUTEX(ss->Mutex);
ss->DisplayList = _mesa_NewHashTable();
ss->TexObjects = _mesa_NewHashTable();
#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
ss->Programs = _mesa_NewHashTable();
#endif
#if FEATURE_ARB_vertex_program
ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
if (!ss->DefaultVertexProgram)
goto cleanup;
#endif
#if FEATURE_ARB_fragment_program
ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!ss->DefaultFragmentProgram)
goto cleanup;
#endif
#if FEATURE_ATI_fragment_shader
ss->DefaultFragmentShader = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, 0);
if (!ss->DefaultFragmentShader)
goto cleanup;
#endif
ss->BufferObjects = _mesa_NewHashTable();
ss->GL2Objects = _mesa_NewHashTable ();
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
if (!ss->Default1D)
goto cleanup;
ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
if (!ss->Default2D)
goto cleanup;
ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
if (!ss->Default3D)
goto cleanup;
ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
if (!ss->DefaultCubeMap)
goto cleanup;
ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
if (!ss->DefaultRect)
goto cleanup;
/* Effectively bind the default textures to all texture units */
ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
#if FEATURE_EXT_framebuffer_object
ss->FrameBuffers = _mesa_NewHashTable();
if (!ss->FrameBuffers)
goto cleanup;
ss->RenderBuffers = _mesa_NewHashTable();
if (!ss->RenderBuffers)
goto cleanup;
#endif
return GL_TRUE;
cleanup:
/* Ran out of memory at some point. Free everything and return NULL */
if (ss->DisplayList)
_mesa_DeleteHashTable(ss->DisplayList);
if (ss->TexObjects)
_mesa_DeleteHashTable(ss->TexObjects);
#if FEATURE_NV_vertex_program
if (ss->Programs)
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
if (ss->DefaultVertexProgram)
ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
#endif
#if FEATURE_ARB_fragment_program
if (ss->DefaultFragmentProgram)
ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
if (ss->DefaultFragmentShader)
ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentShader);
#endif
#if FEATURE_ARB_vertex_buffer_object
if (ss->BufferObjects)
_mesa_DeleteHashTable(ss->BufferObjects);
#endif
if (ss->GL2Objects)
_mesa_DeleteHashTable (ss->GL2Objects);
#if FEATURE_EXT_framebuffer_object
if (ss->FrameBuffers)
_mesa_DeleteHashTable(ss->FrameBuffers);
if (ss->RenderBuffers)
_mesa_DeleteHashTable(ss->RenderBuffers);
#endif
if (ss->Default1D)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
if (ss->Default2D)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
if (ss->Default3D)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
if (ss->DefaultCubeMap)
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
if (ss->DefaultRect)
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
if (ss)
_mesa_free(ss);
return GL_FALSE;
}
/**
* Deallocate a shared state context and all children structures.
*
* \param ctx GL context.
* \param ss shared state pointer.
*
* Frees the display lists, the texture objects (calling the driver texture
* deletion callback to free its private data) and the vertex programs, as well
* as their hash tables.
*
* \sa alloc_shared_state().
*/
static void
free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
{
/* Free display lists */
while (1) {
GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
if (list) {
_mesa_destroy_list(ctx, list);
}
else {
break;
}
}
_mesa_DeleteHashTable(ss->DisplayList);
/* Free texture objects */
ASSERT(ctx->Driver.DeleteTexture);
/* the default textures */
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
(*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
(*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
/* all other textures */
while (1) {
GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
if (texName) {
struct gl_texture_object *texObj = (struct gl_texture_object *)
_mesa_HashLookup(ss->TexObjects, texName);
ASSERT(texObj);
(*ctx->Driver.DeleteTexture)(ctx, texObj);
_mesa_HashRemove(ss->TexObjects, texName);
}
else {
break;
}
}
_mesa_DeleteHashTable(ss->TexObjects);
#if FEATURE_NV_vertex_program
/* Free vertex programs */
while (1) {
GLuint prog = _mesa_HashFirstEntry(ss->Programs);
if (prog) {
struct program *p = (struct program *) _mesa_HashLookup(ss->Programs,
prog);
ASSERT(p);
ctx->Driver.DeleteProgram(ctx, p);
_mesa_HashRemove(ss->Programs, prog);
}
else {
break;
}
}
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
_mesa_delete_program(ctx, ss->DefaultVertexProgram);
#endif
#if FEATURE_ARB_fragment_program
_mesa_delete_program(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
_mesa_delete_program(ctx, ss->DefaultFragmentShader);
#endif
#if FEATURE_ARB_vertex_buffer_object
_mesa_DeleteHashTable(ss->BufferObjects);
#endif
_mesa_DeleteHashTable (ss->GL2Objects);
#if FEATURE_EXT_framebuffer_object
_mesa_DeleteHashTable(ss->FrameBuffers);
_mesa_DeleteHashTable(ss->RenderBuffers);
#endif
_glthread_DESTROY_MUTEX(ss->Mutex);
FREE(ss);
}
/**
* Initialize fields of gl_current_attrib (aka ctx->Current.*)
*/
static void
_mesa_init_current( GLcontext *ctx )
{
GLuint i;
/* Current group */
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
}
/* special cases: */
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
ctx->Current.Index = 1;
ctx->Current.EdgeFlag = GL_TRUE;
}
/**
* Initialize fields of gl_constants (aka ctx->Const.*).
* Use defaults from config.h. The device drivers will often override
* some of these values (such as number of texture units).
*/
static void
_mesa_init_constants( GLcontext *ctx )
{
assert(ctx);
assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
/* Constants, may be overriden (usually only reduced) by device drivers */
ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
ctx->Const.MinPointSize = MIN_POINT_SIZE;
ctx->Const.MaxPointSize = MAX_POINT_SIZE;
ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
ctx->Const.MaxLights = MAX_LIGHTS;
ctx->Const.MaxShininess = 128.0;
ctx->Const.MaxSpotExponent = 128.0;
ctx->Const.MaxViewportWidth = MAX_WIDTH;
ctx->Const.MaxViewportHeight = MAX_HEIGHT;
#if FEATURE_ARB_vertex_program
ctx->Const.MaxVertexProgramInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
ctx->Const.MaxVertexProgramAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
ctx->Const.MaxVertexProgramTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
ctx->Const.MaxVertexProgramLocalParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
ctx->Const.MaxVertexProgramEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;/*XXX*/
ctx->Const.MaxVertexProgramAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
#endif
#if FEATURE_ARB_fragment_program
ctx->Const.MaxFragmentProgramInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
ctx->Const.MaxFragmentProgramTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
ctx->Const.MaxFragmentProgramLocalParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
ctx->Const.MaxFragmentProgramEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;/*XXX*/
ctx->Const.MaxFragmentProgramAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
ctx->Const.MaxFragmentProgramAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
#endif
ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
/* If we're running in the X server, do bounds checking to prevent
* segfaults and server crashes!
*/
#if defined(XFree86LOADER) && defined(IN_MODULE)
ctx->Const.CheckArrayBounds = GL_TRUE;
#else
ctx->Const.CheckArrayBounds = GL_FALSE;
#endif
ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
/* GL_OES_read_format */
ctx->Const.ColorReadFormat = GL_RGBA;
ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
#if FEATURE_EXT_framebuffer_object
ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
#endif
/* sanity checks */
ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
}
/**
* Initialize the attribute groups in a GL context.
*
* \param ctx GL context.
*
* Initializes all the attributes, calling the respective <tt>init*</tt>
* functions for the more complex data structures.
*/
static GLboolean
init_attrib_groups( GLcontext *ctx )
{
assert(ctx);
/* Constants */
_mesa_init_constants( ctx );
/* Extensions */
_mesa_init_extensions( ctx );
/* Attribute Groups */
_mesa_init_accum( ctx );
_mesa_init_attrib( ctx );
_mesa_init_buffer_objects( ctx );
_mesa_init_color( ctx );
_mesa_init_colortables( ctx );
_mesa_init_current( ctx );
_mesa_init_depth( ctx );
_mesa_init_debug( ctx );
_mesa_init_display_list( ctx );
_mesa_init_eval( ctx );
_mesa_init_feedback( ctx );
_mesa_init_fog( ctx );
_mesa_init_histogram( ctx );
_mesa_init_hint( ctx );
_mesa_init_line( ctx );
_mesa_init_lighting( ctx );
_mesa_init_matrix( ctx );
_mesa_init_multisample( ctx );
_mesa_init_occlude( ctx );
_mesa_init_pixel( ctx );
_mesa_init_point( ctx );
_mesa_init_polygon( ctx );
_mesa_init_program( ctx );
_mesa_init_rastpos( ctx );
_mesa_init_scissor( ctx );
_mesa_init_shaderobjects (ctx);
_mesa_init_stencil( ctx );
_mesa_init_transform( ctx );
_mesa_init_varray( ctx );
_mesa_init_viewport( ctx );
if (!_mesa_init_texture( ctx ))
return GL_FALSE;
_mesa_init_texture_s3tc( ctx );
_mesa_init_texture_fxt1( ctx );
/* Miscellaneous */
ctx->NewState = _NEW_ALL;
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
ctx->_Facing = 0;
#if CHAN_TYPE == GL_FLOAT
ctx->ClampFragmentColors = GL_FALSE; /* XXX temporary */
#else
ctx->ClampFragmentColors = GL_TRUE;
#endif
ctx->ClampVertexColors = GL_TRUE;
return GL_TRUE;
}
/**
* This is the default function we plug into all dispatch table slots
* This helps prevents a segfault when someone calls a GL function without
* first checking if the extension's supported.
*/
static int
generic_nop(void)
{
_mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)");
return 0;
}
/**
* Allocate and initialize a new dispatch table.
*/
static struct _glapi_table *
alloc_dispatch_table(void)
{
/* Find the larger of Mesa's dispatch table and libGL's dispatch table.
* In practice, this'll be the same for stand-alone Mesa. But for DRI
* Mesa we do this to accomodate different versions of libGL and various
* DRI drivers.
*/
GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
sizeof(struct _glapi_table) / sizeof(_glapi_proc));
struct _glapi_table *table =
(struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
if (table) {
_glapi_proc *entry = (_glapi_proc *) table;
GLint i;
for (i = 0; i < numEntries; i++) {
entry[i] = (_glapi_proc) generic_nop;
}
}
return table;
}
/**
* Initialize a GLcontext struct (rendering context).
*
* This includes allocating all the other structs and arrays which hang off of
* the context by pointers.
* Note that the driver needs to pass in its dd_function_table here since
* we need to at least call driverFunctions->NewTextureObject to create the
* default texture objects.
*
* Called by _mesa_create_context().
*
* Performs the imports and exports callback tables initialization, and
* miscellaneous one-time initializations. If no shared context is supplied one
* is allocated, and increase its reference count. Setups the GL API dispatch
* tables. Initialize the TNL module. Sets the maximum Z buffer depth.
* Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
* for debug flags.
*
* \param ctx the context to initialize
* \param visual describes the visual attributes for this context
* \param share_list points to context to share textures, display lists,
* etc with, or NULL
* \param driverFunctions table of device driver functions for this context
* to use
* \param driverContext pointer to driver-specific context data
*/
GLboolean
_mesa_initialize_context( GLcontext *ctx,
const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
{
ASSERT(driverContext);
assert(driverFunctions->NewTextureObject);
assert(driverFunctions->FreeTexImageData);
/* If the driver wants core Mesa to use special imports, it'll have to
* override these defaults.
*/
_mesa_init_default_imports( &(ctx->imports), driverContext );
/* initialize the exports (Mesa functions called by the window system) */
_mesa_init_default_exports( &(ctx->exports) );
/* misc one-time initializations */
one_time_init(ctx);
ctx->Visual = *visual;
ctx->DrawBuffer = NULL;
ctx->ReadBuffer = NULL;
ctx->WinSysDrawBuffer = NULL;
ctx->WinSysReadBuffer = NULL;
/* Plug in driver functions and context pointer here.
* This is important because when we call alloc_shared_state() below
* we'll call ctx->Driver.NewTextureObject() to create the default
* textures.
*/
ctx->Driver = *driverFunctions;
ctx->DriverCtx = driverContext;
if (share_list) {
/* share state with another context */
ctx->Shared = share_list->Shared;
}
else {
/* allocate new, unshared state */
if (!alloc_shared_state( ctx )) {
return GL_FALSE;
}
}
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
ctx->Shared->RefCount++;
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
if (!init_attrib_groups( ctx )) {
free_shared_state(ctx, ctx->Shared);
return GL_FALSE;
}
/* setup the API dispatch tables */
ctx->Exec = alloc_dispatch_table();
ctx->Save = alloc_dispatch_table();
if (!ctx->Exec || !ctx->Save) {
free_shared_state(ctx, ctx->Shared);
if (ctx->Exec)
_mesa_free(ctx->Exec);
}
_mesa_init_exec_table(ctx->Exec);
ctx->CurrentDispatch = ctx->Exec;
#if _HAVE_FULL_GL
_mesa_init_dlist_table(ctx->Save);
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
/* Neutral tnl module stuff */
_mesa_init_exec_vtxfmt( ctx );
ctx->TnlModule.Current = NULL;
ctx->TnlModule.SwapCount = 0;
#endif
ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
return GL_TRUE;
}
/**
* Allocate and initialize a GLcontext structure.
* Note that the driver needs to pass in its dd_function_table here since
* we need to at least call driverFunctions->NewTextureObject to initialize
* the rendering context.
*
* \param visual a GLvisual pointer (we copy the struct contents)
* \param share_list another context to share display lists with or NULL
* \param driverFunctions points to the dd_function_table into which the
* driver has plugged in all its special functions.
* \param driverCtx points to the device driver's private context state
*
* \return pointer to a new __GLcontextRec or NULL if error.
*/
GLcontext *
_mesa_create_context( const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
{
GLcontext *ctx;
ASSERT(visual);
ASSERT(driverContext);
ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
if (!ctx)
return NULL;
if (_mesa_initialize_context(ctx, visual, share_list,
driverFunctions, driverContext)) {
return ctx;
}
else {
_mesa_free(ctx);
return NULL;
}
}
/**
* Free the data associated with the given context.
*
* But doesn't free the GLcontext struct itself.
*
* \sa _mesa_initialize_context() and init_attrib_groups().
*/
void
_mesa_free_context_data( GLcontext *ctx )
{
/* if we're destroying the current context, unbind it first */
if (ctx == _mesa_get_current_context()) {
_mesa_make_current(NULL, NULL, NULL);
}
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
_mesa_free_texture_data( ctx );
_mesa_free_matrix_data( ctx );
_mesa_free_viewport_data( ctx );
_mesa_free_colortables_data( ctx );
_mesa_free_program_data(ctx);
_mesa_free_occlude_data(ctx);
#if FEATURE_ARB_vertex_buffer_object
_mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
#endif
/* free dispatch tables */
_mesa_free(ctx->Exec);
_mesa_free(ctx->Save);
/* Shared context state (display lists, textures, etc) */
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
ctx->Shared->RefCount--;
assert(ctx->Shared->RefCount >= 0);
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
if (ctx->Shared->RefCount == 0) {
/* free shared state */
free_shared_state( ctx, ctx->Shared );
}
if (ctx->Extensions.String)
FREE((void *) ctx->Extensions.String);
}
/**
* Destroy a GLcontext structure.
*
* \param ctx GL context.
*
* Calls _mesa_free_context_data() and frees the GLcontext structure itself.
*/
void
_mesa_destroy_context( GLcontext *ctx )
{
if (ctx) {
_mesa_free_context_data(ctx);
FREE( (void *) ctx );
}
}
#if _HAVE_FULL_GL
/**
* Copy attribute groups from one context to another.
*
* \param src source context
* \param dst destination context
* \param mask bitwise OR of GL_*_BIT flags
*
* According to the bits specified in \p mask, copies the corresponding
* attributes from \p src into \p dst. For many of the attributes a simple \c
* memcpy is not enough due to the existence of internal pointers in their data
* structures.
*/
void
_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
{
if (mask & GL_ACCUM_BUFFER_BIT) {
/* OK to memcpy */
dst->Accum = src->Accum;
}
if (mask & GL_COLOR_BUFFER_BIT) {
/* OK to memcpy */
dst->Color = src->Color;
}
if (mask & GL_CURRENT_BIT) {
/* OK to memcpy */
dst->Current = src->Current;
}
if (mask & GL_DEPTH_BUFFER_BIT) {
/* OK to memcpy */
dst->Depth = src->Depth;
}
if (mask & GL_ENABLE_BIT) {
/* no op */
}
if (mask & GL_EVAL_BIT) {
/* OK to memcpy */
dst->Eval = src->Eval;
}
if (mask & GL_FOG_BIT) {
/* OK to memcpy */
dst->Fog = src->Fog;
}
if (mask & GL_HINT_BIT) {
/* OK to memcpy */
dst->Hint = src->Hint;
}
if (mask & GL_LIGHTING_BIT) {
GLuint i;
/* begin with memcpy */
MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light) );
/* fixup linked lists to prevent pointer insanity */
make_empty_list( &(dst->Light.EnabledList) );
for (i = 0; i < MAX_LIGHTS; i++) {
if (dst->Light.Light[i].Enabled) {
insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
}
}
}
if (mask & GL_LINE_BIT) {
/* OK to memcpy */
dst->Line = src->Line;
}
if (mask & GL_LIST_BIT) {
/* OK to memcpy */
dst->List = src->List;
}
if (mask & GL_PIXEL_MODE_BIT) {
/* OK to memcpy */
dst->Pixel = src->Pixel;
}
if (mask & GL_POINT_BIT) {
/* OK to memcpy */
dst->Point = src->Point;
}
if (mask & GL_POLYGON_BIT) {
/* OK to memcpy */
dst->Polygon = src->Polygon;
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
/* Use loop instead of MEMCPY due to problem with Portland Group's
* C compiler. Reported by John Stone.
*/
GLuint i;
for (i = 0; i < 32; i++) {
dst->PolygonStipple[i] = src->PolygonStipple[i];
}
}
if (mask & GL_SCISSOR_BIT) {
/* OK to memcpy */
dst->Scissor = src->Scissor;
}
if (mask & GL_STENCIL_BUFFER_BIT) {
/* OK to memcpy */
dst->Stencil = src->Stencil;
}
if (mask & GL_TEXTURE_BIT) {
/* Cannot memcpy because of pointers */
_mesa_copy_texture_state(src, dst);
}
if (mask & GL_TRANSFORM_BIT) {
/* OK to memcpy */
dst->Transform = src->Transform;
}
if (mask & GL_VIEWPORT_BIT) {
/* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
dst->Viewport.X = src->Viewport.X;
dst->Viewport.Y = src->Viewport.Y;
dst->Viewport.Width = src->Viewport.Width;
dst->Viewport.Height = src->Viewport.Height;
dst->Viewport.Near = src->Viewport.Near;
dst->Viewport.Far = src->Viewport.Far;
_math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
}
/* XXX FIXME: Call callbacks?
*/
dst->NewState = _NEW_ALL;
}
#endif
/**
* Check if the given context can render into the given framebuffer
* by checking visual attributes.
* \return GL_TRUE if compatible, GL_FALSE otherwise.
*/
static GLboolean
check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
{
const GLvisual *ctxvis = &ctx->Visual;
const GLvisual *bufvis = &buffer->Visual;
if (ctxvis == bufvis)
return GL_TRUE;
if (ctxvis->rgbMode != bufvis->rgbMode)
return GL_FALSE;
if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
return GL_FALSE;
if (ctxvis->stereoMode && !bufvis->stereoMode)
return GL_FALSE;
if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
return GL_FALSE;
if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
return GL_FALSE;
if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
return GL_FALSE;
if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
return GL_FALSE;
if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
return GL_FALSE;
if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
return GL_FALSE;
if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
return GL_FALSE;
if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
return GL_FALSE;
return GL_TRUE;
}
/**
* Bind the given context to the given draw-buffer and read-buffer and
* make it the current context for this thread.
*
* \param newCtx new GL context. If NULL then there will be no current GL
* context.
* \param drawBuffer draw framebuffer.
* \param readBuffer read framebuffer.
*
* Check that the context's and framebuffer's visuals are compatible, returning
* immediately otherwise. Sets the glapi current context via
* _glapi_set_context(). If \p newCtx is not NULL, associates \p drawBuffer and
* \p readBuffer with it and calls dd_function_table::ResizeBuffers if the buffers size has changed.
* Calls dd_function_table::MakeCurrent callback if defined.
*
* When a context is bound by the first time and the \c MESA_INFO environment
* variable is set it calls print_info() as an aid for remote user
* troubleshooting.
*/
void
_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
#ifdef NXAGENT_SERVER
int flag;
#endif
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(newCtx, "_mesa_make_current()\n");
/* Check that the context's and framebuffer's visuals are compatible.
*/
if (newCtx && drawBuffer && newCtx->DrawBuffer != drawBuffer) {
if (!check_compatible(newCtx, drawBuffer))
return;
}
if (newCtx && readBuffer && newCtx->ReadBuffer != readBuffer) {
if (!check_compatible(newCtx, readBuffer))
return;
}
#if !defined(IN_DRI_DRIVER)
/* We call this function periodically (just here for now) in
* order to detect when multithreading has begun. In a DRI driver, this
* step is done by the driver loader (e.g., libGL).
*/
_glapi_check_multithread();
#endif /* !defined(IN_DRI_DRIVER) */
_glapi_set_context((void *) newCtx);
ASSERT(_mesa_get_current_context() == newCtx);
if (!newCtx) {
_glapi_set_dispatch(NULL); /* none current */
}
else {
_glapi_set_dispatch(newCtx->CurrentDispatch);
if (drawBuffer && readBuffer) {
/* TODO: check if newCtx and buffer's visual match??? */
ASSERT(drawBuffer->Name == 0);
ASSERT(readBuffer->Name == 0);
newCtx->WinSysDrawBuffer = drawBuffer;
newCtx->WinSysReadBuffer = readBuffer;
#ifdef NXAGENT_SERVER
flag = 0;
if (newCtx->DrawBuffer) {
if (!IsWSDrawBuffer(newCtx->DrawBuffer)) {
if (newCtx->DrawBuffer->Name == 0) {
flag = 1;
}
FreeWSDrawBuffer(newCtx->DrawBuffer);
}
else flag = 1;
}
if (!newCtx->DrawBuffer || flag) {
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
}
#else
/* don't replace user-buffer bindings with window system buffer */
if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
}
#endif
newCtx->NewState |= _NEW_BUFFERS;
#if _HAVE_FULL_GL
if (!drawBuffer->Initialized) {
/* get initial window size */
GLuint bufWidth, bufHeight;
/* ask device driver for size of the buffer */
(*newCtx->Driver.GetBufferSize)(drawBuffer, &bufWidth, &bufHeight);
/* set initial buffer size */
if (newCtx->Driver.ResizeBuffers)
newCtx->Driver.ResizeBuffers(newCtx, drawBuffer,
bufWidth, bufHeight);
drawBuffer->Initialized = GL_TRUE;
}
if (readBuffer != drawBuffer && !readBuffer->Initialized) {
/* get initial window size */
GLuint bufWidth, bufHeight;
/* ask device driver for size of the buffer */
(*newCtx->Driver.GetBufferSize)(readBuffer, &bufWidth, &bufHeight);
/* set initial buffer size */
if (newCtx->Driver.ResizeBuffers)
newCtx->Driver.ResizeBuffers(newCtx, readBuffer,
bufWidth, bufHeight);
readBuffer->Initialized = GL_TRUE;
}
#endif
if (newCtx->FirstTimeCurrent) {
/* set initial viewport and scissor size now */
_mesa_set_viewport(newCtx, 0, 0, drawBuffer->Width, drawBuffer->Height);
newCtx->Scissor.Width = drawBuffer->Width;
newCtx->Scissor.Height = drawBuffer->Height;
}
}
/* Alert the driver - usually passed on to the sw t&l module,
* but also used to detect threaded cases in the radeon codegen
* hw t&l module.
*/
if (newCtx->Driver.MakeCurrent)
newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
/* We can use this to help debug user's problems. Tell them to set
* the MESA_INFO env variable before running their app. Then the
* first time each context is made current we'll print some useful
* information.
*/
if (newCtx->FirstTimeCurrent) {
if (_mesa_getenv("MESA_INFO")) {
_mesa_print_info();
}
newCtx->FirstTimeCurrent = GL_FALSE;
}
}
}
/**
* Make context 'ctx' share the display lists, textures and programs
* that are associated with 'ctxToShare'.
* Any display lists, textures or programs associated with 'ctx' will
* be deleted if nobody else is sharing them.
*/
GLboolean
_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
{
if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
ctx->Shared->RefCount--;
if (ctx->Shared->RefCount == 0) {
free_shared_state(ctx, ctx->Shared);
}
ctx->Shared = ctxToShare->Shared;
ctx->Shared->RefCount++;
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
/**
* Get current context for the calling thread.
*
* \return pointer to the current GL context.
*
* Calls _glapi_get_context(). This isn't the fastest way to get the current
* context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
*/
GLcontext *
_mesa_get_current_context( void )
{
return (GLcontext *) _glapi_get_context();
}
/**
* Get context's current API dispatch table.
*
* It'll either be the immediate-mode execute dispatcher or the display list
* compile dispatcher.
*
* \param ctx GL context.
*
* \return pointer to dispatch_table.
*
* Simply returns __GLcontextRec::CurrentDispatch.
*/
struct _glapi_table *
_mesa_get_dispatch(GLcontext *ctx)
{
return ctx->CurrentDispatch;
}
/*@}*/
/**********************************************************************/
/** \name Miscellaneous functions */
/**********************************************************************/
/*@{*/
/**
* Record an error.
*
* \param ctx GL context.
* \param error error code.
*
* Records the given error code and call the driver's dd_function_table::Error
* function if defined.
*
* \sa
* This is called via _mesa_error().
*/
void
_mesa_record_error( GLcontext *ctx, GLenum error )
{
if (!ctx)
return;
if (ctx->ErrorValue == GL_NO_ERROR) {
ctx->ErrorValue = error;
}
/* Call device driver's error handler, if any. This is used on the Mac. */
if (ctx->Driver.Error) {
(*ctx->Driver.Error)( ctx );
}
}
/**
* Execute glFinish().
*
* Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
* dd_function_table::Finish driver callback, if not NULL.
*/
void GLAPIENTRY
_mesa_Finish( void )
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Finish) {
(*ctx->Driver.Finish)( ctx );
}
}
/**
* Execute glFlush().
*
* Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
* dd_function_table::Flush driver callback, if not NULL.
*/
void GLAPIENTRY
_mesa_Flush( void )
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Flush) {
(*ctx->Driver.Flush)( ctx );
}
}
/*@}*/
/**
* \file context.c
* Mesa context/visual/framebuffer management functions.
* \author Brian Paul
*/
/*
* Mesa 3-D graphics library
* Version: 6.4
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \mainpage Mesa Main Module
*
* \section MainIntroduction Introduction
*
* The Mesa Main module consists of all the files in the main/ directory.
* Among the features of this module are:
* <UL>
* <LI> Structures to represent most GL state </LI>
* <LI> State set/get functions </LI>
* <LI> Display lists </LI>
* <LI> Texture unit, object and image handling </LI>
* <LI> Matrix and attribute stacks </LI>
* </UL>
*
* Other modules are responsible for API dispatch, vertex transformation,
* point/line/triangle setup, rasterization, vertex array caching,
* vertex/fragment programs/shaders, etc.
*
*
* \section AboutDoxygen About Doxygen
*
* If you're viewing this information as Doxygen-generated HTML you'll
* see the documentation index at the top of this page.
*
* The first line lists the Mesa source code modules.
* The second line lists the indexes available for viewing the documentation
* for each module.
*
* Selecting the <b>Main page</b> link will display a summary of the module
* (this page).
*
* Selecting <b>Data Structures</b> will list all C structures.
*
* Selecting the <b>File List</b> link will list all the source files in
* the module.
* Selecting a filename will show a list of all functions defined in that file.
*
* Selecting the <b>Data Fields</b> link will display a list of all
* documented structure members.
*
* Selecting the <b>Globals</b> link will display a list
* of all functions, structures, global variables and macros in the module.
*
*/
#include "glheader.h"
#include "imports.h"
#include "accum.h"
#include "attrib.h"
#include "blend.h"
#include "buffers.h"
#include "bufferobj.h"
#include "colortab.h"
#include "context.h"
#include "debug.h"
#include "depth.h"
#include "dlist.h"
#include "eval.h"
#include "enums.h"
#include "extensions.h"
#include "fbobject.h"
#include "feedback.h"
#include "fog.h"
#include "get.h"
#include "glthread.h"
#include "glapioffsets.h"
#include "histogram.h"
#include "hint.h"
#include "hash.h"
#include "light.h"
#include "lines.h"
#include "macros.h"
#include "matrix.h"
#include "occlude.h"
#include "pixel.h"
#include "points.h"
#include "polygon.h"
#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
#include "program.h"
#endif
#include "rastpos.h"
#include "simple_list.h"
#include "state.h"
#include "stencil.h"
#include "texcompress.h"
#include "teximage.h"
#include "texobj.h"
#include "texstate.h"
#include "mtypes.h"
#include "varray.h"
#include "version.h"
#include "vtxfmt.h"
#if _HAVE_FULL_GL
#include "math/m_translate.h"
#include "math/m_matrix.h"
#include "math/m_xform.h"
#include "math/mathmod.h"
#endif
#include "shaderobjects.h"
#ifdef USE_SPARC_ASM
#include "sparc/sparc.h"
#endif
#ifndef MESA_VERBOSE
int MESA_VERBOSE = 0;
#endif
#ifndef MESA_DEBUG_FLAGS
int MESA_DEBUG_FLAGS = 0;
#endif
/* ubyte -> float conversion */
GLfloat _mesa_ubyte_to_float_color_tab[256];
static void
free_shared_state( GLcontext *ctx, struct gl_shared_state *ss );
/**********************************************************************/
/** \name OpenGL SI-style interface (new in Mesa 3.5)
*
* \if subset
* \note Most of these functions are never called in the Mesa subset.
* \endif
*/
/*@{*/
/**
* Destroy context callback.
*
* \param gc context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::destroyCurrent) when
* the rendering context is to be destroyed.
* \endif
*
* Frees the context data and the context structure.
*/
GLboolean
_mesa_destroyContext(__GLcontext *gc)
{
if (gc) {
_mesa_free_context_data(gc);
_mesa_free(gc);
}
return GL_TRUE;
}
/**
* Unbind context callback.
*
* \param gc context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::loseCurrent)
* when the rendering context is made non-current.
* \endif
*
* No-op
*/
GLboolean
_mesa_loseCurrent(__GLcontext *gc)
{
/* XXX unbind context from thread */
(void) gc;
return GL_TRUE;
}
/**
* Bind context callback.
*
* \param gc context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::makeCurrent)
* when the rendering context is made current.
* \endif
*
* No-op
*/
GLboolean
_mesa_makeCurrent(__GLcontext *gc)
{
/* XXX bind context to thread */
(void) gc;
return GL_TRUE;
}
/**
* Share context callback.
*
* \param gc context.
* \param gcShare shared context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \ifnot subset
* Called by window system/device driver (via __GLexports::shareContext)
* \endif
*
* Update the shared context reference count, gl_shared_state::RefCount.
*/
GLboolean
_mesa_shareContext(__GLcontext *gc, __GLcontext *gcShare)
{
if (gc && gcShare && gc->Shared && gcShare->Shared) {
gc->Shared->RefCount--;
if (gc->Shared->RefCount == 0) {
free_shared_state(gc, gc->Shared);
}
gc->Shared = gcShare->Shared;
gc->Shared->RefCount++;
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
#if _HAVE_FULL_GL
/**
* Copy context callback.
*/
GLboolean
_mesa_copyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask)
{
if (dst && src) {
_mesa_copy_context( src, dst, mask );
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
#endif
/** No-op */
GLboolean
_mesa_forceCurrent(__GLcontext *gc)
{
(void) gc;
return GL_TRUE;
}
/**
* Windows/buffer resizing notification callback.
*
* \param gc GL context.
* \return GL_TRUE on success, or GL_FALSE on failure.
*/
GLboolean
_mesa_notifyResize(__GLcontext *gc)
{
GLint x, y;
GLuint width, height;
__GLdrawablePrivate *d = gc->imports.getDrawablePrivate(gc);
if (!d || !d->getDrawableSize)
return GL_FALSE;
d->getDrawableSize( d, &x, &y, &width, &height );
/* update viewport, resize software buffers, etc. */
return GL_TRUE;
}
/**
* Window/buffer destruction notification callback.
*
* \param gc GL context.
*
* Called when the context's window/buffer is going to be destroyed.
*
* No-op
*/
void
_mesa_notifyDestroy(__GLcontext *gc)
{
/* Unbind from it. */
(void) gc;
}
/**
* Swap buffers notification callback.
*
* \param gc GL context.
*
* Called by window system just before swapping buffers.
* We have to finish any pending rendering.
*/
void
_mesa_notifySwapBuffers(__GLcontext *gc)
{
FLUSH_VERTICES( gc, 0 );
}
/** No-op */
struct __GLdispatchStateRec *
_mesa_dispatchExec(__GLcontext *gc)
{
(void) gc;
return NULL;
}
/** No-op */
void
_mesa_beginDispatchOverride(__GLcontext *gc)
{
(void) gc;
}
/** No-op */
void
_mesa_endDispatchOverride(__GLcontext *gc)
{
(void) gc;
}
/**
* \ifnot subset
* Setup the exports.
*
* The window system will call these functions when it needs Mesa to do
* something.
*
* \note Device drivers should override these functions! For example,
* the Xlib driver should plug in the XMesa*-style functions into this
* structure. The XMesa-style functions should then call the _mesa_*
* version of these functions. This is an approximation to OO design
* (inheritance and virtual functions).
* \endif
*
* \if subset
* No-op.
*
* \endif
*/
static void
_mesa_init_default_exports(__GLexports *exports)
{
#if _HAVE_FULL_GL
exports->destroyContext = _mesa_destroyContext;
exports->loseCurrent = _mesa_loseCurrent;
exports->makeCurrent = _mesa_makeCurrent;
exports->shareContext = _mesa_shareContext;
exports->copyContext = _mesa_copyContext;
exports->forceCurrent = _mesa_forceCurrent;
exports->notifyResize = _mesa_notifyResize;
exports->notifyDestroy = _mesa_notifyDestroy;
exports->notifySwapBuffers = _mesa_notifySwapBuffers;
exports->dispatchExec = _mesa_dispatchExec;
exports->beginDispatchOverride = _mesa_beginDispatchOverride;
exports->endDispatchOverride = _mesa_endDispatchOverride;
#else
(void) exports;
#endif
}
/**
* Exported OpenGL SI interface.
*/
__GLcontext *
__glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes)
{
GLcontext *ctx;
ctx = (GLcontext *) (*imports->calloc)(NULL, 1, sizeof(GLcontext));
if (ctx == NULL) {
return NULL;
}
/* XXX doesn't work at this time */
_mesa_initialize_context(ctx, modes, NULL, NULL, NULL);
ctx->imports = *imports;
return ctx;
}
/**
* Exported OpenGL SI interface.
*/
void
__glCoreNopDispatch(void)
{
#if 0
/* SI */
__gl_dispatch = __glNopDispatchState;
#else
/* Mesa */
_glapi_set_dispatch(NULL);
#endif
}
/*@}*/
/**********************************************************************/
/** \name GL Visual allocation/destruction */
/**********************************************************************/
/*@{*/
/**
* Allocates a GLvisual structure and initializes it via
* _mesa_initialize_visual().
*
* \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
* \param dbFlag double buffering
* \param stereoFlag stereo buffer
* \param depthBits requested bits per depth buffer value. Any value in [0, 32]
* is acceptable but the actual depth type will be GLushort or GLuint as
* needed.
* \param stencilBits requested minimum bits per stencil buffer value
* \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer.
* \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE
* \param redBits number of bits per color component in frame buffer for RGB(A)
* mode. We always use 8 in core Mesa though.
* \param greenBits same as above.
* \param blueBits same as above.
* \param alphaBits same as above.
* \param numSamples not really used.
*
* \return pointer to new GLvisual or NULL if requested parameters can't be
* met.
*
* \note Need to add params for level and numAuxBuffers (at least)
*/
GLvisual *
_mesa_create_visual( GLboolean rgbFlag,
GLboolean dbFlag,
GLboolean stereoFlag,
GLint redBits,
GLint greenBits,
GLint blueBits,
GLint alphaBits,
GLint indexBits,
GLint depthBits,
GLint stencilBits,
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
GLint accumAlphaBits,
GLint numSamples )
{
GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
if (vis) {
if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
redBits, greenBits, blueBits, alphaBits,
indexBits, depthBits, stencilBits,
accumRedBits, accumGreenBits,
accumBlueBits, accumAlphaBits,
numSamples)) {
FREE(vis);
return NULL;
}
}
return vis;
}
/**
* Makes some sanity checks and fills in the fields of the
* GLvisual object with the given parameters. If the caller needs
* to set additional fields, he should just probably init the whole GLvisual
* object himself.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \sa _mesa_create_visual() above for the parameter description.
*/
GLboolean
_mesa_initialize_visual( GLvisual *vis,
GLboolean rgbFlag,
GLboolean dbFlag,
GLboolean stereoFlag,
GLint redBits,
GLint greenBits,
GLint blueBits,
GLint alphaBits,
GLint indexBits,
GLint depthBits,
GLint stencilBits,
GLint accumRedBits,
GLint accumGreenBits,
GLint accumBlueBits,
GLint accumAlphaBits,
GLint numSamples )
{
assert(vis);
if (depthBits < 0 || depthBits > 32) {
return GL_FALSE;
}
if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
return GL_FALSE;
}
if (accumRedBits < 0 || accumRedBits > ACCUM_BITS) {
return GL_FALSE;
}
if (accumGreenBits < 0 || accumGreenBits > ACCUM_BITS) {
return GL_FALSE;
}
if (accumBlueBits < 0 || accumBlueBits > ACCUM_BITS) {
return GL_FALSE;
}
if (accumAlphaBits < 0 || accumAlphaBits > ACCUM_BITS) {
return GL_FALSE;
}
vis->rgbMode = rgbFlag;
vis->doubleBufferMode = dbFlag;
vis->stereoMode = stereoFlag;
vis->redBits = redBits;
vis->greenBits = greenBits;
vis->blueBits = blueBits;
vis->alphaBits = alphaBits;
vis->rgbBits = redBits + greenBits + blueBits;
vis->indexBits = indexBits;
vis->depthBits = depthBits;
vis->stencilBits = stencilBits;
vis->accumRedBits = accumRedBits;
vis->accumGreenBits = accumGreenBits;
vis->accumBlueBits = accumBlueBits;
vis->accumAlphaBits = accumAlphaBits;
vis->haveAccumBuffer = accumRedBits > 0;
vis->haveDepthBuffer = depthBits > 0;
vis->haveStencilBuffer = stencilBits > 0;
vis->numAuxBuffers = 0;
vis->level = 0;
vis->pixmapMode = 0;
vis->sampleBuffers = numSamples > 0 ? 1 : 0;
vis->samples = numSamples;
return GL_TRUE;
}
/**
* Destroy a visual and free its memory.
*
* \param vis visual.
*
* Frees the visual structure.
*/
void
_mesa_destroy_visual( GLvisual *vis )
{
FREE(vis);
}
/*@}*/
/**********************************************************************/
/** \name Context allocation, initialization, destroying
*
* The purpose of the most initialization functions here is to provide the
* default state values according to the OpenGL specification.
*/
/**********************************************************************/
/*@{*/
/**
* One-time initialization mutex lock.
*
* \sa Used by one_time_init().
*/
_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
/**
* Calls all the various one-time-init functions in Mesa.
*
* While holding a global mutex lock, calls several initialization functions,
* and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
* defined.
*
* \sa _mesa_init_lists(), _math_init().
*/
static void
one_time_init( GLcontext *ctx )
{
static GLboolean alreadyCalled = GL_FALSE;
(void) ctx;
_glthread_LOCK_MUTEX(OneTimeLock);
if (!alreadyCalled) {
GLuint i;
/* do some implementation tests */
assert( sizeof(GLbyte) == 1 );
assert( sizeof(GLubyte) == 1 );
assert( sizeof(GLshort) == 2 );
assert( sizeof(GLushort) == 2 );
assert( sizeof(GLint) == 4 );
assert( sizeof(GLuint) == 4 );
_mesa_init_lists();
#if _HAVE_FULL_GL
_math_init();
for (i = 0; i < 256; i++) {
_mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F;
}
#endif
#ifdef USE_SPARC_ASM
_mesa_init_sparc_glapi_relocs();
#endif
if (_mesa_getenv("MESA_DEBUG")) {
_glapi_noop_enable_warnings(GL_TRUE);
_glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
}
else {
_glapi_noop_enable_warnings(GL_FALSE);
}
#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
_mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
MESA_VERSION_STRING, __DATE__, __TIME__);
#endif
alreadyCalled = GL_TRUE;
}
_glthread_UNLOCK_MUTEX(OneTimeLock);
}
/**
* Allocate and initialize a shared context state structure.
* Initializes the display list, texture objects and vertex programs hash
* tables, allocates the texture objects. If it runs out of memory, frees
* everything already allocated before returning NULL.
*
* \return pointer to a gl_shared_state structure on success, or NULL on
* failure.
*/
static GLboolean
alloc_shared_state( GLcontext *ctx )
{
struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
if (!ss)
return GL_FALSE;
ctx->Shared = ss;
_glthread_INIT_MUTEX(ss->Mutex);
ss->DisplayList = _mesa_NewHashTable();
ss->TexObjects = _mesa_NewHashTable();
#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
ss->Programs = _mesa_NewHashTable();
#endif
#if FEATURE_ARB_vertex_program
ss->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
if (!ss->DefaultVertexProgram)
goto cleanup;
#endif
#if FEATURE_ARB_fragment_program
ss->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!ss->DefaultFragmentProgram)
goto cleanup;
#endif
#if FEATURE_ATI_fragment_shader
ss->DefaultFragmentShader = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, 0);
if (!ss->DefaultFragmentShader)
goto cleanup;
#endif
ss->BufferObjects = _mesa_NewHashTable();
ss->GL2Objects = _mesa_NewHashTable ();
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
if (!ss->Default1D)
goto cleanup;
ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
if (!ss->Default2D)
goto cleanup;
ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
if (!ss->Default3D)
goto cleanup;
ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
if (!ss->DefaultCubeMap)
goto cleanup;
ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
if (!ss->DefaultRect)
goto cleanup;
/* Effectively bind the default textures to all texture units */
ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
#if FEATURE_EXT_framebuffer_object
ss->FrameBuffers = _mesa_NewHashTable();
if (!ss->FrameBuffers)
goto cleanup;
ss->RenderBuffers = _mesa_NewHashTable();
if (!ss->RenderBuffers)
goto cleanup;
#endif
return GL_TRUE;
cleanup:
/* Ran out of memory at some point. Free everything and return NULL */
if (ss->DisplayList)
_mesa_DeleteHashTable(ss->DisplayList);
if (ss->TexObjects)
_mesa_DeleteHashTable(ss->TexObjects);
#if FEATURE_NV_vertex_program
if (ss->Programs)
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
if (ss->DefaultVertexProgram)
ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
#endif
#if FEATURE_ARB_fragment_program
if (ss->DefaultFragmentProgram)
ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
if (ss->DefaultFragmentShader)
ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentShader);
#endif
#if FEATURE_ARB_vertex_buffer_object
if (ss->BufferObjects)
_mesa_DeleteHashTable(ss->BufferObjects);
#endif
if (ss->GL2Objects)
_mesa_DeleteHashTable (ss->GL2Objects);
#if FEATURE_EXT_framebuffer_object
if (ss->FrameBuffers)
_mesa_DeleteHashTable(ss->FrameBuffers);
if (ss->RenderBuffers)
_mesa_DeleteHashTable(ss->RenderBuffers);
#endif
if (ss->Default1D)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
if (ss->Default2D)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
if (ss->Default3D)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
if (ss->DefaultCubeMap)
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
if (ss->DefaultRect)
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
if (ss)
_mesa_free(ss);
return GL_FALSE;
}
/**
* Deallocate a shared state context and all children structures.
*
* \param ctx GL context.
* \param ss shared state pointer.
*
* Frees the display lists, the texture objects (calling the driver texture
* deletion callback to free its private data) and the vertex programs, as well
* as their hash tables.
*
* \sa alloc_shared_state().
*/
static void
free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
{
/* Free display lists */
while (1) {
GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
if (list) {
_mesa_destroy_list(ctx, list);
}
else {
break;
}
}
_mesa_DeleteHashTable(ss->DisplayList);
/* Free texture objects */
ASSERT(ctx->Driver.DeleteTexture);
/* the default textures */
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
(*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
(*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
/* all other textures */
while (1) {
GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
if (texName) {
struct gl_texture_object *texObj = (struct gl_texture_object *)
_mesa_HashLookup(ss->TexObjects, texName);
ASSERT(texObj);
(*ctx->Driver.DeleteTexture)(ctx, texObj);
_mesa_HashRemove(ss->TexObjects, texName);
}
else {
break;
}
}
_mesa_DeleteHashTable(ss->TexObjects);
#if FEATURE_NV_vertex_program
/* Free vertex programs */
while (1) {
GLuint prog = _mesa_HashFirstEntry(ss->Programs);
if (prog) {
struct program *p = (struct program *) _mesa_HashLookup(ss->Programs,
prog);
ASSERT(p);
ctx->Driver.DeleteProgram(ctx, p);
_mesa_HashRemove(ss->Programs, prog);
}
else {
break;
}
}
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
_mesa_delete_program(ctx, ss->DefaultVertexProgram);
#endif
#if FEATURE_ARB_fragment_program
_mesa_delete_program(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
_mesa_delete_program(ctx, ss->DefaultFragmentShader);
#endif
#if FEATURE_ARB_vertex_buffer_object
_mesa_DeleteHashTable(ss->BufferObjects);
#endif
_mesa_DeleteHashTable (ss->GL2Objects);
#if FEATURE_EXT_framebuffer_object
_mesa_DeleteHashTable(ss->FrameBuffers);
_mesa_DeleteHashTable(ss->RenderBuffers);
#endif
_glthread_DESTROY_MUTEX(ss->Mutex);
FREE(ss);
}
/**
* Initialize fields of gl_current_attrib (aka ctx->Current.*)
*/
static void
_mesa_init_current( GLcontext *ctx )
{
GLuint i;
/* Current group */
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
}
/* special cases: */
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
ctx->Current.Index = 1;
ctx->Current.EdgeFlag = GL_TRUE;
}
/**
* Initialize fields of gl_constants (aka ctx->Const.*).
* Use defaults from config.h. The device drivers will often override
* some of these values (such as number of texture units).
*/
static void
_mesa_init_constants( GLcontext *ctx )
{
assert(ctx);
assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
/* Constants, may be overriden (usually only reduced) by device drivers */
ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
ctx->Const.MinPointSize = MIN_POINT_SIZE;
ctx->Const.MaxPointSize = MAX_POINT_SIZE;
ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY;
ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
ctx->Const.MaxLights = MAX_LIGHTS;
ctx->Const.MaxShininess = 128.0;
ctx->Const.MaxSpotExponent = 128.0;
ctx->Const.MaxViewportWidth = MAX_WIDTH;
ctx->Const.MaxViewportHeight = MAX_HEIGHT;
#if FEATURE_ARB_vertex_program
ctx->Const.MaxVertexProgramInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
ctx->Const.MaxVertexProgramAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
ctx->Const.MaxVertexProgramTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
ctx->Const.MaxVertexProgramLocalParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
ctx->Const.MaxVertexProgramEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;/*XXX*/
ctx->Const.MaxVertexProgramAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
#endif
#if FEATURE_ARB_fragment_program
ctx->Const.MaxFragmentProgramInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
ctx->Const.MaxFragmentProgramTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
ctx->Const.MaxFragmentProgramLocalParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
ctx->Const.MaxFragmentProgramEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;/*XXX*/
ctx->Const.MaxFragmentProgramAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
ctx->Const.MaxFragmentProgramAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
ctx->Const.MaxFragmentProgramTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
#endif
ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
/* If we're running in the X server, do bounds checking to prevent
* segfaults and server crashes!
*/
#if defined(XFree86LOADER) && defined(IN_MODULE)
ctx->Const.CheckArrayBounds = GL_TRUE;
#else
ctx->Const.CheckArrayBounds = GL_FALSE;
#endif
ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
/* GL_OES_read_format */
ctx->Const.ColorReadFormat = GL_RGBA;
ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
#if FEATURE_EXT_framebuffer_object
ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
#endif
/* sanity checks */
ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
}
/**
* Initialize the attribute groups in a GL context.
*
* \param ctx GL context.
*
* Initializes all the attributes, calling the respective <tt>init*</tt>
* functions for the more complex data structures.
*/
static GLboolean
init_attrib_groups( GLcontext *ctx )
{
assert(ctx);
/* Constants */
_mesa_init_constants( ctx );
/* Extensions */
_mesa_init_extensions( ctx );
/* Attribute Groups */
_mesa_init_accum( ctx );
_mesa_init_attrib( ctx );
_mesa_init_buffer_objects( ctx );
_mesa_init_color( ctx );
_mesa_init_colortables( ctx );
_mesa_init_current( ctx );
_mesa_init_depth( ctx );
_mesa_init_debug( ctx );
_mesa_init_display_list( ctx );
_mesa_init_eval( ctx );
_mesa_init_feedback( ctx );
_mesa_init_fog( ctx );
_mesa_init_histogram( ctx );
_mesa_init_hint( ctx );
_mesa_init_line( ctx );
_mesa_init_lighting( ctx );
_mesa_init_matrix( ctx );
_mesa_init_multisample( ctx );
_mesa_init_occlude( ctx );
_mesa_init_pixel( ctx );
_mesa_init_point( ctx );
_mesa_init_polygon( ctx );
_mesa_init_program( ctx );
_mesa_init_rastpos( ctx );
_mesa_init_scissor( ctx );
_mesa_init_shaderobjects (ctx);
_mesa_init_stencil( ctx );
_mesa_init_transform( ctx );
_mesa_init_varray( ctx );
_mesa_init_viewport( ctx );
if (!_mesa_init_texture( ctx ))
return GL_FALSE;
_mesa_init_texture_s3tc( ctx );
_mesa_init_texture_fxt1( ctx );
/* Miscellaneous */
ctx->NewState = _NEW_ALL;
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
ctx->_Facing = 0;
#if CHAN_TYPE == GL_FLOAT
ctx->ClampFragmentColors = GL_FALSE; /* XXX temporary */
#else
ctx->ClampFragmentColors = GL_TRUE;
#endif
ctx->ClampVertexColors = GL_TRUE;
return GL_TRUE;
}
/**
* This is the default function we plug into all dispatch table slots
* This helps prevents a segfault when someone calls a GL function without
* first checking if the extension's supported.
*/
static int
generic_nop(void)
{
_mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)");
return 0;
}
/**
* Allocate and initialize a new dispatch table.
*/
static struct _glapi_table *
alloc_dispatch_table(void)
{
/* Find the larger of Mesa's dispatch table and libGL's dispatch table.
* In practice, this'll be the same for stand-alone Mesa. But for DRI
* Mesa we do this to accomodate different versions of libGL and various
* DRI drivers.
*/
GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
sizeof(struct _glapi_table) / sizeof(_glapi_proc));
struct _glapi_table *table =
(struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
if (table) {
_glapi_proc *entry = (_glapi_proc *) table;
GLint i;
for (i = 0; i < numEntries; i++) {
entry[i] = (_glapi_proc) generic_nop;
}
}
return table;
}
/**
* Initialize a GLcontext struct (rendering context).
*
* This includes allocating all the other structs and arrays which hang off of
* the context by pointers.
* Note that the driver needs to pass in its dd_function_table here since
* we need to at least call driverFunctions->NewTextureObject to create the
* default texture objects.
*
* Called by _mesa_create_context().
*
* Performs the imports and exports callback tables initialization, and
* miscellaneous one-time initializations. If no shared context is supplied one
* is allocated, and increase its reference count. Setups the GL API dispatch
* tables. Initialize the TNL module. Sets the maximum Z buffer depth.
* Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
* for debug flags.
*
* \param ctx the context to initialize
* \param visual describes the visual attributes for this context
* \param share_list points to context to share textures, display lists,
* etc with, or NULL
* \param driverFunctions table of device driver functions for this context
* to use
* \param driverContext pointer to driver-specific context data
*/
GLboolean
_mesa_initialize_context( GLcontext *ctx,
const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
{
ASSERT(driverContext);
assert(driverFunctions->NewTextureObject);
assert(driverFunctions->FreeTexImageData);
/* If the driver wants core Mesa to use special imports, it'll have to
* override these defaults.
*/
_mesa_init_default_imports( &(ctx->imports), driverContext );
/* initialize the exports (Mesa functions called by the window system) */
_mesa_init_default_exports( &(ctx->exports) );
/* misc one-time initializations */
one_time_init(ctx);
ctx->Visual = *visual;
ctx->DrawBuffer = NULL;
ctx->ReadBuffer = NULL;
ctx->WinSysDrawBuffer = NULL;
ctx->WinSysReadBuffer = NULL;
/* Plug in driver functions and context pointer here.
* This is important because when we call alloc_shared_state() below
* we'll call ctx->Driver.NewTextureObject() to create the default
* textures.
*/
ctx->Driver = *driverFunctions;
ctx->DriverCtx = driverContext;
if (share_list) {
/* share state with another context */
ctx->Shared = share_list->Shared;
}
else {
/* allocate new, unshared state */
if (!alloc_shared_state( ctx )) {
return GL_FALSE;
}
}
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
ctx->Shared->RefCount++;
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
if (!init_attrib_groups( ctx )) {
free_shared_state(ctx, ctx->Shared);
return GL_FALSE;
}
/* setup the API dispatch tables */
ctx->Exec = alloc_dispatch_table();
ctx->Save = alloc_dispatch_table();
if (!ctx->Exec || !ctx->Save) {
free_shared_state(ctx, ctx->Shared);
if (ctx->Exec)
_mesa_free(ctx->Exec);
}
_mesa_init_exec_table(ctx->Exec);
ctx->CurrentDispatch = ctx->Exec;
#if _HAVE_FULL_GL
_mesa_init_dlist_table(ctx->Save);
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
/* Neutral tnl module stuff */
_mesa_init_exec_vtxfmt( ctx );
ctx->TnlModule.Current = NULL;
ctx->TnlModule.SwapCount = 0;
#endif
ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
return GL_TRUE;
}
/**
* Allocate and initialize a GLcontext structure.
* Note that the driver needs to pass in its dd_function_table here since
* we need to at least call driverFunctions->NewTextureObject to initialize
* the rendering context.
*
* \param visual a GLvisual pointer (we copy the struct contents)
* \param share_list another context to share display lists with or NULL
* \param driverFunctions points to the dd_function_table into which the
* driver has plugged in all its special functions.
* \param driverCtx points to the device driver's private context state
*
* \return pointer to a new __GLcontextRec or NULL if error.
*/
GLcontext *
_mesa_create_context( const GLvisual *visual,
GLcontext *share_list,
const struct dd_function_table *driverFunctions,
void *driverContext )
{
GLcontext *ctx;
ASSERT(visual);
ASSERT(driverContext);
ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext));
if (!ctx)
return NULL;
if (_mesa_initialize_context(ctx, visual, share_list,
driverFunctions, driverContext)) {
return ctx;
}
else {
_mesa_free(ctx);
return NULL;
}
}
/**
* Free the data associated with the given context.
*
* But doesn't free the GLcontext struct itself.
*
* \sa _mesa_initialize_context() and init_attrib_groups().
*/
void
_mesa_free_context_data( GLcontext *ctx )
{
/* if we're destroying the current context, unbind it first */
if (ctx == _mesa_get_current_context()) {
_mesa_make_current(NULL, NULL, NULL);
}
_mesa_free_lighting_data( ctx );
_mesa_free_eval_data( ctx );
_mesa_free_texture_data( ctx );
_mesa_free_matrix_data( ctx );
_mesa_free_viewport_data( ctx );
_mesa_free_colortables_data( ctx );
_mesa_free_program_data(ctx);
_mesa_free_occlude_data(ctx);
#if FEATURE_ARB_vertex_buffer_object
_mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
#endif
/* free dispatch tables */
_mesa_free(ctx->Exec);
_mesa_free(ctx->Save);
/* Shared context state (display lists, textures, etc) */
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
ctx->Shared->RefCount--;
assert(ctx->Shared->RefCount >= 0);
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
if (ctx->Shared->RefCount == 0) {
/* free shared state */
free_shared_state( ctx, ctx->Shared );
}
if (ctx->Extensions.String)
FREE((void *) ctx->Extensions.String);
}
/**
* Destroy a GLcontext structure.
*
* \param ctx GL context.
*
* Calls _mesa_free_context_data() and frees the GLcontext structure itself.
*/
void
_mesa_destroy_context( GLcontext *ctx )
{
if (ctx) {
_mesa_free_context_data(ctx);
FREE( (void *) ctx );
}
}
#if _HAVE_FULL_GL
/**
* Copy attribute groups from one context to another.
*
* \param src source context
* \param dst destination context
* \param mask bitwise OR of GL_*_BIT flags
*
* According to the bits specified in \p mask, copies the corresponding
* attributes from \p src into \p dst. For many of the attributes a simple \c
* memcpy is not enough due to the existence of internal pointers in their data
* structures.
*/
void
_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
{
if (mask & GL_ACCUM_BUFFER_BIT) {
/* OK to memcpy */
dst->Accum = src->Accum;
}
if (mask & GL_COLOR_BUFFER_BIT) {
/* OK to memcpy */
dst->Color = src->Color;
}
if (mask & GL_CURRENT_BIT) {
/* OK to memcpy */
dst->Current = src->Current;
}
if (mask & GL_DEPTH_BUFFER_BIT) {
/* OK to memcpy */
dst->Depth = src->Depth;
}
if (mask & GL_ENABLE_BIT) {
/* no op */
}
if (mask & GL_EVAL_BIT) {
/* OK to memcpy */
dst->Eval = src->Eval;
}
if (mask & GL_FOG_BIT) {
/* OK to memcpy */
dst->Fog = src->Fog;
}
if (mask & GL_HINT_BIT) {
/* OK to memcpy */
dst->Hint = src->Hint;
}
if (mask & GL_LIGHTING_BIT) {
GLuint i;
/* begin with memcpy */
MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light) );
/* fixup linked lists to prevent pointer insanity */
make_empty_list( &(dst->Light.EnabledList) );
for (i = 0; i < MAX_LIGHTS; i++) {
if (dst->Light.Light[i].Enabled) {
insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));
}
}
}
if (mask & GL_LINE_BIT) {
/* OK to memcpy */
dst->Line = src->Line;
}
if (mask & GL_LIST_BIT) {
/* OK to memcpy */
dst->List = src->List;
}
if (mask & GL_PIXEL_MODE_BIT) {
/* OK to memcpy */
dst->Pixel = src->Pixel;
}
if (mask & GL_POINT_BIT) {
/* OK to memcpy */
dst->Point = src->Point;
}
if (mask & GL_POLYGON_BIT) {
/* OK to memcpy */
dst->Polygon = src->Polygon;
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
/* Use loop instead of MEMCPY due to problem with Portland Group's
* C compiler. Reported by John Stone.
*/
GLuint i;
for (i = 0; i < 32; i++) {
dst->PolygonStipple[i] = src->PolygonStipple[i];
}
}
if (mask & GL_SCISSOR_BIT) {
/* OK to memcpy */
dst->Scissor = src->Scissor;
}
if (mask & GL_STENCIL_BUFFER_BIT) {
/* OK to memcpy */
dst->Stencil = src->Stencil;
}
if (mask & GL_TEXTURE_BIT) {
/* Cannot memcpy because of pointers */
_mesa_copy_texture_state(src, dst);
}
if (mask & GL_TRANSFORM_BIT) {
/* OK to memcpy */
dst->Transform = src->Transform;
}
if (mask & GL_VIEWPORT_BIT) {
/* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */
dst->Viewport.X = src->Viewport.X;
dst->Viewport.Y = src->Viewport.Y;
dst->Viewport.Width = src->Viewport.Width;
dst->Viewport.Height = src->Viewport.Height;
dst->Viewport.Near = src->Viewport.Near;
dst->Viewport.Far = src->Viewport.Far;
_math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);
}
/* XXX FIXME: Call callbacks?
*/
dst->NewState = _NEW_ALL;
}
#endif
/**
* Check if the given context can render into the given framebuffer
* by checking visual attributes.
* \return GL_TRUE if compatible, GL_FALSE otherwise.
*/
static GLboolean
check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
{
const GLvisual *ctxvis = &ctx->Visual;
const GLvisual *bufvis = &buffer->Visual;
if (ctxvis == bufvis)
return GL_TRUE;
if (ctxvis->rgbMode != bufvis->rgbMode)
return GL_FALSE;
if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
return GL_FALSE;
if (ctxvis->stereoMode && !bufvis->stereoMode)
return GL_FALSE;
if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
return GL_FALSE;
if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)
return GL_FALSE;
if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)
return GL_FALSE;
if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)
return GL_FALSE;
if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)
return GL_FALSE;
if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)
return GL_FALSE;
if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)
return GL_FALSE;
if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)
return GL_FALSE;
return GL_TRUE;
}
/**
* Bind the given context to the given draw-buffer and read-buffer and
* make it the current context for this thread.
*
* \param newCtx new GL context. If NULL then there will be no current GL
* context.
* \param drawBuffer draw framebuffer.
* \param readBuffer read framebuffer.
*
* Check that the context's and framebuffer's visuals are compatible, returning
* immediately otherwise. Sets the glapi current context via
* _glapi_set_context(). If \p newCtx is not NULL, associates \p drawBuffer and
* \p readBuffer with it and calls dd_function_table::ResizeBuffers if the buffers size has changed.
* Calls dd_function_table::MakeCurrent callback if defined.
*
* When a context is bound by the first time and the \c MESA_INFO environment
* variable is set it calls print_info() as an aid for remote user
* troubleshooting.
*/
void
_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(newCtx, "_mesa_make_current()\n");
/* Check that the context's and framebuffer's visuals are compatible.
*/
if (newCtx && drawBuffer && newCtx->DrawBuffer != drawBuffer) {
if (!check_compatible(newCtx, drawBuffer))
return;
}
if (newCtx && readBuffer && newCtx->ReadBuffer != readBuffer) {
if (!check_compatible(newCtx, readBuffer))
return;
}
#if !defined(IN_DRI_DRIVER)
/* We call this function periodically (just here for now) in
* order to detect when multithreading has begun. In a DRI driver, this
* step is done by the driver loader (e.g., libGL).
*/
_glapi_check_multithread();
#endif /* !defined(IN_DRI_DRIVER) */
_glapi_set_context((void *) newCtx);
ASSERT(_mesa_get_current_context() == newCtx);
if (!newCtx) {
_glapi_set_dispatch(NULL); /* none current */
}
else {
_glapi_set_dispatch(newCtx->CurrentDispatch);
if (drawBuffer && readBuffer) {
/* TODO: check if newCtx and buffer's visual match??? */
ASSERT(drawBuffer->Name == 0);
ASSERT(readBuffer->Name == 0);
newCtx->WinSysDrawBuffer = drawBuffer;
newCtx->WinSysReadBuffer = readBuffer;
/* don't replace user-buffer bindings with window system buffer */
if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
}
newCtx->NewState |= _NEW_BUFFERS;
#if _HAVE_FULL_GL
if (!drawBuffer->Initialized) {
/* get initial window size */
GLuint bufWidth, bufHeight;
/* ask device driver for size of the buffer */
(*newCtx->Driver.GetBufferSize)(drawBuffer, &bufWidth, &bufHeight);
/* set initial buffer size */
if (newCtx->Driver.ResizeBuffers)
newCtx->Driver.ResizeBuffers(newCtx, drawBuffer,
bufWidth, bufHeight);
drawBuffer->Initialized = GL_TRUE;
}
if (readBuffer != drawBuffer && !readBuffer->Initialized) {
/* get initial window size */
GLuint bufWidth, bufHeight;
/* ask device driver for size of the buffer */
(*newCtx->Driver.GetBufferSize)(readBuffer, &bufWidth, &bufHeight);
/* set initial buffer size */
if (newCtx->Driver.ResizeBuffers)
newCtx->Driver.ResizeBuffers(newCtx, readBuffer,
bufWidth, bufHeight);
readBuffer->Initialized = GL_TRUE;
}
#endif
if (newCtx->FirstTimeCurrent) {
/* set initial viewport and scissor size now */
_mesa_set_viewport(newCtx, 0, 0, drawBuffer->Width, drawBuffer->Height);
newCtx->Scissor.Width = drawBuffer->Width;
newCtx->Scissor.Height = drawBuffer->Height;
}
}
/* Alert the driver - usually passed on to the sw t&l module,
* but also used to detect threaded cases in the radeon codegen
* hw t&l module.
*/
if (newCtx->Driver.MakeCurrent)
newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
/* We can use this to help debug user's problems. Tell them to set
* the MESA_INFO env variable before running their app. Then the
* first time each context is made current we'll print some useful
* information.
*/
if (newCtx->FirstTimeCurrent) {
if (_mesa_getenv("MESA_INFO")) {
_mesa_print_info();
}
newCtx->FirstTimeCurrent = GL_FALSE;
}
}
}
/**
* Make context 'ctx' share the display lists, textures and programs
* that are associated with 'ctxToShare'.
* Any display lists, textures or programs associated with 'ctx' will
* be deleted if nobody else is sharing them.
*/
GLboolean
_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
{
if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
ctx->Shared->RefCount--;
if (ctx->Shared->RefCount == 0) {
free_shared_state(ctx, ctx->Shared);
}
ctx->Shared = ctxToShare->Shared;
ctx->Shared->RefCount++;
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
/**
* Get current context for the calling thread.
*
* \return pointer to the current GL context.
*
* Calls _glapi_get_context(). This isn't the fastest way to get the current
* context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
*/
GLcontext *
_mesa_get_current_context( void )
{
return (GLcontext *) _glapi_get_context();
}
/**
* Get context's current API dispatch table.
*
* It'll either be the immediate-mode execute dispatcher or the display list
* compile dispatcher.
*
* \param ctx GL context.
*
* \return pointer to dispatch_table.
*
* Simply returns __GLcontextRec::CurrentDispatch.
*/
struct _glapi_table *
_mesa_get_dispatch(GLcontext *ctx)
{
return ctx->CurrentDispatch;
}
/*@}*/
/**********************************************************************/
/** \name Miscellaneous functions */
/**********************************************************************/
/*@{*/
/**
* Record an error.
*
* \param ctx GL context.
* \param error error code.
*
* Records the given error code and call the driver's dd_function_table::Error
* function if defined.
*
* \sa
* This is called via _mesa_error().
*/
void
_mesa_record_error( GLcontext *ctx, GLenum error )
{
if (!ctx)
return;
if (ctx->ErrorValue == GL_NO_ERROR) {
ctx->ErrorValue = error;
}
/* Call device driver's error handler, if any. This is used on the Mac. */
if (ctx->Driver.Error) {
(*ctx->Driver.Error)( ctx );
}
}
/**
* Execute glFinish().
*
* Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
* dd_function_table::Finish driver callback, if not NULL.
*/
void GLAPIENTRY
_mesa_Finish( void )
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Finish) {
(*ctx->Driver.Finish)( ctx );
}
}
/**
* Execute glFlush().
*
* Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the
* dd_function_table::Flush driver callback, if not NULL.
*/
void GLAPIENTRY
_mesa_Flush( void )
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Flush) {
(*ctx->Driver.Flush)( ctx );
}
}
/*@}*/
......@@ -121,7 +121,11 @@ _XcmsGetProperty(
char *prop_ret;
int format_ret;
long len = 6516;
#ifdef NXAGENT_SERVER
unsigned long nitems_ret, after_ret = 0;
#else
unsigned long nitems_ret, after_ret;
#endif
Atom atom_ret;
while (XGetWindowProperty (pDpy, w, property, 0, len, False,
......
/* $Xorg: cmsProp.c,v 1.3 2000/08/17 19:45:10 cpqbld Exp $ */
/*
*
* Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
* All Rights Reserved
*
* This file is a component of an X Window System-specific implementation
* of Xcms based on the TekColor Color Management System. Permission is
* hereby granted to use, copy, modify, sell, and otherwise distribute this
* software and its documentation for any purpose and without fee, provided
* that this copyright, permission, and disclaimer notice is reproduced in
* all copies of this software and in supporting documentation. TekColor
* is a trademark of Tektronix, Inc.
*
* Tektronix makes no representation about the suitability of this software
* for any purpose. It is provided "as is" and with all faults.
*
* TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
* INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX 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 THE PERFORMANCE OF THIS SOFTWARE.
*
* NAME
* XcmsProp.c
*
* DESCRIPTION
* This utility routines for manipulating properties.
*
*/
/* $XFree86$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <X11/Xatom.h>
#include "Xlibint.h"
#include "Xcmsint.h"
#include "Cv.h"
/************************************************************************
* *
* API PRIVATE ROUTINES *
* *
************************************************************************/
/*
* NAME
* _XcmsGetElement -- get an element value from the property passed
*
* SYNOPSIS
*/
unsigned long
_XcmsGetElement(
int format,
char **pValue,
unsigned long *pCount)
/*
* DESCRIPTION
* Get the next element from the property and return it.
* Also increment the pointer the amount needed.
*
* Returns
* unsigned long
*/
{
unsigned long value;
switch (format) {
case 32:
value = *((unsigned long *)(*pValue)) & 0xFFFFFFFF;
*pValue += sizeof(unsigned long);
*pCount -= 1;
break;
case 16:
value = *((unsigned short *)(*pValue));
*pValue += sizeof(unsigned short);
*pCount -= 1;
break;
case 8:
value = *((unsigned char *) (*pValue));
*pValue += 1;
*pCount -= 1;
break;
default:
value = 0;
break;
}
return(value);
}
/*
* NAME
* _XcmsGetProperty -- Determine the existance of a property
*
* SYNOPSIS
*/
int
_XcmsGetProperty(
Display *pDpy,
Window w,
Atom property,
int *pFormat,
unsigned long *pNItems,
unsigned long *pNBytes,
char **pValue)
/*
* DESCRIPTION
*
* Returns
* 0 if property does not exist.
* 1 if property exists.
*/
{
char *prop_ret;
int format_ret;
long len = 6516;
unsigned long nitems_ret, after_ret;
Atom atom_ret;
while (XGetWindowProperty (pDpy, w, property, 0, len, False,
XA_INTEGER, &atom_ret, &format_ret,
&nitems_ret, &after_ret,
(unsigned char **)&prop_ret)) {
if (after_ret > 0) {
len += nitems_ret * (format_ret >> 3);
XFree (prop_ret);
} else {
break;
}
}
if (format_ret == 0 || nitems_ret == 0) {
/* the property does not exist or is of an unexpected type */
return(XcmsFailure);
}
*pFormat = format_ret;
*pNItems = nitems_ret;
*pNBytes = nitems_ret * (format_ret >> 3);
*pValue = prop_ret;
return(XcmsSuccess);
}
......@@ -57,7 +57,7 @@ GLXSRV_DEFINES = -DXFree86Server
-I$(XF86OSSRC) \
-I$(DRMSRCDIR)/shared-core
DEFINES = $(GLX_DEFINES) $(GLXSRV_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
DEFINES = $(GLX_DEFINES) $(GLXSRV_DEFINES) -DNXAGENT_SERVER /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
#ifdef IHaveModules
ModuleObjectRule()
......
XCOMM $XFree86: xc/programs/Xserver/GL/mesa/src/X/Imakefile,v 1.16 2002/11/22 22:56:01 tsi Exp $
#if DoLoadableServer
#if !BuildModuleInSubdir
#define IHaveModules
#elif !defined(IHaveModules)
#define IHaveSubdirs
SUBDIRS = module
#endif
#endif
#include <Server.tmpl>
#define NeedAllMesaSrc
#define NeedToLinkMesaSrc
#define MesaXBuildDir /**/
#define MesaInXServer
#if !defined(IHaveModules) || !BuildModuleInSubdir
#include "../../../../../lib/GL/mesa/drivers/x11/Imakefile.inc"
#else
#include "../../../../../../lib/GL/mesa/drivers/x11/Imakefile.inc"
#endif
LinkSourceFile(compsize.c,$(MESASRCDIR)/src/glx/x11)
DRIVER_SRCS = $(XMESA_SRCS)
DRIVER_OBJS = $(XMESA_OBJS)
COMMON_SRCS = driverfuncs.c
COMMON_OBJS = driverfuncs.o
#ifndef XFree86Version
/* This appears to be the quickest way to build a non-XFree86 server */
GLXSRV_DEFINES = -DXFree86Server
#endif
GLX_SRCS = xf86glx.c xf86glx_util.c compsize.c
GLX_OBJS = xf86glx.o xf86glx_util.o compsize.o
SRCS = $(DRIVER_SRCS) $(GLX_SRCS) $(COMMON_SRCS)
OBJS = $(DRIVER_OBJS) $(GLX_OBJS) $(COMMON_OBJS)
INCLUDES = -I$(SERVERSRC)/GL/mesa/X -I$(XINCLUDESRC) \
-I$(EXTINCSRC) \
-I$(MESASRCDIR)/src/mesa \
-I$(MESASRCDIR)/src/mesa/main \
-I$(MESASRCDIR)/src/mesa/glapi \
-I$(MESASRCDIR)/src/mesa/shader \
-I$(MESASRCDIR)/src -I$(MESASRCDIR)/src/mesa/drivers/x11 \
-I$(MESASRCDIR)/include \
-I$(LIBSRC)/GL/glx -I$(LIBSRC)/GL/include \
-I$(SERVERSRC)/include -I$(SERVERSRC)/GL/include \
-I$(SERVERSRC)/GL/glx \
-I$(XF86OSSRC) \
-I$(DRMSRCDIR)/shared-core
DEFINES = $(GLX_DEFINES) $(GLXSRV_DEFINES) -DNXAGENT_SERVER /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
#ifdef IHaveModules
ModuleObjectRule()
#else
NormalLibraryObjectRule()
#endif
SubdirLibraryRule($(OBJS))
LintLibraryTarget(dri,$(SRCS))
NormalLintTarget($(SRCS))
DependTarget()
#ifdef IHaveSubdirs
MakeSubdirs($(SUBDIRS))
DependSubdirs($(SUBDIRS))
#endif
#if defined(IHaveModules) && BuildModuleInSubdir
LinkSourceFile(xf86glx.c,..)
LinkSourceFile(xf86glx_util.c,..)
#endif
#ifndef MesaDrvSrcDir
#define MesaDrvSrcDir $(MESASRCDIR)/src/mesa/drivers/dri
#endif
MESADRVSRCDIR = MesaDrvSrcDir
LinkSourceFile(driverfuncs.c, $(MESADRVSRCDIR)/../common)
LinkSourceFile(driverfuncs.h, $(MESADRVSRCDIR)/../common)
XCOMM $XFree86: xc/programs/Xserver/GL/mesa/src/X/Imakefile,v 1.16 2002/11/22 22:56:01 tsi Exp $
#if DoLoadableServer
#if !BuildModuleInSubdir
#define IHaveModules
#elif !defined(IHaveModules)
#define IHaveSubdirs
SUBDIRS = module
#endif
#endif
#include <Server.tmpl>
#define NeedAllMesaSrc
#define NeedToLinkMesaSrc
#define MesaXBuildDir /**/
#define MesaInXServer
#if !defined(IHaveModules) || !BuildModuleInSubdir
#include "../../../../../lib/GL/mesa/drivers/x11/Imakefile.inc"
#else
#include "../../../../../../lib/GL/mesa/drivers/x11/Imakefile.inc"
#endif
LinkSourceFile(compsize.c,$(MESASRCDIR)/src/glx/x11)
DRIVER_SRCS = $(XMESA_SRCS)
DRIVER_OBJS = $(XMESA_OBJS)
COMMON_SRCS = driverfuncs.c
COMMON_OBJS = driverfuncs.o
#ifndef XFree86Version
/* This appears to be the quickest way to build a non-XFree86 server */
GLXSRV_DEFINES = -DXFree86Server
#endif
GLX_SRCS = xf86glx.c xf86glx_util.c compsize.c
GLX_OBJS = xf86glx.o xf86glx_util.o compsize.o
SRCS = $(DRIVER_SRCS) $(GLX_SRCS) $(COMMON_SRCS)
OBJS = $(DRIVER_OBJS) $(GLX_OBJS) $(COMMON_OBJS)
INCLUDES = -I$(SERVERSRC)/GL/mesa/X -I$(XINCLUDESRC) \
-I$(EXTINCSRC) \
-I$(MESASRCDIR)/src/mesa \
-I$(MESASRCDIR)/src/mesa/main \
-I$(MESASRCDIR)/src/mesa/glapi \
-I$(MESASRCDIR)/src/mesa/shader \
-I$(MESASRCDIR)/src -I$(MESASRCDIR)/src/mesa/drivers/x11 \
-I$(MESASRCDIR)/include \
-I$(LIBSRC)/GL/glx -I$(LIBSRC)/GL/include \
-I$(SERVERSRC)/include -I$(SERVERSRC)/GL/include \
-I$(SERVERSRC)/GL/glx \
-I$(XF86OSSRC) \
-I$(DRMSRCDIR)/shared-core
DEFINES = $(GLX_DEFINES) $(GLXSRV_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
#ifdef IHaveModules
ModuleObjectRule()
#else
NormalLibraryObjectRule()
#endif
SubdirLibraryRule($(OBJS))
LintLibraryTarget(dri,$(SRCS))
NormalLintTarget($(SRCS))
DependTarget()
#ifdef IHaveSubdirs
MakeSubdirs($(SUBDIRS))
DependSubdirs($(SUBDIRS))
#endif
#if defined(IHaveModules) && BuildModuleInSubdir
LinkSourceFile(xf86glx.c,..)
LinkSourceFile(xf86glx_util.c,..)
#endif
#ifndef MesaDrvSrcDir
#define MesaDrvSrcDir $(MESASRCDIR)/src/mesa/drivers/dri
#endif
MESADRVSRCDIR = MesaDrvSrcDir
LinkSourceFile(driverfuncs.c, $(MESADRVSRCDIR)/../common)
LinkSourceFile(driverfuncs.h, $(MESADRVSRCDIR)/../common)
......@@ -71,6 +71,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "glcontextmodes.h"
#ifdef NXAGENT_SERVER
#include "../main/WSDrawBuffer.h"
#endif
/*
* This structure is statically allocated in the __glXScreens[]
* structure. This struct is not used anywhere other than in
......@@ -95,6 +99,36 @@ static __GLXscreenInfo __glDDXScreenInfo = {
NULL /* WrappedPositionWindow is overwritten */
};
#ifdef NXAGENT_SERVER
WSDrawBufferPtr pWSDrawBuffer = NULL;
void AddWSDrawBuffer(GLframebuffer *mesa_buffer)
{
WSDrawBufferPtr prevWSDB;
WSDrawBufferPtr newWSDB;
WSDrawBufferPtr p;
prevWSDB = NULL;
newWSDB = NULL;
p = pWSDrawBuffer;
while (p != NULL) {
prevWSDB = p;
if (prevWSDB -> DrawBuffer == mesa_buffer) {
return;
}
p = p -> next;
}
newWSDB = malloc(sizeof(WSDrawBufferRec));
newWSDB -> DrawBuffer = mesa_buffer;
newWSDB -> next = NULL;
if (pWSDrawBuffer == NULL)
pWSDrawBuffer = newWSDB;
else
prevWSDB -> next = newWSDB;
}
#endif
void *__glXglDDXScreenInfo(void) {
return &__glDDXScreenInfo;
}
......@@ -748,6 +782,10 @@ void __MESA_destroyBuffer(__GLdrawablePrivate *glPriv)
__MESA_buffer buf = (__MESA_buffer)glPriv->private;
__GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
#ifdef NXAGENT_SERVER
AddWSDrawBuffer(& (buf -> xm_buf -> mesa_buffer) );
#endif
/* Destroy Mesa's buffers */
if (buf->xm_buf)
XMesaDestroyBuffer(buf->xm_buf);
......
/* $XFree86: xc/programs/Xserver/GL/mesa/src/X/xf86glx.c,v 1.19 2003/07/16 01:38:27 dawes Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian E. Paul <brian@precisioninsight.com>
*
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <regionstr.h>
#include <resource.h>
#include <GL/gl.h>
#include <GL/glxint.h>
#include <GL/glxtokens.h>
#include <scrnintstr.h>
#include <config.h>
#include <glxserver.h>
#include <glxscreens.h>
#include <glxdrawable.h>
#include <glxcontext.h>
#include <glxext.h>
#include <glxutil.h>
#include "xf86glxint.h"
#include "context.h"
#include "xmesaP.h"
#include <GL/xf86glx.h>
#include "context.h"
/*
* This define is for the glcore.h header file.
* If you add it here, then make sure you also add it in
* ../../../glx/Imakefile.
*/
#if 0
#define DEBUG
#include <GL/internal/glcore.h>
#undef DEBUG
#else
#include <GL/internal/glcore.h>
#endif
#include "glcontextmodes.h"
#ifdef NXAGENT_SERVER
#include "../main/WSDrawBuffer.h"
#endif
/*
* This structure is statically allocated in the __glXScreens[]
* structure. This struct is not used anywhere other than in
* __glXScreenInit to initialize each of the active screens
* (__glXActiveScreens[]). Several of the fields must be initialized by
* the screenProbe routine before they are copied to the active screens
* struct. In particular, the contextCreate, pGlxVisual, numVisuals,
* and numUsableVisuals fields must be initialized.
*/
static __GLXscreenInfo __glDDXScreenInfo = {
__MESA_screenProbe, /* Must be generic and handle all screens */
__MESA_createContext, /* Substitute screen's createContext routine */
__MESA_createBuffer, /* Substitute screen's createBuffer routine */
NULL, /* Set up modes in probe */
NULL, /* Set up pVisualPriv in probe */
0, /* Set up numVisuals in probe */
0, /* Set up numUsableVisuals in probe */
NULL, /* GLextensions is overwritten by __glXScreenInit */
"Vendor String", /* GLXvendor is overwritten by __glXScreenInit */
"Version String", /* GLXversion is overwritten by __glXScreenInit */
"Extensions String", /* GLXextensions is overwritten by __glXScreenInit */
NULL /* WrappedPositionWindow is overwritten */
};
#ifdef NXAGENT_SERVER
WSDrawBufferPtr pWSDrawBuffer = NULL;
void AddWSDrawBuffer(GLframebuffer *mesa_buffer)
{
WSDrawBufferPtr prevWSDB;
WSDrawBufferPtr newWSDB;
WSDrawBufferPtr p;
prevWSDB = NULL;
newWSDB = NULL;
p = pWSDrawBuffer;
while (p != NULL) {
prevWSDB = p;
if (prevWSDB -> DrawBuffer == mesa_buffer) {
return;
}
p = p -> next;
}
newWSDB = malloc(sizeof(WSDrawBufferRec));
newWSDB -> DrawBuffer = mesa_buffer;
newWSDB -> next = NULL;
if (pWSDrawBuffer == NULL)
pWSDrawBuffer = newWSDB;
else
prevWSDB -> next = newWSDB;
}
#endif
void *__glXglDDXScreenInfo(void) {
return &__glDDXScreenInfo;
}
static __GLXextensionInfo __glDDXExtensionInfo = {
GL_CORE_MESA,
__MESA_resetExtension,
__MESA_initVisuals,
__MESA_setVisualConfigs
};
void *__glXglDDXExtensionInfo(void) {
return &__glDDXExtensionInfo;
}
static __MESA_screen MESAScreens[MAXSCREENS];
static __GLcontext *MESA_CC = NULL;
static int numConfigs = 0;
static __GLXvisualConfig *visualConfigs = NULL;
static void **visualPrivates = NULL;
static int count_bits(unsigned int n)
{
int bits = 0;
while (n > 0) {
if (n & 1) bits++;
n >>= 1;
}
return bits;
}
static XMesaVisual find_mesa_visual(int screen, VisualID vid)
{
__MESA_screen * const pMScr = &MESAScreens[screen];
const __GLcontextModes *modes;
unsigned i = 0;
for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) {
if ( modes->visualID == vid ) {
break;
}
i++;
}
return (modes != NULL) ? pMScr->xm_vis[i] : NULL;
}
/*
* In the case the driver defines no GLX visuals we'll use these.
* Note that for TrueColor and DirectColor visuals, bufferSize is the
* sum of redSize, greenSize, blueSize and alphaSize, which may be larger
* than the nplanes/rootDepth of the server's X11 visuals
*/
#define NUM_FALLBACK_CONFIGS 5
static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
/* [0] = RGB, double buffered, Z */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [1] = RGB, double buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
16, 16, 16, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [2] = RGB+Alpha, double buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 8, /* rgba sizes */
-1, -1, -1, -1, /* rgba masks */
16, 16, 16, 16, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [3] = RGB+Alpha, single buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 8, /* rgba sizes */
-1, -1, -1, -1, /* rgba masks */
16, 16, 16, 16, /* rgba accum sizes */
False, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [4] = CI, double buffered, Z */
{
-1, /* vid */
-1, /* class */
False, /* rgba? (false = color index) */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
};
static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
VisualID *defaultVisp,
int ndepth, DepthPtr pdepth,
int rootDepth)
{
int numRGBconfigs;
int numCIconfigs;
int numVisuals = *nvisualp;
int numNewVisuals;
int numNewConfigs;
VisualPtr pVisual = *visualp;
VisualPtr pVisualNew = NULL;
VisualID *orig_vid = NULL;
__GLcontextModes *modes;
__GLXvisualConfig *pNewVisualConfigs = NULL;
void **glXVisualPriv;
void **pNewVisualPriv;
int found_default;
int i, j, k;
if (numConfigs > 0)
numNewConfigs = numConfigs;
else
numNewConfigs = NUM_FALLBACK_CONFIGS;
/* Alloc space for the list of new GLX visuals */
pNewVisualConfigs = (__GLXvisualConfig *)
__glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
if (!pNewVisualConfigs) {
return FALSE;
}
/* Alloc space for the list of new GLX visual privates */
pNewVisualPriv = (void **) __glXMalloc(numNewConfigs * sizeof(void *));
if (!pNewVisualPriv) {
__glXFree(pNewVisualConfigs);
return FALSE;
}
/*
** If SetVisualConfigs was not called, then use default GLX
** visual configs.
*/
if (numConfigs == 0) {
memcpy(pNewVisualConfigs, FallbackConfigs,
NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
}
else {
/* copy driver's visual config info */
for (i = 0; i < numConfigs; i++) {
pNewVisualConfigs[i] = visualConfigs[i];
pNewVisualPriv[i] = visualPrivates[i];
}
}
/* Count the number of RGB and CI visual configs */
numRGBconfigs = 0;
numCIconfigs = 0;
for (i = 0; i < numNewConfigs; i++) {
if (pNewVisualConfigs[i].rgba)
numRGBconfigs++;
else
numCIconfigs++;
}
/* Count the total number of visuals to compute */
numNewVisuals = 0;
for (i = 0; i < numVisuals; i++) {
numNewVisuals +=
(pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
? numRGBconfigs : numCIconfigs;
}
/* Reset variables for use with the next screen/driver's visual configs */
visualConfigs = NULL;
numConfigs = 0;
/* Alloc temp space for the list of orig VisualIDs for each new visual */
orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID));
if (!orig_vid) {
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisuals */
modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes));
if (modes == NULL) {
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisualPrivates */
glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *));
if (!glXVisualPriv) {
_gl_context_modes_destroy( modes );
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the new list of the X server's visuals */
pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec));
if (!pVisualNew) {
__glXFree(glXVisualPriv);
_gl_context_modes_destroy( modes );
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Initialize the new visuals */
found_default = FALSE;
MESAScreens[screenInfo.numScreens-1].modes = modes;
for (i = j = 0; i < numVisuals; i++) {
int is_rgb = (pVisual[i].class == TrueColor ||
pVisual[i].class == DirectColor);
for (k = 0; k < numNewConfigs; k++) {
if (pNewVisualConfigs[k].rgba != is_rgb)
continue;
assert( modes != NULL );
/* Initialize the new visual */
pVisualNew[j] = pVisual[i];
pVisualNew[j].vid = FakeClientID(0);
/* Check for the default visual */
if (!found_default && pVisual[i].vid == *defaultVisp) {
*defaultVisp = pVisualNew[j].vid;
found_default = TRUE;
}
/* Save the old VisualID */
orig_vid[j] = pVisual[i].vid;
/* Initialize the glXVisual */
_gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] );
modes->visualID = pVisualNew[j].vid;
/*
* If the class is -1, then assume the X visual information
* is identical to what GLX needs, and take them from the X
* visual. NOTE: if class != -1, then all other fields MUST
* be initialized.
*/
if (modes->visualType == GLX_NONE) {
modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class );
modes->redBits = count_bits(pVisual[i].redMask);
modes->greenBits = count_bits(pVisual[i].greenMask);
modes->blueBits = count_bits(pVisual[i].blueMask);
modes->alphaBits = modes->alphaBits;
modes->redMask = pVisual[i].redMask;
modes->greenMask = pVisual[i].greenMask;
modes->blueMask = pVisual[i].blueMask;
modes->alphaMask = modes->alphaMask;
modes->rgbBits = (is_rgb)
? (modes->redBits + modes->greenBits +
modes->blueBits + modes->alphaBits)
: rootDepth;
}
/* Save the device-dependent private for this visual */
glXVisualPriv[j] = pNewVisualPriv[k];
j++;
modes = modes->next;
}
}
assert(j <= numNewVisuals);
/* Save the GLX visuals in the screen structure */
MESAScreens[screenInfo.numScreens-1].num_vis = numNewVisuals;
MESAScreens[screenInfo.numScreens-1].private = glXVisualPriv;
/* Set up depth's VisualIDs */
for (i = 0; i < ndepth; i++) {
int numVids = 0;
VisualID *pVids = NULL;
int k, n = 0;
/* Count the new number of VisualIDs at this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
numVids++;
/* Allocate a new list of VisualIDs for this depth */
pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID));
/* Initialize the new list of VisualIDs for this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
pVids[n++] = pVisualNew[k].vid;
/* Update this depth's list of VisualIDs */
__glXFree(pdepth[i].vids);
pdepth[i].vids = pVids;
pdepth[i].numVids = numVids;
}
/* Update the X server's visuals */
*nvisualp = numNewVisuals;
*visualp = pVisualNew;
/* Free the old list of the X server's visuals */
__glXFree(pVisual);
/* Clean up temporary allocations */
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
/* Free the private list created by DDX HW driver */
if (visualPrivates)
xfree(visualPrivates);
visualPrivates = NULL;
return TRUE;
}
void __MESA_setVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
void **privates)
{
numConfigs = nconfigs;
visualConfigs = configs;
visualPrivates = privates;
}
Bool __MESA_initVisuals(VisualPtr *visualp, DepthPtr *depthp,
int *nvisualp, int *ndepthp, int *rootDepthp,
VisualID *defaultVisp, unsigned long sizes,
int bitsPerRGB)
{
/*
* Setup the visuals supported by this particular screen.
*/
return init_visuals(nvisualp, visualp, defaultVisp,
*ndepthp, *depthp, *rootDepthp);
}
static void fixup_visuals(int screen)
{
ScreenPtr pScreen = screenInfo.screens[screen];
__MESA_screen *pMScr = &MESAScreens[screen];
int j;
__GLcontextModes *modes;
for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) {
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
const int nplanes = (modes->rgbBits - modes->alphaBits);
const VisualPtr pVis = pScreen->visuals;
/* Find a visual that matches the GLX visual's class and size */
for (j = 0; j < pScreen->numVisuals; j++) {
if (pVis[j].class == vis_class &&
pVis[j].nplanes == nplanes) {
/* Fixup the masks */
modes->redMask = pVis[j].redMask;
modes->greenMask = pVis[j].greenMask;
modes->blueMask = pVis[j].blueMask;
/* Recalc the sizes */
modes->redBits = count_bits(modes->redMask);
modes->greenBits = count_bits(modes->greenMask);
modes->blueBits = count_bits(modes->blueMask);
}
}
}
}
static void init_screen_visuals(int screen)
{
ScreenPtr pScreen = screenInfo.screens[screen];
__GLcontextModes *modes;
XMesaVisual *pXMesaVisual;
int *used;
int i, j;
/* Alloc space for the list of XMesa visuals */
pXMesaVisual = (XMesaVisual *)__glXMalloc(MESAScreens[screen].num_vis *
sizeof(XMesaVisual));
__glXMemset(pXMesaVisual, 0,
MESAScreens[screen].num_vis * sizeof(XMesaVisual));
/* FIXME: Change 'used' to be a array of bits (rather than of ints),
* FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less
* FIXME: than 64 or 128 the stack array can be used instead of calling
* FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to
* FIXME: array of bytes instead of ints!
*/
used = (int *)__glXMalloc(pScreen->numVisuals * sizeof(int));
__glXMemset(used, 0, pScreen->numVisuals * sizeof(int));
i = 0;
for ( modes = MESAScreens[screen].modes
; modes != NULL
; modes = modes->next ) {
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
const int nplanes = (modes->rgbBits - modes->alphaBits);
const VisualPtr pVis = pScreen->visuals;
for (j = 0; j < pScreen->numVisuals; j++) {
if (pVis[j].class == vis_class &&
pVis[j].nplanes == nplanes &&
pVis[j].redMask == modes->redMask &&
pVis[j].greenMask == modes->greenMask &&
pVis[j].blueMask == modes->blueMask &&
!used[j]) {
/* Create the XMesa visual */
pXMesaVisual[i] =
XMesaCreateVisual(pScreen,
pVis,
modes->rgbMode,
(modes->alphaBits > 0),
modes->doubleBufferMode,
modes->stereoMode,
GL_TRUE, /* ximage_flag */
modes->depthBits,
modes->stencilBits,
modes->accumRedBits,
modes->accumGreenBits,
modes->accumBlueBits,
modes->accumAlphaBits,
modes->samples,
modes->level,
modes->visualRating);
/* Set the VisualID */
modes->visualID = pVis[j].vid;
/* Mark this visual used */
used[j] = 1;
break;
}
}
if ( j == pScreen->numVisuals ) {
ErrorF("No matching visual for __GLcontextMode with "
"visual class = %d (%d), nplanes = %u\n",
vis_class,
modes->visualType,
(modes->rgbBits - modes->alphaBits) );
}
else if ( modes->visualID == -1 ) {
FatalError( "Matching visual found, but visualID still -1!\n" );
}
i++;
}
__glXFree(used);
MESAScreens[screen].xm_vis = pXMesaVisual;
}
Bool __MESA_screenProbe(int screen)
{
/*
* Set up the current screen's visuals.
*/
__glDDXScreenInfo.modes = MESAScreens[screen].modes;
__glDDXScreenInfo.pVisualPriv = MESAScreens[screen].private;
__glDDXScreenInfo.numVisuals =
__glDDXScreenInfo.numUsableVisuals = MESAScreens[screen].num_vis;
/*
* Set the current screen's createContext routine. This could be
* wrapped by a DDX GLX context creation routine.
*/
__glDDXScreenInfo.createContext = __MESA_createContext;
/*
* The ordering of the rgb compenents might have been changed by the
* driver after mi initialized them.
*/
fixup_visuals(screen);
/*
* Find the GLX visuals that are supported by this screen and create
* XMesa's visuals.
*/
init_screen_visuals(screen);
return TRUE;
}
extern void __MESA_resetExtension(void)
{
int i, j;
XMesaReset();
for (i = 0; i < screenInfo.numScreens; i++) {
for (j = 0; j < MESAScreens[i].num_vis; j++) {
if (MESAScreens[i].xm_vis[j]) {
XMesaDestroyVisual(MESAScreens[i].xm_vis[j]);
MESAScreens[i].xm_vis[j] = NULL;
}
}
_gl_context_modes_destroy( MESAScreens[i].modes );
MESAScreens[i].modes = NULL;
__glXFree(MESAScreens[i].private);
MESAScreens[i].private = NULL;
__glXFree(MESAScreens[i].xm_vis);
MESAScreens[i].xm_vis = NULL;
MESAScreens[i].num_vis = 0;
}
__glDDXScreenInfo.modes = NULL;
MESA_CC = NULL;
}
void __MESA_createBuffer(__GLXdrawablePrivate *glxPriv)
{
DrawablePtr pDraw = glxPriv->pDraw;
XMesaVisual xm_vis = find_mesa_visual(pDraw->pScreen->myNum,
glxPriv->modes->visualID);
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
__MESA_buffer buf;
if (xm_vis == NULL) {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
glxPriv->modes->visualID);
}
buf = (__MESA_buffer)__glXMalloc(sizeof(struct __MESA_bufferRec));
/* Create Mesa's buffers */
if (glxPriv->type == DRAWABLE_WINDOW) {
buf->xm_buf = (void *)XMesaCreateWindowBuffer(xm_vis,
(WindowPtr)pDraw);
} else {
buf->xm_buf = (void *)XMesaCreatePixmapBuffer(xm_vis,
(PixmapPtr)pDraw, 0);
}
/* Wrap the front buffer's resize routine */
buf->fbresize = glPriv->frontBuffer.resize;
glPriv->frontBuffer.resize = __MESA_resizeBuffers;
/* Wrap the swap buffers routine */
buf->fbswap = glxPriv->swapBuffers;
glxPriv->swapBuffers = __MESA_swapBuffers;
/* Save Mesa's private buffer structure */
glPriv->private = (void *)buf;
glPriv->freePrivate = __MESA_destroyBuffer;
}
GLboolean __MESA_resizeBuffers(__GLdrawableBuffer *buffer,
GLint x, GLint y,
GLuint width, GLuint height,
__GLdrawablePrivate *glPriv,
GLuint bufferMask)
{
__MESA_buffer buf = (__MESA_buffer)glPriv->private;
if (buf->xm_buf)
XMesaResizeBuffers(buf->xm_buf);
return (*buf->fbresize)(buffer, x, y, width, height, glPriv, bufferMask);
}
GLboolean __MESA_swapBuffers(__GLXdrawablePrivate *glxPriv)
{
__MESA_buffer buf = (__MESA_buffer)glxPriv->glPriv.private;
/*
** Do not call the wrapped swap buffers routine since Mesa has
** already done the swap.
*/
XMesaSwapBuffers(buf->xm_buf);
return GL_TRUE;
}
void __MESA_destroyBuffer(__GLdrawablePrivate *glPriv)
{
__MESA_buffer buf = (__MESA_buffer)glPriv->private;
__GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
#ifdef NXAGENT_SERVER
AddWSDrawBuffer(& (buf -> xm_buf -> mesa_buffer) );
#endif
/* Destroy Mesa's buffers */
if (buf->xm_buf)
XMesaDestroyBuffer(buf->xm_buf);
/* Unwrap these routines */
glxPriv->swapBuffers = buf->fbswap;
glPriv->frontBuffer.resize = buf->fbresize;
__glXFree(glPriv->private);
glPriv->private = NULL;
}
__GLinterface *__MESA_createContext(__GLimports *imports,
__GLcontextModes *modes,
__GLinterface *shareGC)
{
__GLcontext *gl_ctx = NULL;
__GLcontext *m_share = NULL;
__GLXcontext *glxc = (__GLXcontext *)imports->other;
XMesaVisual xm_vis;
if (shareGC)
m_share = (__GLcontext *)shareGC;
xm_vis = find_mesa_visual(glxc->pScreen->myNum, glxc->modes->visualID);
if (xm_vis) {
XMesaContext xmshare = m_share ? m_share->DriverCtx : 0;
XMesaContext xmctx = XMesaCreateContext(xm_vis, xmshare);
gl_ctx = xmctx ? &xmctx->mesa : 0;
}
else {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
glxc->modes->visualID);
}
if (!gl_ctx)
return NULL;
gl_ctx->imports = *imports;
gl_ctx->exports.destroyContext = __MESA_destroyContext;
gl_ctx->exports.loseCurrent = __MESA_loseCurrent;
gl_ctx->exports.makeCurrent = __MESA_makeCurrent;
gl_ctx->exports.shareContext = __MESA_shareContext;
gl_ctx->exports.copyContext = __MESA_copyContext;
gl_ctx->exports.forceCurrent = __MESA_forceCurrent;
gl_ctx->exports.notifyResize = __MESA_notifyResize;
gl_ctx->exports.notifyDestroy = __MESA_notifyDestroy;
gl_ctx->exports.notifySwapBuffers = __MESA_notifySwapBuffers;
gl_ctx->exports.dispatchExec = __MESA_dispatchExec;
gl_ctx->exports.beginDispatchOverride = __MESA_beginDispatchOverride;
gl_ctx->exports.endDispatchOverride = __MESA_endDispatchOverride;
return (__GLinterface *)gl_ctx;
}
GLboolean __MESA_destroyContext(__GLcontext *gc)
{
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
XMesaDestroyContext( xmesa );
return GL_TRUE;
}
GLboolean __MESA_loseCurrent(__GLcontext *gc)
{
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
MESA_CC = NULL;
__glXLastContext = NULL;
return XMesaLoseCurrent(xmesa);
}
GLboolean __MESA_makeCurrent(__GLcontext *gc)
{
__GLdrawablePrivate *drawPriv = gc->imports.getDrawablePrivate( gc );
__MESA_buffer drawBuf = (__MESA_buffer)drawPriv->private;
__GLdrawablePrivate *readPriv = gc->imports.getReadablePrivate( gc );
__MESA_buffer readBuf = (__MESA_buffer)readPriv->private;
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
MESA_CC = gc;
return XMesaMakeCurrent2(xmesa, drawBuf->xm_buf, readBuf->xm_buf);
}
GLboolean __MESA_shareContext(__GLcontext *gc, __GLcontext *gcShare)
{
/* NOT_DONE */
/* XXX I don't see where/how this could ever be called */
ErrorF("__MESA_shareContext\n");
return GL_FALSE;
}
GLboolean __MESA_copyContext(__GLcontext *dst, const __GLcontext *src,
GLuint mask)
{
XMesaContext xm_dst = (XMesaContext) dst->DriverCtx;
const XMesaContext xm_src = (const XMesaContext) src->DriverCtx;
_mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
return GL_TRUE;
}
GLboolean __MESA_forceCurrent(__GLcontext *gc)
{
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
MESA_CC = gc;
return XMesaForceCurrent(xmesa);
}
GLboolean __MESA_notifyResize(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_notifyResize\n");
return GL_FALSE;
}
void __MESA_notifyDestroy(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_notifyDestroy\n");
return;
}
void __MESA_notifySwapBuffers(__GLcontext *gc)
{
_mesa_notifySwapBuffers(gc);
}
struct __GLdispatchStateRec *__MESA_dispatchExec(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_dispatchExec\n");
return NULL;
}
void __MESA_beginDispatchOverride(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_beginDispatchOverride\n");
return;
}
void __MESA_endDispatchOverride(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_endDispatchOverride\n");
return;
}
/*
* Server-side GLX uses these functions which are normally defined
* in the OpenGL SI.
*/
GLuint __glFloorLog2(GLuint val)
{
int c = 0;
while (val > 1) {
c++;
val >>= 1;
}
return c;
}
/* $XFree86: xc/programs/Xserver/GL/mesa/src/X/xf86glx.c,v 1.19 2003/07/16 01:38:27 dawes Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Kevin E. Martin <kevin@precisioninsight.com>
* Brian E. Paul <brian@precisioninsight.com>
*
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <regionstr.h>
#include <resource.h>
#include <GL/gl.h>
#include <GL/glxint.h>
#include <GL/glxtokens.h>
#include <scrnintstr.h>
#include <config.h>
#include <glxserver.h>
#include <glxscreens.h>
#include <glxdrawable.h>
#include <glxcontext.h>
#include <glxext.h>
#include <glxutil.h>
#include "xf86glxint.h"
#include "context.h"
#include "xmesaP.h"
#include <GL/xf86glx.h>
#include "context.h"
/*
* This define is for the glcore.h header file.
* If you add it here, then make sure you also add it in
* ../../../glx/Imakefile.
*/
#if 0
#define DEBUG
#include <GL/internal/glcore.h>
#undef DEBUG
#else
#include <GL/internal/glcore.h>
#endif
#include "glcontextmodes.h"
/*
* This structure is statically allocated in the __glXScreens[]
* structure. This struct is not used anywhere other than in
* __glXScreenInit to initialize each of the active screens
* (__glXActiveScreens[]). Several of the fields must be initialized by
* the screenProbe routine before they are copied to the active screens
* struct. In particular, the contextCreate, pGlxVisual, numVisuals,
* and numUsableVisuals fields must be initialized.
*/
static __GLXscreenInfo __glDDXScreenInfo = {
__MESA_screenProbe, /* Must be generic and handle all screens */
__MESA_createContext, /* Substitute screen's createContext routine */
__MESA_createBuffer, /* Substitute screen's createBuffer routine */
NULL, /* Set up modes in probe */
NULL, /* Set up pVisualPriv in probe */
0, /* Set up numVisuals in probe */
0, /* Set up numUsableVisuals in probe */
NULL, /* GLextensions is overwritten by __glXScreenInit */
"Vendor String", /* GLXvendor is overwritten by __glXScreenInit */
"Version String", /* GLXversion is overwritten by __glXScreenInit */
"Extensions String", /* GLXextensions is overwritten by __glXScreenInit */
NULL /* WrappedPositionWindow is overwritten */
};
void *__glXglDDXScreenInfo(void) {
return &__glDDXScreenInfo;
}
static __GLXextensionInfo __glDDXExtensionInfo = {
GL_CORE_MESA,
__MESA_resetExtension,
__MESA_initVisuals,
__MESA_setVisualConfigs
};
void *__glXglDDXExtensionInfo(void) {
return &__glDDXExtensionInfo;
}
static __MESA_screen MESAScreens[MAXSCREENS];
static __GLcontext *MESA_CC = NULL;
static int numConfigs = 0;
static __GLXvisualConfig *visualConfigs = NULL;
static void **visualPrivates = NULL;
static int count_bits(unsigned int n)
{
int bits = 0;
while (n > 0) {
if (n & 1) bits++;
n >>= 1;
}
return bits;
}
static XMesaVisual find_mesa_visual(int screen, VisualID vid)
{
__MESA_screen * const pMScr = &MESAScreens[screen];
const __GLcontextModes *modes;
unsigned i = 0;
for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) {
if ( modes->visualID == vid ) {
break;
}
i++;
}
return (modes != NULL) ? pMScr->xm_vis[i] : NULL;
}
/*
* In the case the driver defines no GLX visuals we'll use these.
* Note that for TrueColor and DirectColor visuals, bufferSize is the
* sum of redSize, greenSize, blueSize and alphaSize, which may be larger
* than the nplanes/rootDepth of the server's X11 visuals
*/
#define NUM_FALLBACK_CONFIGS 5
static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
/* [0] = RGB, double buffered, Z */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [1] = RGB, double buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
16, 16, 16, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [2] = RGB+Alpha, double buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 8, /* rgba sizes */
-1, -1, -1, -1, /* rgba masks */
16, 16, 16, 16, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [3] = RGB+Alpha, single buffered, Z, stencil, accum */
{
-1, /* vid */
-1, /* class */
True, /* rgba */
-1, -1, -1, 8, /* rgba sizes */
-1, -1, -1, -1, /* rgba masks */
16, 16, 16, 16, /* rgba accum sizes */
False, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
8, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
/* [4] = CI, double buffered, Z */
{
-1, /* vid */
-1, /* class */
False, /* rgba? (false = color index) */
-1, -1, -1, 0, /* rgba sizes */
-1, -1, -1, 0, /* rgba masks */
0, 0, 0, 0, /* rgba accum sizes */
True, /* doubleBuffer */
False, /* stereo */
-1, /* bufferSize */
16, /* depthSize */
0, /* stencilSize */
0, /* auxBuffers */
0, /* level */
GLX_NONE, /* visualRating */
GLX_NONE, /* transparentPixel */
0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
0 /* transparentIndex */
},
};
static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
VisualID *defaultVisp,
int ndepth, DepthPtr pdepth,
int rootDepth)
{
int numRGBconfigs;
int numCIconfigs;
int numVisuals = *nvisualp;
int numNewVisuals;
int numNewConfigs;
VisualPtr pVisual = *visualp;
VisualPtr pVisualNew = NULL;
VisualID *orig_vid = NULL;
__GLcontextModes *modes;
__GLXvisualConfig *pNewVisualConfigs = NULL;
void **glXVisualPriv;
void **pNewVisualPriv;
int found_default;
int i, j, k;
if (numConfigs > 0)
numNewConfigs = numConfigs;
else
numNewConfigs = NUM_FALLBACK_CONFIGS;
/* Alloc space for the list of new GLX visuals */
pNewVisualConfigs = (__GLXvisualConfig *)
__glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
if (!pNewVisualConfigs) {
return FALSE;
}
/* Alloc space for the list of new GLX visual privates */
pNewVisualPriv = (void **) __glXMalloc(numNewConfigs * sizeof(void *));
if (!pNewVisualPriv) {
__glXFree(pNewVisualConfigs);
return FALSE;
}
/*
** If SetVisualConfigs was not called, then use default GLX
** visual configs.
*/
if (numConfigs == 0) {
memcpy(pNewVisualConfigs, FallbackConfigs,
NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
}
else {
/* copy driver's visual config info */
for (i = 0; i < numConfigs; i++) {
pNewVisualConfigs[i] = visualConfigs[i];
pNewVisualPriv[i] = visualPrivates[i];
}
}
/* Count the number of RGB and CI visual configs */
numRGBconfigs = 0;
numCIconfigs = 0;
for (i = 0; i < numNewConfigs; i++) {
if (pNewVisualConfigs[i].rgba)
numRGBconfigs++;
else
numCIconfigs++;
}
/* Count the total number of visuals to compute */
numNewVisuals = 0;
for (i = 0; i < numVisuals; i++) {
numNewVisuals +=
(pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
? numRGBconfigs : numCIconfigs;
}
/* Reset variables for use with the next screen/driver's visual configs */
visualConfigs = NULL;
numConfigs = 0;
/* Alloc temp space for the list of orig VisualIDs for each new visual */
orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID));
if (!orig_vid) {
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisuals */
modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes));
if (modes == NULL) {
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the list of glXVisualPrivates */
glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *));
if (!glXVisualPriv) {
_gl_context_modes_destroy( modes );
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Alloc space for the new list of the X server's visuals */
pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec));
if (!pVisualNew) {
__glXFree(glXVisualPriv);
_gl_context_modes_destroy( modes );
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
return FALSE;
}
/* Initialize the new visuals */
found_default = FALSE;
MESAScreens[screenInfo.numScreens-1].modes = modes;
for (i = j = 0; i < numVisuals; i++) {
int is_rgb = (pVisual[i].class == TrueColor ||
pVisual[i].class == DirectColor);
for (k = 0; k < numNewConfigs; k++) {
if (pNewVisualConfigs[k].rgba != is_rgb)
continue;
assert( modes != NULL );
/* Initialize the new visual */
pVisualNew[j] = pVisual[i];
pVisualNew[j].vid = FakeClientID(0);
/* Check for the default visual */
if (!found_default && pVisual[i].vid == *defaultVisp) {
*defaultVisp = pVisualNew[j].vid;
found_default = TRUE;
}
/* Save the old VisualID */
orig_vid[j] = pVisual[i].vid;
/* Initialize the glXVisual */
_gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] );
modes->visualID = pVisualNew[j].vid;
/*
* If the class is -1, then assume the X visual information
* is identical to what GLX needs, and take them from the X
* visual. NOTE: if class != -1, then all other fields MUST
* be initialized.
*/
if (modes->visualType == GLX_NONE) {
modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class );
modes->redBits = count_bits(pVisual[i].redMask);
modes->greenBits = count_bits(pVisual[i].greenMask);
modes->blueBits = count_bits(pVisual[i].blueMask);
modes->alphaBits = modes->alphaBits;
modes->redMask = pVisual[i].redMask;
modes->greenMask = pVisual[i].greenMask;
modes->blueMask = pVisual[i].blueMask;
modes->alphaMask = modes->alphaMask;
modes->rgbBits = (is_rgb)
? (modes->redBits + modes->greenBits +
modes->blueBits + modes->alphaBits)
: rootDepth;
}
/* Save the device-dependent private for this visual */
glXVisualPriv[j] = pNewVisualPriv[k];
j++;
modes = modes->next;
}
}
assert(j <= numNewVisuals);
/* Save the GLX visuals in the screen structure */
MESAScreens[screenInfo.numScreens-1].num_vis = numNewVisuals;
MESAScreens[screenInfo.numScreens-1].private = glXVisualPriv;
/* Set up depth's VisualIDs */
for (i = 0; i < ndepth; i++) {
int numVids = 0;
VisualID *pVids = NULL;
int k, n = 0;
/* Count the new number of VisualIDs at this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
numVids++;
/* Allocate a new list of VisualIDs for this depth */
pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID));
/* Initialize the new list of VisualIDs for this depth */
for (j = 0; j < pdepth[i].numVids; j++)
for (k = 0; k < numNewVisuals; k++)
if (pdepth[i].vids[j] == orig_vid[k])
pVids[n++] = pVisualNew[k].vid;
/* Update this depth's list of VisualIDs */
__glXFree(pdepth[i].vids);
pdepth[i].vids = pVids;
pdepth[i].numVids = numVids;
}
/* Update the X server's visuals */
*nvisualp = numNewVisuals;
*visualp = pVisualNew;
/* Free the old list of the X server's visuals */
__glXFree(pVisual);
/* Clean up temporary allocations */
__glXFree(orig_vid);
__glXFree(pNewVisualPriv);
__glXFree(pNewVisualConfigs);
/* Free the private list created by DDX HW driver */
if (visualPrivates)
xfree(visualPrivates);
visualPrivates = NULL;
return TRUE;
}
void __MESA_setVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
void **privates)
{
numConfigs = nconfigs;
visualConfigs = configs;
visualPrivates = privates;
}
Bool __MESA_initVisuals(VisualPtr *visualp, DepthPtr *depthp,
int *nvisualp, int *ndepthp, int *rootDepthp,
VisualID *defaultVisp, unsigned long sizes,
int bitsPerRGB)
{
/*
* Setup the visuals supported by this particular screen.
*/
return init_visuals(nvisualp, visualp, defaultVisp,
*ndepthp, *depthp, *rootDepthp);
}
static void fixup_visuals(int screen)
{
ScreenPtr pScreen = screenInfo.screens[screen];
__MESA_screen *pMScr = &MESAScreens[screen];
int j;
__GLcontextModes *modes;
for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) {
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
const int nplanes = (modes->rgbBits - modes->alphaBits);
const VisualPtr pVis = pScreen->visuals;
/* Find a visual that matches the GLX visual's class and size */
for (j = 0; j < pScreen->numVisuals; j++) {
if (pVis[j].class == vis_class &&
pVis[j].nplanes == nplanes) {
/* Fixup the masks */
modes->redMask = pVis[j].redMask;
modes->greenMask = pVis[j].greenMask;
modes->blueMask = pVis[j].blueMask;
/* Recalc the sizes */
modes->redBits = count_bits(modes->redMask);
modes->greenBits = count_bits(modes->greenMask);
modes->blueBits = count_bits(modes->blueMask);
}
}
}
}
static void init_screen_visuals(int screen)
{
ScreenPtr pScreen = screenInfo.screens[screen];
__GLcontextModes *modes;
XMesaVisual *pXMesaVisual;
int *used;
int i, j;
/* Alloc space for the list of XMesa visuals */
pXMesaVisual = (XMesaVisual *)__glXMalloc(MESAScreens[screen].num_vis *
sizeof(XMesaVisual));
__glXMemset(pXMesaVisual, 0,
MESAScreens[screen].num_vis * sizeof(XMesaVisual));
/* FIXME: Change 'used' to be a array of bits (rather than of ints),
* FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less
* FIXME: than 64 or 128 the stack array can be used instead of calling
* FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to
* FIXME: array of bytes instead of ints!
*/
used = (int *)__glXMalloc(pScreen->numVisuals * sizeof(int));
__glXMemset(used, 0, pScreen->numVisuals * sizeof(int));
i = 0;
for ( modes = MESAScreens[screen].modes
; modes != NULL
; modes = modes->next ) {
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
const int nplanes = (modes->rgbBits - modes->alphaBits);
const VisualPtr pVis = pScreen->visuals;
for (j = 0; j < pScreen->numVisuals; j++) {
if (pVis[j].class == vis_class &&
pVis[j].nplanes == nplanes &&
pVis[j].redMask == modes->redMask &&
pVis[j].greenMask == modes->greenMask &&
pVis[j].blueMask == modes->blueMask &&
!used[j]) {
/* Create the XMesa visual */
pXMesaVisual[i] =
XMesaCreateVisual(pScreen,
pVis,
modes->rgbMode,
(modes->alphaBits > 0),
modes->doubleBufferMode,
modes->stereoMode,
GL_TRUE, /* ximage_flag */
modes->depthBits,
modes->stencilBits,
modes->accumRedBits,
modes->accumGreenBits,
modes->accumBlueBits,
modes->accumAlphaBits,
modes->samples,
modes->level,
modes->visualRating);
/* Set the VisualID */
modes->visualID = pVis[j].vid;
/* Mark this visual used */
used[j] = 1;
break;
}
}
if ( j == pScreen->numVisuals ) {
ErrorF("No matching visual for __GLcontextMode with "
"visual class = %d (%d), nplanes = %u\n",
vis_class,
modes->visualType,
(modes->rgbBits - modes->alphaBits) );
}
else if ( modes->visualID == -1 ) {
FatalError( "Matching visual found, but visualID still -1!\n" );
}
i++;
}
__glXFree(used);
MESAScreens[screen].xm_vis = pXMesaVisual;
}
Bool __MESA_screenProbe(int screen)
{
/*
* Set up the current screen's visuals.
*/
__glDDXScreenInfo.modes = MESAScreens[screen].modes;
__glDDXScreenInfo.pVisualPriv = MESAScreens[screen].private;
__glDDXScreenInfo.numVisuals =
__glDDXScreenInfo.numUsableVisuals = MESAScreens[screen].num_vis;
/*
* Set the current screen's createContext routine. This could be
* wrapped by a DDX GLX context creation routine.
*/
__glDDXScreenInfo.createContext = __MESA_createContext;
/*
* The ordering of the rgb compenents might have been changed by the
* driver after mi initialized them.
*/
fixup_visuals(screen);
/*
* Find the GLX visuals that are supported by this screen and create
* XMesa's visuals.
*/
init_screen_visuals(screen);
return TRUE;
}
extern void __MESA_resetExtension(void)
{
int i, j;
XMesaReset();
for (i = 0; i < screenInfo.numScreens; i++) {
for (j = 0; j < MESAScreens[i].num_vis; j++) {
if (MESAScreens[i].xm_vis[j]) {
XMesaDestroyVisual(MESAScreens[i].xm_vis[j]);
MESAScreens[i].xm_vis[j] = NULL;
}
}
_gl_context_modes_destroy( MESAScreens[i].modes );
MESAScreens[i].modes = NULL;
__glXFree(MESAScreens[i].private);
MESAScreens[i].private = NULL;
__glXFree(MESAScreens[i].xm_vis);
MESAScreens[i].xm_vis = NULL;
MESAScreens[i].num_vis = 0;
}
__glDDXScreenInfo.modes = NULL;
MESA_CC = NULL;
}
void __MESA_createBuffer(__GLXdrawablePrivate *glxPriv)
{
DrawablePtr pDraw = glxPriv->pDraw;
XMesaVisual xm_vis = find_mesa_visual(pDraw->pScreen->myNum,
glxPriv->modes->visualID);
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
__MESA_buffer buf;
if (xm_vis == NULL) {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
glxPriv->modes->visualID);
}
buf = (__MESA_buffer)__glXMalloc(sizeof(struct __MESA_bufferRec));
/* Create Mesa's buffers */
if (glxPriv->type == DRAWABLE_WINDOW) {
buf->xm_buf = (void *)XMesaCreateWindowBuffer(xm_vis,
(WindowPtr)pDraw);
} else {
buf->xm_buf = (void *)XMesaCreatePixmapBuffer(xm_vis,
(PixmapPtr)pDraw, 0);
}
/* Wrap the front buffer's resize routine */
buf->fbresize = glPriv->frontBuffer.resize;
glPriv->frontBuffer.resize = __MESA_resizeBuffers;
/* Wrap the swap buffers routine */
buf->fbswap = glxPriv->swapBuffers;
glxPriv->swapBuffers = __MESA_swapBuffers;
/* Save Mesa's private buffer structure */
glPriv->private = (void *)buf;
glPriv->freePrivate = __MESA_destroyBuffer;
}
GLboolean __MESA_resizeBuffers(__GLdrawableBuffer *buffer,
GLint x, GLint y,
GLuint width, GLuint height,
__GLdrawablePrivate *glPriv,
GLuint bufferMask)
{
__MESA_buffer buf = (__MESA_buffer)glPriv->private;
if (buf->xm_buf)
XMesaResizeBuffers(buf->xm_buf);
return (*buf->fbresize)(buffer, x, y, width, height, glPriv, bufferMask);
}
GLboolean __MESA_swapBuffers(__GLXdrawablePrivate *glxPriv)
{
__MESA_buffer buf = (__MESA_buffer)glxPriv->glPriv.private;
/*
** Do not call the wrapped swap buffers routine since Mesa has
** already done the swap.
*/
XMesaSwapBuffers(buf->xm_buf);
return GL_TRUE;
}
void __MESA_destroyBuffer(__GLdrawablePrivate *glPriv)
{
__MESA_buffer buf = (__MESA_buffer)glPriv->private;
__GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
/* Destroy Mesa's buffers */
if (buf->xm_buf)
XMesaDestroyBuffer(buf->xm_buf);
/* Unwrap these routines */
glxPriv->swapBuffers = buf->fbswap;
glPriv->frontBuffer.resize = buf->fbresize;
__glXFree(glPriv->private);
glPriv->private = NULL;
}
__GLinterface *__MESA_createContext(__GLimports *imports,
__GLcontextModes *modes,
__GLinterface *shareGC)
{
__GLcontext *gl_ctx = NULL;
__GLcontext *m_share = NULL;
__GLXcontext *glxc = (__GLXcontext *)imports->other;
XMesaVisual xm_vis;
if (shareGC)
m_share = (__GLcontext *)shareGC;
xm_vis = find_mesa_visual(glxc->pScreen->myNum, glxc->modes->visualID);
if (xm_vis) {
XMesaContext xmshare = m_share ? m_share->DriverCtx : 0;
XMesaContext xmctx = XMesaCreateContext(xm_vis, xmshare);
gl_ctx = xmctx ? &xmctx->mesa : 0;
}
else {
ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
glxc->modes->visualID);
}
if (!gl_ctx)
return NULL;
gl_ctx->imports = *imports;
gl_ctx->exports.destroyContext = __MESA_destroyContext;
gl_ctx->exports.loseCurrent = __MESA_loseCurrent;
gl_ctx->exports.makeCurrent = __MESA_makeCurrent;
gl_ctx->exports.shareContext = __MESA_shareContext;
gl_ctx->exports.copyContext = __MESA_copyContext;
gl_ctx->exports.forceCurrent = __MESA_forceCurrent;
gl_ctx->exports.notifyResize = __MESA_notifyResize;
gl_ctx->exports.notifyDestroy = __MESA_notifyDestroy;
gl_ctx->exports.notifySwapBuffers = __MESA_notifySwapBuffers;
gl_ctx->exports.dispatchExec = __MESA_dispatchExec;
gl_ctx->exports.beginDispatchOverride = __MESA_beginDispatchOverride;
gl_ctx->exports.endDispatchOverride = __MESA_endDispatchOverride;
return (__GLinterface *)gl_ctx;
}
GLboolean __MESA_destroyContext(__GLcontext *gc)
{
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
XMesaDestroyContext( xmesa );
return GL_TRUE;
}
GLboolean __MESA_loseCurrent(__GLcontext *gc)
{
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
MESA_CC = NULL;
__glXLastContext = NULL;
return XMesaLoseCurrent(xmesa);
}
GLboolean __MESA_makeCurrent(__GLcontext *gc)
{
__GLdrawablePrivate *drawPriv = gc->imports.getDrawablePrivate( gc );
__MESA_buffer drawBuf = (__MESA_buffer)drawPriv->private;
__GLdrawablePrivate *readPriv = gc->imports.getReadablePrivate( gc );
__MESA_buffer readBuf = (__MESA_buffer)readPriv->private;
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
MESA_CC = gc;
return XMesaMakeCurrent2(xmesa, drawBuf->xm_buf, readBuf->xm_buf);
}
GLboolean __MESA_shareContext(__GLcontext *gc, __GLcontext *gcShare)
{
/* NOT_DONE */
/* XXX I don't see where/how this could ever be called */
ErrorF("__MESA_shareContext\n");
return GL_FALSE;
}
GLboolean __MESA_copyContext(__GLcontext *dst, const __GLcontext *src,
GLuint mask)
{
XMesaContext xm_dst = (XMesaContext) dst->DriverCtx;
const XMesaContext xm_src = (const XMesaContext) src->DriverCtx;
_mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
return GL_TRUE;
}
GLboolean __MESA_forceCurrent(__GLcontext *gc)
{
XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
MESA_CC = gc;
return XMesaForceCurrent(xmesa);
}
GLboolean __MESA_notifyResize(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_notifyResize\n");
return GL_FALSE;
}
void __MESA_notifyDestroy(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_notifyDestroy\n");
return;
}
void __MESA_notifySwapBuffers(__GLcontext *gc)
{
_mesa_notifySwapBuffers(gc);
}
struct __GLdispatchStateRec *__MESA_dispatchExec(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_dispatchExec\n");
return NULL;
}
void __MESA_beginDispatchOverride(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_beginDispatchOverride\n");
return;
}
void __MESA_endDispatchOverride(__GLcontext *gc)
{
/* NOT_DONE */
ErrorF("__MESA_endDispatchOverride\n");
return;
}
/*
* Server-side GLX uses these functions which are normally defined
* in the OpenGL SI.
*/
GLuint __glFloorLog2(GLuint val)
{
int c = 0;
while (val > 1) {
c++;
val >>= 1;
}
return c;
}
......@@ -39,7 +39,7 @@ SUBDIRS = module
-I$(LIBSRC)/GL/include \
-I$(XF86SRC) -I$(INCLUDESRC)
DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
DEFINES = $(GLX_DEFINES) -DNXAGENT_SERVER /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
#ifdef IHaveModules
ModuleObjectRule()
......
XCOMM $XdotOrg: xc/programs/Xserver/GL/mesa/main/Imakefile,v 1.2 2004/08/19 07:34:43 kem Exp $
XCOMM $XFree86: xc/programs/Xserver/GL/mesa/src/math/Imakefile,v 1.8 2002/11/22 22:56:01 tsi Exp $
#if DoLoadableServer
#if !BuildModuleInSubdir
#define IHaveModules
#elif !defined(IHaveModules)
#define IHaveSubdirs
SUBDIRS = module
#endif
#endif
/* Large PIC tables needed for Solaris/SPARC builds */
#if defined(SunArchitecture) && defined(SparcArchitecture) && defined(LargePositionIndependentCFlags)
PICFLAGS = LargePositionIndependentCFlags
#endif
#include <Server.tmpl>
#define NeedAllMesaSrc
#define NeedToLinkMesaSrc
#define MesaBuildDir /**/
#if !defined(IHaveModules) || !BuildModuleInSubdir
#include "../../../../../lib/GL/mesa/main/Imakefile.inc"
#else
#include "../../../../../../lib/GL/mesa/main/Imakefile.inc"
#endif
SRCS = $(COREMESABASESRCS)
OBJS = $(COREMESABASEOBJS)
INCLUDES = -I$(MESASRCDIR)/src/mesa \
-I$(MESASRCDIR)/src/mesa/main \
-I$(MESASRCDIR)/src/mesa/shader \
-I$(MESASRCDIR)/src/mesa/glapi \
-I$(MESASRCDIR)/include \
-I$(SERVERSRC)/include -I$(XINCLUDESRC) \
-I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
-I$(LIBSRC)/GL/include \
-I$(XF86SRC) -I$(INCLUDESRC)
DEFINES = $(GLX_DEFINES) -DNXAGENT_SERVER /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
#ifdef IHaveModules
ModuleObjectRule()
#else
NormalLibraryObjectRule()
#endif
SubdirLibraryRule($(OBJS))
LintLibraryTarget(dri,$(SRCS))
NormalLintTarget($(SRCS))
DependTarget()
#ifdef IHaveSubdirs
MakeSubdirs($(SUBDIRS))
DependSubdirs($(SUBDIRS))
#endif
XCOMM $XdotOrg: xc/programs/Xserver/GL/mesa/main/Imakefile,v 1.2 2004/08/19 07:34:43 kem Exp $
XCOMM $XFree86: xc/programs/Xserver/GL/mesa/src/math/Imakefile,v 1.8 2002/11/22 22:56:01 tsi Exp $
#if DoLoadableServer
#if !BuildModuleInSubdir
#define IHaveModules
#elif !defined(IHaveModules)
#define IHaveSubdirs
SUBDIRS = module
#endif
#endif
/* Large PIC tables needed for Solaris/SPARC builds */
#if defined(SunArchitecture) && defined(SparcArchitecture) && defined(LargePositionIndependentCFlags)
PICFLAGS = LargePositionIndependentCFlags
#endif
#include <Server.tmpl>
#define NeedAllMesaSrc
#define NeedToLinkMesaSrc
#define MesaBuildDir /**/
#if !defined(IHaveModules) || !BuildModuleInSubdir
#include "../../../../../lib/GL/mesa/main/Imakefile.inc"
#else
#include "../../../../../../lib/GL/mesa/main/Imakefile.inc"
#endif
SRCS = $(COREMESABASESRCS)
OBJS = $(COREMESABASEOBJS)
INCLUDES = -I$(MESASRCDIR)/src/mesa \
-I$(MESASRCDIR)/src/mesa/main \
-I$(MESASRCDIR)/src/mesa/shader \
-I$(MESASRCDIR)/src/mesa/glapi \
-I$(MESASRCDIR)/include \
-I$(SERVERSRC)/include -I$(XINCLUDESRC) \
-I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
-I$(LIBSRC)/GL/include \
-I$(XF86SRC) -I$(INCLUDESRC)
DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
#ifdef IHaveModules
ModuleObjectRule()
#else
NormalLibraryObjectRule()
#endif
SubdirLibraryRule($(OBJS))
LintLibraryTarget(dri,$(SRCS))
NormalLintTarget($(SRCS))
DependTarget()
#ifdef IHaveSubdirs
MakeSubdirs($(SUBDIRS))
DependSubdirs($(SUBDIRS))
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment