summaryrefslogtreecommitdiff
path: root/src/mesa/main/imports.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/imports.c')
-rw-r--r--src/mesa/main/imports.c250
1 files changed, 173 insertions, 77 deletions
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 5cf1a2baa4..6ffaddcde9 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -557,7 +557,7 @@ _mesa_pow(double x, double y)
* Find the first bit set in a word.
*/
int
-_mesa_ffs(int i)
+_mesa_ffs(int32_t i)
{
#if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__)
register int bit = 0;
@@ -594,11 +594,7 @@ _mesa_ffs(int i)
* if no bits set.
*/
int
-#ifdef __MINGW32__
-_mesa_ffsll(long val)
-#else
-_mesa_ffsll(long long val)
-#endif
+_mesa_ffsll(int64_t val)
{
#ifdef ffsll
return ffsll(val);
@@ -607,11 +603,11 @@ _mesa_ffsll(long long val)
assert(sizeof(val) == 8);
- bit = _mesa_ffs(val);
+ bit = _mesa_ffs((int32_t)val);
if (bit != 0)
return bit;
- bit = _mesa_ffs(val >> 32);
+ bit = _mesa_ffs((int32_t)(val >> 32));
if (bit != 0)
return 32 + bit;
@@ -915,6 +911,20 @@ _mesa_strtod( const char *s, char **end )
return strtod(s, end);
}
+/** Compute simple checksum/hash for a string */
+unsigned int
+_mesa_str_checksum(const char *str)
+{
+ /* This could probably be much better */
+ unsigned int sum, i;
+ const char *c;
+ sum = i = 1;
+ for (c = str; *c; c++)
+ sum += *c * (i % 100);
+ return sum;
+}
+
+
/*@}*/
@@ -950,14 +960,25 @@ _mesa_snprintf( char *str, size_t size, const char *fmt, ... )
void
_mesa_printf( const char *fmtString, ... )
{
+ va_list args;
+ va_start( args, fmtString );
+ vfprintf(stderr, fmtString, args);
+ va_end( args );
+}
+
+/** Wrapper around fprintf(), using vsprintf() for the formatting. */
+void
+_mesa_fprintf( FILE *f, const char *fmtString, ... )
+{
char s[MAXSTRING];
va_list args;
va_start( args, fmtString );
vsnprintf(s, MAXSTRING, fmtString, args);
va_end( args );
- fprintf(stderr,"%s", s);
+ fprintf(f, "%s", s);
}
+
/** Wrapper around vsprintf() */
int
_mesa_vsprintf( char *str, const char *fmt, va_list args )
@@ -972,39 +993,130 @@ _mesa_vsprintf( char *str, const char *fmt, va_list args )
/** \name Diagnostics */
/*@{*/
+static void
+output_if_debug(const char *prefixString, const char *outputString,
+ GLboolean newline)
+{
+ static int debug = -1;
+
+ /* Check the MESA_DEBUG environment variable if it hasn't
+ * been checked yet. We only have to check it once...
+ */
+ if (debug == -1) {
+ char *env = _mesa_getenv("MESA_DEBUG");
+
+ /* In a debug build, we print warning messages *unless*
+ * MESA_DEBUG is 0. In a non-debug build, we don't
+ * print warning messages *unless* MESA_DEBUG is
+ * set *to any value*.
+ */
+#ifdef DEBUG
+ debug = (env != NULL && _mesa_atoi(env) == 0) ? 0 : 1;
+#else
+ debug = (env != NULL) ? 1 : 0;
+#endif
+ }
+
+ /* Now only print the string if we're required to do so. */
+ if (debug) {
+ fprintf(stderr, "%s: %s", prefixString, outputString);
+ if (newline)
+ fprintf(stderr, "\n");
+
+#if defined(_WIN32) && !defined(_WIN32_WCE)
+ /* stderr from windows applications without console is not usually
+ * visible, so communicate with the debugger instead */
+ {
+ char buf[4096];
+ _mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
+ OutputDebugStringA(buf);
+ }
+#endif
+ }
+}
+
+
+/**
+ * Return string version of GL error code.
+ */
+static const char *
+error_string( GLenum error )
+{
+ switch (error) {
+ case GL_NO_ERROR:
+ return "GL_NO_ERROR";
+ case GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+ case GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+ case GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+ case GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+ case GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+ case GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+ case GL_TABLE_TOO_LARGE:
+ return "GL_TABLE_TOO_LARGE";
+ case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
+ return "GL_INVALID_FRAMEBUFFER_OPERATION";
+ default:
+ return "unknown";
+ }
+}
+
+
+/**
+ * When a new type of error is recorded, print a message describing
+ * previous errors which were accumulated.
+ */
+static void
+flush_delayed_errors( GLcontext *ctx )
+{
+ char s[MAXSTRING];
+
+ if (ctx->ErrorDebugCount) {
+ _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
+ ctx->ErrorDebugCount,
+ error_string(ctx->ErrorValue));
+
+ output_if_debug("Mesa", s, GL_TRUE);
+
+ ctx->ErrorDebugCount = 0;
+ }
+}
+
+
/**
* Report a warning (a recoverable error condition) to stderr if
* either DEBUG is defined or the MESA_DEBUG env var is set.
*
* \param ctx GL context.
- * \param fmtString printf() alike format string.
+ * \param fmtString printf()-like format string.
*/
void
_mesa_warning( GLcontext *ctx, const char *fmtString, ... )
{
- GLboolean debug;
char str[MAXSTRING];
va_list args;
- (void) ctx;
va_start( args, fmtString );
(void) vsnprintf( str, MAXSTRING, fmtString, args );
va_end( args );
-#ifdef DEBUG
- debug = GL_TRUE; /* always print warning */
-#else
- debug = _mesa_getenv("MESA_DEBUG") ? GL_TRUE : GL_FALSE;
-#endif
- if (debug) {
- fprintf(stderr, "Mesa warning: %s\n", str);
- }
+
+ if (ctx)
+ flush_delayed_errors( ctx );
+
+ output_if_debug("Mesa warning", str, GL_TRUE);
}
+
/**
- * Report an internla implementation problem.
+ * Report an internal implementation problem.
* Prints the message to stderr via fprintf().
*
* \param ctx GL context.
- * \param s problem description string.
+ * \param fmtString problem description string.
*/
void
_mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
@@ -1021,8 +1133,9 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
}
+
/**
- * Record an OpenGL state error. These usually occur when the users
+ * Record an OpenGL state error. These usually occur when the user
* passes invalid parameters to a GL function.
*
* If debugging is enabled (either at compile-time via the DEBUG macro, or
@@ -1036,69 +1149,52 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
void
_mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... )
{
- const char *debugEnv;
- GLboolean debug;
+ static GLint debug = -1;
- debugEnv = _mesa_getenv("MESA_DEBUG");
+ /* Check debug environment variable only once:
+ */
+ if (debug == -1) {
+ const char *debugEnv = _mesa_getenv("MESA_DEBUG");
#ifdef DEBUG
- if (debugEnv && _mesa_strstr(debugEnv, "silent"))
- debug = GL_FALSE;
- else
- debug = GL_TRUE;
+ if (debugEnv && _mesa_strstr(debugEnv, "silent"))
+ debug = GL_FALSE;
+ else
+ debug = GL_TRUE;
#else
- if (debugEnv)
- debug = GL_TRUE;
- else
- debug = GL_FALSE;
+ if (debugEnv)
+ debug = GL_TRUE;
+ else
+ debug = GL_FALSE;
#endif
+ }
- if (debug) {
- va_list args;
- char where[MAXSTRING];
- const char *errstr;
-
- va_start( args, fmtString );
- vsnprintf( where, MAXSTRING, fmtString, args );
- va_end( args );
-
- switch (error) {
- case GL_NO_ERROR:
- errstr = "GL_NO_ERROR";
- break;
- case GL_INVALID_VALUE:
- errstr = "GL_INVALID_VALUE";
- break;
- case GL_INVALID_ENUM:
- errstr = "GL_INVALID_ENUM";
- break;
- case GL_INVALID_OPERATION:
- errstr = "GL_INVALID_OPERATION";
- break;
- case GL_STACK_OVERFLOW:
- errstr = "GL_STACK_OVERFLOW";
- break;
- case GL_STACK_UNDERFLOW:
- errstr = "GL_STACK_UNDERFLOW";
- break;
- case GL_OUT_OF_MEMORY:
- errstr = "GL_OUT_OF_MEMORY";
- break;
- case GL_TABLE_TOO_LARGE:
- errstr = "GL_TABLE_TOO_LARGE";
- break;
- case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
- errstr = "GL_INVALID_FRAMEBUFFER_OPERATION";
- break;
- default:
- errstr = "unknown";
- break;
+ if (debug) {
+ if (ctx->ErrorValue == error &&
+ ctx->ErrorDebugFmtString == fmtString) {
+ ctx->ErrorDebugCount++;
+ }
+ else {
+ char s[MAXSTRING], s2[MAXSTRING];
+ va_list args;
+
+ flush_delayed_errors( ctx );
+
+ va_start(args, fmtString);
+ vsnprintf(s, MAXSTRING, fmtString, args);
+ va_end(args);
+
+ _mesa_snprintf(s2, MAXSTRING, "%s in %s", error_string(error), s);
+ output_if_debug("Mesa: User error", s2, GL_TRUE);
+
+ ctx->ErrorDebugFmtString = fmtString;
+ ctx->ErrorDebugCount = 0;
}
- _mesa_debug(ctx, "User error: %s in %s\n", errstr, where);
}
_mesa_record_error(ctx, error);
-}
+}
+
/**
* Report debug information. Print error message to stderr via fprintf().
@@ -1116,7 +1212,7 @@ _mesa_debug( const GLcontext *ctx, const char *fmtString, ... )
va_start(args, fmtString);
vsnprintf(s, MAXSTRING, fmtString, args);
va_end(args);
- fprintf(stderr, "Mesa: %s", s);
+ output_if_debug("Mesa", s, GL_FALSE);
#endif /* DEBUG */
(void) ctx;
(void) fmtString;