diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index d67b88b7182f0f40316c6610e535f48de9633cee..d2222a04585315af5076a07e9f8651128b8de554 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -2991,15 +2991,19 @@ void splitCriticalEdges(IR::Function *f, DominatorTree &df, StatementWorklist &w toBB->in[inIdx] = newBB; newBB->out.append(toBB); - BasicBlock *container = 0; - for (container = fromBB->containingGroup(); container; container = container->containingGroup()) { - if (container == toBB || container == toBB->containingGroup()) - break; + // add newBB to the correct loop group + if (toBB->isGroupStart()) { + BasicBlock *container; + for (container = fromBB->containingGroup(); container; container = container->containingGroup()) + if (container == toBB) + break; + if (container == toBB) // if we were already inside the toBB loop + newBB->setContainingGroup(toBB); + else + newBB->setContainingGroup(toBB->containingGroup()); + } else { + newBB->setContainingGroup(toBB->containingGroup()); } - if (container == 0) - container = fromBB->containingGroup(); - - newBB->setContainingGroup(container); // patch the terminator Stmt *terminator = fromBB->terminator(); diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index 59ac548fa8165b7fcbf0af5aa76c97dd4635f653..2a2ce663bc971a13bd76ce618f09a96ea2a61534 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -419,6 +419,7 @@ QQmlDebugServer::QQmlDebugServer() } } #else + Q_UNUSED(&cleanup) if (!appD->qmljsDebugArgumentsString().isEmpty()) { qWarning() << QString(QLatin1String( "QML Debugger: Ignoring \"-qmljsdebugger=%1\". " diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index cb533a0459c4f2853f8ad70b91932054fbfe2d18..088f3203d6b4f7cb333d89da923276a23b3da52b 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -96,8 +96,16 @@ QDataStream &operator>>(QDataStream &ds, QDataStream &operator<<(QDataStream &ds, const QQmlEngineDebugService::QQmlObjectProperty &data) { - ds << (int)data.type << data.name << data.value << data.valueTypeName - << data.binding << data.hasNotifySignal; + ds << (int)data.type << data.name; + // check first whether the data can be saved + // (otherwise we assert in QVariant::operator<<) + QByteArray buffer; + QDataStream fakeStream(&buffer, QIODevice::WriteOnly); + if (QMetaType::save(fakeStream, data.value.type(), data.value.constData())) + ds << data.value; + else + ds << QVariant(); + ds << data.valueTypeName << data.binding << data.hasNotifySignal; return ds; } diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index a59c3892a18f964f443e792bea00b1b353f74761..bb22e30ac1fdeb18719001a1210894dffc4befa6 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -412,25 +412,24 @@ InternalClass *InternalClass::frozen() void InternalClass::destroy() { - if (!engine) - return; - engine = 0; - - propertyTable.~PropertyHash(); - nameMap.~SharedInternalClassData<String *>(); - propertyData.~SharedInternalClassData<PropertyAttributes>(); + QList<InternalClass *> destroyStack; + destroyStack.append(this); - if (m_sealed) - m_sealed->destroy(); - - if (m_frozen) - m_frozen->destroy(); - - for (QHash<Transition, InternalClass *>::ConstIterator it = transitions.begin(), end = transitions.end(); - it != end; ++it) - it.value()->destroy(); - - transitions.clear(); + while (!destroyStack.isEmpty()) { + InternalClass *next = destroyStack.takeLast(); + if (!next->engine) + continue; + next->engine = 0; + next->propertyTable.~PropertyHash(); + next->nameMap.~SharedInternalClassData<String *>(); + next->propertyData.~SharedInternalClassData<PropertyAttributes>(); + if (next->m_sealed) + destroyStack.append(next->m_sealed); + if (next->m_frozen) + destroyStack.append(next->m_frozen); + destroyStack.append(next->transitions.values()); + next->transitions.clear(); + } } struct InternalClassPoolVisitor diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index a29b86fbeac63802c5f4c8e005c7fce0840ca953..37875170383b975a46605ac3ed98b8c8b764c2af 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -174,7 +174,7 @@ struct QQmlLocaleData : public QV4::Object private: static void destroy(Managed *that) { - static_cast<QQmlLocaleData *>(that)->~QQmlLocaleData(); + static_cast<QQmlLocaleData *>(that)->d()->~Data(); } }; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index f6c1412aff58ae43f1b2f0684e16c79f74157c01..262e227b1669678b920b8fc29241d54d05bac41a 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -893,8 +893,10 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, void QQuickWindowPrivate::clearFocusObject() { - if (activeFocusItem) - activeFocusItem->setFocus(false, Qt::OtherFocusReason); + if (activeFocusItem == contentItem) + return; + + clearFocusInScope(contentItem, QQuickItemPrivate::get(contentItem)->subFocusItem, Qt::OtherFocusReason); } void QQuickWindowPrivate::notifyFocusChangesRecur(QQuickItem **items, int remaining) @@ -1250,6 +1252,14 @@ bool QQuickWindow::isPersistentSceneGraph() const +/*! + \qmlattachedproperty Item Window::contentItem + \since 5.4 + + This attached property holds the invisible root item of the scene or + \c null if the item is not in a window. The Window attached property + can be attached to any Item. +*/ /*! \property QQuickWindow::contentItem diff --git a/src/quick/items/qquickwindowattached.cpp b/src/quick/items/qquickwindowattached.cpp index 121da9e5d9f3b3ff84e998ec90525b6403e2cf3b..f74e903be37a6116f9f54a093066f7667ef49dce 100644 --- a/src/quick/items/qquickwindowattached.cpp +++ b/src/quick/items/qquickwindowattached.cpp @@ -65,6 +65,11 @@ QQuickItem *QQuickWindowAttached::activeFocusItem() const return (m_window ? m_window->activeFocusItem() : Q_NULLPTR); } +QQuickItem *QQuickWindowAttached::contentItem() const +{ + return (m_window ? m_window->contentItem() : Q_NULLPTR); +} + void QQuickWindowAttached::windowChanged(QQuickWindow *window) { if (window != m_window) { @@ -83,6 +88,7 @@ void QQuickWindowAttached::windowChanged(QQuickWindow *window) emit activeChanged(); if (!oldWindow || window->activeFocusItem() != oldWindow->activeFocusItem()) emit activeFocusItemChanged(); + emit contentItemChanged(); // QQuickWindowQmlImpl::visibilityChanged also exists, and window might even // be QQuickWindowQmlImpl, but that's not what we are connecting to. diff --git a/src/quick/items/qquickwindowattached_p.h b/src/quick/items/qquickwindowattached_p.h index 12dd273d603139619a3811498109904873202318..7c2b0bc8734d3278979d566cd887ea061786b1e7 100644 --- a/src/quick/items/qquickwindowattached_p.h +++ b/src/quick/items/qquickwindowattached_p.h @@ -49,6 +49,7 @@ class Q_AUTOTEST_EXPORT QQuickWindowAttached : public QObject Q_PROPERTY(QWindow::Visibility visibility READ visibility NOTIFY visibilityChanged) Q_PROPERTY(bool active READ isActive NOTIFY activeChanged) Q_PROPERTY(QQuickItem* activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged) + Q_PROPERTY(QQuickItem* contentItem READ contentItem NOTIFY contentItemChanged) public: QQuickWindowAttached(QObject* attachee); @@ -56,12 +57,14 @@ public: QWindow::Visibility visibility() const; bool isActive() const; QQuickItem* activeFocusItem() const; + QQuickItem* contentItem() const; Q_SIGNALS: void visibilityChanged(); void activeChanged(); void activeFocusItemChanged(); + void contentItemChanged(); protected Q_SLOTS: void windowChanged(QQuickWindow*); diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index 80234d54f5e807469b1a9fb87b7e5f3a023609e3..83704cf0ecc278c34597e0ae333ec4ac64846394 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -174,6 +174,11 @@ void QSGDistanceFieldGlyphCache::update() storeGlyphs(distanceFields); +#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) + foreach (Texture texture, m_textures) + saveTexture(texture.textureId, texture.size.width(), texture.size.height()); +#endif + if (QSG_LOG_TIME_GLYPH().isDebugEnabled()) { quint64 now = qsg_render_timer.elapsed(); qCDebug(QSG_LOG_TIME_GLYPH, @@ -284,6 +289,163 @@ void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, con } } +#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) +#include <QtGui/qopenglfunctions.h> + +void QSGDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) const +{ + QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); + + GLuint fboId; + functions->glGenFramebuffers(1, &fboId); + + GLuint tmpTexture = 0; + functions->glGenTextures(1, &tmpTexture); + functions->glBindTexture(GL_TEXTURE_2D, tmpTexture); + functions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + functions->glBindTexture(GL_TEXTURE_2D, 0); + + functions->glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId); + functions->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, + tmpTexture, 0); + + functions->glActiveTexture(GL_TEXTURE0); + functions->glBindTexture(GL_TEXTURE_2D, textureId); + + functions->glDisable(GL_STENCIL_TEST); + functions->glDisable(GL_DEPTH_TEST); + functions->glDisable(GL_SCISSOR_TEST); + functions->glDisable(GL_BLEND); + + GLfloat textureCoordinateArray[8]; + textureCoordinateArray[0] = 0.0f; + textureCoordinateArray[1] = 0.0f; + textureCoordinateArray[2] = 1.0f; + textureCoordinateArray[3] = 0.0f; + textureCoordinateArray[4] = 1.0f; + textureCoordinateArray[5] = 1.0f; + textureCoordinateArray[6] = 0.0f; + textureCoordinateArray[7] = 1.0f; + + GLfloat vertexCoordinateArray[8]; + vertexCoordinateArray[0] = -1.0f; + vertexCoordinateArray[1] = -1.0f; + vertexCoordinateArray[2] = 1.0f; + vertexCoordinateArray[3] = -1.0f; + vertexCoordinateArray[4] = 1.0f; + vertexCoordinateArray[5] = 1.0f; + vertexCoordinateArray[6] = -1.0f; + vertexCoordinateArray[7] = 1.0f; + + functions->glViewport(0, 0, width, height); + functions->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray); + functions->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray); + + { + static const char *vertexShaderSource = + "attribute vec4 vertexCoordsArray; \n" + "attribute vec2 textureCoordArray; \n" + "varying vec2 textureCoords; \n" + "void main(void) \n" + "{ \n" + " gl_Position = vertexCoordsArray; \n" + " textureCoords = textureCoordArray; \n" + "} \n"; + + static const char *fragmentShaderSource = + "varying vec2 textureCoords; \n" + "uniform sampler2D texture; \n" + "void main() \n" + "{ \n" + " gl_FragColor = texture2D(texture, textureCoords); \n" + "} \n"; + + GLuint vertexShader = functions->glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = functions->glCreateShader(GL_FRAGMENT_SHADER); + + if (vertexShader == 0 || fragmentShader == 0) { + GLenum error = functions->glGetError(); + qWarning("QSGDistanceFieldGlyphCache::saveTexture: Failed to create shaders. (GL error: %x)", + error); + return; + } + + functions->glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); + functions->glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); + functions->glCompileShader(vertexShader); + + GLint len = 1; + functions->glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len); + + char infoLog[2048]; + functions->glGetShaderInfoLog(vertexShader, 2048, NULL, infoLog); + if (qstrlen(infoLog) > 0) + qWarning("Problems compiling vertex shader:\n %s", infoLog); + + functions->glCompileShader(fragmentShader); + functions->glGetShaderInfoLog(fragmentShader, 2048, NULL, infoLog); + if (qstrlen(infoLog) > 0) + qWarning("Problems compiling fragment shader:\n %s", infoLog); + + GLuint shaderProgram = functions->glCreateProgram(); + functions->glAttachShader(shaderProgram, vertexShader); + functions->glAttachShader(shaderProgram, fragmentShader); + + functions->glBindAttribLocation(shaderProgram, 0, "vertexCoordsArray"); + functions->glBindAttribLocation(shaderProgram, 1, "textureCoordArray"); + + functions->glLinkProgram(shaderProgram); + functions->glGetProgramInfoLog(shaderProgram, 2048, NULL, infoLog); + if (qstrlen(infoLog) > 0) + qWarning("Problems linking shaders:\n %s", infoLog); + + functions->glUseProgram(shaderProgram); + functions->glEnableVertexAttribArray(0); + functions->glEnableVertexAttribArray(1); + + int textureUniformLocation = functions->glGetUniformLocation(shaderProgram, "texture"); + functions->glUniform1i(textureUniformLocation, 0); + } + + functions->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + { + GLenum error = functions->glGetError(); + if (error != GL_NO_ERROR) + qWarning("glDrawArrays reported error 0x%x", error); + } + + uchar *data = new uchar[width * height * 4]; + + functions->glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + + QImage image(data, width, height, QImage::Format_ARGB32); + + QByteArray fileName = m_referenceFont.familyName().toLatin1() + '_' + QByteArray::number(textureId); + fileName = fileName.replace('/', '_').replace(' ', '_') + ".png"; + + image.save(QString::fromLocal8Bit(fileName)); + + { + GLenum error = functions->glGetError(); + if (error != GL_NO_ERROR) + qWarning("glReadPixels reported error 0x%x", error); + } + + functions->glDisableVertexAttribArray(0); + functions->glDisableVertexAttribArray(1); + + functions->glDeleteFramebuffers(1, &fboId); + functions->glDeleteTextures(1, &tmpTexture); + + delete[] data; +} +#endif + void QSGNodeVisitorEx::visitChildren(QSGNode *node) { for (QSGNode *child = node->firstChild(); child; child = child->nextSibling()) { diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index a63299fcde25f8a693784bc498273a58ea684e22..962fc5a98a1715b1d8c50d30e495ee1eb74b8c91 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -357,6 +357,10 @@ protected: GlyphData &glyphData(glyph_t glyph); +#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) + void saveTexture(GLuint textureId, int width, int height) const; +#endif + inline bool isCoreProfile() const { return m_coreProfile; } private: diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index b5bdbde3ad85cf766daaacea114cc03cbca36c39..90102f1110976b2a5256946e354daf98430ad6c8 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -161,6 +161,7 @@ public: , m_time(0) , m_vsync(0) , m_mode(VSyncMode) + , m_lag(0) , m_bad(0) , m_good(0) { diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp index 6f54b258ff8f484ff9a9fe9eea4fac168d48839b..f635ccd17b774a580678eb478f70fd1113cc4a9a 100644 --- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp @@ -399,176 +399,6 @@ void QSGSharedDistanceFieldGlyphCache::unregisterOwnerElement(QQuickItem *ownerE } } -#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG_) -# include <QtOpenGL/private/qglextensions_p.h> - -void QSGSharedDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) -{ - GLuint fboId; - glGenFramebuffers(1, &fboId); - - GLuint tmpTexture = 0; - glGenTextures(1, &tmpTexture); - glBindTexture(GL_TEXTURE_2D, tmpTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - - glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId); - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, - tmpTexture, 0); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - - GLfloat textureCoordinateArray[8]; - textureCoordinateArray[0] = 0.0f; - textureCoordinateArray[1] = 0.0f; - textureCoordinateArray[2] = 1.0f; - textureCoordinateArray[3] = 0.0f; - textureCoordinateArray[4] = 1.0f; - textureCoordinateArray[5] = 1.0f; - textureCoordinateArray[6] = 0.0f; - textureCoordinateArray[7] = 1.0f; - - GLfloat vertexCoordinateArray[8]; - vertexCoordinateArray[0] = -1.0f; - vertexCoordinateArray[1] = -1.0f; - vertexCoordinateArray[2] = 1.0f; - vertexCoordinateArray[3] = -1.0f; - vertexCoordinateArray[4] = 1.0f; - vertexCoordinateArray[5] = 1.0f; - vertexCoordinateArray[6] = -1.0f; - vertexCoordinateArray[7] = 1.0f; - - glViewport(0, 0, width, height); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray); - - { - static const char vertexShaderSource[] = - "attribute highp vec4 vertexCoordsArray; \n" - "attribute highp vec2 textureCoordArray; \n" - "varying highp vec2 textureCoords; \n" - "void main(void) \n" - "{ \n" - " gl_Position = vertexCoordsArray; \n" - " textureCoords = textureCoordArray; \n" - "} \n"; - - static const char fragmentShaderSource[] = - "varying highp vec2 textureCoords; \n" - "uniform sampler2D texture; \n" - "void main() \n" - "{ \n" - " gl_FragColor = texture2D(texture, textureCoords); \n" - "} \n"; - - GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - - if (vertexShader == 0 || fragmentShader == 0) { - GLenum error = glGetError(); - qWarning("SharedGraphicsCacheServer::setupShaderPrograms: Failed to create shaders. (GL error: %x)", - error); - return; - } - - glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); - glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); - glCompileShader(vertexShader); - - GLint len = 1; - glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len); - - char infoLog[2048]; - glGetShaderInfoLog(vertexShader, 2048, NULL, infoLog); - if (qstrlen(infoLog) > 0) { - qWarning("SharedGraphicsCacheServer::setupShaderPrograms, problems compiling vertex shader:\n %s", - infoLog); - //return; - } - - glCompileShader(fragmentShader); - glGetShaderInfoLog(fragmentShader, 2048, NULL, infoLog); - if (qstrlen(infoLog) > 0) { - qWarning("SharedGraphicsCacheServer::setupShaderPrograms, problems compiling fragent shader:\n %s", - infoLog); - //return; - } - - GLuint shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - - glBindAttribLocation(shaderProgram, 0, "vertexCoordsArray"); - glBindAttribLocation(shaderProgram, 1, "textureCoordArray"); - - glLinkProgram(shaderProgram); - glGetProgramInfoLog(shaderProgram, 2048, NULL, infoLog); - if (qstrlen(infoLog) > 0) { - qWarning("SharedGraphicsCacheServer::setupShaderPrograms, problems linking shaders:\n %s", - infoLog); - //return; - } - - glUseProgram(shaderProgram); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - - int textureUniformLocation = glGetUniformLocation(shaderProgram, "_qt_texture"); - glUniform1i(textureUniformLocation, 0); - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - qWarning("SharedGraphicsCacheServer::readBackBuffer: glDrawArrays reported error 0x%x", - error); - } - } - - uchar *data = new uchar[width * height * 4]; - - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); - - QImage image(width, height, QImage::Format_ARGB32); - quint32 *dest = reinterpret_cast<quint32 *>(image.bits()); - for (int i=0; i<width*height; ++i) - dest[i] = qRgba(0xff, 0xff, 0xff, data[i]); - - QByteArray fileName = m_cacheId + ' ' + QByteArray::number(textureId); - fileName = fileName.replace('/', '_').replace(' ', '_') + ".png"; - image.save(QString::fromLocal8Bit(fileName)); - - { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - qWarning("SharedGraphicsCacheServer::readBackBuffer: glReadPixels reported error 0x%x", - error); - } - } - - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - - glDeleteFramebuffers(1, &fboId); - glDeleteTextures(1, &tmpTexture); - - delete[] data; -} -#endif - namespace { struct TextureContent { QSize size; @@ -683,9 +513,6 @@ void QSGSharedDistanceFieldGlyphCache::processPendingGlyphs() texture.textureId = m_sharedGraphicsCache->textureIdForBuffer(it.key()); texture.size = m_sharedGraphicsCache->sizeOfBuffer(it.key()); -#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG_) - saveTexture(texture.textureId, texture.size.width(), texture.size.height()); -#endif setGlyphsTexture(it.value().glyphs, texture); ++it; diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index bcb523f90d3ac0a2c2c102a06be7e8f5c7840377..480ac5e569c8a6f69bde7b8ced908a77e0032d03 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -1,6 +1,7 @@ !contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL # DEFINES += QSG_SEPARATE_INDEX_BUFFER +# DEFINES += QSG_DISTANCEFIELD_CACHE_DEBUG # Core API HEADERS += \ diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index 5bbbe8e1e9c30abd38baa048d4b7f2b1b0d6e758..7c931928d4c714422fb93d20863f87ef9bda2ff0 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -36,6 +36,7 @@ #include <QHostAddress> #include <QDebug> #include <QThread> +#include <QModelIndex> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcontext.h> @@ -73,6 +74,16 @@ signals: }; QML_DECLARE_TYPE(NonScriptProperty) +class CustomTypes : public QObject +{ + Q_OBJECT + Q_PROPERTY(QModelIndex modelIndex READ modelIndex) +public: + CustomTypes(QObject *parent = 0) : QObject(parent) {} + + QModelIndex modelIndex() { return QModelIndex(); } +}; + class tst_QQmlEngineDebugService : public QObject { Q_OBJECT @@ -125,6 +136,7 @@ private slots: void setBindingInStates(); void regression_QTCREATORBUG_7451(); + void queryObjectWithNonStreamableTypes(); }; QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject( @@ -314,6 +326,12 @@ void tst_QQmlEngineDebugService::initTestCase() "}\n" ; + // test non-streamable properties + qmlRegisterType<CustomTypes>("Backend", 1, 0, "CustomTypes"); + qml << "import Backend 1.0\n" + "CustomTypes {}" + ; + for (int i=0; i<qml.count(); i++) { QQmlComponent component(m_engine); component.setData(qml[i], QUrl::fromLocalFile("")); @@ -620,7 +638,7 @@ void tst_QQmlEngineDebugService::queryRootContexts() // root context query sends only root object data - it doesn't fill in // the children or property info QCOMPARE(context.objects.count(), 0); - QCOMPARE(context.contexts.count(), 5); + QCOMPARE(context.contexts.count(), 6); QVERIFY(context.contexts[0].debugId >= 0); QCOMPARE(context.contexts[0].name, QString("tst_QQmlDebug_childContext")); } @@ -819,6 +837,26 @@ void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451() } } +void tst_QQmlEngineDebugService::queryObjectWithNonStreamableTypes() +{ + bool success; + + QmlDebugObjectReference rootObject = findRootObject(4, true); + + QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0); + unconnected->queryObject(rootObject, &success); + QVERIFY(!success); + delete unconnected; + + m_dbg->queryObject(rootObject, &success); + QVERIFY(success); + QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); + + QmlDebugObjectReference obj = m_dbg->object(); + + QCOMPARE(findProperty(obj.properties, "modelIndex").value, QVariant()); +} + void tst_QQmlEngineDebugService::queryExpressionResult() { diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp index 921c81ae89ae7a8432f2fc13205b5aae97fc73b1..f6d5d16605ec43564458d6cc3077012d058aae0f 100644 --- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp +++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp @@ -383,8 +383,6 @@ void tst_QQuickAccessible::checkableTest() QScopedPointer<QQuickView> window(new QQuickView()); window->setSource(testFileUrl("checkbuttons.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); QQuickItem *contentItem = window->contentItem(); QVERIFY(contentItem); @@ -462,8 +460,6 @@ void tst_QQuickAccessible::ignoredTest() QScopedPointer<QQuickView> window(new QQuickView()); window->setSource(testFileUrl("ignored.qml")); window->show(); - window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window.data())); QQuickItem *contentItem = window->contentItem(); QVERIFY(contentItem); diff --git a/tests/auto/quick/qquickwindow/data/windowattached.qml b/tests/auto/quick/qquickwindow/data/windowattached.qml index e000d5c6fd137630785ffcea8730936f4b2e1bdc..0e3f1d4b62245bb1a7c87f338f1c982bae497795 100644 --- a/tests/auto/quick/qquickwindow/data/windowattached.qml +++ b/tests/auto/quick/qquickwindow/data/windowattached.qml @@ -6,6 +6,7 @@ Rectangle { width: 100 height: 100 property bool windowActive: root.Window.active + property Item contentItem: root.Window.contentItem Text { objectName: "rectangleWindowText" anchors.centerIn: parent @@ -20,6 +21,7 @@ Rectangle { objectName: "extraWindowText" anchors.centerIn: parent text: (extraWindow.active ? "active" : "inactive") + "\nvisibility: " + Window.visibility + property Item contentItem: Window.contentItem } } } diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 5bd7492d701a453ba9436dbe97eef7cc5635b5c4..a25ed9bf9c9b7ec3e760293b4d2f0f5226508417 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -341,6 +341,7 @@ private slots: void testWindowVisibilityOrder(); void blockClosing(); + void blockCloseMethod(); void crashWhenHoverItemDeleted(); @@ -1739,6 +1740,25 @@ void tst_qquickwindow::blockClosing() QTRY_VERIFY(!window->isVisible()); } +void tst_qquickwindow::blockCloseMethod() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("ucantclosethis.qml")); + QQuickWindow *window = qobject_cast<QQuickWindow *>(component.create()); + QVERIFY(window); + window->show(); + QTest::qWaitForWindowExposed(window); + QVERIFY(window->isVisible()); + QVERIFY(QMetaObject::invokeMethod(window, "close", Qt::DirectConnection)); + QVERIFY(window->isVisible()); + QVERIFY(QMetaObject::invokeMethod(window, "close", Qt::DirectConnection)); + QVERIFY(window->isVisible()); + window->setProperty("canCloseThis", true); + QVERIFY(QMetaObject::invokeMethod(window, "close", Qt::DirectConnection)); + QTRY_VERIFY(!window->isVisible()); +} + void tst_qquickwindow::crashWhenHoverItemDeleted() { // QTBUG-32771 @@ -1952,6 +1972,7 @@ void tst_qquickwindow::attachedProperty() view.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&view)); QVERIFY(view.rootObject()->property("windowActive").toBool()); + QCOMPARE(view.rootObject()->property("contentItem").value<QQuickItem*>(), view.contentItem()); QQuickWindow *innerWindow = view.rootObject()->findChild<QQuickWindow*>("extraWindow"); QVERIFY(innerWindow); @@ -1961,6 +1982,7 @@ void tst_qquickwindow::attachedProperty() QQuickText *text = view.rootObject()->findChild<QQuickText*>("extraWindowText"); QVERIFY(text); QCOMPARE(text->text(), QLatin1String("active\nvisibility: 2")); + QCOMPARE(text->property("contentItem").value<QQuickItem*>(), innerWindow->contentItem()); } class RenderJob : public QRunnable diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index bc339ae3e5e14bea503f44fb73696ad52d566e7b..2a86b724f490015fd16c13f8a429c871b45bac5b 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -405,6 +405,9 @@ int main(int argc, char ** argv) } } + // QtWebEngine needs a shared context in order for the GPU thread to + // upload textures. + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, options.contextSharing); #ifdef QT_WIDGETS_LIB QApplication app(argc, argv); #else @@ -443,15 +446,6 @@ int main(int argc, char ** argv) displayFileDialog(&options); #endif - // QWebEngine needs a shared context in order for the GPU thread to - // upload textures. - QScopedPointer<QOpenGLContext> shareContext; - if (options.contextSharing) { - shareContext.reset(new QOpenGLContext); - shareContext->create(); - qt_gl_set_global_share_context(shareContext.data()); - } - int exitCode = 0; if (!options.file.isEmpty()) {