1 /* $Id: osmesa.c,v 1.7 2000/01/06 09:28:38 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 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"
53 struct osmesa_context
{
54 GLcontext
*gl_ctx
; /* The core GL/Mesa context */
55 GLvisual
*gl_visual
; /* Describes the buffers */
56 GLframebuffer
*gl_buffer
; /* Depth, stencil, accum, etc buffers */
57 GLenum format
; /* either GL_RGBA or GL_COLOR_INDEX */
58 void *buffer
; /* the image buffer */
59 GLint width
, height
; /* size of image buffer */
60 GLuint pixel
; /* current color index or RGBA pixel value */
61 GLuint clearpixel
; /* pixel for clearing the color buffer */
62 GLint rowlength
; /* number of pixels per row */
63 GLint userRowLength
; /* user-specified number of pixels per row */
64 GLint rshift
, gshift
; /* bit shifts for RGBA formats */
66 GLint rind
, gind
, bind
; /* index offsets for RGBA formats */
67 void *rowaddr
[MAX_HEIGHT
]; /* address of first pixel in each image row */
68 GLboolean yup
; /* TRUE -> Y increases upward */
69 /* FALSE -> Y increases downward */
74 /* A forward declaration: */
75 static void osmesa_update_state( GLcontext
*ctx
);
79 /**********************************************************************/
80 /***** Public Functions *****/
81 /**********************************************************************/
85 * Create an Off-Screen Mesa rendering context. The only attribute needed is
86 * an RGBA vs Color-Index mode flag.
88 * Input: format - either GL_RGBA or GL_COLOR_INDEX
89 * sharelist - specifies another OSMesaContext with which to share
90 * display lists. NULL indicates no sharing.
91 * Return: an OSMesaContext or 0 if error
93 OSMesaContext GLAPIENTRY
94 OSMesaCreateContext( GLenum format
, OSMesaContext sharelist
)
97 GLint rshift
, gshift
, bshift
, ashift
;
98 GLint rind
, gind
, bind
;
99 GLint indexBits
, alphaBits
;
103 GLubyte
*i1
= (GLubyte
*) &i4
;
104 GLint little_endian
= *i1
;
107 rind
= gind
= bind
= 0;
108 if (format
==OSMESA_COLOR_INDEX
) {
110 rshift
= gshift
= bshift
= ashift
= 0;
113 else if (format
==OSMESA_RGBA
) {
130 else if (format
==OSMESA_BGRA
) {
147 else if (format
==OSMESA_ARGB
) {
164 else if (format
==OSMESA_RGB
) {
177 else if (format
==OSMESA_BGR
) {
195 osmesa
= (OSMesaContext
) CALLOC_STRUCT(osmesa_context
);
197 osmesa
->gl_visual
= gl_create_visual( rgbmode
,
198 swalpha
, /* software alpha */
199 GL_FALSE
, /* double buffer */
200 GL_FALSE
, /* stereo */
203 rgbmode
? ACCUM_BITS
: 0,
205 8, 8, 8, alphaBits
);
206 if (!osmesa
->gl_visual
) {
210 osmesa
->gl_ctx
= gl_create_context( osmesa
->gl_visual
,
211 sharelist
? sharelist
->gl_ctx
: (GLcontext
*) NULL
,
212 (void *) osmesa
, GL_TRUE
);
213 if (!osmesa
->gl_ctx
) {
214 gl_destroy_visual( osmesa
->gl_visual
);
218 osmesa
->gl_buffer
= gl_create_framebuffer( osmesa
->gl_visual
,
219 osmesa
->gl_visual
->DepthBits
> 0,
220 osmesa
->gl_visual
->StencilBits
> 0,
221 osmesa
->gl_visual
->AccumBits
> 0,
222 osmesa
->gl_visual
->AlphaBits
> 0 );
224 if (!osmesa
->gl_buffer
) {
225 gl_destroy_visual( osmesa
->gl_visual
);
226 gl_destroy_context( osmesa
->gl_ctx
);
230 osmesa
->format
= format
;
231 osmesa
->buffer
= NULL
;
235 osmesa
->clearpixel
= 0;
236 osmesa
->userRowLength
= 0;
237 osmesa
->rowlength
= 0;
238 osmesa
->yup
= GL_TRUE
;
239 osmesa
->rshift
= rshift
;
240 osmesa
->gshift
= gshift
;
241 osmesa
->bshift
= bshift
;
242 osmesa
->ashift
= ashift
;
253 * Destroy an Off-Screen Mesa rendering context.
255 * Input: ctx - the context to destroy
257 void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext ctx
)
260 gl_destroy_visual( ctx
->gl_visual
);
261 gl_destroy_framebuffer( ctx
->gl_buffer
);
262 gl_destroy_context( ctx
->gl_ctx
);
270 * Recompute the values of the context's rowaddr array.
272 static void compute_row_addresses( OSMesaContext ctx
)
277 /* Y=0 is bottom line of window */
278 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
280 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
281 for (i
=0;i
<MAX_HEIGHT
;i
++) {
282 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
286 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
287 /* 3-byte RGB mode */
288 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
289 for (i
=0;i
<MAX_HEIGHT
;i
++) {
290 ctx
->rowaddr
[i
] = origin
+ (i
* (ctx
->rowlength
*3));
293 /* 4-byte RGBA mode */
294 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
295 for (i
=0;i
<MAX_HEIGHT
;i
++) {
296 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
302 /* Y=0 is top line of window */
303 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
305 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
306 for (i
=0;i
<MAX_HEIGHT
;i
++) {
307 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
311 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
312 /* 3-byte RGB mode */
313 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
314 for (i
=0;i
<MAX_HEIGHT
;i
++) {
315 ctx
->rowaddr
[i
] = origin
+ ((ctx
->height
-i
-1) * (ctx
->rowlength
*3));
318 /* 4-byte RGBA mode */
319 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
320 for (i
=0;i
<MAX_HEIGHT
;i
++) {
321 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
330 * Bind an OSMesaContext to an image buffer. The image buffer is just a
331 * block of memory which the client provides. Its size must be at least
332 * as large as width*height*sizeof(type). Its address should be a multiple
333 * of 4 if using RGBA mode.
335 * Image data is stored in the order of glDrawPixels: row-major order
336 * with the lower-left image pixel stored in the first array position
337 * (ie. bottom-to-top).
339 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
340 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
341 * value. If the context is in color indexed mode, each pixel will be
342 * stored as a 1-byte value.
344 * If the context's viewport hasn't been initialized yet, it will now be
345 * initialized to (0,0,width,height).
347 * Input: ctx - the rendering context
348 * buffer - the image buffer memory
349 * type - data type for pixel components, only GL_UNSIGNED_BYTE
351 * width, height - size of image buffer in pixels, at least 1
352 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
353 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
354 * width>internal limit or height>internal limit.
357 OSMesaMakeCurrent( OSMesaContext ctx
, void *buffer
, GLenum type
,
358 GLsizei width
, GLsizei height
)
360 if (!ctx
|| !buffer
|| type
!=GL_UNSIGNED_BYTE
361 || width
<1 || height
<1 || width
>MAX_WIDTH
|| height
>MAX_HEIGHT
) {
365 osmesa_update_state( ctx
->gl_ctx
);
366 gl_make_current( ctx
->gl_ctx
, ctx
->gl_buffer
);
368 ctx
->buffer
= buffer
;
370 ctx
->height
= height
;
371 if (ctx
->userRowLength
)
372 ctx
->rowlength
= ctx
->userRowLength
;
374 ctx
->rowlength
= width
;
376 compute_row_addresses( ctx
);
379 if (ctx
->gl_ctx
->Viewport
.Width
==0) {
380 /* initialize viewport and scissor box to buffer size */
381 _mesa_Viewport( 0, 0, width
, height
);
382 ctx
->gl_ctx
->Scissor
.Width
= width
;
383 ctx
->gl_ctx
->Scissor
.Height
= height
;
392 OSMesaContext GLAPIENTRY
OSMesaGetCurrentContext( void )
394 GLcontext
*ctx
= gl_get_current_context();
396 return (OSMesaContext
) ctx
->DriverCtx
;
403 void GLAPIENTRY
OSMesaPixelStore( GLint pname
, GLint value
)
405 OSMesaContext ctx
= OSMesaGetCurrentContext();
408 case OSMESA_ROW_LENGTH
:
410 gl_error( ctx
->gl_ctx
, GL_INVALID_VALUE
,
411 "OSMesaPixelStore(value)" );
414 ctx
->userRowLength
= value
;
415 ctx
->rowlength
= value
;
418 ctx
->yup
= value
? GL_TRUE
: GL_FALSE
;
421 gl_error( ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaPixelStore(pname)" );
425 compute_row_addresses( ctx
);
429 void GLAPIENTRY
OSMesaGetIntegerv( GLint pname
, GLint
*value
)
431 OSMesaContext ctx
= OSMesaGetCurrentContext();
438 *value
= ctx
->height
;
441 *value
= ctx
->format
;
444 *value
= GL_UNSIGNED_BYTE
;
446 case OSMESA_ROW_LENGTH
:
447 *value
= ctx
->rowlength
;
453 gl_error( ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaGetIntergerv(pname)" );
461 * Return the depth buffer associated with an OSMesa context.
462 * Input: c - the OSMesa context
463 * Output: width, height - size of buffer in pixels
464 * bytesPerValue - bytes per depth value (2 or 4)
465 * buffer - pointer to depth buffer values
466 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
468 GLboolean GLAPIENTRY
OSMesaGetDepthBuffer( OSMesaContext c
, GLint
*width
, GLint
*height
,
469 GLint
*bytesPerValue
, void **buffer
)
471 if ((!c
->gl_buffer
) || (!c
->gl_buffer
->Depth
)) {
479 *width
= c
->gl_buffer
->Width
;
480 *height
= c
->gl_buffer
->Height
;
481 *bytesPerValue
= sizeof(GLdepth
);
482 *buffer
= c
->gl_buffer
->Depth
;
490 /**********************************************************************/
491 /*** Device Driver Functions ***/
492 /**********************************************************************/
498 #define PACK_RGBA(R,G,B,A) ( ((R) << osmesa->rshift) \
499 | ((G) << osmesa->gshift) \
500 | ((B) << osmesa->bshift) \
501 | ((A) << osmesa->ashift) )
503 #define PACK_RGBA2(R,G,B,A) ( ((R) << rshift) \
508 #define UNPACK_RED(P) (((P) >> osmesa->rshift) & 0xff)
509 #define UNPACK_GREEN(P) (((P) >> osmesa->gshift) & 0xff)
510 #define UNPACK_BLUE(P) (((P) >> osmesa->bshift) & 0xff)
511 #define UNPACK_ALPHA(P) (((P) >> osmesa->ashift) & 0xff)
513 #define PIXELADDR1(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + (X))
514 #define PIXELADDR3(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
515 #define PIXELADDR4(X,Y) ((GLuint *) osmesa->rowaddr[Y] + (X))
520 static GLboolean
set_draw_buffer( GLcontext
*ctx
, GLenum mode
)
523 if (mode
==GL_FRONT_LEFT
) {
532 static void set_read_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLenum mode
)
534 /* separate read buffer not supported */
535 ASSERT(buffer
== ctx
->DrawBuffer
);
536 ASSERT(mode
== GL_FRONT_LEFT
);
540 static void clear_index( GLcontext
*ctx
, GLuint index
)
542 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
543 osmesa
->clearpixel
= index
;
548 static void clear_color( GLcontext
*ctx
,
549 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
551 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
552 osmesa
->clearpixel
= PACK_RGBA( r
, g
, b
, a
);
557 static GLbitfield
clear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
558 GLint x
, GLint y
, GLint width
, GLint height
)
560 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
561 const GLuint
*colorMask
= (GLuint
*) &ctx
->Color
.ColorMask
;
563 /* we can't handle color or index masking */
564 if (*colorMask
!= 0xffffffff || ctx
->Color
.IndexMask
!= 0xffffffff)
567 /* sanity check - we only have a front-left buffer */
568 ASSERT((mask
& (DD_FRONT_RIGHT_BIT
| DD_BACK_LEFT_BIT
| DD_BACK_RIGHT_BIT
)) == 0);
570 if (mask
& DD_FRONT_LEFT_BIT
) {
571 if (osmesa
->format
==OSMESA_COLOR_INDEX
) {
573 /* Clear whole CI buffer */
574 MEMSET(osmesa
->buffer
, osmesa
->clearpixel
,
575 osmesa
->rowlength
* osmesa
->height
);
578 /* Clear part of CI buffer */
580 for (i
=0;i
<height
;i
++) {
581 GLubyte
*ptr1
= PIXELADDR1( x
, (y
+i
) );
582 for (j
=0;j
<width
;j
++) {
583 *ptr1
++ = osmesa
->clearpixel
;
588 else if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) {
589 GLubyte rval
= UNPACK_RED(osmesa
->clearpixel
);
590 GLubyte gval
= UNPACK_GREEN(osmesa
->clearpixel
);
591 GLubyte bval
= UNPACK_BLUE(osmesa
->clearpixel
);
592 GLint rind
= osmesa
->rind
;
593 GLint gind
= osmesa
->gind
;
594 GLint bind
= osmesa
->bind
;
597 GLubyte
*ptr3
= (GLubyte
*) osmesa
->buffer
;
598 /* Clear whole RGB buffer */
599 n
= osmesa
->rowlength
* osmesa
->height
;
608 /* Clear part of RGB buffer */
610 for (i
=0;i
<height
;i
++) {
611 GLubyte
*ptr3
= PIXELADDR3( x
, (y
+i
) );
612 for (j
=0;j
<width
;j
++) {
623 /* Clear whole RGBA buffer */
625 n
= osmesa
->rowlength
* osmesa
->height
;
626 ptr4
= (GLuint
*) osmesa
->buffer
;
628 *ptr4
++ = osmesa
->clearpixel
;
632 /* Clear part of RGBA buffer */
634 for (i
=0;i
<height
;i
++) {
635 GLuint
*ptr4
= PIXELADDR4( x
, (y
+i
) );
636 for (j
=0;j
<width
;j
++) {
637 *ptr4
++ = osmesa
->clearpixel
;
643 /* have Mesa clear all other buffers */
644 return mask
& (~DD_FRONT_LEFT_BIT
);
649 static void set_index( GLcontext
*ctx
, GLuint index
)
651 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
652 osmesa
->pixel
= index
;
657 static void set_color( GLcontext
*ctx
,
658 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
660 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
661 osmesa
->pixel
= PACK_RGBA( r
, g
, b
, a
);
666 static void buffer_size( GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
668 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
669 *width
= osmesa
->width
;
670 *height
= osmesa
->height
;
674 /**********************************************************************/
675 /***** Read/write spans/arrays of RGBA pixels *****/
676 /**********************************************************************/
678 /* Write RGBA pixels to an RGBA (or permuted) buffer. */
679 static void write_rgba_span( const GLcontext
*ctx
,
680 GLuint n
, GLint x
, GLint y
,
681 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
683 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
684 GLuint
*ptr4
= PIXELADDR4( x
, y
);
686 GLint rshift
= osmesa
->rshift
;
687 GLint gshift
= osmesa
->gshift
;
688 GLint bshift
= osmesa
->bshift
;
689 GLint ashift
= osmesa
->ashift
;
691 for (i
=0;i
<n
;i
++,ptr4
++) {
693 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
698 for (i
=0;i
<n
;i
++,ptr4
++) {
699 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
705 /* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
706 static void write_rgba_span_rgba( const GLcontext
*ctx
,
707 GLuint n
, GLint x
, GLint y
,
708 CONST GLubyte rgba
[][4],
709 const GLubyte mask
[] )
711 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
712 GLuint
*ptr4
= PIXELADDR4( x
, y
);
713 const GLuint
*rgba4
= (const GLuint
*) rgba
;
723 MEMCPY( ptr4
, rgba4
, n
* 4 );
728 /* Write RGB pixels to an RGBA (or permuted) buffer. */
729 static void write_rgb_span( const GLcontext
*ctx
,
730 GLuint n
, GLint x
, GLint y
,
731 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
733 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
734 GLuint
*ptr4
= PIXELADDR4( x
, y
);
736 GLint rshift
= osmesa
->rshift
;
737 GLint gshift
= osmesa
->gshift
;
738 GLint bshift
= osmesa
->bshift
;
739 GLint ashift
= osmesa
->ashift
;
741 for (i
=0;i
<n
;i
++,ptr4
++) {
743 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255 );
748 for (i
=0;i
<n
;i
++,ptr4
++) {
749 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255);
756 static void write_monocolor_span( const GLcontext
*ctx
,
757 GLuint n
, GLint x
, GLint y
,
758 const GLubyte mask
[] )
760 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
761 GLuint
*ptr4
= PIXELADDR4(x
,y
);
763 for (i
=0;i
<n
;i
++,ptr4
++) {
765 *ptr4
= osmesa
->pixel
;
772 static void write_rgba_pixels( const GLcontext
*ctx
,
773 GLuint n
, const GLint x
[], const GLint y
[],
774 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
776 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
778 GLint rshift
= osmesa
->rshift
;
779 GLint gshift
= osmesa
->gshift
;
780 GLint bshift
= osmesa
->bshift
;
781 GLint ashift
= osmesa
->ashift
;
784 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
785 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
792 static void write_monocolor_pixels( const GLcontext
*ctx
,
793 GLuint n
, const GLint x
[], const GLint y
[],
794 const GLubyte mask
[] )
796 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
800 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
801 *ptr4
= osmesa
->pixel
;
807 static void read_rgba_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
810 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
812 GLuint
*ptr4
= PIXELADDR4(x
,y
);
814 GLuint pixel
= *ptr4
++;
815 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
816 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
817 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
818 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
823 /* Read RGBA pixels from an RGBA buffer */
824 static void read_rgba_span_rgba( const GLcontext
*ctx
,
825 GLuint n
, GLint x
, GLint y
,
828 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
829 GLuint
*ptr4
= PIXELADDR4(x
,y
);
830 MEMCPY( rgba
, ptr4
, n
* 4 * sizeof(GLubyte
) );
834 static void read_rgba_pixels( const GLcontext
*ctx
,
835 GLuint n
, const GLint x
[], const GLint y
[],
836 GLubyte rgba
[][4], const GLubyte mask
[] )
838 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
842 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
843 GLuint pixel
= *ptr4
;
844 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
845 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
846 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
847 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
852 /**********************************************************************/
853 /***** 3 byte RGB pixel support funcs *****/
854 /**********************************************************************/
856 /* Write RGBA pixels to an RGB or BGR buffer. */
857 static void write_rgba_span3( const GLcontext
*ctx
,
858 GLuint n
, GLint x
, GLint y
,
859 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
861 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
862 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
864 GLint rind
= osmesa
->rind
;
865 GLint gind
= osmesa
->gind
;
866 GLint bind
= osmesa
->bind
;
868 for (i
=0;i
<n
;i
++,ptr3
+=3) {
870 ptr3
[rind
] = rgba
[i
][RCOMP
];
871 ptr3
[gind
] = rgba
[i
][GCOMP
];
872 ptr3
[bind
] = rgba
[i
][BCOMP
];
877 for (i
=0;i
<n
;i
++,ptr3
+=3) {
878 ptr3
[rind
] = rgba
[i
][RCOMP
];
879 ptr3
[gind
] = rgba
[i
][GCOMP
];
880 ptr3
[bind
] = rgba
[i
][BCOMP
];
885 /* Write RGB pixels to an RGB or BGR buffer. */
886 static void write_rgb_span3( const GLcontext
*ctx
,
887 GLuint n
, GLint x
, GLint y
,
888 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
890 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
891 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
893 GLint rind
= osmesa
->rind
;
894 GLint gind
= osmesa
->gind
;
895 GLint bind
= osmesa
->bind
;
897 for (i
=0;i
<n
;i
++,ptr3
+=3) {
899 ptr3
[rind
] = rgb
[i
][RCOMP
];
900 ptr3
[gind
] = rgb
[i
][GCOMP
];
901 ptr3
[bind
] = rgb
[i
][BCOMP
];
906 for (i
=0;i
<n
;i
++,ptr3
+=3) {
907 ptr3
[rind
] = rgb
[i
][RCOMP
];
908 ptr3
[gind
] = rgb
[i
][GCOMP
];
909 ptr3
[bind
] = rgb
[i
][BCOMP
];
915 static void write_monocolor_span3( const GLcontext
*ctx
,
916 GLuint n
, GLint x
, GLint y
,
917 const GLubyte mask
[] )
919 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
921 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
922 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
923 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
924 GLint rind
= osmesa
->rind
;
925 GLint gind
= osmesa
->gind
;
926 GLint bind
= osmesa
->bind
;
929 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
931 for (i
=0;i
<n
;i
++,ptr3
+=3) {
940 static void write_rgba_pixels3( const GLcontext
*ctx
,
941 GLuint n
, const GLint x
[], const GLint y
[],
942 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
944 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
946 GLint rind
= osmesa
->rind
;
947 GLint gind
= osmesa
->gind
;
948 GLint bind
= osmesa
->bind
;
952 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
953 ptr3
[rind
] = rgba
[i
][RCOMP
];
954 ptr3
[gind
] = rgba
[i
][GCOMP
];
955 ptr3
[bind
] = rgba
[i
][BCOMP
];
960 static void write_monocolor_pixels3( const GLcontext
*ctx
,
961 GLuint n
, const GLint x
[], const GLint y
[],
962 const GLubyte mask
[] )
964 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
966 GLint rind
= osmesa
->rind
;
967 GLint gind
= osmesa
->gind
;
968 GLint bind
= osmesa
->bind
;
969 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
970 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
971 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
974 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
982 static void read_rgba_span3( const GLcontext
*ctx
,
983 GLuint n
, GLint x
, GLint y
,
986 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
988 GLint rind
= osmesa
->rind
;
989 GLint gind
= osmesa
->gind
;
990 GLint bind
= osmesa
->bind
;
991 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
992 for (i
=0;i
<n
;i
++,ptr3
+=3) {
993 rgba
[i
][RCOMP
] = ptr3
[rind
];
994 rgba
[i
][GCOMP
] = ptr3
[gind
];
995 rgba
[i
][BCOMP
] = ptr3
[bind
];
1000 static void read_rgba_pixels3( const GLcontext
*ctx
,
1001 GLuint n
, const GLint x
[], const GLint y
[],
1002 GLubyte rgba
[][4], const GLubyte mask
[] )
1004 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1006 GLint rind
= osmesa
->rind
;
1007 GLint gind
= osmesa
->gind
;
1008 GLint bind
= osmesa
->bind
;
1011 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1012 rgba
[i
][RCOMP
] = ptr3
[rind
];
1013 rgba
[i
][GCOMP
] = ptr3
[gind
];
1014 rgba
[i
][BCOMP
] = ptr3
[bind
];
1021 /**********************************************************************/
1022 /***** Read/write spans/arrays of CI pixels *****/
1023 /**********************************************************************/
1025 /* Write 32-bit color index to buffer */
1026 static void write_index32_span( const GLcontext
*ctx
,
1027 GLuint n
, GLint x
, GLint y
,
1028 const GLuint index
[], const GLubyte mask
[] )
1030 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1031 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1034 for (i
=0;i
<n
;i
++,ptr1
++) {
1036 *ptr1
= (GLubyte
) index
[i
];
1041 for (i
=0;i
<n
;i
++,ptr1
++) {
1042 *ptr1
= (GLubyte
) index
[i
];
1048 /* Write 8-bit color index to buffer */
1049 static void write_index8_span( const GLcontext
*ctx
,
1050 GLuint n
, GLint x
, GLint y
,
1051 const GLubyte index
[], const GLubyte mask
[] )
1053 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1054 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1057 for (i
=0;i
<n
;i
++,ptr1
++) {
1059 *ptr1
= (GLubyte
) index
[i
];
1064 MEMCPY( ptr1
, index
, n
);
1069 static void write_monoindex_span( const GLcontext
*ctx
,
1070 GLuint n
, GLint x
, GLint y
,
1071 const GLubyte mask
[] )
1073 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1074 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1076 for (i
=0;i
<n
;i
++,ptr1
++) {
1078 *ptr1
= (GLubyte
) osmesa
->pixel
;
1084 static void write_index_pixels( const GLcontext
*ctx
,
1085 GLuint n
, const GLint x
[], const GLint y
[],
1086 const GLuint index
[], const GLubyte mask
[] )
1088 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1092 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1093 *ptr1
= (GLubyte
) index
[i
];
1099 static void write_monoindex_pixels( const GLcontext
*ctx
,
1100 GLuint n
, const GLint x
[], const GLint y
[],
1101 const GLubyte mask
[] )
1103 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1107 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1108 *ptr1
= (GLubyte
) osmesa
->pixel
;
1114 static void read_index_span( const GLcontext
*ctx
,
1115 GLuint n
, GLint x
, GLint y
, GLuint index
[] )
1117 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1119 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1120 for (i
=0;i
<n
;i
++,ptr1
++) {
1121 index
[i
] = (GLuint
) *ptr1
;
1126 static void read_index_pixels( const GLcontext
*ctx
,
1127 GLuint n
, const GLint x
[], const GLint y
[],
1128 GLuint index
[], const GLubyte mask
[] )
1130 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1134 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1135 index
[i
] = (GLuint
) *ptr1
;
1142 /**********************************************************************/
1143 /***** Optimized line rendering *****/
1144 /**********************************************************************/
1148 * Draw a flat-shaded, RGB line into an osmesa buffer.
1150 static void flat_rgba_line( GLcontext
*ctx
,
1151 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1153 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1154 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1155 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1159 #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
1162 #include "..\linetemp.h"
1164 #include "linetemp.h"
1170 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1172 static void flat_rgba_z_line( GLcontext
*ctx
,
1173 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1175 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1176 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1177 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1184 GLuint *ptr4 = PIXELADDR4(X,Y); \
1190 #include "..\linetemp.h"
1192 #include "linetemp.h"
1198 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1200 static void flat_blend_rgba_line( GLcontext
*ctx
,
1201 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1203 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1204 struct vertex_buffer
*VB
= ctx
->VB
;
1205 GLint rshift
= osmesa
->rshift
;
1206 GLint gshift
= osmesa
->gshift
;
1207 GLint bshift
= osmesa
->bshift
;
1208 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1209 GLint msavalue
= 255 - avalue
;
1210 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1211 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1212 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1217 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1219 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1220 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1221 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1226 #include "..\linetemp.h"
1228 #include "linetemp.h"
1233 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1235 static void flat_blend_rgba_z_line( GLcontext
*ctx
,
1236 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1238 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1239 struct vertex_buffer
*VB
= ctx
->VB
;
1240 GLint rshift
= osmesa
->rshift
;
1241 GLint gshift
= osmesa
->gshift
;
1242 GLint bshift
= osmesa
->bshift
;
1243 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1244 GLint msavalue
= 256 - avalue
;
1245 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1246 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1247 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1254 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1256 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1257 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1258 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1264 #include "..\linetemp.h"
1266 #include "linetemp.h"
1271 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1273 static void flat_blend_rgba_z_line_write( GLcontext
*ctx
,
1274 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1276 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1277 struct vertex_buffer
*VB
= ctx
->VB
;
1278 GLint rshift
= osmesa
->rshift
;
1279 GLint gshift
= osmesa
->gshift
;
1280 GLint bshift
= osmesa
->bshift
;
1281 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1282 GLint msavalue
= 256 - avalue
;
1283 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1284 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1285 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1292 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1294 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1295 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1296 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1303 #include "..\linetemp.h"
1305 #include "linetemp.h"
1311 * Analyze context state to see if we can provide a fast line drawing
1312 * function, like those in lines.c. Otherwise, return NULL.
1314 static line_func
choose_line_function( GLcontext
*ctx
)
1316 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1318 if (ctx
->Line
.SmoothFlag
) return NULL
;
1319 if (ctx
->Texture
.Enabled
) return NULL
;
1320 if (ctx
->Light
.ShadeModel
!=GL_FLAT
) return NULL
;
1322 if (ctx
->Line
.Width
==1.0F
1323 && ctx
->Line
.StippleFlag
==GL_FALSE
) {
1325 if (ctx
->RasterMask
==DEPTH_BIT
1326 && ctx
->Depth
.Func
==GL_LESS
1327 && ctx
->Depth
.Mask
==GL_TRUE
) {
1328 switch(osmesa
->format
) {
1332 return flat_rgba_z_line
;
1338 if (ctx
->RasterMask
==0) {
1339 switch(osmesa
->format
) {
1343 return flat_rgba_line
;
1349 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1350 && ctx
->Depth
.Func
==GL_LESS
1351 && ctx
->Depth
.Mask
==GL_TRUE
1352 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1353 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1354 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1355 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1356 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1357 switch(osmesa
->format
) {
1361 return flat_blend_rgba_z_line_write
;
1367 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1368 && ctx
->Depth
.Func
==GL_LESS
1369 && ctx
->Depth
.Mask
==GL_FALSE
1370 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1371 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1372 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1373 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1374 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1375 switch(osmesa
->format
) {
1379 return flat_blend_rgba_z_line
;
1385 if (ctx
->RasterMask
==BLEND_BIT
1386 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1387 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1388 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1389 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1390 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1391 switch(osmesa
->format
) {
1395 return flat_blend_rgba_line
;
1406 /**********************************************************************/
1407 /***** Optimized triangle rendering *****/
1408 /**********************************************************************/
1412 * Smooth-shaded, z-less triangle, RGBA color.
1414 static void smooth_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1415 GLuint v2
, GLuint pv
)
1417 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1418 GLint rshift
= osmesa
->rshift
;
1419 GLint gshift
= osmesa
->gshift
;
1420 GLint bshift
= osmesa
->bshift
;
1421 GLint ashift
= osmesa
->ashift
;
1424 #define INTERP_RGB 1
1425 #define INTERP_ALPHA 1
1426 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1428 GLint i, len = RIGHT-LEFT; \
1429 GLuint *img = PIXELADDR4(LEFT,Y); \
1430 for (i=0;i<len;i++,img++) { \
1431 GLdepth z = FixedToDepth(ffz); \
1432 if (z < zRow[i]) { \
1433 *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg), \
1434 FixedToInt(ffb), FixedToInt(ffa) ); \
1437 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1442 #include "..\tritemp.h"
1444 #include "tritemp.h"
1452 * Flat-shaded, z-less triangle, RGBA color.
1454 static void flat_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1455 GLuint v2
, GLuint pv
)
1457 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1459 #define SETUP_CODE \
1460 GLubyte r = VB->ColorPtr->data[pv][0]; \
1461 GLubyte g = VB->ColorPtr->data[pv][1]; \
1462 GLubyte b = VB->ColorPtr->data[pv][2]; \
1463 GLubyte a = VB->ColorPtr->data[pv][3]; \
1464 GLuint pixel = PACK_RGBA(r,g,b,a);
1466 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1468 GLint i, len = RIGHT-LEFT; \
1469 GLuint *img = PIXELADDR4(LEFT,Y); \
1470 for (i=0;i<len;i++,img++) { \
1471 GLdepth z = FixedToDepth(ffz); \
1472 if (z < zRow[i]) { \
1480 #include "..\tritemp.h"
1482 #include "tritemp.h"
1489 * Return pointer to an accelerated triangle function if possible.
1491 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
1493 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1495 if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) return NULL
;
1497 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
1498 if (ctx
->Polygon
.StippleFlag
) return NULL
;
1499 if (ctx
->Texture
.Enabled
) return NULL
;
1501 if (ctx
->RasterMask
==DEPTH_BIT
1502 && ctx
->Depth
.Func
==GL_LESS
1503 && ctx
->Depth
.Mask
==GL_TRUE
1504 && osmesa
->format
!=OSMESA_COLOR_INDEX
) {
1505 if (ctx
->Light
.ShadeModel
==GL_SMOOTH
) {
1506 return smooth_rgba_z_triangle
;
1509 return flat_rgba_z_triangle
;
1517 static const GLubyte
*get_string( GLcontext
*ctx
, GLenum name
)
1522 return (const GLubyte
*) "Mesa OffScreen";
1529 static void osmesa_update_state( GLcontext
*ctx
)
1531 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1533 ctx
->Driver
.GetString
= get_string
;
1534 ctx
->Driver
.UpdateState
= osmesa_update_state
;
1536 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1537 ctx
->Driver
.SetReadBuffer
= set_read_buffer
;
1538 ctx
->Driver
.Color
= set_color
;
1539 ctx
->Driver
.Index
= set_index
;
1540 ctx
->Driver
.ClearIndex
= clear_index
;
1541 ctx
->Driver
.ClearColor
= clear_color
;
1542 ctx
->Driver
.Clear
= clear
;
1544 ctx
->Driver
.GetBufferSize
= buffer_size
;
1546 ctx
->Driver
.PointsFunc
= NULL
;
1547 ctx
->Driver
.LineFunc
= choose_line_function( ctx
);
1548 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1551 /* RGB(A) span/pixel functions */
1552 if ((osmesa
->format
==OSMESA_RGB
) || (osmesa
->format
==OSMESA_BGR
)) {
1553 /* 3 bytes / pixel in frame buffer */
1554 ctx
->Driver
.WriteRGBASpan
= write_rgba_span3
;
1555 ctx
->Driver
.WriteRGBSpan
= write_rgb_span3
;
1556 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels3
;
1557 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span3
;
1558 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels3
;
1559 ctx
->Driver
.ReadRGBASpan
= read_rgba_span3
;
1560 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels3
;
1563 /* 4 bytes / pixel in frame buffer */
1564 if (osmesa
->format
==OSMESA_RGBA
1565 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1566 ctx
->Driver
.WriteRGBASpan
= write_rgba_span_rgba
;
1568 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1569 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1570 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1571 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span
;
1572 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels
;
1573 if (osmesa
->format
==OSMESA_RGBA
1574 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1575 ctx
->Driver
.ReadRGBASpan
= read_rgba_span_rgba
;
1577 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1578 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1581 /* CI span/pixel functions */
1582 ctx
->Driver
.WriteCI32Span
= write_index32_span
;
1583 ctx
->Driver
.WriteCI8Span
= write_index8_span
;
1584 ctx
->Driver
.WriteMonoCISpan
= write_monoindex_span
;
1585 ctx
->Driver
.WriteCI32Pixels
= write_index_pixels
;
1586 ctx
->Driver
.WriteMonoCIPixels
= write_monoindex_pixels
;
1587 ctx
->Driver
.ReadCI32Span
= read_index_span
;
1588 ctx
->Driver
.ReadCI32Pixels
= read_index_pixels
;