diff options
Diffstat (limited to 'src/quick/scenegraph')
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 |