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