ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

queryobj.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.1
00004  *
00005  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included
00015  * in all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 
00026 #include "glheader.h"
00027 #include "context.h"
00028 #include "hash.h"
00029 #include "imports.h"
00030 #include "queryobj.h"
00031 #include "mtypes.h"
00032 
00033 
00041 struct gl_query_object *
00042 _mesa_new_query_object(GLcontext *ctx, GLuint id)
00043 {
00044    struct gl_query_object *q = MALLOC_STRUCT(gl_query_object);
00045    (void) ctx;
00046    if (q) {
00047       q->Id = id;
00048       q->Result = 0;
00049       q->Active = GL_FALSE;
00050       q->Ready = GL_TRUE;   /* correct, see spec */
00051    }
00052    return q;
00053 }
00054 
00055 
00060 void
00061 _mesa_begin_query(GLcontext *ctx, struct gl_query_object *q)
00062 {
00063    /* no-op */
00064 }
00065 
00066 
00071 void
00072 _mesa_end_query(GLcontext *ctx, struct gl_query_object *q)
00073 {
00074    q->Ready = GL_TRUE;
00075 }
00076 
00077 
00082 void
00083 _mesa_wait_query(GLcontext *ctx, struct gl_query_object *q)
00084 {
00085    /* For software drivers, _mesa_end_query() should have completed the query.
00086     * For real hardware, implement a proper WaitQuery() driver function.
00087     */
00088    assert(q->Ready);
00089 }
00090 
00091 
00096 void
00097 _mesa_delete_query(GLcontext *ctx, struct gl_query_object *q)
00098 {
00099    _mesa_free(q);
00100 }
00101 
00102 
00103 static struct gl_query_object *
00104 lookup_query_object(GLcontext *ctx, GLuint id)
00105 {
00106    return (struct gl_query_object *)
00107       _mesa_HashLookup(ctx->Query.QueryObjects, id);
00108 }
00109 
00110 
00111 
00112 void GLAPIENTRY
00113 _mesa_GenQueriesARB(GLsizei n, GLuint *ids)
00114 {
00115    GLuint first;
00116    GET_CURRENT_CONTEXT(ctx);
00117    ASSERT_OUTSIDE_BEGIN_END(ctx);
00118 
00119    if (n < 0) {
00120       _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
00121       return;
00122    }
00123 
00124    /* No query objects can be active at this time! */
00125    if (ctx->Query.CurrentOcclusionObject ||
00126        ctx->Query.CurrentTimerObject) {
00127       _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB");
00128       return;
00129    }
00130 
00131    first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n);
00132    if (first) {
00133       GLsizei i;
00134       for (i = 0; i < n; i++) {
00135          struct gl_query_object *q
00136             = ctx->Driver.NewQueryObject(ctx, first + i);
00137          if (!q) {
00138             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
00139             return;
00140          }
00141          ids[i] = first + i;
00142          _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
00143       }
00144    }
00145 }
00146 
00147 
00148 void GLAPIENTRY
00149 _mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids)
00150 {
00151    GLint i;
00152    GET_CURRENT_CONTEXT(ctx);
00153    ASSERT_OUTSIDE_BEGIN_END(ctx);
00154 
00155    if (n < 0) {
00156       _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)");
00157       return;
00158    }
00159 
00160    /* No query objects can be active at this time! */
00161    if (ctx->Query.CurrentOcclusionObject ||
00162        ctx->Query.CurrentTimerObject) {
00163       _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB");
00164       return;
00165    }
00166 
00167    for (i = 0; i < n; i++) {
00168       if (ids[i] > 0) {
00169          struct gl_query_object *q = lookup_query_object(ctx, ids[i]);
00170          if (q) {
00171             ASSERT(!q->Active); /* should be caught earlier */
00172             _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]);
00173             ctx->Driver.DeleteQuery(ctx, q);
00174          }
00175       }
00176    }
00177 }
00178 
00179 
00180 GLboolean GLAPIENTRY
00181 _mesa_IsQueryARB(GLuint id)
00182 {
00183    GET_CURRENT_CONTEXT(ctx);
00184    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
00185 
00186    if (id && lookup_query_object(ctx, id))
00187       return GL_TRUE;
00188    else
00189       return GL_FALSE;
00190 }
00191 
00192 
00193 void GLAPIENTRY
00194 _mesa_BeginQueryARB(GLenum target, GLuint id)
00195 {
00196    struct gl_query_object *q;
00197    GET_CURRENT_CONTEXT(ctx);
00198    ASSERT_OUTSIDE_BEGIN_END(ctx);
00199 
00200    FLUSH_VERTICES(ctx, _NEW_DEPTH);
00201 
00202    switch (target) {
00203       case GL_SAMPLES_PASSED_ARB:
00204          if (!ctx->Extensions.ARB_occlusion_query) {
00205             _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
00206             return;
00207          }
00208          if (ctx->Query.CurrentOcclusionObject) {
00209             _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
00210             return;
00211          }
00212          break;
00213 #if FEATURE_EXT_timer_query
00214       case GL_TIME_ELAPSED_EXT:
00215          if (!ctx->Extensions.EXT_timer_query) {
00216             _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
00217             return;
00218          }
00219          if (ctx->Query.CurrentTimerObject) {
00220             _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
00221             return;
00222          }
00223          break;
00224 #endif
00225       default:
00226          _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
00227          return;
00228    }
00229 
00230    if (id == 0) {
00231       _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(id==0)");
00232       return;
00233    }
00234 
00235    q = lookup_query_object(ctx, id);
00236    if (!q) {
00237       /* create new object */
00238       q = ctx->Driver.NewQueryObject(ctx, id);
00239       if (!q) {
00240          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB");
00241          return;
00242       }
00243       _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
00244    }
00245    else {
00246       /* pre-existing object */
00247       if (q->Active) {
00248          _mesa_error(ctx, GL_INVALID_OPERATION,
00249                      "glBeginQueryARB(query already active)");
00250          return;
00251       }
00252    }
00253 
00254    q->Target = target;
00255    q->Active = GL_TRUE;
00256    q->Result = 0;
00257    q->Ready = GL_FALSE;
00258 
00259    if (target == GL_SAMPLES_PASSED_ARB) {
00260       ctx->Query.CurrentOcclusionObject = q;
00261    }
00262 #if FEATURE_EXT_timer_query
00263    else if (target == GL_TIME_ELAPSED_EXT) {
00264       ctx->Query.CurrentTimerObject = q;
00265    }
00266 #endif
00267 
00268    ctx->Driver.BeginQuery(ctx, q);
00269 }
00270 
00271 
00272 void GLAPIENTRY
00273 _mesa_EndQueryARB(GLenum target)
00274 {
00275    struct gl_query_object *q;
00276    GET_CURRENT_CONTEXT(ctx);
00277    ASSERT_OUTSIDE_BEGIN_END(ctx);
00278 
00279    FLUSH_VERTICES(ctx, _NEW_DEPTH);
00280 
00281    switch (target) {
00282       case GL_SAMPLES_PASSED_ARB:
00283          if (!ctx->Extensions.ARB_occlusion_query) {
00284             _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
00285             return;
00286          }
00287          q = ctx->Query.CurrentOcclusionObject;
00288          ctx->Query.CurrentOcclusionObject = NULL;
00289          break;
00290 #if FEATURE_EXT_timer_query
00291       case GL_TIME_ELAPSED_EXT:
00292          if (!ctx->Extensions.EXT_timer_query) {
00293             _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
00294             return;
00295          }
00296          q = ctx->Query.CurrentTimerObject;
00297          ctx->Query.CurrentTimerObject = NULL;
00298          break;
00299 #endif
00300       default:
00301          _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
00302          return;
00303    }
00304 
00305    if (!q || !q->Active) {
00306       _mesa_error(ctx, GL_INVALID_OPERATION,
00307                   "glEndQueryARB(no matching glBeginQueryARB)");
00308       return;
00309    }
00310 
00311    q->Active = GL_FALSE;
00312    ctx->Driver.EndQuery(ctx, q);
00313 }
00314 
00315 
00316 void GLAPIENTRY
00317 _mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params)
00318 {
00319    struct gl_query_object *q;
00320    GET_CURRENT_CONTEXT(ctx);
00321    ASSERT_OUTSIDE_BEGIN_END(ctx);
00322 
00323    switch (target) {
00324       case GL_SAMPLES_PASSED_ARB:
00325          if (!ctx->Extensions.ARB_occlusion_query) {
00326             _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
00327             return;
00328          }
00329          q = ctx->Query.CurrentOcclusionObject;
00330          break;
00331 #if FEATURE_EXT_timer_query
00332       case GL_TIME_ELAPSED_EXT:
00333          if (!ctx->Extensions.EXT_timer_query) {
00334             _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
00335             return;
00336          }
00337          q = ctx->Query.CurrentTimerObject;
00338          break;
00339 #endif
00340       default:
00341          _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)");
00342          return;
00343    }
00344 
00345    switch (pname) {
00346       case GL_QUERY_COUNTER_BITS_ARB:
00347          *params = 8 * sizeof(q->Result);
00348          break;
00349       case GL_CURRENT_QUERY_ARB:
00350          *params = q ? q->Id : 0;
00351          break;
00352       default:
00353          _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)");
00354          return;
00355    }
00356 }
00357 
00358 
00359 void GLAPIENTRY
00360 _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
00361 {
00362    struct gl_query_object *q = NULL;
00363    GET_CURRENT_CONTEXT(ctx);
00364    ASSERT_OUTSIDE_BEGIN_END(ctx);
00365 
00366    if (id)
00367       q = lookup_query_object(ctx, id);
00368 
00369    if (!q || q->Active) {
00370       _mesa_error(ctx, GL_INVALID_OPERATION,
00371                   "glGetQueryObjectivARB(id=%d is invalid or active)", id);
00372       return;
00373    }
00374 
00375    switch (pname) {
00376       case GL_QUERY_RESULT_ARB:
00377          if (!q->Ready)
00378             ctx->Driver.WaitQuery(ctx, q);
00379          /* if result is too large for returned type, clamp to max value */
00380          if (q->Result > 0x7fffffff) {
00381             *params = 0x7fffffff;
00382          }
00383          else {
00384             *params = (GLint)q->Result;
00385          }
00386          break;
00387       case GL_QUERY_RESULT_AVAILABLE_ARB:
00388      if (!q->Ready)
00389         ctx->Driver.CheckQuery( ctx, q );
00390          *params = q->Ready;
00391          break;
00392       default:
00393          _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)");
00394          return;
00395    }
00396 }
00397 
00398 
00399 void GLAPIENTRY
00400 _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
00401 {
00402    struct gl_query_object *q = NULL;
00403    GET_CURRENT_CONTEXT(ctx);
00404    ASSERT_OUTSIDE_BEGIN_END(ctx);
00405 
00406    if (id)
00407       q = lookup_query_object(ctx, id);
00408 
00409    if (!q || q->Active) {
00410       _mesa_error(ctx, GL_INVALID_OPERATION,
00411                   "glGetQueryObjectuivARB(id=%d is invalid or active)", id);
00412       return;
00413    }
00414 
00415    switch (pname) {
00416       case GL_QUERY_RESULT_ARB:
00417          if (!q->Ready)
00418             ctx->Driver.WaitQuery(ctx, q);
00419          /* if result is too large for returned type, clamp to max value */
00420          if (q->Result > 0xffffffff) {
00421             *params = 0xffffffff;
00422          }
00423          else {
00424             *params = (GLuint)q->Result;
00425          }
00426          break;
00427       case GL_QUERY_RESULT_AVAILABLE_ARB:
00428      if (!q->Ready)
00429         ctx->Driver.CheckQuery( ctx, q );
00430          *params = q->Ready;
00431          break;
00432       default:
00433          _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
00434          return;
00435    }
00436 }
00437 
00438 
00439 #if FEATURE_EXT_timer_query
00440 
00444 void GLAPIENTRY
00445 _mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params)
00446 {
00447    struct gl_query_object *q = NULL;
00448    GET_CURRENT_CONTEXT(ctx);
00449    ASSERT_OUTSIDE_BEGIN_END(ctx);
00450 
00451    if (id)
00452       q = lookup_query_object(ctx, id);
00453 
00454    if (!q || q->Active) {
00455       _mesa_error(ctx, GL_INVALID_OPERATION,
00456                   "glGetQueryObjectui64vARB(id=%d is invalid or active)", id);
00457       return;
00458    }
00459 
00460    switch (pname) {
00461       case GL_QUERY_RESULT_ARB:
00462          if (!q->Ready)
00463             ctx->Driver.WaitQuery(ctx, q);
00464          *params = q->Result;
00465          break;
00466       case GL_QUERY_RESULT_AVAILABLE_ARB:
00467      if (!q->Ready)
00468         ctx->Driver.CheckQuery( ctx, q );
00469          *params = q->Ready;
00470          break;
00471       default:
00472          _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)");
00473          return;
00474    }
00475 }
00476 
00477 
00481 void GLAPIENTRY
00482 _mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params)
00483 {
00484    struct gl_query_object *q = NULL;
00485    GET_CURRENT_CONTEXT(ctx);
00486    ASSERT_OUTSIDE_BEGIN_END(ctx);
00487 
00488    if (id)
00489       q = lookup_query_object(ctx, id);
00490 
00491    if (!q || q->Active) {
00492       _mesa_error(ctx, GL_INVALID_OPERATION,
00493                   "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id);
00494       return;
00495    }
00496 
00497    switch (pname) {
00498       case GL_QUERY_RESULT_ARB:
00499          if (!q->Ready)
00500             ctx->Driver.WaitQuery(ctx, q);
00501          *params = q->Result;
00502          break;
00503       case GL_QUERY_RESULT_AVAILABLE_ARB:
00504      if (!q->Ready)
00505         ctx->Driver.CheckQuery( ctx, q );
00506          *params = q->Ready;
00507          break;
00508       default:
00509          _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)");
00510          return;
00511    }
00512 }
00513 
00514 #endif /* FEATURE_EXT_timer_query */
00515 
00516 
00520 void
00521 _mesa_init_query(GLcontext *ctx)
00522 {
00523 #if FEATURE_ARB_occlusion_query
00524    ctx->Query.QueryObjects = _mesa_NewHashTable();
00525    ctx->Query.CurrentOcclusionObject = NULL;
00526 #endif
00527 }
00528 
00529 
00533 static void
00534 delete_queryobj_cb(GLuint id, void *data, void *userData)
00535 {
00536    struct gl_query_object *q= (struct gl_query_object *) data;
00537    GLcontext *ctx = (GLcontext *)userData;
00538    ctx->Driver.DeleteQuery(ctx, q);
00539 }
00540 
00541 
00545 void
00546 _mesa_free_query_data(GLcontext *ctx)
00547 {
00548    _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, ctx);
00549    _mesa_DeleteHashTable(ctx->Query.QueryObjects);
00550 }

Generated on Sun May 27 2012 04:20:25 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.