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