xm_dd.c revision 1832f1cc86758fdcbd122edd5bf9e7a29ccade20
1/* $Id: xm_dd.c,v 1.23 2001/04/27 21:18:25 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28#include "glxheader.h" 29#include "context.h" 30#include "depth.h" 31#include "drawpix.h" 32#include "extensions.h" 33#include "macros.h" 34#include "mem.h" 35#include "mtypes.h" 36#include "state.h" 37#include "texstore.h" 38#include "texformat.h" 39#include "xmesaP.h" 40#include "array_cache/acache.h" 41#include "swrast/swrast.h" 42#include "swrast/s_alphabuf.h" 43#include "swrast_setup/swrast_setup.h" 44#include "tnl/tnl.h" 45#include "tnl/t_context.h" 46 47 48/* 49 * Return the size (width,height of the current color buffer. 50 * This function should be called by the glViewport function because 51 * glViewport is often called when the window gets resized. We need to 52 * update some X/Mesa stuff when that happens. 53 * Output: width - width of buffer in pixels. 54 * height - height of buffer in pixels. 55 */ 56static void 57get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height ) 58{ 59 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 60 unsigned int winwidth, winheight; 61#ifndef XFree86Server 62 Window root; 63 int winx, winy; 64 unsigned int bw, d; 65 66 _glthread_LOCK_MUTEX(_xmesa_lock); 67 XGetGeometry( xmesa->display, xmesa->xm_buffer->frontbuffer, &root, 68 &winx, &winy, &winwidth, &winheight, &bw, &d ); 69 _glthread_UNLOCK_MUTEX(_xmesa_lock); 70#else 71 72 winwidth = xmesa->xm_buffer->frontbuffer->width; 73 winheight = xmesa->xm_buffer->frontbuffer->height; 74#endif 75 76 *width = winwidth; 77 *height = winheight; 78 79 if ( winwidth!=xmesa->xm_buffer->width 80 || winheight!=xmesa->xm_buffer->height) { 81 xmesa->xm_buffer->width = winwidth; 82 xmesa->xm_buffer->height = winheight; 83 xmesa_alloc_back_buffer( xmesa->xm_buffer ); 84 } 85 86 /* Needed by FLIP macro */ 87 xmesa->xm_buffer->bottom = (int) winheight - 1; 88 89 if (xmesa->xm_buffer->backimage) { 90 /* Needed by PIXELADDR1 macro */ 91 xmesa->xm_buffer->ximage_width1 92 = xmesa->xm_buffer->backimage->bytes_per_line; 93 xmesa->xm_buffer->ximage_origin1 94 = (GLubyte *) xmesa->xm_buffer->backimage->data 95 + xmesa->xm_buffer->ximage_width1 * (winheight-1); 96 97 /* Needed by PIXELADDR2 macro */ 98 xmesa->xm_buffer->ximage_width2 99 = xmesa->xm_buffer->backimage->bytes_per_line / 2; 100 xmesa->xm_buffer->ximage_origin2 101 = (GLushort *) xmesa->xm_buffer->backimage->data 102 + xmesa->xm_buffer->ximage_width2 * (winheight-1); 103 104 /* Needed by PIXELADDR3 macro */ 105 xmesa->xm_buffer->ximage_width3 106 = xmesa->xm_buffer->backimage->bytes_per_line; 107 xmesa->xm_buffer->ximage_origin3 108 = (GLubyte *) xmesa->xm_buffer->backimage->data 109 + xmesa->xm_buffer->ximage_width3 * (winheight-1); 110 111 /* Needed by PIXELADDR4 macro */ 112 xmesa->xm_buffer->ximage_width4 = xmesa->xm_buffer->backimage->width; 113 xmesa->xm_buffer->ximage_origin4 114 = (GLuint *) xmesa->xm_buffer->backimage->data 115 + xmesa->xm_buffer->ximage_width4 * (winheight-1); 116 } 117} 118 119 120static void 121finish( GLcontext *ctx ) 122{ 123#ifdef XFree86Server 124 /* NOT_NEEDED */ 125#else 126 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 127 if (xmesa) { 128 _glthread_LOCK_MUTEX(_xmesa_lock); 129 XSync( xmesa->display, False ); 130 _glthread_UNLOCK_MUTEX(_xmesa_lock); 131 } 132#endif 133} 134 135 136static void 137flush( GLcontext *ctx ) 138{ 139#ifdef XFree86Server 140 /* NOT_NEEDED */ 141#else 142 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 143 if (xmesa) { 144 _glthread_LOCK_MUTEX(_xmesa_lock); 145 XFlush( xmesa->display ); 146 _glthread_UNLOCK_MUTEX(_xmesa_lock); 147 } 148#endif 149} 150 151 152 153 154static GLboolean 155set_draw_buffer( GLcontext *ctx, GLenum mode ) 156{ 157 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 158 if (mode == GL_FRONT_LEFT) { 159 /* write to front buffer */ 160 xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer; 161 xmesa_update_span_funcs(ctx); 162 return GL_TRUE; 163 } 164 else if (mode==GL_BACK_LEFT && xmesa->xm_buffer->db_state) { 165 /* write to back buffer */ 166 if (xmesa->xm_buffer->backpixmap) { 167 xmesa->xm_buffer->buffer = 168 (XMesaDrawable)xmesa->xm_buffer->backpixmap; 169 } 170 else if (xmesa->xm_buffer->backimage) { 171 xmesa->xm_buffer->buffer = None; 172 } 173 else { 174 /* just in case there wasn't enough memory for back buffer */ 175 xmesa->xm_buffer->buffer = xmesa->xm_buffer->frontbuffer; 176 } 177 xmesa_update_span_funcs(ctx); 178 return GL_TRUE; 179 } 180 else { 181 return GL_FALSE; 182 } 183} 184 185 186void 187xmesa_set_read_buffer( GLcontext *ctx, GLframebuffer *buffer, GLenum mode ) 188{ 189 XMesaBuffer target; 190 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 191 192 if (buffer == ctx->DrawBuffer) { 193 target = xmesa->xm_buffer; 194 xmesa->use_read_buffer = GL_FALSE; 195 } 196 else { 197 ASSERT(buffer == ctx->ReadBuffer); 198 target = xmesa->xm_read_buffer; 199 xmesa->use_read_buffer = GL_TRUE; 200 } 201 202 if (mode == GL_FRONT_LEFT) { 203 target->buffer = target->frontbuffer; 204 xmesa_update_span_funcs(ctx); 205 } 206 else if (mode==GL_BACK_LEFT && xmesa->xm_read_buffer->db_state) { 207 if (target->backpixmap) { 208 target->buffer = (XMesaDrawable)xmesa->xm_buffer->backpixmap; 209 } 210 else if (target->backimage) { 211 target->buffer = None; 212 } 213 else { 214 /* just in case there wasn't enough memory for back buffer */ 215 target->buffer = target->frontbuffer; 216 } 217 xmesa_update_span_funcs(ctx); 218 } 219 else { 220 _mesa_problem(ctx, "invalid buffer in set_read_buffer() in xmesa2.c"); 221 } 222} 223 224 225 226static void 227clear_index( GLcontext *ctx, GLuint index ) 228{ 229 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 230 xmesa->clearpixel = (unsigned long) index; 231 XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc, 232 (unsigned long) index ); 233} 234 235 236static void 237clear_color( GLcontext *ctx, const GLchan color[4] ) 238{ 239 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 240 xmesa->clearcolor[0] = color[0]; 241 xmesa->clearcolor[1] = color[1]; 242 xmesa->clearcolor[2] = color[2]; 243 xmesa->clearcolor[3] = color[3]; 244 xmesa->clearpixel = xmesa_color_to_pixel( xmesa, color[0], color[1], 245 color[2], color[3], 246 xmesa->xm_visual->undithered_pf ); 247 _glthread_LOCK_MUTEX(_xmesa_lock); 248 XMesaSetForeground( xmesa->display, xmesa->xm_buffer->cleargc, 249 xmesa->clearpixel ); 250 _glthread_UNLOCK_MUTEX(_xmesa_lock); 251} 252 253 254 255/* Set index mask ala glIndexMask */ 256static void 257index_mask( GLcontext *ctx, GLuint mask ) 258{ 259 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 260 if (xmesa->xm_buffer->buffer != XIMAGE) { 261 unsigned long m; 262 if (mask==0xffffffff) { 263 m = ((unsigned long)~0L); 264 } 265 else { 266 m = (unsigned long) mask; 267 } 268 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m ); 269 } 270} 271 272 273/* Implements glColorMask() */ 274static void 275color_mask(GLcontext *ctx, 276 GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask) 277{ 278 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 279 int xclass = GET_VISUAL_CLASS(xmesa->xm_visual); 280 (void) amask; 281 282 if (xmesa->xm_buffer->buffer != XIMAGE 283 && (xclass == TrueColor || xclass == DirectColor)) { 284 unsigned long m; 285 if (rmask && gmask && bmask) { 286 m = ((unsigned long)~0L); 287 } 288 else { 289 m = 0; 290 if (rmask) m |= GET_REDMASK(xmesa->xm_visual); 291 if (gmask) m |= GET_GREENMASK(xmesa->xm_visual); 292 if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual); 293 } 294 XMesaSetPlaneMask( xmesa->display, xmesa->xm_buffer->cleargc, m ); 295 } 296} 297 298 299 300/**********************************************************************/ 301/*** glClear implementations ***/ 302/**********************************************************************/ 303 304 305static void 306clear_front_pixmap( GLcontext *ctx, GLboolean all, 307 GLint x, GLint y, GLint width, GLint height ) 308{ 309 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 310 if (all) { 311 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer, 312 xmesa->xm_buffer->cleargc, 313 0, 0, 314 xmesa->xm_buffer->width+1, 315 xmesa->xm_buffer->height+1 ); 316 } 317 else { 318 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->frontbuffer, 319 xmesa->xm_buffer->cleargc, 320 x, xmesa->xm_buffer->height - y - height, 321 width, height ); 322 } 323} 324 325 326static void 327clear_back_pixmap( GLcontext *ctx, GLboolean all, 328 GLint x, GLint y, GLint width, GLint height ) 329{ 330 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 331 if (all) { 332 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap, 333 xmesa->xm_buffer->cleargc, 334 0, 0, 335 xmesa->xm_buffer->width+1, 336 xmesa->xm_buffer->height+1 ); 337 } 338 else { 339 XMesaFillRectangle( xmesa->display, xmesa->xm_buffer->backpixmap, 340 xmesa->xm_buffer->cleargc, 341 x, xmesa->xm_buffer->height - y - height, 342 width, height ); 343 } 344} 345 346 347static void 348clear_8bit_ximage( GLcontext *ctx, GLboolean all, 349 GLint x, GLint y, GLint width, GLint height ) 350{ 351 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 352 if (all) { 353 size_t n = xmesa->xm_buffer->backimage->bytes_per_line 354 * xmesa->xm_buffer->backimage->height; 355 MEMSET( xmesa->xm_buffer->backimage->data, xmesa->clearpixel, n ); 356 } 357 else { 358 GLint i; 359 for (i=0;i<height;i++) { 360 GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, y+i ); 361 MEMSET( ptr, xmesa->clearpixel, width ); 362 } 363 } 364} 365 366 367static void 368clear_HPCR_ximage( GLcontext *ctx, GLboolean all, 369 GLint x, GLint y, GLint width, GLint height ) 370{ 371 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 372 if (all) { 373 GLint i, c16 = (xmesa->xm_buffer->backimage->bytes_per_line>>4)<<4; 374 GLubyte *ptr = (GLubyte *)xmesa->xm_buffer->backimage->data; 375 for (i=0; i<xmesa->xm_buffer->backimage->height; i++) { 376 GLint j; 377 GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; 378 if (i&1) { 379 sptr += 16; 380 } 381 for (j=0; j<c16; j+=16) { 382 ptr[0] = sptr[0]; 383 ptr[1] = sptr[1]; 384 ptr[2] = sptr[2]; 385 ptr[3] = sptr[3]; 386 ptr[4] = sptr[4]; 387 ptr[5] = sptr[5]; 388 ptr[6] = sptr[6]; 389 ptr[7] = sptr[7]; 390 ptr[8] = sptr[8]; 391 ptr[9] = sptr[9]; 392 ptr[10] = sptr[10]; 393 ptr[11] = sptr[11]; 394 ptr[12] = sptr[12]; 395 ptr[13] = sptr[13]; 396 ptr[14] = sptr[14]; 397 ptr[15] = sptr[15]; 398 ptr += 16; 399 } 400 for (; j<xmesa->xm_buffer->backimage->bytes_per_line; j++) { 401 *ptr = sptr[j&15]; 402 ptr++; 403 } 404 } 405 } 406 else { 407 GLint i; 408 for (i=y; i<y+height; i++) { 409 GLubyte *ptr = PIXELADDR1( xmesa->xm_buffer, x, i ); 410 int j; 411 GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; 412 if (i&1) { 413 sptr += 16; 414 } 415 for (j=x; j<x+width; j++) { 416 *ptr = sptr[j&15]; 417 ptr++; 418 } 419 } 420 } 421} 422 423 424static void 425clear_16bit_ximage( GLcontext *ctx, GLboolean all, 426 GLint x, GLint y, GLint width, GLint height ) 427{ 428 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 429 register GLuint pixel = (GLuint) xmesa->clearpixel; 430 if (xmesa->swapbytes) { 431 pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00); 432 } 433 if (all) { 434 register GLuint n; 435 register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data; 436 if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) { 437 /* low and high bytes are equal so use memset() */ 438 n = xmesa->xm_buffer->backimage->bytes_per_line 439 * xmesa->xm_buffer->height; 440 MEMSET( ptr4, pixel & 0xff, n ); 441 } 442 else { 443 pixel = pixel | (pixel<<16); 444 n = xmesa->xm_buffer->backimage->bytes_per_line 445 * xmesa->xm_buffer->height / 4; 446 do { 447 *ptr4++ = pixel; 448 n--; 449 } while (n!=0); 450 451 if ((xmesa->xm_buffer->backimage->bytes_per_line * 452 xmesa->xm_buffer->height) & 0x2) 453 *(GLushort *)ptr4 = pixel & 0xffff; 454 } 455 } 456 else { 457 register int i, j; 458 for (j=0;j<height;j++) { 459 register GLushort *ptr2 = PIXELADDR2( xmesa->xm_buffer, x, y+j ); 460 for (i=0;i<width;i++) { 461 *ptr2++ = pixel; 462 } 463 } 464 } 465} 466 467 468/* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */ 469static void 470clear_24bit_ximage( GLcontext *ctx, GLboolean all, 471 GLint x, GLint y, GLint width, GLint height ) 472{ 473 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 474 const GLubyte r = xmesa->clearcolor[0]; 475 const GLubyte g = xmesa->clearcolor[1]; 476 const GLubyte b = xmesa->clearcolor[2]; 477 register GLuint clearPixel; 478 if (xmesa->swapbytes) { 479 clearPixel = (b << 16) | (g << 8) | r; 480 } 481 else { 482 clearPixel = (r << 16) | (g << 8) | b; 483 } 484 485 if (all) { 486 if (r==g && g==b) { 487 /* same value for all three components (gray) */ 488 const GLint w3 = xmesa->xm_buffer->width * 3; 489 const GLint h = xmesa->xm_buffer->height; 490 GLint i; 491 for (i = 0; i < h; i++) { 492 bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i); 493 MEMSET(ptr3, r, w3); 494 } 495 } 496 else { 497 /* the usual case */ 498 const GLint w = xmesa->xm_buffer->width; 499 const GLint h = xmesa->xm_buffer->height; 500 GLint i, j; 501 for (i = 0; i < h; i++) { 502 bgr_t *ptr3 = PIXELADDR3(xmesa->xm_buffer, 0, i); 503 for (j = 0; j < w; j++) { 504 ptr3->r = r; 505 ptr3->g = g; 506 ptr3->b = b; 507 ptr3++; 508 } 509 } 510#if 0 /* this code doesn't work for all window widths */ 511 register GLuint *ptr4 = (GLuint *) ptr3; 512 register GLuint px; 513 GLuint pixel4[3]; 514 register GLuint *p = pixel4; 515 pixel4[0] = clearPixel | (clearPixel << 24); 516 pixel4[1] = (clearPixel << 16) | (clearPixel >> 8); 517 pixel4[2] = (clearPixel << 8) | (clearPixel >> 16); 518 switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){ 519 case 0: 520 break; 521 case 1: 522 px = *ptr4 & 0x00ffffff; 523 px |= pixel4[0] & 0xff000000; 524 *ptr4++ = px; 525 px = *ptr4 & 0xffff0000; 526 px |= pixel4[2] & 0x0000ffff; 527 *ptr4 = px; 528 if (0 == --n) 529 break; 530 case 2: 531 px = *ptr4 & 0x0000fffff; 532 px |= pixel4[1] & 0xffff0000; 533 *ptr4++ = px; 534 px = *ptr4 & 0xffffff00; 535 px |= pixel4[2] & 0x000000ff; 536 *ptr4 = px; 537 if (0 == --n) 538 break; 539 case 3: 540 px = *ptr4 & 0x000000ff; 541 px |= pixel4[2] & 0xffffff00; 542 *ptr4++ = px; 543 --n; 544 break; 545 } 546 while (n > 3) { 547 p = pixel4; 548 *ptr4++ = *p++; 549 *ptr4++ = *p++; 550 *ptr4++ = *p++; 551 n -= 4; 552 } 553 switch (n) { 554 case 3: 555 p = pixel4; 556 *ptr4++ = *p++; 557 *ptr4++ = *p++; 558 px = *ptr4 & 0xffffff00; 559 px |= clearPixel & 0xff; 560 *ptr4 = px; 561 break; 562 case 2: 563 p = pixel4; 564 *ptr4++ = *p++; 565 px = *ptr4 & 0xffff0000; 566 px |= *p & 0xffff; 567 *ptr4 = px; 568 break; 569 case 1: 570 px = *ptr4 & 0xff000000; 571 px |= *p & 0xffffff; 572 *ptr4 = px; 573 break; 574 case 0: 575 break; 576 } 577#endif 578 } 579 } 580 else { 581 /* only clear subrect of color buffer */ 582 if (r==g && g==b) { 583 /* same value for all three components (gray) */ 584 GLint j; 585 for (j=0;j<height;j++) { 586 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j ); 587 MEMSET(ptr3, r, 3 * width); 588 } 589 } 590 else { 591 /* non-gray clear color */ 592 GLint i, j; 593 for (j = 0; j < height; j++) { 594 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j ); 595 for (i = 0; i < width; i++) { 596 ptr3->r = r; 597 ptr3->g = g; 598 ptr3->b = b; 599 ptr3++; 600 } 601 } 602#if 0 /* this code might not always (seems ptr3 always == ptr4) */ 603 GLint j; 604 GLuint pixel4[3]; 605 pixel4[0] = clearPixel | (clearPixel << 24); 606 pixel4[1] = (clearPixel << 16) | (clearPixel >> 8); 607 pixel4[2] = (clearPixel << 8) | (clearPixel >> 16); 608 for (j=0;j<height;j++) { 609 bgr_t *ptr3 = PIXELADDR3( xmesa->xm_buffer, x, y+j ); 610 register GLuint *ptr4 = (GLuint *)ptr3; 611 register GLuint *p, px; 612 GLuint w = width; 613 switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){ 614 case 0: 615 break; 616 case 1: 617 px = *ptr4 & 0x00ffffff; 618 px |= pixel4[0] & 0xff000000; 619 *ptr4++ = px; 620 px = *ptr4 & 0xffff0000; 621 px |= pixel4[2] & 0x0000ffff; 622 *ptr4 = px; 623 if (0 == --w) 624 break; 625 case 2: 626 px = *ptr4 & 0x0000fffff; 627 px |= pixel4[1] & 0xffff0000; 628 *ptr4++ = px; 629 px = *ptr4 & 0xffffff00; 630 px |= pixel4[2] & 0x000000ff; 631 *ptr4 = px; 632 if (0 == --w) 633 break; 634 case 3: 635 px = *ptr4 & 0x000000ff; 636 px |= pixel4[2] & 0xffffff00; 637 *ptr4++ = px; 638 --w; 639 break; 640 } 641 while (w > 3){ 642 p = pixel4; 643 *ptr4++ = *p++; 644 *ptr4++ = *p++; 645 *ptr4++ = *p++; 646 w -= 4; 647 } 648 switch (w) { 649 case 3: 650 p = pixel4; 651 *ptr4++ = *p++; 652 *ptr4++ = *p++; 653 px = *ptr4 & 0xffffff00; 654 px |= *p & 0xff; 655 *ptr4 = px; 656 break; 657 case 2: 658 p = pixel4; 659 *ptr4++ = *p++; 660 px = *ptr4 & 0xffff0000; 661 px |= *p & 0xffff; 662 *ptr4 = px; 663 break; 664 case 1: 665 px = *ptr4 & 0xff000000; 666 px |= pixel4[0] & 0xffffff; 667 *ptr4 = px; 668 break; 669 case 0: 670 break; 671 } 672 } 673#endif 674 } 675 } 676} 677 678 679static void 680clear_32bit_ximage( GLcontext *ctx, GLboolean all, 681 GLint x, GLint y, GLint width, GLint height ) 682{ 683 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 684 register GLuint pixel = (GLuint) xmesa->clearpixel; 685 if (xmesa->swapbytes) { 686 pixel = ((pixel >> 24) & 0x000000ff) 687 | ((pixel >> 8) & 0x0000ff00) 688 | ((pixel << 8) & 0x00ff0000) 689 | ((pixel << 24) & 0xff000000); 690 } 691 if (all) { 692 register GLint n = xmesa->xm_buffer->width * xmesa->xm_buffer->height; 693 register GLuint *ptr4 = (GLuint *) xmesa->xm_buffer->backimage->data; 694 if (pixel==0) { 695 MEMSET( ptr4, pixel, 4*n ); 696 } 697 else { 698 do { 699 *ptr4++ = pixel; 700 n--; 701 } while (n!=0); 702 } 703 } 704 else { 705 register int i, j; 706 for (j=0;j<height;j++) { 707 register GLuint *ptr4 = PIXELADDR4( xmesa->xm_buffer, x, y+j ); 708 for (i=0;i<width;i++) { 709 *ptr4++ = pixel; 710 } 711 } 712 } 713} 714 715 716static void 717clear_nbit_ximage( GLcontext *ctx, GLboolean all, 718 GLint x, GLint y, GLint width, GLint height ) 719{ 720 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 721 XMesaImage *img = xmesa->xm_buffer->backimage; 722 if (all) { 723 register int i, j; 724 width = xmesa->xm_buffer->width; 725 height = xmesa->xm_buffer->height; 726 for (j=0;j<height;j++) { 727 for (i=0;i<width;i++) { 728 XMesaPutPixel( img, i, j, xmesa->clearpixel ); 729 } 730 } 731 } 732 else { 733 /* TODO: optimize this */ 734 register int i, j; 735 y = FLIP(xmesa->xm_buffer, y); 736 for (j=0;j<height;j++) { 737 for (i=0;i<width;i++) { 738 XMesaPutPixel( img, x+i, y-j, xmesa->clearpixel ); 739 } 740 } 741 } 742} 743 744 745 746static void 747clear_buffers( GLcontext *ctx, GLbitfield mask, 748 GLboolean all, GLint x, GLint y, GLint width, GLint height ) 749{ 750 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 751 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; 752 753 if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) && 754 xmesa->xm_buffer->mesa_buffer.UseSoftwareAlphaBuffers && 755 ctx->Color.ColorMask[ACOMP]) { 756 _mesa_clear_alpha_buffers(ctx); 757 } 758 759 /* we can't handle color or index masking */ 760 if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { 761 if (mask & DD_FRONT_LEFT_BIT) { 762 ASSERT(xmesa->xm_buffer->front_clear_func); 763 (*xmesa->xm_buffer->front_clear_func)( ctx, all, x, y, width, height ); 764 mask &= ~DD_FRONT_LEFT_BIT; 765 } 766 if (mask & DD_BACK_LEFT_BIT) { 767 ASSERT(xmesa->xm_buffer->back_clear_func); 768 (*xmesa->xm_buffer->back_clear_func)( ctx, all, x, y, width, height ); 769 mask &= ~DD_BACK_LEFT_BIT; 770 } 771 } 772 773 if (mask) 774 _swrast_Clear( ctx, mask, all, x, y, width, height ); 775} 776 777 778static void 779resize_buffers( GLcontext *ctx ) 780{ 781 _swrast_alloc_buffers( ctx ); 782} 783 784#if 0 785/* 786 * This function implements glDrawPixels() with an XPutImage call when 787 * drawing to the front buffer (X Window drawable). 788 * The image format must be GL_BGRA to match the PF_8R8G8B pixel format. 789 * XXX top/bottom edge clipping is broken! 790 */ 791static GLboolean 792drawpixels_8R8G8B( GLcontext *ctx, 793 GLint x, GLint y, GLsizei width, GLsizei height, 794 GLenum format, GLenum type, 795 const struct gl_pixelstore_attrib *unpack, 796 const GLvoid *pixels ) 797{ 798 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 799 XMesaDisplay *dpy = xmesa->xm_visual->display; 800 XMesaDrawable buffer = xmesa->xm_buffer->buffer; 801 XMesaGC gc = xmesa->xm_buffer->gc; 802 assert(dpy); 803 assert(buffer); 804 assert(gc); 805 806 /* XXX also check for pixel scale/bias/lookup/zooming! */ 807 if (format == GL_BGRA && type == GL_UNSIGNED_BYTE) { 808 int dstX = x; 809 int dstY = y; 810 int w = width; 811 int h = height; 812 int srcX = unpack->SkipPixels; 813 int srcY = unpack->SkipRows; 814 if (_mesa_clip_pixelrect(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) { 815 XMesaImage ximage; 816 MEMSET(&ximage, 0, sizeof(XMesaImage)); 817 ximage.width = width; 818 ximage.height = height; 819 ximage.format = ZPixmap; 820 ximage.data = (char *) pixels + (height - 1) * width * 4; 821 ximage.byte_order = LSBFirst; 822 ximage.bitmap_unit = 32; 823 ximage.bitmap_bit_order = LSBFirst; 824 ximage.bitmap_pad = 32; 825 ximage.depth = 24; 826 ximage.bytes_per_line = -width * 4; 827 ximage.bits_per_pixel = 32; 828 ximage.red_mask = 0xff0000; 829 ximage.green_mask = 0x00ff00; 830 ximage.blue_mask = 0x0000ff; 831 dstY = FLIP(xmesa->xm_buffer,dstY) - height + 1; 832 XPutImage(dpy, buffer, gc, &ximage, srcX, srcY, dstX, dstY, w, h); 833 return GL_TRUE; 834 } 835 } 836 return GL_FALSE; 837} 838#endif 839 840 841 842static const GLubyte * 843get_string( GLcontext *ctx, GLenum name ) 844{ 845 (void) ctx; 846 switch (name) { 847 case GL_RENDERER: 848#ifdef XFree86Server 849 return (const GLubyte *) "Mesa GLX Indirect"; 850#else 851 return (const GLubyte *) "Mesa X11"; 852#endif 853 case GL_VENDOR: 854#ifdef XFree86Server 855 return (const GLubyte *) "VA Linux Systems, Inc."; 856#else 857 return NULL; 858#endif 859 default: 860 return NULL; 861 } 862} 863 864 865static void 866enable( GLcontext *ctx, GLenum pname, GLboolean state ) 867{ 868 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 869 870 switch (pname) { 871 case GL_DITHER: 872 if (state) 873 xmesa->pixelformat = xmesa->xm_visual->dithered_pf; 874 else 875 xmesa->pixelformat = xmesa->xm_visual->undithered_pf; 876 break; 877 default: 878 ; /* silence compiler warning */ 879 } 880} 881 882 883void xmesa_update_state( GLcontext *ctx, GLuint new_state ) 884{ 885 const XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; 886 887 /* Propogate statechange information to swrast and swrast_setup 888 * modules. The X11 driver has no internal GL-dependent state. 889 */ 890 _swrast_InvalidateState( ctx, new_state ); 891 _ac_InvalidateState( ctx, new_state ); 892 _tnl_InvalidateState( ctx, new_state ); 893 _swsetup_InvalidateState( ctx, new_state ); 894 895 896 /* setup pointers to front and back buffer clear functions */ 897 xmesa->xm_buffer->front_clear_func = clear_front_pixmap; 898 if (xmesa->xm_buffer->backpixmap != XIMAGE) { 899 xmesa->xm_buffer->back_clear_func = clear_back_pixmap; 900 } 901 else if (sizeof(GLushort)!=2 || sizeof(GLuint)!=4) { 902 xmesa->xm_buffer->back_clear_func = clear_nbit_ximage; 903 } 904 else switch (xmesa->xm_visual->BitsPerPixel) { 905 case 8: 906 if (xmesa->xm_visual->hpcr_clear_flag) { 907 xmesa->xm_buffer->back_clear_func = clear_HPCR_ximage; 908 } 909 else { 910 xmesa->xm_buffer->back_clear_func = clear_8bit_ximage; 911 } 912 break; 913 case 16: 914 xmesa->xm_buffer->back_clear_func = clear_16bit_ximage; 915 break; 916 case 24: 917 xmesa->xm_buffer->back_clear_func = clear_24bit_ximage; 918 break; 919 case 32: 920 xmesa->xm_buffer->back_clear_func = clear_32bit_ximage; 921 break; 922 default: 923 xmesa->xm_buffer->back_clear_func = clear_nbit_ximage; 924 break; 925 } 926 927 xmesa_update_span_funcs(ctx); 928} 929 930 931 932/* Setup pointers and other driver state that is constant for the life 933 * of a context. 934 */ 935void xmesa_init_pointers( GLcontext *ctx ) 936{ 937 TNLcontext *tnl; 938 939 ctx->Driver.GetString = get_string; 940 ctx->Driver.GetBufferSize = get_buffer_size; 941 ctx->Driver.Flush = flush; 942 ctx->Driver.Finish = finish; 943 944 /* Software rasterizer pixel paths: 945 */ 946 ctx->Driver.Accum = _swrast_Accum; 947 ctx->Driver.Bitmap = _swrast_Bitmap; 948 ctx->Driver.Clear = clear_buffers; 949 ctx->Driver.ResizeBuffersMESA = resize_buffers; 950 ctx->Driver.CopyPixels = _swrast_CopyPixels; 951 ctx->Driver.DrawPixels = _swrast_DrawPixels; 952 ctx->Driver.ReadPixels = _swrast_ReadPixels; 953 954 /* Software texture functions: 955 */ 956 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; 957 ctx->Driver.TexImage1D = _mesa_store_teximage1d; 958 ctx->Driver.TexImage2D = _mesa_store_teximage2d; 959 ctx->Driver.TexImage3D = _mesa_store_teximage3d; 960 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; 961 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; 962 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; 963 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; 964 965 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; 966 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; 967 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; 968 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; 969 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; 970 971 972 /* Swrast hooks for imaging extensions: 973 */ 974 ctx->Driver.CopyColorTable = _swrast_CopyColorTable; 975 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; 976 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; 977 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; 978 979 980 /* Statechange callbacks: 981 */ 982 ctx->Driver.SetDrawBuffer = set_draw_buffer; 983 ctx->Driver.ClearIndex = clear_index; 984 ctx->Driver.ClearColor = clear_color; 985 ctx->Driver.IndexMask = index_mask; 986 ctx->Driver.ColorMask = color_mask; 987 ctx->Driver.Enable = enable; 988 989 990 /* Initialize the TNL driver interface: 991 */ 992 tnl = TNL_CONTEXT(ctx); 993 tnl->Driver.RenderStart = _swsetup_RenderStart; 994 tnl->Driver.RenderFinish = _swsetup_RenderFinish; 995 tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices; 996 tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive; 997 tnl->Driver.PointsFunc = _swsetup_Points; 998 tnl->Driver.LineFunc = _swsetup_Line; 999 tnl->Driver.TriangleFunc = _swsetup_Triangle; 1000 tnl->Driver.QuadFunc = _swsetup_Quad; 1001 tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple; 1002 tnl->Driver.RenderInterp = _swsetup_RenderInterp; 1003 tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV; 1004 tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine; 1005 tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon; 1006 1007 (void) DitherValues; /* silenced unused var warning */ 1008} 1009