On 04/25/2014 04:42 AM, Chia-I Wu wrote:
When GL_DEBUG_OUTPUT_SYNCHRONOUS is GL_TRUE, drivers are allowed to log debug
messages from other threads.  That requires gl_debug_state to be protected by
a mutex, even when it is a context state.  While we do not spawn threads in
Mesa yet, this commit makes it easier to do when we want to.

Since the definition of struct gl_debug_state is no longer needed by the rest
of the driver, move it to main/errors.c.  This should make it even harder to
use the struct incorrectly.

Signed-off-by: Chia-I Wu <o...@lunarg.com>
---
  src/mesa/drivers/dri/common/dri_util.c |   5 +-
  src/mesa/main/enable.c                 |  35 ++-------
  src/mesa/main/errors.c                 | 125 ++++++++++++++++++++++++++++++++-
  src/mesa/main/errors.h                 |  10 ++-
  src/mesa/main/get.c                    |  16 +----
  src/mesa/main/getstring.c              |  17 +----
  src/mesa/main/mtypes.h                 |  40 +----------
  src/mesa/state_tracker/st_manager.c    |   4 +-
  8 files changed, 144 insertions(+), 108 deletions(-)

diff --git a/src/mesa/drivers/dri/common/dri_util.c 
b/src/mesa/drivers/dri/common/dri_util.c
index aed73c7..c410474 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -449,10 +449,7 @@ driContextSetFlags(struct gl_context *ctx, uint32_t flags)
      if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
          ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
      if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) {
-        struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
-        if (debug) {
-            debug->DebugOutput = GL_TRUE;
-        }
+       _mesa_set_debug_state_int(ctx, GL_DEBUG_OUTPUT, GL_TRUE);
          ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT;
      }
  }
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index edd4751..0f3bcf0 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -368,26 +368,11 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, 
GLboolean state)
           ctx->Depth.Test = state;
           break;
        case GL_DEBUG_OUTPUT:
-         if (!_mesa_is_desktop_gl(ctx)) {
-            goto invalid_enum_error;
-         }
-         else {
-            struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
-            if (debug) {
-               debug->DebugOutput = state;
-            }
-         }
-         break;
        case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
-         if (!_mesa_is_desktop_gl(ctx)) {
+         if (!_mesa_is_desktop_gl(ctx))
              goto invalid_enum_error;
-         }
-         else {
-            struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
-            if (debug) {
-               debug->SyncOutput = state;
-            }
-         }
+         else
+            _mesa_set_debug_state_int(ctx, cap, state);
           break;
        case GL_DITHER:
           if (ctx->Color.DitherFlag == state)
@@ -1239,21 +1224,11 @@ _mesa_IsEnabled( GLenum cap )
        case GL_CULL_FACE:
           return ctx->Polygon.CullFlag;
        case GL_DEBUG_OUTPUT:
-         if (!_mesa_is_desktop_gl(ctx))
-            goto invalid_enum_error;
-         if (ctx->Debug) {
-            return ctx->Debug->DebugOutput;
-         } else {
-            return GL_FALSE;
-         }
        case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
           if (!_mesa_is_desktop_gl(ctx))
              goto invalid_enum_error;
-         if (ctx->Debug) {
-            return ctx->Debug->SyncOutput;
-         } else {
-            return GL_FALSE;
-         }
+         else
+            return (GLboolean) _mesa_get_debug_state_int(ctx, cap);
        case GL_DEPTH_TEST:
           return ctx->Depth.Test;
        case GL_DITHER:
diff --git a/src/mesa/main/errors.c b/src/mesa/main/errors.c
index 277f38c..9258eb6 100644
--- a/src/mesa/main/errors.c
+++ b/src/mesa/main/errors.c
@@ -47,6 +47,45 @@ struct gl_debug_severity
     GLuint ID;
  };

