removed GL_ prefix from memory macros
[mesa.git] / src / mesa / drivers / osmesa / osmesa.c
1 /* $Id: osmesa.c,v 1.2 1999/10/13 18:43:46 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 /*
29 * Off-Screen Mesa rendering / Rendering into client memory space
30 */
31
32
33 #ifdef PC_HEADER
34 #include "all.h"
35 #else
36 #include <stdlib.h>
37 #include <string.h>
38 #include "GL/osmesa.h"
39 #include "context.h"
40 #include "depth.h"
41 #include "macros.h"
42 #include "matrix.h"
43 #include "types.h"
44 #include "vb.h"
45 #endif
46
47
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 */
60 GLint bshift, ashift;
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 */
65 };
66
67
68
69 #ifdef THREADS
70
71 #include "mthreads.h" /* Mesa platform independent threads interface */
72
73 static MesaTSD osmesa_ctx_tsd;
74
75 static void osmesa_ctx_thread_init() {
76 MesaInitTSD(&osmesa_ctx_tsd);
77 }
78
79 static OSMesaContext osmesa_get_thread_context( void ) {
80 return (OSMesaContext) MesaGetTSD(&osmesa_ctx_tsd);
81 }
82
83 static void osmesa_set_thread_context( OSMesaContext ctx ) {
84 MesaSetTSD(&osmesa_ctx_tsd, ctx, osmesa_ctx_thread_init);
85 }
86
87
88 #else
89 /* One current context for address space, all threads */
90 static OSMesaContext Current = NULL;
91 #endif
92
93
94
95 /* A forward declaration: */
96 static void osmesa_update_state( GLcontext *ctx );
97
98
99
100 /**********************************************************************/
101 /***** Public Functions *****/
102 /**********************************************************************/
103
104
105 /*
106 * Create an Off-Screen Mesa rendering context. The only attribute needed is
107 * an RGBA vs Color-Index mode flag.
108 *
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
113 */
114 OSMesaContext GLAPIENTRY OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
115 {
116 OSMesaContext osmesa;
117 GLint rshift, gshift, bshift, ashift;
118 GLint rind, gind, bind;
119 GLint indexBits, alphaBits;
120 GLboolean rgbmode;
121 GLboolean swalpha;
122 GLuint i4 = 1;
123 GLubyte *i1 = (GLubyte *) &i4;
124 GLint little_endian = *i1;
125
126 swalpha = GL_FALSE;
127 rind = gind = bind = 0;
128 if (format==OSMESA_COLOR_INDEX) {
129 indexBits = 8;
130 rshift = gshift = bshift = ashift = 0;
131 rgbmode = GL_FALSE;
132 }
133 else if (format==OSMESA_RGBA) {
134 indexBits = 0;
135 alphaBits = 8;
136 if (little_endian) {
137 rshift = 0;
138 gshift = 8;
139 bshift = 16;
140 ashift = 24;
141 }
142 else {
143 rshift = 24;
144 gshift = 16;
145 bshift = 8;
146 ashift = 0;
147 }
148 rgbmode = GL_TRUE;
149 }
150 else if (format==OSMESA_BGRA) {
151 indexBits = 0;
152 alphaBits = 8;
153 if (little_endian) {
154 ashift = 0;
155 rshift = 8;
156 gshift = 16;
157 bshift = 24;
158 }
159 else {
160 bshift = 24;
161 gshift = 16;
162 rshift = 8;
163 ashift = 0;
164 }
165 rgbmode = GL_TRUE;
166 }
167 else if (format==OSMESA_ARGB) {
168 indexBits = 0;
169 alphaBits = 8;
170 if (little_endian) {
171 bshift = 0;
172 gshift = 8;
173 rshift = 16;
174 ashift = 24;
175 }
176 else {
177 ashift = 24;
178 rshift = 16;
179 gshift = 8;
180 bshift = 0;
181 }
182 rgbmode = GL_TRUE;
183 }
184 else if (format==OSMESA_RGB) {
185 indexBits = 0;
186 alphaBits = 0;
187 bshift = 0;
188 gshift = 8;
189 rshift = 16;
190 ashift = 24;
191 bind = 2;
192 gind = 1;
193 rind = 0;
194 rgbmode = GL_TRUE;
195 swalpha = GL_TRUE;
196 }
197 else if (format==OSMESA_BGR) {
198 indexBits = 0;
199 alphaBits = 0;
200 bshift = 0;
201 gshift = 8;
202 rshift = 16;
203 ashift = 24;
204 bind = 0;
205 gind = 1;
206 rind = 2;
207 rgbmode = GL_TRUE;
208 swalpha = GL_TRUE;
209 }
210 else {
211 return NULL;
212 }
213
214
215 osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
216 if (osmesa) {
217 osmesa->gl_visual = gl_create_visual( rgbmode,
218 swalpha, /* software alpha */
219 GL_FALSE, /* double buffer */
220 GL_FALSE, /* stereo */
221 DEPTH_BITS,
222 STENCIL_BITS,
223 ACCUM_BITS,
224 indexBits,
225 8, 8, 8, alphaBits );
226 if (!osmesa->gl_visual) {
227 return NULL;
228 }
229
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 );
235 FREE(osmesa);
236 return NULL;
237 }
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 );
242 FREE(osmesa);
243 return NULL;
244 }
245 osmesa->format = format;
246 osmesa->buffer = NULL;
247 osmesa->width = 0;
248 osmesa->height = 0;
249 osmesa->pixel = 0;
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;
258 osmesa->rind = rind;
259 osmesa->gind = gind;
260 osmesa->bind = bind;
261 }
262 return osmesa;
263 }
264
265
266
267 /*
268 * Destroy an Off-Screen Mesa rendering context.
269 *
270 * Input: ctx - the context to destroy
271 */
272 void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx )
273 {
274 if (ctx) {
275 gl_destroy_visual( ctx->gl_visual );
276 gl_destroy_framebuffer( ctx->gl_buffer );
277 gl_destroy_context( ctx->gl_ctx );
278 FREE( ctx );
279 }
280 }
281
282
283
284 /*
285 * Recompute the values of the context's rowaddr array.
286 */
287 static void compute_row_addresses( OSMesaContext ctx )
288 {
289 GLint i;
290
291 if (ctx->yup) {
292 /* Y=0 is bottom line of window */
293 if (ctx->format==OSMESA_COLOR_INDEX) {
294 /* 1-byte CI mode */
295 GLubyte *origin = (GLubyte *) ctx->buffer;
296 for (i=0;i<MAX_HEIGHT;i++) {
297 ctx->rowaddr[i] = origin + i * ctx->rowlength;
298 }
299 }
300 else {
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));
306 }
307 } else {
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;
312 }
313 }
314 }
315 }
316 else {
317 /* Y=0 is top line of window */
318 if (ctx->format==OSMESA_COLOR_INDEX) {
319 /* 1-byte CI mode */
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;
323 }
324 }
325 else {
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));
331 }
332 } else {
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;
337 }
338 }
339 }
340 }
341 }
342
343
344 /*
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.
349 *
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).
353 *
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.
358 *
359 * If the context's viewport hasn't been initialized yet, it will now be
360 * initialized to (0,0,width,height).
361 *
362 * Input: ctx - the rendering context
363 * buffer - the image buffer memory
364 * type - data type for pixel components, only GL_UNSIGNED_BYTE
365 * supported now
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.
370 */
371 GLboolean GLAPIENTRY OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
372 GLsizei width, GLsizei height )
373 {
374 if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
375 || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
376 return GL_FALSE;
377 }
378
379 osmesa_update_state( ctx->gl_ctx );
380 gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
381
382 ctx->buffer = buffer;
383 ctx->width = width;
384 ctx->height = height;
385 if (ctx->userRowLength)
386 ctx->rowlength = ctx->userRowLength;
387 else
388 ctx->rowlength = width;
389
390 #ifdef THREADS
391 /* Set current context for the calling thread */
392 osmesa_set_thread_context(ctx);
393 #else
394 /* Set current context for the address space, all threads */
395 Current = ctx;
396 #endif
397
398 compute_row_addresses( ctx );
399
400 /* init viewport */
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;
406 }
407
408 return GL_TRUE;
409 }
410
411
412
413
414 OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void )
415 {
416 #ifdef THREADS
417 /* Return current handle for the calling thread */
418 return osmesa_get_thread_context();
419 #else
420 /* Return current handle for the address space, all threads */
421 return Current;
422 #endif
423 }
424
425
426
427 void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value )
428 {
429 OSMesaContext ctx = OSMesaGetCurrentContext();
430
431 switch (pname) {
432 case OSMESA_ROW_LENGTH:
433 if (value<0) {
434 gl_error( ctx->gl_ctx, GL_INVALID_VALUE,
435 "OSMesaPixelStore(value)" );
436 return;
437 }
438 ctx->userRowLength = value;
439 ctx->rowlength = value;
440 break;
441 case OSMESA_Y_UP:
442 ctx->yup = value ? GL_TRUE : GL_FALSE;
443 break;
444 default:
445 gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
446 return;
447 }
448
449 compute_row_addresses( ctx );
450 }
451
452
453 void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value )
454 {
455 OSMesaContext ctx = OSMesaGetCurrentContext();
456
457 switch (pname) {
458 case OSMESA_WIDTH:
459 *value = ctx->width;
460 return;
461 case OSMESA_HEIGHT:
462 *value = ctx->height;
463 return;
464 case OSMESA_FORMAT:
465 *value = ctx->format;
466 return;
467 case OSMESA_TYPE:
468 *value = GL_UNSIGNED_BYTE;
469 return;
470 case OSMESA_ROW_LENGTH:
471 *value = ctx->rowlength;
472 return;
473 case OSMESA_Y_UP:
474 *value = ctx->yup;
475 return;
476 default:
477 gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)" );
478 return;
479 }
480 }
481
482
483
484 /*
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.
491 */
492 GLboolean GLAPIENTRY OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
493 GLint *bytesPerValue, void **buffer )
494 {
495 if ((!c->gl_buffer) || (!c->gl_buffer->Depth)) {
496 *width = 0;
497 *height = 0;
498 *bytesPerValue = 0;
499 *buffer = 0;
500 return GL_FALSE;
501 }
502 else {
503 *width = c->gl_buffer->Width;
504 *height = c->gl_buffer->Height;
505 *bytesPerValue = sizeof(GLdepth);
506 *buffer = c->gl_buffer->Depth;
507 return GL_TRUE;
508 }
509 }
510
511
512
513
514 /**********************************************************************/
515 /*** Device Driver Functions ***/
516 /**********************************************************************/
517
518
519 /*
520 * Useful macros:
521 */
522 #define PACK_RGBA(R,G,B,A) ( ((R) << osmesa->rshift) \
523 | ((G) << osmesa->gshift) \
524 | ((B) << osmesa->bshift) \
525 | ((A) << osmesa->ashift) )
526
527 #define PACK_RGBA2(R,G,B,A) ( ((R) << rshift) \
528 | ((G) << gshift) \
529 | ((B) << bshift) \
530 | ((A) << ashift) )
531
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)
536
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))
540
541
542
543
544 static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
545 {
546 (void) ctx;
547 if (mode==GL_FRONT_LEFT) {
548 return GL_TRUE;
549 }
550 else {
551 return GL_FALSE;
552 }
553 }
554
555
556 static void clear_index( GLcontext *ctx, GLuint index )
557 {
558 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
559 osmesa->clearpixel = index;
560 }
561
562
563
564 static void clear_color( GLcontext *ctx,
565 GLubyte r, GLubyte g, GLubyte b, GLubyte a )
566 {
567 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
568 osmesa->clearpixel = PACK_RGBA( r, g, b, a );
569 }
570
571
572
573 static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
574 GLint x, GLint y, GLint width, GLint height )
575 {
576 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
577 if (mask & GL_COLOR_BUFFER_BIT) {
578 if (osmesa->format==OSMESA_COLOR_INDEX) {
579 if (all) {
580 /* Clear whole CI buffer */
581 MEMSET(osmesa->buffer, osmesa->clearpixel,
582 osmesa->rowlength * osmesa->height);
583 }
584 else {
585 /* Clear part of CI buffer */
586 GLint i, j;
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;
591 }
592 }
593 }
594 }
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;
602 if (all) {
603 GLuint i, n;
604 GLubyte *ptr3 = (GLubyte *) osmesa->buffer;
605 /* Clear whole RGB buffer */
606 n = osmesa->rowlength * osmesa->height;
607 for (i=0;i<n;i++) {
608 ptr3[rind] = rval;
609 ptr3[gind] = gval;
610 ptr3[bind] = bval;
611 ptr3 += 3;
612 }
613 }
614 else {
615 /* Clear part of RGB buffer */
616 GLint i, j;
617 for (i=0;i<height;i++) {
618 GLubyte *ptr3 = PIXELADDR3( x, (y+i) );
619 for (j=0;j<width;j++) {
620 ptr3[rind] = rval;
621 ptr3[gind] = gval;
622 ptr3[bind] = bval;
623 ptr3 += 3;
624 }
625 }
626 }
627 }
628 else {
629 if (all) {
630 /* Clear whole RGBA buffer */
631 GLuint i, n, *ptr4;
632 n = osmesa->rowlength * osmesa->height;
633 ptr4 = (GLuint *) osmesa->buffer;
634 for (i=0;i<n;i++) {
635 *ptr4++ = osmesa->clearpixel;
636 }
637 }
638 else {
639 /* Clear part of RGBA buffer */
640 GLint i, j;
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;
645 }
646 }
647 }
648 }
649 }
650 return mask & (~GL_COLOR_BUFFER_BIT);
651 }
652
653
654
655 static void set_index( GLcontext *ctx, GLuint index )
656 {
657 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
658 osmesa->pixel = index;
659 }
660
661
662
663 static void set_color( GLcontext *ctx,
664 GLubyte r, GLubyte g, GLubyte b, GLubyte a )
665 {
666 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
667 osmesa->pixel = PACK_RGBA( r, g, b, a );
668 }
669
670
671
672 static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
673 {
674 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
675 *width = osmesa->width;
676 *height = osmesa->height;
677 }
678
679
680 /**********************************************************************/
681 /***** Read/write spans/arrays of RGBA pixels *****/
682 /**********************************************************************/
683
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[] )
688 {
689 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
690 GLuint *ptr4 = PIXELADDR4( x, y );
691 GLuint i;
692 GLint rshift = osmesa->rshift;
693 GLint gshift = osmesa->gshift;
694 GLint bshift = osmesa->bshift;
695 GLint ashift = osmesa->ashift;
696 if (mask) {
697 for (i=0;i<n;i++,ptr4++) {
698 if (mask[i]) {
699 *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
700 }
701 }
702 }
703 else {
704 for (i=0;i<n;i++,ptr4++) {
705 *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
706 }
707 }
708 }
709
710
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[] )
716 {
717 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
718 GLuint *ptr4 = PIXELADDR4( x, y );
719 const GLuint *rgba4 = (const GLuint *) rgba;
720 GLuint i;
721 if (mask) {
722 for (i=0;i<n;i++) {
723 if (mask[i]) {
724 ptr4[i] = rgba4[i];
725 }
726 }
727 }
728 else {
729 MEMCPY( ptr4, rgba4, n * 4 );
730 }
731 }
732
733
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[] )
738 {
739 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
740 GLuint *ptr4 = PIXELADDR4( x, y );
741 GLuint i;
742 GLint rshift = osmesa->rshift;
743 GLint gshift = osmesa->gshift;
744 GLint bshift = osmesa->bshift;
745 GLint ashift = osmesa->ashift;
746 if (mask) {
747 for (i=0;i<n;i++,ptr4++) {
748 if (mask[i]) {
749 *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
750 }
751 }
752 }
753 else {
754 for (i=0;i<n;i++,ptr4++) {
755 *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
756 }
757 }
758 }
759
760
761
762 static void write_monocolor_span( const GLcontext *ctx,
763 GLuint n, GLint x, GLint y,
764 const GLubyte mask[] )
765 {
766 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
767 GLuint *ptr4 = PIXELADDR4(x,y);
768 GLuint i;
769 for (i=0;i<n;i++,ptr4++) {
770 if (mask[i]) {
771 *ptr4 = osmesa->pixel;
772 }
773 }
774 }
775
776
777
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[] )
781 {
782 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
783 GLuint i;
784 GLint rshift = osmesa->rshift;
785 GLint gshift = osmesa->gshift;
786 GLint bshift = osmesa->bshift;
787 GLint ashift = osmesa->ashift;
788 for (i=0;i<n;i++) {
789 if (mask[i]) {
790 GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
791 *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
792 }
793 }
794 }
795
796
797
798 static void write_monocolor_pixels( const GLcontext *ctx,
799 GLuint n, const GLint x[], const GLint y[],
800 const GLubyte mask[] )
801 {
802 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
803 GLuint i;
804 for (i=0;i<n;i++) {
805 if (mask[i]) {
806 GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
807 *ptr4 = osmesa->pixel;
808 }
809 }
810 }
811
812
813 static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
814 GLubyte rgba[][4] )
815 {
816 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
817 GLuint i;
818 GLuint *ptr4 = PIXELADDR4(x,y);
819 for (i=0;i<n;i++) {
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);
825 }
826 }
827
828
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,
832 GLubyte rgba[][4] )
833 {
834 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
835 GLuint *ptr4 = PIXELADDR4(x,y);
836 MEMCPY( rgba, ptr4, n * 4 * sizeof(GLubyte) );
837 }
838
839
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[] )
843 {
844 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
845 GLuint i;
846 for (i=0;i<n;i++) {
847 if (mask[i]) {
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);
854 }
855 }
856 }
857
858 /**********************************************************************/
859 /***** 3 byte RGB pixel support funcs *****/
860 /**********************************************************************/
861
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[] )
866 {
867 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
868 GLubyte *ptr3 = PIXELADDR3( x, y);
869 GLuint i;
870 GLint rind = osmesa->rind;
871 GLint gind = osmesa->gind;
872 GLint bind = osmesa->bind;
873 if (mask) {
874 for (i=0;i<n;i++,ptr3+=3) {
875 if (mask[i]) {
876 ptr3[rind] = rgba[i][RCOMP];
877 ptr3[gind] = rgba[i][GCOMP];
878 ptr3[bind] = rgba[i][BCOMP];
879 }
880 }
881 }
882 else {
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];
887 }
888 }
889 }
890
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[] )
895 {
896 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
897 GLubyte *ptr3 = PIXELADDR3( x, y);
898 GLuint i;
899 GLint rind = osmesa->rind;
900 GLint gind = osmesa->gind;
901 GLint bind = osmesa->bind;
902 if (mask) {
903 for (i=0;i<n;i++,ptr3+=3) {
904 if (mask[i]) {
905 ptr3[rind] = rgb[i][RCOMP];
906 ptr3[gind] = rgb[i][GCOMP];
907 ptr3[bind] = rgb[i][BCOMP];
908 }
909 }
910 }
911 else {
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];
916 }
917 }
918 }
919
920
921 static void write_monocolor_span3( const GLcontext *ctx,
922 GLuint n, GLint x, GLint y,
923 const GLubyte mask[] )
924 {
925 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
926
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;
933
934
935 GLubyte *ptr3 = PIXELADDR3( x, y);
936 GLuint i;
937 for (i=0;i<n;i++,ptr3+=3) {
938 if (mask[i]) {
939 ptr3[rind] = rval;
940 ptr3[gind] = gval;
941 ptr3[bind] = bval;
942 }
943 }
944 }
945
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[] )
949 {
950 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
951 GLuint i;
952 GLint rind = osmesa->rind;
953 GLint gind = osmesa->gind;
954 GLint bind = osmesa->bind;
955
956 for (i=0;i<n;i++) {
957 if (mask[i]) {
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];
962 }
963 }
964 }
965
966 static void write_monocolor_pixels3( const GLcontext *ctx,
967 GLuint n, const GLint x[], const GLint y[],
968 const GLubyte mask[] )
969 {
970 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
971 GLuint i;
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);
978 for (i=0;i<n;i++) {
979 if (mask[i]) {
980 GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
981 ptr3[rind] = rval;
982 ptr3[gind] = gval;
983 ptr3[bind] = bval;
984 }
985 }
986 }
987
988 static void read_rgba_span3( const GLcontext *ctx,
989 GLuint n, GLint x, GLint y,
990 GLubyte rgba[][4] )
991 {
992 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
993 GLuint i;
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];
1002 rgba[i][ACOMP] = 0;
1003 }
1004 }
1005
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[] )
1009 {
1010 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1011 GLuint i;
1012 GLint rind = osmesa->rind;
1013 GLint gind = osmesa->gind;
1014 GLint bind = osmesa->bind;
1015 for (i=0;i<n;i++) {
1016 if (mask[i]) {
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];
1021 rgba[i][ACOMP] = 0;
1022 }
1023 }
1024 }
1025
1026
1027 /**********************************************************************/
1028 /***** Read/write spans/arrays of CI pixels *****/
1029 /**********************************************************************/
1030
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[] )
1035 {
1036 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1037 GLubyte *ptr1 = PIXELADDR1(x,y);
1038 GLuint i;
1039 if (mask) {
1040 for (i=0;i<n;i++,ptr1++) {
1041 if (mask[i]) {
1042 *ptr1 = (GLubyte) index[i];
1043 }
1044 }
1045 }
1046 else {
1047 for (i=0;i<n;i++,ptr1++) {
1048 *ptr1 = (GLubyte) index[i];
1049 }
1050 }
1051 }
1052
1053
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[] )
1058 {
1059 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1060 GLubyte *ptr1 = PIXELADDR1(x,y);
1061 GLuint i;
1062 if (mask) {
1063 for (i=0;i<n;i++,ptr1++) {
1064 if (mask[i]) {
1065 *ptr1 = (GLubyte) index[i];
1066 }
1067 }
1068 }
1069 else {
1070 MEMCPY( ptr1, index, n );
1071 }
1072 }
1073
1074
1075 static void write_monoindex_span( const GLcontext *ctx,
1076 GLuint n, GLint x, GLint y,
1077 const GLubyte mask[] )
1078 {
1079 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1080 GLubyte *ptr1 = PIXELADDR1(x,y);
1081 GLuint i;
1082 for (i=0;i<n;i++,ptr1++) {
1083 if (mask[i]) {
1084 *ptr1 = (GLubyte) osmesa->pixel;
1085 }
1086 }
1087 }
1088
1089
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[] )
1093 {
1094 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1095 GLuint i;
1096 for (i=0;i<n;i++) {
1097 if (mask[i]) {
1098 GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
1099 *ptr1 = (GLubyte) index[i];
1100 }
1101 }
1102 }
1103
1104
1105 static void write_monoindex_pixels( const GLcontext *ctx,
1106 GLuint n, const GLint x[], const GLint y[],
1107 const GLubyte mask[] )
1108 {
1109 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1110 GLuint i;
1111 for (i=0;i<n;i++) {
1112 if (mask[i]) {
1113 GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
1114 *ptr1 = (GLubyte) osmesa->pixel;
1115 }
1116 }
1117 }
1118
1119
1120 static void read_index_span( const GLcontext *ctx,
1121 GLuint n, GLint x, GLint y, GLuint index[] )
1122 {
1123 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1124 GLuint i;
1125 GLubyte *ptr1 = PIXELADDR1(x,y);
1126 for (i=0;i<n;i++,ptr1++) {
1127 index[i] = (GLuint) *ptr1;
1128 }
1129 }
1130
1131
1132 static void read_index_pixels( const GLcontext *ctx,
1133 GLuint n, const GLint x[], const GLint y[],
1134 GLuint index[], const GLubyte mask[] )
1135 {
1136 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1137 GLuint i;
1138 for (i=0;i<n;i++) {
1139 if (mask[i] ) {
1140 GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
1141 index[i] = (GLuint) *ptr1;
1142 }
1143 }
1144 }
1145
1146
1147
1148 /**********************************************************************/
1149 /***** Optimized line rendering *****/
1150 /**********************************************************************/
1151
1152
1153 /*
1154 * Draw a flat-shaded, RGB line into an osmesa buffer.
1155 */
1156 static void flat_rgba_line( GLcontext *ctx,
1157 GLuint vert0, GLuint vert1, GLuint pvert )
1158 {
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] );
1162
1163 #define INTERP_XY 1
1164 #define CLIP_HACK 1
1165 #define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
1166
1167 #ifdef WIN32
1168 #include "..\linetemp.h"
1169 #else
1170 #include "linetemp.h"
1171 #endif
1172 }
1173
1174
1175 /*
1176 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1177 */
1178 static void flat_rgba_z_line( GLcontext *ctx,
1179 GLuint vert0, GLuint vert1, GLuint pvert )
1180 {
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] );
1184
1185 #define INTERP_XY 1
1186 #define INTERP_Z 1
1187 #define CLIP_HACK 1
1188 #define PLOT(X,Y) \
1189 if (Z < *zPtr) { \
1190 GLuint *ptr4 = PIXELADDR4(X,Y); \
1191 *ptr4 = pixel; \
1192 *zPtr = Z; \
1193 }
1194
1195 #ifdef WIN32
1196 #include "..\linetemp.h"
1197 #else
1198 #include "linetemp.h"
1199 #endif
1200 }
1201
1202
1203 /*
1204 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1205 */
1206 static void flat_blend_rgba_line( GLcontext *ctx,
1207 GLuint vert0, GLuint vert1, GLuint pvert )
1208 {
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;
1219
1220 #define INTERP_XY 1
1221 #define CLIP_HACK 1
1222 #define PLOT(X,Y) \
1223 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1224 GLuint pixel = 0; \
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);\
1228 *ptr4 = pixel; \
1229 }
1230
1231 #ifdef WIN32
1232 #include "..\linetemp.h"
1233 #else
1234 #include "linetemp.h"
1235 #endif
1236 }
1237
1238 /*
1239 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1240 */
1241 static void flat_blend_rgba_z_line( GLcontext *ctx,
1242 GLuint vert0, GLuint vert1, GLuint pvert )
1243 {
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;
1254
1255 #define INTERP_XY 1
1256 #define INTERP_Z 1
1257 #define CLIP_HACK 1
1258 #define PLOT(X,Y) \
1259 if (Z < *zPtr) { \
1260 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1261 GLuint pixel = 0; \
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);\
1265 *ptr4 = pixel; \
1266 } \
1267 }
1268
1269 #ifdef WIN32
1270 #include "..\linetemp.h"
1271 #else
1272 #include "linetemp.h"
1273 #endif
1274 }
1275
1276 /*
1277 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1278 */
1279 static void flat_blend_rgba_z_line_write( GLcontext *ctx,
1280 GLuint vert0, GLuint vert1, GLuint pvert )
1281 {
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;
1292
1293 #define INTERP_XY 1
1294 #define INTERP_Z 1
1295 #define CLIP_HACK 1
1296 #define PLOT(X,Y) \
1297 if (Z < *zPtr) { \
1298 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1299 GLuint pixel = 0; \
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);\
1303 *ptr4 = pixel; \
1304 } \
1305 *zPtr = Z; \
1306 }
1307
1308 #ifdef WIN32
1309 #include "..\linetemp.h"
1310 #else
1311 #include "linetemp.h"
1312 #endif
1313 }
1314
1315
1316 /*
1317 * Analyze context state to see if we can provide a fast line drawing
1318 * function, like those in lines.c. Otherwise, return NULL.
1319 */
1320 static line_func choose_line_function( GLcontext *ctx )
1321 {
1322 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1323
1324 if (ctx->Line.SmoothFlag) return NULL;
1325 if (ctx->Texture.Enabled) return NULL;
1326 if (ctx->Light.ShadeModel!=GL_FLAT) return NULL;
1327
1328 if (ctx->Line.Width==1.0F
1329 && ctx->Line.StippleFlag==GL_FALSE) {
1330
1331 if (ctx->RasterMask==DEPTH_BIT
1332 && ctx->Depth.Func==GL_LESS
1333 && ctx->Depth.Mask==GL_TRUE) {
1334 switch(osmesa->format) {
1335 case OSMESA_RGBA:
1336 case OSMESA_BGRA:
1337 case OSMESA_ARGB:
1338 return flat_rgba_z_line;
1339 default:
1340 return NULL;
1341 }
1342 }
1343
1344 if (ctx->RasterMask==0) {
1345 switch(osmesa->format) {
1346 case OSMESA_RGBA:
1347 case OSMESA_BGRA:
1348 case OSMESA_ARGB:
1349 return flat_rgba_line;
1350 default:
1351 return NULL;
1352 }
1353 }
1354
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) {
1364 case OSMESA_RGBA:
1365 case OSMESA_BGRA:
1366 case OSMESA_ARGB:
1367 return flat_blend_rgba_z_line_write;
1368 default:
1369 return NULL;
1370 }
1371 }
1372
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) {
1382 case OSMESA_RGBA:
1383 case OSMESA_BGRA:
1384 case OSMESA_ARGB:
1385 return flat_blend_rgba_z_line;
1386 default:
1387 return NULL;
1388 }
1389 }
1390
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) {
1398 case OSMESA_RGBA:
1399 case OSMESA_BGRA:
1400 case OSMESA_ARGB:
1401 return flat_blend_rgba_line;
1402 default:
1403 return NULL;
1404 }
1405 }
1406
1407 }
1408 return NULL;
1409 }
1410
1411
1412 /**********************************************************************/
1413 /***** Optimized triangle rendering *****/
1414 /**********************************************************************/
1415
1416
1417 /*
1418 * Smooth-shaded, z-less triangle, RGBA color.
1419 */
1420 static void smooth_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
1421 GLuint v2, GLuint pv )
1422 {
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;
1428 (void) pv;
1429 #define INTERP_Z 1
1430 #define INTERP_RGB 1
1431 #define INTERP_ALPHA 1
1432 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1433 { \
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) ); \
1441 zRow[i] = z; \
1442 } \
1443 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1444 ffz += fdzdx; \
1445 } \
1446 }
1447 #ifdef WIN32
1448 #include "..\tritemp.h"
1449 #else
1450 #include "tritemp.h"
1451 #endif
1452 }
1453
1454
1455
1456
1457 /*
1458 * Flat-shaded, z-less triangle, RGBA color.
1459 */
1460 static void flat_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
1461 GLuint v2, GLuint pv )
1462 {
1463 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1464 #define INTERP_Z 1
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);
1471
1472 #define INNER_LOOP( LEFT, RIGHT, Y ) \
1473 { \
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]) { \
1479 *img = pixel; \
1480 zRow[i] = z; \
1481 } \
1482 ffz += fdzdx; \
1483 } \
1484 }
1485 #ifdef WIN32
1486 #include "..\tritemp.h"
1487 #else
1488 #include "tritemp.h"
1489 #endif
1490 }
1491
1492
1493
1494 /*
1495 * Return pointer to an accelerated triangle function if possible.
1496 */
1497 static triangle_func choose_triangle_function( GLcontext *ctx )
1498 {
1499 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1500
1501 if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) return NULL;
1502
1503 if (ctx->Polygon.SmoothFlag) return NULL;
1504 if (ctx->Polygon.StippleFlag) return NULL;
1505 if (ctx->Texture.Enabled) return NULL;
1506
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;
1513 }
1514 else {
1515 return flat_rgba_z_triangle;
1516 }
1517 }
1518 return NULL;
1519 }
1520
1521
1522
1523 static const GLubyte *get_string( GLcontext *ctx, GLenum name )
1524 {
1525 (void) ctx;
1526 switch (name) {
1527 case GL_RENDERER:
1528 return (const GLubyte *) "Mesa OffScreen";
1529 default:
1530 return NULL;
1531 }
1532 }
1533
1534
1535 static void osmesa_update_state( GLcontext *ctx )
1536 {
1537 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1538
1539 ctx->Driver.GetString = get_string;
1540 ctx->Driver.UpdateState = osmesa_update_state;
1541
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;
1548
1549 ctx->Driver.GetBufferSize = buffer_size;
1550
1551 ctx->Driver.PointsFunc = NULL;
1552 ctx->Driver.LineFunc = choose_line_function( ctx );
1553 ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
1554
1555
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;
1566 }
1567 else {
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;
1572 else
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;
1581 else
1582 ctx->Driver.ReadRGBASpan = read_rgba_span;
1583 ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
1584 }
1585
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;
1594 }