From 0399795d42e12fd2bf65a9910a406804ba2ed5a4 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Thu, 7 Jul 2016 17:17:12 -0400 Subject: [PATCH 1/4] Prevent program crash when unable to open dataset --- modules/globebrowsing/tile/tiledataset.cpp | 2 +- modules/globebrowsing/tile/tiledataset.h | 4 +--- modules/globebrowsing/tile/tileproviderfactory.cpp | 14 +++++++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/modules/globebrowsing/tile/tiledataset.cpp b/modules/globebrowsing/tile/tiledataset.cpp index e10851a9cf..4563dadd09 100644 --- a/modules/globebrowsing/tile/tiledataset.cpp +++ b/modules/globebrowsing/tile/tiledataset.cpp @@ -210,7 +210,7 @@ namespace openspace { result->dimensions = glm::uvec3(io.write.region.numPixels, 1); result->nBytesImageData = io.write.totalNumBytes; - if (_doPreprocessing) { + if (_config.doPreProcessing) { result->preprocessData = preprocess(result, io.write.region); result->error = std::max(result->error, postProcessErrorCheck(result, io)); } diff --git a/modules/globebrowsing/tile/tiledataset.h b/modules/globebrowsing/tile/tiledataset.h index 0d078b19d9..f49c5b117f 100644 --- a/modules/globebrowsing/tile/tiledataset.h +++ b/modules/globebrowsing/tile/tiledataset.h @@ -121,7 +121,7 @@ namespace openspace { ////////////////////////////////////////////////////////////////////////////////// // Initialization // - //////////////////////////////////////////////////////////////////////////////////\ + ////////////////////////////////////////////////////////////////////////////////// void initialize(); void ensureInitialized(); @@ -181,8 +181,6 @@ namespace openspace { TileDepthTransform _depthTransform; TileDataLayout _dataLayout; - bool _doPreprocessing; - static bool GdalHasBeenInitialized; bool hasBeenInitialized; }; diff --git a/modules/globebrowsing/tile/tileproviderfactory.cpp b/modules/globebrowsing/tile/tileproviderfactory.cpp index d6a6c3f0fe..93dc9f9e06 100644 --- a/modules/globebrowsing/tile/tileproviderfactory.cpp +++ b/modules/globebrowsing/tile/tileproviderfactory.cpp @@ -62,7 +62,19 @@ namespace openspace { LERROR("Unknown type: " << type); return nullptr; } - return concreteFactoryIterator->second(desc, initData); + + std::shared_ptr tileProvider; + + try { + tileProvider = concreteFactoryIterator->second(desc, initData); + } + catch (const std::exception& e) { + LERROR(e.what()); + } + catch (...) { + LERROR("Could not open dataset:\n" << desc << "\n"); + } + return tileProvider; } void TileProviderFactory::initialize() { From 67a18c723deed3e4a3f6a9517e5ba9959c2922af Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Thu, 7 Jul 2016 19:45:00 -0400 Subject: [PATCH 2/4] Add method to create empty tile --- modules/globebrowsing/tile/tiledataset.cpp | 29 +++++++++++++++++++--- modules/globebrowsing/tile/tiledataset.h | 8 ++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/modules/globebrowsing/tile/tiledataset.cpp b/modules/globebrowsing/tile/tiledataset.cpp index 4563dadd09..6b1d08fced 100644 --- a/modules/globebrowsing/tile/tiledataset.cpp +++ b/modules/globebrowsing/tile/tiledataset.cpp @@ -119,10 +119,11 @@ namespace openspace { const glm::ivec2 TileDataset::tilePixelSizeDifference = glm::ivec2(4); const PixelRegion TileDataset::padding = PixelRegion(tilePixelStartOffset, tilePixelSizeDifference); - - + bool TileDataset::GdalHasBeenInitialized = false; + + TileDataset::TileDataset(const std::string& gdalDatasetDesc, const Configuration& config) : _config(config) , hasBeenInitialized(false) @@ -202,7 +203,7 @@ namespace openspace { IODescription io = getIODescription(chunkIndex); CPLErr worstError = CPLErr::CE_None; - // Build the Tile IO Result from the data we queried + // Build the Tile IO Result from the data we queride std::shared_ptr result = std::make_shared(); result->imageData = readImageData(io, worstError); result->error = worstError; @@ -218,6 +219,28 @@ namespace openspace { return result; } + + std::shared_ptr TileDataset::defaultTileData() { + ensureInitialized(); + PixelRegion pixelRegion = { PixelCoordinate(0, 0), PixelRange(16, 16) }; + std::shared_ptr result = std::make_shared(); + result->chunkIndex = { 0, 0, 0 }; + result->dimensions = glm::uvec3(pixelRegion.numPixels, 1); + result->nBytesImageData = result->dimensions.x * result->dimensions.y * _dataLayout.bytesPerPixel; + result->imageData = new char[result->nBytesImageData]; + for (size_t i = 0; i < result->nBytesImageData; ++i) { + result->imageData[i] = 0; + } + result->error = CPLErr::CE_None; + + if (_config.doPreProcessing) { + result->preprocessData = preprocess(result, pixelRegion); + //result->error = std::max(result->error, postProcessErrorCheck(result, io)); + } + + return result; + } + int TileDataset::maxChunkLevel() { ensureInitialized(); if (_cached._maxLevel < 0) { diff --git a/modules/globebrowsing/tile/tiledataset.h b/modules/globebrowsing/tile/tiledataset.h index f49c5b117f..0f5d9abf17 100644 --- a/modules/globebrowsing/tile/tiledataset.h +++ b/modules/globebrowsing/tile/tiledataset.h @@ -106,15 +106,18 @@ namespace openspace { // Public interface // ////////////////////////////////////////////////////////////////////////////////// std::shared_ptr readTileData(ChunkIndex chunkIndex); + std::shared_ptr defaultTileData(); int maxChunkLevel(); - TileDepthTransform getDepthTransform() ; - const TileDataLayout& getDataLayout() ; + TileDepthTransform getDepthTransform(); + const TileDataLayout& getDataLayout(); const static glm::ivec2 tilePixelStartOffset; const static glm::ivec2 tilePixelSizeDifference; const static PixelRegion padding; // same as the two above + + private: @@ -132,6 +135,7 @@ namespace openspace { ////////////////////////////////////////////////////////////////////////////////// // GDAL helper methods // ////////////////////////////////////////////////////////////////////////////////// + void gdalEnsureInitialized(); GDALDataset* gdalDataset(const std::string& gdalDatasetDesc); bool gdalHasOverviews() const; From cb7845673951674a87fb1653a6a43292933b58d1 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Fri, 8 Jul 2016 12:30:19 -0400 Subject: [PATCH 3/4] Enable getting a default tile from TileProviders. Used e.g. when no tiles are in memory --- modules/globebrowsing/chunk/chunkrenderer.cpp | 6 +-- .../shaders/globalchunkedlodpatch_fs.glsl | 1 + .../tile/temporaltileprovider.cpp | 43 ++++++++----------- .../globebrowsing/tile/temporaltileprovider.h | 3 ++ modules/globebrowsing/tile/tiledataset.h | 3 -- modules/globebrowsing/tile/tileprovider.cpp | 20 +++++++-- modules/globebrowsing/tile/tileprovider.h | 7 ++- modules/globebrowsing/tile/tileselector.cpp | 3 +- 8 files changed, 50 insertions(+), 36 deletions(-) diff --git a/modules/globebrowsing/chunk/chunkrenderer.cpp b/modules/globebrowsing/chunk/chunkrenderer.cpp index c9f691e649..f56f9293e9 100644 --- a/modules/globebrowsing/chunk/chunkrenderer.cpp +++ b/modules/globebrowsing/chunk/chunkrenderer.cpp @@ -218,9 +218,9 @@ namespace openspace { // Get the texture that should be used for rendering TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(tileProvider, chunkIndex); if (tileAndTransform.tile.status == Tile::Status::Unavailable) { - // don't render if no tile was available - programObject->deactivate(); - return nullptr; + tileAndTransform.tile = tileProvider->getDefaultTile(); + tileAndTransform.uvTransform.uvOffset = { 0, 0 }; + tileAndTransform.uvTransform.uvScale = { 1, 1 }; } activateTileAndSetTileUniforms( diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index ef91f7d753..0d3c8c69d0 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -157,6 +157,7 @@ Fragment getFragment() { frag.depth = fs_position.w; + return frag; } diff --git a/modules/globebrowsing/tile/temporaltileprovider.cpp b/modules/globebrowsing/tile/temporaltileprovider.cpp index 604e09250e..0cb19c2f6e 100644 --- a/modules/globebrowsing/tile/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/temporaltileprovider.cpp @@ -109,48 +109,43 @@ namespace openspace { } TileDepthTransform TemporalTileProvider::depthTransform() { - if (_currentTileProvider == nullptr) { - LDEBUG("Warning: had to call update from depthTransform()"); - update(); - } - + ensureUpdated(); return _currentTileProvider->depthTransform(); } Tile::Status TemporalTileProvider::getTileStatus(const ChunkIndex& chunkIndex) { - if (_currentTileProvider == nullptr) { - LDEBUG("Warning: had to call update from getTileStatus()"); - update(); - } - + ensureUpdated(); return _currentTileProvider->getTileStatus(chunkIndex); } Tile TemporalTileProvider::getTile(const ChunkIndex& chunkIndex) { - if (_currentTileProvider == nullptr) { - LDEBUG("Warning: had to call update from getTile()"); - update(); - } - + ensureUpdated(); return _currentTileProvider->getTile(chunkIndex); } + Tile TemporalTileProvider::getDefaultTile() { + ensureUpdated(); + return _currentTileProvider->getDefaultTile(); + } + int TemporalTileProvider::maxLevel() { + ensureUpdated(); + return _currentTileProvider->maxLevel(); + } + + void TemporalTileProvider::ensureUpdated() { + if (_currentTileProvider == nullptr) { + LDEBUG("Warning: update was done lazily"); + update(); + } + } + void TemporalTileProvider::update() { _currentTileProvider = getTileProvider(); _currentTileProvider->update(); } - int TemporalTileProvider::maxLevel() { - if (_currentTileProvider == nullptr) { - LDEBUG("Warning: had to call update from getAsyncTileReader()"); - update(); - } - - return _currentTileProvider->maxLevel(); - } - std::shared_ptr TemporalTileProvider::getTileProvider(Time t) { Time tCopy(t); diff --git a/modules/globebrowsing/tile/temporaltileprovider.h b/modules/globebrowsing/tile/temporaltileprovider.h index a4dde01dcc..956afe860e 100644 --- a/modules/globebrowsing/tile/temporaltileprovider.h +++ b/modules/globebrowsing/tile/temporaltileprovider.h @@ -121,6 +121,7 @@ namespace openspace { // These methods implements TileProvider virtual Tile getTile(const ChunkIndex& chunkIndex); + virtual Tile getDefaultTile(); virtual Tile::Status getTileStatus(const ChunkIndex& chunkIndex); virtual TileDepthTransform depthTransform(); virtual void update(); @@ -148,6 +149,8 @@ namespace openspace { std::string consumeTemporalMetaData(const std::string &xml); std::string getXMLValue(CPLXMLNode*, const std::string& key, const std::string& defaultVal); + void ensureUpdated(); + ////////////////////////////////////////////////////////////////////////////////// // Members variables // ////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/globebrowsing/tile/tiledataset.h b/modules/globebrowsing/tile/tiledataset.h index 0f5d9abf17..021d3e0c54 100644 --- a/modules/globebrowsing/tile/tiledataset.h +++ b/modules/globebrowsing/tile/tiledataset.h @@ -116,9 +116,6 @@ namespace openspace { const static glm::ivec2 tilePixelSizeDifference; const static PixelRegion padding; // same as the two above - - - private: diff --git a/modules/globebrowsing/tile/tileprovider.cpp b/modules/globebrowsing/tile/tileprovider.cpp index fe8be9b6b1..1ee95a1fea 100644 --- a/modules/globebrowsing/tile/tileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider.cpp @@ -65,6 +65,11 @@ namespace openspace { return _tile; } + Tile SingleImagePrivoder::getDefaultTile() { + return _tile; + } + + Tile::Status SingleImagePrivoder::getTileStatus(const ChunkIndex& index) { return _tile.status; } @@ -99,7 +104,7 @@ namespace openspace { , _framesUntilRequestFlush(framesUntilFlushRequestQueue) , _framesSinceLastRequestFlush(0) { - + _defaultTile = createTile(_asyncTextureDataProvider->getTextureDataProvider()->defaultTileData()); } @@ -140,10 +145,17 @@ namespace openspace { return tile; } + Tile CachingTileProvider::getDefaultTile() { + return _defaultTile; + } + + void CachingTileProvider::initTexturesFromLoadedData() { while (_asyncTextureDataProvider->hasLoadedTextureData()) { std::shared_ptr tileIOResult = _asyncTextureDataProvider->nextTileIOResult(); - initializeAndAddToCache(tileIOResult); + ChunkHashKey key = tileIOResult->chunkIndex.hashKey(); + Tile tile = createTile(tileIOResult); + _tileCache->put(key, tile); } } @@ -184,7 +196,7 @@ namespace openspace { } - void CachingTileProvider::initializeAndAddToCache(std::shared_ptr tileIOResult) { + Tile CachingTileProvider::createTile(std::shared_ptr tileIOResult) { ChunkHashKey key = tileIOResult->chunkIndex.hashKey(); TileDataLayout dataLayout = _asyncTextureDataProvider->getTextureDataProvider()->getDataLayout(); Texture* texturePtr = new Texture( @@ -209,7 +221,7 @@ namespace openspace { tileIOResult->error == CE_None ? Tile::Status::OK : Tile::Status::IOError }; - _tileCache->put(key, tile); + return tile; } diff --git a/modules/globebrowsing/tile/tileprovider.h b/modules/globebrowsing/tile/tileprovider.h index af0a43c997..37b9cc597c 100644 --- a/modules/globebrowsing/tile/tileprovider.h +++ b/modules/globebrowsing/tile/tileprovider.h @@ -68,6 +68,7 @@ namespace openspace { virtual ~TileProvider() { } virtual Tile getTile(const ChunkIndex& chunkIndex) = 0; + virtual Tile getDefaultTile() = 0; virtual Tile::Status getTileStatus(const ChunkIndex& index) = 0; virtual TileDepthTransform depthTransform() = 0; virtual void update() = 0; @@ -84,6 +85,7 @@ namespace openspace { virtual ~SingleImagePrivoder() { } virtual Tile getTile(const ChunkIndex& chunkIndex); + virtual Tile getDefaultTile(); virtual Tile::Status getTileStatus(const ChunkIndex& index); virtual TileDepthTransform depthTransform(); virtual void update(); @@ -110,6 +112,7 @@ namespace openspace { virtual ~CachingTileProvider(); virtual Tile getTile(const ChunkIndex& chunkIndex); + virtual Tile getDefaultTile(); virtual Tile::Status getTileStatus(const ChunkIndex& index); virtual TileDepthTransform depthTransform(); virtual void update(); @@ -130,7 +133,8 @@ namespace openspace { /** Creates an OpenGL texture and pushes the data to the GPU. */ - void initializeAndAddToCache(std::shared_ptr uninitedTexture); + + Tile createTile(std::shared_ptr res); void clearRequestQueue(); @@ -143,6 +147,7 @@ namespace openspace { ////////////////////////////////////////////////////////////////////////////////// std::shared_ptr _tileCache; + Tile _defaultTile; int _framesSinceLastRequestFlush; int _framesUntilRequestFlush; diff --git a/modules/globebrowsing/tile/tileselector.cpp b/modules/globebrowsing/tile/tileselector.cpp index b537334bbc..1fd10d387f 100644 --- a/modules/globebrowsing/tile/tileselector.cpp +++ b/modules/globebrowsing/tile/tileselector.cpp @@ -66,7 +66,8 @@ namespace openspace { } else return { tile, uvTransform }; } - return {Tile::TileUnavailable, uvTransform}; + + return{ Tile::TileUnavailable, uvTransform }; } void TileSelector::ascendToParent(ChunkIndex& chunkIndex, TileUvTransform& uv) { From 35347b2d8d264e4dacb9cac1dc284ee3c5bf9332 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Fri, 8 Jul 2016 12:46:46 -0400 Subject: [PATCH 4/4] Lazy init default tiles. Make TemporalTileProviders only use one default tile --- modules/globebrowsing/tile/temporaltileprovider.cpp | 4 ++-- modules/globebrowsing/tile/temporaltileprovider.h | 2 ++ modules/globebrowsing/tile/tileprovider.cpp | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/globebrowsing/tile/temporaltileprovider.cpp b/modules/globebrowsing/tile/temporaltileprovider.cpp index 0cb19c2f6e..d6fc22a713 100644 --- a/modules/globebrowsing/tile/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/temporaltileprovider.cpp @@ -64,6 +64,7 @@ namespace openspace { // read file std::string xml( (std::istreambuf_iterator(in)), (std::istreambuf_iterator())); _gdalXmlTemplate = consumeTemporalMetaData(xml); + _defaultTile = getTileProvider()->getDefaultTile(); } std::string TemporalTileProvider::consumeTemporalMetaData(const std::string& xml) { @@ -124,8 +125,7 @@ namespace openspace { } Tile TemporalTileProvider::getDefaultTile() { - ensureUpdated(); - return _currentTileProvider->getDefaultTile(); + return _defaultTile; } diff --git a/modules/globebrowsing/tile/temporaltileprovider.h b/modules/globebrowsing/tile/temporaltileprovider.h index 956afe860e..c526c9e37b 100644 --- a/modules/globebrowsing/tile/temporaltileprovider.h +++ b/modules/globebrowsing/tile/temporaltileprovider.h @@ -161,6 +161,8 @@ namespace openspace { std::unordered_map > _tileProviderMap; TileProviderInitData _tileProviderInitData; + Tile _defaultTile; + std::shared_ptr _currentTileProvider; TimeFormat * _timeFormat; diff --git a/modules/globebrowsing/tile/tileprovider.cpp b/modules/globebrowsing/tile/tileprovider.cpp index 1ee95a1fea..e1381d5424 100644 --- a/modules/globebrowsing/tile/tileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider.cpp @@ -104,7 +104,7 @@ namespace openspace { , _framesUntilRequestFlush(framesUntilFlushRequestQueue) , _framesSinceLastRequestFlush(0) { - _defaultTile = createTile(_asyncTextureDataProvider->getTextureDataProvider()->defaultTileData()); + } @@ -146,6 +146,9 @@ namespace openspace { } Tile CachingTileProvider::getDefaultTile() { + if (_defaultTile.texture == nullptr) { + _defaultTile = createTile(_asyncTextureDataProvider->getTextureDataProvider()->defaultTileData()); + } return _defaultTile; }