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