-/* $Id: context.c,v 1.166 2002/06/13 04:49:17 brianp Exp $ */
+/* $Id: context.c,v 1.172 2002/06/18 16:53:46 brianp Exp $ */
/*
* Mesa 3-D graphics library
#include "state.h"
#include "teximage.h"
#include "texobj.h"
+#include "texstate.h"
#include "mtypes.h"
#include "varray.h"
#include "vpstate.h"
{
GLcontext *ctx;
- ctx = (GLcontext *) (*imports->calloc)(0, 1, sizeof(GLcontext));
+ ctx = (GLcontext *) (*imports->calloc)(NULL, 1, sizeof(GLcontext));
if (ctx == NULL) {
return NULL;
}
ctx->Driver.CurrentExecPrimitive=0; /* XXX why is this here??? */
ctx->imports = *imports;
+ _mesa_init_default_exports(&(ctx->exports));
_mesa_initialize_visual(&ctx->Visual,
modes->rgbMode,
assert(buffer);
assert(visual);
+ BZERO(buffer, sizeof(GLframebuffer));
+
/* sanity checks */
if (softwareDepth ) {
assert(visual->depthBits > 0);
* This function just calls all the various one-time-init functions in Mesa.
*/
static void
-one_time_init( void )
+one_time_init( GLcontext *ctx )
{
static GLboolean alreadyCalled = GL_FALSE;
_glthread_LOCK_MUTEX(OneTimeLock);
#ifdef USE_SPARC_ASM
_mesa_init_sparc_glapi_relocs();
#endif
- if (getenv("MESA_DEBUG")) {
+ if (ctx->imports.getenv(ctx, "MESA_DEBUG")) {
_glapi_noop_enable_warnings(GL_TRUE);
}
else {
}
#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
- fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
+ fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
#endif
alreadyCalled = GL_TRUE;
/* Default Texture objects */
outOfMemory = GL_FALSE;
- ss->Default1D = _mesa_alloc_texture_object(ss, 0, 1);
+ ss->Default1D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_1D);
if (!ss->Default1D) {
outOfMemory = GL_TRUE;
}
- ss->Default2D = _mesa_alloc_texture_object(ss, 0, 2);
+ ss->Default2D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_2D);
if (!ss->Default2D) {
outOfMemory = GL_TRUE;
}
- ss->Default3D = _mesa_alloc_texture_object(ss, 0, 3);
+ ss->Default3D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_3D);
if (!ss->Default3D) {
outOfMemory = GL_TRUE;
}
- ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0, 6);
+ ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0,
+ GL_TEXTURE_CUBE_MAP_ARB);
if (!ss->DefaultCubeMap) {
outOfMemory = GL_TRUE;
}
+ ss->DefaultRect = _mesa_alloc_texture_object(ss, 0,
+ GL_TEXTURE_RECTANGLE_NV);
+ if (!ss->DefaultRect) {
+ outOfMemory = GL_TRUE;
+ }
+
if (!ss->DisplayList || !ss->TexObjects || !ss->VertexPrograms
|| outOfMemory) {
/* Ran out of memory at some point. Free everything and return NULL */
_mesa_free_texture_object(ss, ss->Default3D);
if (ss->DefaultCubeMap)
_mesa_free_texture_object(ss, ss->DefaultCubeMap);
+ if (ss->DefaultRect)
+ _mesa_free_texture_object(ss, ss->DefaultRect);
FREE(ss);
return NULL;
}
texUnit->Current2D = ctx->Shared->Default2D;
texUnit->Current3D = ctx->Shared->Default3D;
texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+ texUnit->CurrentRect = ctx->Shared->DefaultRect;
}
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.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
/* Texture group */
ctx->Texture.CurrentUnit = 0; /* multitexture */
- ctx->Texture._ReallyEnabled = 0;
+ ctx->Texture._ReallyEnabled = 0; /* XXX obsolete */
+ ctx->Texture._EnabledUnits = 0;
for (i=0; i<MAX_TEXTURE_UNITS; i++)
init_texture_unit( ctx, i );
ctx->Texture.SharedPalette = GL_FALSE;
_mesa_init_colortable(&ctx->ProxyPostColorMatrixColorTable);
/* GL_NV_vertex_program */
- ctx->VertexProgram.Current = NULL;
- ctx->VertexProgram.CurrentID = 0;
ctx->VertexProgram.Enabled = GL_FALSE;
ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
+ ctx->VertexProgram.CurrentID = 0;
+ ctx->VertexProgram.ErrorPos = -1;
+ ctx->VertexProgram.Current = NULL;
for (i = 0; i < VP_NUM_PROG_REGS / 4; i++) {
ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
ctx->OcclusionResultSaved = GL_FALSE;
/* For debug/development only */
- ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
+ ctx->NoRaster = ctx->imports.getenv(ctx, "MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
ctx->FirstTimeCurrent = GL_TRUE;
/* Dither disable */
- ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
+ ctx->NoDither = ctx->imports.getenv(ctx, "MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
if (ctx->NoDither) {
- if (getenv("MESA_DEBUG")) {
+ if (ctx->imports.getenv(ctx, "MESA_DEBUG")) {
fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
}
ctx->Color.DitherFlag = GL_FALSE;
GLboolean out_of_memory;
GLint i;
- ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, 1);
+ ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_1D);
if (!ctx->Texture.Proxy1D) {
return GL_FALSE;
}
- ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, 2);
+ ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_2D);
if (!ctx->Texture.Proxy2D) {
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
return GL_FALSE;
}
- ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, 3);
+ ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_3D);
if (!ctx->Texture.Proxy3D) {
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
_mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
return GL_FALSE;
}
- ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0, 6);
+ ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0,
+ GL_TEXTURE_CUBE_MAP_ARB);
if (!ctx->Texture.ProxyCubeMap) {
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
_mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
return GL_FALSE;
}
+ ctx->Texture.ProxyRect = _mesa_alloc_texture_object(NULL, 0,
+ GL_TEXTURE_RECTANGLE_NV);
+ if (!ctx->Texture.ProxyRect) {
+ _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
+ _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
+ _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
+ _mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap);
+ return GL_FALSE;
+ }
+
out_of_memory = GL_FALSE;
for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
ctx->Texture.Proxy1D->Image[i] = _mesa_alloc_texture_image();
out_of_memory = GL_TRUE;
}
}
+ ctx->Texture.ProxyRect->Image[0] = _mesa_alloc_texture_image();
+ if (!ctx->Texture.ProxyRect->Image[0])
+ out_of_memory = GL_TRUE;
+
if (out_of_memory) {
for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
if (ctx->Texture.Proxy1D->Image[i]) {
_mesa_free_texture_image(ctx->Texture.ProxyCubeMap->Image[i]);
}
}
+ if (ctx->Texture.ProxyRect->Image[0]) {
+ _mesa_free_texture_image(ctx->Texture.ProxyRect->Image[0]);
+ }
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
_mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
_mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
_mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap);
+ _mesa_free_texture_object(NULL, ctx->Texture.ProxyRect);
return GL_FALSE;
}
else {
ASSERT(imports);
ASSERT(imports->other); /* other points to the device driver's context */
- /* misc one-time initializations */
- one_time_init();
+ /* assing imports */
+ ctx->imports = *imports;
/* initialize the exports (Mesa functions called by the window system) */
- _mesa_init_default_exports( &(ctx->exports) );
+ _mesa_init_default_exports( &(ctx->exports) );
+
+ /* misc one-time initializations */
+ one_time_init(ctx);
#if 0
/**
ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS;
ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
+ ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
init_attrib_groups( ctx );
#endif
- if (getenv("MESA_DEBUG"))
- add_debug_flags(getenv("MESA_DEBUG"));
+ if (ctx->imports.getenv(ctx, "MESA_DEBUG"))
+ add_debug_flags(ctx->imports.getenv(ctx, "MESA_DEBUG"));
- if (getenv("MESA_VERBOSE"))
- add_debug_flags(getenv("MESA_VERBOSE"));
+ if (ctx->imports.getenv(ctx, "MESA_VERBOSE"))
+ add_debug_flags(ctx->imports.getenv(ctx, "MESA_VERBOSE"));
return GL_TRUE;
}
GLcontext *share_list,
const __GLimports *imports )
{
- GLcontext *ctx = (GLcontext *) CALLOC( sizeof(GLcontext) );
- if (!ctx) {
+ GLcontext *ctx;
+
+ ASSERT(visual);
+ ASSERT(imports);
+ ASSERT(imports->calloc);
+
+ ctx = (GLcontext *) imports->calloc(NULL, 1, sizeof(GLcontext));
+ if (!ctx)
return NULL;
- }
+
ctx->Driver.CurrentExecPrimitive = 0; /* XXX why is this here??? */
+
if (_mesa_initialize_context(ctx, visual, share_list, imports)) {
return ctx;
}
else {
- FREE(ctx);
+ imports->free(NULL, ctx);
return NULL;
}
}
_mesa_free_texture_object( NULL, ctx->Texture.Proxy2D );
_mesa_free_texture_object( NULL, ctx->Texture.Proxy3D );
_mesa_free_texture_object( NULL, ctx->Texture.ProxyCubeMap );
+ _mesa_free_texture_object( NULL, ctx->Texture.ProxyRect );
/* Free evaluator data */
if (ctx->EvalMap.Map1Vertex3.Points)
_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
{
if (mask & GL_ACCUM_BUFFER_BIT) {
- MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
+ /* OK to memcpy */
+ dst->Accum = src->Accum;
}
if (mask & GL_COLOR_BUFFER_BIT) {
- MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
+ /* OK to memcpy */
+ dst->Color = src->Color;
}
if (mask & GL_CURRENT_BIT) {
- MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
+ /* OK to memcpy */
+ dst->Current = src->Current;
}
if (mask & GL_DEPTH_BUFFER_BIT) {
- MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
+ /* OK to memcpy */
+ dst->Depth = src->Depth;
}
if (mask & GL_ENABLE_BIT) {
/* no op */
}
if (mask & GL_EVAL_BIT) {
- MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
+ /* OK to memcpy */
+ dst->Eval = src->Eval;
}
if (mask & GL_FOG_BIT) {
- MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
+ /* OK to memcpy */
+ dst->Fog = src->Fog;
}
if (mask & GL_HINT_BIT) {
- MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
+ /* OK to memcpy */
+ dst->Hint = src->Hint;
}
if (mask & GL_LIGHTING_BIT) {
- MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
- /* gl_reinit_light_attrib( &dst->Light ); */
+ 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) {
- MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
+ /* OK to memcpy */
+ dst->Line = src->Line;
}
if (mask & GL_LIST_BIT) {
- MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
+ /* OK to memcpy */
+ dst->List = src->List;
}
if (mask & GL_PIXEL_MODE_BIT) {
- MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
+ /* OK to memcpy */
+ dst->Pixel = src->Pixel;
}
if (mask & GL_POINT_BIT) {
- MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
+ /* OK to memcpy */
+ dst->Point = src->Point;
}
if (mask & GL_POLYGON_BIT) {
- MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
+ /* 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.
*/
- int i;
- for (i=0;i<32;i++) {
+ GLuint i;
+ for (i = 0; i < 32; i++) {
dst->PolygonStipple[i] = src->PolygonStipple[i];
}
}
if (mask & GL_SCISSOR_BIT) {
- MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
+ /* OK to memcpy */
+ dst->Scissor = src->Scissor;
}
if (mask & GL_STENCIL_BUFFER_BIT) {
- MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
+ /* OK to memcpy */
+ dst->Stencil = src->Stencil;
}
if (mask & GL_TEXTURE_BIT) {
- MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
+ /* Cannot memcpy because of pointers */
+ _mesa_copy_texture_state(src, dst);
}
if (mask & GL_TRANSFORM_BIT) {
- MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
+ /* OK to memcpy */
+ dst->Transform = src->Transform;
}
if (mask & GL_VIEWPORT_BIT) {
- MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
+ /* 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;
GLframebuffer *readBuffer )
{
if (MESA_VERBOSE)
- fprintf(stderr, "_mesa_make_current2()\n");
+ _mesa_debug(newCtx, "_mesa_make_current2()\n");
/* Check that the context's and framebuffer's visuals are compatible.
* We could do a lot more checking here but this'll catch obvious
newCtx->DrawBuffer = drawBuffer;
newCtx->ReadBuffer = readBuffer;
newCtx->NewState |= _NEW_BUFFERS;
- /* _mesa_update_state( newCtx ); */
+
+ if (drawBuffer->Width == 0 && drawBuffer->Height == 0) {
+ /* get initial window size */
+ GLuint bufWidth, bufHeight;
+
+ /* ask device driver for size of output buffer */
+ (*newCtx->Driver.GetBufferSize)( drawBuffer, &bufWidth, &bufHeight );
+
+ if (drawBuffer->Width == bufWidth && drawBuffer->Height == bufHeight)
+ return; /* size is as expected */
+
+ drawBuffer->Width = bufWidth;
+ drawBuffer->Height = bufHeight;
+
+ newCtx->Driver.ResizeBuffers( drawBuffer );
+ }
+
+ if (readBuffer != drawBuffer &&
+ readBuffer->Width == 0 && readBuffer->Height == 0) {
+ /* get initial window size */
+ GLuint bufWidth, bufHeight;
+
+ /* ask device driver for size of output buffer */
+ (*newCtx->Driver.GetBufferSize)( readBuffer, &bufWidth, &bufHeight );
+
+ if (readBuffer->Width == bufWidth && readBuffer->Height == bufHeight)
+ return; /* size is as expected */
+
+ readBuffer->Width = bufWidth;
+ readBuffer->Height = bufHeight;
+
+ newCtx->Driver.ResizeBuffers( readBuffer );
+ }
}
+ /* This is only for T&L - a bit out of place, or misnamed (BP) */
if (newCtx->Driver.MakeCurrent)
newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
* information.
*/
if (newCtx->FirstTimeCurrent) {
- if (getenv("MESA_INFO")) {
+ if (newCtx->imports.getenv(newCtx, "MESA_INFO")) {
print_info();
}
newCtx->FirstTimeCurrent = GL_FALSE;
*/
void _mesa_problem( const GLcontext *ctx, const char *s )
{
- fprintf( stderr, "Mesa implementation error: %s\n", s );
+ if (ctx) {
+ ctx->imports.fprintf((GLcontext *) ctx, stderr, "Mesa implementation error: %s\n", s);
+#ifdef XF86DRI
+ ctx->imports.fprintf((GLcontext *) ctx, stderr, "Please report to the DRI bug database at dri.sourceforge.net\n");
+#else
+ ctx->imports.fprintf((GLcontext *) ctx, stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
+#endif
+ }
+ else {
+ /* what can we do if we don't have a context???? */
+ fprintf( stderr, "Mesa implementation error: %s\n", s );
#ifdef XF86DRI
- fprintf( stderr, "Please report to the DRI bug database at dri.sourceforge.net\n");
+ fprintf( stderr, "Please report to the DRI bug database at dri.sourceforge.net\n");
#else
- fprintf( stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
+ fprintf( stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
#endif
- (void) ctx;
+ }
}
void
_mesa_error( GLcontext *ctx, GLenum error, const char *where )
{
- const char *debugEnv = getenv("MESA_DEBUG");
+ const char *debugEnv;
GLboolean debug;
+ if (ctx)
+ debugEnv = ctx->imports.getenv(ctx, "MESA_DEBUG");
+ else
+ /* what can we do??? */
+ debugEnv = "";
+
#ifdef DEBUG
if (debugEnv && strstr(debugEnv, "silent"))
debug = GL_FALSE;
/*
- * Call this to report debug information.
+ * Call this to report debug information. Uses stderr.
*/
void
-_mesa_debug( const char *fmtString, ... )
+_mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
{
-#ifdef DEBUG
va_list args;
va_start( args, fmtString );
- (void) vfprintf( stderr, fmtString, args );
+ (void) ctx->imports.fprintf( (__GLcontext *) ctx, stderr, fmtString, args );
+ va_end( args );
+}
+
+
+/*
+ * A wrapper for printf. Uses stdout.
+ */
+void
+_mesa_printf( const GLcontext *ctx, const char *fmtString, ... )
+{
+ va_list args;
+ va_start( args, fmtString );
+ (void) ctx->imports.fprintf( (__GLcontext *) ctx, stdout, fmtString, args );
va_end( args );
-#endif
}
+
void
_mesa_Finish( void )
{