imports.c revision 9d9afe9393fde99858ddf40e478bc16cf44e60dc
1/** 2 * \file imports.c 3 * Standard C library function wrappers. 4 * 5 * Imports are services which the device driver or window system or 6 * operating system provides to the core renderer. The core renderer (Mesa) 7 * will call these functions in order to do memory allocation, simple I/O, 8 * etc. 9 * 10 * Some drivers will want to override/replace this file with something 11 * specialized, but that'll be rare. 12 * 13 * Eventually, I want to move roll the glheader.h file into this. 14 * 15 * \todo Functions still needed: 16 * - scanf 17 * - qsort 18 * - rand and RAND_MAX 19 */ 20 21/* 22 * Mesa 3-D graphics library 23 * Version: 7.1 24 * 25 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 26 * 27 * Permission is hereby granted, free of charge, to any person obtaining a 28 * copy of this software and associated documentation files (the "Software"), 29 * to deal in the Software without restriction, including without limitation 30 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 31 * and/or sell copies of the Software, and to permit persons to whom the 32 * Software is furnished to do so, subject to the following conditions: 33 * 34 * The above copyright notice and this permission notice shall be included 35 * in all copies or substantial portions of the Software. 36 * 37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 38 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 40 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 41 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 42 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 43 */ 44 45 46 47#include "imports.h" 48#include "context.h" 49#include "version.h" 50 51#ifdef _GNU_SOURCE 52#include <locale.h> 53#ifdef __APPLE__ 54#include <xlocale.h> 55#endif 56#endif 57 58 59#define MAXSTRING 4000 /* for vsnprintf() */ 60 61#ifdef WIN32 62#define vsnprintf _vsnprintf 63#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 ) 64extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg); 65#ifdef __VMS 66#include "vsnprintf.c" 67#endif 68#endif 69 70/**********************************************************************/ 71/** \name Memory */ 72/*@{*/ 73 74/** Wrapper around malloc() */ 75void * 76_mesa_malloc(size_t bytes) 77{ 78 return malloc(bytes); 79} 80 81/** Wrapper around calloc() */ 82void * 83_mesa_calloc(size_t bytes) 84{ 85 return calloc(1, bytes); 86} 87 88/** Wrapper around free() */ 89void 90_mesa_free(void *ptr) 91{ 92 free(ptr); 93} 94 95/** 96 * Allocate aligned memory. 97 * 98 * \param bytes number of bytes to allocate. 99 * \param alignment alignment (must be greater than zero). 100 * 101 * Allocates extra memory to accommodate rounding up the address for 102 * alignment and to record the real malloc address. 103 * 104 * \sa _mesa_align_free(). 105 */ 106void * 107_mesa_align_malloc(size_t bytes, unsigned long alignment) 108{ 109#if defined(HAVE_POSIX_MEMALIGN) 110 void *mem; 111 int err = posix_memalign(& mem, alignment, bytes); 112 (void) err; 113 return mem; 114#elif defined(_WIN32) && defined(_MSC_VER) 115 return _aligned_malloc(bytes, alignment); 116#else 117 uintptr_t ptr, buf; 118 119 ASSERT( alignment > 0 ); 120 121 ptr = (uintptr_t) _mesa_malloc(bytes + alignment + sizeof(void *)); 122 if (!ptr) 123 return NULL; 124 125 buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); 126 *(uintptr_t *)(buf - sizeof(void *)) = ptr; 127 128#ifdef DEBUG 129 /* mark the non-aligned area */ 130 while ( ptr < buf - sizeof(void *) ) { 131 *(unsigned long *)ptr = 0xcdcdcdcd; 132 ptr += sizeof(unsigned long); 133 } 134#endif 135 136 return (void *) buf; 137#endif /* defined(HAVE_POSIX_MEMALIGN) */ 138} 139 140/** 141 * Same as _mesa_align_malloc(), but using _mesa_calloc() instead of 142 * _mesa_malloc() 143 */ 144void * 145_mesa_align_calloc(size_t bytes, unsigned long alignment) 146{ 147#if defined(HAVE_POSIX_MEMALIGN) 148 void *mem; 149 150 mem = _mesa_align_malloc(bytes, alignment); 151 if (mem != NULL) { 152 (void) memset(mem, 0, bytes); 153 } 154 155 return mem; 156#elif defined(_WIN32) && defined(_MSC_VER) 157 void *mem; 158 159 mem = _aligned_malloc(bytes, alignment); 160 if (mem != NULL) { 161 (void) memset(mem, 0, bytes); 162 } 163 164 return mem; 165#else 166 uintptr_t ptr, buf; 167 168 ASSERT( alignment > 0 ); 169 170 ptr = (uintptr_t) _mesa_calloc(bytes + alignment + sizeof(void *)); 171 if (!ptr) 172 return NULL; 173 174 buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1); 175 *(uintptr_t *)(buf - sizeof(void *)) = ptr; 176 177#ifdef DEBUG 178 /* mark the non-aligned area */ 179 while ( ptr < buf - sizeof(void *) ) { 180 *(unsigned long *)ptr = 0xcdcdcdcd; 181 ptr += sizeof(unsigned long); 182 } 183#endif 184 185 return (void *)buf; 186#endif /* defined(HAVE_POSIX_MEMALIGN) */ 187} 188 189/** 190 * Free memory which was allocated with either _mesa_align_malloc() 191 * or _mesa_align_calloc(). 192 * \param ptr pointer to the memory to be freed. 193 * The actual address to free is stored in the word immediately before the 194 * address the client sees. 195 */ 196void 197_mesa_align_free(void *ptr) 198{ 199#if defined(HAVE_POSIX_MEMALIGN) 200 free(ptr); 201#elif defined(_WIN32) && defined(_MSC_VER) 202 _aligned_free(ptr); 203#else 204 void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); 205 void *realAddr = *cubbyHole; 206 _mesa_free(realAddr); 207#endif /* defined(HAVE_POSIX_MEMALIGN) */ 208} 209 210/** 211 * Reallocate memory, with alignment. 212 */ 213void * 214_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize, 215 unsigned long alignment) 216{ 217#if defined(_WIN32) && defined(_MSC_VER) 218 (void) oldSize; 219 return _aligned_realloc(oldBuffer, newSize, alignment); 220#else 221 const size_t copySize = (oldSize < newSize) ? oldSize : newSize; 222 void *newBuf = _mesa_align_malloc(newSize, alignment); 223 if (newBuf && oldBuffer && copySize > 0) { 224 _mesa_memcpy(newBuf, oldBuffer, copySize); 225 } 226 if (oldBuffer) 227 _mesa_align_free(oldBuffer); 228 return newBuf; 229#endif 230} 231 232 233 234/** Reallocate memory */ 235void * 236_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize) 237{ 238 const size_t copySize = (oldSize < newSize) ? oldSize : newSize; 239 void *newBuffer = _mesa_malloc(newSize); 240 if (newBuffer && oldBuffer && copySize > 0) 241 _mesa_memcpy(newBuffer, oldBuffer, copySize); 242 if (oldBuffer) 243 _mesa_free(oldBuffer); 244 return newBuffer; 245} 246 247/** memcpy wrapper */ 248void * 249_mesa_memcpy(void *dest, const void *src, size_t n) 250{ 251#if defined(SUNOS4) 252 return memcpy((char *) dest, (char *) src, (int) n); 253#else 254 return memcpy(dest, src, n); 255#endif 256} 257 258/** Wrapper around memset() */ 259void 260_mesa_memset( void *dst, int val, size_t n ) 261{ 262#if defined(SUNOS4) 263 memset( (char *) dst, (int) val, (int) n ); 264#else 265 memset(dst, val, n); 266#endif 267} 268 269/** 270 * Fill memory with a constant 16bit word. 271 * \param dst destination pointer. 272 * \param val value. 273 * \param n number of words. 274 */ 275void 276_mesa_memset16( unsigned short *dst, unsigned short val, size_t n ) 277{ 278 while (n-- > 0) 279 *dst++ = val; 280} 281 282/** Wrapper around either memset() or bzero() */ 283void 284_mesa_bzero( void *dst, size_t n ) 285{ 286#if defined(__FreeBSD__) 287 bzero( dst, n ); 288#else 289 memset( dst, 0, n ); 290#endif 291} 292 293/** Wrapper around memcmp() */ 294int 295_mesa_memcmp( const void *s1, const void *s2, size_t n ) 296{ 297#if defined(SUNOS4) 298 return memcmp( (char *) s1, (char *) s2, (int) n ); 299#else 300 return memcmp(s1, s2, n); 301#endif 302} 303 304/*@}*/ 305 306 307/**********************************************************************/ 308/** \name Math */ 309/*@{*/ 310 311/** Wrapper around sin() */ 312double 313_mesa_sin(double a) 314{ 315 return sin(a); 316} 317 318/** Single precision wrapper around sin() */ 319float 320_mesa_sinf(float a) 321{ 322 return (float) sin((double) a); 323} 324 325/** Wrapper around cos() */ 326double 327_mesa_cos(double a) 328{ 329 return cos(a); 330} 331 332/** Single precision wrapper around asin() */ 333float 334_mesa_asinf(float x) 335{ 336 return (float) asin((double) x); 337} 338 339/** Single precision wrapper around atan() */ 340float 341_mesa_atanf(float x) 342{ 343 return (float) atan((double) x); 344} 345 346/** Wrapper around sqrt() */ 347double 348_mesa_sqrtd(double x) 349{ 350 return sqrt(x); 351} 352 353 354/* 355 * A High Speed, Low Precision Square Root 356 * by Paul Lalonde and Robert Dawson 357 * from "Graphics Gems", Academic Press, 1990 358 * 359 * SPARC implementation of a fast square root by table 360 * lookup. 361 * SPARC floating point format is as follows: 362 * 363 * BIT 31 30 23 22 0 364 * sign exponent mantissa 365 */ 366static short sqrttab[0x100]; /* declare table of square roots */ 367 368void 369_mesa_init_sqrt_table(void) 370{ 371#if defined(USE_IEEE) && !defined(DEBUG) 372 unsigned short i; 373 fi_type fi; /* to access the bits of a float in C quickly */ 374 /* we use a union defined in glheader.h */ 375 376 for(i=0; i<= 0x7f; i++) { 377 fi.i = 0; 378 379 /* 380 * Build a float with the bit pattern i as mantissa 381 * and an exponent of 0, stored as 127 382 */ 383 384 fi.i = (i << 16) | (127 << 23); 385 fi.f = _mesa_sqrtd(fi.f); 386 387 /* 388 * Take the square root then strip the first 7 bits of 389 * the mantissa into the table 390 */ 391 392 sqrttab[i] = (fi.i & 0x7fffff) >> 16; 393 394 /* 395 * Repeat the process, this time with an exponent of 396 * 1, stored as 128 397 */ 398 399 fi.i = 0; 400 fi.i = (i << 16) | (128 << 23); 401 fi.f = sqrt(fi.f); 402 sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16; 403 } 404#else 405 (void) sqrttab; /* silence compiler warnings */ 406#endif /*HAVE_FAST_MATH*/ 407} 408 409 410/** 411 * Single precision square root. 412 */ 413float 414_mesa_sqrtf( float x ) 415{ 416#if defined(USE_IEEE) && !defined(DEBUG) 417 fi_type num; 418 /* to access the bits of a float in C 419 * we use a union from glheader.h */ 420 421 short e; /* the exponent */ 422 if (x == 0.0F) return 0.0F; /* check for square root of 0 */ 423 num.f = x; 424 e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */ 425 /* exponent is stored with 127 added */ 426 num.i &= 0x7fffff; /* leave only the mantissa */ 427 if (e & 0x01) num.i |= 0x800000; 428 /* the exponent is odd so we have to */ 429 /* look it up in the second half of */ 430 /* the lookup table, so we set the */ 431 /* high bit */ 432 e >>= 1; /* divide the exponent by two */ 433 /* note that in C the shift */ 434 /* operators are sign preserving */ 435 /* for signed operands */ 436 /* Do the table lookup, based on the quaternary mantissa, 437 * then reconstruct the result back into a float 438 */ 439 num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23); 440 441 return num.f; 442#else 443 return (float) _mesa_sqrtd((double) x); 444#endif 445} 446 447 448/** 449 inv_sqrt - A single precision 1/sqrt routine for IEEE format floats. 450 written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk 451 and Vesa Karvonen. 452*/ 453float 454_mesa_inv_sqrtf(float n) 455{ 456#if defined(USE_IEEE) && !defined(DEBUG) 457 float r0, x0, y0; 458 float r1, x1, y1; 459 float r2, x2, y2; 460#if 0 /* not used, see below -BP */ 461 float r3, x3, y3; 462#endif 463 fi_type u; 464 unsigned int magic; 465 466 /* 467 Exponent part of the magic number - 468 469 We want to: 470 1. subtract the bias from the exponent, 471 2. negate it 472 3. divide by two (rounding towards -inf) 473 4. add the bias back 474 475 Which is the same as subtracting the exponent from 381 and dividing 476 by 2. 477 478 floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2) 479 */ 480 481 magic = 381 << 23; 482 483 /* 484 Significand part of magic number - 485 486 With the current magic number, "(magic - u.i) >> 1" will give you: 487 488 for 1 <= u.f <= 2: 1.25 - u.f / 4 489 for 2 <= u.f <= 4: 1.00 - u.f / 8 490 491 This isn't a bad approximation of 1/sqrt. The maximum difference from 492 1/sqrt will be around .06. After three Newton-Raphson iterations, the 493 maximum difference is less than 4.5e-8. (Which is actually close 494 enough to make the following bias academic...) 495 496 To get a better approximation you can add a bias to the magic 497 number. For example, if you subtract 1/2 of the maximum difference in 498 the first approximation (.03), you will get the following function: 499 500 for 1 <= u.f <= 2: 1.22 - u.f / 4 501 for 2 <= u.f <= 3.76: 0.97 - u.f / 8 502 for 3.76 <= u.f <= 4: 0.72 - u.f / 16 503 (The 3.76 to 4 range is where the result is < .5.) 504 505 This is the closest possible initial approximation, but with a maximum 506 error of 8e-11 after three NR iterations, it is still not perfect. If 507 you subtract 0.0332281 instead of .03, the maximum error will be 508 2.5e-11 after three NR iterations, which should be about as close as 509 is possible. 510 511 for 1 <= u.f <= 2: 1.2167719 - u.f / 4 512 for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8 513 for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16 514 515 */ 516 517 magic -= (int)(0.0332281 * (1 << 25)); 518 519 u.f = n; 520 u.i = (magic - u.i) >> 1; 521 522 /* 523 Instead of Newton-Raphson, we use Goldschmidt's algorithm, which 524 allows more parallelism. From what I understand, the parallelism 525 comes at the cost of less precision, because it lets error 526 accumulate across iterations. 527 */ 528 x0 = 1.0f; 529 y0 = 0.5f * n; 530 r0 = u.f; 531 532 x1 = x0 * r0; 533 y1 = y0 * r0 * r0; 534 r1 = 1.5f - y1; 535 536 x2 = x1 * r1; 537 y2 = y1 * r1 * r1; 538 r2 = 1.5f - y2; 539 540#if 1 541 return x2 * r2; /* we can stop here, and be conformant -BP */ 542#else 543 x3 = x2 * r2; 544 y3 = y2 * r2 * r2; 545 r3 = 1.5f - y3; 546 547 return x3 * r3; 548#endif 549#else 550 return (float) (1.0 / sqrt(n)); 551#endif 552} 553 554 555/** Wrapper around pow() */ 556double 557_mesa_pow(double x, double y) 558{ 559 return pow(x, y); 560} 561 562 563/** 564 * Find the first bit set in a word. 565 */ 566int 567_mesa_ffs(int32_t i) 568{ 569#if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__) 570 register int bit = 0; 571 if (i != 0) { 572 if ((i & 0xffff) == 0) { 573 bit += 16; 574 i >>= 16; 575 } 576 if ((i & 0xff) == 0) { 577 bit += 8; 578 i >>= 8; 579 } 580 if ((i & 0xf) == 0) { 581 bit += 4; 582 i >>= 4; 583 } 584 while ((i & 1) == 0) { 585 bit++; 586 i >>= 1; 587 } 588 bit++; 589 } 590 return bit; 591#else 592 return ffs(i); 593#endif 594} 595 596 597/** 598 * Find position of first bit set in given value. 599 * XXX Warning: this function can only be used on 64-bit systems! 600 * \return position of least-significant bit set, starting at 1, return zero 601 * if no bits set. 602 */ 603int 604_mesa_ffsll(int64_t val) 605{ 606#ifdef ffsll 607 return ffsll(val); 608#else 609 int bit; 610 611 assert(sizeof(val) == 8); 612 613 bit = _mesa_ffs((int32_t)val); 614 if (bit != 0) 615 return bit; 616 617 bit = _mesa_ffs((int32_t)(val >> 32)); 618 if (bit != 0) 619 return 32 + bit; 620 621 return 0; 622#endif 623} 624 625 626/** 627 * Return number of bits set in given GLuint. 628 */ 629unsigned int 630_mesa_bitcount(unsigned int n) 631{ 632#if defined(__GNUC__) 633 return __builtin_popcount(n); 634#else 635 unsigned int bits; 636 for (bits = 0; n > 0; n = n >> 1) { 637 bits += (n & 1); 638 } 639 return bits; 640#endif 641} 642 643 644/** 645 * Convert a 4-byte float to a 2-byte half float. 646 * Based on code from: 647 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 648 */ 649GLhalfARB 650_mesa_float_to_half(float val) 651{ 652 const fi_type fi = {val}; 653 const int flt_m = fi.i & 0x7fffff; 654 const int flt_e = (fi.i >> 23) & 0xff; 655 const int flt_s = (fi.i >> 31) & 0x1; 656 int s, e, m = 0; 657 GLhalfARB result; 658 659 /* sign bit */ 660 s = flt_s; 661 662 /* handle special cases */ 663 if ((flt_e == 0) && (flt_m == 0)) { 664 /* zero */ 665 /* m = 0; - already set */ 666 e = 0; 667 } 668 else if ((flt_e == 0) && (flt_m != 0)) { 669 /* denorm -- denorm float maps to 0 half */ 670 /* m = 0; - already set */ 671 e = 0; 672 } 673 else if ((flt_e == 0xff) && (flt_m == 0)) { 674 /* infinity */ 675 /* m = 0; - already set */ 676 e = 31; 677 } 678 else if ((flt_e == 0xff) && (flt_m != 0)) { 679 /* NaN */ 680 m = 1; 681 e = 31; 682 } 683 else { 684 /* regular number */ 685 const int new_exp = flt_e - 127; 686 if (new_exp < -24) { 687 /* this maps to 0 */ 688 /* m = 0; - already set */ 689 e = 0; 690 } 691 else if (new_exp < -14) { 692 /* this maps to a denorm */ 693 unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/ 694 e = 0; 695 switch (exp_val) { 696 case 0: 697 _mesa_warning(NULL, 698 "float_to_half: logical error in denorm creation!\n"); 699 /* m = 0; - already set */ 700 break; 701 case 1: m = 512 + (flt_m >> 14); break; 702 case 2: m = 256 + (flt_m >> 15); break; 703 case 3: m = 128 + (flt_m >> 16); break; 704 case 4: m = 64 + (flt_m >> 17); break; 705 case 5: m = 32 + (flt_m >> 18); break; 706 case 6: m = 16 + (flt_m >> 19); break; 707 case 7: m = 8 + (flt_m >> 20); break; 708 case 8: m = 4 + (flt_m >> 21); break; 709 case 9: m = 2 + (flt_m >> 22); break; 710 case 10: m = 1; break; 711 } 712 } 713 else if (new_exp > 15) { 714 /* map this value to infinity */ 715 /* m = 0; - already set */ 716 e = 31; 717 } 718 else { 719 /* regular */ 720 e = new_exp + 15; 721 m = flt_m >> 13; 722 } 723 } 724 725 result = (s << 15) | (e << 10) | m; 726 return result; 727} 728 729 730/** 731 * Convert a 2-byte half float to a 4-byte float. 732 * Based on code from: 733 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 734 */ 735float 736_mesa_half_to_float(GLhalfARB val) 737{ 738 /* XXX could also use a 64K-entry lookup table */ 739 const int m = val & 0x3ff; 740 const int e = (val >> 10) & 0x1f; 741 const int s = (val >> 15) & 0x1; 742 int flt_m, flt_e, flt_s; 743 fi_type fi; 744 float result; 745 746 /* sign bit */ 747 flt_s = s; 748 749 /* handle special cases */ 750 if ((e == 0) && (m == 0)) { 751 /* zero */ 752 flt_m = 0; 753 flt_e = 0; 754 } 755 else if ((e == 0) && (m != 0)) { 756 /* denorm -- denorm half will fit in non-denorm single */ 757 const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */ 758 float mantissa = ((float) (m)) / 1024.0f; 759 float sign = s ? -1.0f : 1.0f; 760 return sign * mantissa * half_denorm; 761 } 762 else if ((e == 31) && (m == 0)) { 763 /* infinity */ 764 flt_e = 0xff; 765 flt_m = 0; 766 } 767 else if ((e == 31) && (m != 0)) { 768 /* NaN */ 769 flt_e = 0xff; 770 flt_m = 1; 771 } 772 else { 773 /* regular */ 774 flt_e = e + 112; 775 flt_m = m << 13; 776 } 777 778 fi.i = (flt_s << 31) | (flt_e << 23) | flt_m; 779 result = fi.f; 780 return result; 781} 782 783/*@}*/ 784 785 786/**********************************************************************/ 787/** \name Sort & Search */ 788/*@{*/ 789 790/** 791 * Wrapper for bsearch(). 792 */ 793void * 794_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size, 795 int (*compar)(const void *, const void *) ) 796{ 797#if defined(_WIN32_WCE) 798 void *mid; 799 int cmp; 800 while (nmemb) { 801 nmemb >>= 1; 802 mid = (char *)base + nmemb * size; 803 cmp = (*compar)(key, mid); 804 if (cmp == 0) 805 return mid; 806 if (cmp > 0) { 807 base = (char *)mid + size; 808 --nmemb; 809 } 810 } 811 return NULL; 812#else 813 return bsearch(key, base, nmemb, size, compar); 814#endif 815} 816 817/*@}*/ 818 819 820/**********************************************************************/ 821/** \name Environment vars */ 822/*@{*/ 823 824/** 825 * Wrapper for getenv(). 826 */ 827char * 828_mesa_getenv( const char *var ) 829{ 830#if defined(_XBOX) || defined(_WIN32_WCE) 831 return NULL; 832#else 833 return getenv(var); 834#endif 835} 836 837/*@}*/ 838 839 840/**********************************************************************/ 841/** \name String */ 842/*@{*/ 843 844/** 845 * Implemented using _mesa_malloc() and strcpy. 846 * Note that NULL is handled accordingly. 847 */ 848char * 849_mesa_strdup( const char *s ) 850{ 851 if (s) { 852 size_t l = strlen(s); 853 char *s2 = (char *) _mesa_malloc(l + 1); 854 if (s2) 855 strcpy(s2, s); 856 return s2; 857 } 858 else { 859 return NULL; 860 } 861} 862 863/** Wrapper around atoi() */ 864int 865_mesa_atoi(const char *s) 866{ 867 return atoi(s); 868} 869 870/** Wrapper around strtod() */ 871double 872_mesa_strtod( const char *s, char **end ) 873{ 874#ifdef _GNU_SOURCE 875 static locale_t loc = NULL; 876 if (!loc) { 877 loc = newlocale(LC_CTYPE_MASK, "C", NULL); 878 } 879 return strtod_l(s, end, loc); 880#else 881 return strtod(s, end); 882#endif 883} 884 885/** Compute simple checksum/hash for a string */ 886unsigned int 887_mesa_str_checksum(const char *str) 888{ 889 /* This could probably be much better */ 890 unsigned int sum, i; 891 const char *c; 892 sum = i = 1; 893 for (c = str; *c; c++, i++) 894 sum += *c * (i % 100); 895 return sum + i; 896} 897 898 899/*@}*/ 900 901 902/**********************************************************************/ 903/** \name I/O */ 904/*@{*/ 905 906/** Wrapper around vsprintf() */ 907int 908_mesa_sprintf( char *str, const char *fmt, ... ) 909{ 910 int r; 911 va_list args; 912 va_start( args, fmt ); 913 r = vsprintf( str, fmt, args ); 914 va_end( args ); 915 return r; 916} 917 918/** Wrapper around vsnprintf() */ 919int 920_mesa_snprintf( char *str, size_t size, const char *fmt, ... ) 921{ 922 int r; 923 va_list args; 924 va_start( args, fmt ); 925 r = vsnprintf( str, size, fmt, args ); 926 va_end( args ); 927 return r; 928} 929 930/** Wrapper around printf(), using vsprintf() for the formatting. */ 931void 932_mesa_printf( const char *fmtString, ... ) 933{ 934 va_list args; 935 va_start( args, fmtString ); 936 vfprintf(stderr, fmtString, args); 937 va_end( args ); 938} 939 940/** Wrapper around fprintf(), using vsprintf() for the formatting. */ 941void 942_mesa_fprintf( FILE *f, const char *fmtString, ... ) 943{ 944 char s[MAXSTRING]; 945 va_list args; 946 va_start( args, fmtString ); 947 vsnprintf(s, MAXSTRING, fmtString, args); 948 va_end( args ); 949 fprintf(f, "%s", s); 950} 951 952 953/** Wrapper around vsprintf() */ 954int 955_mesa_vsprintf( char *str, const char *fmt, va_list args ) 956{ 957 return vsprintf( str, fmt, args ); 958} 959 960/*@}*/ 961 962 963/**********************************************************************/ 964/** \name Diagnostics */ 965/*@{*/ 966 967static void 968output_if_debug(const char *prefixString, const char *outputString, 969 GLboolean newline) 970{ 971 static int debug = -1; 972 973 /* Check the MESA_DEBUG environment variable if it hasn't 974 * been checked yet. We only have to check it once... 975 */ 976 if (debug == -1) { 977 char *env = _mesa_getenv("MESA_DEBUG"); 978 979 /* In a debug build, we print warning messages *unless* 980 * MESA_DEBUG is 0. In a non-debug build, we don't 981 * print warning messages *unless* MESA_DEBUG is 982 * set *to any value*. 983 */ 984#ifdef DEBUG 985 debug = (env != NULL && _mesa_atoi(env) == 0) ? 0 : 1; 986#else 987 debug = (env != NULL) ? 1 : 0; 988#endif 989 } 990 991 /* Now only print the string if we're required to do so. */ 992 if (debug) { 993 fprintf(stderr, "%s: %s", prefixString, outputString); 994 if (newline) 995 fprintf(stderr, "\n"); 996 997#if defined(_WIN32) && !defined(_WIN32_WCE) 998 /* stderr from windows applications without console is not usually 999 * visible, so communicate with the debugger instead */ 1000 { 1001 char buf[4096]; 1002 _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : ""); 1003 OutputDebugStringA(buf); 1004 } 1005#endif 1006 } 1007} 1008 1009 1010/** 1011 * Return string version of GL error code. 1012 */ 1013static const char * 1014error_string( GLenum error ) 1015{ 1016 switch (error) { 1017 case GL_NO_ERROR: 1018 return "GL_NO_ERROR"; 1019 case GL_INVALID_VALUE: 1020 return "GL_INVALID_VALUE"; 1021 case GL_INVALID_ENUM: 1022 return "GL_INVALID_ENUM"; 1023 case GL_INVALID_OPERATION: 1024 return "GL_INVALID_OPERATION"; 1025 case GL_STACK_OVERFLOW: 1026 return "GL_STACK_OVERFLOW"; 1027 case GL_STACK_UNDERFLOW: 1028 return "GL_STACK_UNDERFLOW"; 1029 case GL_OUT_OF_MEMORY: 1030 return "GL_OUT_OF_MEMORY"; 1031 case GL_TABLE_TOO_LARGE: 1032 return "GL_TABLE_TOO_LARGE"; 1033 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: 1034 return "GL_INVALID_FRAMEBUFFER_OPERATION"; 1035 default: 1036 return "unknown"; 1037 } 1038} 1039 1040 1041/** 1042 * When a new type of error is recorded, print a message describing 1043 * previous errors which were accumulated. 1044 */ 1045static void 1046flush_delayed_errors( GLcontext *ctx ) 1047{ 1048 char s[MAXSTRING]; 1049 1050 if (ctx->ErrorDebugCount) { 1051 _mesa_snprintf(s, MAXSTRING, "%d similar %s errors", 1052 ctx->ErrorDebugCount, 1053 error_string(ctx->ErrorValue)); 1054 1055 output_if_debug("Mesa", s, GL_TRUE); 1056 1057 ctx->ErrorDebugCount = 0; 1058 } 1059} 1060 1061 1062/** 1063 * Report a warning (a recoverable error condition) to stderr if 1064 * either DEBUG is defined or the MESA_DEBUG env var is set. 1065 * 1066 * \param ctx GL context. 1067 * \param fmtString printf()-like format string. 1068 */ 1069void 1070_mesa_warning( GLcontext *ctx, const char *fmtString, ... ) 1071{ 1072 char str[MAXSTRING]; 1073 va_list args; 1074 va_start( args, fmtString ); 1075 (void) vsnprintf( str, MAXSTRING, fmtString, args ); 1076 va_end( args ); 1077 1078 if (ctx) 1079 flush_delayed_errors( ctx ); 1080 1081 output_if_debug("Mesa warning", str, GL_TRUE); 1082} 1083 1084 1085/** 1086 * Report an internal implementation problem. 1087 * Prints the message to stderr via fprintf(). 1088 * 1089 * \param ctx GL context. 1090 * \param fmtString problem description string. 1091 */ 1092void 1093_mesa_problem( const GLcontext *ctx, const char *fmtString, ... ) 1094{ 1095 va_list args; 1096 char str[MAXSTRING]; 1097 (void) ctx; 1098 1099 va_start( args, fmtString ); 1100 vsnprintf( str, MAXSTRING, fmtString, args ); 1101 va_end( args ); 1102 1103 fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str); 1104 fprintf(stderr, "Please report at bugzilla.freedesktop.org\n"); 1105} 1106 1107 1108/** 1109 * Record an OpenGL state error. These usually occur when the user 1110 * passes invalid parameters to a GL function. 1111 * 1112 * If debugging is enabled (either at compile-time via the DEBUG macro, or 1113 * run-time via the MESA_DEBUG environment variable), report the error with 1114 * _mesa_debug(). 1115 * 1116 * \param ctx the GL context. 1117 * \param error the error value. 1118 * \param fmtString printf() style format string, followed by optional args 1119 */ 1120void 1121_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... ) 1122{ 1123 static GLint debug = -1; 1124 1125 /* Check debug environment variable only once: 1126 */ 1127 if (debug == -1) { 1128 const char *debugEnv = _mesa_getenv("MESA_DEBUG"); 1129 1130#ifdef DEBUG 1131 if (debugEnv && strstr(debugEnv, "silent")) 1132 debug = GL_FALSE; 1133 else 1134 debug = GL_TRUE; 1135#else 1136 if (debugEnv) 1137 debug = GL_TRUE; 1138 else 1139 debug = GL_FALSE; 1140#endif 1141 } 1142 1143 if (debug) { 1144 if (ctx->ErrorValue == error && 1145 ctx->ErrorDebugFmtString == fmtString) { 1146 ctx->ErrorDebugCount++; 1147 } 1148 else { 1149 char s[MAXSTRING], s2[MAXSTRING]; 1150 va_list args; 1151 1152 flush_delayed_errors( ctx ); 1153 1154 va_start(args, fmtString); 1155 vsnprintf(s, MAXSTRING, fmtString, args); 1156 va_end(args); 1157 1158 _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s); 1159 output_if_debug("Mesa: User error", s2, GL_TRUE); 1160 1161 ctx->ErrorDebugFmtString = fmtString; 1162 ctx->ErrorDebugCount = 0; 1163 } 1164 } 1165 1166 _mesa_record_error(ctx, error); 1167} 1168 1169 1170/** 1171 * Report debug information. Print error message to stderr via fprintf(). 1172 * No-op if DEBUG mode not enabled. 1173 * 1174 * \param ctx GL context. 1175 * \param fmtString printf()-style format string, followed by optional args. 1176 */ 1177void 1178_mesa_debug( const GLcontext *ctx, const char *fmtString, ... ) 1179{ 1180#ifdef DEBUG 1181 char s[MAXSTRING]; 1182 va_list args; 1183 va_start(args, fmtString); 1184 vsnprintf(s, MAXSTRING, fmtString, args); 1185 va_end(args); 1186 output_if_debug("Mesa", s, GL_FALSE); 1187#endif /* DEBUG */ 1188 (void) ctx; 1189 (void) fmtString; 1190} 1191 1192/*@}*/ 1193