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