From ea9828161251cde3cd49e0792cb8575a278a6707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 22 Dec 2013 19:51:54 +0100 Subject: [PATCH] New class DebugMessage for inserting debug messages via KHR_debug. Previously this was done in DebugMarker only via GREMEDY_string_marker on desktop and EXT_debug_marker on ES, now supporting both three on desktop and KHR/EXT version on ES. The old DebugMarker is now only a thin wrapper around DebugMessage, is marked as deprecated and will be removed in future release. --- src/CMakeLists.txt | 5 +- src/Context.cpp | 2 - src/DebugMarker.cpp | 64 ------- src/DebugMarker.h | 46 ++--- src/DebugMessage.cpp | 153 +++++++++++++++++ src/DebugMessage.h | 267 ++++++++++++++++++++++++++++++ src/Implementation/DebugState.cpp | 25 ++- src/Implementation/DebugState.h | 7 +- src/Implementation/State.cpp | 16 +- src/Magnum.h | 2 +- src/Test/CMakeLists.txt | 2 + src/Test/DebugGLTest.cpp | 103 ++++++++++++ 12 files changed, 581 insertions(+), 111 deletions(-) delete mode 100644 src/DebugMarker.cpp create mode 100644 src/DebugMessage.cpp create mode 100644 src/DebugMessage.h create mode 100644 src/Test/DebugGLTest.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa9bc7516..aaf06f779 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -54,7 +54,7 @@ set(Magnum_SRCS Buffer.cpp ColorFormat.cpp Context.cpp - DebugMarker.cpp + DebugMessage.cpp DefaultFramebuffer.cpp Framebuffer.cpp Image.cpp @@ -112,7 +112,7 @@ set(Magnum_HEADERS ColorFormat.h Context.h CubeMapTexture.h - DebugMarker.h + DebugMessage.h DefaultFramebuffer.h DimensionTraits.h Extensions.h @@ -141,6 +141,7 @@ set(Magnum_HEADERS # Deprecated headers if(BUILD_DEPRECATED) set(Magnum_HEADERS ${Magnum_HEADERS} + DebugMarker.h ImageFormat.h Swizzle.h) endif() diff --git a/src/Context.cpp b/src/Context.cpp index 51fe1582b..856175a24 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -34,7 +34,6 @@ #include "AbstractTexture.h" #include "Buffer.h" #include "BufferTexture.h" -#include "DebugMarker.h" #include "DefaultFramebuffer.h" #include "Extensions.h" #include "Framebuffer.h" @@ -431,7 +430,6 @@ Context::Context() { #ifndef MAGNUM_TARGET_GLES BufferTexture::initializeContextBasedFunctionality(*this); #endif - DebugMarker::initializeContextBasedFunctionality(*this); DefaultFramebuffer::initializeContextBasedFunctionality(*this); Framebuffer::initializeContextBasedFunctionality(*this); Mesh::initializeContextBasedFunctionality(*this); diff --git a/src/DebugMarker.cpp b/src/DebugMarker.cpp deleted file mode 100644 index bebac87ca..000000000 --- a/src/DebugMarker.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš - - 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 - THE AUTHORS OR COPYRIGHT HOLDERS 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 "DebugMarker.h" - -#include - -#include "Context.h" -#include "Extensions.h" - -namespace Magnum { - -DebugMarker::MarkImplementation DebugMarker::markImplementation = &DebugMarker::markImplementationDefault; - -void DebugMarker::initializeContextBasedFunctionality(Context& context) { - /** @todo Re-enable when extension wrangler is available for ES */ - #ifndef MAGNUM_TARGET_GLES - if(context.isExtensionSupported()) { - Debug() << "DebugMarker: using" << Extensions::GL::GREMEDY::string_marker::string() << "features"; - - markImplementation = &DebugMarker::markImplementationDebugger; - } - #else - static_cast(context); - #endif -} - -void DebugMarker::markImplementationDefault(const std::string&) {} - -void DebugMarker::markImplementationDebugger(const std::string& string) { - /** @todo Re-enable when extension wrangler is available for ES */ - #ifndef MAGNUM_TARGET_GLES - glStringMarkerGREMEDY(string.length(), string.data()); - #else - #if 0 - glInsertEventMarkerEXT(string.length(), string.data()); - #else - static_cast(string); - #endif - #endif -} - -} diff --git a/src/DebugMarker.h b/src/DebugMarker.h index 2c32e18a7..802ade424 100644 --- a/src/DebugMarker.h +++ b/src/DebugMarker.h @@ -25,47 +25,33 @@ */ /** @file - * @brief Class Magnum::DebugMarker + * @brief Typedef @ref Magnum::DebugMarker + * @deprecated Use @ref DebugMessage.h instead. */ -#include - -#include "Magnum.h" - -#include "magnumVisibility.h" +#include "DebugMessage.h" +#ifdef MAGNUM_BUILD_DEPRECATED namespace Magnum { /** -@brief Debug marker - -Allows putting debug marker into OpenGL command stream for use with various -debuggers, such as ApiTrace or gDEBugger. -@requires_extension %Extension @extension{GREMEDY,string_marker}. If not - available, this class does nothing. -@requires_es_extension %Extension @es_extension{EXT,debug_marker}. If not - available, this class does nothing. +@copybrief DebugMessage +@deprecated Use @ref Magnum::DebugMessage "DebugMessage" instead. */ -class MAGNUM_EXPORT DebugMarker { - friend class Context; - +class CORRADE_DEPRECATED("use DebugMessage instead") MAGNUM_EXPORT DebugMarker: public DebugMessage { public: - DebugMarker() = delete; - - /** @brief Put string mark into OpenGL command stream */ - static void mark(const std::string& string) { - markImplementation(string); + /** + * @copybrief DebugMessage::insert() + * @deprecated Use @ref Magnum::DebugMessage::insert() "insert()" instead. + */ + static CORRADE_DEPRECATED("use DebugMessage::insert() instead") void mark(const std::string& string) { + insert(Source::Application, Type::Marker, 0, Severity::Notification, string); } - - private: - static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context); - - typedef void(*MarkImplementation)(const std::string&); - static MAGNUM_LOCAL void markImplementationDefault(const std::string& string); - static MAGNUM_LOCAL void markImplementationDebugger(const std::string& string); - static MarkImplementation markImplementation; }; } +#else +#error use DebugMessage.h instead +#endif #endif diff --git a/src/DebugMessage.cpp b/src/DebugMessage.cpp new file mode 100644 index 000000000..b45314baf --- /dev/null +++ b/src/DebugMessage.cpp @@ -0,0 +1,153 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + 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 + THE AUTHORS OR COPYRIGHT HOLDERS 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 "DebugMessage.h" + +#include + +#include "Context.h" +#include "Extensions.h" +#include "Implementation/State.h" +#include "Implementation/DebugState.h" + +namespace Magnum { + +Int DebugMessage::maxLoggedMessages() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().debug->maxLoggedMessages; + + if(value == 0) { + #ifndef MAGNUM_TARGET_GLES + glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES, &value); + #else + glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES_KHR, &value); + #endif + } + + return value; +} + +Int DebugMessage::maxMessageLength() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().debug->maxMessageLength; + + if(value == 0) { + #ifndef MAGNUM_TARGET_GLES + glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &value); + #else + glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH_KHR, &value); + #endif + } + + return value; +} + +void DebugMessage::insert(const Source source, const Type type, const UnsignedInt id, const Severity severity, const std::string& string) { + Context::current()->state().debug->messageInsertImplementation(source, type, id, severity, string); +} + +void DebugMessage::insertImplementationNoOp(Source, Type, UnsignedInt, Severity, const std::string&) {} + +void DebugMessage::insertImplementationKhr(const Source source, const Type type, const UnsignedInt id, const Severity severity, const std::string& string) { + /** @todo Re-enable when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES + glDebugMessageInsert(GLenum(source), GLenum(type), id, GLenum(severity), string.size(), string.data()); + #else + static_cast(source); + static_cast(type); + static_cast(id); + static_cast(severity); + static_cast(string); + CORRADE_INTERNAL_ASSERT(false); + //glDebugMessageInsertEXT(GLenum(source), GLenum(type), id, GLenum(severity), string.size(), string.data()); + #endif +} + +void DebugMessage::insertImplementationExt(Source, Type, UnsignedInt, Severity, const std::string& string) { + /** @todo Re-enable when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES + glInsertEventMarkerEXT(string.size(), string.data()); + #else + static_cast(string); + CORRADE_INTERNAL_ASSERT(false); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void DebugMessage::insertImplementationGremedy(Source, Type, UnsignedInt, Severity, const std::string& string) { + glStringMarkerGREMEDY(string.length(), string.data()); +} +#endif + +#ifndef DOXYGEN_GENERATING_OUTPUT +Debug operator<<(Debug debug, const DebugMessage::Source value) { + switch(value) { + #define _c(value) case DebugMessage::Source::value: return debug << "DebugMessage::Source::" #value; + _c(Api) + _c(WindowSystem) + _c(ShaderCompiler) + _c(ThirdParty) + _c(Application) + _c(Other) + #undef _c + } + + return debug << "DebugMessage::Source::(invalid)"; +} + +Debug operator<<(Debug debug, const DebugMessage::Type value) { + switch(value) { + #define _c(value) case DebugMessage::Type::value: return debug << "DebugMessage::Type::" #value; + _c(Error) + _c(DeprecatedBehavior) + _c(UndefinedBehavior) + _c(Portability) + _c(Performance) + _c(Other) + _c(Marker) + #undef _c + } + + return debug << "DebugMessage::Type::(invalid)"; +} + +Debug operator<<(Debug debug, const DebugMessage::Severity value) { + switch(value) { + #define _c(value) case DebugMessage::Severity::value: return debug << "DebugMessage::Severity::" #value; + _c(High) + _c(Medium) + _c(Low) + _c(Notification) + #undef _c + } + + return debug << "DebugMessage::Severity::(invalid)"; +} +#endif + +} diff --git a/src/DebugMessage.h b/src/DebugMessage.h new file mode 100644 index 000000000..00726c28a --- /dev/null +++ b/src/DebugMessage.h @@ -0,0 +1,267 @@ +#ifndef Magnum_DebugMessage_h +#define Magnum_DebugMessage_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + 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 + THE AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +/** @file + * @brief Class @ref Magnum::DebugMessage + */ + +#include + +#include "Magnum.h" +#include "OpenGL.h" +#include "magnumVisibility.h" + +namespace Magnum { + +namespace Implementation { struct DebugState; } + +/** +@brief Debug message + +Allows inserting debug messages into OpenGL command stream, for example with +conjunction with various debuggers, such as Apitrace or gDEBugger. +*/ +class MAGNUM_EXPORT DebugMessage { + friend class Implementation::DebugState; + + public: + /** + * @brief Message source + * + * @see @ref insert() + */ + enum class Source: GLenum { + /** OpenGL */ + #ifndef MAGNUM_TARGET_GLES + Api = GL_DEBUG_SOURCE_API, + #else + Api = GL_DEBUG_SOURCE_API_KHR, + #endif + + /** Window system (GLX, WGL) */ + #ifndef MAGNUM_TARGET_GLES + WindowSystem = GL_DEBUG_SOURCE_WINDOW_SYSTEM, + #else + WindowSystem = GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR, + #endif + + /** %Shader compiler */ + #ifndef MAGNUM_TARGET_GLES + ShaderCompiler = GL_DEBUG_SOURCE_SHADER_COMPILER, + #else + ShaderCompiler = GL_DEBUG_SOURCE_SHADER_COMPILER_KHR, + #endif + + /** External debugger or third-party middleware */ + #ifndef MAGNUM_TARGET_GLES + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY, + #else + ThirdParty = GL_DEBUG_SOURCE_THIRD_PARTY_KHR, + #endif + + /** The application */ + #ifndef MAGNUM_TARGET_GLES + Application = GL_DEBUG_SOURCE_APPLICATION, + #else + Application = GL_DEBUG_SOURCE_APPLICATION_KHR, + #endif + + /** Any other source */ + #ifndef MAGNUM_TARGET_GLES + Other = GL_DEBUG_SOURCE_OTHER + #else + Other = GL_DEBUG_SOURCE_OTHER_KHR + #endif + }; + + /** + * @brief Message type + * + * @see @ref insert() + */ + enum class Type: GLenum { + /** OpenGL error */ + #ifndef MAGNUM_TARGET_GLES + Error = GL_DEBUG_TYPE_ERROR, + #else + Error = GL_DEBUG_TYPE_ERROR_KHR, + #endif + + /** Behavior that has been marked for deprecation */ + #ifndef MAGNUM_TARGET_GLES + DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, + #else + DeprecatedBehavior = GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR, + #endif + + /** Behavior that is undefined according to the specification */ + #ifndef MAGNUM_TARGET_GLES + UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, + #else + UndefinedBehavior = GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR, + #endif + + /** Non-portable usage of extensions or shaders */ + #ifndef MAGNUM_TARGET_GLES + Portability = GL_DEBUG_TYPE_PORTABILITY, + #else + Portability = GL_DEBUG_TYPE_PORTABILITY_KHR, + #endif + + /** Implementation-dependent performance warning */ + #ifndef MAGNUM_TARGET_GLES + Performance = GL_DEBUG_TYPE_PERFORMANCE, + #else + Performance = GL_DEBUG_TYPE_PERFORMANCE_KHR, + #endif + + /** Any other type */ + #ifndef MAGNUM_TARGET_GLES + Other = GL_DEBUG_TYPE_OTHER, + #else + Other = GL_DEBUG_TYPE_OTHER_KHR, + #endif + + /** Annotation of the command stream */ + #ifndef MAGNUM_TARGET_GLES + Marker = GL_DEBUG_TYPE_MARKER + #else + Marker = GL_DEBUG_TYPE_MARKER_KHR + #endif + }; + + /** + * @brief Message severity + * + * @see @ref insert() + */ + enum class Severity: GLenum { + /** + * Any OpenGL error, dangerous undefined behavior, shader + * compilation errors. + */ + #ifndef MAGNUM_TARGET_GLES + High = GL_DEBUG_SEVERITY_HIGH, + #else + High = GL_DEBUG_SEVERITY_HIGH_KHR, + #endif + + /** + * Severe performance warnings, shader compilation warnings, use of + * deprecated behavior. + */ + #ifndef MAGNUM_TARGET_GLES + Medium = GL_DEBUG_SEVERITY_MEDIUM, + #else + Medium = GL_DEBUG_SEVERITY_MEDIUM_KHR, + #endif + + /** Minor performance warnings, trivial undefined behavior. */ + #ifndef MAGNUM_TARGET_GLES + Low = GL_DEBUG_SEVERITY_LOW, + #else + Low = GL_DEBUG_SEVERITY_LOW_KHR, + #endif + + /** Any message other than error or performance warning. */ + #ifndef MAGNUM_TARGET_GLES + Notification = GL_DEBUG_SEVERITY_NOTIFICATION + #else + Notification = GL_DEBUG_SEVERITY_NOTIFICATION_KHR + #endif + }; + + /** + * @brief Max count of debug messages in log + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If OpenGL 4.3 is not supported and @extension{KHR,debug} + * desktop or ES extension is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_DEBUG_LOGGED_MESSAGES} + */ + static Int maxLoggedMessages(); + + /** + * @brief Max debug message length + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If OpenGL 4.3 is not supported and @extension{KHR,debug} + * desktop or ES extension is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_DEBUG_MESSAGE_LENGTH} + */ + static Int maxMessageLength(); + + /** + * @brief Insert message + * @param source Message source. Allowed values are + * @ref Source::ThirdParty or @ref Source::Application. + * @param type Message type + * @param id Message-specific ID + * @param severity Message severity + * @param string The actual message + * + * If OpenGL 4.3 is not supported and none of @extension{KHR,debug}, + * @extension2{EXT,debug_marker} or @extension{GREMEDY,string_marker} + * is available, this function does nothing. + * + * If @extension{KHR,debug} is not available and only @extension2{EXT,debug_marker} + * or @extension{GREMEDY,string_marker} are available, only @p string + * is used and all other parameters are ignored. The call is then + * equivalent to the following: + * @code + * DebugMessage::insert(DebugMessage::Source::Application, + * DebugMessage::Type::Marker, 0, DebugMessage::Severity::Notification, string); + * @endcode + * + * @see @ref maxMessageLength(), @fn_gl{DebugMessageInsert}, + * @fn_gl_extension2{InsertEventMarker,EXT,debug_marker} or + * @fn_gl_extension{StringMarker,GREMEDY,string_marker} + */ + static void insert(Source source, Type type, UnsignedInt id, Severity severity, const std::string& string); + + DebugMessage() = delete; + + private: + static MAGNUM_LOCAL void insertImplementationNoOp(Source, Type, UnsignedInt, Severity, const std::string&); + static MAGNUM_LOCAL void insertImplementationKhr(Source source, Type type, UnsignedInt id, Severity severity, const std::string& string); + static MAGNUM_LOCAL void insertImplementationExt(Source, Type, UnsignedInt, Severity, const std::string& string); + #ifndef MAGNUM_TARGET_GLES + static MAGNUM_LOCAL void insertImplementationGremedy(Source, Type, UnsignedInt, Severity, const std::string& string); + #endif +}; + +/** @debugoperator{Magnum::DebugMessage} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Source value); + +/** @debugoperator{Magnum::DebugMessage} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Type value); + +/** @debugoperator{Magnum::DebugMessage} */ +Debug MAGNUM_EXPORT operator<<(Debug debug, DebugMessage::Severity value); + +} + +#endif diff --git a/src/Implementation/DebugState.cpp b/src/Implementation/DebugState.cpp index f0c1c1e19..14ea03eea 100644 --- a/src/Implementation/DebugState.cpp +++ b/src/Implementation/DebugState.cpp @@ -30,16 +30,29 @@ namespace Magnum { namespace Implementation { -DebugState::DebugState(Context& context): maxLabelLength(0) { +DebugState::DebugState(Context& context): maxLabelLength(0), maxLoggedMessages(0), maxMessageLength(0) { if(context.isExtensionSupported()) { getLabelImplementation = &AbstractObject::getLabelImplementationKhr; labelImplementation = &AbstractObject::labelImplementationKhr; - } else if(context.isExtensionSupported()) { - getLabelImplementation = &AbstractObject::getLabelImplementationExt; - labelImplementation = &AbstractObject::labelImplementationExt; + messageInsertImplementation = &DebugMessage::insertImplementationKhr; + } else { - getLabelImplementation = &AbstractObject::getLabelImplementationNoOp; - labelImplementation = &AbstractObject::labelImplementationNoOp; + if(context.isExtensionSupported()) { + getLabelImplementation = &AbstractObject::getLabelImplementationExt; + labelImplementation = &AbstractObject::labelImplementationExt; + } else { + getLabelImplementation = &AbstractObject::getLabelImplementationNoOp; + labelImplementation = &AbstractObject::labelImplementationNoOp; + } + + if(context.isExtensionSupported()) + messageInsertImplementation = &DebugMessage::insertImplementationExt; + #ifndef MAGNUM_TARGET_GLES + else if(context.isExtensionSupported()) + messageInsertImplementation = &DebugMessage::insertImplementationGremedy; + #endif + else + messageInsertImplementation = &DebugMessage::insertImplementationNoOp; } } diff --git a/src/Implementation/DebugState.h b/src/Implementation/DebugState.h index 3397c2063..e9995d706 100644 --- a/src/Implementation/DebugState.h +++ b/src/Implementation/DebugState.h @@ -26,8 +26,7 @@ #include -#include "Magnum.h" -#include "OpenGL.h" +#include "DebugMessage.h" namespace Magnum { namespace Implementation { @@ -37,7 +36,9 @@ struct DebugState { std::string(*getLabelImplementation)(GLenum, GLuint); void(*labelImplementation)(GLenum, GLuint, const std::string&); - GLint maxLabelLength; + void(*messageInsertImplementation)(DebugMessage::Source, DebugMessage::Type, UnsignedInt, DebugMessage::Severity, const std::string&); + + GLint maxLabelLength, maxLoggedMessages, maxMessageLength; }; }} diff --git a/src/Implementation/State.cpp b/src/Implementation/State.cpp index 309aa9d6b..ff35e3c64 100644 --- a/src/Implementation/State.cpp +++ b/src/Implementation/State.cpp @@ -45,14 +45,24 @@ State::State(Context& context): renderer(new RendererState), shader(new ShaderState), shaderProgram(new ShaderProgramState), - texture(new TextureState) { + texture(new TextureState) +{ Debug() << "Using optional features:"; if(context.isExtensionSupported()) Debug() << " " << Extensions::GL::KHR::debug::string(); - else if(context.isExtensionSupported()) - Debug() << " " << Extensions::GL::EXT::debug_label::string(); + else { + if(context.isExtensionSupported()) + Debug() << " " << Extensions::GL::EXT::debug_label::string(); + + if(context.isExtensionSupported()) + Debug() << " " << Extensions::GL::EXT::debug_marker::string(); + #ifndef MAGNUM_TARGET_GLES + else if(context.isExtensionSupported()) + Debug() << " " << Extensions::GL::GREMEDY::string_marker::string(); + #endif + } } State::~State() { diff --git a/src/Magnum.h b/src/Magnum.h index 95494aeb9..b32c26603 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -565,7 +565,7 @@ class CubeMapTexture; class CubeMapTextureArray; #endif -/* DebugMarker forward declaration is not needed */ +/* DebugMessage used only statically */ /* DefaultFramebuffer is available only through global instance */ /* DimensionTraits forward declaration is not needed */ diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index 42496328b..6eaf09105 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -26,6 +26,7 @@ corrade_add_test(AbstractImageTest AbstractImageTest.cpp LIBRARIES Magnum) corrade_add_test(AbstractShaderProgramTest AbstractShaderProgramTest.cpp LIBRARIES Magnum) corrade_add_test(ArrayTest ArrayTest.cpp) corrade_add_test(ColorTest ColorTest.cpp LIBRARIES MagnumMathTestLib) +corrade_add_test(DebugMessageTest DebugMessageTest.cpp LIBRARIES Magnum) corrade_add_test(DefaultFramebufferTest DefaultFramebufferTest.cpp LIBRARIES Magnum) corrade_add_test(FramebufferTest FramebufferTest.cpp LIBRARIES Magnum) corrade_add_test(ImageTest ImageTest.cpp LIBRARIES Magnum) @@ -41,6 +42,7 @@ if(BUILD_GL_TESTS) corrade_add_test(AbstractTextureGLTest AbstractTextureGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(BufferGLTest BufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(ContextGLTest ContextGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) + corrade_add_test(DebugGLTest DebugGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(FramebufferGLTest FramebufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(MeshGLTest MeshGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) corrade_add_test(RenderbufferGLTest RenderbufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) diff --git a/src/Test/DebugGLTest.cpp b/src/Test/DebugGLTest.cpp new file mode 100644 index 000000000..43c1689e9 --- /dev/null +++ b/src/Test/DebugGLTest.cpp @@ -0,0 +1,103 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + 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 + THE AUTHORS OR COPYRIGHT HOLDERS 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 "Test/AbstractOpenGLTester.h" + +#include "Context.h" +#include "DebugMessage.h" +#include "Extensions.h" + +#ifdef MAGNUM_BUILD_DEPRECATED +#include "DebugMarker.h" +#endif + +namespace Magnum { namespace Test { + +class DebugGLTest: public AbstractOpenGLTester { + public: + explicit DebugGLTest(); + + void insertMessageNoOp(); + void insertMessage(); + void insertMessageFallback(); + + void deprecated(); +}; + +DebugGLTest::DebugGLTest() { + addTests({&DebugGLTest::insertMessageNoOp, + &DebugGLTest::insertMessage, + &DebugGLTest::insertMessageFallback, + + #ifdef MAGNUM_BUILD_DEPRECATED + &DebugGLTest::deprecated + #endif + }); +} + +void DebugGLTest::insertMessageNoOp() { + if(Context::current()->isExtensionSupported() || + Context::current()->isExtensionSupported() || + Context::current()->isExtensionSupported()) + CORRADE_SKIP("The extensions are supported, cannot test."); + + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void DebugGLTest::insertMessage() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::KHR::debug::string() + std::string(" is not supported")); + + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); + + MAGNUM_VERIFY_NO_ERROR(); +} + +void DebugGLTest::insertMessageFallback() { + if(Context::current()->isExtensionSupported() || + (!Context::current()->isExtensionSupported() && + !Context::current()->isExtensionSupported())) + CORRADE_SKIP("No proper extension is supported"); + + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugMessage::Severity::Notification, "Hello from OpenGL command stream!"); + + MAGNUM_VERIFY_NO_ERROR(); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +void DebugGLTest::deprecated() { + DebugMarker::mark("hello"); + + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +}} + +CORRADE_TEST_MAIN(Magnum::Test::DebugGLTest)