1 /* $Id: osmesa.c,v 1.5 1999/12/10 19:09:59 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
38 #include "GL/osmesa.h"
48 struct osmesa_context
{
49 GLcontext
*gl_ctx
; /* The core GL/Mesa context */
50 GLvisual
*gl_visual
; /* Describes the buffers */
51 GLframebuffer
*gl_buffer
; /* Depth, stencil, accum, etc buffers */
52 GLenum format
; /* either GL_RGBA or GL_COLOR_INDEX */
53 void *buffer
; /* the image buffer */
54 GLint width
, height
; /* size of image buffer */
55 GLuint pixel
; /* current color index or RGBA pixel value */
56 GLuint clearpixel
; /* pixel for clearing the color buffer */
57 GLint rowlength
; /* number of pixels per row */
58 GLint userRowLength
; /* user-specified number of pixels per row */
59 GLint rshift
, gshift
; /* bit shifts for RGBA formats */
61 GLint rind
, gind
, bind
; /* index offsets for RGBA formats */
62 void *rowaddr
[MAX_HEIGHT
]; /* address of first pixel in each image row */
63 GLboolean yup
; /* TRUE -> Y increases upward */
64 /* FALSE -> Y increases downward */
71 #include "mthreads.h" /* Mesa platform independent threads interface */
73 static MesaTSD osmesa_ctx_tsd
;
75 static void osmesa_ctx_thread_init() {
76 MesaInitTSD(&osmesa_ctx_tsd
);
79 static OSMesaContext
osmesa_get_thread_context( void ) {
80 return (OSMesaContext
) MesaGetTSD(&osmesa_ctx_tsd
);
83 static void osmesa_set_thread_context( OSMesaContext ctx
) {
84 MesaSetTSD(&osmesa_ctx_tsd
, ctx
, osmesa_ctx_thread_init
);
89 /* One current context for address space, all threads */
90 static OSMesaContext Current
= NULL
;
95 /* A forward declaration: */
96 static void osmesa_update_state( GLcontext
*ctx
);
100 /**********************************************************************/
101 /***** Public Functions *****/
102 /**********************************************************************/
106 * Create an Off-Screen Mesa rendering context. The only attribute needed is
107 * an RGBA vs Color-Index mode flag.
109 * Input: format - either GL_RGBA or GL_COLOR_INDEX
110 * sharelist - specifies another OSMesaContext with which to share
111 * display lists. NULL indicates no sharing.
112 * Return: an OSMesaContext or 0 if error
114 OSMesaContext GLAPIENTRY
OSMesaCreateContext( GLenum format
, OSMesaContext sharelist
)
116 OSMesaContext osmesa
;
117 GLint rshift
, gshift
, bshift
, ashift
;
118 GLint rind
, gind
, bind
;
119 GLint indexBits
, alphaBits
;
123 GLubyte
*i1
= (GLubyte
*) &i4
;
124 GLint little_endian
= *i1
;
127 rind
= gind
= bind
= 0;
128 if (format
==OSMESA_COLOR_INDEX
) {
130 rshift
= gshift
= bshift
= ashift
= 0;
133 else if (format
==OSMESA_RGBA
) {
150 else if (format
==OSMESA_BGRA
) {
167 else if (format
==OSMESA_ARGB
) {
184 else if (format
==OSMESA_RGB
) {
197 else if (format
==OSMESA_BGR
) {
215 osmesa
= (OSMesaContext
) CALLOC_STRUCT(osmesa_context
);
217 osmesa
->gl_visual
= gl_create_visual( rgbmode
,
218 swalpha
, /* software alpha */
219 GL_FALSE
, /* double buffer */
220 GL_FALSE
, /* stereo */
223 rgbmode
? ACCUM_BITS
: 0,
225 8, 8, 8, alphaBits
);
226 if (!osmesa
->gl_visual
) {
230 osmesa
->gl_ctx
= gl_create_context( osmesa
->gl_visual
,
231 sharelist
? sharelist
->gl_ctx
: (GLcontext
*) NULL
,
232 (void *) osmesa
, GL_TRUE
);
233 if (!osmesa
->gl_ctx
) {
234 gl_destroy_visual( osmesa
->gl_visual
);
238 osmesa
->gl_buffer
= gl_create_framebuffer( osmesa
->gl_visual
,
239 osmesa
->gl_visual
->DepthBits
> 0,
240 osmesa
->gl_visual
->StencilBits
> 0,
241 osmesa
->gl_visual
->AccumBits
> 0,
242 osmesa
->gl_visual
->AlphaBits
> 0 );
244 if (!osmesa
->gl_buffer
) {
245 gl_destroy_visual( osmesa
->gl_visual
);
246 gl_destroy_context( osmesa
->gl_ctx
);
250 osmesa
->format
= format
;
251 osmesa
->buffer
= NULL
;
255 osmesa
->clearpixel
= 0;
256 osmesa
->userRowLength
= 0;
257 osmesa
->rowlength
= 0;
258 osmesa
->yup
= GL_TRUE
;
259 osmesa
->rshift
= rshift
;
260 osmesa
->gshift
= gshift
;
261 osmesa
->bshift
= bshift
;
262 osmesa
->ashift
= ashift
;
273 * Destroy an Off-Screen Mesa rendering context.
275 * Input: ctx - the context to destroy
277 void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext ctx
)
280 gl_destroy_visual( ctx
->gl_visual
);
281 gl_destroy_framebuffer( ctx
->gl_buffer
);
282 gl_destroy_context( ctx
->gl_ctx
);
290 * Recompute the values of the context's rowaddr array.
292 static void compute_row_addresses( OSMesaContext ctx
)
297 /* Y=0 is bottom line of window */
298 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
300 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
301 for (i
=0;i
<MAX_HEIGHT
;i
++) {
302 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
306 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
307 /* 3-byte RGB mode */
308 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
309 for (i
=0;i
<MAX_HEIGHT
;i
++) {
310 ctx
->rowaddr
[i
] = origin
+ (i
* (ctx
->rowlength
*3));
313 /* 4-byte RGBA mode */
314 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
315 for (i
=0;i
<MAX_HEIGHT
;i
++) {
316 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
322 /* Y=0 is top line of window */
323 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
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
;
331 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
332 /* 3-byte RGB mode */
333 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
334 for (i
=0;i
<MAX_HEIGHT
;i
++) {
335 ctx
->rowaddr
[i
] = origin
+ ((ctx
->height
-i
-1) * (ctx
->rowlength
*3));
338 /* 4-byte RGBA mode */
339 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
340 for (i
=0;i
<MAX_HEIGHT
;i
++) {
341 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
350 * Bind an OSMesaContext to an image buffer. The image buffer is just a
351 * block of memory which the client provides. Its size must be at least
352 * as large as width*height*sizeof(type). Its address should be a multiple
353 * of 4 if using RGBA mode.
355 * Image data is stored in the order of glDrawPixels: row-major order
356 * with the lower-left image pixel stored in the first array position
357 * (ie. bottom-to-top).
359 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
360 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
361 * value. If the context is in color indexed mode, each pixel will be
362 * stored as a 1-byte value.
364 * If the context's viewport hasn't been initialized yet, it will now be
365 * initialized to (0,0,width,height).
367 * Input: ctx - the rendering context
368 * buffer - the image buffer memory
369 * type - data type for pixel components, only GL_UNSIGNED_BYTE
371 * width, height - size of image buffer in pixels, at least 1
372 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
373 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
374 * width>internal limit or height>internal limit.
376 GLboolean GLAPIENTRY
OSMesaMakeCurrent( OSMesaContext ctx
, void *buffer
, GLenum type
,
377 GLsizei width
, GLsizei height
)
379 if (!ctx
|| !buffer
|| type
!=GL_UNSIGNED_BYTE
380 || width
<1 || height
<1 || width
>MAX_WIDTH
|| height
>MAX_HEIGHT
) {
384 osmesa_update_state( ctx
->gl_ctx
);
385 gl_make_current( ctx
->gl_ctx
, ctx
->gl_buffer
);
387 ctx
->buffer
= buffer
;
389 ctx
->height
= height
;
390 if (ctx
->userRowLength
)
391 ctx
->rowlength
= ctx
->userRowLength
;
393 ctx
->rowlength
= width
;
396 /* Set current context for the calling thread */
397 osmesa_set_thread_context(ctx
);
399 /* Set current context for the address space, all threads */
403 compute_row_addresses( ctx
);
406 if (ctx
->gl_ctx
->Viewport
.Width
==0) {
407 /* initialize viewport and scissor box to buffer size */
408 _mesa_Viewport( 0, 0, width
, height
);
409 ctx
->gl_ctx
->Scissor
.Width
= width
;
410 ctx
->gl_ctx
->Scissor
.Height
= height
;
419 OSMesaContext GLAPIENTRY
OSMesaGetCurrentContext( void )
422 /* Return current handle for the calling thread */
423 return osmesa_get_thread_context();
425 /* Return current handle for the address space, all threads */
432 void GLAPIENTRY
OSMesaPixelStore( GLint pname
, GLint value
)
434 OSMesaContext ctx
= OSMesaGetCurrentContext();
437 case OSMESA_ROW_LENGTH
:
439 gl_error( ctx
->gl_ctx
, GL_INVALID_VALUE
,
440 "OSMesaPixelStore(value)" );
443 ctx
->userRowLength
= value
;
444 ctx
->rowlength
= value
;
447 ctx
->yup
= value
? GL_TRUE
: GL_FALSE
;
450 gl_error( ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaPixelStore(pname)" );
454 compute_row_addresses( ctx
);
458 void GLAPIENTRY
OSMesaGetIntegerv( GLint pname
, GLint
*value
)
460 OSMesaContext ctx
= OSMesaGetCurrentContext();
467 *value
= ctx
->height
;
470 *value
= ctx
->format
;
473 *value
= GL_UNSIGNED_BYTE
;
475 case OSMESA_ROW_LENGTH
:
476 *value
= ctx
->rowlength
;
482 gl_error( ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaGetIntergerv(pname)" );
490 * Return the depth buffer associated with an OSMesa context.
491 * Input: c - the OSMesa context
492 * Output: width, height - size of buffer in pixels
493 * bytesPerValue - bytes per depth value (2 or 4)
494 * buffer - pointer to depth buffer values
495 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
497 GLboolean GLAPIENTRY
OSMesaGetDepthBuffer( OSMesaContext c
, GLint
*width
, GLint
*height
,
498 GLint
*bytesPerValue
, void **buffer
)
500 if ((!c
->gl_buffer
) || (!c
->gl_buffer
->Depth
)) {
508 *width
= c
->gl_buffer
->Width
;
509 *height
= c
->gl_buffer
->Height
;
510 *bytesPerValue
= sizeof(GLdepth
);
511 *buffer
= c
->gl_buffer
->Depth
;
519 /**********************************************************************/
520 /*** Device Driver Functions ***/
521 /**********************************************************************/
527 #define PACK_RGBA(R,G,B,A) ( ((R) << osmesa->rshift) \
528 | ((G) << osmesa->gshift) \
529 | ((B) << osmesa->bshift) \
530 | ((A) << osmesa->ashift) )
532 #define PACK_RGBA2(R,G,B,A) ( ((R) << rshift) \
537 #define UNPACK_RED(P) (((P) >> osmesa->rshift) & 0xff)
538 #define UNPACK_GREEN(P) (((P) >> osmesa->gshift) & 0xff)
539 #define UNPACK_BLUE(P) (((P) >> osmesa->bshift) & 0xff)
540 #define UNPACK_ALPHA(P) (((P) >> osmesa->ashift) & 0xff)
542 #define PIXELADDR1(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + (X))
543 #define PIXELADDR3(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
544 #define PIXELADDR4(X,Y) ((GLuint *) osmesa->rowaddr[Y] + (X))
549 static GLboolean
set_draw_buffer( GLcontext
*ctx
, GLenum mode
)
552 if (mode
==GL_FRONT_LEFT
) {
561 static void set_read_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLenum mode
)
563 /* separate read buffer not supported */
564 ASSERT(buffer
== ctx
->DrawBuffer
);
565 ASSERT(mode
== GL_FRONT_LEFT
);
569 static void clear_index( GLcontext
*ctx
, GLuint index
)
571 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
572 osmesa
->clearpixel
= index
;
577 static void clear_color( GLcontext
*ctx
,
578 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
580 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
581 osmesa
->clearpixel
= PACK_RGBA( r
, g
, b
, a
);
586 static GLbitfield
clear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
587 GLint x
, GLint y
, GLint width
, GLint height
)
589 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
590 if (mask
& GL_COLOR_BUFFER_BIT
) {
591 if (osmesa
->format
==OSMESA_COLOR_INDEX
) {
593 /* Clear whole CI buffer */
594 MEMSET(osmesa
->buffer
, osmesa
->clearpixel
,
595 osmesa
->rowlength
* osmesa
->height
);
598 /* Clear part of CI buffer */
600 for (i
=0;i
<height
;i
++) {
601 GLubyte
*ptr1
= PIXELADDR1( x
, (y
+i
) );
602 for (j
=0;j
<width
;j
++) {
603 *ptr1
++ = osmesa
->clearpixel
;
608 else if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) {
609 GLubyte rval
= UNPACK_RED(osmesa
->clearpixel
);
610 GLubyte gval
= UNPACK_GREEN(osmesa
->clearpixel
);
611 GLubyte bval
= UNPACK_BLUE(osmesa
->clearpixel
);
612 GLint rind
= osmesa
->rind
;
613 GLint gind
= osmesa
->gind
;
614 GLint bind
= osmesa
->bind
;
617 GLubyte
*ptr3
= (GLubyte
*) osmesa
->buffer
;
618 /* Clear whole RGB buffer */
619 n
= osmesa
->rowlength
* osmesa
->height
;
628 /* Clear part of RGB buffer */
630 for (i
=0;i
<height
;i
++) {
631 GLubyte
*ptr3
= PIXELADDR3( x
, (y
+i
) );
632 for (j
=0;j
<width
;j
++) {
643 /* Clear whole RGBA buffer */
645 n
= osmesa
->rowlength
* osmesa
->height
;
646 ptr4
= (GLuint
*) osmesa
->buffer
;
648 *ptr4
++ = osmesa
->clearpixel
;
652 /* Clear part of RGBA buffer */
654 for (i
=0;i
<height
;i
++) {
655 GLuint
*ptr4
= PIXELADDR4( x
, (y
+i
) );
656 for (j
=0;j
<width
;j
++) {
657 *ptr4
++ = osmesa
->clearpixel
;
663 return mask
& (~GL_COLOR_BUFFER_BIT
);
668 static void set_index( GLcontext
*ctx
, GLuint index
)
670 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
671 osmesa
->pixel
= index
;
676 static void set_color( GLcontext
*ctx
,
677 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
679 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
680 osmesa
->pixel
= PACK_RGBA( r
, g
, b
, a
);
685 static void buffer_size( GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
687 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
688 *width
= osmesa
->width
;
689 *height
= osmesa
->height
;
693 /**********************************************************************/
694 /***** Read/write spans/arrays of RGBA pixels *****/
695 /**********************************************************************/
697 /* Write RGBA pixels to an RGBA (or permuted) buffer. */
698 static void write_rgba_span( const GLcontext
*ctx
,
699 GLuint n
, GLint x
, GLint y
,
700 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
702 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
703 GLuint
*ptr4
= PIXELADDR4( x
, y
);
705 GLint rshift
= osmesa
->rshift
;
706 GLint gshift
= osmesa
->gshift
;
707 GLint bshift
= osmesa
->bshift
;
708 GLint ashift
= osmesa
->ashift
;
710 for (i
=0;i
<n
;i
++,ptr4
++) {
712 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
717 for (i
=0;i
<n
;i
++,ptr4
++) {
718 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
724 /* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
725 static void write_rgba_span_rgba( const GLcontext
*ctx
,
726 GLuint n
, GLint x
, GLint y
,
727 CONST GLubyte rgba
[][4],
728 const GLubyte mask
[] )
730 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
731 GLuint
*ptr4
= PIXELADDR4( x
, y
);
732 const GLuint
*rgba4
= (const GLuint
*) rgba
;
742 MEMCPY( ptr4
, rgba4
, n
* 4 );
747 /* Write RGB pixels to an RGBA (or permuted) buffer. */
748 static void write_rgb_span( const GLcontext
*ctx
,
749 GLuint n
, GLint x
, GLint y
,
750 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
752 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
753 GLuint
*ptr4
= PIXELADDR4( x
, y
);
755 GLint rshift
= osmesa
->rshift
;
756 GLint gshift
= osmesa
->gshift
;
757 GLint bshift
= osmesa
->bshift
;
758 GLint ashift
= osmesa
->ashift
;
760 for (i
=0;i
<n
;i
++,ptr4
++) {
762 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255 );
767 for (i
=0;i
<n
;i
++,ptr4
++) {
768 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255);
775 static void write_monocolor_span( const GLcontext
*ctx
,
776 GLuint n
, GLint x
, GLint y
,
777 const GLubyte mask
[] )
779 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
780 GLuint
*ptr4
= PIXELADDR4(x
,y
);
782 for (i
=0;i
<n
;i
++,ptr4
++) {
784 *ptr4
= osmesa
->pixel
;
791 static void write_rgba_pixels( const GLcontext
*ctx
,
792 GLuint n
, const GLint x
[], const GLint y
[],
793 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
795 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
797 GLint rshift
= osmesa
->rshift
;
798 GLint gshift
= osmesa
->gshift
;
799 GLint bshift
= osmesa
->bshift
;
800 GLint ashift
= osmesa
->ashift
;
803 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
804 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
811 static void write_monocolor_pixels( const GLcontext
*ctx
,
812 GLuint n
, const GLint x
[], const GLint y
[],
813 const GLubyte mask
[] )
815 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
819 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
820 *ptr4
= osmesa
->pixel
;
826 static void read_rgba_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
829 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
831 GLuint
*ptr4
= PIXELADDR4(x
,y
);
833 GLuint pixel
= *ptr4
++;
834 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
835 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
836 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
837 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
842 /* Read RGBA pixels from an RGBA buffer */
843 static void read_rgba_span_rgba( const GLcontext
*ctx
,
844 GLuint n
, GLint x
, GLint y
,
847 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
848 GLuint
*ptr4
= PIXELADDR4(x
,y
);
849 MEMCPY( rgba
, ptr4
, n
* 4 * sizeof(GLubyte
) );
853 static void read_rgba_pixels( const GLcontext
*ctx
,
854 GLuint n
, const GLint x
[], const GLint y
[],
855 GLubyte rgba
[][4], const GLubyte mask
[] )
857 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
861 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
862 GLuint pixel
= *ptr4
;
863 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
864 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
865 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
866 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
871 /**********************************************************************/
872 /***** 3 byte RGB pixel support funcs *****/
873 /**********************************************************************/
875 /* Write RGBA pixels to an RGB or BGR buffer. */
876 static void write_rgba_span3( const GLcontext
*ctx
,
877 GLuint n
, GLint x
, GLint y
,
878 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
880 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
881 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
883 GLint rind
= osmesa
->rind
;
884 GLint gind
= osmesa
->gind
;
885 GLint bind
= osmesa
->bind
;
887 for (i
=0;i
<n
;i
++,ptr3
+=3) {
889 ptr3
[rind
] = rgba
[i
][RCOMP
];
890 ptr3
[gind
] = rgba
[i
][GCOMP
];
891 ptr3
[bind
] = rgba
[i
][BCOMP
];
896 for (i
=0;i
<n
;i
++,ptr3
+=3) {
897 ptr3
[rind
] = rgba
[i
][RCOMP
];
898 ptr3
[gind
] = rgba
[i
][GCOMP
];
899 ptr3
[bind
] = rgba
[i
][BCOMP
];
904 /* Write RGB pixels to an RGB or BGR buffer. */
905 static void write_rgb_span3( const GLcontext
*ctx
,
906 GLuint n
, GLint x
, GLint y
,
907 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
909 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
910 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
912 GLint rind
= osmesa
->rind
;
913 GLint gind
= osmesa
->gind
;
914 GLint bind
= osmesa
->bind
;
916 for (i
=0;i
<n
;i
++,ptr3
+=3) {
918 ptr3
[rind
] = rgb
[i
][RCOMP
];
919 ptr3
[gind
] = rgb
[i
][GCOMP
];
920 ptr3
[bind
] = rgb
[i
][BCOMP
];
925 for (i
=0;i
<n
;i
++,ptr3
+=3) {
926 ptr3
[rind
] = rgb
[i
][RCOMP
];
927 ptr3
[gind
] = rgb
[i
][GCOMP
];
928 ptr3
[bind
] = rgb
[i
][BCOMP
];
934 static void write_monocolor_span3( const GLcontext
*ctx
,
935 GLuint n
, GLint x
, GLint y
,
936 const GLubyte mask
[] )
938 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
940 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
941 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
942 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
943 GLint rind
= osmesa
->rind
;
944 GLint gind
= osmesa
->gind
;
945 GLint bind
= osmesa
->bind
;
948 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
950 for (i
=0;i
<n
;i
++,ptr3
+=3) {
959 static void write_rgba_pixels3( const GLcontext
*ctx
,
960 GLuint n
, const GLint x
[], const GLint y
[],
961 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
963 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
965 GLint rind
= osmesa
->rind
;
966 GLint gind
= osmesa
->gind
;
967 GLint bind
= osmesa
->bind
;
971 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
972 ptr3
[rind
] = rgba
[i
][RCOMP
];
973 ptr3
[gind
] = rgba
[i
][GCOMP
];
974 ptr3
[bind
] = rgba
[i
][BCOMP
];
979 static void write_monocolor_pixels3( const GLcontext
*ctx
,
980 GLuint n
, const GLint x
[], const GLint y
[],
981 const GLubyte mask
[] )
983 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
985 GLint rind
= osmesa
->rind
;
986 GLint gind
= osmesa
->gind
;
987 GLint bind
= osmesa
->bind
;
988 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
989 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
990 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
993 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1001 static void read_rgba_span3( const GLcontext
*ctx
,
1002 GLuint n
, GLint x
, GLint y
,
1005 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1007 GLint rind
= osmesa
->rind
;
1008 GLint gind
= osmesa
->gind
;
1009 GLint bind
= osmesa
->bind
;
1010 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
1011 for (i
=0;i
<n
;i
++,ptr3
+=3) {
1012 rgba
[i
][RCOMP
] = ptr3
[rind
];
1013 rgba
[i
][GCOMP
] = ptr3
[gind
];
1014 rgba
[i
][BCOMP
] = ptr3
[bind
];
1019 static void read_rgba_pixels3( const GLcontext
*ctx
,
1020 GLuint n
, const GLint x
[], const GLint y
[],
1021 GLubyte rgba
[][4], const GLubyte mask
[] )
1023 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1025 GLint rind
= osmesa
->rind
;
1026 GLint gind
= osmesa
->gind
;
1027 GLint bind
= osmesa
->bind
;
1030 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1031 rgba
[i
][RCOMP
] = ptr3
[rind
];
1032 rgba
[i
][GCOMP
] = ptr3
[gind
];
1033 rgba
[i
][BCOMP
] = ptr3
[bind
];
1040 /**********************************************************************/
1041 /***** Read/write spans/arrays of CI pixels *****/
1042 /**********************************************************************/
1044 /* Write 32-bit color index to buffer */
1045 static void write_index32_span( const GLcontext
*ctx
,
1046 GLuint n
, GLint x
, GLint y
,
1047 const GLuint index
[], const GLubyte mask
[] )
1049 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1050 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1053 for (i
=0;i
<n
;i
++,ptr1
++) {
1055 *ptr1
= (GLubyte
) index
[i
];
1060 for (i
=0;i
<n
;i
++,ptr1
++) {
1061 *ptr1
= (GLubyte
) index
[i
];
1067 /* Write 8-bit color index to buffer */
1068 static void write_index8_span( const GLcontext
*ctx
,
1069 GLuint n
, GLint x
, GLint y
,
1070 const GLubyte index
[], const GLubyte mask
[] )
1072 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1073 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1076 for (i
=0;i
<n
;i
++,ptr1
++) {
1078 *ptr1
= (GLubyte
) index
[i
];
1083 MEMCPY( ptr1
, index
, n
);
1088 static void write_monoindex_span( const GLcontext
*ctx
,
1089 GLuint n
, GLint x
, GLint y
,
1090 const GLubyte mask
[] )
1092 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1093 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1095 for (i
=0;i
<n
;i
++,ptr1
++) {
1097 *ptr1
= (GLubyte
) osmesa
->pixel
;
1103 static void write_index_pixels( const GLcontext
*ctx
,
1104 GLuint n
, const GLint x
[], const GLint y
[],
1105 const GLuint index
[], const GLubyte mask
[] )
1107 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1111 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1112 *ptr1
= (GLubyte
) index
[i
];
1118 static void write_monoindex_pixels( const GLcontext
*ctx
,
1119 GLuint n
, const GLint x
[], const GLint y
[],
1120 const GLubyte mask
[] )
1122 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1126 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1127 *ptr1
= (GLubyte
) osmesa
->pixel
;
1133 static void read_index_span( const GLcontext
*ctx
,
1134 GLuint n
, GLint x
, GLint y
, GLuint index
[] )
1136 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1138 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1139 for (i
=0;i
<n
;i
++,ptr1
++) {
1140 index
[i
] = (GLuint
) *ptr1
;
1145 static void read_index_pixels( const GLcontext
*ctx
,
1146 GLuint n
, const GLint x
[], const GLint y
[],
1147 GLuint index
[], const GLubyte mask
[] )
1149 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1153 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1154 index
[i
] = (GLuint
) *ptr1
;
1161 /**********************************************************************/
1162 /***** Optimized line rendering *****/
1163 /**********************************************************************/
1167 * Draw a flat-shaded, RGB line into an osmesa buffer.
1169 static void flat_rgba_line( GLcontext
*ctx
,
1170 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1172 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1173 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1174 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1178 #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
1181 #include "..\linetemp.h"
1183 #include "linetemp.h"
1189 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1191 static void flat_rgba_z_line( GLcontext
*ctx
,
1192 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1194 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1195 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1196 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1203 GLuint *ptr4 = PIXELADDR4(X,Y); \
1209 #include "..\linetemp.h"
1211 #include "linetemp.h"
1217 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1219 static void flat_blend_rgba_line( GLcontext
*ctx
,
1220 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1222 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1223 struct vertex_buffer
*VB
= ctx
->VB
;
1224 GLint rshift
= osmesa
->rshift
;
1225 GLint gshift
= osmesa
->gshift
;
1226 GLint bshift
= osmesa
->bshift
;
1227 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1228 GLint msavalue
= 255 - avalue
;
1229 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1230 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1231 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1236 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1238 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1239 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1240 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1245 #include "..\linetemp.h"
1247 #include "linetemp.h"
1252 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1254 static void flat_blend_rgba_z_line( GLcontext
*ctx
,
1255 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1257 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1258 struct vertex_buffer
*VB
= ctx
->VB
;
1259 GLint rshift
= osmesa
->rshift
;
1260 GLint gshift
= osmesa
->gshift
;
1261 GLint bshift
= osmesa
->bshift
;
1262 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1263 GLint msavalue
= 256 - avalue
;
1264 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1265 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1266 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1273 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1275 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1276 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1277 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1283 #include "..\linetemp.h"
1285 #include "linetemp.h"
1290 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1292 static void flat_blend_rgba_z_line_write( GLcontext
*ctx
,
1293 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1295 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1296 struct vertex_buffer
*VB
= ctx
->VB
;
1297 GLint rshift
= osmesa
->rshift
;
1298 GLint gshift
= osmesa
->gshift
;
1299 GLint bshift
= osmesa
->bshift
;
1300 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1301 GLint msavalue
= 256 - avalue
;
1302 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1303 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1304 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1311 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1313 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1314 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1315 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1322 #include "..\linetemp.h"
1324 #include "linetemp.h"
1330 * Analyze context state to see if we can provide a fast line drawing
1331 * function, like those in lines.c. Otherwise, return NULL.
1333 static line_func
choose_line_function( GLcontext
*ctx
)
1335 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1337 if (ctx
->Line
.SmoothFlag
) return NULL
;
1338 if (ctx
->Texture
.Enabled
) return NULL
;
1339 if (ctx
->Light
.ShadeModel
!=GL_FLAT
) return NULL
;
1341 if (ctx
->Line
.Width
==1.0F
1342 && ctx
->Line
.StippleFlag
==GL_FALSE
) {
1344 if (ctx
->RasterMask
==DEPTH_BIT
1345 && ctx
->Depth
.Func
==GL_LESS
1346 && ctx
->Depth
.Mask
==GL_TRUE
) {
1347 switch(osmesa
->format
) {
1351 return flat_rgba_z_line
;
1357 if (ctx
->RasterMask
==0) {
1358 switch(osmesa
->format
) {
1362 return flat_rgba_line
;
1368 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1369 && ctx
->Depth
.Func
==GL_LESS
1370 && ctx
->Depth
.Mask
==GL_TRUE
1371 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1372 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1373 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1374 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1375 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1376 switch(osmesa
->format
) {
1380 return flat_blend_rgba_z_line_write
;
1386 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1387 && ctx
->Depth
.Func
==GL_LESS
1388 && ctx
->Depth
.Mask
==GL_FALSE
1389 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1390 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1391 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1392 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1393 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1394 switch(osmesa
->format
) {
1398 return flat_blend_rgba_z_line
;
1404 if (ctx
->RasterMask
==BLEND_BIT
1405 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1406 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1407 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1408 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1409 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1410 switch(osmesa
->format
) {
1414 return flat_blend_rgba_line
;
1425 /**********************************************************************/
1426 /***** Optimized triangle rendering *****/
1427 /**********************************************************************/
1431 * Smooth-shaded, z-less triangle, RGBA color.
1433 static void smooth_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1434 GLuint v2
, GLuint pv
)
1436 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1437 GLint rshift
= osmesa
->rshift
;
1438 GLint gshift
= osmesa
->gshift
;
1439 GLint bshift
= osmesa
->bshift
;
1440 GLint ashift
= osmesa
->ashift
;
1443 #define INTERP_RGB 1
1444 #define INTERP_ALPHA 1
1445 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1447 GLint i, len = RIGHT-LEFT; \
1448 GLuint *img = PIXELADDR4(LEFT,Y); \
1449 for (i=0;i<len;i++,img++) { \
1450 GLdepth z = FixedToDepth(ffz); \
1451 if (z < zRow[i]) { \
1452 *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg), \
1453 FixedToInt(ffb), FixedToInt(ffa) ); \
1456 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1461 #include "..\tritemp.h"
1463 #include "tritemp.h"
1471 * Flat-shaded, z-less triangle, RGBA color.
1473 static void flat_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1474 GLuint v2
, GLuint pv
)
1476 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1478 #define SETUP_CODE \
1479 GLubyte r = VB->ColorPtr->data[pv][0]; \
1480 GLubyte g = VB->ColorPtr->data[pv][1]; \
1481 GLubyte b = VB->ColorPtr->data[pv][2]; \
1482 GLubyte a = VB->ColorPtr->data[pv][3]; \
1483 GLuint pixel = PACK_RGBA(r,g,b,a);
1485 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1487 GLint i, len = RIGHT-LEFT; \
1488 GLuint *img = PIXELADDR4(LEFT,Y); \
1489 for (i=0;i<len;i++,img++) { \
1490 GLdepth z = FixedToDepth(ffz); \
1491 if (z < zRow[i]) { \
1499 #include "..\tritemp.h"
1501 #include "tritemp.h"
1508 * Return pointer to an accelerated triangle function if possible.
1510 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
1512 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1514 if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) return NULL
;
1516 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
1517 if (ctx
->Polygon
.StippleFlag
) return NULL
;
1518 if (ctx
->Texture
.Enabled
) return NULL
;
1520 if (ctx
->RasterMask
==DEPTH_BIT
1521 && ctx
->Depth
.Func
==GL_LESS
1522 && ctx
->Depth
.Mask
==GL_TRUE
1523 && osmesa
->format
!=OSMESA_COLOR_INDEX
) {
1524 if (ctx
->Light
.ShadeModel
==GL_SMOOTH
) {
1525 return smooth_rgba_z_triangle
;
1528 return flat_rgba_z_triangle
;
1536 static const GLubyte
*get_string( GLcontext
*ctx
, GLenum name
)
1541 return (const GLubyte
*) "Mesa OffScreen";
1548 static void osmesa_update_state( GLcontext
*ctx
)
1550 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1552 ctx
->Driver
.GetString
= get_string
;
1553 ctx
->Driver
.UpdateState
= osmesa_update_state
;
1555 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1556 ctx
->Driver
.SetReadBuffer
= set_read_buffer
;
1557 ctx
->Driver
.Color
= set_color
;
1558 ctx
->Driver
.Index
= set_index
;
1559 ctx
->Driver
.ClearIndex
= clear_index
;
1560 ctx
->Driver
.ClearColor
= clear_color
;
1561 ctx
->Driver
.Clear
= clear
;
1563 ctx
->Driver
.GetBufferSize
= buffer_size
;
1565 ctx
->Driver
.PointsFunc
= NULL
;
1566 ctx
->Driver
.LineFunc
= choose_line_function( ctx
);
1567 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1570 /* RGB(A) span/pixel functions */
1571 if ((osmesa
->format
==OSMESA_RGB
) || (osmesa
->format
==OSMESA_BGR
)) {
1572 /* 3 bytes / pixel in frame buffer */
1573 ctx
->Driver
.WriteRGBASpan
= write_rgba_span3
;
1574 ctx
->Driver
.WriteRGBSpan
= write_rgb_span3
;
1575 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels3
;
1576 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span3
;
1577 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels3
;
1578 ctx
->Driver
.ReadRGBASpan
= read_rgba_span3
;
1579 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels3
;
1582 /* 4 bytes / pixel in frame buffer */
1583 if (osmesa
->format
==OSMESA_RGBA
1584 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1585 ctx
->Driver
.WriteRGBASpan
= write_rgba_span_rgba
;
1587 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1588 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1589 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1590 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span
;
1591 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels
;
1592 if (osmesa
->format
==OSMESA_RGBA
1593 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1594 ctx
->Driver
.ReadRGBASpan
= read_rgba_span_rgba
;
1596 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1597 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1600 /* CI span/pixel functions */
1601 ctx
->Driver
.WriteCI32Span
= write_index32_span
;
1602 ctx
->Driver
.WriteCI8Span
= write_index8_span
;
1603 ctx
->Driver
.WriteMonoCISpan
= write_monoindex_span
;
1604 ctx
->Driver
.WriteCI32Pixels
= write_index_pixels
;
1605 ctx
->Driver
.WriteMonoCIPixels
= write_monoindex_pixels
;
1606 ctx
->Driver
.ReadCI32Span
= read_index_span
;
1607 ctx
->Driver
.ReadCI32Pixels
= read_index_pixels
;