diff --git a/include/openspace/performance/performancelayout.h b/include/openspace/performance/performancelayout.h index 83cc649a72..06104144db 100644 --- a/include/openspace/performance/performancelayout.h +++ b/include/openspace/performance/performancelayout.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __PERFORMANCEMEASUREMENT_H__ -#define __PERFORMANCEMEASUREMENT_H__ +#ifndef __PERFORMANCELAYOUT_H__ +#define __PERFORMANCELAYOUT_H__ #include @@ -60,14 +60,7 @@ struct PerformanceLayout { FunctionPerformanceLayout functionEntries[MaxValues]; }; -struct FunctionPerformanceHelper { - FunctionPerformanceHelper(); - ~FunctionPerformanceHelper(); - - -}; - } // namespace performance } // namespace openspace -#endif // __PERFORMANCEMEASUREMENT_H__ +#endif // __PERFORMANCELAYOUT_H__ diff --git a/include/openspace/performance/performancemanager.h b/include/openspace/performance/performancemanager.h new file mode 100644 index 0000000000..cce46761c6 --- /dev/null +++ b/include/openspace/performance/performancemanager.h @@ -0,0 +1,58 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#ifndef __PERFORMANCEMANAGER_H__ +#define __PERFORMANCEMANAGER_H__ + +#include + +namespace ghoul { + class SharedMemory; +} + +namespace openspace { + +class SceneGraphNode; + +namespace performance { + +class PerformanceManager { +public: + static const std::string PerformanceMeasurementSharedData; + + PerformanceManager(); + ~PerformanceManager(); + + bool isMeasuringPerformance() const; + void storeScenePerformanceMeasurements(const std::vector& sceneNodes); + +private: + bool _doPerformanceMeasurements; + ghoul::SharedMemory* _performanceMemory; +}; + +} // namespace performance +} // namespace openspace + +#endif // __PERFORMANCEMANAGER_H__ diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index d56e5c09a1..5ff6bfadd6 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -31,6 +31,7 @@ #include #include +#include namespace ghoul { namespace fontrendering { @@ -67,9 +68,6 @@ public: Post }; - - static const std::string PerformanceMeasurementSharedData; - static const std::string KeyFontMono; static const std::string KeyFontLight; @@ -101,8 +99,6 @@ public: void setPerformanceMeasurements(bool performanceMeasurements); bool doesPerformanceMeasurements() const; - - void serialize(SyncBuffer* syncBuffer); void deserialize(SyncBuffer* syncBuffer); @@ -181,7 +177,7 @@ public: private: void setRenderer(std::unique_ptr renderer); RendererImplementation rendererFromString(const std::string& method); - void storePerformanceMeasurements(); + void renderInformation(); void renderScreenLog(); @@ -189,6 +185,8 @@ private: Scene* _sceneGraph; RaycasterManager* _raycasterManager; + std::unique_ptr _performanceManager; + std::unique_ptr _renderer; RendererImplementation _rendererImplementation; ghoul::Dictionary _rendererData; @@ -199,9 +197,6 @@ private: bool _showLog; bool _takeScreenshot; - bool _doPerformanceMeasurements; - ghoul::SharedMemory* _performanceMemory; - float _globalBlackOutFactor; float _fadeDuration; float _currentFadeTime; diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index c749cba218..d1be505f64 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -25,8 +25,9 @@ #include #include +#include +#include #include -#include #include @@ -59,7 +60,7 @@ void GuiPerformanceComponent::render() { ImGui::Begin("Performance", &_isEnabled); if (OsEng.renderEngine().doesPerformanceMeasurements() && - ghoul::SharedMemory::exists(RenderEngine::PerformanceMeasurementSharedData)) + ghoul::SharedMemory::exists(PerformanceManager::PerformanceMeasurementSharedData)) { ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 10000.f); _minMaxValues[1] = fmaxf(_minMaxValues[0], _minMaxValues[1]); @@ -72,24 +73,23 @@ void GuiPerformanceComponent::render() { ImGui::RadioButton("RenderTime", &_sortingSelection, 2); if (!_performanceMemory) - _performanceMemory = new ghoul::SharedMemory(RenderEngine::PerformanceMeasurementSharedData); - + _performanceMemory = new ghoul::SharedMemory(PerformanceManager::PerformanceMeasurementSharedData); void* ptr = _performanceMemory->memory(); - PerformanceLayout layout = *reinterpret_cast(ptr); + PerformanceLayout* layout = reinterpret_cast(ptr); - std::vector indices(layout.nEntries); + std::vector indices(layout->nEntries); std::iota(indices.begin(), indices.end(), 0); // Ordering: // updateEphemeris // UpdateRender // RenderTime - std::vector> averages(layout.nEntries, { 0.f, 0.f, 0.f }); + std::vector> averages(layout->nEntries, { 0.f, 0.f, 0.f }); - for (int i = 0; i < layout.nEntries; ++i) { - const PerformanceLayout::PerformanceLayoutEntry& entry = layout.entries[i]; + for (int i = 0; i < layout->nEntries; ++i) { + const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; int v[3] = { 0, 0, 0 }; @@ -126,8 +126,8 @@ void GuiPerformanceComponent::render() { } - for (int i = 0; i < layout.nEntries; ++i) { - const PerformanceLayout::PerformanceLayoutEntry& entry = layout.entries[indices[i]]; + for (int i = 0; i < layout->nEntries; ++i) { + const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[indices[i]]; if (ImGui::CollapsingHeader(entry.name)) { std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[entry.currentUpdateEphemeris - 1]) + "us"; @@ -136,7 +136,6 @@ void GuiPerformanceComponent::render() { fmt::format("UpdateEphemeris\nAverage: {}us", averages[i][0]).c_str(), &entry.updateEphemeris[0], PerformanceLayout::NumberValues, - //layout.nValuesPerEntry, 0, updateEphemerisTime.c_str(), _minMaxValues[0], diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ec574b652..b0169dc3c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,6 +51,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/network/parallelconnection.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection_lua.inl ${OPENSPACE_BASE_DIR}/src/performance/performancelayout.cpp + ${OPENSPACE_BASE_DIR}/src/performance/performancemanager.cpp ${OPENSPACE_BASE_DIR}/src/properties/matrixproperty.cpp ${OPENSPACE_BASE_DIR}/src/properties/optionproperty.cpp ${OPENSPACE_BASE_DIR}/src/properties/property.cpp @@ -121,6 +122,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h ${OPENSPACE_BASE_DIR}/include/openspace/network/messagestructures.h ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancelayout.h + ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancemanager.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/matrixproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/numericalproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/numericalproperty.inl diff --git a/src/performance/performancelayout.cpp b/src/performance/performancelayout.cpp index 6239714b42..803a577443 100644 --- a/src/performance/performancelayout.cpp +++ b/src/performance/performancelayout.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include diff --git a/src/performance/performancemanager.cpp b/src/performance/performancemanager.cpp new file mode 100644 index 0000000000..46f89ebec8 --- /dev/null +++ b/src/performance/performancemanager.cpp @@ -0,0 +1,118 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 + +#include +#include + +#include +#include + +namespace { + const std::string _loggerCat = "PerformanceManager"; +} + +namespace openspace { +namespace performance { + +const std::string PerformanceManager::PerformanceMeasurementSharedData = + "OpenSpacePerformanceMeasurementSharedData"; + +PerformanceManager::PerformanceManager() + : _performanceMemory(nullptr) +{ +} + +PerformanceManager::~PerformanceManager() { + if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) + ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); +} + +bool PerformanceManager::isMeasuringPerformance() const { + return _doPerformanceMeasurements; +} + +void PerformanceManager::storeScenePerformanceMeasurements( + const std::vector& sceneNodes) +{ + using namespace performance; + + int nNodes = static_cast(sceneNodes.size()); + if (!_performanceMemory) { + // Compute the total size + const int totalSize = sizeof(PerformanceLayout); + LINFO("Create shared memory of " << totalSize << " bytes"); + + try { + ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); + } + catch (const ghoul::SharedMemory::SharedMemoryError& e) { + LINFOC(e.component, e.what()); + } + + ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); + _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); + void* ptr = _performanceMemory->memory(); + + // Using the placement-new to create a PerformanceLayout in the shared memory + PerformanceLayout* layout = new (ptr) PerformanceLayout(nNodes); + + for (int i = 0; i < nNodes; ++i) { + SceneGraphNode* node = sceneNodes[i]; + + memset(layout->sceneGraphEntries[i].name, 0, PerformanceLayout::LengthName); +#ifdef _MSC_VER + strcpy_s(layout->sceneGraphEntries[i].name, node->name().length() + 1, node->name().c_str()); +#else + strcpy(layout->entries[i].name, node->name().c_str()); +#endif + + layout->sceneGraphEntries[i].currentRenderTime = 0; + layout->sceneGraphEntries[i].currentUpdateRenderable = 0; + layout->sceneGraphEntries[i].currentUpdateEphemeris = 0; + } + } + + void* ptr = _performanceMemory->memory(); + PerformanceLayout* layout = reinterpret_cast(ptr); + _performanceMemory->acquireLock(); + for (int i = 0; i < nNodes; ++i) { + SceneGraphNode* node = sceneNodes[i]; + SceneGraphNode::PerformanceRecord r = node->performanceRecord(); + PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; + + entry.renderTime[entry.currentRenderTime] = r.renderTime / 1000.f; + entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; + entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; + + entry.currentRenderTime = (entry.currentRenderTime + 1) % PerformanceLayout::NumberValues; + entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % PerformanceLayout::NumberValues; + entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % PerformanceLayout::NumberValues; + } + _performanceMemory->releaseLock(); +} + +} // namespace performance +} // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 11e914f142..fad8d2131e 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -36,6 +36,8 @@ #include #include +#include + #include #include #include @@ -58,9 +60,6 @@ #include #include -#include - - #include #include #ifdef GHOUL_USE_DEVIL @@ -104,9 +103,6 @@ namespace { namespace openspace { -const std::string RenderEngine::PerformanceMeasurementSharedData = - "OpenSpacePerformanceMeasurementSharedData"; - const std::string RenderEngine::KeyFontMono = "Mono"; const std::string RenderEngine::KeyFontLight = "Light"; @@ -115,12 +111,11 @@ RenderEngine::RenderEngine() , _sceneGraph(nullptr) , _renderer(nullptr) , _rendererImplementation(RendererImplementation::Invalid) + , _performanceManager(nullptr) , _log(nullptr) , _showInfo(true) , _showLog(true) , _takeScreenshot(false) - , _doPerformanceMeasurements(false) - , _performanceMemory(nullptr) , _globalBlackOutFactor(1.f) , _fadeDuration(2.f) , _currentFadeTime(0.f) @@ -139,11 +134,8 @@ RenderEngine::~RenderEngine() { _sceneGraph = nullptr; delete _mainCamera; - delete _performanceMemory; delete _raycasterManager; - if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) - ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); } bool RenderEngine::deinitialize() { @@ -367,7 +359,7 @@ void RenderEngine::postSynchronizationPreDraw() { Time::ref().currentTime(), Time::ref().timeJumped(), Time::ref().deltaTime(), - _doPerformanceMeasurements + _performanceManager != nullptr }); _sceneGraph->evaluate(_mainCamera); @@ -401,7 +393,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (!(OsEng.isMaster() && _disableMasterRendering)) { - _renderer->render(_globalBlackOutFactor, _doPerformanceMeasurements); + _renderer->render(_globalBlackOutFactor, _performanceManager != nullptr); } // Print some useful information on the master viewport @@ -428,8 +420,8 @@ void RenderEngine::postDraw() { _takeScreenshot = false; } - if (_doPerformanceMeasurements) - storePerformanceMeasurements(); + if (_performanceManager) + _performanceManager->storeScenePerformanceMeasurements(scene()->allSceneGraphNodes()); } void RenderEngine::takeScreenshot() { @@ -716,69 +708,16 @@ scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { } void RenderEngine::setPerformanceMeasurements(bool performanceMeasurements) { - _doPerformanceMeasurements = performanceMeasurements; + if (performanceMeasurements) { + if (!_performanceManager) + _performanceManager = std::make_unique(); + } + else + _performanceManager = nullptr; } bool RenderEngine::doesPerformanceMeasurements() const { - return _doPerformanceMeasurements; -} - -void RenderEngine::storePerformanceMeasurements() { - using namespace performance; - - int nNodes = static_cast(scene()->allSceneGraphNodes().size()); - if (!_performanceMemory) { - // Compute the total size - const int totalSize = sizeof(PerformanceLayout); - LINFO("Create shared memory of " << totalSize << " bytes"); - - try { - ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); - } - catch (const ghoul::SharedMemory::SharedMemoryError& e) { - LINFOC(e.component, e.what()); - } - - ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); - _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); - void* ptr = _performanceMemory->memory(); - - // Using the placement-new to create a PerformanceLayout in the shared memory - PerformanceLayout* layout = new (ptr) PerformanceLayout(nNodes); - - for (int i = 0; i < nNodes; ++i) { - SceneGraphNode* node = scene()->allSceneGraphNodes()[i]; - - memset(layout->entries[i].name, 0, PerformanceLayout::LengthName); -#ifdef _MSC_VER - strcpy_s(layout->entries[i].name, node->name().length() + 1, node->name().c_str()); -#else - strcpy(layout->entries[i].name, node->name().c_str()); -#endif - - layout->entries[i].currentRenderTime = 0; - layout->entries[i].currentUpdateRenderable = 0; - layout->entries[i].currentUpdateEphemeris = 0; - } - } - - void* ptr = _performanceMemory->memory(); - PerformanceLayout* layout = reinterpret_cast(ptr); - _performanceMemory->acquireLock(); - for (int i = 0; i < nNodes; ++i) { - SceneGraphNode* node = scene()->allSceneGraphNodes()[i]; - SceneGraphNode::PerformanceRecord r = node->performanceRecord(); - PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i]; - - entry.renderTime[entry.currentRenderTime] = r.renderTime / 1000.f; - entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; - entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; - - entry.currentRenderTime = (entry.currentRenderTime + 1) % PerformanceLayout::NumberValues; - entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % PerformanceLayout::NumberValues; - entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % PerformanceLayout::NumberValues; - } - _performanceMemory->releaseLock(); + return _performanceManager != nullptr; } // This method is temporary and will be removed once the scalegraph is in effect ---abock