summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2016-08-17 13:30:12 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2016-08-17 11:32:27 +0000
commitb63e0069a18e9d49a8c961d5fa27325c527507a1 (patch)
tree2a7740f8747f7caf6fcb525bab5aa90338252983
parent2d3532204c720e2adaefd30dc18e606fcec98598 (diff)
Fix antialiasing support of OpenGL accelerated series
OpenGL accelerated series are now antialiased similarly to non-accelerated series. Task-number: QTRD-2172 Change-Id: Ie8bc014c82d5fa645cf41ab56bebb99fcf8ad301 Reviewed-by: Mika Salmela <mika.salmela@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--examples/charts/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml2
-rw-r--r--examples/charts/qmloscilloscope/qml/qmloscilloscope/main.qml2
-rw-r--r--src/charts/chartpresenter.cpp5
-rw-r--r--src/charts/glwidget.cpp17
-rw-r--r--src/charts/glwidget_p.h7
-rw-r--r--src/charts/qabstractseries.cpp2
-rw-r--r--src/chartsqml2/declarativeabstractrendernode.h1
-rw-r--r--src/chartsqml2/declarativechart.cpp2
-rw-r--r--src/chartsqml2/declarativeopenglrendernode.cpp51
-rw-r--r--src/chartsqml2/declarativeopenglrendernode.h3
-rw-r--r--tests/manual/openglseriestest/mainwindow.cpp7
-rw-r--r--tests/manual/openglseriestest/mainwindow.h1
-rw-r--r--tests/manual/openglseriestest/mainwindow.ui16
13 files changed, 94 insertions, 22 deletions
diff --git a/examples/charts/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml b/examples/charts/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml
index 19277a09..fe3bc869 100644
--- a/examples/charts/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml
+++ b/examples/charts/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml
@@ -96,7 +96,7 @@ ColumnLayout {
id: antialiasButton
text: "Antialias: "
items: ["OFF", "ON"]
- enabled: false
+ enabled: true
currentSelection: 0
onSelectionChanged: antialiasingEnabled(currentSelection == 1);
}
diff --git a/examples/charts/qmloscilloscope/qml/qmloscilloscope/main.qml b/examples/charts/qmloscilloscope/qml/qmloscilloscope/main.qml
index 7c6b2cd7..a8260564 100644
--- a/examples/charts/qmloscilloscope/qml/qmloscilloscope/main.qml
+++ b/examples/charts/qmloscilloscope/qml/qmloscilloscope/main.qml
@@ -56,8 +56,6 @@ Item {
onAntialiasingEnabled: scopeView.antialiasing = enabled;
onOpenGlChanged: {
scopeView.openGL = enabled;
- antialiasButton.enabled = !enabled;
- antialiasButton.currentSelection = 0;
}
}
diff --git a/src/charts/chartpresenter.cpp b/src/charts/chartpresenter.cpp
index e6d38db7..d9b1f03d 100644
--- a/src/charts/chartpresenter.cpp
+++ b/src/charts/chartpresenter.cpp
@@ -562,6 +562,11 @@ void ChartPresenter::updateGLWidget()
#ifndef QT_NO_OPENGL
// GLWidget pointer is wrapped in QPointer as its parent is not in our control, and therefore
// can potentially get deleted unexpectedly.
+ if (!m_glWidget.isNull() && m_glWidget->needsReset()) {
+ m_glWidget->hide();
+ delete m_glWidget.data();
+ m_glWidget.clear();
+ }
if (m_glWidget.isNull() && m_glUseWidget && m_chart->scene()) {
// Find the view of the scene. If the scene has multiple views, only the first view is
// chosen.
diff --git a/src/charts/glwidget.cpp b/src/charts/glwidget.cpp
index c0070dcd..ea2734fc 100644
--- a/src/charts/glwidget.cpp
+++ b/src/charts/glwidget.cpp
@@ -42,7 +42,7 @@
QT_CHARTS_BEGIN_NAMESPACE
-GLWidget::GLWidget(GLXYSeriesDataManager *xyDataManager, QWidget *parent)
+GLWidget::GLWidget(GLXYSeriesDataManager *xyDataManager, QGraphicsView *parent)
: QOpenGLWidget(parent),
m_program(0),
m_shaderAttribLoc(-1),
@@ -50,7 +50,9 @@ GLWidget::GLWidget(GLXYSeriesDataManager *xyDataManager, QWidget *parent)
m_minUniformLoc(-1),
m_deltaUniformLoc(-1),
m_pointSizeUniformLoc(-1),
- m_xyDataManager(xyDataManager)
+ m_xyDataManager(xyDataManager),
+ m_antiAlias(parent->renderHints().testFlag(QPainter::Antialiasing)),
+ m_view(parent)
{
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_AlwaysStackOnTop);
@@ -65,6 +67,7 @@ GLWidget::GLWidget(GLXYSeriesDataManager *xyDataManager, QWidget *parent)
surfaceFormat.setAlphaBufferSize(8);
surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
surfaceFormat.setRenderableType(QSurfaceFormat::DefaultRenderableType);
+ surfaceFormat.setSamples(m_antiAlias ? 4 : 0);
setFormat(surfaceFormat);
connect(xyDataManager, &GLXYSeriesDataManager::seriesRemoved,
@@ -182,14 +185,15 @@ void GLWidget::paintGL()
m_program->setUniformValue(m_minUniformLoc, data->min);
m_program->setUniformValue(m_deltaUniformLoc, data->delta);
m_program->setUniformValue(m_matrixUniformLoc, data->matrix);
-
+ bool dirty = data->dirty;
if (!vbo) {
vbo = new QOpenGLBuffer;
m_seriesBufferMap.insert(i.key(), vbo);
vbo->create();
+ dirty = true;
}
vbo->bind();
- if (data->dirty) {
+ if (dirty) {
vbo->allocate(data->array.constData(), data->array.count() * sizeof(GLfloat));
data->dirty = false;
}
@@ -231,6 +235,11 @@ void GLWidget::resizeGL(int w, int h)
Q_UNUSED(h)
}
+bool GLWidget::needsReset() const
+{
+ return m_view->renderHints().testFlag(QPainter::Antialiasing) != m_antiAlias;
+}
+
QT_CHARTS_END_NAMESPACE
#endif
diff --git a/src/charts/glwidget_p.h b/src/charts/glwidget_p.h
index 024e096a..1ec0fd3d 100644
--- a/src/charts/glwidget_p.h
+++ b/src/charts/glwidget_p.h
@@ -42,6 +42,7 @@
#ifndef QT_NO_OPENGL
#include <QtWidgets/QOpenGLWidget>
+#include <QtWidgets/QGraphicsView>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QOpenGLVertexArrayObject>
#include <QtGui/QOpenGLBuffer>
@@ -60,9 +61,11 @@ class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
Q_OBJECT
public:
- GLWidget(GLXYSeriesDataManager *xyDataManager, QWidget *parent = 0);
+ GLWidget(GLXYSeriesDataManager *xyDataManager, QGraphicsView *parent = 0);
~GLWidget();
+ bool needsReset() const;
+
public Q_SLOTS:
void cleanup();
void cleanXYSeriesResources(const QXYSeries *series);
@@ -84,6 +87,8 @@ private:
QHash<const QAbstractSeries *, QOpenGLBuffer *> m_seriesBufferMap;
GLXYSeriesDataManager *m_xyDataManager;
+ bool m_antiAlias;
+ QGraphicsView *m_view;
};
QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/qabstractseries.cpp b/src/charts/qabstractseries.cpp
index b5c7d8a7..f35bef08 100644
--- a/src/charts/qabstractseries.cpp
+++ b/src/charts/qabstractseries.cpp
@@ -168,7 +168,6 @@ QT_CHARTS_BEGIN_NAMESPACE
\list
\li Series animations are not supported for accelerated series.
- \li Antialiasing is not supported for accelerated series.
\li Point labels are not supported for accelerated series.
\li Pen styles and marker shapes are ignored for accelerated series.
Only solid lines and plain scatter dots are supported.
@@ -224,7 +223,6 @@ QT_CHARTS_BEGIN_NAMESPACE
\list
\li Series animations are not supported for accelerated series.
- \li Antialiasing is not supported for accelerated series.
\li Point labels are not supported for accelerated series.
\li Marker shapes are ignored for accelerated series.
Only plain scatter dots are supported.
diff --git a/src/chartsqml2/declarativeabstractrendernode.h b/src/chartsqml2/declarativeabstractrendernode.h
index afc8c354..554445ba 100644
--- a/src/chartsqml2/declarativeabstractrendernode.h
+++ b/src/chartsqml2/declarativeabstractrendernode.h
@@ -46,6 +46,7 @@ public:
virtual QSize textureSize() const = 0;
virtual void setRect(const QRectF &rect) = 0;
virtual void setSeriesData(bool mapDirty, const GLXYDataMap &dataMap) = 0;
+ virtual void setAntialiasing(bool enable) = 0;
};
diff --git a/src/chartsqml2/declarativechart.cpp b/src/chartsqml2/declarativechart.cpp
index 4dfc3d5d..4600f655 100644
--- a/src/chartsqml2/declarativechart.cpp
+++ b/src/chartsqml2/declarativechart.cpp
@@ -549,6 +549,7 @@ QSGNode *DeclarativeChart::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdateP
node->renderNode()->setRect(adjustedPlotArea);
node->renderNode()->setSeriesData(m_glXYDataManager->mapDirty(),
m_glXYDataManager->dataMap());
+ node->renderNode()->setAntialiasing(antialiasing());
// Clear dirty flags from original xy data
m_glXYDataManager->clearAllDirty();
@@ -720,6 +721,7 @@ void DeclarativeChart::mouseDoubleClickEvent(QMouseEvent *event)
void DeclarativeChart::handleAntialiasingChanged(bool enable)
{
setAntialiasing(enable);
+ emit needRender();
}
void DeclarativeChart::setTheme(DeclarativeChart::Theme theme)
diff --git a/src/chartsqml2/declarativeopenglrendernode.cpp b/src/chartsqml2/declarativeopenglrendernode.cpp
index 0799e36c..9b07a912 100644
--- a/src/chartsqml2/declarativeopenglrendernode.cpp
+++ b/src/chartsqml2/declarativeopenglrendernode.cpp
@@ -47,20 +47,22 @@ QT_CHARTS_BEGIN_NAMESPACE
// It is used as a child node of the chart node.
DeclarativeOpenGLRenderNode::DeclarativeOpenGLRenderNode(QQuickWindow *window) :
QObject(),
- m_texture(0),
+ m_texture(nullptr),
m_imageNode(nullptr),
m_window(window),
m_textureOptions(QQuickWindow::TextureHasAlphaChannel),
m_textureSize(1, 1),
m_recreateFbo(false),
- m_fbo(0),
- m_program(0),
+ m_fbo(nullptr),
+ m_resolvedFbo(nullptr),
+ m_program(nullptr),
m_shaderAttribLoc(-1),
m_colorUniformLoc(-1),
m_minUniformLoc(-1),
m_deltaUniformLoc(-1),
m_pointSizeUniformLoc(-1),
- m_renderNeeded(true)
+ m_renderNeeded(true),
+ m_antialiasing(false)
{
initializeOpenGLFunctions();
@@ -70,13 +72,12 @@ DeclarativeOpenGLRenderNode::DeclarativeOpenGLRenderNode(QQuickWindow *window) :
DeclarativeOpenGLRenderNode::~DeclarativeOpenGLRenderNode()
{
+ cleanXYSeriesResources(0);
+
delete m_texture;
delete m_fbo;
-
+ delete m_resolvedFbo;
delete m_program;
- m_program = 0;
-
- cleanXYSeriesResources(0);
}
static const char *vertexSource =
@@ -138,13 +139,25 @@ void DeclarativeOpenGLRenderNode::recreateFBO()
{
QOpenGLFramebufferObjectFormat fboFormat;
fboFormat.setAttachment(QOpenGLFramebufferObject::NoAttachment);
+
+ int samples = 0;
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+
+ if (m_antialiasing && (!context->isOpenGLES() || context->format().majorVersion() >= 3))
+ samples = 4;
+ fboFormat.setSamples(samples);
+
delete m_fbo;
- m_fbo = new QOpenGLFramebufferObject(m_textureSize.width(),
- m_textureSize.height(),
- fboFormat);
+ delete m_resolvedFbo;
+ m_resolvedFbo = nullptr;
+
+ m_fbo = new QOpenGLFramebufferObject(m_textureSize, fboFormat);
+ if (samples > 0)
+ m_resolvedFbo = new QOpenGLFramebufferObject(m_textureSize);
delete m_texture;
- m_texture = m_window->createTextureFromId(m_fbo->texture(), m_textureSize, m_textureOptions);
+ uint textureId = m_resolvedFbo ? m_resolvedFbo->texture() : m_fbo->texture();
+ m_texture = m_window->createTextureFromId(textureId, m_textureSize, m_textureOptions);
if (!m_imageNode) {
m_imageNode = m_window->createImageNode();
m_imageNode->setFiltering(QSGTexture::Linear);
@@ -218,6 +231,15 @@ void DeclarativeOpenGLRenderNode::setRect(const QRectF &rect)
m_imageNode->setRect(rect);
}
+void DeclarativeOpenGLRenderNode::setAntialiasing(bool enable)
+{
+ if (m_antialiasing != enable) {
+ m_antialiasing = enable;
+ m_recreateFbo = true;
+ m_renderNeeded = true;
+ }
+}
+
void DeclarativeOpenGLRenderNode::renderGL()
{
glClearColor(0, 0, 0, 0);
@@ -281,6 +303,11 @@ void DeclarativeOpenGLRenderNode::renderGL()
}
#endif
+ if (m_resolvedFbo) {
+ QRect rect(QPoint(0, 0), m_fbo->size());
+ QOpenGLFramebufferObject::blitFramebuffer(m_resolvedFbo, rect, m_fbo, rect);
+ }
+
markDirty(DirtyMaterial);
m_window->resetOpenGLState();
}
diff --git a/src/chartsqml2/declarativeopenglrendernode.h b/src/chartsqml2/declarativeopenglrendernode.h
index 09ce64c6..f058fd3f 100644
--- a/src/chartsqml2/declarativeopenglrendernode.h
+++ b/src/chartsqml2/declarativeopenglrendernode.h
@@ -57,6 +57,7 @@ public:
void setSeriesData(bool mapDirty, const GLXYDataMap &dataMap) override;
void setRect(const QRectF &rect) override;
+ void setAntialiasing(bool enable) override;
public Q_SLOTS:
void render();
@@ -74,6 +75,7 @@ private:
bool m_recreateFbo;
GLXYDataMap m_xyDataMap;
QOpenGLFramebufferObject *m_fbo;
+ QOpenGLFramebufferObject *m_resolvedFbo;
QOpenGLShaderProgram *m_program;
int m_shaderAttribLoc;
int m_colorUniformLoc;
@@ -85,6 +87,7 @@ private:
QHash<const QAbstractSeries *, QOpenGLBuffer *> m_seriesBufferMap;
bool m_renderNeeded;
QRectF m_rect;
+ bool m_antialiasing;
};
QT_CHARTS_END_NAMESPACE
diff --git a/tests/manual/openglseriestest/mainwindow.cpp b/tests/manual/openglseriestest/mainwindow.cpp
index e653e483..8b20c7e8 100644
--- a/tests/manual/openglseriestest/mainwindow.cpp
+++ b/tests/manual/openglseriestest/mainwindow.cpp
@@ -104,6 +104,8 @@ MainWindow::MainWindow(QWidget *parent) :
this, SLOT(colorIndexChanged(int)));
connect(ui->widthComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(widthIndexChanged(int)));
+ connect(ui->antiAliasCheckBox, SIGNAL(clicked(bool)),
+ this, SLOT(antiAliasCheckBoxClicked(bool)));
ui->chartView->setChart(m_chart);
ui->chartView->setRenderHint(QPainter::Antialiasing);
@@ -419,6 +421,11 @@ void MainWindow::widthIndexChanged(int index)
}
}
+void MainWindow::antiAliasCheckBoxClicked(bool checked)
+{
+ ui->chartView->setRenderHint(QPainter::Antialiasing, checked);
+}
+
void MainWindow::backgroundIndexChanged(int index)
{
delete m_backgroundBrush;
diff --git a/tests/manual/openglseriestest/mainwindow.h b/tests/manual/openglseriestest/mainwindow.h
index 6ad297f3..8590fea3 100644
--- a/tests/manual/openglseriestest/mainwindow.h
+++ b/tests/manual/openglseriestest/mainwindow.h
@@ -73,6 +73,7 @@ public slots:
void countIndexChanged(int index);
void colorIndexChanged(int index);
void widthIndexChanged(int index);
+ void antiAliasCheckBoxClicked(bool checked);
private:
enum AxisMode {
diff --git a/tests/manual/openglseriestest/mainwindow.ui b/tests/manual/openglseriestest/mainwindow.ui
index e5ca1514..ac52ff7f 100644
--- a/tests/manual/openglseriestest/mainwindow.ui
+++ b/tests/manual/openglseriestest/mainwindow.ui
@@ -545,6 +545,22 @@
</property>
</item>
</widget>
+ <widget class="QCheckBox" name="antiAliasCheckBox">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>370</y>
+ <width>91</width>
+ <height>17</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Antialiasing</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
</widget>
</item>
</layout>