aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp4
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp209
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h94
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp7
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp1
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp30
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp12
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp1
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp10
-rw-r--r--src/quick/scenegraph/scenegraph.pri15
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp7
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture_p.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader.cpp82
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader_p.h72
18 files changed, 538 insertions, 15 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
index 4937565aa9..666f1d0616 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp
@@ -83,7 +83,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *)
bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
{
// Make sure to translate the clip rect into world coordinates
- if (m_clipState.count() == 1) {
+ if (m_clipState.count() == 0 || m_clipState.top().isNull()) {
m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect())));
m_hasClip = true;
} else {
@@ -97,7 +97,7 @@ bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node)
void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *)
{
m_clipState.pop();
- if (m_clipState.count() == 1)
+ if (m_clipState.count() == 0 || m_clipState.top().isNull())
m_hasClip = false;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index 962db20cbc..3f0d1383b9 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -149,6 +149,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose)
emit window->afterAnimating();
cd->syncSceneGraph();
+ rc->endSync();
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index d2186e7cf1..832b69d0cc 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -330,6 +330,7 @@ bool QSGSoftwareRenderThread::event(QEvent *e)
softwareRenderer->setBackingStore(backingStore);
rc->initialize(nullptr);
wd->syncSceneGraph();
+ rc->endSync();
wd->renderSceneGraph(wme->window->size());
*wme->image = backingStore->handle()->toImage();
}
@@ -443,6 +444,7 @@ void QSGSoftwareRenderThread::sync(bool inExpose)
rc->initialize(nullptr);
wd->syncSceneGraph();
+ rc->endSync();
if (!hadRenderer && wd->renderer) {
qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - created renderer");
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
new file mode 100644
index 0000000000..1b8882e9a5
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgpkmhandler_p.h"
+
+#include <QFile>
+#include <QDebug>
+#include <qendian.h>
+#include <qopenglfunctions.h>
+#include <qqmlfile.h>
+
+//#define ETC_DEBUG
+
+#ifndef GL_ETC1_RGB8_OES
+ #define GL_ETC1_RGB8_OES 0x8d64
+#endif
+
+#ifndef GL_COMPRESSED_RGB8_ETC2
+ #define GL_COMPRESSED_RGB8_ETC2 0x9274
+#endif
+
+#ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+ #define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#endif
+
+#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
+ #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static const int headerSize = 16;
+
+static unsigned int typeMap[5] = {
+ GL_ETC1_RGB8_OES,
+ GL_COMPRESSED_RGB8_ETC2,
+ 0, // unused
+ GL_COMPRESSED_RGBA8_ETC2_EAC,
+ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+};
+
+EtcTexture::EtcTexture()
+ : m_texture_id(0), m_uploaded(false)
+{
+ initializeOpenGLFunctions();
+}
+
+EtcTexture::~EtcTexture()
+{
+ if (m_texture_id)
+ glDeleteTextures(1, &m_texture_id);
+}
+
+int EtcTexture::textureId() const
+{
+ if (m_texture_id == 0) {
+ EtcTexture *texture = const_cast<EtcTexture*>(this);
+ texture->glGenTextures(1, &texture->m_texture_id);
+ }
+ return m_texture_id;
+}
+
+bool EtcTexture::hasAlphaChannel() const
+{
+ return m_type == GL_COMPRESSED_RGBA8_ETC2_EAC ||
+ m_type == GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+}
+
+
+void EtcTexture::bind()
+{
+ if (m_uploaded && m_texture_id) {
+ glBindTexture(GL_TEXTURE_2D, m_texture_id);
+ return;
+ }
+
+ if (m_texture_id == 0)
+ glGenTextures(1, &m_texture_id);
+ glBindTexture(GL_TEXTURE_2D, m_texture_id);
+
+#ifdef ETC_DEBUG
+ qDebug() << "glCompressedTexImage2D, width: " << m_size.width() << "height" << m_size.height() <<
+ "paddedWidth: " << m_paddedSize.width() << "paddedHeight: " << m_paddedSize.height();
+#endif
+
+#ifndef QT_NO_DEBUG
+ while (glGetError() != GL_NO_ERROR) { }
+#endif
+
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ Q_ASSERT(ctx != 0);
+ ctx->functions()->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_type,
+ m_size.width(), m_size.height(), 0,
+ (m_paddedSize.width() * m_paddedSize.height()) / 2,
+ m_data.data() + headerSize);
+
+#ifndef QT_NO_DEBUG
+ // Gracefully fail in case of an error...
+ GLuint error = glGetError();
+ if (error != GL_NO_ERROR) {
+ qDebug () << "glCompressedTexImage2D for compressed texture failed, error: " << error;
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &m_texture_id);
+ m_texture_id = 0;
+ return;
+ }
+#endif
+
+ m_uploaded = true;
+ updateBindOptions(true);
+}
+
+class QEtcTextureFactory : public QQuickTextureFactory
+{
+public:
+ QByteArray m_data;
+ QSize m_size;
+ QSize m_paddedSize;
+ unsigned int m_type;
+
+ QSize textureSize() const { return m_size; }
+ int textureByteCount() const { return m_data.size(); }
+
+ QSGTexture *createTexture(QQuickWindow *) const {
+ EtcTexture *texture = new EtcTexture;
+ texture->m_data = m_data;
+ texture->m_size = m_size;
+ texture->m_paddedSize = m_paddedSize;
+ texture->m_type = m_type;
+ return texture;
+ }
+};
+
+QQuickTextureFactory *QSGPkmHandler::read(QIODevice *device)
+{
+ QScopedPointer<QEtcTextureFactory> ret(new QEtcTextureFactory);
+ ret->m_data = device->readAll();
+ if (ret->m_data.isEmpty() || ret->m_data.size() < headerSize)
+ return nullptr;
+
+ const char *rawData = ret->m_data.constData();
+
+ // magic number
+ if (qstrncmp(rawData, "PKM ", 4) != 0)
+ return nullptr;
+
+ // currently ignore version (rawData + 4)
+
+ // texture type
+ quint16 type = qFromBigEndian<quint16>(rawData + 6);
+ static int typeCount = sizeof(typeMap)/sizeof(typeMap[0]);
+ if (type >= typeCount)
+ return nullptr;
+ ret->m_type = typeMap[type];
+
+ // texture size
+ ret->m_paddedSize.setWidth(qFromBigEndian<quint16>(rawData + 8));
+ ret->m_paddedSize.setHeight(qFromBigEndian<quint16>(rawData + 10));
+ if ((ret->m_paddedSize.width() * ret->m_paddedSize.height()) / 2 > ret->m_data.size() - headerSize)
+ return nullptr;
+ ret->m_size.setWidth(qFromBigEndian<quint16>(rawData + 12));
+ ret->m_size.setHeight(qFromBigEndian<quint16>(rawData + 14));
+ if (ret->m_size.isEmpty())
+ return nullptr;
+
+#ifdef ETC_DEBUG
+ qDebug() << "requestTexture returning: " << ret->m_data.length() << "bytes; width: " << ret->m_size.width() << ", height: " << ret->m_size.height();
+#endif
+
+ return ret.take();
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
new file mode 100644
index 0000000000..77097cb80a
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGPKMHANDLER_H
+#define QSGPKMHANDLER_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.
+//
+
+#include <QOpenGLFunctions>
+#include <QQuickImageProvider>
+#include <QtQuick/QSGTexture>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+
+class QSGPkmHandler
+{
+public:
+ QSGPkmHandler() {}
+
+ QQuickTextureFactory *read(QIODevice *device);
+};
+
+class EtcTexture : public QSGTexture, protected QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ EtcTexture();
+ ~EtcTexture();
+
+ void bind();
+
+ QSize textureSize() const { return m_size; }
+ int textureId() const;
+
+ bool hasAlphaChannel() const;
+ bool hasMipmaps() const { return false; }
+
+ QByteArray m_data;
+ QSize m_size;
+ QSize m_paddedSize;
+ GLuint m_texture_id;
+ GLenum m_type;
+ bool m_uploaded;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGPKMHANDLER_H
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 78f2c86f6c..edee29584c 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -969,9 +969,10 @@ bool Renderer::changeBatchRoot(Node *node, Node *root)
void Renderer::nodeChangedBatchRoot(Node *node, Node *root)
{
if (node->type() == QSGNode::ClipNodeType || node->isBatchRoot) {
- if (!changeBatchRoot(node, root))
- return;
- node = root;
+ // When we reach a batchroot, we only need to update it. Its subtree
+ // is relative to that root, so no need to recurse further.
+ changeBatchRoot(node, root);
+ return;
} else if (node->type() == QSGNode::GeometryNodeType) {
// Only need to change the root as nodeChanged anyway flags a full update.
Element *e = node->element();
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index e400928d4e..264b30b897 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -1582,6 +1582,7 @@ QDebug operator<<(QDebug d, const QSGRootNode *n)
d << "RootNode(null)";
return d;
}
+ QDebugStateSaver saver(d);
d << "RootNode" << hex << (const void *) n << (n->isSubtreeBlocked() ? "*BLOCKED*" : "");
#ifdef QSG_RUNTIME_DESCRIPTION
d << QSGNodePrivate::description(n);
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 6ff8f4a76e..84a2523f26 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -194,7 +194,7 @@ protected:
QMutex m_mutex;
QHash<QQuickTextureFactory *, QSGTexture *> m_textures;
QSet<QSGTexture *> m_texturesToDelete;
- QHash<QRawFont, QSGDistanceFieldGlyphCache*> m_glyphCaches;
+ QHash<QString, QSGDistanceFieldGlyphCache *> m_glyphCaches;
QSet<QFontEngine *> m_fontEnginesToClean;
};
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 29600ef0ca..95f3555994 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -271,6 +271,26 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri
}
}
+QString QSGDefaultRenderContext::fontKey(const QRawFont &font)
+{
+ QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
+ if (!fe->faceId().filename.isEmpty()) {
+ QByteArray keyName = fe->faceId().filename;
+ if (font.style() != QFont::StyleNormal)
+ keyName += QByteArray(" I");
+ if (font.weight() != QFont::Normal)
+ keyName += ' ' + QByteArray::number(font.weight());
+ keyName += QByteArray(" DF");
+ return QString::fromUtf8(keyName);
+ } else {
+ return QString::fromLatin1("%1_%2_%3_%4")
+ .arg(font.familyName())
+ .arg(font.styleName())
+ .arg(font.weight())
+ .arg(font.style());
+ }
+}
+
void QSGDefaultRenderContext::initializeShader(QSGMaterialShader *shader)
{
shader->program()->bind();
@@ -288,18 +308,18 @@ QSGDefaultRenderContext *QSGDefaultRenderContext::from(QOpenGLContext *context)
return qobject_cast<QSGDefaultRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>());
}
-QT_END_NAMESPACE
-
-
QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font)
{
- QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(font, 0);
+ QString key = fontKey(font);
+ QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
if (!cache) {
cache = new QSGDefaultDistanceFieldGlyphCache(openglContext(), font);
- m_glyphCaches.insert(font, cache);
+ m_glyphCaches.insert(key, cache);
}
return cache;
}
+QT_END_NAMESPACE
+
#include "moc_qsgdefaultrendercontext_p.cpp"
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 0aed46b658..2537a06988 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -96,6 +96,8 @@ public:
int maxTextureSize() const override { return m_maxTextureSize; }
protected:
+ static QString fontKey(const QRawFont &font);
+
QOpenGLContext *m_gl;
QSGDepthStencilBufferManager *m_depthStencilManager;
int m_maxTextureSize;
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index c11b698a03..4a69b770ed 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -380,6 +380,16 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
bool alsoSwap = data.updatePending;
data.updatePending = false;
+ bool lastDirtyWindow = true;
+ auto i = m_windows.constBegin();
+ while (i != m_windows.constEnd()) {
+ if (i.value().updatePending) {
+ lastDirtyWindow = false;
+ break;
+ }
+ i++;
+ }
+
if (!current)
return;
@@ -407,6 +417,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
emit window->afterAnimating();
cd->syncSceneGraph();
+ if (lastDirtyWindow)
+ rc->endSync();
if (profileFrames)
syncTime = renderTimer.nsecsElapsed();
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 7d77e52b5f..1e5e61e43b 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -425,6 +425,7 @@ bool QSGRenderThread::event(QEvent *e)
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync scene graph";
QQuickWindowPrivate *d = QQuickWindowPrivate::get(ce->window);
d->syncSceneGraph();
+ sgrc->endSync();
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering scene graph";
QQuickWindowPrivate::get(ce->window)->renderSceneGraph(ce->window->size());
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index e16f7ea966..e10e52d95e 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -445,6 +445,14 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
}
}
+ bool lastDirtyWindow = true;
+ for (int i=0; i<m_windows.size(); ++i) {
+ if ( m_windows[i].pendingUpdate) {
+ lastDirtyWindow = false;
+ break;
+ }
+ }
+
d->flushFrameSynchronousEvents();
// Event delivery or processing has caused the window to stop rendering.
if (!windowData(window))
@@ -464,6 +472,8 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
RLDEBUG(" - syncing");
d->syncSceneGraph();
+ if (lastDirtyWindow)
+ m_rc->endSync();
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced,
QQuickProfiler::SceneGraphRenderLoopSync);
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index c6db3df158..b5c72f521c 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -220,3 +220,18 @@ qtConfig(opengl(es1|es2)?) {
$$PWD/shaders/visualization.frag \
$$PWD/shaders/visualization.vert
}
+
+# Compressed Texture API
+HEADERS += \
+ $$PWD/util/qsgtexturereader_p.h
+
+SOURCES += \
+ $$PWD/util/qsgtexturereader.cpp
+
+qtConfig(opengl(es1|es2)?) {
+ HEADERS += \
+ $$PWD/compressedtexture/qsgpkmhandler_p.h
+
+ SOURCES += \
+ $$PWD/compressedtexture/qsgpkmhandler.cpp
+}
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 22f0b13f46..d5f836a525 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -116,7 +116,7 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
Texture *t = 0;
if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) {
if (!m_atlas)
- m_atlas = new Atlas(m_atlas_size);
+ m_atlas = new Atlas(m_atlas_size, this);
// t may be null for atlas allocation failure
t = m_atlas->create(image);
if (t && !hasAlphaChannel && t->hasAlphaChannel())
@@ -125,8 +125,9 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
return t;
}
-Atlas::Atlas(const QSize &size)
- : m_allocator(size)
+Atlas::Atlas(const QSize &size, QObject *parent)
+ : QObject(parent)
+ , m_allocator(size)
, m_texture_id(0)
, m_size(size)
, m_atlas_transient_image_threshold(0)
diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h
index 3dee539547..0bb07e8e89 100644
--- a/src/quick/scenegraph/util/qsgatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgatlastexture_p.h
@@ -88,7 +88,7 @@ private:
class Atlas : public QObject
{
public:
- Atlas(const QSize &size);
+ Atlas(const QSize &size, QObject *parent);
~Atlas();
void invalidate();
diff --git a/src/quick/scenegraph/util/qsgtexturereader.cpp b/src/quick/scenegraph/util/qsgtexturereader.cpp
new file mode 100644
index 0000000000..61729ada18
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgtexturereader.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgtexturereader_p.h"
+
+#include <private/qtquickglobal_p.h>
+
+#if QT_CONFIG(opengl)
+#include <private/qsgpkmhandler_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QSGTextureReader::QSGTextureReader()
+{
+
+}
+
+QQuickTextureFactory *QSGTextureReader::read(QIODevice *device, const QByteArray &format)
+{
+#if QT_CONFIG(opengl)
+ if (format == QByteArrayLiteral("pkm")) {
+ QSGPkmHandler handler;
+ return handler.read(device);
+ }
+#else
+ Q_UNUSED(device)
+ Q_UNUSED(format)
+#endif
+ return nullptr;
+}
+
+bool QSGTextureReader::isTexture(QIODevice *device, const QByteArray &format)
+{
+#if QT_CONFIG(opengl)
+ if (format == QByteArrayLiteral("pkm")) {
+ return device->peek(4) == QByteArrayLiteral("PKM ");
+ }
+#else
+ Q_UNUSED(device)
+ Q_UNUSED(format)
+#endif
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgtexturereader_p.h b/src/quick/scenegraph/util/qsgtexturereader_p.h
new file mode 100644
index 0000000000..7d2fc314a6
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgtexturereader_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGTEXTUREREADER_H
+#define QSGTEXTUREREADER_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.
+//
+
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+class QQuickTextureFactory;
+
+class QSGTextureReader
+{
+public:
+ QSGTextureReader();
+
+ static QQuickTextureFactory *read(QIODevice *device, const QByteArray &format);
+ static bool isTexture(QIODevice *device, const QByteArray &format);
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGTEXTUREREADER_H