Added ctx parameter to _mesa_debug()
[mesa.git] / src / mesa / drivers / osmesa / osmesa.c
1 /* $Id: osmesa.c,v 1.81 2002/06/15 02:38:17 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 void set_draw_buffer( GLcontext *ctx, GLenum mode )
711 {
712 (void) ctx;
713 (void) mode;
714 }
715
716
717 static void set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode )
718 {
719 /* separate read buffer not supported */
720 ASSERT(buffer == ctx->DrawBuffer);
721 ASSERT(mode == GL_FRONT_LEFT);
722 }
723
724
725 static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
726 GLint x, GLint y, GLint width, GLint height )
727 {
728 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
729 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
730
731 /* sanity check - we only have a front-left buffer */
732 ASSERT((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT)) == 0);
733 if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
734 if (mask & DD_FRONT_LEFT_BIT) {
735 if (osmesa->format == OSMESA_COLOR_INDEX) {
736 if (all) {
737 /* Clear whole CI buffer */
738 #if CHAN_TYPE == GL_UNSIGNED_BYTE
739 MEMSET(osmesa->buffer, ctx->Color.ClearIndex,
740 osmesa->rowlength * osmesa->height);
741 #else
742 const GLint n = osmesa->rowlength * osmesa->height;
743 GLchan *buffer = (GLchan *) osmesa->buffer;
744 GLint i;
745 for (i = 0; i < n; i ++) {
746 buffer[i] = ctx->Color.ClearIndex;
747 }
748 #endif
749 }
750 else {
751 /* Clear part of CI buffer */
752 const GLchan clearIndex = (GLchan) ctx->Color.ClearIndex;
753 GLint i, j;
754 for (i = 0; i < height; i++) {
755 GLchan *ptr1 = PIXELADDR1(x, (y + i));
756 for (j = 0; j < width; j++) {
757 *ptr1++ = clearIndex;
758 }
759 }
760 }
761 }
762 else if (osmesa->format == OSMESA_RGB) {
763 const GLchan r = ctx->Color.ClearColor[0];
764 const GLchan g = ctx->Color.ClearColor[1];
765 const GLchan b = ctx->Color.ClearColor[2];
766 if (all) {
767 /* Clear whole RGB buffer */
768 GLuint n = osmesa->rowlength * osmesa->height;
769 GLchan *ptr3 = (GLchan *) osmesa->buffer;
770 GLuint i;
771 for (i = 0; i < n; i++) {
772 PACK_RGB(ptr3, r, g, b);
773 ptr3 += 3;
774 }
775 }
776 else {
777 /* Clear part of RGB buffer */
778 GLint i, j;
779 for (i = 0; i < height; i++) {
780 GLchan *ptr3 = PIXELADDR3(x, (y + i));
781 for (j = 0; j < width; j++) {
782 PACK_RGB(ptr3, r, g, b);
783 ptr3 += 3;
784 }
785 }
786 }
787 }
788 else if (osmesa->format == OSMESA_BGR) {
789 const GLchan r = ctx->Color.ClearColor[0];
790 const GLchan g = ctx->Color.ClearColor[1];
791 const GLchan b = ctx->Color.ClearColor[2];
792 if (all) {
793 /* Clear whole RGB buffer */
794 const GLint n = osmesa->rowlength * osmesa->height;
795 GLchan *ptr3 = (GLchan *) osmesa->buffer;
796 GLint i;
797 for (i = 0; i < n; i++) {
798 PACK_BGR(ptr3, r, g, b);
799 ptr3 += 3;
800 }
801 }
802 else {
803 /* Clear part of RGB buffer */
804 GLint i, j;
805 for (i = 0; i < height; i++) {
806 GLchan *ptr3 = PIXELADDR3(x, (y + i));
807 for (j = 0; j < width; j++) {
808 PACK_BGR(ptr3, r, g, b);
809 ptr3 += 3;
810 }
811 }
812 }
813 }
814 else if (osmesa->format == OSMESA_RGB_565) {
815 const GLchan r = ctx->Color.ClearColor[0];
816 const GLchan g = ctx->Color.ClearColor[1];
817 const GLchan b = ctx->Color.ClearColor[2];
818 GLushort clearPixel;
819 PACK_RGB_565(clearPixel, r, g, b);
820 if (all) {
821 /* Clear whole RGB buffer */
822 const GLuint n = osmesa->rowlength * osmesa->height;
823 GLushort *ptr2 = (GLushort *) osmesa->buffer;
824 GLuint i;
825 for (i = 0; i < n; i++) {
826 *ptr2 = clearPixel;
827 ptr2++;
828 }
829 }
830 else {
831 /* clear scissored region */
832 GLint i, j;
833 for (i = 0; i < height; i++) {
834 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, (y + i));
835 for (j = 0; j < width; j++) {
836 *ptr2 = clearPixel;
837 ptr2++;
838 }
839 }
840 }
841 }
842 else {
843 #if CHAN_TYPE == GL_UNSIGNED_BYTE
844 /* 4-byte pixel value */
845 GLuint clearPixel;
846 GLchan *clr = (GLchan *) &clearPixel;
847 clr[osmesa->rInd] = ctx->Color.ClearColor[0];
848 clr[osmesa->gInd] = ctx->Color.ClearColor[1];
849 clr[osmesa->bInd] = ctx->Color.ClearColor[2];
850 clr[osmesa->aInd] = ctx->Color.ClearColor[3];
851 if (all) {
852 /* Clear whole RGBA buffer */
853 const GLuint n = osmesa->rowlength * osmesa->height;
854 GLuint *ptr4 = (GLuint *) osmesa->buffer;
855 GLuint i;
856 if (clearPixel) {
857 for (i = 0; i < n; i++) {
858 *ptr4++ = clearPixel;
859 }
860 }
861 else {
862 BZERO(ptr4, n * sizeof(GLuint));
863 }
864 }
865 else {
866 /* Clear part of RGBA buffer */
867 GLint i, j;
868 for (i = 0; i < height; i++) {
869 GLuint *ptr4 = (GLuint *) PIXELADDR4(x, (y + i));
870 for (j = 0; j < width; j++) {
871 *ptr4++ = clearPixel;
872 }
873 }
874 }
875 #else
876 const GLchan r = ctx->Color.ClearColor[0];
877 const GLchan g = ctx->Color.ClearColor[1];
878 const GLchan b = ctx->Color.ClearColor[2];
879 const GLchan a = ctx->Color.ClearColor[3];
880 if (all) {
881 /* Clear whole RGBA buffer */
882 const GLuint n = osmesa->rowlength * osmesa->height;
883 GLchan *p = (GLchan *) osmesa->buffer;
884 GLuint i;
885 for (i = 0; i < n; i++) {
886 PACK_RGBA(p, r, g, b, a);
887 p += 4;
888 }
889 }
890 else {
891 /* Clear part of RGBA buffer */
892 GLint i, j;
893 for (i = 0; i < height; i++) {
894 GLchan *p = PIXELADDR4(x, (y + i));
895 for (j = 0; j < width; j++) {
896 PACK_RGBA(p, r, g, b, a);
897 p += 4;
898 }
899 }
900 }
901
902 #endif
903 }
904 mask &= ~DD_FRONT_LEFT_BIT;
905 }
906 }
907
908 if (mask)
909 _swrast_Clear( ctx, mask, all, x, y, width, height );
910 }
911
912
913
914 static void buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
915 {
916 /* don't use GET_CURRENT_CONTEXT(ctx) here - it's a problem on Windows */
917 GLcontext *ctx = (GLcontext *) _glapi_get_context();
918 (void) buffer;
919 if (ctx) {
920 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
921 *width = osmesa->width;
922 *height = osmesa->height;
923 }
924 }
925
926
927 /**********************************************************************/
928 /***** Read/write spans/arrays of RGBA pixels *****/
929 /**********************************************************************/
930
931 /* Write RGBA pixels to an RGBA (or permuted) buffer. */
932 static void
933 write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
934 CONST GLchan rgba[][4], const GLubyte mask[] )
935 {
936 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
937 GLchan *p = PIXELADDR4(x, y);
938 GLuint i;
939 if (mask) {
940 for (i = 0; i < n; i++, p += 4) {
941 if (mask[i]) {
942 PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
943 rgba[i][BCOMP], rgba[i][ACOMP]);
944 }
945 }
946 }
947 else {
948 for (i = 0; i < n; i++, p += 4) {
949 PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
950 rgba[i][BCOMP], rgba[i][ACOMP]);
951 }
952 }
953 }
954
955
956 /* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
957 static void
958 write_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
959 CONST GLchan rgba[][4], const GLubyte mask[] )
960 {
961 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
962 GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
963 const GLuint *rgba4 = (const GLuint *) rgba;
964 GLuint i;
965 ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE);
966 if (mask) {
967 for (i = 0; i < n; i++) {
968 if (mask[i]) {
969 ptr4[i] = rgba4[i];
970 }
971 }
972 }
973 else {
974 MEMCPY( ptr4, rgba4, n * 4 );
975 }
976 }
977
978
979 /* Write RGB pixels to an RGBA (or permuted) buffer. */
980 static void
981 write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
982 CONST GLchan rgb[][3], const GLubyte mask[] )
983 {
984 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
985 GLchan *p = PIXELADDR4(x, y);
986 GLuint i;
987 if (mask) {
988 for (i = 0; i < n; i++, p+=4) {
989 if (mask[i]) {
990 PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
991 }
992 }
993 }
994 else {
995 for (i = 0; i < n; i++, p+=4) {
996 PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX);
997 }
998 }
999 }
1000
1001
1002
1003 static void
1004 write_monocolor_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1005 const GLchan color[4], const GLubyte mask[] )
1006 {
1007 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1008 GLchan *p = PIXELADDR4(x, y);
1009 GLuint i;
1010 for (i = 0; i < n; i++, p += 4) {
1011 if (mask[i]) {
1012 PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
1013 }
1014 }
1015 }
1016
1017
1018
1019 static void
1020 write_rgba_pixels( const GLcontext *ctx, GLuint n,
1021 const GLint x[], const GLint y[],
1022 CONST GLchan rgba[][4], const GLubyte mask[] )
1023 {
1024 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1025 GLuint i;
1026 for (i = 0; i < n; i++) {
1027 if (mask[i]) {
1028 GLchan *p = PIXELADDR4(x[i], y[i]);
1029 PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP],
1030 rgba[i][BCOMP], rgba[i][ACOMP]);
1031 }
1032 }
1033 }
1034
1035
1036
1037 static void
1038 write_monocolor_pixels( const GLcontext *ctx, GLuint n,
1039 const GLint x[], const GLint y[],
1040 const GLchan color[4], const GLubyte mask[] )
1041 {
1042 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1043 GLuint i;
1044 for (i = 0; i < n; i++) {
1045 if (mask[i]) {
1046 GLchan *p = PIXELADDR4(x[i], y[i]);
1047 PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]);
1048 }
1049 }
1050 }
1051
1052
1053 static void
1054 read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1055 GLchan rgba[][4] )
1056 {
1057 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1058 GLuint i;
1059 GLchan *p = PIXELADDR4(x, y);
1060 for (i = 0; i < n; i++, p += 4) {
1061 rgba[i][RCOMP] = UNPACK_RED(p);
1062 rgba[i][GCOMP] = UNPACK_GREEN(p);
1063 rgba[i][BCOMP] = UNPACK_BLUE(p);
1064 rgba[i][ACOMP] = UNPACK_ALPHA(p);
1065 }
1066 }
1067
1068
1069 /* Read RGBA pixels from an RGBA buffer */
1070 static void
1071 read_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1072 GLchan rgba[][4] )
1073 {
1074 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1075 GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y);
1076 MEMCPY( rgba, ptr4, n * 4 * sizeof(GLchan) );
1077 }
1078
1079
1080 static void
1081 read_rgba_pixels( const GLcontext *ctx,
1082 GLuint n, const GLint x[], const GLint y[],
1083 GLchan rgba[][4], const GLubyte mask[] )
1084 {
1085 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1086 GLuint i;
1087 for (i = 0; i < n; i++) {
1088 if (mask[i]) {
1089 const GLchan *p = PIXELADDR4(x[i], y[i]);
1090 rgba[i][RCOMP] = UNPACK_RED(p);
1091 rgba[i][GCOMP] = UNPACK_GREEN(p);
1092 rgba[i][BCOMP] = UNPACK_BLUE(p);
1093 rgba[i][ACOMP] = UNPACK_ALPHA(p);
1094 }
1095 }
1096 }
1097
1098 /**********************************************************************/
1099 /***** 3 byte RGB pixel support funcs *****/
1100 /**********************************************************************/
1101
1102 /* Write RGBA pixels to an RGB buffer. */
1103 static void
1104 write_rgba_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1105 CONST GLchan rgba[][4], const GLubyte mask[] )
1106 {
1107 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1108 GLchan *p = PIXELADDR3(x, y);
1109 GLuint i;
1110 if (mask) {
1111 for (i = 0; i < n; i++, p += 3) {
1112 if (mask[i]) {
1113 PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1114 }
1115 }
1116 }
1117 else {
1118 for (i = 0; i < n; i++, p += 3) {
1119 PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1120 }
1121 }
1122 }
1123
1124 /* Write RGBA pixels to an BGR buffer. */
1125 static void
1126 write_rgba_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1127 CONST GLchan rgba[][4], const GLubyte mask[] )
1128 {
1129 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1130 GLchan *p = PIXELADDR3(x, y);
1131 GLuint i;
1132 if (mask) {
1133 for (i = 0; i < n; i++, p += 3) {
1134 if (mask[i]) {
1135 PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1136 }
1137 }
1138 }
1139 else {
1140 for (i = 0; i < n; i++, p += 3) {
1141 PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1142 }
1143 }
1144 }
1145
1146 /* Write RGB pixels to an RGB buffer. */
1147 static void
1148 write_rgb_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1149 CONST GLchan rgb[][3], const GLubyte mask[] )
1150 {
1151 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1152 GLchan *p = PIXELADDR3(x, y);
1153 GLuint i;
1154 if (mask) {
1155 for (i = 0; i < n; i++, p += 3) {
1156 if (mask[i]) {
1157 PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1158 }
1159 }
1160 }
1161 else {
1162 for (i = 0; i < n; i++, p += 3) {
1163 PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1164 }
1165 }
1166 }
1167
1168 /* Write RGB pixels to an BGR buffer. */
1169 static void
1170 write_rgb_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1171 CONST GLchan rgb[][3], const GLubyte mask[] )
1172 {
1173 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1174 GLchan *p = PIXELADDR3(x, y);
1175 GLuint i;
1176 if (mask) {
1177 for (i = 0; i < n; i++, p += 3) {
1178 if (mask[i]) {
1179 PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1180 }
1181 }
1182 }
1183 else {
1184 for (i = 0; i < n; i++, p += 3) {
1185 PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1186 }
1187 }
1188 }
1189
1190
1191 static void
1192 write_monocolor_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1193 const GLchan color[4], const GLubyte mask[] )
1194 {
1195 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1196 GLchan *p = PIXELADDR3(x, y);
1197 GLuint i;
1198 for (i = 0; i < n; i++, p += 3) {
1199 if (mask[i]) {
1200 PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1201 }
1202 }
1203 }
1204
1205 static void
1206 write_monocolor_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1207 const GLchan color[4], const GLubyte mask[] )
1208 {
1209 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1210 GLchan *p = PIXELADDR3(x, y);
1211 GLuint i;
1212 for (i = 0; i < n; i++, p += 3) {
1213 if (mask[i]) {
1214 PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1215 }
1216 }
1217 }
1218
1219 static void
1220 write_rgba_pixels_RGB( const GLcontext *ctx, GLuint n,
1221 const GLint x[], const GLint y[],
1222 CONST GLchan rgba[][4], const GLubyte mask[] )
1223 {
1224 const OSMesaContext osmesa = (const OSMesaContext) ctx;
1225 GLuint i;
1226 for (i = 0; i < n; i++) {
1227 if (mask[i]) {
1228 GLchan *p = PIXELADDR3(x[i], y[i]);
1229 PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1230 }
1231 }
1232 }
1233
1234 static void
1235 write_rgba_pixels_BGR( const GLcontext *ctx, GLuint n,
1236 const GLint x[], const GLint y[],
1237 CONST GLchan rgba[][4], const GLubyte mask[] )
1238 {
1239 const OSMesaContext osmesa = (const OSMesaContext) ctx;
1240 GLuint i;
1241 for (i = 0; i < n; i++) {
1242 if (mask[i]) {
1243 GLchan *p = PIXELADDR3(x[i], y[i]);
1244 PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1245 }
1246 }
1247 }
1248
1249 static void
1250 write_monocolor_pixels_RGB( const GLcontext *ctx,
1251 GLuint n, const GLint x[], const GLint y[],
1252 const GLchan color[4], const GLubyte mask[] )
1253 {
1254 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1255 GLuint i;
1256 for (i = 0; i < n; i++) {
1257 if (mask[i]) {
1258 GLchan *p = PIXELADDR3(x[i], y[i]);
1259 PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1260 }
1261 }
1262 }
1263
1264 static void
1265 write_monocolor_pixels_BGR( const GLcontext *ctx,
1266 GLuint n, const GLint x[], const GLint y[],
1267 const GLchan color[4], const GLubyte mask[] )
1268 {
1269 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1270 GLuint i;
1271 for (i = 0; i < n; i++) {
1272 if (mask[i]) {
1273 GLchan *p = PIXELADDR3(x[i], y[i]);
1274 PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]);
1275 }
1276 }
1277 }
1278
1279 static void
1280 read_rgba_span3( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1281 GLchan rgba[][4] )
1282 {
1283 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1284 GLuint i;
1285 const GLchan *p = PIXELADDR3(x, y);
1286 for (i = 0; i < n; i++, p += 3) {
1287 rgba[i][RCOMP] = UNPACK_RED(p);
1288 rgba[i][GCOMP] = UNPACK_GREEN(p);
1289 rgba[i][BCOMP] = UNPACK_BLUE(p);
1290 rgba[i][ACOMP] = CHAN_MAX;
1291 }
1292 }
1293
1294 static void
1295 read_rgba_pixels3( const GLcontext *ctx,
1296 GLuint n, const GLint x[], const GLint y[],
1297 GLchan rgba[][4], const GLubyte mask[] )
1298 {
1299 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1300 GLuint i;
1301 for (i = 0; i < n; i++) {
1302 if (mask[i]) {
1303 const GLchan *p = PIXELADDR3(x[i], y[i]);
1304 rgba[i][RCOMP] = UNPACK_RED(p);
1305 rgba[i][GCOMP] = UNPACK_GREEN(p);
1306 rgba[i][BCOMP] = UNPACK_BLUE(p);
1307 rgba[i][ACOMP] = CHAN_MAX;
1308 }
1309 }
1310 }
1311
1312
1313 /**********************************************************************/
1314 /***** 2 byte RGB pixel support funcs *****/
1315 /**********************************************************************/
1316
1317 /* Write RGBA pixels to an RGB_565 buffer. */
1318 static void
1319 write_rgba_span2( const GLcontext *ctx,
1320 GLuint n, GLint x, GLint y,
1321 CONST GLchan rgba[][4], const GLubyte mask[] )
1322 {
1323 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1324 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
1325 GLuint i;
1326 if (mask) {
1327 for (i = 0; i < n; i++, ptr2++) {
1328 if (mask[i]) {
1329 PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1330 }
1331 }
1332 }
1333 else {
1334 for (i = 0; i < n; i++, ptr2++) {
1335 PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1336 }
1337 }
1338 }
1339
1340
1341 /* Write RGB pixels to an RGB_565 buffer. */
1342 static void
1343 write_rgb_span2( const GLcontext *ctx,
1344 GLuint n, GLint x, GLint y,
1345 CONST GLchan rgb[][3], const GLubyte mask[] )
1346 {
1347 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1348 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
1349 GLuint i;
1350 if (mask) {
1351 for (i = 0; i < n; i++, ptr2++) {
1352 if (mask[i]) {
1353 PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1354 }
1355 }
1356 }
1357 else {
1358 for (i = 0; i < n; i++, ptr2++) {
1359 PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1360 }
1361 }
1362 }
1363
1364
1365 static void
1366 write_monocolor_span2( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1367 const GLchan color[4], const GLubyte mask[] )
1368 {
1369 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1370 GLushort pixel;
1371 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y);
1372 GLuint i;
1373 PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
1374 for (i = 0; i < n; i++, ptr2++) {
1375 if (mask[i]) {
1376 *ptr2 = pixel;
1377 }
1378 }
1379 }
1380
1381
1382 static void
1383 write_rgba_pixels2( const GLcontext *ctx,
1384 GLuint n, const GLint x[], const GLint y[],
1385 CONST GLchan rgba[][4], const GLubyte mask[] )
1386 {
1387 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1388 GLuint i;
1389 for (i = 0; i < n; i++) {
1390 if (mask[i]) {
1391 GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
1392 PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1393 }
1394 }
1395 }
1396
1397 static void
1398 write_monocolor_pixels2( const GLcontext *ctx,
1399 GLuint n, const GLint x[], const GLint y[],
1400 const GLchan color[4], const GLubyte mask[] )
1401 {
1402 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1403 GLuint i;
1404 GLushort pixel;
1405 PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]);
1406 for (i = 0; i < n; i++) {
1407 if (mask[i]) {
1408 GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]);
1409 *ptr2 = pixel;
1410 }
1411 }
1412 }
1413
1414 static void
1415 read_rgba_span2( const GLcontext *ctx,
1416 GLuint n, GLint x, GLint y,
1417 GLchan rgba[][4] )
1418 {
1419 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1420 GLuint i;
1421 const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x, y);
1422 for (i = 0; i < n; i++, ptr2++) {
1423 /* This should be fixed to get the low bits right */
1424 rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFe;
1425 rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFc;
1426 rgba[i][BCOMP] = (*ptr2 << 3) & 0xFe;
1427 rgba[i][ACOMP] = 0;
1428 }
1429 }
1430
1431 static void
1432 read_rgba_pixels2( const GLcontext *ctx,
1433 GLuint n, const GLint x[], const GLint y[],
1434 GLchan rgba[][4], const GLubyte mask[] )
1435 {
1436 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1437 GLuint i;
1438 for (i = 0; i < n; i++) {
1439 if (mask[i]) {
1440 /* This should be fixed to get the low bits right */
1441 const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x[i],y[i]);
1442 rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFE;
1443 rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFC;
1444 rgba[i][BCOMP] = (*ptr2 << 3) & 0xFE;
1445 rgba[i][ACOMP] = 0;
1446 }
1447 }
1448 }
1449
1450
1451
1452 /**********************************************************************/
1453 /***** Read/write spans/arrays of CI pixels *****/
1454 /**********************************************************************/
1455
1456 /* Write 32-bit color index to buffer */
1457 static void
1458 write_index32_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1459 const GLuint index[], const GLubyte mask[] )
1460 {
1461 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1462 GLchan *ptr1 = PIXELADDR1(x, y);
1463 GLuint i;
1464 if (mask) {
1465 for (i=0;i<n;i++,ptr1++) {
1466 if (mask[i]) {
1467 *ptr1 = (GLchan) index[i];
1468 }
1469 }
1470 }
1471 else {
1472 for (i=0;i<n;i++,ptr1++) {
1473 *ptr1 = (GLchan) index[i];
1474 }
1475 }
1476 }
1477
1478
1479 /* Write 8-bit color index to buffer */
1480 static void
1481 write_index8_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1482 const GLubyte index[], const GLubyte mask[] )
1483 {
1484 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1485 GLchan *ptr1 = PIXELADDR1(x, y);
1486 GLuint i;
1487 if (mask) {
1488 for (i=0;i<n;i++,ptr1++) {
1489 if (mask[i]) {
1490 *ptr1 = (GLchan) index[i];
1491 }
1492 }
1493 }
1494 else {
1495 MEMCPY(ptr1, index, n * sizeof(GLchan));
1496 }
1497 }
1498
1499
1500 static void
1501 write_monoindex_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
1502 GLuint colorIndex, const GLubyte mask[] )
1503 {
1504 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1505 GLchan *ptr1 = PIXELADDR1(x, y);
1506 GLuint i;
1507 for (i=0;i<n;i++,ptr1++) {
1508 if (mask[i]) {
1509 *ptr1 = (GLchan) colorIndex;
1510 }
1511 }
1512 }
1513
1514
1515 static void
1516 write_index_pixels( const GLcontext *ctx,
1517 GLuint n, const GLint x[], const GLint y[],
1518 const GLuint index[], const GLubyte mask[] )
1519 {
1520 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1521 GLuint i;
1522 for (i=0;i<n;i++) {
1523 if (mask[i]) {
1524 GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1525 *ptr1 = (GLchan) index[i];
1526 }
1527 }
1528 }
1529
1530
1531 static void
1532 write_monoindex_pixels( const GLcontext *ctx,
1533 GLuint n, const GLint x[], const GLint y[],
1534 GLuint colorIndex, const GLubyte mask[] )
1535 {
1536 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1537 GLuint i;
1538 for (i=0;i<n;i++) {
1539 if (mask[i]) {
1540 GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1541 *ptr1 = (GLchan) colorIndex;
1542 }
1543 }
1544 }
1545
1546
1547 static void
1548 read_index_span( const GLcontext *ctx,
1549 GLuint n, GLint x, GLint y, GLuint index[] )
1550 {
1551 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1552 GLuint i;
1553 const GLchan *ptr1 = (const GLchan *) PIXELADDR1(x, y);
1554 for (i=0;i<n;i++,ptr1++) {
1555 index[i] = (GLuint) *ptr1;
1556 }
1557 }
1558
1559
1560 static void
1561 read_index_pixels( const GLcontext *ctx,
1562 GLuint n, const GLint x[], const GLint y[],
1563 GLuint index[], const GLubyte mask[] )
1564 {
1565 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1566 GLuint i;
1567 for (i=0;i<n;i++) {
1568 if (mask[i] ) {
1569 const GLchan *ptr1 = PIXELADDR1(x[i], y[i]);
1570 index[i] = (GLuint) *ptr1;
1571 }
1572 }
1573 }
1574
1575
1576
1577 /**********************************************************************/
1578 /***** Optimized line rendering *****/
1579 /**********************************************************************/
1580
1581
1582 /*
1583 * Draw a flat-shaded, RGB line into an osmesa buffer.
1584 */
1585 static void
1586 flat_rgba_line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
1587 {
1588 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1589 const GLchan *color = vert1->color;
1590
1591 #define INTERP_XY 1
1592 #define CLIP_HACK 1
1593 #define PLOT(X, Y) \
1594 do { \
1595 GLchan *p = PIXELADDR4(X, Y); \
1596 PACK_RGBA(p, color[0], color[1], color[2], color[3]); \
1597 } while (0)
1598
1599 #ifdef WIN32
1600 #include "..\swrast\s_linetemp.h"
1601 #else
1602 #include "swrast/s_linetemp.h"
1603 #endif
1604 }
1605
1606
1607 /*
1608 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1609 */
1610 static void
1611 flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1)
1612 {
1613 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1614 const GLchan *color = vert1->color;
1615
1616 #define INTERP_XY 1
1617 #define INTERP_Z 1
1618 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1619 #define CLIP_HACK 1
1620 #define PLOT(X, Y) \
1621 do { \
1622 if (Z < *zPtr) { \
1623 GLchan *p = PIXELADDR4(X, Y); \
1624 PACK_RGBA(p, color[RCOMP], color[GCOMP], \
1625 color[BCOMP], color[ACOMP]); \
1626 *zPtr = Z; \
1627 } \
1628 } while (0)
1629
1630
1631 #ifdef WIN32
1632 #include "..\swrast\s_linetemp.h"
1633 #else
1634 #include "swrast/s_linetemp.h"
1635 #endif
1636 }
1637
1638
1639 /*
1640 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1641 * XXX update for GLchan
1642 */
1643 static void
1644 flat_blend_rgba_line( GLcontext *ctx,
1645 const SWvertex *vert0, const SWvertex *vert1 )
1646 {
1647 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1648 const GLint rshift = osmesa->rshift;
1649 const GLint gshift = osmesa->gshift;
1650 const GLint bshift = osmesa->bshift;
1651 const GLint avalue = vert0->color[3];
1652 const GLint msavalue = CHAN_MAX - avalue;
1653 const GLint rvalue = vert1->color[0]*avalue;
1654 const GLint gvalue = vert1->color[1]*avalue;
1655 const GLint bvalue = vert1->color[2]*avalue;
1656
1657 #define INTERP_XY 1
1658 #define CLIP_HACK 1
1659 #define PLOT(X,Y) \
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 #if 0 /* XXX use this in the future */
1669 #define PLOT(X,Y) \
1670 { \
1671 GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
1672 pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
1673 pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
1674 pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
1675 pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
1676 }
1677 #endif
1678
1679 #ifdef WIN32
1680 #include "..\swrast\s_linetemp.h"
1681 #else
1682 #include "swrast/s_linetemp.h"
1683 #endif
1684 }
1685
1686
1687 /*
1688 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1689 * But don't write to Z buffer.
1690 * XXX update for GLchan
1691 */
1692 static void
1693 flat_blend_rgba_z_line( GLcontext *ctx,
1694 const SWvertex *vert0, const SWvertex *vert1 )
1695 {
1696 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1697 const GLint rshift = osmesa->rshift;
1698 const GLint gshift = osmesa->gshift;
1699 const GLint bshift = osmesa->bshift;
1700 const GLint avalue = vert0->color[3];
1701 const GLint msavalue = 256 - avalue;
1702 const GLint rvalue = vert1->color[0]*avalue;
1703 const GLint gvalue = vert1->color[1]*avalue;
1704 const GLint bvalue = vert1->color[2]*avalue;
1705
1706 #define INTERP_XY 1
1707 #define INTERP_Z 1
1708 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1709 #define CLIP_HACK 1
1710 #define PLOT(X,Y) \
1711 if (Z < *zPtr) { \
1712 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
1713 GLuint pixel = 0; \
1714 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1715 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1716 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1717 *ptr4 = pixel; \
1718 }
1719
1720 #if 0 /* XXX use this in the future */
1721 #define PLOT(X,Y) \
1722 if (Z < *zPtr) { \
1723 GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
1724 pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
1725 pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
1726 pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
1727 pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
1728 }
1729 #endif
1730
1731 #ifdef WIN32
1732 #include "..\swrast\s_linetemp.h"
1733 #else
1734 #include "swrast/s_linetemp.h"
1735 #endif
1736 }
1737
1738
1739 /*
1740 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1741 * XXX update for GLchan
1742 */
1743 static void
1744 flat_blend_rgba_z_line_write( GLcontext *ctx,
1745 const SWvertex *vert0, const SWvertex *vert1 )
1746 {
1747 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1748 const GLint rshift = osmesa->rshift;
1749 const GLint gshift = osmesa->gshift;
1750 const GLint bshift = osmesa->bshift;
1751 const GLint avalue = vert0->color[3];
1752 const GLint msavalue = 256 - avalue;
1753 const GLint rvalue = vert1->color[0]*avalue;
1754 const GLint gvalue = vert1->color[1]*avalue;
1755 const GLint bvalue = vert1->color[2]*avalue;
1756
1757 #define INTERP_XY 1
1758 #define INTERP_Z 1
1759 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1760 #define CLIP_HACK 1
1761 #define PLOT(X,Y) \
1762 if (Z < *zPtr) { \
1763 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
1764 GLuint pixel = 0; \
1765 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1766 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1767 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1768 *ptr4 = pixel; \
1769 *zPtr = Z; \
1770 }
1771
1772 #if 0 /* XXX use this in the future */
1773 #define PLOT(X,Y) \
1774 if (Z < *zPtr) { \
1775 GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \
1776 pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \
1777 pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \
1778 pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \
1779 pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \
1780 *zPtr = Z; \
1781 }
1782 #endif
1783
1784 #ifdef WIN32
1785 #include "..\swrast\s_linetemp.h"
1786 #else
1787 #include "swrast/s_linetemp.h"
1788 #endif
1789 }
1790
1791
1792 /*
1793 * Analyze context state to see if we can provide a fast line drawing
1794 * function, like those in lines.c. Otherwise, return NULL.
1795 */
1796 static swrast_line_func
1797 osmesa_choose_line_function( GLcontext *ctx )
1798 {
1799 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1800 const SWcontext *swrast = SWRAST_CONTEXT(ctx);
1801
1802 if (CHAN_BITS != 8) return NULL;
1803 if (ctx->RenderMode != GL_RENDER) return NULL;
1804 if (ctx->Line.SmoothFlag) return NULL;
1805 if (ctx->Texture._ReallyEnabled) return NULL;
1806 if (ctx->Light.ShadeModel != GL_FLAT) return NULL;
1807 if (ctx->Line.Width != 1.0F) return NULL;
1808 if (ctx->Line.StippleFlag) return NULL;
1809 if (ctx->Line.SmoothFlag) return NULL;
1810 if (osmesa->format != OSMESA_RGBA &&
1811 osmesa->format != OSMESA_BGRA &&
1812 osmesa->format != OSMESA_ARGB) return NULL;
1813
1814 if (swrast->_RasterMask==DEPTH_BIT
1815 && ctx->Depth.Func==GL_LESS
1816 && ctx->Depth.Mask==GL_TRUE
1817 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
1818 return (swrast_line_func) flat_rgba_z_line;
1819 }
1820
1821 if (swrast->_RasterMask == 0) {
1822 return (swrast_line_func) flat_rgba_line;
1823 }
1824
1825 if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
1826 && ctx->Depth.Func==GL_LESS
1827 && ctx->Depth.Mask==GL_TRUE
1828 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1829 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1830 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1831 && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1832 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1833 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1834 return (swrast_line_func) flat_blend_rgba_z_line_write;
1835 }
1836
1837 if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT)
1838 && ctx->Depth.Func==GL_LESS
1839 && ctx->Depth.Mask==GL_FALSE
1840 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1841 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1842 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1843 && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1844 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1845 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1846 return (swrast_line_func) flat_blend_rgba_z_line;
1847 }
1848
1849 if (swrast->_RasterMask==BLEND_BIT
1850 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1851 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1852 && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1853 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1854 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1855 return (swrast_line_func) flat_blend_rgba_line;
1856 }
1857
1858 return (swrast_line_func) NULL;
1859 }
1860
1861
1862 /**********************************************************************/
1863 /***** Optimized triangle rendering *****/
1864 /**********************************************************************/
1865
1866
1867 /*
1868 * Smooth-shaded, z-less triangle, RGBA color.
1869 */
1870 static void smooth_rgba_z_triangle( GLcontext *ctx,
1871 const SWvertex *v0,
1872 const SWvertex *v1,
1873 const SWvertex *v2 )
1874 {
1875 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1876
1877 #define INTERP_Z 1
1878 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1879 #define INTERP_RGB 1
1880 #define INTERP_ALPHA 1
1881 #define RENDER_SPAN( span ) \
1882 GLuint i; \
1883 GLchan *img = PIXELADDR4(span->x, span->y); \
1884 for (i = 0; i < span->end; i++, img += 4) { \
1885 const GLdepth z = FixedToDepth(span->z); \
1886 if (z < zRow[i]) { \
1887 PACK_RGBA(img, FixedToChan(span->red), \
1888 FixedToChan(span->green), FixedToChan(span->blue), \
1889 FixedToChan(span->alpha)); \
1890 zRow[i] = z; \
1891 } \
1892 span->red += span->redStep; \
1893 span->green += span->greenStep; \
1894 span->blue += span->blueStep; \
1895 span->alpha += span->alphaStep; \
1896 span->z += span->zStep; \
1897 }
1898
1899 #ifdef WIN32
1900 #include "..\swrast\s_tritemp.h"
1901 #else
1902 #include "swrast/s_tritemp.h"
1903 #endif
1904 }
1905
1906
1907
1908
1909 /*
1910 * Flat-shaded, z-less triangle, RGBA color.
1911 */
1912 static void flat_rgba_z_triangle( GLcontext *ctx,
1913 const SWvertex *v0,
1914 const SWvertex *v1,
1915 const SWvertex *v2 )
1916 {
1917 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1918 #define INTERP_Z 1
1919 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1920 #define SETUP_CODE \
1921 GLuint pixel; \
1922 PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1], \
1923 v2->color[2], v2->color[3]);
1924
1925 #define RENDER_SPAN( span ) \
1926 GLuint i; \
1927 GLuint *img = (GLuint *) PIXELADDR4(span->x, span->y); \
1928 for (i = 0; i < span->end; i++) { \
1929 const GLdepth z = FixedToDepth(span->z); \
1930 if (z < zRow[i]) { \
1931 img[i] = pixel; \
1932 zRow[i] = z; \
1933 } \
1934 span->z += span->zStep; \
1935 }
1936
1937 #ifdef WIN32
1938 #include "..\swrast\s_tritemp.h"
1939 #else
1940 #include "swrast/s_tritemp.h"
1941 #endif
1942 }
1943
1944
1945
1946 /*
1947 * Return pointer to an accelerated triangle function if possible.
1948 */
1949 static swrast_tri_func
1950 osmesa_choose_triangle_function( GLcontext *ctx )
1951 {
1952 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
1953 const SWcontext *swrast = SWRAST_CONTEXT(ctx);
1954
1955 if (CHAN_BITS != 8) return (swrast_tri_func) NULL;
1956 if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL;
1957 if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL;
1958 if (ctx->Polygon.StippleFlag) return (swrast_tri_func) NULL;
1959 if (ctx->Texture._ReallyEnabled) return (swrast_tri_func) NULL;
1960 if (osmesa->format != OSMESA_RGBA &&
1961 osmesa->format != OSMESA_BGRA &&
1962 osmesa->format != OSMESA_ARGB) return (swrast_tri_func) NULL;
1963
1964 if (swrast->_RasterMask == DEPTH_BIT &&
1965 ctx->Depth.Func == GL_LESS &&
1966 ctx->Depth.Mask == GL_TRUE &&
1967 ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
1968 if (ctx->Light.ShadeModel == GL_SMOOTH) {
1969 return (swrast_tri_func) smooth_rgba_z_triangle;
1970 }
1971 else {
1972 return (swrast_tri_func) flat_rgba_z_triangle;
1973 }
1974 }
1975 return (swrast_tri_func) NULL;
1976 }
1977
1978
1979
1980 /* Override for the swrast triangle-selection function. Try to use one
1981 * of our internal triangle functions, otherwise fall back to the
1982 * standard swrast functions.
1983 */
1984 static void osmesa_choose_triangle( GLcontext *ctx )
1985 {
1986 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1987
1988 swrast->Triangle = osmesa_choose_triangle_function( ctx );
1989 if (!swrast->Triangle)
1990 _swrast_choose_triangle( ctx );
1991 }
1992
1993 static void osmesa_choose_line( GLcontext *ctx )
1994 {
1995 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1996
1997 swrast->Line = osmesa_choose_line_function( ctx );
1998 if (!swrast->Line)
1999 _swrast_choose_line( ctx );
2000 }
2001
2002
2003 #define OSMESA_NEW_LINE (_NEW_LINE | \
2004 _NEW_TEXTURE | \
2005 _NEW_LIGHT | \
2006 _NEW_DEPTH | \
2007 _NEW_RENDERMODE | \
2008 _SWRAST_NEW_RASTERMASK)
2009
2010 #define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \
2011 _NEW_TEXTURE | \
2012 _NEW_LIGHT | \
2013 _NEW_DEPTH | \
2014 _NEW_RENDERMODE | \
2015 _SWRAST_NEW_RASTERMASK)
2016
2017
2018 /* Extend the software rasterizer with our line and triangle
2019 * functions.
2020 */
2021 static void osmesa_register_swrast_functions( GLcontext *ctx )
2022 {
2023 SWcontext *swrast = SWRAST_CONTEXT( ctx );
2024
2025 swrast->choose_line = osmesa_choose_line;
2026 swrast->choose_triangle = osmesa_choose_triangle;
2027
2028 swrast->invalidate_line |= OSMESA_NEW_LINE;
2029 swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE;
2030 }
2031
2032
2033 static const GLubyte *get_string( GLcontext *ctx, GLenum name )
2034 {
2035 (void) ctx;
2036 switch (name) {
2037 case GL_RENDERER:
2038 #if CHAN_BITS == 32
2039 return (const GLubyte *) "Mesa OffScreen32";
2040 #elif CHAN_BITS == 16
2041 return (const GLubyte *) "Mesa OffScreen16";
2042 #else
2043 return (const GLubyte *) "Mesa OffScreen";
2044 #endif
2045 default:
2046 return NULL;
2047 }
2048 }
2049
2050
2051 static void osmesa_update_state( GLcontext *ctx, GLuint new_state )
2052 {
2053 OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
2054 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
2055 TNLcontext *tnl = TNL_CONTEXT(ctx);
2056
2057 ASSERT((void *) osmesa == (void *) ctx->DriverCtx);
2058
2059 /*
2060 * XXX these function pointers could be initialized just once during
2061 * context creation since they don't depend on any state changes.
2062 */
2063
2064 ctx->Driver.GetString = get_string;
2065 ctx->Driver.UpdateState = osmesa_update_state;
2066 ctx->Driver.SetDrawBuffer = set_draw_buffer;
2067 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
2068 ctx->Driver.GetBufferSize = buffer_size;
2069
2070 ctx->Driver.Accum = _swrast_Accum;
2071 ctx->Driver.Bitmap = _swrast_Bitmap;
2072 ctx->Driver.Clear = clear;
2073 ctx->Driver.CopyPixels = _swrast_CopyPixels;
2074 ctx->Driver.DrawPixels = _swrast_DrawPixels;
2075 ctx->Driver.ReadPixels = _swrast_ReadPixels;
2076
2077 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
2078 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
2079 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
2080 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
2081 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
2082 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
2083 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
2084 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
2085
2086 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
2087 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
2088 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
2089 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
2090 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
2091 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
2092 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
2093 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
2094 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
2095
2096 ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
2097 ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
2098 ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
2099
2100 /* RGB(A) span/pixel functions */
2101 if (osmesa->format == OSMESA_RGB) {
2102 swdd->WriteRGBASpan = write_rgba_span_RGB;
2103 swdd->WriteRGBSpan = write_rgb_span_RGB;
2104 swdd->WriteMonoRGBASpan = write_monocolor_span_RGB;
2105 swdd->WriteRGBAPixels = write_rgba_pixels_RGB;
2106 swdd->WriteMonoRGBAPixels = write_monocolor_pixels_RGB;
2107 swdd->ReadRGBASpan = read_rgba_span3;
2108 swdd->ReadRGBAPixels = read_rgba_pixels3;
2109 }
2110 else if (osmesa->format == OSMESA_BGR) {
2111 swdd->WriteRGBASpan = write_rgba_span_BGR;
2112 swdd->WriteRGBSpan = write_rgb_span_BGR;
2113 swdd->WriteMonoRGBASpan = write_monocolor_span_BGR;
2114 swdd->WriteRGBAPixels = write_rgba_pixels_BGR;
2115 swdd->WriteMonoRGBAPixels = write_monocolor_pixels_BGR;
2116 swdd->ReadRGBASpan = read_rgba_span3;
2117 swdd->ReadRGBAPixels = read_rgba_pixels3;
2118 }
2119 else if (osmesa->format == OSMESA_RGB_565) {
2120 swdd->WriteRGBASpan = write_rgba_span2;
2121 swdd->WriteRGBSpan = write_rgb_span2;
2122 swdd->WriteMonoRGBASpan = write_monocolor_span2;
2123 swdd->WriteRGBAPixels = write_rgba_pixels2;
2124 swdd->WriteMonoRGBAPixels = write_monocolor_pixels2;
2125 swdd->ReadRGBASpan = read_rgba_span2;
2126 swdd->ReadRGBAPixels = read_rgba_pixels2;
2127 }
2128 else {
2129 /* 4 GLchan / pixel in frame buffer */
2130 swdd->WriteRGBSpan = write_rgb_span;
2131 swdd->WriteRGBAPixels = write_rgba_pixels;
2132 swdd->WriteMonoRGBASpan = write_monocolor_span;
2133 swdd->WriteMonoRGBAPixels = write_monocolor_pixels;
2134 if (osmesa->format == OSMESA_RGBA &&
2135 CHAN_TYPE == GL_UNSIGNED_BYTE &&
2136 RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3) {
2137 /* special, fast case */
2138 swdd->WriteRGBASpan = write_rgba_span_rgba;
2139 swdd->ReadRGBASpan = read_rgba_span_rgba;
2140 }
2141 else {
2142 swdd->WriteRGBASpan = write_rgba_span;
2143 swdd->ReadRGBASpan = read_rgba_span;
2144 }
2145 swdd->ReadRGBAPixels = read_rgba_pixels;
2146 }
2147
2148 /* CI span/pixel functions */
2149 swdd->WriteCI32Span = write_index32_span;
2150 swdd->WriteCI8Span = write_index8_span;
2151 swdd->WriteMonoCISpan = write_monoindex_span;
2152 swdd->WriteCI32Pixels = write_index_pixels;
2153 swdd->WriteMonoCIPixels = write_monoindex_pixels;
2154 swdd->ReadCI32Span = read_index_span;
2155 swdd->ReadCI32Pixels = read_index_pixels;
2156
2157 swdd->SetReadBuffer = set_read_buffer;
2158
2159 tnl->Driver.RunPipeline = _tnl_run_pipeline;
2160
2161 _swrast_InvalidateState( ctx, new_state );
2162 _swsetup_InvalidateState( ctx, new_state );
2163 _ac_InvalidateState( ctx, new_state );
2164 _tnl_InvalidateState( ctx, new_state );
2165 }