diff options
Diffstat (limited to 'src')
59 files changed, 562 insertions, 803 deletions
diff --git a/src/compatibility/compatibility.pro b/src/compatibility/compatibility.pro index 7dd6e43f75..0996839fa8 100644 --- a/src/compatibility/compatibility.pro +++ b/src/compatibility/compatibility.pro @@ -5,7 +5,7 @@ MODULE_PRI = ../../modules/qt_declarative.pri QT = qml -pritarget.path = $$[QT_INSTALL_DATA]/mkspecs/modules +pritarget.path = $$[QT_HOST_DATA]/mkspecs/modules pritarget.files = $$MODULE_PRI INSTALLS += pritarget diff --git a/src/plugins/accessible/quick/main.cpp b/src/plugins/accessible/quick/main.cpp index 6ff3d5db9e..2c75e594c2 100644 --- a/src/plugins/accessible/quick/main.cpp +++ b/src/plugins/accessible/quick/main.cpp @@ -99,6 +99,7 @@ QAccessibleInterface *AccessibleQuickFactory::create(const QString &classname, Q case QAccessible::Slider: case QAccessible::SpinBox: case QAccessible::Dial: + case QAccessible::ScrollBar: return new QAccessibleQuickItemValueInterface(item); default: return new QAccessibleQuickItem(item); diff --git a/src/plugins/accessible/quick/qaccessiblequickitem.cpp b/src/plugins/accessible/quick/qaccessiblequickitem.cpp index 78e7ca86ef..6c13377b3f 100644 --- a/src/plugins/accessible/quick/qaccessiblequickitem.cpp +++ b/src/plugins/accessible/quick/qaccessiblequickitem.cpp @@ -278,7 +278,7 @@ QRect itemScreenRect(QQuickItem *item) // parent size. WE MIGHT HAVE TO REVISIT THESE FALLBACKS. if (itemSize.isEmpty()) { itemSize = QSize((int)item->implicitWidth(), (int)item->implicitHeight()); - if (itemSize.isEmpty()) + if (itemSize.isEmpty() && item->parentItem()) // ### Seems that the above fallback is not enough, fallback to use the parent size... itemSize = QSize((int)item->parentItem()->width(), (int)item->parentItem()->height()); } diff --git a/src/plugins/accessible/shared/qqmlaccessible.cpp b/src/plugins/accessible/shared/qqmlaccessible.cpp index 1818ebebfe..70c6b90efe 100644 --- a/src/plugins/accessible/shared/qqmlaccessible.cpp +++ b/src/plugins/accessible/shared/qqmlaccessible.cpp @@ -59,6 +59,13 @@ QQmlAccessible::QQmlAccessible(QObject *object) { } +void *QQmlAccessible::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::ActionInterface) + return static_cast<QAccessibleActionInterface*>(this); + return QAccessibleObject::interface_cast(t); +} + QQmlAccessible::~QQmlAccessible() { } @@ -131,7 +138,15 @@ QStringList QQmlAccessible::actionNames() const break; case QAccessible::RadioButton: case QAccessible::CheckBox: - actions << QAccessibleActionInterface::checkAction(); + actions << QAccessibleActionInterface::checkAction() + << QAccessibleActionInterface::uncheckAction() + << QAccessibleActionInterface::pressAction(); + break; + case QAccessible::Slider: + case QAccessible::SpinBox: + case QAccessible::ScrollBar: + actions << QAccessibleActionInterface::increaseAction() + << QAccessibleActionInterface::decreaseAction(); break; default: break; @@ -141,12 +156,72 @@ QStringList QQmlAccessible::actionNames() const void QQmlAccessible::doAction(const QString &actionName) { - if (role() == QAccessible::PushButton && actionName == QAccessibleActionInterface::pressAction()) { - QMetaObject::invokeMethod(object(), "accessibleAction"); + // Look for and call the accessible[actionName]Action() function on the item. + // This allows for overriding the default action handling. + const QByteArray functionName = "accessible" + actionName.toLatin1() + "Action()"; + if (object()->metaObject()->indexOfMethod(functionName) != -1) { + QMetaObject::invokeMethod(object(), functionName, Q_ARG(QString, actionName)); + return; } - if ((role() == QAccessible::CheckBox || role() == QAccessible::RadioButton) && actionName == QAccessibleActionInterface::checkAction()) { - bool checked = object()->property("checked").toBool(); - object()->setProperty("checked", QVariant(!checked)); + + // Role-specific default action handling follows. Items are excepted to provide + // properties according to role conventions. These will then be read and/or updated + // by the accessibility system. + // Checkable roles : checked + // Value-based roles : (via the value interface: value, minimumValue, maximumValue), stepSize + switch (role()) { + case QAccessible::RadioButton: + case QAccessible::CheckBox: { + QVariant checked = object()->property("checked"); + if (checked.isValid()) { + if (actionName == QAccessibleActionInterface::pressAction()) { + object()->setProperty("checked", QVariant(!checked.toBool())); + } else if (actionName == QAccessibleActionInterface::checkAction()) { + object()->setProperty("checked", QVariant(true)); + } else if (actionName == QAccessibleActionInterface::uncheckAction()) { + object()->setProperty("checked", QVariant(false)); + } + } + break; + } + case QAccessible::Slider: + case QAccessible::SpinBox: + case QAccessible::Dial: + case QAccessible::ScrollBar: { + if (actionName != QAccessibleActionInterface::increaseAction() && + actionName != QAccessibleActionInterface::decreaseAction()) + break; + + // Update the value using QAccessibleValueInterface, respecting + // the minimum and maximum value (if set). Also check for and + // use the "stepSize" property on the item + if (QAccessibleValueInterface *valueIface = valueInterface()) { + QVariant valueV = valueIface->currentValue(); + qreal newValue = valueV.toInt(); + + QVariant stepSizeV = object()->property("stepSize"); + qreal stepSize = stepSizeV.isValid() ? stepSizeV.toReal() : qreal(1.0); + if (actionName == QAccessibleActionInterface::increaseAction()) { + newValue += stepSize; + } else { + newValue -= stepSize; + } + + QVariant minimumValueV = valueIface->minimumValue(); + if (minimumValueV.isValid()) { + newValue = qMax(newValue, minimumValueV.toReal()); + } + QVariant maximumValueV = valueIface->maximumValue(); + if (maximumValueV.isValid()) { + newValue = qMin(newValue, maximumValueV.toReal()); + } + + valueIface->setCurrentValue(QVariant(newValue)); + } + break; + } + default: + break; } } diff --git a/src/plugins/accessible/shared/qqmlaccessible.h b/src/plugins/accessible/shared/qqmlaccessible.h index 570a3c8c40..ec26aa2306 100644 --- a/src/plugins/accessible/shared/qqmlaccessible.h +++ b/src/plugins/accessible/shared/qqmlaccessible.h @@ -74,6 +74,7 @@ class QQmlAccessible: public QAccessibleObject, public QAccessibleActionInterfac { public: ~QQmlAccessible(); + void *interface_cast(QAccessible::InterfaceType t); virtual QRect viewRect() const = 0; QAccessibleInterface *childAt(int, int) const; diff --git a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp index 9bd68e7401..fb18231b94 100644 --- a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp +++ b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp @@ -127,12 +127,12 @@ void QmlOstPlugin::setPort(int port, bool block) if (!ok) { if (d->ost->errorString().length()) qDebug("Error from QOstDevice: %s", qPrintable(d->ost->errorString())); - qWarning("QQmlDebugServer: Unable to listen on OST"); // This message is part of the signalling - do not change the format! + qWarning("QML Debugger: Unable to listen to OST."); // This message is part of the signalling - do not change the format! return; } d->protocol = new QPacketProtocol(d->ost, this); QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); - qWarning("QQmlDebugServer: Waiting for connection via OST"); // This message is part of the signalling - do not change the format! + qWarning("QML Debugger: Waiting for connection via OST."); // This message is part of the signalling - do not change the format! } void QmlOstPlugin::readyRead() diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro b/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro index f0514134d1..2d4de57540 100644 --- a/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro +++ b/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro @@ -1,7 +1,7 @@ load(qt_module) TARGET = qmldbg_qtquick2 -QT += qml-private quick-private core-private gui-private opengl-private v8-private +QT += qml-private quick-private core-private gui-private v8-private load(qt_plugin) diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp index 1c5ec37512..2b12f297e4 100644 --- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp +++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp @@ -147,9 +147,9 @@ void QTcpServerConnection::listen() d->tcpServer = new QTcpServer(this); QObject::connect(d->tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection())); if (d->tcpServer->listen(QHostAddress::Any, d->port)) - qWarning("QQmlDebugServer: Waiting for connection on port %d...", d->port); + qWarning("QML Debugger: Waiting for connection on port %d...", d->port); else - qWarning("QQmlDebugServer: Unable to listen on port %d", d->port); + qWarning("QML Debugger: Unable to listen to port %d.", d->port); } @@ -170,7 +170,7 @@ void QTcpServerConnection::newConnection() Q_D(QTcpServerConnection); if (d->socket && d->socket->peerPort()) { - qWarning("QQmlDebugServer: Another client is already connected"); + qWarning("QML Debugger: Another client is already connected."); QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection(); delete faultyConnection; return; @@ -190,7 +190,7 @@ void QTcpServerConnection::newConnection() void QTcpServerConnection::invalidPacket() { - qWarning("QQmlDebugServer: Received a corrupted packet! Giving up ..."); + qWarning("QML Debugger: Received a corrupted packet! Giving up ..."); } QT_END_NAMESPACE diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri index 10ca9706c4..f85663c01f 100644 --- a/src/qml/debugger/debugger.pri +++ b/src/qml/debugger/debugger.pri @@ -4,7 +4,6 @@ SOURCES += \ $$PWD/qqmldebugclient.cpp \ $$PWD/qqmlenginedebug.cpp \ $$PWD/qqmlprofilerservice.cpp \ - $$PWD/qqmldebughelper.cpp \ $$PWD/qqmldebugserver.cpp \ $$PWD/qqmlinspectorservice.cpp \ $$PWD/qv8debugservice.cpp \ @@ -19,7 +18,6 @@ HEADERS += \ $$PWD/qqmldebugclient_p.h \ $$PWD/qqmlenginedebug_p.h \ $$PWD/qqmlprofilerservice_p.h \ - $$PWD/qqmldebughelper_p.h \ $$PWD/qqmldebugserver_p.h \ $$PWD/qqmldebugserverconnection_p.h \ $$PWD/qqmldebugstatesdelegate_p.h \ diff --git a/src/qml/debugger/qqmldebugclient.cpp b/src/qml/debugger/qqmldebugclient.cpp index 12276b48fa..fcb0861c21 100644 --- a/src/qml/debugger/qqmldebugclient.cpp +++ b/src/qml/debugger/qqmldebugclient.cpp @@ -52,8 +52,8 @@ QT_BEGIN_NAMESPACE const int protocolVersion = 1; -const QString serverId = QLatin1String("QQmlDebugServer"); -const QString clientId = QLatin1String("QQmlDebugClient"); +const QString serverId = QLatin1String("QDeclarativeDebugServer"); +const QString clientId = QLatin1String("QDeclarativeDebugClient"); class QQmlDebugClientPrivate : public QObjectPrivate { diff --git a/src/qml/debugger/qqmldebughelper.cpp b/src/qml/debugger/qqmldebughelper.cpp deleted file mode 100644 index 7158b3609d..0000000000 --- a/src/qml/debugger/qqmldebughelper.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmldebughelper_p.h" - -#include <QtCore/QAbstractAnimation> -#include <QtQml/QJSEngine> - -#include <private/qqmlengine_p.h> -#include <private/qabstractanimation_p.h> -#include <private/qqmlengine_p.h> - -QT_BEGIN_NAMESPACE - -void QQmlDebugHelper::setAnimationSlowDownFactor(qreal factor) -{ - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setSlowModeEnabled(factor != 1.0); - timer->setSlowdownFactor(factor); -} - -void QQmlDebugHelper::enableDebugging() { - qWarning("QQmlDebugHelper::enableDebugging() is deprecated! Add CONFIG += declarative_debug to your .pro file instead."); -#ifndef QQML_NO_DEBUG_PROTOCOL - if (!QQmlEnginePrivate::qml_debugging_enabled) { - qWarning("Qml debugging is enabled. Only use this in a safe environment!"); - } - QQmlEnginePrivate::qml_debugging_enabled = true; -#endif -} - -QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmldebughelper_p.h b/src/qml/debugger/qqmldebughelper_p.h deleted file mode 100644 index 5d2bcc2be0..0000000000 --- a/src/qml/debugger/qqmldebughelper_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQMLDEBUGHELPER_P_H -#define QQMLDEBUGHELPER_P_H - -#include <private/qtqmlglobal_p.h> - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQmlEngine; - -#ifndef QT_BUILD_QML_LIB -#warning Use of this header file is deprecated! Add CONFIG += declarative_debug to your .pro file instead. -#endif - -// Helper methods to access private API through a stable interface -// This is used in the qmljsdebugger library of QtCreator. -class Q_QML_EXPORT QQmlDebugHelper -{ -public: - static void setAnimationSlowDownFactor(qreal factor); - - // Enables remote debugging functionality - // Only use this for debugging in a safe environment! - static void enableDebugging(); -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QQMLDEBUGHELPER_P_H diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index 8d5c597a78..e70632d925 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -60,21 +60,21 @@ QT_BEGIN_NAMESPACE handshake: 1. Client sends - "QQmlDebugServer" 0 version pluginNames + "QDeclarativeDebugServer" 0 version pluginNames version: an int representing the highest protocol version the client knows pluginNames: plugins available on client side 2. Server sends - "QQmlDebugClient" 0 version pluginNames pluginVersions + "QDeclarativeDebugClient" 0 version pluginNames pluginVersions version: an int representing the highest protocol version the client & server know pluginNames: plugins available on server side. plugins both in the client and server message are enabled. client plugin advertisement 1. Client sends - "QQmlDebugServer" 1 pluginNames + "QDeclarativeDebugServer" 1 pluginNames server plugin advertisement 1. Server sends - "QQmlDebugClient" 1 pluginNames pluginVersions + "QDeclarativeDebugClient" 1 pluginNames pluginVersions plugin communication: - Everything send with a header different to "QQmlDebugServer" is sent to the appropriate plugin. + Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin. */ const int protocolVersion = 1; @@ -155,7 +155,7 @@ void QQmlDebugServerPrivate::advertisePlugins() pluginNames << service->name(); pluginVersions << service->version(); } - out << QString(QLatin1String("QQmlDebugClient")) << 1 << pluginNames << pluginVersions; + out << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << pluginNames << pluginVersions; } QMetaObject::invokeMethod(q, "_q_sendMessages", Qt::QueuedConnection, Q_ARG(QList<QByteArray>, QList<QByteArray>() << message)); @@ -180,12 +180,12 @@ QQmlDebugServerConnection *QQmlDebugServerPrivate::loadConnectionPlugin( foreach (const QString &pluginPath, pluginCandidates) { if (qmlDebugVerbose()) - qDebug() << "QQmlDebugServer: Trying to load plugin " << pluginPath << "..."; + qDebug() << "QML Debugger: Trying to load plugin " << pluginPath << "..."; loader.setFileName(pluginPath); if (!loader.load()) { if (qmlDebugVerbose()) - qDebug() << "QQmlDebugServer: Error while loading: " << loader.errorString(); + qDebug() << "QML Debugger: Error while loading: " << loader.errorString(); continue; } if (QObject *instance = loader.instance()) @@ -193,13 +193,13 @@ QQmlDebugServerConnection *QQmlDebugServerPrivate::loadConnectionPlugin( if (connection) { if (qmlDebugVerbose()) - qDebug() << "QQmlDebugServer: Plugin successfully loaded."; + qDebug() << "QML Debugger: Plugin successfully loaded."; return connection; } if (qmlDebugVerbose()) - qDebug() << "QQmlDebugServer: Plugin does not implement interface QQmlDebugServerConnection."; + qDebug() << "QML Debugger: Plugin does not implement interface QQmlDebugServerConnection."; loader.unload(); } @@ -217,7 +217,7 @@ void QQmlDebugServerThread::run() connection->setPort(m_port, m_block); } else { QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp)); - qWarning() << QString::fromAscii("QQmlDebugServer: Ignoring \"-qmljsdebugger=%1\". " + qWarning() << QString::fromAscii("QML Debugger: Ignoring \"-qmljsdebugger=%1\". " "Remote debugger plugin has not been found.").arg(appD->qmljsDebugArgumentsString()); } @@ -263,7 +263,7 @@ QQmlDebugServer *QQmlDebugServer::instance() if (!appD->qmljsDebugArgumentsString().isEmpty()) { if (!QQmlEnginePrivate::qml_debugging_enabled) { qWarning() << QString::fromLatin1( - "QQmlDebugServer: Ignoring \"-qmljsdebugger=%1\". " + "QML Debugger: Ignoring \"-qmljsdebugger=%1\". " "Debugging has not been enabled.").arg( appD->qmljsDebugArgumentsString()); return 0; @@ -299,7 +299,7 @@ QQmlDebugServer *QQmlDebugServer::instance() } else { qWarning() << QString::fromLatin1( - "QQmlDebugServer: Ignoring \"-qmljsdebugger=%1\". " + "QML Debugger: Ignoring \"-qmljsdebugger=%1\". " "Format is -qmljsdebugger=port:<port>[,block]").arg( appD->qmljsDebugArgumentsString()); } @@ -307,7 +307,7 @@ QQmlDebugServer *QQmlDebugServer::instance() #else if (!appD->qmljsDebugArgumentsString().isEmpty()) { qWarning() << QString::fromLatin1( - "QQmlDebugServer: Ignoring \"-qmljsdebugger=%1\". " + "QML Debugger: Ignoring \"-qmljsdebugger=%1\". " "QtQml is not configured for debugging.").arg( appD->qmljsDebugArgumentsString()); } @@ -354,7 +354,7 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) QString name; in >> name; - if (name == QLatin1String("QQmlDebugServer")) { + if (name == QLatin1String("QDeclarativeDebugServer")) { int op = -1; in >> op; if (op == 0) { @@ -373,7 +373,7 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) pluginVersions << service->version(); } - out << QString(QLatin1String("QQmlDebugClient")) << 0 << protocolVersion << pluginNames << pluginVersions; + out << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << pluginNames << pluginVersions; } d->connection->send(QList<QByteArray>() << helloAnswer); @@ -389,7 +389,7 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) iter.value()->stateChanged(newState); } - qWarning("QQmlDebugServer: Connection established"); + qWarning("QML Debugger: Connection established."); d->messageArrivedCondition.wakeAll(); } else if (op == 1) { @@ -414,7 +414,7 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) } } else { - qWarning("QQmlDebugServer: Invalid control message %d", op); + qWarning("QML Debugger: Invalid control message %d.", op); d->connection->disconnect(); return; } @@ -427,7 +427,7 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) QReadLocker(&d->pluginsLock); QHash<QString, QQmlDebugService *>::Iterator iter = d->plugins.find(name); if (iter == d->plugins.end()) { - qWarning() << "QQmlDebugServer: Message received for missing plugin" << name; + qWarning() << "QML Debugger: Message received for missing plugin" << name << "."; } else { (*iter)->messageReceived(message); @@ -435,7 +435,7 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message) d->messageArrivedCondition.wakeAll(); } } else { - qWarning("QQmlDebugServer: Invalid hello message"); + qWarning("QML Debugger: Invalid hello message."); } } diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp index 9eb9489566..a1cc4fe0a3 100644 --- a/src/qml/debugger/qqmldebugservice.cpp +++ b/src/qml/debugger/qqmldebugservice.cpp @@ -140,7 +140,7 @@ struct ObjectReferenceHash }; } -Q_GLOBAL_STATIC(ObjectReferenceHash, objectReferenceHash); +Q_GLOBAL_STATIC(ObjectReferenceHash, objectReferenceHash) /*! diff --git a/src/qml/debugger/qqmlenginedebug.cpp b/src/qml/debugger/qqmlenginedebug.cpp index 597e7aeb04..65af181f1b 100644 --- a/src/qml/debugger/qqmlenginedebug.cpp +++ b/src/qml/debugger/qqmlenginedebug.cpp @@ -96,7 +96,7 @@ public: QQmlEngineDebugClient::QQmlEngineDebugClient(QQmlDebugConnection *client, QQmlEngineDebugPrivate *p) - : QQmlDebugClient(QLatin1String("QQmlEngine"), client), priv(p) + : QQmlDebugClient(QLatin1String("QDeclarativeEngine"), client), priv(p) { } diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index be2e826bdf..114d7ef63f 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC(QQmlEngineDebugService, qmlEngineDebugService); +Q_GLOBAL_STATIC(QQmlEngineDebugService, qmlEngineDebugService) QQmlEngineDebugService *QQmlEngineDebugService::instance() { @@ -67,7 +67,7 @@ QQmlEngineDebugService *QQmlEngineDebugService::instance() } QQmlEngineDebugService::QQmlEngineDebugService(QObject *parent) - : QQmlDebugService(QLatin1String("QQmlEngine"), 1, parent), + : QQmlDebugService(QLatin1String("QDeclarativeEngine"), 1, parent), m_watch(new QQmlWatcher(this)), m_statesDelegate(0) { diff --git a/src/qml/debugger/qqmlinspectorservice.cpp b/src/qml/debugger/qqmlinspectorservice.cpp index 508d12eefa..c494045bff 100644 --- a/src/qml/debugger/qqmlinspectorservice.cpp +++ b/src/qml/debugger/qqmlinspectorservice.cpp @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QQmlInspectorService, serviceInstance) QQmlInspectorService::QQmlInspectorService() - : QQmlDebugService(QLatin1String("QQmlObserverMode"), 1) + : QQmlDebugService(QLatin1String("QDeclarativeObserverMode"), 1) , m_currentInspectorPlugin(0) { registerService(); diff --git a/src/qml/qml/ftw/qfastmetabuilder.cpp b/src/qml/qml/ftw/qfastmetabuilder.cpp index 02f50911ea..08ea76b37e 100644 --- a/src/qml/qml/ftw/qfastmetabuilder.cpp +++ b/src/qml/qml/ftw/qfastmetabuilder.cpp @@ -197,7 +197,8 @@ void QFastMetaBuilder::setProperty(int index, const StringRef &name, const Strin QMetaType::Type mtype, PropertyFlag flags, int notifySignal) { Q_ASSERT(!m_data.isEmpty()); - Q_ASSERT(!name.isEmpty() && !type.isEmpty()); + Q_ASSERT(!name.isEmpty()); + Q_ASSERT(!type.isEmpty()); QMetaObjectPrivate *p = priv(m_data); Q_ASSERT(index < p->propertyCount); diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index 23c4adc7b4..9304a75fbf 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -2865,7 +2865,8 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) { // Reserve space for name - p->nameRef = builder.newString(p->name.utf8length()); + if (p->type != Object::DynamicProperty::Alias || resolveAlias) + p->nameRef = builder.newString(p->name.utf8length()); int propertyType = 0; bool readonly = false; @@ -3102,7 +3103,7 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod // Allocate default property if necessary if (defaultProperty) - strcpy(defPropRef.data(), "DefaultProperty"); + defPropRef.load("DefaultProperty"); // Now allocate signals for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) { @@ -3231,6 +3232,8 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, int propIndex, int aliasIndex, Object::DynamicProperty &prop) { + Q_ASSERT(!prop.nameRef.isEmpty()); + Q_ASSERT(prop.typeRef.isEmpty()); if (!prop.defaultValue) COMPILE_EXCEPTION(obj, tr("No property alias location")); @@ -3325,7 +3328,6 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder, VMD *vmd = (QQmlVMEMetaData *)data.data(); *(vmd->aliasData() + aliasIndex) = aliasData; - prop.nameRef = builder.newString(prop.name.utf8length()); prop.resolvedCustomTypeName = pool->NewByteArray(typeName); prop.typeRef = builder.newString(typeName.length()); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 54c9d048df..90b8bcd8bb 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -996,7 +996,7 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler() { #ifndef QQML_NO_DEBUG_PROTOCOL if (!QQmlEnginePrivate::qml_debugging_enabled) { - qWarning("Qml debugging is enabled. Only use this in a safe environment!"); + qWarning("QML debugging is enabled. Only use this in a safe environment."); } QQmlEnginePrivate::qml_debugging_enabled = true; #endif diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp index d1c2faa138..db59a7266f 100644 --- a/src/qml/qml/qqmlscript.cpp +++ b/src/qml/qml/qqmlscript.cpp @@ -924,7 +924,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node) { "int", strlen("int"), Object::DynamicProperty::Int, "int", strlen("int") }, { "bool", strlen("bool"), Object::DynamicProperty::Bool, "bool", strlen("bool") }, { "double", strlen("double"), Object::DynamicProperty::Real, "double", strlen("double") }, - { "real", strlen("real"), Object::DynamicProperty::Real, "qreal", strlen("qreal") }, + { "real", strlen("real"), Object::DynamicProperty::Real, "double", strlen("double") }, { "string", strlen("string"), Object::DynamicProperty::String, "QString", strlen("QString") }, { "url", strlen("url"), Object::DynamicProperty::Url, "QUrl", strlen("QUrl") }, { "color", strlen("color"), Object::DynamicProperty::Color, "QColor", strlen("QColor") }, diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp index 0efb2686df..32581a072c 100644 --- a/src/qml/qml/v4/qv4irbuilder.cpp +++ b/src/qml/qml/v4/qv4irbuilder.cpp @@ -684,7 +684,7 @@ bool QV4IRBuilder::visit(AST::CallExpression *ast) //ExprResult base = expression(ast->base); QString id; for (int i = 0; i < names.size(); ++i) { - if (! i) + if (i) id += QLatin1Char('.'); id += names.at(i); } diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 8101408ced..143ccee960 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1188,9 +1188,7 @@ v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args) QCoreApplication::Encoding encoding = QCoreApplication::UnicodeUTF8; if (args.Length() > 3) { QString encStr = v8engine->toString(args[3]); - if (encStr == QLatin1String("CodecForTr")) { - encoding = QCoreApplication::CodecForTr; - } else if (encStr == QLatin1String("UnicodeUTF8")) { + if (encStr == QLatin1String("UnicodeUTF8")) { encoding = QCoreApplication::UnicodeUTF8; } else { QString msg = QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr); diff --git a/src/quick/items/context2d/context2d.pri b/src/quick/items/context2d/context2d.pri index 84346f68c6..c73d58b020 100644 --- a/src/quick/items/context2d/context2d.pri +++ b/src/quick/items/context2d/context2d.pri @@ -2,7 +2,6 @@ SOURCES += \ $$PWD/qquickcanvasitem.cpp \ $$PWD/qquickcanvascontext.cpp \ $$PWD/qquickcontext2d.cpp \ - $$PWD/qquickcanvasitemnode.cpp \ $$PWD/qquickcontext2dtile.cpp \ $$PWD/qquickcontext2dtexture.cpp \ $$PWD/qquickcontext2dcommandbuffer.cpp \ @@ -11,7 +10,6 @@ HEADERS += \ $$PWD/qquickcanvasitem_p.h \ $$PWD/qquickcanvascontext_p.h \ $$PWD/qquickcontext2d_p.h \ - $$PWD/qquickcanvasitemnode_p.h \ $$PWD/qquickcontext2dtile_p.h \ $$PWD/qquickcontext2dtexture_p.h \ $$PWD/qquickcontext2dcommandbuffer_p.h \ diff --git a/src/quick/items/context2d/qquickcanvascontext.cpp b/src/quick/items/context2d/qquickcanvascontext.cpp index bb1065bd6a..39f178b941 100644 --- a/src/quick/items/context2d/qquickcanvascontext.cpp +++ b/src/quick/items/context2d/qquickcanvascontext.cpp @@ -66,10 +66,6 @@ void QQuickCanvasContext::flush() { } -void QQuickCanvasContext::sync() -{ -} - QT_END_NAMESPACE diff --git a/src/quick/items/context2d/qquickcanvascontext_p.h b/src/quick/items/context2d/qquickcanvascontext_p.h index 37b5fa33fa..37ce698f15 100644 --- a/src/quick/items/context2d/qquickcanvascontext_p.h +++ b/src/quick/items/context2d/qquickcanvascontext_p.h @@ -68,13 +68,8 @@ public: virtual void init(QQuickCanvasItem *canvasItem, const QVariantMap &args) = 0; virtual void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth); - - // Indicate this is a good time to begin composition virtual void flush(); - // Cause render (if necessary) to surface via execution unit - virtual void sync(); - virtual void setV8Engine(QV8Engine *engine) = 0; virtual v8::Handle<v8::Object> v8value() const = 0; diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 550ab20403..f89ac186eb 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -44,7 +44,7 @@ #include <private/qquickitem_p.h> #include <private/qquickcanvascontext_p.h> #include <private/qquickcontext2d_p.h> -#include <private/qquickcanvasitemnode_p.h> +#include <qsgsimpletexturenode.h> #include <QtQuick/private/qquickpixmapcache_p.h> #include <qqmlinfo.h> @@ -86,8 +86,8 @@ QQuickCanvasItemPrivate::QQuickCanvasItemPrivate() , hasCanvasWindow(false) , available(false) , contextInitialized(false) - , renderTarget(QQuickCanvasItem::Image) - , renderStrategy(QQuickCanvasItem::Threaded) + , renderTarget(QQuickCanvasItem::FramebufferObject) + , renderStrategy(QQuickCanvasItem::Cooperative) { } @@ -379,7 +379,7 @@ void QQuickCanvasItem::setCanvasWindow(const QRectF& rect) context will choose appropriate options and Canvas will signal the change to the properties. - The default render target is \c Canvas.Image. + The default render target is \c Canvas.FramebufferObject. */ QQuickCanvasItem::RenderTarget QQuickCanvasItem::renderTarget() const { @@ -419,7 +419,7 @@ void QQuickCanvasItem::setRenderTarget(QQuickCanvasItem::RenderTarget target) the GUI thread. Selecting \c Canvas.Cooperative, does not guarantee rendering will occur on a thread separate from the GUI thread. - The default value is \c Canvas.Threaded. + The default value is \c Canvas.Cooperative. \sa QtQuick2::Canvas::renderTarget */ @@ -463,30 +463,29 @@ void QQuickCanvasItem::sceneGraphInitialized() void QQuickCanvasItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickCanvasItem); - QQuickItem::geometryChanged(newGeometry, oldGeometry); - const qreal w = newGeometry.width(); - const qreal h = newGeometry.height(); + QQuickItem::geometryChanged(newGeometry, oldGeometry); - if (!d->hasCanvasSize) { - d->canvasSize = QSizeF(w, h); + QSizeF newSize = newGeometry.size(); + if (!d->hasCanvasSize && d->canvasSize != newSize) { + d->canvasSize = newSize; emit canvasSizeChanged(); } - if (!d->hasTileSize) { - d->tileSize = d->canvasSize.toSize(); + if (!d->hasTileSize && d->tileSize != newSize) { + d->tileSize = newSize.toSize(); emit tileSizeChanged(); } - if (!d->hasCanvasWindow) { - d->canvasWindow = QRectF(0, 0, w, h); + const QRectF rect = QRectF(QPointF(0, 0), newSize); + + if (!d->hasCanvasWindow && d->canvasWindow != rect) { + d->canvasWindow = rect; emit canvasWindowChanged(); } - if (d->available) { - polish(); - update(); - } + if (d->available) + requestPaint(); } void QQuickCanvasItem::componentComplete() @@ -549,8 +548,12 @@ void QQuickCanvasItem::updatePolish() } } - if (d->contextInitialized) - d->context->flush(); + if (d->contextInitialized) { + if (d->renderStrategy == QQuickCanvasItem::Cooperative) + update(); + else + d->context->flush(); + } } QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) @@ -560,17 +563,23 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData if (!d->contextInitialized) return 0; - QQuickCanvasItemNode *node = static_cast<QQuickCanvasItemNode*>(oldNode); + class CanvasTextureNode : public QSGSimpleTextureNode + { + public: + CanvasTextureNode() : QSGSimpleTextureNode() {} + ~CanvasTextureNode() {delete texture();} + }; + + CanvasTextureNode *node = static_cast<CanvasTextureNode*>(oldNode); if (!node) { - node = new QQuickCanvasItemNode; + node = new CanvasTextureNode; } if (d->renderStrategy == QQuickCanvasItem::Cooperative) - d->context->sync(); + d->context->flush(); node->setTexture(d->context->texture()); - node->setSize(d->canvasWindow.size()); - node->update(); + node->setRect(QRectF(QPoint(0, 0), d->canvasWindow.size())); return node; } diff --git a/src/quick/items/context2d/qquickcanvasitemnode.cpp b/src/quick/items/context2d/qquickcanvasitemnode.cpp deleted file mode 100644 index 5a2dd80ff1..0000000000 --- a/src/quick/items/context2d/qquickcanvasitemnode.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickcanvasitemnode_p.h" - -#include <QtQuick/private/qsgcontext_p.h> -#include <QtCore/qmath.h> - -QT_BEGIN_NAMESPACE - - -QQuickCanvasItemNode::QQuickCanvasItemNode() - : QSGGeometryNode() - , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) - , m_texture(0) - , m_size(1, 1) - , m_dirtyGeometry(false) - , m_dirtyTexture(false) -{ - setMaterial(&m_materialO); - setOpaqueMaterial(&m_material); - setGeometry(&m_geometry); -} - -QQuickCanvasItemNode::~QQuickCanvasItemNode() -{ - delete m_texture; -} - -void QQuickCanvasItemNode::setSize(const QSizeF& size) -{ - if (m_size != size) { - m_dirtyGeometry = true; - m_size = size; - } -} - -void QQuickCanvasItemNode::setTexture(QSGDynamicTexture* texture) -{ - if (texture != m_texture) { - m_dirtyTexture = true; - m_texture = texture; - } -} - -void QQuickCanvasItemNode::update() -{ - if (m_dirtyGeometry) - updateGeometry(); - if (m_dirtyTexture) - updateTexture(); - - m_dirtyGeometry = false; - m_dirtyTexture = false; -} - -void QQuickCanvasItemNode::updateTexture() -{ - m_material.setTexture(m_texture); - m_materialO.setTexture(m_texture); - markDirty(DirtyMaterial); -} - -void QQuickCanvasItemNode::updateGeometry() -{ - QRectF source = m_texture->normalizedTextureSubRect(); - QSGGeometry::updateTexturedRectGeometry(&m_geometry, - QRectF(0, 0, m_size.width(), m_size.height()), - source); - markDirty(DirtyGeometry); -} - -QT_END_NAMESPACE - diff --git a/src/quick/items/context2d/qquickcanvasitemnode_p.h b/src/quick/items/context2d/qquickcanvasitemnode_p.h deleted file mode 100644 index 7eb7d2aec5..0000000000 --- a/src/quick/items/context2d/qquickcanvasitemnode_p.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKCONTEXT2DNODE_P_H -#define QQUICKCONTEXT2DNODE_P_H - -#include <QtQuick/qsgnode.h> -#include <QtQuick/qsgtexturematerial.h> - -#include "qquickcanvasitem_p.h" -#include "qquickcontext2dtexture_p.h" -#include "qquickcontext2d_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QSGDynamicTexture; - -class QQuickCanvasItemNode : public QSGGeometryNode -{ -public: - QQuickCanvasItemNode(); - ~QQuickCanvasItemNode(); - - void setTexture(QSGDynamicTexture *texture); - void update(); - void setSize(const QSizeF& size); - -private: - void updateTexture(); - void updateGeometry(); - - QSGOpaqueTextureMaterial m_material; - QSGTextureMaterial m_materialO; - QSGGeometry m_geometry; - QSGTexture* m_texture; - QSizeF m_size; - - bool m_dirtyGeometry; - bool m_dirtyTexture; -}; - -QT_END_HEADER - -QT_END_NAMESPACE - -#endif // QQUICKCONTEXT2DNODE_P_H diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index fc2ada2867..05577e8c5c 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -100,21 +100,6 @@ QT_BEGIN_NAMESPACE \image qml-item-canvas-context.gif */ -QLockedCommandBuffer::QLockedCommandBuffer(QQuickContext2DCommandBuffer *b) - : m_buffer(b) -{ - m_buffer->lockQueue(); -} - -QLockedCommandBuffer::~QLockedCommandBuffer() -{ - m_buffer->unlockQueue(); -} - -QQuickContext2DCommandBuffer* QLockedCommandBuffer::operator->() const -{ - return m_buffer; -} Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); @@ -3196,7 +3181,7 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args switch (m_renderTarget) { case QQuickCanvasItem::Image: - m_texture = new QQuickContext2DImageTexture(m_renderStrategy == QQuickCanvasItem::Threaded); // ?? || Coop + m_texture = new QQuickContext2DImageTexture(m_renderStrategy == QQuickCanvasItem::Threaded); break; case QQuickCanvasItem::FramebufferObject: m_texture = new QQuickContext2DFBOTexture; @@ -3221,6 +3206,13 @@ void QQuickContext2D::prepare(const QSize& canvasSize, const QSize& tileSize, co void QQuickContext2D::flush() { + if (!m_buffer->isEmpty()) { + QMutexLocker lock(&m_bufferMutex); + m_bufferQueue.enqueue(m_buffer); + m_buffer = new QQuickContext2DCommandBuffer; + } else + return; + switch (m_renderStrategy) { case QQuickCanvasItem::Immediate: // Cause the texture to consume paint commands immediately @@ -3231,19 +3223,12 @@ void QQuickContext2D::flush() m_texture->paint(); break; case QQuickCanvasItem::Cooperative: - // Add to the update list in SG - m_canvas->update(); // FIXME + // NOTE: On SG Thread + m_texture->paint(); break; } } -// On SG render thread -void QQuickContext2D::sync() -{ - if (m_renderStrategy == QQuickCanvasItem::Cooperative) - m_texture->paint(); -} - QSGDynamicTexture *QQuickContext2D::texture() const { return m_texture; @@ -3251,6 +3236,15 @@ QSGDynamicTexture *QQuickContext2D::texture() const QImage QQuickContext2D::toImage(const QRectF& bounds) { + switch (m_renderStrategy) { + case QQuickCanvasItem::Immediate: + case QQuickCanvasItem::Threaded: + flush(); + break; + case QQuickCanvasItem::Cooperative: + break; + } + return m_texture->toImage(bounds); } @@ -3475,4 +3469,10 @@ void QQuickContext2D::setV8Engine(QV8Engine *engine) } } +QQuickContext2DCommandBuffer* QQuickContext2D::nextBuffer() +{ + QMutexLocker lock(&m_bufferMutex); + return m_bufferQueue.isEmpty() ? 0 : m_bufferQueue.dequeue(); +} + QT_END_NAMESPACE diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h index 239a244739..3230881134 100644 --- a/src/quick/items/context2d/qquickcontext2d_p.h +++ b/src/quick/items/context2d/qquickcontext2d_p.h @@ -51,6 +51,7 @@ #include <QtGui/qpainterpath.h> #include <QtCore/qstring.h> #include <QtCore/qstack.h> +#include <QtCore/qqueue.h> #include <private/qv8engine_p.h> @@ -70,14 +71,6 @@ class QQuickContext2DTexture; class QQuickPixmap; class QSGTexture; -class QLockedCommandBuffer { -public: - QLockedCommandBuffer(QQuickContext2DCommandBuffer *b); - ~QLockedCommandBuffer(); - QQuickContext2DCommandBuffer* operator->() const; -private: - QQuickContext2DCommandBuffer *m_buffer; -}; class Q_QUICK_EXPORT QQuickContext2D : public QQuickCanvasContext { @@ -179,7 +172,9 @@ public: void setV8Engine(QV8Engine *eng); QQuickCanvasItem* canvas() const { return m_canvas; } - QLockedCommandBuffer buffer() const { return m_buffer; } + QQuickContext2DCommandBuffer* buffer() const { return m_buffer; } + QQuickContext2DCommandBuffer* nextBuffer(); + bool bufferValid() const { return m_buffer != 0; } void popState(); void pushState(); @@ -221,6 +216,8 @@ public: QQuickContext2DTexture *m_texture; QQuickCanvasItem::RenderTarget m_renderTarget; QQuickCanvasItem::RenderStrategy m_renderStrategy; + QQueue<QQuickContext2DCommandBuffer*> m_bufferQueue; + QMutex m_bufferMutex; }; diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index 28460e2164..bdf147151e 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -75,10 +75,8 @@ Q_GLOBAL_STATIC(QThread, globalCanvasThreadRenderInstance) QQuickContext2DTexture::QQuickContext2DTexture() : m_context(0) , m_item(0) - , m_canvasSize(QSize(1, 1)) - , m_tileSize(QSize(1, 1)) - , m_canvasWindow(QRect(0, 0, 1, 1)) , m_dirtyCanvas(false) + , m_canvasWindowChanged(false) , m_dirtyTexture(false) , m_threadRendering(false) , m_smooth(false) @@ -144,6 +142,7 @@ bool QQuickContext2DTexture::setCanvasWindow(const QRect& r) { if (m_canvasWindow != r) { m_canvasWindow = r; + m_canvasWindowChanged = true; return true; } return false; @@ -178,6 +177,7 @@ void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& setCanvasSize(canvasSize); setTileSize(ts); + setCanvasWindow(canvasWindow); if (canvasSize == canvasWindow.size()) { m_tiledCanvas = false; @@ -196,13 +196,14 @@ void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& void QQuickContext2DTexture::paintWithoutTiles() { - QLockedCommandBuffer ccb = m_context->buffer(); + QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer(); - if (ccb->isEmpty()) + if (!ccb || ccb->isEmpty()) return; QPaintDevice* device = beginPainting(); if (!device) { + delete ccb; endPainting(); return; } @@ -219,6 +220,7 @@ void QQuickContext2DTexture::paintWithoutTiles() ccb->replay(&p, m_state); ccb->clear(); + delete ccb; endPainting(); @@ -270,7 +272,12 @@ void QQuickContext2DTexture::paint() if (beginPainting()) { QQuickContext2D::State oldState = m_state; - QLockedCommandBuffer ccb = m_context->buffer(); + QQuickContext2DCommandBuffer* ccb = m_context->nextBuffer(); + if (!ccb || ccb->isEmpty()) { + endPainting(); + delete ccb; + return; + } foreach (QQuickContext2DTile* tile, m_tiles) { bool dirtyTile = false, dirtyCanvas = false, smooth = false; @@ -297,6 +304,7 @@ void QQuickContext2DTexture::paint() compositeTile(tile); } ccb->clear(); + delete ccb; endPainting(); m_state = oldState; markDirtyTexture(); @@ -331,7 +339,7 @@ QRect QQuickContext2DTexture::createTiles(const QRect& window) return QRect(); } - QRect r = tiledRect(window, m_tileSize); + QRect r = tiledRect(window, adjustedTileSize(m_tileSize)); const int tw = m_tileSize.width(); const int th = m_tileSize.height(); @@ -379,6 +387,30 @@ void QQuickContext2DTexture::clearTiles() m_tiles.clear(); } +QSize QQuickContext2DTexture::adjustedTileSize(const QSize &ts) +{ + return ts; +} + +static inline QSize npotAdjustedSize(const QSize &size) +{ + static bool checked = false; + static bool npotSupported = false; + + if (!checked) { + npotSupported = QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); + checked = true; + } + + if (npotSupported) { + return QSize(qMax(QT_MINIMUM_FBO_SIZE, size.width()), + qMax(QT_MINIMUM_FBO_SIZE, size.height())); + } + + return QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width())), + qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height()))); +} + QQuickContext2DFBOTexture::QQuickContext2DFBOTexture() : QQuickContext2DTexture() , m_fbo(0) @@ -395,47 +427,9 @@ QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture() delete m_paint_device; } -bool QQuickContext2DFBOTexture::setCanvasSize(const QSize &size) -{ - QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width())) - , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height()))); - - if (m_canvasSize != s) { - m_canvasSize = s; - m_dirtyCanvas = true; - return true; - } - return false; -} - -bool QQuickContext2DFBOTexture::setTileSize(const QSize &size) +QSize QQuickContext2DFBOTexture::adjustedTileSize(const QSize &ts) { - QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width())) - , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height()))); - if (m_tileSize != s) { - m_tileSize = s; - m_dirtyCanvas = true; - return true; - } - return false; -} - -bool QQuickContext2DFBOTexture::setCanvasWindow(const QRect& canvasWindow) -{ - QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().width())) - , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().height()))); - - - bool doChanged = false; - if (m_fboSize != s) { - m_fboSize = s; - doChanged = true; - } - - if (m_canvasWindow != canvasWindow) - m_canvasWindow = canvasWindow; - - return doChanged; + return npotAdjustedSize(ts); } void QQuickContext2DFBOTexture::bind() @@ -550,9 +544,13 @@ QPaintDevice* QQuickContext2DFBOTexture::beginPainting() m_fbo = 0; m_multisampledFbo = 0; return 0; - } else if (!m_fbo || m_fbo->size() != m_fboSize) { + } else if (!m_fbo || m_canvasWindowChanged) { delete m_fbo; delete m_multisampledFbo; + + m_fboSize = npotAdjustedSize(m_canvasWindow.size()); + m_canvasWindowChanged = false; + if (doMultisampling()) { { QOpenGLFramebufferObjectFormat format; @@ -719,9 +717,10 @@ QPaintDevice* QQuickContext2DImageTexture::beginPainting() if (m_canvasWindow.size().isEmpty()) return 0; - if (m_image.size() != m_canvasWindow.size()) { + if (m_canvasWindowChanged) { m_image = QImage(m_canvasWindow.size(), QImage::Format_ARGB32_Premultiplied); m_image.fill(0x00000000); + m_canvasWindowChanged = false; } return &m_image; diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h index 9e00ece16c..81b239dc16 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture_p.h +++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h @@ -81,9 +81,9 @@ public: virtual QImage toImage(const QRectF& region = QRectF()) = 0; static QRect tiledRect(const QRectF& window, const QSize& tileSize); - virtual bool setCanvasSize(const QSize &size); - virtual bool setTileSize(const QSize &size); - virtual bool setCanvasWindow(const QRect& canvasWindow); + bool setCanvasSize(const QSize &size); + bool setTileSize(const QSize &size); + bool setCanvasWindow(const QRect& canvasWindow); void setSmooth(bool smooth); bool setDirtyRect(const QRect &dirtyRect); virtual void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth); @@ -104,6 +104,7 @@ protected: virtual void compositeTile(QQuickContext2DTile* tile) = 0; void clearTiles(); + virtual QSize adjustedTileSize(const QSize &ts); QRect createTiles(const QRect& window); QList<QQuickContext2DTile*> m_tiles; @@ -117,6 +118,7 @@ protected: QRect m_canvasWindow; uint m_dirtyCanvas : 1; + uint m_canvasWindowChanged : 1; uint m_dirtyTexture : 1; uint m_threadRendering : 1; uint m_smooth : 1; @@ -144,9 +146,8 @@ public: virtual QQuickCanvasItem::RenderTarget renderTarget() const; virtual void compositeTile(QQuickContext2DTile* tile); virtual void bind(); - virtual bool setCanvasSize(const QSize &size); - virtual bool setTileSize(const QSize &size); - virtual bool setCanvasWindow(const QRect& canvasWindow); + QSize adjustedTileSize(const QSize &ts); + private Q_SLOTS: void grabImage(); diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp index 177454eedc..1e07d96690 100644 --- a/src/quick/items/qquickaccessibleattached.cpp +++ b/src/quick/items/qquickaccessibleattached.cpp @@ -104,6 +104,7 @@ QT_BEGIN_NAMESPACE } Accessible.name: label.text Accessible.role: Accessible.Button + funtion accessiblePressAction { ... } } \endqml @@ -117,24 +118,19 @@ QT_BEGIN_NAMESPACE \o \row - \o CheckBox - \o checked - \o The check state of the check box. + \o Button + \o function accessiblePressAction + \o Called when the button receives a press action. The implementation should visually simulate a button click and perform the button action. \row - \o RadioButton + \o CheckBox, Radiobutton \o checked - \o The selected state of the radio button. - \row - \o Button - \o checkable - \o Whether the button is checkable. + \o The check state of the check box. Updated on Press, Check and Uncheck actions. \row - \o Button - \o checked - \o Whether the button is checked (only if checkable is true). + \o Slider, SpinBox, Dial, ScrollBar + \o value, minimumValue, maximumValue, stepSize + \o value will be updated on increase and decrase actions, in accordance with the other properties \endtable - */ QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent) diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 85c520b577..170a37c979 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -163,34 +163,40 @@ QQuickRootItem::QQuickRootItem() { } +/*! \reimp */ void QQuickCanvas::exposeEvent(QExposeEvent *) { Q_D(QQuickCanvas); - d->windowManager->paint(this); + d->windowManager->exposureChanged(this); } +/*! \reimp */ void QQuickCanvas::resizeEvent(QResizeEvent *) { Q_D(QQuickCanvas); d->windowManager->resize(this, size()); } +/*! \reimp */ void QQuickCanvas::showEvent(QShowEvent *) { d_func()->windowManager->show(this); } +/*! \reimp */ void QQuickCanvas::hideEvent(QHideEvent *) { d_func()->windowManager->hide(this); } +/*! \reimp */ void QQuickCanvas::focusOutEvent(QFocusEvent *) { Q_D(QQuickCanvas); d->rootItem->setFocus(false); } +/*! \reimp */ void QQuickCanvas::focusInEvent(QFocusEvent *) { Q_D(QQuickCanvas); @@ -846,7 +852,7 @@ bool QQuickCanvasPrivate::clearHover() return accepted; } - +/*! \reimp */ bool QQuickCanvas::event(QEvent *e) { Q_D(QQuickCanvas); @@ -886,6 +892,7 @@ bool QQuickCanvas::event(QEvent *e) return QWindow::event(e); } +/*! \reimp */ void QQuickCanvas::keyPressEvent(QKeyEvent *e) { Q_D(QQuickCanvas); @@ -894,6 +901,7 @@ void QQuickCanvas::keyPressEvent(QKeyEvent *e) sendEvent(d->activeFocusItem, e); } +/*! \reimp */ void QQuickCanvas::keyReleaseEvent(QKeyEvent *e) { Q_D(QQuickCanvas); @@ -978,6 +986,7 @@ bool QQuickCanvasPrivate::deliverMouseEvent(QMouseEvent *event) return false; } +/*! \reimp */ void QQuickCanvas::mousePressEvent(QMouseEvent *event) { Q_D(QQuickCanvas); @@ -990,6 +999,7 @@ void QQuickCanvas::mousePressEvent(QMouseEvent *event) d->deliverMouseEvent(event); } +/*! \reimp */ void QQuickCanvas::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickCanvas); @@ -1008,6 +1018,7 @@ void QQuickCanvas::mouseReleaseEvent(QMouseEvent *event) d->mouseGrabberItem = 0; } +/*! \reimp */ void QQuickCanvas::mouseDoubleClickEvent(QMouseEvent *event) { Q_D(QQuickCanvas); @@ -1045,6 +1056,7 @@ bool QQuickCanvasPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item, return hoverEvent.isAccepted(); } +/*! \reimp */ void QQuickCanvas::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickCanvas); @@ -1178,6 +1190,7 @@ bool QQuickCanvasPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event } #ifndef QT_NO_WHEELEVENT +/*! \reimp */ void QQuickCanvas::wheelEvent(QWheelEvent *event) { Q_D(QQuickCanvas); diff --git a/src/quick/items/qquickcanvas.h b/src/quick/items/qquickcanvas.h index 0b6b01b05a..4ac9509896 100644 --- a/src/quick/items/qquickcanvas.h +++ b/src/quick/items/qquickcanvas.h @@ -124,7 +124,7 @@ Q_SIGNALS: void afterRendering(); void clearColorChanged(const QColor &); -public slots: +public Q_SLOTS: void releaseResources(); protected: diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 45fbc9f93e..a78ab4c4e5 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -1884,6 +1884,10 @@ void QQuickGridView::viewportMoved() FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i)); item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to); } + if (d->currentItem) { + FxGridItemSG *item = static_cast<FxGridItemSG*>(d->currentItem); + item->item->setVisible(item->rowPos() + d->rowSize() >= from && item->rowPos() <= to); + } if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving) d->moveReason = QQuickGridViewPrivate::Mouse; diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 516cf0c1bb..e368d1aaec 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1664,7 +1664,7 @@ void QQuickItemViewPrivate::layout() for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) { FxViewItem *item = *it; - if (item->transitionRunning() || prepareNonVisibleItemTransition(item, viewBounds)) { + if (prepareNonVisibleItemTransition(item, viewBounds)) { ++it; } else { releaseItem(item); @@ -1676,7 +1676,9 @@ void QQuickItemViewPrivate::layout() visibleItems[i]->startTransition(transitioner); for (int i=0; i<releasePendingTransition.count(); i++) releasePendingTransition[i]->startTransition(transitioner); + transitioner->setPopulateTransitionEnabled(false); + transitioner->resetTargetLists(); } runDelayedRemoveTransition = false; @@ -1955,36 +1957,10 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions() if (!transitioner) return; - transitioner->addTransitionIndexes.clear(); - transitioner->addTransitionTargets.clear(); - transitioner->moveTransitionIndexes.clear(); - transitioner->moveTransitionTargets.clear(); - + // must call for every visible item to init or discard transitions QRectF viewBounds(0, position(), q->width(), q->height()); - for (int i=0; i<visibleItems.count(); i++) { - // must call for every visible item to init or discard transitions - if (!visibleItems[i]->prepareTransition(viewBounds)) - continue; - if (visibleItems[i]->isTransitionTarget) { - switch (visibleItems[i]->nextTransitionType) { - case QQuickItemViewTransitioner::NoTransition: - break; - case QQuickItemViewTransitioner::PopulateTransition: - case QQuickItemViewTransitioner::AddTransition: - transitioner->addTransitionIndexes.append(visibleItems[i]->index); - transitioner->addTransitionTargets.append(visibleItems[i]->item); - break; - case QQuickItemViewTransitioner::MoveTransition: - transitioner->moveTransitionIndexes.append(visibleItems[i]->index); - transitioner->moveTransitionTargets.append(visibleItems[i]->item); - break; - case QQuickItemViewTransitioner::RemoveTransition: - // removed targets won't be in visibleItems, handle these - // in prepareNonVisibleItemTransition() - break; - } - } - } + for (int i=0; i<visibleItems.count(); i++) + visibleItems[i]->prepareTransition(transitioner, viewBounds); } void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQuickChangeSet::MoveKey, FxViewItem *> *removedItems) @@ -1992,10 +1968,8 @@ void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQuickChangeSet::Move if (!transitioner) return; - transitioner->removeTransitionIndexes.clear(); - transitioner->removeTransitionTargets.clear(); - - if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)) { + if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true) + || transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) { for (QHash<QQuickChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin(); it != removedItems->end(); ) { bool isRemove = it.key().moveId < 0; @@ -2024,21 +1998,12 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition) repositionItemAt(item, item->index, 0); - if (!item->prepareTransition(viewBounds)) - return false; - if (item->isTransitionTarget) { - if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition) { - transitioner->moveTransitionIndexes.append(item->index); - transitioner->moveTransitionTargets.append(item->item); - } else if (item->nextTransitionType == QQuickItemViewTransitioner::RemoveTransition) { - transitioner->removeTransitionIndexes.append(item->index); - transitioner->removeTransitionTargets.append(item->item); - } + if (item->prepareTransition(transitioner, viewBounds)) { + item->releaseAfterTransition = true; + return true; } - - item->releaseAfterTransition = true; - return true; + return false; } void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickViewItem *i) diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index 54375bf4ff..5669ef927e 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -165,28 +165,30 @@ QQuickItemViewTransitioner::~QQuickItemViewTransitioner() bool QQuickItemViewTransitioner::canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const { if (!asTarget - && type != QQuickItemViewTransitioner::NoTransition && type != QQuickItemViewTransitioner::PopulateTransition + && type != NoTransition && type != PopulateTransition && displacedTransition && displacedTransition->enabled()) { return true; } switch (type) { - case QQuickItemViewTransitioner::NoTransition: + case NoTransition: break; - case QQuickItemViewTransitioner::PopulateTransition: + case PopulateTransition: return usePopulateTransition && populateTransition && populateTransition->enabled(); - case QQuickItemViewTransitioner::AddTransition: + case AddTransition: + if (usePopulateTransition) + return false; if (asTarget) return addTransition && addTransition->enabled(); else return addDisplacedTransition && addDisplacedTransition->enabled(); - case QQuickItemViewTransitioner::MoveTransition: + case MoveTransition: if (asTarget) return moveTransition && moveTransition->enabled(); else return moveDisplacedTransition && moveDisplacedTransition->enabled(); - case QQuickItemViewTransitioner::RemoveTransition: + case RemoveTransition: if (asTarget) return removeTransition && removeTransition->enabled(); else @@ -197,27 +199,42 @@ bool QQuickItemViewTransitioner::canTransition(QQuickItemViewTransitioner::Trans void QQuickItemViewTransitioner::transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget) { - bool matchedTransition = false; - if (type == QQuickItemViewTransitioner::AddTransition) { - // don't run add transitions for added items while populating - if (usePopulateTransition) - matchedTransition = false; - else - matchedTransition = canTransition(type, isTarget); - } else { - matchedTransition = canTransition(type, isTarget); - } + item->setNextTransition(type, isTarget); +} - if (matchedTransition) { - item->setNextTransition(type, isTarget); - } else { - // the requested transition type is not valid, but the item is scheduled/in another - // transition, so cancel it to allow the item to move directly to the correct pos - if (item->transitionScheduledOrRunning()) - item->stopTransition(); +void QQuickItemViewTransitioner::addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index) +{ + switch (type) { + case NoTransition: + break; + case PopulateTransition: + case AddTransition: + addTransitionIndexes << index; + addTransitionTargets << item->item; + break; + case MoveTransition: + moveTransitionIndexes << index; + moveTransitionTargets << item->item; + break; + case RemoveTransition: + removeTransitionIndexes << index; + removeTransitionTargets << item->item; + break; } } +void QQuickItemViewTransitioner::resetTargetLists() +{ + addTransitionIndexes.clear(); + addTransitionTargets.clear(); + + removeTransitionIndexes.clear(); + removeTransitionTargets.clear(); + + moveTransitionIndexes.clear(); + moveTransitionTargets.clear(); +} + QQuickTransition *QQuickItemViewTransitioner::transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget) { if (type == QQuickItemViewTransitioner::NoTransition) @@ -254,14 +271,14 @@ QQuickTransition *QQuickItemViewTransitioner::transitionObject(QQuickItemViewTra const QList<int> &QQuickItemViewTransitioner::targetIndexes(QQuickItemViewTransitioner::TransitionType type) const { switch (type) { - case QQuickItemViewTransitioner::NoTransition: + case NoTransition: break; - case QQuickItemViewTransitioner::PopulateTransition: - case QQuickItemViewTransitioner::AddTransition: + case PopulateTransition: + case AddTransition: return addTransitionIndexes; - case QQuickItemViewTransitioner::MoveTransition: + case MoveTransition: return moveTransitionIndexes; - case QQuickItemViewTransitioner::RemoveTransition: + case RemoveTransition: return removeTransitionIndexes; } @@ -271,14 +288,14 @@ const QList<int> &QQuickItemViewTransitioner::targetIndexes(QQuickItemViewTransi const QList<QObject *> &QQuickItemViewTransitioner::targetItems(QQuickItemViewTransitioner::TransitionType type) const { switch (type) { - case QQuickItemViewTransitioner::NoTransition: + case NoTransition: break; - case QQuickItemViewTransitioner::PopulateTransition: - case QQuickItemViewTransitioner::AddTransition: + case PopulateTransition: + case AddTransition: return addTransitionTargets; - case QQuickItemViewTransitioner::MoveTransition: + case MoveTransition: return moveTransitionTargets; - case QQuickItemViewTransitioner::RemoveTransition: + case RemoveTransition: return removeTransitionTargets; } @@ -305,6 +322,7 @@ QQuickViewItem::QQuickViewItem(QQuickItem *i) , index(-1) , isTransitionTarget(false) , nextTransitionToSet(false) + , prepared(false) { } @@ -373,7 +391,7 @@ bool QQuickViewItem::isPendingRemoval() const return false; } -bool QQuickViewItem::prepareTransition(const QRectF &viewBounds) +bool QQuickViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) { bool doTransition = false; @@ -393,7 +411,8 @@ bool QQuickViewItem::prepareTransition(const QRectF &viewBounds) } case QQuickItemViewTransitioner::PopulateTransition: { - return true; + doTransition = true; + break; } case QQuickItemViewTransitioner::AddTransition: case QQuickItemViewTransitioner::RemoveTransition: @@ -408,14 +427,11 @@ bool QQuickViewItem::prepareTransition(const QRectF &viewBounds) doTransition = (nextTransitionType == QQuickItemViewTransitioner::AddTransition) ? viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height())) : viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height())); - if (!doTransition) - item->setPos(nextTransitionTo); } else { + // do transition if moving from or into visible area if (viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height())) || viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height()))) { doTransition = transitionWillChangePosition(); - } else { - item->setPos(nextTransitionTo); } } break; @@ -425,14 +441,28 @@ bool QQuickViewItem::prepareTransition(const QRectF &viewBounds) doTransition = viewBounds.isNull() || viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height())) || viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height())); - if (!doTransition) - item->setPos(nextTransitionTo); } break; } - if (!doTransition) + if (doTransition) { + // add item to target lists even if canTransition() is false for a target transition, + // since the target lists still need to be filled for displaced transitions + if (isTransitionTarget) + transitioner->addToTargetLists(nextTransitionType, this, index); + doTransition = transitioner->canTransition(nextTransitionType, isTransitionTarget); + } + + if (!doTransition) { + // if transition type is not valid, the previous transition still has to be + // canceled so that the item can move immediately to the right position + if (transition) + transition->cancel(); + item->setPos(nextTransitionTo); resetTransitionData(); + } + + prepared = true; return doTransition; } @@ -441,6 +471,11 @@ void QQuickViewItem::startTransition(QQuickItemViewTransitioner *transitioner) if (nextTransitionType == QQuickItemViewTransitioner::NoTransition) return; + if (!prepared) { + qWarning("QQuickViewItem::prepareTransition() not called!"); + return; + } + if (!transition || transition->m_type != nextTransitionType || transition->m_isTarget != isTransitionTarget) { delete transition; transition = new QQuickItemViewTransitionJob; @@ -453,17 +488,7 @@ void QQuickViewItem::startTransition(QQuickItemViewTransitioner *transitioner) transition->startTransition(this, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget); nextTransitionType = QQuickItemViewTransitioner::NoTransition; -} - -void QQuickViewItem::stopTransition() -{ - if (transition) { - transition->cancel(); - delete transition; - transition = 0; - } - resetTransitionData(); - finishedTransition(); + prepared = false; } void QQuickViewItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem) diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 3fb43d6b96..73c238e929 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -82,6 +82,9 @@ public: bool canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const; void transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget); + void addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index); + void resetTargetLists(); + QQuickTransition *transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget); const QList<int> &targetIndexes(QQuickItemViewTransitioner::TransitionType type) const; const QList<QObject *> &targetItems(QQuickItemViewTransitioner::TransitionType type) const; @@ -136,9 +139,8 @@ public: bool transitionRunning() const; bool isPendingRemoval() const; - bool prepareTransition(const QRectF &viewBounds); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); void startTransition(QQuickItemViewTransitioner *transitioner); - void stopTransition(); QPointF nextTransitionTo; QQuickItem *item; @@ -147,6 +149,7 @@ public: int index; bool isTransitionTarget; bool nextTransitionToSet; + bool prepared; private: friend class QQuickItemViewTransitioner; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 5e9a685cf5..a2f687c86b 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -615,20 +615,17 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d // We've jumped more than a page. Estimate which items are now // visible and fill from there. int count = (fillFrom - itemEnd) / (averageSize + spacing); - for (int i = 0; i < visibleItems.count(); ++i) - releaseItem(visibleItems.at(i)); - visibleItems.clear(); - modelIndex += count; - if (modelIndex >= model->count()) { - count -= modelIndex - model->count() + 1; - modelIndex = model->count() - 1; - } else if (modelIndex < 0) { - count -= modelIndex; - modelIndex = 0; - } - visibleIndex = modelIndex; - visiblePos = itemEnd + count * (averageSize + spacing); - itemEnd = visiblePos; + int newModelIdx = qBound(0, modelIndex + count, model->count()); + count = newModelIdx - modelIndex; + if (count) { + for (int i = 0; i < visibleItems.count(); ++i) + releaseItem(visibleItems.at(i)); + visibleItems.clear(); + modelIndex = newModelIdx; + visibleIndex = modelIndex; + visiblePos = itemEnd + count * (averageSize + spacing); + itemEnd = visiblePos; + } } bool changed = false; @@ -2553,6 +2550,8 @@ void QQuickListView::viewportMoved() FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i)); item->item->setVisible(item->endPosition() >= from && item->position() <= to); } + if (d->currentItem) + d->currentItem->item->setVisible(d->currentItem->endPosition() >= from && d->currentItem->position() <= to); if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving) d->moveReason = QQuickListViewPrivate::Mouse; diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index ec2c980879..ef57242319 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -697,7 +697,7 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event) void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::mouseMoveEvent(event); return; } @@ -783,7 +783,7 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickMouseArea); d->stealMouse = false; - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::mouseReleaseEvent(event); } else { d->saveEvent(event); @@ -820,7 +820,7 @@ void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event) void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::hoverEnterEvent(event); } else { d->lastPos = event->posF(); @@ -837,7 +837,7 @@ void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event) void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) { + if (!d->absorb && !d->pressed) { QQuickItem::hoverMoveEvent(event); } else { d->lastPos = event->posF(); @@ -854,7 +854,7 @@ void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event) void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event) { Q_D(QQuickMouseArea); - if (!d->absorb) + if (!d->absorb && !d->pressed) QQuickItem::hoverLeaveEvent(event); else setHovered(false); @@ -935,7 +935,7 @@ bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event) bool QQuickMouseArea::childMouseEventFilter(QQuickItem *i, QEvent *e) { Q_D(QQuickMouseArea); - if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren()) + if (!d->pressed && (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren())) return QQuickItem::childMouseEventFilter(i, e); switch (e->type()) { case QEvent::MouseButtonPress: diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index e1d0457916..e9a0c179e0 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -246,11 +246,8 @@ void QQuickBasePositioner::prePositioning() if (addedIndex < 0) addedIndex = posItem.index; PositionedItem *theItem = &positionedItems[positionedItems.count()-1]; - d->transitioner->transitionNextReposition(theItem, QQuickItemViewTransitioner::AddTransition, true); - d->transitioner->addTransitionIndexes << posItem.index; - d->transitioner->addTransitionTargets << posItem.item; } } } else { @@ -273,8 +270,6 @@ void QQuickBasePositioner::prePositioning() addedIndex = item->index; d->transitioner->transitionNextReposition(&positionedItems[positionedItems.count()-1], QQuickItemViewTransitioner::AddTransition, true); - d->transitioner->addTransitionIndexes << item->index; - d->transitioner->addTransitionTargets << item->item; } } else { item->isNew = false; @@ -307,12 +302,11 @@ void QQuickBasePositioner::prePositioning() if (d->transitioner) { QRectF viewBounds; - for (int i=0; i<positionedItems.count(); i++) { - if (positionedItems[i].prepareTransition(viewBounds)) - positionedItems[i].startTransition(d->transitioner); - } - d->transitioner->addTransitionIndexes.clear(); - d->transitioner->addTransitionTargets.clear(); + for (int i=0; i<positionedItems.count(); i++) + positionedItems[i].prepareTransition(d->transitioner, viewBounds); + for (int i=0; i<positionedItems.count(); i++) + positionedItems[i].startTransition(d->transitioner); + d->transitioner->resetTargetLists(); } d->doingPositioning = false; diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 7d1411aa6e..ab4a3ab7b6 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -497,6 +497,7 @@ void QQuickView::resizeEvent(QResizeEvent *e) QQuickCanvas::resizeEvent(e); } +/*! \reimp */ void QQuickView::keyPressEvent(QKeyEvent *e) { QQmlProfilerService::addEvent(QQmlProfilerService::Key); @@ -504,6 +505,7 @@ void QQuickView::keyPressEvent(QKeyEvent *e) QQuickCanvas::keyPressEvent(e); } +/*! \reimp */ void QQuickView::keyReleaseEvent(QKeyEvent *e) { QQmlProfilerService::addEvent(QQmlProfilerService::Key); @@ -511,6 +513,7 @@ void QQuickView::keyReleaseEvent(QKeyEvent *e) QQuickCanvas::keyReleaseEvent(e); } +/*! \reimp */ void QQuickView::mouseMoveEvent(QMouseEvent *e) { QQmlProfilerService::addEvent(QQmlProfilerService::Mouse); @@ -518,6 +521,7 @@ void QQuickView::mouseMoveEvent(QMouseEvent *e) QQuickCanvas::mouseMoveEvent(e); } +/*! \reimp */ void QQuickView::mousePressEvent(QMouseEvent *e) { QQmlProfilerService::addEvent(QQmlProfilerService::Mouse); @@ -525,6 +529,7 @@ void QQuickView::mousePressEvent(QMouseEvent *e) QQuickCanvas::mousePressEvent(e); } +/*! \reimp */ void QQuickView::mouseReleaseEvent(QMouseEvent *e) { QQmlProfilerService::addEvent(QQmlProfilerService::Mouse); diff --git a/src/quick/items/qquickview.h b/src/quick/items/qquickview.h index 89cca506f7..2143a80723 100644 --- a/src/quick/items/qquickview.h +++ b/src/quick/items/qquickview.h @@ -64,8 +64,8 @@ class Q_QUICK_EXPORT QQuickView : public QQuickCanvas Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true) Q_ENUMS(ResizeMode Status) public: - explicit QQuickView(QWindow *parent = 0, Qt::WindowFlags f = 0); - QQuickView(const QUrl &source, QWindow *parent = 0, Qt::WindowFlags f = 0); + explicit QQuickView(QWindow *parent = 0, Qt::WindowFlags f = Qt::Window); + QQuickView(const QUrl &source, QWindow *parent = 0, Qt::WindowFlags f = Qt::Window); virtual ~QQuickView(); QUrl source() const; diff --git a/src/quick/items/qquickwindowmanager.cpp b/src/quick/items/qquickwindowmanager.cpp index 5de8ad1279..12c5dbd932 100644 --- a/src/quick/items/qquickwindowmanager.cpp +++ b/src/quick/items/qquickwindowmanager.cpp @@ -188,7 +188,7 @@ public: void canvasDestroyed(QQuickCanvas *canvas); - void paint(QQuickCanvas *canvas); + void exposureChanged(QQuickCanvas *canvas); QImage grab(QQuickCanvas *canvas); void resize(QQuickCanvas *canvas, const QSize &size); void handleDeferredUpdate(); @@ -297,7 +297,7 @@ public: void initializeGL(); void renderCanvas(QQuickCanvas *canvas); - void paint(QQuickCanvas *canvas); + void exposureChanged(QQuickCanvas *canvas); QImage grab(QQuickCanvas *canvas); void resize(QQuickCanvas *canvas, const QSize &size); void wakeup(); @@ -333,14 +333,21 @@ QQuickWindowManager *QQuickWindowManager::instance() static QQuickWindowManager *theInstance; if (!theInstance) { - bool fancy = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL); + + theInstance = QSGContext::createWindowManager(); + + bool fancy = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::BufferQueueingOpenGL); if (qmlNoThreadedRenderer()) fancy = false; + if (qmlFixedAnimationStep()) QUnifiedTimer::instance(true)->setConsistentTiming(true); - theInstance = fancy - ? (QQuickWindowManager*) new QQuickRenderThreadSingleContextWindowManager - : (QQuickWindowManager*) new QQuickTrivialWindowManager; + + if (!theInstance) { + theInstance = fancy + ? (QQuickWindowManager*) new QQuickRenderThreadSingleContextWindowManager + : (QQuickWindowManager*) new QQuickTrivialWindowManager; + } } return theInstance; } @@ -932,26 +939,15 @@ void QQuickRenderThreadSingleContextWindowManager::animationStopped() } -void QQuickRenderThreadSingleContextWindowManager::paint(QQuickCanvas *canvas) +void QQuickRenderThreadSingleContextWindowManager::exposureChanged(QQuickCanvas *canvas) { Q_UNUSED(canvas); #ifdef THREAD_DEBUG - printf("GUI: paint called: %p\n", canvas); + printf("GUI: exposure changed: %p\n", canvas); #endif - lockInGui(); - exhaustSyncEvent(); - - isPaintCompleted = false; - while (isRunning() && !isPaintCompleted) { - if (isRenderBlocked) - wake(); - wait(); - } - unlockInGui(); - #ifdef THREAD_DEBUG - printf("GUI: paint done: %p\n", canvas); + printf("GUI: exposure changed done: %p\n", canvas); #endif } @@ -1234,13 +1230,8 @@ void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas) maybeUpdate(canvas); } -void QQuickTrivialWindowManager::paint(QQuickCanvas *canvas) +void QQuickTrivialWindowManager::exposureChanged(QQuickCanvas *canvas) { - if (!m_windows.contains(canvas)) - return; - - m_windows[canvas].updatePending = true; - renderCanvas(canvas); } QImage QQuickTrivialWindowManager::grab(QQuickCanvas *canvas) diff --git a/src/quick/items/qquickwindowmanager_p.h b/src/quick/items/qquickwindowmanager_p.h index 9372e90f5e..eb877d4756 100644 --- a/src/quick/items/qquickwindowmanager_p.h +++ b/src/quick/items/qquickwindowmanager_p.h @@ -43,13 +43,14 @@ #define QQUICKWINDOWMANAGER_P_H #include <QtGui/QImage> +#include <qtquickglobal.h> QT_BEGIN_NAMESPACE class QQuickCanvas; class QSGContext; -class QQuickWindowManager +class Q_QUICK_EXPORT QQuickWindowManager { public: virtual ~QQuickWindowManager(); @@ -59,7 +60,7 @@ public: virtual void canvasDestroyed(QQuickCanvas *canvas) = 0; - virtual void paint(QQuickCanvas *canvas) = 0; + virtual void exposureChanged(QQuickCanvas *canvas) = 0; virtual QImage grab(QQuickCanvas *canvas) = 0; virtual void resize(QQuickCanvas *canvas, const QSize &size) = 0; diff --git a/src/quick/particles/qquickimageparticle.cpp b/src/quick/particles/qquickimageparticle.cpp index 7f87dabe7d..ae1688b94d 100644 --- a/src/quick/particles/qquickimageparticle.cpp +++ b/src/quick/particles/qquickimageparticle.cpp @@ -1404,7 +1404,7 @@ void QQuickImageParticle::finishBuildParticleNodes() } if (colortable.isNull()){//###Goes through image just for this - colortable = QImage(1,1,QImage::Format_ARGB32); + colortable = QImage(1,1,QImage::Format_ARGB32_Premultiplied); colortable.fill(Qt::white); } getState<ImageMaterialData>(m_material)->colorTable = QSGPlainTexture::fromImage(colortable); diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index 92045c55f4..9608ebe861 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -243,6 +243,8 @@ void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &g for (int i = 0; i < count; ++i) { GlyphPosition glyph = glyphs.at(i); + Q_ASSERT(m_cacheData->glyphPaths.contains(glyph.glyph)); + QPainterPath path = m_cacheData->glyphPaths.value(glyph.glyph); QRectF br = path.boundingRect(); TexCoord c; diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index ffc64b6edc..02fbaa1a7f 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -109,6 +109,7 @@ public: QOpenGLContext *gl; QHash<QSGMaterialType *, QSGMaterialShader *> materials; + QMutex textureMutex; QHash<QQuickTextureFactory *, QSGTexture *> textures; QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager; @@ -118,6 +119,13 @@ public: bool distanceFieldDisabled; }; +class QSGTextureCleanupEvent : public QEvent +{ +public: + QSGTextureCleanupEvent(QSGTexture *t) : QEvent(QEvent::User), texture(t) { } + ~QSGTextureCleanupEvent() { delete texture; } + QSGTexture *texture; +}; /*! \class QSGContext @@ -146,8 +154,10 @@ QSGContext::~QSGContext() void QSGContext::invalidate() { Q_D(QSGContext); + d->textureMutex.lock(); qDeleteAll(d->textures.values()); d->textures.clear(); + d->textureMutex.unlock(); qDeleteAll(d->materials.values()); d->materials.clear(); delete d->distanceFieldCacheManager; @@ -165,6 +175,7 @@ QSGTexture *QSGContext::textureForFactory(QQuickTextureFactory *factory, QQuickC if (!factory) return 0; + d->textureMutex.lock(); QSGTexture *texture = d->textures.value(factory); if (!texture) { if (QQuickDefaultTextureFactory *dtf = qobject_cast<QQuickDefaultTextureFactory *>(factory)) @@ -172,8 +183,9 @@ QSGTexture *QSGContext::textureForFactory(QQuickTextureFactory *factory, QQuickC else texture = factory->createTexture(canvas); d->textures.insert(factory, texture); - connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *))); + connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)), Qt::DirectConnection); } + d->textureMutex.unlock(); return texture; } @@ -183,9 +195,16 @@ void QSGContext::textureFactoryDestroyed(QObject *o) Q_D(QSGContext); QQuickTextureFactory *f = static_cast<QQuickTextureFactory *>(o); - // This function will only be called on the scene graph thread, so it is - // safe to directly delete the texture here. - delete d->textures.take(f); + d->textureMutex.lock(); + QSGTexture *t = d->textures.take(f); + d->textureMutex.unlock(); + + if (t) { + if (t->thread() == thread()) + t->deleteLater(); + else + QCoreApplication::postEvent(this, new QSGTextureCleanupEvent(t)); + } } diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 0f8b5ae1de..dfb960f420 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -68,6 +68,7 @@ class QSGTexture; class QSGMaterial; class QSGMaterialShader; class QSGEngine; +class QQuickWindowManager; class QOpenGLContext; class QOpenGLFramebufferObject; @@ -122,6 +123,7 @@ public: virtual QAnimationDriver *createAnimationDriver(QObject *parent); static QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image); + static QQuickWindowManager *createWindowManager(); public slots: diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index b8a66fd0c0..bd1c4cece8 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -152,5 +152,23 @@ QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &im } +/*! + \fn QQuickWindowManager *createWindowManager() + + Calls into the scene graph adaptation if available and creates a hardware + specific window manager. + */ + +QQuickWindowManager *QSGContext::createWindowManager() +{ + QSGAdaptionPluginData *plugin = contextFactory(); + if (plugin->factory) + return plugin->factory->createWindowManager(); + return 0; +} + + + + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h index acff222fb0..2c4531c239 100644 --- a/src/quick/scenegraph/qsgcontextplugin_p.h +++ b/src/quick/scenegraph/qsgcontextplugin_p.h @@ -53,11 +53,14 @@ QT_BEGIN_NAMESPACE class QSGContext; +class QQuickWindowManager; + struct Q_QUICK_EXPORT QSGContextFactoryInterface : public QFactoryInterface { virtual QSGContext *create(const QString &key) const = 0; virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image) = 0; + virtual QQuickWindowManager *createWindowManager() = 0; }; #define QSGContextFactoryInterface_iid \ @@ -76,6 +79,7 @@ public: virtual QSGContext *create(const QString &key) const = 0; virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) { return 0; } + virtual QQuickWindowManager *createWindowManager() { return 0; } }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp index 46bd141909..76fb9036f4 100644 --- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp @@ -126,6 +126,7 @@ void QSGSharedDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs #endif m_requestedGlyphsThatHaveNotBeenReturned.unite(glyphs); + m_requestedGlyphs.unite(glyphs); QVector<quint32> glyphsVector; glyphsVector.reserve(glyphs.size()); @@ -198,6 +199,8 @@ void QSGSharedDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs m_cacheId.constData(), glyphs.size()); #endif + m_requestedGlyphs.subtract(glyphs); + QVector<quint32> glyphsVector; glyphsVector.reserve(glyphs.size()); @@ -588,19 +591,21 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsUpdated(const QByteArray &cach #endif for (int i=0; i<itemIds.size(); ++i) { - PendingGlyph &pendingGlyph = m_pendingReadyGlyphs[itemIds.at(i)]; - void *oldBuffer = pendingGlyph.buffer; - Q_ASSERT(bufferSize.height() >= pendingGlyph.bufferSize.height()); + if (m_requestedGlyphs.contains(itemIds.at(i))) { + PendingGlyph &pendingGlyph = m_pendingReadyGlyphs[itemIds.at(i)]; + void *oldBuffer = pendingGlyph.buffer; + Q_ASSERT(bufferSize.height() >= pendingGlyph.bufferSize.height()); - pendingGlyph.buffer = bufferId; - pendingGlyph.position = positions.at(i); - pendingGlyph.bufferSize = bufferSize; + pendingGlyph.buffer = bufferId; + pendingGlyph.position = positions.at(i); + pendingGlyph.bufferSize = bufferSize; - m_sharedGraphicsCache->referenceBuffer(bufferId); - if (oldBuffer != 0) - m_sharedGraphicsCache->dereferenceBuffer(oldBuffer); + m_sharedGraphicsCache->referenceBuffer(bufferId); + if (oldBuffer != 0) + m_sharedGraphicsCache->dereferenceBuffer(oldBuffer); - m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)); + m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)); + } } } @@ -616,8 +621,10 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsInvalidated(const QByteArray & if (m_cacheId != cacheId) return; - for (int i=0; i<itemIds.size(); ++i) - m_pendingInvalidatedGlyphs.insert(itemIds.at(i)); + for (int i=0; i<itemIds.size(); ++i) { + if (m_requestedGlyphs.contains(itemIds.at(i))) + m_pendingInvalidatedGlyphs.insert(itemIds.at(i)); + } } emit glyphsPending(); @@ -638,8 +645,8 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsMissing(const QByteArray &cach #endif for (int i=0; i<itemIds.size(); ++i) { - m_pendingMissingGlyphs.insert(itemIds.at(i)); - m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)); + if (m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i))) + m_pendingMissingGlyphs.insert(itemIds.at(i)); } } diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h index 3052f20813..4a91b4473a 100644 --- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h @@ -87,6 +87,7 @@ private: void saveTexture(GLuint textureId, int width, int height); QSet<quint32> m_requestedGlyphsThatHaveNotBeenReturned; + QSet<quint32> m_requestedGlyphs; QWaitCondition m_pendingGlyphsCondition; QByteArray m_cacheId; QPlatformSharedGraphicsCache *m_sharedGraphicsCache; diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index 4a1db050d6..dc85230943 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -70,6 +70,23 @@ QQuickTextureFactory::~QQuickTextureFactory() } +/*! + \fn QImage QQuickTextureFactory::image() const + + Returns an image version of this texture. + + The lifespan of the returned image is unknown, so the implementation should + return a self contained QImage, not make use of the QImage(uchar *, ...) + constructor. + + This function is not commonly used and is expected to be slow. + */ + +QImage QQuickTextureFactory::image() const +{ + return QImage(); +} + /*! \fn QSGTexture *QQuickTextureFactory::createTexture() const diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h index 153a4bab8e..2a5d146124 100644 --- a/src/quick/util/qquickimageprovider.h +++ b/src/quick/util/qquickimageprovider.h @@ -65,6 +65,7 @@ public: virtual QSGTexture *createTexture(QQuickCanvas *canvas) const = 0; virtual QSize textureSize() const = 0; virtual int textureByteCount() const = 0; + virtual QImage image() const; }; class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 350940c93c..5c73e519e1 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -93,6 +93,16 @@ QSGTexture *QQuickDefaultTextureFactory::createTexture(QQuickCanvas *) const return t; } +static QQuickTextureFactory *textureFactoryForImage(const QImage &image) +{ + if (image.isNull()) + return 0; + QQuickTextureFactory *texture = QSGContext::createTextureFactoryFromImage(image); + if (texture) + return texture; + return new QQuickDefaultTextureFactory(image); +} + class QQuickPixmapReader; class QQuickPixmapData; class QQuickPixmapReply : public QObject @@ -114,16 +124,14 @@ public: class Event : public QEvent { public: - Event(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory, const QImage &image); + Event(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory); ReadError error; QString errorString; QSize implicitSize; - QImage image; QQuickTextureFactory *textureFactory; }; - void postReply(ReadError, const QString &, const QSize &, const QImage &image); - void postReply(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory, const QImage &image); + void postReply(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory); Q_SIGNALS: @@ -218,27 +226,21 @@ public: declarativePixmaps.insert(pixmap); } - QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QImage &p, const QSize &s, const QSize &r) + QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture, const QSize &s, const QSize &r) : refCount(1), inCache(false), privatePixmap(false), pixmapStatus(QQuickPixmap::Ready), - url(u), image(p), implicitSize(s), requestSize(r), textureFactory(new QQuickDefaultTextureFactory(p)), reply(0), prevUnreferenced(0), + url(u), implicitSize(s), requestSize(r), textureFactory(texture), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), nextUnreferenced(0) { declarativePixmaps.insert(pixmap); } - QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *factory, const QImage &p, const QSize &s, const QSize &r) - : refCount(1), inCache(false), privatePixmap(false), pixmapStatus(QQuickPixmap::Ready), - url(u), image(p), implicitSize(s), requestSize(r), textureFactory(factory), reply(0), prevUnreferenced(0), - prevUnreferencedPtr(0), nextUnreferenced(0) - { - declarativePixmaps.insert(pixmap); - } - - QQuickPixmapData(QQuickPixmap *pixmap, const QImage &p) + QQuickPixmapData(QQuickPixmap *pixmap, QQuickTextureFactory *texture) : refCount(1), inCache(false), privatePixmap(true), pixmapStatus(QQuickPixmap::Ready), - image(p), implicitSize(p.size()), requestSize(p.size()), textureFactory(new QQuickDefaultTextureFactory(p)), reply(0), prevUnreferenced(0), + textureFactory(texture), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), nextUnreferenced(0) { + if (texture) + requestSize = implicitSize = texture->textureSize(); declarativePixmaps.insert(pixmap); } @@ -266,7 +268,6 @@ public: QQuickPixmap::Status pixmapStatus; QUrl url; QString errorString; - QImage image; QSize implicitSize; QSize requestSize; @@ -294,22 +295,14 @@ int QQuickPixmapReader::threadNetworkRequestDone = -1; void QQuickPixmapReply::postReply(ReadError error, const QString &errorString, - const QSize &implicitSize, const QImage &image) + const QSize &implicitSize, QQuickTextureFactory *factory) { loading = false; - QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, new QQuickDefaultTextureFactory(image), image)); + QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, factory)); } -void QQuickPixmapReply::postReply(ReadError error, const QString &errorString, - const QSize &implicitSize, QQuickTextureFactory *factory, - const QImage &image) -{ - loading = false; - QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, factory, image)); -} - -QQuickPixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, QQuickTextureFactory *factory, const QImage &i) - : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), image(i), textureFactory(factory) +QQuickPixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, QQuickTextureFactory *factory) + : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), textureFactory(factory) { } @@ -441,13 +434,8 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply) } // send completion event to the QQuickPixmapReply mutex.lock(); - if (!cancelled.contains(job)) { - QQuickTextureFactory *factory = QSGContext::createTextureFactoryFromImage(image); - if (factory) - job->postReply(error, errorString, readSize, factory, image); - else - job->postReply(error, errorString, readSize, image); - } + if (!cancelled.contains(job)) + job->postReply(error, errorString, readSize, textureFactoryForImage(image)); mutex.unlock(); } reply->deleteLater(); @@ -538,7 +526,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u QImage image; mutex.lock(); if (!cancelled.contains(runningJob)) - runningJob->postReply(errorCode, errorStr, readSize, image); + runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image)); mutex.unlock(); } else if (imageType == QQuickImageProvider::Image) { QImage image = provider->requestImage(imageId(url), &readSize, requestSize); @@ -549,14 +537,8 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString()); } mutex.lock(); - if (!cancelled.contains(runningJob)) { - QQuickTextureFactory *factory = QSGContext::createTextureFactoryFromImage(image); - if (factory) - runningJob->postReply(errorCode, errorStr, readSize, factory, image); - else - runningJob->postReply(errorCode, errorStr, readSize, image); - } - + if (!cancelled.contains(runningJob)) + runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image)); mutex.unlock(); } else { QQuickTextureFactory *t = provider->requestTexture(imageId(url), &readSize, requestSize); @@ -568,7 +550,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u } mutex.lock(); if (!cancelled.contains(runningJob)) - runningJob->postReply(errorCode, errorStr, readSize, t, QImage()); + runningJob->postReply(errorCode, errorStr, readSize, t); mutex.unlock(); } @@ -590,13 +572,8 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u errorCode = QQuickPixmapReply::Loading; } mutex.lock(); - if (!cancelled.contains(runningJob)) { - QQuickTextureFactory *factory = QSGContext::createTextureFactoryFromImage(image); - if (factory) - runningJob->postReply(errorCode, errorStr, readSize, factory, image); - else - runningJob->postReply(errorCode, errorStr, readSize, image); - } + if (!cancelled.contains(runningJob)) + runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image)); mutex.unlock(); } else { // Network resource @@ -877,10 +854,7 @@ bool QQuickPixmapReply::event(QEvent *event) data->pixmapStatus = (de->error == NoError) ? QQuickPixmap::Ready : QQuickPixmap::Error; if (data->pixmapStatus == QQuickPixmap::Ready) { - if (de->textureFactory) { - data->textureFactory = de->textureFactory; - } - data->image = de->image; + data->textureFactory = de->textureFactory; data->implicitSize = de->implicitSize; } else { data->errorString = de->errorString; @@ -902,7 +876,7 @@ int QQuickPixmapData::cost() const { if (textureFactory) return textureFactory->textureByteCount(); - return image.byteCount(); + return 0; } void QQuickPixmapData::addref() @@ -974,7 +948,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QQuickTextureFactory *texture = provider->requestTexture(imageId(url), &readSize, requestSize); if (texture) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, texture, QImage(), readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize); } } @@ -983,7 +957,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QImage image = provider->requestImage(imageId(url), &readSize, requestSize); if (!image.isNull()) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, image, readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(image), readSize, requestSize); } } case QQuickImageProvider::Pixmap: @@ -991,7 +965,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize); if (!pixmap.isNull()) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, pixmap.toImage(), readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(pixmap.toImage()), readSize, requestSize); } } } @@ -1014,7 +988,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q if (readImage(url, &f, &image, &errorString, &readSize, requestSize)) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, image, readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(image), readSize, requestSize); } errorString = QQuickPixmap::tr("Invalid image data: %1").arg(url.toString()); @@ -1126,10 +1100,10 @@ QQuickTextureFactory *QQuickPixmap::textureFactory() const return 0; } -const QImage &QQuickPixmap::image() const +QImage QQuickPixmap::image() const { - if (d) - return d->image; + if (d && d->textureFactory) + return d->textureFactory->image(); else return nullPixmap()->image; } @@ -1139,29 +1113,29 @@ void QQuickPixmap::setImage(const QImage &p) clear(); if (!p.isNull()) - d = new QQuickPixmapData(this, p); + d = new QQuickPixmapData(this, textureFactoryForImage(p)); } int QQuickPixmap::width() const { - if (d) - return d->textureFactory ? d->textureFactory->textureSize().width() : d->image.width(); + if (d && d->textureFactory) + return d->textureFactory->textureSize().width(); else return 0; } int QQuickPixmap::height() const { - if (d) - return d->textureFactory ? d->textureFactory->textureSize().height() : d->image.height(); + if (d && d->textureFactory) + return d->textureFactory->textureSize().height(); else return 0; } QRect QQuickPixmap::rect() const { - if (d) - return d->textureFactory ? QRect(QPoint(), d->textureFactory->textureSize()) : d->image.rect(); + if (d && d->textureFactory) + return QRect(QPoint(), d->textureFactory->textureSize()); else return QRect(); } diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h index ef17a12709..03f2e65cc2 100644 --- a/src/quick/util/qquickpixmapcache_p.h +++ b/src/quick/util/qquickpixmapcache_p.h @@ -104,7 +104,7 @@ public: const QUrl &url() const; const QSize &implicitSize() const; const QSize &requestSize() const; - const QImage &image() const; + QImage image() const; void setImage(const QImage &); QQuickTextureFactory *textureFactory() const; |