Commit 0227c942 authored by Jakob Weiss's avatar Jakob Weiss

Fixed Qt crash due painting from invalid thread

invalidate() failed for events triggered by sigslot signals, as the makeCurrent() only works from the Qt main thread. Invalidation now goes through the Qt Signals/Slots mechanism to end up in the right thread.
parent 7e8eb70e
...@@ -103,6 +103,8 @@ namespace campvis { ...@@ -103,6 +103,8 @@ namespace campvis {
p_renderBChannel.setVisible(false); p_renderBChannel.setVisible(false);
p_renderAChannel.setVisible(false); p_renderAChannel.setVisible(false);
connect(this, &DataContainerInspectorCanvas::s_invalidated, this, &DataContainerInspectorCanvas::onInvalidated);
init(); init();
} }
...@@ -250,9 +252,10 @@ namespace campvis { ...@@ -250,9 +252,10 @@ namespace campvis {
LGL_ERROR; LGL_ERROR;
} }
void DataContainerInspectorCanvas::invalidate() { void DataContainerInspectorCanvas::onInvalidated() {
// only if inited // only if inited
if (_quad != 0 && _paintShader != 0 && this->isVisible()) { if (_quad != 0 && _paintShader != 0 && this->isVisible()) {
this->makeCurrent(); this->makeCurrent();
paint(); paint();
this->swap(); this->swap();
...@@ -272,11 +275,11 @@ namespace campvis { ...@@ -272,11 +275,11 @@ namespace campvis {
} }
void DataContainerInspectorCanvas::repaint() { void DataContainerInspectorCanvas::repaint() {
invalidate(); emit s_invalidated();
} }
void DataContainerInspectorCanvas::sizeChanged(const cgt::ivec2& size) { void DataContainerInspectorCanvas::sizeChanged(const cgt::ivec2& size) {
invalidate(); emit s_invalidated();
} }
void DataContainerInspectorCanvas::mouseMoveEvent(cgt::MouseEvent* e) void DataContainerInspectorCanvas::mouseMoveEvent(cgt::MouseEvent* e)
...@@ -340,7 +343,7 @@ namespace campvis { ...@@ -340,7 +343,7 @@ namespace campvis {
_tcp.process(_localDataContainer); _tcp.process(_localDataContainer);
e->accept(); e->accept();
_geometriesDirty = true; _geometriesDirty = true;
invalidate(); emit s_invalidated();
} }
} }
...@@ -362,7 +365,7 @@ namespace campvis { ...@@ -362,7 +365,7 @@ namespace campvis {
} }
if (_texturesDirty) if (_texturesDirty)
invalidate(); emit s_invalidated();
} }
void DataContainerInspectorCanvas::setDataHandles(const std::vector< std::pair<QString, QtDataHandle> >& handles) { void DataContainerInspectorCanvas::setDataHandles(const std::vector< std::pair<QString, QtDataHandle> >& handles) {
...@@ -389,7 +392,7 @@ namespace campvis { ...@@ -389,7 +392,7 @@ namespace campvis {
_texturesDirty = true; _texturesDirty = true;
} }
invalidate(); emit s_invalidated();
} }
void DataContainerInspectorCanvas::updateTextures() { void DataContainerInspectorCanvas::updateTextures() {
...@@ -445,12 +448,12 @@ namespace campvis { ...@@ -445,12 +448,12 @@ namespace campvis {
void DataContainerInspectorCanvas::onPropertyChanged(const AbstractProperty* prop) { void DataContainerInspectorCanvas::onPropertyChanged(const AbstractProperty* prop) {
// ignore properties of the geometry renderer // ignore properties of the geometry renderer
if (prop != &p_geometryRendererProperties) if (prop != &p_geometryRendererProperties)
invalidate(); emit s_invalidated();
} }
void DataContainerInspectorCanvas::onGeometryRendererPropertyChanged(const AbstractProperty* prop) { void DataContainerInspectorCanvas::onGeometryRendererPropertyChanged(const AbstractProperty* prop) {
_geometriesDirty = true; _geometriesDirty = true;
invalidate(); emit s_invalidated();
} }
void DataContainerInspectorCanvas::renderGeometryIntoTexture(const std::string& name, int textureIndex) { void DataContainerInspectorCanvas::renderGeometryIntoTexture(const std::string& name, int textureIndex) {
......
...@@ -131,6 +131,7 @@ namespace campvis { ...@@ -131,6 +131,7 @@ namespace campvis {
signals: signals:
void s_colorChanged(const cgt::svec3& texel, const cgt::vec4&); void s_colorChanged(const cgt::svec3& texel, const cgt::vec4&);
void s_depthChanged(const cgt::svec3& texel, float depth); void s_depthChanged(const cgt::svec3& texel, float depth);
void s_invalidated(); ///< signals an invalidation event
private slots: private slots:
/** /**
...@@ -140,6 +141,11 @@ namespace campvis { ...@@ -140,6 +141,11 @@ namespace campvis {
*/ */
void onDataContainerChanged(const QString& key, QtDataHandle dh); void onDataContainerChanged(const QString& key, QtDataHandle dh);
/**
* To be called when the canvas is invalidated, issues new paint job.
*/
void onInvalidated();
protected: protected:
/** /**
* Performs the painting. * Performs the painting.
...@@ -164,11 +170,6 @@ namespace campvis { ...@@ -164,11 +170,6 @@ namespace campvis {
*/ */
void resetTrackball(); void resetTrackball();
/**
* To be called when the canvas is invalidated, issues new paint job.
*/
void invalidate();
/** /**
* Renders the given 2D texture. * Renders the given 2D texture.
* Binds the texture to the shader, sets the uniforms and renders the quad. * Binds the texture to the shader, sets the uniforms and renders the quad.
......
...@@ -64,6 +64,8 @@ namespace campvis { ...@@ -64,6 +64,8 @@ namespace campvis {
updateManipulators(); updateManipulators();
setEventTypes(cgt::Event::MOUSEPRESSEVENT); setEventTypes(cgt::Event::MOUSEPRESSEVENT);
connect(this, &Geometry1DTransferFunctionEditor::s_invalidated, this, &Geometry1DTransferFunctionEditor::onInvalidated);
} }
Geometry1DTransferFunctionEditor::~Geometry1DTransferFunctionEditor() { Geometry1DTransferFunctionEditor::~Geometry1DTransferFunctionEditor() {
...@@ -77,7 +79,7 @@ namespace campvis { ...@@ -77,7 +79,7 @@ namespace campvis {
Geometry1DTransferFunction* gtf = static_cast<Geometry1DTransferFunction*>(_transferFunction); Geometry1DTransferFunction* gtf = static_cast<Geometry1DTransferFunction*>(_transferFunction);
_lblIntensityLeft->setText(QString::number(gtf->getIntensityDomain().x)); _lblIntensityLeft->setText(QString::number(gtf->getIntensityDomain().x));
_lblIntensityRight->setText(QString::number(gtf->getIntensityDomain().y)); _lblIntensityRight->setText(QString::number(gtf->getIntensityDomain().y));
invalidate(); emit s_invalidated();
} }
void Geometry1DTransferFunctionEditor::paint() { void Geometry1DTransferFunctionEditor::paint() {
...@@ -180,7 +182,7 @@ namespace campvis { ...@@ -180,7 +182,7 @@ namespace campvis {
(*it)->setViewportSize(size); (*it)->setViewportSize(size);
} }
} }
invalidate(); emit s_invalidated();
} }
void Geometry1DTransferFunctionEditor::mousePressEvent(cgt::MouseEvent* e) { void Geometry1DTransferFunctionEditor::mousePressEvent(cgt::MouseEvent* e) {
...@@ -200,16 +202,16 @@ namespace campvis { ...@@ -200,16 +202,16 @@ namespace campvis {
} }
else { else {
_selectedGeometry = 0; _selectedGeometry = 0;
invalidate(); emit s_invalidated();
e->ignore(); e->ignore();
} }
} }
void Geometry1DTransferFunctionEditor::repaint() { void Geometry1DTransferFunctionEditor::repaint() {
invalidate(); emit s_invalidated();
} }
void Geometry1DTransferFunctionEditor::invalidate() { void Geometry1DTransferFunctionEditor::onInvalidated() {
// TODO: check, whether this should be done in an extra thread // TODO: check, whether this should be done in an extra thread
cgt::GLContextScopedLock lock(_canvas); cgt::GLContextScopedLock lock(_canvas);
paint(); paint();
...@@ -298,7 +300,7 @@ namespace campvis { ...@@ -298,7 +300,7 @@ namespace campvis {
void Geometry1DTransferFunctionEditor::onWholeTFGeometryManipulatorSelected(WholeTFGeometryManipulator* wtf /* :) */) { void Geometry1DTransferFunctionEditor::onWholeTFGeometryManipulatorSelected(WholeTFGeometryManipulator* wtf /* :) */) {
_selectedGeometry = wtf; _selectedGeometry = wtf;
invalidate(); emit s_invalidated();
} }
void Geometry1DTransferFunctionEditor::onBtnAddGeometryClicked() { void Geometry1DTransferFunctionEditor::onBtnAddGeometryClicked() {
...@@ -332,7 +334,7 @@ namespace campvis { ...@@ -332,7 +334,7 @@ namespace campvis {
void Geometry1DTransferFunctionEditor::onCbLogScaleStateChanged(int state) { void Geometry1DTransferFunctionEditor::onCbLogScaleStateChanged(int state) {
_logScale = (state & Qt::Checked); _logScale = (state & Qt::Checked);
invalidate(); emit s_invalidated();
} }
void Geometry1DTransferFunctionEditor::onTfAboutToBeDeleted() { void Geometry1DTransferFunctionEditor::onTfAboutToBeDeleted() {
......
...@@ -94,6 +94,12 @@ namespace campvis { ...@@ -94,6 +94,12 @@ namespace campvis {
*/ */
void onWholeTFGeometryManipulatorSelected(WholeTFGeometryManipulator* wtf /* :) */); void onWholeTFGeometryManipulatorSelected(WholeTFGeometryManipulator* wtf /* :) */);
signals:
/**
* To be called when the canvas is invalidated, issues new paint job.
*/
void s_invalidated();
protected slots: protected slots:
/** /**
* Slot to be called when _btnAddGeometry was clicked. * Slot to be called when _btnAddGeometry was clicked.
...@@ -111,6 +117,11 @@ namespace campvis { ...@@ -111,6 +117,11 @@ namespace campvis {
*/ */
void onCbLogScaleStateChanged(int state); void onCbLogScaleStateChanged(int state);
/**
* Slot reacting to the invalidated signal, issueing a new paint job
*/
void onInvalidated();
protected: protected:
/** /**
* Disconnects this editor from the handled TF and cleans up everything. * Disconnects this editor from the handled TF and cleans up everything.
...@@ -133,11 +144,6 @@ namespace campvis { ...@@ -133,11 +144,6 @@ namespace campvis {
*/ */
void updateManipulators(); void updateManipulators();
/**
* To be called when the canvas is invalidated, issues new paint job.
*/
void invalidate();
/** /**
* Sets up the GUI stuff. * Sets up the GUI stuff.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment