updates from Daniel Borca
[mesa.git] / src / mesa / main / context.c
index 6fc70b545a9786c8e313987cd6382971c537397c..7fa32c601c0871bb44cb209988ab9996fd5e3022 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.169 2002/06/16 01:10:41 brianp Exp $ */
+/* $Id: context.c,v 1.175 2002/07/09 01:22:50 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -49,6 +49,7 @@
 #include "state.h"
 #include "teximage.h"
 #include "texobj.h"
+#include "texstate.h"
 #include "mtypes.h"
 #include "varray.h"
 #include "vpstate.h"
@@ -461,6 +462,8 @@ _mesa_initialize_framebuffer( GLframebuffer *buffer,
    assert(buffer);
    assert(visual);
 
+   BZERO(buffer, sizeof(GLframebuffer));
+
    /* sanity checks */
    if (softwareDepth ) {
       assert(visual->depthBits > 0);
@@ -576,13 +579,14 @@ one_time_init( GLcontext *ctx )
 #endif
       if (ctx->imports.getenv(ctx, "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__)
-      fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
+      _mesa_debug(ctx, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
 #endif
 
       alreadyCalled = GL_TRUE;
@@ -974,7 +978,6 @@ init_attrib_groups( GLcontext *ctx )
    ctx->Color.ColorLogicOpEnabled = GL_FALSE;
    ctx->Color.LogicOp = GL_COPY;
    ctx->Color.DitherFlag = GL_TRUE;
-   ctx->Color.MultiDrawBuffer = GL_FALSE;
 
    /* Current group */
    ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 0.0, 0.0, 0.0, 0.0 );
@@ -1443,11 +1446,12 @@ init_attrib_groups( GLcontext *ctx )
    _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;
@@ -1476,7 +1480,7 @@ init_attrib_groups( GLcontext *ctx )
    ctx->NoDither = ctx->imports.getenv(ctx, "MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
    if (ctx->NoDither) {
       if (ctx->imports.getenv(ctx, "MESA_DEBUG")) {
-         fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
+         _mesa_debug(ctx, "MESA_NO_DITHER set - dithering disabled\n");
       }
       ctx->Color.DitherFlag = GL_FALSE;
    }
@@ -1684,17 +1688,17 @@ _mesa_initialize_context( GLcontext *ctx,
 
    if (visual->doubleBufferMode) {
       ctx->Color.DrawBuffer = GL_BACK;
-      ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
-      ctx->Color.DrawDestMask = BACK_LEFT_BIT;
+      ctx->Color._DriverDrawBuffer = GL_BACK_LEFT;
+      ctx->Color._DrawDestMask = BACK_LEFT_BIT;
       ctx->Pixel.ReadBuffer = GL_BACK;
-      ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
+      ctx->Pixel._DriverReadBuffer = GL_BACK_LEFT;
    }
    else {
       ctx->Color.DrawBuffer = GL_FRONT;
-      ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
-      ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
+      ctx->Color._DriverDrawBuffer = GL_FRONT_LEFT;
+      ctx->Color._DrawDestMask = FRONT_LEFT_BIT;
       ctx->Pixel.ReadBuffer = GL_FRONT;
-      ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
+      ctx->Pixel._DriverReadBuffer = GL_FRONT_LEFT;
    }
 
    if (!alloc_proxy_textures(ctx)) {
@@ -1711,6 +1715,8 @@ _mesa_initialize_context( GLcontext *ctx,
    _glapi_add_entrypoint("glCompressedTexSubImage2DARB", 558);
    _glapi_add_entrypoint("glCompressedTexSubImage1DARB", 559);
    _glapi_add_entrypoint("glGetCompressedTexImageARB", 560);
+   /* XXX we should add a bunch of new functions here */
+
 
    /* 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
@@ -1978,72 +1984,104 @@ void
 _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;
@@ -2053,28 +2091,28 @@ _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
 
 static void print_info( void )
 {
-   fprintf(stderr, "Mesa GL_VERSION = %s\n",
+   _mesa_debug(NULL, "Mesa GL_VERSION = %s\n",
           (char *) _mesa_GetString(GL_VERSION));
-   fprintf(stderr, "Mesa GL_RENDERER = %s\n",
+   _mesa_debug(NULL, "Mesa GL_RENDERER = %s\n",
           (char *) _mesa_GetString(GL_RENDERER));
-   fprintf(stderr, "Mesa GL_VENDOR = %s\n",
+   _mesa_debug(NULL, "Mesa GL_VENDOR = %s\n",
           (char *) _mesa_GetString(GL_VENDOR));
-   fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n",
+   _mesa_debug(NULL, "Mesa GL_EXTENSIONS = %s\n",
           (char *) _mesa_GetString(GL_EXTENSIONS));
 #if defined(THREADS)
-   fprintf(stderr, "Mesa thread-safe: YES\n");
+   _mesa_debug(NULL, "Mesa thread-safe: YES\n");
 #else
-   fprintf(stderr, "Mesa thread-safe: NO\n");
+   _mesa_debug(NULL, "Mesa thread-safe: NO\n");
 #endif
 #if defined(USE_X86_ASM)
-   fprintf(stderr, "Mesa x86-optimized: YES\n");
+   _mesa_debug(NULL, "Mesa x86-optimized: YES\n");
 #else
-   fprintf(stderr, "Mesa x86-optimized: NO\n");
+   _mesa_debug(NULL, "Mesa x86-optimized: NO\n");
 #endif
 #if defined(USE_SPARC_ASM)
-   fprintf(stderr, "Mesa sparc-optimized: YES\n");
+   _mesa_debug(NULL, "Mesa sparc-optimized: YES\n");
 #else
-   fprintf(stderr, "Mesa sparc-optimized: NO\n");
+   _mesa_debug(NULL, "Mesa sparc-optimized: NO\n");
 #endif
 }
 
@@ -2134,7 +2172,39 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
         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) */
@@ -2202,112 +2272,12 @@ _mesa_get_dispatch(GLcontext *ctx)
 
 
 /*
- * This function is called when the Mesa user has stumbled into a code
- * path which may not be implemented fully or correctly.
- */
-void _mesa_problem( const GLcontext *ctx, const char *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");
-#else
-      fprintf( stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" );
-#endif
-   }
-}
-
-
-
-/*
- * This is called to inform the user that he or she has tried to do
- * something illogical or if there's likely a bug in their program
- * (like enabled depth testing without a depth buffer).
- */
-void
-_mesa_warning( const GLcontext *ctx, const char *s )
-{
-   (*ctx->imports.warning)((__GLcontext *) ctx, (char *) s);
-}
-
-
-
-/*
- * This is Mesa's error handler.  Normally, all that's done is the updating
- * of the current error value.  If Mesa is compiled with -DDEBUG or if the
- * environment variable "MESA_DEBUG" is defined then a real error message
- * is printed to stderr.
- * Input:  ctx - the GL context
- *         error - the error value
- *         where - usually the name of function where error was detected
+ * Record the given error code and call the driver's Error function if defined.
+ * This is called via _mesa_error().
  */
 void
-_mesa_error( GLcontext *ctx, GLenum error, const char *where )
+_mesa_record_error( GLcontext *ctx, GLenum error )
 {
-   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;
-   else
-      debug = GL_TRUE;
-#else
-   if (debugEnv)
-      debug = GL_TRUE;
-   else
-      debug = GL_FALSE;
-#endif
-
-   if (debug) {
-      const char *errstr;
-      switch (error) {
-        case GL_NO_ERROR:
-           errstr = "GL_NO_ERROR";
-           break;
-        case GL_INVALID_VALUE:
-           errstr = "GL_INVALID_VALUE";
-           break;
-        case GL_INVALID_ENUM:
-           errstr = "GL_INVALID_ENUM";
-           break;
-        case GL_INVALID_OPERATION:
-           errstr = "GL_INVALID_OPERATION";
-           break;
-        case GL_STACK_OVERFLOW:
-           errstr = "GL_STACK_OVERFLOW";
-           break;
-        case GL_STACK_UNDERFLOW:
-           errstr = "GL_STACK_UNDERFLOW";
-           break;
-        case GL_OUT_OF_MEMORY:
-           errstr = "GL_OUT_OF_MEMORY";
-           break;
-         case GL_TABLE_TOO_LARGE:
-            errstr = "GL_TABLE_TOO_LARGE";
-            break;
-        default:
-           errstr = "unknown";
-           break;
-      }
-      fprintf(stderr, "Mesa user error: %s in %s\n", errstr, where);
-   }
-
    if (!ctx)
       return;
 
@@ -2322,33 +2292,6 @@ _mesa_error( GLcontext *ctx, GLenum error, const char *where )
 }
 
 
-/*
- * Call this to report debug information.  Uses stderr.
- */
-void
-_mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
-{
-   va_list args;
-   va_start( args, fmtString );  
-   (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 );
-}
-
-
-
 void
 _mesa_Finish( void )
 {