Merge branch 'feature/osirisrex' of github.com:OpenSpace/OpenSpace into feature/osirisrex

This commit is contained in:
Kalle Bladin
2016-08-12 12:29:29 -04:00
47 changed files with 1153 additions and 4657 deletions

View File

@@ -42,6 +42,7 @@ public:
bool windowHasResized() const override;
double averageDeltaTime() const override;
double deltaTime() const override;
glm::vec2 mousePosition() const override;
uint32_t mouseButtons(int maxNumber) const override;
glm::ivec2 currentWindowSize() const override;

View File

@@ -79,6 +79,12 @@ public:
*/
virtual double averageDeltaTime() const;
/**
* Returns the frametime in seconds. On default, this method returns <code>0.0</code>.
* \return The frametime in seconds
*/
virtual double deltaTime() const;
/**
* Returns the location of the mouse cursor in pixel screen coordinates. On default,
* this method returns <code>0,0</code>.

View File

@@ -25,6 +25,8 @@
#ifndef __PERFORMANCEMANAGER_H__
#define __PERFORMANCEMANAGER_H__
#include <openspace/performance/performancelayout.h>
#include <ghoul/misc/sharedmemory.h>
#include <map>
@@ -43,8 +45,9 @@ namespace performance {
class PerformanceManager {
public:
static const std::string PerformanceMeasurementSharedData;
static void createGlobalSharedMemory();
static void destroyGlobalSharedMemory();
PerformanceManager();
~PerformanceManager();
@@ -54,6 +57,8 @@ public:
void storeIndividualPerformanceMeasurement(std::string identifier, long long nanoseconds);
void storeScenePerformanceMeasurements(const std::vector<SceneGraphNode*>& sceneNodes);
PerformanceLayout* performanceData();
private:
bool _doPerformanceMeasurements;

View File

@@ -68,8 +68,15 @@ public:
Post
};
enum class FrametimeType {
DtTimeAvg = 0,
FPS,
FPSAvg
};
static const std::string KeyFontMono;
static const std::string KeyFontLight;
static const std::vector<FrametimeType> FrametimeTypes;
RenderEngine();
~RenderEngine();
@@ -97,6 +104,7 @@ public:
void takeScreenshot();
void toggleInfoText(bool b);
void toggleFrametimeType(int t);
// Performance measurements
void setPerformanceMeasurements(bool performanceMeasurements);
@@ -199,6 +207,8 @@ private:
ghoul::Dictionary _resolveData;
ScreenLog* _log;
FrametimeType _frametimeType;
bool _showInfo;
bool _showLog;
bool _takeScreenshot;

View File

@@ -48,8 +48,12 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.h
${CMAKE_CURRENT_SOURCE_DIR}/geometry/convexhull.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/temporaltileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/chunkindextileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/cachingtileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tilediskcache.h
${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.h
@@ -65,7 +69,6 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.h
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.h
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.h
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.h
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentqueue.h
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.h
@@ -95,8 +98,13 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.cpp
${CMAKE_CURRENT_SOURCE_DIR}/geometry/convexhull.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/temporaltileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/chunkindextileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/cachingtileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tilediskcache.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.cpp
@@ -113,10 +121,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
@@ -165,4 +170,4 @@ else (WIN32)
openspace-module-globebrowsing
${GDAL_LIBRARY}
)
endif ()
endif ()

View File

@@ -42,7 +42,7 @@
#include <modules/globebrowsing/chunk/chunknode.h>
#include <modules/globebrowsing/chunk/chunkrenderer.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/other/statscollector.h>

View File

@@ -24,8 +24,7 @@
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <modules/globebrowsing/tile/temporaltileprovider.h>
#include <ghoul/misc/threadpool.h>
#include <modules/globebrowsing/tile/tileselector.h>
// open space includes

View File

@@ -44,7 +44,7 @@
#include <modules/globebrowsing/tile/tileprovidermanager.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <ghoul/misc/threadpool.h>
#include <modules/globebrowsing/other/distanceswitch.h>
namespace ghoul {

View File

@@ -32,7 +32,7 @@
#include <queue>
#include <modules/globebrowsing/other/concurrentqueue.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <ghoul/misc/threadpool.h>
#include <ghoul/misc/assert.h>
@@ -64,7 +64,7 @@ namespace openspace {
template<typename P>
class ConcurrentJobManager{
public:
ConcurrentJobManager(std::shared_ptr<ThreadPool> pool) : threadPool(pool)
ConcurrentJobManager(std::shared_ptr<ghoul::ThreadPool> pool) : threadPool(pool)
{
}
@@ -75,14 +75,14 @@ namespace openspace {
void enqueueJob(std::shared_ptr<Job<P>> job) {
threadPool->enqueue([this, job]() {
threadPool->queue([this, job]() {
job->execute();
_finishedJobs.push(job);
});
}
void clearEnqueuedJobs() {
threadPool->clearTasks();
threadPool->clearRemainingTasks();
}
std::shared_ptr<Job<P>> popFinishedJob() {
@@ -95,14 +95,14 @@ namespace openspace {
}
void reset() {
threadPool->clearTasks();
threadPool->clearRemainingTasks();
}
private:
ConcurrentQueue<std::shared_ptr<Job<P>>> _finishedJobs;
std::shared_ptr<ThreadPool> threadPool;
std::shared_ptr<ghoul::ThreadPool> threadPool;
};

View File

@@ -1,126 +0,0 @@
/*****************************************************************************************
* *
* 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 <glm/glm.hpp>
#include <memory>
#include <ostream>
#include <thread>
#include <queue>
#include <modules/globebrowsing/other/concurrentqueue.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <ghoul/misc/assert.h>
#include <iostream>
namespace openspace {
Worker::Worker(ThreadPool& pool)
: pool(pool)
{
}
void Worker::operator()() {
std::function<void()> task;
while (true) {
// acquire lock
{
std::unique_lock<std::mutex> lock(pool.queue_mutex);
// look for a work item
while (!pool.stop && pool.tasks.empty()) {
// if there are none wait for notification
pool.condition.wait(lock);
}
if (pool.stop) { // exit if the pool is stopped
return;
}
// get the task from the queue
task = pool.tasks.front();
pool.tasks.pop_front();
}// release lock
// execute the task
task();
}
}
ThreadPool::ThreadPool(size_t numThreads)
: stop(false)
{
for (size_t i = 0; i < numThreads; ++i) {
workers.push_back(std::thread(Worker(*this)));
}
}
// the destructor joins all threads
ThreadPool::~ThreadPool() {
// stop all threads
stop = true;
condition.notify_all();
// join them
for (size_t i = 0; i < workers.size(); ++i) {
workers[i].join();
}
}
// add new work item to the pool
void ThreadPool::enqueue(std::function<void()> f) {
{ // acquire lock
std::unique_lock<std::mutex> lock(queue_mutex);
// add the task
tasks.push_back(f);
} // release lock
// wake up one thread
condition.notify_one();
}
void ThreadPool::clearTasks() {
{ // acquire lock
std::unique_lock<std::mutex> lock(queue_mutex);
tasks.clear();
} // release lock
}
} // namespace openspace

View File

@@ -1,81 +0,0 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
#ifndef __THREAD_POOL_H__
#define __THREAD_POOL_H__
#include <glm/glm.hpp>
#include <memory>
#include <ostream>
#include <thread>
#include <queue>
#include <modules/globebrowsing/other/concurrentqueue.h>
#include <ghoul/misc/assert.h>
// Implementatin based on http://progsch.net/wordpress/?p=81
namespace openspace {
class ThreadPool;
class Worker {
public:
Worker(ThreadPool& pool);
void operator()();
private:
ThreadPool& pool;
};
class ThreadPool {
public:
ThreadPool(size_t numThreads);
~ThreadPool();
void enqueue(std::function<void()> f);
void clearTasks();
private:
friend class Worker;
std::vector<std::thread> workers;
std::deque<std::function<void()>> tasks;
std::mutex queue_mutex;
std::condition_variable condition;
bool stop;
};
} // namespace openspace
#endif // __THREAD_POOL_H__

View File

@@ -28,7 +28,7 @@
#include <ghoul/misc/assert.h>
#include <modules/globebrowsing/tile/asynctilereader.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/tile/tilediskcache.h>
@@ -117,9 +117,9 @@ namespace openspace {
AsyncTileDataProvider::AsyncTileDataProvider(
std::shared_ptr<TileDataset> tileDataset,
std::shared_ptr<ThreadPool> pool)
std::shared_ptr<ghoul::ThreadPool> pool)
: _tileDataset(tileDataset)
, _concurrentJobManager(pool)
, _threadPool(pool)
{
}
@@ -133,59 +133,51 @@ namespace openspace {
return _tileDataset;
}
bool AsyncTileDataProvider::enqueueTextureData(const ChunkIndex& chunkIndex) {
//auto tileDiskCache = std::make_shared<TileDiskCache>("test");
bool AsyncTileDataProvider::enqueueTileIO(const ChunkIndex& chunkIndex) {
if (satisfiesEnqueueCriteria(chunkIndex)) {
auto job = std::make_shared<TileLoadJob>(_tileDataset, chunkIndex);
//auto job = std::make_shared<DiskCachedTileLoadJob>(_tileDataset, chunkIndex, tileDiskCache, "ReadAndWrite");
_concurrentJobManager.enqueueJob(job);
_enqueuedTileRequests[chunkIndex.hashKey()] = chunkIndex;
const static auto job = [](const ChunkIndex& chunkIndex, std::shared_ptr<TileDataset> tileDataset) {
return tileDataset->readTileData(chunkIndex);
};
FutureResult futureResult = _threadPool->queue(job, chunkIndex, _tileDataset);
_futureTileIOResults[chunkIndex.hashKey()] = std::move(futureResult);
return true;
}
return false;
}
bool AsyncTileDataProvider::hasLoadedTextureData() const{
return _concurrentJobManager.numFinishedJobs() > 0;
}
std::shared_ptr<TileIOResult> AsyncTileDataProvider::nextTileIOResult() {
auto tileIOResult = _concurrentJobManager.popFinishedJob()->product();
ChunkHashKey key = tileIOResult->chunkIndex.hashKey();
if (_enqueuedTileRequests.find(key) != _enqueuedTileRequests.end()) {
_enqueuedTileRequests.erase(key);
}
return tileIOResult;
}
bool AsyncTileDataProvider::satisfiesEnqueueCriteria(const ChunkIndex& chunkIndex) const {
auto it = _enqueuedTileRequests.begin();
auto end = _enqueuedTileRequests.end();
for (; it != end; it++) {
const ChunkIndex& otherChunk = it->second;
if (chunkIndex.level == otherChunk.level &&
chunkIndex.manhattan(otherChunk) < 1) {
return false;
std::vector<std::shared_ptr<TileIOResult>> AsyncTileDataProvider::getTileIOResults() {
std::vector<std::shared_ptr<TileIOResult>> readyResults;
auto it = _futureTileIOResults.begin();
while(it != _futureTileIOResults.end()) {
std::future_status status = it->second.wait_for(std::chrono::seconds(0));
if (status == std::future_status::ready) {
readyResults.push_back(it->second.get());
it = _futureTileIOResults.erase(it);
}
else {
it++;
}
}
return true;
return readyResults;
}
bool AsyncTileDataProvider::satisfiesEnqueueCriteria(const ChunkIndex& chunkIndex) const {
// only allow tile to be enqueued if it's not already enqueued
return _futureTileIOResults.find(chunkIndex.hashKey()) == _futureTileIOResults.end();
}
void AsyncTileDataProvider::reset() {
_enqueuedTileRequests.clear();
_concurrentJobManager.reset();
// also clear tiles that has just been finished loading
while (hasLoadedTextureData()) {
nextTileIOResult(); // get it and throw it away
}
_futureTileIOResults.clear();
_threadPool->stop(ghoul::ThreadPool::RunRemainingTasks::No);
_threadPool->start();
getTextureDataProvider()->reset();
}
void AsyncTileDataProvider::clearRequestQueue() {
_concurrentJobManager.clearEnqueuedJobs();
_enqueuedTileRequests.clear();
_threadPool->clearRemainingTasks();
_futureTileIOResults.clear();
}
} // namespace openspace

View File

@@ -33,7 +33,7 @@
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/other/concurrentjobmanager.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <ghoul/misc/threadpool.h>
#include <modules/globebrowsing/tile/tiledataset.h>
@@ -118,15 +118,13 @@ namespace openspace {
public:
AsyncTileDataProvider(std::shared_ptr<TileDataset> textureDataProvider,
std::shared_ptr<ThreadPool> pool);
std::shared_ptr<ghoul::ThreadPool> pool);
~AsyncTileDataProvider();
bool enqueueTextureData(const ChunkIndex& chunkIndex);
bool hasLoadedTextureData() const;
std::shared_ptr<TileIOResult> nextTileIOResult();
bool enqueueTileIO(const ChunkIndex& chunkIndex);
std::vector<std::shared_ptr<TileIOResult>> getTileIOResults();
void reset();
void clearRequestQueue();
@@ -138,10 +136,12 @@ namespace openspace {
virtual bool satisfiesEnqueueCriteria(const ChunkIndex&) const;
private:
using FutureResult = std::future<std::shared_ptr<TileIOResult>>;
std::shared_ptr<TileDataset> _tileDataset;
ConcurrentJobManager<TileIOResult> _concurrentJobManager;
std::unordered_map<ChunkHashKey, ChunkIndex> _enqueuedTileRequests;
std::shared_ptr<ghoul::ThreadPool> _threadPool;
std::unordered_map<ChunkHashKey, FutureResult> _futureTileIOResults;
};

View File

@@ -97,8 +97,7 @@ namespace openspace {
LayeredTexturePreprocessingData preprocessingData)
{
_updatedOnLastCall = false;
if (!(preprocessingData == _preprocessingData) || _programObject == nullptr)
{
if (!(preprocessingData == _preprocessingData) || _programObject == nullptr) {
recompileShaderProgram(preprocessingData);
_updatedOnLastCall = true;
}
@@ -134,8 +133,9 @@ namespace openspace {
for (size_t i = 0; i < keyValuePairs.size(); i++) {
shaderDictionary.setValue(keyValuePairs[i].first, keyValuePairs[i].second);
}
// Remove old program
_programObject.release();
OsEng.renderEngine().removeRenderProgram(_programObject);
_programObject = OsEng.renderEngine().buildRenderProgram(
_shaderName,

View File

@@ -30,7 +30,7 @@
#include <ghoul/misc/assert.h>
#include <modules/globebrowsing/tile/tiledataset.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/geometry/angle.h>

View File

@@ -31,16 +31,17 @@
#include <iostream>
#include <unordered_map>
#include "gdal_priv.h"
#include <gdal_priv.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/misc/threadpool.h>
#include <modules/globebrowsing/tile/tileioresult.h>
#include <modules/globebrowsing/tile/tiledatatype.h>
#include <modules/globebrowsing/tile/pixelregion.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/other/threadpool.h>
namespace openspace {

View File

@@ -27,7 +27,7 @@
#include <modules/globebrowsing/chunk/chunkindex.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <ghoul/filesystem/filesystem>

View File

@@ -1,398 +0,0 @@
/*****************************************************************************************
* *
* 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 <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tilediskcache.h>
#include <modules/globebrowsing/tile/tileprovidermanager.h>
#include <modules/globebrowsing/chunk/chunkindex.h>
#include <openspace/engine/downloadmanager.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/font/fontmanager.h>
#include <openspace/engine/openspaceengine.h>
#include <sstream>
namespace {
const std::string _loggerCat = "TileProvider";
}
namespace openspace {
const Tile Tile::TileUnavailable = {nullptr, nullptr, Tile::Status::Unavailable };
Tile Tile::createPlainTile(const glm::uvec2& size, const glm::uvec4& color) {
using namespace ghoul::opengl;
// Create pixel data
int numBytes = size.x * size.y * 4 * 1;
char* pixels = new char[numBytes];
size_t numPixels = size.x * size.y;
size_t i = 0;
for (size_t p = 0; p < numPixels; p++){
pixels[i++] = color.r;
pixels[i++] = color.g;
pixels[i++] = color.b;
pixels[i++] = color.a;
}
// Create ghoul texture
auto texture = std::make_shared<Texture>(glm::uvec3(size, 1));
texture->setDataOwnership(Texture::TakeOwnership::Yes);
texture->setPixelData(pixels);
texture->uploadTexture();
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
// Create tile
Tile tile;
tile.status = Tile::Status::OK;
tile.preprocessData = nullptr;
tile.texture = texture;
return tile;
}
//////////////////////////////////////////////////////////////////////////////////////
// Chunk Index Tile Provider //
//////////////////////////////////////////////////////////////////////////////////////
ChunkIndexTileProvider::ChunkIndexTileProvider(const glm::uvec2& textureSize, size_t fontSize)
: _tileCache(500)
, _textureSize(textureSize)
, _fontSize(fontSize)
{
using namespace ghoul::fontrendering;
_font = OsEng.fontManager().font("Mono", _fontSize);
_fontRenderer = std::unique_ptr<FontRenderer>(FontRenderer::createDefault());
_fontRenderer->setFramebufferSize(textureSize);
glGenFramebuffers(1, &_fbo);
}
ChunkIndexTileProvider::~ChunkIndexTileProvider() {
glDeleteFramebuffers(1, &_fbo);
}
Tile ChunkIndexTileProvider::getTile(const ChunkIndex& chunkIndex) {
ChunkHashKey key = chunkIndex.hashKey();
if (!_tileCache.exist(key)) {
_tileCache.put(key, createChunkIndexTile(chunkIndex));
}
return _tileCache.get(key);
}
Tile ChunkIndexTileProvider::getDefaultTile() {
return Tile::TileUnavailable;
}
Tile::Status ChunkIndexTileProvider::getTileStatus(const ChunkIndex& index) {
return Tile::Status::OK;
}
TileDepthTransform ChunkIndexTileProvider::depthTransform() {
TileDepthTransform transform;
transform.depthOffset = 0.0f;
transform.depthScale = 1.0f;
return transform;
}
void ChunkIndexTileProvider::update() {
// nothing to be done
}
void ChunkIndexTileProvider::reset() {
_tileCache.clear();
}
Tile ChunkIndexTileProvider::createChunkIndexTile(const ChunkIndex& chunkIndex) {
glm::uvec4 color = { 0, 0, 0, 0 };
Tile tile = Tile::createPlainTile(_textureSize, color);
// Keep track of defaultFBO and viewport to be able to reset state when done
GLint defaultFBO;
GLint viewport[4];
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
glGetIntegerv(GL_VIEWPORT, viewport);
// Render to texture
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
*(tile.texture),
0
);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
//LDEBUG(status);
glViewport(
0, 0,
static_cast<GLsizei>(tile.texture->width()),
static_cast<GLsizei>(tile.texture->height())
);
_fontRenderer->render(
*_font,
glm::vec2(
_textureSize.x / 4 - (_textureSize.x / 32) * log10(1 << chunkIndex.level),
_textureSize.y / 2 + _fontSize),
glm::vec4(1.0, 0.0, 0.0, 1.0),
"level: %i \nx: %i \ny: %i",
chunkIndex.level, chunkIndex.x, chunkIndex.y
);
// Reset state: bind default FBO and set viewport to what it was
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
return tile;
}
int ChunkIndexTileProvider::maxLevel() {
return 1337; // unlimited
}
//////////////////////////////////////////////////////////////////////////////////////
// Single Image Tile Provider //
//////////////////////////////////////////////////////////////////////////////////////
SingleImagePrivoder::SingleImagePrivoder(const std::string& imagePath)
: _imagePath(imagePath)
{
reset();
}
Tile SingleImagePrivoder::getTile(const ChunkIndex& chunkIndex) {
return _tile;
}
Tile SingleImagePrivoder::getDefaultTile() {
return _tile;
}
Tile::Status SingleImagePrivoder::getTileStatus(const ChunkIndex& index) {
return _tile.status;
}
TileDepthTransform SingleImagePrivoder::depthTransform() {
TileDepthTransform transform;
transform.depthOffset = 0.0f;
transform.depthScale = 1.0f;
return transform;
}
void SingleImagePrivoder::update() {
// nothing to be done
}
void SingleImagePrivoder::reset() {
_tile = Tile();
_tile.texture = std::shared_ptr<Texture>(ghoul::io::TextureReader::ref().loadTexture(_imagePath).release());
_tile.status = _tile.texture != nullptr ? Tile::Status::OK : Tile::Status::IOError;
_tile.preprocessData = nullptr;
_tile.texture->uploadTexture();
_tile.texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
}
int SingleImagePrivoder::maxLevel() {
return 1337; // unlimited
}
//////////////////////////////////////////////////////////////////////////////////////
// Caching Tile Provider //
//////////////////////////////////////////////////////////////////////////////////////
CachingTileProvider::CachingTileProvider(std::shared_ptr<AsyncTileDataProvider> tileReader,
std::shared_ptr<TileCache> tileCache,
int framesUntilFlushRequestQueue)
: _asyncTextureDataProvider(tileReader)
, _tileCache(tileCache)
, _framesUntilRequestFlush(framesUntilFlushRequestQueue)
, _framesSinceLastRequestFlush(0)
{
}
CachingTileProvider::~CachingTileProvider(){
clearRequestQueue();
}
void CachingTileProvider::update() {
initTexturesFromLoadedData();
if (_framesSinceLastRequestFlush++ > _framesUntilRequestFlush) {
clearRequestQueue();
}
}
void CachingTileProvider::reset() {
_tileCache->clear();
_asyncTextureDataProvider->reset();
}
int CachingTileProvider::maxLevel() {
return _asyncTextureDataProvider->getTextureDataProvider()->maxChunkLevel();
}
Tile CachingTileProvider::getTile(const ChunkIndex& chunkIndex) {
Tile tile = Tile::TileUnavailable;
if (chunkIndex.level > maxLevel()) {
tile.status = Tile::Status::OutOfRange;
return tile;
}
ChunkHashKey key = chunkIndex.hashKey();
if (_tileCache->exist(key)) {
return _tileCache->get(key);
}
else {
_asyncTextureDataProvider->enqueueTextureData(chunkIndex);
}
return tile;
}
Tile CachingTileProvider::getDefaultTile() {
if (_defaultTile.texture == nullptr) {
_defaultTile = createTile(_asyncTextureDataProvider->getTextureDataProvider()->defaultTileData());
}
return _defaultTile;
}
void CachingTileProvider::initTexturesFromLoadedData() {
while (_asyncTextureDataProvider->hasLoadedTextureData()) {
std::shared_ptr<TileIOResult> tileIOResult = _asyncTextureDataProvider->nextTileIOResult();
ChunkHashKey key = tileIOResult->chunkIndex.hashKey();
Tile tile = createTile(tileIOResult);
_tileCache->put(key, tile);
}
}
void CachingTileProvider::clearRequestQueue() {
_asyncTextureDataProvider->clearRequestQueue();
_framesSinceLastRequestFlush = 0;
}
Tile::Status CachingTileProvider::getTileStatus(const ChunkIndex& chunkIndex) {
auto tileDataset = _asyncTextureDataProvider->getTextureDataProvider();
if (chunkIndex.level > tileDataset->maxChunkLevel()) {
return Tile::Status::OutOfRange;
}
ChunkHashKey key = chunkIndex.hashKey();
if (_tileCache->exist(key)) {
return _tileCache->get(key).status;
}
return Tile::Status::Unavailable;
}
Tile CachingTileProvider::getOrStartFetchingTile(ChunkIndex chunkIndex) {
ChunkHashKey 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();
}
Tile CachingTileProvider::createTile(std::shared_ptr<TileIOResult> tileIOResult) {
ChunkHashKey key = tileIOResult->chunkIndex.hashKey();
TileDataLayout 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> texture = std::shared_ptr<Texture>(texturePtr);
texture->uploadTexture();
// AnisotropicMipMap must be set after texture is uploaded. Why?!
texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
Tile tile = {
texture,
tileIOResult->preprocessData,
tileIOResult->error == CE_None ? Tile::Status::OK : Tile::Status::IOError
};
return tile;
}
} // namespace openspace

View File

@@ -0,0 +1,186 @@
/*****************************************************************************************
* *
* 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 <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tileprovider/cachingtileprovider.h>
#include <modules/globebrowsing/chunk/chunkindex.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <openspace/engine/openspaceengine.h>
namespace {
const std::string _loggerCat = "TileProvider";
}
namespace openspace {
CachingTileProvider::CachingTileProvider(std::shared_ptr<AsyncTileDataProvider> tileReader,
std::shared_ptr<TileCache> tileCache,
int framesUntilFlushRequestQueue)
: _asyncTextureDataProvider(tileReader)
, _tileCache(tileCache)
, _framesUntilRequestFlush(framesUntilFlushRequestQueue)
, _framesSinceLastRequestFlush(0)
{
}
CachingTileProvider::~CachingTileProvider(){
clearRequestQueue();
}
void CachingTileProvider::update() {
initTexturesFromLoadedData();
if (_framesSinceLastRequestFlush++ > _framesUntilRequestFlush) {
clearRequestQueue();
}
}
void CachingTileProvider::reset() {
_tileCache->clear();
_asyncTextureDataProvider->reset();
}
int CachingTileProvider::maxLevel() {
return _asyncTextureDataProvider->getTextureDataProvider()->maxChunkLevel();
}
Tile CachingTileProvider::getTile(const ChunkIndex& chunkIndex) {
Tile tile = Tile::TileUnavailable;
if (chunkIndex.level > maxLevel()) {
tile.status = Tile::Status::OutOfRange;
return tile;
}
ChunkHashKey key = chunkIndex.hashKey();
if (_tileCache->exist(key)) {
return _tileCache->get(key);
}
else {
_asyncTextureDataProvider->enqueueTileIO(chunkIndex);
}
return tile;
}
Tile CachingTileProvider::getDefaultTile() {
if (_defaultTile.texture == nullptr) {
_defaultTile = createTile(_asyncTextureDataProvider->getTextureDataProvider()->defaultTileData());
}
return _defaultTile;
}
void CachingTileProvider::initTexturesFromLoadedData() {
auto readyTileIOResults = _asyncTextureDataProvider->getTileIOResults();
for(auto tileIOResult : readyTileIOResults){
ChunkHashKey key = tileIOResult->chunkIndex.hashKey();
Tile tile = createTile(tileIOResult);
_tileCache->put(key, tile);
}
}
void CachingTileProvider::clearRequestQueue() {
_asyncTextureDataProvider->clearRequestQueue();
_framesSinceLastRequestFlush = 0;
}
Tile::Status CachingTileProvider::getTileStatus(const ChunkIndex& chunkIndex) {
auto tileDataset = _asyncTextureDataProvider->getTextureDataProvider();
if (chunkIndex.level > tileDataset->maxChunkLevel()) {
return Tile::Status::OutOfRange;
}
ChunkHashKey key = chunkIndex.hashKey();
if (_tileCache->exist(key)) {
return _tileCache->get(key).status;
}
return Tile::Status::Unavailable;
}
Tile CachingTileProvider::getOrStartFetchingTile(ChunkIndex chunkIndex) {
ChunkHashKey hashkey = chunkIndex.hashKey();
if (_tileCache->exist(hashkey)) {
return _tileCache->get(hashkey);
}
else {
_asyncTextureDataProvider->enqueueTileIO(chunkIndex);
return Tile::TileUnavailable;
}
}
TileDepthTransform CachingTileProvider::depthTransform() {
return _asyncTextureDataProvider->getTextureDataProvider()->getDepthTransform();
}
Tile CachingTileProvider::createTile(std::shared_ptr<TileIOResult> tileIOResult) {
ChunkHashKey key = tileIOResult->chunkIndex.hashKey();
TileDataLayout 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> texture = std::shared_ptr<Texture>(texturePtr);
texture->uploadTexture();
// AnisotropicMipMap must be set after texture is uploaded. Why?!
texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
Tile tile = {
texture,
tileIOResult->preprocessData,
tileIOResult->error == CE_None ? Tile::Status::OK : Tile::Status::IOError
};
return tile;
}
} // namespace openspace

View File

@@ -22,25 +22,18 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __TILE_PROVIDER_H__
#define __TILE_PROVIDER_H__
#ifndef __CACHING_TILE_PROVIDER_H__
#define __CACHING_TILE_PROVIDER_H__
#include <gdal_priv.h>
#include <openspace/engine/downloadmanager.h>
#include <set>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h> // absPath
#include <ghoul/opengl/texture.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/font/fontrenderer.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/tile/asynctilereader.h>
#include <modules/globebrowsing/other/lrucache.h>
@@ -50,92 +43,6 @@
namespace openspace {
using namespace ghoul::opengl;
struct Tile {
std::shared_ptr<Texture> texture;
std::shared_ptr<TilePreprocessData> preprocessData;
enum class Status { Unavailable, OutOfRange, IOError, OK } status;
/**
* Instantiaes a new tile unicolored tile. The texture gets the provided size and
* color in rgba. Color values ranges between 0-255.
*/
static Tile createPlainTile(const glm::uvec2& size, const glm::uvec4& color);
static const Tile TileUnavailable;
};
class TileProvider {
public:
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;
virtual void reset() = 0;
virtual int maxLevel() = 0;
};
typedef LRUCache<ChunkHashKey, Tile> TileCache;
class ChunkIndexTileProvider : public TileProvider {
public:
ChunkIndexTileProvider(const glm::uvec2& textureSize = {512, 512}, size_t fontSize = 48);
virtual ~ChunkIndexTileProvider();
virtual Tile getTile(const ChunkIndex& chunkIndex);
virtual Tile getDefaultTile();
virtual Tile::Status getTileStatus(const ChunkIndex& index);
virtual TileDepthTransform depthTransform();
virtual void update();
virtual void reset();
virtual int maxLevel();
private:
Tile createChunkIndexTile(const ChunkIndex& chunkIndex);
std::shared_ptr<ghoul::fontrendering::Font> _font;
std::unique_ptr<ghoul::fontrendering::FontRenderer> _fontRenderer;
TileCache _tileCache;
glm::uvec2 _textureSize;
size_t _fontSize;
GLuint _fbo;
};
class SingleImagePrivoder : public TileProvider {
public:
SingleImagePrivoder(const std::string& imagePath);
virtual ~SingleImagePrivoder() { }
virtual Tile getTile(const ChunkIndex& chunkIndex);
virtual Tile getDefaultTile();
virtual Tile::Status getTileStatus(const ChunkIndex& index);
virtual TileDepthTransform depthTransform();
virtual void update();
virtual void reset();
virtual int maxLevel();
private:
Tile _tile;
std::string _imagePath;
};
/**
Provides tiles through GDAL datasets which can be defined with xml files
@@ -198,12 +105,9 @@ namespace openspace {
std::shared_ptr<AsyncTileDataProvider> _asyncTextureDataProvider;
};
} // namespace openspace
#endif // __TILE_PROVIDER_H__
#endif // __CACHING_TILE_PROVIDER_H__

View File

@@ -0,0 +1,154 @@
/*****************************************************************************************
* *
* 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 <modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h>
#include <modules/globebrowsing/chunk/chunkindex.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/font/fontmanager.h>
#include <openspace/engine/openspaceengine.h>
#include <sstream>
namespace {
const std::string _loggerCat = "TileProvider";
}
namespace openspace {
ChunkIndexTileProvider::ChunkIndexTileProvider(const glm::uvec2& textureSize, size_t fontSize)
: _tileCache(500)
, _textureSize(textureSize)
, _fontSize(fontSize)
{
using namespace ghoul::fontrendering;
_font = OsEng.fontManager().font("Mono", _fontSize);
_fontRenderer = std::unique_ptr<FontRenderer>(FontRenderer::createDefault());
_fontRenderer->setFramebufferSize(textureSize);
glGenFramebuffers(1, &_fbo);
}
ChunkIndexTileProvider::~ChunkIndexTileProvider() {
glDeleteFramebuffers(1, &_fbo);
}
Tile ChunkIndexTileProvider::getTile(const ChunkIndex& chunkIndex) {
ChunkHashKey key = chunkIndex.hashKey();
if (!_tileCache.exist(key)) {
_tileCache.put(key, createChunkIndexTile(chunkIndex));
}
return _tileCache.get(key);
}
Tile ChunkIndexTileProvider::getDefaultTile() {
return Tile::TileUnavailable;
}
Tile::Status ChunkIndexTileProvider::getTileStatus(const ChunkIndex& index) {
return Tile::Status::OK;
}
TileDepthTransform ChunkIndexTileProvider::depthTransform() {
TileDepthTransform transform;
transform.depthOffset = 0.0f;
transform.depthScale = 1.0f;
return transform;
}
void ChunkIndexTileProvider::update() {
// nothing to be done
}
void ChunkIndexTileProvider::reset() {
_tileCache.clear();
}
Tile ChunkIndexTileProvider::createChunkIndexTile(const ChunkIndex& chunkIndex) {
glm::uvec4 color = { 0, 0, 0, 0 };
Tile tile = Tile::createPlainTile(_textureSize, color);
// Keep track of defaultFBO and viewport to be able to reset state when done
GLint defaultFBO;
GLint viewport[4];
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
glGetIntegerv(GL_VIEWPORT, viewport);
// Render to texture
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
*(tile.texture),
0
);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
//LDEBUG(status);
glViewport(
0, 0,
static_cast<GLsizei>(tile.texture->width()),
static_cast<GLsizei>(tile.texture->height())
);
_fontRenderer->render(
*_font,
glm::vec2(
_textureSize.x / 4 - (_textureSize.x / 32) * log10(1 << chunkIndex.level),
_textureSize.y / 2 + _fontSize),
glm::vec4(1.0, 0.0, 0.0, 1.0),
"level: %i \nx: %i \ny: %i",
chunkIndex.level, chunkIndex.x, chunkIndex.y
);
// Reset state: bind default FBO and set viewport to what it was
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
return tile;
}
int ChunkIndexTileProvider::maxLevel() {
return 1337; // unlimited
}
} // namespace openspace

View File

@@ -0,0 +1,82 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
#ifndef __CHUNK_INDEX_TILE_PROVIDER_H__
#define __CHUNK_INDEX_TILE_PROVIDER_H__
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h> // absPath
#include <ghoul/opengl/texture.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/font/fontmanager.h>
#include <modules/globebrowsing/tile/asynctilereader.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/other/lrucache.h>
//////////////////////////////////////////////////////////////////////////////////////////
// TILE PROVIDER //
//////////////////////////////////////////////////////////////////////////////////////////
namespace openspace {
class ChunkIndexTileProvider : public TileProvider {
public:
ChunkIndexTileProvider(const glm::uvec2& textureSize = {512, 512}, size_t fontSize = 48);
virtual ~ChunkIndexTileProvider();
virtual Tile getTile(const ChunkIndex& chunkIndex);
virtual Tile getDefaultTile();
virtual Tile::Status getTileStatus(const ChunkIndex& index);
virtual TileDepthTransform depthTransform();
virtual void update();
virtual void reset();
virtual int maxLevel();
private:
Tile createChunkIndexTile(const ChunkIndex& chunkIndex);
std::shared_ptr<ghoul::fontrendering::Font> _font;
std::unique_ptr<ghoul::fontrendering::FontRenderer> _fontRenderer;
TileCache _tileCache;
glm::uvec2 _textureSize;
size_t _fontSize;
GLuint _fbo;
};
} // namespace openspace
#endif // __CHUNK_INDEX_TILE_PROVIDER_H__

View File

@@ -0,0 +1,92 @@
/*****************************************************************************************
* *
* 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 <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tileprovider/singleimageprovider.h>
#include <modules/globebrowsing/chunk/chunkindex.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <openspace/engine/openspaceengine.h>
namespace {
const std::string _loggerCat = "SingleImageProvider";
}
namespace openspace {
SingleImagePrivoder::SingleImagePrivoder(const std::string& imagePath)
: _imagePath(imagePath)
{
reset();
}
Tile SingleImagePrivoder::getTile(const ChunkIndex& chunkIndex) {
return _tile;
}
Tile SingleImagePrivoder::getDefaultTile() {
return _tile;
}
Tile::Status SingleImagePrivoder::getTileStatus(const ChunkIndex& index) {
return _tile.status;
}
TileDepthTransform SingleImagePrivoder::depthTransform() {
TileDepthTransform transform;
transform.depthOffset = 0.0f;
transform.depthScale = 1.0f;
return transform;
}
void SingleImagePrivoder::update() {
// nothing to be done
}
void SingleImagePrivoder::reset() {
_tile = Tile();
_tile.texture = std::shared_ptr<Texture>(ghoul::io::TextureReader::ref().loadTexture(_imagePath).release());
_tile.status = _tile.texture != nullptr ? Tile::Status::OK : Tile::Status::IOError;
_tile.preprocessData = nullptr;
_tile.texture->uploadTexture();
_tile.texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
}
int SingleImagePrivoder::maxLevel() {
return 1337; // unlimited
}
} // namespace openspace

View File

@@ -0,0 +1,75 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
#ifndef __SINGLE_IMAGE_PROVIDER_H__
#define __SINGLE_IMAGE_PROVIDER_H__
#include <gdal_priv.h>
#include <openspace/engine/downloadmanager.h>
#include <set>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h> // absPath
#include <ghoul/opengl/texture.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/font/fontrenderer.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/tile/asynctilereader.h>
namespace openspace {
using namespace ghoul::opengl;
class SingleImagePrivoder : public TileProvider {
public:
SingleImagePrivoder(const std::string& imagePath);
virtual ~SingleImagePrivoder() { }
virtual Tile getTile(const ChunkIndex& chunkIndex);
virtual Tile getDefaultTile();
virtual Tile::Status getTileStatus(const ChunkIndex& index);
virtual TileDepthTransform depthTransform();
virtual void update();
virtual void reset();
virtual int maxLevel();
private:
Tile _tile;
std::string _imagePath;
};
} // namespace openspace
#endif // __SINGLE_IMAGE_PROVIDER_H__

View File

@@ -24,7 +24,7 @@
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/temporaltileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/temporaltileprovider.h>
#include <modules/globebrowsing/tile/tileproviderfactory.h>
#include <modules/globebrowsing/chunk/chunkindex.h>

View File

@@ -29,14 +29,13 @@
#include <ghoul/opengl/texture.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <openspace/util/time.h>
#include <unordered_map>
#include "gdal_priv.h"
#include <gdal_priv.h>
@@ -47,18 +46,6 @@
namespace openspace {
struct TileProviderInitData {
int minimumPixelSize;
int threads;
int cacheSize;
int framesUntilRequestQueueFlush;
bool preprocessTiles = false;
};
//////////////////////////////////////////////////////////////////////////////////////
// Time Id Providers //
//////////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,90 @@
/*****************************************************************************************
* *
* 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 <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/chunk/chunkindex.h>
#include <openspace/engine/downloadmanager.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/font/fontmanager.h>
#include <openspace/engine/openspaceengine.h>
#include <sstream>
namespace {
const std::string _loggerCat = "TileProvider";
}
namespace openspace {
const Tile Tile::TileUnavailable = {nullptr, nullptr, Tile::Status::Unavailable };
Tile Tile::createPlainTile(const glm::uvec2& size, const glm::uvec4& color) {
using namespace ghoul::opengl;
// Create pixel data
int numBytes = size.x * size.y * 4 * 1;
char* pixels = new char[numBytes];
size_t numPixels = size.x * size.y;
size_t i = 0;
for (size_t p = 0; p < numPixels; p++){
pixels[i++] = color.r;
pixels[i++] = color.g;
pixels[i++] = color.b;
pixels[i++] = color.a;
}
// Create ghoul texture
auto texture = std::make_shared<Texture>(glm::uvec3(size, 1));
texture->setDataOwnership(Texture::TakeOwnership::Yes);
texture->setPixelData(pixels);
texture->uploadTexture();
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
// Create tile
Tile tile;
tile.status = Tile::Status::OK;
tile.preprocessData = nullptr;
tile.texture = texture;
return tile;
}
} // namespace openspace

View File

@@ -0,0 +1,105 @@
/*****************************************************************************************
* *
* 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. *
****************************************************************************************/
#ifndef __TILE_PROVIDER_H__
#define __TILE_PROVIDER_H__
#include <gdal_priv.h>
#include <openspace/engine/downloadmanager.h>
#include <set>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h> // absPath
#include <ghoul/opengl/texture.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/font/fontrenderer.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/asynctilereader.h>
#include <modules/globebrowsing/other/lrucache.h>
//////////////////////////////////////////////////////////////////////////////////////////
// TILE PROVIDER //
//////////////////////////////////////////////////////////////////////////////////////////
namespace openspace {
using namespace ghoul::opengl;
struct Tile {
std::shared_ptr<Texture> texture;
std::shared_ptr<TilePreprocessData> preprocessData;
enum class Status { Unavailable, OutOfRange, IOError, OK } status;
/**
* Instantiaes a new tile unicolored tile. The texture gets the provided size and
* color in rgba. Color values ranges between 0-255.
*/
static Tile createPlainTile(const glm::uvec2& size, const glm::uvec4& color);
static const Tile TileUnavailable;
};
class TileProvider {
public:
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;
virtual void reset() = 0;
virtual int maxLevel() = 0;
};
typedef LRUCache<ChunkHashKey, Tile> TileCache;
struct TileProviderInitData {
int minimumPixelSize;
int threads;
int cacheSize;
int framesUntilRequestQueueFlush;
bool preprocessTiles = false;
};
} // namespace openspace
#endif // __TILE_PROVIDER_H__

