1 /* $Id: osmesa.c,v 1.11 2000/03/17 15:32:29 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
29 * Off-Screen Mesa rendering / Rendering into client memory space
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 gl_make_current() and gl_get_current_context()
34 * functions. Those functions are thread-safe.
43 #include "GL/osmesa.h"
54 * This is the OS/Mesa context struct.
55 * Notice how it includes a GLcontext. By doing this we're mimicking
56 * C++ inheritance/derivation.
57 * Later, we can cast a GLcontext pointer into an OSMesaContext pointer
60 struct osmesa_context
{
61 GLcontext gl_ctx
; /* The core GL/Mesa context */
62 GLvisual
*gl_visual
; /* Describes the buffers */
63 GLframebuffer
*gl_buffer
; /* Depth, stencil, accum, etc buffers */
64 GLenum format
; /* either GL_RGBA or GL_COLOR_INDEX */
65 void *buffer
; /* the image buffer */
66 GLint width
, height
; /* size of image buffer */
67 GLuint pixel
; /* current color index or RGBA pixel value */
68 GLuint clearpixel
; /* pixel for clearing the color buffer */
69 GLint rowlength
; /* number of pixels per row */
70 GLint userRowLength
; /* user-specified number of pixels per row */
71 GLint rshift
, gshift
; /* bit shifts for RGBA formats */
73 GLint rind
, gind
, bind
; /* index offsets for RGBA formats */
74 void *rowaddr
[MAX_HEIGHT
]; /* address of first pixel in each image row */
75 GLboolean yup
; /* TRUE -> Y increases upward */
76 /* FALSE -> Y increases downward */
77 GLboolean bVisible
; /* TRUE if geometry is visible */
82 /* A forward declaration: */
83 static void osmesa_update_state( GLcontext
*ctx
);
87 /**********************************************************************/
88 /***** Public Functions *****/
89 /**********************************************************************/
93 * Create an Off-Screen Mesa rendering context. The only attribute needed is
94 * an RGBA vs Color-Index mode flag.
96 * Input: format - either GL_RGBA or GL_COLOR_INDEX
97 * sharelist - specifies another OSMesaContext with which to share
98 * display lists. NULL indicates no sharing.
99 * Return: an OSMesaContext or 0 if error
101 OSMesaContext GLAPIENTRY
102 OSMesaCreateContext( GLenum format
, OSMesaContext sharelist
)
104 OSMesaContext osmesa
;
105 GLint rshift
, gshift
, bshift
, ashift
;
106 GLint rind
, gind
, bind
;
107 GLint indexBits
, alphaBits
;
111 GLubyte
*i1
= (GLubyte
*) &i4
;
112 GLint little_endian
= *i1
;
115 rind
= gind
= bind
= 0;
116 if (format
==OSMESA_COLOR_INDEX
) {
118 rshift
= gshift
= bshift
= ashift
= 0;
121 else if (format
==OSMESA_RGBA
) {
138 else if (format
==OSMESA_BGRA
) {
155 else if (format
==OSMESA_ARGB
) {
172 else if (format
==OSMESA_RGB
) {
185 else if (format
==OSMESA_BGR
) {
203 osmesa
= (OSMesaContext
) CALLOC_STRUCT(osmesa_context
);
205 osmesa
->gl_visual
= gl_create_visual( rgbmode
,
206 swalpha
, /* software alpha */
207 GL_FALSE
, /* double buffer */
208 GL_FALSE
, /* stereo */
209 DEFAULT_SOFTWARE_DEPTH_BITS
,
211 rgbmode
? ACCUM_BITS
: 0,
213 8, 8, 8, alphaBits
);
214 if (!osmesa
->gl_visual
) {
218 if (!gl_initialize_context_data(&osmesa
->gl_ctx
,
220 sharelist
? &sharelist
->gl_ctx
221 : (GLcontext
*) NULL
,
222 (void *) osmesa
, GL_TRUE
)) {
223 gl_destroy_visual( osmesa
->gl_visual
);
229 osmesa
->gl_buffer
= gl_create_framebuffer( osmesa
->gl_visual
,
230 osmesa
->gl_visual
->DepthBits
> 0,
231 osmesa
->gl_visual
->StencilBits
> 0,
232 osmesa
->gl_visual
->AccumBits
> 0,
233 osmesa
->gl_visual
->AlphaBits
> 0 );
235 if (!osmesa
->gl_buffer
) {
236 gl_destroy_visual( osmesa
->gl_visual
);
237 gl_free_context_data( &osmesa
->gl_ctx
);
241 osmesa
->format
= format
;
242 osmesa
->buffer
= NULL
;
246 osmesa
->clearpixel
= 0;
247 osmesa
->userRowLength
= 0;
248 osmesa
->rowlength
= 0;
249 osmesa
->yup
= GL_TRUE
;
250 osmesa
->rshift
= rshift
;
251 osmesa
->gshift
= gshift
;
252 osmesa
->bshift
= bshift
;
253 osmesa
->ashift
= ashift
;
257 osmesa
->bVisible
= GL_FALSE
;
265 * Destroy an Off-Screen Mesa rendering context.
267 * Input: ctx - the context to destroy
269 void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext ctx
)
272 gl_destroy_visual( ctx
->gl_visual
);
273 gl_destroy_framebuffer( ctx
->gl_buffer
);
274 gl_free_context_data( &ctx
->gl_ctx
);
282 * Recompute the values of the context's rowaddr array.
284 static void compute_row_addresses( OSMesaContext ctx
)
289 /* Y=0 is bottom line of window */
290 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
292 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
293 for (i
=0;i
<MAX_HEIGHT
;i
++) {
294 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
298 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
299 /* 3-byte RGB mode */
300 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
301 for (i
=0;i
<MAX_HEIGHT
;i
++) {
302 ctx
->rowaddr
[i
] = origin
+ (i
* (ctx
->rowlength
*3));
305 /* 4-byte RGBA mode */
306 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
307 for (i
=0;i
<MAX_HEIGHT
;i
++) {
308 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
314 /* Y=0 is top line of window */
315 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
317 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
318 for (i
=0;i
<MAX_HEIGHT
;i
++) {
319 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
323 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
324 /* 3-byte RGB mode */
325 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
326 for (i
=0;i
<MAX_HEIGHT
;i
++) {
327 ctx
->rowaddr
[i
] = origin
+ ((ctx
->height
-i
-1) * (ctx
->rowlength
*3));
330 /* 4-byte RGBA mode */
331 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
332 for (i
=0;i
<MAX_HEIGHT
;i
++) {
333 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
342 * Bind an OSMesaContext to an image buffer. The image buffer is just a
343 * block of memory which the client provides. Its size must be at least
344 * as large as width*height*sizeof(type). Its address should be a multiple
345 * of 4 if using RGBA mode.
347 * Image data is stored in the order of glDrawPixels: row-major order
348 * with the lower-left image pixel stored in the first array position
349 * (ie. bottom-to-top).
351 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
352 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
353 * value. If the context is in color indexed mode, each pixel will be
354 * stored as a 1-byte value.
356 * If the context's viewport hasn't been initialized yet, it will now be
357 * initialized to (0,0,width,height).
359 * Input: ctx - the rendering context
360 * buffer - the image buffer memory
361 * type - data type for pixel components, only GL_UNSIGNED_BYTE
363 * width, height - size of image buffer in pixels, at least 1
364 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
365 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
366 * width>internal limit or height>internal limit.
369 OSMesaMakeCurrent( OSMesaContext ctx
, void *buffer
, GLenum type
,
370 GLsizei width
, GLsizei height
)
372 if (!ctx
|| !buffer
|| type
!=GL_UNSIGNED_BYTE
373 || width
<1 || height
<1 || width
>MAX_WIDTH
|| height
>MAX_HEIGHT
) {
377 osmesa_update_state( &ctx
->gl_ctx
);
378 gl_make_current( &ctx
->gl_ctx
, ctx
->gl_buffer
);
380 ctx
->buffer
= buffer
;
382 ctx
->height
= height
;
383 if (ctx
->userRowLength
)
384 ctx
->rowlength
= ctx
->userRowLength
;
386 ctx
->rowlength
= width
;
388 compute_row_addresses( ctx
);
391 if (ctx
->gl_ctx
.Viewport
.Width
==0) {
392 /* initialize viewport and scissor box to buffer size */
393 _mesa_Viewport( 0, 0, width
, height
);
394 ctx
->gl_ctx
.Scissor
.Width
= width
;
395 ctx
->gl_ctx
.Scissor
.Height
= height
;
403 OSMesaContext GLAPIENTRY
OSMesaGetCurrentContext( void )
405 GLcontext
*ctx
= gl_get_current_context();
407 return (OSMesaContext
) ctx
;
414 void GLAPIENTRY
OSMesaPixelStore( GLint pname
, GLint value
)
416 OSMesaContext ctx
= OSMesaGetCurrentContext();
419 case OSMESA_ROW_LENGTH
:
421 gl_error( &ctx
->gl_ctx
, GL_INVALID_VALUE
,
422 "OSMesaPixelStore(value)" );
425 ctx
->userRowLength
= value
;
426 ctx
->rowlength
= value
;
429 ctx
->yup
= value
? GL_TRUE
: GL_FALSE
;
432 gl_error( &ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaPixelStore(pname)" );
436 compute_row_addresses( ctx
);
440 void GLAPIENTRY
OSMesaGetIntegerv( GLint pname
, GLint
*value
)
442 OSMesaContext ctx
= OSMesaGetCurrentContext();
449 *value
= ctx
->height
;
452 *value
= ctx
->format
;
455 *value
= GL_UNSIGNED_BYTE
;
457 case OSMESA_ROW_LENGTH
:
458 *value
= ctx
->rowlength
;
464 gl_error(&ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaGetIntergerv(pname)");
469 void GLAPIENTRY
OSMesaGetBooleanv( GLint pname
, GLboolean
*value
)
471 OSMesaContext ctx
= OSMesaGetCurrentContext();
474 case OSMESA_OCCLUSION_TEST_RESULT_HP
:
475 *value
= ctx
->bVisible
;
476 ctx
->bVisible
= GL_FALSE
;
479 gl_error(&ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaGetBooleanv(pname)" );
485 * Return the depth buffer associated with an OSMesa context.
486 * Input: c - the OSMesa context
487 * Output: width, height - size of buffer in pixels
488 * bytesPerValue - bytes per depth value (2 or 4)
489 * buffer - pointer to depth buffer values
490 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
492 GLboolean GLAPIENTRY
OSMesaGetDepthBuffer( OSMesaContext c
, GLint
*width
, GLint
*height
,
493 GLint
*bytesPerValue
, void **buffer
)
495 if ((!c
->gl_buffer
) || (!c
->gl_buffer
->DepthBuffer
)) {
503 *width
= c
->gl_buffer
->Width
;
504 *height
= c
->gl_buffer
->Height
;
505 *bytesPerValue
= sizeof(GLdepth
);
506 *buffer
= c
->gl_buffer
->DepthBuffer
;
514 /**********************************************************************/
515 /*** Device Driver Functions ***/
516 /**********************************************************************/
522 #define PACK_RGBA(R,G,B,A) ( ((R) << osmesa->rshift) \
523 | ((G) << osmesa->gshift) \
524 | ((B) << osmesa->bshift) \
525 | ((A) << osmesa->ashift) )
527 #define PACK_RGBA2(R,G,B,A) ( ((R) << rshift) \
532 #define UNPACK_RED(P) (((P) >> osmesa->rshift) & 0xff)
533 #define UNPACK_GREEN(P) (((P) >> osmesa->gshift) & 0xff)
534 #define UNPACK_BLUE(P) (((P) >> osmesa->bshift) & 0xff)
535 #define UNPACK_ALPHA(P) (((P) >> osmesa->ashift) & 0xff)
537 #define PIXELADDR1(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + (X))
538 #define PIXELADDR3(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
539 #define PIXELADDR4(X,Y) ((GLuint *) osmesa->rowaddr[Y] + (X))
544 static GLboolean
set_draw_buffer( GLcontext
*ctx
, GLenum mode
)
547 if (mode
==GL_FRONT_LEFT
) {
556 static void set_read_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLenum mode
)
558 /* separate read buffer not supported */
559 ASSERT(buffer
== ctx
->DrawBuffer
);
560 ASSERT(mode
== GL_FRONT_LEFT
);
564 static void clear_index( GLcontext
*ctx
, GLuint index
)
566 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
567 osmesa
->clearpixel
= index
;
572 static void clear_color( GLcontext
*ctx
,
573 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
575 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
576 osmesa
->clearpixel
= PACK_RGBA( r
, g
, b
, a
);
581 static GLbitfield
clear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
582 GLint x
, GLint y
, GLint width
, GLint height
)
584 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
585 const GLuint
*colorMask
= (GLuint
*) &ctx
->Color
.ColorMask
;
587 /* we can't handle color or index masking */
588 if (*colorMask
!= 0xffffffff || ctx
->Color
.IndexMask
!= 0xffffffff)
591 /* sanity check - we only have a front-left buffer */
592 ASSERT((mask
& (DD_FRONT_RIGHT_BIT
| DD_BACK_LEFT_BIT
| DD_BACK_RIGHT_BIT
)) == 0);
594 if (mask
& DD_FRONT_LEFT_BIT
) {
595 if (osmesa
->format
==OSMESA_COLOR_INDEX
) {
597 /* Clear whole CI buffer */
598 MEMSET(osmesa
->buffer
, osmesa
->clearpixel
,
599 osmesa
->rowlength
* osmesa
->height
);
602 /* Clear part of CI buffer */
604 for (i
=0;i
<height
;i
++) {
605 GLubyte
*ptr1
= PIXELADDR1( x
, (y
+i
) );
606 for (j
=0;j
<width
;j
++) {
607 *ptr1
++ = osmesa
->clearpixel
;
612 else if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) {
613 GLubyte rval
= UNPACK_RED(osmesa
->clearpixel
);
614 GLubyte gval
= UNPACK_GREEN(osmesa
->clearpixel
);
615 GLubyte bval
= UNPACK_BLUE(osmesa
->clearpixel
);
616 GLint rind
= osmesa
->rind
;
617 GLint gind
= osmesa
->gind
;
618 GLint bind
= osmesa
->bind
;
621 GLubyte
*ptr3
= (GLubyte
*) osmesa
->buffer
;
622 /* Clear whole RGB buffer */
623 n
= osmesa
->rowlength
* osmesa
->height
;
632 /* Clear part of RGB buffer */
634 for (i
=0;i
<height
;i
++) {
635 GLubyte
*ptr3
= PIXELADDR3( x
, (y
+i
) );
636 for (j
=0;j
<width
;j
++) {
647 /* Clear whole RGBA buffer */
649 n
= osmesa
->rowlength
* osmesa
->height
;
650 ptr4
= (GLuint
*) osmesa
->buffer
;
652 *ptr4
++ = osmesa
->clearpixel
;
656 /* Clear part of RGBA buffer */
658 for (i
=0;i
<height
;i
++) {
659 GLuint
*ptr4
= PIXELADDR4( x
, (y
+i
) );
660 for (j
=0;j
<width
;j
++) {
661 *ptr4
++ = osmesa
->clearpixel
;
667 /* have Mesa clear all other buffers */
668 return mask
& (~DD_FRONT_LEFT_BIT
);
673 static void set_index( GLcontext
*ctx
, GLuint index
)
675 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
676 osmesa
->pixel
= index
;
681 static void set_color( GLcontext
*ctx
,
682 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
684 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
685 osmesa
->pixel
= PACK_RGBA( r
, g
, b
, a
);
690 static void buffer_size( GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
692 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
693 *width
= osmesa
->width
;
694 *height
= osmesa
->height
;
698 /**********************************************************************/
699 /***** Read/write spans/arrays of RGBA pixels *****/
700 /**********************************************************************/
702 /* Write RGBA pixels to an RGBA (or permuted) buffer. */
703 static void write_rgba_span( const GLcontext
*ctx
,
704 GLuint n
, GLint x
, GLint y
,
705 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
707 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
708 GLuint
*ptr4
= PIXELADDR4( x
, y
);
710 GLint rshift
= osmesa
->rshift
;
711 GLint gshift
= osmesa
->gshift
;
712 GLint bshift
= osmesa
->bshift
;
713 GLint ashift
= osmesa
->ashift
;
714 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
716 for (i
=0;i
<n
;i
++,ptr4
++) {
718 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
723 for (i
=0;i
<n
;i
++,ptr4
++) {
724 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
730 /* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
731 static void write_rgba_span_rgba( const GLcontext
*ctx
,
732 GLuint n
, GLint x
, GLint y
,
733 CONST GLubyte rgba
[][4],
734 const GLubyte mask
[] )
736 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
737 GLuint
*ptr4
= PIXELADDR4( x
, y
);
738 const GLuint
*rgba4
= (const GLuint
*) rgba
;
740 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
749 MEMCPY( ptr4
, rgba4
, n
* 4 );
754 /* Write RGB pixels to an RGBA (or permuted) buffer. */
755 static void write_rgb_span( const GLcontext
*ctx
,
756 GLuint n
, GLint x
, GLint y
,
757 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
759 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
760 GLuint
*ptr4
= PIXELADDR4( x
, y
);
762 GLint rshift
= osmesa
->rshift
;
763 GLint gshift
= osmesa
->gshift
;
764 GLint bshift
= osmesa
->bshift
;
765 GLint ashift
= osmesa
->ashift
;
766 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
768 for (i
=0;i
<n
;i
++,ptr4
++) {
770 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255 );
775 for (i
=0;i
<n
;i
++,ptr4
++) {
776 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255);
783 static void write_monocolor_span( const GLcontext
*ctx
,
784 GLuint n
, GLint x
, GLint y
,
785 const GLubyte mask
[] )
787 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
788 GLuint
*ptr4
= PIXELADDR4(x
,y
);
790 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
791 for (i
=0;i
<n
;i
++,ptr4
++) {
793 *ptr4
= osmesa
->pixel
;
800 static void write_rgba_pixels( const GLcontext
*ctx
,
801 GLuint n
, const GLint x
[], const GLint y
[],
802 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
804 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
806 GLint rshift
= osmesa
->rshift
;
807 GLint gshift
= osmesa
->gshift
;
808 GLint bshift
= osmesa
->bshift
;
809 GLint ashift
= osmesa
->ashift
;
810 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
813 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
814 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
821 static void write_monocolor_pixels( const GLcontext
*ctx
,
822 GLuint n
, const GLint x
[], const GLint y
[],
823 const GLubyte mask
[] )
825 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
827 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
830 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
831 *ptr4
= osmesa
->pixel
;
837 static void read_rgba_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
840 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
842 GLuint
*ptr4
= PIXELADDR4(x
,y
);
844 GLuint pixel
= *ptr4
++;
845 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
846 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
847 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
848 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
853 /* Read RGBA pixels from an RGBA buffer */
854 static void read_rgba_span_rgba( const GLcontext
*ctx
,
855 GLuint n
, GLint x
, GLint y
,
858 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
859 GLuint
*ptr4
= PIXELADDR4(x
,y
);
860 MEMCPY( rgba
, ptr4
, n
* 4 * sizeof(GLubyte
) );
864 static void read_rgba_pixels( const GLcontext
*ctx
,
865 GLuint n
, const GLint x
[], const GLint y
[],
866 GLubyte rgba
[][4], const GLubyte mask
[] )
868 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
872 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
873 GLuint pixel
= *ptr4
;
874 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
875 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
876 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
877 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
882 /**********************************************************************/
883 /***** 3 byte RGB pixel support funcs *****/
884 /**********************************************************************/
886 /* Write RGBA pixels to an RGB or BGR buffer. */
887 static void write_rgba_span3( const GLcontext
*ctx
,
888 GLuint n
, GLint x
, GLint y
,
889 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
891 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
892 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
894 GLint rind
= osmesa
->rind
;
895 GLint gind
= osmesa
->gind
;
896 GLint bind
= osmesa
->bind
;
897 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
899 for (i
=0;i
<n
;i
++,ptr3
+=3) {
901 ptr3
[rind
] = rgba
[i
][RCOMP
];
902 ptr3
[gind
] = rgba
[i
][GCOMP
];
903 ptr3
[bind
] = rgba
[i
][BCOMP
];
908 for (i
=0;i
<n
;i
++,ptr3
+=3) {
909 ptr3
[rind
] = rgba
[i
][RCOMP
];
910 ptr3
[gind
] = rgba
[i
][GCOMP
];
911 ptr3
[bind
] = rgba
[i
][BCOMP
];
916 /* Write RGB pixels to an RGB or BGR buffer. */
917 static void write_rgb_span3( const GLcontext
*ctx
,
918 GLuint n
, GLint x
, GLint y
,
919 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
921 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
922 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
924 GLint rind
= osmesa
->rind
;
925 GLint gind
= osmesa
->gind
;
926 GLint bind
= osmesa
->bind
;
927 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
929 for (i
=0;i
<n
;i
++,ptr3
+=3) {
931 ptr3
[rind
] = rgb
[i
][RCOMP
];
932 ptr3
[gind
] = rgb
[i
][GCOMP
];
933 ptr3
[bind
] = rgb
[i
][BCOMP
];
938 for (i
=0;i
<n
;i
++,ptr3
+=3) {
939 ptr3
[rind
] = rgb
[i
][RCOMP
];
940 ptr3
[gind
] = rgb
[i
][GCOMP
];
941 ptr3
[bind
] = rgb
[i
][BCOMP
];
947 static void write_monocolor_span3( const GLcontext
*ctx
,
948 GLuint n
, GLint x
, GLint y
,
949 const GLubyte mask
[] )
951 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
953 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
954 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
955 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
956 GLint rind
= osmesa
->rind
;
957 GLint gind
= osmesa
->gind
;
958 GLint bind
= osmesa
->bind
;
961 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
963 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
964 for (i
=0;i
<n
;i
++,ptr3
+=3) {
973 static void write_rgba_pixels3( const GLcontext
*ctx
,
974 GLuint n
, const GLint x
[], const GLint y
[],
975 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
977 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
979 GLint rind
= osmesa
->rind
;
980 GLint gind
= osmesa
->gind
;
981 GLint bind
= osmesa
->bind
;
982 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
985 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
986 ptr3
[rind
] = rgba
[i
][RCOMP
];
987 ptr3
[gind
] = rgba
[i
][GCOMP
];
988 ptr3
[bind
] = rgba
[i
][BCOMP
];
993 static void write_monocolor_pixels3( const GLcontext
*ctx
,
994 GLuint n
, const GLint x
[], const GLint y
[],
995 const GLubyte mask
[] )
997 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
999 GLint rind
= osmesa
->rind
;
1000 GLint gind
= osmesa
->gind
;
1001 GLint bind
= osmesa
->bind
;
1002 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
1003 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
1004 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
1005 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1008 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1016 static void read_rgba_span3( const GLcontext
*ctx
,
1017 GLuint n
, GLint x
, GLint y
,
1020 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1022 GLint rind
= osmesa
->rind
;
1023 GLint gind
= osmesa
->gind
;
1024 GLint bind
= osmesa
->bind
;
1025 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
1026 for (i
=0;i
<n
;i
++,ptr3
+=3) {
1027 rgba
[i
][RCOMP
] = ptr3
[rind
];
1028 rgba
[i
][GCOMP
] = ptr3
[gind
];
1029 rgba
[i
][BCOMP
] = ptr3
[bind
];
1034 static void read_rgba_pixels3( const GLcontext
*ctx
,
1035 GLuint n
, const GLint x
[], const GLint y
[],
1036 GLubyte rgba
[][4], const GLubyte mask
[] )
1038 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1040 GLint rind
= osmesa
->rind
;
1041 GLint gind
= osmesa
->gind
;
1042 GLint bind
= osmesa
->bind
;
1045 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1046 rgba
[i
][RCOMP
] = ptr3
[rind
];
1047 rgba
[i
][GCOMP
] = ptr3
[gind
];
1048 rgba
[i
][BCOMP
] = ptr3
[bind
];
1055 /**********************************************************************/
1056 /***** Read/write spans/arrays of CI pixels *****/
1057 /**********************************************************************/
1059 /* Write 32-bit color index to buffer */
1060 static void write_index32_span( const GLcontext
*ctx
,
1061 GLuint n
, GLint x
, GLint y
,
1062 const GLuint index
[], const GLubyte mask
[] )
1064 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1065 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1067 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1069 for (i
=0;i
<n
;i
++,ptr1
++) {
1071 *ptr1
= (GLubyte
) index
[i
];
1076 for (i
=0;i
<n
;i
++,ptr1
++) {
1077 *ptr1
= (GLubyte
) index
[i
];
1083 /* Write 8-bit color index to buffer */
1084 static void write_index8_span( const GLcontext
*ctx
,
1085 GLuint n
, GLint x
, GLint y
,
1086 const GLubyte index
[], const GLubyte mask
[] )
1088 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1089 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1091 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1093 for (i
=0;i
<n
;i
++,ptr1
++) {
1095 *ptr1
= (GLubyte
) index
[i
];
1100 MEMCPY( ptr1
, index
, n
);
1105 static void write_monoindex_span( const GLcontext
*ctx
,
1106 GLuint n
, GLint x
, GLint y
,
1107 const GLubyte mask
[] )
1109 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1110 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1112 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1113 for (i
=0;i
<n
;i
++,ptr1
++) {
1115 *ptr1
= (GLubyte
) osmesa
->pixel
;
1121 static void write_index_pixels( const GLcontext
*ctx
,
1122 GLuint n
, const GLint x
[], const GLint y
[],
1123 const GLuint index
[], const GLubyte mask
[] )
1125 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1127 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1130 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1131 *ptr1
= (GLubyte
) index
[i
];
1137 static void write_monoindex_pixels( const GLcontext
*ctx
,
1138 GLuint n
, const GLint x
[], const GLint y
[],
1139 const GLubyte mask
[] )
1141 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1143 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1146 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1147 *ptr1
= (GLubyte
) osmesa
->pixel
;
1153 static void read_index_span( const GLcontext
*ctx
,
1154 GLuint n
, GLint x
, GLint y
, GLuint index
[] )
1156 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1158 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1159 for (i
=0;i
<n
;i
++,ptr1
++) {
1160 index
[i
] = (GLuint
) *ptr1
;
1165 static void read_index_pixels( const GLcontext
*ctx
,
1166 GLuint n
, const GLint x
[], const GLint y
[],
1167 GLuint index
[], const GLubyte mask
[] )
1169 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1173 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1174 index
[i
] = (GLuint
) *ptr1
;
1181 /**********************************************************************/
1182 /***** Optimized line rendering *****/
1183 /**********************************************************************/
1187 * Draw a flat-shaded, RGB line into an osmesa buffer.
1189 static void flat_rgba_line( GLcontext
*ctx
,
1190 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1192 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1193 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1194 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1195 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1199 #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
1202 #include "..\linetemp.h"
1204 #include "linetemp.h"
1210 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1212 static void flat_rgba_z_line( GLcontext
*ctx
,
1213 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1215 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1216 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1217 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1218 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1222 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1226 GLuint *ptr4 = PIXELADDR4(X,Y); \
1232 #include "..\linetemp.h"
1234 #include "linetemp.h"
1240 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1242 static void flat_blend_rgba_line( GLcontext
*ctx
,
1243 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1245 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1246 struct vertex_buffer
*VB
= ctx
->VB
;
1247 GLint rshift
= osmesa
->rshift
;
1248 GLint gshift
= osmesa
->gshift
;
1249 GLint bshift
= osmesa
->bshift
;
1250 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1251 GLint msavalue
= 255 - avalue
;
1252 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1253 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1254 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1255 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1260 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1262 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1263 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1264 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1269 #include "..\linetemp.h"
1271 #include "linetemp.h"
1277 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1279 static void flat_blend_rgba_z_line( GLcontext
*ctx
,
1280 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1282 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1283 struct vertex_buffer
*VB
= ctx
->VB
;
1284 GLint rshift
= osmesa
->rshift
;
1285 GLint gshift
= osmesa
->gshift
;
1286 GLint bshift
= osmesa
->bshift
;
1287 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1288 GLint msavalue
= 256 - avalue
;
1289 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1290 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1291 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1292 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1296 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1300 GLuint *ptr4 = PIXELADDR4(X,Y); \
1302 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1303 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1304 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1309 #include "..\linetemp.h"
1311 #include "linetemp.h"
1317 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1319 static void flat_blend_rgba_z_line_write( GLcontext
*ctx
,
1320 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1322 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1323 struct vertex_buffer
*VB
= ctx
->VB
;
1324 GLint rshift
= osmesa
->rshift
;
1325 GLint gshift
= osmesa
->gshift
;
1326 GLint bshift
= osmesa
->bshift
;
1327 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1328 GLint msavalue
= 256 - avalue
;
1329 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1330 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1331 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1332 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1336 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1340 GLuint *ptr4 = PIXELADDR4(X,Y); \
1342 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1343 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1344 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1350 #include "..\linetemp.h"
1352 #include "linetemp.h"
1358 * Analyze context state to see if we can provide a fast line drawing
1359 * function, like those in lines.c. Otherwise, return NULL.
1361 static line_func
choose_line_function( GLcontext
*ctx
)
1363 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1365 if (ctx
->Line
.SmoothFlag
) return NULL
;
1366 if (ctx
->Texture
.Enabled
) return NULL
;
1367 if (ctx
->Light
.ShadeModel
!=GL_FLAT
) return NULL
;
1369 if (ctx
->Line
.Width
==1.0F
1370 && ctx
->Line
.StippleFlag
==GL_FALSE
) {
1372 if (ctx
->RasterMask
==DEPTH_BIT
1373 && ctx
->Depth
.Func
==GL_LESS
1374 && ctx
->Depth
.Mask
==GL_TRUE
1375 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
1376 switch(osmesa
->format
) {
1380 return flat_rgba_z_line
;
1386 if (ctx
->RasterMask
==0) {
1387 switch(osmesa
->format
) {
1391 return flat_rgba_line
;
1397 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1398 && ctx
->Depth
.Func
==GL_LESS
1399 && ctx
->Depth
.Mask
==GL_TRUE
1400 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1401 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1402 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1403 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1404 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1405 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1406 switch(osmesa
->format
) {
1410 return flat_blend_rgba_z_line_write
;
1416 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1417 && ctx
->Depth
.Func
==GL_LESS
1418 && ctx
->Depth
.Mask
==GL_FALSE
1419 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1420 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1421 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1422 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1423 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1424 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1425 switch(osmesa
->format
) {
1429 return flat_blend_rgba_z_line
;
1435 if (ctx
->RasterMask
==BLEND_BIT
1436 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1437 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1438 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1439 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1440 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1441 switch(osmesa
->format
) {
1445 return flat_blend_rgba_line
;
1456 /**********************************************************************/
1457 /***** Optimized triangle rendering *****/
1458 /**********************************************************************/
1462 * Smooth-shaded, z-less triangle, RGBA color.
1464 static void smooth_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1465 GLuint v2
, GLuint pv
)
1467 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1468 GLint rshift
= osmesa
->rshift
;
1469 GLint gshift
= osmesa
->gshift
;
1470 GLint bshift
= osmesa
->bshift
;
1471 GLint ashift
= osmesa
->ashift
;
1473 osmesa
->bVisible
= GL_TRUE
; /* if here, the occlusion test is misused */
1475 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1476 #define INTERP_RGB 1
1477 #define INTERP_ALPHA 1
1478 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1480 GLint i, len = RIGHT-LEFT; \
1481 GLuint *img = PIXELADDR4(LEFT,Y); \
1482 for (i=0;i<len;i++,img++) { \
1483 GLdepth z = FixedToDepth(ffz); \
1484 if (z < zRow[i]) { \
1485 *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg), \
1486 FixedToInt(ffb), FixedToInt(ffa) ); \
1489 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1494 #include "..\tritemp.h"
1496 #include "tritemp.h"
1504 * Flat-shaded, z-less triangle, RGBA color.
1506 static void flat_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1507 GLuint v2
, GLuint pv
)
1509 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1511 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1512 #define SETUP_CODE \
1513 GLubyte r = VB->ColorPtr->data[pv][0]; \
1514 GLubyte g = VB->ColorPtr->data[pv][1]; \
1515 GLubyte b = VB->ColorPtr->data[pv][2]; \
1516 GLubyte a = VB->ColorPtr->data[pv][3]; \
1517 GLuint pixel = PACK_RGBA(r,g,b,a);
1519 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1521 GLint i, len = RIGHT-LEFT; \
1522 GLuint *img = PIXELADDR4(LEFT,Y); \
1523 for (i=0;i<len;i++,img++) { \
1524 GLdepth z = FixedToDepth(ffz); \
1525 if (z < zRow[i]) { \
1533 #include "..\tritemp.h"
1535 #include "tritemp.h"
1542 * Return pointer to an accelerated triangle function if possible.
1544 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
1546 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1548 if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) return NULL
;
1550 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
1551 if (ctx
->Polygon
.StippleFlag
) return NULL
;
1552 if (ctx
->Texture
.Enabled
) return NULL
;
1554 if (ctx
->RasterMask
==DEPTH_BIT
1555 && ctx
->Depth
.Func
==GL_LESS
1556 && ctx
->Depth
.Mask
==GL_TRUE
1557 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1558 && osmesa
->format
!=OSMESA_COLOR_INDEX
) {
1559 if (ctx
->Light
.ShadeModel
==GL_SMOOTH
) {
1560 return smooth_rgba_z_triangle
;
1563 return flat_rgba_z_triangle
;
1571 /**********************************************************************/
1572 /***** Occlusion rendering routines *****/
1573 /**********************************************************************/
1575 #define OCC_STD_MASK_TEST \
1576 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx; \
1577 if (osmesa->bVisible) return; \
1580 for (i=0;i<n;i++) if (mask[i]) { \
1581 osmesa->bVisible = GL_TRUE; \
1585 osmesa->bVisible = GL_TRUE; \
1593 static void write_index32_span_occ( const GLcontext
*ctx
,
1594 GLuint n
, GLint x
, GLint y
,
1595 const GLuint index
[], const GLubyte mask
[] )
1601 static void write_index8_span_occ( const GLcontext
*ctx
,
1602 GLuint n
, GLint x
, GLint y
,
1603 const GLubyte index
[], const GLubyte mask
[] )
1609 static void write_monoindex_span_occ( const GLcontext
*ctx
,
1610 GLuint n
, GLint x
, GLint y
,
1611 const GLubyte mask
[] )
1617 static void write_index_pixels_occ( const GLcontext
*ctx
,
1618 GLuint n
, const GLint x
[], const GLint y
[],
1619 const GLuint index
[], const GLubyte mask
[] )
1625 static void write_monoindex_pixels_occ( const GLcontext
*ctx
,
1626 GLuint n
, const GLint x
[], const GLint y
[],
1627 const GLubyte mask
[] )
1635 static void write_rgba_span_occ( const GLcontext
*ctx
,
1636 GLuint n
, GLint x
, GLint y
,
1637 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
1643 static void write_rgb_span_occ( const GLcontext
*ctx
,
1644 GLuint n
, GLint x
, GLint y
,
1645 CONST GLubyte rgb
[][3],
1646 const GLubyte mask
[] )
1652 static void write_rgba_pixels_occ( const GLcontext
*ctx
,
1653 GLuint n
, const GLint x
[], const GLint y
[],
1654 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
1660 static void write_monocolor_span_occ( const GLcontext
*ctx
,
1661 GLuint n
, GLint x
, GLint y
,
1662 const GLubyte mask
[] )
1668 static void write_monocolor_pixels_occ( const GLcontext
*ctx
,
1669 GLuint n
, const GLint x
[], const GLint y
[],
1670 const GLubyte mask
[] )
1679 static void line_occ( GLcontext
*ctx
,
1680 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1682 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1683 osmesa
->bVisible
= GL_TRUE
;
1687 static void line_z_occ( GLcontext
*ctx
,
1688 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1690 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1691 if (osmesa
->bVisible
) return;
1695 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1699 osmesa->bVisible = GL_TRUE; \
1704 #include "..\linetemp.h"
1706 #include "linetemp.h"
1712 *** Triangle Drawing
1714 static void triangle_occ( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1715 GLuint v2
, GLuint pv
)
1717 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1718 osmesa
->bVisible
= GL_TRUE
;
1722 static void triangle_z_occ( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1723 GLuint v2
, GLuint pv
)
1725 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1726 if (osmesa
->bVisible
) return;
1728 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1729 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1731 GLint i, len = RIGHT-LEFT; \
1732 for (i=0;i<len;i++) { \
1733 GLdepth z = FixedToDepth(ffz); \
1734 if (z < zRow[i]) { \
1735 osmesa->bVisible = GL_TRUE; \
1742 #include "..\tritemp.h"
1744 #include "tritemp.h"
1749 static const GLubyte
*get_string( GLcontext
*ctx
, GLenum name
)
1754 return (const GLubyte
*) "Mesa OffScreen";
1761 static void osmesa_update_state( GLcontext
*ctx
)
1763 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1765 ASSERT((void *) osmesa
== (void *) ctx
->DriverCtx
);
1767 ctx
->Driver
.GetString
= get_string
;
1768 ctx
->Driver
.UpdateState
= osmesa_update_state
;
1770 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1771 ctx
->Driver
.SetReadBuffer
= set_read_buffer
;
1772 ctx
->Driver
.Color
= set_color
;
1773 ctx
->Driver
.Index
= set_index
;
1774 ctx
->Driver
.ClearIndex
= clear_index
;
1775 ctx
->Driver
.ClearColor
= clear_color
;
1776 ctx
->Driver
.Clear
= clear
;
1778 ctx
->Driver
.GetBufferSize
= buffer_size
;
1780 ctx
->Driver
.PointsFunc
= NULL
;
1781 ctx
->Driver
.LineFunc
= choose_line_function( ctx
);
1782 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1785 /* RGB(A) span/pixel functions */
1786 if ((osmesa
->format
==OSMESA_RGB
) || (osmesa
->format
==OSMESA_BGR
)) {
1787 /* 3 bytes / pixel in frame buffer */
1788 ctx
->Driver
.WriteRGBASpan
= write_rgba_span3
;
1789 ctx
->Driver
.WriteRGBSpan
= write_rgb_span3
;
1790 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels3
;
1791 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span3
;
1792 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels3
;
1793 ctx
->Driver
.ReadRGBASpan
= read_rgba_span3
;
1794 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels3
;
1797 /* 4 bytes / pixel in frame buffer */
1798 if (osmesa
->format
==OSMESA_RGBA
1799 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1800 ctx
->Driver
.WriteRGBASpan
= write_rgba_span_rgba
;
1802 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1803 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1804 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1805 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span
;
1806 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels
;
1807 if (osmesa
->format
==OSMESA_RGBA
1808 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1809 ctx
->Driver
.ReadRGBASpan
= read_rgba_span_rgba
;
1811 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1812 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1815 /* CI span/pixel functions */
1816 ctx
->Driver
.WriteCI32Span
= write_index32_span
;
1817 ctx
->Driver
.WriteCI8Span
= write_index8_span
;
1818 ctx
->Driver
.WriteMonoCISpan
= write_monoindex_span
;
1819 ctx
->Driver
.WriteCI32Pixels
= write_index_pixels
;
1820 ctx
->Driver
.WriteMonoCIPixels
= write_monoindex_pixels
;
1821 ctx
->Driver
.ReadCI32Span
= read_index_span
;
1822 ctx
->Driver
.ReadCI32Pixels
= read_index_pixels
;
1824 /* Occlusion test cases:
1825 * If no buffers have been selected for writing,
1826 * we swap in occlusion routines that:
1827 * (1) check the current flag and return if set
1828 * (2) set the flag if any pixel would be updated
1829 * Note: all the other buffer writing routines will
1830 * always set the visible flag so in cases of "improper"
1831 * extension use will just cause unnecessary rasterization
1832 * to occur. The image will be correct in any case.
1834 if ((ctx
->Color
.IndexMask
== 0) &&
1835 (ctx
->Color
.ColorMask
[0] == 0) &&
1836 (ctx
->Color
.ColorMask
[1] == 0) &&
1837 (ctx
->Color
.ColorMask
[2] == 0) &&
1838 (ctx
->Color
.ColorMask
[3] == 0) &&
1839 (ctx
->Stencil
.Enabled
== GL_FALSE
)) {
1841 /* XXX depth.func == GL_LESS ? */
1843 ctx
->Driver
.WriteCI32Span
= write_index32_span_occ
;
1844 ctx
->Driver
.WriteCI8Span
= write_index8_span_occ
;
1845 ctx
->Driver
.WriteMonoCISpan
= write_monoindex_span_occ
;
1846 ctx
->Driver
.WriteCI32Pixels
= write_index_pixels_occ
;
1847 ctx
->Driver
.WriteMonoCIPixels
= write_monoindex_pixels_occ
;
1849 ctx
->Driver
.WriteRGBASpan
= write_rgba_span_occ
;
1850 ctx
->Driver
.WriteRGBSpan
= write_rgb_span_occ
;
1851 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels_occ
;
1852 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span_occ
;
1853 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels_occ
;
1855 if (ctx
->RasterMask
& DEPTH_BIT
) {
1856 ctx
->Driver
.LineFunc
= line_z_occ
;
1857 ctx
->Driver
.TriangleFunc
= triangle_z_occ
;
1859 ctx
->Driver
.LineFunc
= line_occ
;
1860 ctx
->Driver
.TriangleFunc
= triangle_occ
;