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

72
src/Query.h

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

Loading…
Cancel
Save