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