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/qsgsoftwarerenderablenode.cpp5
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp239
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h121
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp171
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h34
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h82
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp1
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h8
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h4
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp6
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp4
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer.cpp2
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer_p.h44
-rw-r--r--src/quick/scenegraph/qsgdefaultspritenode.cpp6
-rw-r--r--src/quick/scenegraph/scenegraph.pri3
-rw-r--r--src/quick/scenegraph/util/qsgengine.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader.cpp49
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader_p.h18
21 files changed, 583 insertions, 222 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
index bd2946c675..7fb531cca3 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
@@ -218,8 +218,9 @@ void QSGSoftwareRenderableNode::update()
m_boundingRectMin = QRect();
m_boundingRectMax = QRect();
} else {
- m_boundingRectMin = m_boundingRectMin.intersected(m_clipRegion.rects().constFirst());
- m_boundingRectMax = m_boundingRectMax.intersected(m_clipRegion.rects().constFirst());
+ const auto rects = m_clipRegion.begin();
+ m_boundingRectMin = m_boundingRectMin.intersected(rects[0]);
+ m_boundingRectMax = m_boundingRectMax.intersected(rects[0]);
}
}
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
new file mode 100644
index 0000000000..6d51ed9d61
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** 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 "qsgcompressedtexture_p.h"
+#include <QOpenGLContext>
+#include <QOpenGLTexture>
+#include <QOpenGLFunctions>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO, "qt.scenegraph.textureio");
+
+bool QSGCompressedTextureData::isValid() const
+{
+ if (data.isNull() || size.isEmpty() || !format)
+ return false;
+ if (dataLength < 0 || dataOffset < 0 || dataOffset >= data.length())
+ return false;
+ if (dataLength > 0 && qint64(dataOffset) + qint64(dataLength) > qint64(data.length()))
+ return false;
+
+ return true;
+}
+
+int QSGCompressedTextureData::sizeInBytes() const
+{
+ if (!isValid())
+ return 0;
+ return dataLength > 0 ? dataLength : data.length() - dataOffset;
+}
+
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QSGCompressedTextureData *d)
+{
+ QDebugStateSaver saver(dbg);
+
+ dbg.nospace() << "QSGCompressedTextureData(";
+ if (d) {
+ dbg << d->logName << ' ';
+ dbg << static_cast<QOpenGLTexture::TextureFormat>(d->format)
+ << "[0x" << hex << d->format << dec << "]";
+ dbg.space() << (d->hasAlpha ? "with" : "no") << "alpha" << d->size
+ << "databuffer" << d->data.size() << "offset" << d->dataOffset << "length";
+ dbg.nospace() << d->dataLength << ")";
+ } else {
+ dbg << "null)";
+ }
+ return dbg;
+}
+
+QSGCompressedTexture::QSGCompressedTexture(const DataPtr& texData)
+ : m_textureData(texData)
+{
+ if (m_textureData) {
+ m_size = m_textureData->size;
+ m_hasAlpha = m_textureData->hasAlpha;
+ }
+}
+
+QSGCompressedTexture::~QSGCompressedTexture()
+{
+#if QT_CONFIG(opengl)
+ if (m_textureId) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return;
+
+ funcs->glDeleteTextures(1, &m_textureId);
+ }
+#endif
+}
+
+int QSGCompressedTexture::textureId() const
+{
+#if QT_CONFIG(opengl)
+ if (!m_textureId) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return 0;
+
+ funcs->glGenTextures(1, &m_textureId);
+ }
+#endif
+ return m_textureId;
+}
+
+QSize QSGCompressedTexture::textureSize() const
+{
+ return m_size;
+}
+
+bool QSGCompressedTexture::hasAlphaChannel() const
+{
+ return m_hasAlpha;
+}
+
+bool QSGCompressedTexture::hasMipmaps() const
+{
+ return false;
+}
+
+void QSGCompressedTexture::bind()
+{
+#if QT_CONFIG(opengl)
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return;
+
+ if (!textureId())
+ return;
+
+ funcs->glBindTexture(GL_TEXTURE_2D, m_textureId);
+
+ if (m_uploaded)
+ return;
+
+ QByteArray logName(m_textureData ? m_textureData->logName : QByteArrayLiteral("(unset)"));
+
+ if (!m_textureData || !m_textureData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid texture data for %s", logName.constData());
+ funcs->glBindTexture(GL_TEXTURE_2D, 0);
+ return;
+ }
+
+ if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) {
+ qCDebug(QSG_LOG_TEXTUREIO) << "Uploading texture" << m_textureData.data();
+ while (funcs->glGetError() != GL_NO_ERROR);
+ }
+
+ funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_textureData->format,
+ m_size.width(), m_size.height(), 0, m_textureData->sizeInBytes(),
+ m_textureData->data.constData() + m_textureData->dataOffset);
+
+ if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) {
+ GLuint error = funcs->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCDebug(QSG_LOG_TEXTUREIO, "glCompressedTexImage2D failed for %s, error 0x%x", logName.constData(), error);
+ }
+ }
+
+ m_textureData.clear(); // Release this memory, not needed anymore
+
+ updateBindOptions(true);
+ m_uploaded = true;
+#endif // QT_CONFIG(opengl)
+}
+
+bool QSGCompressedTexture::formatIsOpaque(quint32 glTextureFormat)
+{
+ switch (glTextureFormat) {
+ case QOpenGLTexture::RGB_DXT1:
+ case QOpenGLTexture::R_ATI1N_UNorm:
+ case QOpenGLTexture::R_ATI1N_SNorm:
+ case QOpenGLTexture::RG_ATI2N_UNorm:
+ case QOpenGLTexture::RG_ATI2N_SNorm:
+ case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
+ case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ case QOpenGLTexture::RGB8_ETC1:
+ case QOpenGLTexture::SRGB_DXT1:
+ return true;
+ break;
+ default:
+ return false;
+ }
+}
+
+QSGCompressedTextureFactory::QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr &texData)
+ : m_textureData(texData)
+{
+}
+
+QSGTexture *QSGCompressedTextureFactory::createTexture(QQuickWindow *) const
+{
+ if (!m_textureData || !m_textureData->isValid())
+ return nullptr;
+
+ return new QSGCompressedTexture(m_textureData);
+}
+
+int QSGCompressedTextureFactory::textureByteCount() const
+{
+ return m_textureData ? m_textureData->sizeInBytes() : 0;
+}
+
+
+QSize QSGCompressedTextureFactory::textureSize() const
+{
+ if (m_textureData && m_textureData->isValid())
+ return m_textureData->size;
+ return QSize();
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
new file mode 100644
index 0000000000..dfedac5558
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** 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 QSGCOMPRESSEDTEXTURE_P_H
+#define QSGCOMPRESSEDTEXTURE_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.
+//
+
+#include <QSGTexture>
+#include <QtQuick/private/qsgcontext_p.h>
+#include <QQuickTextureFactory>
+#include <QOpenGLFunctions>
+
+QT_BEGIN_NAMESPACE
+
+struct Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureData
+{
+ QByteArray logName;
+ QByteArray data;
+ QSize size;
+ uint format = 0;
+ int dataOffset = 0;
+ int dataLength = 0;
+ bool hasAlpha = false;
+
+ bool isValid() const;
+ int sizeInBytes() const;
+};
+
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug, const QSGCompressedTextureData *);
+
+
+class Q_QUICK_PRIVATE_EXPORT QSGCompressedTexture : public QSGTexture
+{
+ Q_OBJECT
+public:
+ typedef QSharedPointer<QSGCompressedTextureData> DataPtr;
+
+ QSGCompressedTexture(const DataPtr& texData);
+ virtual ~QSGCompressedTexture();
+
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+
+ void bind() override;
+
+ const QSGCompressedTextureData *textureData();
+
+ static bool formatIsOpaque(quint32 glTextureFormat);
+
+protected:
+ DataPtr m_textureData;
+ QSize m_size;
+ mutable uint m_textureId = 0;
+ bool m_hasAlpha = false;
+ bool m_uploaded = false;
+};
+
+
+class Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureFactory : public QQuickTextureFactory
+{
+public:
+ QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr& texData);
+ QSGTexture *createTexture(QQuickWindow *) const override;
+ int textureByteCount() const override;
+ QSize textureSize() const override;
+
+protected:
+ QSGCompressedTexture::DataPtr m_textureData;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGCOMPRESSEDTEXTURE_P_H
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
index 62066a136a..daec23d478 100644
--- a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
@@ -38,173 +38,82 @@
****************************************************************************/
#include "qsgpkmhandler_p.h"
+#include "qsgcompressedtexture_p.h"
#include <QFile>
#include <QDebug>
#include <qendian.h>
#include <qopenglfunctions.h>
#include <qqmlfile.h>
+#include <QOpenGLTexture>
//#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
+ QOpenGLTexture::RGB8_ETC1, // GL_ETC1_RGB8_OES,
+ QOpenGLTexture::RGB8_ETC2, // GL_COMPRESSED_RGB8_ETC2,
+ 0, // unused (obsolete)
+ QOpenGLTexture::RGBA8_ETC2_EAC, // GL_COMPRESSED_RGBA8_ETC2_EAC,
+ QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2 // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
};
-QEtcTexture::QEtcTexture()
- : m_texture_id(0), m_uploaded(false)
-{
- initializeOpenGLFunctions();
-}
-
-QEtcTexture::~QEtcTexture()
-{
- if (m_texture_id)
- glDeleteTextures(1, &m_texture_id);
-}
-
-int QEtcTexture::textureId() const
-{
- if (m_texture_id == 0) {
- QEtcTexture *texture = const_cast<QEtcTexture*>(this);
- texture->glGenTextures(1, &texture->m_texture_id);
- }
- return m_texture_id;
-}
-
-bool QEtcTexture::hasAlphaChannel() const
-{
- return m_type == GL_COMPRESSED_RGBA8_ETC2_EAC ||
- m_type == GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
-}
-
-
-void QEtcTexture::bind()
+bool QSGPkmHandler::canRead(const QByteArray &suffix, const QByteArray &block)
{
- 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
+ Q_UNUSED(suffix)
-#ifndef QT_NO_DEBUG
- while (glGetError() != GL_NO_ERROR) { }
-#endif
-
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- Q_ASSERT(ctx != 0);
- const int compFactor = m_type == GL_COMPRESSED_RGBA8_ETC2_EAC ? 1 : 2;
- ctx->functions()->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_type,
- m_size.width(), m_size.height(), 0,
- (m_paddedSize.width() * m_paddedSize.height()) / compFactor,
- 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);
+ return block.startsWith("PKM ");
}
-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 {
- QEtcTexture *texture = new QEtcTexture;
- 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)
+QQuickTextureFactory *QSGPkmHandler::read()
{
- QScopedPointer<QEtcTextureFactory> ret(new QEtcTextureFactory);
- ret->m_data = device->readAll();
- if (ret->m_data.isEmpty() || ret->m_data.size() < headerSize)
+ if (!device())
return nullptr;
- const char *rawData = ret->m_data.constData();
+ QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create());
- // magic number
- if (qstrncmp(rawData, "PKM ", 4) != 0)
+ texData->data = device()->readAll();
+ if (texData->data.size() < headerSize || !canRead(QByteArray(), texData->data)) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid PKM file %s", logName().constData());
return nullptr;
+ }
+
+ const char *rawData = texData->data.constData();
- // currently ignore version (rawData + 4)
+ // ignore version (rawData + 4 & 5)
// texture type
quint16 type = qFromBigEndian<quint16>(rawData + 6);
- static int typeCount = sizeof(typeMap)/sizeof(typeMap[0]);
- if (type >= typeCount)
+ if (type > sizeof(typeMap)/sizeof(typeMap[0])) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Unknown compression format in PKM file %s", logName().constData());
return nullptr;
- ret->m_type = typeMap[type];
+ }
+ texData->format = typeMap[type];
+ texData->hasAlpha = !QSGCompressedTexture::formatIsOpaque(texData->format);
// 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())
+ /* Actual data length depends on format; for now just use 0, i.e. rest-of-file
+ QSize paddedSize(qFromBigEndian<quint16>(rawData + 8), qFromBigEndian<quint16>(rawData + 10));
+ texData->dataLength = (paddedSize.width() / 4) * (paddedSize.height() / 4) * 8;
+ */
+ QSize texSize(qFromBigEndian<quint16>(rawData + 12), qFromBigEndian<quint16>(rawData + 14));
+ texData->size = texSize;
+
+ texData->dataOffset = headerSize;
+
+ if (!texData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid values in header of PKM file %s", logName().constData());
return nullptr;
+ }
+ texData->logName = logName();
#ifdef ETC_DEBUG
- qDebug() << "requestTexture returning: " << ret->m_data.length() << "bytes; width: " << ret->m_size.width() << ", height: " << ret->m_size.height();
+ qDebug() << "PKM file handler read" << texData.data();
#endif
-
- return ret.take();
+ return new QSGCompressedTextureFactory(texData);
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
index eb6b2e46c0..6154c51b84 100644
--- a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
@@ -51,42 +51,18 @@
// We mean it.
//
-#include <QOpenGLFunctions>
-#include <QQuickImageProvider>
-#include <QtQuick/QSGTexture>
-#include <QUrl>
+#include "qsgtexturefilehandler_p.h"
QT_BEGIN_NAMESPACE
-class QSGPkmHandler
+class QSGPkmHandler : public QSGTextureFileHandler
{
public:
- QSGPkmHandler() {}
+ using QSGTextureFileHandler::QSGTextureFileHandler;
- QQuickTextureFactory *read(QIODevice *device);
-};
-
-class QEtcTexture : public QSGTexture, protected QOpenGLFunctions
-{
- Q_OBJECT
-public:
- QEtcTexture();
- ~QEtcTexture();
-
- void bind();
-
- QSize textureSize() const { return m_size; }
- int textureId() const;
-
- bool hasAlphaChannel() const;
- bool hasMipmaps() const { return false; }
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
- QByteArray m_data;
- QSize m_size;
- QSize m_paddedSize;
- GLuint m_texture_id;
- GLenum m_type;
- bool m_uploaded;
+ QQuickTextureFactory *read() override;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h
new file mode 100644
index 0000000000..43358b2846
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h
@@ -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$
+**
+****************************************************************************/
+
+#ifndef QSGTEXTUREFILEHANDLER_P_H
+#define QSGTEXTUREFILEHANDLER_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.
+//
+
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO)
+
+class QQuickTextureFactory;
+
+class QSGTextureFileHandler
+{
+public:
+ QSGTextureFileHandler(QIODevice *device, const QByteArray &logName = QByteArray())
+ : m_device(device)
+ {
+ m_logName = !logName.isEmpty() ? logName : QByteArrayLiteral("(unknown)");
+ }
+
+ virtual QQuickTextureFactory *read() = 0;
+ QIODevice *device() const { return m_device; }
+ QByteArray logName() const { return m_logName; }
+
+private:
+ QIODevice *m_device = nullptr;
+ QByteArray m_logName;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGTEXTUREFILEHANDLER_P_H
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
index eb9e7cea7c..304dc008d5 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
@@ -90,7 +90,7 @@ Q_SIGNALS:
void sceneGraphChanged();
protected:
- explicit QSGAbstractRenderer(QObject *parent = Q_NULLPTR);
+ explicit QSGAbstractRenderer(QObject *parent = nullptr);
virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) = 0;
private:
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 067e9fc762..7531ae7604 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -55,6 +55,7 @@
#include <QtGui/QOpenGLFunctions_1_0>
#include <QtGui/QOpenGLFunctions_3_2_Core>
+#include <private/qnumeric_p.h>
#include <private/qquickprofiler_p.h>
#include "qsgmaterialshader_p.h"
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index b0a14d23b9..5c39242029 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -627,9 +627,9 @@ public:
};
protected:
- void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE;
- void render() Q_DECL_OVERRIDE;
- void releaseCachedResources() Q_DECL_OVERRIDE;
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
+ void render() override;
+ void releaseCachedResources() override;
private:
enum ClipTypeBit
@@ -698,7 +698,7 @@ private:
void visualizeOverdraw();
void visualizeOverdraw_helper(Node *node);
void visualizeDrawGeometry(const QSGGeometry *g);
- void setCustomRenderMode(const QByteArray &mode) Q_DECL_OVERRIDE;
+ void setCustomRenderMode(const QByteArray &mode) override;
QSGDefaultRenderContext *m_context;
QSet<Node *> m_taggedRoots;
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index 1467f2233d..f2708b2b96 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -151,7 +151,7 @@ public:
QT_DEPRECATED void clearDirty() { }
void markDirty(DirtyState bits);
- QT_DEPRECATED DirtyState dirtyState() const { return Q_NULLPTR; }
+ QT_DEPRECATED DirtyState dirtyState() const { return nullptr; }
virtual bool isSubtreeBlocked() const;
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index 1cb4c56316..b890728fd8 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -86,8 +86,8 @@ public:
bool isMirrored() const;
void renderScene(const QSGBindable &bindable);
- virtual void renderScene(uint fboId = 0) Q_DECL_OVERRIDE;
- virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE;
+ void renderScene(uint fboId = 0) override;
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
QSGNodeUpdater *nodeUpdater() const;
void setNodeUpdater(QSGNodeUpdater *updater);
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index d460794573..fb66a6ebb1 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -143,7 +143,7 @@ public:
qCDebug(QSG_LOG_INFO, "Animation Driver: using walltime");
}
- void start() Q_DECL_OVERRIDE
+ void start() override
{
m_time = 0;
m_timer.start();
@@ -151,14 +151,14 @@ public:
QAnimationDriver::start();
}
- qint64 elapsed() const Q_DECL_OVERRIDE
+ qint64 elapsed() const override
{
return m_mode == VSyncMode
? qint64(m_time)
: qint64(m_time) + m_wallTime.elapsed();
}
- void advance() Q_DECL_OVERRIDE
+ void advance() override
{
qint64 delta = m_timer.restart();
diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index 5914b42809..02d4b79b76 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -90,7 +90,7 @@ public:
explicit QSGContextPlugin(QObject *parent = 0);
virtual ~QSGContextPlugin();
- virtual QStringList keys() const override = 0;
+ QStringList keys() const override = 0;
QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) override { return 0; }
QSGRenderLoop *createWindowManager() override { return 0; }
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index edb6e92a0d..0169f097bc 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -301,7 +301,7 @@ public:
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/32bitcolortext.frag"));
}
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) Q_DECL_OVERRIDE;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
};
void QSG32BitColorTextShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -310,7 +310,7 @@ void QSG32BitColorTextShader::updateState(const RenderState &state, QSGMaterial
QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
- if (oldMaterial == Q_NULLPTR || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
+ if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
float opacity = material->color().w() * state.opacity();
program()->setUniformValue(m_color_id, opacity);
}
diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp
index 86d74acf54..cd9c4a9a90 100644
--- a/src/quick/scenegraph/qsgdefaultlayer.cpp
+++ b/src/quick/scenegraph/qsgdefaultlayer.cpp
@@ -60,7 +60,7 @@ namespace
public:
BindableFbo(QOpenGLFramebufferObject *fbo, QSGDepthStencilBuffer *depthStencil);
virtual ~BindableFbo();
- void bind() const Q_DECL_OVERRIDE;
+ void bind() const override;
private:
QOpenGLFramebufferObject *m_fbo;
QSGDepthStencilBuffer *m_depthStencil;
diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h
index 7b09293095..06355e0c21 100644
--- a/src/quick/scenegraph/qsgdefaultlayer_p.h
+++ b/src/quick/scenegraph/qsgdefaultlayer_p.h
@@ -69,56 +69,56 @@ public:
QSGDefaultLayer(QSGRenderContext *context);
~QSGDefaultLayer();
- bool updateTexture() Q_DECL_OVERRIDE;
+ bool updateTexture() override;
// The item's "paint node", not effect node.
QSGNode *item() const { return m_item; }
- void setItem(QSGNode *item) Q_DECL_OVERRIDE;
+ void setItem(QSGNode *item) override;
QRectF rect() const { return m_rect; }
- void setRect(const QRectF &rect) Q_DECL_OVERRIDE;
+ void setRect(const QRectF &rect) override;
QSize size() const { return m_size; }
- void setSize(const QSize &size) Q_DECL_OVERRIDE;
+ void setSize(const QSize &size) override;
- void setHasMipmaps(bool mipmap) Q_DECL_OVERRIDE;
+ void setHasMipmaps(bool mipmap) override;
- void bind() Q_DECL_OVERRIDE;
+ void bind() override;
- bool hasAlphaChannel() const Q_DECL_OVERRIDE;
- bool hasMipmaps() const Q_DECL_OVERRIDE;
- int textureId() const Q_DECL_OVERRIDE;
- QSize textureSize() const Q_DECL_OVERRIDE { return m_size; }
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+ int textureId() const override;
+ QSize textureSize() const override { return m_size; }
GLenum format() const { return m_format; }
- void setFormat(GLenum format) Q_DECL_OVERRIDE;
+ void setFormat(GLenum format) override;
bool live() const { return bool(m_live); }
- void setLive(bool live) Q_DECL_OVERRIDE;
+ void setLive(bool live) override;
bool recursive() const { return bool(m_recursive); }
- void setRecursive(bool recursive) Q_DECL_OVERRIDE;
+ void setRecursive(bool recursive) override;
- void setDevicePixelRatio(qreal ratio) Q_DECL_OVERRIDE { m_device_pixel_ratio = ratio; }
+ void setDevicePixelRatio(qreal ratio) override { m_device_pixel_ratio = ratio; }
bool mirrorHorizontal() const { return bool(m_mirrorHorizontal); }
- void setMirrorHorizontal(bool mirror) Q_DECL_OVERRIDE;
+ void setMirrorHorizontal(bool mirror) override;
bool mirrorVertical() const { return bool(m_mirrorVertical); }
- void setMirrorVertical(bool mirror) Q_DECL_OVERRIDE;
+ void setMirrorVertical(bool mirror) override;
- void scheduleUpdate() Q_DECL_OVERRIDE;
+ void scheduleUpdate() override;
- QImage toImage() const Q_DECL_OVERRIDE;
+ QImage toImage() const override;
- QRectF normalizedTextureSubRect() const Q_DECL_OVERRIDE;
+ QRectF normalizedTextureSubRect() const override;
int samples() const { return m_samples; }
- void setSamples(int samples) Q_DECL_OVERRIDE { m_samples = samples; }
+ void setSamples(int samples) override { m_samples = samples; }
public Q_SLOTS:
- void markDirtyTexture() Q_DECL_OVERRIDE;
- void invalidated() Q_DECL_OVERRIDE;
+ void markDirtyTexture() override;
+ void invalidated() override;
private:
void grab();
diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp
index 5eb8fb6e08..7fe6048d59 100644
--- a/src/quick/scenegraph/qsgdefaultspritenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp
@@ -109,7 +109,7 @@ public:
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.frag"));
}
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) Q_DECL_OVERRIDE
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) override
{
QQuickSpriteMaterial *m = static_cast<QQuickSpriteMaterial *>(newEffect);
m->texture->bind();
@@ -122,14 +122,14 @@ public:
program()->setUniformValue(m_matrix_id, state.combinedMatrix());
}
- void initialize() Q_DECL_OVERRIDE {
+ void initialize() override {
m_matrix_id = program()->uniformLocation("qt_Matrix");
m_opacity_id = program()->uniformLocation("qt_Opacity");
m_animData_id = program()->uniformLocation("animData");
m_animPos_id = program()->uniformLocation("animPos");
}
- char const *const *attributeNames() const Q_DECL_OVERRIDE {
+ char const *const *attributeNames() const override {
static const char *attr[] = {
"vPos",
"vTex",
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index b5c72f521c..377a4647da 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -230,8 +230,11 @@ SOURCES += \
qtConfig(opengl(es1|es2)?) {
HEADERS += \
+ $$PWD/compressedtexture/qsgcompressedtexture_p.h \
+ $$PWD/compressedtexture/qsgtexturefilehandler_p.h \
$$PWD/compressedtexture/qsgpkmhandler_p.h
SOURCES += \
+ $$PWD/compressedtexture/qsgcompressedtexture.cpp \
$$PWD/compressedtexture/qsgpkmhandler.cpp
}
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
index 3c8b61852e..514e6e8c2b 100644
--- a/src/quick/scenegraph/util/qsgengine.h
+++ b/src/quick/scenegraph/util/qsgengine.h
@@ -67,7 +67,7 @@ public:
};
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
- explicit QSGEngine(QObject *parent = Q_NULLPTR);
+ explicit QSGEngine(QObject *parent = nullptr);
~QSGEngine();
void initialize(QOpenGLContext *context);
diff --git a/src/quick/scenegraph/util/qsgtexturereader.cpp b/src/quick/scenegraph/util/qsgtexturereader.cpp
index 61729ada18..cf4edf29b8 100644
--- a/src/quick/scenegraph/util/qsgtexturereader.cpp
+++ b/src/quick/scenegraph/util/qsgtexturereader.cpp
@@ -45,38 +45,55 @@
#include <private/qsgpkmhandler_p.h>
#endif
+#include <QFileInfo>
+
QT_BEGIN_NAMESPACE
-QSGTextureReader::QSGTextureReader()
+QSGTextureReader::QSGTextureReader(QIODevice *device, const QString &fileName)
+ : m_device(device), m_fileInfo(fileName)
{
-
}
-QQuickTextureFactory *QSGTextureReader::read(QIODevice *device, const QByteArray &format)
+QQuickTextureFactory *QSGTextureReader::read()
{
#if QT_CONFIG(opengl)
- if (format == QByteArrayLiteral("pkm")) {
- QSGPkmHandler handler;
- return handler.read(device);
- }
+ if (!isTexture())
+ return nullptr;
+ return m_handler->read();
#else
- Q_UNUSED(device)
- Q_UNUSED(format)
-#endif
return nullptr;
+#endif
}
-bool QSGTextureReader::isTexture(QIODevice *device, const QByteArray &format)
+bool QSGTextureReader::isTexture()
{
#if QT_CONFIG(opengl)
- if (format == QByteArrayLiteral("pkm")) {
- return device->peek(4) == QByteArrayLiteral("PKM ");
+ if (!checked) {
+ checked = true;
+ if (!init())
+ return false;
+
+ QByteArray headerBlock = m_device->peek(64);
+ QByteArray suffix = m_fileInfo.suffix().toLower().toLatin1();
+ QByteArray logName = m_fileInfo.fileName().toUtf8();
+
+ // Currently the handlers are hardcoded; later maybe a list of plugins
+ if (QSGPkmHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QSGPkmHandler(m_device, logName);
+ }
+ // else if OtherHandler::canRead() ...etc.
}
+ return (m_handler != nullptr);
#else
- Q_UNUSED(device)
- Q_UNUSED(format)
-#endif
return false;
+#endif
+}
+
+bool QSGTextureReader::init()
+{
+ if (!m_device)
+ return false;
+ return m_device->isReadable();
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgtexturereader_p.h b/src/quick/scenegraph/util/qsgtexturereader_p.h
index 7d2fc314a6..8251e4c696 100644
--- a/src/quick/scenegraph/util/qsgtexturereader_p.h
+++ b/src/quick/scenegraph/util/qsgtexturereader_p.h
@@ -52,19 +52,31 @@
//
#include <QString>
+#include <QFileInfo>
QT_BEGIN_NAMESPACE
class QIODevice;
class QQuickTextureFactory;
+class QSGTextureFileHandler;
class QSGTextureReader
{
public:
- QSGTextureReader();
+ QSGTextureReader(QIODevice *device, const QString &fileName = QString());
- static QQuickTextureFactory *read(QIODevice *device, const QByteArray &format);
- static bool isTexture(QIODevice *device, const QByteArray &format);
+ QQuickTextureFactory *read();
+ bool isTexture();
+
+ // TBD access function to params
+ // TBD ask for identified fmt
+
+private:
+ bool init();
+ QIODevice *m_device = nullptr;
+ QFileInfo m_fileInfo;
+ QSGTextureFileHandler *m_handler = nullptr;
+ bool checked = false;
};
QT_END_NAMESPACE