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