aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-07-14 12:43:46 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-07-15 09:30:31 +0000
commitc2414e16aba2ad499a49d3661a2961795c9a9dc9 (patch)
tree08c8d0a06bc4c9bb218f45739daf3b48540cd2d0 /src
parent12de7bbc1ee2959f4e31a345b4573242d34474cf (diff)
Fix rendercontrol grabs with the software backend
Calling grabWindow recurses (since that is implemented via QQuickRenderControl::grab...) so it's not an option. Instead, call directly in the software renderer implementation. Fix also the size of the offscreen QQuickWindow when using QQuickWidget in combination with the software backend. Change-Id: I857a2cc0aebbbaa5d52d809aeaec37c15b0787b9 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickrendercontrol.cpp29
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp7
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp5
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h1
-rw-r--r--src/quickwidgets/qquickwidget.cpp11
6 files changed, 44 insertions, 11 deletions
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index dbe1add345..8c18c58224 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -56,9 +56,9 @@
#include <QtQuick/QQuickWindow>
#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qsgsoftwarerenderer_p.h>
#include <QtCore/private/qobject_p.h>
-
QT_BEGIN_NAMESPACE
#ifndef QT_NO_OPENGL
extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
@@ -369,12 +369,31 @@ QImage QQuickRenderControl::grab()
if (!d->window)
return QImage();
- render();
+ QImage grabContent;
+
+ if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) {
#ifndef QT_NO_OPENGL
- QImage grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false);
-#else
- QImage grabContent = d->window->grabWindow();
+ render();
+ grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false);
#endif
+ } else if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ QSGSoftwareRenderer *softwareRenderer = static_cast<QSGSoftwareRenderer *>(cd->renderer);
+ if (softwareRenderer) {
+ const qreal dpr = d->window->effectiveDevicePixelRatio();
+ const QSize imageSize = d->window->size() * dpr;
+ grabContent = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
+ grabContent.setDevicePixelRatio(dpr);
+ QPaintDevice *prevDev = softwareRenderer->currentPaintDevice();
+ softwareRenderer->setCurrentPaintDevice(&grabContent);
+ softwareRenderer->markDirty();
+ render();
+ softwareRenderer->setCurrentPaintDevice(prevDev);
+ }
+ } else {
+ qWarning("QQuickRenderControl: grabs are not supported with the current Qt Quick backend");
+ }
+
return grabContent;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
index 26efba5b13..a6cb99ae05 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
@@ -236,7 +236,7 @@ void QSGAbstractSoftwareRenderer::setBackgroundSize(const QSize &size)
m_background->setRect(0.0f, 0.0f, size.width(), size.height());
renderableNode(m_background)->markGeometryDirty();
// Invalidate the whole scene when the background is resized
- m_dirtyRegion = QRegion(m_background->rect().toRect());
+ markDirty();
}
QColor QSGAbstractSoftwareRenderer::backgroundColor()
@@ -322,4 +322,9 @@ void QSGAbstractSoftwareRenderer::nodeOpacityUpdated(QSGNode *node)
m_nodeUpdater->updateNodes(node);
}
+void QSGAbstractSoftwareRenderer::markDirty()
+{
+ m_dirtyRegion = QRegion(m_background->rect().toRect());
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
index 73410b09f5..905577b92a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
@@ -75,6 +75,8 @@ public:
void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
+ void markDirty();
+
protected:
QRegion renderNodes(QPainter *painter);
void buildRenderList();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
index 7bf06f8081..257009472e 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
@@ -69,6 +69,11 @@ void QSGSoftwareRenderer::setCurrentPaintDevice(QPaintDevice *device)
m_backingStore = nullptr;
}
+QPaintDevice *QSGSoftwareRenderer::currentPaintDevice() const
+{
+ return m_paintDevice;
+}
+
void QSGSoftwareRenderer::setBackingStore(QBackingStore *backingStore)
{
m_backingStore = backingStore;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
index a201e4887e..bb28da4ca5 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
@@ -65,6 +65,7 @@ public:
virtual ~QSGSoftwareRenderer();
void setCurrentPaintDevice(QPaintDevice *device);
+ QPaintDevice *currentPaintDevice() const;
void setBackingStore(QBackingStore *backingStore);
QRegion flushRegion() const;
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 2a014546e1..b25e2d348d 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -894,6 +894,12 @@ void QQuickWidget::createFramebufferObject()
if (size().isEmpty())
return;
+ // Even though this is just an offscreen window we should set the position on it, as it might be
+ // useful for an item to know the actual position of the scene.
+ // Note: The position will be update when we get a move event (see: updatePosition()).
+ const QPoint &globalPos = mapToGlobal(QPoint(0, 0));
+ d->offscreenWindow->setGeometry(globalPos.x(), globalPos.y(), width(), height());
+
if (d->useSoftwareRenderer) {
const QSize imageSize = size() * devicePixelRatio();
d->softwareImage = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
@@ -961,11 +967,6 @@ void QQuickWidget::createFramebufferObject()
}
#endif
- // Even though this is just an offscreen window we should set the position on it, as it might be
- // useful for an item to know the actual position of the scene.
- // Note: The position will be update when we get a move event (see: updatePosition()).
- const QPoint &globalPos = mapToGlobal(QPoint(0, 0));
- d->offscreenWindow->setGeometry(globalPos.x(), globalPos.y(), width(), height());
d->offscreenWindow->setRenderTarget(d->fbo);
if (samples > 0)