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