Merge branch 'master' into feature/multitouch

This commit is contained in:
Jonathan Bosson
2017-07-13 21:02:43 -06:00
committed by GitHub
12 changed files with 347 additions and 22 deletions
+6 -1
View File
@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -62,8 +62,11 @@ const string ConfigurationManager::KeyConfigScene = "Scene";
const string ConfigurationManager::KeyConfigTask = "Task";
const string ConfigurationManager::KeyLogging = "Logging";
const string ConfigurationManager::PartLogDir = "LogDir";
const string ConfigurationManager::PartLogLevel = "LogLevel";
const string ConfigurationManager::PartImmediateFlush = "ImmediateFlush";
const string ConfigurationManager::PartLogPerformancePrefix = "PerformancePrefix";
const string ConfigurationManager::PartLogs = "Logs";
const string ConfigurationManager::PartAppend = "Append";
const string ConfigurationManager::PartCapabilitiesVerbosity = "CapabilitiesVerbosity";
@@ -97,6 +100,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;
+32 -1
View File
@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -86,6 +86,20 @@ documentation::Documentation ConfigurationManager::Documentation() {
{
ConfigurationManager::KeyLogging,
new TableVerifier({
{
ConfigurationManager::PartLogDir,
new StringVerifier,
"The directory for logs."
"Default value is \"${BASE_PATH}\"",
Optional::Yes
},
{
ConfigurationManager::PartLogPerformancePrefix,
new StringVerifier,
"A string to prefix PerformanceMeasurement logfiles."
"Default value is \"PM-\"",
Optional::Yes
},
{
ConfigurationManager::PartLogLevel,
new StringInListVerifier(
@@ -383,6 +397,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
}
}
};
+89 -1
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();
+144 -8
View File
@@ -30,9 +30,12 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/sharedmemory.h>
#include <ghoul/misc/onscopeexit.h>
#include <ghoul/filesystem/filesystem.h>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <fstream>
namespace {
const char* _loggerCat = "PerformanceManager";
@@ -130,12 +133,16 @@ void PerformanceManager::destroyGlobalSharedMemory() {
PerformanceManager::PerformanceManager()
: _performanceMemory(nullptr)
, _tick(0)
, _loggingEnabled(false)
, _logDir(absPath("${BASE_PATH}"))
, _prefix("PM-")
, _ext("log")
{
using ghoul::SharedMemory;
PerformanceManager::createGlobalSharedMemory();
SharedMemory sharedMemory(GlobalSharedMemoryName);
ghoul::SharedMemory sharedMemory(GlobalSharedMemoryName);
sharedMemory.acquireLock();
OnExit([&](){sharedMemory.releaseLock();});
@@ -151,7 +158,7 @@ PerformanceManager::PerformanceManager()
const int totalSize = sizeof(PerformanceLayout);
LINFO("Create shared memory '" + localName + "' of " << totalSize << " bytes");
if (SharedMemory::exists(localName)) {
if (ghoul::SharedMemory::exists(localName)) {
throw ghoul::RuntimeError(
"Shared Memory '" + localName + "' block already existed"
);
@@ -196,11 +203,131 @@ bool PerformanceManager::isMeasuringPerformance() const {
return _doPerformanceMeasurements;
}
void PerformanceManager::outputLogs() {
// Log Layout values
PerformanceLayout* layout = performanceData();
// Log function performance
for (size_t n = 0; n < layout->nFunctionEntries; n++) {
const auto function = layout->functionEntries[n];
const std::string filename = formatLogName(function.name);
std::ofstream out = std::ofstream(absPath(filename), std::ofstream::out | std::ofstream::app);
// Comma separate data
for (size_t i = 0; i < PerformanceLayout::NumberValues; i++) {
const std::vector<float> data = { function.time[i] };
writeData(out, data);
}
out.close();
}
// Log scene object performance
for (size_t n = 0; n < layout->nScaleGraphEntries; n++) {
const auto node = layout->sceneGraphEntries[n];
// Open file
const std::string filename = formatLogName(node.name);
std::ofstream out = std::ofstream(absPath(filename), std::ofstream::out | std::ofstream::app);
// Comma separate data
for (size_t i = 0; i < PerformanceLayout::NumberValues; i++) {
const std::vector<float> data = {
node.renderTime[i],
node.updateRenderable[i],
node.updateRotation[i],
node.updateScaling[i],
node.updateTranslation[i]
};
writeData(out, data);
}
out.close();
}
}
void PerformanceManager::writeData(std::ofstream& out, const std::vector<float>& data) {
for (size_t i = 0; i < data.size() - 1; i++) {
out << data[i] << ",";
}
out << data[data.size() - 1] << "\n";
}
std::string PerformanceManager::formatLogName(std::string nodeName) {
// Replace any colons with dashes
std::replace(nodeName.begin(), nodeName.end(), ':', '-');
return _logDir + "/" + _prefix + nodeName + _suffix + "." + _ext;
}
void PerformanceManager::logDir(std::string dir) {
_logDir = absPath(dir);
}
std::string PerformanceManager::logDir() const {
return _logDir;
}
void PerformanceManager::prefix(std::string prefix) {
_prefix = prefix;
}
std::string PerformanceManager::prefix() const {
return _prefix;
}
void PerformanceManager::enableLogging() {
setLogging(true);
}
void PerformanceManager::disableLogging() {
setLogging(false);
}
void PerformanceManager::toggleLogging() {
setLogging(!_loggingEnabled);
}
void PerformanceManager::setLogging(bool enabled) {
// Create the log directory if it doesn't exist. Do it here, so that it
// only tests once each time output is enabled
if (enabled) {
// If it can't create the directory, it's not logging so set false
enabled = createLogDir();
}
_loggingEnabled = enabled;
}
bool PerformanceManager::createLogDir() {
// Done if it exists
ghoul::filesystem::Directory dir(_logDir);
if (FileSys.directoryExists(dir)) {
return true;
}
// Error and set false if can't create
try {
FileSys.createDirectory(dir, ghoul::filesystem::FileSystem::Recursive::Yes);
}
catch (const ghoul::filesystem::FileSystem::FileSystemException& e) {
LERROR("Could not create log directory: " << e.message);
return false;
}
return true;
}
bool PerformanceManager::loggingEnabled() const {
return _loggingEnabled;
}
PerformanceLayout* PerformanceManager::performanceData() {
void* ptr = _performanceMemory->memory();
return reinterpret_cast<PerformanceLayout*>(ptr);
}
void PerformanceManager::tick() {
_tick = (_tick + 1) % PerformanceLayout::NumberValues;
}
void PerformanceManager::storeIndividualPerformanceMeasurement
(std::string identifier, long long microseconds)
{
@@ -261,42 +388,51 @@ void PerformanceManager::storeScenePerformanceMeasurements(
SceneGraphNode::PerformanceRecord r = node->performanceRecord();
PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i];
// Covert nano to microseconds
const float micro = 1000.f;
std::rotate(
std::begin(entry.renderTime),
std::next(std::begin(entry.renderTime)),
std::end(entry.renderTime)
);
entry.renderTime[PerformanceLayout::NumberValues - 1] = r.renderTime / 1000.f;
entry.renderTime[PerformanceLayout::NumberValues - 1] = r.renderTime / micro;
std::rotate(
std::begin(entry.updateTranslation),
std::next(std::begin(entry.updateTranslation)),
std::end(entry.updateTranslation)
);
entry.updateTranslation[PerformanceLayout::NumberValues - 1] = r.updateTimeTranslation / 1000.f;
entry.updateTranslation[PerformanceLayout::NumberValues - 1] = r.updateTimeTranslation / micro;
std::rotate(
std::begin(entry.updateRotation),
std::next(std::begin(entry.updateRotation)),
std::end(entry.updateRotation)
);
entry.updateRotation[PerformanceLayout::NumberValues - 1] = r.updateTimeRotation / 1000.f;
entry.updateRotation[PerformanceLayout::NumberValues - 1] = r.updateTimeRotation / micro;
std::rotate(
std::begin(entry.updateScaling),
std::next(std::begin(entry.updateScaling)),
std::end(entry.updateScaling)
);
entry.updateScaling[PerformanceLayout::NumberValues - 1] = r.updateTimeScaling / 1000.f;
entry.updateScaling[PerformanceLayout::NumberValues - 1] = r.updateTimeScaling / micro;
std::rotate(
std::begin(entry.updateRenderable),
std::next(std::begin(entry.updateRenderable)),
std::end(entry.updateRenderable)
);
entry.updateRenderable[PerformanceLayout::NumberValues - 1] = r.updateTimeRenderable / 1000.f;
entry.updateRenderable[PerformanceLayout::NumberValues - 1] = r.updateTimeRenderable / micro;
}
_performanceMemory->releaseLock();
if (_loggingEnabled && _tick == PerformanceLayout::NumberValues - 1) {
outputLogs();
}
tick();
}
} // namespace performance
+8
View File
@@ -134,6 +134,14 @@ RenderEngine::RenderEngine()
if (_performanceMeasurements) {
if (!_performanceManager) {
_performanceManager = std::make_unique<performance::PerformanceManager>();
const std::string KeyLogDir = ConfigurationManager::KeyLogging + "." + ConfigurationManager::PartLogDir;
const std::string KeyPrefix = ConfigurationManager::KeyLogging + "." + ConfigurationManager::PartLogPerformancePrefix;
if (OsEng.configurationManager().hasKeyAndValue<std::string>(KeyLogDir)) {
_performanceManager->logDir(OsEng.configurationManager().value<std::string>(KeyLogDir));
}
if (OsEng.configurationManager().hasKeyAndValue<std::string>(KeyPrefix)) {
_performanceManager->prefix(OsEng.configurationManager().value<std::string>(KeyPrefix));
}
}
}
else {