From 70dd5e24ce29adeab48932082863b3e3e3e4ba47 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 3 Jun 2020 11:18:13 +0200 Subject: Remove QQuickOpenGLShaderEffect This also removes QQuickUniformAnimator, which is not yet ported to RHI (QTBUG-83976) Task-number: QTBUG-83977 Change-Id: I3e656e6817ac991371b7f6557f050e122635d279 Reviewed-by: Eirik Aavitsland --- src/quick/CMakeLists.txt | 6 - src/quick/doc/snippets/qml/animators.qml | 86 +- src/quick/items/items.pri | 7 - src/quick/items/qquickgenericshadereffect.cpp | 2 +- src/quick/items/qquickopenglshadereffect.cpp | 996 ----------------------- src/quick/items/qquickopenglshadereffect_p.h | 197 ----- src/quick/items/qquickopenglshadereffectnode.cpp | 524 ------------ src/quick/items/qquickopenglshadereffectnode_p.h | 167 ---- src/quick/items/qquickrendercontrol.cpp | 12 +- src/quick/items/qquickshadereffect.cpp | 142 +--- src/quick/items/qquickshadereffect_p.h | 8 - src/quick/scenegraph/qsgrenderloop.cpp | 6 - src/quick/scenegraph/qsgthreadedrenderloop.cpp | 7 - src/quick/util/qquickanimator.cpp | 2 +- src/quick/util/qquickanimator_p.h | 4 +- src/quick/util/qquickanimatorjob.cpp | 20 +- src/quick/util/qquickanimatorjob_p.h | 4 +- 17 files changed, 57 insertions(+), 2133 deletions(-) delete mode 100644 src/quick/items/qquickopenglshadereffect.cpp delete mode 100644 src/quick/items/qquickopenglshadereffect_p.h delete mode 100644 src/quick/items/qquickopenglshadereffectnode.cpp delete mode 100644 src/quick/items/qquickopenglshadereffectnode_p.h (limited to 'src') diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt index c6a134b639..89ae3c7fe8 100644 --- a/src/quick/CMakeLists.txt +++ b/src/quick/CMakeLists.txt @@ -502,12 +502,6 @@ qt_extend_target(Quick CONDITION QT_FEATURE_quick_shadereffect items/qquickshadereffectsource.cpp items/qquickshadereffectsource_p.h ) -qt_extend_target(Quick CONDITION QT_FEATURE_opengl AND QT_FEATURE_quick_shadereffect - SOURCES - items/qquickopenglshadereffect.cpp items/qquickopenglshadereffect_p.h - items/qquickopenglshadereffectnode.cpp items/qquickopenglshadereffectnode_p.h -) - #### Keys ignored in scope 41:.:items:items/items.pri:QT_FEATURE_opengl: # OTHER_FILES = "$$PWD/shaders/shadereffect.vert" "$$PWD/shaders/shadereffect.frag" "$$PWD/shaders/shadereffectfallback.vert" "$$PWD/shaders/shadereffectfallback.frag" "$$PWD/shaders/shadereffect_core.vert" "$$PWD/shaders/shadereffect_core.frag" "$$PWD/shaders/shadereffectfallback_core.vert" "$$PWD/shaders/shadereffectfallback_core.frag" diff --git a/src/quick/doc/snippets/qml/animators.qml b/src/quick/doc/snippets/qml/animators.qml index a182d68ae2..87684f2792 100644 --- a/src/quick/doc/snippets/qml/animators.qml +++ b/src/quick/doc/snippets/qml/animators.qml @@ -220,50 +220,52 @@ Rectangle { } //! [opacity target] //![shaderon] -ShaderEffect { - width: 50 - height: 50 - property variant t; - UniformAnimator on t { - from: 0 - to: 1 - duration: 1000 - } - fragmentShader: - " - uniform lowp float t; - varying highp vec2 qt_TexCoord0; - void main() { - lowp float c = qt_TexCoord0.y; - gl_FragColor = vec4(c * t, 0, 0, 1); - } - " -} +// Uniform animators are not yet ported to Qt 6 +//ShaderEffect { +// width: 50 +// height: 50 +// property variant t; +// UniformAnimator on t { +// from: 0 +// to: 1 +// duration: 1000 +// } +// fragmentShader: +// " +// uniform lowp float t; +// varying highp vec2 qt_TexCoord0; +// void main() { +// lowp float c = qt_TexCoord0.y; +// gl_FragColor = vec4(c * t, 0, 0, 1); +// } +// " +//} //![shaderon] //![shader target] -ShaderEffect { - id: shader - width: 50 - height: 50 - property variant t; - UniformAnimator { - target: shader - uniform: "t" - from: 0 - to: 1 - duration: 1000 - running: true - } - fragmentShader: - " - uniform lowp float t; - varying highp vec2 qt_TexCoord0; - void main() { - lowp float c = qt_TexCoord0.y; - gl_FragColor = vec4(0, 0, c * t, 1); - } - " -} +// Uniform animators are not yet ported to Qt 6 +//ShaderEffect { +// id: shader +// width: 50 +// height: 50 +// property variant t; +// UniformAnimator { +// target: shader +// uniform: "t" +// from: 0 +// to: 1 +// duration: 1000 +// running: true +// } +// fragmentShader: +// " +// uniform lowp float t; +// varying highp vec2 qt_TexCoord0; +// void main() { +// lowp float c = qt_TexCoord0.y; +// gl_FragColor = vec4(0, 0, c * t, 1); +// } +// " +//} //![shader target] //![mixed] Rectangle { diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index aeb7e72fd0..f514c306ff 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -218,13 +218,6 @@ qtConfig(quick-shadereffect) { $$PWD/qquickgenericshadereffect.cpp qtConfig(opengl) { - SOURCES += \ - $$PWD/qquickopenglshadereffect.cpp \ - $$PWD/qquickopenglshadereffectnode.cpp - HEADERS += \ - $$PWD/qquickopenglshadereffect_p.h \ - $$PWD/qquickopenglshadereffectnode_p.h - OTHER_FILES += \ $$PWD/shaders/shadereffect.vert \ $$PWD/shaders/shadereffect.frag \ diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp index 928836e0db..6f82d94ae9 100644 --- a/src/quick/items/qquickgenericshadereffect.cpp +++ b/src/quick/items/qquickgenericshadereffect.cpp @@ -612,7 +612,7 @@ void QQuickGenericShaderEffect::updateShaderVars(Shader shaderType) if (propIdx >= 0) { if (pd && !pd->isFunction()) { if (pd->notifyIndex() == -1) { - qWarning("QQuickOpenGLShaderEffect: property '%s' does not have notification method!", v.name.constData()); + qWarning("QQuickGenericShaderEffect: property '%s' does not have notification method!", v.name.constData()); } else { auto *&mapper = m_mappers[shaderType][i]; if (!mapper) { diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp deleted file mode 100644 index 280cdbf831..0000000000 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ /dev/null @@ -1,996 +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 - -#include -#include -#include "qquickitem_p.h" - -#include -#include -#include "qquickwindow.h" - -#include "qquickimage_p.h" -#include "qquickshadereffectsource_p.h" -#include "qquickshadereffectmesh_p.h" - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -// Note: this legacy ShaderEffect implementation is used only when running -// directly with OpenGL. This is going to go away in the future (Qt 6?), since -// the RHI path uses QQuickGenericShaderEffect always. - -namespace { - - enum VariableQualifier { - AttributeQualifier, - UniformQualifier - }; - - inline bool qt_isalpha(char c) - { - char ch = c | 0x20; - return (ch >= 'a' && ch <= 'z') || c == '_'; - } - - inline bool qt_isalnum(char c) - { - return qt_isalpha(c) || (c >= '0' && c <= '9'); - } - - inline bool qt_isspace(char c) - { - return c == ' ' || (c >= 0x09 && c <= 0x0d); - } - - // Returns -1 if not found, returns index to first character after the name if found. - int qt_search_for_variable(const char *s, int length, int index, VariableQualifier &decl, - int &typeIndex, int &typeLength, - int &nameIndex, int &nameLength, - QQuickOpenGLShaderEffectCommon::Key::ShaderType shaderType) - { - enum Identifier { - QualifierIdentifier, // Base state - PrecisionIdentifier, - TypeIdentifier, - NameIdentifier - }; - Identifier expected = QualifierIdentifier; - bool compilerDirectiveExpected = index == 0; - - while (index < length) { - // Skip whitespace. - while (qt_isspace(s[index])) { - compilerDirectiveExpected |= s[index] == '\n'; - ++index; - } - - if (qt_isalpha(s[index])) { - // Read identifier. - int idIndex = index; - ++index; - while (qt_isalnum(s[index])) - ++index; - int idLength = index - idIndex; - - const int attrLen = sizeof("attribute") - 1; - const int inLen = sizeof("in") - 1; - const int uniLen = sizeof("uniform") - 1; - const int loLen = sizeof("lowp") - 1; - const int medLen = sizeof("mediump") - 1; - const int hiLen = sizeof("highp") - 1; - - switch (expected) { - case QualifierIdentifier: - if (idLength == attrLen && qstrncmp("attribute", s + idIndex, attrLen) == 0) { - decl = AttributeQualifier; - expected = PrecisionIdentifier; - } else if (shaderType == QQuickOpenGLShaderEffectCommon::Key::VertexShader - && idLength == inLen && qstrncmp("in", s + idIndex, inLen) == 0) { - decl = AttributeQualifier; - expected = PrecisionIdentifier; - } else if (idLength == uniLen && qstrncmp("uniform", s + idIndex, uniLen) == 0) { - decl = UniformQualifier; - expected = PrecisionIdentifier; - } - break; - case PrecisionIdentifier: - if ((idLength == loLen && qstrncmp("lowp", s + idIndex, loLen) == 0) - || (idLength == medLen && qstrncmp("mediump", s + idIndex, medLen) == 0) - || (idLength == hiLen && qstrncmp("highp", s + idIndex, hiLen) == 0)) - { - expected = TypeIdentifier; - break; - } - Q_FALLTHROUGH(); - case TypeIdentifier: - typeIndex = idIndex; - typeLength = idLength; - expected = NameIdentifier; - break; - case NameIdentifier: - nameIndex = idIndex; - nameLength = idLength; - return index; // Attribute or uniform declaration found. Return result. - default: - break; - } - } else if (s[index] == '#' && compilerDirectiveExpected) { - // Skip compiler directives. - ++index; - while (index < length && (s[index] != '\n' || s[index - 1] == '\\')) - ++index; - } else if (s[index] == '/' && s[index + 1] == '/') { - // Skip comments. - index += 2; - while (index < length && s[index] != '\n') - ++index; - } else if (s[index] == '/' && s[index + 1] == '*') { - // Skip comments. - index += 2; - while (index < length && (s[index] != '*' || s[index + 1] != '/')) - ++index; - if (index < length) - index += 2; // Skip star-slash. - } else { - expected = QualifierIdentifier; - ++index; - } - compilerDirectiveExpected = false; - } - return -1; - } -} - -namespace QtPrivate { -class MappedSlotObject: public QtPrivate::QSlotObjectBase -{ -public: - typedef std::function PropChangedFunc; - - explicit MappedSlotObject(PropChangedFunc f) - : QSlotObjectBase(&impl), _signalIndex(-1), func(std::move(f)) - { ref(); } - - void setSignalIndex(int idx) { _signalIndex = idx; } - int signalIndex() const { return _signalIndex; } - -private: - int _signalIndex; - PropChangedFunc func; - - static void impl(int which, QSlotObjectBase *this_, QObject *, void **a, bool *ret) - { - auto thiz = static_cast(this_); - switch (which) { - case Destroy: - delete thiz; - break; - case Call: - thiz->func(); - break; - case Compare: - *ret = thiz == reinterpret_cast(a[0]); - break; - case NumOperations: ; - } - } -}; -} - -QQuickOpenGLShaderEffectCommon::~QQuickOpenGLShaderEffectCommon() -{ - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) - clearSignalMappers(shaderType); -} - -void QQuickOpenGLShaderEffectCommon::disconnectPropertySignals(QQuickItem *item, Key::ShaderType shaderType) -{ - for (int i = 0; i < uniformData[shaderType].size(); ++i) { - if (signalMappers[shaderType].at(i) == 0) - continue; - const UniformData &d = uniformData[shaderType].at(i); - auto mapper = signalMappers[shaderType].at(i); - void *a = mapper; - QObjectPrivate::disconnect(item, mapper->signalIndex(), &a); - if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { - QQuickItem *source = qobject_cast(qvariant_cast(d.value)); - if (source) { - if (item->window()) - QQuickItemPrivate::get(source)->derefWindow(); - QObject::disconnect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*))); - } - } - } -} - -void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item, - const QMetaObject *itemMetaObject, - Key::ShaderType shaderType) -{ - auto engine = qmlEngine(item); - if (!engine) - return; - - QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(engine, item); - for (int i = 0; i < uniformData[shaderType].size(); ++i) { - if (signalMappers[shaderType].at(i) == 0) - continue; - const UniformData &d = uniformData[shaderType].at(i); - QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr); - if (pd && !pd->isFunction()) { - if (pd->notifyIndex() == -1) { - qWarning("QQuickOpenGLShaderEffect: property '%s' does not have notification method!", d.name.constData()); - } else { - auto *mapper = signalMappers[shaderType].at(i); - mapper->setSignalIndex(itemMetaObject->property(d.propertyIndex).notifySignal().methodIndex()); - Q_ASSERT(item->metaObject() == itemMetaObject); - bool ok = QObjectPrivate::connectImpl(item, pd->notifyIndex(), item, nullptr, mapper, - Qt::AutoConnection, nullptr, itemMetaObject); - if (!ok) - qWarning() << "Failed to connect to property" << itemMetaObject->property(d.propertyIndex).name() - << "(" << d.propertyIndex << ", signal index" << pd->notifyIndex() - << ") of item" << item; - } - } else { - // If the source is set via a dynamic property, like the layer is, then we need this - // check to disable the warning. - if (!item->property(d.name).isValid()) - qWarning("QQuickOpenGLShaderEffect: '%s' does not have a matching property!", d.name.constData()); - } - - if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { - QQuickItem *source = qobject_cast(qvariant_cast(d.value)); - if (source) { - if (item->window()) - QQuickItemPrivate::get(source)->refWindow(item->window()); - QObject::connect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*))); - } - } - } -} - -void QQuickOpenGLShaderEffectCommon::updateParseLog(bool ignoreAttributes) -{ - parseLog.clear(); - if (!ignoreAttributes) { - if (!attributes.contains(qtPositionAttributeName())) { - parseLog += QLatin1String("Warning: Missing reference to \'") - + QLatin1String(qtPositionAttributeName()) - + QLatin1String("\'.\n"); - } - if (!attributes.contains(qtTexCoordAttributeName())) { - parseLog += QLatin1String("Warning: Missing reference to \'") - + QLatin1String(qtTexCoordAttributeName()) - + QLatin1String("\'.\n"); - } - } - bool respectsMatrix = false; - bool respectsOpacity = false; - for (int i = 0; i < uniformData[Key::VertexShader].size(); ++i) - respectsMatrix |= uniformData[Key::VertexShader].at(i).specialType == UniformData::Matrix; - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < uniformData[shaderType].size(); ++i) - respectsOpacity |= uniformData[shaderType].at(i).specialType == UniformData::Opacity; - } - if (!respectsMatrix) - parseLog += QLatin1String("Warning: Vertex shader is missing reference to \'qt_Matrix\'.\n"); - if (!respectsOpacity) - parseLog += QLatin1String("Warning: Shaders are missing reference to \'qt_Opacity\'.\n"); -} - -void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, - const QMetaObject *itemMetaObject, - Key::ShaderType shaderType, - const QByteArray &code) -{ - auto engine = qmlEngine(item); - QQmlPropertyCache *propCache = (engine) ? QQmlData::ensurePropertyCache(engine, item) : nullptr; - int index = 0; - int typeIndex = -1; - int typeLength = 0; - int nameIndex = -1; - int nameLength = 0; - const char *s = code.constData(); - VariableQualifier decl = AttributeQualifier; - while ((index = qt_search_for_variable(s, code.size(), index, decl, typeIndex, typeLength, - nameIndex, nameLength, shaderType)) != -1) - { - if (decl == AttributeQualifier) { - if (shaderType == Key::VertexShader) - attributes.append(QByteArray(s + nameIndex, nameLength)); - } else { - Q_ASSERT(decl == UniformQualifier); - - const int sampLen = sizeof("sampler2D") - 1; - const int sampExtLen = sizeof("samplerExternalOES") - 1; - const int opLen = sizeof("qt_Opacity") - 1; - const int matLen = sizeof("qt_Matrix") - 1; - const int srLen = sizeof("qt_SubRect_") - 1; - - UniformData d; - QtPrivate::MappedSlotObject *mapper = nullptr; - d.name = QByteArray(s + nameIndex, nameLength); - if (nameLength == opLen && qstrncmp("qt_Opacity", s + nameIndex, opLen) == 0) { - d.specialType = UniformData::Opacity; - } else if (nameLength == matLen && qstrncmp("qt_Matrix", s + nameIndex, matLen) == 0) { - d.specialType = UniformData::Matrix; - } else if (nameLength > srLen && qstrncmp("qt_SubRect_", s + nameIndex, srLen) == 0) { - d.specialType = UniformData::SubRect; - } else { - if (propCache) { - if (QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr)) { - if (!pd->isFunction()) - d.propertyIndex = pd->coreIndex(); - } - } - const int mappedId = uniformData[shaderType].size() | (shaderType << 16); - mapper = new QtPrivate::MappedSlotObject([this, mappedId](){ - this->mappedPropertyChanged(mappedId); - }); - if (typeLength == sampLen && qstrncmp("sampler2D", s + typeIndex, sampLen) == 0) - d.specialType = UniformData::Sampler; - else if (typeLength == sampExtLen && qstrncmp("samplerExternalOES", s + typeIndex, sampExtLen) == 0) - d.specialType = UniformData::SamplerExternal; - else - d.specialType = UniformData::None; - d.setValueFromProperty(item, itemMetaObject); - } - uniformData[shaderType].append(d); - signalMappers[shaderType].append(mapper); - } - } -} - -void QQuickOpenGLShaderEffectCommon::updateShader(QQuickItem *item, - const QMetaObject *itemMetaObject, - Key::ShaderType shaderType) -{ - disconnectPropertySignals(item, shaderType); - uniformData[shaderType].clear(); - clearSignalMappers(shaderType); - if (shaderType == Key::VertexShader) - attributes.clear(); - - // A qrc or file URL means the shader source is to be read from the specified file. - QUrl srcUrl(QString::fromUtf8(source.sourceCode[shaderType])); - if (!srcUrl.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) || srcUrl.isLocalFile()) { - if (!fileSelector) { - fileSelector = new QFileSelector(item); - // There may not be an OpenGL context accessible here. So rely on - // the window's requestedFormat(). - if (item->window() - && item->window()->requestedFormat().profile() == QSurfaceFormat::CoreProfile) { - fileSelector->setExtraSelectors(QStringList() << QStringLiteral("glslcore")); - } - } - const QString fn = fileSelector->select(QQmlFile::urlToLocalFileOrQrc(srcUrl)); - QFile f(fn); - if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { - source.sourceCode[shaderType] = f.readAll(); - f.close(); - } else { - qWarning("ShaderEffect: Failed to read %s", qPrintable(fn)); - source.sourceCode[shaderType] = QByteArray(); - } - } - - const QByteArray &code = source.sourceCode[shaderType]; - if (code.isEmpty()) { - // Optimize for default code. - if (shaderType == Key::VertexShader) { - attributes.append(QByteArray(qtPositionAttributeName())); - attributes.append(QByteArray(qtTexCoordAttributeName())); - UniformData d; - d.name = "qt_Matrix"; - d.specialType = UniformData::Matrix; - uniformData[Key::VertexShader].append(d); - signalMappers[Key::VertexShader].append(0); - } else if (shaderType == Key::FragmentShader) { - UniformData d; - d.name = "qt_Opacity"; - d.specialType = UniformData::Opacity; - uniformData[Key::FragmentShader].append(d); - signalMappers[Key::FragmentShader].append(0); - auto mapper = new QtPrivate::MappedSlotObject([this](){ - mappedPropertyChanged(1 | (Key::FragmentShader << 16)); - }); - const char *sourceName = "source"; - d.name = sourceName; - d.setValueFromProperty(item, itemMetaObject); - d.specialType = UniformData::Sampler; - uniformData[Key::FragmentShader].append(d); - signalMappers[Key::FragmentShader].append(mapper); - } - } else { - lookThroughShaderCode(item, itemMetaObject, shaderType, code); - } - - connectPropertySignals(item, itemMetaObject, shaderType); -} - -void QQuickOpenGLShaderEffectCommon::updateMaterial(QQuickOpenGLShaderEffectNode *node, - QQuickOpenGLShaderEffectMaterial *material, - bool updateUniforms, bool updateUniformValues, - bool updateTextureProviders) -{ - if (updateUniforms) { - for (int i = 0; i < material->textureProviders.size(); ++i) { - QSGTextureProvider *t = material->textureProviders.at(i); - if (t) { - QObject::disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); - QObject::disconnect(t, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); - } - } - - // First make room in the textureProviders array. Set to proper value further down. - int textureProviderCount = 0; - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < uniformData[shaderType].size(); ++i) { - if (uniformData[shaderType].at(i).specialType == UniformData::Sampler || - uniformData[shaderType].at(i).specialType == UniformData::SamplerExternal) - ++textureProviderCount; - } - material->uniforms[shaderType] = uniformData[shaderType]; - } - material->textureProviders.fill(0, textureProviderCount); - updateUniformValues = false; - updateTextureProviders = true; - } - - if (updateUniformValues) { - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - Q_ASSERT(uniformData[shaderType].size() == material->uniforms[shaderType].size()); - for (int i = 0; i < uniformData[shaderType].size(); ++i) - material->uniforms[shaderType][i].value = uniformData[shaderType].at(i).value; - } - } - - if (updateTextureProviders) { - int index = 0; - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < uniformData[shaderType].size(); ++i) { - const UniformData &d = uniformData[shaderType].at(i); - if (d.specialType != UniformData::Sampler && d.specialType != UniformData::SamplerExternal) - continue; - QSGTextureProvider *oldProvider = material->textureProviders.at(index); - QSGTextureProvider *newProvider = nullptr; - QQuickItem *source = qobject_cast(qvariant_cast(d.value)); - if (source && source->isTextureProvider()) - newProvider = source->textureProvider(); - if (newProvider != oldProvider) { - if (oldProvider) { - QObject::disconnect(oldProvider, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); - QObject::disconnect(oldProvider, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); - } - if (newProvider) { - Q_ASSERT_X(newProvider->thread() == QThread::currentThread(), - "QQuickOpenGLShaderEffect::updatePaintNode", - "Texture provider must belong to the rendering thread"); - QObject::connect(newProvider, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture())); - QObject::connect(newProvider, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*))); - } else { - const char *typeName = source ? source->metaObject()->className() : d.value.typeName(); - qWarning("ShaderEffect: Property '%s' is not assigned a valid texture provider (%s).", - d.name.constData(), typeName); - } - material->textureProviders[index] = newProvider; - } - ++index; - } - } - Q_ASSERT(index == material->textureProviders.size()); - } -} - -void QQuickOpenGLShaderEffectCommon::updateWindow(QQuickWindow *window) -{ - // See comment in QQuickOpenGLShaderEffectCommon::propertyChanged(). - if (window) { - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < uniformData[shaderType].size(); ++i) { - const UniformData &d = uniformData[shaderType].at(i); - if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { - QQuickItem *source = qobject_cast(qvariant_cast(d.value)); - if (source) - QQuickItemPrivate::get(source)->refWindow(window); - } - } - } - } else { - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < uniformData[shaderType].size(); ++i) { - const UniformData &d = uniformData[shaderType].at(i); - if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { - QQuickItem *source = qobject_cast(qvariant_cast(d.value)); - if (source) - QQuickItemPrivate::get(source)->derefWindow(); - } - } - } - } -} - -void QQuickOpenGLShaderEffectCommon::sourceDestroyed(QObject *object) -{ - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < uniformData[shaderType].size(); ++i) { - UniformData &d = uniformData[shaderType][i]; - if ((d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) && d.value.canConvert()) { - if (qvariant_cast(d.value) == object) - d.value = QVariant(); - } - } - } -} - -static bool qquick_uniqueInUniformData(QQuickItem *source, const QVector *uniformData, int typeToSkip, int indexToSkip) -{ - for (int s=0; s(d.value) == source) - return false; - } - } - return true; -} - -void QQuickOpenGLShaderEffectCommon::propertyChanged(QQuickItem *item, - const QMetaObject *itemMetaObject, - int mappedId, bool *textureProviderChanged) -{ - Key::ShaderType shaderType = Key::ShaderType(mappedId >> 16); - int index = mappedId & 0xffff; - UniformData &d = uniformData[shaderType][index]; - if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { - QQuickItem *source = qobject_cast(qvariant_cast(d.value)); - if (source) { - if (item->window()) - QQuickItemPrivate::get(source)->derefWindow(); - - // QObject::disconnect() will disconnect all matching connections. If the same - // source has been attached to two separate samplers, then changing one of them - // would trigger both to be disconnected. Without the connection we'll end up - // with a dangling pointer in the uniformData. - if (qquick_uniqueInUniformData(source, uniformData, shaderType, index)) - QObject::disconnect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*))); - } - - d.setValueFromProperty(item, itemMetaObject); - - source = qobject_cast(qvariant_cast(d.value)); - if (source) { - // 'source' needs a window to get a scene graph node. It usually gets one through its - // parent, but if the source item is "inline" rather than a reference -- i.e. - // "property variant source: Image { }" instead of "property variant source: foo" -- it - // will not get a parent. In those cases, 'source' should get the window from 'item'. - if (item->window()) - QQuickItemPrivate::get(source)->refWindow(item->window()); - QObject::connect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*))); - } - if (textureProviderChanged) - *textureProviderChanged = true; - } else { - d.setValueFromProperty(item, itemMetaObject); - if (textureProviderChanged) - *textureProviderChanged = false; - } -} - -void QQuickOpenGLShaderEffectCommon::clearSignalMappers(int shader) -{ - for (auto mapper : qAsConst(signalMappers[shader])) { - if (mapper) - mapper->destroyIfLastRef(); - } - signalMappers[shader].clear(); -} - -QQuickOpenGLShaderEffect::QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QObject *parent) - : QObject(parent) - , m_item(item) - , m_itemMetaObject(nullptr) - , m_meshResolution(1, 1) - , m_mesh(nullptr) - , m_cullMode(QQuickShaderEffect::NoCulling) - , m_status(QQuickShaderEffect::Uncompiled) - , m_common(this, [this](int mappedId){this->propertyChanged(mappedId);}) - , m_blending(true) - , m_dirtyUniforms(true) - , m_dirtyUniformValues(true) - , m_dirtyTextureProviders(true) - , m_dirtyProgram(true) - , m_dirtyParseLog(true) - , m_dirtyMesh(true) - , m_dirtyGeometry(true) - , m_customVertexShader(false) - , m_supportsAtlasTextures(false) - , m_vertNeedsUpdate(true) - , m_fragNeedsUpdate(true) -{ -} - -QQuickOpenGLShaderEffect::~QQuickOpenGLShaderEffect() -{ - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) - m_common.disconnectPropertySignals(m_item, Key::ShaderType(shaderType)); -} - -void QQuickOpenGLShaderEffect::setFragmentShader(const QByteArray &code) -{ - if (m_common.source.sourceCode[Key::FragmentShader].constData() == code.constData()) - return; - m_common.source.sourceCode[Key::FragmentShader] = code; - m_dirtyProgram = true; - m_dirtyParseLog = true; - - m_fragNeedsUpdate = true; - if (m_item->isComponentComplete()) - maybeUpdateShaders(); - - m_item->update(); - if (m_status != QQuickShaderEffect::Uncompiled) { - m_status = QQuickShaderEffect::Uncompiled; - emit m_item->statusChanged(); - } - emit m_item->fragmentShaderChanged(); -} - -void QQuickOpenGLShaderEffect::setVertexShader(const QByteArray &code) -{ - if (m_common.source.sourceCode[Key::VertexShader].constData() == code.constData()) - return; - m_common.source.sourceCode[Key::VertexShader] = code; - m_dirtyProgram = true; - m_dirtyParseLog = true; - m_customVertexShader = true; - - m_vertNeedsUpdate = true; - if (m_item->isComponentComplete()) - maybeUpdateShaders(); - - m_item->update(); - if (m_status != QQuickShaderEffect::Uncompiled) { - m_status = QQuickShaderEffect::Uncompiled; - emit m_item->statusChanged(); - } - emit m_item->vertexShaderChanged(); -} - -void QQuickOpenGLShaderEffect::setBlending(bool enable) -{ - if (blending() == enable) - return; - - m_blending = enable; - m_item->update(); - - emit m_item->blendingChanged(); -} - -QVariant QQuickOpenGLShaderEffect::mesh() const -{ - return m_mesh ? QVariant::fromValue(static_cast(m_mesh)) - : QVariant::fromValue(m_meshResolution); -} - -void QQuickOpenGLShaderEffect::setMesh(const QVariant &mesh) -{ - QQuickShaderEffectMesh *newMesh = qobject_cast(qvariant_cast(mesh)); - if (newMesh && newMesh == m_mesh) - return; - if (m_mesh) - disconnect(m_mesh, SIGNAL(geometryChanged()), this, nullptr); - m_mesh = newMesh; - if (m_mesh) { - connect(m_mesh, SIGNAL(geometryChanged()), this, SLOT(updateGeometry())); - } else { - if (mesh.canConvert()) { - m_meshResolution = mesh.toSize(); - } else { - QList res = mesh.toByteArray().split('x'); - bool ok = res.size() == 2; - if (ok) { - int w = res.at(0).toInt(&ok); - if (ok) { - int h = res.at(1).toInt(&ok); - if (ok) - m_meshResolution = QSize(w, h); - } - } - if (!ok) - qWarning("ShaderEffect: mesh property must be size or object deriving from QQuickShaderEffectMesh."); - } - m_defaultMesh.setResolution(m_meshResolution); - } - - m_dirtyMesh = true; - m_dirtyParseLog = true; - m_item->update(); - emit m_item->meshChanged(); -} - -void QQuickOpenGLShaderEffect::setCullMode(QQuickShaderEffect::CullMode face) -{ - if (face == m_cullMode) - return; - m_cullMode = face; - m_item->update(); - emit m_item->cullModeChanged(); -} - -void QQuickOpenGLShaderEffect::setSupportsAtlasTextures(bool supports) -{ - if (supports == m_supportsAtlasTextures) - return; - m_supportsAtlasTextures = supports; - updateGeometry(); - emit m_item->supportsAtlasTexturesChanged(); -} - -QString QQuickOpenGLShaderEffect::parseLog() -{ - maybeUpdateShaders(true); - - if (m_dirtyParseLog) { - m_common.updateParseLog(m_mesh != nullptr); - m_dirtyParseLog = false; - } - return m_common.parseLog; -} - -void QQuickOpenGLShaderEffect::handleEvent(QEvent *event) -{ - if (event->type() == QEvent::DynamicPropertyChange) { - QDynamicPropertyChangeEvent *e = static_cast(event); - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < m_common.uniformData[shaderType].size(); ++i) { - if (m_common.uniformData[shaderType].at(i).name == e->propertyName()) { - bool textureProviderChanged; - m_common.propertyChanged(m_item, m_itemMetaObject, - (shaderType << 16) | i, &textureProviderChanged); - m_dirtyTextureProviders |= textureProviderChanged; - m_dirtyUniformValues = true; - m_item->update(); - } - } - } - } -} - -void QQuickOpenGLShaderEffect::updateGeometry() -{ - m_dirtyGeometry = true; - m_item->update(); -} - -void QQuickOpenGLShaderEffect::updateGeometryIfAtlased() -{ - if (m_supportsAtlasTextures) - updateGeometry(); -} - -void QQuickOpenGLShaderEffect::updateLogAndStatus(const QString &log, int status) -{ - m_log = parseLog() + log; - m_status = QQuickShaderEffect::Status(status); - emit m_item->logChanged(); - emit m_item->statusChanged(); -} - -void QQuickOpenGLShaderEffect::sourceDestroyed(QObject *object) -{ - m_common.sourceDestroyed(object); -} - -void QQuickOpenGLShaderEffect::propertyChanged(int mappedId) -{ - bool textureProviderChanged; - m_common.propertyChanged(m_item, m_itemMetaObject, mappedId, &textureProviderChanged); - m_dirtyTextureProviders |= textureProviderChanged; - m_dirtyUniformValues = true; - m_item->update(); -} - -void QQuickOpenGLShaderEffect::handleGeometryChanged(const QRectF &, const QRectF &) -{ - m_dirtyGeometry = true; -} - -QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) -{ - QQuickOpenGLShaderEffectNode *node = static_cast(oldNode); - - // In the case of zero-size or a bad vertex shader, don't try to create a node... - if (m_common.attributes.isEmpty() || m_item->width() <= 0 || m_item->height() <= 0) { - if (node) - delete node; - return nullptr; - } - - if (!node) { - node = new QQuickOpenGLShaderEffectNode; - node->setMaterial(new QQuickOpenGLShaderEffectMaterial(node)); - node->setFlag(QSGNode::OwnsMaterial, true); - m_dirtyProgram = true; - m_dirtyUniforms = true; - m_dirtyGeometry = true; - connect(node, SIGNAL(logAndStatusChanged(QString,int)), this, SLOT(updateLogAndStatus(QString,int))); - connect(node, &QQuickOpenGLShaderEffectNode::dirtyTexture, - this, &QQuickOpenGLShaderEffect::updateGeometryIfAtlased); - } - - QQuickOpenGLShaderEffectMaterial *material = static_cast(node->material()); - - // Update blending - if (bool(material->flags() & QSGMaterial::Blending) != m_blending) { - material->setFlag(QSGMaterial::Blending, m_blending); - node->markDirty(QSGNode::DirtyMaterial); - } - - if (int(material->cullMode) != int(m_cullMode)) { - material->cullMode = QQuickShaderEffect::CullMode(m_cullMode); - node->markDirty(QSGNode::DirtyMaterial); - } - - if (m_dirtyProgram) { - Key s = m_common.source; - QSGShaderSourceBuilder builder; - if (s.sourceCode[Key::FragmentShader].isEmpty()) { - builder.appendSourceFile(QStringLiteral(":/qt-project.org/items/shaders/shadereffect.frag")); - s.sourceCode[Key::FragmentShader] = builder.source(); - builder.clear(); - } - if (s.sourceCode[Key::VertexShader].isEmpty()) { - builder.appendSourceFile(QStringLiteral(":/qt-project.org/items/shaders/shadereffect.vert")); - s.sourceCode[Key::VertexShader] = builder.source(); - } - - material->setProgramSource(s); - material->attributes = m_common.attributes; - node->markDirty(QSGNode::DirtyMaterial); - m_dirtyProgram = false; - m_dirtyUniforms = true; - } - - if (m_dirtyUniforms || m_dirtyUniformValues || m_dirtyTextureProviders) { - m_common.updateMaterial(node, material, m_dirtyUniforms, m_dirtyUniformValues, - m_dirtyTextureProviders); - node->markDirty(QSGNode::DirtyMaterial); - m_dirtyUniforms = m_dirtyUniformValues = m_dirtyTextureProviders = false; - } - - QRectF srcRect(0, 0, 1, 1); - bool geometryUsesTextureSubRect = false; - if (m_supportsAtlasTextures && material->textureProviders.size() == 1) { - QSGTextureProvider *provider = material->textureProviders.at(0); - if (provider && provider->texture()) { - srcRect = provider->texture()->normalizedTextureSubRect(); - geometryUsesTextureSubRect = true; - } - } - - if (bool(material->flags() & QSGMaterial::RequiresFullMatrix) != m_customVertexShader) { - material->setFlag(QSGMaterial::RequiresFullMatrix, m_customVertexShader); - node->markDirty(QSGNode::DirtyMaterial); - } - - if (material->geometryUsesTextureSubRect != geometryUsesTextureSubRect) { - material->geometryUsesTextureSubRect = geometryUsesTextureSubRect; - node->markDirty(QSGNode::DirtyMaterial); - } - - if (m_dirtyMesh) { - node->setGeometry(nullptr); - m_dirtyMesh = false; - m_dirtyGeometry = true; - } - - if (m_dirtyGeometry) { - node->setFlag(QSGNode::OwnsGeometry, false); - QSGGeometry *geometry = node->geometry(); - QRectF rect(0, 0, m_item->width(), m_item->height()); - QQuickShaderEffectMesh *mesh = m_mesh ? m_mesh : &m_defaultMesh; - - int posIndex = 0; - if (!mesh->validateAttributes(m_common.attributes, &posIndex)) { - QString log = mesh->log(); - if (!log.isNull()) { - m_log = parseLog() + QLatin1String("*** Mesh ***\n") + log; - m_status = QQuickShaderEffect::Error; - emit m_item->logChanged(); - emit m_item->statusChanged(); - } - delete node; - return nullptr; - } - - geometry = mesh->updateGeometry(geometry, m_common.attributes.count(), posIndex, srcRect, rect); - - node->setGeometry(geometry); - node->setFlag(QSGNode::OwnsGeometry, true); - - m_dirtyGeometry = false; - } - - return node; -} - -void QQuickOpenGLShaderEffect::maybeUpdateShaders(bool force) -{ - if (!m_itemMetaObject) - m_itemMetaObject = m_item->metaObject(); - - // Defer processing if a window is not yet associated with the item. This - // is because the actual scenegraph backend is not known so conditions - // based on GraphicsInfo.shaderType and similar evaluate to wrong results. - if (!m_item->window() && !force) { - m_item->polish(); - return; - } - - if (m_vertNeedsUpdate) { - m_vertNeedsUpdate = false; - m_common.updateShader(m_item, m_itemMetaObject, Key::VertexShader); - } - - if (m_fragNeedsUpdate) { - m_fragNeedsUpdate = false; - m_common.updateShader(m_item, m_itemMetaObject, Key::FragmentShader); - } -} - -void QQuickOpenGLShaderEffect::handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) -{ - if (change == QQuickItem::ItemSceneChange) - m_common.updateWindow(value.window); -} - -QT_END_NAMESPACE - -#include "moc_qquickopenglshadereffect_p.cpp" diff --git a/src/quick/items/qquickopenglshadereffect_p.h b/src/quick/items/qquickopenglshadereffect_p.h deleted file mode 100644 index 0a2ee00115..0000000000 --- a/src/quick/items/qquickopenglshadereffect_p.h +++ /dev/null @@ -1,197 +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 QQUICKOPENGLSHADEREFFECT_P_H -#define QQUICKOPENGLSHADEREFFECT_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 - -QT_REQUIRE_CONFIG(quick_shadereffect); - -#include - -#include -#include -#include -#include -#include "qquickshadereffect_p.h" -#include "qquickshadereffectmesh_p.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -class QSGContext; -class QFileSelector; -class QQuickOpenGLCustomMaterialShader; - -namespace QtPrivate { -class MappedSlotObject; -} - -// Used by QQuickOpenGLShaderEffect. -struct Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectCommon -{ - typedef QQuickOpenGLShaderEffectMaterialKey Key; - typedef QQuickOpenGLShaderEffectMaterial::UniformData UniformData; - - QQuickOpenGLShaderEffectCommon(QObject *host, std::function mappedPropertyChanged) - : host(host), mappedPropertyChanged(mappedPropertyChanged), fileSelector(nullptr) - { } - - ~QQuickOpenGLShaderEffectCommon(); - - void disconnectPropertySignals(QQuickItem *item, Key::ShaderType shaderType); - void connectPropertySignals(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType); - void updateParseLog(bool ignoreAttributes); - void lookThroughShaderCode(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType, const QByteArray &code); - void updateShader(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType); - void updateMaterial(QQuickOpenGLShaderEffectNode *node, QQuickOpenGLShaderEffectMaterial *material, - bool updateUniforms, bool updateUniformValues, bool updateTextureProviders); - void updateWindow(QQuickWindow *window); - - // Called by slots in QQuickOpenGLShaderEffect: - void sourceDestroyed(QObject *object); - void propertyChanged(QQuickItem *item, const QMetaObject *itemMetaObject, int mappedId, bool *textureProviderChanged); - - void clearSignalMappers(int shader); - - QObject *host; - std::function mappedPropertyChanged; - Key source; - QVector attributes; - QVector uniformData[Key::ShaderTypeCount]; - QVector signalMappers[Key::ShaderTypeCount]; - QString parseLog; - QFileSelector *fileSelector; -}; - - -class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffect : public QObject -{ - Q_OBJECT - -public: - QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QObject *parent = nullptr); - ~QQuickOpenGLShaderEffect() override; - - QByteArray fragmentShader() const { return m_common.source.sourceCode[Key::FragmentShader]; } - void setFragmentShader(const QByteArray &code); - - QByteArray vertexShader() const { return m_common.source.sourceCode[Key::VertexShader]; } - void setVertexShader(const QByteArray &code); - - bool blending() const { return m_blending; } - void setBlending(bool enable); - - QVariant mesh() const; - void setMesh(const QVariant &mesh); - - QQuickShaderEffect::CullMode cullMode() const { return m_cullMode; } - void setCullMode(QQuickShaderEffect::CullMode face); - - QString log() const { return m_log; } - QQuickShaderEffect::Status status() const { return m_status; } - - bool supportsAtlasTextures() const { return m_supportsAtlasTextures; } - void setSupportsAtlasTextures(bool supports); - - QString parseLog(); - - void handleEvent(QEvent *); - void handleGeometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - QSGNode *handleUpdatePaintNode(QSGNode *, QQuickItem::UpdatePaintNodeData *); - void handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value); - void maybeUpdateShaders(bool force = false); - -private Q_SLOTS: - void updateGeometry(); - void updateGeometryIfAtlased(); - void updateLogAndStatus(const QString &log, int status); - void sourceDestroyed(QObject *object); - -private: - void propertyChanged(int mappedId); - - friend class QQuickCustomMaterialShader; - friend class QQuickOpenGLShaderEffectNode; - - typedef QQuickOpenGLShaderEffectMaterialKey Key; - typedef QQuickOpenGLShaderEffectMaterial::UniformData UniformData; - - QQuickShaderEffect *m_item; - const QMetaObject *m_itemMetaObject; - QSize m_meshResolution; - QQuickShaderEffectMesh *m_mesh; - QQuickGridMesh m_defaultMesh; - QQuickShaderEffect::CullMode m_cullMode; - QString m_log; - QQuickShaderEffect::Status m_status; - - QQuickOpenGLShaderEffectCommon m_common; - - uint m_blending : 1; - uint m_dirtyUniforms : 1; - uint m_dirtyUniformValues : 1; - uint m_dirtyTextureProviders : 1; - uint m_dirtyProgram : 1; - uint m_dirtyParseLog : 1; - uint m_dirtyMesh : 1; - uint m_dirtyGeometry : 1; - uint m_customVertexShader : 1; - uint m_supportsAtlasTextures : 1; - uint m_vertNeedsUpdate : 1; - uint m_fragNeedsUpdate : 1; -}; - -QT_END_NAMESPACE - -#endif // QQUICKOPENGLSHADEREFFECT_P_H diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp deleted file mode 100644 index 019450935f..0000000000 --- a/src/quick/items/qquickopenglshadereffectnode.cpp +++ /dev/null @@ -1,524 +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 - -#include "qquickopenglshadereffect_p.h" -#include -#include -#include -#include -#include -#include - -#ifndef GL_TEXTURE_EXTERNAL_OES -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#endif - -QT_BEGIN_NAMESPACE - -static bool hasAtlasTexture(const QVector &textureProviders) -{ - for (int i = 0; i < textureProviders.size(); ++i) { - QSGTextureProvider *t = textureProviders.at(i); - if (t && t->texture() && t->texture()->isAtlasTexture()) - return true; - } - return false; -} - -class QQuickCustomMaterialShader : public QSGMaterialShader -{ -public: - QQuickCustomMaterialShader(const QQuickOpenGLShaderEffectMaterialKey &key, const QVector &attributes); - void deactivate() override; - void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override; - char const *const *attributeNames() const override; - -protected: - friend class QQuickOpenGLShaderEffectNode; - - void compile() override; - const char *vertexShader() const override; - const char *fragmentShader() const override; - - const QQuickOpenGLShaderEffectMaterialKey m_key; - QVector m_attributes; - QVector m_attributeNames; - QString m_log; - bool m_compiled; - - QVector m_uniformLocs[QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount]; - uint m_initialized : 1; -}; - -QQuickCustomMaterialShader::QQuickCustomMaterialShader(const QQuickOpenGLShaderEffectMaterialKey &key, const QVector &attributes) - : m_key(key) - , m_attributes(attributes) - , m_compiled(false) - , m_initialized(false) -{ - const int attributesCount = m_attributes.count(); - m_attributeNames.reserve(attributesCount + 1); - for (int i = 0; i < attributesCount; ++i) - m_attributeNames.append(m_attributes.at(i).constData()); - m_attributeNames.append(0); -} - -void QQuickCustomMaterialShader::deactivate() -{ - QSGMaterialShader::deactivate(); - QOpenGLContext::currentContext()->functions()->glDisable(GL_CULL_FACE); -} - -void QQuickCustomMaterialShader::updateState(const RenderState &, QSGMaterial *newEffect, QSGMaterial *) -{ - typedef QQuickOpenGLShaderEffectMaterial::UniformData UniformData; - - Q_ASSERT(newEffect != nullptr); - - QQuickOpenGLShaderEffectMaterial *material = static_cast(newEffect); - if (!material->m_emittedLogChanged && material->m_node) { - material->m_emittedLogChanged = true; - emit material->m_node->logAndStatusChanged(m_log, m_compiled ? QQuickShaderEffect::Compiled - : QQuickShaderEffect::Error); - } - - int textureProviderIndex = 0; - if (!m_initialized) { - for (int shaderType = 0; shaderType < QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) { - Q_ASSERT(m_uniformLocs[shaderType].isEmpty()); - m_uniformLocs[shaderType].reserve(material->uniforms[shaderType].size()); - for (int i = 0; i < material->uniforms[shaderType].size(); ++i) { - const UniformData &d = material->uniforms[shaderType].at(i); - QByteArray name = d.name; - if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { - program()->setUniformValue(d.name.constData(), textureProviderIndex++); - // We don't need to store the sampler uniform locations, since their values - // only need to be set once. Look for the "qt_SubRect_" uniforms instead. - // These locations are used when binding the textures later. - name = "qt_SubRect_" + name; - } - m_uniformLocs[shaderType].append(program()->uniformLocation(name.constData())); - } - } - m_initialized = true; - textureProviderIndex = 0; - } - -#if 0 - QOpenGLFunctions *functions = state.context()->functions(); - for (int shaderType = 0; shaderType < QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) { - for (int i = 0; i < material->uniforms[shaderType].size(); ++i) { - const UniformData &d = material->uniforms[shaderType].at(i); - int loc = m_uniformLocs[shaderType].at(i); - if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { - int idx = textureProviderIndex++; - functions->glActiveTexture(GL_TEXTURE0 + idx); - if (QSGTextureProvider *provider = material->textureProviders.at(idx)) { - if (QSGTexture *texture = provider->texture()) { - -#ifndef QT_NO_DEBUG - if (!qsg_safeguard_texture(texture)) - continue; -#endif - - if (loc >= 0) { - QRectF r = texture->normalizedTextureSubRect(); - program()->setUniformValue(loc, r.x(), r.y(), r.width(), r.height()); - } else if (texture->isAtlasTexture() && !material->geometryUsesTextureSubRect) { - texture = texture->removedFromAtlas(); - } - texture->bind(); - continue; - } - } - if (d.specialType == UniformData::Sampler) - functions->glBindTexture(GL_TEXTURE_2D, 0); - else if (d.specialType == UniformData::SamplerExternal) - functions->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); - } else if (d.specialType == UniformData::Opacity) { - program()->setUniformValue(loc, state.opacity()); - } else if (d.specialType == UniformData::Matrix) { - if (state.isMatrixDirty()) - program()->setUniformValue(loc, state.combinedMatrix()); - } else if (d.specialType == UniformData::None) { - switch (int(d.value.userType())) { - case QMetaType::QColor: - program()->setUniformValue(loc, qt_premultiply_color(qvariant_cast(d.value))); - break; - case QMetaType::Float: - program()->setUniformValue(loc, qvariant_cast(d.value)); - break; - case QMetaType::Double: - program()->setUniformValue(loc, (float) qvariant_cast(d.value)); - break; - case QMetaType::QTransform: - program()->setUniformValue(loc, qvariant_cast(d.value)); - break; - case QMetaType::Int: - program()->setUniformValue(loc, d.value.toInt()); - break; - case QMetaType::Bool: - program()->setUniformValue(loc, GLint(d.value.toBool())); - break; - case QMetaType::QSize: - case QMetaType::QSizeF: - program()->setUniformValue(loc, d.value.toSizeF()); - break; - case QMetaType::QPoint: - case QMetaType::QPointF: - program()->setUniformValue(loc, d.value.toPointF()); - break; - case QMetaType::QRect: - case QMetaType::QRectF: - { - QRectF r = d.value.toRectF(); - program()->setUniformValue(loc, r.x(), r.y(), r.width(), r.height()); - } - break; - case QMetaType::QVector2D: - program()->setUniformValue(loc, qvariant_cast(d.value)); - break; - case QMetaType::QVector3D: - program()->setUniformValue(loc, qvariant_cast(d.value)); - break; - case QMetaType::QVector4D: - program()->setUniformValue(loc, qvariant_cast(d.value)); - break; - case QMetaType::QQuaternion: - { - QQuaternion q = qvariant_cast(d.value); - program()->setUniformValue(loc, q.x(), q.y(), q.z(), q.scalar()); - } - break; - case QMetaType::QMatrix4x4: - program()->setUniformValue(loc, qvariant_cast(d.value)); - break; - default: - break; - } - } - } - } - functions->glActiveTexture(GL_TEXTURE0); - - const QQuickOpenGLShaderEffectMaterial *oldMaterial = static_cast(oldEffect); - if (oldEffect == nullptr || material->cullMode != oldMaterial->cullMode) { - switch (material->cullMode) { - case QQuickShaderEffect::FrontFaceCulling: - functions->glEnable(GL_CULL_FACE); - functions->glCullFace(GL_FRONT); - break; - case QQuickShaderEffect::BackFaceCulling: - functions->glEnable(GL_CULL_FACE); - functions->glCullFace(GL_BACK); - break; - default: - functions->glDisable(GL_CULL_FACE); - break; - } - } -#endif -} - -char const *const *QQuickCustomMaterialShader::attributeNames() const -{ - return m_attributeNames.constData(); -} - -void QQuickCustomMaterialShader::compile() -{ - Q_ASSERT_X(!program()->isLinked(), "QQuickCustomMaterialShader::compile()", "Compile called multiple times!"); - - m_log.clear(); - m_compiled = true; - if (!program()->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader())) { - m_log += QLatin1String("*** Vertex shader ***\n") + program()->log(); - m_compiled = false; - } - if (!program()->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader())) { - m_log += QLatin1String("*** Fragment shader ***\n") + program()->log(); - m_compiled = false; - } - - char const *const *attr = attributeNames(); -#ifndef QT_NO_DEBUG - int maxVertexAttribs = 0; - QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); - int attrCount = 0; - while (attrCount < maxVertexAttribs && attr[attrCount]) - ++attrCount; - if (attr[attrCount]) { - qWarning("List of attribute names is too long.\n" - "Maximum number of attributes on this hardware is %i.\n" - "Vertex shader:\n%s\n" - "Fragment shader:\n%s\n", - maxVertexAttribs, vertexShader(), fragmentShader()); - } -#endif - - if (m_compiled) { -#ifndef QT_NO_DEBUG - for (int i = 0; i < attrCount; ++i) { -#else - for (int i = 0; attr[i]; ++i) { -#endif - if (*attr[i]) - program()->bindAttributeLocation(attr[i], i); - } - m_compiled = program()->link(); - m_log += program()->log(); - } - - if (!m_compiled) { - qWarning("QQuickCustomMaterialShader: Shader compilation failed:"); - qWarning() << program()->log(); - - QSGShaderSourceBuilder::initializeProgramFromFiles( - program(), - QStringLiteral(":/qt-project.org/items/shaders/shadereffectfallback.vert"), - QStringLiteral(":/qt-project.org/items/shaders/shadereffectfallback.frag")); - -#ifndef QT_NO_DEBUG - for (int i = 0; i < attrCount; ++i) { -#else - for (int i = 0; attr[i]; ++i) { -#endif - if (qstrcmp(attr[i], qtPositionAttributeName()) == 0) - program()->bindAttributeLocation("v", i); - } - program()->link(); - } -} - -const char *QQuickCustomMaterialShader::vertexShader() const -{ - return m_key.sourceCode[QQuickOpenGLShaderEffectMaterialKey::VertexShader].constData(); -} - -const char *QQuickCustomMaterialShader::fragmentShader() const -{ - return m_key.sourceCode[QQuickOpenGLShaderEffectMaterialKey::FragmentShader].constData(); -} - - -bool QQuickOpenGLShaderEffectMaterialKey::operator == (const QQuickOpenGLShaderEffectMaterialKey &other) const -{ - for (int shaderType = 0; shaderType < ShaderTypeCount; ++shaderType) { - if (sourceCode[shaderType] != other.sourceCode[shaderType]) - return false; - } - return true; -} - -bool QQuickOpenGLShaderEffectMaterialKey::operator != (const QQuickOpenGLShaderEffectMaterialKey &other) const -{ - return !(*this == other); -} - -size_t qHash(const QQuickOpenGLShaderEffectMaterialKey &key) -{ - size_t hash = 1; - typedef QQuickOpenGLShaderEffectMaterialKey Key; - for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) - hash = hash * 31337 + qHash(key.sourceCode[shaderType]); - return hash; -} - -class QQuickOpenGLShaderEffectMaterialCache : public QObject -{ - Q_OBJECT -public: - static QQuickOpenGLShaderEffectMaterialCache *get(bool create = true) { - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - QQuickOpenGLShaderEffectMaterialCache *me = ctx->findChild(QStringLiteral("__qt_ShaderEffectCache"), Qt::FindDirectChildrenOnly); - if (!me && create) { - me = new QQuickOpenGLShaderEffectMaterialCache(); - me->setObjectName(QStringLiteral("__qt_ShaderEffectCache")); - me->setParent(ctx); - } - return me; - } - QHash cache; -}; - -QQuickOpenGLShaderEffectMaterial::QQuickOpenGLShaderEffectMaterial(QQuickOpenGLShaderEffectNode *node) - : cullMode(QQuickShaderEffect::NoCulling) - , geometryUsesTextureSubRect(false) - , m_node(node) - , m_emittedLogChanged(false) -{ - setFlag(Blending | RequiresFullMatrix, true); -} - -QSGMaterialType *QQuickOpenGLShaderEffectMaterial::type() const -{ - return m_type; -} - -QSGMaterialShader *QQuickOpenGLShaderEffectMaterial::createShader() const -{ - return new QQuickCustomMaterialShader(m_source, attributes); -} - -bool QQuickOpenGLShaderEffectMaterial::UniformData::operator == (const UniformData &other) const -{ - if (specialType != other.specialType) - return false; - if (name != other.name) - return false; - - if (specialType == UniformData::Sampler || specialType == UniformData::SamplerExternal) { - // We can't check the source objects as these live in the GUI thread, - // so return true here and rely on the textureProvider check for - // equality of these.. - return true; - } else { - return value == other.value; - } -} - -int QQuickOpenGLShaderEffectMaterial::compare(const QSGMaterial *o) const -{ - const QQuickOpenGLShaderEffectMaterial *other = static_cast(o); - if ((hasAtlasTexture(textureProviders) && !geometryUsesTextureSubRect) || (hasAtlasTexture(other->textureProviders) && !other->geometryUsesTextureSubRect)) - return 1; - if (cullMode != other->cullMode) - return 1; - for (int shaderType = 0; shaderType < QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) { - if (uniforms[shaderType] != other->uniforms[shaderType]) - return 1; - } - - // Check the texture providers.. - if (textureProviders.size() != other->textureProviders.size()) - return 1; - for (int i=0; itextureProviders.at(i); - if (!tp1 || !tp2) - return tp1 == tp2 ? 0 : 1; - QSGTexture *t1 = tp1->texture(); - QSGTexture *t2 = tp2->texture(); - if (!t1 || !t2) - return t1 == t2 ? 0 : 1; - // Check texture id's as textures may be in the same atlas. - if (t1->textureId() != t2->textureId()) - return 1; - } - return 0; -} - -void QQuickOpenGLShaderEffectMaterial::setProgramSource(const QQuickOpenGLShaderEffectMaterialKey &source) -{ - m_source = source; - m_emittedLogChanged = false; - - QQuickOpenGLShaderEffectMaterialCache *cache = QQuickOpenGLShaderEffectMaterialCache::get(); - m_type = cache->cache.value(m_source); - if (!m_type) { - m_type = new QSGMaterialType(); - cache->cache.insert(source, m_type); - } -} - -void QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache() -{ - QQuickOpenGLShaderEffectMaterialCache *cache = QQuickOpenGLShaderEffectMaterialCache::get(false); - if (cache) { - qDeleteAll(cache->cache); - delete cache; - } -} - -void QQuickOpenGLShaderEffectMaterial::updateTextures() const -{ - for (int i = 0; i < textureProviders.size(); ++i) { - if (QSGTextureProvider *provider = textureProviders.at(i)) { - if (QSGDynamicTexture *texture = qobject_cast(provider->texture())) - texture->updateTexture(); - } - } -} - -void QQuickOpenGLShaderEffectMaterial::invalidateTextureProvider(const QObject *provider) -{ - for (int i = 0; i < textureProviders.size(); ++i) { - if (provider == textureProviders.at(i)) - textureProviders[i] = nullptr; - } -} - - -QQuickOpenGLShaderEffectNode::QQuickOpenGLShaderEffectNode() -{ - QSGNode::setFlag(UsePreprocess, true); - -#ifdef QSG_RUNTIME_DESCRIPTION - qsgnode_set_description(this, QLatin1String("shadereffect")); -#endif -} - -QQuickOpenGLShaderEffectNode::~QQuickOpenGLShaderEffectNode() -{ -} - -void QQuickOpenGLShaderEffectNode::markDirtyTexture() -{ - markDirty(DirtyMaterial); - Q_EMIT dirtyTexture(); -} - -void QQuickOpenGLShaderEffectNode::textureProviderDestroyed(QObject *object) -{ - Q_ASSERT(material()); - static_cast(material())->invalidateTextureProvider(object); -} - -void QQuickOpenGLShaderEffectNode::preprocess() -{ - Q_ASSERT(material()); - static_cast(material())->updateTextures(); -} - -#include "qquickopenglshadereffectnode.moc" -#include "moc_qquickopenglshadereffectnode_p.cpp" - -QT_END_NAMESPACE diff --git a/src/quick/items/qquickopenglshadereffectnode_p.h b/src/quick/items/qquickopenglshadereffectnode_p.h deleted file mode 100644 index 377c34eb95..0000000000 --- a/src/quick/items/qquickopenglshadereffectnode_p.h +++ /dev/null @@ -1,167 +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 QQUICKOPENGLSHADEREFFECTNODE_P_H -#define QQUICKOPENGLSHADEREFFECTNODE_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 - -QT_REQUIRE_CONFIG(quick_shadereffect); - -#include -#include -#include -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -struct QQuickOpenGLShaderEffectMaterialKey { - enum ShaderType - { - VertexShader, - FragmentShader, - ShaderTypeCount - }; - - QByteArray sourceCode[ShaderTypeCount]; - - bool operator == (const QQuickOpenGLShaderEffectMaterialKey &other) const; - bool operator != (const QQuickOpenGLShaderEffectMaterialKey &other) const; -}; - -size_t qHash(const QQuickOpenGLShaderEffectMaterialKey &key); - -class QQuickCustomMaterialShader; -class QQuickOpenGLShaderEffectNode; -class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectMaterial : public QSGMaterial -{ -public: - struct UniformData - { - enum SpecialType { None, Sampler, SamplerExternal, SubRect, Opacity, Matrix }; - - QByteArray name; - QVariant value; - int propertyIndex = -1; - SpecialType specialType; - - bool operator == (const UniformData &other) const; - - void setValueFromProperty(QObject *item, const QMetaObject *itemMetaObject) - { - if (propertyIndex == -1) { - value = item->property(name); - } else { - value = itemMetaObject->property(propertyIndex).read(item); - } - } - }; - - explicit QQuickOpenGLShaderEffectMaterial(QQuickOpenGLShaderEffectNode *node = nullptr); - QSGMaterialType *type() const override; - QSGMaterialShader *createShader() const override; - int compare(const QSGMaterial *other) const override; - - QVector attributes; - QVector uniforms[QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount]; - QVector textureProviders; - QQuickShaderEffect::CullMode cullMode; - bool geometryUsesTextureSubRect; - - void setProgramSource(const QQuickOpenGLShaderEffectMaterialKey &source); - void updateTextures() const; - void invalidateTextureProvider(const QObject *provider); - - static void cleanupMaterialCache(); - -protected: - friend class QQuickCustomMaterialShader; - - // Each material needs a unique type to ensure that the renderer has a one - // and exactly one GL program for every unique set of shader sources. - // setProgramSource() stores the sources in a cache along with the right - // type. The type is cleaned up in cleanupMaterialCache() which is called - // when the GL context is shut down. - QSGMaterialType *m_type; - QQuickOpenGLShaderEffectMaterialKey m_source; - - QQuickOpenGLShaderEffectNode *m_node; - bool m_emittedLogChanged; -}; - - -class QSGShaderEffectMesh; - -class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectNode : public QObject, public QSGGeometryNode -{ - Q_OBJECT -public: - QQuickOpenGLShaderEffectNode(); - ~QQuickOpenGLShaderEffectNode() override; - - void preprocess() override; - -Q_SIGNALS: - void logAndStatusChanged(const QString &, int status); - void dirtyTexture(); - -private Q_SLOTS: - void markDirtyTexture(); - void textureProviderDestroyed(QObject *object); -}; - -QT_END_NAMESPACE - -#endif // QQUICKOPENGLSHADEREFFECTNODE_P_H diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index 79cf8b73bc..6a84f55578 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -46,11 +46,10 @@ #include #include +#include + #if QT_CONFIG(opengl) # include -#if QT_CONFIG(quick_shadereffect) -# include -#endif #endif #include #include @@ -207,12 +206,9 @@ void QQuickRenderControlPrivate::windowDestroyed() rc->invalidate(); QQuickWindowPrivate::get(window)->animationController.reset(); - -#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) - if (QOpenGLContext::currentContext()) - QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); +#if QT_CONFIG(quick_shadereffect) + QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); #endif - window = nullptr; } } diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index dee997b22d..7a37410faa 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -40,9 +40,6 @@ #include #include #include -#if QT_CONFIG(opengl) -#include -#endif #include #if QT_CONFIG(opengl) /* || QT_CONFIG(vulkan) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) */ #include @@ -299,38 +296,17 @@ QSGContextFactoryInterface::Flags qsg_backend_flags(); QQuickShaderEffect::QQuickShaderEffect(QQuickItem *parent) : QQuickItem(*new QQuickShaderEffectPrivate, parent), -#if QT_CONFIG(opengl) - m_glImpl(nullptr), -#endif m_impl(nullptr) { setFlag(QQuickItem::ItemHasContents); -#if QT_CONFIG(opengl) /* || QT_CONFIG(vulkan) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) */ - if (QSGRhiSupport::instance()->isRhiEnabled()) { - m_impl = new QQuickGenericShaderEffect(this, this); - } else -#endif - { -#if QT_CONFIG(opengl) - if (!qsg_backend_flags().testFlag(QSGContextFactoryInterface::SupportsShaderEffectNode)) - m_glImpl = new QQuickOpenGLShaderEffect(this, this); - - if (!m_glImpl) -#endif - m_impl = new QQuickGenericShaderEffect(this, this); - } + m_impl = new QQuickGenericShaderEffect(this, this); } QQuickShaderEffect::~QQuickShaderEffect() { // Delete the implementations now, while they still have have // valid references back to us. -#if QT_CONFIG(opengl) - auto *glImpl = m_glImpl; - m_glImpl = nullptr; - delete glImpl; -#endif auto *impl = m_impl; m_impl = nullptr; delete impl; @@ -356,21 +332,11 @@ QQuickShaderEffect::~QQuickShaderEffect() QByteArray QQuickShaderEffect::fragmentShader() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->fragmentShader(); -#endif return m_impl->fragmentShader(); } void QQuickShaderEffect::setFragmentShader(const QByteArray &code) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->setFragmentShader(code); - return; - } -#endif m_impl->setFragmentShader(code); } @@ -393,21 +359,11 @@ void QQuickShaderEffect::setFragmentShader(const QByteArray &code) QByteArray QQuickShaderEffect::vertexShader() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->vertexShader(); -#endif return m_impl->vertexShader(); } void QQuickShaderEffect::setVertexShader(const QByteArray &code) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->setVertexShader(code); - return; - } -#endif m_impl->setVertexShader(code); } @@ -422,21 +378,11 @@ void QQuickShaderEffect::setVertexShader(const QByteArray &code) bool QQuickShaderEffect::blending() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->blending(); -#endif return m_impl->blending(); } void QQuickShaderEffect::setBlending(bool enable) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->setBlending(enable); - return; - } -#endif m_impl->setBlending(enable); } @@ -455,21 +401,11 @@ void QQuickShaderEffect::setBlending(bool enable) QVariant QQuickShaderEffect::mesh() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->mesh(); -#endif return m_impl->mesh(); } void QQuickShaderEffect::setMesh(const QVariant &mesh) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->setMesh(mesh); - return; - } -#endif m_impl->setMesh(mesh); } @@ -489,21 +425,11 @@ void QQuickShaderEffect::setMesh(const QVariant &mesh) QQuickShaderEffect::CullMode QQuickShaderEffect::cullMode() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->cullMode(); -#endif return m_impl->cullMode(); } void QQuickShaderEffect::setCullMode(CullMode face) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->setCullMode(face); - return; - } -#endif return m_impl->setCullMode(face); } @@ -530,21 +456,11 @@ void QQuickShaderEffect::setCullMode(CullMode face) bool QQuickShaderEffect::supportsAtlasTextures() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->supportsAtlasTextures(); -#endif return m_impl->supportsAtlasTextures(); } void QQuickShaderEffect::setSupportsAtlasTextures(bool supports) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->setSupportsAtlasTextures(supports); - return; - } -#endif m_impl->setSupportsAtlasTextures(supports); } @@ -586,30 +502,16 @@ void QQuickShaderEffect::setSupportsAtlasTextures(bool supports) QString QQuickShaderEffect::log() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->log(); -#endif return m_impl->log(); } QQuickShaderEffect::Status QQuickShaderEffect::status() const { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->status(); -#endif return m_impl->status(); } bool QQuickShaderEffect::event(QEvent *e) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->handleEvent(e); - return QQuickItem::event(e); - } -#endif if (m_impl) m_impl->handleEvent(e); return QQuickItem::event(e); @@ -617,48 +519,23 @@ bool QQuickShaderEffect::event(QEvent *e) void QQuickShaderEffect::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->handleGeometryChanged(newGeometry, oldGeometry); - QQuickItem::geometryChange(newGeometry, oldGeometry); - return; - } -#endif m_impl->handleGeometryChanged(newGeometry, oldGeometry); QQuickItem::geometryChange(newGeometry, oldGeometry); } QSGNode *QQuickShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->handleUpdatePaintNode(oldNode, updatePaintNodeData); -#endif return m_impl->handleUpdatePaintNode(oldNode, updatePaintNodeData); } void QQuickShaderEffect::componentComplete() { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->maybeUpdateShaders(); - QQuickItem::componentComplete(); - return; - } -#endif m_impl->maybeUpdateShaders(); QQuickItem::componentComplete(); } void QQuickShaderEffect::itemChange(ItemChange change, const ItemChangeData &value) { -#if QT_CONFIG(opengl) - if (m_glImpl) { - m_glImpl->handleItemChange(change, value); - QQuickItem::itemChange(change, value); - return; - } -#endif m_impl->handleItemChange(change, value); QQuickItem::itemChange(change, value); } @@ -670,10 +547,6 @@ bool QQuickShaderEffect::isComponentComplete() const QString QQuickShaderEffect::parseLog() // for OpenGL-based autotests { -#if QT_CONFIG(opengl) - if (m_glImpl) - return m_glImpl->parseLog(); -#endif return m_impl->parseLog(); } @@ -682,22 +555,9 @@ void QQuickShaderEffectPrivate::updatePolish() Q_Q(QQuickShaderEffect); if (!qmlEngine(q)) return; -#if QT_CONFIG(opengl) - if (q->m_glImpl) { - q->m_glImpl->maybeUpdateShaders(); - return; - } -#endif q->m_impl->maybeUpdateShaders(); } -#if QT_CONFIG(opengl) -bool QQuickShaderEffect::isOpenGLShaderEffect() const -{ - return m_glImpl != nullptr; -} -#endif - QT_END_NAMESPACE #include "moc_qquickshadereffect_p.cpp" diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h index b3d5473ae4..504a1efcf1 100644 --- a/src/quick/items/qquickshadereffect_p.h +++ b/src/quick/items/qquickshadereffect_p.h @@ -60,7 +60,6 @@ QT_REQUIRE_CONFIG(quick_shadereffect); QT_BEGIN_NAMESPACE -class QQuickOpenGLShaderEffect; class QQuickGenericShaderEffect; class QQuickShaderEffectPrivate; @@ -120,10 +119,6 @@ public: bool isComponentComplete() const; QString parseLog(); -#if QT_CONFIG(opengl) - bool isOpenGLShaderEffect() const; -#endif - Q_SIGNALS: void fragmentShaderChanged(); void vertexShaderChanged(); @@ -142,9 +137,6 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value) override; private: -#if QT_CONFIG(opengl) - QQuickOpenGLShaderEffect *m_glImpl; -#endif QQuickGenericShaderEffect *m_impl; Q_DECLARE_PRIVATE(QQuickShaderEffect) diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 6dd700630c..c2b1550689 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -66,9 +66,6 @@ #if QT_CONFIG(opengl) #include -#if QT_CONFIG(quick_shadereffect) -#include -#endif #include #endif @@ -406,9 +403,6 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) #if QT_CONFIG(quick_shadereffect) QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); -#if QT_CONFIG(opengl) - QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); -#endif #endif if (d->swapchain) { diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 76f65e5f85..6237114f0e 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -65,9 +65,6 @@ #include #include -#if QT_CONFIG(quick_shadereffect) -#include -#endif #include #include @@ -550,10 +547,6 @@ void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor #if QT_CONFIG(quick_shadereffect) QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); -#if QT_CONFIG(opengl) - if (current) - QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); -#endif #endif // The canvas nodes must be cleaned up regardless if we are in the destructor.. diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp index d1ff78f8bc..3a7c3ef808 100644 --- a/src/quick/util/qquickanimator.cpp +++ b/src/quick/util/qquickanimator.cpp @@ -504,7 +504,7 @@ QQuickRotationAnimator::RotationDirection QQuickRotationAnimator::direction() co return d->direction; } -#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) +#if 0 // QTBUG-83976 /*! \qmltype UniformAnimator \instantiates QQuickUniformAnimator diff --git a/src/quick/util/qquickanimator_p.h b/src/quick/util/qquickanimator_p.h index 0bcf4c40a4..a7c219ce1a 100644 --- a/src/quick/util/qquickanimator_p.h +++ b/src/quick/util/qquickanimator_p.h @@ -184,7 +184,7 @@ protected: QString propertyName() const override { return QStringLiteral("rotation"); } }; -#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) +#if 0 // QTBUG-83976 class QQuickUniformAnimatorPrivate; class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimator : public QQuickAnimator { @@ -217,7 +217,7 @@ QML_DECLARE_TYPE(QQuickYAnimator) QML_DECLARE_TYPE(QQuickScaleAnimator) QML_DECLARE_TYPE(QQuickRotationAnimator) QML_DECLARE_TYPE(QQuickOpacityAnimator) -#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) +#if 0 // QTBUG-83976 QML_DECLARE_TYPE(QQuickUniformAnimator) #endif #endif // QQUICKANIMATOR_P_H diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 8879ef1e57..b46e2db258 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -43,7 +43,7 @@ #include "qquickanimator_p.h" #include "qquickanimator_p_p.h" #include -#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) +#if 0 // QTBUG-83976 # include # include # include @@ -431,9 +431,6 @@ void QQuickXAnimatorJob::writeBack() void QQuickXAnimatorJob::updateCurrentTime(int time) { -#if QT_CONFIG(opengl) - Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); -#endif if (!m_helper) return; @@ -450,9 +447,6 @@ void QQuickYAnimatorJob::writeBack() void QQuickYAnimatorJob::updateCurrentTime(int time) { -#if QT_CONFIG(opengl) - Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); -#endif if (!m_helper) return; @@ -469,9 +463,6 @@ void QQuickScaleAnimatorJob::writeBack() void QQuickScaleAnimatorJob::updateCurrentTime(int time) { -#if QT_CONFIG(opengl) - Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); -#endif if (!m_helper) return; @@ -492,9 +483,6 @@ extern QVariant _q_interpolateCounterclockwiseRotation(qreal &f, qreal &t, qreal void QQuickRotationAnimatorJob::updateCurrentTime(int time) { -#if QT_CONFIG(opengl) - Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); -#endif if (!m_helper) return; @@ -600,10 +588,6 @@ void QQuickOpacityAnimatorJob::writeBack() void QQuickOpacityAnimatorJob::updateCurrentTime(int time) { -#if QT_CONFIG(opengl) - Q_ASSERT(!m_controller || !m_controller->m_window->openglContext() || m_controller->m_window->openglContext()->thread() == QThread::currentThread()); -#endif - if (!m_opacityNode) return; @@ -612,7 +596,7 @@ void QQuickOpacityAnimatorJob::updateCurrentTime(int time) } -#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) +#if 0 // QTBUG-83976 QQuickUniformAnimatorJob::QQuickUniformAnimatorJob() : m_node(nullptr) , m_uniformIndex(-1) diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index 74085526c0..eaec1946ba 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -69,7 +69,7 @@ class QQuickAbstractAnimation; class QQuickAnimatorController; class QQuickAnimatorProxyJobPrivate; -class QQuickOpenGLShaderEffectNode; +class QQuickShaderEffectNode; class QSGOpacityNode; @@ -289,7 +289,7 @@ public: private: QSGOpacityNode *m_opacityNode; }; -#if QT_CONFIG(opengl) +#if 0 // QTBUG-83976 class Q_QUICK_PRIVATE_EXPORT QQuickUniformAnimatorJob : public QQuickAnimatorJob { public: -- cgit v1.2.3