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