diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2021-01-12 15:20:05 +0100 |
---|---|---|
committer | bstoeger <32835590+bstoeger@users.noreply.github.com> | 2021-01-20 08:47:18 +0100 |
commit | 2b961414d7a52d442f5ecd8c2e42e43d044d0d5e (patch) | |
tree | b1d6c47b94dfc80481aaad2e3cfde35335646576 /stats/chartitem.h | |
parent | 9be23b5f3f8373ba115f4e66e77c0537abe982b2 (diff) | |
download | subsurface-2b961414d7a52d442f5ecd8c2e42e43d044d0d5e.tar.gz |
statistics: draw legend as a QSGNode
In order not to waste CPU by constantly rerendering the chart,
we must use these weird OpenGL QSGNode things. The interface
is appallingly low-level and unfriendly.
As a first test, try to convert the legend. Create a wrapper
class that represents a rectangular item with a texture
and that will certainly need some (lots of) optimization.
Make sure that all low-level QSG-objects are only accessed
in the rendering thread. This means that the wrapper has
to maintain a notion of "dirtiness" of the state. I.e.
which part of the QSG-objects have to be modified.
From the low-level wrapper derive a class that draws a rounded
rectangle for every resize. The child class of that must then
paint on the rectangle after every resize.
That looks all not very fortunate, but it displays a
legend and will make it possible to move the legend
without and drawing operations, only shifting around
an OpenGL surface.
The render thread goes through all chart-items and
rerenders them if dirty. Currently, on deletion
of these items, this list is not reset. I.e. currently
it is not supported to remove individual items.
Only the full scene can be cleared!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'stats/chartitem.h')
-rw-r--r-- | stats/chartitem.h | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/stats/chartitem.h b/stats/chartitem.h new file mode 100644 index 000000000..fb4b67dff --- /dev/null +++ b/stats/chartitem.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +// Wrappers around QSGImageNode that allow painting onto an image +// and then turning that into a texture to be displayed in a QQuickItem. +#ifndef CHART_ITEM_H +#define CHART_ITEM_H + +#include <memory> +#include <QPainter> + +class QSGImageNode; +class QSGTexture; +class StatsView; + +class ChartItem { +public: + ChartItem(StatsView &v); + ~ChartItem(); + // Attention: The children are responsible for updating the item. None of these calls will. + void resize(QSizeF size); // Resets the canvas. Attention: image is *unitialized*. + void setPos(QPointF pos); + void render(); // Only call on render thread! + QRectF getRect() const; + bool dirty; // If true, call render() when rebuilding the scene +protected: + std::unique_ptr<QPainter> painter; + std::unique_ptr<QImage> img; + QSizeF sceneSize() const; + void setTextureDirty(); + void setPositionDirty(); +private: + StatsView &view; + QRectF rect; + bool positionDirty; + bool textureDirty; + std::unique_ptr<QSGImageNode> node; + std::unique_ptr<QSGTexture> texture; +}; + +// Draw a rectangular background after resize. Children are responsible for calling update(). +class ChartRectItem : public ChartItem { +public: + ChartRectItem(StatsView &v, const QPen &pen, const QBrush &brush, double radius); + ~ChartRectItem(); + void resize(QSizeF size); +private: + QPen pen; + QBrush brush; + double radius; +}; + +#endif |