Some cleanup of Globe browsing

This commit is contained in:
Alexander Bock
2017-12-30 11:12:53 -05:00
parent e4875dd8d6
commit 16595db09f
13 changed files with 98 additions and 109 deletions

View File

@@ -50,6 +50,7 @@ public:
std::vector<Item> putAndFetchPopped(const KeyType& key, const ValueType& value);
void clear();
bool exist(const KeyType& key) const;
/**
* If value exists, the value is bumped to the front of the queue.
* \returns true if value of this key exists.
@@ -73,6 +74,7 @@ public:
private:
void putWithoutCleaning(const KeyType& key, const ValueType& value);
void clean();
std::vector<Item> cleanAndFetchPopped();
Items _itemList;

View File

@@ -56,7 +56,7 @@ LRUCache<KeyType, ValueType, HasherType>::putAndFetchPopped(const KeyType& key,
template<typename KeyType, typename ValueType, typename HasherType>
bool LRUCache<KeyType, ValueType, HasherType>::exist(const KeyType& key) const {
return _itemMap.count(key) > 0;
return (_itemMap.count(key) > 0);
}
template<typename KeyType, typename ValueType, typename HasherType>
@@ -78,7 +78,7 @@ bool LRUCache<KeyType, ValueType, HasherType>::touch(const KeyType& key) {
template<typename KeyType, typename ValueType, typename HasherType>
bool LRUCache<KeyType, ValueType, HasherType>::isEmpty() const {
return _itemMap.size() == 0;
return (_itemMap.size() == 0);
}
template<typename KeyType, typename ValueType, typename HasherType>
@@ -92,8 +92,10 @@ ValueType LRUCache<KeyType, ValueType, HasherType>::get(const KeyType& key) {
template<typename KeyType, typename ValueType, typename HasherType>
std::pair<KeyType, ValueType> LRUCache<KeyType, ValueType, HasherType>::popMRU() {
ghoul_assert(_itemList.size() > 0,
"Can not pop from LRU cache. Ensure cache is not empty.");
ghoul_assert(
_itemList.size() > 0,
"Can not pop from LRU cache. Ensure cache is not empty."
);
auto first_it = _itemList.begin();
_itemMap.erase(first_it->first);
std::pair<KeyType, ValueType> toReturn = _itemList.front();
@@ -103,8 +105,10 @@ std::pair<KeyType, ValueType> LRUCache<KeyType, ValueType, HasherType>::popMRU()
template<typename KeyType, typename ValueType, typename HasherType>
std::pair<KeyType, ValueType> LRUCache<KeyType, ValueType, HasherType>::popLRU() {
ghoul_assert(_itemList.size() > 0,
"Can not pop from LRU cache. Ensure cache is not empty.");
ghoul_assert(
_itemList.size() > 0,
"Can not pop from LRU cache. Ensure cache is not empty."
);
auto lastIt = _itemList.end();
lastIt--;
_itemMap.erase(lastIt->first);

View File

@@ -84,50 +84,43 @@ namespace openspace::globebrowsing::cache {
MemoryAwareTileCache::MemoryAwareTileCache()
: PropertyOwner({ "TileCache" })
, _numTextureBytesAllocatedOnCPU(0)
, _cpuAllocatedTileData(CpuAllocatedDataInfo, 1024, 128, 2048, 1)
, _gpuAllocatedTileData(GpuAllocatedDataInfo, 1024, 128, 2048, 1)
, _tileCacheSize(TileCacheSizeInfo, 1024, 128, 2048, 1)
, _cpuAllocatedTileData(CpuAllocatedDataInfo, 1024, 128, 16384, 1)
, _gpuAllocatedTileData(GpuAllocatedDataInfo, 1024, 128, 16384, 1)
, _tileCacheSize(TileCacheSizeInfo, 1024, 128, 16384, 1)
, _applyTileCacheSize(ApplyTileCacheInfo)
, _clearTileCache(ClearTileCacheInfo)
, _usePbo(UsePboInfo, false)
{
createDefaultTextureContainers();
// Properties
_clearTileCache.onChange(
[&]{
clear();
});
_applyTileCacheSize.onChange(
[&]{
setSizeEstimated(_tileCacheSize * 1024 * 1024);
});
_clearTileCache.onChange([&]{ clear(); });
addProperty(_clearTileCache);
_applyTileCacheSize.onChange([&]{ setSizeEstimated(_tileCacheSize * 1024 * 1024); });
addProperty(_applyTileCacheSize);
_cpuAllocatedTileData.setMaxValue(
static_cast<int>(CpuCap.installedMainMemory() * 0.25)
static_cast<int>(CpuCap.installedMainMemory() * 0.95)
);
_cpuAllocatedTileData.setReadOnly(true);
addProperty(_cpuAllocatedTileData);
_gpuAllocatedTileData.setMaxValue(
static_cast<int>(CpuCap.installedMainMemory() * 0.25)
static_cast<int>(CpuCap.installedMainMemory() * 0.95)
);
_gpuAllocatedTileData.setReadOnly(true);
addProperty(_gpuAllocatedTileData);
_tileCacheSize.setMaxValue(
static_cast<int>(CpuCap.installedMainMemory() * 0.25)
static_cast<int>(CpuCap.installedMainMemory() * 0.95)
);
addProperty(_tileCacheSize);
addProperty(_usePbo);
setSizeEstimated(_tileCacheSize * 1024 * 1024);
_cpuAllocatedTileData.setReadOnly(true);
_gpuAllocatedTileData.setReadOnly(true);
addProperty(_clearTileCache);
addProperty(_applyTileCacheSize);
addProperty(_cpuAllocatedTileData);
addProperty(_gpuAllocatedTileData);
addProperty(_tileCacheSize);
addProperty(_usePbo);
}
MemoryAwareTileCache::~MemoryAwareTileCache()
{ }
void MemoryAwareTileCache::clear() {
LINFO("Clearing tile cache");
_numTextureBytesAllocatedOnCPU = 0;
@@ -142,8 +135,10 @@ void MemoryAwareTileCache::clear() {
void MemoryAwareTileCache::createDefaultTextureContainers() {
for (int id = 0; id < layergroupid::NUM_LAYER_GROUPS; id++) {
TileTextureInitData initData =
LayerManager::getTileTextureInitData(layergroupid::GroupID(id), true);
TileTextureInitData initData = LayerManager::getTileTextureInitData(
layergroupid::GroupID(id),
true
);
assureTextureContainerExists(initData);
}
}
@@ -172,7 +167,7 @@ void MemoryAwareTileCache::setSizeEstimated(size_t estimatedSize) {
_textureContainerMap.cend(),
size_t(0),
[](size_t s, const std::pair<const TileTextureInitData::HashKey,
TextureContainerTileCache>& p)
TextureContainerTileCache>& p)
{
return s + p.second.first->tileTextureInitData().totalNumBytes();
}
@@ -194,22 +189,28 @@ void MemoryAwareTileCache::resetTextureContainerSize(size_t numTexturesPerTextur
}
bool MemoryAwareTileCache::exist(ProviderTileKey key) const {
TextureContainerMap::const_iterator result =
std::find_if(_textureContainerMap.cbegin(), _textureContainerMap.cend(),
[&](const std::pair<const TileTextureInitData::HashKey,
TextureContainerTileCache>& p){
return p.second.second->exist(key);
});
TextureContainerMap::const_iterator result = std::find_if(
_textureContainerMap.cbegin(),
_textureContainerMap.cend(),
[&](const std::pair<const TileTextureInitData::HashKey,
TextureContainerTileCache>& p)
{
return p.second.second->exist(key);
}
);
return result != _textureContainerMap.cend();
}
Tile MemoryAwareTileCache::get(ProviderTileKey key) {
TextureContainerMap::const_iterator it =
std::find_if(_textureContainerMap.cbegin(), _textureContainerMap.cend(),
[&](const std::pair<const TileTextureInitData::HashKey,
TextureContainerTileCache>& p){
return p.second.second->exist(key);
});
TextureContainerMap::const_iterator it = std::find_if(
_textureContainerMap.cbegin(),
_textureContainerMap.cend(),
[&](const std::pair<const TileTextureInitData::HashKey,
TextureContainerTileCache>& p)
{
return p.second.second->exist(key);
}
);
if (it != _textureContainerMap.cend()) {
return it->second.second->get(key);
}
@@ -219,16 +220,16 @@ Tile MemoryAwareTileCache::get(ProviderTileKey key) {
}
ghoul::opengl::Texture* MemoryAwareTileCache::getTexture(
const TileTextureInitData& initData)
const TileTextureInitData& initData)
{
ghoul::opengl::Texture* texture;
// if this texture type does not exist among the texture containers
// it needs to be created
TileTextureInitData::HashKey initDataKey = initData.hashKey();
assureTextureContainerExists(initData);
// Now we know that the texture container exists,
// check if there are any unused textures
texture = _textureContainerMap[initDataKey].first->getTextureIfFree();
ghoul::opengl::Texture* texture =
_textureContainerMap[initDataKey].first->getTextureIfFree();
// Second option. No more textures available. Pop from the LRU cache
if (!texture) {
Tile oldTile = _textureContainerMap[initDataKey].second->popLRU().second;
@@ -239,7 +240,7 @@ ghoul::opengl::Texture* MemoryAwareTileCache::getTexture(
}
void MemoryAwareTileCache::createTileAndPut(ProviderTileKey key,
std::shared_ptr<RawTile> rawTile)
std::shared_ptr<RawTile> rawTile)
{
ghoul_precondition(rawTile, "RawTile can not be null");
using ghoul::opengl::Texture;
@@ -282,7 +283,8 @@ void MemoryAwareTileCache::createTileAndPut(ProviderTileKey key,
}
void MemoryAwareTileCache::put(const ProviderTileKey& key,
const TileTextureInitData::HashKey& initDataKey, Tile tile)
const TileTextureInitData::HashKey& initDataKey,
Tile tile)
{
_textureContainerMap[initDataKey].second->put(key, tile);
return;

View File

@@ -86,7 +86,6 @@ struct ProviderTileHasher {
class MemoryAwareTileCache : public properties::PropertyOwner {
public:
MemoryAwareTileCache();
~MemoryAwareTileCache();
void clear();
void setSizeEstimated(size_t estimatedSize);

View File

@@ -38,10 +38,6 @@ TextureContainer::TextureContainer(TileTextureInitData initData, size_t numTextu
void TextureContainer::reset() {
_textures.clear();
_freeTexture = 0;
ghoul::opengl::Texture::AllocateData allocate =
_initData.shouldAllocateDataOnCPU() ?
ghoul::opengl::Texture::AllocateData::Yes :
ghoul::opengl::Texture::AllocateData::No;
for (size_t i = 0; i < _numTextures; ++i) {
auto tex = std::make_unique<ghoul::opengl::Texture>(
_initData.dimensions(),
@@ -50,7 +46,7 @@ void TextureContainer::reset() {
_initData.glType(),
ghoul::opengl::Texture::FilterMode::Linear,
ghoul::opengl::Texture::WrappingMode::ClampToEdge,
allocate
ghoul::opengl::Texture::AllocateData(_initData.shouldAllocateDataOnCPU())
);
tex->setDataOwnership(ghoul::opengl::Texture::TakeOwnership::Yes);
@@ -67,17 +63,17 @@ void TextureContainer::reset(size_t numTextures) {
}
ghoul::opengl::Texture* TextureContainer::getTextureIfFree() {
ghoul::opengl::Texture* texture = nullptr;
if (_freeTexture < _textures.size()) {
texture = _textures[_freeTexture].get();
ghoul::opengl::Texture* texture = _textures[_freeTexture].get();
_freeTexture++;
return texture;
}
else {
return nullptr;
}
return texture;
}
const openspace::globebrowsing::TileTextureInitData&
TextureContainer::tileTextureInitData() const
{
const TileTextureInitData& TextureContainer::tileTextureInitData() const {
return _initData;
}

View File

@@ -26,16 +26,15 @@
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
#include <modules/globebrowsing/rendering/layer/layergroup.h>
#include <modules/globebrowsing/rendering/layer/layermanager.h>
#include <modules/globebrowsing/tile/tileselector.h>
#include <modules/globebrowsing/tile/tilemetadata.h>
#include <modules/globebrowsing/rendering/layer/layergroup.h>
#include <openspace/util/updatestructures.h>
namespace openspace::globebrowsing {
const float Chunk::DEFAULT_HEIGHT = 0.0f;
Chunk::Chunk(const RenderableGlobe& owner, const TileIndex& tileIndex, bool initVisible)
: _owner(owner)
, _tileIndex(tileIndex)
@@ -90,7 +89,7 @@ Chunk::Status Chunk::update(const RenderData& data) {
}
}
Chunk::BoundingHeights Chunk::getBoundingHeights() const {
Chunk::BoundingHeights Chunk::boundingHeights() const {
using ChunkTileSettingsPair = std::pair<ChunkTile, const LayerRenderSettings*>;
BoundingHeights boundingHeights {
@@ -100,19 +99,15 @@ Chunk::BoundingHeights Chunk::getBoundingHeights() const {
// In the future, this should be abstracted away and more easily queryable.
// One must also handle how to sample pick one out of multiplte heightmaps
std::shared_ptr<LayerManager> layerManager =
owner().chunkedLodGlobe()->layerManager();
std::shared_ptr<LayerManager> lm = owner().chunkedLodGlobe()->layerManager();
// The raster of a height map is the first one. We assume that the height map is
// a single raster image. If it is not we will just use the first raster
// (that is channel 0).
const size_t HeightChannel = 0;
const LayerGroup& heightmaps = layerManager->layerGroup(
layergroupid::GroupID::HeightLayers
);
const LayerGroup& heightmaps = lm->layerGroup(layergroupid::GroupID::HeightLayers);
std::vector<ChunkTileSettingsPair> chunkTileSettingPairs =
tileselector::getTilesAndSettingsUnsorted(
heightmaps, _tileIndex);
tileselector::getTilesAndSettingsUnsorted(heightmaps, _tileIndex);
bool lastHadMissingData = true;
for (const ChunkTileSettingsPair& chunkTileSettingsPair : chunkTileSettingPairs) {
@@ -124,21 +119,17 @@ Chunk::BoundingHeights Chunk::getBoundingHeights() const {
if (goodTile && hasTileMetaData) {
std::shared_ptr<TileMetaData> tileMetaData = chunkTile.tile.metaData();
float minValue =
settings->performLayerSettings(tileMetaData->minValues[HeightChannel]);
float maxValue =
settings->performLayerSettings(tileMetaData->maxValues[HeightChannel]);
float minValue = settings->performLayerSettings(
tileMetaData->minValues[HeightChannel]
);
float maxValue = settings->performLayerSettings(
tileMetaData->maxValues[HeightChannel]
);
if (!boundingHeights.available) {
if (tileMetaData->hasMissingData[HeightChannel]) {
boundingHeights.min = std::min(
DEFAULT_HEIGHT,
minValue
);
boundingHeights.max = std::max(
DEFAULT_HEIGHT,
maxValue
);
boundingHeights.min = std::min(DEFAULT_HEIGHT, minValue);
boundingHeights.max = std::max(DEFAULT_HEIGHT, maxValue);
}
else {
boundingHeights.min = minValue;
@@ -147,14 +138,8 @@ Chunk::BoundingHeights Chunk::getBoundingHeights() const {
boundingHeights.available = true;
}
else {
boundingHeights.min = std::min(
boundingHeights.min,
minValue
);
boundingHeights.max = std::max(
boundingHeights.max,
maxValue
);
boundingHeights.min = std::min(boundingHeights.min, minValue);
boundingHeights.max = std::max(boundingHeights.max, maxValue);
}
lastHadMissingData = tileMetaData->hasMissingData[HeightChannel];
}
@@ -168,11 +153,11 @@ Chunk::BoundingHeights Chunk::getBoundingHeights() const {
return boundingHeights;
}
std::vector<glm::dvec4> Chunk::getBoundingPolyhedronCorners() const {
std::vector<glm::dvec4> Chunk::boundingPolyhedronCorners() const {
const Ellipsoid& ellipsoid = owner().ellipsoid();
const GeodeticPatch& patch = surfacePatch();
BoundingHeights boundingHeight = getBoundingHeights();
BoundingHeights boundingHeight = boundingHeights();
// assume worst case
double patchCenterRadius = ellipsoid.maximumRadius();

View File

@@ -41,7 +41,7 @@ struct TileIndex;
class Chunk {
public:
const static float DEFAULT_HEIGHT;
constexpr static float DEFAULT_HEIGHT = 0.f;
struct BoundingHeights {
float min, max;
@@ -51,7 +51,7 @@ public:
enum class Status {
DoNothing,
WantMerge,
WantSplit,
WantSplit
};
Chunk(const RenderableGlobe& owner, const TileIndex& tileIndex,
@@ -74,7 +74,7 @@ public:
* Returns a convex polyhedron of eight vertices tightly bounding the volume of
* the Chunk.
*/
std::vector<glm::dvec4> getBoundingPolyhedronCorners() const;
std::vector<glm::dvec4> boundingPolyhedronCorners() const;
const GeodeticPatch& surfacePatch() const;
const RenderableGlobe& owner() const;
@@ -90,7 +90,7 @@ public:
* This means that high level Chunks can have BoundingHeights that are not
* tightly fitting.
*/
BoundingHeights getBoundingHeights() const;
BoundingHeights boundingHeights() const;
private:
const RenderableGlobe& _owner;

