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