Sync with trunk r63637.
[reactos.git] / dll / opengl / 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 #include <precomp.h>
47
48 #ifdef _GNU_SOURCE
49 #include <locale.h>
50 #ifdef __APPLE__
51 #include <xlocale.h>
52 #endif
53 #endif
54
55 #define MAXSTRING 4000 /* for vsnprintf() */
56
57 #ifdef WIN32
58 #define vsnprintf _vsnprintf
59 #elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )
60 extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
61 #ifdef __VMS
62 #include "vsnprintf.c"
63 #endif
64 #endif
65
66 /**********************************************************************/
67 /** \name Memory */
68 /*@{*/
69
70 /**
71 * Allocate aligned memory.
72 *
73 * \param bytes number of bytes to allocate.
74 * \param alignment alignment (must be greater than zero).
75 *
76 * Allocates extra memory to accommodate rounding up the address for
77 * alignment and to record the real malloc address.
78 *
79 * \sa _mesa_align_free().
80 */
81 void *
82 _mesa_align_malloc(size_t bytes, unsigned long alignment)
83 {
84 #if defined(HAVE_POSIX_MEMALIGN)
85 void *mem;
86 int err = posix_memalign(& mem, alignment, bytes);
87 if (err)
88 return NULL;
89 return mem;
90 #elif defined(_WIN32) && defined(_MSC_VER)
91 return _aligned_malloc(bytes, alignment);
92 #else
93 uintptr_t ptr, buf;
94
95 ASSERT( alignment > 0 );
96
97 ptr = (uintptr_t) malloc(bytes + alignment + sizeof(void *));
98 if (!ptr)
99 return NULL;
100
101 buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
102 *(uintptr_t *)(buf - sizeof(void *)) = ptr;
103
104 #ifdef DEBUG
105 /* mark the non-aligned area */
106 while ( ptr < buf - sizeof(void *) ) {
107 *(unsigned long *)ptr = 0xcdcdcdcd;
108 ptr += sizeof(unsigned long);
109 }
110 #endif
111
112 return (void *) buf;
113 #endif /* defined(HAVE_POSIX_MEMALIGN) */
114 }
115
116 /**
117 * Same as _mesa_align_malloc(), but using calloc(1, ) instead of
118 * malloc()
119 */
120 void *
121 _mesa_align_calloc(size_t bytes, unsigned long alignment)
122 {
123 #if defined(HAVE_POSIX_MEMALIGN)
124 void *mem;
125
126 mem = _mesa_align_malloc(bytes, alignment);
127 if (mem != NULL) {
128 (void) memset(mem, 0, bytes);
129 }
130
131 return mem;
132 #elif defined(_WIN32) && defined(_MSC_VER)
133 void *mem;
134
135 mem = _aligned_malloc(bytes, alignment);
136 if (mem != NULL) {
137 (void) memset(mem, 0, bytes);
138 }
139
140 return mem;
141 #else
142 uintptr_t ptr, buf;
143
144 ASSERT( alignment > 0 );
145
146 ptr = (uintptr_t) calloc(1, bytes + alignment + sizeof(void *));
147 if (!ptr)
148 return NULL;
149
150 buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
151 *(uintptr_t *)(buf - sizeof(void *)) = ptr;
152
153 #ifdef DEBUG
154 /* mark the non-aligned area */
155 while ( ptr < buf - sizeof(void *) ) {
156 *(unsigned long *)ptr = 0xcdcdcdcd;
157 ptr += sizeof(unsigned long);
158 }
159 #endif
160
161 return (void *)buf;
162 #endif /* defined(HAVE_POSIX_MEMALIGN) */
163 }
164
165 /**
166 * Free memory which was allocated with either _mesa_align_malloc()
167 * or _mesa_align_calloc().
168 * \param ptr pointer to the memory to be freed.
169 * The actual address to free is stored in the word immediately before the
170 * address the client sees.
171 */
172 void
173 _mesa_align_free(void *ptr)
174 {
175 #if defined(HAVE_POSIX_MEMALIGN)
176 free(ptr);
177 #elif defined(_WIN32) && defined(_MSC_VER)
178 _aligned_free(ptr);
179 #else
180 void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
181 void *realAddr = *cubbyHole;
182 free(realAddr);
183 #endif /* defined(HAVE_POSIX_MEMALIGN) */
184 }
185
186 /**
187 * Reallocate memory, with alignment.
188 */
189 void *
190 _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
191 unsigned long alignment)
192 {
193 #if defined(_WIN32) && defined(_MSC_VER)
194 (void) oldSize;
195 return _aligned_realloc(oldBuffer, newSize, alignment);
196 #else
197 const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
198 void *newBuf = _mesa_align_malloc(newSize, alignment);
199 if (newBuf && oldBuffer && copySize > 0) {
200 memcpy(newBuf, oldBuffer, copySize);
201 }
202 if (oldBuffer)
203 _mesa_align_free(oldBuffer);
204 return newBuf;
205 #endif
206 }
207
208
209
210 /** Reallocate memory */
211 void *
212 _mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
213 {
214 const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
215 void *newBuffer = malloc(newSize);
216 if (newBuffer && oldBuffer && copySize > 0)
217 memcpy(newBuffer, oldBuffer, copySize);
218 if (oldBuffer)
219 free(oldBuffer);
220 return newBuffer;
221 }
222
223 /**
224 * Fill memory with a constant 16bit word.
225 * \param dst destination pointer.
226 * \param val value.
227 * \param n number of words.
228 */
229 void
230 _mesa_memset16( unsigned short *dst, unsigned short val, size_t n )
231 {
232 while (n-- > 0)
233 *dst++ = val;
234 }
235
236 /*@}*/
237
238
239 /**********************************************************************/
240 /** \name Math */
241 /*@{*/
242
243 /** Wrapper around sqrt() */
244 double
245 _mesa_sqrtd(double x)
246 {
247 return sqrt(x);
248 }
249
250
251 /*
252 * A High Speed, Low Precision Square Root
253 * by Paul Lalonde and Robert Dawson
254 * from "Graphics Gems", Academic Press, 1990
255 *
256 * SPARC implementation of a fast square root by table
257 * lookup.
258 * SPARC floating point format is as follows:
259 *
260 * BIT 31 30 23 22 0
261 * sign exponent mantissa
262 */
263 static short sqrttab[0x100]; /* declare table of square roots */
264
265 void
266 _mesa_init_sqrt_table(void)
267 {
268 #if defined(USE_IEEE) && !defined(DEBUG)
269 unsigned short i;
270 fi_type fi; /* to access the bits of a float in C quickly */
271 /* we use a union defined in glheader.h */
272
273 for(i=0; i<= 0x7f; i++) {
274 fi.i = 0;
275
276 /*
277 * Build a float with the bit pattern i as mantissa
278 * and an exponent of 0, stored as 127
279 */
280
281 fi.i = (i << 16) | (127 << 23);
282 fi.f = _mesa_sqrtd(fi.f);
283
284 /*
285 * Take the square root then strip the first 7 bits of
286 * the mantissa into the table
287 */
288
289 sqrttab[i] = (fi.i & 0x7fffff) >> 16;
290
291 /*
292 * Repeat the process, this time with an exponent of
293 * 1, stored as 128
294 */
295
296 fi.i = 0;
297 fi.i = (i << 16) | (128 << 23);
298 fi.f = sqrt(fi.f);
299 sqrttab[i+0x80] = (fi.i & 0x7fffff) >> 16;
300 }
301 #else
302 (void) sqrttab; /* silence compiler warnings */
303 #endif /*HAVE_FAST_MATH*/
304 }
305
306
307 /**
308 * Single precision square root.
309 */
310 float
311 _mesa_sqrtf( float x )
312 {
313 #if defined(USE_IEEE) && !defined(DEBUG)
314 fi_type num;
315 /* to access the bits of a float in C
316 * we use a union from glheader.h */
317
318 short e; /* the exponent */
319 if (x == 0.0F) return 0.0F; /* check for square root of 0 */
320 num.f = x;
321 e = (num.i >> 23) - 127; /* get the exponent - on a SPARC the */
322 /* exponent is stored with 127 added */
323 num.i &= 0x7fffff; /* leave only the mantissa */
324 if (e & 0x01) num.i |= 0x800000;
325 /* the exponent is odd so we have to */
326 /* look it up in the second half of */
327 /* the lookup table, so we set the */
328 /* high bit */
329 e >>= 1; /* divide the exponent by two */
330 /* note that in C the shift */
331 /* operators are sign preserving */
332 /* for signed operands */
333 /* Do the table lookup, based on the quaternary mantissa,
334 * then reconstruct the result back into a float
335 */
336 num.i = ((sqrttab[num.i >> 16]) << 16) | ((e + 127) << 23);
337
338 return num.f;
339 #else
340 return (float) _mesa_sqrtd((double) x);
341 #endif
342 }
343
344
345 /**
346 inv_sqrt - A single precision 1/sqrt routine for IEEE format floats.
347 written by Josh Vanderhoof, based on newsgroup posts by James Van Buskirk
348 and Vesa Karvonen.
349 */
350 float
351 _mesa_inv_sqrtf(float n)
352 {
353 #if defined(USE_IEEE) && !defined(DEBUG)
354 float r0, x0, y0;
355 float r1, x1, y1;
356 float r2, x2, y2;
357 #if 0 /* not used, see below -BP */
358 float r3, x3, y3;
359 #endif
360 fi_type u;
361 unsigned int magic;
362
363 /*
364 Exponent part of the magic number -
365
366 We want to:
367 1. subtract the bias from the exponent,
368 2. negate it
369 3. divide by two (rounding towards -inf)
370 4. add the bias back
371
372 Which is the same as subtracting the exponent from 381 and dividing
373 by 2.
374
375 floor(-(x - 127) / 2) + 127 = floor((381 - x) / 2)
376 */
377
378 magic = 381 << 23;
379
380 /*
381 Significand part of magic number -
382
383 With the current magic number, "(magic - u.i) >> 1" will give you:
384
385 for 1 <= u.f <= 2: 1.25 - u.f / 4
386 for 2 <= u.f <= 4: 1.00 - u.f / 8
387
388 This isn't a bad approximation of 1/sqrt. The maximum difference from
389 1/sqrt will be around .06. After three Newton-Raphson iterations, the
390 maximum difference is less than 4.5e-8. (Which is actually close
391 enough to make the following bias academic...)
392
393 To get a better approximation you can add a bias to the magic
394 number. For example, if you subtract 1/2 of the maximum difference in
395 the first approximation (.03), you will get the following function:
396
397 for 1 <= u.f <= 2: 1.22 - u.f / 4
398 for 2 <= u.f <= 3.76: 0.97 - u.f / 8
399 for 3.76 <= u.f <= 4: 0.72 - u.f / 16
400 (The 3.76 to 4 range is where the result is < .5.)
401
402 This is the closest possible initial approximation, but with a maximum
403 error of 8e-11 after three NR iterations, it is still not perfect. If
404 you subtract 0.0332281 instead of .03, the maximum error will be
405 2.5e-11 after three NR iterations, which should be about as close as
406 is possible.
407
408 for 1 <= u.f <= 2: 1.2167719 - u.f / 4
409 for 2 <= u.f <= 3.73: 0.9667719 - u.f / 8
410 for 3.73 <= u.f <= 4: 0.7167719 - u.f / 16
411
412 */
413
414 magic -= (int)(0.0332281 * (1 << 25));
415
416 u.f = n;
417 u.i = (magic - u.i) >> 1;
418
419 /*
420 Instead of Newton-Raphson, we use Goldschmidt's algorithm, which
421 allows more parallelism. From what I understand, the parallelism
422 comes at the cost of less precision, because it lets error
423 accumulate across iterations.
424 */
425 x0 = 1.0f;
426 y0 = 0.5f * n;
427 r0 = u.f;
428
429 x1 = x0 * r0;
430 y1 = y0 * r0 * r0;
431 r1 = 1.5f - y1;
432
433 x2 = x1 * r1;
434 y2 = y1 * r1 * r1;
435 r2 = 1.5f - y2;
436
437 #if 1
438 return x2 * r2; /* we can stop here, and be conformant -BP */
439 #else
440 x3 = x2 * r2;
441 y3 = y2 * r2 * r2;
442 r3 = 1.5f - y3;
443
444 return x3 * r3;
445 #endif
446 #else
447 return (float) (1.0 / sqrt(n));
448 #endif
449 }
450
451 #ifndef __GNUC__
452 /**
453 * Find the first bit set in a word.
454 */
455 int
456 _mesa_ffs(int32_t i)
457 {
458 #if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__)
459 register int bit = 0;
460 if (i != 0) {
461 if ((i & 0xffff) == 0) {
462 bit += 16;
463 i >>= 16;
464 }
465 if ((i & 0xff) == 0) {
466 bit += 8;
467 i >>= 8;
468 }
469 if ((i & 0xf) == 0) {
470 bit += 4;
471 i >>= 4;
472 }
473 while ((i & 1) == 0) {
474 bit++;
475 i >>= 1;
476 }
477 bit++;
478 }
479 return bit;
480 #else
481 return ffs(i);
482 #endif
483 }
484
485
486 /**
487 * Find position of first bit set in given value.
488 * XXX Warning: this function can only be used on 64-bit systems!
489 * \return position of least-significant bit set, starting at 1, return zero
490 * if no bits set.
491 */
492 int
493 _mesa_ffsll(int64_t val)
494 {
495 int bit;
496
497 assert(sizeof(val) == 8);
498
499 bit = _mesa_ffs((int32_t)val);
500 if (bit != 0)
501 return bit;
502
503 bit = _mesa_ffs((int32_t)(val >> 32));
504 if (bit != 0)
505 return 32 + bit;
506
507 return 0;
508 }
509 #endif
510
511 #if !defined(__GNUC__) ||\
512 ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
513 /**
514 * Return number of bits set in given GLuint.
515 */
516 unsigned int
517 _mesa_bitcount(unsigned int n)
518 {
519 unsigned int bits;
520 for (bits = 0; n > 0; n = n >> 1) {
521 bits += (n & 1);
522 }
523 return bits;
524 }
525
526 /**
527 * Return number of bits set in given 64-bit uint.
528 */
529 unsigned int
530 _mesa_bitcount_64(uint64_t n)
531 {
532 unsigned int bits;
533 for (bits = 0; n > 0; n = n >> 1) {
534 bits += (n & 1);
535 }
536 return bits;
537 }
538 #endif
539
540 /*@}*/
541
542
543 /**********************************************************************/
544 /** \name Sort & Search */
545 /*@{*/
546
547 /**
548 * Wrapper for bsearch().
549 */
550 void *
551 _mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
552 int (*compar)(const void *, const void *) )
553 {
554 #if defined(_WIN32_WCE)
555 void *mid;
556 int cmp;
557 while (nmemb) {
558 nmemb >>= 1;
559 mid = (char *)base + nmemb * size;
560 cmp = (*compar)(key, mid);
561 if (cmp == 0)
562 return mid;
563 if (cmp > 0) {
564 base = (char *)mid + size;
565 --nmemb;
566 }
567 }
568 return NULL;
569 #else
570 return bsearch(key, base, nmemb, size, compar);
571 #endif
572 }
573
574 /*@}*/
575
576
577 /**********************************************************************/
578 /** \name Environment vars */
579 /*@{*/
580
581 /**
582 * Wrapper for getenv().
583 */
584 char *
585 _mesa_getenv( const char *var )
586 {
587 #if defined(_XBOX) || defined(_WIN32_WCE)
588 return NULL;
589 #else
590 return getenv(var);
591 #endif
592 }
593
594 /*@}*/
595
596
597 /**********************************************************************/
598 /** \name String */
599 /*@{*/
600
601 /**
602 * Implemented using malloc() and strcpy.
603 * Note that NULL is handled accordingly.
604 */
605 char *
606 _mesa_strdup( const char *s )
607 {
608 if (s) {
609 size_t l = strlen(s);
610 char *s2 = (char *) malloc(l + 1);
611 if (s2)
612 strcpy(s2, s);
613 return s2;
614 }
615 else {
616 return NULL;
617 }
618 }
619
620 /** Wrapper around strtof() */
621 float
622 _mesa_strtof( const char *s, char **end )
623 {
624 #if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
625 !defined(ANDROID) && !defined(__HAIKU__)
626 static locale_t loc = NULL;
627 if (!loc) {
628 loc = newlocale(LC_CTYPE_MASK, "C", NULL);
629 }
630 return strtof_l(s, end, loc);
631 #elif defined(_ISOC99_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
632 return strtof(s, end);
633 #else
634 return (float)strtod(s, end);
635 #endif
636 }
637
638 /** Compute simple checksum/hash for a string */
639 unsigned int
640 _mesa_str_checksum(const char *str)
641 {
642 /* This could probably be much better */
643 unsigned int sum, i;
644 const char *c;
645 sum = i = 1;
646 for (c = str; *c; c++, i++)
647 sum += *c * (i % 100);
648 return sum + i;
649 }
650
651
652 /*@}*/
653
654
655 /** Wrapper around vsnprintf() */
656 int
657 _mesa_snprintf( char *str, size_t size, const char *fmt, ... )
658 {
659 int r;
660 va_list args;
661 va_start( args, fmt );
662 r = vsnprintf( str, size, fmt, args );
663 va_end( args );
664 return r;
665 }
666
667
668 /**********************************************************************/
669 /** \name Diagnostics */
670 /*@{*/
671
672 static void
673 output_if_debug(const char *prefixString, const char *outputString,
674 GLboolean newline)
675 {
676 static int debug = -1;
677
678 /* Check the MESA_DEBUG environment variable if it hasn't
679 * been checked yet. We only have to check it once...
680 */
681 if (debug == -1) {
682 char *env = _mesa_getenv("MESA_DEBUG");
683
684 /* In a debug build, we print warning messages *unless*
685 * MESA_DEBUG is 0. In a non-debug build, we don't
686 * print warning messages *unless* MESA_DEBUG is
687 * set *to any value*.
688 */
689 #ifdef DEBUG
690 debug = (env != NULL && atoi(env) == 0) ? 0 : 1;
691 #else
692 debug = (env != NULL) ? 1 : 0;
693 #endif
694 }
695
696 /* Now only print the string if we're required to do so. */
697 if (debug) {
698 fprintf(stderr, "%s: %s", prefixString, outputString);
699 if (newline)
700 fprintf(stderr, "\n");
701
702 #if defined(_WIN32) && !defined(_WIN32_WCE)
703 /* stderr from windows applications without console is not usually
704 * visible, so communicate with the debugger instead */
705 {
706 char buf[4096];
707 _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
708 OutputDebugStringA(buf);
709 }
710 #endif
711 }
712 }
713
714
715 /**
716 * Return string version of GL error code.
717 */
718 static const char *
719 error_string( GLenum error )
720 {
721 switch (error) {
722 case GL_NO_ERROR:
723 return "GL_NO_ERROR";
724 case GL_INVALID_VALUE:
725 return "GL_INVALID_VALUE";
726 case GL_INVALID_ENUM:
727 return "GL_INVALID_ENUM";
728 case GL_INVALID_OPERATION:
729 return "GL_INVALID_OPERATION";
730 case GL_STACK_OVERFLOW:
731 return "GL_STACK_OVERFLOW";
732 case GL_STACK_UNDERFLOW:
733 return "GL_STACK_UNDERFLOW";
734 case GL_OUT_OF_MEMORY:
735 return "GL_OUT_OF_MEMORY";
736 case GL_TABLE_TOO_LARGE:
737 return "GL_TABLE_TOO_LARGE";
738 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
739 return "GL_INVALID_FRAMEBUFFER_OPERATION";
740 default:
741 return "unknown";
742 }
743 }
744
745
746 /**
747 * When a new type of error is recorded, print a message describing
748 * previous errors which were accumulated.
749 */
750 static void
751 flush_delayed_errors( struct gl_context *ctx )
752 {
753 char s[MAXSTRING];
754
755 if (ctx->ErrorDebugCount) {
756 _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
757 ctx->ErrorDebugCount,
758 error_string(ctx->ErrorValue));
759
760 output_if_debug("Mesa", s, GL_TRUE);
761
762 ctx->ErrorDebugCount = 0;
763 }
764 }
765
766
767 /**
768 * Report a warning (a recoverable error condition) to stderr if
769 * either DEBUG is defined or the MESA_DEBUG env var is set.
770 *
771 * \param ctx GL context.
772 * \param fmtString printf()-like format string.
773 */
774 void
775 _mesa_warning( struct gl_context *ctx, const char *fmtString, ... )
776 {
777 char str[MAXSTRING];
778 va_list args;
779 va_start( args, fmtString );
780 (void) vsnprintf( str, MAXSTRING, fmtString, args );
781 va_end( args );
782
783 if (ctx)
784 flush_delayed_errors( ctx );
785
786 output_if_debug("Mesa warning", str, GL_TRUE);
787 }
788
789
790 /**
791 * Report an internal implementation problem.
792 * Prints the message to stderr via fprintf().
793 *
794 * \param ctx GL context.
795 * \param fmtString problem description string.
796 */
797 void
798 _mesa_problem( const struct gl_context *ctx, const char *fmtString, ... )
799 {
800 va_list args;
801 char str[MAXSTRING];
802 static int numCalls = 0;
803
804 (void) ctx;
805
806 if (numCalls < 50) {
807 numCalls++;
808
809 va_start( args, fmtString );
810 vsnprintf( str, MAXSTRING, fmtString, args );
811 va_end( args );
812 fprintf(stderr, "Mesa %s implementation error: %s\n",
813 MESA_VERSION_STRING, str);
814 fprintf(stderr, "Please report at bugs.freedesktop.org\n");
815 }
816 }
817
818
819 /**
820 * Record an OpenGL state error. These usually occur when the user
821 * passes invalid parameters to a GL function.
822 *
823 * If debugging is enabled (either at compile-time via the DEBUG macro, or
824 * run-time via the MESA_DEBUG environment variable), report the error with
825 * _mesa_debug().
826 *
827 * \param ctx the GL context.
828 * \param error the error value.
829 * \param fmtString printf() style format string, followed by optional args
830 */
831 void
832 _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
833 {
834 static GLint debug = -1;
835
836 /* Check debug environment variable only once:
837 */
838 if (debug == -1) {
839 const char *debugEnv = _mesa_getenv("MESA_DEBUG");
840
841 #ifdef DEBUG
842 if (debugEnv && strstr(debugEnv, "silent"))
843 debug = GL_FALSE;
844 else
845 debug = GL_TRUE;
846 #else
847 if (debugEnv)
848 debug = GL_TRUE;
849 else
850 debug = GL_FALSE;
851 #endif
852 }
853
854 if (debug) {
855 if (ctx->ErrorValue == error &&
856 ctx->ErrorDebugFmtString == fmtString) {
857 ctx->ErrorDebugCount++;
858 }
859 else {
860 char s[MAXSTRING], s2[MAXSTRING];
861 va_list args;
862
863 flush_delayed_errors( ctx );
864
865 va_start(args, fmtString);
866 vsnprintf(s, MAXSTRING, fmtString, args);
867 va_end(args);
868
869 _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s);
870 output_if_debug("Mesa: User error", s2, GL_TRUE);
871
872 ctx->ErrorDebugFmtString = fmtString;
873 ctx->ErrorDebugCount = 0;
874 }
875 }
876
877 _mesa_record_error(ctx, error);
878 }
879
880
881 /**
882 * Report debug information. Print error message to stderr via fprintf().
883 * No-op if DEBUG mode not enabled.
884 *
885 * \param ctx GL context.
886 * \param fmtString printf()-style format string, followed by optional args.
887 */
888 void
889 _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... )
890 {
891 //#ifdef DEBUG
892 char s[MAXSTRING];
893 va_list args;
894 va_start(args, fmtString);
895 vsnprintf(s, MAXSTRING, fmtString, args);
896 va_end(args);
897 output_if_debug("Mesa", s, GL_FALSE);
898 //#endif /* DEBUG */
899 (void) ctx;
900 (void) fmtString;
901 }
902
903 /*@}*/