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