1 /* $Id: osmesa.c,v 1.2 1999/10/13 18:43:46 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 */
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 if (!osmesa
->gl_buffer
) {
240 gl_destroy_visual( osmesa
->gl_visual
);
241 gl_destroy_context( osmesa
->gl_ctx
);
245 osmesa
->format
= format
;
246 osmesa
->buffer
= NULL
;
250 osmesa
->clearpixel
= 0;
251 osmesa
->userRowLength
= 0;
252 osmesa
->rowlength
= 0;
253 osmesa
->yup
= GL_TRUE
;
254 osmesa
->rshift
= rshift
;
255 osmesa
->gshift
= gshift
;
256 osmesa
->bshift
= bshift
;
257 osmesa
->ashift
= ashift
;
268 * Destroy an Off-Screen Mesa rendering context.
270 * Input: ctx - the context to destroy
272 void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext ctx
)
275 gl_destroy_visual( ctx
->gl_visual
);
276 gl_destroy_framebuffer( ctx
->gl_buffer
);
277 gl_destroy_context( ctx
->gl_ctx
);
285 * Recompute the values of the context's rowaddr array.
287 static void compute_row_addresses( OSMesaContext ctx
)
292 /* Y=0 is bottom line of window */
293 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
295 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
296 for (i
=0;i
<MAX_HEIGHT
;i
++) {
297 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
301 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
302 /* 3-byte RGB mode */
303 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
304 for (i
=0;i
<MAX_HEIGHT
;i
++) {
305 ctx
->rowaddr
[i
] = origin
+ (i
* (ctx
->rowlength
*3));
308 /* 4-byte RGBA mode */
309 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
310 for (i
=0;i
<MAX_HEIGHT
;i
++) {
311 ctx
->rowaddr
[i
] = origin
+ i
* ctx
->rowlength
;
317 /* Y=0 is top line of window */
318 if (ctx
->format
==OSMESA_COLOR_INDEX
) {
320 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
321 for (i
=0;i
<MAX_HEIGHT
;i
++) {
322 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
326 if ((ctx
->format
==OSMESA_RGB
) || (ctx
->format
==OSMESA_BGR
)) {
327 /* 3-byte RGB mode */
328 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
329 for (i
=0;i
<MAX_HEIGHT
;i
++) {
330 ctx
->rowaddr
[i
] = origin
+ ((ctx
->height
-i
-1) * (ctx
->rowlength
*3));
333 /* 4-byte RGBA mode */
334 GLuint
*origin
= (GLuint
*) ctx
->buffer
;
335 for (i
=0;i
<MAX_HEIGHT
;i
++) {
336 ctx
->rowaddr
[i
] = origin
+ (ctx
->height
-i
-1) * ctx
->rowlength
;
345 * Bind an OSMesaContext to an image buffer. The image buffer is just a
346 * block of memory which the client provides. Its size must be at least
347 * as large as width*height*sizeof(type). Its address should be a multiple
348 * of 4 if using RGBA mode.
350 * Image data is stored in the order of glDrawPixels: row-major order
351 * with the lower-left image pixel stored in the first array position
352 * (ie. bottom-to-top).
354 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
355 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
356 * value. If the context is in color indexed mode, each pixel will be
357 * stored as a 1-byte value.
359 * If the context's viewport hasn't been initialized yet, it will now be
360 * initialized to (0,0,width,height).
362 * Input: ctx - the rendering context
363 * buffer - the image buffer memory
364 * type - data type for pixel components, only GL_UNSIGNED_BYTE
366 * width, height - size of image buffer in pixels, at least 1
367 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
368 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
369 * width>internal limit or height>internal limit.
371 GLboolean GLAPIENTRY
OSMesaMakeCurrent( OSMesaContext ctx
, void *buffer
, GLenum type
,
372 GLsizei width
, GLsizei height
)
374 if (!ctx
|| !buffer
|| type
!=GL_UNSIGNED_BYTE
375 || width
<1 || height
<1 || width
>MAX_WIDTH
|| height
>MAX_HEIGHT
) {
379 osmesa_update_state( ctx
->gl_ctx
);
380 gl_make_current( ctx
->gl_ctx
, ctx
->gl_buffer
);
382 ctx
->buffer
= buffer
;
384 ctx
->height
= height
;
385 if (ctx
->userRowLength
)
386 ctx
->rowlength
= ctx
->userRowLength
;
388 ctx
->rowlength
= width
;
391 /* Set current context for the calling thread */
392 osmesa_set_thread_context(ctx
);
394 /* Set current context for the address space, all threads */
398 compute_row_addresses( ctx
);
401 if (ctx
->gl_ctx
->Viewport
.Width
==0) {
402 /* initialize viewport and scissor box to buffer size */
403 gl_Viewport( ctx
->gl_ctx
, 0, 0, width
, height
);
404 ctx
->gl_ctx
->Scissor
.Width
= width
;
405 ctx
->gl_ctx
->Scissor
.Height
= height
;
414 OSMesaContext GLAPIENTRY
OSMesaGetCurrentContext( void )
417 /* Return current handle for the calling thread */
418 return osmesa_get_thread_context();
420 /* Return current handle for the address space, all threads */
427 void GLAPIENTRY
OSMesaPixelStore( GLint pname
, GLint value
)
429 OSMesaContext ctx
= OSMesaGetCurrentContext();
432 case OSMESA_ROW_LENGTH
:
434 gl_error( ctx
->gl_ctx
, GL_INVALID_VALUE
,
435 "OSMesaPixelStore(value)" );
438 ctx
->userRowLength
= value
;
439 ctx
->rowlength
= value
;
442 ctx
->yup
= value
? GL_TRUE
: GL_FALSE
;
445 gl_error( ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaPixelStore(pname)" );
449 compute_row_addresses( ctx
);
453 void GLAPIENTRY
OSMesaGetIntegerv( GLint pname
, GLint
*value
)
455 OSMesaContext ctx
= OSMesaGetCurrentContext();
462 *value
= ctx
->height
;
465 *value
= ctx
->format
;
468 *value
= GL_UNSIGNED_BYTE
;
470 case OSMESA_ROW_LENGTH
:
471 *value
= ctx
->rowlength
;
477 gl_error( ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaGetIntergerv(pname)" );
485 * Return the depth buffer associated with an OSMesa context.
486 * Input: c - the OSMesa context
487 * Output: width, height - size of buffer in pixels
488 * bytesPerValue - bytes per depth value (2 or 4)
489 * buffer - pointer to depth buffer values
490 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
492 GLboolean GLAPIENTRY
OSMesaGetDepthBuffer( OSMesaContext c
, GLint
*width
, GLint
*height
,
493 GLint
*bytesPerValue
, void **buffer
)
495 if ((!c
->gl_buffer
) || (!c
->gl_buffer
->Depth
)) {
503 *width
= c
->gl_buffer
->Width
;
504 *height
= c
->gl_buffer
->Height
;
505 *bytesPerValue
= sizeof(GLdepth
);
506 *buffer
= c
->gl_buffer
->Depth
;
514 /**********************************************************************/
515 /*** Device Driver Functions ***/
516 /**********************************************************************/
522 #define PACK_RGBA(R,G,B,A) ( ((R) << osmesa->rshift) \
523 | ((G) << osmesa->gshift) \
524 | ((B) << osmesa->bshift) \
525 | ((A) << osmesa->ashift) )
527 #define PACK_RGBA2(R,G,B,A) ( ((R) << rshift) \
532 #define UNPACK_RED(P) (((P) >> osmesa->rshift) & 0xff)
533 #define UNPACK_GREEN(P) (((P) >> osmesa->gshift) & 0xff)
534 #define UNPACK_BLUE(P) (((P) >> osmesa->bshift) & 0xff)
535 #define UNPACK_ALPHA(P) (((P) >> osmesa->ashift) & 0xff)
537 #define PIXELADDR1(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + (X))
538 #define PIXELADDR3(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
539 #define PIXELADDR4(X,Y) ((GLuint *) osmesa->rowaddr[Y] + (X))
544 static GLboolean
set_buffer( GLcontext
*ctx
, GLenum mode
)
547 if (mode
==GL_FRONT_LEFT
) {
556 static void clear_index( GLcontext
*ctx
, GLuint index
)
558 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
559 osmesa
->clearpixel
= index
;
564 static void clear_color( GLcontext
*ctx
,
565 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
567 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
568 osmesa
->clearpixel
= PACK_RGBA( r
, g
, b
, a
);
573 static GLbitfield
clear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
574 GLint x
, GLint y
, GLint width
, GLint height
)
576 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
577 if (mask
& GL_COLOR_BUFFER_BIT
) {
578 if (osmesa
->format
==OSMESA_COLOR_INDEX
) {
580 /* Clear whole CI buffer */
581 MEMSET(osmesa
->buffer
, osmesa
->clearpixel
,
582 osmesa
->rowlength
* osmesa
->height
);
585 /* Clear part of CI buffer */
587 for (i
=0;i
<height
;i
++) {
588 GLubyte
*ptr1
= PIXELADDR1( x
, (y
+i
) );
589 for (j
=0;j
<width
;j
++) {
590 *ptr1
++ = osmesa
->clearpixel
;
595 else if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) {
596 GLubyte rval
= UNPACK_RED(osmesa
->clearpixel
);
597 GLubyte gval
= UNPACK_GREEN(osmesa
->clearpixel
);
598 GLubyte bval
= UNPACK_BLUE(osmesa
->clearpixel
);
599 GLint rind
= osmesa
->rind
;
600 GLint gind
= osmesa
->gind
;
601 GLint bind
= osmesa
->bind
;
604 GLubyte
*ptr3
= (GLubyte
*) osmesa
->buffer
;
605 /* Clear whole RGB buffer */
606 n
= osmesa
->rowlength
* osmesa
->height
;
615 /* Clear part of RGB buffer */
617 for (i
=0;i
<height
;i
++) {
618 GLubyte
*ptr3
= PIXELADDR3( x
, (y
+i
) );
619 for (j
=0;j
<width
;j
++) {
630 /* Clear whole RGBA buffer */
632 n
= osmesa
->rowlength
* osmesa
->height
;
633 ptr4
= (GLuint
*) osmesa
->buffer
;
635 *ptr4
++ = osmesa
->clearpixel
;
639 /* Clear part of RGBA buffer */
641 for (i
=0;i
<height
;i
++) {
642 GLuint
*ptr4
= PIXELADDR4( x
, (y
+i
) );
643 for (j
=0;j
<width
;j
++) {
644 *ptr4
++ = osmesa
->clearpixel
;
650 return mask
& (~GL_COLOR_BUFFER_BIT
);
655 static void set_index( GLcontext
*ctx
, GLuint index
)
657 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
658 osmesa
->pixel
= index
;
663 static void set_color( GLcontext
*ctx
,
664 GLubyte r
, GLubyte g
, GLubyte b
, GLubyte a
)
666 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
667 osmesa
->pixel
= PACK_RGBA( r
, g
, b
, a
);
672 static void buffer_size( GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
674 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
675 *width
= osmesa
->width
;
676 *height
= osmesa
->height
;
680 /**********************************************************************/
681 /***** Read/write spans/arrays of RGBA pixels *****/
682 /**********************************************************************/
684 /* Write RGBA pixels to an RGBA (or permuted) buffer. */
685 static void write_rgba_span( const GLcontext
*ctx
,
686 GLuint n
, GLint x
, GLint y
,
687 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
689 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
690 GLuint
*ptr4
= PIXELADDR4( x
, y
);
692 GLint rshift
= osmesa
->rshift
;
693 GLint gshift
= osmesa
->gshift
;
694 GLint bshift
= osmesa
->bshift
;
695 GLint ashift
= osmesa
->ashift
;
697 for (i
=0;i
<n
;i
++,ptr4
++) {
699 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
704 for (i
=0;i
<n
;i
++,ptr4
++) {
705 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
711 /* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
712 static void write_rgba_span_rgba( const GLcontext
*ctx
,
713 GLuint n
, GLint x
, GLint y
,
714 CONST GLubyte rgba
[][4],
715 const GLubyte mask
[] )
717 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
718 GLuint
*ptr4
= PIXELADDR4( x
, y
);
719 const GLuint
*rgba4
= (const GLuint
*) rgba
;
729 MEMCPY( ptr4
, rgba4
, n
* 4 );
734 /* Write RGB pixels to an RGBA (or permuted) buffer. */
735 static void write_rgb_span( const GLcontext
*ctx
,
736 GLuint n
, GLint x
, GLint y
,
737 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
739 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
740 GLuint
*ptr4
= PIXELADDR4( x
, y
);
742 GLint rshift
= osmesa
->rshift
;
743 GLint gshift
= osmesa
->gshift
;
744 GLint bshift
= osmesa
->bshift
;
745 GLint ashift
= osmesa
->ashift
;
747 for (i
=0;i
<n
;i
++,ptr4
++) {
749 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255 );
754 for (i
=0;i
<n
;i
++,ptr4
++) {
755 *ptr4
= PACK_RGBA2( rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255);
762 static void write_monocolor_span( const GLcontext
*ctx
,
763 GLuint n
, GLint x
, GLint y
,
764 const GLubyte mask
[] )
766 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
767 GLuint
*ptr4
= PIXELADDR4(x
,y
);
769 for (i
=0;i
<n
;i
++,ptr4
++) {
771 *ptr4
= osmesa
->pixel
;
778 static void write_rgba_pixels( const GLcontext
*ctx
,
779 GLuint n
, const GLint x
[], const GLint y
[],
780 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
782 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
784 GLint rshift
= osmesa
->rshift
;
785 GLint gshift
= osmesa
->gshift
;
786 GLint bshift
= osmesa
->bshift
;
787 GLint ashift
= osmesa
->ashift
;
790 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
791 *ptr4
= PACK_RGBA2( rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
], rgba
[i
][ACOMP
] );
798 static void write_monocolor_pixels( const GLcontext
*ctx
,
799 GLuint n
, const GLint x
[], const GLint y
[],
800 const GLubyte mask
[] )
802 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
806 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
807 *ptr4
= osmesa
->pixel
;
813 static void read_rgba_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
816 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
818 GLuint
*ptr4
= PIXELADDR4(x
,y
);
820 GLuint pixel
= *ptr4
++;
821 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
822 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
823 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
824 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
829 /* Read RGBA pixels from an RGBA buffer */
830 static void read_rgba_span_rgba( const GLcontext
*ctx
,
831 GLuint n
, GLint x
, GLint y
,
834 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
835 GLuint
*ptr4
= PIXELADDR4(x
,y
);
836 MEMCPY( rgba
, ptr4
, n
* 4 * sizeof(GLubyte
) );
840 static void read_rgba_pixels( const GLcontext
*ctx
,
841 GLuint n
, const GLint x
[], const GLint y
[],
842 GLubyte rgba
[][4], const GLubyte mask
[] )
844 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
848 GLuint
*ptr4
= PIXELADDR4(x
[i
],y
[i
]);
849 GLuint pixel
= *ptr4
;
850 rgba
[i
][RCOMP
] = UNPACK_RED(pixel
);
851 rgba
[i
][GCOMP
] = UNPACK_GREEN(pixel
);
852 rgba
[i
][BCOMP
] = UNPACK_BLUE(pixel
);
853 rgba
[i
][ACOMP
] = UNPACK_ALPHA(pixel
);
858 /**********************************************************************/
859 /***** 3 byte RGB pixel support funcs *****/
860 /**********************************************************************/
862 /* Write RGBA pixels to an RGB or BGR buffer. */
863 static void write_rgba_span3( const GLcontext
*ctx
,
864 GLuint n
, GLint x
, GLint y
,
865 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
867 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
868 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
870 GLint rind
= osmesa
->rind
;
871 GLint gind
= osmesa
->gind
;
872 GLint bind
= osmesa
->bind
;
874 for (i
=0;i
<n
;i
++,ptr3
+=3) {
876 ptr3
[rind
] = rgba
[i
][RCOMP
];
877 ptr3
[gind
] = rgba
[i
][GCOMP
];
878 ptr3
[bind
] = rgba
[i
][BCOMP
];
883 for (i
=0;i
<n
;i
++,ptr3
+=3) {
884 ptr3
[rind
] = rgba
[i
][RCOMP
];
885 ptr3
[gind
] = rgba
[i
][GCOMP
];
886 ptr3
[bind
] = rgba
[i
][BCOMP
];
891 /* Write RGB pixels to an RGB or BGR buffer. */
892 static void write_rgb_span3( const GLcontext
*ctx
,
893 GLuint n
, GLint x
, GLint y
,
894 CONST GLubyte rgb
[][3], const GLubyte mask
[] )
896 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
897 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
899 GLint rind
= osmesa
->rind
;
900 GLint gind
= osmesa
->gind
;
901 GLint bind
= osmesa
->bind
;
903 for (i
=0;i
<n
;i
++,ptr3
+=3) {
905 ptr3
[rind
] = rgb
[i
][RCOMP
];
906 ptr3
[gind
] = rgb
[i
][GCOMP
];
907 ptr3
[bind
] = rgb
[i
][BCOMP
];
912 for (i
=0;i
<n
;i
++,ptr3
+=3) {
913 ptr3
[rind
] = rgb
[i
][RCOMP
];
914 ptr3
[gind
] = rgb
[i
][GCOMP
];
915 ptr3
[bind
] = rgb
[i
][BCOMP
];
921 static void write_monocolor_span3( const GLcontext
*ctx
,
922 GLuint n
, GLint x
, GLint y
,
923 const GLubyte mask
[] )
925 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
927 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
928 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
929 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
930 GLint rind
= osmesa
->rind
;
931 GLint gind
= osmesa
->gind
;
932 GLint bind
= osmesa
->bind
;
935 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
937 for (i
=0;i
<n
;i
++,ptr3
+=3) {
946 static void write_rgba_pixels3( const GLcontext
*ctx
,
947 GLuint n
, const GLint x
[], const GLint y
[],
948 CONST GLubyte rgba
[][4], const GLubyte mask
[] )
950 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
952 GLint rind
= osmesa
->rind
;
953 GLint gind
= osmesa
->gind
;
954 GLint bind
= osmesa
->bind
;
958 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
959 ptr3
[rind
] = rgba
[i
][RCOMP
];
960 ptr3
[gind
] = rgba
[i
][GCOMP
];
961 ptr3
[bind
] = rgba
[i
][BCOMP
];
966 static void write_monocolor_pixels3( const GLcontext
*ctx
,
967 GLuint n
, const GLint x
[], const GLint y
[],
968 const GLubyte mask
[] )
970 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
972 GLint rind
= osmesa
->rind
;
973 GLint gind
= osmesa
->gind
;
974 GLint bind
= osmesa
->bind
;
975 GLubyte rval
= UNPACK_RED(osmesa
->pixel
);
976 GLubyte gval
= UNPACK_GREEN(osmesa
->pixel
);
977 GLubyte bval
= UNPACK_BLUE(osmesa
->pixel
);
980 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
988 static void read_rgba_span3( const GLcontext
*ctx
,
989 GLuint n
, GLint x
, GLint y
,
992 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
994 GLint rind
= osmesa
->rind
;
995 GLint gind
= osmesa
->gind
;
996 GLint bind
= osmesa
->bind
;
997 GLubyte
*ptr3
= PIXELADDR3( x
, y
);
998 for (i
=0;i
<n
;i
++,ptr3
+=3) {
999 rgba
[i
][RCOMP
] = ptr3
[rind
];
1000 rgba
[i
][GCOMP
] = ptr3
[gind
];
1001 rgba
[i
][BCOMP
] = ptr3
[bind
];
1006 static void read_rgba_pixels3( const GLcontext
*ctx
,
1007 GLuint n
, const GLint x
[], const GLint y
[],
1008 GLubyte rgba
[][4], const GLubyte mask
[] )
1010 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1012 GLint rind
= osmesa
->rind
;
1013 GLint gind
= osmesa
->gind
;
1014 GLint bind
= osmesa
->bind
;
1017 GLubyte
*ptr3
= PIXELADDR3(x
[i
],y
[i
]);
1018 rgba
[i
][RCOMP
] = ptr3
[rind
];
1019 rgba
[i
][GCOMP
] = ptr3
[gind
];
1020 rgba
[i
][BCOMP
] = ptr3
[bind
];
1027 /**********************************************************************/
1028 /***** Read/write spans/arrays of CI pixels *****/
1029 /**********************************************************************/
1031 /* Write 32-bit color index to buffer */
1032 static void write_index32_span( const GLcontext
*ctx
,
1033 GLuint n
, GLint x
, GLint y
,
1034 const GLuint index
[], const GLubyte mask
[] )
1036 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1037 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1040 for (i
=0;i
<n
;i
++,ptr1
++) {
1042 *ptr1
= (GLubyte
) index
[i
];
1047 for (i
=0;i
<n
;i
++,ptr1
++) {
1048 *ptr1
= (GLubyte
) index
[i
];
1054 /* Write 8-bit color index to buffer */
1055 static void write_index8_span( const GLcontext
*ctx
,
1056 GLuint n
, GLint x
, GLint y
,
1057 const GLubyte index
[], const GLubyte mask
[] )
1059 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1060 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1063 for (i
=0;i
<n
;i
++,ptr1
++) {
1065 *ptr1
= (GLubyte
) index
[i
];
1070 MEMCPY( ptr1
, index
, n
);
1075 static void write_monoindex_span( const GLcontext
*ctx
,
1076 GLuint n
, GLint x
, GLint y
,
1077 const GLubyte mask
[] )
1079 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1080 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1082 for (i
=0;i
<n
;i
++,ptr1
++) {
1084 *ptr1
= (GLubyte
) osmesa
->pixel
;
1090 static void write_index_pixels( const GLcontext
*ctx
,
1091 GLuint n
, const GLint x
[], const GLint y
[],
1092 const GLuint index
[], const GLubyte mask
[] )
1094 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1098 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1099 *ptr1
= (GLubyte
) index
[i
];
1105 static void write_monoindex_pixels( const GLcontext
*ctx
,
1106 GLuint n
, const GLint x
[], const GLint y
[],
1107 const GLubyte mask
[] )
1109 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1113 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1114 *ptr1
= (GLubyte
) osmesa
->pixel
;
1120 static void read_index_span( const GLcontext
*ctx
,
1121 GLuint n
, GLint x
, GLint y
, GLuint index
[] )
1123 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1125 GLubyte
*ptr1
= PIXELADDR1(x
,y
);
1126 for (i
=0;i
<n
;i
++,ptr1
++) {
1127 index
[i
] = (GLuint
) *ptr1
;
1132 static void read_index_pixels( const GLcontext
*ctx
,
1133 GLuint n
, const GLint x
[], const GLint y
[],
1134 GLuint index
[], const GLubyte mask
[] )
1136 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1140 GLubyte
*ptr1
= PIXELADDR1(x
[i
],y
[i
]);
1141 index
[i
] = (GLuint
) *ptr1
;
1148 /**********************************************************************/
1149 /***** Optimized line rendering *****/
1150 /**********************************************************************/
1154 * Draw a flat-shaded, RGB line into an osmesa buffer.
1156 static void flat_rgba_line( GLcontext
*ctx
,
1157 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1159 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1160 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1161 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1165 #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
1168 #include "..\linetemp.h"
1170 #include "linetemp.h"
1176 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1178 static void flat_rgba_z_line( GLcontext
*ctx
,
1179 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1181 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1182 GLubyte
*color
= ctx
->VB
->ColorPtr
->data
[pvert
];
1183 unsigned long pixel
= PACK_RGBA( color
[0], color
[1], color
[2], color
[3] );
1190 GLuint *ptr4 = PIXELADDR4(X,Y); \
1196 #include "..\linetemp.h"
1198 #include "linetemp.h"
1204 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1206 static void flat_blend_rgba_line( GLcontext
*ctx
,
1207 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1209 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1210 struct vertex_buffer
*VB
= ctx
->VB
;
1211 GLint rshift
= osmesa
->rshift
;
1212 GLint gshift
= osmesa
->gshift
;
1213 GLint bshift
= osmesa
->bshift
;
1214 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1215 GLint msavalue
= 255 - avalue
;
1216 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1217 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1218 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1223 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1225 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1226 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1227 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1232 #include "..\linetemp.h"
1234 #include "linetemp.h"
1239 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1241 static void flat_blend_rgba_z_line( GLcontext
*ctx
,
1242 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1244 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1245 struct vertex_buffer
*VB
= ctx
->VB
;
1246 GLint rshift
= osmesa
->rshift
;
1247 GLint gshift
= osmesa
->gshift
;
1248 GLint bshift
= osmesa
->bshift
;
1249 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1250 GLint msavalue
= 256 - avalue
;
1251 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1252 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1253 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1260 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1262 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1263 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1264 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1270 #include "..\linetemp.h"
1272 #include "linetemp.h"
1277 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1279 static void flat_blend_rgba_z_line_write( GLcontext
*ctx
,
1280 GLuint vert0
, GLuint vert1
, GLuint pvert
)
1282 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1283 struct vertex_buffer
*VB
= ctx
->VB
;
1284 GLint rshift
= osmesa
->rshift
;
1285 GLint gshift
= osmesa
->gshift
;
1286 GLint bshift
= osmesa
->bshift
;
1287 GLint avalue
= VB
->ColorPtr
->data
[pvert
][3];
1288 GLint msavalue
= 256 - avalue
;
1289 GLint rvalue
= VB
->ColorPtr
->data
[pvert
][0]*avalue
;
1290 GLint gvalue
= VB
->ColorPtr
->data
[pvert
][1]*avalue
;
1291 GLint bvalue
= VB
->ColorPtr
->data
[pvert
][2]*avalue
;
1298 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1300 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1301 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1302 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1309 #include "..\linetemp.h"
1311 #include "linetemp.h"
1317 * Analyze context state to see if we can provide a fast line drawing
1318 * function, like those in lines.c. Otherwise, return NULL.
1320 static line_func
choose_line_function( GLcontext
*ctx
)
1322 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1324 if (ctx
->Line
.SmoothFlag
) return NULL
;
1325 if (ctx
->Texture
.Enabled
) return NULL
;
1326 if (ctx
->Light
.ShadeModel
!=GL_FLAT
) return NULL
;
1328 if (ctx
->Line
.Width
==1.0F
1329 && ctx
->Line
.StippleFlag
==GL_FALSE
) {
1331 if (ctx
->RasterMask
==DEPTH_BIT
1332 && ctx
->Depth
.Func
==GL_LESS
1333 && ctx
->Depth
.Mask
==GL_TRUE
) {
1334 switch(osmesa
->format
) {
1338 return flat_rgba_z_line
;
1344 if (ctx
->RasterMask
==0) {
1345 switch(osmesa
->format
) {
1349 return flat_rgba_line
;
1355 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1356 && ctx
->Depth
.Func
==GL_LESS
1357 && ctx
->Depth
.Mask
==GL_TRUE
1358 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1359 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1360 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1361 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1362 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1363 switch(osmesa
->format
) {
1367 return flat_blend_rgba_z_line_write
;
1373 if (ctx
->RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1374 && ctx
->Depth
.Func
==GL_LESS
1375 && ctx
->Depth
.Mask
==GL_FALSE
1376 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1377 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1378 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1379 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1380 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1381 switch(osmesa
->format
) {
1385 return flat_blend_rgba_z_line
;
1391 if (ctx
->RasterMask
==BLEND_BIT
1392 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1393 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1394 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1395 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1396 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1397 switch(osmesa
->format
) {
1401 return flat_blend_rgba_line
;
1412 /**********************************************************************/
1413 /***** Optimized triangle rendering *****/
1414 /**********************************************************************/
1418 * Smooth-shaded, z-less triangle, RGBA color.
1420 static void smooth_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1421 GLuint v2
, GLuint pv
)
1423 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1424 GLint rshift
= osmesa
->rshift
;
1425 GLint gshift
= osmesa
->gshift
;
1426 GLint bshift
= osmesa
->bshift
;
1427 GLint ashift
= osmesa
->ashift
;
1430 #define INTERP_RGB 1
1431 #define INTERP_ALPHA 1
1432 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1434 GLint i, len = RIGHT-LEFT; \
1435 GLuint *img = PIXELADDR4(LEFT,Y); \
1436 for (i=0;i<len;i++,img++) { \
1437 GLdepth z = FixedToDepth(ffz); \
1438 if (z < zRow[i]) { \
1439 *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg), \
1440 FixedToInt(ffb), FixedToInt(ffa) ); \
1443 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1448 #include "..\tritemp.h"
1450 #include "tritemp.h"
1458 * Flat-shaded, z-less triangle, RGBA color.
1460 static void flat_rgba_z_triangle( GLcontext
*ctx
, GLuint v0
, GLuint v1
,
1461 GLuint v2
, GLuint pv
)
1463 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1465 #define SETUP_CODE \
1466 GLubyte r = VB->ColorPtr->data[pv][0]; \
1467 GLubyte g = VB->ColorPtr->data[pv][1]; \
1468 GLubyte b = VB->ColorPtr->data[pv][2]; \
1469 GLubyte a = VB->ColorPtr->data[pv][3]; \
1470 GLuint pixel = PACK_RGBA(r,g,b,a);
1472 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1474 GLint i, len = RIGHT-LEFT; \
1475 GLuint *img = PIXELADDR4(LEFT,Y); \
1476 for (i=0;i<len;i++,img++) { \
1477 GLdepth z = FixedToDepth(ffz); \
1478 if (z < zRow[i]) { \
1486 #include "..\tritemp.h"
1488 #include "tritemp.h"
1495 * Return pointer to an accelerated triangle function if possible.
1497 static triangle_func
choose_triangle_function( GLcontext
*ctx
)
1499 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1501 if ((osmesa
->format
==OSMESA_RGB
)||(osmesa
->format
==OSMESA_BGR
)) return NULL
;
1503 if (ctx
->Polygon
.SmoothFlag
) return NULL
;
1504 if (ctx
->Polygon
.StippleFlag
) return NULL
;
1505 if (ctx
->Texture
.Enabled
) return NULL
;
1507 if (ctx
->RasterMask
==DEPTH_BIT
1508 && ctx
->Depth
.Func
==GL_LESS
1509 && ctx
->Depth
.Mask
==GL_TRUE
1510 && osmesa
->format
!=OSMESA_COLOR_INDEX
) {
1511 if (ctx
->Light
.ShadeModel
==GL_SMOOTH
) {
1512 return smooth_rgba_z_triangle
;
1515 return flat_rgba_z_triangle
;
1523 static const GLubyte
*get_string( GLcontext
*ctx
, GLenum name
)
1528 return (const GLubyte
*) "Mesa OffScreen";
1535 static void osmesa_update_state( GLcontext
*ctx
)
1537 OSMesaContext osmesa
= (OSMesaContext
) ctx
->DriverCtx
;
1539 ctx
->Driver
.GetString
= get_string
;
1540 ctx
->Driver
.UpdateState
= osmesa_update_state
;
1542 ctx
->Driver
.SetBuffer
= set_buffer
;
1543 ctx
->Driver
.Color
= set_color
;
1544 ctx
->Driver
.Index
= set_index
;
1545 ctx
->Driver
.ClearIndex
= clear_index
;
1546 ctx
->Driver
.ClearColor
= clear_color
;
1547 ctx
->Driver
.Clear
= clear
;
1549 ctx
->Driver
.GetBufferSize
= buffer_size
;
1551 ctx
->Driver
.PointsFunc
= NULL
;
1552 ctx
->Driver
.LineFunc
= choose_line_function( ctx
);
1553 ctx
->Driver
.TriangleFunc
= choose_triangle_function( ctx
);
1556 /* RGB(A) span/pixel functions */
1557 if ((osmesa
->format
==OSMESA_RGB
) || (osmesa
->format
==OSMESA_BGR
)) {
1558 /* 3 bytes / pixel in frame buffer */
1559 ctx
->Driver
.WriteRGBASpan
= write_rgba_span3
;
1560 ctx
->Driver
.WriteRGBSpan
= write_rgb_span3
;
1561 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels3
;
1562 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span3
;
1563 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels3
;
1564 ctx
->Driver
.ReadRGBASpan
= read_rgba_span3
;
1565 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels3
;
1568 /* 4 bytes / pixel in frame buffer */
1569 if (osmesa
->format
==OSMESA_RGBA
1570 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1571 ctx
->Driver
.WriteRGBASpan
= write_rgba_span_rgba
;
1573 ctx
->Driver
.WriteRGBASpan
= write_rgba_span
;
1574 ctx
->Driver
.WriteRGBSpan
= write_rgb_span
;
1575 ctx
->Driver
.WriteRGBAPixels
= write_rgba_pixels
;
1576 ctx
->Driver
.WriteMonoRGBASpan
= write_monocolor_span
;
1577 ctx
->Driver
.WriteMonoRGBAPixels
= write_monocolor_pixels
;
1578 if (osmesa
->format
==OSMESA_RGBA
1579 && RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3)
1580 ctx
->Driver
.ReadRGBASpan
= read_rgba_span_rgba
;
1582 ctx
->Driver
.ReadRGBASpan
= read_rgba_span
;
1583 ctx
->Driver
.ReadRGBAPixels
= read_rgba_pixels
;
1586 /* CI span/pixel functions */
1587 ctx
->Driver
.WriteCI32Span
= write_index32_span
;
1588 ctx
->Driver
.WriteCI8Span
= write_index8_span
;
1589 ctx
->Driver
.WriteMonoCISpan
= write_monoindex_span
;
1590 ctx
->Driver
.WriteCI32Pixels
= write_index_pixels
;
1591 ctx
->Driver
.WriteMonoCIPixels
= write_monoindex_pixels
;
1592 ctx
->Driver
.ReadCI32Span
= read_index_span
;
1593 ctx
->Driver
.ReadCI32Pixels
= read_index_pixels
;