From a30c4c6ca018413db8f8ca5c766a6f0d3f8af6be Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 23 Apr 2014 14:17:55 +0800 Subject: [PATCH] mesa: clean up debug output namespace handling Add functions to provide these operations on a struct gl_debug_namespace: init(): initialize the namespace copy(): copy all elements from one namespace to another clear(): clear all elements (to free the memories) set(): set the value of an element set_all(): set the value of all elements get(): get the value of an element A debug namespace is like a sparse array. The length of the array is huge, 2^sizeof(GLuint), but most of the elements assume the same value sepcified by set_all(). Signed-off-by: Chia-I Wu Reviewed-by: Brian Paul --- src/mesa/main/errors.c | 350 +++++++++++++++++++++++++---------------- 1 file changed, 211 insertions(+), 139 deletions(-) diff --git a/src/mesa/main/errors.c b/src/mesa/main/errors.c index 6f145686211..20d8d6019c0 100644 --- a/src/mesa/main/errors.c +++ b/src/mesa/main/errors.c @@ -274,6 +274,207 @@ debug_message_store(struct gl_debug_message *msg, } } +static void +debug_namespace_init(struct gl_debug_namespace *ns) +{ + int sev; + + memset(ns, 0, sizeof(*ns)); + + ns->IDs = _mesa_NewHashTable(); + assert(ns->IDs); + + for (sev = 0; sev < Elements(ns->Severity); sev++) + make_empty_list(&ns->Severity[sev]); + + /* Enable all the messages with severity HIGH or MEDIUM by default */ + ns->Defaults[MESA_DEBUG_SEVERITY_HIGH] = GL_TRUE; + ns->Defaults[MESA_DEBUG_SEVERITY_MEDIUM] = GL_TRUE; +} + +static void +debug_namespace_clear_cb(GLuint key, void *data, void *userData) +{ +} + +static void +debug_namespace_clear(struct gl_debug_namespace *ns) +{ + int sev; + + _mesa_HashDeleteAll(ns->IDs, debug_namespace_clear_cb, NULL); + _mesa_DeleteHashTable(ns->IDs); + + for (sev = 0; sev < Elements(ns->Severity); sev++) { + struct simple_node *node, *tmp; + + foreach_s(node, tmp, &ns->Severity[sev]) + free(node); + } +} + +static bool +debug_namespace_copy(struct gl_debug_namespace *dst, + const struct gl_debug_namespace *src) +{ + bool err = false; + int sev; + + /* copy id settings */ + dst->IDs = _mesa_HashClone(src->IDs); + if (!dst->IDs) + return false; + + for (sev = 0; sev < Elements(dst->Severity); sev++) { + struct simple_node *node; + + /* copy default settings for unknown ids */ + dst->Defaults[sev] = src->Defaults[sev]; + + make_empty_list(&dst->Severity[sev]); + if (err) + continue; + + /* copy known id severity settings */ + foreach(node, &src->Severity[sev]) { + const struct gl_debug_severity *entry = + (const struct gl_debug_severity *) node; + struct gl_debug_severity *copy; + + copy = malloc(sizeof(*copy)); + if (!copy) { + err = true; + break; + } + + copy->ID = entry->ID; + insert_at_tail(&dst->Severity[sev], ©->link); + } + } + + if (err) { + debug_namespace_clear(dst); + return false; + } + + return true; +} + +/** + * Set the state of \p id in the namespace. + */ +static bool +debug_namespace_set(struct gl_debug_namespace *ns, + GLuint id, bool enabled) +{ + uintptr_t state; + + /* In addition to not being able to store zero as a value, HashTable also + * can't use zero as a key. + */ + if (id) + state = (uintptr_t) _mesa_HashLookup(ns->IDs, id); + else + state = ns->ZeroID; + + if (state == NOT_FOUND) + state = enabled ? ENABLED : DISABLED; + else { + if (enabled) + state |= ENABLED_BIT; + else + state &= ~ENABLED_BIT; + } + + if (id) + _mesa_HashInsert(ns->IDs, id, (void *) state); + else + ns->ZeroID = state; + + return true; +} + +/** + * Set the default state of the namespace for \p severity. When \p severity + * is MESA_DEBUG_SEVERITY_COUNT, the default values for all severities are + * updated. + */ +static void +debug_namespace_set_all(struct gl_debug_namespace *ns, + enum mesa_debug_severity severity, + bool enabled) +{ + int sev, end; + + if (severity >= Elements(ns->Severity)) { + end = severity; + severity = 0; + } else { + end = severity + 1; + } + + for (sev = severity; sev < end; sev++) { + struct simple_node *node; + struct gl_debug_severity *entry; + + /* change the default for IDs we've never seen before. */ + ns->Defaults[sev] = enabled; + + /* Now change the state of IDs we *have* seen... */ + foreach(node, &ns->Severity[sev]) { + entry = (struct gl_debug_severity *) node; + debug_namespace_set(ns, entry->ID, enabled); + } + } +} + +/** + * Get the state of \p id in the namespace. + */ +static bool +debug_namespace_get(struct gl_debug_namespace *ns, GLuint id, + enum mesa_debug_severity severity) +{ + uintptr_t state = 0; + + /* In addition to not being able to store zero as a value, HashTable also + * can't use zero as a key. + */ + if (id) + state = (uintptr_t) _mesa_HashLookup(ns->IDs, id); + else + state = ns->ZeroID; + + /* Only do this once for each ID. This makes sure the ID exists in, + * at most, one list, and does not pointlessly appear multiple times. + */ + if (!(state & KNOWN_SEVERITY)) { + struct gl_debug_severity *entry; + + if (state == NOT_FOUND) { + if (ns->Defaults[severity]) + state = ENABLED; + else + state = DISABLED; + } + + entry = malloc(sizeof *entry); + if (entry) { + state |= KNOWN_SEVERITY; + + if (id) + _mesa_HashInsert(ns->IDs, id, (void *) state); + else + ns->ZeroID = state; + + entry->ID = id; + insert_at_tail(&ns->Severity[severity], &entry->link); + } + } + + return (state & ENABLED_BIT); +} + /** * Allocate and initialize context debug state. */ @@ -281,7 +482,7 @@ static struct gl_debug_state * debug_create(void) { struct gl_debug_state *debug; - int s, t, sev; + int s, t; debug = CALLOC_STRUCT(gl_debug_state); if (!debug) @@ -290,29 +491,13 @@ debug_create(void) /* Initialize state for filtering known debug messages. */ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) { for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) { - struct gl_debug_namespace *nspace = - &debug->Groups[0].Namespaces[s][t]; - - nspace->IDs = _mesa_NewHashTable(); - assert(nspace->IDs); - - for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) - make_empty_list(&nspace->Severity[sev]); - - /* Enable all the messages with severity HIGH or MEDIUM by default */ - nspace->Defaults[MESA_DEBUG_SEVERITY_HIGH] = GL_TRUE; - nspace->Defaults[MESA_DEBUG_SEVERITY_MEDIUM] = GL_TRUE; + debug_namespace_init(&debug->Groups[0].Namespaces[s][t]); } } return debug; } -static void -debug_clear_group_cb(GLuint key, void *data, void *userData) -{ -} - /** * Free debug state for the given stack depth. */ @@ -322,24 +507,11 @@ debug_clear_group(struct gl_debug_state *debug, GLint gstack) struct gl_debug_group *grp = &debug->Groups[gstack]; enum mesa_debug_type t; enum mesa_debug_source s; - enum mesa_debug_severity sev; /* Tear down state for filtering debug messages. */ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) { for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) { - struct gl_debug_namespace *nspace = &grp->Namespaces[s][t]; - - _mesa_HashDeleteAll(nspace->IDs, debug_clear_group_cb, NULL); - _mesa_DeleteHashTable(nspace->IDs); - for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) { - struct simple_node *node, *tmp; - struct gl_debug_severity *entry; - - foreach_s(node, tmp, &nspace->Severity[sev]) { - entry = (struct gl_debug_severity *)node; - free(entry); - } - } + debug_namespace_clear(&grp->Namespaces[s][t]); } } } @@ -371,29 +543,8 @@ debug_set_message_enable(struct gl_debug_state *debug, const GLint gstack = debug->GroupStackDepth; struct gl_debug_namespace *nspace = &debug->Groups[gstack].Namespaces[source][type]; - uintptr_t state; - - /* In addition to not being able to store zero as a value, HashTable also - * can't use zero as a key. - */ - if (id) - state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id); - else - state = nspace->ZeroID; - - if (state == NOT_FOUND) - state = enabled ? ENABLED : DISABLED; - else { - if (enabled) - state |= ENABLED_BIT; - else - state &= ~ENABLED_BIT; - } - if (id) - _mesa_HashInsert(nspace->IDs, id, (void*)state); - else - nspace->ZeroID = state; + debug_namespace_set(nspace, id, enabled); } /* @@ -415,7 +566,7 @@ debug_set_message_enable_all(struct gl_debug_state *debug, GLboolean enabled) { const GLint gstack = debug->GroupStackDepth; - int s, t, sev, smax, tmax, sevmax; + int s, t, smax, tmax; if (source == MESA_DEBUG_SOURCE_COUNT) { source = 0; @@ -431,31 +582,11 @@ debug_set_message_enable_all(struct gl_debug_state *debug, tmax = type+1; } - if (severity == MESA_DEBUG_SEVERITY_COUNT) { - severity = 0; - sevmax = MESA_DEBUG_SEVERITY_COUNT; - } else { - sevmax = severity+1; - } - for (s = source; s < smax; s++) { for (t = type; t < tmax; t++) { struct gl_debug_namespace *nspace = &debug->Groups[gstack].Namespaces[s][t]; - - for (sev = severity; sev < sevmax; sev++) { - struct simple_node *node; - struct gl_debug_severity *entry; - - /* change the default for IDs we've never seen before. */ - nspace->Defaults[sev] = enabled; - - /* Now change the state of IDs we *have* seen... */ - foreach(node, &nspace->Severity[sev]) { - entry = (struct gl_debug_severity *)node; - debug_set_message_enable(debug, s, t, entry->ID, enabled); - } - } + debug_namespace_set_all(nspace, severity, enabled); } } } @@ -473,48 +604,11 @@ debug_is_message_enabled(struct gl_debug_state *debug, const GLint gstack = debug->GroupStackDepth; struct gl_debug_group *grp = &debug->Groups[gstack]; struct gl_debug_namespace *nspace = &grp->Namespaces[source][type]; - uintptr_t state = 0; if (!debug->DebugOutput) return false; - /* In addition to not being able to store zero as a value, HashTable also - * can't use zero as a key. - */ - if (id) - state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id); - else - state = nspace->ZeroID; - - /* Only do this once for each ID. This makes sure the ID exists in, - * at most, one list, and does not pointlessly appear multiple times. - */ - if (!(state & KNOWN_SEVERITY)) { - struct gl_debug_severity *entry; - - if (state == NOT_FOUND) { - if (nspace->Defaults[severity]) - state = ENABLED; - else - state = DISABLED; - } - - entry = malloc(sizeof *entry); - if (!entry) - goto out; - - state |= KNOWN_SEVERITY; - - if (id) - _mesa_HashInsert(nspace->IDs, id, (void*)state); - else - nspace->ZeroID = state; - - entry->ID = id; - insert_at_tail(&nspace->Severity[severity], &entry->link); - } -out: - return (state & ENABLED_BIT); + return debug_namespace_get(nspace, id, severity); } /** @@ -592,7 +686,7 @@ static void debug_push_group(struct gl_debug_state *debug) { const GLint gstack = debug->GroupStackDepth; - int s, t, sev; + int s, t; /* inherit the control volume of the debug group previously residing on * the top of the debug group stack @@ -604,30 +698,8 @@ debug_push_group(struct gl_debug_state *debug) struct gl_debug_namespace *next = &debug->Groups[gstack + 1].Namespaces[s][t]; - /* copy id settings */ - next->IDs = _mesa_HashClone(nspace->IDs); - - for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) { - struct simple_node *node; - - /* copy default settings for unknown ids */ - next->Defaults[sev] = nspace->Defaults[sev]; - - /* copy known id severity settings */ - make_empty_list(&next->Severity[sev]); - foreach(node, &nspace->Severity[sev]) { - const struct gl_debug_severity *entry = - (const struct gl_debug_severity *) node; - struct gl_debug_severity *copy; - - copy = malloc(sizeof *entry); - if (!copy) - goto out; - - copy->ID = entry->ID; - insert_at_tail(&next->Severity[sev], ©->link); - } - } + if (!debug_namespace_copy(next, nspace)) + goto out; } } -- 2.30.2