1 /* $Id: osmesa.c,v 1.20 2000/09/08 16:41:39 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.
42 #include "GL/osmesa.h"
49 #include "extensions.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 */
81 /* A forward declaration: */
82 static void osmesa_update_state( GLcontext
*ctx
);
86 /**********************************************************************/
87 /***** Public Functions *****/
88 /**********************************************************************/
92 * Create an Off-Screen Mesa rendering context. The only attribute needed is
93 * an RGBA vs Color-Index mode flag.
95 * Input: format - either GL_RGBA or GL_COLOR_INDEX
96 * sharelist - specifies another OSMesaContext with which to share
97 * display lists. NULL indicates no sharing.
98 * Return: an OSMesaContext or 0 if error
100 OSMesaContext GLAPIENTRY
101 OSMesaCreateContext( GLenum format
, OSMesaContext sharelist
)
103 return OSMesaCreateContextExt(format
, DEFAULT_SOFTWARE_DEPTH_BITS
,
112 * Create context and specify size of ancillary buffers.
114 OSMesaContext GLAPIENTRY
115 OSMesaCreateContextExt( GLenum format
, GLint depthBits
, GLint stencilBits
,
116 GLint accumBits
, OSMesaContext sharelist
)
118 OSMesaContext osmesa
;
119 GLint rshift
, gshift
, bshift
, ashift
;
120 GLint rind
, gind
, bind
;
121 GLint indexBits
, redBits
, greenBits
, blueBits
, alphaBits
;
125 GLubyte
*i1
= (GLubyte
*) &i4
;
126 GLint little_endian
= *i1
;
129 rind
= gind
= bind
= 0;
130 if (format
==OSMESA_COLOR_INDEX
) {
132 rshift
= gshift
= bshift
= ashift
= 0;
135 else if (format
==OSMESA_RGBA
) {
155 else if (format
==OSMESA_BGRA
) {
175 else if (format
==OSMESA_ARGB
) {
195 else if (format
==OSMESA_RGB
) {
211 else if (format
==OSMESA_BGR
) {
232 osmesa
= (OSMesaContext
) CALLOC_STRUCT(osmesa_context
);
234 osmesa
->gl_visual
= _mesa_create_visual( rgbmode
,
235 GL_FALSE
, /* double buffer */
236 GL_FALSE
, /* stereo */
247 alphaBits
? accumBits
: 0,
250 if (!osmesa
->gl_visual
) {
255 if (!_mesa_initialize_context(&osmesa
->gl_ctx
,
257 sharelist
? &sharelist
->gl_ctx
258 : (GLcontext
*) NULL
,
259 (void *) osmesa
, GL_TRUE
)) {
260 _mesa_destroy_visual( osmesa
->gl_visual
);
264 gl_extensions_enable(&(osmesa
->gl_ctx
),"GL_HP_occlusion_test");
265 gl_extensions_enable(&(osmesa
->gl_ctx
), "GL_ARB_texture_cube_map");
266 gl_extensions_enable(&(osmesa
->gl_ctx
), "GL_EXT_texture_env_combine");
268 osmesa
->gl_buffer
= gl_create_framebuffer( osmesa
->gl_visual
,
269 osmesa
->gl_visual
->DepthBits
> 0,
270 osmesa
->gl_visual
->StencilBits
> 0,
271 osmesa
->gl_visual
->AccumRedBits
> 0,
272 osmesa
->gl_visual
->AlphaBits
> 0 );
274 if (!osmesa
->gl_buffer
) {
275 gl_destroy_visual( osmesa
->gl_visual
);
276 gl_free_context_data( &osmesa
->gl_ctx
);
280 osmesa
->format
= format
;
281 osmesa
->buffer
= NULL
;
285 osmesa
->clearpixel
= 0;
286 osmesa
->userRowLength
= 0;
287 osmesa
->rowlength
= 0;
288 osmesa
->yup
= GL_TRUE
;
289 osmesa
->rshift
= rshift
;
290 osmesa
->gshift
= gshift
;
291 osmesa
->bshift
= bshift
;
292 osmesa
->ashift
= ashift
;
304 * Destroy an Off-Screen Mesa rendering context.
306 * Input: ctx - the context to destroy
308 void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext ctx
)
311 gl_destroy_visual( ctx
->gl_visual
);
312 gl_destroy_framebuffer( ctx
->gl_buffer
);
313 gl_free_context_data( &ctx
->gl_ctx
);
321 * Recompute the values of the context's rowaddr array.
323 static void compute_row_addresses( OSMesaContext ctx
)
328 /* Y=0 is bottom line of window */
329 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
331 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
332 for (i
=0;i
<MAX_HEIGHT
;i
++) {
333 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
337 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
338 /* 3-byte RGB mode */
339 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
340 for (i
=0;i
<MAX_HEIGHT
;i
++) {
341 ctx
->rowaddr
[i
] = origin
+ (i
* (ctx
->rowlength
*3));
344 /* 4-byte RGBA mode */
345 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
346 for (i
=0;i
<MAX_HEIGHT
;i
++) {
347 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
353 /* Y=0 is top line of window */
354 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
356 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
357 for (i
=0;i
<MAX_HEIGHT
;i
++) {
358 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
362 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
363 /* 3-byte RGB mode */
364 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
365 for (i
=0;i
<MAX_HEIGHT
;i
++) {
366 ctx
->rowaddr
[i
] = origin
+ ((ctx
->height
-i
-1) * (ctx
->rowlength
*3));
369 /* 4-byte RGBA mode */
370 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
371 for (i
=0;i
<MAX_HEIGHT
;i
++) {
372 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
381 * Bind an OSMesaContext to an image buffer. The image buffer is just a
382 * block of memory which the client provides. Its size must be at least
383 * as large as width*height*sizeof(type). Its address should be a multiple
384 * of 4 if using RGBA mode.
386 * Image data is stored in the order of glDrawPixels: row-major order
387 * with the lower-left image pixel stored in the first array position
388 * (ie. bottom-to-top).
390 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
391 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
392 * value. If the context is in color indexed mode, each pixel will be
393 * stored as a 1-byte value.
395 * If the context's viewport hasn't been initialized yet, it will now be
396 * initialized to (0,0,width,height).
398 * Input: ctx - the rendering context
399 * buffer - the image buffer memory
400 * type - data type for pixel components, only GL_UNSIGNED_BYTE
402 * width, height - size of image buffer in pixels, at least 1
403 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
404 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
405 * width>internal limit or height>internal limit.
408 OSMesaMakeCurrent( OSMesaContext ctx
, void *buffer
, GLenum type
,
409 GLsizei width
, GLsizei height
)
411 if (!ctx
|| !buffer
|| type
!=GL_UNSIGNED_BYTE
412 || width
<1 || height
<1 || width
>MAX_WIDTH
|| height
>MAX_HEIGHT
) {
416 osmesa_update_state( &ctx
->gl_ctx
);
417 gl_make_current( &ctx
->gl_ctx
, ctx
->gl_buffer
);
419 ctx
->buffer
= buffer
;
421 ctx
->height
= height
;
422 if (ctx
->userRowLength
)
423 ctx
->rowlength
= ctx
->userRowLength
;
425 ctx
->rowlength
= width
;
427 compute_row_addresses( ctx
);
430 if (ctx
->gl_ctx
.Viewport
.Width
==0) {
431 /* initialize viewport and scissor box to buffer size */
432 _mesa_Viewport( 0, 0, width
, height
);
433 ctx
->gl_ctx
.Scissor
.Width
= width
;
434 ctx
->gl_ctx
.Scissor
.Height
= height
;
442 OSMesaContext GLAPIENTRY
OSMesaGetCurrentContext( void )
444 GLcontext
*ctx
= gl_get_current_context();
446 return (OSMesaContext
) ctx
;
453 void GLAPIENTRY
OSMesaPixelStore( GLint pname
, GLint value
)
455 OSMesaContext ctx
= OSMesaGetCurrentContext();
458 case OSMESA_ROW_LENGTH
:
460 gl_error( &ctx
->gl_ctx
, GL_INVALID_VALUE
,
461 "OSMesaPixelStore(value)" );
464 ctx
->userRowLength
= value
;
465 ctx
->rowlength
= value
;
468 ctx
->yup
= value
? GL_TRUE
: GL_FALSE
;
471 gl_error( &ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaPixelStore(pname)" );
475 compute_row_addresses( ctx
);
479 void GLAPIENTRY
OSMesaGetIntegerv( GLint pname
, GLint
*value
)
481 OSMesaContext ctx
= OSMesaGetCurrentContext();
488 *value
= ctx
->height
;
491 *value
= ctx
->format
;
494 *value
= GL_UNSIGNED_BYTE
;
496 case OSMESA_ROW_LENGTH
:
497 *value
= ctx
->rowlength
;
503 gl_error(&ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaGetIntergerv(pname)");
509 * Return the depth buffer associated with an OSMesa context.
510 * Input: c - the OSMesa context
511 * Output: width, height - size of buffer in pixels
512 * bytesPerValue - bytes per depth value (2 or 4)
513 * buffer - pointer to depth buffer values
514 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
517 OSMesaGetDepthBuffer( OSMesaContext c
, GLint
*width
, GLint
*height
,
518 GLint
*bytesPerValue
, void **buffer
)
520 if ((!c
->gl_buffer
) || (!c
->gl_buffer
->DepthBuffer
)) {
528 *width
= c
->gl_buffer
->Width
;
529 *height
= c
->gl_buffer
->Height
;
530 *bytesPerValue
= sizeof(GLdepth
);
531 *buffer
= c
->gl_buffer
->DepthBuffer
;
537 * Return the color buffer associated with an OSMesa context.
538 * Input: c - the OSMesa context
539 * Output: width, height - size of buffer in pixels
540 * format - the pixel format (OSMESA_FORMAT)
541 * buffer - pointer to color buffer values
542 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
545 OSMesaGetColorBuffer( OSMesaContext c
, GLint
*width
,
546 GLint
*height
, GLint
*format
, void **buffer
)
564 /**********************************************************************/
565 /*** Device Driver Functions ***/
566 /**********************************************************************/
572 #define PACK_RGBA(R,G,B,A) ( ((R) << osmesa->rshift) \
573 | ((G) << osmesa->gshift) \
574 | ((B) << osmesa->bshift) \
575 | ((A) << osmesa->ashift) )
577 #define PACK_RGBA2(R,G,B,A) ( ((R) << rshift) \
582 #define UNPACK_RED(P) (((P) >> osmesa->rshift) & 0xff)
583 #define UNPACK_GREEN(P) (((P) >> osmesa->gshift) & 0xff)
584 #define UNPACK_BLUE(P) (((P) >> osmesa->bshift) & 0xff)
585 #define UNPACK_ALPHA(P) (((P) >> osmesa->ashift) & 0xff)
587 #define PIXELADDR1(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + (X))
588 #define PIXELADDR3(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
589 #define PIXELADDR4(X,Y) ((GLuint *) osmesa->rowaddr[Y] + (X))
594 static GLboolean
set_draw_buffer( GLcontext
*ctx
, GLenum mode
)
597 if (mode
==GL_FRONT_LEFT
) {
606 static void set_read_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLenum mode
)
608 /* separate read buffer not supported */
609 ASSERT(buffer
== ctx
->DrawBuffer
);
610 ASSERT(mode
== GL_FRONT_LEFT
);
614 static void clear_index( GLcontext
*ctx
, GLuint index
)
616 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
617 osmesa
->clearpixel
= index
;
622 static void clear_color( GLcontext
*ctx
,
623 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
625 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
626 osmesa
->clearpixel
= PACK_RGBA( r
, g
, b
, a
);
631 static GLbitfield
clear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
632 GLint x
, GLint y
, GLint width
, GLint height
)
634 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
635 const GLuint
*colorMask
= (GLuint
*) &ctx
->Color
.ColorMask
;
637 /* we can't handle color or index masking */
638 if (*colorMask
!= 0xffffffff || ctx
->Color
.IndexMask
!= 0xffffffff)
641 /* sanity check - we only have a front-left buffer */
642 ASSERT((mask
& (DD_FRONT_RIGHT_BIT
| DD_BACK_LEFT_BIT
| DD_BACK_RIGHT_BIT
)) == 0);
644 if (mask
& DD_FRONT_LEFT_BIT
) {
645 if (osmesa
->format
==OSMESA_COLOR_INDEX
) {
647 /* Clear whole CI buffer */
648 MEMSET(osmesa
->buffer
, osmesa
->clearpixel
,
649 osmesa
->rowlength
* osmesa
->height
);
652 /* Clear part of CI buffer */
654 for (i
=0;i
<height
;i
++) {
655 GLubyte
*ptr1
= PIXELADDR1( x
, (y
+i
) );
656 for (j
=0;j
<width
;j
++) {
657 *ptr1
++ = osmesa
->clearpixel
;
662 else if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) {
663 GLubyte rval
= UNPACK_RED(osmesa
->clearpixel
);
664 GLubyte gval
= UNPACK_GREEN(osmesa
->clearpixel
);
665 GLubyte bval
= UNPACK_BLUE(osmesa
->clearpixel
);
666 GLint rind
= osmesa
->rind
;
667 GLint gind
= osmesa
->gind
;
668 GLint bind
= osmesa
->bind
;
671 GLubyte
*ptr3
= (GLubyte
*) osmesa
->buffer
;
672 /* Clear whole RGB buffer */
673 n
= osmesa
->rowlength
* osmesa
->height
;
682 /* Clear part of RGB buffer */
684 for (i
=0;i
<height
;i
++) {
685 GLubyte
*ptr3
= PIXELADDR3( x
, (y
+i
) );
686 for (j
=0;j
<width
;j
++) {
697 /* Clear whole RGBA buffer */
699 n
= osmesa
->rowlength
* osmesa
->height
;
700 ptr4
= (GLuint
*) osmesa
->buffer
;
701 if (osmesa
->clearpixel
) {
703 *ptr4
++ = osmesa
->clearpixel
;
707 BZERO(ptr4
, n
* sizeof(GLuint
));
711 /* Clear part of RGBA buffer */
713 for (i
=0;i
<height
;i
++) {
714 GLuint
*ptr4
= PIXELADDR4( x
, (y
+i
) );
715 for (j
=0;j
<width
;j
++) {
716 *ptr4
++ = osmesa
->clearpixel
;
722 /* have Mesa clear all other buffers */
723 return mask
& (~DD_FRONT_LEFT_BIT
);
728 static void set_index( GLcontext
*ctx
, GLuint index
)
730 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
731 osmesa
->pixel
= index
;
736 static void set_color( GLcontext
*ctx
,
737 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
739 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
740 osmesa
->pixel
= PACK_RGBA( r
, g
, b
, a
);
745 static void buffer_size( GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
747 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
748 *width
= osmesa
->width
;
749 *height
= osmesa
->height
;
753 /**********************************************************************/
754 /***** Read/write spans/arrays of RGBA pixels *****/
755 /**********************************************************************/
757 /* Write RGBA pixels to an RGBA (or permuted) buffer. */
758 static void write_rgba_span( const GLcontext
*ctx
,
759 GLuint n
, GLint x
, GLint y
,
760 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
762 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
763 GLuint
*ptr4
= PIXELADDR4( x
, y
);
765 GLint rshift
= osmesa
->rshift
;
766 GLint gshift
= osmesa
->gshift
;
767 GLint bshift
= osmesa
->bshift
;
768 GLint ashift
= osmesa
->ashift
;
770 for (i
=0;i
<n
;i
++,ptr4
++) {
772 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
777 for (i
=0;i
<n
;i
++,ptr4
++) {
778 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
784 /* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
785 static void write_rgba_span_rgba( const GLcontext
*ctx
,
786 GLuint n
, GLint x
, GLint y
,
787 CONST GLubyte rgba
[][4],
788 const GLubyte mask
[] )
790 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
791 GLuint
*ptr4
= PIXELADDR4( x
, y
);
792 const GLuint
*rgba4
= (const GLuint
*) rgba
;
802 MEMCPY( ptr4
, rgba4
, n
* 4 );
807 /* Write RGB pixels to an RGBA (or permuted) buffer. */
808 static void write_rgb_span( const GLcontext
*ctx
,
809 GLuint n
, GLint x
, GLint y
,
810 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
812 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
813 GLuint
*ptr4
= PIXELADDR4( x
, y
);
815 GLint rshift
= osmesa
->rshift
;
816 GLint gshift
= osmesa
->gshift
;
817 GLint bshift
= osmesa
->bshift
;
818 GLint ashift
= osmesa
->ashift
;
820 for (i
=0;i
<n
;i
++,ptr4
++) {
822 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255 );
827 for (i
=0;i
<n
;i
++,ptr4
++) {
828 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255);
835 static void write_monocolor_span( const GLcontext
*ctx
,
836 GLuint n
, GLint x
, GLint y
,
837 const GLubyte mask
[] )
839 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
840 GLuint
*ptr4
= PIXELADDR4(x
,y
);
842 for (i
=0;i
<n
;i
++,ptr4
++) {
844 *ptr4
= osmesa
->pixel
;
851 static void write_rgba_pixels( const GLcontext
*ctx
,
852 GLuint n
, const GLint x
[], const GLint y
[],
853 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
855 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
857 GLint rshift
= osmesa
->rshift
;
858 GLint gshift
= osmesa
->gshift
;
859 GLint bshift
= osmesa
->bshift
;
860 GLint ashift
= osmesa
->ashift
;
863 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
864 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
871 static void write_monocolor_pixels( const GLcontext
*ctx
,
872 GLuint n
, const GLint x
[], const GLint y
[],
873 const GLubyte mask
[] )
875 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
879 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
880 *ptr4
= osmesa
->pixel
;
886 static void read_rgba_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
889 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
891 GLuint
*ptr4
= PIXELADDR4(x
,y
);
893 GLuint pixel
= *ptr4
++;
894 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
895 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
896 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
897 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
902 /* Read RGBA pixels from an RGBA buffer */
903 static void read_rgba_span_rgba( const GLcontext
*ctx
,
904 GLuint n
, GLint x
, GLint y
,
907 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
908 GLuint
*ptr4
= PIXELADDR4(x
,y
);
909 MEMCPY( rgba
, ptr4
, n
* 4 * sizeof(GLubyte
) );
913 static void read_rgba_pixels( const GLcontext
*ctx
,
914 GLuint n
, const GLint x
[], const GLint y
[],
915 GLubyte rgba
[][4], const GLubyte mask
[] )
917 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
921 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
922 GLuint pixel
= *ptr4
;
923 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
924 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
925 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
926 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
931 /**********************************************************************/
932 /***** 3 byte RGB pixel support funcs *****/
933 /**********************************************************************/
935 /* Write RGBA pixels to an RGB or BGR buffer. */
936 static void write_rgba_span3( const GLcontext
*ctx
,
937 GLuint n
, GLint x
, GLint y
,
938 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
940 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
941 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
943 GLint rind
= osmesa
->rind
;
944 GLint gind
= osmesa
->gind
;
945 GLint bind
= osmesa
->bind
;
947 for (i
=0;i
<n
;i
++,ptr3
+=3) {
949 ptr3
[rind
] = rgba
[i
][RCOMP
];
950 ptr3
[gind
] = rgba
[i
][GCOMP
];
951 ptr3
[bind
] = rgba
[i
][BCOMP
];
956 for (i
=0;i
<n
;i
++,ptr3
+=3) {
957 ptr3
[rind
] = rgba
[i
][RCOMP
];
958 ptr3
[gind
] = rgba
[i
][GCOMP
];
959 ptr3
[bind
] = rgba
[i
][BCOMP
];
964 /* Write RGB pixels to an RGB or BGR buffer. */
965 static void write_rgb_span3( const GLcontext
*ctx
,
966 GLuint n
, GLint x
, GLint y
,
967 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
969 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
970 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
972 GLint rind
= osmesa
->rind
;
973 GLint gind
= osmesa
->gind
;
974 GLint bind
= osmesa
->bind
;
976 for (i
=0;i
<n
;i
++,ptr3
+=3) {
978 ptr3
[rind
] = rgb
[i
][RCOMP
];
979 ptr3
[gind
] = rgb
[i
][GCOMP
];
980 ptr3
[bind
] = rgb
[i
][BCOMP
];
985 for (i
=0;i
<n
;i
++,ptr3
+=3) {
986 ptr3
[rind
] = rgb
[i
][RCOMP
];
987 ptr3
[gind
] = rgb
[i
][GCOMP
];
988 ptr3
[bind
] = rgb
[i
][BCOMP
];
994 static void write_monocolor_span3( const GLcontext
*ctx
,
995 GLuint n
, GLint x
, GLint y
,
996 const GLubyte mask
[] )
998 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1000 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
1001 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
1002 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
1003 GLint rind
= osmesa
->rind
;
1004 GLint gind
= osmesa
->gind
;
1005 GLint bind
= osmesa
->bind
;
1006 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
1008 for (i
=0;i
<n
;i
++,ptr3
+=3) {
1017 static void write_rgba_pixels3( const GLcontext
*ctx
,
1018 GLuint n
, const GLint x
[], const GLint y
[],
1019 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
1021 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1023 GLint rind
= osmesa
->rind
;
1024 GLint gind
= osmesa
->gind
;
1025 GLint bind
= osmesa
->bind
;
1028 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1029 ptr3
[rind
] = rgba
[i
][RCOMP
];
1030 ptr3
[gind
] = rgba
[i
][GCOMP
];
1031 ptr3
[bind
] = rgba
[i
][BCOMP
];
1036 static void write_monocolor_pixels3( const GLcontext
*ctx
,
1037 GLuint n
, const GLint x
[], const GLint y
[],
1038 const GLubyte mask
[] )
1040 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1042 GLint rind
= osmesa
->rind
;
1043 GLint gind
= osmesa
->gind
;
1044 GLint bind
= osmesa
->bind
;
1045 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
1046 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
1047 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
1050 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1058 static void read_rgba_span3( const GLcontext
*ctx
,
1059 GLuint n
, GLint x
, GLint y
,
1062 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1064 GLint rind
= osmesa
->rind
;
1065 GLint gind
= osmesa
->gind
;
1066 GLint bind
= osmesa
->bind
;
1067 const GLubyte
*ptr3
= PIXELADDR3( x
, y
);
1068 for (i
=0;i
<n
;i
++,ptr3
+=3) {
1069 rgba
[i
][RCOMP
] = ptr3
[rind
];
1070 rgba
[i
][GCOMP
] = ptr3
[gind
];
1071 rgba
[i
][BCOMP
] = ptr3
[bind
];
1076 static void read_rgba_pixels3( const GLcontext
*ctx
,
1077 GLuint n
, const GLint x
[], const GLint y
[],
1078 GLubyte rgba
[][4], const GLubyte mask
[] )
1080 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1082 GLint rind
= osmesa
->rind
;
1083 GLint gind
= osmesa
->gind
;
1084 GLint bind
= osmesa
->bind
;
1087 const GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1088 rgba
[i
][RCOMP
] = ptr3
[rind
];
1089 rgba
[i
][GCOMP
] = ptr3
[gind
];
1090 rgba
[i
][BCOMP
] = ptr3
[bind
];
1097 /**********************************************************************/
1098 /***** Read/write spans/arrays of CI pixels *****/
1099 /**********************************************************************/
1101 /* Write 32-bit color index to buffer */
1102 static void write_index32_span( const GLcontext
*ctx
,
1103 GLuint n
, GLint x
, GLint y
,
1104 const GLuint index
[], const GLubyte mask
[] )
1106 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1107 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1110 for (i
=0;i
<n
;i
++,ptr1
++) {
1112 *ptr1
= (GLubyte
) index
[i
];
1117 for (i
=0;i
<n
;i
++,ptr1
++) {
1118 *ptr1
= (GLubyte
) index
[i
];
1124 /* Write 8-bit color index to buffer */
1125 static void write_index8_span( const GLcontext
*ctx
,
1126 GLuint n
, GLint x
, GLint y
,
1127 const GLubyte index
[], const GLubyte mask
[] )
1129 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1130 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1133 for (i
=0;i
<n
;i
++,ptr1
++) {
1135 *ptr1
= (GLubyte
) index
[i
];
1140 MEMCPY( ptr1
, index
, n
);
1145 static void write_monoindex_span( const GLcontext
*ctx
,
1146 GLuint n
, GLint x
, GLint y
,
1147 const GLubyte mask
[] )
1149 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1150 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1152 for (i
=0;i
<n
;i
++,ptr1
++) {
1154 *ptr1
= (GLubyte
) osmesa
->pixel
;
1160 static void write_index_pixels( const GLcontext
*ctx
,
1161 GLuint n
, const GLint x
[], const GLint y
[],
1162 const GLuint index
[], const GLubyte mask
[] )
1164 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1168 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1169 *ptr1
= (GLubyte
) index
[i
];
1175 static void write_monoindex_pixels( const GLcontext
*ctx
,
1176 GLuint n
, const GLint x
[], const GLint y
[],
1177 const GLubyte mask
[] )
1179 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1183 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1184 *ptr1
= (GLubyte
) osmesa
->pixel
;
1190 static void read_index_span( const GLcontext
*ctx
,
1191 GLuint n
, GLint x
, GLint y
, GLuint index
[] )
1193 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1195 const GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1196 for (i
=0;i
<n
;i
++,ptr1
++) {
1197 index
[i
] = (GLuint
) *ptr1
;
1202 static void read_index_pixels( const GLcontext
*ctx
,
1203 GLuint n
, const GLint x
[], const GLint y
[],
1204 GLuint index
[], const GLubyte mask
[] )
1206 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1210 const GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1211 index
[i
] = (GLuint
) *ptr1
;
1218 /**********************************************************************/
1219 /***** Optimized line rendering *****/
1220 /**********************************************************************/
1224 * Draw a flat-shaded, RGB line into an osmesa buffer.
1226 static void flat_rgba_line( GLcontext
*ctx
,
1227 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1229 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1230 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1231 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1235 #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
1238 #include "..\linetemp.h"
1240 #include "linetemp.h"
1246 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1248 static void flat_rgba_z_line( GLcontext
*ctx
,
1249 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1251 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1252 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1253 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1257 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1261 GLuint *ptr4 = PIXELADDR4(X,Y); \
1267 #include "..\linetemp.h"
1269 #include "linetemp.h"
1275 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1277 static void flat_blend_rgba_line( GLcontext
*ctx
,
1278 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1280 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1281 struct vertex_buffer
*VB
= ctx
->VB
;
1282 GLint rshift
= osmesa
->rshift
;
1283 GLint gshift
= osmesa
->gshift
;
1284 GLint bshift
= osmesa
->bshift
;
1285 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1286 GLint msavalue
= 255 - avalue
;
1287 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1288 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1289 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1294 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1296 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1297 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1298 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1303 #include "..\linetemp.h"
1305 #include "linetemp.h"
1311 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1313 static void flat_blend_rgba_z_line( GLcontext
*ctx
,
1314 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1316 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1317 struct vertex_buffer
*VB
= ctx
->VB
;
1318 GLint rshift
= osmesa
->rshift
;
1319 GLint gshift
= osmesa
->gshift
;
1320 GLint bshift
= osmesa
->bshift
;
1321 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1322 GLint msavalue
= 256 - avalue
;
1323 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1324 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1325 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1329 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1333 GLuint *ptr4 = PIXELADDR4(X,Y); \
1335 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1336 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1337 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1342 #include "..\linetemp.h"
1344 #include "linetemp.h"
1350 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1352 static void flat_blend_rgba_z_line_write( GLcontext
*ctx
,
1353 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1355 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1356 struct vertex_buffer
*VB
= ctx
->VB
;
1357 GLint rshift
= osmesa
->rshift
;
1358 GLint gshift
= osmesa
->gshift
;
1359 GLint bshift
= osmesa
->bshift
;
1360 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1361 GLint msavalue
= 256 - avalue
;
1362 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1363 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1364 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1368 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1372 GLuint *ptr4 = PIXELADDR4(X,Y); \
1374 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1375 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1376 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1382 #include "..\linetemp.h"
1384 #include "linetemp.h"
1390 * Analyze context state to see if we can provide a fast line drawing
1391 * function, like those in lines.c. Otherwise, return NULL.
1393 static line_func
choose_line_function( GLcontext
*ctx
)
1395 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1397 if (ctx
->Line
.SmoothFlag
) return NULL
;
1398 if (ctx
->Texture
.Enabled
) return NULL
;
1399 if (ctx
->Light
.ShadeModel
!=GL_FLAT
) return NULL
;
1401 if (ctx
->Line
.Width
==1.0F
1402 && ctx
->Line
.StippleFlag
==GL_FALSE
) {
1404 if (ctx
->RasterMask
==DEPTH_BIT
1405 && ctx
->Depth
.Func
==GL_LESS
1406 && ctx
->Depth
.Mask
==GL_TRUE
1407 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
1408 switch(osmesa
->format
) {
1412 return flat_rgba_z_line
;
1418 if (ctx
->RasterMask
==0) {
1419 switch(osmesa
->format
) {
1423 return flat_rgba_line
;
1429 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1430 && ctx
->Depth
.Func
==GL_LESS
1431 && ctx
->Depth
.Mask
==GL_TRUE
1432 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1433 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1434 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1435 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1436 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1437 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1438 switch(osmesa
->format
) {
1442 return flat_blend_rgba_z_line_write
;
1448 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1449 && ctx
->Depth
.Func
==GL_LESS
1450 && ctx
->Depth
.Mask
==GL_FALSE
1451 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1452 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1453 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1454 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1455 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1456 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1457 switch(osmesa
->format
) {
1461 return flat_blend_rgba_z_line
;
1467 if (ctx
->RasterMask
==BLEND_BIT
1468 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1469 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1470 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1471 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1472 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1473 switch(osmesa
->format
) {
1477 return flat_blend_rgba_line
;
1488 /**********************************************************************/
1489 /***** Optimized triangle rendering *****/
1490 /**********************************************************************/
1494 * Smooth-shaded, z-less triangle, RGBA color.
1496 static void smooth_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1497 GLuint v2
, GLuint pv
)
1499 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1500 GLint rshift
= osmesa
->rshift
;
1501 GLint gshift
= osmesa
->gshift
;
1502 GLint bshift
= osmesa
->bshift
;
1503 GLint ashift
= osmesa
->ashift
;
1507 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1508 #define INTERP_RGB 1
1509 #define INTERP_ALPHA 1
1510 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1512 GLint i, len = RIGHT-LEFT; \
1513 GLuint *img = PIXELADDR4(LEFT,Y); \
1514 for (i=0;i<len;i++,img++) { \
1515 GLdepth z = FixedToDepth(ffz); \
1516 if (z < zRow[i]) { \
1517 *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg), \
1518 FixedToInt(ffb), FixedToInt(ffa) ); \
1521 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1526 #include "..\tritemp.h"
1528 #include "tritemp.h"
1536 * Flat-shaded, z-less triangle, RGBA color.
1538 static void flat_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1539 GLuint v2
, GLuint pv
)
1541 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1543 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1544 #define SETUP_CODE \
1545 GLubyte r = VB->ColorPtr->data[pv][0]; \
1546 GLubyte g = VB->ColorPtr->data[pv][1]; \
1547 GLubyte b = VB->ColorPtr->data[pv][2]; \
1548 GLubyte a = VB->ColorPtr->data[pv][3]; \
1549 GLuint pixel = PACK_RGBA(r,g,b,a);
1551 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1553 GLint i, len = RIGHT-LEFT; \
1554 GLuint *img = PIXELADDR4(LEFT,Y); \
1555 for (i=0;i<len;i++,img++) { \
1556 GLdepth z = FixedToDepth(ffz); \
1557 if (z < zRow[i]) { \
1565 #include "..\tritemp.h"
1567 #include "tritemp.h"
1574 * Return pointer to an accelerated triangle function if possible.
1576 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
1578 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1580 if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) return NULL
;
1582 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
1583 if (ctx
->Polygon
.StippleFlag
) return NULL
;
1584 if (ctx
->Texture
.Enabled
) return NULL
;
1586 if (ctx
->RasterMask
==DEPTH_BIT
1587 && ctx
->Depth
.Func
==GL_LESS
1588 && ctx
->Depth
.Mask
==GL_TRUE
1589 && ctx
->Visual
->DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1590 && osmesa
->format
!=OSMESA_COLOR_INDEX
) {
1591 if (ctx
->Light
.ShadeModel
==GL_SMOOTH
) {
1592 return smooth_rgba_z_triangle
;
1595 return flat_rgba_z_triangle
;
1603 static const GLubyte
*get_string( GLcontext
*ctx
, GLenum name
)
1608 return (const GLubyte
*) "Mesa OffScreen";
1615 static void osmesa_update_state( GLcontext
*ctx
)
1617 OSMesaContext osmesa
= (OSMesaContext
) ctx
;
1619 ASSERT((void *) osmesa
== (void *) ctx
->DriverCtx
);
1621 ctx
->Driver
.GetString
= get_string
;
1622 ctx
->Driver
.UpdateState
= osmesa_update_state
;
1624 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1625 ctx
->Driver
.SetReadBuffer
= set_read_buffer
;
1626 ctx
->Driver
.Color
= set_color
;
1627 ctx
->Driver
.Index
= set_index
;
1628 ctx
->Driver
.ClearIndex
= clear_index
;
1629 ctx
->Driver
.ClearColor
= clear_color
;
1630 ctx
->Driver
.Clear
= clear
;
1632 ctx
->Driver
.GetBufferSize
= buffer_size
;
1634 ctx
->Driver
.PointsFunc
= NULL
;
1635 ctx
->Driver
.LineFunc
= choose_line_function( ctx
);
1636 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1639 /* RGB(A) span/pixel functions */
1640 if ((osmesa
->format
==OSMESA_RGB
) || (osmesa
->format
==OSMESA_BGR
)) {
1641 /* 3 bytes / pixel in frame buffer */
1642 ctx
->Driver
.WriteRGBASpan
= write_rgba_span3
;
1643 ctx
->Driver
.WriteRGBSpan
= write_rgb_span3
;
1644 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels3
;
1645 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span3
;
1646 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels3
;
1647 ctx
->Driver
.ReadRGBASpan
= read_rgba_span3
;
1648 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels3
;
1651 /* 4 bytes / pixel in frame buffer */
1652 if (osmesa
->format
==OSMESA_RGBA
1653 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1654 ctx
->Driver
.WriteRGBASpan
= write_rgba_span_rgba
;
1656 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1657 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1658 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1659 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span
;
1660 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels
;
1661 if (osmesa
->format
==OSMESA_RGBA
1662 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1663 ctx
->Driver
.ReadRGBASpan
= read_rgba_span_rgba
;
1665 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1666 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1669 /* CI span/pixel functions */
1670 ctx
->Driver
.WriteCI32Span
= write_index32_span
;
1671 ctx
->Driver
.WriteCI8Span
= write_index8_span
;
1672 ctx
->Driver
.WriteMonoCISpan
= write_monoindex_span
;
1673 ctx
->Driver
.WriteCI32Pixels
= write_index_pixels
;
1674 ctx
->Driver
.WriteMonoCIPixels
= write_monoindex_pixels
;
1675 ctx
->Driver
.ReadCI32Span
= read_index_span
;
1676 ctx
->Driver
.ReadCI32Pixels
= read_index_pixels
;