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