Subversion Repositories shark

Rev

Rev 59 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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