/*
 * 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 "queryobj.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);
}
