Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 0be65bc3 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Merge branch 'tgt-dll' into 'development'

Tgt Dll
parents da038689 464f1ff4
......@@ -27,11 +27,11 @@
#include "tgt/assert.h"
#include "tgt/exception.h"
#include "tgt/glcanvas.h"
#include "tgt/glcontextmanager.h"
#include "tgt/gpucapabilities.h"
#include "tgt/shadermanager.h"
#include "tgt/qt/qtapplication.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tbb/compat/thread"
#include "application/campvispainter.h"
......@@ -61,7 +61,7 @@ namespace campvis {
QApplication::setAttribute(Qt::AA_X11InitThreads);
_mainWindow = new MainWindow(this);
tgt::QtContextManager::init();
tgt::GlContextManager::init();
OpenGLJobProcessor::init();
SimpleJobProcessor::init();
......@@ -85,23 +85,14 @@ namespace campvis {
void CampVisApplication::init() {
tgtAssert(_initialized == false, "Tried to initialize CampVisApplication twice.");
// parse argument list and create pipelines
QStringList pipelinesToAdd = this->arguments();
for (int i = 1; i < pipelinesToAdd.size(); ++i) {
DataContainer* dc = createAndAddDataContainer("DataContainer #" + StringUtils::toString(_dataContainers.size() + 1));
AbstractPipeline* p = PipelineFactory::getRef().createPipeline(pipelinesToAdd[i].toStdString(), dc);
if (p != 0)
addPipeline(pipelinesToAdd[i].toStdString(), p);
}
// Init TGT
tgt::InitFeature::Features featureset = tgt::InitFeature::ALL;
tgt::init(featureset);
LogMgr.getConsoleLog()->addCat("", true);
// create a local OpenGL context and init GL
_localContext = tgt::GlContextManager::getRef().createContext("AppContext", "", tgt::ivec2(16, 16));
tgtAssert(_localContext != 0, "Could not create local OpenGL context");
_localContext = new QtThreadedCanvas("", tgt::ivec2(16, 16));
tgt::GlContextManager::getRef().registerContextAndInitGlew(_localContext);
tgt::GLContextScopedLock lock(_localContext);
......@@ -143,18 +134,18 @@ namespace campvis {
LERROR("Your system does not support GLSL Shader Version 3.30, which is mandatory. CAMPVis will probably not work as intended.");
}
// init pipeline first
for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
(*it)->init();
}
GLJobProc.start();
GLJobProc.registerContext(_localContext);
// Now init painters:
for (std::vector< std::pair<AbstractPipeline*, CampVisPainter*> >::iterator it = _visualizations.begin(); it != _visualizations.end(); ++it) {
it->second->init();
// parse argument list and create pipelines
QStringList pipelinesToAdd = this->arguments();
for (int i = 1; i < pipelinesToAdd.size(); ++i) {
DataContainer* dc = createAndAddDataContainer("DataContainer #" + StringUtils::toString(_dataContainers.size() + 1));
AbstractPipeline* p = PipelineFactory::getRef().createPipeline(pipelinesToAdd[i].toStdString(), dc);
if (p != 0)
addPipeline(pipelinesToAdd[i].toStdString(), p);
}
GLJobProc.start();
GLJobProc.registerContext(_localContext);
_initialized = true;
}
......@@ -188,7 +179,7 @@ namespace campvis {
OpenGLJobProcessor::deinit();
PipelineFactory::deinit();
tgt::QtContextManager::deinit();
tgt::GlContextManager::deinit();
tgt::deinit();
// MainWindow dtor needs a valid CampVisApplication, so we need to call it here instead of during destruction.
......@@ -214,30 +205,8 @@ namespace campvis {
void CampVisApplication::addPipeline(const std::string& name, AbstractPipeline* pipeline) {
tgtAssert(pipeline != 0, "Pipeline must not be 0.");
// if CAMPVis is already fully initialized, we need to temporarily shut down its
// OpenGL job processor, since we need to create a new context.
if (_initialized) {
GLJobProc.pause();
{
tgt::QtThreadedCanvas* canvas = dynamic_cast<tgt::QtThreadedCanvas*>(tgt::GlContextManager::getRef().createContext(name, "CAMPVis", tgt::ivec2(512, 512)));
tgtAssert(canvas != 0, "Dynamic cast failed. This should not be the case, since we initialized the GlContextManager singleton with a QtContextManager.");
tgt::GLContextScopedLock lock(canvas);
addPipelineImpl(canvas, name, pipeline);
}
GLJobProc.resume();
}
else {
tgt::QtThreadedCanvas* canvas = dynamic_cast<tgt::QtThreadedCanvas*>(tgt::GlContextManager::getRef().createContext(name, "CAMPVis", tgt::ivec2(512, 512)));
tgtAssert(canvas != 0, "Dynamic cast failed. This should not be the case, since we initialized the GlContextManager singleton with a QtContextManager.");
addPipelineImpl(canvas, name, pipeline);
}
s_PipelinesChanged();
}
void CampVisApplication::addPipelineImpl(tgt::QtThreadedCanvas* canvas, const std::string& name, AbstractPipeline* pipeline) {
// create canvas and painter for the pipeline and connect all together
tgt::QtThreadedCanvas* canvas = new tgt::QtThreadedCanvas("CAMPVis", tgt::ivec2(512, 512));
GLJobProc.registerContext(canvas);
canvas->init();
......@@ -248,17 +217,25 @@ namespace campvis {
_visualizations.push_back(std::make_pair(pipeline, painter));
_pipelines.push_back(pipeline);
if (_initialized) {
LGL_ERROR;
pipeline->init();
LGL_ERROR;
painter->init();
LGL_ERROR;
}
tgt::GlContextManager::getRef().releaseCurrentContext();
_mainWindow->addVisualizationPipelineWidget(name, canvas);
// initialize context (GLEW) and pipeline in OpenGL thread)
GLJobProc.enqueueJob(
canvas,
makeJobOnHeap<CampVisApplication, tgt::GLCanvas*, AbstractPipeline*>(this, &CampVisApplication::initGlContextAndPipeline, canvas, pipeline),
OpenGLJobProcessor::SerialJob);
s_PipelinesChanged();
}
void CampVisApplication::initGlContextAndPipeline(tgt::GLCanvas* canvas, AbstractPipeline* pipeline) {
tgt::GlContextManager::getRef().registerContextAndInitGlew(canvas);
pipeline->init();
LGL_ERROR;
canvas->getPainter()->init();
LGL_ERROR;
// enable pipeline and invalidate all processors
pipeline->setEnabled(true);
for (std::vector<AbstractProcessor*>::const_iterator it = pipeline->getProcessors().begin(); it != pipeline->getProcessors().end(); ++it) {
......
......@@ -130,7 +130,8 @@ namespace campvis {
sigslot::signal0<> s_DataContainersChanged;
private:
void addPipelineImpl(tgt::QtThreadedCanvas* canvas, const std::string& name, AbstractPipeline* pipeline);
void initGlContextAndPipeline(tgt::GLCanvas* canvas, AbstractPipeline* pipeline);
/// All pipelines
std::vector<AbstractPipeline*> _pipelines;
......
......@@ -29,7 +29,7 @@
#include "tgt/painter.h"
#include "tgt/event/eventlistener.h"
#include "tgt/event/mouseevent.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tgt/glcontextmanager.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "tbb/mutex.h"
......
......@@ -29,8 +29,6 @@
#include "tgt/filesystem.h"
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tgt/qt/qtthreadedcanvas.h"
#ifdef CAMPVIS_HAS_MODULE_DEVIL
#include <IL/il.h>
......@@ -53,7 +51,7 @@
#include "application/gui/datacontainertreewidget.h"
#include "application/gui/qtdatahandle.h"
#include "application//gui/datacontainerfileloaderwidget.h"
#include "application/gui/datacontainerfileloaderwidget.h"
#include "modules/io/processors/genericimagereader.h"
#include <QFileDialog>
......
......@@ -27,8 +27,6 @@
#include "sigslot/sigslot.h"
#include "tgt/painter.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "tbb/mutex.h"
#include "application/gui/qtdatahandle.h"
......
......@@ -27,8 +27,6 @@
#include "sigslot/sigslot.h"
#include "tgt/painter.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "tbb/mutex.h"
#include "application/tools/bufferinglog.h"
......
......@@ -248,8 +248,8 @@ namespace campvis {
QLabel* lblOpacityBottom = new QLabel(tr("0%"), this);
_layout->addWidget(lblOpacityBottom, 3, 0, 1, 1, Qt::AlignRight);
_canvas = dynamic_cast<tgt::QtThreadedCanvas*>(tgt::GlContextManager::getRef().createContext("tfcanvas", "", tgt::ivec2(256, 128), tgt::GLCanvas::RGBA_BUFFER, false));
tgtAssert(_canvas != 0, "Could not cast to QtThreadedCanvas*, something is wrong here!");
_canvas = new tgt::QtThreadedCanvas("", tgt::ivec2(256, 128), tgt::GLCanvas::RGBA_BUFFER, false);
tgt::GlContextManager::getRef().registerContextAndInitGlew(_canvas);
GLJobProc.registerContext(_canvas);
_canvas->setPainter(this, false);
......
......@@ -229,8 +229,8 @@ namespace campvis {
QLabel* lblOpacityBottom = new QLabel(tr("0%"), this);
_layout->addWidget(lblOpacityBottom, 3, 0, 1, 1, Qt::AlignRight);
_canvas = dynamic_cast<tgt::QtThreadedCanvas*>(tgt::GlContextManager::getRef().createContext("tfcanvas ", "", tgt::ivec2(256, 128), tgt::GLCanvas::RGBA_BUFFER, false));
tgtAssert(_canvas != 0, "Could not cast to QtThreadedCanvas*, something is wrong here!");
_canvas = new tgt::QtThreadedCanvas("", tgt::ivec2(256, 128), tgt::GLCanvas::RGBA_BUFFER, false);
tgt::GlContextManager::getRef().registerContextAndInitGlew(_canvas);
GLJobProc.registerContext(_canvas);
_canvas->setPainter(this, false);
......
......@@ -90,6 +90,7 @@ IF(WIN32)
LIST(APPEND CampvisGlobalDefinitions "-DNOMINMAX" "-D_CRT_SECURE_NO_DEPRECATE")
# Disable warnings for Microsoft compiler:
# C4251 class needs to have dll interface (used for std classes)
# C4290: C++ exception specification ignored except to indicate a function is
# not __declspec(nothrow)
# C4390: ';' : empty controlled statement found; is this the intent?
......@@ -97,7 +98,7 @@ IF(WIN32)
# C4503: The decorated name was longer than the compiler limit (4096), and was truncated.
# Occurs in AutoEvaluatePipeline due to some nested nested map-iterator-map. Could
# not be deactivated locally...
LIST(APPEND CampvisGlobalDefinitions /wd4290 /wd4390 /wd4503)
LIST(APPEND CampvisGlobalDefinitions /wd4251 /wd4290 /wd4390 /wd4503)
# enable parallel builds in Visual Studio
LIST(APPEND CampvisGlobalDefinitions /MP)
......@@ -112,6 +113,7 @@ IF(WIN32)
IF(CAMPVIS_SHARED_LIBS)
# Linking against Windows DLLs requires explicit instantiation of templates
LIST(APPEND CampvisGlobalDefinitions "-DDLL_TEMPLATE_INST")
LIST(APPEND CampvisGlobalDefinitions "-DCAMPVIS_DYNAMIC_LIBS")
IF(NOT CAMPVIS_GENERATE_MANIFEST)
# Do not embed manifest into binaries in debug mode (slows down incremental linking)
......
......@@ -12,7 +12,14 @@ IF(TGT_WITH_WMI)
ADD_DEFINITIONS("-DTGT_WITH_WMI")
ADD_DEFINITIONS("-D_WIN32_DCOM") #< for CoInitializeSecurity() to be defined
LIST(APPEND CampvisGlobalExternalLibs "WbemUuid")
ENDIF(TGT_WITH_WMI)
ENDIF(TGT_WITH_WMI)
IF(CAMPVIS_SHARED_LIBS)
SET(BUILD_SHARED_LIBS TRUE)
IF(MSVC)
ADD_DEFINITIONS("-DTGT_BUILD_DLL")
ENDIF()
ENDIF()
# headers
......@@ -74,14 +81,12 @@ IF(TGT_WITH_QT)
LIST(APPEND TGT_HEADERS
qt/qtapplication.h
qt/qtcanvas.h
qt/qtcontextmanager.h
qt/qtthreadedcanvas.h
qt/qttimer.h)
LIST(APPEND TGT_SOURCES
qt/qtapplication.cpp
qt/qtcanvas.cpp
qt/qtcontextmanager.cpp
qt/qtthreadedcanvas.cpp
qt/qttimer.cpp)
ENDIF(TGT_WITH_QT)
......@@ -92,9 +97,6 @@ ENDIF(TGT_WITH_QT)
################################################################################
ADD_LIBRARY(tgt ${TGT_SOURCES} ${TGT_HEADERS})
ADD_DEFINITIONS(${CampvisGlobalDefinitions} ${CampvisModulesDefinitions} ${QT_DEFINITIONS})
IF(CAMPVIS_SHARED_LIBS AND MSVC)
ADD_DEFINITIONS("-DTGT_BUILD_DLL")
ENDIF()
INCLUDE_DIRECTORIES(${CampvisGlobalIncludeDirs} ${CampvisModulesIncludeDirs})
TARGET_LINK_LIBRARIES(tgt ${CampvisGlobalExternalLibs} ${QT_LIBRARIES})
......
......@@ -196,7 +196,7 @@ protected:
};
/// ostream-operator
std::ostream& operator<< (std::ostream& o, const Bounds& b);
TGT_API std::ostream& operator<< (std::ostream& o, const Bounds& b);
} // namespace
......
......@@ -3,13 +3,14 @@
#include "tgt/exception.h"
#include "tgt/tgt_gl.h"
#include "tgt/types.h"
#include <set>
namespace tgt {
class VertexAttribute;
class BufferObject {
class TGT_API BufferObject {
public:
enum TargetType {
ARRAY_BUFFER = GL_ARRAY_BUFFER,
......
......@@ -194,6 +194,11 @@ public:
/// Getter
bool isInitialized() const { return initialized_; }
/// Acqures this canvas as current context
virtual void acquireAsCurrentContext() = 0;
/// Releases this canvas as current context
virtual void releaseAsCurrentContext() = 0;
protected:
/// Use the painter_ to actually paint something on the canvas
......
......@@ -3,9 +3,7 @@
#include "tgt/assert.h"
namespace tgt {
GlContextManager* GlContextManager::singletonClass_ = 0;
GlContextManager::GlContextManager()
: _currentContext(0)
{
......@@ -13,22 +11,12 @@ namespace tgt {
GlContextManager::~GlContextManager()
{
for (std::map<std::string, GLCanvas*>::iterator it = _contexts.begin(); it != _contexts.end(); ++it) {
delete it->second;
for (std::set<GLCanvas*>::iterator it = _contexts.begin(); it != _contexts.end(); ++it) {
delete *it;
}
_contexts.clear();
}
GLCanvas* GlContextManager::getContextByKey(const std::string& key) {
tbb::mutex::scoped_lock lock(_localMutex);
std::map<std::string, GLCanvas*>::iterator it = _contexts.find(key);
if (it != _contexts.end())
return it->second;
else
return 0;
}
void GlContextManager::lock() {
_glMutex.lock();
}
......@@ -51,20 +39,6 @@ namespace tgt {
return _currentContext;
}
GlContextManager* GlContextManager::getPtr() {
tgtAssert( singletonClass_ != 0, "singletonClass_ has not been intitialized." );
return singletonClass_;
}
GlContextManager& GlContextManager::getRef() {
tgtAssert( singletonClass_ != 0 , "singletonClass_ has not been intitialized." );
return *singletonClass_;
}
bool GlContextManager::isInited() {
return (singletonClass_ != 0);
}
void GlContextManager::lockAndAcquire(GLCanvas* context) {
lock();
setCurrent(context);
......@@ -79,16 +53,52 @@ namespace tgt {
setCurrent(context);
}
void GlContextManager::registerContextAndInitGlew(GLCanvas* context) {
tgtAssert(context != 0, "Given context must not be 0.");
tgtAssert(_contexts.find(context) == _contexts.end(), "Tried to double register the same context.");
{
tbb::mutex::scoped_lock localLock(_localMutex);
_contexts.insert(context);
}
// Init GLEW for this context
GLenum err = glewInit();
if (err != GLEW_OK) {
// Problem: glewInit failed, something is seriously wrong.
tgtAssert(false, "glewInit failed");
std::cerr << "glewInit failed, error: " << glewGetErrorString(err) << std::endl;
exit(EXIT_FAILURE);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
}
void GlContextManager::removeContext(GLCanvas* context) {
_currentContext = 0;
tbb::mutex::scoped_lock lock(_localMutex);
for (std::map<std::string, GLCanvas*>::iterator it = _contexts.begin(); it != _contexts.end(); ++it) {
if (it->second == context) {
_contexts.erase(it);
break;
std::set<GLCanvas*>::iterator it = _contexts.find(context);
if (it != _contexts.end()) {
_contexts.erase(it);
}
}
void GlContextManager::setCurrent(GLCanvas* context) {
if (_currentContext != context) {
if (context == 0) {
// explicitely release OpenGL context
_currentContext->releaseAsCurrentContext();
_currentContext = 0;
}
else {
context->acquireAsCurrentContext();
LGL_ERROR;
_currentContext = context;
}
}
}
}
......@@ -3,19 +3,18 @@
#include "tgt/singleton.h"
#include "tgt/glcanvas.h"
#include "tgt/types.h"
#include <tbb/mutex.h> // TODO: TBB dependency in TGT is not that beautiful...
#include <map>
#include <set>
#include <string>
class QWidget;
namespace tgt {
class GLCanvas;
/**
* Manages multiple shared OpenGL contexts and offers methods to ensure that only one context is active at a time.
*/
class GlContextManager : public Singleton<GlContextManager> {
class TGT_API GlContextManager : public Singleton<GlContextManager> {
public:
/**
* Creates a new QtGLContext for the OpenGL context of \a canvas.
......@@ -29,68 +28,50 @@ namespace tgt {
virtual ~GlContextManager();
/**
* Get Pointer of the actual class
* @return Pointer of the actual class
*/
static GlContextManager* getPtr();
/**
* Get reference of the actual class
* @return reference of the actual class
*/
static GlContextManager& getRef();
/**
* Has the actual class been inited?
* Registers \a canvas as new managed OpenGL context and initializes GLEW.
* \param canvas OpenGL context to register
*/
static bool isInited();
/**
* Creates a new OpenGL context in a QtThreadedCanvas with the given arguments.
* Parameters are the same as in QtThreadedCanvas() but context sharing is enables per default.
*
* \note Must be called with the OpenGL mutex acquired!
*
* \note The created canvas/context is owned by this ContextManager. Hence, you may not
* delete it yourself!
*
* \param key Key of the context to create, must be unique.
* \param title Window title
* \param size Window size
* \return The newly created QtThreadedCanvas.
*/
virtual GLCanvas* createContext(
const std::string& key,
const std::string& title = "",
const ivec2& size = ivec2(GLCanvas::DEFAULT_WINDOW_WIDTH, GLCanvas::DEFAULT_WINDOW_HEIGHT),
const GLCanvas::Buffers buffers = GLCanvas::RGBADD,
bool shared = true) = 0;
void registerContextAndInitGlew(GLCanvas* context);
/**
* Removes the OpenGL context \a context from the list of managed contexts.
* \param context Context to remove.
*/
virtual void removeContext(GLCanvas* context);
void removeContext(GLCanvas* context);
/**
* Returns the OpenGL context with the given key \a key, 0 if no such context exists.
* \param key Key of the context to return.
* \return The OpenGL context with the given key \a key, 0 if no such context exists.
* Returns the currently active OpenGL context.
* \return _currentContext
*/
GLCanvas* getContextByKey(const std::string& key);
GLCanvas* getCurrentContext() const;
/**
* Returns the mutex protecting the OpenGL context
* \return _glMutex
*/
tbb::mutex& getGlMutex();
/**
* Acquires \a context as current OpenGL context.
* \param context OpenGL context to acquire.
*/
void acquireContext(GLCanvas* context);
/**
* Releases the currently bound OpenGL context.
*/
void releaseCurrentContext();
/**
* Locks the OpenGL context mutex and acquires \a context as current OpenGl context.
* \param context OpenGL context to acquire.
*/
void lockAndAcquire(GLCanvas* context);
/**
* Releases the currently bound OpenGL context and also releases the OpenGL mutex.
*/
void releaseAndUnlock();
protected:
......@@ -99,7 +80,7 @@ namespace tgt {
* If \a context is already the current context, nothing will happen.
* \param context Context to set as current.
*/
virtual void setCurrent(GLCanvas* context) = 0;
void setCurrent(GLCanvas* context);
/**
* Locks the OpenGL device for other threads acessing the ContextManager.
......@@ -114,16 +95,14 @@ namespace tgt {
void unlock();
std::map<std::string, GLCanvas*> _contexts; ///< Map of all OpenGL contexts
std::set<GLCanvas*> _contexts; ///< Map of all OpenGL contexts
GLCanvas* _currentContext; ///< Current active OpenGL context
tbb::mutex _glMutex; ///< Mutex protecting OpenGL for multi-threaded access
tbb::mutex _localMutex; ///< local mutex to prodect _contexts
static GlContextManager* singletonClass_;
};
/**
* Scoped lockAndAcquire for a GLContext, that automatically unlocks the context on destruction.
*/
......
......@@ -44,7 +44,7 @@ namespace tgt {
around a given center (or, if you will, to rotate the camera around and focus it
on that center while it is continuously moving on a sphere).
*/
class Trackball : public Navigation {
class TGT_API Trackball : public Navigation {
public:
/// Constructor
......
......@@ -33,6 +33,7 @@
#include "tgt/tgt_gl.h"
#include "tgt/singleton.h"
#include "tgt/types.h"
#include <tbb/atomic.h>
#include <tbb/concurrent_vector.h>
#include <tbb/spin_mutex.h>
......@@ -45,7 +46,7 @@ namespace tgt {
*
* This class is to be considered as thread-safe.
*/