/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2016 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include #include #include #include #include #include #include #include #include #include namespace { const std::string _loggerCat = "TileProvider"; } namespace openspace { const Tile Tile::TileUnavailable = {nullptr, nullptr, Tile::Status::Unavailable }; CachingTileProvider::CachingTileProvider(std::shared_ptr tileReader, std::shared_ptr tileCache, int framesUntilFlushRequestQueue) : _asyncTextureDataProvider(tileReader) , _tileCache(tileCache) , _framesSinceLastRequestFlush(0) { } CachingTileProvider::~CachingTileProvider(){ clearRequestQueue(); } void CachingTileProvider::prerender() { initTexturesFromLoadedData(); if (_framesSinceLastRequestFlush++ > _framesUntilRequestFlush) { clearRequestQueue(); } } std::shared_ptr CachingTileProvider::getAsyncTileReader() { return _asyncTextureDataProvider; } Tile CachingTileProvider::getTile(const ChunkIndex& chunkIndex) { Tile tile = Tile::TileUnavailable; auto tileDataset = _asyncTextureDataProvider->getTextureDataProvider(); if (chunkIndex.level > tileDataset->getMaximumLevel()) { tile.status = Tile::Status::OutOfRange; return tile; } HashKey key = chunkIndex.hashKey(); if (_tileCache->exist(key)) { return _tileCache->get(key); } else { _asyncTextureDataProvider->enqueueTextureData(chunkIndex); } return tile; } void CachingTileProvider::initTexturesFromLoadedData() { while (_asyncTextureDataProvider->hasLoadedTextureData()) { std::shared_ptr tileIOResult = _asyncTextureDataProvider->nextTileIOResult(); initializeAndAddToCache(tileIOResult); } } void CachingTileProvider::clearRequestQueue() { _asyncTextureDataProvider->clearRequestQueue(); _framesSinceLastRequestFlush = 0; } Tile::Status CachingTileProvider::getTileStatus(const ChunkIndex& chunkIndex) { auto tileDataset = _asyncTextureDataProvider->getTextureDataProvider(); if (chunkIndex.level > tileDataset->getMaximumLevel()) { return Tile::Status::OutOfRange; } HashKey key = chunkIndex.hashKey(); if (_tileCache->exist(key)) { return _tileCache->get(key).status; } return Tile::Status::Unavailable; } Tile CachingTileProvider::getOrStartFetchingTile(ChunkIndex chunkIndex) { HashKey hashkey = chunkIndex.hashKey(); if (_tileCache->exist(hashkey)) { return _tileCache->get(hashkey); } else { _asyncTextureDataProvider->enqueueTextureData(chunkIndex); return Tile::TileUnavailable; } } TileDepthTransform CachingTileProvider::depthTransform() { return _asyncTextureDataProvider->getTextureDataProvider()->getDepthTransform(); } void CachingTileProvider::initializeAndAddToCache(std::shared_ptr tileIOResult) { HashKey key = tileIOResult->chunkIndex.hashKey(); TileDataset::DataLayout dataLayout = _asyncTextureDataProvider->getTextureDataProvider()->getDataLayout(); Texture* texturePtr = new Texture( tileIOResult->imageData, tileIOResult->dimensions, dataLayout.textureFormat.ghoulFormat, dataLayout.textureFormat.glFormat, dataLayout.glType, Texture::FilterMode::Linear, Texture::WrappingMode::ClampToEdge); // The texture should take ownership of the data std::shared_ptr texture = std::shared_ptr(texturePtr); //texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); texture->uploadTexture(); Tile tile = { texture, tileIOResult->preprocessData, tileIOResult->error == CE_None ? Tile::Status::OK : Tile::Status::IOError }; _tileCache->put(key, tile); } } // namespace openspace