From b0ced704bcaeb6dc71622c9ce87b78f3b5bd827c Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Thu, 2 Feb 2017 14:22:08 +0100 Subject: Canvas Item: Prevent polish loop when calling requestAnimationFrame Currently if you call requestAnimationFrame within the callback given by requestAnimationFrame there is a polish loop. This is however the common way when using Canvas2D in the browser to get screen refresh rate animations. This patch makes sure that polish won't be called when processing polish items by calling polish indirectly. Task-number: QTBUG-55778 Change-Id: Ib96e39f7ca3cecc33609976e9049cc309768f9f7 Reviewed-by: Laszlo Agocs --- src/quick/items/context2d/qquickcanvasitem.cpp | 20 +++++++++++++++++++- src/quick/items/context2d/qquickcanvasitem_p.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index b772ed97d2..1167f408f5 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -640,6 +640,17 @@ void QQuickCanvasItem::releaseResources() } } +bool QQuickCanvasItem::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::PolishRequest: + polish(); + return true; + default: + return QQuickItem::event(event); + } +} + void QQuickCanvasItem::invalidateSceneGraph() { Q_D(QQuickCanvasItem); @@ -651,6 +662,12 @@ void QQuickCanvasItem::invalidateSceneGraph() d->textureProvider = 0; } +void QQuickCanvasItem::schedulePolish() +{ + auto polishRequestEvent = new QEvent(QEvent::PolishRequest); + QCoreApplication::postEvent(this, polishRequestEvent); +} + void QQuickCanvasItem::componentComplete() { QQuickItem::componentComplete(); @@ -892,8 +909,9 @@ void QQuickCanvasItem::requestAnimationFrame(QQmlV4Function *args) d->animationCallbacks.insert(++id, QV4::PersistentValue(scope.engine, f->asReturnedValue())); + // QTBUG-55778: Calling polish directly here can lead to a polish loop if (isVisible()) - polish(); + schedulePolish(); args->setReturnValue(QV4::Encode(id)); } diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h index 8af84d0e7c..217ae9bb69 100644 --- a/src/quick/items/context2d/qquickcanvasitem_p.h +++ b/src/quick/items/context2d/qquickcanvasitem_p.h @@ -182,6 +182,7 @@ private Q_SLOTS: void sceneGraphInitialized(); void checkAnimationCallbacks(); void invalidateSceneGraph(); + void schedulePolish(); protected: void componentComplete() Q_DECL_OVERRIDE; @@ -190,6 +191,7 @@ protected: QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; void releaseResources() Q_DECL_OVERRIDE; + bool event(QEvent *event) Q_DECL_OVERRIDE; private: Q_DECLARE_PRIVATE(QQuickCanvasItem) Q_INVOKABLE void delayedCreate(); -- cgit v1.2.3 From ecd4c83ef764f086f2e101b4201484f3d828c0e3 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 3 Feb 2017 10:10:52 +0100 Subject: Allow to pass all the relevant info to QQuickPixmap::isCached If we don't allow to pass the QQuickImageProviderOptions to the isCached we are missing one of the three components that identify if the pixmap is actually cached. Old code is ok for the QQuickAnimatedImagePrivate use case since it always creates QQuickPixmap with the default QQuickImageProviderOptions options, but if someone else wants to use QQuickPixmap::isCached they will need to be able to pass the options part of the cache key. Change-Id: I3153ad9ed30e7332b5cb4896dcebd408f2bd9afe Reviewed-by: Robin Burchell --- src/quick/items/qquickanimatedimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index a1833081c8..22ea4774be 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -67,7 +67,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine .arg(current)); } if (!requestedUrl.isEmpty()) { - if (QQuickPixmap::isCached(requestedUrl, QSize())) + if (QQuickPixmap::isCached(requestedUrl, QSize(), QQuickImageProviderOptions())) pixmap = new QQuickPixmap(engine, requestedUrl); else pixmap = new QQuickPixmap(requestedUrl, _movie->currentImage()); -- cgit v1.2.3 From eea43b5cc5aa6fab0d7523f92a83a5f75849782d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 7 Feb 2017 13:37:44 +0100 Subject: Fix a crash in canvas2d when calling some methods This fixes a regression introduced in change 4d23faf34192cef372f846dcf02fd8cc398b14c0, where some return values from functions weren't properly encoded as QV4::Value. Task-number: QTBUG-58683 Change-Id: I9dc5f1eb8f5779c58f8b062b9ae3d02284ab2678 Reviewed-by: Simon Hausmann Reviewed-by: J-P Nurmi --- src/quick/items/context2d/qquickcontext2d.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index b0c1d50907..e25cc5ccbe 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -1879,7 +1879,7 @@ void QQuickJSContext2D::method_get_lineWidth(const QV4::BuiltinFunction *, QV4:: QV4::Scoped r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.lineWidth); + RETURN_RESULT(QV4::Encode(r->d()->context->state.lineWidth)); } void QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -1906,7 +1906,7 @@ void QQuickJSContext2D::method_get_miterLimit(const QV4::BuiltinFunction *, QV4: QV4::Scoped r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.miterLimit); + RETURN_RESULT(QV4::Encode(r->d()->context->state.miterLimit)); } void QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -1933,7 +1933,7 @@ void QQuickJSContext2D::method_get_shadowBlur(const QV4::BuiltinFunction *, QV4: QV4::Scoped r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.shadowBlur); + RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowBlur)); } void QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -1990,7 +1990,7 @@ void QQuickJSContext2D::method_get_shadowOffsetX(const QV4::BuiltinFunction *, Q QV4::Scoped r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.shadowOffsetX); + RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetX)); } void QQuickJSContext2D::method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -2016,7 +2016,7 @@ void QQuickJSContext2D::method_get_shadowOffsetY(const QV4::BuiltinFunction *, Q QV4::Scoped r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.shadowOffsetY); + RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetY)); } void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -3043,7 +3043,7 @@ void QQuickJSContext2DPixelData::proto_get_length(const QV4::BuiltinFunction *, if (!r || r->d()->image->isNull()) RETURN_UNDEFINED(); - RETURN_RESULT(r->d()->image->width() * r->d()->image->height() * 4); + RETURN_RESULT(QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4)); } QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, uint index, bool *hasProperty) -- cgit v1.2.3 From f145f33d529c2b59ace7a3cdfd5463e68787f40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 8 Feb 2017 16:25:12 +0100 Subject: Rename Window.targetScreen to screen, and pick up changes to the screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The screen property can be used for both setting the initital screen, and for reading out the current screen, so 'targetScreen' was not an ideal name for this property. Change-Id: I1b617085b1e8e0e437355740be5d3cee9379c47f Reviewed-by: Laszlo Agocs Reviewed-by: Shawn Rutledge Reviewed-by: Tor Arne Vestbø --- src/quick/items/qquickscreen.cpp | 6 +++--- src/quick/items/qquickscreen_p.h | 2 +- src/quick/items/qquickwindow.cpp | 26 +++++++++++++------------- src/quick/items/qquickwindowmodule.cpp | 22 ++++++---------------- src/quick/items/qquickwindowmodule_p.h | 8 ++++---- 5 files changed, 27 insertions(+), 37 deletions(-) (limited to 'src/quick/items') diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index 9347b55c70..20c6973ee1 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -207,9 +207,9 @@ QT_BEGIN_NAMESPACE By default it is set to the value of the QScreen that the window uses. */ -QQuickScreenInfo::QQuickScreenInfo(QObject *parent) - : QObject(parent), - m_screen(nullptr) +QQuickScreenInfo::QQuickScreenInfo(QObject *parent, QScreen *wrappedScreen) + : QObject(parent) + , m_screen(wrappedScreen) { } diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index 06efb3ab45..99e1466631 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -84,7 +84,7 @@ class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 1) public: - QQuickScreenInfo(QObject *parent = nullptr); + QQuickScreenInfo(QObject *parent = nullptr, QScreen *wrappedScreen = nullptr); QString name() const; int width() const; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 0e7c50ffcf..0ebd644d69 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -4172,25 +4172,25 @@ void QQuickWindow::resetOpenGLState() */ /*! - \qmlproperty variant Window::targetScreen + \qmlproperty variant Window::screen - Specifies the screen the window should be placed on. Equivalent to - QWindow::setScreen(). + The screen with which the window is associated. - The value must be an element from the Qt.application.screens array. + If specified before showing a window, will result in the window being shown + on that screen, unless an explicit window position has been set. The value + must be an element from the Qt.application.screens array. - By default the value is null which leads to using the primary screen. - - \note To ensure that the window is associated with the desired screen right - upon the underlying native window's initial creation, make sure this - property is set as early as possible and that the setting of its value is - not deferred. This can be particularly important on embedded platforms - without a windowing system, where only one window per screen is allowed at a - time. + \note To ensure that the window is associated with the desired screen when + the underlying native window is created, make sure this property is set as + early as possible and that the setting of its value is not deferred. This + can be particularly important on embedded platforms without a windowing system, + where only one window per screen is allowed at a time. Setting the screen after + a window has been created does not move the window if the new screen is part of + the same virtual desktop as the old screen. \since 5.9 - \sa QWindow::setScreen(), QScreen, Qt.application + \sa QWindow::setScreen(), QWindow::screen(), QScreen, Qt.application */ /*! diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index 42313e4584..6211b7802f 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -59,7 +59,6 @@ public: : complete(false) , visible(false) , visibility(QQuickWindow::AutomaticVisibility) - , targetScreen(nullptr) { } @@ -67,7 +66,6 @@ public: bool visible; QQuickWindow::Visibility visibility; QV4::PersistentValue rootItemMarker; - QObject *targetScreen; }; QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent) @@ -75,6 +73,7 @@ QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent) { connect(this, &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::visibleChanged); connect(this, &QWindow::visibilityChanged, this, &QQuickWindowQmlImpl::visibilityChanged); + connect(this, &QWindow::screenChanged, this, &QQuickWindowQmlImpl::screenChanged); } void QQuickWindowQmlImpl::setVisible(bool visible) @@ -175,24 +174,15 @@ void QQuickWindowQmlImpl::setWindowVisibility() } } -QObject *QQuickWindowQmlImpl::targetScreen() const +QObject *QQuickWindowQmlImpl::screen() const { - Q_D(const QQuickWindowQmlImpl); - return d->targetScreen; + return new QQuickScreenInfo(const_cast(this), QWindow::screen()); } -void QQuickWindowQmlImpl::setTargetScreen(QObject *screen) +void QQuickWindowQmlImpl::setScreen(QObject *screen) { - Q_D(QQuickWindowQmlImpl); - if (d->targetScreen != screen) { - d->targetScreen = screen; - emit targetScreenChanged(); - QQuickScreenInfo *screenWrapper = qobject_cast(screen); - if (screenWrapper) - setScreen(screenWrapper->wrappedScreen()); - else - setScreen(nullptr); - } + QQuickScreenInfo *screenWrapper = qobject_cast(screen); + QWindow::setScreen(screenWrapper ? screenWrapper->wrappedScreen() : nullptr); } void QQuickWindowModule::defineModule() diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h index 7ca29880ea..16130bc8a0 100644 --- a/src/quick/items/qquickwindowmodule_p.h +++ b/src/quick/items/qquickwindowmodule_p.h @@ -67,7 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) - Q_PROPERTY(QObject *targetScreen READ targetScreen WRITE setTargetScreen NOTIFY targetScreenChanged REVISION 2) + Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 2) public: QQuickWindowQmlImpl(QWindow *parent = Q_NULLPTR); @@ -75,15 +75,15 @@ public: void setVisible(bool visible); void setVisibility(Visibility visibility); - QObject *targetScreen() const; - void setTargetScreen(QObject *screen); + QObject *screen() const; + void setScreen(QObject *screen); static QQuickWindowAttached *qmlAttachedProperties(QObject *object); Q_SIGNALS: void visibleChanged(bool arg); void visibilityChanged(QWindow::Visibility visibility); - Q_REVISION(2) void targetScreenChanged(); + Q_REVISION(2) void screenChanged(); protected: void classBegin() Q_DECL_OVERRIDE; -- cgit v1.2.3