mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-02 16:59:37 -05:00
Performance Optimizations (#450)
* Make derived transform classes less involved in simulation state * Add performance measurements in openspaceengine * Avoid redundant transformation lookups * Fix bug causing redundant calls to GPULayerManager::bind * Move water reflectance to alpha component of normal buffer. Remove otherData buffer.
This commit is contained in:
@@ -41,6 +41,9 @@
|
||||
#include <openspace/interaction/luaconsole.h>
|
||||
#include <openspace/network/networkengine.h>
|
||||
#include <openspace/network/parallelconnection.h>
|
||||
|
||||
#include <openspace/performance/performancemeasurement.h>
|
||||
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
#include <openspace/rendering/dashboarditem.h>
|
||||
#include <openspace/rendering/loadingscreen.h>
|
||||
@@ -1209,6 +1212,15 @@ void OpenSpaceEngine::initializeGL() {
|
||||
|
||||
void OpenSpaceEngine::preSynchronization() {
|
||||
LTRACE("OpenSpaceEngine::preSynchronization(begin)");
|
||||
|
||||
std::unique_ptr<performance::PerformanceMeasurement> perf;
|
||||
if (OsEng.renderEngine().performanceManager()) {
|
||||
perf = std::make_unique<performance::PerformanceMeasurement>(
|
||||
"OpenSpaceEngine::preSynchronization",
|
||||
OsEng.renderEngine().performanceManager()
|
||||
);
|
||||
}
|
||||
|
||||
FileSys.triggerFilesystemEvents();
|
||||
|
||||
if (_hasScheduledAssetLoading) {
|
||||
@@ -1258,6 +1270,14 @@ void OpenSpaceEngine::preSynchronization() {
|
||||
void OpenSpaceEngine::postSynchronizationPreDraw() {
|
||||
LTRACE("OpenSpaceEngine::postSynchronizationPreDraw(begin)");
|
||||
|
||||
std::unique_ptr<performance::PerformanceMeasurement> perf;
|
||||
if (OsEng.renderEngine().performanceManager()) {
|
||||
perf = std::make_unique<performance::PerformanceMeasurement>(
|
||||
"OpenSpaceEngine::postSynchronizationPreDraw",
|
||||
OsEng.renderEngine().performanceManager()
|
||||
);
|
||||
}
|
||||
|
||||
bool master = _windowWrapper->isMaster();
|
||||
_syncEngine->postSynchronization(SyncEngine::IsMaster(master));
|
||||
|
||||
@@ -1315,6 +1335,15 @@ void OpenSpaceEngine::render(const glm::mat4& sceneMatrix,
|
||||
const glm::mat4& projectionMatrix)
|
||||
{
|
||||
LTRACE("OpenSpaceEngine::render(begin)");
|
||||
|
||||
std::unique_ptr<performance::PerformanceMeasurement> perf;
|
||||
if (OsEng.renderEngine().performanceManager()) {
|
||||
perf = std::make_unique<performance::PerformanceMeasurement>(
|
||||
"OpenSpaceEngine::render",
|
||||
OsEng.renderEngine().performanceManager()
|
||||
);
|
||||
}
|
||||
|
||||
OnExit([] {
|
||||
LTRACE("OpenSpaceEngine::render(end)");
|
||||
});
|
||||
@@ -1340,6 +1369,14 @@ void OpenSpaceEngine::drawOverlays() {
|
||||
LTRACE("OpenSpaceEngine::drawOverlays(end)");
|
||||
});
|
||||
|
||||
std::unique_ptr<performance::PerformanceMeasurement> perf;
|
||||
if (OsEng.renderEngine().performanceManager()) {
|
||||
perf = std::make_unique<performance::PerformanceMeasurement>(
|
||||
"OpenSpaceEngine::drawOverlays",
|
||||
OsEng.renderEngine().performanceManager()
|
||||
);
|
||||
}
|
||||
|
||||
const bool isGuiWindow =
|
||||
_windowWrapper->hasGuiWindow() ? _windowWrapper->isGuiWindow() : true;
|
||||
|
||||
@@ -1368,6 +1405,14 @@ void OpenSpaceEngine::drawOverlays() {
|
||||
void OpenSpaceEngine::postDraw() {
|
||||
LTRACE("OpenSpaceEngine::postDraw(begin)");
|
||||
|
||||
std::unique_ptr<performance::PerformanceMeasurement> perf;
|
||||
if (OsEng.renderEngine().performanceManager()) {
|
||||
perf = std::make_unique<performance::PerformanceMeasurement>(
|
||||
"OpenSpaceEngine::postDraw",
|
||||
OsEng.renderEngine().performanceManager()
|
||||
);
|
||||
}
|
||||
|
||||
_renderEngine->postDraw();
|
||||
|
||||
for (const auto& func : _moduleCallbacks.postDraw) {
|
||||
|
||||
@@ -33,11 +33,12 @@
|
||||
namespace openspace::performance {
|
||||
|
||||
PerformanceMeasurement::PerformanceMeasurement(std::string identifier,
|
||||
performance::PerformanceManager* manager)
|
||||
std::shared_ptr<performance::PerformanceManager> manager
|
||||
)
|
||||
: _identifier(std::move(identifier))
|
||||
, _manager(manager)
|
||||
{
|
||||
if (_manager) {
|
||||
if (_manager.lock()) {
|
||||
glFinish();
|
||||
|
||||
_startTime = std::chrono::high_resolution_clock::now();
|
||||
@@ -50,8 +51,8 @@ PerformanceMeasurement::~PerformanceMeasurement() {
|
||||
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
endTime - _startTime).count();
|
||||
|
||||
if (_manager) {
|
||||
_manager->storeIndividualPerformanceMeasurement(std::move(_identifier), duration);
|
||||
if (std::shared_ptr<performance::PerformanceManager> m = _manager.lock()) {
|
||||
m->storeIndividualPerformanceMeasurement(std::move(_identifier), duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,6 @@ void FramebufferRenderer::initialize() {
|
||||
|
||||
// Deferred framebuffer
|
||||
glGenTextures(1, &_deferredColorTexture);
|
||||
glGenTextures(1, &_mainOtherDataTexture);
|
||||
glGenTextures(1, &_mainPositionTexture);
|
||||
glGenTextures(1, &_mainNormalTexture);
|
||||
glGenFramebuffers(1, &_deferredFramebuffer);
|
||||
@@ -153,19 +152,12 @@ void FramebufferRenderer::initialize() {
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_mainOtherDataTexture,
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_mainPositionTexture,
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT3,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_mainNormalTexture,
|
||||
0
|
||||
@@ -251,7 +243,6 @@ void FramebufferRenderer::deinitialize() {
|
||||
|
||||
// DEBUG: deferred g-buffer
|
||||
glDeleteTextures(1, &_deferredColorTexture);
|
||||
glDeleteTextures(1, &_mainOtherDataTexture);
|
||||
glDeleteTextures(1, &_mainPositionTexture);
|
||||
glDeleteTextures(1, &_mainNormalTexture);
|
||||
|
||||
@@ -374,16 +365,6 @@ void FramebufferRenderer::updateResolution() {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainOtherDataTexture);
|
||||
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_nAaSamples,
|
||||
GL_RGBA32F,
|
||||
GLsizei(_resolution.x),
|
||||
GLsizei(_resolution.y),
|
||||
true);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainPositionTexture);
|
||||
|
||||
glTexImage2DMultisample(
|
||||
@@ -945,8 +926,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
Time time = OsEng.timeManager().time();
|
||||
|
||||
@@ -959,15 +939,19 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
|
||||
// deferred g-buffer
|
||||
GLenum textureBuffers[4] = {
|
||||
GLenum textureBuffers[3] = {
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_COLOR_ATTACHMENT3
|
||||
};
|
||||
glDrawBuffers(4, textureBuffers);
|
||||
glDrawBuffers(3, textureBuffers);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glEnablei(GL_BLEND, 0);
|
||||
glDisablei(GL_BLEND, 1);
|
||||
glDisablei(GL_BLEND, 2);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Background);
|
||||
_scene->render(data, tasks);
|
||||
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Opaque);
|
||||
@@ -1092,14 +1076,6 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure
|
||||
mainDColorTextureUnit
|
||||
);
|
||||
|
||||
ghoul::opengl::TextureUnit otherDataTextureUnit;
|
||||
otherDataTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainOtherDataTexture);
|
||||
deferredcastProgram->setUniform(
|
||||
"otherDataTexture",
|
||||
otherDataTextureUnit
|
||||
);
|
||||
|
||||
ghoul::opengl::TextureUnit mainPositionTextureUnit;
|
||||
mainPositionTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainPositionTexture);
|
||||
|
||||
@@ -263,7 +263,7 @@ RenderEngine::RenderEngine()
|
||||
prefix = OsEng.configurationManager().value<std::string>(KeyPrefix);
|
||||
}
|
||||
|
||||
_performanceManager = std::make_unique<performance::PerformanceManager>(
|
||||
_performanceManager = std::make_shared<performance::PerformanceManager>(
|
||||
loggingDir,
|
||||
prefix
|
||||
);
|
||||
@@ -918,8 +918,8 @@ bool RenderEngine::doesPerformanceMeasurements() const {
|
||||
return _performanceManager != nullptr;
|
||||
}
|
||||
|
||||
performance::PerformanceManager* RenderEngine::performanceManager() {
|
||||
return _performanceManager.get();
|
||||
std::shared_ptr<performance::PerformanceManager> RenderEngine::performanceManager() {
|
||||
return _performanceManager;
|
||||
}
|
||||
|
||||
void RenderEngine::addScreenSpaceRenderable(std::shared_ptr<ScreenSpaceRenderable> s) {
|
||||
|
||||
+15
-2
@@ -27,6 +27,7 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
@@ -70,8 +71,13 @@ std::unique_ptr<Rotation> Rotation::createFromDictionary(
|
||||
|
||||
Rotation::Rotation()
|
||||
: properties::PropertyOwner({ "Rotation" })
|
||||
, _needsUpdate(true)
|
||||
{}
|
||||
|
||||
void Rotation::requireUpdate() {
|
||||
_needsUpdate = true;
|
||||
}
|
||||
|
||||
Rotation::Rotation(const ghoul::Dictionary&)
|
||||
: properties::PropertyOwner({ "Rotation" })
|
||||
{}
|
||||
@@ -81,9 +87,16 @@ bool Rotation::initialize() {
|
||||
}
|
||||
|
||||
const glm::dmat3& Rotation::matrix() const {
|
||||
return _matrix;
|
||||
return _cachedMatrix;
|
||||
}
|
||||
|
||||
void Rotation::update(const UpdateData&) {}
|
||||
void Rotation::update(const Time& time) {
|
||||
if (!_needsUpdate && time.j2000Seconds() == _cachedTime) {
|
||||
return;
|
||||
}
|
||||
_cachedMatrix = matrix(time);
|
||||
_cachedTime = time.j2000Seconds();
|
||||
_needsUpdate = false;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
+17
-4
@@ -58,6 +58,10 @@ documentation::Documentation Scale::Documentation() {
|
||||
};
|
||||
}
|
||||
|
||||
void Scale::requireUpdate() {
|
||||
_needsUpdate = true;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Scale> Scale::createFromDictionary(const ghoul::Dictionary& dictionary) {
|
||||
documentation::testSpecificationAndThrow(Documentation(), dictionary, "Scale");
|
||||
@@ -72,17 +76,26 @@ std::unique_ptr<Scale> Scale::createFromDictionary(const ghoul::Dictionary& dict
|
||||
|
||||
Scale::Scale()
|
||||
: properties::PropertyOwner({ "Scale" })
|
||||
, _scale(1.0)
|
||||
, _cachedScale(1.0)
|
||||
, _needsUpdate(true)
|
||||
{}
|
||||
|
||||
bool Scale::initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
double Scale::scaleValue() const {
|
||||
return _scale;
|
||||
double Scale::scaleValue() const
|
||||
{
|
||||
return _cachedScale;
|
||||
}
|
||||
|
||||
void Scale::update(const UpdateData&) {}
|
||||
void Scale::update(const Time& time) {
|
||||
if (!_needsUpdate && time.j2000Seconds() == _cachedTime) {
|
||||
return;
|
||||
}
|
||||
_cachedScale = scaleValue(time);
|
||||
_cachedTime = time.j2000Seconds();
|
||||
_needsUpdate = false;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -255,14 +255,14 @@ void SceneGraphNode::update(const UpdateData& data) {
|
||||
glFinish();
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
_transform.translation->update(data);
|
||||
_transform.translation->update(data.time);
|
||||
|
||||
glFinish();
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
_performanceRecord.updateTimeTranslation = (end - start).count();
|
||||
}
|
||||
else {
|
||||
_transform.translation->update(data);
|
||||
_transform.translation->update(data.time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,14 +271,14 @@ void SceneGraphNode::update(const UpdateData& data) {
|
||||
glFinish();
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
_transform.rotation->update(data);
|
||||
_transform.rotation->update(data.time);
|
||||
|
||||
glFinish();
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
_performanceRecord.updateTimeRotation = (end - start).count();
|
||||
}
|
||||
else {
|
||||
_transform.rotation->update(data);
|
||||
_transform.rotation->update(data.time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,14 +287,14 @@ void SceneGraphNode::update(const UpdateData& data) {
|
||||
glFinish();
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
_transform.scale->update(data);
|
||||
_transform.scale->update(data.time);
|
||||
|
||||
glFinish();
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
_performanceRecord.updateTimeScaling = (end - start).count();
|
||||
}
|
||||
else {
|
||||
_transform.scale->update(data);
|
||||
_transform.scale->update(data.time);
|
||||
}
|
||||
}
|
||||
UpdateData newUpdateData = data;
|
||||
|
||||
+21
-14
@@ -73,35 +73,42 @@ std::unique_ptr<Translation> Translation::createFromDictionary(
|
||||
|
||||
Translation::Translation()
|
||||
: properties::PropertyOwner({ "Translation" })
|
||||
, _positionValue(glm::dvec3(0.0))
|
||||
, _cachedPosition(glm::dvec3(0.0))
|
||||
, _needsUpdate(true)
|
||||
{}
|
||||
|
||||
bool Translation::initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Translation::update(const UpdateData&) {}
|
||||
void Translation::update(const Time& time) {
|
||||
if (!_needsUpdate && time.j2000Seconds() == _cachedTime) {
|
||||
return;
|
||||
}
|
||||
glm::dvec3 oldPosition = _cachedPosition;
|
||||
_cachedPosition = position(time);
|
||||
_cachedTime = time.j2000Seconds();
|
||||
_needsUpdate = false;
|
||||
|
||||
if (oldPosition != _cachedPosition) {
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
glm::dvec3 Translation::position() const {
|
||||
return _positionValue;
|
||||
return _cachedPosition;
|
||||
}
|
||||
|
||||
glm::dvec3 Translation::position(double time) {
|
||||
update({
|
||||
{},
|
||||
time,
|
||||
false
|
||||
});
|
||||
|
||||
return position();
|
||||
}
|
||||
|
||||
void Translation::notifyObservers() {
|
||||
void Translation::notifyObservers() const {
|
||||
if (_onParameterChangeCallback) {
|
||||
_onParameterChangeCallback();
|
||||
}
|
||||
}
|
||||
|
||||
void Translation::requireUpdate() {
|
||||
_needsUpdate = true;
|
||||
}
|
||||
|
||||
void Translation::onParameterChange(std::function<void()> callback) {
|
||||
_onParameterChangeCallback = std::move(callback);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user