diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-06-04 21:32:01 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-06-08 09:55:53 +0200 |
commit | 3f5e21a0cc9f41f1747e5c431695e7798ee489db (patch) | |
tree | ccd9f02554d16f68fb66a8f2dd59368dd1a43c30 | |
parent | c8dd51333f14941d9a5c2d3798768df342aa48d4 (diff) |
Remove OpenGL dependency from QSGTexture
The QSGTexture API is now clean, the OpenGL-specific functions are
removed.
Docs are to be updated in a separate patch.
QSGPlainTexture, and a number of texture related places have to follow
suit.
The OpenGL atlas texture implementation is now removed.
Task-number: QTBUG-84717
Task-number: QTBUG-84623
Change-Id: I1aab3b8b9145bb74ad39ef836ce540fc851292c5
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
32 files changed, 27 insertions, 1552 deletions
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index 89ae3c7fe8..c1362e5bb6 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -399,7 +399,6 @@ qt_extend_target(Quick CONDITION QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT scenegraph/util/qsgdefaultpainternode.cpp scenegraph/util/qsgdefaultpainternode_p.h scenegraph/util/qsgdefaultrectanglenode.cpp scenegraph/util/qsgdefaultrectanglenode_p.h scenegraph/util/qsgdepthstencilbuffer.cpp scenegraph/util/qsgdepthstencilbuffer_p.h - scenegraph/util/qsgopenglatlastexture.cpp scenegraph/util/qsgopenglatlastexture_p.h scenegraph/util/qsgrhiatlastexture.cpp scenegraph/util/qsgrhiatlastexture_p.h scenegraph/util/qsgshadersourcebuilder.cpp scenegraph/util/qsgshadersourcebuilder_p.h ) diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index 1cf3891488..96af4008df 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -463,11 +463,13 @@ QSGTexture *QQuickContext2DFBOTexture::textureForNextFrame(QSGTexture *lastTextu if (m_dirtyTexture) { if (!m_gl) { // on a rendering thread, use the fbo directly... - texture->setTextureId(m_fbo->texture()); + // ### glpurge + //texture->setTextureId(m_fbo->texture()); } else { // on GUI or custom thread, use display textures... m_displayTexture = m_displayTexture == 0 ? 1 : 0; - texture->setTextureId(m_displayTextures[m_displayTexture]); + // ### glpurge + //texture->setTextureId(m_displayTextures[m_displayTexture]); } texture->setTextureSize(m_fbo->size()); m_dirtyTexture = false; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index e86bd02335..7cdfde44de 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -4846,59 +4846,6 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image, CreateText return d->context->createTexture(image, flags); } - -#if QT_DEPRECATED_SINCE(5, 15) -/*! - Creates a new QSGTexture object from an existing OpenGL texture \a id and \a size. - - The caller of the function is responsible for deleting the returned texture. - - The returned texture will be using \c GL_TEXTURE_2D as texture target and - assumes that internal format is \c {GL_RGBA}. Reimplement QSGTexture to - create textures with different parameters. - - Use \a options to customize the texture attributes. The TextureUsesAtlas - option is ignored. - - \warning This function will return null if the scenegraph has not yet been - initialized or OpenGL is not in use. - - \note This function only has an effect when using the default OpenGL scene graph - adaptation. - - \note This function has no effect when running on the RHI graphics - abstraction. Use createTextureFromNativeObject() instead. - - \obsolete - - \sa sceneGraphInitialized(), QSGTexture - */ -QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, CreateTextureOptions options) const -{ -#if QT_CONFIG(opengl) - Q_D(const QQuickWindow); - if (!d->rhi) { - if (openglContext()) { - QSGPlainTexture *texture = new QSGPlainTexture(); - texture->setTextureId(id); - texture->setHasAlphaChannel(options & TextureHasAlphaChannel); - texture->setOwnsTexture(options & TextureOwnsGLTexture); - texture->setTextureSize(size); - return texture; - } - } else { - qWarning("createTextureFromId() must not be called when running on the RHI. " - "Use createTextureFromNativeObject() instead."); - } -#else - Q_UNUSED(id) - Q_UNUSED(size) - Q_UNUSED(options) -#endif - return nullptr; -} -#endif - /*! \enum QQuickWindow::NativeObjectType \since 5.14 @@ -4972,13 +4919,6 @@ QSGTexture *QQuickWindow::createTextureFromNativeObject(NativeObjectType type, texture->setOwnsTexture(true); // texture meaning the QRhiTexture here, not the native object texture->setTextureSize(size); return texture; - } else if (openglContext()) { - QSGPlainTexture *texture = new QSGPlainTexture; - texture->setTextureId(uint(nativeObjectHandle)); - texture->setHasAlphaChannel(options & TextureHasAlphaChannel); - texture->setOwnsTexture(options & TextureOwnsGLTexture); - texture->setTextureSize(size); - return texture; } #else Q_UNUSED(nativeObjectHandle); diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index ed24d01c05..5266debec5 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -155,11 +155,6 @@ public: QSGTexture *createTextureFromImage(const QImage &image) const; QSGTexture *createTextureFromImage(const QImage &image, CreateTextureOptions options) const; -#if QT_DEPRECATED_SINCE(5, 15) - QT_DEPRECATED_X("Use createTextureFromNativeObject() instead") - QSGTexture *createTextureFromId(uint id, const QSize &size, CreateTextureOptions options = CreateTextureOption()) const; -#endif - QSGTexture *createTextureFromNativeObject(NativeObjectType type, quint64 nativeObjectHandle, int nativeLayout, diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp index 0d599209b7..35d84a2d7e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -65,11 +65,6 @@ QSGSoftwareLayer::~QSGSoftwareLayer() invalidated(); } -int QSGSoftwareLayer::textureId() const -{ - return 0; -} - qint64 QSGSoftwareLayer::comparisonKey() const { return 0; @@ -90,10 +85,6 @@ bool QSGSoftwareLayer::hasMipmaps() const return false; } -void QSGSoftwareLayer::bind() -{ -} - bool QSGSoftwareLayer::updateTexture() { bool doGrab = (m_live || m_grab) && m_dirtyTexture; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h index c1b5686d0a..387e6e9eb8 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h @@ -71,11 +71,9 @@ public: // QSGTexture interface public: qint64 comparisonKey() const override; - int textureId() const override; QSize textureSize() const override; bool hasAlphaChannel() const override; bool hasMipmaps() const override; - void bind() override; // QSGDynamicTexture interface public: diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp index 0812290def..16bccb073e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp @@ -60,11 +60,6 @@ QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QPixmap &pixmap) { } -int QSGSoftwarePixmapTexture::textureId() const -{ - return 0; -} - QSize QSGSoftwarePixmapTexture::textureSize() const { return m_pixmap.size(); @@ -80,11 +75,6 @@ bool QSGSoftwarePixmapTexture::hasMipmaps() const return false; } -void QSGSoftwarePixmapTexture::bind() -{ - Q_UNREACHABLE(); -} - qint64 QSGSoftwarePixmapTexture::comparisonKey() const { return 0; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h index 801d33c091..96473f280c 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h @@ -65,11 +65,9 @@ public: QSGSoftwarePixmapTexture(const QPixmap &pixmap); qint64 comparisonKey() const override; - int textureId() const override; QSize textureSize() const override; bool hasAlphaChannel() const override; bool hasMipmaps() const override; - void bind() override; const QPixmap &pixmap() const { return m_pixmap; } diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp index c7176875d6..bfb0023527 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp @@ -39,9 +39,7 @@ #include "qsgcompressedtexture_p.h" -#include <QOpenGLContext> #include <QOpenGLTexture> -#include <QOpenGLFunctions> #include <QDebug> #include <QtQuick/private/qquickwindow_p.h> #include <QtQuick/private/qquickitem_p.h> @@ -61,41 +59,11 @@ QSGCompressedTexture::QSGCompressedTexture(const QTextureFileData &texData) 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 - delete m_texture; } -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; -} - qint64 QSGCompressedTexture::comparisonKey() const { - // not textureId() as that would create an id when not yet done - that's not wanted here - if (m_textureId) - return m_textureId; - if (m_texture) return qint64(m_texture); @@ -118,51 +86,6 @@ 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; - - if (!m_textureData.isValid()) { - qCDebug(QSG_LOG_TEXTUREIO, "Invalid texture data for %s", m_textureData.logName().constData()); - funcs->glBindTexture(GL_TEXTURE_2D, 0); - return; - } - - if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) { - qCDebug(QSG_LOG_TEXTUREIO) << "Uploading texture" << m_textureData; - while (funcs->glGetError() != GL_NO_ERROR); - } - - funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_textureData.glInternalFormat(), - m_size.width(), m_size.height(), 0, m_textureData.dataLength(), - 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", m_textureData.logName().constData(), error); - } - } - - m_textureData = QTextureFileData(); // Release this memory, not needed anymore - - updateBindOptions(true); - m_uploaded = true; -#endif // QT_CONFIG(opengl) -} - QSGCompressedTexture::FormatInfo QSGCompressedTexture::formatInfo(quint32 glTextureFormat) { switch (glTextureFormat) { diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h index 228f8dd7b7..cf62c4f893 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h @@ -74,8 +74,6 @@ public: bool hasMipmaps() const override; qint64 comparisonKey() const override; - int textureId() const override; - void bind() override; QRhiTexture *rhiTexture() const override; void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override; @@ -92,7 +90,6 @@ public: protected: QTextureFileData m_textureData; QSize m_size; - mutable uint m_textureId = 0; QRhiTexture *m_texture = nullptr; bool m_hasAlpha = false; bool m_uploaded = false; diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp index b90dff910d..eecd0fe44d 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.cpp +++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp @@ -38,10 +38,6 @@ ****************************************************************************/ #include "qsgtexture_p.h" -#if QT_CONFIG(opengl) -# include <qopenglcontext.h> -# include <qopenglfunctions.h> -#endif #include <private/qqmlglobal_p.h> #include <private/qsgmaterialshader_p.h> #include <QtGui/private/qrhi_p.h> @@ -64,6 +60,8 @@ #endif #ifndef QT_NO_DEBUG +Q_GLOBAL_STATIC(QSet<QSGTexture *>, qsg_valid_texture_set) +Q_GLOBAL_STATIC(QMutex, qsg_valid_texture_mutex) static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK"); #endif @@ -103,16 +101,6 @@ QSGSamplerDescription QSGSamplerDescription::fromTexture(QSGTexture *t) return s; } -#if QT_CONFIG(opengl) -#ifndef QT_NO_DEBUG -inline static bool isPowerOfTwo(int x) -{ - // Assumption: x >= 1 - return x == (x & -x); -} -#endif -#endif - QSGTexturePrivate::QSGTexturePrivate() : wrapChanged(false) , filteringChanged(false) @@ -340,32 +328,6 @@ static void qt_debug_remove_texture(QSGTexture* texture) For Vulkan, \c layout contains a \c VkImageLayout value. */ - -#ifndef QT_NO_DEBUG -Q_QUICK_PRIVATE_EXPORT void qsg_set_material_failure(); -#endif - -#ifndef QT_NO_DEBUG -Q_GLOBAL_STATIC(QSet<QSGTexture *>, qsg_valid_texture_set) -Q_GLOBAL_STATIC(QMutex, qsg_valid_texture_mutex) - -bool qsg_safeguard_texture(QSGTexture *texture) -{ -#if QT_CONFIG(opengl) - QMutexLocker locker(qsg_valid_texture_mutex()); - if (!qsg_valid_texture_set()->contains(texture)) { - qWarning() << "Invalid texture accessed:" << (void *) texture; - qsg_set_material_failure(); - QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0); - return false; - } -#else - Q_UNUSED(texture) -#endif - return true; -} -#endif - /*! Constructs the QSGTexture base class. */ @@ -411,21 +373,6 @@ QSGTexture::~QSGTexture() } /*! - \fn void QSGTexture::bind() - - Call this function to bind this texture to the current texture - target. - - Binding a texture may also include uploading the texture data from - a previously set QImage. - - \warning This function should only be called when running with the - direct OpenGL rendering path. - - \warning This function can only be called from the rendering thread. - */ - -/*! \fn QRectF QSGTexture::convertToNormalizedSourceRect(const QRectF &rect) const Returns \a rect converted to normalized coordinates. @@ -477,18 +424,6 @@ bool QSGTexture::isAtlasTexture() const } /*! - \fn int QSGTexture::textureId() const - - Returns the OpenGL texture id for this texture. - - The default value is 0, indicating that it is an invalid texture id. - - The function should at all times return the correct texture id. - - \warning This function can only be called from the rendering thread. - */ - -/*! \fn qint64 QSGTexture::comparisonKey() const Returns a key suitable for comparing textures. Typically used in @@ -657,74 +592,6 @@ QSGTexture::WrapMode QSGTexture::verticalWrapMode() const return (QSGTexture::WrapMode) d_func()->verticalWrap; } - -/*! - Update the texture state to match the filtering, mipmap and wrap options - currently set. - - If \a force is true, all properties will be updated regardless of weither - they have changed or not. - */ -void QSGTexture::updateBindOptions(bool force) // legacy (GL-only) -{ -#if QT_CONFIG(opengl) - Q_D(QSGTexture); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - force |= isAtlasTexture(); - - if (force || d->filteringChanged) { - bool linear = d->filterMode == Linear; - GLint minFilter = linear ? GL_LINEAR : GL_NEAREST; - GLint magFilter = linear ? GL_LINEAR : GL_NEAREST; - - if (hasMipmaps()) { - if (d->mipmapMode == Nearest) - minFilter = linear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST; - else if (d->mipmapMode == Linear) - minFilter = linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR; - } - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); - d->filteringChanged = false; - } - - if (force || d->anisotropyChanged) { - d->anisotropyChanged = false; - if (QOpenGLContext::currentContext()->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"))) - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, float(1 << (d->anisotropyLevel))); - } - - if (force || d->wrapChanged) { -#ifndef QT_NO_DEBUG - if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat - || d->horizontalWrap == MirroredRepeat || d->verticalWrap == MirroredRepeat) - { - bool npotSupported = QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); - QSize size = textureSize(); - bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); - if (!npotSupported && isNpot) - qWarning("Scene Graph: This system does not support the REPEAT wrap mode for non-power-of-two textures."); - } -#endif - GLenum wrapS = GL_CLAMP_TO_EDGE; - if (d->horizontalWrap == Repeat) - wrapS = GL_REPEAT; - else if (d->horizontalWrap == MirroredRepeat) - wrapS = GL_MIRRORED_REPEAT; - GLenum wrapT = GL_CLAMP_TO_EDGE; - if (d->verticalWrap == Repeat) - wrapT = GL_REPEAT; - else if (d->verticalWrap == MirroredRepeat) - wrapT = GL_MIRRORED_REPEAT; - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); - d->wrapChanged = false; - } -#else - Q_UNUSED(force) -#endif -} - /*! \return the QRhiTexture for this QSGTexture or null if there is none (either because a valid texture has not been created internally yet, or because the diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h index 067a5151fd..2d9d6b4403 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.h +++ b/src/quick/scenegraph/coreapi/qsgtexture.h @@ -86,7 +86,6 @@ public: }; virtual qint64 comparisonKey() const = 0; - virtual int textureId() const = 0; // ### Qt 6: remove virtual QRhiTexture *rhiTexture() const; NativeTexture nativeTexture() const; virtual QSize textureSize() const = 0; @@ -99,9 +98,6 @@ public: virtual QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates = nullptr) const; - virtual void bind() = 0; // ### Qt 6: remove - void updateBindOptions(bool force = false); // ### Qt 6: remove - virtual void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates); void setMipmapFiltering(Filtering filter); diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index e0d9d5db68..3ee5d6fdb7 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -302,19 +302,6 @@ void QSGDistanceFieldGlyphCache::markGlyphsToRender(const QVector<glyph_t> &glyp m_pendingGlyphs.add(glyphs.at(i)); } -void QSGDistanceFieldGlyphCache::updateTexture(uint oldTex, uint newTex, const QSize &newTexSize) -{ - int count = m_textures.count(); - for (int i = 0; i < count; ++i) { - Texture &tex = m_textures[i]; - if (tex.textureId == oldTex) { - tex.textureId = newTex; - tex.size = newTexSize; - return; - } - } -} - void QSGDistanceFieldGlyphCache::updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize) { int count = m_textures.count(); diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 4ded2eeb8c..31f90bd0b2 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -447,18 +447,11 @@ public: }; struct Texture { - uint textureId = 0; QRhiTexture *texture = nullptr; QSize size; - bool rhiBased = false; bool operator == (const Texture &other) const { - if (rhiBased != other.rhiBased) - return false; - if (rhiBased) - return texture == other.texture; - else - return textureId == other.textureId; + return texture == other.texture; } }; @@ -519,11 +512,9 @@ protected: void markGlyphsToRender(const QVector<glyph_t> &glyphs); inline void removeGlyph(glyph_t glyph); - void updateTexture(uint oldTex, uint newTex, const QSize &newTexSize); void updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize); inline bool containsGlyph(glyph_t glyph); - uint textureIdForGlyph(glyph_t glyph) const; GlyphData &glyphData(glyph_t glyph); GlyphData &emptyData(glyph_t glyph); diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index e13b16c95b..8c66dc348f 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -638,35 +638,19 @@ int QSGTextMaskMaterial::compare(const QSGMaterial *o) const bool QSGTextMaskMaterial::ensureUpToDate() { - if (m_rhi) { - QSGRhiTextureGlyphCache *gc = rhiGlyphCache(); - QSize glyphCacheSize(gc->width(), gc->height()); - if (glyphCacheSize != m_size) { - if (m_texture) - delete m_texture; - m_texture = new QSGPlainTexture; - m_texture->setTexture(gc->texture()); - m_texture->setTextureSize(QSize(gc->width(), gc->height())); - m_texture->setOwnsTexture(false); - m_size = glyphCacheSize; - return true; - } - return false; - - } else { - QSize glyphCacheSize(openglGlyphCache()->width(), openglGlyphCache()->height()); - if (glyphCacheSize != m_size) { - if (m_texture) - delete m_texture; - m_texture = new QSGPlainTexture(); - m_texture->setTextureId(openglGlyphCache()->texture()); - m_texture->setTextureSize(QSize(openglGlyphCache()->width(), openglGlyphCache()->height())); - m_texture->setOwnsTexture(false); - m_size = glyphCacheSize; - return true; - } - return false; + QSGRhiTextureGlyphCache *gc = rhiGlyphCache(); + QSize glyphCacheSize(gc->width(), gc->height()); + if (glyphCacheSize != m_size) { + if (m_texture) + delete m_texture; + m_texture = new QSGPlainTexture; + m_texture->setTexture(gc->texture()); + m_texture->setTextureSize(QSize(gc->width(), gc->height())); + m_texture->setOwnsTexture(false); + m_size = glyphCacheSize; + return true; } + return false; } diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 0214b1b94c..5dc73fa3ad 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -48,7 +48,6 @@ #include <QtQuick/private/qsgrhidistancefieldglyphcache_p.h> #include <QtQuick/private/qsgmaterialshader_p.h> -#include <QtQuick/private/qsgopenglatlastexture_p.h> #include <QtQuick/private/qsgcompressedtexture_p.h> QT_BEGIN_NAMESPACE @@ -64,7 +63,6 @@ QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context) , m_brokenIBOs(false) , m_serializedRender(false) , m_attachToGLContext(true) - , m_glAtlasManager(nullptr) , m_rhiAtlasManager(nullptr) , m_currentFrameCommandBuffer(nullptr) , m_currentFrameRenderPass(nullptr) @@ -124,9 +122,6 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant::fromValue(this)); } - if (!m_glAtlasManager) - m_glAtlasManager = new QSGOpenGLAtlasTexture::Manager(m_initParams.initialSurfacePixelSize); - // WebGL: A given WebGLBuffer object may only be bound to one of // the ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target in its // lifetime. An attempt to bind a buffer object to the other @@ -169,11 +164,6 @@ void QSGDefaultRenderContext::invalidate() Another alternative would be to use a QPointer in QSGOpenGLAtlasTexture::Texture, but this seemed simpler. */ - if (m_glAtlasManager) { - m_glAtlasManager->invalidate(); - m_glAtlasManager->deleteLater(); - m_glAtlasManager = nullptr; - } if (m_rhiAtlasManager) { m_rhiAtlasManager->invalidate(); m_rhiAtlasManager->deleteLater(); @@ -321,12 +311,6 @@ QSGTexture *QSGDefaultRenderContext::createTexture(const QImage &image, uint fla if (t) return t; } - } else { - if (!mipmap && atlas && openglContext() && QThread::currentThread() == openglContext()->thread()) { - QSGTexture *t = m_glAtlasManager->create(image, alpha); - if (t) - return t; - } } QSGPlainTexture *texture = new QSGPlainTexture; @@ -346,12 +330,8 @@ QSGTexture *QSGDefaultRenderContext::compressedTextureForFactory(const QSGCompre { // This is only used for atlasing compressed textures. Returning null implies no atlas. - if (m_rhi && QThread::currentThread() == m_rhi->thread()) { + if (m_rhi && QThread::currentThread() == m_rhi->thread()) return m_rhiAtlasManager->create(factory); - } else if (openglContext() && QThread::currentThread() == openglContext()->thread()) { - // The atlas implementation is only supported from the render thread - return m_glAtlasManager->create(factory); - } return nullptr; } diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h index a2d3a1b20c..4cf989b345 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -174,7 +174,6 @@ protected: bool m_brokenIBOs; bool m_serializedRender; bool m_attachToGLContext; - QSGOpenGLAtlasTexture::Manager *m_glAtlasManager; QSGRhiAtlasTexture::Manager *m_rhiAtlasManager; QRhiCommandBuffer *m_currentFrameCommandBuffer; QRhiRenderPassDescriptor *m_currentFrameRenderPass; diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp index 0fa680a244..8371fb9303 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp @@ -224,11 +224,8 @@ void QSGDistanceFieldGlyphNode::updateGeometry() const QPointF position = positions.at(i); const QSGDistanceFieldGlyphCache::Texture *texture = m_glyph_cache->glyphTexture(glyphIndex); - if ((!texture->rhiBased && texture->textureId && !m_texture) - || (texture->rhiBased && texture->texture && !m_texture)) - { + if (texture->texture && !m_texture) m_texture = texture; - } // As we use UNSIGNED_SHORT indexing in the geometry, we overload the // "glyphsInOtherTextures" concept as overflow for if there are more @@ -237,7 +234,7 @@ void QSGDistanceFieldGlyphNode::updateGeometry() // primitive restart) This will cause sub-nodes to be recursively // created to handle any number of glyphs. if (m_texture != texture || vp.size() >= 65535) { - if (texture->textureId) { + if (texture->texture) { GlyphInfo &glyphInfo = glyphsInOtherTextures[texture]; glyphInfo.indexes.append(glyphIndex); glyphInfo.positions.append(position); diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp index 8a4e0d0e9f..7fac5a3e72 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp @@ -39,7 +39,6 @@ #include "qsgdistancefieldglyphnode_p_p.h" #include "qsgrhidistancefieldglyphcache_p.h" -#include <qopenglfunctions.h> #include <QtGui/qsurface.h> #include <QtGui/qwindow.h> #include <qmath.h> @@ -241,8 +240,8 @@ int QSGDistanceFieldTextMaterial::compare(const QSGMaterial *o) const } if (m_color != other->m_color) return &m_color < &other->m_color ? -1 : 1; - qintptr t0 = m_texture ? (m_texture->rhiBased ? qintptr(m_texture->texture) : qintptr(m_texture->textureId)) : 0; - qintptr t1 = other->m_texture ? (other->m_texture->rhiBased ? qintptr(other->m_texture->texture) : qintptr(other->m_texture->textureId)) : 0; + qintptr t0 = m_texture ? qintptr(m_texture->texture) : 0; + qintptr t1 = other->m_texture ? qintptr(other->m_texture->texture) : 0; const qintptr diff = t0 - t1; return diff < 0 ? -1 : (diff > 0 ? 1 : 0); } diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp index 851da3dc8e..6e7e2b5118 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp @@ -193,7 +193,6 @@ void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &gly Texture t; t.texture = i.key()->texture; t.size = i.key()->size; - t.rhiBased = true; setGlyphsTexture(i.value(), t); } } @@ -526,7 +525,6 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) Texture t; t.texture = texInfo->texture; t.size = texInfo->size; - t.rhiBased = true; setGlyphsTexture(glyphs, t); diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp index e5c0fc4de0..459c1872a3 100644 --- a/src/quick/scenegraph/qsgrhilayer.cpp +++ b/src/quick/scenegraph/qsgrhilayer.cpp @@ -87,17 +87,6 @@ bool QSGRhiLayer::hasMipmaps() const return m_mipmap; } -int QSGRhiLayer::textureId() const -{ - Q_ASSERT_X(false, "QSGRhiLayer::textureId()", "Not implemented for RHI"); - return 0; -} - -void QSGRhiLayer::bind() -{ - Q_ASSERT_X(false, "QSGRhiLayer::bind()", "Not implemented for RHI"); -} - QRhiTexture *QSGRhiLayer::rhiTexture() const { return m_texture; diff --git a/src/quick/scenegraph/qsgrhilayer_p.h b/src/quick/scenegraph/qsgrhilayer_p.h index eaa2c6d7b0..6e3db911fa 100644 --- a/src/quick/scenegraph/qsgrhilayer_p.h +++ b/src/quick/scenegraph/qsgrhilayer_p.h @@ -73,8 +73,6 @@ public: bool hasMipmaps() const override; QSize textureSize() const override { return m_size; } - void bind() override; - int textureId() const override; qint64 comparisonKey() const override; QRhiTexture *rhiTexture() const override; void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override; diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index 4a1cdb6aed..a9fd39dac5 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -72,11 +72,9 @@ SOURCES += \ qtConfig(opengl(es1|es2)?) { HEADERS += \ $$PWD/util/qsgdepthstencilbuffer_p.h \ - $$PWD/util/qsgshadersourcebuilder_p.h \ - $$PWD/util/qsgopenglatlastexture_p.h + $$PWD/util/qsgshadersourcebuilder_p.h SOURCES += \ $$PWD/util/qsgdepthstencilbuffer.cpp \ - $$PWD/util/qsgopenglatlastexture.cpp \ $$PWD/util/qsgshadersourcebuilder.cpp # rhi, still tied to OpenGL-enabled Qt builds for now diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp index cd8426db97..e704624a96 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp @@ -60,19 +60,6 @@ QSGPainterTexture::QSGPainterTexture() m_retain_image = true; } -void QSGPainterTexture::bind() -{ - if (m_dirty_rect.isNull()) { - QSGPlainTexture::bind(); - return; - } - - setImage(m_image); - QSGPlainTexture::bind(); - - m_dirty_rect = QRect(); -} - void QSGPainterTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) { if (!m_dirty_rect.isNull()) { @@ -324,7 +311,8 @@ void QSGDefaultPainterNode::updateRenderTarget() texture->setOwnsTexture(true); texture->setTextureSize(m_textureSize); } else { - texture->setTextureId(m_fbo->texture()); + // ### glpurge + //texture->setTextureId(m_fbo->texture()); texture->setOwnsTexture(false); texture->setTextureSize(m_fboSize); } diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h index b2402dc70e..c02fdec40b 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h +++ b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h @@ -72,7 +72,6 @@ public: void setDirtyRect(const QRect &rect) { m_dirty_rect = rect; } - void bind() override; void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override; private: diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp deleted file mode 100644 index f9bc0a552c..0000000000 --- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp +++ /dev/null @@ -1,625 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "qsgopenglatlastexture_p.h" - -#include <QtCore/QVarLengthArray> -#include <QtCore/QElapsedTimer> -#include <QtCore/QtMath> - -#include <QOpenGLContext> -#include <QOpenGLTexture> -#include <QOpenGLFunctions> -#include <QtGui/QGuiApplication> -#include <QtGui/QScreen> -#include <QtGui/QSurface> -#include <QtGui/QWindow> -#include <QtGui/qpa/qplatformnativeinterface.h> - -#include <private/qqmlglobal_p.h> -#include <private/qsgtexture_p.h> -#include <private/qsgcompressedtexture_p.h> -#include <private/qsgcompressedatlastexture_p.h> - -#include <private/qquickprofiler_p.h> - -#include <qtquick_tracepoints_p.h> - -QT_BEGIN_NAMESPACE - -#ifndef GL_BGRA -#define GL_BGRA 0x80E1 -#endif - -int qt_sg_envInt(const char *name, int defaultValue); - -static QElapsedTimer qsg_renderer_timer; - -// DEFINE_BOOL_CONFIG_OPTION(qsgEnableCompressedAtlas, QSG_ENABLE_COMPRESSED_ATLAS) - -namespace QSGOpenGLAtlasTexture -{ - -Manager::Manager(const QSize &surfacePixelSize) - : m_atlas(nullptr) -{ - QOpenGLContext *gl = QOpenGLContext::currentContext(); - Q_ASSERT(gl); - int max; - gl->functions()->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); - - int w = qMin(max, qt_sg_envInt("QSG_ATLAS_WIDTH", qMax(512U, qNextPowerOfTwo(surfacePixelSize.width() - 1)))); - int h = qMin(max, qt_sg_envInt("QSG_ATLAS_HEIGHT", qMax(512U, qNextPowerOfTwo(surfacePixelSize.height() - 1)))); - - if (gl->surface()->surfaceClass() == QSurface::Window) { - QWindow *window = static_cast<QWindow *>(gl->surface()); - // Coverwindows, optimize for memory rather than speed - if ((window->type() & Qt::CoverWindow) == Qt::CoverWindow) { - w /= 2; - h /= 2; - } - } - - m_atlas_size_limit = qt_sg_envInt("QSG_ATLAS_SIZE_LIMIT", qMax(w, h) / 2); - m_atlas_size = QSize(w, h); - - qCDebug(QSG_LOG_INFO, "opengl texture atlas dimensions: %dx%d", w, h); -} - -Manager::~Manager() -{ - Q_ASSERT(m_atlas == nullptr); - Q_ASSERT(m_atlases.isEmpty()); -} - -void Manager::invalidate() -{ - if (m_atlas) { - m_atlas->invalidate(); - m_atlas->deleteLater(); - m_atlas = nullptr; - } - - QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.begin(); - while (i != m_atlases.end()) { - i.value()->invalidate(); - i.value()->deleteLater(); - ++i; - } - m_atlases.clear(); -} - -QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel) -{ - Texture *t = nullptr; - if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) { - if (!m_atlas) - m_atlas = new Atlas(m_atlas_size); - // t may be null for atlas allocation failure - t = m_atlas->create(image); - if (t && !hasAlphaChannel && t->hasAlphaChannel()) - t->setHasAlphaChannel(false); - } - return t; -} - -QSGTexture *Manager::create(const QSGCompressedTextureFactory *factory) -{ - Q_UNUSED(factory) - return nullptr; - - // DirectGL path disabled -#if 0 - QSGTexture *t = nullptr; - if (!qsgEnableCompressedAtlas() || !factory->m_textureData.isValid()) - return t; - - // TODO: further abstract the atlas and remove this restriction - unsigned int format = factory->m_textureData.glInternalFormat(); - switch (format) { - case QOpenGLTexture::RGB8_ETC1: - case QOpenGLTexture::RGB8_ETC2: - case QOpenGLTexture::RGBA8_ETC2_EAC: - case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: - case QOpenGLTexture::RGB_DXT1: - case QOpenGLTexture::RGBA_DXT1: - case QOpenGLTexture::RGBA_DXT3: - case QOpenGLTexture::RGBA_DXT5: - break; - default: - return t; - } - - QSize size = factory->m_textureData.size(); - if (size.width() < m_atlas_size_limit && size.height() < m_atlas_size_limit) { - QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.find(format); - if (i == m_atlases.end()) { - // must be multiple of 4 - QSize paddedSize(((m_atlas_size.width() + 3) / 4) * 4, ((m_atlas_size.height() + 3) / 4) * 4); - i = m_atlases.insert(format, new QSGCompressedAtlasTexture::Atlas(paddedSize, format)); - } - - // must be multiple of 4 - QSize paddedSize(((size.width() + 3) / 4) * 4, ((size.height() + 3) / 4) * 4); - QByteArray data = factory->m_textureData.data(); - t = i.value()->create(data, factory->m_textureData.dataLength(), factory->m_textureData.dataOffset(), size, paddedSize); - } - return t; -#endif -} - -AtlasBase::AtlasBase(const QSize &size) - : m_allocator(size) - , m_texture_id(0) - , m_size(size) - , m_allocated(false) -{ -} - -AtlasBase::~AtlasBase() -{ - Q_ASSERT(!m_texture_id); -} - -void AtlasBase::invalidate() -{ - if (m_texture_id && QOpenGLContext::currentContext()) - QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; -} - -int AtlasBase::textureId() const -{ - if (!m_texture_id) { - Q_ASSERT(QOpenGLContext::currentContext()); - QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<AtlasBase *>(this)->m_texture_id); - } - - return m_texture_id; -} - -void AtlasBase::bind(QSGTexture::Filtering filtering) -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - if (!m_allocated) { - m_allocated = true; - - while (funcs->glGetError() != GL_NO_ERROR) ; - - funcs->glGenTextures(1, &m_texture_id); - funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -#if !QT_CONFIG(opengles2) - if (!QOpenGLContext::currentContext()->isOpenGLES()) - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); -#endif - generateTexture(); - - GLenum errorCode = funcs->glGetError(); - if (errorCode == GL_OUT_OF_MEMORY) { - qDebug("QSGTextureAtlas: texture atlas allocation failed, out of memory"); - funcs->glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; - } else if (errorCode != GL_NO_ERROR) { - qDebug("QSGTextureAtlas: texture atlas allocation failed, code=%x", errorCode); - funcs->glDeleteTextures(1, &m_texture_id); - m_texture_id = 0; - } - } else { - funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); - } - - if (m_texture_id == 0) - return; - - // Upload all pending images.. - for (int i=0; i<m_pending_uploads.size(); ++i) { - - bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled(); - if (profileFrames) - qsg_renderer_timer.start(); - - Q_TRACE_SCOPE(QSG_texture_prepare); - Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare); - - // Skip bind, convert, swizzle; they're irrelevant - Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareStart, 3); - Q_TRACE(QSG_texture_upload_entry); - - uploadPendingTexture(i); - - Q_TRACE(QSG_texture_upload_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareUpload); - - // Skip mipmap; unused - Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareUpload, 1); - Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareMipmap); - } - - GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR; - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f); - - m_pending_uploads.clear(); -} - -void AtlasBase::remove(TextureBase *t) -{ - QRect atlasRect = t->atlasSubRect(); - m_allocator.deallocate(atlasRect); - m_pending_uploads.removeOne(t); -} - -Atlas::Atlas(const QSize &size) - : AtlasBase(size) - , m_atlas_transient_image_threshold(0) -{ - - m_internalFormat = GL_RGBA; - m_externalFormat = GL_BGRA; - -#if !QT_CONFIG(opengles2) - if (QOpenGLContext::currentContext()->isOpenGLES()) { -#endif - -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) - QString *deviceName = - static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName")); - static bool wrongfullyReportsBgra8888Support = deviceName != 0 - && (deviceName->compare(QLatin1String("samsung SM-T211"), Qt::CaseInsensitive) == 0 - || deviceName->compare(QLatin1String("samsung SM-T210"), Qt::CaseInsensitive) == 0 - || deviceName->compare(QLatin1String("samsung SM-T215"), Qt::CaseInsensitive) == 0); -#else - static bool wrongfullyReportsBgra8888Support = false; - // The Raspberry Pi (both 1 and 2) GPU refuses framebuffers with BGRA color attachments. - const GLubyte *renderer = QOpenGLContext::currentContext()->functions()->glGetString(GL_RENDERER); - if (renderer && strstr((const char *) renderer, "VideoCore IV")) - wrongfullyReportsBgra8888Support = true; -#endif // ANDROID - - if (qEnvironmentVariableIsSet("QSG_ATLAS_NO_BGRA_WORKAROUNDS")) - wrongfullyReportsBgra8888Support = false; - - const char *ext = (const char *) QOpenGLContext::currentContext()->functions()->glGetString(GL_EXTENSIONS); - if (ext && !wrongfullyReportsBgra8888Support - && (strstr(ext, "GL_EXT_bgra") - || strstr(ext, "GL_EXT_texture_format_BGRA8888") - || strstr(ext, "GL_IMG_texture_format_BGRA8888"))) { - m_internalFormat = m_externalFormat = GL_BGRA; -#if defined(Q_OS_DARWIN) && !defined(Q_OS_OSX) - } else if (ext && strstr(ext, "GL_APPLE_texture_format_BGRA8888")) { - m_internalFormat = GL_RGBA; - m_externalFormat = GL_BGRA; -#endif // IOS || TVOS - } else { - m_internalFormat = m_externalFormat = GL_RGBA; - } - -#if !QT_CONFIG(opengles2) - } -#endif - - m_use_bgra_fallback = qEnvironmentVariableIsSet("QSG_ATLAS_USE_BGRA_FALLBACK"); - m_debug_overlay = qEnvironmentVariableIsSet("QSG_ATLAS_OVERLAY"); - - // images smaller than this will retain their QImage. - // by default no images are retained (favoring memory) - // set to a very large value to retain all images (allowing quick removal from the atlas) - m_atlas_transient_image_threshold = qt_sg_envInt("QSG_ATLAS_TRANSIENT_IMAGE_THRESHOLD", 0); -} - -Atlas::~Atlas() -{ -} - -Texture *Atlas::create(const QImage &image) -{ - // No need to lock, as manager already locked it. - QRect rect = m_allocator.allocate(QSize(image.width() + 2, image.height() + 2)); - if (rect.width() > 0 && rect.height() > 0) { - Texture *t = new Texture(this, rect, image); - m_pending_uploads << t; - return t; - } - return nullptr; -} - -void Atlas::upload(Texture *texture) -{ - const QImage &image = texture->image(); - const QRect &r = texture->atlasSubRect(); - - QImage tmp(r.width(), r.height(), QImage::Format_ARGB32_Premultiplied); - { - QPainter p(&tmp); - p.setCompositionMode(QPainter::CompositionMode_Source); - - int w = r.width(); - int h = r.height(); - int iw = image.width(); - int ih = image.height(); - - p.drawImage(1, 1, image); - p.drawImage(1, 0, image, 0, 0, iw, 1); - p.drawImage(1, h - 1, image, 0, ih - 1, iw, 1); - p.drawImage(0, 1, image, 0, 0, 1, ih); - p.drawImage(w - 1, 1, image, iw - 1, 0, 1, ih); - p.drawImage(0, 0, image, 0, 0, 1, 1); - p.drawImage(0, h - 1, image, 0, ih - 1, 1, 1); - p.drawImage(w - 1, 0, image, iw - 1, 0, 1, 1); - p.drawImage(w - 1, h - 1, image, iw - 1, ih - 1, 1, 1); - if (m_debug_overlay) { - p.setCompositionMode(QPainter::CompositionMode_SourceAtop); - p.fillRect(0, 0, iw, ih, QBrush(QColor::fromRgbF(1, 0, 1, 0.5))); - } - } - - if (m_externalFormat == GL_RGBA) - tmp = std::move(tmp).convertToFormat(QImage::Format_RGBA8888_Premultiplied); - QOpenGLContext::currentContext()->functions()->glTexSubImage2D(GL_TEXTURE_2D, 0, - r.x(), r.y(), r.width(), r.height(), - m_externalFormat, GL_UNSIGNED_BYTE, tmp.constBits()); -} - -void Atlas::uploadBgra(Texture *texture) -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - const QRect &r = texture->atlasSubRect(); - QImage image = texture->image(); - - if (image.isNull()) - return; - - if (image.format() != QImage::Format_ARGB32_Premultiplied - && image.format() != QImage::Format_RGB32) { - image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - } - - if (m_debug_overlay) { - QPainter p(&image); - p.setCompositionMode(QPainter::CompositionMode_SourceAtop); - p.fillRect(0, 0, image.width(), image.height(), QBrush(QColor::fromRgbF(0, 1, 1, 0.5))); - } - - QVarLengthArray<quint32, 512> tmpBits(qMax(image.width() + 2, image.height() + 2)); - int iw = image.width(); - int ih = image.height(); - int bpl = image.bytesPerLine() / 4; - const quint32 *src = (const quint32 *) image.constBits(); - quint32 *dst = tmpBits.data(); - - // top row, padding corners - dst[0] = src[0]; - memcpy(dst + 1, src, iw * sizeof(quint32)); - dst[1 + iw] = src[iw-1]; - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, r.x(), r.y(), iw + 2, 1, m_externalFormat, GL_UNSIGNED_BYTE, dst); - - // bottom row, padded corners - const quint32 *lastRow = src + bpl * (ih - 1); - dst[0] = lastRow[0]; - memcpy(dst + 1, lastRow, iw * sizeof(quint32)); - dst[1 + iw] = lastRow[iw-1]; - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, r.x(), r.y() + ih + 1, iw + 2, 1, m_externalFormat, GL_UNSIGNED_BYTE, dst); - - // left column - for (int i=0; i<ih; ++i) - dst[i] = src[i * bpl]; - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, r.x(), r.y() + 1, 1, ih, m_externalFormat, GL_UNSIGNED_BYTE, dst); - - // right column - for (int i=0; i<ih; ++i) - dst[i] = src[i * bpl + iw - 1]; - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, r.x() + iw + 1, r.y() + 1, 1, ih, m_externalFormat, GL_UNSIGNED_BYTE, dst); - - // Inner part of the image.... - if (bpl != iw) { - int sy = r.y() + 1; - int ey = sy + r.height() - 2; - for (int y = sy; y < ey; ++y) { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, r.x() + 1, y, r.width() - 2, 1, m_externalFormat, GL_UNSIGNED_BYTE, src); - src += bpl; - } - } else { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2, m_externalFormat, GL_UNSIGNED_BYTE, src); - } -} - -void Atlas::generateTexture() -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, nullptr); - -#if 0 - QImage pink(m_size.width(), m_size.height(), QImage::Format_ARGB32_Premultiplied); - pink.fill(0); - QPainter p(&pink); - QLinearGradient redGrad(0, 0, m_size.width(), 0); - redGrad.setColorAt(0, Qt::black); - redGrad.setColorAt(1, Qt::red); - p.fillRect(0, 0, m_size.width(), m_size.height(), redGrad); - p.setCompositionMode(QPainter::CompositionMode_Plus); - QLinearGradient blueGrad(0, 0, 0, m_size.height()); - blueGrad.setColorAt(0, Qt::black); - blueGrad.setColorAt(1, Qt::blue); - p.fillRect(0, 0, m_size.width(), m_size.height(), blueGrad); - p.end(); - - funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, pink.constBits()); -#endif -} - -void Atlas::uploadPendingTexture(int i) -{ - Texture *t = static_cast<Texture*>(m_pending_uploads.at(i)); - if (m_externalFormat == GL_BGRA && - !m_use_bgra_fallback) { - uploadBgra(t); - } else { - upload(t); - } - const QSize textureSize = t->textureSize(); - if (textureSize.width() > m_atlas_transient_image_threshold || - textureSize.height() > m_atlas_transient_image_threshold) - t->releaseImage(); - - qCDebug(QSG_LOG_TIME_TEXTURE, "atlastexture uploaded in: %lldms (%dx%d)", - qsg_renderer_timer.elapsed(), - t->textureSize().width(), - t->textureSize().height()); -} - -TextureBase::TextureBase(AtlasBase *atlas, const QRect &textureRect) - : m_allocated_rect(textureRect) - , m_atlas(atlas) -{ -} - -TextureBase::~TextureBase() -{ - m_atlas->remove(this); -} - -qint64 TextureBase::comparisonKey() const -{ - // We need special care here: a typical comparisonKey() implementation - // returns a unique result when there is no underlying texture yet. This is - // not quite ideal for atlasing however since textures with the same atlas - // should be considered equal regardless of the state of the underlying - // graphics resources. - - // base the comparison on the atlas ptr; this way textures for the same - // atlas are considered equal - return qint64(m_atlas); -} - -void TextureBase::bind() -{ - m_atlas->bind(filtering()); -} - -Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image) - : TextureBase(atlas, textureRect) - , m_image(image) - , m_nonatlas_texture(nullptr) - , m_has_alpha(image.hasAlphaChannel()) -{ - qreal w = atlas->size().width(); - qreal h = atlas->size().height(); - QRect nopad = atlasSubRectWithoutPadding(); - m_texture_coords_rect = QRectF(nopad.x() / w, - nopad.y() / h, - nopad.width() / w, - nopad.height() / h); -} - -Texture::~Texture() -{ - if (m_nonatlas_texture) - delete m_nonatlas_texture; -} - -QSGTexture *Texture::removedFromAtlas(QRhiResourceUpdateBatch *) const -{ - if (m_nonatlas_texture) { - m_nonatlas_texture->setMipmapFiltering(mipmapFiltering()); - m_nonatlas_texture->setFiltering(filtering()); - return m_nonatlas_texture; - } - - if (!m_image.isNull()) { - m_nonatlas_texture = new QSGPlainTexture(); - m_nonatlas_texture->setImage(m_image); - m_nonatlas_texture->setFiltering(filtering()); - - } else { - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - // bind the atlas texture as an fbo and extract the texture.. - - // First extract the currently bound fbo so we can restore it later. - GLint currentFbo; - f->glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFbo); - - // Create an FBO and bind the atlas texture into it. - GLuint fbo; - f->glGenFramebuffers(1, &fbo); - f->glBindFramebuffer(GL_FRAMEBUFFER, fbo); - f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_atlas->textureId(), 0); - - // Create the target texture, QSGPlainTexture below will deal with the texparams, so we don't - // need to worry about those here. - GLuint texture; - f->glGenTextures(1, &texture); - f->glBindTexture(GL_TEXTURE_2D, texture); - QRect r = atlasSubRectWithoutPadding(); - // and copy atlas into our texture. - while (f->glGetError() != GL_NO_ERROR) ; - f->glCopyTexImage2D(GL_TEXTURE_2D, 0, static_cast<Atlas*>(m_atlas)->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0); - // BGRA may have been rejected by some GLES implementations - if (f->glGetError() != GL_NO_ERROR) - f->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r.x(), r.y(), r.width(), r.height(), 0); - - m_nonatlas_texture = new QSGPlainTexture(); - m_nonatlas_texture->setTextureId(texture); - m_nonatlas_texture->setOwnsTexture(true); - m_nonatlas_texture->setHasAlphaChannel(m_has_alpha); - m_nonatlas_texture->setTextureSize(r.size()); - - // cleanup: unbind our atlas from the fbo, rebind the old default and delete the fbo. - f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - f->glBindFramebuffer(GL_FRAMEBUFFER, (GLuint) currentFbo); - f->glDeleteFramebuffers(1, &fbo); - } - - m_nonatlas_texture->setMipmapFiltering(mipmapFiltering()); - m_nonatlas_texture->setFiltering(filtering()); - return m_nonatlas_texture; -} - -} - -QT_END_NAMESPACE - -#include "moc_qsgopenglatlastexture_p.cpp" diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture_p.h b/src/quick/scenegraph/util/qsgopenglatlastexture_p.h deleted file mode 100644 index d9d9d3175e..0000000000 --- a/src/quick/scenegraph/util/qsgopenglatlastexture_p.h +++ /dev/null @@ -1,208 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 QSGOPENGLATLASTEXTURE_P_H -#define QSGOPENGLATLASTEXTURE_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 <QtCore/QSize> - -#include <qopengl.h> - -#include <QtQuick/QSGTexture> -#include <QtQuick/private/qsgplaintexture_p.h> -#include <QtQuick/private/qsgareaallocator_p.h> - -QT_BEGIN_NAMESPACE - -namespace QSGCompressedAtlasTexture { - class Atlas; -} -class QSGCompressedTextureFactory; - -namespace QSGOpenGLAtlasTexture -{ - -class Texture; -class TextureBase; -class Atlas; - -class Manager : public QObject -{ - Q_OBJECT - -public: - Manager(const QSize &surfacePixelSize); - ~Manager(); - - QSGTexture *create(const QImage &image, bool hasAlphaChannel); - QSGTexture *create(const QSGCompressedTextureFactory *factory); - void invalidate(); - -private: - Atlas *m_atlas; - // set of atlases for different compressed formats - QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*> m_atlases; - - QSize m_atlas_size; - int m_atlas_size_limit; -}; - -class AtlasBase : public QObject -{ - Q_OBJECT -public: - AtlasBase(const QSize &size); - ~AtlasBase(); - - void invalidate(); - - qint64 comparisonKey() const { return m_texture_id; } - int textureId() const; - void bind(QSGTexture::Filtering filtering); - - void remove(TextureBase *t); - - QSize size() const { return m_size; } - -protected: - virtual void generateTexture() = 0; - virtual void uploadPendingTexture(int i) = 0; - -protected: - QSGAreaAllocator m_allocator; - unsigned int m_texture_id; - QSize m_size; - QList<TextureBase *> m_pending_uploads; - -private: - bool m_allocated; -}; - -class Atlas : public AtlasBase -{ -public: - Atlas(const QSize &size); - ~Atlas(); - - void generateTexture() override; - void uploadPendingTexture(int i) override; - - void upload(Texture *texture); - void uploadBgra(Texture *texture); - - Texture *create(const QImage &image); - - uint internalFormat() const { return m_internalFormat; } - uint externalFormat() const { return m_externalFormat; } - -private: - uint m_internalFormat; - uint m_externalFormat; - - int m_atlas_transient_image_threshold; - - uint m_use_bgra_fallback: 1; - uint m_debug_overlay : 1; -}; - -class TextureBase : public QSGTexture -{ - Q_OBJECT -public: - TextureBase(AtlasBase *atlas, const QRect &textureRect); - ~TextureBase(); - - qint64 comparisonKey() const override; - int textureId() const override { return m_atlas->textureId(); } - bool isAtlasTexture() const override { return true; } - - QRect atlasSubRect() const { return m_allocated_rect; } - - void bind() override; - -protected: - QRect m_allocated_rect; - AtlasBase *m_atlas; -}; - -class Texture : public TextureBase -{ - Q_OBJECT -public: - Texture(Atlas *atlas, const QRect &textureRect, const QImage &image); - ~Texture(); - - QSize textureSize() const override { return atlasSubRectWithoutPadding().size(); } - void setHasAlphaChannel(bool alpha) { m_has_alpha = alpha; } - bool hasAlphaChannel() const override { return m_has_alpha; } - bool hasMipmaps() const override { return false; } - - QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; } - - QRect atlasSubRect() const { return m_allocated_rect; } - QRect atlasSubRectWithoutPadding() const { return m_allocated_rect.adjusted(1, 1, -1, -1); } - - QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *) const override; - - void releaseImage() { m_image = QImage(); } - const QImage &image() const { return m_image; } - -private: - QRectF m_texture_coords_rect; - QImage m_image; - mutable QSGPlainTexture *m_nonatlas_texture; - bool m_has_alpha; -}; - -} - -QT_END_NAMESPACE - -#endif diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp index 55ea0bf181..9069804b35 100644 --- a/src/quick/scenegraph/util/qsgplaintexture.cpp +++ b/src/quick/scenegraph/util/qsgplaintexture.cpp @@ -44,37 +44,17 @@ #include <private/qqmlglobal_p.h> #include <QtGui/qguiapplication.h> #include <QtGui/qpa/qplatformnativeinterface.h> -#if QT_CONFIG(opengl) -# include <qopenglcontext.h> -# include <qopenglfunctions.h> -# include <private/qopengltextureuploader_p.h> -# include <private/qsgdefaultrendercontext_p.h> -#endif #include <QtGui/private/qrhi_p.h> #include <qtquick_tracepoints_p.h> -#if QT_CONFIG(opengl) -static QElapsedTimer qsg_renderer_timer; -#endif - -#ifndef GL_BGRA -#define GL_BGRA 0x80E1 -#endif - -#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#endif - QT_BEGIN_NAMESPACE QSGPlainTexture::QSGPlainTexture() : QSGTexture(*(new QSGPlainTexturePrivate)) - , m_texture_id(0) , m_texture(nullptr) , m_has_alpha(false) , m_dirty_texture(false) - , m_dirty_bind_options(false) , m_owns_texture(true) , m_mipmaps_generated(false) , m_retain_image(false) @@ -84,11 +64,9 @@ QSGPlainTexture::QSGPlainTexture() QSGPlainTexture::QSGPlainTexture(QSGPlainTexturePrivate &dd) : QSGTexture(dd) - , m_texture_id(0) , m_texture(nullptr) , m_has_alpha(false) , m_dirty_texture(false) - , m_dirty_bind_options(false) , m_owns_texture(true) , m_mipmaps_generated(false) , m_retain_image(false) @@ -98,10 +76,6 @@ QSGPlainTexture::QSGPlainTexture(QSGPlainTexturePrivate &dd) QSGPlainTexture::~QSGPlainTexture() { -#if QT_CONFIG(opengl) - if (m_texture_id && m_owns_texture && QOpenGLContext::currentContext()) - QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); -#endif if (m_texture && m_owns_texture) delete m_texture; } @@ -112,166 +86,7 @@ void QSGPlainTexture::setImage(const QImage &image) m_texture_size = image.size(); m_has_alpha = image.hasAlphaChannel(); m_dirty_texture = true; - m_dirty_bind_options = true; m_mipmaps_generated = false; - } - -int QSGPlainTexture::textureId() const // legacy (GL-only) -{ - if (m_dirty_texture) { - if (m_image.isNull()) { - // The actual texture and id will be updated/deleted in a later bind() - // or ~QSGPlainTexture so just keep it minimal here. - return 0; - } else if (m_texture_id == 0){ -#if QT_CONFIG(opengl) - // Generate a texture id for use later and return it. - QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<QSGPlainTexture *>(this)->m_texture_id); -#endif - return m_texture_id; - } - } - return m_texture_id; -} - -void QSGPlainTexture::setTextureId(int id) // legacy (GL-only) -{ -#if QT_CONFIG(opengl) - if (m_texture_id && m_owns_texture) - QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); -#endif - - m_texture_id = id; - m_dirty_texture = false; - m_dirty_bind_options = true; - m_image = QImage(); - m_mipmaps_generated = false; -} - -void QSGPlainTexture::bind() // legacy (GL-only) -{ -#if QT_CONFIG(opengl) - Q_TRACE_SCOPE(QSG_texture_prepare); - QOpenGLContext *context = QOpenGLContext::currentContext(); - QOpenGLFunctions *funcs = context->functions(); - if (!m_dirty_texture) { - Q_TRACE_SCOPE(QSG_texture_bind); - funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); - if (mipmapFiltering() != QSGTexture::None && !m_mipmaps_generated) { - funcs->glGenerateMipmap(GL_TEXTURE_2D); - m_mipmaps_generated = true; - } - updateBindOptions(m_dirty_bind_options); - m_dirty_bind_options = false; - return; - } - - m_dirty_texture = false; - - bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled(); - if (profileFrames) - qsg_renderer_timer.start(); - Q_QUICK_SG_PROFILE_START_SYNCHRONIZED(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTextureDeletion); - - - if (m_image.isNull()) { - if (m_texture_id && m_owns_texture) { - Q_TRACE_SCOPE(QSG_texture_delete); - funcs->glDeleteTextures(1, &m_texture_id); - qCDebug(QSG_LOG_TIME_TEXTURE, "plain texture deleted in %dms - %dx%d", - (int) qsg_renderer_timer.elapsed(), - m_texture_size.width(), - m_texture_size.height()); - Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTextureDeletion, - QQuickProfiler::SceneGraphTextureDeletionDelete); - } - m_texture_id = 0; - m_texture_size = QSize(); - m_has_alpha = false; - - return; - } - - Q_TRACE(QSG_texture_bind_entry); - - if (m_texture_id == 0) - funcs->glGenTextures(1, &m_texture_id); - funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); - - qint64 bindTime = 0; - if (profileFrames) - bindTime = qsg_renderer_timer.nsecsElapsed(); - Q_TRACE(QSG_texture_bind_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareBind); - Q_TRACE(QSG_texture_upload_entry); - - // ### TODO: check for out-of-memory situations... - - QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption; - - // Downscale the texture to fit inside the max texture limit if it is too big. - // It would be better if the image was already downscaled to the right size, - // but this information is not always available at that time, so as a last - // resort we can do it here. Texture coordinates are normalized, so it - // won't cause any problems and actual texture sizes will be written - // based on QSGTexture::textureSize which is updated after this, so that - // should be ok. - int max; - if (auto rc = QSGDefaultRenderContext::from(context)) - max = rc->maxTextureSize(); - else - funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); - - m_texture_size = m_texture_size.boundedTo(QSize(max, max)); - - // Scale to a power of two size if mipmapping is requested and the - // texture is npot and npot textures are not properly supported. - if (mipmapFiltering() != QSGTexture::None - && !funcs->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)) { - options |= QOpenGLTextureUploader::PowerOfTwoBindOption; - } - - updateBindOptions(m_dirty_bind_options); - - QOpenGLTextureUploader::textureImage(GL_TEXTURE_2D, m_image, options, QSize(max, max)); - - qint64 uploadTime = 0; - if (profileFrames) - uploadTime = qsg_renderer_timer.nsecsElapsed(); - Q_TRACE(QSG_texture_upload_exit); - Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareUpload); - Q_TRACE(QSG_texture_mipmap_entry); - - if (mipmapFiltering() != QSGTexture::None) { - funcs->glGenerateMipmap(GL_TEXTURE_2D); - m_mipmaps_generated = true; - } - - qint64 mipmapTime = 0; - if (profileFrames) { - mipmapTime = qsg_renderer_timer.nsecsElapsed(); - qCDebug(QSG_LOG_TIME_TEXTURE, - "plain texture uploaded in: %dms (%dx%d), bind=%d, upload=%d, mipmap=%d%s", - int(mipmapTime / 1000000), - m_texture_size.width(), m_texture_size.height(), - int(bindTime / 1000000), - int((uploadTime - bindTime)/1000000), - int((mipmapTime - uploadTime)/1000000), - m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : ""); - } - Q_TRACE(QSG_texture_mipmap_exit); - Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare, - QQuickProfiler::SceneGraphTexturePrepareMipmap); - - m_texture_rect = QRectF(0, 0, 1, 1); - - m_dirty_bind_options = false; - if (!m_retain_image) - m_image = QImage(); -#endif } void QSGPlainTexture::setTexture(QRhiTexture *texture) // RHI only @@ -281,7 +96,6 @@ void QSGPlainTexture::setTexture(QRhiTexture *texture) // RHI only m_texture = texture; m_dirty_texture = false; - m_dirty_bind_options = true; m_image = QImage(); m_mipmaps_generated = false; } @@ -306,10 +120,6 @@ void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::Native qint64 QSGPlainTexture::comparisonKey() const { - // not textureId() as that would create an id when not yet done - that's not wanted here - if (m_texture_id) - return m_texture_id; - if (m_texture) return qint64(m_texture); diff --git a/src/quick/scenegraph/util/qsgplaintexture_p.h b/src/quick/scenegraph/util/qsgplaintexture_p.h index 3589bdbcf7..58a22cbfcf 100644 --- a/src/quick/scenegraph/util/qsgplaintexture_p.h +++ b/src/quick/scenegraph/util/qsgplaintexture_p.h @@ -70,8 +70,6 @@ public: void setOwnsTexture(bool owns) { m_owns_texture = owns; } bool ownsTexture() const { return m_owns_texture; } - void setTextureId(int id); - int textureId() const override; void setTextureSize(const QSize &size) { m_texture_size = size; } QSize textureSize() const override { return m_texture_size; } @@ -85,8 +83,6 @@ public: qint64 comparisonKey() const override; - void bind() override; - QRhiTexture *rhiTexture() const override; void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override; @@ -106,7 +102,6 @@ protected: QImage m_image; - uint m_texture_id; QSize m_texture_size; QRectF m_texture_rect; QRhiTexture *m_texture; diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture_p.h b/src/quick/scenegraph/util/qsgrhiatlastexture_p.h index 0ef14c1ce0..14ef2bef42 100644 --- a/src/quick/scenegraph/util/qsgrhiatlastexture_p.h +++ b/src/quick/scenegraph/util/qsgrhiatlastexture_p.h @@ -158,8 +158,6 @@ public: ~TextureBase(); qint64 comparisonKey() const override; - int textureId() const override { return 0; } // not used - void bind() override { } // not used QRhiTexture *rhiTexture() const override; void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override; diff --git a/src/quickshapes/qquickshape.cpp b/src/quickshapes/qquickshape.cpp index 5e2cfc6622..b71e872841 100644 --- a/src/quickshapes/qquickshape.cpp +++ b/src/quickshapes/qquickshape.cpp @@ -1591,83 +1591,6 @@ QSGTexture *QQuickShapeGradientCache::get(const QQuickShapeGradientCacheKey &gra return tx; } -#if QT_CONFIG(opengl) - -// contexts sharing with each other get the same cache instance -class QQuickShapeGradientCacheWrapper -{ -public: - QQuickShapeGradientOpenGLCache *get(QOpenGLContext *context) - { - return m_resource.value<QQuickShapeGradientOpenGLCache>(context); - } - -private: - QOpenGLMultiGroupSharedResource m_resource; -}; - -QQuickShapeGradientOpenGLCache *QQuickShapeGradientOpenGLCache::currentCache() -{ - static QQuickShapeGradientCacheWrapper qt_path_gradient_caches; - return qt_path_gradient_caches.get(QOpenGLContext::currentContext()); -} - -// let QOpenGLContext manage the lifetime of the cached textures -QQuickShapeGradientOpenGLCache::~QQuickShapeGradientOpenGLCache() -{ - m_cache.clear(); -} - -void QQuickShapeGradientOpenGLCache::invalidateResource() -{ - m_cache.clear(); -} - -void QQuickShapeGradientOpenGLCache::freeResource(QOpenGLContext *) -{ - qDeleteAll(m_cache); - m_cache.clear(); -} - -QSGTexture *QQuickShapeGradientOpenGLCache::get(const QQuickShapeGradientCacheKey &grad) -{ - QSGPlainTexture *tx = m_cache[grad]; - if (!tx) { - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - GLuint id; - f->glGenTextures(1, &id); - f->glBindTexture(GL_TEXTURE_2D, id); - static const uint W = 1024; // texture size is 1024x1 - uint buf[W]; - generateGradientColorTable(grad, buf, W, 1.0f); - f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); - tx = new QSGPlainTexture; - tx->setTextureId(id); - switch (grad.spread) { - case QQuickShapeGradient::PadSpread: - tx->setHorizontalWrapMode(QSGTexture::ClampToEdge); - tx->setVerticalWrapMode(QSGTexture::ClampToEdge); - break; - case QQuickShapeGradient::RepeatSpread: - tx->setHorizontalWrapMode(QSGTexture::Repeat); - tx->setVerticalWrapMode(QSGTexture::Repeat); - break; - case QQuickShapeGradient::ReflectSpread: - tx->setHorizontalWrapMode(QSGTexture::MirroredRepeat); - tx->setVerticalWrapMode(QSGTexture::MirroredRepeat); - break; - default: - qWarning("Unknown gradient spread mode %d", grad.spread); - break; - } - tx->setFiltering(QSGTexture::Linear); - m_cache[grad] = tx; - } - return tx; -} - -#endif // QT_CONFIG(opengl) - QT_END_NAMESPACE #include "moc_qquickshape_p.cpp" diff --git a/src/quickshapes/qquickshape_p_p.h b/src/quickshapes/qquickshape_p_p.h index 7851137465..3a76f0996b 100644 --- a/src/quickshapes/qquickshape_p_p.h +++ b/src/quickshapes/qquickshape_p_p.h @@ -219,27 +219,6 @@ private: QHash<QQuickShapeGradientCacheKey, QSGPlainTexture *> m_textures; }; -#if QT_CONFIG(opengl) - -class QQuickShapeGradientOpenGLCache : public QOpenGLSharedResource -{ -public: - QQuickShapeGradientOpenGLCache(QOpenGLContext *context) : QOpenGLSharedResource(context->shareGroup()) { } - ~QQuickShapeGradientOpenGLCache(); - - void invalidateResource() override; - void freeResource(QOpenGLContext *) override; - - QSGTexture *get(const QQuickShapeGradientCacheKey &grad); - - static QQuickShapeGradientOpenGLCache *currentCache(); - -private: - QHash<QQuickShapeGradientCacheKey, QSGPlainTexture *> m_cache; -}; - -#endif // QT_CONFIG(opengl) - QT_END_NAMESPACE #endif |