From f85f06719267487c953537c77f5957e4b65b314b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 30 Apr 2013 00:59:55 +0200 Subject: [PATCH] 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. --- src/Query.cpp | 72 ++++++++++++++++----------------------------------- src/Query.h | 72 +++++++++++++++++++++------------------------------ 2 files changed, 52 insertions(+), 92 deletions(-) diff --git a/src/Query.cpp b/src/Query.cpp index a0697fd40..dec28ca04 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -24,9 +24,11 @@ #include "Query.h" +#include + 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() { + 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() { } template<> UnsignedInt AbstractQuery::result() { + 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() { #ifndef MAGNUM_TARGET_GLES template<> Int AbstractQuery::result() { + CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {}); + Int result; glGetQueryObjectiv(_id, GL_QUERY_RESULT, &result); return result; } template<> UnsignedLong AbstractQuery::result() { + CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {}); + UnsignedLong result; glGetQueryObjectui64v(_id, GL_QUERY_RESULT, &result); return result; } template<> Long AbstractQuery::result() { + 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() { #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(target), id()); - this->target = new Target(target); -} - -void PrimitiveQuery::end() { - if(!target) return; - - glEndQuery(static_cast(*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(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(*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(target), id()); - this->target = new Target(target); -} - -void TimeQuery::end() { - if(!target) return; - - glEndQuery(static_cast(*target)); - delete target; - target = nullptr; + target = {}; } -#endif } diff --git a/src/Query.h b/src/Query.h index 3f5401014..205ed1621 100644 --- a/src/Query.h +++ b/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 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(); @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