Remove _mesa_memcpy in favor of plain memcpy.
[mesa.git] / src / mesa / main / imports.c
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 )
64 extern 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() */
75 void *
76 _mesa_malloc(size_t bytes)
77 {
78 return malloc(bytes);
79 }
80
81 /** Wrapper around calloc() */
82 void *
83 _mesa_calloc(size_t bytes)
84 {
85 return calloc(1, bytes);
86 }
87
88 /** Wrapper around free() */
89 void
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 */
106 void *
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 */
144 void *
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 */
196 void
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 */
213 void *
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 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 */
235 void *
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 memcpy(newBuffer, oldBuffer, copySize);
242 if (oldBuffer)
243 _mesa_free(oldBuffer);
244 return newBuffer;
245 }
246
247 /** Wrapper around memset() */
248 void
249 _mesa_memset( void *dst, int val, size_t n )
250 {
251 #if defined(SUNOS4)
252 memset( (char *) dst, (int) val, (int) n );
253 #else
254 memset(dst, val, n);
255 #endif
256 }
257
258 /**
259 * Fill memory with a constant 16bit word.
260 * \param dst destination pointer.
261 * \param val value.
262 * \param n number of words.
263 */
264 void
265 _mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
266 {
267 while (n-- > 0)
268 *dst++ = val;
269 }
270
271 /** Wrapper around either memset() or bzero() */
272 void
273 _mesa_bzero( void *dst, size_t n )
274 {
275 #if defined(__FreeBSD__)
276 bzero( dst, n );
277 #else
278 memset( dst, 0, n );
279 #endif
280 }
281
282 /** Wrapper around memcmp() */
283 int
284 _mesa_memcmp( const void *s1, const void *s2, size_t n )
285 {
286 #if defined(SUNOS4)
287 return memcmp( (char *) s1, (char *) s2, (int) n );
288 #else
289 return memcmp(s1, s2, n);
290 #endif
291 }
292
293 /*@}*/
294
295
296 /**********************************************************************/
297 /** \name Math */
298 /*@{*/
299
300 /** Wrapper around sin() */
301 double
302 _mesa_sin(double a)
303 {
304 return sin(a);
305 }
306
307 /** Single precision wrapper around sin() */
308 float
309 _mesa_sinf(float a)
310 {
311 return (float) sin((double) a);
312 }
313
314 /** Wrapper around cos() */
315 double
316 _mesa_cos(double a)
317 {
318 return cos(a);
319 }
320
321 /** Single precision wrapper around asin() */
322 float
323 _mesa_asinf(float x)
324 {
325 return (float) asin((double) x);
326 }
327
328 /** Single precision wrapper around atan() */
329 float
330 _mesa_atanf(float x)
331 {
332 return (float) atan((double) x);
333 }
334
335 /** Wrapper around sqrt() */
336 double
337 _mesa_sqrtd(double x)
338 {
339 return sqrt(x);
340 }
341
342
343 /*
344 * A High Speed, Low Precision Square Root
345 * by Paul Lalonde and Robert Dawson
346 * from "Graphics Gems", Academic Press, 1990
347 *
348 * SPARC implementation of a fast square root by table
349 * lookup.
350 * SPARC floating point format is as follows:
351 *
352 * BIT 31 30 23 22 0
353 * sign exponent mantissa
354 */
355 static short sqrttab[0x100]; /* declare table of square roots */
356
357 void
358 _mesa_init_sqrt_table(void)
359 {
360 #if defined(USE_IEEE) && !defined(DEBUG)
361 unsigned short i;
362 fi_type fi; /* to access the bits of a float in C quickly */
363 /* we use a union defined in glheader.h */
364
365 for(i=0; i<= 0x7f; i++) {
366 fi.i = 0;
367
368 /*
369 * Build a float with the bit pattern i as mantissa
370 * and an exponent of 0, stored as 127
371 */
372
373 fi.i = (i << 16) | (127 << 23);
374 fi.f = _mesa_sqrtd(fi.f);
375
376 /*
377 * Take the square root then strip the first 7 bits of
378 * the mantissa into the table
379 */
380
381 sqrttab[i] = (fi.i & 0x7fffff) >> 16;
382
383 /*
384 * Repeat the process, this time with an exponent of
385 * 1, stored as 128
386 */
387
388 fi.i = 0;
389 fi.i = (i << 16) | (128 << 23);
390 fi.f = sqrt(fi.f);
391 sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
392 }
393 #else
394 (void) sqrttab; /* silence compiler warnings */
395 #endif /*HAVE_FAST_MATH*/
396 }
397
398
399 /**
400 * Single precision square root.
401 */
402 float
403 _mesa_sqrtf( float x )
404 {
405 #if defined(USE_IEEE) && !defined(DEBUG)
406 fi_type num;
407 /* to access the bits of a float in C
408 * we use a union from glheader.h */
409
410 short e; /* the exponent */
411 if (x == 0.0F) return 0.0F; /* check for square root of 0 */
412 num.f = x;
413 e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */
414 /* exponent is stored with 127 added */
415 num.i &= 0x7fffff; /* leave only the mantissa */
416 if (e & 0x01) num.i |= 0x800000;
417 /* the exponent is odd so we have to */
418 /* look it up in the second half of */
419 /* the lookup table, so we set the */
420 /* high bit */
421 e >>= 1; /* divide the exponent by two */
422 /* note that in C the shift */
423 /* operators are sign preserving */
424 /* for signed operands */
425 /* Do the table lookup, based on the quaternary mantissa,
426 * then reconstruct the result back into a float
427 */
428 num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
429
430 return num.f;
431 #else
432 return (float) _mesa_sqrtd((double) x);
433 #endif
434 }
435
436
437 /**
438 inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
439 written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
440 and Vesa Karvonen.
441 */
442 float
443 _mesa_inv_sqrtf(float n)
444 {
445 #if defined(USE_IEEE) && !defined(DEBUG)
446 float r0, x0, y0;
447 float r1, x1, y1;
448 float r2, x2, y2;
449 #if 0 /* not used, see below -BP */
450 float r3, x3, y3;
451 #endif
452 fi_type u;
453 unsigned int magic;
454
455 /*
456 Exponent part of the magic number -
457
458 We want to:
459 1. subtract the bias from the exponent,
460 2. negate it
461 3. divide by two (rounding towards -inf)
462 4. add the bias back
463
464 Which is the same as subtracting the exponent from 381 and dividing
465 by 2.
466
467 floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
468 */
469
470 magic = 381 << 23;
471
472 /*
473 Significand part of magic number -
474
475 With the current magic number, "(magic - u.i) >> 1" will give you:
476
477 for 1 <= u.f <= 2: 1.25 - u.f / 4
478 for 2 <= u.f <= 4: 1.00 - u.f / 8
479
480 This isn't a bad approximation of 1/sqrt. The maximum difference from
481 1/sqrt will be around .06. After three Newton-Raphson iterations, the
482 maximum difference is less than 4.5e-8. (Which is actually close
483 enough to make the following bias academic...)
484
485 To get a better approximation you can add a bias to the magic
486 number. For example, if you subtract 1/2 of the maximum difference in
487 the first approximation (.03), you will get the following function:
488
489 for 1 <= u.f <= 2: 1.22 - u.f / 4
490 for 2 <= u.f <= 3.76: 0.97 - u.f / 8
491 for 3.76 <= u.f <= 4: 0.72 - u.f / 16
492 (The 3.76 to 4 range is where the result is < .5.)
493
494 This is the closest possible initial approximation, but with a maximum
495 error of 8e-11 after three NR iterations, it is still not perfect. If
496 you subtract 0.0332281 instead of .03, the maximum error will be
497 2.5e-11 after three NR iterations, which should be about as close as
498 is possible.
499
500 for 1 <= u.f <= 2: 1.2167719 - u.f / 4
501 for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
502 for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
503
504 */
505
506 magic -= (int)(0.0332281 * (1 << 25));
507
508 u.f = n;
509 u.i = (magic - u.i) >> 1;
510
511 /*
512 Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
513 allows more parallelism. From what I understand, the parallelism
514 comes at the cost of less precision, because it lets error
515 accumulate across iterations.
516 */
517 x0 = 1.0f;
518 y0 = 0.5f * n;
519 r0 = u.f;
520
521 x1 = x0 * r0;
522 y1 = y0 * r0 * r0;
523 r1 = 1.5f - y1;
524
525 x2 = x1 * r1;
526 y2 = y1 * r1 * r1;
527 r2 = 1.5f - y2;
528
529 #if 1
530 return x2 * r2; /* we can stop here, and be conformant -BP */
531 #else
532 x3 = x2 * r2;
533 y3 = y2 * r2 * r2;
534 r3 = 1.5f - y3;
535
536 return x3 * r3;
537 #endif
538 #else
539 return (float) (1.0 / sqrt(n));
540 #endif
541 }
542
543
544 /** Wrapper around pow() */
545 double
546 _mesa_pow(double x, double y)
547 {
548 return pow(x, y);
549 }
550
551
552 /**
553 * Find the first bit set in a word.
554 */
555 int
556 _mesa_ffs(int32_t i)
557 {
558 #if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__)
559 register int bit = 0;
560 if (i != 0) {
561 if ((i & 0xffff) == 0) {
562 bit += 16;
563 i >>= 16;
564 }
565 if ((i & 0xff) == 0) {
566 bit += 8;
567 i >>= 8;
568 }
569 if ((i & 0xf) == 0) {
570 bit += 4;
571 i >>= 4;
572 }
573 while ((i & 1) == 0) {
574 bit++;
575 i >>= 1;
576 }
577 bit++;
578 }
579 return bit;
580 #else
581 return ffs(i);
582 #endif
583 }
584
585
586 /**
587 * Find position of first bit set in given value.
588 * XXX Warning: this function can only be used on 64-bit systems!
589 * \return position of least-significant bit set, starting at 1, return zero
590 * if no bits set.
591 */
592 int
593 _mesa_ffsll(int64_t val)
594 {
595 #ifdef ffsll
596 return ffsll(val);
597 #else
598 int bit;
599
600 assert(sizeof(val) == 8);
601
602 bit = _mesa_ffs((int32_t)val);
603 if (bit != 0)
604 return bit;
605
606 bit = _mesa_ffs((int32_t)(val >> 32));
607 if (bit != 0)
608 return 32 + bit;
609
610 return 0;
611 #endif
612 }
613
614
615 /**
616 * Return number of bits set in given GLuint.
617 */
618 unsigned int
619 _mesa_bitcount(unsigned int n)
620 {
621 #if defined(__GNUC__)
622 return __builtin_popcount(n);
623 #else
624 unsigned int bits;
625 for (bits = 0; n > 0; n = n >> 1) {
626 bits += (n & 1);
627 }
628 return bits;
629 #endif
630 }
631
632
633 /**
634 * Convert a 4-byte float to a 2-byte half float.
635 * Based on code from:
636 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
637 */
638 GLhalfARB
639 _mesa_float_to_half(float val)
640 {
641 const fi_type fi = {val};
642 const int flt_m = fi.i & 0x7fffff;
643 const int flt_e = (fi.i >> 23) & 0xff;
644 const int flt_s = (fi.i >> 31) & 0x1;
645 int s, e, m = 0;
646 GLhalfARB result;
647
648 /* sign bit */
649 s = flt_s;
650
651 /* handle special cases */
652 if ((flt_e == 0) && (flt_m == 0)) {
653 /* zero */
654 /* m = 0; - already set */
655 e = 0;
656 }
657 else if ((flt_e == 0) && (flt_m != 0)) {
658 /* denorm -- denorm float maps to 0 half */
659 /* m = 0; - already set */
660 e = 0;
661 }
662 else if ((flt_e == 0xff) && (flt_m == 0)) {
663 /* infinity */
664 /* m = 0; - already set */
665 e = 31;
666 }
667 else if ((flt_e == 0xff) && (flt_m != 0)) {
668 /* NaN */
669 m = 1;
670 e = 31;
671 }
672 else {
673 /* regular number */
674 const int new_exp = flt_e - 127;
675 if (new_exp < -24) {
676 /* this maps to 0 */
677 /* m = 0; - already set */
678 e = 0;
679 }
680 else if (new_exp < -14) {
681 /* this maps to a denorm */
682 unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
683 e = 0;
684 switch (exp_val) {
685 case 0:
686 _mesa_warning(NULL,
687 "float_to_half: logical error in denorm creation!\n");
688 /* m = 0; - already set */
689 break;
690 case 1: m = 512 + (flt_m >> 14); break;
691 case 2: m = 256 + (flt_m >> 15); break;
692 case 3: m = 128 + (flt_m >> 16); break;
693 case 4: m = 64 + (flt_m >> 17); break;
694 case 5: m = 32 + (flt_m >> 18); break;
695 case 6: m = 16 + (flt_m >> 19); break;
696 case 7: m = 8 + (flt_m >> 20); break;
697 case 8: m = 4 + (flt_m >> 21); break;
698 case 9: m = 2 + (flt_m >> 22); break;
699 case 10: m = 1; break;
700 }
701 }
702 else if (new_exp > 15) {
703 /* map this value to infinity */
704 /* m = 0; - already set */
705 e = 31;
706 }
707 else {
708 /* regular */
709 e = new_exp + 15;
710 m = flt_m >> 13;
711 }
712 }
713
714 result = (s << 15) | (e << 10) | m;
715 return result;
716 }
717
718
719 /**
720 * Convert a 2-byte half float to a 4-byte float.
721 * Based on code from:
722 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
723 */
724 float
725 _mesa_half_to_float(GLhalfARB val)
726 {
727 /* XXX could also use a 64K-entry lookup table */
728 const int m = val & 0x3ff;
729 const int e = (val >> 10) & 0x1f;
730 const int s = (val >> 15) & 0x1;
731 int flt_m, flt_e, flt_s;
732 fi_type fi;
733 float result;
734
735 /* sign bit */
736 flt_s = s;
737
738 /* handle special cases */
739 if ((e == 0) && (m == 0)) {
740 /* zero */
741 flt_m = 0;
742 flt_e = 0;
743 }
744 else if ((e == 0) && (m != 0)) {
745 /* denorm -- denorm half will fit in non-denorm single */
746 const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
747 float mantissa = ((float) (m)) / 1024.0f;
748 float sign = s ? -1.0f : 1.0f;
749 return sign * mantissa * half_denorm;
750 }
751 else if ((e == 31) && (m == 0)) {
752 /* infinity */
753 flt_e = 0xff;
754 flt_m = 0;
755 }
756 else if ((e == 31) && (m != 0)) {
757 /* NaN */
758 flt_e = 0xff;
759 flt_m = 1;
760 }
761 else {
762 /* regular */
763 flt_e = e + 112;
764 flt_m = m << 13;
765 }
766
767 fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
768 result = fi.f;
769 return result;
770 }
771
772 /*@}*/
773
774
775 /**********************************************************************/
776 /** \name Sort & Search */
777 /*@{*/
778
779 /**
780 * Wrapper for bsearch().
781 */
782 void *
783 _mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
784 int (*compar)(const void *, const void *) )
785 {
786 #if defined(_WIN32_WCE)
787 void *mid;
788 int cmp;
789 while (nmemb) {
790 nmemb >>= 1;
791 mid = (char *)base + nmemb * size;
792 cmp = (*compar)(key, mid);
793 if (cmp == 0)
794 return mid;
795 if (cmp > 0) {
796 base = (char *)mid + size;
797 --nmemb;
798 }
799 }
800 return NULL;
801 #else
802 return bsearch(key, base, nmemb, size, compar);
803 #endif
804 }
805
806 /*@}*/
807
808
809 /**********************************************************************/
810 /** \name Environment vars */
811 /*@{*/
812
813 /**
814 * Wrapper for getenv().
815 */
816 char *
817 _mesa_getenv( const char *var )
818 {
819 #if defined(_XBOX) || defined(_WIN32_WCE)
820 return NULL;
821 #else
822 return getenv(var);
823 #endif
824 }
825
826 /*@}*/
827
828
829 /**********************************************************************/
830 /** \name String */
831 /*@{*/
832
833 /**
834 * Implemented using _mesa_malloc() and strcpy.
835 * Note that NULL is handled accordingly.
836 */
837 char *
838 _mesa_strdup( const char *s )
839 {
840 if (s) {
841 size_t l = strlen(s);
842 char *s2 = (char *) _mesa_malloc(l + 1);
843 if (s2)
844 strcpy(s2, s);
845 return s2;
846 }
847 else {
848 return NULL;
849 }
850 }
851
852 /** Wrapper around strtod() */
853 double
854 _mesa_strtod( const char *s, char **end )
855 {
856 #ifdef _GNU_SOURCE
857 static locale_t loc = NULL;
858 if (!loc) {
859 loc = newlocale(LC_CTYPE_MASK, "C", NULL);
860 }
861 return strtod_l(s, end, loc);
862 #else
863 return strtod(s, end);
864 #endif
865 }
866
867 /** Compute simple checksum/hash for a string */
868 unsigned int
869 _mesa_str_checksum(const char *str)
870 {
871 /* This could probably be much better */
872 unsigned int sum, i;
873 const char *c;
874 sum = i = 1;
875 for (c = str; *c; c++, i++)
876 sum += *c * (i % 100);
877 return sum + i;
878 }
879
880
881 /*@}*/
882
883
884 /**********************************************************************/
885 /** \name I/O */
886 /*@{*/
887
888 /** Wrapper around vsprintf() */
889 int
890 _mesa_sprintf( char *str, const char *fmt, ... )
891 {
892 int r;
893 va_list args;
894 va_start( args, fmt );
895 r = vsprintf( str, fmt, args );
896 va_end( args );
897 return r;
898 }
899
900 /** Wrapper around vsnprintf() */
901 int
902 _mesa_snprintf( char *str, size_t size, const char *fmt, ... )
903 {
904 int r;
905 va_list args;
906 va_start( args, fmt );
907 r = vsnprintf( str, size, fmt, args );
908 va_end( args );
909 return r;
910 }
911
912 /** Wrapper around printf(), using vsprintf() for the formatting. */
913 void
914 _mesa_printf( const char *fmtString, ... )
915 {
916 va_list args;
917 va_start( args, fmtString );
918 vfprintf(stderr, fmtString, args);
919 va_end( args );
920 }
921
922 /** Wrapper around fprintf(), using vsprintf() for the formatting. */
923 void
924 _mesa_fprintf( FILE *f, const char *fmtString, ... )
925 {
926 char s[MAXSTRING];
927 va_list args;
928 va_start( args, fmtString );
929 vsnprintf(s, MAXSTRING, fmtString, args);
930 va_end( args );
931 fprintf(f, "%s", s);
932 }
933
934
935 /** Wrapper around vsprintf() */
936 int
937 _mesa_vsprintf( char *str, const char *fmt, va_list args )
938 {
939 return vsprintf( str, fmt, args );
940 }
941
942 /*@}*/
943
944
945 /**********************************************************************/
946 /** \name Diagnostics */
947 /*@{*/
948
949 static void
950 output_if_debug(const char *prefixString, const char *outputString,
951 GLboolean newline)
952 {
953 static int debug = -1;
954
955 /* Check the MESA_DEBUG environment variable if it hasn't
956 * been checked yet. We only have to check it once...
957 */
958 if (debug == -1) {
959 char *env = _mesa_getenv("MESA_DEBUG");
960
961 /* In a debug build, we print warning messages *unless*
962 * MESA_DEBUG is 0. In a non-debug build, we don't
963 * print warning messages *unless* MESA_DEBUG is
964 * set *to any value*.
965 */
966 #ifdef DEBUG
967 debug = (env != NULL && atoi(env) == 0) ? 0 : 1;
968 #else
969 debug = (env != NULL) ? 1 : 0;
970 #endif
971 }
972
973 /* Now only print the string if we're required to do so. */
974 if (debug) {
975 fprintf(stderr, "%s: %s", prefixString, outputString);
976 if (newline)
977 fprintf(stderr, "\n");
978
979 #if defined(_WIN32) && !defined(_WIN32_WCE)
980 /* stderr from windows applications without console is not usually
981 * visible, so communicate with the debugger instead */
982 {
983 char buf[4096];
984 _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
985 OutputDebugStringA(buf);
986 }
987 #endif
988 }
989 }
990
991
992 /**
993 * Return string version of GL error code.
994 */
995 static const char *
996 error_string( GLenum error )
997 {
998 switch (error) {
999 case GL_NO_ERROR:
1000 return "GL_NO_ERROR";
1001 case GL_INVALID_VALUE:
1002 return "GL_INVALID_VALUE";
1003 case GL_INVALID_ENUM:
1004 return "GL_INVALID_ENUM";
1005 case GL_INVALID_OPERATION:
1006 return "GL_INVALID_OPERATION";
1007 case GL_STACK_OVERFLOW:
1008 return "GL_STACK_OVERFLOW";
1009 case GL_STACK_UNDERFLOW:
1010 return "GL_STACK_UNDERFLOW";
1011 case GL_OUT_OF_MEMORY:
1012 return "GL_OUT_OF_MEMORY";
1013 case GL_TABLE_TOO_LARGE:
1014 return "GL_TABLE_TOO_LARGE";
1015 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
1016 return "GL_INVALID_FRAMEBUFFER_OPERATION";
1017 default:
1018 return "unknown";
1019 }
1020 }
1021
1022
1023 /**
1024 * When a new type of error is recorded, print a message describing
1025 * previous errors which were accumulated.
1026 */
1027 static void
1028 flush_delayed_errors( GLcontext *ctx )
1029 {
1030 char s[MAXSTRING];
1031
1032 if (ctx->ErrorDebugCount) {
1033 _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
1034 ctx->ErrorDebugCount,
1035 error_string(ctx->ErrorValue));
1036
1037 output_if_debug("Mesa", s, GL_TRUE);
1038
1039 ctx->ErrorDebugCount = 0;
1040 }
1041 }
1042
1043
1044 /**
1045 * Report a warning (a recoverable error condition) to stderr if
1046 * either DEBUG is defined or the MESA_DEBUG env var is set.
1047 *
1048 * \param ctx GL context.
1049 * \param fmtString printf()-like format string.
1050 */
1051 void
1052 _mesa_warning( GLcontext *ctx, const char *fmtString, ... )
1053 {
1054 char str[MAXSTRING];
1055 va_list args;
1056 va_start( args, fmtString );
1057 (void) vsnprintf( str, MAXSTRING, fmtString, args );
1058 va_end( args );
1059
1060 if (ctx)
1061 flush_delayed_errors( ctx );
1062
1063 output_if_debug("Mesa warning", str, GL_TRUE);
1064 }
1065
1066
1067 /**
1068 * Report an internal implementation problem.
1069 * Prints the message to stderr via fprintf().
1070 *
1071 * \param ctx GL context.
1072 * \param fmtString problem description string.
1073 */
1074 void
1075 _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
1076 {
1077 va_list args;
1078 char str[MAXSTRING];
1079 (void) ctx;
1080
1081 va_start( args, fmtString );
1082 vsnprintf( str, MAXSTRING, fmtString, args );
1083 va_end( args );
1084
1085 fprintf(stderr, "Mesa %s implementation error: %s\n", MESA_VERSION_STRING, str);
1086 fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
1087 }
1088
1089
1090 /**
1091 * Record an OpenGL state error. These usually occur when the user
1092 * passes invalid parameters to a GL function.
1093 *
1094 * If debugging is enabled (either at compile-time via the DEBUG macro, or
1095 * run-time via the MESA_DEBUG environment variable), report the error with
1096 * _mesa_debug().
1097 *
1098 * \param ctx the GL context.
1099 * \param error the error value.
1100 * \param fmtString printf() style format string, followed by optional args
1101 */
1102 void
1103 _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
1104 {
1105 static GLint debug = -1;
1106
1107 /* Check debug environment variable only once:
1108 */
1109 if (debug == -1) {
1110 const char *debugEnv = _mesa_getenv("MESA_DEBUG");
1111
1112 #ifdef DEBUG
1113 if (debugEnv && strstr(debugEnv, "silent"))
1114 debug = GL_FALSE;
1115 else
1116 debug = GL_TRUE;
1117 #else
1118 if (debugEnv)
1119 debug = GL_TRUE;
1120 else
1121 debug = GL_FALSE;
1122 #endif
1123 }
1124
1125 if (debug) {
1126 if (ctx->ErrorValue == error &&
1127 ctx->ErrorDebugFmtString == fmtString) {
1128 ctx->ErrorDebugCount++;
1129 }
1130 else {
1131 char s[MAXSTRING], s2[MAXSTRING];
1132 va_list args;
1133
1134 flush_delayed_errors( ctx );
1135
1136 va_start(args, fmtString);
1137 vsnprintf(s, MAXSTRING, fmtString, args);
1138 va_end(args);
1139
1140 _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s);
1141 output_if_debug("Mesa: User error", s2, GL_TRUE);
1142
1143 ctx->ErrorDebugFmtString = fmtString;
1144 ctx->ErrorDebugCount = 0;
1145 }
1146 }
1147
1148 _mesa_record_error(ctx, error);
1149 }
1150
1151
1152 /**
1153 * Report debug information. Print error message to stderr via fprintf().
1154 * No-op if DEBUG mode not enabled.
1155 *
1156 * \param ctx GL context.
1157 * \param fmtString printf()-style format string, followed by optional args.
1158 */
1159 void
1160 _mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
1161 {
1162 #ifdef DEBUG
1163 char s[MAXSTRING];
1164 va_list args;
1165 va_start(args, fmtString);
1166 vsnprintf(s, MAXSTRING, fmtString, args);
1167 va_end(args);
1168 output_if_debug("Mesa", s, GL_FALSE);
1169 #endif /* DEBUG */
1170 (void) ctx;
1171 (void) fmtString;
1172 }
1173
1174 /*@}*/