diff options
Diffstat (limited to 'src/quick/scenegraph/adaptations/software')
7 files changed, 38 insertions, 38 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp index 02cf8209d1..30088846a6 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp @@ -193,6 +193,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(); diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h index 04a17ea377..c68a933384 100644 --- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h @@ -86,6 +86,8 @@ protected: void setBackgroundSize(const QSize &size); QColor backgroundColor(); QSize backgroundSize(); + // only known after calling optimizeRenderList() + bool isOpaque() const { return m_isOpaque; } private: void nodeAdded(QSGNode *node); @@ -102,6 +104,7 @@ private: QRegion m_dirtyRegion; QRegion m_obscuredRegion; + bool m_isOpaque; QSGSoftwareRenderableNodeUpdater *m_nodeUpdater; }; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode_p.h index f21667fdf7..5c95eb064a 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; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp index bd5d8f72c0..9d30c43f87 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -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. diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp index ad6cf39425..186fd92fb7 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp @@ -82,13 +82,6 @@ void QSGSoftwarePixmapRenderer::render(QPaintDevice *target) setBackgroundSize(QSize(target->width(), target->height())); 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_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 cecc6c21ca..bd2946c675 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); |