+/**
+ * An error, warning, or other piece of debug information for an application
+ * to consume via GL_ARB_debug_output/GL_KHR_debug.
+ */
+struct gl_debug_msg
+{
+   enum mesa_debug_source source;
+   enum mesa_debug_type type;
+   GLuint id;
+   enum mesa_debug_severity severity;
+   GLsizei length;
+   GLcharARB *message;
+};
+
+struct gl_debug_namespace
+{
+   struct _mesa_HashTable *IDs;
+   unsigned ZeroID; /* a HashTable won't take zero, so store its state here */
+   /** lists of IDs in the hash table at each severity */
+   struct simple_node Severity[MESA_DEBUG_SEVERITY_COUNT];
+};
+
+struct gl_debug_state
+{
+   GLDEBUGPROC Callback;
+   const void *CallbackData;
+   GLboolean SyncOutput;
+   GLboolean DebugOutput;
+   GLboolean 
Defaults[MAX_DEBUG_GROUP_STACK_DEPTH][MESA_DEBUG_SEVERITY_COUNT][MESA_DEBUG_SOURCE_COUNT][MESA_DEBUG_TYPE_COUNT];
+   struct gl_debug_namespace 
Namespaces[MAX_DEBUG_GROUP_STACK_DEPTH][MESA_DEBUG_SOURCE_COUNT][MESA_DEBUG_TYPE_COUNT];
+   struct gl_debug_msg Log[MAX_DEBUG_LOGGED_MESSAGES];
+   struct gl_debug_msg DebugGroupMsgs[MAX_DEBUG_GROUP_STACK_DEPTH];
+   GLint GroupStackDepth;
+   GLint NumMessages;
+   GLint NextMsg;
+   GLint NextMsgLength; /* redundant, but copied here from Log[NextMsg].length
+                           for the sake of the offsetof() code in get.c */
+};
+
  static char out_of_memory[] = "Debugging error: out of memory";

  static const GLenum debug_source_enums[] = {
@@ -597,7 +636,7 @@ debug_pop_group(struct gl_debug_state *debug)
   * Return debug state for the context.  The debug state will be allocated
   * and initialized upon the first call.
   */
-struct gl_debug_state *
+static struct gl_debug_state *
  _mesa_get_debug_state(struct gl_context *ctx)
  {
     if (!ctx->Debug) {
@@ -610,6 +649,90 @@ _mesa_get_debug_state(struct gl_context *ctx)
     return ctx->Debug;
  }


I think it would be good to have comments on the following three new functions to explain their purpose and parameters.


+bool
+_mesa_set_debug_state_int(struct gl_context *ctx, GLenum pname, GLint val)
+{
+   struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+
+   if (!debug)
+      return false;
+
+   switch (pname) {
+   case GL_DEBUG_OUTPUT:
+      debug->DebugOutput = (val != 0);
+      break;
+   case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
+      debug->SyncOutput = (val != 0);
+      break;
+   default:
+      assert(!"unknown debug output param");
+      break;
+   }
+
+   return true;
+}
+
+GLint
+_mesa_get_debug_state_int(struct gl_context *ctx, GLenum pname)
+{
+   struct gl_debug_state *debug;
+   GLint val;
+
+   debug = ctx->Debug;
+   if (!debug)
+      return 0;
+
+   switch (pname) {
+   case GL_DEBUG_OUTPUT:
+      val = debug->DebugOutput;
+      break;
+   case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
+      val = debug->SyncOutput;
+      break;
+   case GL_DEBUG_LOGGED_MESSAGES:
+      val = debug->NumMessages;
+      break;
+   case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+      val = debug->NextMsgLength;
+      break;
+   case GL_DEBUG_GROUP_STACK_DEPTH:
+      val = debug->GroupStackDepth;
+      break;
+   default:
+      assert(!"unknown debug output param");
+      val = 0;
+      break;
+   }
+
+   return val;
+}
+
+void *
+_mesa_get_debug_state_ptr(struct gl_context *ctx, GLenum pname)
+{
+   struct gl_debug_state *debug;
+   void *val;
+
+   debug = ctx->Debug;
+   if (!debug)
+      return NULL;
+
+   switch (pname) {
+   case GL_DEBUG_CALLBACK_FUNCTION_ARB:
+      val = (void *) debug->Callback;
+      break;
+   case GL_DEBUG_CALLBACK_USER_PARAM_ARB:
+      val = (void *) debug->CallbackData;
+      break;
+   default:
+      assert(!"unknown debug output param");
+      val = NULL;
+      break;
+   }
+
+   return val;
+}
+

  /**
   * Log a client or driver debug message.


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to