From c1f076b9ce72bc9866b8a8e494c17f54b8f0edb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 21 Sep 2024 13:00:45 +0200 Subject: [PATCH] Paintable: caching the rendered SVG. --- src/widget/paintable.cpp | 66 ++++++++++++++++++++++++---------------- src/widget/paintable.h | 1 + 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/widget/paintable.cpp b/src/widget/paintable.cpp index 781c7e8f5129..5acae01a22d0 100644 --- a/src/widget/paintable.cpp +++ b/src/widget/paintable.cpp @@ -54,6 +54,7 @@ Paintable::Paintable(const PixmapSource& source, DrawMode mode, double scaleFact if (!source.isSVG()) { m_pPixmap.reset(WPixmapStore::getPixmapNoCache(source.getPath(), scaleFactor)); } else { + qDebug() << "Paintable()" << source.getPath(); auto pSvg = std::make_unique(); if (!source.getSvgSourceData().isEmpty()) { // Call here the different overload for svg content @@ -100,39 +101,43 @@ bool Paintable::isNull() const { } QSize Paintable::size() const { + if (m_pSvg) { + return m_pSvg->defaultSize(); + } if (m_pPixmap) { return m_pPixmap->size(); - } else if (m_pSvg) { - return m_pSvg->defaultSize(); } return QSize(); } int Paintable::width() const { - if (m_pPixmap) { - return m_pPixmap->width(); - } else if (m_pSvg) { + if (m_pSvg) { QSize size = m_pSvg->defaultSize(); return size.width(); } + if (m_pPixmap) { + return m_pPixmap->width(); + } return 0; } int Paintable::height() const { - if (m_pPixmap) { - return m_pPixmap->height(); - } else if (m_pSvg) { + if (m_pSvg) { QSize size = m_pSvg->defaultSize(); return size.height(); } + if (m_pPixmap) { + return m_pPixmap->height(); + } return 0; } QRectF Paintable::rect() const { + if (m_pSvg) { + return QRectF(QPointF(0, 0), m_pSvg->defaultSize()); + } if (m_pPixmap) { return m_pPixmap->rect(); - } else if (m_pSvg) { - return QRectF(QPointF(0, 0), m_pSvg->defaultSize()); } return QRectF(); } @@ -245,8 +250,29 @@ void Paintable::drawCentered(const QRectF& targetRect, QPainter* pPainter, void Paintable::drawInternal(const QRectF& targetRect, QPainter* pPainter, const QRectF& sourceRect) { - // qDebug() << "Paintable::drawInternal" << DrawModeToString(m_drawMode) - // << targetRect << sourceRect; + qDebug() << "Paintable::drawInternal" << DrawModeToString(m_drawMode) + << targetRect << sourceRect; + if (m_pSvg) { + if (m_drawMode == TILE) { + qWarning() << "Tiled SVG should have been rendered to pixmap!"; + } else { + if (!m_pPixmap || + m_pPixmap->size() != targetRect.size().toSize() || + m_lastSourceRect != sourceRect) { + qDebug() << "Paintable cache miss"; + qreal devicePixelRatio = pPainter->device()->devicePixelRatio(); + m_pPixmap = std::make_unique(targetRect.size().toSize()); + m_pPixmap->setDevicePixelRatio(devicePixelRatio); + m_pPixmap->fill(Qt::transparent); + auto pixmapPainter = QPainter(m_pPixmap.get()); + m_pSvg->setViewBox(sourceRect); + m_pSvg->render(&pixmapPainter); + m_lastSourceRect = sourceRect; + } + pPainter->drawPixmap(targetRect.topLeft(), *m_pPixmap); + } + return; + } if (m_pPixmap) { // Note: Qt rounds the target rect to device pixels internally // using roundInDeviceCoordinates() @@ -263,21 +289,7 @@ void Paintable::drawInternal(const QRectF& targetRect, QPainter* pPainter, pPainter->drawPixmap(targetRect, *m_pPixmap, sourceRect); } } - } else if (m_pSvg) { - if (m_drawMode == TILE) { - qWarning() << "Tiled SVG should have been rendered to pixmap!"; - } else { - // NOTE(rryan): QSvgRenderer render does not clip for us -- it - // applies a world transformation using viewBox and renders the - // entire SVG to the painter. We save/restore the QPainter in case - // there is an existing clip region (I don't know of any Mixxx code - // that uses one but we may in the future). - PainterScope PainterScope(pPainter); - pPainter->setClipping(true); - pPainter->setClipRect(targetRect); - m_pSvg->setViewBox(sourceRect); - m_pSvg->render(pPainter, targetRect); - } + return; } } diff --git a/src/widget/paintable.h b/src/widget/paintable.h index 0e61390cd9e7..3097361784eb 100644 --- a/src/widget/paintable.h +++ b/src/widget/paintable.h @@ -57,4 +57,5 @@ class Paintable { std::unique_ptr m_pPixmap; std::unique_ptr m_pSvg; DrawMode m_drawMode; + QRectF m_lastSourceRect; };