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

Last change on this file since 2962 was 2962, checked in by jeroen, 25 years ago

* empty log message *

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