Move OpenGL in globebrowsing from constructors into initialization functions

Place entire scene loading into separate thread
This commit is contained in:
Alexander Bock
2017-11-03 16:25:06 -04:00
parent 735d6378d9
commit b886925616
16 changed files with 176 additions and 62 deletions

View File

@@ -259,17 +259,24 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
addPropertySubOwner(_layerManager.get());
//addPropertySubOwner(_pointGlobe.get());
}
void RenderableGlobe::initializeGL() {
_layerManager->initialize();
_layerManager->update();
_distanceSwitch.initializeGL();
// Recompile the shaders directly so that it is not done the first time the render
// function is called.
_chunkedLodGlobe->recompileShaders();
}
void RenderableGlobe::initializeGL() {
_distanceSwitch.initializeGL();
}
void RenderableGlobe::deinitializeGL() {
_distanceSwitch.deinitializeGL();
_layerManager->deinitialize();
}
bool RenderableGlobe::isReady() const {

View File

@@ -38,7 +38,7 @@ namespace openspace::globebrowsing {
ChunkRenderer::ChunkRenderer(std::shared_ptr<Grid> grid,
std::shared_ptr<LayerManager> layerManager)
: _grid(grid)
,_layerManager(layerManager)
, _layerManager(layerManager)
{
_globalLayerShaderManager = std::make_shared<LayerShaderManager>(
"GlobalChunkedLodPatch",

View File

@@ -219,6 +219,18 @@ Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
addPropertySubOwner(_layerAdjustment);
}
void Layer::initialize() {
if (_tileProvider) {
_tileProvider->initialize();
}
}
void Layer::deinitialize() {
if (_tileProvider) {
_tileProvider->deinitialize();
}
}
ChunkTilePile Layer::getChunkTilePile(const TileIndex& tileIndex, int pileSize) const {
if (_tileProvider) {
return _tileProvider->getChunkTilePile(tileIndex, pileSize);

View File

@@ -55,6 +55,9 @@ public:
Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict, LayerGroup& parent);
void initialize();
void deinitialize();
ChunkTilePile getChunkTilePile(const TileIndex& tileIndex, int pileSize) const;
Tile::Status getTileStatus(const TileIndex& index) const;

View File

@@ -79,6 +79,18 @@ LayerGroup::LayerGroup(layergroupid::GroupID id, const ghoul::Dictionary& dict)
}
}
void LayerGroup::initialize() {
for (const std::shared_ptr<Layer>& l : _layers) {
l->initialize();
}
}
void LayerGroup::deinitialize() {
for (const std::shared_ptr<Layer>& l : _layers) {
l->deinitialize();
}
}
void LayerGroup::update() {
_activeLayers.clear();
@@ -102,7 +114,7 @@ void LayerGroup::addLayer(const ghoul::Dictionary& layerDict) {
}
else {
_layers.push_back(layer);
update();
//update();
if (_onChangeCallback) {
_onChangeCallback();
}

View File

@@ -46,6 +46,9 @@ struct LayerGroup : public properties::PropertyOwner {
LayerGroup(layergroupid::GroupID id);
LayerGroup(layergroupid::GroupID id, const ghoul::Dictionary& dict);
void initialize();
void deinitialize();
/// Updates all layers tile providers within this group
void update();

View File

@@ -68,6 +68,18 @@ LayerManager::LayerManager(const ghoul::Dictionary& layerGroupsDict)
}
}
void LayerManager::initialize() {
for (const std::shared_ptr<LayerGroup>& lg : _layerGroups) {
lg->initialize();
}
}
void LayerManager::deinitialize() {
for (const std::shared_ptr<LayerGroup>& lg : _layerGroups) {
lg->deinitialize();
}
}
void LayerManager::addLayer(layergroupid::GroupID groupId, ghoul::Dictionary layerDict) {
ghoul_assert(groupId != layergroupid::Unknown, "Layer group ID must be known");
_layerGroups[groupId]->addLayer(layerDict);

View File

@@ -45,6 +45,9 @@ class LayerManager : public properties::PropertyOwner {
public:
LayerManager(const ghoul::Dictionary& textureCategoriesDictionary);
void initialize();
void deinitialize();
void addLayer(layergroupid::GroupID groupId, ghoul::Dictionary layerDict);
void deleteLayer(layergroupid::GroupID groupId, std::string layerName);

View File

@@ -84,15 +84,10 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
if (hasStart && hasEnd) {
const std::string start = dictionary.value<std::string>(KeyPreCacheStartTime);
const std::string end = dictionary.value<std::string>(KeyPreCacheEndTime);
std::vector<Time> preCacheTimes = _timeQuantizer.quantized(
_preCacheTimes = _timeQuantizer.quantized(
Time(Time::convertTime(start)),
Time(Time::convertTime(end))
);
LINFO("Preloading: " << _filePath.value());
for (const Time& t : preCacheTimes) {
getTileProvider(t);
}
}
_successfulInitialization = true;
}
@@ -102,6 +97,21 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
}
}
bool TemporalTileProvider::initialize() {
bool success = TileProvider::initialize();
if (!_preCacheTimes.empty()) {
LINFO("Preloading: " << _filePath.value());
for (const Time& t : _preCacheTimes) {
getTileProvider(t);
}
_preCacheTimes.clear();
}
return success;
}
bool TemporalTileProvider::readFilePath() {
std::ifstream in(_filePath.value().c_str());
std::string xml;
@@ -295,6 +305,7 @@ std::shared_ptr<TileProvider> TemporalTileProvider::getTileProvider(
}
else {
std::shared_ptr<TileProvider> tileProvider = initTileProvider(timekey);
tileProvider->initialize();
_tileProviderMap[timekey] = tileProvider;
return tileProvider;

View File

@@ -200,6 +200,8 @@ public:
*/
TemporalTileProvider(const ghoul::Dictionary& dictionary);
bool initialize() override;
// These methods implements the TileProvider interface
virtual Tile getTile(const TileIndex& tileIndex) override;
@@ -329,6 +331,9 @@ private:
TimeFormat* _timeFormat;
TimeQuantizer _timeQuantizer;
std::vector<Time> _preCacheTimes;
bool _successfulInitialization;
};

View File

@@ -47,16 +47,27 @@ TextTileProvider::TextTileProvider(const TileTextureInitData& initData, size_t f
, _fontSize(fontSize)
{
_tileCache = OsEng.moduleEngine().module<GlobeBrowsingModule>()->tileCache();
_font = OsEng.fontManager().font("Mono", static_cast<float>(_fontSize));
_fontRenderer = std::unique_ptr<FontRenderer>(FontRenderer::createDefault());
_fontRenderer->setFramebufferSize(glm::vec2(_initData.dimensions()));
glGenFramebuffers(1, &_fbo);
}
TextTileProvider::~TextTileProvider() {
TextTileProvider::~TextTileProvider() {}
bool TextTileProvider::initialize() {
bool res = TileProvider::initialize();
_font = OsEng.fontManager().font("Mono", static_cast<float>(_fontSize));
_fontRenderer = std::unique_ptr<FontRenderer>(FontRenderer::createDefault());
_fontRenderer->setFramebufferSize(glm::vec2(_initData.dimensions()));
glGenFramebuffers(1, &_fbo);
return res;
}
bool TextTileProvider::deinitialize() {
glDeleteFramebuffers(1, &_fbo);
return TileProvider::deinitialize();
}
Tile TextTileProvider::getTile(const TileIndex& tileIndex) {

View File

@@ -53,6 +53,9 @@ public:
TextTileProvider(const TileTextureInitData& initData, size_t fontSize = 48);
virtual ~TextTileProvider() override;
bool initialize() override;
bool deinitialize() override;
// The TileProvider interface below is implemented in this class
virtual Tile getTile(const TileIndex& tileIndex) override;
virtual Tile::Status getTileStatus(const TileIndex& index) override;

View File

@@ -55,17 +55,13 @@ TileProvider::TileProvider()
: properties::PropertyOwner({ "tileProvider" })
, _initialized(false)
, _defaultTile(nullptr, nullptr, Tile::Status::Unavailable)
{
initialize();
}
{}
TileProvider::TileProvider(const ghoul::Dictionary&)
: properties::PropertyOwner({ "tileProvider" })
, _initialized(false)
, _defaultTile(nullptr, nullptr, Tile::Status::Unavailable)
{
initialize();
}
{}
float TileProvider::noDataValueAsFloat() {
ghoul_assert(_initialized, "TileProvider was not initialized.");

View File

@@ -111,6 +111,24 @@ TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) {
}
}
bool TileProviderByLevel::initialize() {
bool success = TileProvider::initialize();
for (const std::shared_ptr<TileProvider>& tp : _levelTileProviders) {
success &= tp->initialize();
}
return success;
}
bool TileProviderByLevel::deinitialize() {
bool success = true;
for (const std::shared_ptr<TileProvider>& tp : _levelTileProviders) {
success &= tp->deinitialize();
}
return TileProvider::deinitialize() && success;
}
Tile TileProviderByLevel::getTile(const TileIndex& tileIndex) {
TileProvider* provider = levelProvider(tileIndex.level);
if (provider) {

View File

@@ -37,6 +37,9 @@ public:
TileProviderByLevel(const std::string& imagePath);
virtual ~TileProviderByLevel() = default;
bool initialize() override;
bool deinitialize() override;
virtual Tile getTile(const TileIndex& tileIndex) override;
virtual Tile::Status getTileStatus(const TileIndex& index) override;
virtual TileDepthTransform depthTransform() override;

View File

@@ -577,50 +577,61 @@ void OpenSpaceEngine::loadScene(const std::string& scenePath) {
}
Scene* scene;
try {
scene = _sceneManager->loadScene(scenePath);
} catch (const ghoul::FileNotFoundError& e) {
LERRORC(e.component, e.message);
return;
} catch (const Scene::InvalidSceneError& e) {
LERRORC(e.component, e.message);
return;
} catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
return;
}
catch (const std::exception& e) {
LERROR(e.what());
return;
}
catch (...) {
LERROR("Unknown error loading the scene");
return;
}
Scene* previousScene = _renderEngine->scene();
if (previousScene) {
_syncEngine->removeSyncables(_timeManager->getSyncables());
_syncEngine->removeSyncables(_renderEngine->getSyncables());
_syncEngine->removeSyncable(_scriptEngine.get());
_renderEngine->setScene(nullptr);
_renderEngine->setCamera(nullptr);
_sceneManager->unloadScene(*previousScene);
}
// Initialize the RenderEngine
_renderEngine->setScene(scene);
_renderEngine->setCamera(scene->camera());
_renderEngine->setGlobalBlackOutFactor(0.0);
_renderEngine->startFading(1, 3.0);
_loadingScreen = std::make_unique<LoadingScreen>();
// We can initialize all SceneGraphNodes in a separate thread since none of them use
// an OpenGL context
std::atomic_bool initializeFinished = false;
std::thread t([scene, &initializeFinished, this]() {
bool errorWhileLoading = false;
std::thread t([&scene, scenePath, &initializeFinished, &errorWhileLoading, this]() {
try {
scene = _sceneManager->loadScene(scenePath);
}
catch (const ghoul::FileNotFoundError& e) {
LERRORC(e.component, e.message);
errorWhileLoading = true;
return;
}
catch (const Scene::InvalidSceneError& e) {
LERRORC(e.component, e.message);
errorWhileLoading = true;
return;
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
errorWhileLoading = true;
return;
}
catch (const std::exception& e) {
LERROR(e.what());
errorWhileLoading = true;
return;
}
catch (...) {
LERROR("Unknown error loading the scene");
errorWhileLoading = true;
return;
}
Scene* previousScene = _renderEngine->scene();
if (previousScene) {
_syncEngine->removeSyncables(_timeManager->getSyncables());
_syncEngine->removeSyncables(_renderEngine->getSyncables());
_syncEngine->removeSyncable(_scriptEngine.get());
_renderEngine->setScene(nullptr);
_renderEngine->setCamera(nullptr);
_sceneManager->unloadScene(*previousScene);
}
// Initialize the RenderEngine
_renderEngine->setScene(scene);
_renderEngine->setCamera(scene->camera());
_renderEngine->setGlobalBlackOutFactor(0.0);
_renderEngine->startFading(1, 3.0);
scene->initialize();
postLoadingScreenMessage("Finished initializing");
initializeFinished = true;
@@ -638,6 +649,10 @@ void OpenSpaceEngine::loadScene(const std::string& scenePath) {
t.join();
_loadingScreen = nullptr;
if (errorWhileLoading) {
return;
}
scene->initializeGL();
// Update the scene so that position of objects are set in case they are used in