diff options
Diffstat (limited to 'src/quick/scenegraph/adaptations/software')
23 files changed, 209 insertions, 122 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp index 02cf8209d1..2e5fdbbe6b 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -77,6 +77,11 @@ QSGSoftwareRenderableNode *QSGAbstractSoftwareRenderer::renderableNode(QSGNode * return m_nodes.value(node, nullptr); } +const QLinkedList<QSGSoftwareRenderableNode*> &QSGAbstractSoftwareRenderer::renderableNodes() const +{ + return m_renderableNodes; +} + void QSGAbstractSoftwareRenderer::addNodeMapping(QSGNode *node, QSGSoftwareRenderableNode *renderableNode) { m_nodes.insert(node, renderableNode); @@ -193,6 +198,12 @@ QRegion QSGAbstractSoftwareRenderer::optimizeRenderList() } } + if (m_obscuredRegion.contains(m_background->rect().toAlignedRect())) { + m_isOpaque = true; + } else { + m_isOpaque = false; + } + // Empty dirtyRegion (for second pass) m_dirtyRegion = QRegion(); m_obscuredRegion = QRegion(); @@ -227,11 +238,11 @@ void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color) renderableNode(m_background)->markMaterialDirty(); } -void QSGAbstractSoftwareRenderer::setBackgroundSize(const QSize &size) +void QSGAbstractSoftwareRenderer::setBackgroundRect(const QRect &rect) { - if (m_background->rect().size().toSize() == size) + if (m_background->rect().toRect() == rect) return; - m_background->setRect(0.0f, 0.0f, size.width(), size.height()); + m_background->setRect(rect); renderableNode(m_background)->markGeometryDirty(); // Invalidate the whole scene when the background is resized markDirty(); @@ -242,21 +253,21 @@ QColor QSGAbstractSoftwareRenderer::backgroundColor() return m_background->color(); } -QSize QSGAbstractSoftwareRenderer::backgroundSize() +QRect QSGAbstractSoftwareRenderer::backgroundRect() { - return m_background->rect().size().toSize(); + return m_background->rect().toRect(); } void QSGAbstractSoftwareRenderer::nodeAdded(QSGNode *node) { - qCDebug(lc2DRender) << "nodeAdded" << (void*)node; + qCDebug(lc2DRender, "nodeAdded %p", (void*)node); m_nodeUpdater->updateNodes(node); } void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node) { - qCDebug(lc2DRender) << "nodeRemoved" << (void*)node; + qCDebug(lc2DRender, "nodeRemoved %p", (void*)node); auto renderable = renderableNode(node); // remove mapping @@ -280,7 +291,7 @@ void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeGeometryUpdated"; + qCDebug(lc2DRender, "nodeGeometryUpdated"); // Mark node as dirty auto renderable = renderableNode(node); @@ -293,7 +304,7 @@ void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeMaterialUpdated"; + qCDebug(lc2DRender, "nodeMaterialUpdated"); // Mark node as dirty auto renderable = renderableNode(node); @@ -306,7 +317,7 @@ void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeMaterialUpdated"; + qCDebug(lc2DRender, "nodeMaterialUpdated"); // Update children nodes m_nodeUpdater->updateNodes(node); @@ -314,7 +325,7 @@ void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node) void QSGAbstractSoftwareRenderer::nodeOpacityUpdated(QSGNode *node) { - qCDebug(lc2DRender) << "nodeOpacityUpdated"; + qCDebug(lc2DRender, "nodeOpacityUpdated"); // Update children nodes m_nodeUpdater->updateNodes(node); diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h index 905577b92a..99204ef25e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h @@ -63,7 +63,7 @@ class QSGSimpleRectNode; class QSGSoftwareRenderableNode; class QSGSoftwareRenderableNodeUpdater; -class QSGAbstractSoftwareRenderer : public QSGRenderer +class Q_QUICK_PRIVATE_EXPORT QSGAbstractSoftwareRenderer : public QSGRenderer { public: QSGAbstractSoftwareRenderer(QSGRenderContext *context); @@ -83,9 +83,12 @@ protected: QRegion optimizeRenderList(); void setBackgroundColor(const QColor &color); - void setBackgroundSize(const QSize &size); + void setBackgroundRect(const QRect &rect); QColor backgroundColor(); - QSize backgroundSize(); + QRect backgroundRect(); + // only known after calling optimizeRenderList() + bool isOpaque() const { return m_isOpaque; } + const QLinkedList<QSGSoftwareRenderableNode*> &renderableNodes() const; private: void nodeAdded(QSGNode *node); @@ -102,6 +105,7 @@ private: QRegion m_dirtyRegion; QRegion m_obscuredRegion; + bool m_isOpaque = false; QSGSoftwareRenderableNodeUpdater *m_nodeUpdater; }; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp index 92c02b4966..c33144344f 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation.cpp @@ -74,6 +74,7 @@ QSGContextFactoryInterface::Flags QSGSoftwareAdaptation::flags(const QString &) QSGRenderLoop *QSGSoftwareAdaptation::createWindowManager() { +#if QT_CONFIG(thread) static bool threaded = false; static bool envChecked = false; if (!envChecked) { @@ -83,10 +84,11 @@ QSGRenderLoop *QSGSoftwareAdaptation::createWindowManager() if (threaded) return new QSGSoftwareThreadedRenderLoop; +#endif return new QSGSoftwareRenderLoop(); } -QSGSoftwareContext *QSGSoftwareAdaptation::instance = 0; +QSGSoftwareContext *QSGSoftwareAdaptation::instance = nullptr; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h index ffe54b5d4b..8b2a545033 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareadaptation_p.h @@ -62,7 +62,7 @@ class QSGSoftwareContext; class QSGSoftwareAdaptation : public QSGContextPlugin { public: - QSGSoftwareAdaptation(QObject *parent = 0); + QSGSoftwareAdaptation(QObject *parent = nullptr); QStringList keys() const override; QSGContext *create(const QString &key) const override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index aa850a80db..5b5bf005d8 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -205,12 +205,12 @@ QSGRendererInterface::ShaderType QSGSoftwareContext::shaderType() const QSGRendererInterface::ShaderCompilationTypes QSGSoftwareContext::shaderCompilationType() const { - return 0; + return nullptr; } QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() const { - return 0; + return nullptr; } void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp index 21f20c66cd..dd789b78c7 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp @@ -49,12 +49,40 @@ QSGSoftwareGlyphNode::QSGSoftwareGlyphNode() setGeometry(&m_geometry); } +namespace { +QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs) +{ + qreal minX = 0; + qreal minY = 0; + qreal maxX = 0; + qreal maxY = 0; + + for (int i = 0, n = qMin(glyphs.glyphIndexes().size(), glyphs.positions().size()); i < n; ++i) { + QRectF glyphRect = glyphs.rawFont().boundingRect(glyphs.glyphIndexes()[i]); + glyphRect.translate(glyphs.positions()[i]); + + if (i == 0) { + minX = glyphRect.left(); + minY = glyphRect.top(); + maxX = glyphRect.right(); + maxY = glyphRect.bottom(); + } else { + minX = qMin(glyphRect.left(), minX); + minY = qMin(glyphRect.top(), minY); + maxX = qMax(glyphRect.right(),maxX); + maxY = qMax(glyphRect.bottom(), maxY); + } + } + QRectF boundingRect(QPointF(minX, minY), QPointF(maxX, maxY)); + return boundingRect.translated(position - QPointF(0.0, glyphs.rawFont().ascent())); +} +} void QSGSoftwareGlyphNode::setGlyphs(const QPointF &position, const QGlyphRun &glyphs) { m_position = position; m_glyphRun = glyphs; - m_bounding_rect = glyphs.boundingRect().translated(m_position - QPointF(0.0, glyphs.rawFont().ascent())); + m_bounding_rect = calculateBoundingRect(position, glyphs); } void QSGSoftwareGlyphNode::setColor(const QColor &color) @@ -91,8 +119,8 @@ void QSGSoftwareGlyphNode::paint(QPainter *painter) QPointF pos = m_position - QPointF(0, m_glyphRun.rawFont().ascent()); qreal offset = 1.0; - if (painter->device()->devicePixelRatio() != 0) - offset = 1.0 / painter->device()->devicePixelRatio(); + if (painter->device()->devicePixelRatioF() > 0.0) + offset = 1.0 / painter->device()->devicePixelRatioF(); switch (m_style) { case QQuickText::Normal: break; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp index 10291b9cb5..da5d39db20 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp @@ -68,6 +68,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin QMargins sourceMargins = normalizedMargins(sourceMarginsIn); QMargins targetMargins = normalizedMargins(targetMarginsIn); + const qreal sourceDpr = pixmap.devicePixelRatioF(); + sourceMargins *= sourceDpr; + // source center const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); const int sourceCenterLeft = sourceRect.left() + sourceMargins.left(); @@ -89,20 +92,13 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin int columns = 3; int rows = 3; if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0) - columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth))); + columns = qMax(3, 2 + qCeil((targetCenterWidth * sourceDpr) / qreal(sourceCenterWidth))); if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0) - rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight))); + rows = qMax(3, 2 + qCeil((targetCenterHeight * sourceDpr) / qreal(sourceCenterHeight))); xTarget.resize(columns + 1); yTarget.resize(rows + 1); - bool oldAA = painter->testRenderHint(QPainter::Antialiasing); - if (painter->paintEngine()->type() != QPaintEngine::OpenGL - && painter->paintEngine()->type() != QPaintEngine::OpenGL2 - && oldAA && painter->combinedTransform().type() != QTransform::TxNone) { - painter->setRenderHint(QPainter::Antialiasing, false); - } - xTarget[0] = targetRect.left(); xTarget[1] = targetCenterLeft; xTarget[columns - 1] = targetCenterRight; @@ -121,7 +117,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin dx = targetCenterWidth; break; case Qt::RepeatTile: - dx = sourceCenterWidth; + dx = sourceCenterWidth / sourceDpr; break; case Qt::RoundTile: dx = targetCenterWidth / qreal(columns - 2); @@ -136,7 +132,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin dy = targetCenterHeight; break; case Qt::RepeatTile: - dy = sourceCenterHeight; + dy = sourceCenterHeight / sourceDpr; break; case Qt::RoundTile: dy = targetCenterHeight / qreal(rows - 2); @@ -308,9 +304,6 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint); if (translucentData.size()) painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap); - - if (oldAA) - painter->setRenderHint(QPainter::Antialiasing, true); } } // QSGSoftwareHelpers namespace @@ -318,8 +311,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin QSGSoftwareInternalImageNode::QSGSoftwareInternalImageNode() : m_innerSourceRect(0, 0, 1, 1) , m_subSourceRect(0, 0, 1, 1) - , m_texture(0) + , m_texture(nullptr) , m_mirror(false) + , m_textureIsLayer(false) , m_smooth(true) , m_tileHorizontal(false) , m_tileVertical(false) @@ -366,6 +360,7 @@ void QSGSoftwareInternalImageNode::setTexture(QSGTexture *texture) { m_texture = texture; m_cachedMirroredPixmapIsDirty = true; + m_textureIsLayer = static_cast<bool>(qobject_cast<QSGSoftwareLayer*>(texture)); markDirty(DirtyMaterial); } @@ -415,8 +410,13 @@ void QSGSoftwareInternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrap void QSGSoftwareInternalImageNode::update() { if (m_cachedMirroredPixmapIsDirty) { - if (m_mirror) { - m_cachedMirroredPixmap = pixmap().transformed(QTransform(-1, 0, 0, 1, 0, 0)); + if (m_mirror || m_textureIsLayer) { + QTransform transform( + (m_mirror ? -1 : 1), 0, + 0 , (m_textureIsLayer ? -1 :1), + 0 , 0 + ); + m_cachedMirroredPixmap = pixmap().transformed(transform); } else { //Cleanup cached pixmap if necessary if (!m_cachedMirroredPixmap.isNull()) @@ -436,6 +436,7 @@ void QSGSoftwareInternalImageNode::preprocess() } if (doDirty) markDirty(DirtyMaterial); + m_cachedMirroredPixmapIsDirty = doDirty; } static Qt::TileRule getTileRule(qreal factor) @@ -453,8 +454,10 @@ static Qt::TileRule getTileRule(qreal factor) void QSGSoftwareInternalImageNode::paint(QPainter *painter) { painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); + // Disable antialiased clipping. It causes transformed tiles to have gaps. + painter->setRenderHint(QPainter::Antialiasing, false); - const QPixmap &pm = m_mirror ? m_cachedMirroredPixmap : pixmap(); + const QPixmap &pm = m_mirror || m_textureIsLayer ? m_cachedMirroredPixmap : pixmap(); if (m_innerTargetRect != m_targetRect) { // border image @@ -462,7 +465,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter) m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom()); QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height())); QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()), - margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0)); + margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr)); return; } @@ -470,8 +473,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter) painter->save(); qreal sx = m_targetRect.width()/(m_subSourceRect.width()*pm.width()); qreal sy = m_targetRect.height()/(m_subSourceRect.height()*pm.height()); - QMatrix transform(sx, 0, 0, sy, 0, 0); - painter->setMatrix(transform, true); + painter->setTransform(QTransform::fromScale(sx, sy), true); painter->drawTiledPixmap(QRectF(m_targetRect.x()/sx, m_targetRect.y()/sy, m_targetRect.width()/sx, m_targetRect.height()/sy), pm, QPointF(m_subSourceRect.left()*pm.width(), m_subSourceRect.top()*pm.height())); @@ -483,6 +485,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter) } } + QRectF QSGSoftwareInternalImageNode::rect() const { return m_targetRect; @@ -490,12 +493,13 @@ QRectF QSGSoftwareInternalImageNode::rect() const const QPixmap &QSGSoftwareInternalImageNode::pixmap() const { - if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(m_texture)) { + if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(m_texture)) return pt->pixmap(); - } else { - QSGSoftwareLayer *layer = qobject_cast<QSGSoftwareLayer*>(m_texture); + if (QSGSoftwareLayer *layer = qobject_cast<QSGSoftwareLayer*>(m_texture)) return layer->pixmap(); - } + Q_ASSERT(m_texture == nullptr); + static const QPixmap nullPixmap; + return nullPixmap; } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h index f21667fdf7..b80bacbaa0 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h @@ -124,8 +124,8 @@ public: QRectF rect() const; -private: const QPixmap &pixmap() const; +private: QRectF m_targetRect; QRectF m_innerTargetRect; @@ -136,6 +136,7 @@ private: QPixmap m_cachedMirroredPixmap; bool m_mirror; + bool m_textureIsLayer; bool m_smooth; bool m_tileHorizontal; bool m_tileVertical; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp index f6898b3879..f50fa00b0b 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE QSGSoftwareInternalRectangleNode::QSGSoftwareInternalRectangleNode() : m_penWidth(0) , m_radius(0) + , m_vertical(true) , m_cornerPixmapIsDirty(true) , m_devicePixelRatio(1) { @@ -120,7 +121,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st for (const QGradientStop &stop : qAsConst(stops)) { if (stop.first < 0.0 || stop.first > 1.0) { needsNormalization = true; - continue; + break; } } @@ -186,6 +187,15 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st markDirty(DirtyMaterial); } +void QSGSoftwareInternalRectangleNode::setGradientVertical(bool vertical) +{ + if (m_vertical != vertical) { + m_vertical = vertical; + m_cornerPixmapIsDirty = true; + markDirty(DirtyMaterial); + } +} + void QSGSoftwareInternalRectangleNode::setRadius(qreal radius) { if (m_radius != radius) { @@ -209,7 +219,7 @@ void QSGSoftwareInternalRectangleNode::update() } if (!m_stops.isEmpty()) { - QLinearGradient gradient(QPoint(0,0), QPoint(0,1)); + QLinearGradient gradient(QPoint(0,0), QPoint(m_vertical ? 0 : 1, m_vertical ? 1 : 0)); gradient.setStops(m_stops); gradient.setCoordinateMode(QGradient::ObjectBoundingMode); m_brush = QBrush(gradient); @@ -227,8 +237,8 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter) { //We can only check for a device pixel ratio change when we know what //paint device is being used. - if (painter->device()->devicePixelRatio() != m_devicePixelRatio) { - m_devicePixelRatio = painter->device()->devicePixelRatio(); + if (!qFuzzyCompare(painter->device()->devicePixelRatioF(), m_devicePixelRatio)) { + m_devicePixelRatio = painter->device()->devicePixelRatioF(); generateCornerPixmap(); } @@ -245,7 +255,7 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter) } else { //Rounded Rects and Rects with Borders //Avoids broken behaviors of QPainter::drawRect/roundedRect - QPixmap pixmap = QPixmap(m_rect.width() * m_devicePixelRatio, m_rect.height() * m_devicePixelRatio); + QPixmap pixmap = QPixmap(qRound(m_rect.width() * m_devicePixelRatio), qRound(m_rect.height() * m_devicePixelRatio)); pixmap.fill(Qt::transparent); pixmap.setDevicePixelRatio(m_devicePixelRatio); QPainter pixmapPainter(&pixmap); @@ -356,7 +366,7 @@ void QSGSoftwareInternalRectangleNode::paintRectangle(QPainter *painter, const Q } else { //blit 4 corners to border - int scaledRadius = radius * m_devicePixelRatio; + int scaledRadius = qRound(radius * m_devicePixelRatio); QRectF topLeftCorner(QPointF(rect.x(), rect.y()), QPointF(rect.x() + radius, rect.y() + radius)); painter->drawPixmap(topLeftCorner, m_cornerPixmap, QRectF(0, 0, scaledRadius, scaledRadius)); @@ -415,8 +425,11 @@ void QSGSoftwareInternalRectangleNode::generateCornerPixmap() { //Generate new corner Pixmap int radius = qFloor(qMin(qMin(m_rect.width(), m_rect.height()) * 0.5, m_radius)); + const auto width = qRound(radius * 2 * m_devicePixelRatio); + + if (m_cornerPixmap.width() != width) + m_cornerPixmap = QPixmap(width, width); - m_cornerPixmap = QPixmap(radius * 2 * m_devicePixelRatio, radius * 2 * m_devicePixelRatio); m_cornerPixmap.setDevicePixelRatio(m_devicePixelRatio); m_cornerPixmap.fill(Qt::transparent); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h index f363e279e1..125520de26 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h @@ -69,6 +69,7 @@ public: void setPenColor(const QColor &color) override; void setPenWidth(qreal width) override; void setGradientStops(const QGradientStops &stops) override; + void setGradientVertical(bool vertical) override; void setRadius(qreal radius) override; void setAntialiasing(bool antialiasing) override { Q_UNUSED(antialiasing) } void setAligned(bool aligned) override; @@ -91,11 +92,12 @@ private: double m_radius; QPen m_pen; QBrush m_brush; + bool m_vertical; bool m_cornerPixmapIsDirty; QPixmap m_cornerPixmap; - int m_devicePixelRatio; + qreal m_devicePixelRatio; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp index 2954f591ad..70378d2950 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -45,12 +45,12 @@ QT_BEGIN_NAMESPACE QSGSoftwareLayer::QSGSoftwareLayer(QSGRenderContext *renderContext) - : m_item(0) + : m_item(nullptr) , m_context(renderContext) - , m_renderer(0) + , m_renderer(nullptr) , m_device_pixel_ratio(1) , m_mirrorHorizontal(false) - , m_mirrorVertical(false) + , m_mirrorVertical(true) , m_live(true) , m_grab(true) , m_recursive(false) @@ -203,7 +203,7 @@ void QSGSoftwareLayer::markDirtyTexture() void QSGSoftwareLayer::invalidated() { delete m_renderer; - m_renderer = 0; + m_renderer = nullptr; } void QSGSoftwareLayer::grab() @@ -229,9 +229,6 @@ void QSGSoftwareLayer::grab() if (m_pixmap.size() != m_size) { m_pixmap = QPixmap(m_size); m_pixmap.setDevicePixelRatio(m_device_pixel_ratio); - // This fill here is wasteful, but necessary because it is the only way - // to force a QImage based pixmap to have an alpha channel. - m_pixmap.fill(Qt::transparent); } // Render texture. @@ -243,9 +240,9 @@ void QSGSoftwareLayer::grab() m_renderer->setDeviceRect(m_size); m_renderer->setViewportRect(m_size); QRect mirrored(m_mirrorHorizontal ? m_rect.right() * m_device_pixel_ratio : m_rect.left() * m_device_pixel_ratio, - m_mirrorVertical ? m_rect.top() * m_device_pixel_ratio : m_rect.bottom() * m_device_pixel_ratio, + m_mirrorVertical ? m_rect.bottom() * m_device_pixel_ratio : m_rect.top() * m_device_pixel_ratio, m_mirrorHorizontal ? -m_rect.width() * m_device_pixel_ratio : m_rect.width() * m_device_pixel_ratio, - m_mirrorVertical ? m_rect.height() * m_device_pixel_ratio : -m_rect.height() * m_device_pixel_ratio); + m_mirrorVertical ? -m_rect.height() * m_device_pixel_ratio : m_rect.height() * m_device_pixel_ratio); m_renderer->setProjectionRect(mirrored); m_renderer->setClearColor(Qt::transparent); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp index 34b0cd5b72..60ae06dd94 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepainternode.cpp @@ -47,7 +47,7 @@ QSGSoftwarePainterNode::QSGSoftwarePainterNode(QQuickPaintedItem *item) : QSGPainterNode() , m_preferredRenderTarget(QQuickPaintedItem::Image) , m_item(item) - , m_texture(0) + , m_texture(nullptr) , m_dirtyContents(false) , m_opaquePainting(false) , m_linear_filtering(false) diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp index ad6cf39425..bb4afc8301 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp @@ -79,16 +79,9 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target) QElapsedTimer renderTimer; // Setup background item - setBackgroundSize(QSize(target->width(), target->height())); + setBackgroundRect(m_projectionRect.normalized()); setBackgroundColor(clearColor()); - QPainter painter(target); - painter.setRenderHint(QPainter::Antialiasing); - painter.setWindow(m_projectionRect); - auto rc = static_cast<QSGSoftwareRenderContext *>(context()); - QPainter *prevPainter = rc->m_activePainter; - rc->m_activePainter = &painter; - renderTimer.start(); buildRenderList(); qint64 buildRenderListTime = renderTimer.restart(); @@ -101,6 +94,19 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target) optimizeRenderList(); qint64 optimizeRenderListTime = renderTimer.restart(); + if (!isOpaque() && target->devType() == QInternal::Pixmap) { + // This fill here is wasteful, but necessary because it is the only way + // to force a QImage based pixmap to have an alpha channel. + static_cast<QPixmap *>(target)->fill(Qt::transparent); + } + + QPainter painter(target); + painter.setRenderHint(QPainter::Antialiasing); + painter.setWindow(m_projectionRect); + auto rc = static_cast<QSGSoftwareRenderContext *>(context()); + QPainter *prevPainter = rc->m_activePainter; + rc->m_activePainter = &painter; + QRegion paintedRegion = renderNodes(&painter); qint64 renderTime = renderTimer.elapsed(); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp index 77d21ec042..20286a03d5 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qsgsoftwarepublicnodes_p.h" +#include "qsgsoftwarelayer_p.h" #include "qsgsoftwarepixmaptexture_p.h" #include "qsgsoftwareinternalimagenode_p.h" @@ -98,12 +99,17 @@ void QSGSoftwareImageNode::paint(QPainter *painter) updateCachedMirroredPixmap(); painter->setRenderHint(QPainter::SmoothPixmapTransform, (m_filtering == QSGTexture::Linear)); + // Disable antialiased clipping. It causes transformed tiles to have gaps. + painter->setRenderHint(QPainter::Antialiasing, false); if (!m_cachedPixmap.isNull()) { painter->drawPixmap(m_rect, m_cachedPixmap, m_sourceRect); } else if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(m_texture)) { const QPixmap &pm = pt->pixmap(); painter->drawPixmap(m_rect, pm, m_sourceRect); + } else if (QSGSoftwareLayer *pt = qobject_cast<QSGSoftwareLayer *>(m_texture)) { + const QPixmap &pm = pt->pixmap(); + painter->drawPixmap(m_rect, pm, m_sourceRect); } else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(m_texture)) { const QImage &im = pt->image(); painter->drawImage(m_rect, im, m_sourceRect); @@ -115,7 +121,6 @@ void QSGSoftwareImageNode::updateCachedMirroredPixmap() if (m_transformMode == NoTransform) { m_cachedPixmap = QPixmap(); } else { - if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(m_texture)) { QTransform mirrorTransform; if (m_transformMode.testFlag(MirrorVertically)) @@ -123,6 +128,13 @@ void QSGSoftwareImageNode::updateCachedMirroredPixmap() if (m_transformMode.testFlag(MirrorHorizontally)) mirrorTransform = mirrorTransform.scale(-1, 1); m_cachedPixmap = pt->pixmap().transformed(mirrorTransform); + } else if (QSGSoftwareLayer *pt = qobject_cast<QSGSoftwareLayer *>(m_texture)) { + QTransform mirrorTransform; + if (m_transformMode.testFlag(MirrorVertically)) + mirrorTransform = mirrorTransform.scale(1, -1); + if (m_transformMode.testFlag(MirrorHorizontally)) + mirrorTransform = mirrorTransform.scale(-1, 1); + m_cachedPixmap = pt->pixmap().transformed(mirrorTransform); } else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(m_texture)) { m_cachedPixmap = QPixmap::fromImage(pt->image().mirrored(m_transformMode.testFlag(MirrorHorizontally), m_transformMode.testFlag(MirrorVertically))); } else { @@ -144,10 +156,11 @@ void QSGSoftwareNinePatchNode::setTexture(QSGTexture *texture) QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(texture); if (!pt) { qWarning() << "Image used with invalid texture format."; - return; + } else { + m_pixmap = pt->pixmap(); + markDirty(DirtyMaterial); } - m_pixmap = pt->pixmap(); - markDirty(DirtyMaterial); + delete texture; } void QSGSoftwareNinePatchNode::setBounds(const QRectF &bounds) @@ -184,11 +197,14 @@ void QSGSoftwareNinePatchNode::update() void QSGSoftwareNinePatchNode::paint(QPainter *painter) { + // Disable antialiased clipping. It causes transformed tiles to have gaps. + painter->setRenderHint(QPainter::Antialiasing, false); + if (m_margins.isNull()) painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height())); else QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()), - m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(0)); + m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr)); } QRectF QSGSoftwareNinePatchNode::bounds() const diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h index 9f1913205b..114137fb55 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes_p.h @@ -133,6 +133,8 @@ public: QRectF bounds() const; + bool isOpaque() const { return !m_pixmap.hasAlphaChannel(); } + private: QPixmap m_pixmap; QRectF m_bounds; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp index 8036baf166..7fb531cca3 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp @@ -134,73 +134,58 @@ void QSGSoftwareRenderableNode::update() { // Update the Node properties m_isDirty = true; + m_isOpaque = false; QRectF boundingRect; switch (m_nodeType) { case QSGSoftwareRenderableNode::SimpleRect: - if (m_handle.simpleRectNode->color().alpha() == 255 && !m_transform.isRotating()) + if (m_handle.simpleRectNode->color().alpha() == 255) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleRectNode->rect(); break; case QSGSoftwareRenderableNode::SimpleTexture: - if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel() && !m_transform.isRotating()) + if (!m_handle.simpleTextureNode->texture()->hasAlphaChannel()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleTextureNode->rect(); break; case QSGSoftwareRenderableNode::Image: - // There isn't a way to tell, so assume it's not - m_isOpaque = false; + m_isOpaque = !m_handle.imageNode->pixmap().hasAlphaChannel(); boundingRect = m_handle.imageNode->rect().toRect(); break; case QSGSoftwareRenderableNode::Painter: - if (m_handle.painterNode->opaquePainting() && !m_transform.isRotating()) + if (m_handle.painterNode->opaquePainting()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = QRectF(0, 0, m_handle.painterNode->size().width(), m_handle.painterNode->size().height()); break; case QSGSoftwareRenderableNode::Rectangle: - if (m_handle.rectangleNode->isOpaque() && !m_transform.isRotating()) + if (m_handle.rectangleNode->isOpaque()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.rectangleNode->rect(); break; case QSGSoftwareRenderableNode::Glyph: // Always has alpha - m_isOpaque = false; - boundingRect = m_handle.glpyhNode->boundingRect(); break; case QSGSoftwareRenderableNode::NinePatch: - // Difficult to tell, assume non-opaque - m_isOpaque = false; + m_isOpaque = m_handle.ninePatchNode->isOpaque(); boundingRect = m_handle.ninePatchNode->bounds(); break; case QSGSoftwareRenderableNode::SimpleRectangle: - if (m_handle.simpleRectangleNode->color().alpha() == 255 && !m_transform.isRotating()) + if (m_handle.simpleRectangleNode->color().alpha() == 255) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleRectangleNode->rect(); break; case QSGSoftwareRenderableNode::SimpleImage: - if (!m_handle.simpleImageNode->texture()->hasAlphaChannel() && !m_transform.isRotating()) + if (!m_handle.simpleImageNode->texture()->hasAlphaChannel()) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.simpleImageNode->rect(); break; @@ -211,10 +196,8 @@ void QSGSoftwareRenderableNode::update() break; #endif case QSGSoftwareRenderableNode::RenderNode: - if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering) && !m_transform.isRotating()) + if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering)) m_isOpaque = true; - else - m_isOpaque = false; boundingRect = m_handle.renderNode->rect(); break; @@ -222,6 +205,9 @@ void QSGSoftwareRenderableNode::update() break; } + if (m_transform.isRotating()) + m_isOpaque = false; + const QRectF transformedRect = m_transform.mapRect(boundingRect); m_boundingRectMin = toRectMin(transformedRect); m_boundingRectMax = toRectMax(transformedRect); @@ -232,8 +218,9 @@ void QSGSoftwareRenderableNode::update() m_boundingRectMin = QRect(); m_boundingRectMax = QRect(); } else { - m_boundingRectMin = m_boundingRectMin.intersected(m_clipRegion.rects().first()); - m_boundingRectMax = m_boundingRectMax.intersected(m_clipRegion.rects().first()); + const auto rects = m_clipRegion.begin(); + m_boundingRectMin = m_boundingRectMin.intersected(rects[0]); + m_boundingRectMax = m_boundingRectMax.intersected(rects[0]); } } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h index 8fc87db179..b20d0a1828 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h @@ -72,7 +72,7 @@ class QSGSoftwareNinePatchNode; class QSGSoftwareSpriteNode; class QSGRenderNode; -class QSGSoftwareRenderableNode +class Q_QUICK_PRIVATE_EXPORT QSGSoftwareRenderableNode { public: enum NodeType { @@ -104,6 +104,7 @@ public: bool isOpaque() const { return m_isOpaque; } bool isDirty() const { return m_isDirty; } bool isDirtyRegionEmpty() const; + QSGNode *handle() const { return m_handle.node; } void setTransform(const QTransform &transform); void setClipRegion(const QRegion &clipRegion, bool hasClipRegion = true); @@ -123,6 +124,7 @@ public: private: union RenderableNodeHandle { + QSGNode *node; QSGSimpleRectNode *simpleRectNode; QSGSimpleTextureNode *simpleTextureNode; QSGSoftwareInternalImageNode *imageNode; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp index 4937565aa9..fabecfcbb8 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp @@ -83,7 +83,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *) bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node) { // Make sure to translate the clip rect into world coordinates - if (m_clipState.count() == 1) { + if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) { m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect()))); m_hasClip = true; } else { @@ -97,7 +97,7 @@ bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node) void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *) { m_clipState.pop(); - if (m_clipState.count() == 1) + if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) m_hasClip = false; } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp index 85d04fe136..e9ed52d428 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp @@ -112,8 +112,9 @@ void QSGSoftwareRenderer::render() QElapsedTimer renderTimer; setBackgroundColor(clearColor()); - setBackgroundSize(QSize(m_paintDevice->width() / m_paintDevice->devicePixelRatio(), - m_paintDevice->height() / m_paintDevice->devicePixelRatio())); + setBackgroundRect(QRect(0, 0, + m_paintDevice->width() / m_paintDevice->devicePixelRatioF(), + m_paintDevice->height() / m_paintDevice->devicePixelRatioF())); // Build Renderlist // The renderlist is created by visiting each node in the tree and when a @@ -155,6 +156,7 @@ void QSGSoftwareRenderer::render() m_flushRegion = renderNodes(&painter); qint64 renderTime = renderTimer.elapsed(); + painter.end(); if (m_backingStore != nullptr) m_backingStore->endPaint(); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index 962db20cbc..f5a41410ee 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -45,6 +45,7 @@ #include <private/qquickwindow_p.h> #include <QElapsedTimer> +#include <private/qquickanimatorcontroller_p.h> #include <private/qquickprofiler_p.h> #include <private/qsgsoftwarerenderer_p.h> #include <qpa/qplatformbackingstore.h> @@ -97,8 +98,9 @@ void QSGSoftwareRenderLoop::windowDestroyed(QQuickWindow *window) if (m_windows.size() == 0) { rc->invalidate(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); } + + delete d->animationController; } void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) @@ -149,6 +151,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) emit window->afterAnimating(); cd->syncSceneGraph(); + rc->endSync(); if (profileFrames) syncTime = renderTimer.nsecsElapsed(); @@ -195,7 +198,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) int(polishTime / 1000000), int((syncTime - polishTime) / 1000000), int((renderTime - syncTime) / 1000000), - int((swapTime - renderTime) / 10000000), + int((swapTime - renderTime) / 1000000), int(lastFrameTime.msecsTo(QTime::currentTime()))); lastFrameTime = QTime::currentTime(); } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp index ba7bbc2d11..d4e5e98d68 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp @@ -123,7 +123,7 @@ void QSGSoftwareSpriteNode::paint(QPainter *painter) // XXX try to do some kind of interpolation between sourceA and sourceB using time painter->drawPixmap(QRectF(0, 0, m_size.width(), m_size.height()), pixmap, - QRectF(m_sourceA, m_spriteSize)); + QRectF(m_sourceA * pixmap.devicePixelRatioF(), m_spriteSize * pixmap.devicePixelRatioF())); } bool QSGSoftwareSpriteNode::isOpaque() const diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index d2186e7cf1..f8973af2fb 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -294,7 +294,7 @@ bool QSGSoftwareRenderThread::event(QEvent *e) } rc->invalidate(); QCoreApplication::processEvents(); - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); if (wme->destroying) delete wd->animationController; } @@ -330,6 +330,7 @@ bool QSGSoftwareRenderThread::event(QEvent *e) softwareRenderer->setBackingStore(backingStore); rc->initialize(nullptr); wd->syncSceneGraph(); + rc->endSync(); wd->renderSceneGraph(wme->window->size()); *wme->image = backingStore->handle()->toImage(); } @@ -443,6 +444,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose) rc->initialize(nullptr); wd->syncSceneGraph(); + rc->endSync(); if (!hadRenderer && wd->renderer) { qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - created renderer"); @@ -454,7 +456,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose) // Process deferred deletes now, directly after the sync as deleteLater // on the GUI must now also have resulted in SG changes and the delete // is a safe operation. - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); } if (!inExpose) { @@ -521,7 +523,7 @@ void QSGSoftwareRenderThread::syncAndRender() // rate of the current screen the window is on. int blockTime = vsyncDelta - (int) renderThrottleTimer.elapsed(); if (blockTime > 0) { - qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "RT - blocking for " << blockTime << "ms"; + qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - blocking for %d ms", blockTime); msleep(blockTime); } renderThrottleTimer.restart(); diff --git a/src/quick/scenegraph/adaptations/software/software.pri b/src/quick/scenegraph/adaptations/software/software.pri index de5f01cdee..278dbe7944 100644 --- a/src/quick/scenegraph/adaptations/software/software.pri +++ b/src/quick/scenegraph/adaptations/software/software.pri @@ -18,8 +18,7 @@ SOURCES += \ $$PWD/qsgsoftwarerenderlistbuilder.cpp \ $$PWD/qsgsoftwarerenderloop.cpp \ $$PWD/qsgsoftwarelayer.cpp \ - $$PWD/qsgsoftwareadaptation.cpp \ - $$PWD/qsgsoftwarethreadedrenderloop.cpp + $$PWD/qsgsoftwareadaptation.cpp HEADERS += \ $$PWD/qsgsoftwarecontext_p.h \ @@ -37,8 +36,7 @@ HEADERS += \ $$PWD/qsgsoftwarerenderlistbuilder_p.h \ $$PWD/qsgsoftwarerenderloop_p.h \ $$PWD/qsgsoftwarelayer_p.h \ - $$PWD/qsgsoftwareadaptation_p.h \ - $$PWD/qsgsoftwarethreadedrenderloop_p.h + $$PWD/qsgsoftwareadaptation_p.h qtConfig(quick-sprite) { SOURCES += \ @@ -46,3 +44,10 @@ qtConfig(quick-sprite) { HEADERS += \ $$PWD/qsgsoftwarespritenode_p.h } + +qtConfig(thread) { + SOURCES += \ + $$PWD/qsgsoftwarethreadedrenderloop.cpp + HEADERS +=\ + $$PWD/qsgsoftwarethreadedrenderloop_p.h +} |