Make more use of temporary string objects in the TimeQuantizer

Add GPU markers to the rendering
This commit is contained in:
Alexander Bock
2020-08-19 18:26:11 +02:00
parent 6ac5d536fa
commit e93f1833be
19 changed files with 145 additions and 105 deletions

View File

@@ -33,11 +33,15 @@
#include <string>
#include <vector>
#include <set>
#include "SpiceUsr.h"
#include "SpiceZpr.h"
namespace openspace {
namespace scripting { struct LuaLibrary; }
void throwSpiceError(const std::string& errorMessage);
class SpiceManager {
public:
BooleanType(UseException);
@@ -462,6 +466,7 @@ public:
* \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html
*/
double ephemerisTimeFromDate(const std::string& timeString) const;
double ephemerisTimeFromDate(const char* timeString) const;
/**
* Converts the passed \p ephemerisTime into a human-readable date string with a
@@ -476,11 +481,33 @@ public:
*
* \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html
*/
template <int N = 31>
std::string dateFromEphemerisTime(double ephemerisTime,
std::string_view format = "YYYY MON DDTHR:MN:SC.### ::RND") const;
const char (&format)[N] = "YYYY MON DDTHR:MN:SC.### ::RND") const
{
static_assert(N != 0, "Format must not be empty");
std::string res;
res.resize(N);
dateFromEphemerisTime(ephemerisTime, res.data(), N, format);
return res;
}
template <int N>
void dateFromEphemerisTime(double ephemerisTime, char* outBuf, int bufferSize,
std::string_view format = "YYYY MON DDTHR:MN:SC.### ::RND") const;
const char (&format)[N] = "YYYY MON DDTHR:MN:SC.### ::RND") const
{
static_assert(N != 0, "Format must not be empty");
ghoul_assert(N > bufferSize - 1, "Buffer size too small");
timout_c(ephemerisTime, format, bufferSize - 1, outBuf);
if (failed_c()) {
throwSpiceError(fmt::format(
"Error converting ephemeris time '{}' to date with format '{}'",
ephemerisTime, format
));
}
}
/**
* Returns the \p position of a \p target body relative to an \p observer in a

View File

@@ -64,6 +64,7 @@ public:
* \pre \p timeString must not be empty
*/
static double convertTime(const std::string& time);
static double convertTime(const char* time);
explicit Time(double secondsJ2000 = -1);
explicit Time(const std::string& time);
@@ -113,13 +114,13 @@ public:
* thus also compliant with the Spice library.
* \return The current time as a formatted date string
*/
std::string UTC() const;
std::string_view UTC() const;
/**
* Returns the current time as a ISO 8601 formatted, i.e YYYY-MM-DDThh:mm:ssZ
* \return The current time as a ISO 8601 formatted string
*/
std::string ISO8601() const;
std::string_view ISO8601() const;
/**
* Advances the simulation time using the deltaTime() and the <code>tickTime</code>.

View File

@@ -245,7 +245,7 @@ bool FieldlinesState::loadStateFromJson(const std::string& pathToJsonFile,
*/
void FieldlinesState::saveStateToOsfls(const std::string& absPath) {
// ------------------------------- Create the file ------------------------------- //
std::string pathSafeTimeString = Time(_triggerTime).ISO8601();
std::string pathSafeTimeString = std::string(Time(_triggerTime).ISO8601());
pathSafeTimeString.replace(13, 1, "-");
pathSafeTimeString.replace(16, 1, "-");
pathSafeTimeString.replace(19, 1, "-");
@@ -341,7 +341,7 @@ void FieldlinesState::saveStateToJson(const std::string& absPath) {
json jFile;
const std::string timeStr = Time(_triggerTime).ISO8601();
std::string_view timeStr = Time(_triggerTime).ISO8601();
const size_t nLines = _lineStart.size();
// const size_t nPoints = _vertexPositions.size();
const size_t nExtras = _extraQuantities.size();

View File

@@ -278,9 +278,9 @@ std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time&
switch (type) {
case TemporalTileProvider::TimeFormatType::YYYY_MM_DD:
return t.ISO8601().substr(0, 10);
return std::string(t.ISO8601().substr(0, 10));
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmmss: {
std::string ts = t.ISO8601().substr(0, 19);
std::string ts = std::string(t.ISO8601().substr(0, 19));
// YYYY_MM_DDThh_mm_ss -> YYYYMMDD_hhmmss
ts.erase(std::remove(ts.begin(), ts.end(), '-'), ts.end());
@@ -289,7 +289,7 @@ std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time&
return ts;
}
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmm: {
std::string ts = t.ISO8601().substr(0, 16);
std::string ts = std::string(t.ISO8601().substr(0, 16));
// YYYY_MM_DDThh_mm -> YYYYMMDD_hhmm
ts.erase(std::remove(ts.begin(), ts.end(), '-'), ts.end());
@@ -298,9 +298,9 @@ std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time&
return ts;
}
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThhColonmmColonssZ:
return t.ISO8601().substr(0, 19) + "Z";
return std::string(t.ISO8601().substr(0, 19)) + "Z";
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThh_mm_ssZ: {
std::string timeString = t.ISO8601().substr(0, 19) + "Z";
std::string timeString = std::string(t.ISO8601().substr(0, 19)) + "Z";
replace(timeString.begin(), timeString.end(), ':', '_');
return timeString;
}
@@ -423,7 +423,10 @@ std::string consumeTemporalMetaData(TemporalTileProvider& t, const std::string&
}
try {
t.timeQuantizer.setStartEndRange(start.ISO8601(), end.ISO8601());
t.timeQuantizer.setStartEndRange(
std::string(start.ISO8601()),
std::string(end.ISO8601())
);
t.timeQuantizer.setResolution(timeResolution);
}
catch (const ghoul::RuntimeError& e) {

View File

@@ -137,11 +137,11 @@ std::string RangedTime::clamp(const std::string& checkTime) {
}
}
std::string RangedTime::start() const {
std::string_view RangedTime::start() const {
return _start;
}
std::string RangedTime::end() const {
std::string_view RangedTime::end() const {
return _end;
}
@@ -174,10 +174,14 @@ std::string DateTime::ISO8601() const {
};
double DateTime::J2000() const {
Time t;
std::string timeString = ISO8601();
t.setTime(timeString);
return t.j2000Seconds();
char Buffer[20];
std::memset(Buffer, 0, 20);
fmt::format_to(
Buffer,
"{:0>4}-{:0>2}-{:0>2}T{:0>2}:{:0>2}:{:0>2}",
_year, _month, _day, _hour, _minute, _second
);
return Time::convertTime(Buffer);
}
void DateTime::operator=(DateTime& src) {
@@ -471,7 +475,7 @@ double TimeQuantizer::computeSecondsFromResolution(const int valueIn, const char
bool TimeQuantizer::quantize(Time& t, bool clamp) {
ZoneScoped
const std::string unquantizedStr = t.ISO8601();
std::string_view unquantizedStr = t.ISO8601();
DateTime unquantized(unquantizedStr);
// resolutionFraction helps to improve iteration performance
constexpr const double ResolutionFraction = 0.7;
@@ -514,7 +518,7 @@ bool TimeQuantizer::quantize(Time& t, bool clamp) {
return true;
}
else if (clamp) {
const std::string clampedTime = _timerange.clamp(unquantizedStr);
const std::string clampedTime = _timerange.clamp(std::string(unquantizedStr));
t.setTime(clampedTime);
return true;
}
@@ -612,7 +616,7 @@ std::vector<std::string> TimeQuantizer::quantized(Time& start, Time& end) {
std::vector<std::string> result;
DateTime itr = s;
RangedTime range(start.ISO8601(), end.ISO8601());
RangedTime range(std::string(start.ISO8601()), std::string(end.ISO8601()));
while (range.includes(Time(itr.ISO8601()))) {
itr.incrementOnce(static_cast<int>(_resolutionValue), _resolutionUnit);
result.push_back(itr.ISO8601());

View File

@@ -76,14 +76,14 @@ public:
*
* \returns The ISO8601 date/time string that defines the start of the range
*/
std::string start() const;
std::string_view start() const;
/*
* Get the end date/time of the time range
*
* \returns The ISO8601 date/time string that defines the end of the range
*/
std::string end() const;
std::string_view end() const;
/*
* Set the start date/time of the time range

View File

@@ -63,7 +63,7 @@ namespace {
openspace::gui::CaptionText("Mission Progress");
ImGui::Text("%s", startTime.UTC().c_str());
ImGui::Text("%s", std::string(startTime.UTC()).c_str());
ImGui::SameLine();
float v = static_cast<float>(currentTime);
const float s = static_cast<float>(startTime.j2000Seconds());
@@ -74,10 +74,10 @@ namespace {
&v,
s,
e,
openspace::global::timeManager.time().UTC().c_str()
std::string(openspace::global::timeManager.time().UTC()).c_str()
);
ImGui::SameLine();
ImGui::Text("%s", endTime.UTC().c_str());
ImGui::Text("%s", std::string(endTime.UTC()).c_str());
openspace::gui::CaptionText("Phases");

View File

@@ -211,7 +211,10 @@ void GuiSpaceTimeComponent::render() {
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 10.f);
ImGui::Text("Current Date: %s", global::timeManager.time().UTC().c_str());
ImGui::Text(
"Current Date: %s",
std::string(global::timeManager.time().UTC()).c_str()
);
constexpr int BufferSize = 256;
static char Buffer[BufferSize];
@@ -296,7 +299,7 @@ void GuiSpaceTimeComponent::render() {
const bool nowDay = ImGui::Button("Now");
if (nowDay) {
std::string nowTime = Time::now().UTC();
std::string nowTime = std::string(Time::now().UTC());
// UTC returns a string of the type YYYY MMM DDTHH:mm:ss.xxx
// setTime doesn't like the T in it and wants a space instead
nowTime[11] = ' ';

View File

@@ -269,8 +269,9 @@ std::string IswaManager::iswaUrl(int id, double timestamp, const std::string& ty
}
//std::string t = Time::ref().currentTimeUTC();
std::string t = SpiceManager::ref().dateFromEphemerisTime(timestamp);
std::stringstream ss(t);
std::string_view t = SpiceManager::ref().dateFromEphemerisTime(timestamp);
std::stringstream ss;
ss << t;
std::string token;
std::getline(ss, token, ' ');

View File

@@ -109,7 +109,7 @@ void TimeTopic::sendCurrentTime() {
}
void TimeTopic::sendFullTimeData() {
const std::string currentTime = global::timeManager.time().ISO8601();
std::string_view currentTime = global::timeManager.time().ISO8601();
const double deltaTime = global::timeManager.deltaTime();
const double targetDeltaTime = global::timeManager.targetDeltaTime();
const bool isPaused = global::timeManager.isPaused();

View File

@@ -230,7 +230,7 @@ void DashboardItemInstruments::render(glm::vec2& penPosition) {
ghoul::fontrendering::CrDirection::Down
);
std::string str = SpiceManager::ref().dateFromEphemerisTime(
std::string_view str = SpiceManager::ref().dateFromEphemerisTime(
sequencer.nextCaptureTime(global::timeManager.time().j2000Seconds()),
"YYYY MON DD HR:MN:SC"
);

View File

@@ -112,12 +112,12 @@ ghoul::Dictionary RawVolumeMetadata::dictionary() {
}
if (hasTime) {
std::string timeString = Time(time).ISO8601();
std::string_view timeString = Time(time).ISO8601();
// Do not include time offset in time string
if (timeString.back() == 'Z') {
timeString.pop_back();
timeString = timeString.substr(0, timeString.size() - 1);
}
dict.setValue<std::string>(KeyTime, timeString);
dict.setValue<std::string>(KeyTime, std::string(timeString));
}
return dict;
}

View File

@@ -1057,6 +1057,8 @@ void OpenSpaceEngine::writeSceneDocumentation() {
void OpenSpaceEngine::preSynchronization() {
ZoneScoped
TracyGpuZone("preSynchronization")
LTRACE("OpenSpaceEngine::preSynchronization(begin)");
FileSys.triggerFilesystemEvents();
@@ -1125,6 +1127,7 @@ void OpenSpaceEngine::preSynchronization() {
void OpenSpaceEngine::postSynchronizationPreDraw() {
ZoneScoped
TracyGpuZone("postSynchronizationPreDraw")
LTRACE("OpenSpaceEngine::postSynchronizationPreDraw(begin)");
bool master = global::windowDelegate.isMaster();
@@ -1196,6 +1199,7 @@ void OpenSpaceEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& view
const glm::mat4& projectionMatrix)
{
ZoneScoped
TracyGpuZone("Render")
LTRACE("OpenSpaceEngine::render(begin)");
const bool isGuiWindow =
@@ -1220,6 +1224,7 @@ void OpenSpaceEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& view
void OpenSpaceEngine::drawOverlays() {
ZoneScoped
TracyGpuZone("Draw2D")
LTRACE("OpenSpaceEngine::drawOverlays(begin)");
const bool isGuiWindow =
@@ -1244,6 +1249,7 @@ void OpenSpaceEngine::drawOverlays() {
void OpenSpaceEngine::postDraw() {
ZoneScoped
TracyGpuZone("postDraw")
LTRACE("OpenSpaceEngine::postDraw(begin)");
global::renderEngine.postDraw();

View File

@@ -1132,6 +1132,7 @@ void FramebufferRenderer::updateDownscaledVolume() {
void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFactor) {
ZoneScoped
TracyGpuZone("FramebufferRenderer")
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
@@ -1177,25 +1178,31 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
RendererTasks tasks;
{
TracyGpuZone("Background")
GLDebugGroup group("Background");
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Background);
scene->render(data, tasks);
}
{
TracyGpuZone("Opaque")
GLDebugGroup group("Opaque");
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Opaque);
scene->render(data, tasks);
}
{
TracyGpuZone("PreDeferredTransparent")
GLDebugGroup group("PreDeferredTransparent");
data.renderBinMask = static_cast<int>(Renderable::RenderBin::PreDeferredTransparent);
data.renderBinMask = static_cast<int>(
Renderable::RenderBin::PreDeferredTransparent
);
scene->render(data, tasks);
}
// Run Volume Tasks
{
TracyGpuZone("Raycaster Tasks")
GLDebugGroup group("Raycaster Tasks");
performRaycasterTasks(tasks.raycasterTasks);
@@ -1205,6 +1212,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
}
if (!tasks.deferredcasterTasks.empty()) {
TracyGpuZone("Deferred Caster Tasks")
GLDebugGroup group("Deferred Caster Tasks");
// We use ping pong rendering in order to be able to
@@ -1220,12 +1228,16 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
glEnablei(GL_BLEND, 0);
{
TracyGpuZone("PostDeferredTransparent")
GLDebugGroup group("PostDeferredTransparent");
data.renderBinMask = static_cast<int>(Renderable::RenderBin::PostDeferredTransparent);
data.renderBinMask = static_cast<int>(
Renderable::RenderBin::PostDeferredTransparent
);
scene->render(data, tasks);
}
{
TracyGpuZone("Overlay")
GLDebugGroup group("Overlay");
data.renderBinMask = static_cast<int>(Renderable::RenderBin::Overlay);
scene->render(data, tasks);
@@ -1252,12 +1264,14 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
{
// Apply the selected TMO on the results and resolve the result to the default FBO
TracyGpuZone("Apply TMO")
GLDebugGroup group("Apply TMO");
applyTMO(blackoutFactor);
}
if (_enableFXAA) {
TracyGpuZone("Apply FXAA")
GLDebugGroup group("Apply FXAA");
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
applyFXAA();
@@ -1268,6 +1282,8 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector<RaycasterTask>
ZoneScoped
for (const RaycasterTask& raycasterTask : tasks) {
TracyGpuZone("Raycaster")
VolumeRaycaster* raycaster = raycasterTask.raycaster;
glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer);
@@ -1399,6 +1415,8 @@ void FramebufferRenderer::performDeferredTasks(
ZoneScoped
for (const DeferredcasterTask& deferredcasterTask : tasks) {
TracyGpuZone("Deferredcaster")
Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster;
ghoul::opengl::ProgramObject* deferredcastProgram = nullptr;

View File

@@ -80,7 +80,7 @@ int saveSettingsToProfile(lua_State* L) {
}
const properties::PropertyOwner& root = global::rootPropertyOwner;
std::string currentTime = global::timeManager.time().ISO8601();
std::string currentTime = std::string(global::timeManager.time().ISO8601());
interaction::NavigationHandler::NavigationState navState =
global::navigationHandler.navigationState();
global::profile.saveCurrentSettingsToProfile(root, currentTime, navState);

View File

@@ -43,18 +43,6 @@ namespace {
// as the maximum message length
constexpr const unsigned SpiceErrorBufferSize = 1841;
// This method checks if one of the previous SPICE methods has failed. If it has, an
// exception with the SPICE error message is thrown
// If an error occurred, true is returned, otherwise, false
void throwSpiceError(const std::string& errorMessage) {
if (openspace::SpiceManager::ref().exceptionHandling()) {
char buffer[SpiceErrorBufferSize];
getmsg_c("LONG", SpiceErrorBufferSize, buffer);
reset_c();
throw openspace::SpiceManager::SpiceException(errorMessage + ": " + buffer);
}
}
const char* toString(openspace::SpiceManager::FieldOfViewMethod m) {
using SM = openspace::SpiceManager;
switch (m) {
@@ -196,6 +184,18 @@ SpiceManager& SpiceManager::ref() {
return *_instance;
}
// This method checks if one of the previous SPICE methods has failed. If it has, an
// exception with the SPICE error message is thrown
// If an error occurred, true is returned, otherwise, false
void throwSpiceError(const std::string& errorMessage) {
if (openspace::SpiceManager::ref().exceptionHandling()) {
char buffer[SpiceErrorBufferSize];
getmsg_c("LONG", SpiceErrorBufferSize, buffer);
reset_c();
throw openspace::SpiceManager::SpiceException(errorMessage + ": " + buffer);
}
}
SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) {
ghoul_assert(!filePath.empty(), "Empty file path");
ghoul_assert(
@@ -474,58 +474,20 @@ double SpiceManager::spacecraftClockToET(const std::string& craft, double craftT
double SpiceManager::ephemerisTimeFromDate(const std::string& timeString) const {
ghoul_assert(!timeString.empty(), "Empty timeString");
return ephemerisTimeFromDate(timeString.c_str());
}
double SpiceManager::ephemerisTimeFromDate(const char* timeString) const {
ghoul_assert(!timeString.empty(), "Empty timeString");
double et;
str2et_c(timeString.c_str(), &et);
str2et_c(timeString, &et);
if (failed_c()) {
throwSpiceError(fmt::format("Error converting date '{}'", timeString));
}
return et;
}
std::string SpiceManager::dateFromEphemerisTime(double ephemerisTime,
std::string_view format) const
{
ghoul_assert(!formatString.empty(), "Format is empty");
ghoul_assert(formatString.back() == '\0', "Format string must be null-terminated");
if (format.size() < 32) {
constexpr const int BufferSize = 32;
SpiceChar buffer[BufferSize];
dateFromEphemerisTime(ephemerisTime, buffer, BufferSize, format);
return std::string(buffer);
}
else if (format.size() < 256) {
constexpr const int BufferSize = 256;
SpiceChar buffer[BufferSize];
dateFromEphemerisTime(ephemerisTime, buffer, BufferSize, format);
return std::string(buffer);
}
else {
std::string res;
res.resize(format.size() + 1);
dateFromEphemerisTime(ephemerisTime, res.data(), format.size(), format);
return res;
}
}
void SpiceManager::dateFromEphemerisTime(double ephemerisTime, char* outBuf,
int bufferSize,
std::string_view formatString) const
{
ghoul_assert(!formatString.empty(), "Format is empty");
ghoul_assert(formatString.back() == '\0', "Format string must be null-terminated");
ghoul_assert(formatString.size() > bufferSize - 1, "Buffer size too small");
timout_c(ephemerisTime, formatString.data(), bufferSize - 1, outBuf);
if (failed_c()) {
throwSpiceError(
fmt::format("Error converting ephemeris time '{}' to date with format '{}'",
ephemerisTime, formatString
)
);
}
}
glm::dvec3 SpiceManager::targetPosition(const std::string& target,
const std::string& observer,
const std::string& referenceFrame,

View File

@@ -24,7 +24,9 @@
#include <openspace/util/time.h>
#include <openspace/engine/globals.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/util/memorymanager.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/syncbuffer.h>
#include <openspace/util/timemanager.h>
@@ -43,6 +45,10 @@ double Time::convertTime(const std::string& time) {
return SpiceManager::ref().ephemerisTimeFromDate(time);
}
double Time::convertTime(const char* time) {
return SpiceManager::ref().ephemerisTimeFromDate(time);
}
Time::Time(double secondsJ2000) : _time(secondsJ2000) {}
Time::Time(const std::string& time) :
@@ -79,17 +85,26 @@ void Time::setTime(const std::string& time) {
_time = SpiceManager::ref().ephemerisTimeFromDate(time);
}
std::string Time::UTC() const {
return SpiceManager::ref().dateFromEphemerisTime(_time);
std::string_view Time::UTC() const {
constexpr const char Format[] = "YYYY MON DDTHR:MN:SC.### ::RND";
char* b = reinterpret_cast<char*>(global::memoryManager.TemporaryMemory.allocate(32));
std::memset(b, 0, 32);
SpiceManager::ref().dateFromEphemerisTime(_time, b, 32, Format);
return std::string_view(b, 32);
}
std::string Time::ISO8601() const {
std::string_view Time::ISO8601() const {
ZoneScoped
return SpiceManager::ref().dateFromEphemerisTime(
_time,
"YYYY-MM-DDTHR:MN:SC.###"
);
constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SC.###";
char* b = reinterpret_cast<char*>(global::memoryManager.TemporaryMemory.allocate(24));
std::memset(b, 0, 24);
SpiceManager::ref().dateFromEphemerisTime(_time, b, 24, Format);
return std::string_view(b, 24);
}
scripting::LuaLibrary Time::luaLibrary() {

View File

@@ -506,7 +506,7 @@ int time_interpolateTimeRelative(lua_State* L) {
* It is returned by calling the Time::currentTime method.
*/
int time_currentTime(lua_State* L) {
lua_pushnumber(L, global::timeManager.time().j2000Seconds());
ghoul::lua::push(L, global::timeManager.time().j2000Seconds());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}
@@ -518,7 +518,7 @@ int time_currentTime(lua_State* L) {
* timezone by calling the Time::UTC method
*/
int time_currentTimeUTC(lua_State* L) {
lua_pushstring(L, global::timeManager.time().UTC().c_str());
ghoul::lua::push(L, global::timeManager.time().UTC());
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
return 1;
}