View File

@@ -50,7 +50,7 @@ int Distance::getDesiredLevel(const Chunk& chunk, const RenderData& data) const
glm::dvec3 patchNormal = ellipsoid.geodeticSurfaceNormal(pointOnPatch);
glm::dvec3 patchPosition = ellipsoid.cartesianSurfacePosition(pointOnPatch);
Chunk::BoundingHeights heights = chunk.getBoundingHeights();
Chunk::BoundingHeights heights = chunk.boundingHeights();
double heightToChunk = heights.min;
// Offset position according to height

View File

@@ -72,7 +72,7 @@ int ProjectedArea::getDesiredLevel(const Chunk& chunk, const RenderData& data) c
// | |
// +-----------------+ <-- south east corner
Chunk::BoundingHeights heights = chunk.getBoundingHeights();
Chunk::BoundingHeights heights = chunk.boundingHeights();
const Geodetic3 c = { center, heights.min };
const Geodetic3 c1 = { Geodetic2(center.lat, closestCorner.lon), heights.min };
const Geodetic3 c2 = { Geodetic2(closestCorner.lat, center.lon), heights.min };

View File

@@ -26,6 +26,7 @@
#define __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKCULLER___H__
namespace openspace { struct RenderData; }
namespace openspace::globebrowsing { class Chunk; }
namespace openspace::globebrowsing::culling {

View File

@@ -26,6 +26,7 @@
#include <modules/globebrowsing/chunk/chunk.h>
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <openspace/util/updatestructures.h>
namespace openspace::globebrowsing::culling {
@@ -42,7 +43,7 @@ bool FrustumCuller::isCullable(const Chunk& chunk, const RenderData& data) {
data.camera.sgctInternal.projectionMatrix()
) * viewTransform * modelTransform;
const std::vector<glm::dvec4>& corners = chunk.getBoundingPolyhedronCorners();
const std::vector<glm::dvec4>& corners = chunk.boundingPolyhedronCorners();
// Create a bounding box that fits the patch corners
AABB3 bounds; // in screen space

View File

@@ -37,7 +37,7 @@ bool HorizonCuller::isCullable(const Chunk& chunk, const RenderData& data) {
const Ellipsoid& ellipsoid = chunk.owner().ellipsoid();
const GeodeticPatch& patch = chunk.surfacePatch();
float maxHeight = chunk.getBoundingHeights().max;
float maxHeight = chunk.boundingHeights().max;
glm::dvec3 globePosition = glm::dvec3(0,0,0); // In model space it is 0
double minimumGlobeRadius = ellipsoid.minimumRadius();

View File

@@ -325,8 +325,7 @@ void ChunkedLodGlobe::debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp
if (_owner.debugProperties().showChunkBounds ||
_owner.debugProperties().showChunkAABB)
{
const std::vector<glm::dvec4> modelSpaceCorners =
chunk.getBoundingPolyhedronCorners();
std::vector<glm::dvec4> modelSpaceCorners = chunk.boundingPolyhedronCorners();
std::vector<glm::vec4> clippingSpaceCorners(8);
AABB3 screenSpaceBounds;