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