Add the ability to add OpenGL error checking and function call logging though the openspace.cfg file

This commit is contained in:
Alexander Bock
2017-07-13 14:52:13 -04:00
parent 3a0023e45c
commit c3929f5d6d
5 changed files with 119 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -144,6 +144,11 @@ public:
static const std::string PartFilterIdentifierIdentifier;
/// The part of the key storing a list of severities that should be filtered out
static const std::string PartFilterSeverity;
/// The part of the key storing whether the OpenGL state should be checked each call
static const std::string KeyCheckOpenGLState;
/// The part of the key storing whether each OpenGL call should be logged
static const std::string KeyLogEachOpenGLCall;
/**
* Iteratively walks the directory structure starting with \p filename to find the

View File

@@ -74,6 +74,9 @@ return {
Documentation = "${DOCUMENTATION}/Documentation.html",
FactoryDocumentation = "${DOCUMENTATION}/FactoryDocumentation.html",
-- CheckOpenGLState = true,
-- LogEachOpenGLCall = true,
ShutdownCountdown = 3,
-- OnScreenTextScaling = "framebuffer",
-- PerSceneCache = true,

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -97,6 +97,8 @@ const string ConfigurationManager::PartFilterIdentifierSource = "Source";
const string ConfigurationManager::PartFilterIdentifierType = "Type";
const string ConfigurationManager::PartFilterIdentifierIdentifier = "Identifier";
const string ConfigurationManager::PartFilterSeverity = "PartFilterSeverity";
const string ConfigurationManager::KeyCheckOpenGLState = "CheckOpenGLState";
const string ConfigurationManager::KeyLogEachOpenGLCall = "LogEachOpenGLCall";
string ConfigurationManager::findConfiguration(const string& filename) {
using ghoul::filesystem::Directory;

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -383,6 +383,23 @@ documentation::Documentation ConfigurationManager::Documentation() {
}),
"Determines the settings for the creation of an OpenGL debug context.",
Optional::Yes
},
{
ConfigurationManager::KeyCheckOpenGLState,
new BoolVerifier,
"Determines whether the OpenGL state is checked after each OpenGL function "
"call. This will dramatically slow down the rendering, but will make finding "
"OpenGL errors easier. This defaults to 'false'.",
Optional::Yes
},
{
ConfigurationManager::KeyLogEachOpenGLCall,
new BoolVerifier,
"Determines whether each OpenGL call that happens should be logged using the "
"'TRACE' loglevel. This will bring the rendering to a crawl but provides "
"useful debugging features for the order in which OpenGL calls occur. This "
"defaults to 'false'.",
Optional::Yes
}
}
};

View File

@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -59,6 +59,7 @@
#include <openspace/util/transformationmanager.h>
#include <ghoul/ghoul.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/misc/onscopeexit.h>
#include <ghoul/cmdparser/commandlineparser.h>
#include <ghoul/cmdparser/singlecommand.h>
@@ -70,6 +71,7 @@
#include <ghoul/opengl/debugcontext.h>
#include <ghoul/systemcapabilities/systemcapabilities>
#include <glbinding/callbacks.h>
#if defined(_MSC_VER) && defined(OPENSPACE_ENABLE_VLD)
#include <vld.h>
@@ -79,6 +81,8 @@
#include <Windows.h>
#endif
#include <numeric>
#include "openspaceengine_lua.inl"
using namespace openspace::scripting;
@@ -978,6 +982,90 @@ void OpenSpaceEngine::initializeGL() {
LTRACE("OpenSpaceEngine::initializeGL::DebugContext(end)");
}
// The ordering of the KeyCheckOpenGLState and KeyLogEachOpenGLCall are important as
// the callback mask in glbinding is stateful for each context, and since
// KeyLogEachOpenGLCall is more specific, we want it to be able to overwrite the
// state from KeyCheckOpenGLState
if (_configurationManager->hasKey(ConfigurationManager::KeyCheckOpenGLState)) {
const bool val = _configurationManager->value<bool>(
ConfigurationManager::KeyCheckOpenGLState
);
if (val) {
using namespace glbinding;
setCallbackMaskExcept(CallbackMask::After, { "glGetError" });
setAfterCallback([](const FunctionCall& f) {
const GLenum error = glGetError();
switch (error) {
case GL_NO_ERROR:
break;
case GL_INVALID_ENUM:
LERRORC(
"OpenGL Invalid State",
"Function " << f.toString() << ": GL_INVALID_ENUM"
);
break;
case GL_INVALID_VALUE:
LERRORC(
"OpenGL Invalid State",
"Function " << f.toString() << ": GL_INVALID_VALUE"
);
break;
case GL_INVALID_OPERATION:
LERRORC(
"OpenGL Invalid State",
"Function " << f.toString() << ": GL_INVALID_OPERATION"
);
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
LERRORC(
"OpenGL Invalid State",
"Function " << f.toString() <<
": GL_INVALID_FRAMEBUFFER_OPERATION"
);
break;
case GL_OUT_OF_MEMORY:
LERRORC(
"OpenGL Invalid State",
"Function " << f.toString() << ": GL_OUT_OF_MEMORY"
);
break;
default:
LERRORC(
"OpenGL Invalid State",
"Unknown error code: " << std::hex << error
);
}
});
}
}
if (_configurationManager->hasKey(ConfigurationManager::KeyLogEachOpenGLCall)) {
const bool val = _configurationManager->value<bool>(
ConfigurationManager::KeyLogEachOpenGLCall
);
if (val) {
using namespace glbinding;
setCallbackMask(CallbackMask::After | CallbackMask::ParametersAndReturnValue);
glbinding::setAfterCallback([](const glbinding::FunctionCall& call) {
std::string arguments = std::accumulate(
call.parameters.begin(),
call.parameters.end(),
std::string("("),
[](std::string a, AbstractValue* v) {
return a + ", " + v->asString();
}
);
std::string returnValue = call.returnValue ?
" -> " + call.returnValue->asString() :
"";
LTRACEC("OpenGL", call.function->name() << arguments << returnValue);
});
}
}
LINFO("Initializing Rendering Engine");
_renderEngine->initializeGL();