osmesa.c revision 206eda8b69ab3c63e9597015189f49d1bda9356f
1/* $Id: osmesa.c,v 1.59 2001/06/27 13:56:17 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 if (format==OSMESA_RGB_565) {
255      indexBits = 0;
256      redBits = 5;
257      greenBits = 6;
258      blueBits = 5;
259      alphaBits = 0;
260      rshift = 11;
261      gshift = 5;
262      bshift = 0;
263      ashift = 0;
264      rind = 0; /* not used */
265      gind = 0;
266      bind = 0;
267      rgbmode = GL_TRUE;
268      swalpha = GL_FALSE;
269   }
270   else {
271      return NULL;
272   }
273
274
275   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
276   if (osmesa) {
277      osmesa->gl_visual = _mesa_create_visual( rgbmode,
278                                               GL_FALSE,    /* double buffer */
279                                               GL_FALSE,    /* stereo */
280                                               redBits,
281                                               greenBits,
282                                               blueBits,
283                                               alphaBits,
284                                               indexBits,
285                                               depthBits,
286                                               stencilBits,
287                                               accumBits,
288                                               accumBits,
289                                               accumBits,
290                                               alphaBits ? accumBits : 0,
291                                               1            /* num samples */
292                                               );
293      if (!osmesa->gl_visual) {
294         FREE(osmesa);
295         return NULL;
296      }
297
298      if (!_mesa_initialize_context(&osmesa->gl_ctx,
299                                    osmesa->gl_visual,
300                                    sharelist ? &sharelist->gl_ctx
301                                              : (GLcontext *) NULL,
302                                    (void *) osmesa, GL_TRUE )) {
303         _mesa_destroy_visual( osmesa->gl_visual );
304         FREE(osmesa);
305         return NULL;
306      }
307
308      _mesa_enable_sw_extensions(&(osmesa->gl_ctx));
309
310      osmesa->gl_buffer = _mesa_create_framebuffer( osmesa->gl_visual,
311                                          osmesa->gl_visual->depthBits > 0,
312                                          osmesa->gl_visual->stencilBits > 0,
313                                          osmesa->gl_visual->accumRedBits > 0,
314                                          swalpha );
315
316      if (!osmesa->gl_buffer) {
317         _mesa_destroy_visual( osmesa->gl_visual );
318         _mesa_free_context_data( &osmesa->gl_ctx );
319         FREE(osmesa);
320         return NULL;
321      }
322      osmesa->format = format;
323      osmesa->buffer = NULL;
324      osmesa->width = 0;
325      osmesa->height = 0;
326      osmesa->userRowLength = 0;
327      osmesa->rowlength = 0;
328      osmesa->yup = GL_TRUE;
329      osmesa->rshift = rshift;
330      osmesa->gshift = gshift;
331      osmesa->bshift = bshift;
332      osmesa->ashift = ashift;
333      osmesa->rInd = rind;
334      osmesa->gInd = gind;
335      osmesa->bInd = bind;
336      osmesa->aInd = aind;
337
338
339      /* Initialize the software rasterizer and helper modules.
340       */
341      {
342	 GLcontext *ctx = &osmesa->gl_ctx;
343
344	 _swrast_CreateContext( ctx );
345	 _ac_CreateContext( ctx );
346	 _tnl_CreateContext( ctx );
347	 _swsetup_CreateContext( ctx );
348
349	 osmesa_register_swrast_functions( ctx );
350      }
351   }
352   return osmesa;
353}
354
355
356
357
358/*
359 * Destroy an Off-Screen Mesa rendering context.
360 *
361 * Input:  ctx - the context to destroy
362 */
363void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
364{
365   if (ctx) {
366      _swsetup_DestroyContext( &ctx->gl_ctx );
367      _tnl_DestroyContext( &ctx->gl_ctx );
368      _ac_DestroyContext( &ctx->gl_ctx );
369      _swrast_DestroyContext( &ctx->gl_ctx );
370
371      _mesa_destroy_visual( ctx->gl_visual );
372      _mesa_destroy_framebuffer( ctx->gl_buffer );
373      _mesa_free_context_data( &ctx->gl_ctx );
374      FREE( ctx );
375   }
376}
377
378
379
380/*
381 * Recompute the values of the context's rowaddr array.
382 */
383static void compute_row_addresses( OSMesaContext ctx )
384{
385   GLint bytesPerPixel, bytesPerRow, i;
386   GLubyte *origin = (GLubyte *) ctx->buffer;
387
388   if (ctx->format == OSMESA_COLOR_INDEX) {
389      /* CI mode */
390      bytesPerPixel = 1 * sizeof(GLchan);
391   }
392   else if ((ctx->format == OSMESA_RGB) || (ctx->format == OSMESA_BGR)) {
393      /* RGB mode */
394      bytesPerPixel = 3 * sizeof(GLchan);
395   }
396   else if (ctx->format == OSMESA_RGB_565) {
397      /* 5/6/5 RGB pixel in 16 bits */
398      bytesPerPixel = 2;
399   }
400   else {
401      /* RGBA mode */
402      bytesPerPixel = 4 * sizeof(GLchan);
403   }
404
405   bytesPerRow = ctx->rowlength * bytesPerPixel;
406
407   if (ctx->yup) {
408      /* Y=0 is bottom line of window */
409      for (i = 0; i < MAX_HEIGHT; i++) {
410         ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + i * bytesPerRow);
411      }
412   }
413   else {
414      /* Y=0 is top line of window */
415      for (i = 0; i < MAX_HEIGHT; i++) {
416         GLint j = ctx->height - i - 1;
417         ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + j * bytesPerRow);
418      }
419   }
420}
421
422
423/*
424 * Bind an OSMesaContext to an image buffer.  The image buffer is just a
425 * block of memory which the client provides.  Its size must be at least
426 * as large as width*height*sizeof(type).  Its address should be a multiple
427 * of 4 if using RGBA mode.
428 *
429 * Image data is stored in the order of glDrawPixels:  row-major order
430 * with the lower-left image pixel stored in the first array position
431 * (ie. bottom-to-top).
432 *
433 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
434 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
435 * value.  If the context is in color indexed mode, each pixel will be
436 * stored as a 1-byte value.
437 *
438 * If the context's viewport hasn't been initialized yet, it will now be
439 * initialized to (0,0,width,height).
440 *
441 * Input:  ctx - the rendering context
442 *         buffer - the image buffer memory
443 *         type - data type for pixel components, only GL_UNSIGNED_BYTE
444 *                and GL_UNSIGNED_SHORT_5_6_5 supported now.
445 *         width, height - size of image buffer in pixels, at least 1
446 * Return:  GL_TRUE if success, GL_FALSE if error because of invalid ctx,
447 *          invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
448 *          width>internal limit or height>internal limit.
449 */
450GLboolean GLAPIENTRY
451OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
452                   GLsizei width, GLsizei height )
453{
454   if (!ctx || !buffer ||
455       width < 1 || height < 1 ||
456       width > MAX_WIDTH || height > MAX_HEIGHT) {
457      return GL_FALSE;
458   }
459
460   if (ctx->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) {
461      return GL_FALSE;
462   }
463   else if (type != CHAN_TYPE) {
464      return GL_FALSE;
465   }
466
467   osmesa_update_state( &ctx->gl_ctx, 0 );
468   _mesa_make_current( &ctx->gl_ctx, ctx->gl_buffer );
469
470   ctx->buffer = buffer;
471   ctx->width = width;
472   ctx->height = height;
473   if (ctx->userRowLength)
474      ctx->rowlength = ctx->userRowLength;
475   else
476      ctx->rowlength = width;
477
478   compute_row_addresses( ctx );
479
480   /* init viewport */
481   if (ctx->gl_ctx.Viewport.Width==0) {
482      /* initialize viewport and scissor box to buffer size */
483      _mesa_Viewport( 0, 0, width, height );
484      ctx->gl_ctx.Scissor.Width = width;
485      ctx->gl_ctx.Scissor.Height = height;
486   }
487
488   return GL_TRUE;
489}
490
491
492
493OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
494{
495   GLcontext *ctx = _mesa_get_current_context();
496   if (ctx)
497      return (OSMesaContext) ctx;
498   else
499      return NULL;
500}
501
502
503
504void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
505{
506   OSMesaContext ctx = OSMesaGetCurrentContext();
507
508   switch (pname) {
509      case OSMESA_ROW_LENGTH:
510         if (value<0) {
511            _mesa_error( &ctx->gl_ctx, GL_INVALID_VALUE,
512                      "OSMesaPixelStore(value)" );
513            return;
514         }
515         ctx->userRowLength = value;
516         ctx->rowlength = value;
517         break;
518      case OSMESA_Y_UP:
519         ctx->yup = value ? GL_TRUE : GL_FALSE;
520         break;
521      default:
522         _mesa_error( &ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
523         return;
524   }
525
526   compute_row_addresses( ctx );
527}
528
529
530void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
531{
532   OSMesaContext ctx = OSMesaGetCurrentContext();
533
534   switch (pname) {
535      case OSMESA_WIDTH:
536         *value = ctx->width;
537         return;
538      case OSMESA_HEIGHT:
539         *value = ctx->height;
540         return;
541      case OSMESA_FORMAT:
542         *value = ctx->format;
543         return;
544      case OSMESA_TYPE:
545         *value = CHAN_TYPE;
546         return;
547      case OSMESA_ROW_LENGTH:
548         *value = ctx->rowlength;
549         return;
550      case OSMESA_Y_UP:
551         *value = ctx->yup;
552         return;
553      default:
554         _mesa_error(&ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
555         return;
556   }
557}
558
559/*
560 * Return the depth buffer associated with an OSMesa context.
561 * Input:  c - the OSMesa context
562 * Output:  width, height - size of buffer in pixels
563 *          bytesPerValue - bytes per depth value (2 or 4)
564 *          buffer - pointer to depth buffer values
565 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
566 */
567GLboolean GLAPIENTRY
568OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
569                      GLint *bytesPerValue, void **buffer )
570{
571   if ((!c->gl_buffer) || (!c->gl_buffer->DepthBuffer)) {
572      *width = 0;
573      *height = 0;
574      *bytesPerValue = 0;
575      *buffer = 0;
576      return GL_FALSE;
577   }
578   else {
579      *width = c->gl_buffer->Width;
580      *height = c->gl_buffer->Height;
581      if (c->gl_visual->depthBits <= 16)
582         *bytesPerValue = sizeof(GLushort);
583      else
584         *bytesPerValue = sizeof(GLuint);
585      *buffer = c->gl_buffer->DepthBuffer;
586      return GL_TRUE;
587   }
588}
589
590/*
591 * Return the color buffer associated with an OSMesa context.
592 * Input:  c - the OSMesa context
593 * Output:  width, height - size of buffer in pixels
594 *          format - the pixel format (OSMESA_FORMAT)
595 *          buffer - pointer to color buffer values
596 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
597 */
598GLboolean GLAPIENTRY
599OSMesaGetColorBuffer( OSMesaContext c, GLint *width,
600                      GLint *height, GLint *format, void **buffer )
601{
602   if (!c->buffer) {
603      *width = 0;
604      *height = 0;
605      *format = 0;
606      *buffer = 0;
607      return GL_FALSE;
608   }
609   else {
610      *width = c->width;
611      *height = c->height;
612      *format = c->format;
613      *buffer = c->buffer;
614      return GL_TRUE;
615   }
616}
617
618/**********************************************************************/
619/*** Device Driver Functions                                        ***/
620/**********************************************************************/
621
622
623/*
624 * Useful macros:
625 */
626
627#define PACK_RGBA(DST, R, G, B, A)	\
628do {					\
629   (DST)[osmesa->rInd] = R;		\
630   (DST)[osmesa->gInd] = G;		\
631   (DST)[osmesa->bInd] = B;		\
632   (DST)[osmesa->aInd] = A;		\
633} while (0)
634
635#define PACK_RGB(DST, R, G, B)  \
636do {				\
637   (DST)[0] = R;		\
638   (DST)[1] = G;		\
639   (DST)[2] = B;		\
640} while (0)
641
642#define PACK_BGR(DST, R, G, B)  \
643do {				\
644   (DST)[0] = B;		\
645   (DST)[1] = G;		\
646   (DST)[2] = R;		\
647} while (0)
648
649#define PACK_RGB_565(DST, R, G, B)					\
650do {									\
651   (DST) = (((R) << 8) & 0xf800) | (((G) << 3) & 0x7e0) | ((B) >> 3);\
652} while (0)
653
654
655#define UNPACK_RED(P)      ( (P)[osmesa->rInd] )
656#define UNPACK_GREEN(P)    ( (P)[osmesa->gInd] )
657#define UNPACK_BLUE(P)     ( (P)[osmesa->bInd] )
658#define UNPACK_ALPHA(P)    ( (P)[osmesa->aInd] )
659
660
661#define PIXELADDR1(X,Y)  (osmesa->rowaddr[Y] + (X))
662#define PIXELADDR2(X,Y)  (osmesa->rowaddr[Y] + 2 * (X))
663#define PIXELADDR3(X,Y)  (osmesa->rowaddr[Y] + 3 * (X))
664#define PIXELADDR4(X,Y)  (osmesa->rowaddr[Y] + 4 * (X))
665
666
667
668static GLboolean set_draw_buffer( GLcontext *ctx, GLenum mode )
669{
670   (void) ctx;
671   if (mode==GL_FRONT_LEFT) {
672      return GL_TRUE;
673   }
674   else {
675      return GL_FALSE;
676   }
677}
678
679
680static void set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode )
681{
682   /* separate read buffer not supported */
683   ASSERT(buffer == ctx->DrawBuffer);
684   ASSERT(mode == GL_FRONT_LEFT);
685}
686
687
688static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
689		   GLint x, GLint y, GLint width, GLint height )
690{
691   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
692   const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
693
694   /* sanity check - we only have a front-left buffer */
695   ASSERT((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT)) == 0);
696   if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
697      if (mask & DD_FRONT_LEFT_BIT) {
698	 if (osmesa->format == OSMESA_COLOR_INDEX) {
699	    if (all) {
700	       /* Clear whole CI buffer */
701#if CHAN_TYPE == GL_UNSIGNED_BYTE
702	       MEMSET(osmesa->buffer, ctx->Color.ClearIndex,
703		      osmesa->rowlength * osmesa->height);
704#else
705	       const GLint n = osmesa->rowlength * osmesa->height;
706	       GLchan *buffer = (GLchan *) osmesa->buffer;
707	       GLint i;
708	       for (i = 0; i < n; i ++) {
709		  buffer[i] = ctx->Color.ClearIndex;
710	       }
711#endif
712	    }
713	    else {
714	       /* Clear part of CI buffer */
715	       const GLchan clearIndex = (GLchan) ctx->Color.ClearIndex;
716	       GLint i, j;
717	       for (i = 0; i < height; i++) {
718		  GLchan *ptr1 = PIXELADDR1(x, (y + i));
719		  for (j = 0; j < width; j++) {
720		     *ptr1++ = clearIndex;
721		  }
722	       }
723	    }
724	 }
725	 else if (osmesa->format == OSMESA_RGB) {
726	    const GLchan r = ctx->Color.ClearColor[0];
727	    const GLchan g = ctx->Color.ClearColor[1];
728	    const GLchan b = ctx->Color.ClearColor[2];
729	    if (all) {
730	       /* Clear whole RGB buffer */
731	       GLuint n = osmesa->rowlength * osmesa->height;
732	       GLchan *ptr3 = (GLchan *) osmesa->buffer;
733	       GLuint i;
734	       for (i = 0; i < n; i++) {
735		  PACK_RGB(ptr3, r, g, b);
736		  ptr3 += 3;
737	       }
738	    }
739	    else {
740	       /* Clear part of RGB buffer */
741	       GLint i, j;
742	       for (i = 0; i < height; i++) {
743		  GLchan *ptr3 = PIXELADDR3(x, (y + i));
744		  for (j = 0; j < width; j++) {
745		     PACK_RGB(ptr3, r, g, b);
746		     ptr3 += 3;
747		  }
748	       }
749	    }
750	 }
751	 else if (osmesa->format == OSMESA_BGR) {
752	    const GLchan r = ctx->Color.ClearColor[0];
753	    const GLchan g = ctx->Color.ClearColor[1];
754	    const GLchan b = ctx->Color.ClearColor[2];
755	    if (all) {
756	       /* Clear whole RGB buffer */
757	       const GLint n = osmesa->rowlength * osmesa->height;
758	       GLchan *ptr3 = (GLchan *) osmesa->buffer;
759	       GLint i;
760	       for (i = 0; i < n; i++) {
761		  PACK_BGR(ptr3, r, g, b);
762		  ptr3 += 3;
763	       }
764	    }
765	    else {
766	       /* Clear part of RGB buffer */
767	       GLint i, j;
768	       for (i = 0; i < height; i++) {
769		  GLchan *ptr3 = PIXELADDR3(x, (y + i));
770		  for (j = 0; j < width; j++) {
771		     PACK_BGR(ptr3, r, g, b);
772		     ptr3 += 3;
773		  }
774	       }
775	    }
776	 }
777         else if (osmesa->format == OSMESA_RGB_565) {
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            GLushort clearPixel;
782            PACK_RGB_565(clearPixel, r, g, b);
783            if (all) {
784               /* Clear whole RGB buffer */
785	       const GLint n = osmesa->rowlength * osmesa->height;
786               GLushort *ptr2 = (GLushort *) osmesa->buffer;
787               GLuint  i;
788               for (i = 0; i < n; i++) {
789                  *ptr2 = clearPixel;
790                  ptr2++;
791               }
792            }
793            else {
794               /* clear scissored region */
795               GLint i, j;
796               for (i = 0; i < height; i++) {
797                  GLushort *ptr2 = (GLushort *) PIXELADDR2(x, (y + i));
798                  for (j = 0; j < width; j++) {
799                     *ptr2 = clearPixel;
800                     ptr2++;
801                  }
802               }
803            }
804         }
805	 else {
806#if CHAN_TYPE == GL_UNSIGNED_BYTE
807	    /* 4-byte pixel value */
808	    GLuint clearPixel;
809	    GLchan *clr = (GLchan *) &clearPixel;
810	    clr[osmesa->rInd] = ctx->Color.ClearColor[0];
811	    clr[osmesa->gInd] = ctx->Color.ClearColor[1];
812	    clr[osmesa->bInd] = ctx->Color.ClearColor[2];
813	    clr[osmesa->aInd] = ctx->Color.ClearColor[3];
814	    if (all) {
815	       /* Clear whole RGBA buffer */
816	       const GLuint n = osmesa->rowlength * osmesa->height;
817	       GLuint *ptr4 = (GLuint *) osmesa->buffer;
818	       GLuint i;
819	       if (clearPixel) {
820		  for (i = 0; i < n; i++) {
821		     *ptr4++ = clearPixel;
822		  }
823	       }
824	       else {
825		  BZERO(ptr4, n * sizeof(GLuint));
826	       }
827	    }
828	    else {
829	       /* Clear part of RGBA buffer */
830	       GLint i, j;
831	       for (i = 0; i < height; i++) {
832		  GLuint *ptr4 = (GLuint *) PIXELADDR4(x, (y + i));
833		  for (j = 0; j < width; j++) {
834		     *ptr4++ = clearPixel;
835		  }
836	       }
837	    }
838#else
839	    const GLchan r = ctx->Color.ClearColor[0];
840	    const GLchan g = ctx->Color.ClearColor[1];
841	    const GLchan b = ctx->Color.ClearColor[2];
842	    const GLchan a = ctx->Color.ClearColor[3];
843	    if (all) {
844	       /* Clear whole RGBA buffer */
845	       const GLuint n = osmesa->rowlength * osmesa->height;
846	       GLchan *p = (GLchan *) osmesa->buffer;
847	       GLuint i;
848	       for (i = 0; i < n; i++) {
849		  PACK_RGBA(p, r, g, b, a);
850		  p += 4;
851	       }
852	    }
853	    else {
854	       /* Clear part of RGBA buffer */
855	       GLint i, j;
856	       for (i = 0; i < height; i++) {
857		  GLchan *p = PIXELADDR4(x, (y + i));
858		  for (j = 0; j < width; j++) {
859		     PACK_RGBA(p, r, g, b, a);
860		     p += 4;
861		  }
862	       }
863	    }
864
865#endif
866	 }
867	 mask &= ~DD_FRONT_LEFT_BIT;
868      }
869   }
870
871   if (mask)
872      _swrast_Clear( ctx, mask, all, x, y, width, height );
873}
874
875
876
877static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
878{
879   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
880   *width = osmesa->width;
881   *height = osmesa->height;
882}
883
884
885/**********************************************************************/
886/*****        Read/write spans/arrays of RGBA pixels              *****/
887/**********************************************************************/
888
889/* Write RGBA pixels to an RGBA (or permuted) buffer. */
890static void
891write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
892                 CONST GLchan rgba[][4], const GLubyte mask[] )
893{
894   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
895   GLchan *p = PIXELADDR4(x, y);
896   GLuint i;
897   if (mask) {
898      for (i = 0; i < n; i++, p += 4) {
899         if (mask[i]) {
900            PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
901                         rgba[i][BCOMP], rgba[i][ACOMP]);
902         }
903      }
904   }
905   else {
906      for (i = 0; i < n; i++, p += 4) {
907         PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
908                      rgba[i][BCOMP], rgba[i][ACOMP]);
909      }
910   }
911}
912
913
914/* Write RGBA pixels to an RGBA buffer.  This is the fastest span-writer. */
915static void
916write_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
917                      CONST GLchan rgba[][4], const GLubyte mask[] )
918{
919   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
920   GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
921   const GLuint *rgba4 = (const GLuint *) rgba;
922   GLuint i;
923   ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE);
924   if (mask) {
925      for (i = 0; i < n; i++) {
926         if (mask[i]) {
927            ptr4[i] = rgba4[i];
928         }
929      }
930   }
931   else {
932      MEMCPY( ptr4, rgba4, n * 4 );
933   }
934}
935
936
937/* Write RGB pixels to an RGBA (or permuted) buffer. */
938static void
939write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
940                CONST GLchan rgb[][3], const GLubyte mask[] )
941{
942   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
943   GLchan *p = PIXELADDR4(x, y);
944   GLuint i;
945   if (mask) {
946      for (i = 0; i < n; i++, p+=4) {
947         if (mask[i]) {
948            PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
949         }
950      }
951   }
952   else {
953      for (i = 0; i < n; i++, p+=4) {
954         PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
955      }
956   }
957}
958
959
960
961static void
962write_monocolor_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
963                      const GLchan color[4], const GLubyte mask[] )
964{
965   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
966   GLchan *p = PIXELADDR4(x, y);
967   GLuint i;
968   for (i = 0; i < n; i++, p += 4) {
969      if (mask[i]) {
970         PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
971      }
972   }
973}
974
975
976
977static void
978write_rgba_pixels( const GLcontext *ctx, GLuint n,
979                   const GLint x[], const GLint y[],
980                   CONST 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         GLchan *p = PIXELADDR4(x[i], y[i]);
987         PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
988                      rgba[i][BCOMP], rgba[i][ACOMP]);
989      }
990   }
991}
992
993
994
995static void
996write_monocolor_pixels( const GLcontext *ctx, GLuint n,
997                        const GLint x[], const GLint y[],
998                        const GLchan color[4], const GLubyte mask[] )
999{
1000   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1001   GLuint i;
1002   for (i = 0; i < n; i++) {
1003      if (mask[i]) {
1004         GLchan *p = PIXELADDR4(x[i], y[i]);
1005         PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
1006      }
1007   }
1008}
1009
1010
1011static void
1012read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1013                GLchan rgba[][4] )
1014{
1015   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1016   GLuint i;
1017   GLchan *p = PIXELADDR4(x, y);
1018   for (i = 0; i < n; i++, p += 4) {
1019      rgba[i][RCOMP] = UNPACK_RED(p);
1020      rgba[i][GCOMP] = UNPACK_GREEN(p);
1021      rgba[i][BCOMP] = UNPACK_BLUE(p);
1022      rgba[i][ACOMP] = UNPACK_ALPHA(p);
1023   }
1024}
1025
1026
1027/* Read RGBA pixels from an RGBA buffer */
1028static void
1029read_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1030                     GLchan rgba[][4] )
1031{
1032   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1033   GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
1034   MEMCPY( rgba, ptr4, n * 4 * sizeof(GLchan) );
1035}
1036
1037
1038static void
1039read_rgba_pixels( const GLcontext *ctx,
1040                  GLuint n, const GLint x[], const GLint y[],
1041                  GLchan rgba[][4], const GLubyte mask[] )
1042{
1043   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1044   GLuint i;
1045   for (i = 0; i < n; i++) {
1046      if (mask[i]) {
1047         const GLchan *p = PIXELADDR4(x[i], y[i]);
1048         rgba[i][RCOMP] = UNPACK_RED(p);
1049         rgba[i][GCOMP] = UNPACK_GREEN(p);
1050         rgba[i][BCOMP] = UNPACK_BLUE(p);
1051         rgba[i][ACOMP] = UNPACK_ALPHA(p);
1052      }
1053   }
1054}
1055
1056/**********************************************************************/
1057/*****                3 byte RGB pixel support funcs              *****/
1058/**********************************************************************/
1059
1060/* Write RGBA pixels to an RGB buffer. */
1061static void
1062write_rgba_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1063                     CONST GLchan rgba[][4], const GLubyte mask[] )
1064{
1065   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1066   GLchan *p = PIXELADDR3(x, y);
1067   GLuint i;
1068   if (mask) {
1069      for (i = 0; i < n; i++, p += 3) {
1070         if (mask[i]) {
1071            PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1072         }
1073      }
1074   }
1075   else {
1076      for (i = 0; i < n; i++, p += 3) {
1077         PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1078      }
1079   }
1080}
1081
1082/* Write RGBA pixels to an BGR buffer. */
1083static void
1084write_rgba_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1085                     CONST GLchan rgba[][4], const GLubyte mask[] )
1086{
1087   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1088   GLchan *p = PIXELADDR3(x, y);
1089   GLuint i;
1090   if (mask) {
1091      for (i = 0; i < n; i++, p += 3) {
1092         if (mask[i]) {
1093            PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1094         }
1095      }
1096   }
1097   else {
1098      for (i = 0; i < n; i++, p += 3) {
1099         PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1100      }
1101   }
1102}
1103
1104/* Write RGB pixels to an RGB buffer. */
1105static void
1106write_rgb_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1107                    CONST GLchan rgb[][3], const GLubyte mask[] )
1108{
1109   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1110   GLchan *p = PIXELADDR3(x, y);
1111   GLuint i;
1112   if (mask) {
1113      for (i = 0; i < n; i++, p += 3) {
1114         if (mask[i]) {
1115            PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1116         }
1117      }
1118   }
1119   else {
1120      for (i = 0; i < n; i++, p += 3) {
1121         PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1122      }
1123   }
1124}
1125
1126/* Write RGB pixels to an BGR buffer. */
1127static void
1128write_rgb_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1129                    CONST GLchan rgb[][3], const GLubyte mask[] )
1130{
1131   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1132   GLchan *p = PIXELADDR3(x, y);
1133   GLuint i;
1134   if (mask) {
1135      for (i = 0; i < n; i++, p += 3) {
1136         if (mask[i]) {
1137            PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1138         }
1139      }
1140   }
1141   else {
1142      for (i = 0; i < n; i++, p += 3) {
1143         PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1144      }
1145   }
1146}
1147
1148
1149static void
1150write_monocolor_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1151                          const GLchan color[4], const GLubyte mask[] )
1152{
1153   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1154   GLchan *p = PIXELADDR3(x, y);
1155   GLuint i;
1156   for (i = 0; i < n; i++, p += 3) {
1157      if (mask[i]) {
1158         PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1159      }
1160   }
1161}
1162
1163static void
1164write_monocolor_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1165                          const GLchan color[4], const GLubyte mask[] )
1166{
1167   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1168   GLchan *p = PIXELADDR3(x, y);
1169   GLuint i;
1170   for (i = 0; i < n; i++, p += 3) {
1171      if (mask[i]) {
1172         PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1173      }
1174   }
1175}
1176
1177static void
1178write_rgba_pixels_RGB( const GLcontext *ctx, GLuint n,
1179                       const GLint x[], const GLint y[],
1180                       CONST GLchan rgba[][4], const GLubyte mask[] )
1181{
1182   const OSMesaContext osmesa = (const OSMesaContext) ctx;
1183   GLuint i;
1184   for (i = 0; i < n; i++) {
1185      if (mask[i]) {
1186         GLchan *p = PIXELADDR3(x[i], y[i]);
1187         PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1188      }
1189   }
1190}
1191
1192static void
1193write_rgba_pixels_BGR( const GLcontext *ctx, GLuint n,
1194                       const GLint x[], const GLint y[],
1195                       CONST GLchan rgba[][4], const GLubyte mask[] )
1196{
1197   const OSMesaContext osmesa = (const OSMesaContext) ctx;
1198   GLuint i;
1199   for (i = 0; i < n; i++) {
1200      if (mask[i]) {
1201         GLchan *p = PIXELADDR3(x[i], y[i]);
1202         PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1203      }
1204   }
1205}
1206
1207static void
1208write_monocolor_pixels_RGB( const GLcontext *ctx,
1209                            GLuint n, const GLint x[], const GLint y[],
1210                            const GLchan color[4], const GLubyte mask[] )
1211{
1212   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1213   GLuint i;
1214   for (i = 0; i < n; i++) {
1215      if (mask[i]) {
1216         GLchan *p = PIXELADDR3(x[i], y[i]);
1217         PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1218      }
1219   }
1220}
1221
1222static void
1223write_monocolor_pixels_BGR( const GLcontext *ctx,
1224                            GLuint n, const GLint x[], const GLint y[],
1225                            const GLchan color[4], const GLubyte mask[] )
1226{
1227   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1228   GLuint i;
1229   for (i = 0; i < n; i++) {
1230      if (mask[i]) {
1231         GLchan *p = PIXELADDR3(x[i], y[i]);
1232         PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1233      }
1234   }
1235}
1236
1237static void
1238read_rgba_span3( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1239                 GLchan rgba[][4] )
1240{
1241   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1242   GLuint i;
1243   const GLchan *p = PIXELADDR3(x, y);
1244   for (i = 0; i < n; i++, p += 3) {
1245      rgba[i][RCOMP] = UNPACK_RED(p);
1246      rgba[i][GCOMP] = UNPACK_GREEN(p);
1247      rgba[i][BCOMP] = UNPACK_BLUE(p);
1248      rgba[i][ACOMP] = CHAN_MAX;
1249   }
1250}
1251
1252static void
1253read_rgba_pixels3( const GLcontext *ctx,
1254                   GLuint n, const GLint x[], const GLint y[],
1255                   GLchan rgba[][4], const GLubyte mask[] )
1256{
1257   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1258   GLuint i;
1259   for (i = 0; i < n; i++) {
1260      if (mask[i]) {
1261         const GLchan *p = PIXELADDR3(x[i], y[i]);
1262         rgba[i][RCOMP] = UNPACK_RED(p);
1263         rgba[i][GCOMP] = UNPACK_GREEN(p);
1264         rgba[i][BCOMP] = UNPACK_BLUE(p);
1265         rgba[i][ACOMP] = CHAN_MAX;
1266      }
1267   }
1268}
1269
1270
1271/**********************************************************************/
1272/*****                2 byte RGB pixel support funcs              *****/
1273/**********************************************************************/
1274
1275/* Write RGBA pixels to an RGB_565 buffer. */
1276static void
1277write_rgba_span2( const GLcontext *ctx,
1278                  GLuint n, GLint x, GLint y,
1279                  CONST GLubyte rgba[][4], const GLubyte mask[] )
1280{
1281   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1282   GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
1283   GLuint i;
1284   if (mask) {
1285      for (i = 0; i < n; i++, ptr2++) {
1286         if (mask[i]) {
1287            PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1288         }
1289      }
1290   }
1291   else {
1292      for (i = 0; i < n; i++, ptr2++) {
1293         PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1294      }
1295   }
1296}
1297
1298
1299/* Write RGB pixels to an RGB_565 buffer. */
1300static void
1301write_rgb_span2( const GLcontext *ctx,
1302                 GLuint n, GLint x, GLint y,
1303                 CONST GLubyte rgb[][3], const GLubyte mask[] )
1304{
1305   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1306   GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
1307   GLuint i;
1308   if (mask) {
1309      for (i = 0; i < n; i++, ptr2++) {
1310         if (mask[i]) {
1311            PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1312         }
1313      }
1314   }
1315   else {
1316      for (i = 0; i < n; i++, ptr2++) {
1317         PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1318      }
1319   }
1320}
1321
1322
1323static void
1324write_monocolor_span2( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1325                       const GLchan color[4], const GLubyte mask[] )
1326{
1327   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1328   GLushort pixel;
1329   GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
1330   GLuint i;
1331   PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
1332   for (i = 0; i < n; i++, ptr2++) {
1333      if (mask[i]) {
1334         *ptr2 = pixel;
1335      }
1336   }
1337}
1338
1339
1340static void
1341write_rgba_pixels2( const GLcontext *ctx,
1342                    GLuint n, const GLint x[], const GLint y[],
1343                    CONST GLubyte rgba[][4], const GLubyte mask[] )
1344{
1345   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1346   GLuint i;
1347   for (i = 0; i < n; i++) {
1348      if (mask[i]) {
1349         GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
1350         PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1351      }
1352   }
1353}
1354
1355static void
1356write_monocolor_pixels2( const GLcontext *ctx,
1357                         GLuint n, const GLint x[], const GLint y[],
1358                         const GLchan color[4], const GLubyte mask[] )
1359{
1360   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1361   GLuint i;
1362   GLushort pixel;
1363   PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
1364   for (i = 0; i < n; i++) {
1365      if (mask[i]) {
1366         GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
1367         *ptr2 = pixel;
1368      }
1369   }
1370}
1371
1372static void
1373read_rgba_span2( const GLcontext *ctx,
1374                 GLuint n, GLint x, GLint y,
1375                 GLubyte rgba[][4] )
1376{
1377   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1378   GLuint i;
1379   const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x, y);
1380   for (i = 0; i < n; i++, ptr2++) {
1381      /* This should be fixed to get the low bits right */
1382      rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFe;
1383      rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFc;
1384      rgba[i][BCOMP] = (*ptr2 << 3) & 0xFe;
1385      rgba[i][ACOMP] = 0;
1386   }
1387}
1388
1389static void
1390read_rgba_pixels2( const GLcontext *ctx,
1391                   GLuint n, const GLint x[], const GLint y[],
1392                   GLubyte rgba[][4], const GLubyte mask[] )
1393{
1394   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1395   GLuint i;
1396   for (i = 0; i < n; i++) {
1397      if (mask[i]) {
1398         /* This should be fixed to get the low bits right */
1399         const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x[i],y[i]);
1400         rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFE;
1401         rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFC;
1402         rgba[i][BCOMP] = (*ptr2 << 3) & 0xFE;
1403         rgba[i][ACOMP] = 0;
1404      }
1405   }
1406}
1407
1408
1409
1410/**********************************************************************/
1411/*****        Read/write spans/arrays of CI pixels                *****/
1412/**********************************************************************/
1413
1414/* Write 32-bit color index to buffer */
1415static void
1416write_index32_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1417                    const GLuint index[], const GLubyte mask[] )
1418{
1419   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1420   GLchan *ptr1 = PIXELADDR1(x, y);
1421   GLuint i;
1422   if (mask) {
1423      for (i=0;i<n;i++,ptr1++) {
1424         if (mask[i]) {
1425            *ptr1 = (GLchan) index[i];
1426         }
1427      }
1428   }
1429   else {
1430      for (i=0;i<n;i++,ptr1++) {
1431         *ptr1 = (GLchan) index[i];
1432      }
1433   }
1434}
1435
1436
1437/* Write 8-bit color index to buffer */
1438static void
1439write_index8_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1440                   const GLubyte index[], const GLubyte mask[] )
1441{
1442   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1443   GLchan *ptr1 = PIXELADDR1(x, y);
1444   GLuint i;
1445   if (mask) {
1446      for (i=0;i<n;i++,ptr1++) {
1447         if (mask[i]) {
1448            *ptr1 = (GLchan) index[i];
1449         }
1450      }
1451   }
1452   else {
1453      MEMCPY(ptr1, index, n * sizeof(GLchan));
1454   }
1455}
1456
1457
1458static void
1459write_monoindex_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1460                      GLuint colorIndex, const GLubyte mask[] )
1461{
1462   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1463   GLchan *ptr1 = PIXELADDR1(x, y);
1464   GLuint i;
1465   for (i=0;i<n;i++,ptr1++) {
1466      if (mask[i]) {
1467         *ptr1 = (GLchan) colorIndex;
1468      }
1469   }
1470}
1471
1472
1473static void
1474write_index_pixels( const GLcontext *ctx,
1475                    GLuint n, const GLint x[], const GLint y[],
1476                    const GLuint index[], const GLubyte mask[] )
1477{
1478   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1479   GLuint i;
1480   for (i=0;i<n;i++) {
1481      if (mask[i]) {
1482         GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1483         *ptr1 = (GLchan) index[i];
1484      }
1485   }
1486}
1487
1488
1489static void
1490write_monoindex_pixels( const GLcontext *ctx,
1491                        GLuint n, const GLint x[], const GLint y[],
1492                        GLuint colorIndex, const GLubyte mask[] )
1493{
1494   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1495   GLuint i;
1496   for (i=0;i<n;i++) {
1497      if (mask[i]) {
1498         GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1499         *ptr1 = (GLchan) colorIndex;
1500      }
1501   }
1502}
1503
1504
1505static void
1506read_index_span( const GLcontext *ctx,
1507                 GLuint n, GLint x, GLint y, GLuint index[] )
1508{
1509   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1510   GLuint i;
1511   const GLchan *ptr1 = (const GLchan *) PIXELADDR1(x, y);
1512   for (i=0;i<n;i++,ptr1++) {
1513      index[i] = (GLuint) *ptr1;
1514   }
1515}
1516
1517
1518static void
1519read_index_pixels( const GLcontext *ctx,
1520                   GLuint n, const GLint x[], const GLint y[],
1521                   GLuint index[], const GLubyte mask[] )
1522{
1523   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1524   GLuint i;
1525   for (i=0;i<n;i++) {
1526      if (mask[i] ) {
1527         const GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1528         index[i] = (GLuint) *ptr1;
1529      }
1530   }
1531}
1532
1533
1534
1535/**********************************************************************/
1536/*****                   Optimized line rendering                 *****/
1537/**********************************************************************/
1538
1539
1540/*
1541 * Draw a flat-shaded, RGB line into an osmesa buffer.
1542 */
1543static void
1544flat_rgba_line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
1545{
1546   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1547   const GLchan *color = vert0->color;
1548
1549#define INTERP_XY 1
1550#define CLIP_HACK 1
1551#define PLOT(X, Y)						\
1552do {								\
1553   GLchan *p = PIXELADDR4(X, Y);				\
1554   PACK_RGBA(p, color[0], color[1], color[2], color[3]);	\
1555} while (0)
1556
1557#ifdef WIN32
1558#include "..\swrast\s_linetemp.h"
1559#else
1560#include "swrast/s_linetemp.h"
1561#endif
1562}
1563
1564
1565/*
1566 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1567 */
1568static void
1569flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
1570{
1571   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1572   const GLchan *color = vert0->color;
1573
1574#define INTERP_XY 1
1575#define INTERP_Z 1
1576#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1577#define CLIP_HACK 1
1578#define PLOT(X, Y)					\
1579do {							\
1580   if (Z < *zPtr) {					\
1581      GLchan *p = PIXELADDR4(X, Y);			\
1582      PACK_RGBA(p, color[RCOMP], color[GCOMP],		\
1583                   color[BCOMP], color[ACOMP]);		\
1584      *zPtr = Z;					\
1585   }							\
1586} while (0)
1587
1588
1589#ifdef WIN32
1590#include "..\swrast\s_linetemp.h"
1591#else
1592#include "swrast/s_linetemp.h"
1593#endif
1594}
1595
1596
1597/*
1598 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1599 * XXX update for GLchan
1600 */
1601static void
1602flat_blend_rgba_line( GLcontext *ctx,
1603                      const SWvertex *vert0, const SWvertex *vert1 )
1604{
1605   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1606   const GLint rshift = osmesa->rshift;
1607   const GLint gshift = osmesa->gshift;
1608   const GLint bshift = osmesa->bshift;
1609   const GLint avalue = vert0->color[3];
1610   const GLint msavalue = CHAN_MAX - avalue;
1611   const GLint rvalue = vert0->color[0]*avalue;
1612   const GLint gvalue = vert0->color[1]*avalue;
1613   const GLint bvalue = vert0->color[2]*avalue;
1614
1615#define INTERP_XY 1
1616#define CLIP_HACK 1
1617#define PLOT(X,Y)					\
1618   { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);	\
1619     GLuint  pixel = 0;					\
1620     pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1621     pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1622     pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1623     *ptr4 = pixel;					\
1624   }
1625
1626#ifdef WIN32
1627#include "..\swrast\s_linetemp.h"
1628#else
1629#include "swrast/s_linetemp.h"
1630#endif
1631}
1632
1633
1634/*
1635 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1636 * XXX update for GLchan
1637 */
1638static void
1639flat_blend_rgba_z_line( GLcontext *ctx,
1640                        const SWvertex *vert0, const SWvertex *vert1 )
1641{
1642   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1643   const GLint rshift = osmesa->rshift;
1644   const GLint gshift = osmesa->gshift;
1645   const GLint bshift = osmesa->bshift;
1646   const GLint avalue = vert0->color[3];
1647   const GLint msavalue = 256 - avalue;
1648   const GLint rvalue = vert0->color[0]*avalue;
1649   const GLint gvalue = vert0->color[1]*avalue;
1650   const GLint bvalue = vert0->color[2]*avalue;
1651
1652#define INTERP_XY 1
1653#define INTERP_Z 1
1654#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1655#define CLIP_HACK 1
1656#define PLOT(X,Y)							\
1657	if (Z < *zPtr) {						\
1658	   GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);			\
1659	   GLuint  pixel = 0;						\
1660	   pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);	\
1661	   pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);	\
1662	   pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);	\
1663	   *ptr4 = pixel; 						\
1664	}
1665
1666#ifdef WIN32
1667#include "..\swrast\s_linetemp.h"
1668#else
1669#include "swrast/s_linetemp.h"
1670#endif
1671}
1672
1673
1674/*
1675 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1676 * XXX update for GLchan
1677 */
1678static void
1679flat_blend_rgba_z_line_write( GLcontext *ctx,
1680                              const SWvertex *vert0, const SWvertex *vert1 )
1681{
1682   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1683   const GLint rshift = osmesa->rshift;
1684   const GLint gshift = osmesa->gshift;
1685   const GLint bshift = osmesa->bshift;
1686   const GLint avalue = vert0->color[3];
1687   const GLint msavalue = 256 - avalue;
1688   const GLint rvalue = vert0->color[0]*avalue;
1689   const GLint gvalue = vert0->color[1]*avalue;
1690   const GLint bvalue = vert0->color[2]*avalue;
1691
1692#define INTERP_XY 1
1693#define INTERP_Z 1
1694#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1695#define CLIP_HACK 1
1696#define PLOT(X,Y)							\
1697	if (Z < *zPtr) {						\
1698	   GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y);			\
1699	   GLuint  pixel = 0;						\
1700	   pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);	\
1701	   pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);	\
1702	   pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);	\
1703	   *ptr4 = pixel;						\
1704	   *zPtr = Z;							\
1705	}
1706
1707#ifdef WIN32
1708#include "..\swrast\s_linetemp.h"
1709#else
1710#include "swrast/s_linetemp.h"
1711#endif
1712}
1713
1714
1715/*
1716 * Analyze context state to see if we can provide a fast line drawing
1717 * function, like those in lines.c.  Otherwise, return NULL.
1718 */
1719static swrast_line_func
1720osmesa_choose_line_function( GLcontext *ctx )
1721{
1722   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1723   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
1724
1725   if (CHAN_BITS != 8)                    return NULL;
1726   if (ctx->RenderMode != GL_RENDER)      return NULL;
1727   if (ctx->Line.SmoothFlag)              return NULL;
1728   if (ctx->Texture._ReallyEnabled)       return NULL;
1729   if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
1730   if (ctx->Line.Width != 1.0F)           return NULL;
1731   if (ctx->Line.StippleFlag)             return NULL;
1732   if (ctx->Line.SmoothFlag)              return NULL;
1733   if (osmesa->format != OSMESA_RGBA &&
1734       osmesa->format != OSMESA_BGRA &&
1735       osmesa->format != OSMESA_ARGB)     return NULL;
1736
1737   if (swrast->_RasterMask==DEPTH_BIT
1738       && ctx->Depth.Func==GL_LESS
1739       && ctx->Depth.Mask==GL_TRUE
1740       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
1741      return flat_rgba_z_line;
1742   }
1743
1744   if (swrast->_RasterMask == 0) {
1745      return flat_rgba_line;
1746   }
1747
1748   if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
1749       && ctx->Depth.Func==GL_LESS
1750       && ctx->Depth.Mask==GL_TRUE
1751       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1752       && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1753       && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1754       && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1755       && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1756       && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1757      return flat_blend_rgba_z_line_write;
1758   }
1759
1760   if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
1761       && ctx->Depth.Func==GL_LESS
1762       && ctx->Depth.Mask==GL_FALSE
1763       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1764       && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1765       && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1766       && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1767       && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1768       && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1769      return flat_blend_rgba_z_line;
1770   }
1771
1772   if (swrast->_RasterMask==BLEND_BIT
1773       && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1774       && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1775       && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1776       && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1777       && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1778      return flat_blend_rgba_line;
1779   }
1780
1781   return NULL;
1782}
1783
1784
1785/**********************************************************************/
1786/*****                 Optimized triangle rendering               *****/
1787/**********************************************************************/
1788
1789
1790/*
1791 * Smooth-shaded, z-less triangle, RGBA color.
1792 */
1793static void smooth_rgba_z_triangle( GLcontext *ctx,
1794				    const SWvertex *v0,
1795                                    const SWvertex *v1,
1796                                    const SWvertex *v2 )
1797{
1798   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1799
1800#define INTERP_Z 1
1801#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1802#define INTERP_RGB 1
1803#define INTERP_ALPHA 1
1804#define RENDER_SPAN( span )					\
1805   GLuint i;							\
1806   GLchan *img = PIXELADDR4(span.x, span.y); 			\
1807   for (i = 0; i < span.count; i++, img += 4) {			\
1808      const GLdepth z = FixedToDepth(span.z);			\
1809      if (z < zRow[i]) {					\
1810         PACK_RGBA(img, FixedToInt(span.red),			\
1811            FixedToInt(span.green), FixedToInt(span.blue),	\
1812            FixedToInt(span.alpha));				\
1813         zRow[i] = z;						\
1814      }								\
1815      span.red += span.redStep;					\
1816      span.green += span.greenStep;				\
1817      span.blue += span.blueStep;				\
1818      span.alpha += span.alphaStep;				\
1819      span.z += span.zStep;					\
1820   }
1821
1822#ifdef WIN32
1823#include "..\swrast\s_tritemp.h"
1824#else
1825#include "swrast/s_tritemp.h"
1826#endif
1827}
1828
1829
1830
1831
1832/*
1833 * Flat-shaded, z-less triangle, RGBA color.
1834 */
1835static void flat_rgba_z_triangle( GLcontext *ctx,
1836				  const SWvertex *v0,
1837                                  const SWvertex *v1,
1838                                  const SWvertex *v2 )
1839{
1840   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1841#define INTERP_Z 1
1842#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1843#define SETUP_CODE						\
1844   GLuint pixel;						\
1845   PACK_RGBA((GLchan *) &pixel, v0->color[0], v0->color[1],	\
1846                                v0->color[2], v0->color[3]);
1847
1848#define RENDER_SPAN( span )				\
1849   GLuint i;						\
1850   GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y);	\
1851   for (i = 0; i < span.count; i++) {			\
1852      const GLdepth z = FixedToDepth(span.z);		\
1853      if (z < zRow[i]) {				\
1854         img[i] = pixel;				\
1855         zRow[i] = z;					\
1856      }							\
1857      span.z += span.zStep;				\
1858   }
1859
1860#ifdef WIN32
1861#include "..\swrast\s_tritemp.h"
1862#else
1863#include "swrast/s_tritemp.h"
1864#endif
1865}
1866
1867
1868
1869/*
1870 * Return pointer to an accelerated triangle function if possible.
1871 */
1872static swrast_tri_func
1873osmesa_choose_triangle_function( GLcontext *ctx )
1874{
1875   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1876   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
1877
1878   if (CHAN_BITS != 8)                  return (swrast_tri_func) NULL;
1879   if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
1880   if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
1881   if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
1882   if (ctx->Texture._ReallyEnabled)     return (swrast_tri_func) NULL;
1883   if (osmesa->format != OSMESA_RGBA &&
1884       osmesa->format != OSMESA_BGRA &&
1885       osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
1886
1887   if (swrast->_RasterMask == DEPTH_BIT &&
1888       ctx->Depth.Func == GL_LESS &&
1889       ctx->Depth.Mask == GL_TRUE &&
1890       ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
1891      if (ctx->Light.ShadeModel == GL_SMOOTH) {
1892         return smooth_rgba_z_triangle;
1893      }
1894      else {
1895         return flat_rgba_z_triangle;
1896      }
1897   }
1898   return (swrast_tri_func) NULL;
1899}
1900
1901
1902
1903/* Override for the swrast triangle-selection function.  Try to use one
1904 * of our internal triangle functions, otherwise fall back to the
1905 * standard swrast functions.
1906 */
1907static void osmesa_choose_triangle( GLcontext *ctx )
1908{
1909   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1910
1911   swrast->Triangle = osmesa_choose_triangle_function( ctx );
1912   if (!swrast->Triangle)
1913      _swrast_choose_triangle( ctx );
1914}
1915
1916static void osmesa_choose_line( GLcontext *ctx )
1917{
1918   SWcontext *swrast = SWRAST_CONTEXT(ctx);
1919
1920   swrast->Line = osmesa_choose_line_function( ctx );
1921   if (!swrast->Line)
1922      _swrast_choose_line( ctx );
1923}
1924
1925
1926#define OSMESA_NEW_LINE   (_NEW_LINE | \
1927                           _NEW_TEXTURE | \
1928                           _NEW_LIGHT | \
1929                           _NEW_DEPTH | \
1930                           _NEW_RENDERMODE | \
1931                           _SWRAST_NEW_RASTERMASK)
1932
1933#define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \
1934                             _NEW_TEXTURE | \
1935                             _NEW_LIGHT | \
1936                             _NEW_DEPTH | \
1937                             _NEW_RENDERMODE | \
1938                             _SWRAST_NEW_RASTERMASK)
1939
1940
1941/* Extend the software rasterizer with our line and triangle
1942 * functions.
1943 */
1944static void osmesa_register_swrast_functions( GLcontext *ctx )
1945{
1946   SWcontext *swrast = SWRAST_CONTEXT( ctx );
1947
1948   swrast->choose_line = osmesa_choose_line;
1949   swrast->choose_triangle = osmesa_choose_triangle;
1950
1951   swrast->invalidate_line |= OSMESA_NEW_LINE;
1952   swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE;
1953}
1954
1955
1956static const GLubyte *get_string( GLcontext *ctx, GLenum name )
1957{
1958   (void) ctx;
1959   switch (name) {
1960      case GL_RENDERER:
1961         return (const GLubyte *) "Mesa OffScreen";
1962      default:
1963         return NULL;
1964   }
1965}
1966
1967
1968static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
1969{
1970   OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1971   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1972   TNLcontext *tnl = TNL_CONTEXT(ctx);
1973
1974   ASSERT((void *) osmesa == (void *) ctx->DriverCtx);
1975
1976   /*
1977    * XXX these function pointers could be initialized just once during
1978    * context creation since they don't depend on any state changes.
1979    */
1980
1981   ctx->Driver.GetString = get_string;
1982   ctx->Driver.UpdateState = osmesa_update_state;
1983   ctx->Driver.SetDrawBuffer = set_draw_buffer;
1984   ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
1985   ctx->Driver.GetBufferSize = buffer_size;
1986
1987   ctx->Driver.Accum = _swrast_Accum;
1988   ctx->Driver.Bitmap = _swrast_Bitmap;
1989   ctx->Driver.Clear = clear;
1990   ctx->Driver.CopyPixels = _swrast_CopyPixels;
1991   ctx->Driver.DrawPixels = _swrast_DrawPixels;
1992   ctx->Driver.ReadPixels = _swrast_ReadPixels;
1993
1994   ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1995   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1996   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1997   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1998   ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1999   ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
2000   ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
2001   ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
2002
2003   ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
2004   ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
2005   ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
2006   ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
2007   ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
2008   ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
2009   ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
2010   ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
2011   ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
2012
2013
2014   /* RGB(A) span/pixel functions */
2015   if (osmesa->format == OSMESA_RGB) {
2016      swdd->WriteRGBASpan = write_rgba_span_RGB;
2017      swdd->WriteRGBSpan = write_rgb_span_RGB;
2018      swdd->WriteMonoRGBASpan = write_monocolor_span_RGB;
2019      swdd->WriteRGBAPixels = write_rgba_pixels_RGB;
2020      swdd->WriteMonoRGBAPixels = write_monocolor_pixels_RGB;
2021      swdd->ReadRGBASpan = read_rgba_span3;
2022      swdd->ReadRGBAPixels = read_rgba_pixels3;
2023   }
2024   else if (osmesa->format == OSMESA_BGR) {
2025      swdd->WriteRGBASpan = write_rgba_span_BGR;
2026      swdd->WriteRGBSpan = write_rgb_span_BGR;
2027      swdd->WriteMonoRGBASpan = write_monocolor_span_BGR;
2028      swdd->WriteRGBAPixels = write_rgba_pixels_BGR;
2029      swdd->WriteMonoRGBAPixels = write_monocolor_pixels_BGR;
2030      swdd->ReadRGBASpan = read_rgba_span3;
2031      swdd->ReadRGBAPixels = read_rgba_pixels3;
2032   }
2033   else if (osmesa->format == OSMESA_RGB_565) {
2034      swdd->WriteRGBASpan = write_rgba_span2;
2035      swdd->WriteRGBSpan = write_rgb_span2;
2036      swdd->WriteMonoRGBASpan = write_monocolor_span2;
2037      swdd->WriteRGBAPixels = write_rgba_pixels2;
2038      swdd->WriteMonoRGBAPixels = write_monocolor_pixels2;
2039      swdd->ReadRGBASpan = read_rgba_span2;
2040      swdd->ReadRGBAPixels = read_rgba_pixels2;
2041   }
2042   else {
2043      /* 4 GLchan / pixel in frame buffer */
2044      swdd->WriteRGBSpan = write_rgb_span;
2045      swdd->WriteRGBAPixels = write_rgba_pixels;
2046      swdd->WriteMonoRGBASpan = write_monocolor_span;
2047      swdd->WriteMonoRGBAPixels = write_monocolor_pixels;
2048      if (osmesa->format == OSMESA_RGBA &&
2049          CHAN_TYPE == GL_UNSIGNED_BYTE &&
2050          RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3) {
2051         /* special, fast case */
2052         swdd->WriteRGBASpan = write_rgba_span_rgba;
2053         swdd->ReadRGBASpan = read_rgba_span_rgba;
2054      }
2055      else {
2056         swdd->WriteRGBASpan = write_rgba_span;
2057         swdd->ReadRGBASpan = read_rgba_span;
2058      }
2059      swdd->ReadRGBAPixels = read_rgba_pixels;
2060   }
2061
2062   /* CI span/pixel functions */
2063   swdd->WriteCI32Span = write_index32_span;
2064   swdd->WriteCI8Span = write_index8_span;
2065   swdd->WriteMonoCISpan = write_monoindex_span;
2066   swdd->WriteCI32Pixels = write_index_pixels;
2067   swdd->WriteMonoCIPixels = write_monoindex_pixels;
2068   swdd->ReadCI32Span = read_index_span;
2069   swdd->ReadCI32Pixels = read_index_pixels;
2070
2071   swdd->SetReadBuffer = set_read_buffer;
2072
2073   tnl->Driver.RunPipeline = _tnl_run_pipeline;
2074   tnl->Driver.RenderStart = _swsetup_RenderStart;
2075   tnl->Driver.RenderFinish = _swsetup_RenderFinish;
2076   tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices;
2077   tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive;
2078   tnl->Driver.PointsFunc = _swsetup_Points;
2079   tnl->Driver.LineFunc = _swsetup_Line;
2080   tnl->Driver.TriangleFunc = _swsetup_Triangle;
2081   tnl->Driver.QuadFunc = _swsetup_Quad;
2082   tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
2083   tnl->Driver.RenderInterp = _swsetup_RenderInterp;
2084   tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
2085   tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
2086   tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
2087
2088
2089   _swrast_InvalidateState( ctx, new_state );
2090   _swsetup_InvalidateState( ctx, new_state );
2091   _ac_InvalidateState( ctx, new_state );
2092   _tnl_InvalidateState( ctx, new_state );
2093}
2094