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