View File

@@ -24,6 +24,11 @@
#include <modules/globebrowsing/tile/tileproviderfactory.h>
#include <modules/globebrowsing/tile/tileprovider/singleimageprovider.h>
#include <modules/globebrowsing/tile/tileprovider/cachingtileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/temporaltileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h>
#include <ghoul/logging/logmanager.h>
#include "cpl_minixml.h"
@@ -82,9 +87,9 @@ namespace openspace {
TileDataset::Configuration config;
config.doPreProcessing = initData.preprocessTiles;
config.minimumTilePixelSize = initData.minimumPixelSize;
auto tileDataset = std::make_shared<TileDataset>(desc, config);
auto threadPool = std::make_shared<ThreadPool>(1);
auto threadPool = std::make_shared<ghoul::ThreadPool>(1);
auto tileReader = std::make_shared<AsyncTileDataProvider>(tileDataset, threadPool);
auto tileCache = std::make_shared<TileCache>(initData.cacheSize);
auto tileProvider = std::make_shared<CachingTileProvider>(tileReader, tileCache, initData.framesUntilRequestQueueFlush);

View File

@@ -26,8 +26,7 @@
#define __TILE_PROVIDER_FACTORY_H__
#include <modules/globebrowsing/tile/temporaltileprovider.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <ghoul/misc/dictionary.h>

View File

@@ -66,7 +66,6 @@ namespace openspace {
//////////////////////////////////////////////////////////////////////////////////////
TileProviderManager::TileProviderManager(
const ghoul::Dictionary& textureCategoriesDictionary,
const ghoul::Dictionary& textureInitDictionary){

View File

@@ -26,13 +26,10 @@
#define __TILE_PROVIDER_MANAGER_H__
#include <modules/globebrowsing/tile/temporaltileprovider.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/temporaltileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/tile/layeredtextures.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <ghoul/misc/dictionary.h>
#include <memory>
@@ -72,6 +69,7 @@ namespace openspace {
const ghoul::Dictionary& textureInitDictionary);
~TileProviderManager();
TileProviderGroup& getTileProviderGroup(size_t groupId);
TileProviderGroup& getTileProviderGroup(LayeredTextures::TextureCategory);

View File

@@ -28,7 +28,7 @@
#include "gdal_priv.h"
#include <modules/globebrowsing/chunk/chunkindex.h>
#include <modules/globebrowsing/tile/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/tile/tileprovidermanager.h>
#include <vector>

View File

@@ -58,19 +58,7 @@ void GuiPerformanceComponent::render() {
ImGui::Begin("Performance", &_isEnabled);
if (OsEng.renderEngine().doesPerformanceMeasurements()) {
ghoul_assert(
SharedMemory::exists(PerformanceManager::PerformanceMeasurementSharedData),
"Shared Memory block was not allocated"
);
if (!_performanceMemory) {
_performanceMemory = std::make_unique<ghoul::SharedMemory>(
PerformanceManager::PerformanceMeasurementSharedData
);
}
PerformanceLayout* layout = reinterpret_cast<PerformanceLayout*>(
_performanceMemory->memory()
);
PerformanceLayout* layout = OsEng.renderEngine().performanceManager()->performanceData();
ImGui::Checkbox("SceneGraph", &_sceneGraphIsEnabled);
ImGui::Checkbox("Functions", &_functionsIsEnabled);

View File

@@ -11,6 +11,9 @@ helper.setCommonKeys = function()
openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)")
openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)")
openspace.bindKey("t", "openspace.toggleFrametimeType(1)")
openspace.bindKey("Shift+t", "openspace.toggleFrametimeType(0)")
openspace.bindKey("ESC", "openspace.toggleShutdown()")
openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()")

View File

@@ -61,6 +61,10 @@ bool SGCTWindowWrapper::windowHasResized() const {
double SGCTWindowWrapper::averageDeltaTime() const {
return sgct::Engine::instance()->getAvgDt();
}
double SGCTWindowWrapper::deltaTime() const {
return sgct::Engine::instance()->getDt();
}
glm::vec2 SGCTWindowWrapper::mousePosition() const {
int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId();

View File

@@ -45,6 +45,10 @@ bool WindowWrapper::windowHasResized() const {
double WindowWrapper::averageDeltaTime() const {
return 0.0;
}
double WindowWrapper::deltaTime() const {
return 0.0;
}
glm::vec2 WindowWrapper::mousePosition() const {
return glm::vec2(0.f);

View File

@@ -29,41 +29,153 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/sharedmemory.h>
#include <ghoul/misc/onscopeexit.h>
namespace {
const std::string _loggerCat = "PerformanceManager";
const std::string GlobalSharedMemoryName = "OpenSpacePerformanceMeasurementData";
// Probably 255 performance blocks per node are enough, so we can get away with
// 4 bytes (one uint8_t for the number, one uint8_t for the reference count to keep
// the global memory alive, and 2 bytes to enforce alignment)
const size_t GlobalSharedMemorySize = 4;
const int MaximumNumber = 256;
struct GlobalMemory {
uint8_t number;
uint8_t referenceCount;
std::array<uint8_t, 2> alignment;
};
const std::string LocalSharedMemoryNameBase = "PerformanceMeasurement_";
}
namespace openspace {
namespace performance {
const std::string PerformanceManager::PerformanceMeasurementSharedData =
"OpenSpacePerformanceMeasurementSharedData";
// The Performance Manager will use a level of indirection in order to support multiple
// PerformanceManagers running in parallel:
// The ghoul::SharedData block addressed by OpenSpacePerformanceMeasurementSharedData
// will only get allocated once and contains the total number of allocated shared memory
// blocks alongside a list of names of these blocks
//
void PerformanceManager::createGlobalSharedMemory() {
static_assert(
sizeof(GlobalMemory) == GlobalSharedMemorySize,
"The global memory struct does not fit the allocated global memory space"
);
using ghoul::SharedMemory;
if (SharedMemory::exists(GlobalSharedMemoryName)) {
SharedMemory sharedMemory(GlobalSharedMemoryName);
sharedMemory.acquireLock();
GlobalMemory* m = reinterpret_cast<GlobalMemory*>(sharedMemory.memory());
++(m->referenceCount);
LINFO(
"Using global shared memory block for performance measurements. "
"Reference count: " << int(m->referenceCount)
);
sharedMemory.releaseLock();
}
else {
LINFO("Creating global shared memory block for performance measurements");
SharedMemory::create(GlobalSharedMemoryName, GlobalSharedMemorySize);
// Initialize the data
SharedMemory sharedMemory(GlobalSharedMemoryName);
sharedMemory.acquireLock();
new (sharedMemory.memory()) GlobalMemory;
GlobalMemory* m = reinterpret_cast<GlobalMemory*>(sharedMemory.memory());
m->number = 0;
m->referenceCount = 1;
sharedMemory.releaseLock();
}
}
void PerformanceManager::destroyGlobalSharedMemory() {
using ghoul::SharedMemory;
if (!SharedMemory::exists(GlobalSharedMemoryName)) {
LWARNING("Global shared memory for Performance measurements did not exist");
return;
}
SharedMemory sharedMemory(GlobalSharedMemoryName);
sharedMemory.acquireLock();
GlobalMemory* m = reinterpret_cast<GlobalMemory*>(sharedMemory.memory());
--(m->referenceCount);
LINFO("Global shared performance memory reference count: " << int(m->referenceCount));
if (m->referenceCount == 0) {
LINFO("Removing global shared performance memory");
// When the global memory is deleted, we have to get rid of all local memory as
// well. In principle, none should be left, but OpenSpace crashing might leave
// some of the memory orphaned
for (int i = 0; i < std::numeric_limits<uint8_t>::max(); ++i) {
std::string localName = LocalSharedMemoryNameBase + std::to_string(i);
if (SharedMemory::exists(localName)) {
LINFO("Removing shared memory: " << localName);
SharedMemory::remove(localName);
}
}
SharedMemory::remove(GlobalSharedMemoryName);
}
sharedMemory.releaseLock();
}
PerformanceManager::PerformanceManager()
: _performanceMemory(nullptr)
{
using ghoul::SharedMemory;
PerformanceManager::createGlobalSharedMemory();
SharedMemory sharedMemory(GlobalSharedMemoryName);
sharedMemory.acquireLock();
OnExit([&](){sharedMemory.releaseLock();});
GlobalMemory* m = reinterpret_cast<GlobalMemory*>(sharedMemory.memory());
// The the first free block (which also coincides with the number of blocks
uint8_t blockIndex = m->number;
++(m->number);
std::string localName = LocalSharedMemoryNameBase + std::to_string(blockIndex);
// Compute the total size
const int totalSize = sizeof(PerformanceLayout);
LINFO("Create shared memory of " << totalSize << " bytes");
LINFO("Create shared memory '" + localName + "' of " << totalSize << " bytes");
if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) {
LWARNING("Shared memory for Performance measurements already existed. Removing.");
ghoul::SharedMemory::remove(PerformanceMeasurementSharedData);
if (SharedMemory::exists(localName)) {
throw ghoul::RuntimeError(
"Shared Memory '" + localName + "' block already existed"
);
}
ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize);
_performanceMemory = std::make_unique<ghoul::SharedMemory>(PerformanceMeasurementSharedData);
void* ptr = _performanceMemory->memory();
ghoul::SharedMemory::create(localName, totalSize);
_performanceMemory = std::make_unique<ghoul::SharedMemory>(localName);
// Using the placement-new to create a PerformanceLayout in the shared memory
new (ptr) PerformanceLayout;
new (_performanceMemory->memory()) PerformanceLayout;
}
PerformanceManager::~PerformanceManager() {
ghoul::SharedMemory::remove(PerformanceMeasurementSharedData);
if (_performanceMemory) {
ghoul::SharedMemory sharedMemory(GlobalSharedMemoryName);
sharedMemory.acquireLock();
GlobalMemory* m = reinterpret_cast<GlobalMemory*>(sharedMemory.memory());
--(m->number);
sharedMemory.releaseLock();
LINFO("Remove shared memory '" << _performanceMemory->name() << "'");
ghoul::SharedMemory::remove(_performanceMemory->name());
}
PerformanceManager::destroyGlobalSharedMemory();
}
void PerformanceManager::resetPerformanceMeasurements() {
@@ -79,12 +191,16 @@ void PerformanceManager::resetPerformanceMeasurements() {
bool PerformanceManager::isMeasuringPerformance() const {
return _doPerformanceMeasurements;
}
PerformanceLayout* PerformanceManager::performanceData() {
void* ptr = _performanceMemory->memory();
return reinterpret_cast<PerformanceLayout*>(ptr);
}
void PerformanceManager::storeIndividualPerformanceMeasurement
(std::string identifier, long long microseconds)
{
void* ptr = _performanceMemory->memory();
PerformanceLayout* layout = reinterpret_cast<PerformanceLayout*>(ptr);
PerformanceLayout* layout = performanceData();
_performanceMemory->acquireLock();
auto it = individualPerformanceLocations.find(identifier);
@@ -119,8 +235,7 @@ void PerformanceManager::storeScenePerformanceMeasurements(
{
using namespace performance;
void* ptr = _performanceMemory->memory();
PerformanceLayout* layout = reinterpret_cast<PerformanceLayout*>(ptr);
PerformanceLayout* layout = performanceData();
_performanceMemory->acquireLock();
int nNodes = static_cast<int>(sceneNodes.size());

View File

@@ -106,7 +106,12 @@ namespace openspace {
const std::string RenderEngine::KeyFontMono = "Mono";
const std::string RenderEngine::KeyFontLight = "Light";
const std::vector<RenderEngine::FrametimeType> RenderEngine::FrametimeTypes({
RenderEngine::FrametimeType::DtTimeAvg,
RenderEngine::FrametimeType::FPS,
RenderEngine::FrametimeType::FPSAvg
});
RenderEngine::RenderEngine()
: _mainCamera(nullptr)
, _sceneGraph(nullptr)
@@ -121,6 +126,7 @@ RenderEngine::RenderEngine()
, _fadeDuration(2.f)
, _currentFadeTime(0.f)
, _fadeDirection(0)
, _frametimeType(FrametimeType::DtTimeAvg)
// , _sgctRenderStatisticsVisible(false)
{
_onScreenInformation = {
@@ -461,6 +467,21 @@ void RenderEngine::toggleInfoText(bool b) {
_showInfo = b;
}
void RenderEngine::toggleFrametimeType(int t) {
std::vector<FrametimeType>::const_iterator it = std::find(
FrametimeTypes.begin(), FrametimeTypes.end(), _frametimeType);
if (!t && it == FrametimeTypes.begin())
it = FrametimeTypes.end();
t > 0 ? ++it : --it;
if (t && it == FrametimeTypes.end())
it = FrametimeTypes.begin();
_frametimeType = *it;
}
Scene* RenderEngine::scene() {
// TODO custom assert (ticket #5)
assert(_sceneGraph);
@@ -714,6 +735,12 @@ scripting::LuaLibrary RenderEngine::luaLibrary() {
"bool",
"Toggles the showing of render information on-screen text"
},
{
"toggleFrametimeType",
&luascriptfunctions::toggleFrametimeType,
"int",
"Toggle showing FPS or Average Frametime in heads up info"
},
{
"setPerformanceMeasurement",
&luascriptfunctions::setPerformanceMeasurement,
@@ -760,11 +787,13 @@ scripting::LuaLibrary RenderEngine::luaLibrary() {
void RenderEngine::setPerformanceMeasurements(bool performanceMeasurements) {
if (performanceMeasurements) {
if (!_performanceManager)
if (!_performanceManager) {
_performanceManager = std::make_unique<performance::PerformanceManager>();
}
}
else
else {
_performanceManager = nullptr;
}
}
bool RenderEngine::doesPerformanceMeasurements() const {
@@ -1249,11 +1278,36 @@ void RenderEngine::renderInformation() {
Time::ref().deltaTime()
);
RenderFontCr(*_fontInfo,
penPosition,
"Avg. Frametime: %.5f",
OsEng.windowWrapper().averageDeltaTime()
);
switch (_frametimeType) {
case FrametimeType::DtTimeAvg:
RenderFontCr(*_fontInfo,
penPosition,
"Avg. Frametime: %.5f",
OsEng.windowWrapper().averageDeltaTime()
);
break;
case FrametimeType::FPS:
RenderFontCr(*_fontInfo,
penPosition,
"FPS: %3.2f",
1.0 / OsEng.windowWrapper().deltaTime()
);
break;
case FrametimeType::FPSAvg:
RenderFontCr(*_fontInfo,
penPosition,
"Avg. FPS: %3.2f",
1.0 / OsEng.windowWrapper().averageDeltaTime()
);
break;
default:
RenderFontCr(*_fontInfo,
penPosition,
"Avg. Frametime: %.5f",
OsEng.windowWrapper().averageDeltaTime()
);
break;
}
#ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED
bool hasNewHorizons = scene()->sceneGraphNode("NewHorizons");

View File

@@ -33,8 +33,9 @@ namespace luascriptfunctions {
*/
int takeScreenshot(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 0)
if (nArguments != 0) {
return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments);
}
OsEng.renderEngine().takeScreenshot();
return 0;
}
@@ -46,12 +47,14 @@ int takeScreenshot(lua_State* L) {
*/
int setRenderer(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
const int type = lua_type(L, -1);
if (type != LUA_TSTRING)
if (type != LUA_TSTRING) {
return luaL_error(L, "Expected argument of type 'string'");
}
std::string r = lua_tostring(L, -1);
OsEng.renderEngine().setRendererFromString(r);
return 0;
@@ -64,8 +67,9 @@ int setRenderer(lua_State* L) {
*/
int setNAaSamples(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
double t = luaL_checknumber(L, -1);
@@ -77,21 +81,41 @@ int setNAaSamples(lua_State* L) {
/**
* \ingroup LuaScripts
* visualizeABuffer(bool):
* Toggle the visualization of the ABuffer
* Toggle heads-up info display on master node
*/
int showRenderInformation(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
const int type = lua_type(L, -1);
if (type != LUA_TBOOLEAN)
if (type != LUA_TBOOLEAN) {
return luaL_error(L, "Expected argument of type 'bool'");
}
bool b = lua_toboolean(L, -1) != 0;
OsEng.renderEngine().toggleInfoText(b);
return 0;
}
/**
* \ingroup LuaScripts
* toggleFramerateType(bool):
* Cycle through showing FPS or Average Frametime in heads up info
*/
int toggleFrametimeType(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
const int type = lua_type(L, -1);
if (type != LUA_TNUMBER)
return luaL_error(L, "Expected argument of type 'number'");
int t = lua_tonumber(L, -1);
OsEng.renderEngine().toggleFrametimeType(t);
return 0;
}
/**
* \ingroup LuaScripts
* visualizeABuffer(bool):
@@ -99,8 +123,9 @@ int showRenderInformation(lua_State* L) {
*/
int setPerformanceMeasurement(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
bool b = lua_toboolean(L, -1) != 0;
OsEng.renderEngine().setPerformanceMeasurements(b);
@@ -114,8 +139,9 @@ int setPerformanceMeasurement(lua_State* L) {
*/
int toggleFade(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
double t = luaL_checknumber(L, -1);
@@ -133,8 +159,9 @@ int toggleFade(lua_State* L) {
*/
int fadeIn(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
double t = luaL_checknumber(L, -1);
@@ -148,8 +175,9 @@ int fadeIn(lua_State* L) {
*/
int fadeOut(lua_State* L) {
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
double t = luaL_checknumber(L, -1);
@@ -161,8 +189,9 @@ int registerScreenSpaceRenderable(lua_State* L) {
using ghoul::lua::errorLocation;
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
ghoul::Dictionary d;
try {
@@ -183,8 +212,9 @@ int unregisterScreenSpaceRenderable(lua_State* L) {
using ghoul::lua::errorLocation;
int nArguments = lua_gettop(L);
if (nArguments != 1)
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
std::string name = luaL_checkstring(L, -1);

View File

@@ -1,156 +0,0 @@
# Find the library
if(WIN32)
# Check for visual studio
if(NOT MSVC)
message(FATAL_ERROR "Only visual studio supported!")
endif(NOT MSVC)
# make sure sgct knows about windows
add_definitions(-D__WIN32__)
# search for SGCT, 64-bit and 32-bit
if (CMAKE_CL_64)
set(SGCT_PATH "C:/Program Files/SGCT")
else (CMAKE_CL_64)
set(SGCT_PATH "C:/Program Files (x86)/SGCT")
endif (CMAKE_CL_64)
file(GLOB SGCT_WINDOWS_PATHS "${SGCT_PATH}/SGCT_*")
# sort and reverse the list to find the most recent (a.k.a. highest number) version
list(SORT SGCT_WINDOWS_PATHS)
list(REVERSE SGCT_WINDOWS_PATHS)
foreach(path ${SGCT_WINDOWS_PATHS})
find_path(SGCT_ROOT_DIR include/sgct.h HINTS
"${path}"
)
if (SGCT_ROOT_DIR)
break()
endif ()
endforeach(path)
# Check if found the SGCT root directory
if(NOT SGCT_ROOT_DIR)
message("Could not locate SGCT in ${SGCT_PATH}!")
endif(NOT SGCT_ROOT_DIR)
find_path(SGCT_ROOT_DIR include/sgct.h HINTS
"${SGCT_WINDOWS_PATHS}"
)
# construct the correct library path
if (MSVC10)
set(SGCT_LIBRARY_FOLDER "${SGCT_ROOT_DIR}/lib/msvc10")
elseif (MSVC11)
set(SGCT_LIBRARY_FOLDER "${SGCT_ROOT_DIR}/lib/msvc11")
elseif (MSVC12)
set(SGCT_LIBRARY_FOLDER "${SGCT_ROOT_DIR}/lib/msvc12")
elseif (MSVC14)
set(SGCT_LIBRARY_FOLDER "${SGCT_ROOT_DIR}/lib/msvc14")
endif (MSVC10)
if (CMAKE_CL_64)
set(SGCT_LIBRARY_FOLDER "${SGCT_LIBRARY_FOLDER}_x64")
endif (CMAKE_CL_64)
# Find the sgct library
set(SGCT_LIBRARY
"ws2_32.lib"
optimized "${SGCT_LIBRARY_FOLDER}/sgct.lib"
debug "${SGCT_LIBRARY_FOLDER}/sgctd.lib"
)
else()
find_path(SGCT_ROOT_DIR include/sgct.h HINTS
"/opt/local/include/sgct"
"/usr/local/include/sgct"
"/usr/include/sgct"
"/opt/local"
"/usr/local"
"/usr"
)
if(NOT SGCT_ROOT_DIR)
message(FATAL_ERROR "Could not locate SGCT!")
endif(NOT SGCT_ROOT_DIR)
# OS X has cpp11 support
if (APPLE)
set(SGCT_NAME "sgct_cpp11")
else(APPLE)
set(SGCT_NAME "sgct")
endif(APPLE)
# check if debug or release version of sgct should be used
if(CMAKE_BUILD_TYPE MATCHES Debug)
set(SGCT_NAME "${SGCT_NAME}d")
endif(CMAKE_BUILD_TYPE MATCHES Debug)
# Find the sgct library
find_library(SGCT_LIBRARY NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}${SGCT_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}
HINTS "${SGCT_ROOT_DIR}/lib")
endif()
# make sure glew is static
add_definitions(-DGLEW_STATIC)
if (APPLE)
find_library(FRAMEWORK_IOKit
NAMES IOKit
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH
)
find_library(FRAMEWORK_CoreVideo
NAMES CoreVideo
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH
)
find_library(FRAMEWORK_Cocoa
NAMES Cocoa
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH
)
set(SGCT_DEPENDENCIES ${SGCT_DEPENDENCIES} ${FRAMEWORK_IOKit} ${FRAMEWORK_CoreVideo} ${FRAMEWORK_Cocoa})
endif (APPLE)
if(UNIX AND NOT APPLE)
find_package(XRandR)
find_package(Xi)
find_package(Threads)
if(NOT XRANDR_FOUND)
message(FATAL_ERROR "XRandR not found!")
endif(NOT XRANDR_FOUND)
if(NOT XI_FOUND)
message(FATAL_ERROR "Xi not found!")
endif(NOT XI_FOUND)
if(NOT THREADS_FOUND)
message(FATAL_ERROR "Threads not found!")
endif(NOT THREADS_FOUND)
set(SGCT_DEPENDENCIES ${SGCT_DEPENDENCIES} ${XRANDR_LIBRARIES} ${XI_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} Xxf86vm )
endif(UNIX AND NOT APPLE)
# includes
set(SGCT_INCLUDES "${SGCT_ROOT_DIR}/include")
include_directories(${SGCT_INCLUDE_DIRS})
# libraries
set(SGCT_INCLUDE_DIRECTORIES ${SGCT_INCLUDES})
set(SGCT_LIBRARIES ${SGCT_LIBRARY} ${SGCT_DEPENDENCIES})
# handle the QUIETLY and REQUIRED arguments and set SGCT_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(SGCT DEFAULT_MSG
SGCT_LIBRARY SGCT_INCLUDES)
mark_as_advanced(SGCT_INCLUDE_DIR SGCT_LIBRARY )
if(SGCT_FOUND)
MESSAGE(STATUS "SGCT found: ${SGCT_INCLUDES}/sgct.h")
else()
MESSAGE(FATAL_ERROR "SGCT not found!")
endif(SGCT_FOUND)

View File

@@ -1,25 +0,0 @@
set(SPICE_INCLUDE_DIR "${SPICE_ROOT_DIR}/include")
if(WIN32)
if (${MSVC_VERSION} EQUAL 1800)
set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/msvc12/cspice.lib")
endif ()
if (${MSVC_VERSION} EQUAL 1900)
set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/msvc14/cspice.lib")
endif ()
elseif(APPLE)
set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/gcc_osx/cspice.a")
else()
set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/gcc_linux/cspice.a")
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SPICE DEFAULT_MSG SPICE_LIBRARY SPICE_INCLUDE_DIR)
if(SPICE_FOUND)
set(SPICE_LIBRARIES ${SPICE_LIBRARY})
set(SPICE_INCLUDE_DIRS ${SPICE_INCLUDE_DIR})
endif()
mark_as_advanced(SPICE_INCLUDE_DIR SPICE_LIBRARY)

File diff suppressed because it is too large Load Diff

View File

@@ -38,7 +38,6 @@
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
//#include <test_chunknode.inl>
#include <test_lrucache.inl>
#include <test_threadpool.inl>
#include <test_aabb.inl>
#include <test_convexhull.inl>

View File

@@ -25,7 +25,7 @@
#include "gtest/gtest.h"
#include <modules/globebrowsing/other/concurrentjobmanager.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <ghoul/misc/threadpool.h>
#define _USE_MATH_DEFINES
#include <math.h>
@@ -68,7 +68,7 @@ private:
TEST_F(ConcurrentJobManagerTest, Basic) {
std::shared_ptr<ThreadPool> pool = std::make_shared<ThreadPool>(1);
std::shared_ptr<ghoul::ThreadPool> pool = std::make_shared<ghoul::ThreadPool>(1);
ConcurrentJobManager<int> jobManager(pool);
@@ -147,7 +147,7 @@ struct VerboseJob : public Job<VerboseProduct>{
TEST_F(ConcurrentJobManagerTest, JobCreation) {
std::shared_ptr<ThreadPool> pool = std::make_shared<ThreadPool>(1);
std::shared_ptr<ghoul::ThreadPool> pool = std::make_shared<ghoul::ThreadPool>(1);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));

View File

@@ -1,59 +0,0 @@
/*****************************************************************************************
* *
* 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 "gtest/gtest.h"
#include <modules/globebrowsing/other/threadpool.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <glm/glm.hpp>
class ThreadPoolTest : public testing::Test {};
using namespace openspace;
using namespace std::chrono_literals;
TEST_F(ThreadPoolTest, Basic) {
ThreadPool pool(5);
int val = 0;
for (int i = 0; i < 10; ++i) {
pool.enqueue([&val, i]() {
std::this_thread::sleep_for(std::chrono::milliseconds(100 + 10*i));
val++;
});
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
EXPECT_EQ(10, val) << "10 tasks taking 100 to 190 ms on 5 threads should take less than 1000 ms";
}