Rename occlude.[ch] to queryobj.[ch] to better reflect contents.
authorBrian <brian@yutani.localnet.net>
Sat, 21 Apr 2007 18:36:39 +0000 (12:36 -0600)
committerBrian <brian@yutani.localnet.net>
Sat, 21 Apr 2007 18:36:39 +0000 (12:36 -0600)
src/mesa/main/occlude.c [deleted file]
src/mesa/main/occlude.h [deleted file]
src/mesa/main/queryobj.c [new file with mode: 0644]
src/mesa/main/queryobj.h [new file with mode: 0644]

diff --git a/src/mesa/main/occlude.c b/src/mesa/main/occlude.c
deleted file mode 100644 (file)
index 5fef4a8..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.1
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "glheader.h"
-#include "context.h"
-#include "hash.h"
-#include "imports.h"
-#include "occlude.h"
-#include "mtypes.h"
-
-
-/**
- * Allocate a new query object.  This is a fallback routine called via
- * ctx->Driver.NewQueryObject().
- * \param ctx - rendering context
- * \param id - the new object's ID
- * \return pointer to new query_object object or NULL if out of memory.
- */
-struct gl_query_object *
-_mesa_new_query_object(GLcontext *ctx, GLuint id)
-{
-   struct gl_query_object *q = MALLOC_STRUCT(gl_query_object);
-   (void) ctx;
-   if (q) {
-      q->Id = id;
-      q->Result = 0;
-      q->Active = GL_FALSE;
-      q->Ready = GL_TRUE;   /* correct, see spec */
-   }
-   return q;
-}
-
-
-/**
- * Delete an occlusion query object.
- * Not removed from hash table here.
- * XXX maybe add Delete() method to gl_query_object class and call that instead
- */
-static void
-delete_query_object(struct gl_query_object *q)
-{
-   FREE(q);
-}
-
-
-static struct gl_query_object *
-lookup_query_object(GLcontext *ctx, GLuint id)
-{
-   return (struct gl_query_object *)
-      _mesa_HashLookup(ctx->Query.QueryObjects, id);
-}
-
-
-
-void GLAPIENTRY
-_mesa_GenQueriesARB(GLsizei n, GLuint *ids)
-{
-   GLuint first;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (n < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
-      return;
-   }
-
-   /* No query objects can be active at this time! */
-   if (ctx->Query.CurrentOcclusionObject ||
-       ctx->Query.CurrentTimerObject) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB");
-      return;
-   }
-
-   first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n);
-   if (first) {
-      GLsizei i;
-      for (i = 0; i < n; i++) {
-         struct gl_query_object *q
-            = ctx->Driver.NewQueryObject(ctx, first + i);
-         if (!q) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
-            return;
-         }
-         ids[i] = first + i;
-         _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
-      }
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids)
-{
-   GLint i;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (n < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)");
-      return;
-   }
-
-   /* No query objects can be active at this time! */
-   if (ctx->Query.CurrentOcclusionObject ||
-       ctx->Query.CurrentTimerObject) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB");
-      return;
-   }
-
-   for (i = 0; i < n; i++) {
-      if (ids[i] > 0) {
-         struct gl_query_object *q = lookup_query_object(ctx, ids[i]);
-         if (q) {
-            ASSERT(!q->Active); /* should be caught earlier */
-            _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]);
-            delete_query_object(q);
-         }
-      }
-   }
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsQueryARB(GLuint id)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
-
-   if (id && lookup_query_object(ctx, id))
-      return GL_TRUE;
-   else
-      return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_BeginQueryARB(GLenum target, GLuint id)
-{
-   struct gl_query_object *q;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_DEPTH);
-
-   switch (target) {
-      case GL_SAMPLES_PASSED_ARB:
-         if (!ctx->Extensions.ARB_occlusion_query) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
-            return;
-         }
-         if (ctx->Query.CurrentOcclusionObject) {
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
-            return;
-         }
-         break;
-#if FEATURE_EXT_timer_query
-      case GL_TIME_ELAPSED_EXT:
-         if (!ctx->Extensions.EXT_timer_query) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
-            return;
-         }
-         if (ctx->Query.CurrentTimerObject) {
-            _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
-            return;
-         }
-         break;
-#endif
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
-         return;
-   }
-
-   if (id == 0) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(id==0)");
-      return;
-   }
-
-   q = lookup_query_object(ctx, id);
-   if (!q) {
-      /* create new object */
-      q = ctx->Driver.NewQueryObject(ctx, id);
-      if (!q) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB");
-         return;
-      }
-      _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
-   }
-   else {
-      /* pre-existing object */
-      if (q->Active) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glBeginQueryARB(query already active)");
-         return;
-      }
-   }
-
-   q->Active = GL_TRUE;
-   q->Result = 0;
-   q->Ready = GL_FALSE;
-
-   if (target == GL_SAMPLES_PASSED_ARB) {
-      ctx->Query.CurrentOcclusionObject = q;
-   }
-#if FEATURE_EXT_timer_query
-   else if (target == GL_TIME_ELAPSED_EXT) {
-      ctx->Query.CurrentTimerObject = q;
-   }
-#endif
-
-   if (ctx->Driver.BeginQuery) {
-      ctx->Driver.BeginQuery(ctx, target, q);
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_EndQueryARB(GLenum target)
-{
-   struct gl_query_object *q;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_DEPTH);
-
-   switch (target) {
-      case GL_SAMPLES_PASSED_ARB:
-         if (!ctx->Extensions.ARB_occlusion_query) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
-            return;
-         }
-         q = ctx->Query.CurrentOcclusionObject;
-         ctx->Query.CurrentOcclusionObject = NULL;
-         break;
-#if FEATURE_EXT_timer_query
-      case GL_TIME_ELAPSED_EXT:
-         if (!ctx->Extensions.EXT_timer_query) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
-            return;
-         }
-         q = ctx->Query.CurrentTimerObject;
-         ctx->Query.CurrentTimerObject = NULL;
-         break;
-#endif
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
-         return;
-   }
-
-   if (!q || !q->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glEndQueryARB(no matching glBeginQueryARB)");
-      return;
-   }
-
-   q->Active = GL_FALSE;
-   if (ctx->Driver.EndQuery) {
-      ctx->Driver.EndQuery(ctx, target, q);
-   }
-   else {
-      /* if we're using software rendering/querying */
-      q->Ready = GL_TRUE;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params)
-{
-   struct gl_query_object *q;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   switch (target) {
-      case GL_SAMPLES_PASSED_ARB:
-         if (!ctx->Extensions.ARB_occlusion_query) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
-            return;
-         }
-         q = ctx->Query.CurrentOcclusionObject;
-         break;
-#if FEATURE_EXT_timer_query
-      case GL_TIME_ELAPSED_EXT:
-         if (!ctx->Extensions.EXT_timer_query) {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
-            return;
-         }
-         q = ctx->Query.CurrentTimerObject;
-         break;
-#endif
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)");
-         return;
-   }
-
-   switch (pname) {
-      case GL_QUERY_COUNTER_BITS_ARB:
-         *params = 8 * sizeof(q->Result);
-         break;
-      case GL_CURRENT_QUERY_ARB:
-         *params = q ? q->Id : 0;
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)");
-         return;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
-{
-   struct gl_query_object *q = NULL;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (id)
-      q = lookup_query_object(ctx, id);
-
-   if (!q || q->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetQueryObjectivARB(id=%d is invalid or active)", id);
-      return;
-   }
-
-   switch (pname) {
-      case GL_QUERY_RESULT_ARB:
-         while (!q->Ready) {
-            /* Wait for the query to finish! */
-            /* If using software rendering, the result will always be ready
-             * by time we get here.  Otherwise, we must be using hardware!
-             */
-            ASSERT(ctx->Driver.EndQuery);
-         }
-         /* if result is too large for returned type, clamp to max value */
-         if (q->Result > 0x7fffffff) {
-            *params = 0x7fffffff;
-         }
-         else {
-            *params = q->Result;
-         }
-         break;
-      case GL_QUERY_RESULT_AVAILABLE_ARB:
-         /* XXX revisit when we have a hardware implementation! */
-         *params = q->Ready;
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)");
-         return;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
-{
-   struct gl_query_object *q = NULL;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (id)
-      q = lookup_query_object(ctx, id);
-
-   if (!q || q->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetQueryObjectuivARB(id=%d is invalid or active)", id);
-      return;
-   }
-
-   switch (pname) {
-      case GL_QUERY_RESULT_ARB:
-         while (!q->Ready) {
-            /* Wait for the query to finish! */
-            /* If using software rendering, the result will always be ready
-             * by time we get here.  Otherwise, we must be using hardware!
-             */
-            ASSERT(ctx->Driver.EndQuery);
-         }
-         /* if result is too large for returned type, clamp to max value */
-         if (q->Result > 0xffffffff) {
-            *params = 0xffffffff;
-         }
-         else {
-            *params = q->Result;
-         }
-         break;
-      case GL_QUERY_RESULT_AVAILABLE_ARB:
-         /* XXX revisit when we have a hardware implementation! */
-         *params = q->Ready;
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
-         return;
-   }
-}
-
-
-#if FEATURE_EXT_timer_query
-
-/**
- * New with GL_EXT_timer_query
- */
-void GLAPIENTRY
-_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params)
-{
-   struct gl_query_object *q = NULL;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (id)
-      q = lookup_query_object(ctx, id);
-
-   if (!q || q->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetQueryObjectui64vARB(id=%d is invalid or active)", id);
-      return;
-   }
-
-   switch (pname) {
-      case GL_QUERY_RESULT_ARB:
-         while (!q->Ready) {
-            /* Wait for the query to finish! */
-            /* If using software rendering, the result will always be ready
-             * by time we get here.  Otherwise, we must be using hardware!
-             */
-            ASSERT(ctx->Driver.EndQuery);
-         }
-         *params = q->Result;
-         break;
-      case GL_QUERY_RESULT_AVAILABLE_ARB:
-         /* XXX revisit when we have a hardware implementation! */
-         *params = q->Ready;
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)");
-         return;
-   }
-}
-
-
-/**
- * New with GL_EXT_timer_query
- */
-void GLAPIENTRY
-_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params)
-{
-   struct gl_query_object *q = NULL;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (id)
-      q = lookup_query_object(ctx, id);
-
-   if (!q || q->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id);
-      return;
-   }
-
-   switch (pname) {
-      case GL_QUERY_RESULT_ARB:
-         while (!q->Ready) {
-            /* Wait for the query to finish! */
-            /* If using software rendering, the result will always be ready
-             * by time we get here.  Otherwise, we must be using hardware!
-             */
-            ASSERT(ctx->Driver.EndQuery);
-         }
-         *params = q->Result;
-         break;
-      case GL_QUERY_RESULT_AVAILABLE_ARB:
-         /* XXX revisit when we have a hardware implementation! */
-         *params = q->Ready;
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)");
-         return;
-   }
-}
-
-#endif /* FEATURE_EXT_timer_query */
-
-
-/**
- * Allocate/init the context state related to query objects.
- */
-void
-_mesa_init_query(GLcontext *ctx)
-{
-#if FEATURE_ARB_occlusion_query
-   ctx->Query.QueryObjects = _mesa_NewHashTable();
-   ctx->Query.CurrentOcclusionObject = NULL;
-#endif
-}
-
-
-/**
- * Callback for deleting a query object.  Called by _mesa_HashDeleteAll().
- */
-static void
-delete_queryobj_cb(GLuint id, void *data, void *userData)
-{
-   struct gl_query_object *q= (struct gl_query_object *) data;
-   (void) userData;
-   delete_query_object(q);
-}
-
-
-/**
- * Free the context state related to query objects.
- */
-void
-_mesa_free_query_data(GLcontext *ctx)
-{
-   _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, NULL);
-   _mesa_DeleteHashTable(ctx->Query.QueryObjects);
-}
diff --git a/src/mesa/main/occlude.h b/src/mesa/main/occlude.h
deleted file mode 100644 (file)
index ada8cf8..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef OCCLUDE_H
-#define OCCLUDE_H
-
-
-extern struct gl_query_object *
-_mesa_new_query_object(GLcontext *ctx, GLuint id);
-
-extern void
-_mesa_init_query(GLcontext *ctx);
-
-extern void
-_mesa_free_query_data(GLcontext *ctx);
-
-extern void GLAPIENTRY
-_mesa_GenQueriesARB(GLsizei n, GLuint *ids);
-
-extern void GLAPIENTRY
-_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids);
-
-extern GLboolean GLAPIENTRY
-_mesa_IsQueryARB(GLuint id);
-
-extern void GLAPIENTRY
-_mesa_BeginQueryARB(GLenum target, GLuint id);
-
-extern void GLAPIENTRY
-_mesa_EndQueryARB(GLenum target);
-
-extern void GLAPIENTRY
-_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params);
-
-extern void GLAPIENTRY
-_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params);
-
-extern void GLAPIENTRY
-_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params);
-
-
-#endif /* OCCLUDE_H */
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
new file mode 100644 (file)
index 0000000..5fef4a8
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.1
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "hash.h"
+#include "imports.h"
+#include "occlude.h"
+#include "mtypes.h"
+
+
+/**
+ * Allocate a new query object.  This is a fallback routine called via
+ * ctx->Driver.NewQueryObject().
+ * \param ctx - rendering context
+ * \param id - the new object's ID
+ * \return pointer to new query_object object or NULL if out of memory.
+ */
+struct gl_query_object *
+_mesa_new_query_object(GLcontext *ctx, GLuint id)
+{
+   struct gl_query_object *q = MALLOC_STRUCT(gl_query_object);
+   (void) ctx;
+   if (q) {
+      q->Id = id;
+      q->Result = 0;
+      q->Active = GL_FALSE;
+      q->Ready = GL_TRUE;   /* correct, see spec */
+   }
+   return q;
+}
+
+
+/**
+ * Delete an occlusion query object.
+ * Not removed from hash table here.
+ * XXX maybe add Delete() method to gl_query_object class and call that instead
+ */
+static void
+delete_query_object(struct gl_query_object *q)
+{
+   FREE(q);
+}
+
+
+static struct gl_query_object *
+lookup_query_object(GLcontext *ctx, GLuint id)
+{
+   return (struct gl_query_object *)
+      _mesa_HashLookup(ctx->Query.QueryObjects, id);
+}
+
+
+
+void GLAPIENTRY
+_mesa_GenQueriesARB(GLsizei n, GLuint *ids)
+{
+   GLuint first;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
+      return;
+   }
+
+   /* No query objects can be active at this time! */
+   if (ctx->Query.CurrentOcclusionObject ||
+       ctx->Query.CurrentTimerObject) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB");
+      return;
+   }
+
+   first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n);
+   if (first) {
+      GLsizei i;
+      for (i = 0; i < n; i++) {
+         struct gl_query_object *q
+            = ctx->Driver.NewQueryObject(ctx, first + i);
+         if (!q) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
+            return;
+         }
+         ids[i] = first + i;
+         _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
+      }
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids)
+{
+   GLint i;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)");
+      return;
+   }
+
+   /* No query objects can be active at this time! */
+   if (ctx->Query.CurrentOcclusionObject ||
+       ctx->Query.CurrentTimerObject) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB");
+      return;
+   }
+
+   for (i = 0; i < n; i++) {
+      if (ids[i] > 0) {
+         struct gl_query_object *q = lookup_query_object(ctx, ids[i]);
+         if (q) {
+            ASSERT(!q->Active); /* should be caught earlier */
+            _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]);
+            delete_query_object(q);
+         }
+      }
+   }
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsQueryARB(GLuint id)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+   if (id && lookup_query_object(ctx, id))
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_BeginQueryARB(GLenum target, GLuint id)
+{
+   struct gl_query_object *q;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_DEPTH);
+
+   switch (target) {
+      case GL_SAMPLES_PASSED_ARB:
+         if (!ctx->Extensions.ARB_occlusion_query) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
+            return;
+         }
+         if (ctx->Query.CurrentOcclusionObject) {
+            _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
+            return;
+         }
+         break;
+#if FEATURE_EXT_timer_query
+      case GL_TIME_ELAPSED_EXT:
+         if (!ctx->Extensions.EXT_timer_query) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
+            return;
+         }
+         if (ctx->Query.CurrentTimerObject) {
+            _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
+            return;
+         }
+         break;
+#endif
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
+         return;
+   }
+
+   if (id == 0) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(id==0)");
+      return;
+   }
+
+   q = lookup_query_object(ctx, id);
+   if (!q) {
+      /* create new object */
+      q = ctx->Driver.NewQueryObject(ctx, id);
+      if (!q) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB");
+         return;
+      }
+      _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
+   }
+   else {
+      /* pre-existing object */
+      if (q->Active) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glBeginQueryARB(query already active)");
+         return;
+      }
+   }
+
+   q->Active = GL_TRUE;
+   q->Result = 0;
+   q->Ready = GL_FALSE;
+
+   if (target == GL_SAMPLES_PASSED_ARB) {
+      ctx->Query.CurrentOcclusionObject = q;
+   }
+#if FEATURE_EXT_timer_query
+   else if (target == GL_TIME_ELAPSED_EXT) {
+      ctx->Query.CurrentTimerObject = q;
+   }
+#endif
+
+   if (ctx->Driver.BeginQuery) {
+      ctx->Driver.BeginQuery(ctx, target, q);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_EndQueryARB(GLenum target)
+{
+   struct gl_query_object *q;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_DEPTH);
+
+   switch (target) {
+      case GL_SAMPLES_PASSED_ARB:
+         if (!ctx->Extensions.ARB_occlusion_query) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+            return;
+         }
+         q = ctx->Query.CurrentOcclusionObject;
+         ctx->Query.CurrentOcclusionObject = NULL;
+         break;
+#if FEATURE_EXT_timer_query
+      case GL_TIME_ELAPSED_EXT:
+         if (!ctx->Extensions.EXT_timer_query) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+            return;
+         }
+         q = ctx->Query.CurrentTimerObject;
+         ctx->Query.CurrentTimerObject = NULL;
+         break;
+#endif
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+         return;
+   }
+
+   if (!q || !q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glEndQueryARB(no matching glBeginQueryARB)");
+      return;
+   }
+
+   q->Active = GL_FALSE;
+   if (ctx->Driver.EndQuery) {
+      ctx->Driver.EndQuery(ctx, target, q);
+   }
+   else {
+      /* if we're using software rendering/querying */
+      q->Ready = GL_TRUE;
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params)
+{
+   struct gl_query_object *q;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   switch (target) {
+      case GL_SAMPLES_PASSED_ARB:
+         if (!ctx->Extensions.ARB_occlusion_query) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+            return;
+         }
+         q = ctx->Query.CurrentOcclusionObject;
+         break;
+#if FEATURE_EXT_timer_query
+      case GL_TIME_ELAPSED_EXT:
+         if (!ctx->Extensions.EXT_timer_query) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+            return;
+         }
+         q = ctx->Query.CurrentTimerObject;
+         break;
+#endif
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)");
+         return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_COUNTER_BITS_ARB:
+         *params = 8 * sizeof(q->Result);
+         break;
+      case GL_CURRENT_QUERY_ARB:
+         *params = q ? q->Id : 0;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)");
+         return;
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
+{
+   struct gl_query_object *q = NULL;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (id)
+      q = lookup_query_object(ctx, id);
+
+   if (!q || q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetQueryObjectivARB(id=%d is invalid or active)", id);
+      return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_RESULT_ARB:
+         while (!q->Ready) {
+            /* Wait for the query to finish! */
+            /* If using software rendering, the result will always be ready
+             * by time we get here.  Otherwise, we must be using hardware!
+             */
+            ASSERT(ctx->Driver.EndQuery);
+         }
+         /* if result is too large for returned type, clamp to max value */
+         if (q->Result > 0x7fffffff) {
+            *params = 0x7fffffff;
+         }
+         else {
+            *params = q->Result;
+         }
+         break;
+      case GL_QUERY_RESULT_AVAILABLE_ARB:
+         /* XXX revisit when we have a hardware implementation! */
+         *params = q->Ready;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)");
+         return;
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
+{
+   struct gl_query_object *q = NULL;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (id)
+      q = lookup_query_object(ctx, id);
+
+   if (!q || q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetQueryObjectuivARB(id=%d is invalid or active)", id);
+      return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_RESULT_ARB:
+         while (!q->Ready) {
+            /* Wait for the query to finish! */
+            /* If using software rendering, the result will always be ready
+             * by time we get here.  Otherwise, we must be using hardware!
+             */
+            ASSERT(ctx->Driver.EndQuery);
+         }
+         /* if result is too large for returned type, clamp to max value */
+         if (q->Result > 0xffffffff) {
+            *params = 0xffffffff;
+         }
+         else {
+            *params = q->Result;
+         }
+         break;
+      case GL_QUERY_RESULT_AVAILABLE_ARB:
+         /* XXX revisit when we have a hardware implementation! */
+         *params = q->Ready;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
+         return;
+   }
+}
+
+
+#if FEATURE_EXT_timer_query
+
+/**
+ * New with GL_EXT_timer_query
+ */
+void GLAPIENTRY
+_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params)
+{
+   struct gl_query_object *q = NULL;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (id)
+      q = lookup_query_object(ctx, id);
+
+   if (!q || q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetQueryObjectui64vARB(id=%d is invalid or active)", id);
+      return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_RESULT_ARB:
+         while (!q->Ready) {
+            /* Wait for the query to finish! */
+            /* If using software rendering, the result will always be ready
+             * by time we get here.  Otherwise, we must be using hardware!
+             */
+            ASSERT(ctx->Driver.EndQuery);
+         }
+         *params = q->Result;
+         break;
+      case GL_QUERY_RESULT_AVAILABLE_ARB:
+         /* XXX revisit when we have a hardware implementation! */
+         *params = q->Ready;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)");
+         return;
+   }
+}
+
+
+/**
+ * New with GL_EXT_timer_query
+ */
+void GLAPIENTRY
+_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params)
+{
+   struct gl_query_object *q = NULL;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (id)
+      q = lookup_query_object(ctx, id);
+
+   if (!q || q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id);
+      return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_RESULT_ARB:
+         while (!q->Ready) {
+            /* Wait for the query to finish! */
+            /* If using software rendering, the result will always be ready
+             * by time we get here.  Otherwise, we must be using hardware!
+             */
+            ASSERT(ctx->Driver.EndQuery);
+         }
+         *params = q->Result;
+         break;
+      case GL_QUERY_RESULT_AVAILABLE_ARB:
+         /* XXX revisit when we have a hardware implementation! */
+         *params = q->Ready;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)");
+         return;
+   }
+}
+
+#endif /* FEATURE_EXT_timer_query */
+
+
+/**
+ * Allocate/init the context state related to query objects.
+ */
+void
+_mesa_init_query(GLcontext *ctx)
+{
+#if FEATURE_ARB_occlusion_query
+   ctx->Query.QueryObjects = _mesa_NewHashTable();
+   ctx->Query.CurrentOcclusionObject = NULL;
+#endif
+}
+
+
+/**
+ * Callback for deleting a query object.  Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_queryobj_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_query_object *q= (struct gl_query_object *) data;
+   (void) userData;
+   delete_query_object(q);
+}
+
+
+/**
+ * Free the context state related to query objects.
+ */
+void
+_mesa_free_query_data(GLcontext *ctx)
+{
+   _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, NULL);
+   _mesa_DeleteHashTable(ctx->Query.QueryObjects);
+}
diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h
new file mode 100644 (file)
index 0000000..ada8cf8
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef OCCLUDE_H
+#define OCCLUDE_H
+
+
+extern struct gl_query_object *
+_mesa_new_query_object(GLcontext *ctx, GLuint id);
+
+extern void
+_mesa_init_query(GLcontext *ctx);
+
+extern void
+_mesa_free_query_data(GLcontext *ctx);
+
+extern void GLAPIENTRY
+_mesa_GenQueriesARB(GLsizei n, GLuint *ids);
+
+extern void GLAPIENTRY
+_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsQueryARB(GLuint id);
+
+extern void GLAPIENTRY
+_mesa_BeginQueryARB(GLenum target, GLuint id);
+
+extern void GLAPIENTRY
+_mesa_EndQueryARB(GLenum target);
+
+extern void GLAPIENTRY
+_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params);
+
+extern void GLAPIENTRY
+_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params);
+
+
+#endif /* OCCLUDE_H */