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