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