kde-frameworks/kdeclarative: Fix crashes on window moves etc.
authorAndreas Sturmlechner <asturm@gentoo.org>
Sun, 21 Apr 2019 20:50:18 +0000 (22:50 +0200)
committerAndreas Sturmlechner <asturm@gentoo.org>
Mon, 22 Apr 2019 10:41:18 +0000 (12:41 +0200)
KDE-Bug: https://bugs.kde.org/show_bug.cgi?id=403453
Package-Manager: Portage-2.3.64, Repoman-2.3.12
Signed-off-by: Andreas Sturmlechner <asturm@gentoo.org>
kde-frameworks/kdeclarative/files/kdeclarative-5.57.0-fix-plotter-crash.patch [new file with mode: 0644]
kde-frameworks/kdeclarative/kdeclarative-5.57.0-r1.ebuild [new file with mode: 0644]

diff --git a/kde-frameworks/kdeclarative/files/kdeclarative-5.57.0-fix-plotter-crash.patch b/kde-frameworks/kdeclarative/files/kdeclarative-5.57.0-fix-plotter-crash.patch
new file mode 100644 (file)
index 0000000..1416510
--- /dev/null
@@ -0,0 +1,262 @@
+From 0aab7d23a2ce155c4beb5cf77fcac02c93b183b7 Mon Sep 17 00:00:00 2001
+From: David Edmundson <kde@davidedmundson.co.uk>
+Date: Thu, 18 Apr 2019 11:15:06 +0100
+Subject: Plotter: Scope GL Program to lifespan of scenegraph node
+
+Summary:
+Currently the QOpenGLProgram was static. This works when you only have
+one OpenGL context that is never invalidated.
+
+Instead we shoul have a new program created for each context. There is
+no benefit of being static when we can use the cached shader loading.
+
+As we need a program per context, we would need to handle windowChanged
+and sceneGraphInvalidated manually. Instead we can scope the program to
+the QSGNode which will be deleted and recreated on the render thread
+automatically by the scene graph backend.
+
+We can also drop ManagedTextureNode and use
+QSGSimpleTextureNode::setOwnsTexture which does the same thing.
+
+BUG: 403453
+
+Test Plan:
+Created a CPU load viewer on my panel
+Dragged it to my desktop
+Previously that didn't render anything
+Now it does
+
+It should fix the crashes that we
+see on window moves and handling sceneGraphInvalidated
+
+Reviewers: #plasma
+
+Subscribers: kde-frameworks-devel
+
+Tags: #frameworks
+
+Differential Revision: https://phabricator.kde.org/D20656
+---
+ src/qmlcontrols/kquickcontrolsaddons/plotter.cpp | 106 ++++++++++++++---------
+ src/qmlcontrols/kquickcontrolsaddons/plotter.h   |  11 +--
+ 2 files changed, 68 insertions(+), 49 deletions(-)
+
+diff --git a/src/qmlcontrols/kquickcontrolsaddons/plotter.cpp b/src/qmlcontrols/kquickcontrolsaddons/plotter.cpp
+index 650151d..8495bbd 100644
+--- a/src/qmlcontrols/kquickcontrolsaddons/plotter.cpp
++++ b/src/qmlcontrols/kquickcontrolsaddons/plotter.cpp
+@@ -44,8 +44,6 @@
+ #include <QDebug>
+-#include <QuickAddons/ManagedTextureNode>
+-
+ #include <math.h>
+ //completely arbitrary
+@@ -262,16 +260,58 @@ void PlotTexture::recreate(const QSize &size)
+     m_size = size;
+ }
++class PlotSGNode: public QSGSimpleTextureNode
++{
++public:
++    PlotSGNode();
++    void bind() {
++        m_program->bind();
++    }
++    void setMatrix(const QMatrix4x4 &matrix) {
++        m_program->setUniformValue(u_matrix, matrix);
++    }
++    void setColor1(const QColor &color) {
++        m_program->setUniformValue(u_color1, color);
++    }
++    void setColor2(const QColor &color) {
++        m_program->setUniformValue(u_color2, color);
++    }
++    void setYMin(float min) {
++        m_program->setUniformValue(u_yMin, min);
++    }
++    void setYMax(float max) {
++        m_program->setUniformValue(u_yMax, max);
++    }
++    ~PlotSGNode() = default;
++private:
++    QScopedPointer<QOpenGLShaderProgram> m_program;
++    int u_matrix;
++    int u_color1;
++    int u_color2;
++    int u_yMin;
++    int u_yMax;
++};
++
++PlotSGNode::PlotSGNode():
++    m_program(new QOpenGLShaderProgram)
++{
++    setOwnsTexture(true);
++    m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vs_source);
++    m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fs_source);
++    m_program->bindAttributeLocation("vertex", 0);
++    m_program->link();
++
++    u_yMin = m_program->uniformLocation("yMin");
++    u_yMax = m_program->uniformLocation("yMax");
++    u_color1 = m_program->uniformLocation("color1");
++    u_color2 = m_program->uniformLocation("color2");
++    u_matrix = m_program->uniformLocation("matrix");
++}
+-// ----------------------
+-QOpenGLShaderProgram *Plotter::s_program = nullptr;
+-int Plotter::u_matrix;
+-int Plotter::u_color1;
+-int Plotter::u_color2;
+-int Plotter::u_yMin;
+-int Plotter::u_yMax;
++
++// ----------------------
+ Plotter::Plotter(QQuickItem *parent)
+     : QQuickItem(parent),
+@@ -652,18 +692,18 @@ void Plotter::render()
+     glEnableVertexAttribArray(0);
+     // Bind the shader program
+-    s_program->bind();
+-    s_program->setUniformValue(u_matrix, m_matrix);
++    m_node->bind();
++    m_node->setMatrix(m_matrix);
+     // Draw the lines
+     QColor color1 = m_gridColor;
+     QColor color2 = m_gridColor;
+     color1.setAlphaF(0.10);
+     color2.setAlphaF(0.40);
+-    s_program->setUniformValue(u_yMin, (float) 0.0);
+-    s_program->setUniformValue(u_yMax, (float) height());
+-    s_program->setUniformValue(u_color1, color1);
+-    s_program->setUniformValue(u_color2, color2);
++    m_node->setYMin((float) 0.0);
++    m_node->setYMax((float) height());
++    m_node->setColor1(color1);
++    m_node->setColor2(color2);
+     glDrawArrays(GL_LINES, 0, (m_horizontalLineCount+1) * 2 );
+@@ -677,18 +717,18 @@ void Plotter::render()
+         color2 = data->color();
+         color2.setAlphaF(0.60);
+         // Draw the graph
+-        s_program->setUniformValue(u_yMin, min);
+-        s_program->setUniformValue(u_yMax, max);
+-        s_program->setUniformValue(u_color1, data->color());
+-        s_program->setUniformValue(u_color2, color2);
++        m_node->setYMin(min);
++        m_node->setYMax(max);
++        m_node->setColor1(data->color());
++        m_node->setColor2(color2);
+         //+2 is for the bottom line
+         glDrawArrays(GL_TRIANGLE_STRIP, m_horizontalLineCount*2 + 2 + oldCount.first + oldCount.second, verticesCounts[data].first);
+         oldCount.first += verticesCounts[data].first;
+-        s_program->setUniformValue(u_color1, data->color());
+-        s_program->setUniformValue(u_color2, data->color());
++        m_node->setColor1(data->color());
++        m_node->setColor2(data->color());
+         glDrawArrays(GL_LINE_STRIP, m_horizontalLineCount*2 + 2 + oldCount.first + oldCount.second, verticesCounts[data].second);
+         oldCount.second += verticesCounts[data].second;
+@@ -697,8 +737,8 @@ void Plotter::render()
+     glDisable(GL_BLEND);
+-    s_program->setUniformValue(u_color1, m_gridColor);
+-    s_program->setUniformValue(u_color2, m_gridColor);
++    m_node->setColor1(m_gridColor);
++    m_node->setColor2(m_gridColor);
+     glDrawArrays(GL_LINES, vertices.count()-2, 2);
+     if (m_haveMSAA && m_haveFramebufferBlit) {
+@@ -723,7 +763,7 @@ QSGNode *Plotter::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updateP
+         return nullptr;
+     }
+-    ManagedTextureNode *n = static_cast<ManagedTextureNode *>(oldNode);
++    PlotSGNode *n = static_cast<PlotSGNode *>(oldNode);
+     if (width() == 0 && height() == 0) {
+         delete oldNode;
+@@ -731,8 +771,8 @@ QSGNode *Plotter::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updateP
+     }
+     if (!n) {
+-        n = new ManagedTextureNode();
+-        n->setTexture(QSharedPointer<QSGTexture>(new PlotTexture(window()->openglContext())));
++        n = new PlotSGNode();
++        n->setTexture(new PlotTexture(window()->openglContext()));
+         n->setFiltering(QSGTexture::Linear);
+         m_node = n;
+@@ -786,20 +826,6 @@ QSGNode *Plotter::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updateP
+         m_initialized = true;
+     }
+-    if (!s_program) {
+-        s_program = new QOpenGLShaderProgram;
+-        s_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vs_source);
+-        s_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fs_source);
+-        s_program->bindAttributeLocation("vertex", 0);
+-        s_program->link();
+-
+-        u_yMin = s_program->uniformLocation("yMin");
+-        u_yMax = s_program->uniformLocation("yMax");
+-        u_color1 = s_program->uniformLocation("color1");
+-        u_color2 = s_program->uniformLocation("color2");
+-        u_matrix = s_program->uniformLocation("matrix");
+-    }
+-
+     //we need a size always equal or smaller, size.toSize() won't do
+     const QSize targetTextureSize(qRound(boundingRect().size().width()), qRound(boundingRect().size().height()));
+     if (n->texture()->textureSize() != targetTextureSize) {
+diff --git a/src/qmlcontrols/kquickcontrolsaddons/plotter.h b/src/qmlcontrols/kquickcontrolsaddons/plotter.h
+index 01c0ef2..11ae233 100644
+--- a/src/qmlcontrols/kquickcontrolsaddons/plotter.h
++++ b/src/qmlcontrols/kquickcontrolsaddons/plotter.h
+@@ -47,7 +47,7 @@
+ #include <QQuickWindow>
+ #include <QMutex>
+-class ManagedTextureNode;
++class PlotSGNode;
+ /**
+  * a Plotter can draw a graph of values arriving from an arbitrary number of data sources
+@@ -242,7 +242,7 @@ private:
+     QList<PlotData *> m_plotData;
+     GLuint m_fbo = 0;
+-    ManagedTextureNode *m_node = nullptr;
++    PlotSGNode *m_node = nullptr;
+     qreal m_min;
+     qreal m_max;
+     qreal m_rangeMax;
+@@ -262,13 +262,6 @@ private:
+     int m_samples;
+     QPointer <QQuickWindow> m_window;
+     QMutex m_mutex;
+-
+-    static QOpenGLShaderProgram *s_program;
+-    static int u_matrix;
+-    static int u_color1;
+-    static int u_color2;
+-    static int u_yMin;
+-    static int u_yMax;
+ };
+ #endif
+-- 
+cgit v1.1
diff --git a/kde-frameworks/kdeclarative/kdeclarative-5.57.0-r1.ebuild b/kde-frameworks/kdeclarative/kdeclarative-5.57.0-r1.ebuild
new file mode 100644 (file)
index 0000000..823e38e
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright 1999-2019 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+KDE_TEST="false"
+inherit kde5
+
+DESCRIPTION="Framework providing integration of QML and KDE work spaces"
+LICENSE="LGPL-2+"
+KEYWORDS="~amd64 ~arm ~arm64 ~x86"
+IUSE=""
+
+DEPEND="
+       $(add_frameworks_dep kconfig)
+       $(add_frameworks_dep kcoreaddons)
+       $(add_frameworks_dep kglobalaccel)
+       $(add_frameworks_dep ki18n)
+       $(add_frameworks_dep kiconthemes)
+       $(add_frameworks_dep kio)
+       $(add_frameworks_dep kpackage)
+       $(add_frameworks_dep kservice)
+       $(add_frameworks_dep kwidgetsaddons)
+       $(add_frameworks_dep kwindowsystem)
+       $(add_qt_dep qtdeclarative)
+       $(add_qt_dep qtgui)
+       $(add_qt_dep qtnetwork)
+       $(add_qt_dep qtwidgets)
+       media-libs/libepoxy
+"
+RDEPEND="${DEPEND}"
+
+PATCHES=( "${FILESDIR}/${P}-fix-plotter-crash.patch" )