osmesa.c revision 2db44ffe9d591b0686755e2128ae9a6a1611f2a5
1/* $Id: osmesa.c,v 1.57 2001/06/14 18:30:14 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * Off-Screen Mesa rendering / Rendering into client memory space
30 *
31 * Note on thread safety:  this driver is thread safe.  All
32 * functions are reentrant.  The notion of current context is
33 * managed by the core _mesa_make_current() and _mesa_get_current_context()
34 * functions.  Those functions are thread-safe.
35 */
36
37
38#include "glheader.h"
39#include "GL/osmesa.h"
40#include "context.h"
41#include "colormac.h"
42#include "depth.h"
43#include "extensions.h"
44#include "macros.h"
45#include "matrix.h"
46#include "mem.h"
47#include "mmath.h"
48#include "mtypes.h"
49#include "texformat.h"
50#include "texstore.h"
51#include "array_cache/acache.h"
52#include "swrast/swrast.h"
53#include "swrast_setup/swrast_setup.h"
54#include "swrast/s_context.h"
55#include "swrast/s_depth.h"
56#include "swrast/s_lines.h"
57#include "swrast/s_triangle.h"
58#include "swrast/s_trispan.h"
59#include "tnl/tnl.h"
60#include "tnl/t_context.h"
61#include "tnl/t_pipeline.h"
62
63
64
65/*
66 * This is the OS/Mesa context struct.
67 * Notice how it includes a GLcontext.  By doing this we're mimicking
68 * C++ inheritance/derivation.
69 * Later, we can cast a GLcontext pointer into an OSMesaContext pointer
70 * or vice versa.
71 */
72struct osmesa_context {
73   GLcontext gl_ctx;		/* The core GL/Mesa context */
74   GLvisual *gl_visual;		/* Describes the buffers */
75   GLframebuffer *gl_buffer;	/* Depth, stencil, accum, etc buffers */
76   GLenum format;		/* either GL_RGBA or GL_COLOR_INDEX */
77   void *buffer;		/* the image buffer */
78   GLint width, height;		/* size of image buffer */
79   GLint rowlength;		/* number of pixels per row */
80   GLint userRowLength;		/* user-specified number of pixels per row */
81   GLint rshift, gshift;	/* bit shifts for RGBA formats */
82   GLint bshift, ashift;
83   GLint rInd, gInd, bInd, aInd;/* index offsets for RGBA formats */
84   GLchan *rowaddr[MAX_HEIGHT];	/* address of first pixel in each image row */
85   GLboolean yup;		/* TRUE  -> Y increases upward */
86				/* FALSE -> Y increases downward */
87};
88
89
90
91/* A forward declaration: */
92static void osmesa_update_state( GLcontext *ctx, GLuint newstate );
93static void osmesa_register_swrast_functions( GLcontext *ctx );
94
95
96
97#define OSMESA_CONTEXT(ctx)  ((OSMesaContext) (ctx->DriverCtx))
98
99
100
101/**********************************************************************/
102/*****                    Public Functions                        *****/
103/**********************************************************************/
104
105
106/*
107 * Create an Off-Screen Mesa rendering context.  The only attribute needed is
108 * an RGBA vs Color-Index mode flag.
109 *
110 * Input:  format - either GL_RGBA or GL_COLOR_INDEX
111 *         sharelist - specifies another OSMesaContext with which to share
112 *                     display lists.  NULL indicates no sharing.
113 * Return:  an OSMesaContext or 0 if error
114 */
115OSMesaContext GLAPIENTRY
116OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
117{
118   return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
119                                 8, 16, sharelist);
120}
121
122
123
124/*
125 * New in Mesa 3.5
126 *
127 * Create context and specify size of ancillary buffers.
128 */
129OSMesaContext GLAPIENTRY
130OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
131                        GLint accumBits, OSMesaContext sharelist )
132{
133   OSMesaContext osmesa;
134   GLint rshift, gshift, bshift, ashift;
135   GLint rind, gind, bind, aind;
136   GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
137   GLboolean rgbmode;
138   GLboolean swalpha;
139   const GLuint i4 = 1;
140   const GLubyte *i1 = (GLubyte *) &i4;
141   const GLint little_endian = *i1;
142
143   swalpha = GL_FALSE;
144   rind = gind = bind = aind = 0;
145   if (format==OSMESA_COLOR_INDEX) {
146      indexBits = 8;
147      rshift = gshift = bshift = ashift = 0;
148      rgbmode = GL_FALSE;
149   }
150   else if (format==OSMESA_RGBA) {
151      indexBits = 0;
152      redBits = CHAN_BITS;
153      greenBits = CHAN_BITS;
154      blueBits = CHAN_BITS;
155      alphaBits = CHAN_BITS;
156      rind = 0;
157      gind = 1;
158      bind = 2;
159      aind = 3;
160      if (little_endian) {
161         rshift = 0;
162         gshift = 8;
163         bshift = 16;
164         ashift = 24;
165      }
166      else {
167         rshift = 24;
168         gshift = 16;
169         bshift = 8;
170         ashift = 0;
171      }
172      rgbmode = GL_TRUE;
173   }
174   else if (format==OSMESA_BGRA) {
175      indexBits = 0;
176      redBits = CHAN_BITS;
177      greenBits = CHAN_BITS;
178      blueBits = CHAN_BITS;
179      alphaBits = CHAN_BITS;
180      rind = 2;
181      gind = 1;
182      bind = 0;
183      aind = 3;
184      if (little_endian) {
185         ashift = 0;
186         rshift = 8;
187         gshift = 16;
188         bshift = 24;
189      }
190      else {
191         bshift = 24;
192         gshift = 16;
193         rshift = 8;
194         ashift = 0;
195      }
196      rgbmode = GL_TRUE;
197   }
198   else if (format==OSMESA_ARGB) {
199      indexBits = 0;
200      redBits = CHAN_BITS;
201      greenBits = CHAN_BITS;
202      blueBits = CHAN_BITS;
203      alphaBits = CHAN_BITS;
204      rind = 1;
205      gind = 2;
206      bind = 3;
207      aind = 0;
208      if (little_endian) {
209         bshift = 0;
210         gshift = 8;
211         rshift = 16;
212         ashift = 24;
213      }
214      else {
215         ashift = 24;
216         rshift = 16;
217         gshift = 8;
218         bshift = 0;
219      }
220      rgbmode = GL_TRUE;
221   }
222   else if (format==OSMESA_RGB) {
223      indexBits = 0;
224      redBits = CHAN_BITS;
225      greenBits = CHAN_BITS;
226      blueBits = CHAN_BITS;
227      alphaBits = 0;
228      bshift = 0;
229      gshift = 8;
230      rshift = 16;
231      ashift = 24;
232      rind = 0;
233      gind = 1;
234      bind = 2;
235      rgbmode = GL_TRUE;
236      swalpha = GL_TRUE;
237   }
238   else if (format==OSMESA_BGR) {
239      indexBits = 0;
240      redBits = CHAN_BITS;
241      greenBits = CHAN_BITS;
242      blueBits = CHAN_BITS;
243      alphaBits = 0;
244      bshift = 0;
245      gshift = 8;
246      rshift = 16;
247      ashift = 24;
248      rind = 2;
249      gind = 1;
250      bind = 0;
251      rgbmode = GL_TRUE;
252      swalpha = GL_TRUE;
253   }
254   else {
255      return NULL;
256   }
257
258
259   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
260   if (osmesa) {
261      osmesa->gl_visual = _mesa_create_visual( rgbmode,
262                                               GL_FALSE,    /* double buffer */
263                                               GL_FALSE,    /* stereo */
264                                               redBits,
265                                               greenBits,
266                                               blueBits,
267                                               alphaBits,
268                                               indexBits,
269                                               depthBits,
270                                               stencilBits,
271                                               accumBits,
272                                               accumBits,
273                                               accumBits,
274                                               alphaBits ? accumBits : 0,
275                                               1            /* num samples */
276                                               );
277      if (!osmesa->gl_visual) {
278         FREE(osmesa);
279         return NULL;
280      }
281
282      if (!_mesa_initialize_context(&osmesa->gl_ctx,
283                                    osmesa->gl_visual,
284                                    sharelist ? &sharelist->gl_ctx
285                                              : (GLcontext *) NULL,
286                                    (void *) osmesa, GL_TRUE )) {
287         _mesa_destroy_visual( osmesa->gl_visual );
288         FREE(osmesa);
289         return NULL;
290      }
291
292      _mesa_enable_sw_extensions(&(osmesa->gl_ctx));
293
294      osmesa->gl_buffer = _mesa_create_framebuffer( osmesa->gl_visual,
295                                          osmesa->gl_visual->depthBits > 0,
296                                          osmesa->gl_visual->stencilBits > 0,
297                                          osmesa->gl_visual->accumRedBits > 0,
298                                          swalpha );
299
300      if (!osmesa->gl_buffer) {
301         _mesa_destroy_visual( osmesa->gl_visual );
302         _mesa_free_context_data( &osmesa->gl_ctx );
303         FREE(osmesa);
304         return NULL;
305      }
306      osmesa->format = format;
307      osmesa->buffer = NULL;
308      osmesa->width = 0;
309      osmesa->height = 0;
310      osmesa->userRowLength = 0;
311      osmesa->rowlength = 0;
312      osmesa->yup = GL_TRUE;
313      osmesa->rshift = rshift;
314      osmesa->gshift = gshift;
315      osmesa->bshift = bshift;
316      osmesa->ashift = ashift;
317      osmesa->rInd = rind;
318      osmesa->gInd = gind;
319      osmesa->bInd = bind;
320      osmesa->aInd = aind;
321
322
323      /* Initialize the software rasterizer and helper modules.
324       */
325      {
326	 GLcontext *ctx = &osmesa->gl_ctx;
327
328	 _swrast_CreateContext( ctx );
329	 _ac_CreateContext( ctx );
330	 _tnl_CreateContext( ctx );
331	 _swsetup_CreateContext( ctx );
332
333	 osmesa_register_swrast_functions( ctx );
334      }
335   }
336   return osmesa;
337}
338
339
340
341
342/*
343 * Destroy an Off-Screen Mesa rendering context.
344 *
345 * Input:  ctx - the context to destroy
346 */
347void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
348{
349   if (ctx) {
350      _swsetup_DestroyContext( &ctx->gl_ctx );
351      _tnl_DestroyContext( &ctx->gl_ctx );
352      _ac_DestroyContext( &ctx->gl_ctx );
353      _swrast_DestroyContext( &ctx->gl_ctx );
354
355      _mesa_destroy_visual( ctx->gl_visual );
356      _mesa_destroy_framebuffer( ctx->gl_buffer );
357      _mesa_free_context_data( &ctx->gl_ctx );
358      FREE( ctx );
359   }
360}
361
362
363
364/*
365 * Recompute the values of the context's rowaddr array.
366 */
367static void compute_row_addresses( OSMesaContext ctx )
368{
369   GLint bytesPerPixel, bytesPerRow, i;
370   GLubyte *origin = (GLubyte *) ctx->buffer;
371
372   if (ctx->format == OSMESA_COLOR_INDEX) {
373      /* CI mode */
374      bytesPerPixel = 1 * sizeof(GLchan);
375   }
376   else if ((ctx->format == OSMESA_RGB) || (ctx->format == OSMESA_BGR)) {
377      /* RGB mode */
378      bytesPerPixel = 3 * sizeof(GLchan);
379   }
380   else {
381      /* RGBA mode */
382      bytesPerPixel = 4 * sizeof(GLchan);
383   }
384
385   bytesPerRow = ctx->rowlength * bytesPerPixel;
386
387   if (ctx->yup) {
388      /* Y=0 is bottom line of window */
389      for (i = 0; i < MAX_HEIGHT; i++) {
390         ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + i * bytesPerRow);
391      }
392   }
393   else {
394      /* Y=0 is top line of window */
395      for (i = 0; i < MAX_HEIGHT; i++) {
396         GLint j = ctx->height - i - 1;
397         ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + j * bytesPerRow);
398      }
399   }
400}
401
402
403/*
404 * Bind an OSMesaContext to an image buffer.  The image buffer is just a
405 * block of memory which the client provides.  Its size must be at least
406 * as large as width*height*sizeof(type).  Its address should be a multiple
407 * of 4 if using RGBA mode.
408 *
409 * Image data is stored in the order of glDrawPixels:  row-major order
410 * with the lower-left image pixel stored in the first array position
411 * (ie. bottom-to-top).
412 *
413 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
414 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
415 * value.  If the context is in color indexed mode, each pixel will be
416 * stored as a 1-byte value.
417 *
418 * If the context's viewport hasn't been initialized yet, it will now be
419 * initialized to (0,0,width,height).
420 *
421 * Input:  ctx - the rendering context
422 *         buffer - the image buffer memory
423 *         type - data type for pixel components, only GL_UNSIGNED_BYTE
424 *                supported now
425 *         width, height - size of image buffer in pixels, at least 1
426 * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
427 *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
428 *          width>internal limit or height>internal limit.
429 */
430GLboolean GLAPIENTRY
431OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
432                   GLsizei width, GLsizei height )
433{
434   if (!ctx || !buffer || type != CHAN_TYPE ||
435       width < 1 || height < 1 ||
436       width > MAX_WIDTH || height > MAX_HEIGHT) {
437      return GL_FALSE;
438   }
439
440   osmesa_update_state( &ctx->gl_ctx, 0 );
441   _mesa_make_current( &ctx->gl_ctx, ctx->gl_buffer );
442
443   ctx->buffer = buffer;
444   ctx->width = width;
445   ctx->height = height;
446   if (ctx->userRowLength)
447      ctx->rowlength = ctx->userRowLength;
448   else
449      ctx->rowlength = width;
450
451   compute_row_addresses( ctx );
452
453   /* init viewport */
454   if (ctx->gl_ctx.Viewport.Width==0) {
455      /* initialize viewport and scissor box to buffer size */
456      _mesa_Viewport( 0, 0, width, height );
457      ctx->gl_ctx.Scissor.Width = width;
458      ctx->gl_ctx.Scissor.Height = height;
459   }
460
461   return GL_TRUE;
462}
463
464
465
466OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
467{
468   GLcontext *ctx = _mesa_get_current_context();
469   if (ctx)
470      return (OSMesaContext) ctx;
471   else
472      return NULL;
473}
474
475
476
477void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
478{
479   OSMesaContext ctx = OSMesaGetCurrentContext();
480
481   switch (pname) {
482      case OSMESA_ROW_LENGTH:
483         if (value<0) {
484            _mesa_error( &ctx->gl_ctx, GL_INVALID_VALUE,
485                      "OSMesaPixelStore(value)" );
486            return;
487         }
488         ctx->userRowLength = value;
489         ctx->rowlength = value;
490         break;
491      case OSMESA_Y_UP:
492         ctx->yup = value ? GL_TRUE : GL_FALSE;
493         break;
494      default:
495         _mesa_error( &ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
496         return;
497   }
498
499   compute_row_addresses( ctx );
500}
501
502
503void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
504{
505   OSMesaContext ctx = OSMesaGetCurrentContext();
506
507   switch (pname) {
508      case OSMESA_WIDTH:
509         *value = ctx->width;
510         return;
511      case OSMESA_HEIGHT:
512         *value = ctx->height;
513         return;
514      case OSMESA_FORMAT:
515         *value = ctx->format;
516         return;
517      case OSMESA_TYPE:
518         *value = CHAN_TYPE;
519         return;
520      case OSMESA_ROW_LENGTH:
521         *value = ctx->rowlength;
522         return;
523      case OSMESA_Y_UP:
524         *value = ctx->yup;
525         return;
526      default:
527         _mesa_error(&ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
528         return;
529   }
530}
531
532/*
533 * Return the depth buffer associated with an OSMesa context.
534 * Input:  c - the OSMesa context
535 * Output:  width, height - size of buffer in pixels
536 *          bytesPerValue - bytes per depth value (2 or 4)
537 *          buffer - pointer to depth buffer values
538 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
539 */
540GLboolean GLAPIENTRY
541OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
542                      GLint *bytesPerValue, void **buffer )
543{
544   if ((!c->gl_buffer) || (!c->gl_buffer->DepthBuffer)) {
545      *width = 0;
546      *height = 0;
547      *bytesPerValue = 0;
548      *buffer = 0;
549      return GL_FALSE;
550   }
551   else {
552      *width = c->gl_buffer->Width;
553      *height = c->gl_buffer->Height;
554      if (c->gl_visual->depthBits <= 16)
555         *bytesPerValue = sizeof(GLushort);
556      else
557         *bytesPerValue = sizeof(GLuint);
558      *buffer = c->gl_buffer->DepthBuffer;
559      return GL_TRUE;
560   }
561}
562
563/*
564 * Return the color buffer associated with an OSMesa context.
565 * Input:  c - the OSMesa context
566 * Output:  width, height - size of buffer in pixels
567 *          format - the pixel format (OSMESA_FORMAT)
568 *          buffer - pointer to color buffer values
569 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
570 */
571GLboolean GLAPIENTRY
572OSMesaGetColorBuffer( OSMesaContext c, GLint *width,
573                      GLint *height, GLint *format, void **buffer )
574{
575   if (!c->buffer) {
576      *width = 0;
577      *height = 0;
578      *format = 0;
579      *buffer = 0;
580      return GL_FALSE;
581   }
582   else {
583      *width = c->width;
584      *height = c->height;
585      *format = c->format;
586      *buffer = c->buffer;
587      return GL_TRUE;
588   }
589}
590
591/**********************************************************************/
592/*** Device Driver Functions                                        ***/
593/**********************************************************************/
594
595
596/*
597 * Useful macros:
598 */
599
600#define PACK_RGBA(DST, R, G, B, A)	\
601do {					\
602   (DST)[osmesa->rInd] = R;		\
603   (DST)[osmesa->gInd] = G;		\
604   (DST)[osmesa->bInd] = B;		\
605   (DST)[osmesa->aInd] = A;		\
606} while (0)
607
608#define PACK_RGB(DST, R, G, B)  \
609do {				\
610   (DST)[0] = R;		\
611   (DST)[1] = G;		\
612   (DST)[2] = B;		\
613} while (0)
614
615#define PACK_BGR(DST, R, G, B)  \
616do {				\
617   (DST)[0] = B;		\
618   (DST)[1] = G;		\
619   (DST)[2] = R;		\
620} while (0)
621
622
623#define UNPACK_RED(P)      ( (P)[osmesa->rInd] )
624#define UNPACK_GREEN(P)    ( (P)[osmesa->gInd] )
625#define UNPACK_BLUE(P)     ( (P)[osmesa->bInd] )
626#define UNPACK_ALPHA(P)    ( (P)[osmesa->aInd] )
627
628
629#define PIXELADDR1(X,Y)  (osmesa->rowaddr[Y] + (X))
630#define PIXELADDR3(X,Y)  (osmesa->rowaddr[Y] + 3 * (X))
631#define PIXELADDR4(X,Y)  (osmesa->rowaddr[Y] + 4 * (X))
632
633
634
635static GLboolean set_draw_buffer( GLcontext *ctx, GLenum mode )
636{
637   (void) ctx;
638   if (mode==GL_FRONT_LEFT) {
639      return GL_TRUE;
640   }
641   else {
642      return GL_FALSE;
643   }
644}
645
646
647static void set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode )
648{
649   /* separate read buffer not supported */
650   ASSERT(buffer == ctx->DrawBuffer);
651   ASSERT(mode == GL_FRONT_LEFT);
652}
653
654
655static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
656		   GLint x, GLint y, GLint width, GLint height )
657{
658   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
659   const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
660
661   /* sanity check - we only have a front-left buffer */
662   ASSERT((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT)) == 0);
663   if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
664      if (mask & DD_FRONT_LEFT_BIT) {
665	 if (osmesa->format == OSMESA_COLOR_INDEX) {
666	    if (all) {
667	       /* Clear whole CI buffer */
668#if CHAN_TYPE == GL_UNSIGNED_BYTE
669	       MEMSET(osmesa->buffer, ctx->Color.ClearIndex,
670		      osmesa->rowlength * osmesa->height);
671#else
672	       const GLint n = osmesa->rowlength * osmesa->height;
673	       GLchan *buffer = (GLchan *) osmesa->buffer;
674	       GLint i;
675	       for (i = 0; i < n; i ++) {
676		  buffer[i] = ctx->Color.ClearIndex;
677	       }
678#endif
679	    }
680	    else {
681	       /* Clear part of CI buffer */
682	       const GLchan clearIndex = (GLchan) ctx->Color.ClearIndex;
683	       GLint i, j;
684	       for (i = 0; i < height; i++) {
685		  GLchan *ptr1 = PIXELADDR1(x, (y + i));
686		  for (j = 0; j < width; j++) {
687		     *ptr1++ = clearIndex;
688		  }
689	       }
690	    }
691	 }
692	 else if (osmesa->format == OSMESA_RGB) {
693	    const GLchan r = ctx->Color.ClearColor[0];
694	    const GLchan g = ctx->Color.ClearColor[1];
695	    const GLchan b = ctx->Color.ClearColor[2];
696	    if (all) {
697	       /* Clear whole RGB buffer */
698	       GLuint n = osmesa->rowlength * osmesa->height;
699	       GLchan *ptr3 = (GLchan *) osmesa->buffer;
700	       GLuint i;
701	       for (i = 0; i < n; i++) {
702		  PACK_RGB(ptr3, r, g, b);
703		  ptr3 += 3;
704	       }
705	    }
706	    else {
707	       /* Clear part of RGB buffer */
708	       GLint i, j;
709	       for (i = 0; i < height; i++) {
710		  GLchan *ptr3 = PIXELADDR3(x, (y + i));
711		  for (j = 0; j < width; j++) {
712		     PACK_RGB(ptr3, r, g, b);
713		     ptr3 += 3;
714		  }
715	       }
716	    }
717	 }
718	 else if (osmesa->format == OSMESA_BGR) {
719	    const GLchan r = ctx->Color.ClearColor[0];
720	    const GLchan g = ctx->Color.ClearColor[1];
721	    const GLchan b = ctx->Color.ClearColor[2];
722	    if (all) {
723	       /* Clear whole RGB buffer */
724	       const GLint n = osmesa->rowlength * osmesa->height;
725	       GLchan *ptr3 = (GLchan *) osmesa->buffer;
726	       GLint i;
727	       for (i = 0; i < n; i++) {
728		  PACK_BGR(ptr3, r, g, b);
729		  ptr3 += 3;
730	       }
731	    }
732	    else {
733	       /* Clear part of RGB buffer */
734	       GLint i, j;
735	       for (i = 0; i < height; i++) {
736		  GLchan *ptr3 = PIXELADDR3(x, (y + i));
737		  for (j = 0; j < width; j++) {
738		     PACK_BGR(ptr3, r, g, b);
739		     ptr3 += 3;
740		  }
741	       }
742	    }
743	 }
744	 else {
745#if CHAN_TYPE == GL_UNSIGNED_BYTE
746	    /* 4-byte pixel value */
747	    GLuint clearPixel;
748	    GLchan *clr = (GLchan *) &clearPixel;
749	    clr[osmesa->rInd] = ctx->Color.ClearColor[0];
750	    clr[osmesa->gInd] = ctx->Color.ClearColor[1];
751	    clr[osmesa->bInd] = ctx->Color.ClearColor[2];
752	    clr[osmesa->aInd] = ctx->Color.ClearColor[3];
753	    if (all) {
754	       /* Clear whole RGBA buffer */
755	       const GLuint n = osmesa->rowlength * osmesa->height;
756	       GLuint *ptr4 = (GLuint *) osmesa->buffer;
757	       GLuint i;
758	       if (clearPixel) {
759		  for (i = 0; i < n; i++) {
760		     *ptr4++ = clearPixel;
761		  }
762	       }
763	       else {
764		  BZERO(ptr4, n * sizeof(GLuint));
765	       }
766	    }
767	    else {
768	       /* Clear part of RGBA buffer */
769	       GLint i, j;
770	       for (i = 0; i < height; i++) {
771		  GLuint *ptr4 = (GLuint *) PIXELADDR4(x, (y + i));
772		  for (j = 0; j < width; j++) {
773		     *ptr4++ = clearPixel;
774		  }
775	       }
776	    }
777#else
778	    const GLchan r = ctx->Color.ClearColor[0];
779	    const GLchan g = ctx->Color.ClearColor[1];
780	    const GLchan b = ctx->Color.ClearColor[2];
781	    const GLchan a = ctx->Color.ClearColor[3];
782	    if (all) {
783	       /* Clear whole RGBA buffer */
784	       const GLuint n = osmesa->rowlength * osmesa->height;
785	       GLchan *p = (GLchan *) osmesa->buffer;
786	       GLuint i;
787	       for (i = 0; i < n; i++) {
788		  PACK_RGBA(p, r, g, b, a);
789		  p += 4;
790	       }
791	    }
792	    else {
793	       /* Clear part of RGBA buffer */
794	       GLint i, j;
795	       for (i = 0; i < height; i++) {
796		  GLchan *p = PIXELADDR4(x, (y + i));
797		  for (j = 0; j < width; j++) {
798		     PACK_RGBA(p, r, g, b, a);
799		     p += 4;
800		  }
801	       }
802	    }
803
804#endif
805	 }
806	 mask &= ~DD_FRONT_LEFT_BIT;
807      }
808   }
809
810   if (mask)
811      _swrast_Clear( ctx, mask, all, x, y, width, height );
812}
813
814
815
816static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
817{
818   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
819   *width = osmesa->width;
820   *height = osmesa->height;
821}
822
823
824/**********************************************************************/
825/*****        Read/write spans/arrays of RGBA pixels              *****/
826/**********************************************************************/
827
828/* Write RGBA pixels to an RGBA (or permuted) buffer. */
829static void
830write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
831                 CONST GLchan rgba[][4], const GLubyte mask[] )
832{
833   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
834   GLchan *p = PIXELADDR4(x, y);
835   GLuint i;
836   if (mask) {
837      for (i = 0; i < n; i++, p += 4) {
838         if (mask[i]) {
839            PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
840                         rgba[i][BCOMP], rgba[i][ACOMP]);
841         }
842      }
843   }
844   else {
845      for (i = 0; i < n; i++, p += 4) {
846         PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
847                      rgba[i][BCOMP], rgba[i][ACOMP]);
848      }
849   }
850}
851
852
853/* Write RGBA pixels to an RGBA buffer.  This is the fastest span-writer. */
854static void
855write_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
856                      CONST GLchan rgba[][4], const GLubyte mask[] )
857{
858   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
859   GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
860   const GLuint *rgba4 = (const GLuint *) rgba;
861   GLuint i;
862   ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE);
863   if (mask) {
864      for (i = 0; i < n; i++) {
865         if (mask[i]) {
866            ptr4[i] = rgba4[i];
867         }
868      }
869   }
870   else {
871      MEMCPY( ptr4, rgba4, n * 4 );
872   }
873}
874
875
876/* Write RGB pixels to an RGBA (or permuted) buffer. */
877static void
878write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
879                CONST GLchan rgb[][3], const GLubyte mask[] )
880{
881   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
882   GLchan *p = PIXELADDR4(x, y);
883   GLuint i;
884   if (mask) {
885      for (i = 0; i < n; i++, p+=4) {
886         if (mask[i]) {
887            PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
888         }
889      }
890   }
891   else {
892      for (i = 0; i < n; i++, p+=4) {
893         PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
894      }
895   }
896}
897
898
899
900static void
901write_monocolor_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
902                      const GLchan color[4], const GLubyte mask[] )
903{
904   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
905   GLchan *p = PIXELADDR4(x, y);
906   GLuint i;
907   for (i = 0; i < n; i++, p += 4) {
908      if (mask[i]) {
909         PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
910      }
911   }
912}
913
914
915
916static void
917write_rgba_pixels( const GLcontext *ctx, GLuint n,
918                   const GLint x[], const GLint y[],
919                   CONST GLchan rgba[][4], const GLubyte mask[] )
920{
921   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
922   GLuint i;
923   for (i = 0; i < n; i++) {
924      if (mask[i]) {
925         GLchan *p = PIXELADDR4(x[i], y[i]);
926         PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
927                      rgba[i][BCOMP], rgba[i][ACOMP]);
928      }
929   }
930}
931
932
933
934static void
935write_monocolor_pixels( const GLcontext *ctx, GLuint n,
936                        const GLint x[], const GLint y[],
937                        const GLchan color[4], const GLubyte mask[] )
938{
939   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
940   GLuint i;
941   for (i = 0; i < n; i++) {
942      if (mask[i]) {
943         GLchan *p = PIXELADDR4(x[i], y[i]);
944         PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
945      }
946   }
947}
948
949
950static void
951read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
952                GLchan rgba[][4] )
953{
954   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
955   GLuint i;
956   GLchan *p = PIXELADDR4(x, y);
957   for (i = 0; i < n; i++, p += 4) {
958      rgba[i][RCOMP] = UNPACK_RED(p);
959      rgba[i][GCOMP] = UNPACK_GREEN(p);
960      rgba[i][BCOMP] = UNPACK_BLUE(p);
961      rgba[i][ACOMP] = UNPACK_ALPHA(p);
962   }
963}
964
965
966/* Read RGBA pixels from an RGBA buffer */
967static void
968read_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
969                     GLchan rgba[][4] )
970{
971   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
972   GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
973   MEMCPY( rgba, ptr4, n * 4 * sizeof(GLchan) );
974}
975
976
977static void
978read_rgba_pixels( const GLcontext *ctx,
979                  GLuint n, const GLint x[], const GLint y[],
980                  GLchan rgba[][4], const GLubyte mask[] )
981{
982   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
983   GLuint i;
984   for (i = 0; i < n; i++) {
985      if (mask[i]) {
986         const GLchan *p = PIXELADDR4(x[i], y[i]);
987         rgba[i][RCOMP] = UNPACK_RED(p);
988         rgba[i][GCOMP] = UNPACK_GREEN(p);
989         rgba[i][BCOMP] = UNPACK_BLUE(p);
990         rgba[i][ACOMP] = UNPACK_ALPHA(p);
991      }
992   }
993}
994
995/**********************************************************************/
996/*****                3 byte RGB pixel support funcs              *****/
997/**********************************************************************/
998
999/* Write RGBA pixels to an RGB buffer. */
1000static void
1001write_rgba_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1002                     CONST GLchan rgba[][4], const GLubyte mask[] )
1003{
1004   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1005   GLchan *p = PIXELADDR3(x, y);
1006   GLuint i;
1007   if (mask) {
1008      for (i = 0; i < n; i++, p += 3) {
1009         if (mask[i]) {
1010            PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1011         }
1012      }
1013   }
1014   else {
1015      for (i = 0; i < n; i++, p += 3) {
1016         PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1017      }
1018   }
1019}
1020
1021/* Write RGBA pixels to an BGR buffer. */
1022static void
1023write_rgba_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1024                     CONST GLchan rgba[][4], const GLubyte mask[] )
1025{
1026   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1027   GLchan *p = PIXELADDR3(x, y);
1028   GLuint i;
1029   if (mask) {
1030      for (i = 0; i < n; i++, p += 3) {
1031         if (mask[i]) {
1032            PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1033         }
1034      }
1035   }
1036   else {
1037      for (i = 0; i < n; i++, p += 3) {
1038         PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1039      }
1040   }
1041}
1042
1043/* Write RGB pixels to an RGB buffer. */
1044static void
1045write_rgb_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1046                    CONST GLchan rgb[][3], const GLubyte mask[] )
1047{
1048   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1049   GLchan *p = PIXELADDR3(x, y);
1050   GLuint i;
1051   if (mask) {
1052      for (i = 0; i < n; i++, p += 3) {
1053         if (mask[i]) {
1054            PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1055         }
1056      }
1057   }
1058   else {
1059      for (i = 0; i < n; i++, p += 3) {
1060         PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1061      }
1062   }
1063}
1064
1065/* Write RGB pixels to an BGR buffer. */
1066static void
1067write_rgb_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1068                    CONST GLchan rgb[][3], const GLubyte mask[] )
1069{
1070   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1071   GLchan *p = PIXELADDR3(x, y);
1072   GLuint i;
1073   if (mask) {
1074      for (i = 0; i < n; i++, p += 3) {
1075         if (mask[i]) {
1076            PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1077         }
1078      }
1079   }
1080   else {
1081      for (i = 0; i < n; i++, p += 3) {
1082         PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1083      }
1084   }
1085}
1086
1087
1088static void
1089write_monocolor_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1090                          const GLchan color[4], const GLubyte mask[] )
1091{
1092   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1093   GLchan *p = PIXELADDR3(x, y);
1094   GLuint i;
1095   for (i = 0; i < n; i++, p += 3) {
1096      if (mask[i]) {
1097         PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1098      }
1099   }
1100}
1101
1102static void
1103write_monocolor_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1104                          const GLchan color[4], const GLubyte mask[] )
1105{
1106   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1107   GLchan *p = PIXELADDR3(x, y);
1108   GLuint i;
1109   for (i = 0; i < n; i++, p += 3) {
1110      if (mask[i]) {
1111         PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1112      }
1113   }
1114}
1115
1116static void
1117write_rgba_pixels_RGB( const GLcontext *ctx, GLuint n,
1118                       const GLint x[], const GLint y[],
1119                       CONST GLchan rgba[][4], const GLubyte mask[] )
1120{
1121   const OSMesaContext osmesa = (const OSMesaContext) ctx;
1122   GLuint i;
1123   for (i = 0; i < n; i++) {
1124      if (mask[i]) {
1125         GLchan *p = PIXELADDR3(x[i], y[i]);
1126         PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1127      }
1128   }
1129}
1130
1131static void
1132write_rgba_pixels_BGR( const GLcontext *ctx, GLuint n,
1133                       const GLint x[], const GLint y[],
1134                       CONST GLchan rgba[][4], const GLubyte mask[] )
1135{
1136   const OSMesaContext osmesa = (const OSMesaContext) ctx;
1137   GLuint i;
1138   for (i = 0; i < n; i++) {
1139      if (mask[i]) {
1140         GLchan *p = PIXELADDR3(x[i], y[i]);
1141         PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1142      }
1143   }
1144}
1145
1146static void
1147write_monocolor_pixels_RGB( const GLcontext *ctx,
1148                            GLuint n, const GLint x[], const GLint y[],
1149                            const GLchan color[4], const GLubyte mask[] )
1150{
1151   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1152   GLuint i;
1153   for (i = 0; i < n; i++) {
1154      if (mask[i]) {
1155         GLchan *p = PIXELADDR3(x[i], y[i]);
1156         PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1157      }
1158   }
1159}
1160
1161static void
1162write_monocolor_pixels_BGR( const GLcontext *ctx,
1163                            GLuint n, const GLint x[], const GLint y[],
1164                            const GLchan color[4], const GLubyte mask[] )
1165{
1166   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1167   GLuint i;
1168   for (i = 0; i < n; i++) {
1169      if (mask[i]) {
1170         GLchan *p = PIXELADDR3(x[i], y[i]);
1171         PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1172      }
1173   }
1174}
1175
1176static void
1177read_rgba_span3( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1178                 GLchan rgba[][4] )
1179{
1180   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1181   GLuint i;
1182   const GLchan *p = PIXELADDR3(x, y);
1183   for (i = 0; i < n; i++, p += 3) {
1184      rgba[i][RCOMP] = UNPACK_RED(p);
1185      rgba[i][GCOMP] = UNPACK_GREEN(p);
1186      rgba[i][BCOMP] = UNPACK_BLUE(p);
1187      rgba[i][ACOMP] = 255;
1188   }
1189}
1190
1191static void
1192read_rgba_pixels3( const GLcontext *ctx,
1193                   GLuint n, const GLint x[], const GLint y[],
1194                   GLchan rgba[][4], const GLubyte mask[] )
1195{
1196   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1197   GLuint i;
1198   for (i = 0; i < n; i++) {
1199      if (mask[i]) {
1200         const GLchan *p = PIXELADDR3(x[i], y[i]);
1201         rgba[i][RCOMP] = UNPACK_RED(p);
1202         rgba[i][GCOMP] = UNPACK_GREEN(p);
1203         rgba[i][BCOMP] = UNPACK_BLUE(p);
1204         rgba[i][ACOMP] = 255;
1205      }
1206   }
1207}
1208
1209
1210/**********************************************************************/
1211/*****        Read/write spans/arrays of CI pixels                *****/
1212/**********************************************************************/
1213
1214/* Write 32-bit color index to buffer */
1215static void
1216write_index32_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1217                    const GLuint index[], const GLubyte mask[] )
1218{
1219   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1220   GLchan *ptr1 = PIXELADDR1(x, y);
1221   GLuint i;
1222   if (mask) {
1223      for (i=0;i<n;i++,ptr1++) {
1224         if (mask[i]) {
1225            *ptr1 = (GLchan) index[i];
1226         }
1227      }
1228   }
1229   else {
1230      for (i=0;i<n;i++,ptr1++) {
1231         *ptr1 = (GLchan) index[i];
1232      }
1233   }
1234}
1235
1236
1237/* Write 8-bit color index to buffer */
1238static void
1239write_index8_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1240                   const GLubyte index[], const GLubyte mask[] )
1241{
1242   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1243   GLchan *ptr1 = PIXELADDR1(x, y);
1244   GLuint i;
1245   if (mask) {
1246      for (i=0;i<n;i++,ptr1++) {
1247         if (mask[i]) {
1248            *ptr1 = (GLchan) index[i];
1249         }
1250      }
1251   }
1252   else {
1253      MEMCPY(ptr1, index, n * sizeof(GLchan));
1254   }
1255}
1256
1257
1258static void
1259write_monoindex_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1260                      GLuint colorIndex, const GLubyte mask[] )
1261{
1262   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1263   GLchan *ptr1 = PIXELADDR1(x, y);
1264   GLuint i;
1265   for (i=0;i<n;i++,ptr1++) {
1266      if (mask[i]) {
1267         *ptr1 = (GLchan) colorIndex;
1268      }
1269   }
1270}
1271
1272
1273static void
1274write_index_pixels( const GLcontext *ctx,
1275                    GLuint n, const GLint x[], const GLint y[],
1276                    const GLuint index[], const GLubyte mask[] )
1277{
1278   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1279   GLuint i;
1280   for (i=0;i<n;i++) {
1281      if (mask[i]) {
1282         GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1283         *ptr1 = (GLchan) index[i];
1284      }
1285   }
1286}
1287
1288
1289static void
1290write_monoindex_pixels( const GLcontext *ctx,
1291                        GLuint n, const GLint x[], const GLint y[],
1292                        GLuint colorIndex, const GLubyte mask[] )
1293{
1294   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1295   GLuint i;
1296   for (i=0;i<n;i++) {
1297      if (mask[i]) {
1298         GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1299         *ptr1 = (GLchan) colorIndex;
1300      }
1301   }
1302}
1303
1304
1305static void
1306read_index_span( const GLcontext *ctx,
1307                 GLuint n, GLint x, GLint y, GLuint index[] )
1308{
1309   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1310   GLuint i;
1311   const GLchan *ptr1 = (const GLchan *) PIXELADDR1(x, y);
1312   for (i=0;i<n;i++,ptr1++) {
1313      index[i] = (GLuint) *ptr1;
1314   }
1315}
1316
1317
1318static void
1319read_index_pixels( const GLcontext *ctx,
1320                   GLuint n, const GLint x[], const GLint y[],
1321                   GLuint index[], const GLubyte mask[] )
1322{
1323   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1324   GLuint i;
1325   for (i=0;i<n;i++) {
1326      if (mask[i] ) {
1327         const GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1328         index[i] = (GLuint) *ptr1;
1329      }
1330   }
1331}
1332
1333
1334
1335/**********************************************************************/
1336/*****                   Optimized line rendering                 *****/
1337/**********************************************************************/
1338
1339
1340/*
1341 * Draw a flat-shaded, RGB line into an osmesa buffer.
1342 */
1343static void
1344flat_rgba_line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
1345{
1346   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1347   const GLchan *color = vert0->color;
1348
1349#define INTERP_XY 1
1350#define CLIP_HACK 1
1351#define PLOT(X, Y)						\
1352do {								\
1353   GLchan *p = PIXELADDR4(X, Y);				\
1354   PACK_RGBA(p, color[0], color[1], color[2], color[3]);	\
1355} while (0)
1356
1357#ifdef WIN32
1358#include "..\swrast\s_linetemp.h"
1359#else
1360#include "swrast/s_linetemp.h"
1361#endif
1362}
1363
1364
1365/*
1366 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1367 */
1368static void
1369flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
1370{
1371   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1372   const GLchan *color = vert0->color;
1373
1374#define INTERP_XY 1
1375#define INTERP_Z 1
1376#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1377#define CLIP_HACK 1
1378#define PLOT(X, Y)					\
1379do {							\
1380   if (Z < *zPtr) {					\
1381      GLchan *p = PIXELADDR4(X, Y);			\
1382      PACK_RGBA(p, color[RCOMP], color[GCOMP],		\
1383                   color[BCOMP], color[ACOMP]);		\
1384      *zPtr = Z;					\
1385   }							\
1386} while (0)
1387
1388
1389#ifdef WIN32
1390#include "..\swrast\s_linetemp.h"
1391#else
1392#include "swrast/s_linetemp.h"
1393#endif
1394}
1395
1396
1397/*
1398 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1399 * XXX update for GLchan
1400 */
1401static void
1402flat_blend_rgba_line( GLcontext *ctx,
1403                      const SWvertex *vert0, const SWvertex *vert1 )
1404{
1405   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1406   const GLint rshift = osmesa->rshift;
1407   const GLint gshift = osmesa->gshift;
1408   const GLint bshift = osmesa->bshift;
1409   const GLint avalue = vert0->color[3];
1410   const GLint msavalue = 255 - avalue;
1411   const GLint rvalue = vert0->color[0]*avalue;
1412   const GLint gvalue = vert0->color[1]*avalue;
1413   const GLint bvalue = vert0->color[2]*avalue;
1414
1415#define INTERP_XY 1
1416#define CLIP_HACK 1
1417#define PLOT(X,Y)					\
1418   { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);		\
1419     GLuint  pixel = 0;					\
1420     pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1421     pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1422     pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1423     *ptr4 = pixel;					\
1424   }
1425
1426#ifdef WIN32
1427#include "..\swrast\s_linetemp.h"
1428#else
1429#include "swrast/s_linetemp.h"
1430#endif
1431}
1432
1433
1434/*
1435 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1436 * XXX update for GLchan
1437 */
1438static void
1439flat_blend_rgba_z_line( GLcontext *ctx,
1440                        const SWvertex *vert0, const SWvertex *vert1 )
1441{
1442   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1443   const GLint rshift = osmesa->rshift;
1444   const GLint gshift = osmesa->gshift;
1445   const GLint bshift = osmesa->bshift;
1446   const GLint avalue = vert0->color[3];
1447   const GLint msavalue = 256 - avalue;
1448   const GLint rvalue = vert0->color[0]*avalue;
1449   const GLint gvalue = vert0->color[1]*avalue;
1450   const GLint bvalue = vert0->color[2]*avalue;
1451
1452#define INTERP_XY 1
1453#define INTERP_Z 1
1454#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1455#define CLIP_HACK 1
1456#define PLOT(X,Y)							\
1457	if (Z < *zPtr) {						\
1458	   GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);			\
1459	   GLuint  pixel = 0;						\
1460	   pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);	\
1461	   pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);	\
1462	   pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);	\
1463	   *ptr4 = pixel; 						\
1464	}
1465
1466#ifdef WIN32
1467#include "..\swrast\s_linetemp.h"
1468#else
1469#include "swrast/s_linetemp.h"
1470#endif
1471}
1472
1473
1474/*
1475 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1476 * XXX update for GLchan
1477 */
1478static void
1479flat_blend_rgba_z_line_write( GLcontext *ctx,
1480                              const SWvertex *vert0, const SWvertex *vert1 )
1481{
1482   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1483   const GLint rshift = osmesa->rshift;
1484   const GLint gshift = osmesa->gshift;
1485   const GLint bshift = osmesa->bshift;
1486   const GLint avalue = vert0->color[3];
1487   const GLint msavalue = 256 - avalue;
1488   const GLint rvalue = vert0->color[0]*avalue;
1489   const GLint gvalue = vert0->color[1]*avalue;
1490   const GLint bvalue = vert0->color[2]*avalue;
1491
1492#define INTERP_XY 1
1493#define INTERP_Z 1
1494#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1495#define CLIP_HACK 1
1496#define PLOT(X,Y)							\
1497	if (Z < *zPtr) {						\
1498	   GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);			\
1499	   GLuint  pixel = 0;						\
1500	   pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);	\
1501	   pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);	\
1502	   pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);	\
1503	   *ptr4 = pixel;						\
1504	   *zPtr = Z;							\
1505	}
1506
1507#ifdef WIN32
1508#include "..\swrast\s_linetemp.h"
1509#else
1510#include "swrast/s_linetemp.h"
1511#endif
1512}
1513
1514
1515/*
1516 * Analyze context state to see if we can provide a fast line drawing
1517 * function, like those in lines.c.  Otherwise, return NULL.
1518 */
1519static swrast_line_func
1520osmesa_choose_line_function( GLcontext *ctx )
1521{
1522   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1523   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
1524
1525   if (CHAN_BITS != 8)                    return NULL;
1526   if (ctx->RenderMode != GL_RENDER)      return NULL;
1527   if (ctx->Line.SmoothFlag)              return NULL;
1528   if (ctx->Texture._ReallyEnabled)       return NULL;
1529   if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
1530   if (ctx->Line.Width != 1.0F)           return NULL;
1531   if (ctx->Line.StippleFlag)             return NULL;
1532   if (ctx->Line.SmoothFlag)              return NULL;
1533   if (osmesa->format != OSMESA_RGBA &&
1534       osmesa->format != OSMESA_BGRA &&
1535       osmesa->format != OSMESA_ARGB)     return NULL;
1536
1537   if (swrast->_RasterMask==DEPTH_BIT
1538       && ctx->Depth.Func==GL_LESS
1539       && ctx->Depth.Mask==GL_TRUE
1540       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
1541      return flat_rgba_z_line;
1542   }
1543
1544   if (swrast->_RasterMask == 0) {
1545      return flat_rgba_line;
1546   }
1547
1548   if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
1549       && ctx->Depth.Func==GL_LESS
1550       && ctx->Depth.Mask==GL_TRUE
1551       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1552       && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1553       && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1554       && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1555       && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1556       && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1557      return flat_blend_rgba_z_line_write;
1558   }
1559
1560   if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
1561       && ctx->Depth.Func==GL_LESS
1562       && ctx->Depth.Mask==GL_FALSE
1563       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1564       && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1565       && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1566       && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1567       && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1568       && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1569      return flat_blend_rgba_z_line;
1570   }
1571
1572   if (swrast->_RasterMask==BLEND_BIT
1573       && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1574       && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1575       && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1576       && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1577       && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1578      return flat_blend_rgba_line;
1579   }
1580
1581   return NULL;
1582}
1583
1584
1585/**********************************************************************/
1586/*****                 Optimized triangle rendering               *****/
1587/**********************************************************************/
1588
1589
1590/*
1591 * Smooth-shaded, z-less triangle, RGBA color.
1592 */
1593static void smooth_rgba_z_triangle( GLcontext *ctx,
1594				    const SWvertex *v0,
1595                                    const SWvertex *v1,
1596                                    const SWvertex *v2 )
1597{
1598   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1599
1600#define INTERP_Z 1
1601#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1602#define INTERP_RGB 1
1603#define INTERP_ALPHA 1
1604#define RENDER_SPAN( span )					\
1605   GLuint i;							\
1606   GLchan *img = PIXELADDR4(span.x, span.y); 			\
1607   for (i = 0; i < span.count; i++, img += 4) {			\
1608      const GLdepth z = FixedToDepth(span.z);			\
1609      if (z < zRow[i]) {					\
1610         PACK_RGBA(img, FixedToInt(span.red),			\
1611            FixedToInt(span.green), FixedToInt(span.blue),	\
1612            FixedToInt(span.alpha));				\
1613         zRow[i] = z;						\
1614      }								\
1615      span.red += span.redStep;					\
1616      span.green += span.greenStep;				\
1617      span.blue += span.blueStep;				\
1618      span.alpha += span.alphaStep;				\
1619      span.z += span.zStep;					\
1620   }
1621
1622#ifdef WIN32
1623#include "..\swrast\s_tritemp.h"
1624#else
1625#include "swrast/s_tritemp.h"
1626#endif
1627}
1628
1629
1630
1631
1632/*
1633 * Flat-shaded, z-less triangle, RGBA color.
1634 */
1635static void flat_rgba_z_triangle( GLcontext *ctx,
1636				  const SWvertex *v0,
1637                                  const SWvertex *v1,
1638                                  const SWvertex *v2 )
1639{
1640   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1641#define INTERP_Z 1
1642#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1643#define SETUP_CODE						\
1644   GLuint pixel;						\
1645   PACK_RGBA((GLchan *) &pixel, v0->color[0], v0->color[1],	\
1646                                v0->color[2], v0->color[3]);
1647
1648#define RENDER_SPAN( span )				\
1649   GLuint i;						\
1650   GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y);	\
1651   for (i = 0; i < span.count; i++) {			\
1652      const GLdepth z = FixedToDepth(span.z);		\
1653      if (z < zRow[i]) {				\
1654         img[i] = pixel;				\
1655         zRow[i] = z;					\
1656      }							\
1657      span.z += span.zStep;				\
1658   }
1659
1660#ifdef WIN32
1661#include "..\swrast\s_tritemp.h"
1662#else
1663#include "swrast/s_tritemp.h"
1664#endif
1665}
1666
1667
1668
1669/*
1670 * Return pointer to an accelerated triangle function if possible.
1671 */
1672static swrast_tri_func
1673osmesa_choose_triangle_function( GLcontext *ctx )
1674{
1675   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1676   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
1677
1678   if (CHAN_BITS != 8)                  return (swrast_tri_func) NULL;
1679   if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
1680   if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
1681   if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
1682   if (ctx->Texture._ReallyEnabled)     return (swrast_tri_func) NULL;
1683   if (osmesa->format != OSMESA_RGBA &&
1684       osmesa->format != OSMESA_BGRA &&
1685       osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
1686
1687   if (swrast->_RasterMask == DEPTH_BIT &&
1688       ctx->Depth.Func == GL_LESS &&
1689       ctx->Depth.Mask == GL_TRUE &&
1690       ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
1691      if (ctx->Light.ShadeModel == GL_SMOOTH) {
1692         return smooth_rgba_z_triangle;
1693      }
1694      else {
1695         return flat_rgba_z_triangle;
1696      }
1697   }
1698   return (swrast_tri_func) NULL;
1699}
1700
1701
1702
1703/* Override for the swrast triangle-selection function.  Try to use one
1704 * of our internal triangle functions, otherwise fall back to the
1705 * standard swrast functions.
1706 */
1707static void osmesa_choose_triangle( GLcontext *ctx )
1708{
1709   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1710
1711   swrast->Triangle = osmesa_choose_triangle_function( ctx );
1712   if (!swrast->Triangle)
1713      _swrast_choose_triangle( ctx );
1714}
1715
1716static void osmesa_choose_line( GLcontext *ctx )
1717{
1718   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1719
1720   swrast->Line = osmesa_choose_line_function( ctx );
1721   if (!swrast->Line)
1722      _swrast_choose_line( ctx );
1723}
1724
1725
1726#define OSMESA_NEW_LINE   (_NEW_LINE | \
1727                           _NEW_TEXTURE | \
1728                           _NEW_LIGHT | \
1729                           _NEW_DEPTH | \
1730                           _NEW_RENDERMODE | \
1731                           _SWRAST_NEW_RASTERMASK)
1732
1733#define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \
1734                             _NEW_TEXTURE | \
1735                             _NEW_LIGHT | \
1736                             _NEW_DEPTH | \
1737                             _NEW_RENDERMODE | \
1738                             _SWRAST_NEW_RASTERMASK)
1739
1740
1741/* Extend the software rasterizer with our line and triangle
1742 * functions.
1743 */
1744static void osmesa_register_swrast_functions( GLcontext *ctx )
1745{
1746   SWcontext *swrast = SWRAST_CONTEXT( ctx );
1747
1748   swrast->choose_line = osmesa_choose_line;
1749   swrast->choose_triangle = osmesa_choose_triangle;
1750
1751   swrast->invalidate_line |= OSMESA_NEW_LINE;
1752   swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE;
1753}
1754
1755
1756static const GLubyte *get_string( GLcontext *ctx, GLenum name )
1757{
1758   (void) ctx;
1759   switch (name) {
1760      case GL_RENDERER:
1761         return (const GLubyte *) "Mesa OffScreen";
1762      default:
1763         return NULL;
1764   }
1765}
1766
1767
1768static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
1769{
1770   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1771   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1772   TNLcontext *tnl = TNL_CONTEXT(ctx);
1773
1774   ASSERT((void *) osmesa == (void *) ctx->DriverCtx);
1775
1776   /*
1777    * XXX these function pointers could be initialized just once during
1778    * context creation since they don't depend on any state changes.
1779    */
1780
1781   ctx->Driver.GetString = get_string;
1782   ctx->Driver.UpdateState = osmesa_update_state;
1783   ctx->Driver.SetDrawBuffer = set_draw_buffer;
1784   ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
1785   ctx->Driver.GetBufferSize = buffer_size;
1786
1787   ctx->Driver.Accum = _swrast_Accum;
1788   ctx->Driver.Bitmap = _swrast_Bitmap;
1789   ctx->Driver.Clear = clear;
1790   ctx->Driver.CopyPixels = _swrast_CopyPixels;
1791   ctx->Driver.DrawPixels = _swrast_DrawPixels;
1792   ctx->Driver.ReadPixels = _swrast_ReadPixels;
1793
1794   ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1795   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1796   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1797   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1798   ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1799   ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1800   ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1801   ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1802
1803   ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1804   ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1805   ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1806   ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1807   ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1808   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1809   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1810   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1811   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1812
1813
1814   /* RGB(A) span/pixel functions */
1815   if (osmesa->format == OSMESA_RGB) {
1816      swdd->WriteRGBASpan = write_rgba_span_RGB;
1817      swdd->WriteRGBSpan = write_rgb_span_RGB;
1818      swdd->WriteMonoRGBASpan = write_monocolor_span_RGB;
1819      swdd->WriteRGBAPixels = write_rgba_pixels_RGB;
1820      swdd->WriteMonoRGBAPixels = write_monocolor_pixels_RGB;
1821      swdd->ReadRGBASpan = read_rgba_span3;
1822      swdd->ReadRGBAPixels = read_rgba_pixels3;
1823   }
1824   else if (osmesa->format == OSMESA_BGR) {
1825      swdd->WriteRGBASpan = write_rgba_span_BGR;
1826      swdd->WriteRGBSpan = write_rgb_span_BGR;
1827      swdd->WriteMonoRGBASpan = write_monocolor_span_BGR;
1828      swdd->WriteRGBAPixels = write_rgba_pixels_BGR;
1829      swdd->WriteMonoRGBAPixels = write_monocolor_pixels_BGR;
1830      swdd->ReadRGBASpan = read_rgba_span3;
1831      swdd->ReadRGBAPixels = read_rgba_pixels3;
1832   }
1833   else {
1834      /* 4 GLchan / pixel in frame buffer */
1835      swdd->WriteRGBSpan = write_rgb_span;
1836      swdd->WriteRGBAPixels = write_rgba_pixels;
1837      swdd->WriteMonoRGBASpan = write_monocolor_span;
1838      swdd->WriteMonoRGBAPixels = write_monocolor_pixels;
1839      if (osmesa->format == OSMESA_RGBA &&
1840          CHAN_TYPE == GL_UNSIGNED_BYTE &&
1841          RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3) {
1842         /* special, fast case */
1843         swdd->WriteRGBASpan = write_rgba_span_rgba;
1844         swdd->ReadRGBASpan = read_rgba_span_rgba;
1845      }
1846      else {
1847         swdd->WriteRGBASpan = write_rgba_span;
1848         swdd->ReadRGBASpan = read_rgba_span;
1849      }
1850      swdd->ReadRGBAPixels = read_rgba_pixels;
1851   }
1852
1853   /* CI span/pixel functions */
1854   swdd->WriteCI32Span = write_index32_span;
1855   swdd->WriteCI8Span = write_index8_span;
1856   swdd->WriteMonoCISpan = write_monoindex_span;
1857   swdd->WriteCI32Pixels = write_index_pixels;
1858   swdd->WriteMonoCIPixels = write_monoindex_pixels;
1859   swdd->ReadCI32Span = read_index_span;
1860   swdd->ReadCI32Pixels = read_index_pixels;
1861
1862   swdd->SetReadBuffer = set_read_buffer;
1863
1864   tnl->Driver.RunPipeline = _tnl_run_pipeline;
1865   tnl->Driver.RenderStart = _swsetup_RenderStart;
1866   tnl->Driver.RenderFinish = _swsetup_RenderFinish;
1867   tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
1868   tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
1869   tnl->Driver.PointsFunc = _swsetup_Points;
1870   tnl->Driver.LineFunc = _swsetup_Line;
1871   tnl->Driver.TriangleFunc = _swsetup_Triangle;
1872   tnl->Driver.QuadFunc = _swsetup_Quad;
1873   tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
1874   tnl->Driver.RenderInterp = _swsetup_RenderInterp;
1875   tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
1876   tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
1877   tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
1878
1879
1880   _swrast_InvalidateState( ctx, new_state );
1881   _swsetup_InvalidateState( ctx, new_state );
1882   _ac_InvalidateState( ctx, new_state );
1883   _tnl_InvalidateState( ctx, new_state );
1884}
1885