source: trunk/src/opengl/mesa/osmesa.c@ 3079

Last change on this file since 3079 was 2970, checked in by sandervl, 25 years ago

Reapplied TLS fixes

File size: 46.7 KB
Line 
1/* $Id: osmesa.c,v 1.2 2000-03-02 13:27:30 sandervl 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#ifdef __WIN32OS2__
33#include <windows.h>
34#endif
35
36
37#ifdef PC_HEADER
38#include "all.h"
39#else
40#include <stdlib.h>
41#include <string.h>
42#include "types.h"
43#include "osmesa.h"
44#include "context.h"
45#include "depth.h"
46#include "macros.h"
47#include "matrix.h"
48#include "vb.h"
49#endif
50
51
52struct osmesa_context {
53 GLcontext *gl_ctx; /* The core GL/Mesa context */
54 GLvisual *gl_visual; /* Describes the buffers */
55 GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers */
56 GLenum format; /* either GL_RGBA or GL_COLOR_INDEX */
57 void *buffer; /* the image buffer */
58 GLint width, height; /* size of image buffer */
59 GLuint pixel; /* current color index or RGBA pixel value */
60 GLuint clearpixel; /* pixel for clearing the color buffer */
61 GLint rowlength; /* number of pixels per row */
62 GLint userRowLength; /* user-specified number of pixels per row */
63 GLint rshift, gshift; /* bit shifts for RGBA formats */
64 GLint bshift, ashift;
65 GLint rind, gind, bind; /* index offsets for RGBA formats */
66 void *rowaddr[MAX_HEIGHT]; /* address of first pixel in each image row */
67 GLboolean yup; /* TRUE -> Y increases upward */
68 /* FALSE -> Y increases downward */
69};
70
71
72
73#ifdef THREADS
74
75#include "mthreads.h" /* Mesa platform independent threads interface */
76
77static MesaTSD osmesa_ctx_tsd;
78
79static void osmesa_ctx_thread_init() {
80 MesaInitTSD(&osmesa_ctx_tsd);
81}
82
83static OSMesaContext osmesa_get_thread_context( void ) {
84#ifdef __WIN32OS2__
85 return (OSMesaContext) MesaGetTSD(&osmesa_ctx_tsd, osmesa_ctx_thread_init);
86#else
87 return (OSMesaContext) MesaGetTSD(&osmesa_ctx_tsd);
88#endif
89}
90
91static void osmesa_set_thread_context( OSMesaContext ctx ) {
92 MesaSetTSD(&osmesa_ctx_tsd, ctx, osmesa_ctx_thread_init);
93}
94
95
96#else
97 /* One current context for address space, all threads */
98 static OSMesaContext Current = NULL;
99#endif
100
101
102
103/* A forward declaration: */
104static void osmesa_update_state( GLcontext *ctx );
105
106
107
108/**********************************************************************/
109/***** Public Functions *****/
110/**********************************************************************/
111
112
113/*
114 * Create an Off-Screen Mesa rendering context. The only attribute needed is
115 * an RGBA vs Color-Index mode flag.
116 *
117 * Input: format - either GL_RGBA or GL_COLOR_INDEX
118 * sharelist - specifies another OSMesaContext with which to share
119 * display lists. NULL indicates no sharing.
120 * Return: an OSMesaContext or 0 if error
121 */
122OSMesaContext WIN32API OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
123{
124 OSMesaContext osmesa;
125 GLint rshift, gshift, bshift, ashift;
126 GLint rind, gind, bind;
127 GLint indexBits, alphaBits;
128 GLboolean rgbmode;
129 GLboolean swalpha;
130 GLuint i4 = 1;
131 GLubyte *i1 = (GLubyte *) &i4;
132 GLint little_endian = *i1;
133
134 swalpha = GL_FALSE;
135 rind = gind = bind = 0;
136 if (format==OSMESA_COLOR_INDEX) {
137 indexBits = 8;
138 rshift = gshift = bshift = ashift = 0;
139 rgbmode = GL_FALSE;
140 }
141 else if (format==OSMESA_RGBA) {
142 indexBits = 0;
143 alphaBits = 8;
144 if (little_endian) {
145 rshift = 0;
146 gshift = 8;
147 bshift = 16;
148 ashift = 24;
149 }
150 else {
151 rshift = 24;
152 gshift = 16;
153 bshift = 8;
154 ashift = 0;
155 }
156 rgbmode = GL_TRUE;
157 }
158 else if (format==OSMESA_BGRA) {
159 indexBits = 0;
160 alphaBits = 8;
161 if (little_endian) {
162 ashift = 0;
163 rshift = 8;
164 gshift = 16;
165 bshift = 24;
166 }
167 else {
168 bshift = 24;
169 gshift = 16;
170 rshift = 8;
171 ashift = 0;
172 }
173 rgbmode = GL_TRUE;
174 }
175 else if (format==OSMESA_ARGB) {
176 indexBits = 0;
177 alphaBits = 8;
178 if (little_endian) {
179 bshift = 0;
180 gshift = 8;
181 rshift = 16;
182 ashift = 24;
183 }
184 else {
185 ashift = 24;
186 rshift = 16;
187 gshift = 8;
188 bshift = 0;
189 }
190 rgbmode = GL_TRUE;
191 }
192 else if (format==OSMESA_RGB) {
193 indexBits = 0;
194 alphaBits = 0;
195 bshift = 0;
196 gshift = 8;
197 rshift = 16;
198 ashift = 24;
199 bind = 2;
200 gind = 1;
201 rind = 0;
202 rgbmode = GL_TRUE;
203 swalpha = GL_TRUE;
204 }
205 else if (format==OSMESA_BGR) {
206 indexBits = 0;
207 alphaBits = 0;
208 bshift = 0;
209 gshift = 8;
210 rshift = 16;
211 ashift = 24;
212 bind = 0;
213 gind = 1;
214 rind = 2;
215 rgbmode = GL_TRUE;
216 swalpha = GL_TRUE;
217 }
218 else {
219 return NULL;
220 }
221
222
223 osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
224 if (osmesa) {
225 osmesa->gl_visual = gl_create_visual( rgbmode,
226 swalpha, /* software alpha */
227 GL_FALSE, /* double buffer */
228 GL_FALSE, /* stereo */
229 DEPTH_BITS,
230 STENCIL_BITS,
231 ACCUM_BITS,
232 indexBits,
233 8, 8, 8, alphaBits );
234 if (!osmesa->gl_visual) {
235 return NULL;
236 }
237
238 osmesa->gl_ctx = gl_create_context( osmesa->gl_visual,
239 sharelist ? sharelist->gl_ctx : (GLcontext *) NULL,
240 (void *) osmesa, GL_TRUE );
241 if (!osmesa->gl_ctx) {
242 gl_destroy_visual( osmesa->gl_visual );
243 FREE(osmesa);
244 return NULL;
245 }
246 osmesa->gl_buffer = gl_create_framebuffer( osmesa->gl_visual );
247 if (!osmesa->gl_buffer) {
248 gl_destroy_visual( osmesa->gl_visual );
249 gl_destroy_context( osmesa->gl_ctx );
250 FREE(osmesa);
251 return NULL;
252 }
253 osmesa->format = format;
254 osmesa->buffer = NULL;
255 osmesa->width = 0;
256 osmesa->height = 0;
257 osmesa->pixel = 0;
258 osmesa->clearpixel = 0;
259 osmesa->userRowLength = 0;
260 osmesa->rowlength = 0;
261 osmesa->yup = GL_TRUE;
262 osmesa->rshift = rshift;
263 osmesa->gshift = gshift;
264 osmesa->bshift = bshift;
265 osmesa->ashift = ashift;
266 osmesa->rind = rind;
267 osmesa->gind = gind;
268 osmesa->bind = bind;
269 }
270 return osmesa;
271}
272
273
274
275/*
276 * Destroy an Off-Screen Mesa rendering context.
277 *
278 * Input: ctx - the context to destroy
279 */
280void WIN32API OSMesaDestroyContext( OSMesaContext ctx )
281{
282 if (ctx) {
283 gl_destroy_visual( ctx->gl_visual );
284 gl_destroy_framebuffer( ctx->gl_buffer );
285 gl_destroy_context( ctx->gl_ctx );
286 FREE( ctx );
287 }
288}
289
290
291
292/*
293 * Recompute the values of the context's rowaddr array.
294 */
295static void compute_row_addresses( OSMesaContext ctx )
296{
297 GLint i;
298
299 if (ctx->yup) {
300 /* Y=0 is bottom line of window */
301 if (ctx->format==OSMESA_COLOR_INDEX) {
302 /* 1-byte CI mode */
303 GLubyte *origin = (GLubyte *) ctx->buffer;
304 for (i=0;i<MAX_HEIGHT;i++) {
305 ctx->rowaddr[i] = origin + i * ctx->rowlength;
306 }
307 }
308 else {
309 if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
310 /* 3-byte RGB mode */
311 GLubyte *origin = (GLubyte *) ctx->buffer;
312 for (i=0;i<MAX_HEIGHT;i++) {
313 ctx->rowaddr[i] = origin + (i * (ctx->rowlength*3));
314 }
315 } else {
316 /* 4-byte RGBA mode */
317 GLuint *origin = (GLuint *) ctx->buffer;
318 for (i=0;i<MAX_HEIGHT;i++) {
319 ctx->rowaddr[i] = origin + i * ctx->rowlength;
320 }
321 }
322 }
323 }
324 else {
325 /* Y=0 is top line of window */
326 if (ctx->format==OSMESA_COLOR_INDEX) {
327 /* 1-byte CI 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;
331 }
332 }
333 else {
334 if ((ctx->format==OSMESA_RGB) || (ctx->format==OSMESA_BGR)) {
335 /* 3-byte RGB mode */
336 GLubyte *origin = (GLubyte *) ctx->buffer;
337 for (i=0;i<MAX_HEIGHT;i++) {
338 ctx->rowaddr[i] = origin + ((ctx->height-i-1) * (ctx->rowlength*3));
339 }
340 } else {
341 /* 4-byte RGBA mode */
342 GLuint *origin = (GLuint *) ctx->buffer;
343 for (i=0;i<MAX_HEIGHT;i++) {
344 ctx->rowaddr[i] = origin + (ctx->height-i-1) * ctx->rowlength;
345 }
346 }
347 }
348 }
349}
350
351
352/*
353 * Bind an OSMesaContext to an image buffer. The image buffer is just a
354 * block of memory which the client provides. Its size must be at least
355 * as large as width*height*sizeof(type). Its address should be a multiple
356 * of 4 if using RGBA mode.
357 *
358 * Image data is stored in the order of glDrawPixels: row-major order
359 * with the lower-left image pixel stored in the first array position
360 * (ie. bottom-to-top).
361 *
362 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the
363 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA
364 * value. If the context is in color indexed mode, each pixel will be
365 * stored as a 1-byte value.
366 *
367 * If the context's viewport hasn't been initialized yet, it will now be
368 * initialized to (0,0,width,height).
369 *
370 * Input: ctx - the rendering context
371 * buffer - the image buffer memory
372 * type - data type for pixel components, only GL_UNSIGNED_BYTE
373 * supported now
374 * width, height - size of image buffer in pixels, at least 1
375 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx,
376 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1,
377 * width>internal limit or height>internal limit.
378 */
379GLboolean WIN32API OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
380 GLsizei width, GLsizei height )
381{
382 if (!ctx || !buffer || type!=GL_UNSIGNED_BYTE
383 || width<1 || height<1 || width>MAX_WIDTH || height>MAX_HEIGHT) {
384 return GL_FALSE;
385 }
386
387 osmesa_update_state( ctx->gl_ctx );
388 gl_make_current( ctx->gl_ctx, ctx->gl_buffer );
389
390 ctx->buffer = buffer;
391 ctx->width = width;
392 ctx->height = height;
393 if (ctx->userRowLength)
394 ctx->rowlength = ctx->userRowLength;
395 else
396 ctx->rowlength = width;
397
398#ifdef THREADS
399 /* Set current context for the calling thread */
400 osmesa_set_thread_context(ctx);
401#else
402 /* Set current context for the address space, all threads */
403 Current = ctx;
404#endif
405
406 compute_row_addresses( ctx );
407
408 /* init viewport */
409 if (ctx->gl_ctx->Viewport.Width==0) {
410 /* initialize viewport and scissor box to buffer size */
411 gl_Viewport( ctx->gl_ctx, 0, 0, width, height );
412 ctx->gl_ctx->Scissor.Width = width;
413 ctx->gl_ctx->Scissor.Height = height;
414 }
415
416 return GL_TRUE;
417}
418
419
420
421
422OSMesaContext WIN32API OSMesaGetCurrentContext( void )
423{
424#ifdef THREADS
425 /* Return current handle for the calling thread */
426 return osmesa_get_thread_context();
427#else
428 /* Return current handle for the address space, all threads */
429 return Current;
430#endif
431}
432
433
434
435void WIN32API OSMesaPixelStore( GLint pname, GLint value )
436{
437 OSMesaContext ctx = OSMesaGetCurrentContext();
438
439 switch (pname) {
440 case OSMESA_ROW_LENGTH:
441 if (value<0) {
442 gl_error( ctx->gl_ctx, GL_INVALID_VALUE,
443 "OSMesaPixelStore(value)" );
444 return;
445 }
446 ctx->userRowLength = value;
447 ctx->rowlength = value;
448 break;
449 case OSMESA_Y_UP:
450 ctx->yup = value ? GL_TRUE : GL_FALSE;
451 break;
452 default:
453 gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
454 return;
455 }
456
457 compute_row_addresses( ctx );
458}
459
460
461void WIN32API OSMesaGetIntegerv( GLint pname, GLint *value )
462{
463 OSMesaContext ctx = OSMesaGetCurrentContext();
464
465 switch (pname) {
466 case OSMESA_WIDTH:
467 *value = ctx->width;
468 return;
469 case OSMESA_HEIGHT:
470 *value = ctx->height;
471 return;
472 case OSMESA_FORMAT:
473 *value = ctx->format;
474 return;
475 case OSMESA_TYPE:
476 *value = GL_UNSIGNED_BYTE;
477 return;
478 case OSMESA_ROW_LENGTH:
479 *value = ctx->rowlength;
480 return;
481 case OSMESA_Y_UP:
482 *value = ctx->yup;
483 return;
484 default:
485 gl_error( ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)" );
486 return;
487 }
488}
489
490
491
492/*
493 * Return the depth buffer associated with an OSMesa context.
494 * Input: c - the OSMesa context
495 * Output: width, height - size of buffer in pixels
496 * bytesPerValue - bytes per depth value (2 or 4)
497 * buffer - pointer to depth buffer values
498 * Return: GL_TRUE or GL_FALSE to indicate success or failure.
499 */
500GLboolean WIN32API OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
501 GLint *bytesPerValue, void **buffer )
502{
503 if ((!c->gl_buffer) || (!c->gl_buffer->Depth)) {
504 *width = 0;
505 *height = 0;
506 *bytesPerValue = 0;
507 *buffer = 0;
508 return GL_FALSE;
509 }
510 else {
511 *width = c->gl_buffer->Width;
512 *height = c->gl_buffer->Height;
513 *bytesPerValue = sizeof(GLdepth);
514 *buffer = c->gl_buffer->Depth;
515 return GL_TRUE;
516 }
517}
518
519
520
521
522/**********************************************************************/
523/*** Device Driver Functions ***/
524/**********************************************************************/
525
526
527/*
528 * Useful macros:
529 */
530#define PACK_RGBA(R,G,B,A) ( ((R) << osmesa->rshift) \
531 | ((G) << osmesa->gshift) \
532 | ((B) << osmesa->bshift) \
533 | ((A) << osmesa->ashift) )
534
535#define PACK_RGBA2(R,G,B,A) ( ((R) << rshift) \
536 | ((G) << gshift) \
537 | ((B) << bshift) \
538 | ((A) << ashift) )
539
540#define UNPACK_RED(P) (((P) >> osmesa->rshift) & 0xff)
541#define UNPACK_GREEN(P) (((P) >> osmesa->gshift) & 0xff)
542#define UNPACK_BLUE(P) (((P) >> osmesa->bshift) & 0xff)
543#define UNPACK_ALPHA(P) (((P) >> osmesa->ashift) & 0xff)
544
545#define PIXELADDR1(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + (X))
546#define PIXELADDR3(X,Y) ((GLubyte *) osmesa->rowaddr[Y] + ((X)*3))
547#define PIXELADDR4(X,Y) ((GLuint *) osmesa->rowaddr[Y] + (X))
548
549
550
551
552static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
553{
554 (void) ctx;
555 if (mode==GL_FRONT_LEFT) {
556 return GL_TRUE;
557 }
558 else {
559 return GL_FALSE;
560 }
561}
562
563
564static void clear_index( GLcontext *ctx, GLuint index )
565{
566 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
567 osmesa->clearpixel = index;
568}
569
570
571
572static void clear_color( GLcontext *ctx,
573 GLubyte r, GLubyte g, GLubyte b, GLubyte a )
574{
575 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
576 osmesa->clearpixel = PACK_RGBA( r, g, b, a );
577}
578
579
580
581static GLbitfield clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
582 GLint x, GLint y, GLint width, GLint height )
583{
584 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
585 if (mask & GL_COLOR_BUFFER_BIT) {
586 if (osmesa->format==OSMESA_COLOR_INDEX) {
587 if (all) {
588 /* Clear whole CI buffer */
589 MEMSET(osmesa->buffer, osmesa->clearpixel,
590 osmesa->rowlength * osmesa->height);
591 }
592 else {
593 /* Clear part of CI buffer */
594 GLint i, j;
595 for (i=0;i<height;i++) {
596 GLubyte *ptr1 = PIXELADDR1( x, (y+i) );
597 for (j=0;j<width;j++) {
598 *ptr1++ = osmesa->clearpixel;
599 }
600 }
601 }
602 }
603 else if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) {
604 GLubyte rval = UNPACK_RED(osmesa->clearpixel);
605 GLubyte gval = UNPACK_GREEN(osmesa->clearpixel);
606 GLubyte bval = UNPACK_BLUE(osmesa->clearpixel);
607 GLint rind = osmesa->rind;
608 GLint gind = osmesa->gind;
609 GLint bind = osmesa->bind;
610 if (all) {
611 GLuint i, n;
612 GLubyte *ptr3 = (GLubyte *) osmesa->buffer;
613 /* Clear whole RGB buffer */
614 n = osmesa->rowlength * osmesa->height;
615 for (i=0;i<n;i++) {
616 ptr3[rind] = rval;
617 ptr3[gind] = gval;
618 ptr3[bind] = bval;
619 ptr3 += 3;
620 }
621 }
622 else {
623 /* Clear part of RGB buffer */
624 GLint i, j;
625 for (i=0;i<height;i++) {
626 GLubyte *ptr3 = PIXELADDR3( x, (y+i) );
627 for (j=0;j<width;j++) {
628 ptr3[rind] = rval;
629 ptr3[gind] = gval;
630 ptr3[bind] = bval;
631 ptr3 += 3;
632 }
633 }
634 }
635 }
636 else {
637 if (all) {
638 /* Clear whole RGBA buffer */
639 GLuint i, n, *ptr4;
640 n = osmesa->rowlength * osmesa->height;
641 ptr4 = (GLuint *) osmesa->buffer;
642 for (i=0;i<n;i++) {
643 *ptr4++ = osmesa->clearpixel;
644 }
645 }
646 else {
647 /* Clear part of RGBA buffer */
648 GLint i, j;
649 for (i=0;i<height;i++) {
650 GLuint *ptr4 = PIXELADDR4( x, (y+i) );
651 for (j=0;j<width;j++) {
652 *ptr4++ = osmesa->clearpixel;
653 }
654 }
655 }
656 }
657 }
658 return mask & (~GL_COLOR_BUFFER_BIT);
659}
660
661
662
663static void set_index( GLcontext *ctx, GLuint index )
664{
665 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
666 osmesa->pixel = index;
667}
668
669
670
671static void set_color( GLcontext *ctx,
672 GLubyte r, GLubyte g, GLubyte b, GLubyte a )
673{
674 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
675 osmesa->pixel = PACK_RGBA( r, g, b, a );
676}
677
678
679
680static void buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
681{
682 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
683 *width = osmesa->width;
684 *height = osmesa->height;
685}
686
687
688/**********************************************************************/
689/***** Read/write spans/arrays of RGBA pixels *****/
690/**********************************************************************/
691
692/* Write RGBA pixels to an RGBA (or permuted) buffer. */
693static void write_rgba_span( const GLcontext *ctx,
694 GLuint n, GLint x, GLint y,
695 CONST GLubyte rgba[][4], const GLubyte mask[] )
696{
697 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
698 GLuint *ptr4 = PIXELADDR4( x, y );
699 GLuint i;
700 GLint rshift = osmesa->rshift;
701 GLint gshift = osmesa->gshift;
702 GLint bshift = osmesa->bshift;
703 GLint ashift = osmesa->ashift;
704 if (mask) {
705 for (i=0;i<n;i++,ptr4++) {
706 if (mask[i]) {
707 *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
708 }
709 }
710 }
711 else {
712 for (i=0;i<n;i++,ptr4++) {
713 *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
714 }
715 }
716}
717
718
719/* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */
720static void write_rgba_span_rgba( const GLcontext *ctx,
721 GLuint n, GLint x, GLint y,
722 CONST GLubyte rgba[][4],
723 const GLubyte mask[] )
724{
725 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
726 GLuint *ptr4 = PIXELADDR4( x, y );
727 const GLuint *rgba4 = (const GLuint *) rgba;
728 GLuint i;
729 if (mask) {
730 for (i=0;i<n;i++) {
731 if (mask[i]) {
732 ptr4[i] = rgba4[i];
733 }
734 }
735 }
736 else {
737 MEMCPY( ptr4, rgba4, n * 4 );
738 }
739}
740
741
742/* Write RGB pixels to an RGBA (or permuted) buffer. */
743static void write_rgb_span( const GLcontext *ctx,
744 GLuint n, GLint x, GLint y,
745 CONST GLubyte rgb[][3], const GLubyte mask[] )
746{
747 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
748 GLuint *ptr4 = PIXELADDR4( x, y );
749 GLuint i;
750 GLint rshift = osmesa->rshift;
751 GLint gshift = osmesa->gshift;
752 GLint bshift = osmesa->bshift;
753 GLint ashift = osmesa->ashift;
754 if (mask) {
755 for (i=0;i<n;i++,ptr4++) {
756 if (mask[i]) {
757 *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255 );
758 }
759 }
760 }
761 else {
762 for (i=0;i<n;i++,ptr4++) {
763 *ptr4 = PACK_RGBA2( rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], 255);
764 }
765 }
766}
767
768
769
770static void write_monocolor_span( const GLcontext *ctx,
771 GLuint n, GLint x, GLint y,
772 const GLubyte mask[] )
773{
774 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
775 GLuint *ptr4 = PIXELADDR4(x,y);
776 GLuint i;
777 for (i=0;i<n;i++,ptr4++) {
778 if (mask[i]) {
779 *ptr4 = osmesa->pixel;
780 }
781 }
782}
783
784
785
786static void write_rgba_pixels( const GLcontext *ctx,
787 GLuint n, const GLint x[], const GLint y[],
788 CONST GLubyte rgba[][4], const GLubyte mask[] )
789{
790 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
791 GLuint i;
792 GLint rshift = osmesa->rshift;
793 GLint gshift = osmesa->gshift;
794 GLint bshift = osmesa->bshift;
795 GLint ashift = osmesa->ashift;
796 for (i=0;i<n;i++) {
797 if (mask[i]) {
798 GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
799 *ptr4 = PACK_RGBA2( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], rgba[i][ACOMP] );
800 }
801 }
802}
803
804
805
806static void write_monocolor_pixels( const GLcontext *ctx,
807 GLuint n, const GLint x[], const GLint y[],
808 const GLubyte mask[] )
809{
810 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
811 GLuint i;
812 for (i=0;i<n;i++) {
813 if (mask[i]) {
814 GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
815 *ptr4 = osmesa->pixel;
816 }
817 }
818}
819
820
821static void read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y,
822 GLubyte rgba[][4] )
823{
824 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
825 GLuint i;
826 GLuint *ptr4 = PIXELADDR4(x,y);
827 for (i=0;i<n;i++) {
828 GLuint pixel = *ptr4++;
829 rgba[i][RCOMP] = UNPACK_RED(pixel);
830 rgba[i][GCOMP] = UNPACK_GREEN(pixel);
831 rgba[i][BCOMP] = UNPACK_BLUE(pixel);
832 rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
833 }
834}
835
836
837/* Read RGBA pixels from an RGBA buffer */
838static void read_rgba_span_rgba( const GLcontext *ctx,
839 GLuint n, GLint x, GLint y,
840 GLubyte rgba[][4] )
841{
842 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
843 GLuint *ptr4 = PIXELADDR4(x,y);
844 MEMCPY( rgba, ptr4, n * 4 * sizeof(GLubyte) );
845}
846
847
848static void read_rgba_pixels( const GLcontext *ctx,
849 GLuint n, const GLint x[], const GLint y[],
850 GLubyte rgba[][4], const GLubyte mask[] )
851{
852 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
853 GLuint i;
854 for (i=0;i<n;i++) {
855 if (mask[i]) {
856 GLuint *ptr4 = PIXELADDR4(x[i],y[i]);
857 GLuint pixel = *ptr4;
858 rgba[i][RCOMP] = UNPACK_RED(pixel);
859 rgba[i][GCOMP] = UNPACK_GREEN(pixel);
860 rgba[i][BCOMP] = UNPACK_BLUE(pixel);
861 rgba[i][ACOMP] = UNPACK_ALPHA(pixel);
862 }
863 }
864}
865
866/**********************************************************************/
867/***** 3 byte RGB pixel support funcs *****/
868/**********************************************************************/
869
870/* Write RGBA pixels to an RGB or BGR buffer. */
871static void write_rgba_span3( const GLcontext *ctx,
872 GLuint n, GLint x, GLint y,
873 CONST GLubyte rgba[][4], const GLubyte mask[] )
874{
875 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
876 GLubyte *ptr3 = PIXELADDR3( x, y);
877 GLuint i;
878 GLint rind = osmesa->rind;
879 GLint gind = osmesa->gind;
880 GLint bind = osmesa->bind;
881 if (mask) {
882 for (i=0;i<n;i++,ptr3+=3) {
883 if (mask[i]) {
884 ptr3[rind] = rgba[i][RCOMP];
885 ptr3[gind] = rgba[i][GCOMP];
886 ptr3[bind] = rgba[i][BCOMP];
887 }
888 }
889 }
890 else {
891 for (i=0;i<n;i++,ptr3+=3) {
892 ptr3[rind] = rgba[i][RCOMP];
893 ptr3[gind] = rgba[i][GCOMP];
894 ptr3[bind] = rgba[i][BCOMP];
895 }
896 }
897}
898
899/* Write RGB pixels to an RGB or BGR buffer. */
900static void write_rgb_span3( const GLcontext *ctx,
901 GLuint n, GLint x, GLint y,
902 CONST GLubyte rgb[][3], const GLubyte mask[] )
903{
904 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
905 GLubyte *ptr3 = PIXELADDR3( x, y);
906 GLuint i;
907 GLint rind = osmesa->rind;
908 GLint gind = osmesa->gind;
909 GLint bind = osmesa->bind;
910 if (mask) {
911 for (i=0;i<n;i++,ptr3+=3) {
912 if (mask[i]) {
913 ptr3[rind] = rgb[i][RCOMP];
914 ptr3[gind] = rgb[i][GCOMP];
915 ptr3[bind] = rgb[i][BCOMP];
916 }
917 }
918 }
919 else {
920 for (i=0;i<n;i++,ptr3+=3) {
921 ptr3[rind] = rgb[i][RCOMP];
922 ptr3[gind] = rgb[i][GCOMP];
923 ptr3[bind] = rgb[i][BCOMP];
924 }
925 }
926}
927
928
929static void write_monocolor_span3( const GLcontext *ctx,
930 GLuint n, GLint x, GLint y,
931 const GLubyte mask[] )
932{
933 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
934
935 GLubyte rval = UNPACK_RED(osmesa->pixel);
936 GLubyte gval = UNPACK_GREEN(osmesa->pixel);
937 GLubyte bval = UNPACK_BLUE(osmesa->pixel);
938 GLint rind = osmesa->rind;
939 GLint gind = osmesa->gind;
940 GLint bind = osmesa->bind;
941
942
943 GLubyte *ptr3 = PIXELADDR3( x, y);
944 GLuint i;
945 for (i=0;i<n;i++,ptr3+=3) {
946 if (mask[i]) {
947 ptr3[rind] = rval;
948 ptr3[gind] = gval;
949 ptr3[bind] = bval;
950 }
951 }
952}
953
954static void write_rgba_pixels3( const GLcontext *ctx,
955 GLuint n, const GLint x[], const GLint y[],
956 CONST GLubyte rgba[][4], const GLubyte mask[] )
957{
958 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
959 GLuint i;
960 GLint rind = osmesa->rind;
961 GLint gind = osmesa->gind;
962 GLint bind = osmesa->bind;
963
964 for (i=0;i<n;i++) {
965 if (mask[i]) {
966 GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
967 ptr3[rind] = rgba[i][RCOMP];
968 ptr3[gind] = rgba[i][GCOMP];
969 ptr3[bind] = rgba[i][BCOMP];
970 }
971 }
972}
973
974static void write_monocolor_pixels3( const GLcontext *ctx,
975 GLuint n, const GLint x[], const GLint y[],
976 const GLubyte mask[] )
977{
978 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
979 GLuint i;
980 GLint rind = osmesa->rind;
981 GLint gind = osmesa->gind;
982 GLint bind = osmesa->bind;
983 GLubyte rval = UNPACK_RED(osmesa->pixel);
984 GLubyte gval = UNPACK_GREEN(osmesa->pixel);
985 GLubyte bval = UNPACK_BLUE(osmesa->pixel);
986 for (i=0;i<n;i++) {
987 if (mask[i]) {
988 GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
989 ptr3[rind] = rval;
990 ptr3[gind] = gval;
991 ptr3[bind] = bval;
992 }
993 }
994}
995
996static void read_rgba_span3( const GLcontext *ctx,
997 GLuint n, GLint x, GLint y,
998 GLubyte rgba[][4] )
999{
1000 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1001 GLuint i;
1002 GLint rind = osmesa->rind;
1003 GLint gind = osmesa->gind;
1004 GLint bind = osmesa->bind;
1005 GLubyte *ptr3 = PIXELADDR3( x, y);
1006 for (i=0;i<n;i++,ptr3+=3) {
1007 rgba[i][RCOMP] = ptr3[rind];
1008 rgba[i][GCOMP] = ptr3[gind];
1009 rgba[i][BCOMP] = ptr3[bind];
1010 rgba[i][ACOMP] = 0;
1011 }
1012}
1013
1014static void read_rgba_pixels3( const GLcontext *ctx,
1015 GLuint n, const GLint x[], const GLint y[],
1016 GLubyte rgba[][4], const GLubyte mask[] )
1017{
1018 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1019 GLuint i;
1020 GLint rind = osmesa->rind;
1021 GLint gind = osmesa->gind;
1022 GLint bind = osmesa->bind;
1023 for (i=0;i<n;i++) {
1024 if (mask[i]) {
1025 GLubyte *ptr3 = PIXELADDR3(x[i],y[i]);
1026 rgba[i][RCOMP] = ptr3[rind];
1027 rgba[i][GCOMP] = ptr3[gind];
1028 rgba[i][BCOMP] = ptr3[bind];
1029 rgba[i][ACOMP] = 0;
1030 }
1031 }
1032}
1033
1034
1035/**********************************************************************/
1036/***** Read/write spans/arrays of CI pixels *****/
1037/**********************************************************************/
1038
1039/* Write 32-bit color index to buffer */
1040static void write_index32_span( const GLcontext *ctx,
1041 GLuint n, GLint x, GLint y,
1042 const GLuint index[], const GLubyte mask[] )
1043{
1044 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1045 GLubyte *ptr1 = PIXELADDR1(x,y);
1046 GLuint i;
1047 if (mask) {
1048 for (i=0;i<n;i++,ptr1++) {
1049 if (mask[i]) {
1050 *ptr1 = (GLubyte) index[i];
1051 }
1052 }
1053 }
1054 else {
1055 for (i=0;i<n;i++,ptr1++) {
1056 *ptr1 = (GLubyte) index[i];
1057 }
1058 }
1059}
1060
1061
1062/* Write 8-bit color index to buffer */
1063static void write_index8_span( const GLcontext *ctx,
1064 GLuint n, GLint x, GLint y,
1065 const GLubyte index[], const GLubyte mask[] )
1066{
1067 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1068 GLubyte *ptr1 = PIXELADDR1(x,y);
1069 GLuint i;
1070 if (mask) {
1071 for (i=0;i<n;i++,ptr1++) {
1072 if (mask[i]) {
1073 *ptr1 = (GLubyte) index[i];
1074 }
1075 }
1076 }
1077 else {
1078 MEMCPY( ptr1, index, n );
1079 }
1080}
1081
1082
1083static void write_monoindex_span( const GLcontext *ctx,
1084 GLuint n, GLint x, GLint y,
1085 const GLubyte mask[] )
1086{
1087 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1088 GLubyte *ptr1 = PIXELADDR1(x,y);
1089 GLuint i;
1090 for (i=0;i<n;i++,ptr1++) {
1091 if (mask[i]) {
1092 *ptr1 = (GLubyte) osmesa->pixel;
1093 }
1094 }
1095}
1096
1097
1098static void write_index_pixels( const GLcontext *ctx,
1099 GLuint n, const GLint x[], const GLint y[],
1100 const GLuint index[], const GLubyte mask[] )
1101{
1102 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1103 GLuint i;
1104 for (i=0;i<n;i++) {
1105 if (mask[i]) {
1106 GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
1107 *ptr1 = (GLubyte) index[i];
1108 }
1109 }
1110}
1111
1112
1113static void write_monoindex_pixels( const GLcontext *ctx,
1114 GLuint n, const GLint x[], const GLint y[],
1115 const GLubyte mask[] )
1116{
1117 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1118 GLuint i;
1119 for (i=0;i<n;i++) {
1120 if (mask[i]) {
1121 GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
1122 *ptr1 = (GLubyte) osmesa->pixel;
1123 }
1124 }
1125}
1126
1127
1128static void read_index_span( const GLcontext *ctx,
1129 GLuint n, GLint x, GLint y, GLuint index[] )
1130{
1131 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1132 GLuint i;
1133 GLubyte *ptr1 = PIXELADDR1(x,y);
1134 for (i=0;i<n;i++,ptr1++) {
1135 index[i] = (GLuint) *ptr1;
1136 }
1137}
1138
1139
1140static void read_index_pixels( const GLcontext *ctx,
1141 GLuint n, const GLint x[], const GLint y[],
1142 GLuint index[], const GLubyte mask[] )
1143{
1144 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1145 GLuint i;
1146 for (i=0;i<n;i++) {
1147 if (mask[i] ) {
1148 GLubyte *ptr1 = PIXELADDR1(x[i],y[i]);
1149 index[i] = (GLuint) *ptr1;
1150 }
1151 }
1152}
1153
1154
1155
1156/**********************************************************************/
1157/***** Optimized line rendering *****/
1158/**********************************************************************/
1159
1160
1161/*
1162 * Draw a flat-shaded, RGB line into an osmesa buffer.
1163 */
1164static void flat_rgba_line( GLcontext *ctx,
1165 GLuint vert0, GLuint vert1, GLuint pvert )
1166{
1167 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1168 GLubyte *color = ctx->VB->ColorPtr->data[pvert];
1169 unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
1170
1171#define INTERP_XY 1
1172#define CLIP_HACK 1
1173#define PLOT(X,Y) { GLuint *ptr4 = PIXELADDR4(X,Y); *ptr4 = pixel; }
1174
1175#ifdef WIN32
1176#include "..\linetemp.h"
1177#else
1178#include "linetemp.h"
1179#endif
1180}
1181
1182
1183/*
1184 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
1185 */
1186static void flat_rgba_z_line( GLcontext *ctx,
1187 GLuint vert0, GLuint vert1, GLuint pvert )
1188{
1189 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1190 GLubyte *color = ctx->VB->ColorPtr->data[pvert];
1191 unsigned long pixel = PACK_RGBA( color[0], color[1], color[2], color[3] );
1192
1193#define INTERP_XY 1
1194#define INTERP_Z 1
1195#define CLIP_HACK 1
1196#define PLOT(X,Y) \
1197 if (Z < *zPtr) { \
1198 GLuint *ptr4 = PIXELADDR4(X,Y); \
1199 *ptr4 = pixel; \
1200 *zPtr = Z; \
1201 }
1202
1203#ifdef WIN32
1204#include "..\linetemp.h"
1205#else
1206#include "linetemp.h"
1207#endif
1208}
1209
1210
1211/*
1212 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer.
1213 */
1214static void flat_blend_rgba_line( GLcontext *ctx,
1215 GLuint vert0, GLuint vert1, GLuint pvert )
1216{
1217 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1218 struct vertex_buffer *VB = ctx->VB;
1219 GLint rshift = osmesa->rshift;
1220 GLint gshift = osmesa->gshift;
1221 GLint bshift = osmesa->bshift;
1222 GLint avalue = VB->ColorPtr->data[pvert][3];
1223 GLint msavalue = 255 - avalue;
1224 GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
1225 GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
1226 GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
1227
1228#define INTERP_XY 1
1229#define CLIP_HACK 1
1230#define PLOT(X,Y) \
1231 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1232 GLuint pixel = 0; \
1233 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1234 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1235 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1236 *ptr4 = pixel; \
1237 }
1238
1239#ifdef WIN32
1240#include "..\linetemp.h"
1241#else
1242#include "linetemp.h"
1243#endif
1244}
1245
1246/*
1247 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1248 */
1249static void flat_blend_rgba_z_line( GLcontext *ctx,
1250 GLuint vert0, GLuint vert1, GLuint pvert )
1251{
1252 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1253 struct vertex_buffer *VB = ctx->VB;
1254 GLint rshift = osmesa->rshift;
1255 GLint gshift = osmesa->gshift;
1256 GLint bshift = osmesa->bshift;
1257 GLint avalue = VB->ColorPtr->data[pvert][3];
1258 GLint msavalue = 256 - avalue;
1259 GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
1260 GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
1261 GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
1262
1263#define INTERP_XY 1
1264#define INTERP_Z 1
1265#define CLIP_HACK 1
1266#define PLOT(X,Y) \
1267 if (Z < *zPtr) { \
1268 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1269 GLuint pixel = 0; \
1270 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1271 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1272 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1273 *ptr4 = pixel; \
1274 } \
1275 }
1276
1277#ifdef WIN32
1278#include "..\linetemp.h"
1279#else
1280#include "linetemp.h"
1281#endif
1282}
1283
1284/*
1285 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer.
1286 */
1287static void flat_blend_rgba_z_line_write( GLcontext *ctx,
1288 GLuint vert0, GLuint vert1, GLuint pvert )
1289{
1290 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1291 struct vertex_buffer *VB = ctx->VB;
1292 GLint rshift = osmesa->rshift;
1293 GLint gshift = osmesa->gshift;
1294 GLint bshift = osmesa->bshift;
1295 GLint avalue = VB->ColorPtr->data[pvert][3];
1296 GLint msavalue = 256 - avalue;
1297 GLint rvalue = VB->ColorPtr->data[pvert][0]*avalue;
1298 GLint gvalue = VB->ColorPtr->data[pvert][1]*avalue;
1299 GLint bvalue = VB->ColorPtr->data[pvert][2]*avalue;
1300
1301#define INTERP_XY 1
1302#define INTERP_Z 1
1303#define CLIP_HACK 1
1304#define PLOT(X,Y) \
1305 if (Z < *zPtr) { \
1306 { GLuint *ptr4 = PIXELADDR4(X,Y); \
1307 GLuint pixel = 0; \
1308 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\
1309 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\
1310 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\
1311 *ptr4 = pixel; \
1312 } \
1313 *zPtr = Z; \
1314 }
1315
1316#ifdef WIN32
1317#include "..\linetemp.h"
1318#else
1319#include "linetemp.h"
1320#endif
1321}
1322
1323
1324/*
1325 * Analyze context state to see if we can provide a fast line drawing
1326 * function, like those in lines.c. Otherwise, return NULL.
1327 */
1328static line_func choose_line_function( GLcontext *ctx )
1329{
1330 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1331
1332 if (ctx->Line.SmoothFlag) return NULL;
1333 if (ctx->Texture.Enabled) return NULL;
1334 if (ctx->Light.ShadeModel!=GL_FLAT) return NULL;
1335
1336 if (ctx->Line.Width==1.0F
1337 && ctx->Line.StippleFlag==GL_FALSE) {
1338
1339 if (ctx->RasterMask==DEPTH_BIT
1340 && ctx->Depth.Func==GL_LESS
1341 && ctx->Depth.Mask==GL_TRUE) {
1342 switch(osmesa->format) {
1343 case OSMESA_RGBA:
1344 case OSMESA_BGRA:
1345 case OSMESA_ARGB:
1346 return flat_rgba_z_line;
1347 default:
1348 return NULL;
1349 }
1350 }
1351
1352 if (ctx->RasterMask==0) {
1353 switch(osmesa->format) {
1354 case OSMESA_RGBA:
1355 case OSMESA_BGRA:
1356 case OSMESA_ARGB:
1357 return flat_rgba_line;
1358 default:
1359 return NULL;
1360 }
1361 }
1362
1363 if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
1364 && ctx->Depth.Func==GL_LESS
1365 && ctx->Depth.Mask==GL_TRUE
1366 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1367 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1368 && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1369 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1370 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1371 switch(osmesa->format) {
1372 case OSMESA_RGBA:
1373 case OSMESA_BGRA:
1374 case OSMESA_ARGB:
1375 return flat_blend_rgba_z_line_write;
1376 default:
1377 return NULL;
1378 }
1379 }
1380
1381 if (ctx->RasterMask==(DEPTH_BIT|BLEND_BIT)
1382 && ctx->Depth.Func==GL_LESS
1383 && ctx->Depth.Mask==GL_FALSE
1384 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1385 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1386 && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1387 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1388 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1389 switch(osmesa->format) {
1390 case OSMESA_RGBA:
1391 case OSMESA_BGRA:
1392 case OSMESA_ARGB:
1393 return flat_blend_rgba_z_line;
1394 default:
1395 return NULL;
1396 }
1397 }
1398
1399 if (ctx->RasterMask==BLEND_BIT
1400 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA
1401 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA
1402 && ctx->Color.BlendSrcA==GL_SRC_ALPHA
1403 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA
1404 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
1405 switch(osmesa->format) {
1406 case OSMESA_RGBA:
1407 case OSMESA_BGRA:
1408 case OSMESA_ARGB:
1409 return flat_blend_rgba_line;
1410 default:
1411 return NULL;
1412 }
1413 }
1414
1415 }
1416 return NULL;
1417}
1418
1419
1420/**********************************************************************/
1421/***** Optimized triangle rendering *****/
1422/**********************************************************************/
1423
1424
1425/*
1426 * Smooth-shaded, z-less triangle, RGBA color.
1427 */
1428static void smooth_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
1429 GLuint v2, GLuint pv )
1430{
1431 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1432 GLint rshift = osmesa->rshift;
1433 GLint gshift = osmesa->gshift;
1434 GLint bshift = osmesa->bshift;
1435 GLint ashift = osmesa->ashift;
1436 (void) pv;
1437#define INTERP_Z 1
1438#define INTERP_RGB 1
1439#define INTERP_ALPHA 1
1440#define INNER_LOOP( LEFT, RIGHT, Y ) \
1441{ \
1442 GLint i, len = RIGHT-LEFT; \
1443 GLuint *img = PIXELADDR4(LEFT,Y); \
1444 for (i=0;i<len;i++,img++) { \
1445 GLdepth z = FixedToDepth(ffz); \
1446 if (z < zRow[i]) { \
1447 *img = PACK_RGBA2( FixedToInt(ffr), FixedToInt(ffg), \
1448 FixedToInt(ffb), FixedToInt(ffa) ); \
1449 zRow[i] = z; \
1450 } \
1451 ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx;\
1452 ffz += fdzdx; \
1453 } \
1454}
1455#ifdef WIN32
1456#include "..\tritemp.h"
1457#else
1458#include "tritemp.h"
1459#endif
1460}
1461
1462
1463
1464
1465/*
1466 * Flat-shaded, z-less triangle, RGBA color.
1467 */
1468static void flat_rgba_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
1469 GLuint v2, GLuint pv )
1470{
1471 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1472#define INTERP_Z 1
1473#define SETUP_CODE \
1474 GLubyte r = VB->ColorPtr->data[pv][0]; \
1475 GLubyte g = VB->ColorPtr->data[pv][1]; \
1476 GLubyte b = VB->ColorPtr->data[pv][2]; \
1477 GLubyte a = VB->ColorPtr->data[pv][3]; \
1478 GLuint pixel = PACK_RGBA(r,g,b,a);
1479
1480#define INNER_LOOP( LEFT, RIGHT, Y ) \
1481{ \
1482 GLint i, len = RIGHT-LEFT; \
1483 GLuint *img = PIXELADDR4(LEFT,Y); \
1484 for (i=0;i<len;i++,img++) { \
1485 GLdepth z = FixedToDepth(ffz); \
1486 if (z < zRow[i]) { \
1487 *img = pixel; \
1488 zRow[i] = z; \
1489 } \
1490 ffz += fdzdx; \
1491 } \
1492}
1493#ifdef WIN32
1494#include "..\tritemp.h"
1495#else
1496#include "tritemp.h"
1497#endif
1498}
1499
1500
1501
1502/*
1503 * Return pointer to an accelerated triangle function if possible.
1504 */
1505static triangle_func choose_triangle_function( GLcontext *ctx )
1506{
1507 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1508
1509 if ((osmesa->format==OSMESA_RGB)||(osmesa->format==OSMESA_BGR)) return NULL;
1510
1511 if (ctx->Polygon.SmoothFlag) return NULL;
1512 if (ctx->Polygon.StippleFlag) return NULL;
1513 if (ctx->Texture.Enabled) return NULL;
1514
1515 if (ctx->RasterMask==DEPTH_BIT
1516 && ctx->Depth.Func==GL_LESS
1517 && ctx->Depth.Mask==GL_TRUE
1518 && osmesa->format!=OSMESA_COLOR_INDEX) {
1519 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1520 return smooth_rgba_z_triangle;
1521 }
1522 else {
1523 return flat_rgba_z_triangle;
1524 }
1525 }
1526 return NULL;
1527}
1528
1529
1530
1531static const GLubyte *get_string( GLcontext *ctx, GLenum name )
1532{
1533 (void) ctx;
1534 switch (name) {
1535 case GL_RENDERER:
1536 return (const GLubyte *) "Mesa OffScreen";
1537 default:
1538 return NULL;
1539 }
1540}
1541
1542
1543static void osmesa_update_state( GLcontext *ctx )
1544{
1545 OSMesaContext osmesa = (OSMesaContext) ctx->DriverCtx;
1546
1547 ctx->Driver.GetString = get_string;
1548 ctx->Driver.UpdateState = osmesa_update_state;
1549
1550 ctx->Driver.SetBuffer = set_buffer;
1551 ctx->Driver.Color = set_color;
1552 ctx->Driver.Index = set_index;
1553 ctx->Driver.ClearIndex = clear_index;
1554 ctx->Driver.ClearColor = clear_color;
1555 ctx->Driver.Clear = clear;
1556
1557 ctx->Driver.GetBufferSize = buffer_size;
1558
1559 ctx->Driver.PointsFunc = NULL;
1560 ctx->Driver.LineFunc = choose_line_function( ctx );
1561 ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
1562
1563
1564 /* RGB(A) span/pixel functions */
1565 if ((osmesa->format==OSMESA_RGB) || (osmesa->format==OSMESA_BGR)) {
1566 /* 3 bytes / pixel in frame buffer */
1567 ctx->Driver.WriteRGBASpan = write_rgba_span3;
1568 ctx->Driver.WriteRGBSpan = write_rgb_span3;
1569 ctx->Driver.WriteRGBAPixels = write_rgba_pixels3;
1570 ctx->Driver.WriteMonoRGBASpan = write_monocolor_span3;
1571 ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels3;
1572 ctx->Driver.ReadRGBASpan = read_rgba_span3;
1573 ctx->Driver.ReadRGBAPixels = read_rgba_pixels3;
1574 }
1575 else {
1576 /* 4 bytes / pixel in frame buffer */
1577 if (osmesa->format==OSMESA_RGBA
1578 && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
1579 ctx->Driver.WriteRGBASpan = write_rgba_span_rgba;
1580 else
1581 ctx->Driver.WriteRGBASpan = write_rgba_span;
1582 ctx->Driver.WriteRGBSpan = write_rgb_span;
1583 ctx->Driver.WriteRGBAPixels = write_rgba_pixels;
1584 ctx->Driver.WriteMonoRGBASpan = write_monocolor_span;
1585 ctx->Driver.WriteMonoRGBAPixels = write_monocolor_pixels;
1586 if (osmesa->format==OSMESA_RGBA
1587 && RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3)
1588 ctx->Driver.ReadRGBASpan = read_rgba_span_rgba;
1589 else
1590 ctx->Driver.ReadRGBASpan = read_rgba_span;
1591 ctx->Driver.ReadRGBAPixels = read_rgba_pixels;
1592 }
1593
1594 /* CI span/pixel functions */
1595 ctx->Driver.WriteCI32Span = write_index32_span;
1596 ctx->Driver.WriteCI8Span = write_index8_span;
1597 ctx->Driver.WriteMonoCISpan = write_monoindex_span;
1598 ctx->Driver.WriteCI32Pixels = write_index_pixels;
1599 ctx->Driver.WriteMonoCIPixels = write_monoindex_pixels;
1600 ctx->Driver.ReadCI32Span = read_index_span;
1601 ctx->Driver.ReadCI32Pixels = read_index_pixels;
1602}
Note: See TracBrowser for help on using the repository browser.