aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/adaptations
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@qt.io>2016-04-18 16:39:40 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-04-20 13:22:36 +0000
commit8139a219ddae7f2f14d74f923b78b39af756a402 (patch)
treecec3d56e3549c69c60473086eff879894ff887f6 /src/quick/scenegraph/adaptations
parent27d23848a36f9f5688eff2bed7a9dd1778fdd8ac (diff)
2DRenderer: Have renderers tied to QPaintDevice
Previously the software renderer would create a backing store for a given window if one was needed. This has been moved to the render loop where the backingstore is flushed to the window. This refactoring should make the software renderers flexible enough to work with QQuickRenderControl. Change-Id: Idbbb1da870afbf28e45213a887be68dba11dc592 Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Diffstat (limited to 'src/quick/scenegraph/adaptations')
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp71
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h19
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp25
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h3
8 files changed, 53 insertions, 73 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 2ed1da46f4..a9dbd7e325 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -89,7 +89,6 @@ QT_BEGIN_NAMESPACE
QSGSoftwareRenderContext::QSGSoftwareRenderContext(QSGContext *ctx)
: QSGRenderContext(ctx)
- , currentWindow(0)
, m_initialized(false)
{
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h
index 8f9daceb7e..12568706d4 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h
@@ -76,7 +76,6 @@ public:
QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const override;
QSGRenderer *createRenderer() override;
- QWindow *currentWindow;
bool m_initialized;
};
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
index acc55bb2db..304106a84d 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
@@ -73,12 +73,12 @@ void QSGSoftwarePixmapRenderer::render()
}
-void QSGSoftwarePixmapRenderer::render(QPixmap *target)
+void QSGSoftwarePixmapRenderer::render(QPaintDevice *target)
{
QElapsedTimer renderTimer;
// Setup background item
- setBackgroundSize(target->size());
+ setBackgroundSize(QSize(target->width(), target->height()));
setBackgroundColor(clearColor());
QPainter painter(target);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h
index 3a2b92e857..3b4fb304e7 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h
@@ -64,7 +64,7 @@ public:
void renderScene(uint fboId = 0) final;
void render() final;
- void render(QPixmap *target);
+ void render(QPaintDevice *target);
void setProjectionRect(const QRect &projectionRect);
private:
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
index 939178e532..433f166315 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
@@ -44,9 +44,7 @@
#include "qsgsoftwarecontext_p.h"
#include "qsgsoftwarerenderablenode_p.h"
-#include <QtGui/QWindow>
-#include <QtQuick/QSGSimpleRectNode>
-
+#include <QtGui/QPaintDevice>
#include <QElapsedTimer>
Q_LOGGING_CATEGORY(lcRenderer, "qt.scenegraph.softwarecontext.renderer")
@@ -62,6 +60,16 @@ QSGSoftwareRenderer::~QSGSoftwareRenderer()
{
}
+void QSGSoftwareRenderer::setCurrentPaintDevice(QPaintDevice *device)
+{
+ m_paintDevice = device;
+}
+
+QRegion QSGSoftwareRenderer::flushRegion() const
+{
+ return m_flushRegion;
+}
+
void QSGSoftwareRenderer::renderScene(uint)
{
class B : public QSGBindable
@@ -74,32 +82,15 @@ void QSGSoftwareRenderer::renderScene(uint)
void QSGSoftwareRenderer::render()
{
- QElapsedTimer renderTimer;
-
- QWindow *currentWindow = static_cast<QSGSoftwareRenderContext*>(m_context)->currentWindow;
- if (!m_backingStore)
- m_backingStore.reset(new QBackingStore(currentWindow));
+ if (!m_paintDevice)
+ return;
- if (m_backingStore->size() != currentWindow->size()) {
- m_backingStore->resize(currentWindow->size());
- }
+ QElapsedTimer renderTimer;
setBackgroundColor(clearColor());
- setBackgroundSize(currentWindow->size());
-
- const QRect rect(0, 0, currentWindow->width(), currentWindow->height());
- m_backingStore->beginPaint(rect);
-
- QPaintDevice *device = m_backingStore->paintDevice();
-#ifndef QTQUICK2D_DEBUG_FLUSH
- QPainter painter(device);
-#else
- if (m_outputBuffer.size() != m_backingStore->size()) {
- m_outputBuffer = QImage(m_backingStore->size(), QImage::Format_ARGB32_Premultiplied);
- m_outputBuffer.fill(Qt::transparent);
- }
- QPainter painter(&m_outputBuffer);
-#endif
+ setBackgroundSize(QSize(m_paintDevice->width(), m_paintDevice->height()));
+
+ QPainter painter(m_paintDevice);
painter.setRenderHint(QPainter::Antialiasing);
// Build Renderlist
@@ -125,34 +116,10 @@ void QSGSoftwareRenderer::render()
qint64 optimizeRenderListTime = renderTimer.restart();
// Render the contents Renderlist
- QRegion dirtyRegion = renderNodes(&painter);
+ m_flushRegion = renderNodes(&painter);
qint64 renderTime = renderTimer.elapsed();
- qCDebug(lcRenderer) << "render" << dirtyRegion << buildRenderListTime << optimizeRenderListTime << renderTime;
-
-#ifdef QTQUICK2D_DEBUG_FLUSH
- // Keep up with the last 5 flushes
- if (m_previousFlushes.count() == 5)
- m_previousFlushes.pop_front();
- m_previousFlushes.append(dirtyRegion);
-
- QPainter backingStorePainter(device);
- backingStorePainter.drawImage(QRect(0, 0, m_backingStore->size().width(), m_backingStore->size().height()), m_outputBuffer, m_outputBuffer.rect());
- QPen pen(Qt::NoPen);
- QBrush brush(QColor(255, 0, 0, 50));
- backingStorePainter.setPen(pen);
- backingStorePainter.setBrush(brush);
- for (auto region : qAsConst(m_previousFlushes)) {
- backingStorePainter.drawRects(region.rects());
- }
- m_backingStore->endPaint();
-
- m_backingStore->flush(rect);
-#else
- m_backingStore->endPaint();
- // Flush the updated regions to the window
- m_backingStore->flush(dirtyRegion);
-#endif
+ qCDebug(lcRenderer) << "render" << m_flushRegion << buildRenderListTime << optimizeRenderListTime << renderTime;
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
index 2b367ec934..bc059438f4 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
@@ -53,15 +53,9 @@
#include "qsgabstractsoftwarerenderer_p.h"
-#include <QtGui/QBackingStore>
-
-#ifdef QTQUICK2D_DEBUG_FLUSH
-#include <QtGui/QImage>
-#endif
-
QT_BEGIN_NAMESPACE
-class QSGSimpleRectNode;
+class QPaintDevice;
class QSGSoftwareRenderer : public QSGAbstractSoftwareRenderer
{
@@ -69,19 +63,16 @@ public:
QSGSoftwareRenderer(QSGRenderContext *context);
virtual ~QSGSoftwareRenderer();
- QBackingStore *backingStore() const { return m_backingStore.data(); }
+ void setCurrentPaintDevice(QPaintDevice *device);
+ QRegion flushRegion() const;
protected:
void renderScene(uint fboId = 0) final;
void render() final;
private:
- QScopedPointer<QBackingStore> m_backingStore;
-
-#ifdef QTQUICK2D_DEBUG_FLUSH
- QVector<QRegion> m_previousFlushes;
- QImage m_outputBuffer;
-#endif
+ QPaintDevice* m_paintDevice;
+ QRegion m_flushRegion;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index d004aa70d8..12e1889627 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -49,6 +49,8 @@
#include <private/qsgsoftwarerenderer_p.h>
#include <qpa/qplatformbackingstore.h>
+#include <QtGui/QBackingStore>
+
QT_BEGIN_NAMESPACE
QSGSoftwareRenderLoop::QSGSoftwareRenderLoop()
@@ -70,6 +72,10 @@ void QSGSoftwareRenderLoop::show(QQuickWindow *window)
data.grabOnly = false;
m_windows[window] = data;
+ if (m_backingStores[window] == nullptr) {
+ m_backingStores[window] = new QBackingStore(window);
+ }
+
maybeUpdate(window);
}
@@ -82,6 +88,8 @@ void QSGSoftwareRenderLoop::hide(QQuickWindow *window)
void QSGSoftwareRenderLoop::windowDestroyed(QQuickWindow *window)
{
m_windows.remove(window);
+ delete m_backingStores[window];
+ m_backingStores.remove(window);
hide(window);
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
@@ -101,9 +109,13 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window)
WindowData &data = const_cast<WindowData &>(m_windows[window]);
+ //Resize the backing store if necessary
+ if (m_backingStores[window]->size() != window->size()) {
+ m_backingStores[window]->resize(window->size());
+ }
+
// ### create QPainter and set up pointer to current window/painter
QSGSoftwareRenderContext *ctx = static_cast<QSGSoftwareRenderContext*>(cd->context);
- ctx->currentWindow = window;
ctx->initializeIfNeeded();
bool alsoSwap = data.updatePending;
@@ -137,18 +149,27 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window)
syncTime = renderTimer.nsecsElapsed();
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
+ //Tell the renderer about the windows backing store
+ auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
+ if (softwareRenderer)
+ softwareRenderer->setCurrentPaintDevice(m_backingStores[window]->paintDevice());
+
+ m_backingStores[window]->beginPaint(QRect(0, 0, window->width(), window->height()));
cd->renderSceneGraph(window->size());
+ m_backingStores[window]->endPaint();
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
if (data.grabOnly) {
- grabContent = static_cast<QSGSoftwareRenderer*>(cd->renderer)->backingStore()->handle()->toImage();
+ grabContent = m_backingStores[window]->handle()->toImage();
data.grabOnly = false;
}
if (alsoSwap && window->isVisible()) {
+ //Flush backingstore to window
+ m_backingStores[window]->flush(softwareRenderer->flushRegion());
cd->fireFrameSwapped();
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h
index 06cf7dce79..02dcf4eefa 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop_p.h
@@ -55,6 +55,8 @@
QT_BEGIN_NAMESPACE
+class QBackingStore;
+
class QSGSoftwareRenderLoop : public QSGRenderLoop
{
Q_OBJECT
@@ -90,6 +92,7 @@ public:
};
QHash<QQuickWindow *, WindowData> m_windows;
+ QHash<QQuickWindow *, QBackingStore *> m_backingStores;
QSGContext *sg;
QSGRenderContext *rc;