diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2016-01-22 11:31:22 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2016-03-17 11:27:53 +0000 |
commit | 7ff2cc9c1f037fa9159bc24d8a47778ebac2390a (patch) | |
tree | d96af4c0415662906c1c6fa5a64601b539cb106a /src/render/framegraph | |
parent | c01bc22c287e58186a285b3f8507711fd982fd05 (diff) |
Renderer/QRenderTargetSurfaceSelector: implement proper synchronization
This is needed to avoid rendering on a surface that has been destroyed.
Change-Id: Iadc2a32e2e0113704ca4df48df6bcdd1a0d8256c
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/framegraph')
-rw-r--r-- | src/render/framegraph/qrendersurfaceselector.cpp | 49 | ||||
-rw-r--r-- | src/render/framegraph/qrendersurfaceselector_p.h | 2 | ||||
-rw-r--r-- | src/render/framegraph/rendersurfaceselector.cpp | 17 | ||||
-rw-r--r-- | src/render/framegraph/rendersurfaceselector_p.h | 6 |
4 files changed, 74 insertions, 0 deletions
diff --git a/src/render/framegraph/qrendersurfaceselector.cpp b/src/render/framegraph/qrendersurfaceselector.cpp index a0d7e3a47..8bd31ac12 100644 --- a/src/render/framegraph/qrendersurfaceselector.cpp +++ b/src/render/framegraph/qrendersurfaceselector.cpp @@ -86,6 +86,7 @@ namespace Qt3DRender { QRenderSurfaceSelectorPrivate::QRenderSurfaceSelectorPrivate() : Qt3DRender::QFrameGraphNodePrivate() , m_surface(Q_NULLPTR) + , m_surfaceEventFilter(new Qt3DRender::Render::PlatformSurfaceFilter()) { } @@ -143,6 +144,23 @@ void QRenderSurfaceSelector::setSurface(QSurface *surface) return; d->m_surface = surface; + // The platform surface filter only deals with QObject + // We assume therefore that our surface is actually a QObject underneath + if (d->m_surface) { + switch (d->m_surface->surfaceClass()) { + case QSurface::Window: + d->m_surfaceEventFilter->setSurface(static_cast<QWindow *>(d->m_surface)); + break; + case QSurface::Offscreen: + d->m_surfaceEventFilter->setSurface(static_cast<QOffscreenSurface *>(d->m_surface)); + break; + default: + break; + } + } else { + QWindow *nullWindow = Q_NULLPTR; + d->m_surfaceEventFilter->setSurface(nullWindow); + } emit surfaceChanged(surface); } @@ -177,6 +195,37 @@ void QRenderSurfaceSelector::setWindow(QWindow *window) return; d->m_surface = window; + d->m_surfaceEventFilter->setSurface(window); + + if (window) { + QObject::connect(window, &QWindow::widthChanged, [=] (int width) { + if (d->m_changeArbiter != Q_NULLPTR) { + Qt3DCore::QScenePropertyChangePtr change( + new Qt3DCore::QScenePropertyChange( + Qt3DCore::NodeUpdated, + Qt3DCore::QSceneChange::Node, + id())); + + change->setPropertyName("width"); + change->setValue(QVariant::fromValue(width)); + d->notifyObservers(change); + } + }); + QObject::connect(window, &QWindow::heightChanged, [=] (int height) { + if (d->m_changeArbiter != Q_NULLPTR) { + Qt3DCore::QScenePropertyChangePtr change( + new Qt3DCore::QScenePropertyChange( + Qt3DCore::NodeUpdated, + Qt3DCore::QSceneChange::Node, + id())); + + change->setPropertyName("height"); + change->setValue(QVariant::fromValue(height)); + d->notifyObservers(change); + } + }); + } + emit windowChanged(window); emit surfaceChanged(d->m_surface); } diff --git a/src/render/framegraph/qrendersurfaceselector_p.h b/src/render/framegraph/qrendersurfaceselector_p.h index 136ad0991..33e9eab96 100644 --- a/src/render/framegraph/qrendersurfaceselector_p.h +++ b/src/render/framegraph/qrendersurfaceselector_p.h @@ -52,6 +52,7 @@ // #include <Qt3DRender/private/qframegraphnode_p.h> +#include <Qt3DRender/private/platformsurfacefilter_p.h> #include <QtGui/qsurface.h> #include <QtGui/qwindow.h> @@ -69,6 +70,7 @@ public: QSurface *m_surface; QSize m_externalRenderTargetSize; + QScopedPointer<Qt3DRender::Render::PlatformSurfaceFilter> m_surfaceEventFilter; }; } // namespace Qt3DRender diff --git a/src/render/framegraph/rendersurfaceselector.cpp b/src/render/framegraph/rendersurfaceselector.cpp index 738e1f231..838b03c57 100644 --- a/src/render/framegraph/rendersurfaceselector.cpp +++ b/src/render/framegraph/rendersurfaceselector.cpp @@ -43,6 +43,7 @@ #include <Qt3DCore/qscenepropertychange.h> #include <QtGui/qwindow.h> +#include <QtGui/qscreen.h> #include <QtGui/qoffscreensurface.h> QT_BEGIN_NAMESPACE @@ -55,6 +56,9 @@ namespace Render { RenderSurfaceSelector::RenderSurfaceSelector() : FrameGraphNode(FrameGraphNode::Surface) , m_surface(Q_NULLPTR) + , m_width(0) + , m_height(0) + , m_devicePixelRatio(0.0f) { } @@ -64,6 +68,15 @@ void RenderSurfaceSelector::updateFromPeer(Qt3DCore::QNode *peer) m_surface = selector->surface(); setEnabled(selector->isEnabled()); setRenderTargetSize(selector->externalRenderTargetSize()); + if (m_surface) { + if (m_surface->surfaceClass() == QSurface::Window) { + QWindow *window = static_cast<QWindow *>(m_surface); + m_width = window->width(); + m_height = window->height(); + if (window->screen()) + m_devicePixelRatio = window->screen()->devicePixelRatio(); + } + } } void RenderSurfaceSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -77,6 +90,10 @@ void RenderSurfaceSelector::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) setEnabled(propertyChange->value().toBool()); else if (propertyChange->propertyName() == QByteArrayLiteral("externalRenderTargetSize")) setRenderTargetSize(propertyChange->value().toSize()); + else if (propertyChange->propertyName() == QByteArrayLiteral("width")) + m_width = propertyChange->value().toInt(); + else if (propertyChange->propertyName() == QByteArrayLiteral("height")) + m_height = propertyChange->value().toInt(); markDirty(AbstractRenderer::AllDirty); } } diff --git a/src/render/framegraph/rendersurfaceselector_p.h b/src/render/framegraph/rendersurfaceselector_p.h index 114a52a31..8c84695a8 100644 --- a/src/render/framegraph/rendersurfaceselector_p.h +++ b/src/render/framegraph/rendersurfaceselector_p.h @@ -72,10 +72,16 @@ public: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; QSurface *surface() const { return m_surface; } + inline int width() const Q_DECL_NOEXCEPT { return m_width; } + inline int height() const Q_DECL_NOEXCEPT { return m_height; } + inline float devicePixelRatio() const Q_DECL_NOEXCEPT { return m_devicePixelRatio; } private: QSurface *m_surface; QSize m_renderTargetSize; + int m_width; + int m_height; + float m_devicePixelRatio; }; } // namespace Render |