1 /* $Id: osmesa.c,v 1.54 2001/05/10 12:22:32 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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 _mesa_make_current() and _mesa_get_current_context()
34 * functions. Those functions are thread-safe.
39 #include "GL/osmesa.h"
43 #include "extensions.h"
49 #include "texformat.h"
51 #include "array_cache/acache.h"
52 #include "swrast/swrast.h"
53 #include "swrast_setup/swrast_setup.h"
54 #include "swrast/s_context.h"
55 #include "swrast/s_depth.h"
56 #include "swrast/s_lines.h"
57 #include "swrast/s_triangle.h"
59 #include "tnl/t_context.h"
60 #include "tnl/t_pipeline.h"
65 * This is the OS/Mesa context struct.
66 * Notice how it includes a GLcontext. By doing this we're mimicking
67 * C++ inheritance/derivation.
68 * Later, we can cast a GLcontext pointer into an OSMesaContext pointer
71 struct osmesa_context
{
72 GLcontext gl_ctx
; /* The core GL/Mesa context */
73 GLvisual
*gl_visual
; /* Describes the buffers */
74 GLframebuffer
*gl_buffer
; /* Depth, stencil, accum, etc buffers */
75 GLenum format
; /* either GL_RGBA or GL_COLOR_INDEX */
76 void *buffer
; /* the image buffer */
77 GLint width
, height
; /* size of image buffer */
78 GLint rowlength
; /* number of pixels per row */
79 GLint userRowLength
; /* user-specified number of pixels per row */
80 GLint rshift
, gshift
; /* bit shifts for RGBA formats */
82 GLint rInd
, gInd
, bInd
, aInd
;/* index offsets for RGBA formats */
83 GLchan
*rowaddr
[MAX_HEIGHT
]; /* address of first pixel in each image row */
84 GLboolean yup
; /* TRUE -> Y increases upward */
85 /* FALSE -> Y increases downward */
90 /* A forward declaration: */
91 static void osmesa_update_state( GLcontext
*ctx
, GLuint newstate
);
92 static void osmesa_register_swrast_functions( GLcontext
*ctx
);
96 #define OSMESA_CONTEXT(ctx) ((OSMesaContext) (ctx->DriverCtx))
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
115 OSMesaCreateContext( GLenum format
, OSMesaContext sharelist
)
117 return OSMesaCreateContextExt(format
, DEFAULT_SOFTWARE_DEPTH_BITS
,
126 * Create context and specify size of ancillary buffers.
128 OSMesaContext GLAPIENTRY
129 OSMesaCreateContextExt( GLenum format
, GLint depthBits
, GLint stencilBits
,
130 GLint accumBits
, OSMesaContext sharelist
)
132 OSMesaContext osmesa
;
133 GLint rshift
, gshift
, bshift
, ashift
;
134 GLint rind
, gind
, bind
, aind
;
135 GLint indexBits
= 0, redBits
= 0, greenBits
= 0, blueBits
= 0, alphaBits
=0;
139 const GLubyte
*i1
= (GLubyte
*) &i4
;
140 const GLint little_endian
= *i1
;
143 rind
= gind
= bind
= aind
= 0;
144 if (format
==OSMESA_COLOR_INDEX
) {
146 rshift
= gshift
= bshift
= ashift
= 0;
149 else if (format
==OSMESA_RGBA
) {
152 greenBits
= CHAN_BITS
;
153 blueBits
= CHAN_BITS
;
154 alphaBits
= CHAN_BITS
;
173 else if (format
==OSMESA_BGRA
) {
176 greenBits
= CHAN_BITS
;
177 blueBits
= CHAN_BITS
;
178 alphaBits
= CHAN_BITS
;
197 else if (format
==OSMESA_ARGB
) {
200 greenBits
= CHAN_BITS
;
201 blueBits
= CHAN_BITS
;
202 alphaBits
= CHAN_BITS
;
221 else if (format
==OSMESA_RGB
) {
224 greenBits
= CHAN_BITS
;
225 blueBits
= CHAN_BITS
;
237 else if (format
==OSMESA_BGR
) {
240 greenBits
= CHAN_BITS
;
241 blueBits
= CHAN_BITS
;
258 osmesa
= (OSMesaContext
) CALLOC_STRUCT(osmesa_context
);
260 osmesa
->gl_visual
= _mesa_create_visual( rgbmode
,
261 GL_FALSE
, /* double buffer */
262 GL_FALSE
, /* stereo */
273 alphaBits
? accumBits
: 0,
276 if (!osmesa
->gl_visual
) {
281 if (!_mesa_initialize_context(&osmesa
->gl_ctx
,
283 sharelist
? &sharelist
->gl_ctx
284 : (GLcontext
*) NULL
,
285 (void *) osmesa
, GL_TRUE
)) {
286 _mesa_destroy_visual( osmesa
->gl_visual
);
291 _mesa_enable_sw_extensions(&(osmesa
->gl_ctx
));
293 osmesa
->gl_buffer
= _mesa_create_framebuffer( osmesa
->gl_visual
,
294 osmesa
->gl_visual
->depthBits
> 0,
295 osmesa
->gl_visual
->stencilBits
> 0,
296 osmesa
->gl_visual
->accumRedBits
> 0,
297 osmesa
->gl_visual
->alphaBits
> 0 );
299 if (!osmesa
->gl_buffer
) {
300 _mesa_destroy_visual( osmesa
->gl_visual
);
301 _mesa_free_context_data( &osmesa
->gl_ctx
);
305 osmesa
->format
= format
;
306 osmesa
->buffer
= NULL
;
309 osmesa
->userRowLength
= 0;
310 osmesa
->rowlength
= 0;
311 osmesa
->yup
= GL_TRUE
;
312 osmesa
->rshift
= rshift
;
313 osmesa
->gshift
= gshift
;
314 osmesa
->bshift
= bshift
;
315 osmesa
->ashift
= ashift
;
322 /* Initialize the software rasterizer and helper modules.
325 GLcontext
*ctx
= &osmesa
->gl_ctx
;
327 _swrast_CreateContext( ctx
);
328 _ac_CreateContext( ctx
);
329 _tnl_CreateContext( ctx
);
330 _swsetup_CreateContext( ctx
);
332 osmesa_register_swrast_functions( ctx
);
342 * Destroy an Off-Screen Mesa rendering context.
344 * Input: ctx - the context to destroy
346 void GLAPIENTRY
OSMesaDestroyContext( OSMesaContext ctx
)
349 _swsetup_DestroyContext( &ctx
->gl_ctx
);
350 _tnl_DestroyContext( &ctx
->gl_ctx
);
351 _ac_DestroyContext( &ctx
->gl_ctx
);
352 _swrast_DestroyContext( &ctx
->gl_ctx
);
354 _mesa_destroy_visual( ctx
->gl_visual
);
355 _mesa_destroy_framebuffer( ctx
->gl_buffer
);
356 _mesa_free_context_data( &ctx
->gl_ctx
);
364 * Recompute the values of the context's rowaddr array.
366 static void compute_row_addresses( OSMesaContext ctx
)
368 GLint bytesPerPixel
, bytesPerRow
, i
;
369 GLubyte
*origin
= (GLubyte
*) ctx
->buffer
;
371 if (ctx
->format
== OSMESA_COLOR_INDEX
) {
373 bytesPerPixel
= 1 * sizeof(GLchan
);
375 else if ((ctx
->format
== OSMESA_RGB
) || (ctx
->format
== OSMESA_BGR
)) {
377 bytesPerPixel
= 3 * sizeof(GLchan
);
381 bytesPerPixel
= 4 * sizeof(GLchan
);
384 bytesPerRow
= ctx
->rowlength
* bytesPerPixel
;
387 /* Y=0 is bottom line of window */
388 for (i
= 0; i
< MAX_HEIGHT
; i
++) {
389 ctx
->rowaddr
[i
] = (GLchan
*) ((GLubyte
*) origin
+ i
* bytesPerRow
);
393 /* Y=0 is top line of window */
394 for (i
= 0; i
< MAX_HEIGHT
; i
++) {
395 GLint j
= ctx
->height
- i
- 1;
396 ctx
->rowaddr
[i
] = (GLchan
*) ((GLubyte
*) origin
+ j
* bytesPerRow
);
403 * Bind an OSMesaContext to an image buffer. The image buffer is just a
404 * block of memory which the client provides. Its size must be at least
405 * as large as width*height*sizeof(type). Its address should be a multiple
406 * of 4 if using RGBA mode.
408 * Image data is stored in the order of glDrawPixels: row-major order
409 * with the lower-left image pixel stored in the first array position
410 * (ie. bottom-to-top).
412 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
413 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
414 * value. If the context is in color indexed mode, each pixel will be
415 * stored as a 1-byte value.
417 * If the context's viewport hasn't been initialized yet, it will now be
418 * initialized to (0,0,width,height).
420 * Input: ctx - the rendering context
421 * buffer - the image buffer memory
422 * type - data type for pixel components, only GL_UNSIGNED_BYTE
424 * width, height - size of image buffer in pixels, at least 1
425 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
426 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
427 * width>internal limit or height>internal limit.
430 OSMesaMakeCurrent( OSMesaContext ctx
, void *buffer
, GLenum type
,
431 GLsizei width
, GLsizei height
)
433 if (!ctx
|| !buffer
|| type
!= CHAN_TYPE
||
434 width
< 1 || height
< 1 ||
435 width
> MAX_WIDTH
|| height
> MAX_HEIGHT
) {
439 osmesa_update_state( &ctx
->gl_ctx
, 0 );
440 _mesa_make_current( &ctx
->gl_ctx
, ctx
->gl_buffer
);
442 ctx
->buffer
= buffer
;
444 ctx
->height
= height
;
445 if (ctx
->userRowLength
)
446 ctx
->rowlength
= ctx
->userRowLength
;
448 ctx
->rowlength
= width
;
450 compute_row_addresses( ctx
);
453 if (ctx
->gl_ctx
.Viewport
.Width
==0) {
454 /* initialize viewport and scissor box to buffer size */
455 _mesa_Viewport( 0, 0, width
, height
);
456 ctx
->gl_ctx
.Scissor
.Width
= width
;
457 ctx
->gl_ctx
.Scissor
.Height
= height
;
465 OSMesaContext GLAPIENTRY
OSMesaGetCurrentContext( void )
467 GLcontext
*ctx
= _mesa_get_current_context();
469 return (OSMesaContext
) ctx
;
476 void GLAPIENTRY
OSMesaPixelStore( GLint pname
, GLint value
)
478 OSMesaContext ctx
= OSMesaGetCurrentContext();
481 case OSMESA_ROW_LENGTH
:
483 _mesa_error( &ctx
->gl_ctx
, GL_INVALID_VALUE
,
484 "OSMesaPixelStore(value)" );
487 ctx
->userRowLength
= value
;
488 ctx
->rowlength
= value
;
491 ctx
->yup
= value
? GL_TRUE
: GL_FALSE
;
494 _mesa_error( &ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaPixelStore(pname)" );
498 compute_row_addresses( ctx
);
502 void GLAPIENTRY
OSMesaGetIntegerv( GLint pname
, GLint
*value
)
504 OSMesaContext ctx
= OSMesaGetCurrentContext();
511 *value
= ctx
->height
;
514 *value
= ctx
->format
;
519 case OSMESA_ROW_LENGTH
:
520 *value
= ctx
->rowlength
;
526 _mesa_error(&ctx
->gl_ctx
, GL_INVALID_ENUM
, "OSMesaGetIntergerv(pname)");
532 * Return the depth buffer associated with an OSMesa context.
533 * Input: c - the OSMesa context
534 * Output: width, height - size of buffer in pixels
535 * bytesPerValue - bytes per depth value (2 or 4)
536 * buffer - pointer to depth buffer values
537 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
540 OSMesaGetDepthBuffer( OSMesaContext c
, GLint
*width
, GLint
*height
,
541 GLint
*bytesPerValue
, void **buffer
)
543 if ((!c
->gl_buffer
) || (!c
->gl_buffer
->DepthBuffer
)) {
551 *width
= c
->gl_buffer
->Width
;
552 *height
= c
->gl_buffer
->Height
;
553 if (c
->gl_visual
->depthBits
<= 16)
554 *bytesPerValue
= sizeof(GLushort
);
556 *bytesPerValue
= sizeof(GLuint
);
557 *buffer
= c
->gl_buffer
->DepthBuffer
;
563 * Return the color buffer associated with an OSMesa context.
564 * Input: c - the OSMesa context
565 * Output: width, height - size of buffer in pixels
566 * format - the pixel format (OSMESA_FORMAT)
567 * buffer - pointer to color buffer values
568 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
571 OSMesaGetColorBuffer( OSMesaContext c
, GLint
*width
,
572 GLint
*height
, GLint
*format
, void **buffer
)
590 /**********************************************************************/
591 /*** Device Driver Functions ***/
592 /**********************************************************************/
599 #define PACK_RGBA(DST, R, G, B, A) \
601 (DST)[osmesa->rInd] = R; \
602 (DST)[osmesa->gInd] = G; \
603 (DST)[osmesa->bInd] = B; \
604 (DST)[osmesa->aInd] = A; \
607 #define PACK_RGB(DST, R, G, B) \
614 #define PACK_BGR(DST, R, G, B) \
622 #define UNPACK_RED(P) ( (P)[osmesa->rInd] )
623 #define UNPACK_GREEN(P) ( (P)[osmesa->gInd] )
624 #define UNPACK_BLUE(P) ( (P)[osmesa->bInd] )
625 #define UNPACK_ALPHA(P) ( (P)[osmesa->aInd] )
628 #define PIXELADDR1(X,Y) (osmesa->rowaddr[Y] + (X))
629 #define PIXELADDR3(X,Y) (osmesa->rowaddr[Y] + 3 * (X))
630 #define PIXELADDR4(X,Y) (osmesa->rowaddr[Y] + 4 * (X))
634 static GLboolean
set_draw_buffer( GLcontext
*ctx
, GLenum mode
)
637 if (mode
==GL_FRONT_LEFT
) {
646 static void set_read_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLenum mode
)
648 /* separate read buffer not supported */
649 ASSERT(buffer
== ctx
->DrawBuffer
);
650 ASSERT(mode
== GL_FRONT_LEFT
);
654 static void clear( GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
655 GLint x
, GLint y
, GLint width
, GLint height
)
657 OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
658 const GLuint
*colorMask
= (GLuint
*) &ctx
->Color
.ColorMask
;
660 /* sanity check - we only have a front-left buffer */
661 ASSERT((mask
& (DD_FRONT_RIGHT_BIT
| DD_BACK_LEFT_BIT
| DD_BACK_RIGHT_BIT
)) == 0);
662 if (*colorMask
== 0xffffffff && ctx
->Color
.IndexMask
== 0xffffffff) {
663 if (mask
& DD_FRONT_LEFT_BIT
) {
664 if (osmesa
->format
== OSMESA_COLOR_INDEX
) {
666 /* Clear whole CI buffer */
667 #if CHAN_TYPE == GL_UNSIGNED_BYTE
668 MEMSET(osmesa
->buffer
, ctx
->Color
.ClearIndex
,
669 osmesa
->rowlength
* osmesa
->height
);
671 const GLint n
= osmesa
->rowlength
* osmesa
->height
;
672 GLchan
*buffer
= (GLchan
*) osmesa
->buffer
;
674 for (i
= 0; i
< n
; i
++) {
675 buffer
[i
] = ctx
->Color
.ClearIndex
;
680 /* Clear part of CI buffer */
681 const GLchan clearIndex
= (GLchan
) ctx
->Color
.ClearIndex
;
683 for (i
= 0; i
< height
; i
++) {
684 GLchan
*ptr1
= PIXELADDR1(x
, (y
+ i
));
685 for (j
= 0; j
< width
; j
++) {
686 *ptr1
++ = clearIndex
;
691 else if (osmesa
->format
== OSMESA_RGB
) {
692 const GLchan r
= ctx
->Color
.ClearColor
[0];
693 const GLchan g
= ctx
->Color
.ClearColor
[1];
694 const GLchan b
= ctx
->Color
.ClearColor
[2];
696 /* Clear whole RGB buffer */
697 GLuint n
= osmesa
->rowlength
* osmesa
->height
;
698 GLchan
*ptr3
= (GLchan
*) osmesa
->buffer
;
700 for (i
= 0; i
< n
; i
++) {
701 PACK_RGB(ptr3
, r
, g
, b
);
706 /* Clear part of RGB buffer */
708 for (i
= 0; i
< height
; i
++) {
709 GLchan
*ptr3
= PIXELADDR3(x
, (y
+ i
));
710 for (j
= 0; j
< width
; j
++) {
711 PACK_RGB(ptr3
, r
, g
, b
);
717 else if (osmesa
->format
== OSMESA_BGR
) {
718 const GLchan r
= ctx
->Color
.ClearColor
[0];
719 const GLchan g
= ctx
->Color
.ClearColor
[1];
720 const GLchan b
= ctx
->Color
.ClearColor
[2];
722 /* Clear whole RGB buffer */
723 const GLint n
= osmesa
->rowlength
* osmesa
->height
;
724 GLchan
*ptr3
= (GLchan
*) osmesa
->buffer
;
726 for (i
= 0; i
< n
; i
++) {
727 PACK_BGR(ptr3
, r
, g
, b
);
732 /* Clear part of RGB buffer */
734 for (i
= 0; i
< height
; i
++) {
735 GLchan
*ptr3
= PIXELADDR3(x
, (y
+ i
));
736 for (j
= 0; j
< width
; j
++) {
737 PACK_BGR(ptr3
, r
, g
, b
);
744 #if CHAN_TYPE == GL_UNSIGNED_BYTE
745 /* 4-byte pixel value */
747 GLchan
*clr
= (GLchan
*) &clearPixel
;
748 clr
[osmesa
->rInd
] = ctx
->Color
.ClearColor
[0];
749 clr
[osmesa
->gInd
] = ctx
->Color
.ClearColor
[1];
750 clr
[osmesa
->bInd
] = ctx
->Color
.ClearColor
[2];
751 clr
[osmesa
->aInd
] = ctx
->Color
.ClearColor
[3];
753 /* Clear whole RGBA buffer */
754 const GLuint n
= osmesa
->rowlength
* osmesa
->height
;
755 GLuint
*ptr4
= (GLuint
*) osmesa
->buffer
;
758 for (i
= 0; i
< n
; i
++) {
759 *ptr4
++ = clearPixel
;
763 BZERO(ptr4
, n
* sizeof(GLuint
));
767 /* Clear part of RGBA buffer */
769 for (i
= 0; i
< height
; i
++) {
770 GLuint
*ptr4
= (GLuint
*) PIXELADDR4(x
, (y
+ i
));
771 for (j
= 0; j
< width
; j
++) {
772 *ptr4
++ = clearPixel
;
777 const GLchan r
= ctx
->Color
.ClearColor
[0];
778 const GLchan g
= ctx
->Color
.ClearColor
[1];
779 const GLchan b
= ctx
->Color
.ClearColor
[2];
780 const GLchan a
= ctx
->Color
.ClearColor
[3];
782 /* Clear whole RGBA buffer */
783 const GLuint n
= osmesa
->rowlength
* osmesa
->height
;
784 GLchan
*p
= (GLchan
*) osmesa
->buffer
;
786 for (i
= 0; i
< n
; i
++) {
787 PACK_RGBA(p
, r
, g
, b
, a
);
792 /* Clear part of RGBA buffer */
794 for (i
= 0; i
< height
; i
++) {
795 GLchan
*p
= PIXELADDR4(x
, (y
+ i
));
796 for (j
= 0; j
< width
; j
++) {
797 PACK_RGBA(p
, r
, g
, b
, a
);
805 mask
&= ~DD_FRONT_LEFT_BIT
;
810 _swrast_Clear( ctx
, mask
, all
, x
, y
, width
, height
);
815 static void buffer_size( GLcontext
*ctx
, GLuint
*width
, GLuint
*height
)
817 OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
818 *width
= osmesa
->width
;
819 *height
= osmesa
->height
;
823 /**********************************************************************/
824 /***** Read/write spans/arrays of RGBA pixels *****/
825 /**********************************************************************/
827 /* Write RGBA pixels to an RGBA (or permuted) buffer. */
829 write_rgba_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
830 CONST GLchan rgba
[][4], const GLubyte mask
[] )
832 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
833 GLchan
*p
= PIXELADDR4(x
, y
);
836 for (i
= 0; i
< n
; i
++, p
+= 4) {
838 PACK_RGBA(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
839 rgba
[i
][BCOMP
], rgba
[i
][ACOMP
]);
844 for (i
= 0; i
< n
; i
++, p
+= 4) {
845 PACK_RGBA(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
846 rgba
[i
][BCOMP
], rgba
[i
][ACOMP
]);
852 /* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
854 write_rgba_span_rgba( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
855 CONST GLchan rgba
[][4], const GLubyte mask
[] )
857 OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
858 GLuint
*ptr4
= (GLuint
*) PIXELADDR4(x
, y
);
859 const GLuint
*rgba4
= (const GLuint
*) rgba
;
861 ASSERT(CHAN_TYPE
== GL_UNSIGNED_BYTE
);
863 for (i
= 0; i
< n
; i
++) {
870 MEMCPY( ptr4
, rgba4
, n
* 4 );
875 /* Write RGB pixels to an RGBA (or permuted) buffer. */
877 write_rgb_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
878 CONST GLchan rgb
[][3], const GLubyte mask
[] )
880 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
881 GLchan
*p
= PIXELADDR4(x
, y
);
884 for (i
= 0; i
< n
; i
++, p
+=4) {
886 PACK_RGBA(p
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255);
891 for (i
= 0; i
< n
; i
++, p
+=4) {
892 PACK_RGBA(p
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
], 255);
900 write_monocolor_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
901 const GLchan color
[4], const GLubyte mask
[] )
903 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
904 GLchan
*p
= PIXELADDR4(x
, y
);
906 for (i
= 0; i
< n
; i
++, p
+= 4) {
908 PACK_RGBA(p
, color
[RCOMP
], color
[GCOMP
], color
[BCOMP
], color
[ACOMP
]);
916 write_rgba_pixels( const GLcontext
*ctx
, GLuint n
,
917 const GLint x
[], const GLint y
[],
918 CONST GLchan rgba
[][4], const GLubyte mask
[] )
920 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
922 for (i
= 0; i
< n
; i
++) {
924 GLchan
*p
= PIXELADDR4(x
[i
], y
[i
]);
925 PACK_RGBA(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
926 rgba
[i
][BCOMP
], rgba
[i
][ACOMP
]);
934 write_monocolor_pixels( const GLcontext
*ctx
, GLuint n
,
935 const GLint x
[], const GLint y
[],
936 const GLchan color
[4], const GLubyte mask
[] )
938 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
940 for (i
= 0; i
< n
; i
++) {
942 GLchan
*p
= PIXELADDR4(x
[i
], y
[i
]);
943 PACK_RGBA(p
, color
[RCOMP
], color
[GCOMP
], color
[BCOMP
], color
[ACOMP
]);
950 read_rgba_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
953 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
955 GLchan
*p
= PIXELADDR4(x
, y
);
956 for (i
= 0; i
< n
; i
++, p
+= 4) {
957 rgba
[i
][RCOMP
] = UNPACK_RED(p
);
958 rgba
[i
][GCOMP
] = UNPACK_GREEN(p
);
959 rgba
[i
][BCOMP
] = UNPACK_BLUE(p
);
960 rgba
[i
][ACOMP
] = UNPACK_ALPHA(p
);
965 /* Read RGBA pixels from an RGBA buffer */
967 read_rgba_span_rgba( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
970 OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
971 GLuint
*ptr4
= (GLuint
*) PIXELADDR4(x
, y
);
972 MEMCPY( rgba
, ptr4
, n
* 4 * sizeof(GLchan
) );
977 read_rgba_pixels( const GLcontext
*ctx
,
978 GLuint n
, const GLint x
[], const GLint y
[],
979 GLchan rgba
[][4], const GLubyte mask
[] )
981 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
983 for (i
= 0; i
< n
; i
++) {
985 const GLchan
*p
= PIXELADDR4(x
[i
], y
[i
]);
986 rgba
[i
][RCOMP
] = UNPACK_RED(p
);
987 rgba
[i
][GCOMP
] = UNPACK_GREEN(p
);
988 rgba
[i
][BCOMP
] = UNPACK_BLUE(p
);
989 rgba
[i
][ACOMP
] = UNPACK_ALPHA(p
);
994 /**********************************************************************/
995 /***** 3 byte RGB pixel support funcs *****/
996 /**********************************************************************/
998 /* Write RGBA pixels to an RGB buffer. */
1000 write_rgba_span_RGB( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1001 CONST GLchan rgba
[][4], const GLubyte mask
[] )
1003 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1004 GLchan
*p
= PIXELADDR3(x
, y
);
1007 for (i
= 0; i
< n
; i
++, p
+= 3) {
1009 PACK_RGB(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1014 for (i
= 0; i
< n
; i
++, p
+= 3) {
1015 PACK_RGB(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1020 /* Write RGBA pixels to an BGR buffer. */
1022 write_rgba_span_BGR( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1023 CONST GLchan rgba
[][4], const GLubyte mask
[] )
1025 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1026 GLchan
*p
= PIXELADDR3(x
, y
);
1029 for (i
= 0; i
< n
; i
++, p
+= 3) {
1031 PACK_BGR(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1036 for (i
= 0; i
< n
; i
++, p
+= 3) {
1037 PACK_BGR(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1042 /* Write RGB pixels to an RGB buffer. */
1044 write_rgb_span_RGB( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1045 CONST GLchan rgb
[][3], const GLubyte mask
[] )
1047 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1048 GLchan
*p
= PIXELADDR3(x
, y
);
1051 for (i
= 0; i
< n
; i
++, p
+= 3) {
1053 PACK_RGB(p
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
1058 for (i
= 0; i
< n
; i
++, p
+= 3) {
1059 PACK_RGB(p
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
1064 /* Write RGB pixels to an BGR buffer. */
1066 write_rgb_span_BGR( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1067 CONST GLchan rgb
[][3], const GLubyte mask
[] )
1069 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1070 GLchan
*p
= PIXELADDR3(x
, y
);
1073 for (i
= 0; i
< n
; i
++, p
+= 3) {
1075 PACK_BGR(p
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
1080 for (i
= 0; i
< n
; i
++, p
+= 3) {
1081 PACK_BGR(p
, rgb
[i
][RCOMP
], rgb
[i
][GCOMP
], rgb
[i
][BCOMP
]);
1088 write_monocolor_span_RGB( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1089 const GLchan color
[4], const GLubyte mask
[] )
1091 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1092 GLchan
*p
= PIXELADDR3(x
, y
);
1094 for (i
= 0; i
< n
; i
++, p
+= 3) {
1096 PACK_RGB(p
, color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
1102 write_monocolor_span_BGR( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1103 const GLchan color
[4], const GLubyte mask
[] )
1105 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1106 GLchan
*p
= PIXELADDR3(x
, y
);
1108 for (i
= 0; i
< n
; i
++, p
+= 3) {
1110 PACK_BGR(p
, color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
1116 write_rgba_pixels_RGB( const GLcontext
*ctx
, GLuint n
,
1117 const GLint x
[], const GLint y
[],
1118 CONST GLchan rgba
[][4], const GLubyte mask
[] )
1120 const OSMesaContext osmesa
= (const OSMesaContext
) ctx
;
1122 for (i
= 0; i
< n
; i
++) {
1124 GLchan
*p
= PIXELADDR3(x
[i
], y
[i
]);
1125 PACK_RGB(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1131 write_rgba_pixels_BGR( const GLcontext
*ctx
, GLuint n
,
1132 const GLint x
[], const GLint y
[],
1133 CONST GLchan rgba
[][4], const GLubyte mask
[] )
1135 const OSMesaContext osmesa
= (const OSMesaContext
) ctx
;
1137 for (i
= 0; i
< n
; i
++) {
1139 GLchan
*p
= PIXELADDR3(x
[i
], y
[i
]);
1140 PACK_BGR(p
, rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1146 write_monocolor_pixels_RGB( const GLcontext
*ctx
,
1147 GLuint n
, const GLint x
[], const GLint y
[],
1148 const GLchan color
[4], const GLubyte mask
[] )
1150 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1152 for (i
= 0; i
< n
; i
++) {
1154 GLchan
*p
= PIXELADDR3(x
[i
], y
[i
]);
1155 PACK_RGB(p
, color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
1161 write_monocolor_pixels_BGR( const GLcontext
*ctx
,
1162 GLuint n
, const GLint x
[], const GLint y
[],
1163 const GLchan color
[4], const GLubyte mask
[] )
1165 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1167 for (i
= 0; i
< n
; i
++) {
1169 GLchan
*p
= PIXELADDR3(x
[i
], y
[i
]);
1170 PACK_BGR(p
, color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
1176 read_rgba_span3( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1179 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1181 const GLchan
*p
= PIXELADDR3(x
, y
);
1182 for (i
= 0; i
< n
; i
++, p
+= 3) {
1183 rgba
[i
][RCOMP
] = UNPACK_RED(p
);
1184 rgba
[i
][GCOMP
] = UNPACK_GREEN(p
);
1185 rgba
[i
][BCOMP
] = UNPACK_BLUE(p
);
1186 rgba
[i
][ACOMP
] = 255;
1191 read_rgba_pixels3( const GLcontext
*ctx
,
1192 GLuint n
, const GLint x
[], const GLint y
[],
1193 GLchan rgba
[][4], const GLubyte mask
[] )
1195 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1197 for (i
= 0; i
< n
; i
++) {
1199 const GLchan
*p
= PIXELADDR3(x
[i
], y
[i
]);
1200 rgba
[i
][RCOMP
] = UNPACK_RED(p
);
1201 rgba
[i
][GCOMP
] = UNPACK_GREEN(p
);
1202 rgba
[i
][BCOMP
] = UNPACK_BLUE(p
);
1203 rgba
[i
][ACOMP
] = 255;
1209 /**********************************************************************/
1210 /***** Read/write spans/arrays of CI pixels *****/
1211 /**********************************************************************/
1213 /* Write 32-bit color index to buffer */
1215 write_index32_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1216 const GLuint index
[], const GLubyte mask
[] )
1218 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1219 GLchan
*ptr1
= PIXELADDR1(x
, y
);
1222 for (i
=0;i
<n
;i
++,ptr1
++) {
1224 *ptr1
= (GLchan
) index
[i
];
1229 for (i
=0;i
<n
;i
++,ptr1
++) {
1230 *ptr1
= (GLchan
) index
[i
];
1236 /* Write 8-bit color index to buffer */
1238 write_index8_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1239 const GLubyte index
[], const GLubyte mask
[] )
1241 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1242 GLchan
*ptr1
= PIXELADDR1(x
, y
);
1245 for (i
=0;i
<n
;i
++,ptr1
++) {
1247 *ptr1
= (GLchan
) index
[i
];
1252 MEMCPY(ptr1
, index
, n
* sizeof(GLchan
));
1258 write_monoindex_span( const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
1259 GLuint colorIndex
, const GLubyte mask
[] )
1261 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1262 GLchan
*ptr1
= PIXELADDR1(x
, y
);
1264 for (i
=0;i
<n
;i
++,ptr1
++) {
1266 *ptr1
= (GLchan
) colorIndex
;
1273 write_index_pixels( const GLcontext
*ctx
,
1274 GLuint n
, const GLint x
[], const GLint y
[],
1275 const GLuint index
[], const GLubyte mask
[] )
1277 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1281 GLchan
*ptr1
= PIXELADDR1(x
[i
], y
[i
]);
1282 *ptr1
= (GLchan
) index
[i
];
1289 write_monoindex_pixels( const GLcontext
*ctx
,
1290 GLuint n
, const GLint x
[], const GLint y
[],
1291 GLuint colorIndex
, const GLubyte mask
[] )
1293 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1297 GLchan
*ptr1
= PIXELADDR1(x
[i
], y
[i
]);
1298 *ptr1
= (GLchan
) colorIndex
;
1305 read_index_span( const GLcontext
*ctx
,
1306 GLuint n
, GLint x
, GLint y
, GLuint index
[] )
1308 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1310 const GLchan
*ptr1
= (const GLchan
*) PIXELADDR1(x
, y
);
1311 for (i
=0;i
<n
;i
++,ptr1
++) {
1312 index
[i
] = (GLuint
) *ptr1
;
1318 read_index_pixels( const GLcontext
*ctx
,
1319 GLuint n
, const GLint x
[], const GLint y
[],
1320 GLuint index
[], const GLubyte mask
[] )
1322 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1326 const GLchan
*ptr1
= PIXELADDR1(x
[i
], y
[i
]);
1327 index
[i
] = (GLuint
) *ptr1
;
1334 /**********************************************************************/
1335 /***** Optimized line rendering *****/
1336 /**********************************************************************/
1340 * Draw a flat-shaded, RGB line into an osmesa buffer.
1343 flat_rgba_line( GLcontext
*ctx
, const SWvertex
*vert0
, const SWvertex
*vert1
)
1345 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1346 const GLchan
*color
= vert0
->color
;
1350 #define PLOT(X, Y) \
1352 GLchan *p = PIXELADDR4(X, Y); \
1353 PACK_RGBA(p, color[0], color[1], color[2], color[3]); \
1357 #include "..\swrast\s_linetemp.h"
1359 #include "swrast/s_linetemp.h"
1365 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1368 flat_rgba_z_line(GLcontext
*ctx
, const SWvertex
*vert0
, const SWvertex
*vert1
)
1370 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1371 const GLchan
*color
= vert0
->color
;
1375 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1377 #define PLOT(X, Y) \
1380 GLchan *p = PIXELADDR4(X, Y); \
1381 PACK_RGBA(p, color[RCOMP], color[GCOMP], \
1382 color[BCOMP], color[ACOMP]); \
1389 #include "..\swrast\s_linetemp.h"
1391 #include "swrast/s_linetemp.h"
1397 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1398 * XXX update for GLchan
1401 flat_blend_rgba_line( GLcontext
*ctx
,
1402 const SWvertex
*vert0
, const SWvertex
*vert1
)
1404 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1405 const GLint rshift
= osmesa
->rshift
;
1406 const GLint gshift
= osmesa
->gshift
;
1407 const GLint bshift
= osmesa
->bshift
;
1408 const GLint avalue
= vert0
->color
[3];
1409 const GLint msavalue
= 255 - avalue
;
1410 const GLint rvalue
= vert0
->color
[0]*avalue
;
1411 const GLint gvalue
= vert0
->color
[1]*avalue
;
1412 const GLint bvalue
= vert0
->color
[2]*avalue
;
1417 { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
1419 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1420 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1421 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1426 #include "..\swrast\s_linetemp.h"
1428 #include "swrast/s_linetemp.h"
1434 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1435 * XXX update for GLchan
1438 flat_blend_rgba_z_line( GLcontext
*ctx
,
1439 const SWvertex
*vert0
, const SWvertex
*vert1
)
1441 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1442 const GLint rshift
= osmesa
->rshift
;
1443 const GLint gshift
= osmesa
->gshift
;
1444 const GLint bshift
= osmesa
->bshift
;
1445 const GLint avalue
= vert0
->color
[3];
1446 const GLint msavalue
= 256 - avalue
;
1447 const GLint rvalue
= vert0
->color
[0]*avalue
;
1448 const GLint gvalue
= vert0
->color
[1]*avalue
;
1449 const GLint bvalue
= vert0
->color
[2]*avalue
;
1453 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1457 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
1459 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1460 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1461 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1466 #include "..\swrast\s_linetemp.h"
1468 #include "swrast/s_linetemp.h"
1474 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1475 * XXX update for GLchan
1478 flat_blend_rgba_z_line_write( GLcontext
*ctx
,
1479 const SWvertex
*vert0
, const SWvertex
*vert1
)
1481 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1482 const GLint rshift
= osmesa
->rshift
;
1483 const GLint gshift
= osmesa
->gshift
;
1484 const GLint bshift
= osmesa
->bshift
;
1485 const GLint avalue
= vert0
->color
[3];
1486 const GLint msavalue
= 256 - avalue
;
1487 const GLint rvalue
= vert0
->color
[0]*avalue
;
1488 const GLint gvalue
= vert0
->color
[1]*avalue
;
1489 const GLint bvalue
= vert0
->color
[2]*avalue
;
1493 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1497 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \
1499 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \
1500 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \
1501 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \
1507 #include "..\swrast\s_linetemp.h"
1509 #include "swrast/s_linetemp.h"
1515 * Analyze context state to see if we can provide a fast line drawing
1516 * function, like those in lines.c. Otherwise, return NULL.
1518 static swrast_line_func
1519 osmesa_choose_line_function( GLcontext
*ctx
)
1521 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1522 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1524 if (CHAN_BITS
!= 8) return NULL
;
1525 if (ctx
->RenderMode
!= GL_RENDER
) return NULL
;
1526 if (ctx
->Line
.SmoothFlag
) return NULL
;
1527 if (ctx
->Texture
._ReallyEnabled
) return NULL
;
1528 if (ctx
->Light
.ShadeModel
!= GL_FLAT
) return NULL
;
1529 if (ctx
->Line
.Width
!= 1.0F
) return NULL
;
1530 if (ctx
->Line
.StippleFlag
) return NULL
;
1531 if (ctx
->Line
.SmoothFlag
) return NULL
;
1532 if (osmesa
->format
!= OSMESA_RGBA
&&
1533 osmesa
->format
!= OSMESA_BGRA
&&
1534 osmesa
->format
!= OSMESA_ARGB
) return NULL
;
1536 if (swrast
->_RasterMask
==DEPTH_BIT
1537 && ctx
->Depth
.Func
==GL_LESS
1538 && ctx
->Depth
.Mask
==GL_TRUE
1539 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
1540 return flat_rgba_z_line
;
1543 if (swrast
->_RasterMask
== 0) {
1544 return flat_rgba_line
;
1547 if (swrast
->_RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1548 && ctx
->Depth
.Func
==GL_LESS
1549 && ctx
->Depth
.Mask
==GL_TRUE
1550 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1551 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1552 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1553 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1554 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1555 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1556 return flat_blend_rgba_z_line_write
;
1559 if (swrast
->_RasterMask
==(DEPTH_BIT
|BLEND_BIT
)
1560 && ctx
->Depth
.Func
==GL_LESS
1561 && ctx
->Depth
.Mask
==GL_FALSE
1562 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
1563 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1564 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1565 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1566 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1567 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1568 return flat_blend_rgba_z_line
;
1571 if (swrast
->_RasterMask
==BLEND_BIT
1572 && ctx
->Color
.BlendSrcRGB
==GL_SRC_ALPHA
1573 && ctx
->Color
.BlendDstRGB
==GL_ONE_MINUS_SRC_ALPHA
1574 && ctx
->Color
.BlendSrcA
==GL_SRC_ALPHA
1575 && ctx
->Color
.BlendDstA
==GL_ONE_MINUS_SRC_ALPHA
1576 && ctx
->Color
.BlendEquation
==GL_FUNC_ADD_EXT
) {
1577 return flat_blend_rgba_line
;
1584 /**********************************************************************/
1585 /***** Optimized triangle rendering *****/
1586 /**********************************************************************/
1590 * Smooth-shaded, z-less triangle, RGBA color.
1592 static void smooth_rgba_z_triangle( GLcontext
*ctx
,
1595 const SWvertex
*v2
)
1597 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1600 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1601 #define INTERP_RGB 1
1602 #define INTERP_ALPHA 1
1603 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1605 GLint i, len = RIGHT-LEFT; \
1606 GLchan *img = PIXELADDR4(LEFT, Y); \
1607 for (i = 0; i < len; i++, img += 4) { \
1608 GLdepth z = FixedToDepth(ffz); \
1609 if (z < zRow[i]) { \
1610 PACK_RGBA(img, FixedToInt(ffr), FixedToInt(ffg), \
1611 FixedToInt(ffb), FixedToInt(ffa)); \
1614 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1619 #include "..\swrast\s_tritemp.h"
1621 #include "swrast/s_tritemp.h"
1629 * Flat-shaded, z-less triangle, RGBA color.
1631 static void flat_rgba_z_triangle( GLcontext
*ctx
,
1634 const SWvertex
*v2
)
1636 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1638 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
1639 #define SETUP_CODE \
1641 PACK_RGBA((GLchan *) &pixel, v0->color[0], v0->color[1], \
1642 v0->color[2], v0->color[3]);
1644 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1646 GLint i, len = RIGHT-LEFT; \
1647 GLuint *img = (GLuint *) PIXELADDR4(LEFT, Y); \
1648 for (i=0;i<len;i++) { \
1649 GLdepth z = FixedToDepth(ffz); \
1650 if (z < zRow[i]) { \
1658 #include "..\swrast\s_tritemp.h"
1660 #include "swrast/s_tritemp.h"
1667 * Return pointer to an accelerated triangle function if possible.
1669 static swrast_tri_func
1670 osmesa_choose_triangle_function( GLcontext
*ctx
)
1672 const OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1673 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1675 if (CHAN_BITS
!= 8) return (swrast_tri_func
) NULL
;
1676 if (ctx
->RenderMode
!= GL_RENDER
) return (swrast_tri_func
) NULL
;
1677 if (ctx
->Polygon
.SmoothFlag
) return (swrast_tri_func
) NULL
;
1678 if (ctx
->Polygon
.StippleFlag
) return (swrast_tri_func
) NULL
;
1679 if (ctx
->Texture
._ReallyEnabled
) return (swrast_tri_func
) NULL
;
1680 if (osmesa
->format
!= OSMESA_RGBA
&&
1681 osmesa
->format
!= OSMESA_BGRA
&&
1682 osmesa
->format
!= OSMESA_ARGB
) return (swrast_tri_func
) NULL
;
1684 if (swrast
->_RasterMask
== DEPTH_BIT
&&
1685 ctx
->Depth
.Func
== GL_LESS
&&
1686 ctx
->Depth
.Mask
== GL_TRUE
&&
1687 ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
1688 if (ctx
->Light
.ShadeModel
== GL_SMOOTH
) {
1689 return smooth_rgba_z_triangle
;
1692 return flat_rgba_z_triangle
;
1695 return (swrast_tri_func
) NULL
;
1700 /* Override for the swrast triangle-selection function. Try to use one
1701 * of our internal triangle functions, otherwise fall back to the
1702 * standard swrast functions.
1704 static void osmesa_choose_triangle( GLcontext
*ctx
)
1706 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1708 swrast
->Triangle
= osmesa_choose_triangle_function( ctx
);
1709 if (!swrast
->Triangle
)
1710 _swrast_choose_triangle( ctx
);
1713 static void osmesa_choose_line( GLcontext
*ctx
)
1715 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1717 swrast
->Line
= osmesa_choose_line_function( ctx
);
1719 _swrast_choose_line( ctx
);
1723 #define OSMESA_NEW_LINE (_NEW_LINE | \
1728 _SWRAST_NEW_RASTERMASK)
1730 #define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \
1735 _SWRAST_NEW_RASTERMASK)
1738 /* Extend the software rasterizer with our line and triangle
1741 static void osmesa_register_swrast_functions( GLcontext
*ctx
)
1743 SWcontext
*swrast
= SWRAST_CONTEXT( ctx
);
1745 swrast
->choose_line
= osmesa_choose_line
;
1746 swrast
->choose_triangle
= osmesa_choose_triangle
;
1748 swrast
->invalidate_line
|= OSMESA_NEW_LINE
;
1749 swrast
->invalidate_triangle
|= OSMESA_NEW_TRIANGLE
;
1753 static const GLubyte
*get_string( GLcontext
*ctx
, GLenum name
)
1758 return (const GLubyte
*) "Mesa OffScreen";
1765 static void osmesa_update_state( GLcontext
*ctx
, GLuint new_state
)
1767 OSMesaContext osmesa
= OSMESA_CONTEXT(ctx
);
1768 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1769 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1771 ASSERT((void *) osmesa
== (void *) ctx
->DriverCtx
);
1774 * XXX these function pointers could be initialized just once during
1775 * context creation since they don't depend on any state changes.
1778 ctx
->Driver
.GetString
= get_string
;
1779 ctx
->Driver
.UpdateState
= osmesa_update_state
;
1780 ctx
->Driver
.SetDrawBuffer
= set_draw_buffer
;
1781 ctx
->Driver
.ResizeBuffersMESA
= _swrast_alloc_buffers
;
1782 ctx
->Driver
.GetBufferSize
= buffer_size
;
1784 ctx
->Driver
.Accum
= _swrast_Accum
;
1785 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1786 ctx
->Driver
.Clear
= clear
;
1787 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1788 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1789 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1791 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
1792 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
1793 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
1794 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
1795 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
1796 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
1797 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
1798 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
1800 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
1801 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
1802 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
1803 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
1804 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
1805 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1806 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1807 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1808 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
1811 /* RGB(A) span/pixel functions */
1812 if (osmesa
->format
== OSMESA_RGB
) {
1813 swdd
->WriteRGBASpan
= write_rgba_span_RGB
;
1814 swdd
->WriteRGBSpan
= write_rgb_span_RGB
;
1815 swdd
->WriteMonoRGBASpan
= write_monocolor_span_RGB
;
1816 swdd
->WriteRGBAPixels
= write_rgba_pixels_RGB
;
1817 swdd
->WriteMonoRGBAPixels
= write_monocolor_pixels_RGB
;
1818 swdd
->ReadRGBASpan
= read_rgba_span3
;
1819 swdd
->ReadRGBAPixels
= read_rgba_pixels3
;
1821 else if (osmesa
->format
== OSMESA_BGR
) {
1822 swdd
->WriteRGBASpan
= write_rgba_span_BGR
;
1823 swdd
->WriteRGBSpan
= write_rgb_span_BGR
;
1824 swdd
->WriteMonoRGBASpan
= write_monocolor_span_BGR
;
1825 swdd
->WriteRGBAPixels
= write_rgba_pixels_BGR
;
1826 swdd
->WriteMonoRGBAPixels
= write_monocolor_pixels_BGR
;
1827 swdd
->ReadRGBASpan
= read_rgba_span3
;
1828 swdd
->ReadRGBAPixels
= read_rgba_pixels3
;
1831 /* 4 bytes / pixel in frame buffer */
1832 swdd
->WriteRGBSpan
= write_rgb_span
;
1833 swdd
->WriteRGBAPixels
= write_rgba_pixels
;
1834 swdd
->WriteMonoRGBASpan
= write_monocolor_span
;
1835 swdd
->WriteMonoRGBAPixels
= write_monocolor_pixels
;
1836 if (osmesa
->format
== OSMESA_RGBA
&&
1837 CHAN_TYPE
== GL_UNSIGNED_BYTE
&&
1838 RCOMP
==0 && GCOMP
==1 && BCOMP
==2 && ACOMP
==3) {
1839 /* special, fast case */
1840 swdd
->WriteRGBASpan
= write_rgba_span_rgba
;
1841 swdd
->ReadRGBASpan
= read_rgba_span_rgba
;
1844 swdd
->WriteRGBASpan
= write_rgba_span
;
1845 swdd
->ReadRGBASpan
= read_rgba_span
;
1847 swdd
->ReadRGBAPixels
= read_rgba_pixels
;
1850 /* CI span/pixel functions */
1851 swdd
->WriteCI32Span
= write_index32_span
;
1852 swdd
->WriteCI8Span
= write_index8_span
;
1853 swdd
->WriteMonoCISpan
= write_monoindex_span
;
1854 swdd
->WriteCI32Pixels
= write_index_pixels
;
1855 swdd
->WriteMonoCIPixels
= write_monoindex_pixels
;
1856 swdd
->ReadCI32Span
= read_index_span
;
1857 swdd
->ReadCI32Pixels
= read_index_pixels
;
1859 swdd
->SetReadBuffer
= set_read_buffer
;
1861 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1862 tnl
->Driver
.RenderStart
= _swsetup_RenderStart
;
1863 tnl
->Driver
.RenderFinish
= _swsetup_RenderFinish
;
1864 tnl
->Driver
.BuildProjectedVertices
= _swsetup_BuildProjectedVertices
;
1865 tnl
->Driver
.RenderPrimitive
= _swsetup_RenderPrimitive
;
1866 tnl
->Driver
.PointsFunc
= _swsetup_Points
;
1867 tnl
->Driver
.LineFunc
= _swsetup_Line
;
1868 tnl
->Driver
.TriangleFunc
= _swsetup_Triangle
;
1869 tnl
->Driver
.QuadFunc
= _swsetup_Quad
;
1870 tnl
->Driver
.ResetLineStipple
= _swrast_ResetLineStipple
;
1871 tnl
->Driver
.RenderInterp
= _swsetup_RenderInterp
;
1872 tnl
->Driver
.RenderCopyPV
= _swsetup_RenderCopyPV
;
1873 tnl
->Driver
.RenderClippedLine
= _swsetup_RenderClippedLine
;
1874 tnl
->Driver
.RenderClippedPolygon
= _swsetup_RenderClippedPolygon
;
1877 _swrast_InvalidateState( ctx
, new_state
);
1878 _swsetup_InvalidateState( ctx
, new_state
);
1879 _ac_InvalidateState( ctx
, new_state
);
1880 _tnl_InvalidateState( ctx
, new_state
);