diff options
author | Yevhen Kyriukha <kirgene@gmail.com> | 2017-05-21 23:02:37 +0300 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-06-23 07:37:42 +0000 |
commit | 717618d0b05b751ab155c55a6c2b03c56cffc99b (patch) | |
tree | 2a2e55b10f71e1371f89927b135c29d882e36e53 /src/quick | |
parent | aa048e7a6c4c1b72839cea95c386c6ccc12be420 (diff) |
Support external textures (samplerExternalOES) in ShaderEffect
samplerExternalOES type defined in OES_EGL_image_external extension
is used on embedded platforms to achieve zero-copy of textures.
[ChangeLog][Qt Quick] Added support for samplerExternalOES sampler
type in ShaderEffect
Task-number: QTBUG-59462
Change-Id: Ib1e864f2e1321949b0a6539d37b92d2b62541ea8
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickopenglshadereffect.cpp | 28 | ||||
-rw-r--r-- | src/quick/items/qquickopenglshadereffectnode.cpp | 15 | ||||
-rw-r--r-- | src/quick/items/qquickopenglshadereffectnode_p.h | 2 |
3 files changed, 29 insertions, 16 deletions
diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index 4fcfe04b55..c3e0ba05bd 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -230,7 +230,7 @@ void QQuickOpenGLShaderEffectCommon::disconnectPropertySignals(QQuickItem *item, auto mapper = signalMappers[shaderType].at(i); void *a = mapper; QObjectPrivate::disconnect(item, mapper->signalIndex(), &a); - if (d.specialType == UniformData::Sampler) { + if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value)); if (source) { if (item->window()) @@ -272,7 +272,7 @@ void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item, qWarning("QQuickOpenGLShaderEffect: '%s' does not have a matching property!", d.name.constData()); } - if (d.specialType == UniformData::Sampler) { + if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value)); if (source) { if (item->window()) @@ -335,6 +335,7 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, 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; @@ -357,8 +358,12 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, mapper = new QtPrivate::MappedSlotObject([this, mappedId](){ this->mappedPropertyChanged(mappedId); }); - bool sampler = typeLength == sampLen && qstrncmp("sampler2D", s + typeIndex, sampLen) == 0; - d.specialType = sampler ? UniformData::Sampler : UniformData::None; + 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); @@ -451,7 +456,8 @@ void QQuickOpenGLShaderEffectCommon::updateMaterial(QQuickOpenGLShaderEffectNode 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) + if (uniformData[shaderType].at(i).specialType == UniformData::Sampler || + uniformData[shaderType].at(i).specialType == UniformData::SamplerExternal) ++textureProviderCount; } material->uniforms[shaderType] = uniformData[shaderType]; @@ -474,7 +480,7 @@ void QQuickOpenGLShaderEffectCommon::updateMaterial(QQuickOpenGLShaderEffectNode 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) + if (d.specialType != UniformData::Sampler && d.specialType != UniformData::SamplerExternal) continue; QSGTextureProvider *oldProvider = material->textureProviders.at(index); QSGTextureProvider *newProvider = 0; @@ -513,7 +519,7 @@ void QQuickOpenGLShaderEffectCommon::updateWindow(QQuickWindow *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) { + if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value)); if (source) QQuickItemPrivate::get(source)->refWindow(window); @@ -524,7 +530,7 @@ void QQuickOpenGLShaderEffectCommon::updateWindow(QQuickWindow *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) { + if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value)); if (source) QQuickItemPrivate::get(source)->derefWindow(); @@ -539,7 +545,7 @@ 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.value.canConvert<QObject *>()) { + if ((d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) && d.value.canConvert<QObject *>()) { if (qvariant_cast<QObject *>(d.value) == object) d.value = QVariant(); } @@ -554,7 +560,7 @@ static bool qquick_uniqueInUniformData(QQuickItem *source, const QVector<QQuickO if (s == typeToSkip && i == indexToSkip) continue; const QQuickOpenGLShaderEffectMaterial::UniformData &d = uniformData[s][i]; - if (d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::Sampler && qvariant_cast<QObject *>(d.value) == source) + if ((d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::Sampler || d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::SamplerExternal) && qvariant_cast<QObject *>(d.value) == source) return false; } } @@ -568,7 +574,7 @@ void QQuickOpenGLShaderEffectCommon::propertyChanged(QQuickItem *item, Key::ShaderType shaderType = Key::ShaderType(mappedId >> 16); int index = mappedId & 0xffff; UniformData &d = uniformData[shaderType][index]; - if (d.specialType == UniformData::Sampler) { + if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value)); if (source) { if (item->window()) diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp index e1ea98641d..5dbfee73cb 100644 --- a/src/quick/items/qquickopenglshadereffectnode.cpp +++ b/src/quick/items/qquickopenglshadereffectnode.cpp @@ -47,6 +47,10 @@ #include <QtCore/qmutex.h> #include <QtGui/qopenglfunctions.h> +#ifndef GL_TEXTURE_EXTERNAL_OES +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#endif + QT_BEGIN_NAMESPACE static bool hasAtlasTexture(const QVector<QSGTextureProvider *> &textureProviders) @@ -124,7 +128,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri 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) { + 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. @@ -143,7 +147,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri 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) { + if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { int idx = textureProviderIndex++; functions->glActiveTexture(GL_TEXTURE0 + idx); if (QSGTextureProvider *provider = material->textureProviders.at(idx)) { @@ -164,7 +168,10 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri continue; } } - functions->glBindTexture(GL_TEXTURE_2D, 0); + 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) { @@ -396,7 +403,7 @@ bool QQuickOpenGLShaderEffectMaterial::UniformData::operator == (const UniformDa if (name != other.name) return false; - if (specialType == UniformData::Sampler) { + 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.. diff --git a/src/quick/items/qquickopenglshadereffectnode_p.h b/src/quick/items/qquickopenglshadereffectnode_p.h index aea28e6612..784294d9eb 100644 --- a/src/quick/items/qquickopenglshadereffectnode_p.h +++ b/src/quick/items/qquickopenglshadereffectnode_p.h @@ -90,7 +90,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectMaterial : public QSGMateri public: struct UniformData { - enum SpecialType { None, Sampler, SubRect, Opacity, Matrix }; + enum SpecialType { None, Sampler, SamplerExternal, SubRect, Opacity, Matrix }; QByteArray name; QVariant value; |