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