mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-26 05:58:48 -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:
@@ -195,6 +195,12 @@ void RenderableTrailOrbit::update(const UpdateData& data) {
|
||||
// Update the trails; the report contains whether any of the other values has been
|
||||
// touched and if so, how many
|
||||
UpdateReport report = updateTrails(data);
|
||||
_previousTime = data.time.j2000Seconds();
|
||||
|
||||
// Do not do anything if no point needs to be updated
|
||||
if (!report.permanentPointsNeedUpdate && !report.floatingPointNeedsUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2
|
||||
// Write the current location into the floating position
|
||||
@@ -205,14 +211,16 @@ void RenderableTrailOrbit::update(const UpdateData& data) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _primaryRenderInformation._vBufferID);
|
||||
|
||||
// 3
|
||||
if (!report.needsUpdate) {
|
||||
// If no other values have been touched, we only need to upload the floating value
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
_primaryRenderInformation.first * sizeof(TrailVBOLayout),
|
||||
sizeof(TrailVBOLayout),
|
||||
_vertexArray.data() + _primaryRenderInformation.first
|
||||
);
|
||||
if (!report.permanentPointsNeedUpdate) {
|
||||
if (report.floatingPointNeedsUpdate) {
|
||||
// If no other values have been touched, we only need to upload the floating value
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
_primaryRenderInformation.first * sizeof(TrailVBOLayout),
|
||||
sizeof(TrailVBOLayout),
|
||||
_vertexArray.data() + _primaryRenderInformation.first
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Otherwise we need to check how many values have been changed
|
||||
@@ -315,7 +323,7 @@ void RenderableTrailOrbit::update(const UpdateData& data) {
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
|
||||
glBindVertexArray(0);
|
||||
_previousTime = data.time.j2000Seconds();
|
||||
|
||||
}
|
||||
|
||||
RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
@@ -323,14 +331,14 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
{
|
||||
if (_needsFullSweep) {
|
||||
fullSweep(data.time.j2000Seconds());
|
||||
return { true, UpdateReport::All } ;
|
||||
return { false, true, UpdateReport::All } ;
|
||||
}
|
||||
|
||||
|
||||
const double Epsilon = 1e-7;
|
||||
// When time stands still (at the iron hill), we don't need to perform any work
|
||||
if (std::abs(data.time.j2000Seconds() - _previousTime) < Epsilon) {
|
||||
return { false, 0 };
|
||||
return { false, false, 0 };
|
||||
}
|
||||
|
||||
double secondsPerPoint = _period / (_resolution - 1);
|
||||
@@ -345,14 +353,14 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
// intervals
|
||||
|
||||
if (std::abs(delta) < Epsilon) {
|
||||
return { false, 0 };
|
||||
return { false, false, 0 };
|
||||
}
|
||||
|
||||
if (delta > 0.0) {
|
||||
// Check whether we need to drop a new permanent point. This is only the case if
|
||||
// enough (> secondsPerPoint) time has passed since the last permanent point
|
||||
if (std::abs(delta) < secondsPerPoint) {
|
||||
return { false, 0 };
|
||||
return { true, false, 0 };
|
||||
}
|
||||
|
||||
// See how many points we need to drop
|
||||
@@ -362,7 +370,7 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
// array, it is faster to regenerate the entire array
|
||||
if (nNewPoints >= _resolution) {
|
||||
fullSweep(data.time.j2000Seconds());
|
||||
return { true, UpdateReport::All };
|
||||
return { false, true, UpdateReport::All };
|
||||
}
|
||||
|
||||
for (int i = 0; i < nNewPoints; ++i) {
|
||||
@@ -386,7 +394,7 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
// future
|
||||
_firstPointTime += nNewPoints * secondsPerPoint;
|
||||
|
||||
return { true, nNewPoints };
|
||||
return { false, true, nNewPoints };
|
||||
}
|
||||
else {
|
||||
// See how many new points needs to be generated. Delta is negative, so we need
|
||||
@@ -397,7 +405,7 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
// array, it is faster to regenerate the entire array
|
||||
if (nNewPoints >= _resolution) {
|
||||
fullSweep(data.time.j2000Seconds());
|
||||
return { true, UpdateReport::All };
|
||||
return { false, true, UpdateReport::All };
|
||||
}
|
||||
|
||||
for (int i = 0; i < nNewPoints; ++i) {
|
||||
@@ -423,7 +431,7 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
|
||||
// The previously youngest point has become nNewPoints steps older
|
||||
_lastPointTime -= nNewPoints * secondsPerPoint;
|
||||
|
||||
return { true, -nNewPoints };
|
||||
return { false, true, -nNewPoints };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,9 +66,10 @@ private:
|
||||
/// about which parts of the vertex array to update
|
||||
struct UpdateReport {
|
||||
static const int All = 0; ///< The entire array was touched in the update
|
||||
|
||||
/// If \c true at least one point was touched
|
||||
bool needsUpdate;
|
||||
/// If \c true the floating point needs to be updated
|
||||
bool floatingPointNeedsUpdate;
|
||||
/// If \c true at least one of their permanent point were touched
|
||||
bool permanentPointsNeedUpdate;
|
||||
/// Returns the number of fixed points that were touched in the update method
|
||||
/// If this value is negative, the newest values were replaced, if positive the
|
||||
/// oldest
|
||||
|
||||
@@ -533,10 +533,9 @@ bool FixedRotation::initialize() {
|
||||
return res;
|
||||
}
|
||||
|
||||
void FixedRotation::update(const UpdateData&) {
|
||||
glm::dmat3 FixedRotation::matrix(const Time& time) const {
|
||||
if (!_enabled) {
|
||||
_matrix = glm::dmat3();
|
||||
return;
|
||||
return glm::dmat3();
|
||||
}
|
||||
|
||||
glm::vec3 x = xAxis();
|
||||
@@ -554,10 +553,10 @@ void FixedRotation::update(const UpdateData&) {
|
||||
"Dangerously collinear vectors detected: " <<
|
||||
"x: " << x << " y: " << y << " z: " << z
|
||||
);
|
||||
_matrix = glm::dmat3();
|
||||
return glm::dmat3();
|
||||
}
|
||||
else {
|
||||
_matrix = {
|
||||
return {
|
||||
x.x, x.y, x.z,
|
||||
y.x, y.y, y.z,
|
||||
z.x, z.y, z.z
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
void update(const UpdateData& data) override;
|
||||
glm::dmat3 matrix(const Time& time) const override;
|
||||
|
||||
private:
|
||||
glm::vec3 xAxis() const;
|
||||
|
||||
@@ -74,6 +74,14 @@ LuaRotation::LuaRotation()
|
||||
, _state(false)
|
||||
{
|
||||
addProperty(_luaScriptFile);
|
||||
|
||||
_luaScriptFile.onChange([&]() {
|
||||
requireUpdate();
|
||||
_fileHandle = std::make_unique<ghoul::filesystem::File>(_luaScriptFile);
|
||||
_fileHandle->setCallback([&](const ghoul::filesystem::File&) {
|
||||
requireUpdate();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
LuaRotation::LuaRotation(const ghoul::Dictionary& dictionary)
|
||||
@@ -88,7 +96,7 @@ LuaRotation::LuaRotation(const ghoul::Dictionary& dictionary)
|
||||
_luaScriptFile = absPath(dictionary.value<std::string>(ScriptInfo.identifier));
|
||||
}
|
||||
|
||||
void LuaRotation::update(const UpdateData& data) {
|
||||
glm::dmat3 LuaRotation::matrix(const Time& time) const {
|
||||
ghoul::lua::runScriptFile(_state, _luaScriptFile);
|
||||
|
||||
// Get the scaling function
|
||||
@@ -99,11 +107,11 @@ void LuaRotation::update(const UpdateData& data) {
|
||||
"LuaRotation",
|
||||
"Script '" << _luaScriptFile << "' does not have a function 'rotation'"
|
||||
);
|
||||
return;
|
||||
return glm::dmat3(1.0);
|
||||
}
|
||||
|
||||
// First argument is the number of seconds past the J2000 epoch in ingame time
|
||||
lua_pushnumber(_state, data.time.j2000Seconds());
|
||||
lua_pushnumber(_state, time.j2000Seconds());
|
||||
|
||||
// Second argument is the number of milliseconds past the J2000 epoch in wallclock
|
||||
using namespace std::chrono;
|
||||
@@ -129,7 +137,7 @@ void LuaRotation::update(const UpdateData& data) {
|
||||
values[i] = luaL_checknumber(_state, -1 - i);
|
||||
}
|
||||
|
||||
_matrix = glm::make_mat3(values);
|
||||
return glm::make_mat3(values);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
|
||||
#include <ghoul/lua/luastate.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -40,12 +41,13 @@ public:
|
||||
LuaRotation();
|
||||
LuaRotation(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void update(const UpdateData& data) override;
|
||||
glm::dmat3 matrix(const Time& data) const override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
properties::StringProperty _luaScriptFile;
|
||||
std::unique_ptr<ghoul::filesystem::File> _fileHandle;
|
||||
ghoul::lua::LuaState _state;
|
||||
};
|
||||
|
||||
|
||||
@@ -67,7 +67,9 @@ StaticRotation::StaticRotation()
|
||||
: _rotationMatrix(RotationInfo, glm::dmat3(1.0), glm::dmat3(-1.0), glm::dmat3(1.0))
|
||||
{
|
||||
addProperty(_rotationMatrix);
|
||||
_rotationMatrix.onChange([this]() { _matrix = _rotationMatrix; });
|
||||
_rotationMatrix.onChange([this]() {
|
||||
requireUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary)
|
||||
@@ -92,4 +94,8 @@ StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary)
|
||||
|
||||
}
|
||||
|
||||
glm::dmat3 StaticRotation::matrix(const Time&) const {
|
||||
return _rotationMatrix;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
StaticRotation();
|
||||
StaticRotation(const ghoul::Dictionary& dictionary);
|
||||
|
||||
glm::dmat3 matrix(const Time& time) const override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
|
||||
@@ -69,6 +69,14 @@ LuaScale::LuaScale()
|
||||
, _state(false)
|
||||
{
|
||||
addProperty(_luaScriptFile);
|
||||
|
||||
_luaScriptFile.onChange([&]() {
|
||||
requireUpdate();
|
||||
_fileHandle = std::make_unique<ghoul::filesystem::File>(_luaScriptFile);
|
||||
_fileHandle->setCallback([&](const ghoul::filesystem::File&) {
|
||||
requireUpdate();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
LuaScale::LuaScale(const ghoul::Dictionary& dictionary)
|
||||
@@ -79,7 +87,7 @@ LuaScale::LuaScale(const ghoul::Dictionary& dictionary)
|
||||
_luaScriptFile = absPath(dictionary.value<std::string>(ScriptInfo.identifier));
|
||||
}
|
||||
|
||||
void LuaScale::update(const UpdateData& data) {
|
||||
double LuaScale::scaleValue(const Time& time) const {
|
||||
ghoul::lua::runScriptFile(_state, _luaScriptFile);
|
||||
|
||||
// Get the scaling function
|
||||
@@ -90,11 +98,11 @@ void LuaScale::update(const UpdateData& data) {
|
||||
"LuaScale",
|
||||
"Script '" << _luaScriptFile << "' does not have a function 'scale'"
|
||||
);
|
||||
return;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// First argument is the number of seconds past the J2000 epoch in ingame time
|
||||
lua_pushnumber(_state, data.time.j2000Seconds());
|
||||
lua_pushnumber(_state, time.j2000Seconds());
|
||||
|
||||
// Second argument is the number of milliseconds past the J2000 epoch in wallclock
|
||||
using namespace std::chrono;
|
||||
@@ -115,7 +123,7 @@ void LuaScale::update(const UpdateData& data) {
|
||||
);
|
||||
}
|
||||
|
||||
_scale = luaL_checknumber(_state, -1);
|
||||
return luaL_checknumber(_state, -1);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
|
||||
#include <ghoul/lua/luastate.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -40,12 +41,13 @@ public:
|
||||
LuaScale();
|
||||
LuaScale(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void update(const UpdateData& data) override;
|
||||
double scaleValue(const Time& time) const override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
properties::StringProperty _luaScriptFile;
|
||||
std::unique_ptr<ghoul::filesystem::File> _fileHandle;
|
||||
ghoul::lua::LuaState _state;
|
||||
};
|
||||
|
||||
|
||||
@@ -54,12 +54,18 @@ documentation::Documentation StaticScale::Documentation() {
|
||||
};
|
||||
}
|
||||
|
||||
double StaticScale::scaleValue(const Time&) const {
|
||||
return _scaleValue;
|
||||
}
|
||||
|
||||
StaticScale::StaticScale()
|
||||
: _scaleValue(ScaleInfo, 1.0, 1.0, 1e6)
|
||||
{
|
||||
addProperty(_scaleValue);
|
||||
|
||||
_scaleValue.onChange([&](){ _scale = _scaleValue; });
|
||||
_scaleValue.onChange([this]() {
|
||||
requireUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
StaticScale::StaticScale(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -37,6 +37,7 @@ class StaticScale : public Scale {
|
||||
public:
|
||||
StaticScale();
|
||||
StaticScale(const ghoul::Dictionary& dictionary);
|
||||
double scaleValue(const Time& time) const override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ Fragment getFragment() {
|
||||
frag.color = gridColor;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
frag.gOtherData = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ Fragment getFragment() {
|
||||
}
|
||||
|
||||
// G-Buffer
|
||||
frag.gOtherData = vec4(frag.color.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
frag.gNormal = vec4(vs_gNormal, 1.0);
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ Fragment getFragment() {
|
||||
}
|
||||
|
||||
// G-Buffer
|
||||
frag.gOtherData = vec4(frag.color.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
// There is no normal here
|
||||
// TODO: Add the correct normal if necessary (JCC)
|
||||
|
||||
@@ -46,7 +46,6 @@ Fragment getFragment() {
|
||||
frag.depth = pscDepth(position);
|
||||
|
||||
// G-Buffer
|
||||
frag.gOtherData = vec4(frag.color.xyz, 1.0);
|
||||
frag.gPosition = vs_gPosition;
|
||||
// There is no normal here
|
||||
// TODO: Add the correct normal (JCC)
|
||||
|
||||
@@ -77,8 +77,10 @@ LuaTranslation::LuaTranslation()
|
||||
addProperty(_luaScriptFile);
|
||||
|
||||
_luaScriptFile.onChange([&](){
|
||||
requireUpdate();
|
||||
_fileHandle = std::make_unique<ghoul::filesystem::File>(_luaScriptFile);
|
||||
_fileHandle->setCallback([&](const ghoul::filesystem::File&) {
|
||||
requireUpdate();
|
||||
notifyObservers();
|
||||
});
|
||||
});
|
||||
@@ -96,7 +98,7 @@ LuaTranslation::LuaTranslation(const ghoul::Dictionary& dictionary)
|
||||
_luaScriptFile = absPath(dictionary.value<std::string>(ScriptInfo.identifier));
|
||||
}
|
||||
|
||||
void LuaTranslation::update(const UpdateData& data) {
|
||||
glm::dvec3 LuaTranslation::position(const Time& time) const {
|
||||
ghoul::lua::runScriptFile(_state, _luaScriptFile);
|
||||
|
||||
// Get the scaling function
|
||||
@@ -107,11 +109,11 @@ void LuaTranslation::update(const UpdateData& data) {
|
||||
"LuaScale",
|
||||
"Script '" << _luaScriptFile << "' does not have a function 'translation'"
|
||||
);
|
||||
return;
|
||||
return glm::dvec3(0.0);
|
||||
}
|
||||
|
||||
// First argument is the number of seconds past the J2000 epoch in ingame time
|
||||
lua_pushnumber(_state, data.time.j2000Seconds());
|
||||
lua_pushnumber(_state, time.j2000Seconds());
|
||||
|
||||
// Second argument is the number of milliseconds past the J2000 epoch in wallclock
|
||||
using namespace std::chrono;
|
||||
@@ -137,7 +139,7 @@ void LuaTranslation::update(const UpdateData& data) {
|
||||
values[i] = luaL_checknumber(_state, -1 - i);
|
||||
}
|
||||
|
||||
_positionValue = glm::make_vec3(values);
|
||||
return glm::make_vec3(values);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -43,15 +43,14 @@ public:
|
||||
LuaTranslation();
|
||||
LuaTranslation(const ghoul::Dictionary& dictionary);
|
||||
|
||||
virtual void update(const UpdateData& data) override;
|
||||
glm::dvec3 position(const Time& time) const override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
properties::StringProperty _luaScriptFile;
|
||||
ghoul::lua::LuaState _state;
|
||||
|
||||
std::unique_ptr<ghoul::filesystem::File> _fileHandle;
|
||||
ghoul::lua::LuaState _state;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -70,7 +70,14 @@ StaticTranslation::StaticTranslation()
|
||||
{
|
||||
addProperty(_position);
|
||||
|
||||
_position.onChange([&](){ _positionValue = _position; });
|
||||
_position.onChange([this]() {
|
||||
requireUpdate();
|
||||
notifyObservers();
|
||||
});
|
||||
}
|
||||
|
||||
glm::dvec3 StaticTranslation::position(const Time&) const {
|
||||
return _position;
|
||||
}
|
||||
|
||||
StaticTranslation::StaticTranslation(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
StaticTranslation();
|
||||
StaticTranslation(const ghoul::Dictionary& dictionary);
|
||||
|
||||
glm::dvec3 position(const Time& time) const;
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user