Browse Source

Greatly simplified Query implementations.

All work is now done in AbstractQuery, subclasses define only
strongly-typed interface around it. No heap allocations, no virtual
destructors needed. Added also asserts into result(), begin() and end()
to harden the implementation.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
f85f067192
  1. 72
      src/Query.cpp
  2. 72
      src/Query.h

72
src/Query.cpp

@ -24,9 +24,11 @@
#include "Query.h" #include "Query.h"
#include <Utility/Assert.h>
namespace Magnum { namespace Magnum {
AbstractQuery::AbstractQuery() { AbstractQuery::AbstractQuery(): target() {
/** @todo Get some extension wrangler instead to avoid undeclared glGenQueries() on ES2 */ /** @todo Get some extension wrangler instead to avoid undeclared glGenQueries() on ES2 */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
glGenQueries(1, &_id); glGenQueries(1, &_id);
@ -41,6 +43,8 @@ AbstractQuery::~AbstractQuery() {
} }
bool AbstractQuery::resultAvailable() { bool AbstractQuery::resultAvailable() {
CORRADE_ASSERT(!target, "AbstractQuery::resultAvailable(): the query is currently running", false);
/** @todo Re-enable when extension wrangler is available for ES */ /** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
GLuint result; GLuint result;
@ -53,6 +57,8 @@ bool AbstractQuery::resultAvailable() {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template<> bool AbstractQuery::result<bool>() { template<> bool AbstractQuery::result<bool>() {
CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
/** @todo Re-enable when extension wrangler is available for ES */ /** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
GLuint result; GLuint result;
@ -64,6 +70,8 @@ template<> bool AbstractQuery::result<bool>() {
} }
template<> UnsignedInt AbstractQuery::result<UnsignedInt>() { template<> UnsignedInt AbstractQuery::result<UnsignedInt>() {
CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
/** @todo Re-enable when extension wrangler is available for ES */ /** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
UnsignedInt result; UnsignedInt result;
@ -76,18 +84,24 @@ template<> UnsignedInt AbstractQuery::result<UnsignedInt>() {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
template<> Int AbstractQuery::result<Int>() { template<> Int AbstractQuery::result<Int>() {
CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
Int result; Int result;
glGetQueryObjectiv(_id, GL_QUERY_RESULT, &result); glGetQueryObjectiv(_id, GL_QUERY_RESULT, &result);
return result; return result;
} }
template<> UnsignedLong AbstractQuery::result<UnsignedLong>() { template<> UnsignedLong AbstractQuery::result<UnsignedLong>() {
CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
UnsignedLong result; UnsignedLong result;
glGetQueryObjectui64v(_id, GL_QUERY_RESULT, &result); glGetQueryObjectui64v(_id, GL_QUERY_RESULT, &result);
return result; return result;
} }
template<> Long AbstractQuery::result<Long>() { template<> Long AbstractQuery::result<Long>() {
CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
Long result; Long result;
glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &result); glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &result);
return result; return result;
@ -95,65 +109,23 @@ template<> Long AbstractQuery::result<Long>() {
#endif #endif
#endif #endif
#ifndef MAGNUM_TARGET_GLES2 void AbstractQuery::begin(GLenum target) {
PrimitiveQuery::PrimitiveQuery(): target(nullptr) {} CORRADE_ASSERT(!this->target, "AbstractQuery::begin(): the query is already running", );
PrimitiveQuery::~PrimitiveQuery() { delete target; }
void PrimitiveQuery::begin(Target target) {
glBeginQuery(static_cast<GLenum>(target), id());
this->target = new Target(target);
}
void PrimitiveQuery::end() {
if(!target) return;
glEndQuery(static_cast<GLenum>(*target));
delete target;
target = nullptr;
}
#endif
SampleQuery::SampleQuery(): target(nullptr) {}
SampleQuery::~SampleQuery() { delete target; }
void SampleQuery::begin(Target target) {
/** @todo Re-enable when extension wrangler is available for ES */ /** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
glBeginQuery(static_cast<GLenum>(target), id()); glBeginQuery(this->target = target, id());
#endif #endif
this->target = new Target(target);
} }
void SampleQuery::end() { void AbstractQuery::end() {
if(!target) return; CORRADE_ASSERT(target, "AbstractQuery::end(): the query is not running", );
/** @todo Re-enable when extension wrangler is available for ES */ /** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
glEndQuery(static_cast<GLenum>(*target)); glEndQuery(target);
#endif #endif
delete target; target = {};
target = nullptr;
}
#ifndef MAGNUM_TARGET_GLES
TimeQuery::TimeQuery(): target(nullptr) {}
TimeQuery::~TimeQuery() { delete target; }
void TimeQuery::begin(Target target) {
glBeginQuery(static_cast<GLenum>(target), id());
this->target = new Target(target);
}
void TimeQuery::end() {
if(!target) return;
glEndQuery(static_cast<GLenum>(*target));
delete target;
target = nullptr;
} }
#endif
} }

72
src/Query.h

@ -28,8 +28,9 @@
* @brief Class Magnum::AbstractQuery, Magnum::Query, Magnum::SampleQuery, Magnum::TimeQuery * @brief Class Magnum::AbstractQuery, Magnum::Query, Magnum::SampleQuery, Magnum::TimeQuery
*/ */
#include "Magnum.h"
#include "OpenGL.h" #include "OpenGL.h"
#include "Types.h"
#include "magnumConfigure.h"
#include "magnumVisibility.h" #include "magnumVisibility.h"
namespace Magnum { namespace Magnum {
@ -44,6 +45,7 @@ information.
*/ */
class MAGNUM_EXPORT AbstractQuery { class MAGNUM_EXPORT AbstractQuery {
public: public:
#ifdef DOXYGEN_GENERATING_OUTPUT
/** /**
* @brief Constructor * @brief Constructor
* *
@ -51,6 +53,7 @@ class MAGNUM_EXPORT AbstractQuery {
* @see @fn_gl{GenQueries} * @see @fn_gl{GenQueries}
*/ */
explicit AbstractQuery(); explicit AbstractQuery();
#endif
/** /**
* @brief Destructor * @brief Destructor
@ -58,7 +61,7 @@ class MAGNUM_EXPORT AbstractQuery {
* Deletes assigned OpenGL query. * Deletes assigned OpenGL query.
* @see @fn_gl{DeleteQueries} * @see @fn_gl{DeleteQueries}
*/ */
virtual ~AbstractQuery() = 0; ~AbstractQuery();
/** @brief OpenGL query ID */ /** @brief OpenGL query ID */
inline GLuint id() const { return _id; } inline GLuint id() const { return _id; }
@ -86,8 +89,22 @@ class MAGNUM_EXPORT AbstractQuery {
*/ */
template<class T> T result(); template<class T> T result();
/**
* @brief End query
*
* The result can be then retrieved by calling result().
* @see @fn_gl{EndQuery}
*/
void end();
protected:
explicit AbstractQuery();
void begin(GLenum target);
private: private:
GLuint _id; GLuint _id;
GLenum target;
}; };
@ -124,7 +141,7 @@ UnsignedInt primitiveCount = q.result<UnsignedInt>();
@requires_gl30 %Extension @extension{EXT,transform_feedback} @requires_gl30 %Extension @extension{EXT,transform_feedback}
@requires_gles30 Only sample queries are available on OpenGL ES 2.0. @requires_gles30 Only sample queries are available on OpenGL ES 2.0.
*/ */
class MAGNUM_EXPORT PrimitiveQuery: public AbstractQuery { class PrimitiveQuery: public AbstractQuery {
public: public:
/** @brief Query target */ /** @brief Query target */
enum Target: GLenum { enum Target: GLenum {
@ -142,28 +159,15 @@ class MAGNUM_EXPORT PrimitiveQuery: public AbstractQuery {
TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
}; };
explicit PrimitiveQuery();
~PrimitiveQuery();
/** /**
* @brief Begin query * @brief Begin query
* *
* Begins counting of given @p target until end() is called. * Begins counting of given @p target until end() is called.
* @see @fn_gl{BeginQuery} * @see @fn_gl{BeginQuery}
*/ */
void begin(Target target); inline void begin(Target target) {
AbstractQuery::begin(GLenum(target));
/** }
* @brief End query
*
* The result can be then retrieved by calling result().
* @see @fn_gl{EndQuery}
*/
void end();
private:
Target* target;
}; };
#endif #endif
@ -203,7 +207,7 @@ q.endConditionalRender();
@endcode @endcode
@requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean} @requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean}
*/ */
class MAGNUM_EXPORT SampleQuery: public AbstractQuery { class SampleQuery: public AbstractQuery {
public: public:
/** @brief Query target */ /** @brief Query target */
enum Target: GLenum { enum Target: GLenum {
@ -273,15 +277,10 @@ class MAGNUM_EXPORT SampleQuery: public AbstractQuery {
}; };
#endif #endif
explicit SampleQuery();
~SampleQuery();
/** @copydoc PrimitiveQuery::begin() */ /** @copydoc PrimitiveQuery::begin() */
void begin(Target target); inline void begin(Target target) {
AbstractQuery::begin(GLenum(target));
/** @copydoc PrimitiveQuery::end() */ }
void end();
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
@ -306,9 +305,6 @@ class MAGNUM_EXPORT SampleQuery: public AbstractQuery {
glEndConditionalRender(); glEndConditionalRender();
} }
#endif #endif
private:
Target* target;
}; };
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -353,10 +349,6 @@ class TimeQuery: public AbstractQuery {
TimeElapsed = GL_TIME_ELAPSED TimeElapsed = GL_TIME_ELAPSED
}; };
explicit TimeQuery();
~TimeQuery();
/** /**
* @brief Query timestamp * @brief Query timestamp
* *
@ -367,13 +359,9 @@ class TimeQuery: public AbstractQuery {
} }
/** @copydoc PrimitiveQuery::begin() */ /** @copydoc PrimitiveQuery::begin() */
void begin(Target target); inline void begin(Target target) {
AbstractQuery::begin(GLenum(target));
/** @copydoc PrimitiveQuery::end() */ }
void end();
private:
Target* target;
}; };
#endif #endif

Loading…
Cancel
Save