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

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
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -103,6 +103,8 @@ namespace campvis {
        p_renderBChannel.setVisible(false);
        p_renderAChannel.setVisible(false);

		    connect(this, &DataContainerInspectorCanvas::s_invalidated, this, &DataContainerInspectorCanvas::onInvalidated);

        init();
    }

@@ -250,9 +252,10 @@ namespace campvis {
        LGL_ERROR;
    }

    void DataContainerInspectorCanvas::invalidate() {
    void DataContainerInspectorCanvas::onInvalidated() {
        // only if inited
        if (_quad != 0 && _paintShader != 0 && this->isVisible()) {
			
            this->makeCurrent();
            paint();
            this->swap();
@@ -272,11 +275,11 @@ namespace campvis {
    }

    void DataContainerInspectorCanvas::repaint() {
        invalidate();
        emit s_invalidated();
    }

    void DataContainerInspectorCanvas::sizeChanged(const cgt::ivec2& size) {
        invalidate();
		    emit s_invalidated();
    }

    void DataContainerInspectorCanvas::mouseMoveEvent(cgt::MouseEvent* e)
@@ -340,7 +343,7 @@ namespace campvis {
            _tcp.process(_localDataContainer);
            e->accept();
            _geometriesDirty = true;
            invalidate();
			      emit s_invalidated();
        }
    }

@@ -362,7 +365,7 @@ namespace campvis {
        }

        if (_texturesDirty)
            invalidate();
			    emit s_invalidated();
    }

    void DataContainerInspectorCanvas::setDataHandles(const std::vector< std::pair<QString, QtDataHandle> >& handles) {
@@ -389,7 +392,7 @@ namespace campvis {
            _texturesDirty = true;
        }

        invalidate();
		    emit s_invalidated();
    }

    void DataContainerInspectorCanvas::updateTextures() {
@@ -445,12 +448,12 @@ namespace campvis {
    void DataContainerInspectorCanvas::onPropertyChanged(const AbstractProperty* prop) {
        // ignore properties of the geometry renderer
        if (prop != &p_geometryRendererProperties)
            invalidate();
			    emit s_invalidated();
    }

    void DataContainerInspectorCanvas::onGeometryRendererPropertyChanged(const AbstractProperty* prop) {
        _geometriesDirty = true;
        invalidate();
		      emit s_invalidated();
    }

    void DataContainerInspectorCanvas::renderGeometryIntoTexture(const std::string& name, int textureIndex) {
+6 −5
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ namespace campvis {
    signals:
        void s_colorChanged(const cgt::svec3& texel, const cgt::vec4&);
        void s_depthChanged(const cgt::svec3& texel, float depth);
		    void s_invalidated();				///< signals an invalidation event

    private slots:
        /**
@@ -140,6 +141,11 @@ namespace campvis {
         */
        void onDataContainerChanged(const QString& key, QtDataHandle dh);

		    /**
		    * To be called when the canvas is invalidated, issues new paint job.
		    */
		    void onInvalidated();

    protected:
        /**
         * Performs the painting.
@@ -164,11 +170,6 @@ namespace campvis {
         */
        void resetTrackball();

        /**
         * To be called when the canvas is invalidated, issues new paint job.
         */
        void invalidate();

        /**
         * Renders the given 2D texture.
         * Binds the texture to the shader, sets the uniforms and renders the quad.
+9 −7
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ namespace campvis {

        updateManipulators();
        setEventTypes(cgt::Event::MOUSEPRESSEVENT);

        connect(this, &Geometry1DTransferFunctionEditor::s_invalidated, this, &Geometry1DTransferFunctionEditor::onInvalidated);
    }

    Geometry1DTransferFunctionEditor::~Geometry1DTransferFunctionEditor() {
@@ -77,7 +79,7 @@ namespace campvis {
        Geometry1DTransferFunction* gtf = static_cast<Geometry1DTransferFunction*>(_transferFunction);
        _lblIntensityLeft->setText(QString::number(gtf->getIntensityDomain().x));
        _lblIntensityRight->setText(QString::number(gtf->getIntensityDomain().y));
        invalidate();
        emit s_invalidated();
    }

    void Geometry1DTransferFunctionEditor::paint() {
@@ -180,7 +182,7 @@ namespace campvis {
                (*it)->setViewportSize(size);
            }
        }
        invalidate();
        emit s_invalidated();
    }

    void Geometry1DTransferFunctionEditor::mousePressEvent(cgt::MouseEvent* e) {
@@ -200,16 +202,16 @@ namespace campvis {
        }
        else {
            _selectedGeometry = 0;
            invalidate();
            emit s_invalidated();
            e->ignore();
        }
    }

    void Geometry1DTransferFunctionEditor::repaint() {
        invalidate();
        emit s_invalidated();
    }

    void Geometry1DTransferFunctionEditor::invalidate() {
    void Geometry1DTransferFunctionEditor::onInvalidated() {
        // TODO: check, whether this should be done in an extra thread
        cgt::GLContextScopedLock lock(_canvas);
        paint();
@@ -298,7 +300,7 @@ namespace campvis {

    void Geometry1DTransferFunctionEditor::onWholeTFGeometryManipulatorSelected(WholeTFGeometryManipulator* wtf /* :) */) {
        _selectedGeometry = wtf;
        invalidate();
        emit s_invalidated();
    }

    void Geometry1DTransferFunctionEditor::onBtnAddGeometryClicked() {
@@ -332,7 +334,7 @@ namespace campvis {

    void Geometry1DTransferFunctionEditor::onCbLogScaleStateChanged(int state) {
        _logScale = (state & Qt::Checked);
        invalidate();
        emit s_invalidated();
    }

    void Geometry1DTransferFunctionEditor::onTfAboutToBeDeleted() {
+11 −5
Original line number Diff line number Diff line
@@ -94,6 +94,12 @@ namespace campvis {
         */
        void onWholeTFGeometryManipulatorSelected(WholeTFGeometryManipulator* wtf /* :) */);

    signals:
        /**
        * To be called when the canvas is invalidated, issues new paint job.
        */
        void s_invalidated();

    protected slots:
        /**
         * Slot to be called when _btnAddGeometry was clicked.
@@ -111,6 +117,11 @@ namespace campvis {
         */
        void onCbLogScaleStateChanged(int state);

        /**
         * Slot reacting to the invalidated signal, issueing a new paint job
         */
        void onInvalidated();

    protected:
        /**
         * Disconnects this editor from the handled TF and cleans up everything.
@@ -133,11 +144,6 @@ namespace campvis {
         */
        void updateManipulators();

        /**
         * To be called when the canvas is invalidated, issues new paint job.
         */
        void invalidate();

        /**
         * Sets up the GUI stuff.
         */