osmesa.c revision 8afe7de8deaf3c9613fd68b344de8c52b02b1879
1/* $Id: osmesa.c,v 1.82 2002/06/15 03:03:10 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 void set_draw_buffer( GLcontext *ctx, GLenum mode ) 711{ 712 (void) ctx; 713 (void) mode; 714} 715 716 717static void set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode ) 718{ 719 /* separate read buffer not supported */ 720 ASSERT(buffer == ctx->DrawBuffer); 721 ASSERT(mode == GL_FRONT_LEFT); 722} 723 724 725static void clear( GLcontext *ctx, GLbitfield mask, GLboolean all, 726 GLint x, GLint y, GLint width, GLint height ) 727{ 728 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 729 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; 730 731 /* sanity check - we only have a front-left buffer */ 732 ASSERT((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT)) == 0); 733 if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { 734 if (mask & DD_FRONT_LEFT_BIT) { 735 if (osmesa->format == OSMESA_COLOR_INDEX) { 736 if (all) { 737 /* Clear whole CI buffer */ 738#if CHAN_TYPE == GL_UNSIGNED_BYTE 739 MEMSET(osmesa->buffer, ctx->Color.ClearIndex, 740 osmesa->rowlength * osmesa->height); 741#else 742 const GLint n = osmesa->rowlength * osmesa->height; 743 GLchan *buffer = (GLchan *) osmesa->buffer; 744 GLint i; 745 for (i = 0; i < n; i ++) { 746 buffer[i] = ctx->Color.ClearIndex; 747 } 748#endif 749 } 750 else { 751 /* Clear part of CI buffer */ 752 const GLchan clearIndex = (GLchan) ctx->Color.ClearIndex; 753 GLint i, j; 754 for (i = 0; i < height; i++) { 755 GLchan *ptr1 = PIXELADDR1(x, (y + i)); 756 for (j = 0; j < width; j++) { 757 *ptr1++ = clearIndex; 758 } 759 } 760 } 761 } 762 else if (osmesa->format == OSMESA_RGB) { 763 const GLchan r = ctx->Color.ClearColor[0]; 764 const GLchan g = ctx->Color.ClearColor[1]; 765 const GLchan b = ctx->Color.ClearColor[2]; 766 if (all) { 767 /* Clear whole RGB buffer */ 768 GLuint n = osmesa->rowlength * osmesa->height; 769 GLchan *ptr3 = (GLchan *) osmesa->buffer; 770 GLuint i; 771 for (i = 0; i < n; i++) { 772 PACK_RGB(ptr3, r, g, b); 773 ptr3 += 3; 774 } 775 } 776 else { 777 /* Clear part of RGB buffer */ 778 GLint i, j; 779 for (i = 0; i < height; i++) { 780 GLchan *ptr3 = PIXELADDR3(x, (y + i)); 781 for (j = 0; j < width; j++) { 782 PACK_RGB(ptr3, r, g, b); 783 ptr3 += 3; 784 } 785 } 786 } 787 } 788 else if (osmesa->format == OSMESA_BGR) { 789 const GLchan r = ctx->Color.ClearColor[0]; 790 const GLchan g = ctx->Color.ClearColor[1]; 791 const GLchan b = ctx->Color.ClearColor[2]; 792 if (all) { 793 /* Clear whole RGB buffer */ 794 const GLint n = osmesa->rowlength * osmesa->height; 795 GLchan *ptr3 = (GLchan *) osmesa->buffer; 796 GLint i; 797 for (i = 0; i < n; i++) { 798 PACK_BGR(ptr3, r, g, b); 799 ptr3 += 3; 800 } 801 } 802 else { 803 /* Clear part of RGB buffer */ 804 GLint i, j; 805 for (i = 0; i < height; i++) { 806 GLchan *ptr3 = PIXELADDR3(x, (y + i)); 807 for (j = 0; j < width; j++) { 808 PACK_BGR(ptr3, r, g, b); 809 ptr3 += 3; 810 } 811 } 812 } 813 } 814 else if (osmesa->format == OSMESA_RGB_565) { 815 const GLchan r = ctx->Color.ClearColor[0]; 816 const GLchan g = ctx->Color.ClearColor[1]; 817 const GLchan b = ctx->Color.ClearColor[2]; 818 GLushort clearPixel; 819 PACK_RGB_565(clearPixel, r, g, b); 820 if (all) { 821 /* Clear whole RGB buffer */ 822 const GLuint n = osmesa->rowlength * osmesa->height; 823 GLushort *ptr2 = (GLushort *) osmesa->buffer; 824 GLuint i; 825 for (i = 0; i < n; i++) { 826 *ptr2 = clearPixel; 827 ptr2++; 828 } 829 } 830 else { 831 /* clear scissored region */ 832 GLint i, j; 833 for (i = 0; i < height; i++) { 834 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, (y + i)); 835 for (j = 0; j < width; j++) { 836 *ptr2 = clearPixel; 837 ptr2++; 838 } 839 } 840 } 841 } 842 else { 843#if CHAN_TYPE == GL_UNSIGNED_BYTE 844 /* 4-byte pixel value */ 845 GLuint clearPixel; 846 GLchan *clr = (GLchan *) &clearPixel; 847 clr[osmesa->rInd] = ctx->Color.ClearColor[0]; 848 clr[osmesa->gInd] = ctx->Color.ClearColor[1]; 849 clr[osmesa->bInd] = ctx->Color.ClearColor[2]; 850 clr[osmesa->aInd] = ctx->Color.ClearColor[3]; 851 if (all) { 852 /* Clear whole RGBA buffer */ 853 const GLuint n = osmesa->rowlength * osmesa->height; 854 GLuint *ptr4 = (GLuint *) osmesa->buffer; 855 GLuint i; 856 if (clearPixel) { 857 for (i = 0; i < n; i++) { 858 *ptr4++ = clearPixel; 859 } 860 } 861 else { 862 BZERO(ptr4, n * sizeof(GLuint)); 863 } 864 } 865 else { 866 /* Clear part of RGBA buffer */ 867 GLint i, j; 868 for (i = 0; i < height; i++) { 869 GLuint *ptr4 = (GLuint *) PIXELADDR4(x, (y + i)); 870 for (j = 0; j < width; j++) { 871 *ptr4++ = clearPixel; 872 } 873 } 874 } 875#else 876 const GLchan r = ctx->Color.ClearColor[0]; 877 const GLchan g = ctx->Color.ClearColor[1]; 878 const GLchan b = ctx->Color.ClearColor[2]; 879 const GLchan a = ctx->Color.ClearColor[3]; 880 if (all) { 881 /* Clear whole RGBA buffer */ 882 const GLuint n = osmesa->rowlength * osmesa->height; 883 GLchan *p = (GLchan *) osmesa->buffer; 884 GLuint i; 885 for (i = 0; i < n; i++) { 886 PACK_RGBA(p, r, g, b, a); 887 p += 4; 888 } 889 } 890 else { 891 /* Clear part of RGBA buffer */ 892 GLint i, j; 893 for (i = 0; i < height; i++) { 894 GLchan *p = PIXELADDR4(x, (y + i)); 895 for (j = 0; j < width; j++) { 896 PACK_RGBA(p, r, g, b, a); 897 p += 4; 898 } 899 } 900 } 901 902#endif 903 } 904 mask &= ~DD_FRONT_LEFT_BIT; 905 } 906 } 907 908 if (mask) 909 _swrast_Clear( ctx, mask, all, x, y, width, height ); 910} 911 912 913 914static void buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) 915{ 916 /* don't use GET_CURRENT_CONTEXT(ctx) here - it's a problem on Windows */ 917 GLcontext *ctx = (GLcontext *) _glapi_get_context(); 918 (void) buffer; 919 if (ctx) { 920 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 921 *width = osmesa->width; 922 *height = osmesa->height; 923 } 924} 925 926 927/**********************************************************************/ 928/***** Read/write spans/arrays of RGBA pixels *****/ 929/**********************************************************************/ 930 931/* Write RGBA pixels to an RGBA (or permuted) buffer. */ 932static void 933write_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y, 934 CONST GLchan rgba[][4], const GLubyte mask[] ) 935{ 936 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 937 GLchan *p = PIXELADDR4(x, y); 938 GLuint i; 939 if (mask) { 940 for (i = 0; i < n; i++, p += 4) { 941 if (mask[i]) { 942 PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP], 943 rgba[i][BCOMP], rgba[i][ACOMP]); 944 } 945 } 946 } 947 else { 948 for (i = 0; i < n; i++, p += 4) { 949 PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP], 950 rgba[i][BCOMP], rgba[i][ACOMP]); 951 } 952 } 953} 954 955 956/* Write RGBA pixels to an RGBA buffer. This is the fastest span-writer. */ 957static void 958write_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y, 959 CONST GLchan rgba[][4], const GLubyte mask[] ) 960{ 961 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 962 GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y); 963 const GLuint *rgba4 = (const GLuint *) rgba; 964 GLuint i; 965 ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE); 966 if (mask) { 967 for (i = 0; i < n; i++) { 968 if (mask[i]) { 969 ptr4[i] = rgba4[i]; 970 } 971 } 972 } 973 else { 974 MEMCPY( ptr4, rgba4, n * 4 ); 975 } 976} 977 978 979/* Write RGB pixels to an RGBA (or permuted) buffer. */ 980static void 981write_rgb_span( const GLcontext *ctx, GLuint n, GLint x, GLint y, 982 CONST GLchan rgb[][3], const GLubyte mask[] ) 983{ 984 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 985 GLchan *p = PIXELADDR4(x, y); 986 GLuint i; 987 if (mask) { 988 for (i = 0; i < n; i++, p+=4) { 989 if (mask[i]) { 990 PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX); 991 } 992 } 993 } 994 else { 995 for (i = 0; i < n; i++, p+=4) { 996 PACK_RGBA(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP], CHAN_MAX); 997 } 998 } 999} 1000 1001 1002 1003static void 1004write_monocolor_span( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1005 const GLchan color[4], const GLubyte mask[] ) 1006{ 1007 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1008 GLchan *p = PIXELADDR4(x, y); 1009 GLuint i; 1010 for (i = 0; i < n; i++, p += 4) { 1011 if (mask[i]) { 1012 PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]); 1013 } 1014 } 1015} 1016 1017 1018 1019static void 1020write_rgba_pixels( const GLcontext *ctx, GLuint n, 1021 const GLint x[], const GLint y[], 1022 CONST GLchan rgba[][4], const GLubyte mask[] ) 1023{ 1024 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1025 GLuint i; 1026 for (i = 0; i < n; i++) { 1027 if (mask[i]) { 1028 GLchan *p = PIXELADDR4(x[i], y[i]); 1029 PACK_RGBA(p, rgba[i][RCOMP], rgba[i][GCOMP], 1030 rgba[i][BCOMP], rgba[i][ACOMP]); 1031 } 1032 } 1033} 1034 1035 1036 1037static void 1038write_monocolor_pixels( const GLcontext *ctx, GLuint n, 1039 const GLint x[], const GLint y[], 1040 const GLchan color[4], const GLubyte mask[] ) 1041{ 1042 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1043 GLuint i; 1044 for (i = 0; i < n; i++) { 1045 if (mask[i]) { 1046 GLchan *p = PIXELADDR4(x[i], y[i]); 1047 PACK_RGBA(p, color[RCOMP], color[GCOMP], color[BCOMP], color[ACOMP]); 1048 } 1049 } 1050} 1051 1052 1053static void 1054read_rgba_span( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1055 GLchan rgba[][4] ) 1056{ 1057 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1058 GLuint i; 1059 GLchan *p = PIXELADDR4(x, y); 1060 for (i = 0; i < n; i++, p += 4) { 1061 rgba[i][RCOMP] = UNPACK_RED(p); 1062 rgba[i][GCOMP] = UNPACK_GREEN(p); 1063 rgba[i][BCOMP] = UNPACK_BLUE(p); 1064 rgba[i][ACOMP] = UNPACK_ALPHA(p); 1065 } 1066} 1067 1068 1069/* Read RGBA pixels from an RGBA buffer */ 1070static void 1071read_rgba_span_rgba( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1072 GLchan rgba[][4] ) 1073{ 1074 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1075 GLuint *ptr4 = (GLuint *) PIXELADDR4(x, y); 1076 MEMCPY( rgba, ptr4, n * 4 * sizeof(GLchan) ); 1077} 1078 1079 1080static void 1081read_rgba_pixels( const GLcontext *ctx, 1082 GLuint n, const GLint x[], const GLint y[], 1083 GLchan rgba[][4], const GLubyte mask[] ) 1084{ 1085 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1086 GLuint i; 1087 for (i = 0; i < n; i++) { 1088 if (mask[i]) { 1089 const GLchan *p = PIXELADDR4(x[i], y[i]); 1090 rgba[i][RCOMP] = UNPACK_RED(p); 1091 rgba[i][GCOMP] = UNPACK_GREEN(p); 1092 rgba[i][BCOMP] = UNPACK_BLUE(p); 1093 rgba[i][ACOMP] = UNPACK_ALPHA(p); 1094 } 1095 } 1096} 1097 1098/**********************************************************************/ 1099/***** 3 byte RGB pixel support funcs *****/ 1100/**********************************************************************/ 1101 1102/* Write RGBA pixels to an RGB buffer. */ 1103static void 1104write_rgba_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1105 CONST GLchan rgba[][4], const GLubyte mask[] ) 1106{ 1107 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1108 GLchan *p = PIXELADDR3(x, y); 1109 GLuint i; 1110 if (mask) { 1111 for (i = 0; i < n; i++, p += 3) { 1112 if (mask[i]) { 1113 PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1114 } 1115 } 1116 } 1117 else { 1118 for (i = 0; i < n; i++, p += 3) { 1119 PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1120 } 1121 } 1122} 1123 1124/* Write RGBA pixels to an BGR buffer. */ 1125static void 1126write_rgba_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1127 CONST GLchan rgba[][4], const GLubyte mask[] ) 1128{ 1129 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1130 GLchan *p = PIXELADDR3(x, y); 1131 GLuint i; 1132 if (mask) { 1133 for (i = 0; i < n; i++, p += 3) { 1134 if (mask[i]) { 1135 PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1136 } 1137 } 1138 } 1139 else { 1140 for (i = 0; i < n; i++, p += 3) { 1141 PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1142 } 1143 } 1144} 1145 1146/* Write RGB pixels to an RGB buffer. */ 1147static void 1148write_rgb_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1149 CONST GLchan rgb[][3], const GLubyte mask[] ) 1150{ 1151 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1152 GLchan *p = PIXELADDR3(x, y); 1153 GLuint i; 1154 if (mask) { 1155 for (i = 0; i < n; i++, p += 3) { 1156 if (mask[i]) { 1157 PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); 1158 } 1159 } 1160 } 1161 else { 1162 for (i = 0; i < n; i++, p += 3) { 1163 PACK_RGB(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); 1164 } 1165 } 1166} 1167 1168/* Write RGB pixels to an BGR buffer. */ 1169static void 1170write_rgb_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1171 CONST GLchan rgb[][3], const GLubyte mask[] ) 1172{ 1173 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1174 GLchan *p = PIXELADDR3(x, y); 1175 GLuint i; 1176 if (mask) { 1177 for (i = 0; i < n; i++, p += 3) { 1178 if (mask[i]) { 1179 PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); 1180 } 1181 } 1182 } 1183 else { 1184 for (i = 0; i < n; i++, p += 3) { 1185 PACK_BGR(p, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); 1186 } 1187 } 1188} 1189 1190 1191static void 1192write_monocolor_span_RGB( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1193 const GLchan color[4], const GLubyte mask[] ) 1194{ 1195 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1196 GLchan *p = PIXELADDR3(x, y); 1197 GLuint i; 1198 for (i = 0; i < n; i++, p += 3) { 1199 if (mask[i]) { 1200 PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]); 1201 } 1202 } 1203} 1204 1205static void 1206write_monocolor_span_BGR( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1207 const GLchan color[4], const GLubyte mask[] ) 1208{ 1209 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1210 GLchan *p = PIXELADDR3(x, y); 1211 GLuint i; 1212 for (i = 0; i < n; i++, p += 3) { 1213 if (mask[i]) { 1214 PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]); 1215 } 1216 } 1217} 1218 1219static void 1220write_rgba_pixels_RGB( const GLcontext *ctx, GLuint n, 1221 const GLint x[], const GLint y[], 1222 CONST GLchan rgba[][4], const GLubyte mask[] ) 1223{ 1224 const OSMesaContext osmesa = (const OSMesaContext) ctx; 1225 GLuint i; 1226 for (i = 0; i < n; i++) { 1227 if (mask[i]) { 1228 GLchan *p = PIXELADDR3(x[i], y[i]); 1229 PACK_RGB(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1230 } 1231 } 1232} 1233 1234static void 1235write_rgba_pixels_BGR( const GLcontext *ctx, GLuint n, 1236 const GLint x[], const GLint y[], 1237 CONST GLchan rgba[][4], const GLubyte mask[] ) 1238{ 1239 const OSMesaContext osmesa = (const OSMesaContext) ctx; 1240 GLuint i; 1241 for (i = 0; i < n; i++) { 1242 if (mask[i]) { 1243 GLchan *p = PIXELADDR3(x[i], y[i]); 1244 PACK_BGR(p, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1245 } 1246 } 1247} 1248 1249static void 1250write_monocolor_pixels_RGB( const GLcontext *ctx, 1251 GLuint n, const GLint x[], const GLint y[], 1252 const GLchan color[4], const GLubyte mask[] ) 1253{ 1254 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1255 GLuint i; 1256 for (i = 0; i < n; i++) { 1257 if (mask[i]) { 1258 GLchan *p = PIXELADDR3(x[i], y[i]); 1259 PACK_RGB(p, color[RCOMP], color[GCOMP], color[BCOMP]); 1260 } 1261 } 1262} 1263 1264static void 1265write_monocolor_pixels_BGR( const GLcontext *ctx, 1266 GLuint n, const GLint x[], const GLint y[], 1267 const GLchan color[4], const GLubyte mask[] ) 1268{ 1269 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1270 GLuint i; 1271 for (i = 0; i < n; i++) { 1272 if (mask[i]) { 1273 GLchan *p = PIXELADDR3(x[i], y[i]); 1274 PACK_BGR(p, color[RCOMP], color[GCOMP], color[BCOMP]); 1275 } 1276 } 1277} 1278 1279static void 1280read_rgba_span3( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1281 GLchan rgba[][4] ) 1282{ 1283 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1284 GLuint i; 1285 const GLchan *p = PIXELADDR3(x, y); 1286 for (i = 0; i < n; i++, p += 3) { 1287 rgba[i][RCOMP] = UNPACK_RED(p); 1288 rgba[i][GCOMP] = UNPACK_GREEN(p); 1289 rgba[i][BCOMP] = UNPACK_BLUE(p); 1290 rgba[i][ACOMP] = CHAN_MAX; 1291 } 1292} 1293 1294static void 1295read_rgba_pixels3( const GLcontext *ctx, 1296 GLuint n, const GLint x[], const GLint y[], 1297 GLchan rgba[][4], const GLubyte mask[] ) 1298{ 1299 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1300 GLuint i; 1301 for (i = 0; i < n; i++) { 1302 if (mask[i]) { 1303 const GLchan *p = PIXELADDR3(x[i], y[i]); 1304 rgba[i][RCOMP] = UNPACK_RED(p); 1305 rgba[i][GCOMP] = UNPACK_GREEN(p); 1306 rgba[i][BCOMP] = UNPACK_BLUE(p); 1307 rgba[i][ACOMP] = CHAN_MAX; 1308 } 1309 } 1310} 1311 1312 1313/**********************************************************************/ 1314/***** 2 byte RGB pixel support funcs *****/ 1315/**********************************************************************/ 1316 1317/* Write RGBA pixels to an RGB_565 buffer. */ 1318static void 1319write_rgba_span2( const GLcontext *ctx, 1320 GLuint n, GLint x, GLint y, 1321 CONST GLchan rgba[][4], const GLubyte mask[] ) 1322{ 1323 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1324 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y); 1325 GLuint i; 1326 if (mask) { 1327 for (i = 0; i < n; i++, ptr2++) { 1328 if (mask[i]) { 1329 PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1330 } 1331 } 1332 } 1333 else { 1334 for (i = 0; i < n; i++, ptr2++) { 1335 PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1336 } 1337 } 1338} 1339 1340 1341/* Write RGB pixels to an RGB_565 buffer. */ 1342static void 1343write_rgb_span2( const GLcontext *ctx, 1344 GLuint n, GLint x, GLint y, 1345 CONST GLchan rgb[][3], const GLubyte mask[] ) 1346{ 1347 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1348 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y); 1349 GLuint i; 1350 if (mask) { 1351 for (i = 0; i < n; i++, ptr2++) { 1352 if (mask[i]) { 1353 PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); 1354 } 1355 } 1356 } 1357 else { 1358 for (i = 0; i < n; i++, ptr2++) { 1359 PACK_RGB_565(*ptr2, rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); 1360 } 1361 } 1362} 1363 1364 1365static void 1366write_monocolor_span2( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1367 const GLchan color[4], const GLubyte mask[] ) 1368{ 1369 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1370 GLushort pixel; 1371 GLushort *ptr2 = (GLushort *) PIXELADDR2(x, y); 1372 GLuint i; 1373 PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]); 1374 for (i = 0; i < n; i++, ptr2++) { 1375 if (mask[i]) { 1376 *ptr2 = pixel; 1377 } 1378 } 1379} 1380 1381 1382static void 1383write_rgba_pixels2( const GLcontext *ctx, 1384 GLuint n, const GLint x[], const GLint y[], 1385 CONST GLchan rgba[][4], const GLubyte mask[] ) 1386{ 1387 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1388 GLuint i; 1389 for (i = 0; i < n; i++) { 1390 if (mask[i]) { 1391 GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]); 1392 PACK_RGB_565(*ptr2, rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); 1393 } 1394 } 1395} 1396 1397static void 1398write_monocolor_pixels2( const GLcontext *ctx, 1399 GLuint n, const GLint x[], const GLint y[], 1400 const GLchan color[4], const GLubyte mask[] ) 1401{ 1402 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1403 GLuint i; 1404 GLushort pixel; 1405 PACK_RGB_565(pixel, color[RCOMP], color[GCOMP], color[BCOMP]); 1406 for (i = 0; i < n; i++) { 1407 if (mask[i]) { 1408 GLushort *ptr2 = (GLushort *) PIXELADDR2(x[i],y[i]); 1409 *ptr2 = pixel; 1410 } 1411 } 1412} 1413 1414static void 1415read_rgba_span2( const GLcontext *ctx, 1416 GLuint n, GLint x, GLint y, 1417 GLchan rgba[][4] ) 1418{ 1419 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1420 GLuint i; 1421 const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x, y); 1422 for (i = 0; i < n; i++, ptr2++) { 1423 /* This should be fixed to get the low bits right */ 1424 rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFe; 1425 rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFc; 1426 rgba[i][BCOMP] = (*ptr2 << 3) & 0xFe; 1427 rgba[i][ACOMP] = 0; 1428 } 1429} 1430 1431static void 1432read_rgba_pixels2( const GLcontext *ctx, 1433 GLuint n, const GLint x[], const GLint y[], 1434 GLchan rgba[][4], const GLubyte mask[] ) 1435{ 1436 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1437 GLuint i; 1438 for (i = 0; i < n; i++) { 1439 if (mask[i]) { 1440 /* This should be fixed to get the low bits right */ 1441 const GLushort *ptr2 = (const GLushort *) PIXELADDR2(x[i],y[i]); 1442 rgba[i][RCOMP] = (*ptr2 >> 8) & 0xFE; 1443 rgba[i][GCOMP] = (*ptr2 >> 3) & 0xFC; 1444 rgba[i][BCOMP] = (*ptr2 << 3) & 0xFE; 1445 rgba[i][ACOMP] = 0; 1446 } 1447 } 1448} 1449 1450 1451 1452/**********************************************************************/ 1453/***** Read/write spans/arrays of CI pixels *****/ 1454/**********************************************************************/ 1455 1456/* Write 32-bit color index to buffer */ 1457static void 1458write_index32_span( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1459 const GLuint index[], const GLubyte mask[] ) 1460{ 1461 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1462 GLchan *ptr1 = PIXELADDR1(x, y); 1463 GLuint i; 1464 if (mask) { 1465 for (i=0;i<n;i++,ptr1++) { 1466 if (mask[i]) { 1467 *ptr1 = (GLchan) index[i]; 1468 } 1469 } 1470 } 1471 else { 1472 for (i=0;i<n;i++,ptr1++) { 1473 *ptr1 = (GLchan) index[i]; 1474 } 1475 } 1476} 1477 1478 1479/* Write 8-bit color index to buffer */ 1480static void 1481write_index8_span( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1482 const GLubyte index[], const GLubyte mask[] ) 1483{ 1484 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1485 GLchan *ptr1 = PIXELADDR1(x, y); 1486 GLuint i; 1487 if (mask) { 1488 for (i=0;i<n;i++,ptr1++) { 1489 if (mask[i]) { 1490 *ptr1 = (GLchan) index[i]; 1491 } 1492 } 1493 } 1494 else { 1495 MEMCPY(ptr1, index, n * sizeof(GLchan)); 1496 } 1497} 1498 1499 1500static void 1501write_monoindex_span( const GLcontext *ctx, GLuint n, GLint x, GLint y, 1502 GLuint colorIndex, const GLubyte mask[] ) 1503{ 1504 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1505 GLchan *ptr1 = PIXELADDR1(x, y); 1506 GLuint i; 1507 for (i=0;i<n;i++,ptr1++) { 1508 if (mask[i]) { 1509 *ptr1 = (GLchan) colorIndex; 1510 } 1511 } 1512} 1513 1514 1515static void 1516write_index_pixels( const GLcontext *ctx, 1517 GLuint n, const GLint x[], const GLint y[], 1518 const GLuint index[], const GLubyte mask[] ) 1519{ 1520 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1521 GLuint i; 1522 for (i=0;i<n;i++) { 1523 if (mask[i]) { 1524 GLchan *ptr1 = PIXELADDR1(x[i], y[i]); 1525 *ptr1 = (GLchan) index[i]; 1526 } 1527 } 1528} 1529 1530 1531static void 1532write_monoindex_pixels( const GLcontext *ctx, 1533 GLuint n, const GLint x[], const GLint y[], 1534 GLuint colorIndex, const GLubyte mask[] ) 1535{ 1536 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1537 GLuint i; 1538 for (i=0;i<n;i++) { 1539 if (mask[i]) { 1540 GLchan *ptr1 = PIXELADDR1(x[i], y[i]); 1541 *ptr1 = (GLchan) colorIndex; 1542 } 1543 } 1544} 1545 1546 1547static void 1548read_index_span( const GLcontext *ctx, 1549 GLuint n, GLint x, GLint y, GLuint index[] ) 1550{ 1551 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1552 GLuint i; 1553 const GLchan *ptr1 = (const GLchan *) PIXELADDR1(x, y); 1554 for (i=0;i<n;i++,ptr1++) { 1555 index[i] = (GLuint) *ptr1; 1556 } 1557} 1558 1559 1560static void 1561read_index_pixels( const GLcontext *ctx, 1562 GLuint n, const GLint x[], const GLint y[], 1563 GLuint index[], const GLubyte mask[] ) 1564{ 1565 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1566 GLuint i; 1567 for (i=0;i<n;i++) { 1568 if (mask[i] ) { 1569 const GLchan *ptr1 = PIXELADDR1(x[i], y[i]); 1570 index[i] = (GLuint) *ptr1; 1571 } 1572 } 1573} 1574 1575 1576 1577/**********************************************************************/ 1578/***** Optimized line rendering *****/ 1579/**********************************************************************/ 1580 1581 1582/* 1583 * Draw a flat-shaded, RGB line into an osmesa buffer. 1584 */ 1585static void 1586flat_rgba_line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) 1587{ 1588 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1589 const GLchan *color = vert1->color; 1590 1591#define INTERP_XY 1 1592#define CLIP_HACK 1 1593#define PLOT(X, Y) \ 1594do { \ 1595 GLchan *p = PIXELADDR4(X, Y); \ 1596 PACK_RGBA(p, color[0], color[1], color[2], color[3]); \ 1597} while (0) 1598 1599#ifdef WIN32 1600#include "..\swrast\s_linetemp.h" 1601#else 1602#include "swrast/s_linetemp.h" 1603#endif 1604} 1605 1606 1607/* 1608 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer. 1609 */ 1610static void 1611flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1) 1612{ 1613 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1614 const GLchan *color = vert1->color; 1615 1616#define INTERP_XY 1 1617#define INTERP_Z 1 1618#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1619#define CLIP_HACK 1 1620#define PLOT(X, Y) \ 1621do { \ 1622 if (Z < *zPtr) { \ 1623 GLchan *p = PIXELADDR4(X, Y); \ 1624 PACK_RGBA(p, color[RCOMP], color[GCOMP], \ 1625 color[BCOMP], color[ACOMP]); \ 1626 *zPtr = Z; \ 1627 } \ 1628} while (0) 1629 1630 1631#ifdef WIN32 1632#include "..\swrast\s_linetemp.h" 1633#else 1634#include "swrast/s_linetemp.h" 1635#endif 1636} 1637 1638 1639/* 1640 * Draw a flat-shaded, alpha-blended, RGB line into an osmesa buffer. 1641 * XXX update for GLchan 1642 */ 1643static void 1644flat_blend_rgba_line( GLcontext *ctx, 1645 const SWvertex *vert0, const SWvertex *vert1 ) 1646{ 1647 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1648 const GLint rshift = osmesa->rshift; 1649 const GLint gshift = osmesa->gshift; 1650 const GLint bshift = osmesa->bshift; 1651 const GLint avalue = vert0->color[3]; 1652 const GLint msavalue = CHAN_MAX - avalue; 1653 const GLint rvalue = vert1->color[0]*avalue; 1654 const GLint gvalue = vert1->color[1]*avalue; 1655 const GLint bvalue = vert1->color[2]*avalue; 1656 1657#define INTERP_XY 1 1658#define CLIP_HACK 1 1659#define PLOT(X,Y) \ 1660 { GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \ 1661 GLuint pixel = 0; \ 1662 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift);\ 1663 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift);\ 1664 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift);\ 1665 *ptr4 = pixel; \ 1666 } 1667 1668#if 0 /* XXX use this in the future */ 1669#define PLOT(X,Y) \ 1670 { \ 1671 GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \ 1672 pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \ 1673 pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \ 1674 pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \ 1675 pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \ 1676 } 1677#endif 1678 1679#ifdef WIN32 1680#include "..\swrast\s_linetemp.h" 1681#else 1682#include "swrast/s_linetemp.h" 1683#endif 1684} 1685 1686 1687/* 1688 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer. 1689 * But don't write to Z buffer. 1690 * XXX update for GLchan 1691 */ 1692static void 1693flat_blend_rgba_z_line( GLcontext *ctx, 1694 const SWvertex *vert0, const SWvertex *vert1 ) 1695{ 1696 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1697 const GLint rshift = osmesa->rshift; 1698 const GLint gshift = osmesa->gshift; 1699 const GLint bshift = osmesa->bshift; 1700 const GLint avalue = vert0->color[3]; 1701 const GLint msavalue = 256 - avalue; 1702 const GLint rvalue = vert1->color[0]*avalue; 1703 const GLint gvalue = vert1->color[1]*avalue; 1704 const GLint bvalue = vert1->color[2]*avalue; 1705 1706#define INTERP_XY 1 1707#define INTERP_Z 1 1708#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1709#define CLIP_HACK 1 1710#define PLOT(X,Y) \ 1711 if (Z < *zPtr) { \ 1712 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \ 1713 GLuint pixel = 0; \ 1714 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \ 1715 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \ 1716 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \ 1717 *ptr4 = pixel; \ 1718 } 1719 1720#if 0 /* XXX use this in the future */ 1721#define PLOT(X,Y) \ 1722 if (Z < *zPtr) { \ 1723 GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \ 1724 pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \ 1725 pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \ 1726 pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \ 1727 pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \ 1728 } 1729#endif 1730 1731#ifdef WIN32 1732#include "..\swrast\s_linetemp.h" 1733#else 1734#include "swrast/s_linetemp.h" 1735#endif 1736} 1737 1738 1739/* 1740 * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer. 1741 * XXX update for GLchan 1742 */ 1743static void 1744flat_blend_rgba_z_line_write( GLcontext *ctx, 1745 const SWvertex *vert0, const SWvertex *vert1 ) 1746{ 1747 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1748 const GLint rshift = osmesa->rshift; 1749 const GLint gshift = osmesa->gshift; 1750 const GLint bshift = osmesa->bshift; 1751 const GLint avalue = vert0->color[3]; 1752 const GLint msavalue = 256 - avalue; 1753 const GLint rvalue = vert1->color[0]*avalue; 1754 const GLint gvalue = vert1->color[1]*avalue; 1755 const GLint bvalue = vert1->color[2]*avalue; 1756 1757#define INTERP_XY 1 1758#define INTERP_Z 1 1759#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1760#define CLIP_HACK 1 1761#define PLOT(X,Y) \ 1762 if (Z < *zPtr) { \ 1763 GLuint *ptr4 = (GLuint *) PIXELADDR4(X, Y); \ 1764 GLuint pixel = 0; \ 1765 pixel |=((((((*ptr4) >> rshift) & 0xff)*msavalue+rvalue)>>8) << rshift); \ 1766 pixel |=((((((*ptr4) >> gshift) & 0xff)*msavalue+gvalue)>>8) << gshift); \ 1767 pixel |=((((((*ptr4) >> bshift) & 0xff)*msavalue+bvalue)>>8) << bshift); \ 1768 *ptr4 = pixel; \ 1769 *zPtr = Z; \ 1770 } 1771 1772#if 0 /* XXX use this in the future */ 1773#define PLOT(X,Y) \ 1774 if (Z < *zPtr) { \ 1775 GLchan *pixel = (GLchan *) PIXELADDR4(X, Y); \ 1776 pixel[rInd] = (pixel[rInd] * msavalue + rvalue) >> CHAN_BITS; \ 1777 pixel[gInd] = (pixel[gInd] * msavalue + gvalue) >> CHAN_BITS; \ 1778 pixel[bInd] = (pixel[bInd] * msavalue + bvalue) >> CHAN_BITS; \ 1779 pixel[aInd] = (pixel[aInd] * msavalue + avalue) >> CHAN_BITS; \ 1780 *zPtr = Z; \ 1781 } 1782#endif 1783 1784#ifdef WIN32 1785#include "..\swrast\s_linetemp.h" 1786#else 1787#include "swrast/s_linetemp.h" 1788#endif 1789} 1790 1791 1792/* 1793 * Analyze context state to see if we can provide a fast line drawing 1794 * function, like those in lines.c. Otherwise, return NULL. 1795 */ 1796static swrast_line_func 1797osmesa_choose_line_function( GLcontext *ctx ) 1798{ 1799 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1800 const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1801 1802 if (CHAN_BITS != 8) return NULL; 1803 if (ctx->RenderMode != GL_RENDER) return NULL; 1804 if (ctx->Line.SmoothFlag) return NULL; 1805 if (ctx->Texture._EnabledUnits) return NULL; 1806 if (ctx->Light.ShadeModel != GL_FLAT) return NULL; 1807 if (ctx->Line.Width != 1.0F) return NULL; 1808 if (ctx->Line.StippleFlag) return NULL; 1809 if (ctx->Line.SmoothFlag) return NULL; 1810 if (osmesa->format != OSMESA_RGBA && 1811 osmesa->format != OSMESA_BGRA && 1812 osmesa->format != OSMESA_ARGB) return NULL; 1813 1814 if (swrast->_RasterMask==DEPTH_BIT 1815 && ctx->Depth.Func==GL_LESS 1816 && ctx->Depth.Mask==GL_TRUE 1817 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { 1818 return (swrast_line_func) flat_rgba_z_line; 1819 } 1820 1821 if (swrast->_RasterMask == 0) { 1822 return (swrast_line_func) flat_rgba_line; 1823 } 1824 1825 if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT) 1826 && ctx->Depth.Func==GL_LESS 1827 && ctx->Depth.Mask==GL_TRUE 1828 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS 1829 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA 1830 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA 1831 && ctx->Color.BlendSrcA==GL_SRC_ALPHA 1832 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA 1833 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { 1834 return (swrast_line_func) flat_blend_rgba_z_line_write; 1835 } 1836 1837 if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT) 1838 && ctx->Depth.Func==GL_LESS 1839 && ctx->Depth.Mask==GL_FALSE 1840 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS 1841 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA 1842 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA 1843 && ctx->Color.BlendSrcA==GL_SRC_ALPHA 1844 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA 1845 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { 1846 return (swrast_line_func) flat_blend_rgba_z_line; 1847 } 1848 1849 if (swrast->_RasterMask==BLEND_BIT 1850 && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA 1851 && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA 1852 && ctx->Color.BlendSrcA==GL_SRC_ALPHA 1853 && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA 1854 && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { 1855 return (swrast_line_func) flat_blend_rgba_line; 1856 } 1857 1858 return (swrast_line_func) NULL; 1859} 1860 1861 1862/**********************************************************************/ 1863/***** Optimized triangle rendering *****/ 1864/**********************************************************************/ 1865 1866 1867/* 1868 * Smooth-shaded, z-less triangle, RGBA color. 1869 */ 1870static void smooth_rgba_z_triangle( GLcontext *ctx, 1871 const SWvertex *v0, 1872 const SWvertex *v1, 1873 const SWvertex *v2 ) 1874{ 1875 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1876 1877#define INTERP_Z 1 1878#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1879#define INTERP_RGB 1 1880#define INTERP_ALPHA 1 1881#define RENDER_SPAN( span ) \ 1882 GLuint i; \ 1883 GLchan *img = PIXELADDR4(span->x, span->y); \ 1884 for (i = 0; i < span->end; i++, img += 4) { \ 1885 const GLdepth z = FixedToDepth(span->z); \ 1886 if (z < zRow[i]) { \ 1887 PACK_RGBA(img, FixedToChan(span->red), \ 1888 FixedToChan(span->green), FixedToChan(span->blue), \ 1889 FixedToChan(span->alpha)); \ 1890 zRow[i] = z; \ 1891 } \ 1892 span->red += span->redStep; \ 1893 span->green += span->greenStep; \ 1894 span->blue += span->blueStep; \ 1895 span->alpha += span->alphaStep; \ 1896 span->z += span->zStep; \ 1897 } 1898 1899#ifdef WIN32 1900#include "..\swrast\s_tritemp.h" 1901#else 1902#include "swrast/s_tritemp.h" 1903#endif 1904} 1905 1906 1907 1908 1909/* 1910 * Flat-shaded, z-less triangle, RGBA color. 1911 */ 1912static void flat_rgba_z_triangle( GLcontext *ctx, 1913 const SWvertex *v0, 1914 const SWvertex *v1, 1915 const SWvertex *v2 ) 1916{ 1917 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1918#define INTERP_Z 1 1919#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 1920#define SETUP_CODE \ 1921 GLuint pixel; \ 1922 PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1], \ 1923 v2->color[2], v2->color[3]); 1924 1925#define RENDER_SPAN( span ) \ 1926 GLuint i; \ 1927 GLuint *img = (GLuint *) PIXELADDR4(span->x, span->y); \ 1928 for (i = 0; i < span->end; i++) { \ 1929 const GLdepth z = FixedToDepth(span->z); \ 1930 if (z < zRow[i]) { \ 1931 img[i] = pixel; \ 1932 zRow[i] = z; \ 1933 } \ 1934 span->z += span->zStep; \ 1935 } 1936 1937#ifdef WIN32 1938#include "..\swrast\s_tritemp.h" 1939#else 1940#include "swrast/s_tritemp.h" 1941#endif 1942} 1943 1944 1945 1946/* 1947 * Return pointer to an accelerated triangle function if possible. 1948 */ 1949static swrast_tri_func 1950osmesa_choose_triangle_function( GLcontext *ctx ) 1951{ 1952 const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 1953 const SWcontext *swrast = SWRAST_CONTEXT(ctx); 1954 1955 if (CHAN_BITS != 8) return (swrast_tri_func) NULL; 1956 if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL; 1957 if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL; 1958 if (ctx->Polygon.StippleFlag) return (swrast_tri_func) NULL; 1959 if (ctx->Texture._EnabledUnits) return (swrast_tri_func) NULL; 1960 if (osmesa->format != OSMESA_RGBA && 1961 osmesa->format != OSMESA_BGRA && 1962 osmesa->format != OSMESA_ARGB) return (swrast_tri_func) NULL; 1963 1964 if (swrast->_RasterMask == DEPTH_BIT && 1965 ctx->Depth.Func == GL_LESS && 1966 ctx->Depth.Mask == GL_TRUE && 1967 ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { 1968 if (ctx->Light.ShadeModel == GL_SMOOTH) { 1969 return (swrast_tri_func) smooth_rgba_z_triangle; 1970 } 1971 else { 1972 return (swrast_tri_func) flat_rgba_z_triangle; 1973 } 1974 } 1975 return (swrast_tri_func) NULL; 1976} 1977 1978 1979 1980/* Override for the swrast triangle-selection function. Try to use one 1981 * of our internal triangle functions, otherwise fall back to the 1982 * standard swrast functions. 1983 */ 1984static void osmesa_choose_triangle( GLcontext *ctx ) 1985{ 1986 SWcontext *swrast = SWRAST_CONTEXT(ctx); 1987 1988 swrast->Triangle = osmesa_choose_triangle_function( ctx ); 1989 if (!swrast->Triangle) 1990 _swrast_choose_triangle( ctx ); 1991} 1992 1993static void osmesa_choose_line( GLcontext *ctx ) 1994{ 1995 SWcontext *swrast = SWRAST_CONTEXT(ctx); 1996 1997 swrast->Line = osmesa_choose_line_function( ctx ); 1998 if (!swrast->Line) 1999 _swrast_choose_line( ctx ); 2000} 2001 2002 2003#define OSMESA_NEW_LINE (_NEW_LINE | \ 2004 _NEW_TEXTURE | \ 2005 _NEW_LIGHT | \ 2006 _NEW_DEPTH | \ 2007 _NEW_RENDERMODE | \ 2008 _SWRAST_NEW_RASTERMASK) 2009 2010#define OSMESA_NEW_TRIANGLE (_NEW_POLYGON | \ 2011 _NEW_TEXTURE | \ 2012 _NEW_LIGHT | \ 2013 _NEW_DEPTH | \ 2014 _NEW_RENDERMODE | \ 2015 _SWRAST_NEW_RASTERMASK) 2016 2017 2018/* Extend the software rasterizer with our line and triangle 2019 * functions. 2020 */ 2021static void osmesa_register_swrast_functions( GLcontext *ctx ) 2022{ 2023 SWcontext *swrast = SWRAST_CONTEXT( ctx ); 2024 2025 swrast->choose_line = osmesa_choose_line; 2026 swrast->choose_triangle = osmesa_choose_triangle; 2027 2028 swrast->invalidate_line |= OSMESA_NEW_LINE; 2029 swrast->invalidate_triangle |= OSMESA_NEW_TRIANGLE; 2030} 2031 2032 2033static const GLubyte *get_string( GLcontext *ctx, GLenum name ) 2034{ 2035 (void) ctx; 2036 switch (name) { 2037 case GL_RENDERER: 2038#if CHAN_BITS == 32 2039 return (const GLubyte *) "Mesa OffScreen32"; 2040#elif CHAN_BITS == 16 2041 return (const GLubyte *) "Mesa OffScreen16"; 2042#else 2043 return (const GLubyte *) "Mesa OffScreen"; 2044#endif 2045 default: 2046 return NULL; 2047 } 2048} 2049 2050 2051static void osmesa_update_state( GLcontext *ctx, GLuint new_state ) 2052{ 2053 OSMesaContext osmesa = OSMESA_CONTEXT(ctx); 2054 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); 2055 TNLcontext *tnl = TNL_CONTEXT(ctx); 2056 2057 ASSERT((void *) osmesa == (void *) ctx->DriverCtx); 2058 2059 /* 2060 * XXX these function pointers could be initialized just once during 2061 * context creation since they don't depend on any state changes. 2062 */ 2063 2064 ctx->Driver.GetString = get_string; 2065 ctx->Driver.UpdateState = osmesa_update_state; 2066 ctx->Driver.SetDrawBuffer = set_draw_buffer; 2067 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; 2068 ctx->Driver.GetBufferSize = buffer_size; 2069 2070 ctx->Driver.Accum = _swrast_Accum; 2071 ctx->Driver.Bitmap = _swrast_Bitmap; 2072 ctx->Driver.Clear = clear; 2073 ctx->Driver.CopyPixels = _swrast_CopyPixels; 2074 ctx->Driver.DrawPixels = _swrast_DrawPixels; 2075 ctx->Driver.ReadPixels = _swrast_ReadPixels; 2076 2077 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; 2078 ctx->Driver.TexImage1D = _mesa_store_teximage1d; 2079 ctx->Driver.TexImage2D = _mesa_store_teximage2d; 2080 ctx->Driver.TexImage3D = _mesa_store_teximage3d; 2081 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; 2082 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; 2083 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; 2084 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; 2085 2086 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; 2087 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; 2088 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; 2089 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; 2090 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; 2091 ctx->Driver.CopyColorTable = _swrast_CopyColorTable; 2092 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; 2093 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; 2094 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; 2095 2096 ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; 2097 ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; 2098 ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; 2099 2100 /* RGB(A) span/pixel functions */ 2101 if (osmesa->format == OSMESA_RGB) { 2102 swdd->WriteRGBASpan = write_rgba_span_RGB; 2103 swdd->WriteRGBSpan = write_rgb_span_RGB; 2104 swdd->WriteMonoRGBASpan = write_monocolor_span_RGB; 2105 swdd->WriteRGBAPixels = write_rgba_pixels_RGB; 2106 swdd->WriteMonoRGBAPixels = write_monocolor_pixels_RGB; 2107 swdd->ReadRGBASpan = read_rgba_span3; 2108 swdd->ReadRGBAPixels = read_rgba_pixels3; 2109 } 2110 else if (osmesa->format == OSMESA_BGR) { 2111 swdd->WriteRGBASpan = write_rgba_span_BGR; 2112 swdd->WriteRGBSpan = write_rgb_span_BGR; 2113 swdd->WriteMonoRGBASpan = write_monocolor_span_BGR; 2114 swdd->WriteRGBAPixels = write_rgba_pixels_BGR; 2115 swdd->WriteMonoRGBAPixels = write_monocolor_pixels_BGR; 2116 swdd->ReadRGBASpan = read_rgba_span3; 2117 swdd->ReadRGBAPixels = read_rgba_pixels3; 2118 } 2119 else if (osmesa->format == OSMESA_RGB_565) { 2120 swdd->WriteRGBASpan = write_rgba_span2; 2121 swdd->WriteRGBSpan = write_rgb_span2; 2122 swdd->WriteMonoRGBASpan = write_monocolor_span2; 2123 swdd->WriteRGBAPixels = write_rgba_pixels2; 2124 swdd->WriteMonoRGBAPixels = write_monocolor_pixels2; 2125 swdd->ReadRGBASpan = read_rgba_span2; 2126 swdd->ReadRGBAPixels = read_rgba_pixels2; 2127 } 2128 else { 2129 /* 4 GLchan / pixel in frame buffer */ 2130 swdd->WriteRGBSpan = write_rgb_span; 2131 swdd->WriteRGBAPixels = write_rgba_pixels; 2132 swdd->WriteMonoRGBASpan = write_monocolor_span; 2133 swdd->WriteMonoRGBAPixels = write_monocolor_pixels; 2134 if (osmesa->format == OSMESA_RGBA && 2135 CHAN_TYPE == GL_UNSIGNED_BYTE && 2136 RCOMP==0 && GCOMP==1 && BCOMP==2 && ACOMP==3) { 2137 /* special, fast case */ 2138 swdd->WriteRGBASpan = write_rgba_span_rgba; 2139 swdd->ReadRGBASpan = read_rgba_span_rgba; 2140 } 2141 else { 2142 swdd->WriteRGBASpan = write_rgba_span; 2143 swdd->ReadRGBASpan = read_rgba_span; 2144 } 2145 swdd->ReadRGBAPixels = read_rgba_pixels; 2146 } 2147 2148 /* CI span/pixel functions */ 2149 swdd->WriteCI32Span = write_index32_span; 2150 swdd->WriteCI8Span = write_index8_span; 2151 swdd->WriteMonoCISpan = write_monoindex_span; 2152 swdd->WriteCI32Pixels = write_index_pixels; 2153 swdd->WriteMonoCIPixels = write_monoindex_pixels; 2154 swdd->ReadCI32Span = read_index_span; 2155 swdd->ReadCI32Pixels = read_index_pixels; 2156 2157 swdd->SetReadBuffer = set_read_buffer; 2158 2159 tnl->Driver.RunPipeline = _tnl_run_pipeline; 2160 2161 _swrast_InvalidateState( ctx, new_state ); 2162 _swsetup_InvalidateState( ctx, new_state ); 2163 _ac_InvalidateState( ctx, new_state ); 2164 _tnl_InvalidateState( ctx, new_state ); 2165} 2166