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