osmesa.c revision 2a88946f9ad82350c2f7edc2185bf9394d2d4764
1/* $Id: osmesa.c,v 1.64 2001/08/28 22:46:22 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28/* 29 * Off-Screen Mesa rendering / Rendering into client memory space 30 * 31 * Note on thread safety: this driver is thread safe. All 32 * functions are reentrant. The notion of current context is 33 * managed by the core _mesa_make_current() and _mesa_get_current_context() 34 * functions. Those functions are thread-safe. 35 */ 36 37 38#include "glheader.h" 39#include "GL/osmesa.h" 40#include "context.h" 41#include "colormac.h" 42#include "depth.h" 43#include "extensions.h" 44#include "macros.h" 45#include "matrix.h" 46#include "mem.h" 47#include "mmath.h" 48#include "mtypes.h" 49#include "texformat.h" 50#include "texstore.h" 51#include "array_cache/acache.h" 52#include "swrast/swrast.h" 53#include "swrast_setup/swrast_setup.h" 54#include "swrast/s_context.h" 55#include "swrast/s_depth.h" 56#include "swrast/s_lines.h" 57#include "swrast/s_triangle.h" 58#include "swrast/s_trispan.h" 59#include "tnl/tnl.h" 60#include "tnl/t_context.h" 61#include "tnl/t_pipeline.h" 62 63 64 65/* 66 * This is the OS/Mesa context struct. 67 * Notice how it includes a GLcontext. By doing this we're mimicking 68 * C++ inheritance/derivation. 69 * Later, we can cast a GLcontext pointer into an OSMesaContext pointer 70 * or vice versa. 71 */ 72struct osmesa_context { 73 GLcontext gl_ctx; /* The core GL/Mesa context */ 74 GLvisual *gl_visual; /* Describes the buffers */ 75 GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers */ 76 GLenum format; /* either GL_RGBA or GL_COLOR_INDEX */ 77 void *buffer; /* the image buffer */ 78 GLint width, height; /* size of image buffer */ 79 GLint rowlength; /* number of pixels per row */ 80 GLint userRowLength; /* user-specified number of pixels per row */ 81 GLint rshift, gshift; /* bit shifts for RGBA formats */ 82 GLint bshift, ashift; 83 GLint rInd, gInd, bInd, aInd;/* index offsets for RGBA formats */ 84 GLchan *rowaddr[MAX_HEIGHT]; /* address of first pixel in each image row */ 85 GLboolean yup; /* TRUE -> Y increases upward */ 86 /* FALSE -> Y increases downward */ 87}; 88 89 90 91/* A forward declaration: */ 92static void osmesa_update_state( GLcontext *ctx, GLuint newstate ); 93static void osmesa_register_swrast_functions( GLcontext *ctx ); 94 95 96 97#define OSMESA_CONTEXT(ctx) ((OSMesaContext) (ctx->DriverCtx)) 98 99 100 101/**********************************************************************/ 102/***** Public Functions *****/ 103/**********************************************************************/ 104 105 106/* 107 * Create an Off-Screen Mesa rendering context. The only attribute needed is 108 * an RGBA vs Color-Index mode flag. 109 * 110 * Input: format - either GL_RGBA or GL_COLOR_INDEX 111 * sharelist - specifies another OSMesaContext with which to share 112 * display lists. NULL indicates no sharing. 113 * Return: an OSMesaContext or 0 if error 114 */ 115OSMesaContext GLAPIENTRY 116OSMesaCreateContext( GLenum format, OSMesaContext sharelist ) 117{ 118 return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS, 119 8, 16, sharelist); 120} 121 122 123 124/* 125 * New in Mesa 3.5 126 * 127 * Create context and specify size of ancillary buffers. 128 */ 129OSMesaContext GLAPIENTRY 130OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, 131 GLint accumBits, OSMesaContext sharelist ) 132{ 133 OSMesaContext osmesa; 134 GLint rshift, gshift, bshift, ashift; 135 GLint rind, gind, bind, aind; 136 GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0; 137 GLboolean rgbmode; 138 GLboolean swalpha; 139 const GLuint i4 = 1; 140 const GLubyte *i1 = (GLubyte *) &i4; 141 const GLint little_endian = *i1; 142 143 swalpha = GL_FALSE; 144 rind = gind = bind = aind = 0; 145 if (format==OSMESA_COLOR_INDEX) { 146 indexBits = 8; 147 rshift = gshift = bshift = ashift = 0; 148 rgbmode = GL_FALSE; 149 } 150 else if (format==OSMESA_RGBA) { 151 indexBits = 0; 152 redBits = CHAN_BITS; 153 greenBits = CHAN_BITS; 154 blueBits = CHAN_BITS; 155 alphaBits = CHAN_BITS; 156 rind = 0; 157 gind = 1; 158 bind = 2; 159 aind = 3; 160 if (little_endian) { 161 rshift = 0; 162 gshift = 8; 163 bshift = 16; 164 ashift = 24; 165 } 166 else { 167 rshift = 24; 168 gshift = 16; 169 bshift = 8; 170 ashift = 0; 171 } 172 rgbmode = GL_TRUE; 173 } 174 else if (format==OSMESA_BGRA) { 175 indexBits = 0; 176 redBits = CHAN_BITS; 177 greenBits = CHAN_BITS; 178 blueBits = CHAN_BITS; 179 alphaBits = CHAN_BITS; 180 rind = 2; 181 gind = 1; 182 bind = 0; 183 aind = 3; 184 if (little_endian) { 185 ashift = 0; 186 rshift = 8; 187 gshift = 16; 188 bshift = 24; 189 } 190 else { 191 bshift = 24; 192 gshift = 16; 193 rshift = 8; 194 ashift = 0; 195 } 196 rgbmode = GL_TRUE; 197 } 198 else if (format==OSMESA_ARGB) { 199 indexBits = 0; 200 redBits = CHAN_BITS; 201 greenBits = CHAN_BITS; 202 blueBits = CHAN_BITS; 203 alphaBits = CHAN_BITS; 204 rind = 1; 205 gind = 2; 206 bind = 3; 207 aind = 0; 208 if (little_endian) { 209 bshift = 0; 210 gshift = 8; 211 rshift = 16; 212 ashift = 24; 213 } 214 else { 215 ashift = 24; 216 rshift = 16; 217 gshift = 8; 218 bshift = 0; 219 } 220 rgbmode = GL_TRUE; 221 } 222 else if (format==OSMESA_RGB) { 223 indexBits = 0; 224 redBits = CHAN_BITS; 225 greenBits = CHAN_BITS; 226 blueBits = CHAN_BITS; 227 alphaBits = 0; 228 bshift = 0; 229 gshift = 8; 230 rshift = 16; 231 ashift = 24; 232 rind = 0; 233 gind = 1; 234 bind = 2; 235 rgbmode = GL_TRUE; 236 swalpha = GL_TRUE; 237 } 238 else if (format==OSMESA_BGR) { 239 indexBits = 0; 240 redBits = CHAN_BITS; 241 greenBits = CHAN_BITS; 242 blueBits = CHAN_BITS; 243 alphaBits = 0; 244 bshift = 0; 245 gshift = 8; 246 rshift = 16; 247 ashift = 24; 248 rind = 2; 249 gind = 1; 250 bind = 0; 251 rgbmode = GL_TRUE; 252 swalpha = GL_TRUE; 253 } 254 else if (format==OSMESA_RGB_565) { 255 indexBits = 0; 256 redBits = 5; 257 greenBits = 6; 258 blueBits = 5; 259 alphaBits = 0; 260 rshift = 11; 261 gshift = 5; 262 bshift = 0; 263 ashift = 0; 264 rind = 0; /* not used */ 265 gind = 0; 266 bind = 0; 267 rgbmode = GL_TRUE; 268 swalpha = GL_FALSE; 269 } 270 else { 271 return NULL; 272 } 273 274 275 osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context); 276 if (osmesa) { 277 osmesa->gl_visual = _mesa_create_visual( rgbmode, 278 GL_FALSE, /* double buffer */ 279 GL_FALSE, /* stereo */ 280 redBits, 281 greenBits, 282 blueBits, 283 alphaBits, 284 indexBits, 285 depthBits, 286 stencilBits, 287 accumBits, 288 accumBits, 289 accumBits, 290 alphaBits ? accumBits : 0, 291 1 /* num samples */ 292 ); 293 if (!osmesa->gl_visual) { 294 FREE(osmesa); 295 return NULL; 296 } 297 298 if (!_mesa_initialize_context(&osmesa->gl_ctx, 299 osmesa->gl_visual, 300 sharelist ? &sharelist->gl_ctx 301 : (GLcontext *) NULL, 302 (void *) osmesa, GL_TRUE )) { 303 _mesa_destroy_visual( osmesa->gl_visual ); 304 FREE(osmesa); 305 return NULL; 306 } 307 308 _mesa_enable_sw_extensions(&(osmesa->gl_ctx)); 309 _mesa_enable_1_3_extensions(&(osmesa->gl_ctx)); 310 311 osmesa->gl_buffer = _mesa_create_framebuffer( osmesa->gl_visual, 312 osmesa->gl_visual->depthBits > 0, 313 osmesa->gl_visual->stencilBits > 0, 314 osmesa->gl_visual->accumRedBits > 0, 315 swalpha ); 316 317 if (!osmesa->gl_buffer) { 318 _mesa_destroy_visual( osmesa->gl_visual ); 319 _mesa_free_context_data( &osmesa->gl_ctx ); 320 FREE(osmesa); 321 return NULL; 322 } 323 osmesa->format = format; 324 osmesa->buffer = NULL; 325 osmesa->width = 0; 326 osmesa->height = 0; 327 osmesa->userRowLength = 0; 328 osmesa->rowlength = 0; 329 osmesa->yup = GL_TRUE; 330 osmesa->rshift = rshift; 331 osmesa->gshift = gshift; 332 osmesa->bshift = bshift; 333 osmesa->ashift = ashift; 334 osmesa->rInd = rind; 335 osmesa->gInd = gind; 336 osmesa->bInd = bind; 337 osmesa->aInd = aind; 338 339 340 /* Initialize the software rasterizer and helper modules. 341 */ 342 { 343 GLcontext *ctx = &osmesa->gl_ctx; 344 345 _swrast_CreateContext( ctx ); 346 _ac_CreateContext( ctx ); 347 _tnl_CreateContext( ctx ); 348 _swsetup_CreateContext( ctx ); 349 350 _swsetup_Wakeup( ctx ); 351 osmesa_register_swrast_functions( ctx ); 352 } 353 } 354 return osmesa; 355} 356 357 358 359 360/* 361 * Destroy an Off-Screen Mesa rendering context. 362 * 363 * Input: ctx - the context to destroy 364 */ 365void GLAPIENTRY OSMesaDestroyContext( OSMesaContext ctx ) 366{ 367 if (ctx) { 368 _swsetup_DestroyContext( &ctx->gl_ctx ); 369 _tnl_DestroyContext( &ctx->gl_ctx ); 370 _ac_DestroyContext( &ctx->gl_ctx ); 371 _swrast_DestroyContext( &ctx->gl_ctx ); 372 373 _mesa_destroy_visual( ctx->gl_visual ); 374 _mesa_destroy_framebuffer( ctx->gl_buffer ); 375 _mesa_free_context_data( &ctx->gl_ctx ); 376 FREE( ctx ); 377 } 378} 379 380 381 382/* 383 * Recompute the values of the context's rowaddr array. 384 */ 385static void compute_row_addresses( OSMesaContext ctx ) 386{ 387 GLint bytesPerPixel, bytesPerRow, i; 388 GLubyte *origin = (GLubyte *) ctx->buffer; 389 390 if (ctx->format == OSMESA_COLOR_INDEX) { 391 /* CI mode */ 392 bytesPerPixel = 1 * sizeof(GLchan); 393 } 394 else if ((ctx->format == OSMESA_RGB) || (ctx->format == OSMESA_BGR)) { 395 /* RGB mode */ 396 bytesPerPixel = 3 * sizeof(GLchan); 397 } 398 else if (ctx->format == OSMESA_RGB_565) { 399 /* 5/6/5 RGB pixel in 16 bits */ 400 bytesPerPixel = 2; 401 } 402 else { 403 /* RGBA mode */ 404 bytesPerPixel = 4 * sizeof(GLchan); 405 } 406 407 bytesPerRow = ctx->rowlength * bytesPerPixel; 408 409 if (ctx->yup) { 410 /* Y=0 is bottom line of window */ 411 for (i = 0; i < MAX_HEIGHT; i++) { 412 ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + i * bytesPerRow); 413 } 414 } 415 else { 416 /* Y=0 is top line of window */ 417 for (i = 0; i < MAX_HEIGHT; i++) { 418 GLint j = ctx->height - i - 1; 419 ctx->rowaddr[i] = (GLchan *) ((GLubyte *) origin + j * bytesPerRow); 420 } 421 } 422} 423 424 425/* 426 * Bind an OSMesaContext to an image buffer. The image buffer is just a 427 * block of memory which the client provides. Its size must be at least 428 * as large as width*height*sizeof(type). Its address should be a multiple 429 * of 4 if using RGBA mode. 430 * 431 * Image data is stored in the order of glDrawPixels: row-major order 432 * with the lower-left image pixel stored in the first array position 433 * (ie. bottom-to-top). 434 * 435 * Since the only type initially supported is GL_UNSIGNED_BYTE, if the 436 * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA 437 * value. If the context is in color indexed mode, each pixel will be 438 * stored as a 1-byte value. 439 * 440 * If the context's viewport hasn't been initialized yet, it will now be 441 * initialized to (0,0,width,height). 442 * 443 * Input: ctx - the rendering context 444 * buffer - the image buffer memory 445 * type - data type for pixel components, only GL_UNSIGNED_BYTE 446 * and GL_UNSIGNED_SHORT_5_6_5 supported now. 447 * width, height - size of image buffer in pixels, at least 1 448 * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx, 449 * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1, 450 * width>internal limit or height>internal limit. 451 */ 452GLboolean GLAPIENTRY 453OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type, 454 GLsizei width, GLsizei height ) 455{ 456 if (!ctx || !buffer || 457 width < 1 || height < 1 || 458 width > MAX_WIDTH || height > MAX_HEIGHT) { 459 return GL_FALSE; 460 } 461 462 if (ctx->format == OSMESA_RGB_565) { 463 if (type != GL_UNSIGNED_SHORT_5_6_5) 464 return GL_FALSE; 465 } 466 else if (type != CHAN_TYPE) { 467 return GL_FALSE; 468 } 469 470 osmesa_update_state( &ctx->gl_ctx, 0 ); 471 _mesa_make_current( &ctx->gl_ctx, ctx->gl_buffer ); 472 473 ctx->buffer = buffer; 474 ctx->width = width; 475 ctx->height = height; 476 if (ctx->userRowLength) 477 ctx->rowlength = ctx->userRowLength; 478 else 479 ctx->rowlength = width; 480 481 compute_row_addresses( ctx ); 482 483 /* init viewport */ 484 if (ctx->gl_ctx.Viewport.Width==0) { 485 /* initialize viewport and scissor box to buffer size */ 486 _mesa_Viewport( 0, 0, width, height ); 487 ctx->gl_ctx.Scissor.Width = width; 488 ctx->gl_ctx.Scissor.Height = height; 489 } 490 491 return GL_TRUE; 492} 493 494 495 496OSMesaContext GLAPIENTRY OSMesaGetCurrentContext( void ) 497{ 498 GLcontext *ctx = _mesa_get_current_context(); 499 if (ctx) 500 return (OSMesaContext) ctx; 501 else 502 return NULL; 503} 504 505 506 507void GLAPIENTRY OSMesaPixelStore( GLint pname, GLint value ) 508{ 509 OSMesaContext ctx = OSMesaGetCurrentContext(); 510 511 switch (pname) { 512 case OSMESA_ROW_LENGTH: 513 if (value<0) { 514 _mesa_error( &ctx->gl_ctx, GL_INVALID_VALUE, 515 "OSMesaPixelStore(value)" ); 516 return; 517 } 518 ctx->userRowLength = value; 519 ctx->rowlength = value; 520 break; 521 case OSMESA_Y_UP: 522 ctx->yup = value ? GL_TRUE : GL_FALSE; 523 break; 524 default: 525 _mesa_error( &ctx->gl_ctx, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" ); 526 return; 527 } 528 529 compute_row_addresses( ctx ); 530} 531 532 533void GLAPIENTRY OSMesaGetIntegerv( GLint pname, GLint *value ) 534{ 535 OSMesaContext ctx = OSMesaGetCurrentContext(); 536 537 switch (pname) { 538 case OSMESA_WIDTH: 539 *value = ctx->width; 540 return; 541 case OSMESA_HEIGHT: 542 *value = ctx->height; 543 return; 544 case OSMESA_FORMAT: 545 *value = ctx->format; 546 return; 547 case OSMESA_TYPE: 548 *value = CHAN_TYPE; 549 return; 550 case OSMESA_ROW_LENGTH: 551 *value = ctx->rowlength; 552 return; 553 case OSMESA_Y_UP: 554 *value = ctx->yup; 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 */ 570GLboolean 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 */ 601GLboolean 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 GLint 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 = vert0->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 = vert0->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 = vert0->color[0]*avalue; 1615 const GLint gvalue = vert0->color[1]*avalue; 1616 const GLint bvalue = vert0->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#ifdef WIN32 1630#include "..\swrast\s_linetemp.h" 1631#else 1632#include "swrast/s_linetemp.h" 1633#endif 1634} 1635 1636 1637/* 1638 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer. 1639 * XXX update for GLchan 1640 */ 1641static void 1642flat_blend_rgba_z_line( GLcontext *ctx, 1643 const SWvertex *vert0, const SWvertex *vert1 ) 1644{ 1645 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1646 const GLint rshift = osmesa->rshift; 1647 const GLint gshift = osmesa->gshift; 1648 const GLint bshift = osmesa->bshift; 1649 const GLint avalue = vert0->color[3]; 1650 const GLint msavalue = 256 - avalue; 1651 const GLint rvalue = vert0->color[0]*avalue; 1652 const GLint gvalue = vert0->color[1]*avalue; 1653 const GLint bvalue = vert0->color[2]*avalue; 1654 1655#define INTERP_XY 1 1656#define INTERP_Z 1 1657#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1658#define CLIP_HACK 1 1659#define PLOT(X,Y) \ 1660 if (Z < *zPtr) { \ 1661 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \ 1662 GLuint pixel = 0; \ 1663 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \ 1664 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \ 1665 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \ 1666 *ptr4 = pixel; \ 1667 } 1668 1669#ifdef WIN32 1670#include "..\swrast\s_linetemp.h" 1671#else 1672#include "swrast/s_linetemp.h" 1673#endif 1674} 1675 1676 1677/* 1678 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer. 1679 * XXX update for GLchan 1680 */ 1681static void 1682flat_blend_rgba_z_line_write( GLcontext *ctx, 1683 const SWvertex *vert0, const SWvertex *vert1 ) 1684{ 1685 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1686 const GLint rshift = osmesa->rshift; 1687 const GLint gshift = osmesa->gshift; 1688 const GLint bshift = osmesa->bshift; 1689 const GLint avalue = vert0->color[3]; 1690 const GLint msavalue = 256 - avalue; 1691 const GLint rvalue = vert0->color[0]*avalue; 1692 const GLint gvalue = vert0->color[1]*avalue; 1693 const GLint bvalue = vert0->color[2]*avalue; 1694 1695#define INTERP_XY 1 1696#define INTERP_Z 1 1697#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1698#define CLIP_HACK 1 1699#define PLOT(X,Y) \ 1700 if (Z < *zPtr) { \ 1701 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \ 1702 GLuint pixel = 0; \ 1703 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \ 1704 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \ 1705 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \ 1706 *ptr4 = pixel; \ 1707 *zPtr = Z; \ 1708 } 1709 1710#ifdef WIN32 1711#include "..\swrast\s_linetemp.h" 1712#else 1713#include "swrast/s_linetemp.h" 1714#endif 1715} 1716 1717 1718/* 1719 * Analyze context state to see if we can provide a fast line drawing 1720 * function, like those in lines.c. Otherwise, return NULL. 1721 */ 1722static swrast_line_func 1723osmesa_choose_line_function( GLcontext *ctx ) 1724{ 1725 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1726 const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1727 1728 if (CHAN_BITS != 8) return NULL; 1729 if (ctx->RenderMode != GL_RENDER) return NULL; 1730 if (ctx->Line.SmoothFlag) return NULL; 1731 if (ctx->Texture._ReallyEnabled) return NULL; 1732 if (ctx->Light.ShadeModel != GL_FLAT) return NULL; 1733 if (ctx->Line.Width != 1.0F) return NULL; 1734 if (ctx->Line.StippleFlag) return NULL; 1735 if (ctx->Line.SmoothFlag) return NULL; 1736 if (osmesa->format != OSMESA_RGBA && 1737 osmesa->format != OSMESA_BGRA && 1738 osmesa->format != OSMESA_ARGB) return NULL; 1739 1740 if (swrast->_RasterMask==DEPTH_BIT 1741 && ctx->Depth.Func==GL_LESS 1742 && ctx->Depth.Mask==GL_TRUE 1743 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { 1744 return flat_rgba_z_line; 1745 } 1746 1747 if (swrast->_RasterMask == 0) { 1748 return flat_rgba_line; 1749 } 1750 1751 if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT) 1752 && ctx->Depth.Func==GL_LESS 1753 && ctx->Depth.Mask==GL_TRUE 1754 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS 1755 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA 1756 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA 1757 && ctx->Color.BlendSrcA==GL_SRC_ALPHA 1758 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA 1759 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { 1760 return flat_blend_rgba_z_line_write; 1761 } 1762 1763 if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT) 1764 && ctx->Depth.Func==GL_LESS 1765 && ctx->Depth.Mask==GL_FALSE 1766 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS 1767 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA 1768 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA 1769 && ctx->Color.BlendSrcA==GL_SRC_ALPHA 1770 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA 1771 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { 1772 return flat_blend_rgba_z_line; 1773 } 1774 1775 if (swrast->_RasterMask==BLEND_BIT 1776 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA 1777 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA 1778 && ctx->Color.BlendSrcA==GL_SRC_ALPHA 1779 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA 1780 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { 1781 return flat_blend_rgba_line; 1782 } 1783 1784 return NULL; 1785} 1786 1787 1788/**********************************************************************/ 1789/***** Optimized triangle rendering *****/ 1790/**********************************************************************/ 1791 1792 1793/* 1794 * Smooth-shaded, z-less triangle, RGBA color. 1795 */ 1796static void smooth_rgba_z_triangle( GLcontext *ctx, 1797 const SWvertex *v0, 1798 const SWvertex *v1, 1799 const SWvertex *v2 ) 1800{ 1801 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1802 1803#define INTERP_Z 1 1804#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1805#define INTERP_RGB 1 1806#define INTERP_ALPHA 1 1807#define RENDER_SPAN( span ) \ 1808 GLuint i; \ 1809 GLchan *img = PIXELADDR4(span.x, span.y); \ 1810 for (i = 0; i < span.count; i++, img += 4) { \ 1811 const GLdepth z = FixedToDepth(span.z); \ 1812 if (z < zRow[i]) { \ 1813 PACK_RGBA(img, FixedToChan(span.red), \ 1814 FixedToChan(span.green), FixedToChan(span.blue), \ 1815 FixedToChan(span.alpha)); \ 1816 zRow[i] = z; \ 1817 } \ 1818 span.red += span.redStep; \ 1819 span.green += span.greenStep; \ 1820 span.blue += span.blueStep; \ 1821 span.alpha += span.alphaStep; \ 1822 span.z += span.zStep; \ 1823 } 1824 1825#ifdef WIN32 1826#include "..\swrast\s_tritemp.h" 1827#else 1828#include "swrast/s_tritemp.h" 1829#endif 1830} 1831 1832 1833 1834 1835/* 1836 * Flat-shaded, z-less triangle, RGBA color. 1837 */ 1838static void flat_rgba_z_triangle( GLcontext *ctx, 1839 const SWvertex *v0, 1840 const SWvertex *v1, 1841 const SWvertex *v2 ) 1842{ 1843 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1844#define INTERP_Z 1 1845#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1846#define SETUP_CODE \ 1847 GLuint pixel; \ 1848 PACK_RGBA((GLchan *) &pixel, v0->color[0], v0->color[1], \ 1849 v0->color[2], v0->color[3]); 1850 1851#define RENDER_SPAN( span ) \ 1852 GLuint i; \ 1853 GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y); \ 1854 for (i = 0; i < span.count; i++) { \ 1855 const GLdepth z = FixedToDepth(span.z); \ 1856 if (z < zRow[i]) { \ 1857 img[i] = pixel; \ 1858 zRow[i] = z; \ 1859 } \ 1860 span.z += span.zStep; \ 1861 } 1862 1863#ifdef WIN32 1864#include "..\swrast\s_tritemp.h" 1865#else 1866#include "swrast/s_tritemp.h" 1867#endif 1868} 1869 1870 1871 1872/* 1873 * Return pointer to an accelerated triangle function if possible. 1874 */ 1875static swrast_tri_func 1876osmesa_choose_triangle_function( GLcontext *ctx ) 1877{ 1878 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1879 const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1880 1881 if (CHAN_BITS != 8) return (swrast_tri_func) NULL; 1882 if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL; 1883 if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL; 1884 if (ctx->Polygon.StippleFlag) return (swrast_tri_func) NULL; 1885 if (ctx->Texture._ReallyEnabled) return (swrast_tri_func) NULL; 1886 if (osmesa->format != OSMESA_RGBA && 1887 osmesa->format != OSMESA_BGRA && 1888 osmesa->format != OSMESA_ARGB) return (swrast_tri_func) NULL; 1889 1890 if (swrast->_RasterMask == DEPTH_BIT && 1891 ctx->Depth.Func == GL_LESS && 1892 ctx->Depth.Mask == GL_TRUE && 1893 ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { 1894 if (ctx->Light.ShadeModel == GL_SMOOTH) { 1895 return smooth_rgba_z_triangle; 1896 } 1897 else { 1898 return flat_rgba_z_triangle; 1899 } 1900 } 1901 return (swrast_tri_func) NULL; 1902} 1903 1904 1905 1906/* Override for the swrast triangle-selection function. Try to use one 1907 * of our internal triangle functions, otherwise fall back to the 1908 * standard swrast functions. 1909 */ 1910static void osmesa_choose_triangle( GLcontext *ctx ) 1911{ 1912 SWcontext *swrast = SWRAST_CONTEXT(ctx); 1913 1914 swrast->Triangle = osmesa_choose_triangle_function( ctx ); 1915 if (!swrast->Triangle) 1916 _swrast_choose_triangle( ctx ); 1917} 1918 1919static void osmesa_choose_line( GLcontext *ctx ) 1920{ 1921 SWcontext *swrast = SWRAST_CONTEXT(ctx); 1922 1923 swrast->Line = osmesa_choose_line_function( ctx ); 1924 if (!swrast->Line) 1925 _swrast_choose_line( ctx ); 1926} 1927 1928 1929#define OSMESA_NEW_LINE (_NEW_LINE | \ 1930 _NEW_TEXTURE | \ 1931 _NEW_LIGHT | \ 1932 _NEW_DEPTH | \ 1933 _NEW_RENDERMODE | \ 1934 _SWRAST_NEW_RASTERMASK) 1935 1936#define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \ 1937 _NEW_TEXTURE | \ 1938 _NEW_LIGHT | \ 1939 _NEW_DEPTH | \ 1940 _NEW_RENDERMODE | \ 1941 _SWRAST_NEW_RASTERMASK) 1942 1943 1944/* Extend the software rasterizer with our line and triangle 1945 * functions. 1946 */ 1947static void osmesa_register_swrast_functions( GLcontext *ctx ) 1948{ 1949 SWcontext *swrast = SWRAST_CONTEXT( ctx ); 1950 1951 swrast->choose_line = osmesa_choose_line; 1952 swrast->choose_triangle = osmesa_choose_triangle; 1953 1954 swrast->invalidate_line |= OSMESA_NEW_LINE; 1955 swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE; 1956} 1957 1958 1959static const GLubyte *get_string( GLcontext *ctx, GLenum name ) 1960{ 1961 (void) ctx; 1962 switch (name) { 1963 case GL_RENDERER: 1964 return (const GLubyte *) "Mesa OffScreen"; 1965 default: 1966 return NULL; 1967 } 1968} 1969 1970 1971static void osmesa_update_state( GLcontext *ctx, GLuint new_state ) 1972{ 1973 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1974 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); 1975 TNLcontext *tnl = TNL_CONTEXT(ctx); 1976 1977 ASSERT((void *) osmesa == (void *) ctx->DriverCtx); 1978 1979 /* 1980 * XXX these function pointers could be initialized just once during 1981 * context creation since they don't depend on any state changes. 1982 */ 1983 1984 ctx->Driver.GetString = get_string; 1985 ctx->Driver.UpdateState = osmesa_update_state; 1986 ctx->Driver.SetDrawBuffer = set_draw_buffer; 1987 ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers; 1988 ctx->Driver.GetBufferSize = buffer_size; 1989 1990 ctx->Driver.Accum = _swrast_Accum; 1991 ctx->Driver.Bitmap = _swrast_Bitmap; 1992 ctx->Driver.Clear = clear; 1993 ctx->Driver.CopyPixels = _swrast_CopyPixels; 1994 ctx->Driver.DrawPixels = _swrast_DrawPixels; 1995 ctx->Driver.ReadPixels = _swrast_ReadPixels; 1996 1997 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; 1998 ctx->Driver.TexImage1D = _mesa_store_teximage1d; 1999 ctx->Driver.TexImage2D = _mesa_store_teximage2d; 2000 ctx->Driver.TexImage3D = _mesa_store_teximage3d; 2001 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; 2002 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; 2003 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; 2004 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; 2005 2006 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; 2007 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; 2008 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; 2009 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; 2010 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; 2011 ctx->Driver.CopyColorTable = _swrast_CopyColorTable; 2012 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; 2013 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; 2014 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; 2015 2016 2017 /* RGB(A) span/pixel functions */ 2018 if (osmesa->format == OSMESA_RGB) { 2019 swdd->WriteRGBASpan = write_rgba_span_RGB; 2020 swdd->WriteRGBSpan = write_rgb_span_RGB; 2021 swdd->WriteMonoRGBASpan = write_monocolor_span_RGB; 2022 swdd->WriteRGBAPixels = write_rgba_pixels_RGB; 2023 swdd->WriteMonoRGBAPixels = write_monocolor_pixels_RGB; 2024 swdd->ReadRGBASpan = read_rgba_span3; 2025 swdd->ReadRGBAPixels = read_rgba_pixels3; 2026 } 2027 else if (osmesa->format == OSMESA_BGR) { 2028 swdd->WriteRGBASpan = write_rgba_span_BGR; 2029 swdd->WriteRGBSpan = write_rgb_span_BGR; 2030 swdd->WriteMonoRGBASpan = write_monocolor_span_BGR; 2031 swdd->WriteRGBAPixels = write_rgba_pixels_BGR; 2032 swdd->WriteMonoRGBAPixels = write_monocolor_pixels_BGR; 2033 swdd->ReadRGBASpan = read_rgba_span3; 2034 swdd->ReadRGBAPixels = read_rgba_pixels3; 2035 } 2036 else if (osmesa->format == OSMESA_RGB_565) { 2037 swdd->WriteRGBASpan = write_rgba_span2; 2038 swdd->WriteRGBSpan = write_rgb_span2; 2039 swdd->WriteMonoRGBASpan = write_monocolor_span2; 2040 swdd->WriteRGBAPixels = write_rgba_pixels2; 2041 swdd->WriteMonoRGBAPixels = write_monocolor_pixels2; 2042 swdd->ReadRGBASpan = read_rgba_span2; 2043 swdd->ReadRGBAPixels = read_rgba_pixels2; 2044 } 2045 else { 2046 /* 4 GLchan / pixel in frame buffer */ 2047 swdd->WriteRGBSpan = write_rgb_span; 2048 swdd->WriteRGBAPixels = write_rgba_pixels; 2049 swdd->WriteMonoRGBASpan = write_monocolor_span; 2050 swdd->WriteMonoRGBAPixels = write_monocolor_pixels; 2051 if (osmesa->format == OSMESA_RGBA && 2052 CHAN_TYPE == GL_UNSIGNED_BYTE && 2053 RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3) { 2054 /* special, fast case */ 2055 swdd->WriteRGBASpan = write_rgba_span_rgba; 2056 swdd->ReadRGBASpan = read_rgba_span_rgba; 2057 } 2058 else { 2059 swdd->WriteRGBASpan = write_rgba_span; 2060 swdd->ReadRGBASpan = read_rgba_span; 2061 } 2062 swdd->ReadRGBAPixels = read_rgba_pixels; 2063 } 2064 2065 /* CI span/pixel functions */ 2066 swdd->WriteCI32Span = write_index32_span; 2067 swdd->WriteCI8Span = write_index8_span; 2068 swdd->WriteMonoCISpan = write_monoindex_span; 2069 swdd->WriteCI32Pixels = write_index_pixels; 2070 swdd->WriteMonoCIPixels = write_monoindex_pixels; 2071 swdd->ReadCI32Span = read_index_span; 2072 swdd->ReadCI32Pixels = read_index_pixels; 2073 2074 swdd->SetReadBuffer = set_read_buffer; 2075 2076 tnl->Driver.RunPipeline = _tnl_run_pipeline; 2077 2078 _swrast_InvalidateState( ctx, new_state ); 2079 _swsetup_InvalidateState( ctx, new_state ); 2080 _ac_InvalidateState( ctx, new_state ); 2081 _tnl_InvalidateState( ctx, new_state ); 2082} 2083