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:
Emil Axelsson
2018-01-08 09:43:41 +01:00
committed by GitHub
parent 237affa80d
commit 4c2f72226f
57 changed files with 296 additions and 205 deletions
+45
View File
@@ -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) {
+5 -4
View File
@@ -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);
}
}
+9 -33
View File
@@ -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);
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
+6 -6
View File
@@ -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
View File
@@ -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);
}