diff options
author | Andy Nichols <andy.nichols@qt.io> | 2016-04-18 16:39:40 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-04-20 13:22:36 +0000 |
commit | 8139a219ddae7f2f14d74f923b78b39af756a402 (patch) | |
tree | cec3d56e3549c69c60473086eff879894ff887f6 /src/quick/scenegraph/adaptations | |
parent | 27d23848a36f9f5688eff2bed7a9dd1778fdd8ac (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')
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; |