2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 3acfe9a9 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Work on Issue #44: Removed GLContext interface and merged functionality into...

Work on Issue #44: Removed GLContext interface and merged functionality into GlCanvas. Introducing abstract (Qt-free) tgt::GlContextManager interface, being implemented by tgt::QtContextManager. Further clean up of related code.
parent 32220286
......@@ -31,7 +31,7 @@
#include "tgt/assert.h"
#include "tgt/exception.h"
#include "tgt/glcontext.h"
#include "tgt/glcanvas.h"
#include "tgt/gpucapabilities.h"
#include "tgt/shadermanager.h"
#include "tgt/qt/qtapplication.h"
......@@ -108,10 +108,10 @@ namespace campvis {
LogMgr.getConsoleLog()->addCat("", true);
// create a local OpenGL context and init GL
_localContext = CtxtMgr.createContext("AppContext", "", tgt::ivec2(16, 16));
_localContext = tgt::GlContextManager::getRef().createContext("AppContext", "", tgt::ivec2(16, 16));
tgtAssert(_localContext != 0, "Could not create local OpenGL context");
tgt::GLContextScopedLock lock(_localContext->getContext());
tgt::GLContextScopedLock lock(_localContext);
tgt::initGL(featureset);
ShdrMgr.setGlobalHeader("#version 330\n");
......@@ -195,7 +195,7 @@ namespace campvis {
{
// Deinit everything OpenGL related using the local context.
tgt::GLContextScopedLock lock(_localContext->getContext());
tgt::GLContextScopedLock lock(_localContext);
// Deinit pipeline first
for (std::vector<AbstractPipeline*>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
......@@ -238,7 +238,7 @@ namespace campvis {
tgtAssert(_initialized, "Tried to run uninitialized CampVisApplication.");
// disconnect OpenGL context from this thread so that the other threads can acquire an OpenGL context.
CtxtMgr.releaseCurrentContext();
tgt::GlContextManager::getRef().releaseCurrentContext();
_mainWindow->show();
......@@ -256,14 +256,16 @@ namespace campvis {
if (_initialized) {
GLJobProc.pause();
{
tgt::QtThreadedCanvas* canvas = CtxtMgr.createContext(name, "CAMPVis", tgt::ivec2(512, 512));
tgt::GLContextScopedLock lock(canvas->getContext());
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 = CtxtMgr.createContext(name, "CAMPVis", tgt::ivec2(512, 512));
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);
}
......@@ -291,7 +293,7 @@ namespace campvis {
LGL_ERROR;
}
CtxtMgr.releaseCurrentContext();
tgt::GlContextManager::getRef().releaseCurrentContext();
_mainWindow->addVisualizationPipelineWidget(name, canvas);
// enable pipeline and invalidate all processors
......
......@@ -41,6 +41,7 @@
#include "core/datastructures/datacontainer.h"
namespace tgt {
class GLCanvas;
class QtThreadedCanvas;
}
......@@ -141,7 +142,7 @@ namespace campvis {
std::vector<DataContainer*> _dataContainers;
/// A local OpenGL context used for initialization
tgt::QtThreadedCanvas* _localContext;
tgt::GLCanvas* _localContext;
/// Main window hosting GUI stuff
MainWindow* _mainWindow;
......
......@@ -35,8 +35,6 @@
#include "tgt/shadermanager.h"
#include "tgt/textureunit.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "tgt/qt/qtglcontext.h"
#include "tgt/qt/qtcontextmanager.h"
#include "core/datastructures/imagedata.h"
......@@ -50,8 +48,7 @@ namespace campvis {
const std::string CampVisPainter::loggerCat_ = "CAMPVis.core.CampVisPainter";
CampVisPainter::CampVisPainter(tgt::GLCanvas* canvas, AbstractPipeline* pipeline)
: Runnable()
, tgt::Painter(canvas)
: tgt::Painter(canvas)
, _pipeline(0)
, _copyShader(0)
{
......@@ -64,31 +61,6 @@ namespace campvis {
}
void CampVisPainter::stop() {
// we need to execute run() one more time to ensure correct release of the OpenGL context
_stopExecution = true;
_renderCondition.notify_all();
Runnable::stop();
}
void CampVisPainter::run() {
std::unique_lock<tbb::mutex> lock(CtxtMgr.getGlMutex());
while (! _stopExecution) {
/*getCanvas()->getContext()->acquire();
paint();
getCanvas()->swap();*/
//while (!_stopExecution)
_renderCondition.wait(lock);
}
// release OpenGL context, so that other threads can access it
CtxtMgr.releaseCurrentContext();
}
void CampVisPainter::paint() {
if (getCanvas() == 0)
return;
......
......@@ -36,7 +36,6 @@
#include "tgt/logmanager.h"
#include "tgt/painter.h"
#include "core/tools/runnable.h"
namespace tgt {
class Shader;
......@@ -48,14 +47,8 @@ namespace campvis {
/**
* Painter class for CAMPVis, rendering the render target of an AbstractPipeline.
* This painter implements Runnable, hence, it runs in its own thread and the associated canvas
* must be of type QtThreadedCanvas.
* Rendering is implemented using condidional wait - hence the canvas is only updated when
* \a pipeline emits the s_RenderTargetChanged signal.
*
* \sa Runnable, AbstractPipeline
*/
class CampVisPainter : public Runnable, public tgt::Painter, public sigslot::has_slots<> {
class CampVisPainter : public tgt::Painter, public sigslot::has_slots<> {
public:
/**
* Creates a new CampVisPainter rendering the render target of \a pipeline on \a canvas.
......@@ -69,15 +62,6 @@ namespace campvis {
*/
virtual ~CampVisPainter();
/// \see Runnable::stop
void stop();
/**
* Performs the rendering using conditional wait.
* \sa Runnable::run
*/
void run();
/**
* Schedule a repaint job for the pipeline's render target
*/
......
......@@ -31,7 +31,7 @@
#include "tgt/assert.h"
#include "tgt/shadermanager.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tgt/glcontextmanager.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "application/gui/qtcolortools.h"
......@@ -245,7 +245,9 @@ namespace campvis {
QLabel* lblOpacityBottom = new QLabel(tr("0%"), this);
_layout->addWidget(lblOpacityBottom, 3, 0, 1, 1, Qt::AlignRight);
_canvas = CtxtMgr.createContext("tfcanvas", "", tgt::ivec2(256, 128), tgt::GLCanvas::RGBA_BUFFER, 0, false);
_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!");
GLJobProc.registerContext(_canvas);
_canvas->setPainter(this, false);
_layout->addWidget(_canvas, 1, 1, 3, 3);
......
......@@ -31,7 +31,7 @@
#include "tgt/assert.h"
#include "tgt/shadermanager.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tgt/glcontextmanager.h"
#include "tgt/qt/qtthreadedcanvas.h"
#include "application/gui/qtcolortools.h"
......@@ -231,7 +231,9 @@ namespace campvis {
QLabel* lblOpacityBottom = new QLabel(tr("0%"), this);
_layout->addWidget(lblOpacityBottom, 3, 0, 1, 1, Qt::AlignRight);
_canvas = CtxtMgr.createContext("tfcanvas", "", tgt::ivec2(256, 128), tgt::GLCanvas::RGBA_BUFFER, 0, false);
_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!");
GLJobProc.registerContext(_canvas);
_canvas->setPainter(this, false);
_layout->addWidget(_canvas, 1, 1, 3, 3);
......
......@@ -30,8 +30,8 @@
#include "geometrydata.h"
#include "tgt/buffer.h"
#include "tgt/vertexarrayobject.h"
#include "tgt/glcontextmanager.h"
#include "tgt/qt/qtcontextmanager.h"
#include "core/tools/opengljobprocessor.h"
namespace campvis {
......@@ -116,7 +116,7 @@ namespace campvis {
void GeometryData::createGLBuffers() const {
if (! _buffersInitialized)
_context = CtxtMgr.getCurrentContext();
_context = tgt::GlContextManager::getRef().getCurrentContext();
}
const tgt::BufferObject* GeometryData::getVerticesBuffer() const {
......
......@@ -37,7 +37,7 @@
namespace tgt {
class BufferObject;
class QtCanvas;
class GLCanvas;
}
namespace campvis {
......@@ -111,7 +111,7 @@ namespace campvis {
};
private:
mutable tgt::QtCanvas* _context; ///< OpenGL context the buffers were created in (so that they can be deleted correctly)
mutable tgt::GLCanvas* _context; ///< OpenGL context the buffers were created in (so that they can be deleted correctly)
};
}
......
......@@ -130,7 +130,7 @@ namespace campvis {
ImageRepresentationLocal* toReturn = 0;
GLJobProc.pause();
try {
tgt::GLContextScopedLock lock(context->getContext());
tgt::GLContextScopedLock lock(context);
WeaklyTypedPointer wtp = tester->getWeaklyTypedPointer();
toReturn = convertToGenericLocal(source, wtp);
}
......
......@@ -32,7 +32,6 @@
#include "tgt/exception.h"
#include "tgt/glcanvas.h"
#include "tgt/glcontext.h"
#include "tgt/tgt_gl.h"
#include "core/pipeline/visualizationprocessor.h"
......
......@@ -30,7 +30,6 @@
#include "autoevaluationpipeline.h"
#include "tgt/tgt_gl.h"
#include "tgt/glcanvas.h"
#include "tgt/glcontext.h"
#include "core/pipeline/visualizationprocessor.h"
#include "core/properties/datanameproperty.h"
#include "core/tools/job.h"
......
......@@ -32,7 +32,7 @@
#include "tgt/assert.h"
#include "tgt/logmanager.h"
#include "tgt/openglgarbagecollector.h"
#include "tgt/qt/qtcontextmanager.h"
#include "tgt/glcontextmanager.h"
#include "core/tools/job.h"
namespace campvis {
......@@ -62,7 +62,7 @@ namespace campvis {
}
void OpenGLJobProcessor::run() {
std::unique_lock<tbb::mutex> lock(CtxtMgr.getGlMutex());
std::unique_lock<tbb::mutex> lock(tgt::GlContextManager::getRef().getGlMutex());
clock_t lastCleanupTime = clock() * 1000 / CLOCKS_PER_SEC;
while (! _stopExecution) {
......@@ -94,7 +94,7 @@ namespace campvis {
glFinish();
LGL_ERROR;
}
context->getContext()->acquire();
tgt::GlContextManager::getRef().acquireContext(context);
_currentContext = context;
}
......@@ -136,23 +136,23 @@ namespace campvis {
while (_pause > 0) {
GLGC.deleteGarbage();
lastCleanupTime = clock();
CtxtMgr.releaseCurrentContext();
tgt::GlContextManager::getRef().releaseCurrentContext();
_evaluationCondition.wait(lock);
_currentContext->getContext()->acquire();
tgt::GlContextManager::getRef().acquireContext(_currentContext);
hadWork = true;
}
if (! hadWork) {
GLGC.deleteGarbage();
lastCleanupTime = clock();
CtxtMgr.releaseCurrentContext();
tgt::GlContextManager::getRef().releaseCurrentContext();
_evaluationCondition.wait(lock);
_currentContext->getContext()->acquire();
tgt::GlContextManager::getRef().acquireContext(_currentContext);
}
}
// release OpenGL context, so that other threads can access it
CtxtMgr.releaseCurrentContext();
tgt::GlContextManager::getRef().releaseCurrentContext();
}
void OpenGLJobProcessor::pause() {
......
......@@ -38,7 +38,7 @@ SET(TGT_SOURCES
framebufferobject.cpp
frustum.cpp
glcanvas.cpp
glcontext.cpp
glcontextmanager.cpp
gpucapabilities.cpp
gpucapabilitieswindows.cpp
guiapplication.cpp
......@@ -74,7 +74,6 @@ SET(TGT_SOURCES
qt/qtapplication.cpp
qt/qtcanvas.cpp
qt/qtcontextmanager.cpp
qt/qtglcontext.cpp
qt/qtthreadedcanvas.cpp
qt/qttimer.cpp
)
......
......@@ -23,7 +23,7 @@
**********************************************************************/
#include "tgt/glcanvas.h"
#include "tgt/glcontext.h"
#include "tgt/glcontextmanager.h"
#include "tgt/camera.h"
#include "tgt/painter.h"
......@@ -63,7 +63,7 @@ void GLCanvas::sizeChanged(const ivec2& size) {
}
void GLCanvas::paint() {
GLContextScopedLock lock(getContext());
GLContextScopedLock lock(this);
if (painter_)
painter_->repaint();
if (autoFlush_) {
......@@ -94,7 +94,7 @@ Painter* GLCanvas::getPainter() const {
void GLCanvas::initPainter() {
if (painter_) {
{
GLContextScopedLock lock(getContext());
GLContextScopedLock lock(this);
painter_->init();
}
painter_->sizeChanged(size_);
......
......@@ -38,7 +38,6 @@
namespace tgt {
class Camera;
class GLContext;
class Painter;
/**
......@@ -106,14 +105,6 @@ public:
*/
//virtual void getGLFocus() = 0;
/**
* If we use several GLCanvases, we have to switch the OpenGL context when we switch between
* canvases; this method returns the context of this canvas.
*
* To be overridden by derived Canvas classes.
*/
virtual GLContext* getContext() = 0;
/**
* Toggles fullscreen mode.
*
......
#include "glcontext.h"
namespace tgt {
GLContext::GLContext() {
}
GLContext::~GLContext() {
}
}
#ifndef GLCONTEXT_H__
#define GLCONTEXT_H__
#include "tgt/vector.h"
namespace tgt {
/**
* Abstract base class for thread-safe OpenGL contexts.
*/
class TGT_API GLContext {
public:
GLContext();
~GLContext();
virtual void acquire() = 0;
virtual void lockAndAcquire() = 0;
virtual void unlock() = 0;
virtual ivec2 getViewportSize() const = 0;
};
/**
* Scoped lockAndAcquire for a GLContext, that automatically unlocks the context on destruction.
*/
class TGT_API GLContextScopedLock {
public:
GLContextScopedLock(GLContext* context)
: _context(context)
{
if (_context)
_context->lockAndAcquire();
};
~GLContextScopedLock() {
if (_context)
_context->unlock();
}
private:
GLContext* _context;
};
} // namespace tgt
#endif // GLCONTEXT_H__
#include "glcontextmanager.h"
#include "tgt/assert.h"
namespace tgt {
GlContextManager* GlContextManager::singletonClass_ = 0;
GlContextManager::GlContextManager()
: _currentContext(0)
{
}
GlContextManager::~GlContextManager()
{
for (std::map<std::string, GLCanvas*>::iterator it = _contexts.begin(); it != _contexts.end(); ++it) {
delete it->second;
}
_contexts.clear();
}
GLCanvas* GlContextManager::getContextByKey(const std::string& key) {
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();
}
void GlContextManager::unlock() {
_glMutex.unlock();
}
tbb::mutex& GlContextManager::getGlMutex() {
return _glMutex;
}
void GlContextManager::releaseCurrentContext() {
glFinish();
setCurrent(0);
}
GLCanvas* GlContextManager::getCurrentContext() const {
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);
}
void GlContextManager::releaseAndUnlock() {
releaseCurrentContext();
unlock();
}
void GlContextManager::acquireContext(GLCanvas* context) {
setCurrent(context);
}
}
#ifndef GLCONTEXTMANAGER_H__
#define GLCONTEXTMANAGER_H__
#include "tgt/singleton.h"
#include "tgt/glcanvas.h"
#include <tbb/mutex.h> // TODO: TBB dependency in TGT is not that beautiful...
#include <map>
#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> {
public:
/**
* Creates a new QtGLContext for the OpenGL context of \a canvas.
* \param canvas QtCanvas with the OpenGL context to manage
*/
GlContextManager();
/**
* Destructor
*/
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?
*/
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;
/**
* 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.
*/
GLCanvas* getContextByKey(const std::string& key);
GLCanvas* getCurrentContext() const;