So far the items to be recalculated in the drawing thread had a "dirty" flag and were kept in one array par z-level. Once the series are implemented in terms of QSGNodes, there may lots of these items. To make this more efficient when only one or two of these items change (e.g. highlighting due to mouseover), keep the dirty items in a linked list. Of course, this makes the draw first version of the chart less efficient. There are more fancy ways of implementing the double-linked list, but the few ns gained in the render thread are hardly worth it. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
85 lines
2.3 KiB
C++
85 lines
2.3 KiB
C++
// 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 QSGGeometry;
|
|
class QSGGeometryNode;
|
|
class QSGFlatColorMaterial;
|
|
class QSGImageNode;
|
|
class QSGTexture;
|
|
class StatsView;
|
|
enum class ChartZValue : int;
|
|
|
|
class ChartItem {
|
|
public:
|
|
ChartItem(StatsView &v, ChartZValue z);
|
|
virtual ~ChartItem();
|
|
virtual void render() = 0; // Only call on render thread!
|
|
QRectF getRect() const;
|
|
bool dirty; // If true, call render() when rebuilding the scene
|
|
ChartItem *dirtyPrev, *dirtyNext; // Double linked list of dirty items
|
|
const ChartZValue zValue;
|
|
protected:
|
|
QSizeF sceneSize() const;
|
|
StatsView &view;
|
|
};
|
|
|
|
// A chart item that blits a precalculated pixmap onto the scene.
|
|
class ChartPixmapItem : public ChartItem {
|
|
public:
|
|
ChartPixmapItem(StatsView &v, ChartZValue z);
|
|
~ChartPixmapItem();
|
|
|
|
void setPos(QPointF pos);
|
|
void render() override; // Only call on render thread!
|
|
QRectF getRect() const;
|
|
protected:
|
|
void resize(QSizeF size); // Resets the canvas. Attention: image is *unitialized*.
|
|
std::unique_ptr<QPainter> painter;
|
|
std::unique_ptr<QImage> img;
|
|
void setTextureDirty();
|
|
void setPositionDirty();
|
|
private:
|
|
QRectF rect;
|
|
bool positionDirty; // true if the position changed since last render
|
|
bool textureDirty; // true if the pixmap changed since last render
|
|
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 ChartPixmapItem {
|
|
public:
|
|
ChartRectItem(StatsView &v, ChartZValue z, const QPen &pen, const QBrush &brush, double radius);
|
|
~ChartRectItem();
|
|
void resize(QSizeF size);
|
|
private:
|
|
QPen pen;
|
|
QBrush brush;
|
|
double radius;
|
|
};
|
|
|
|
class ChartLineItem : public ChartItem {
|
|
public:
|
|
ChartLineItem(StatsView &v, ChartZValue z, QColor color, double width);
|
|
~ChartLineItem();
|
|
void setLine(QPointF from, QPointF to);
|
|
void render() override; // Only call on render thread!
|
|
private:
|
|
QPointF from, to;
|
|
QColor color;
|
|
double width;
|
|
bool positionDirty;
|
|
bool materialDirty;
|
|
std::unique_ptr<QSGGeometryNode> node;
|
|
std::unique_ptr<QSGFlatColorMaterial> material;
|
|
std::unique_ptr<QSGGeometry> geometry;
|
|
};
|
|
|
|
#endif
|