From 48cc0fde46328ec771d4610f8c13441b04530cab Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Mon, 22 Jun 2020 17:05:19 +0200 Subject: IMX: Prepare vivante plugin for RHI Task-number: QTBUG-78678 Change-Id: I61a62b71f5731949a7e1094efc854bd3d7d1aa6a Reviewed-by: Laszlo Agocs --- src/plugins/videonode/imx6/imx6.pro | 3 + src/plugins/videonode/imx6/imx6.qrc | 6 ++ .../videonode/imx6/qsgvivantevideomaterial.cpp | 3 +- .../videonode/imx6/qsgvivantevideomaterial.h | 10 ++- .../imx6/qsgvivantevideomaterialshader.cpp | 93 +++++++++------------ .../videonode/imx6/qsgvivantevideomaterialshader.h | 16 +--- src/plugins/videonode/imx6/shaders/compile.bat | 41 +++++++++ src/plugins/videonode/imx6/shaders/rgba.frag | 18 ++++ src/plugins/videonode/imx6/shaders/rgba.frag.qsb | Bin 0 -> 1771 bytes src/plugins/videonode/imx6/shaders/rgba.vert | 20 +++++ src/plugins/videonode/imx6/shaders/rgba.vert.qsb | Bin 0 -> 1909 bytes src/qtmultimediaquicktools/qsgvideotexture_p.h | 3 +- 12 files changed, 141 insertions(+), 72 deletions(-) create mode 100644 src/plugins/videonode/imx6/imx6.qrc create mode 100755 src/plugins/videonode/imx6/shaders/compile.bat create mode 100644 src/plugins/videonode/imx6/shaders/rgba.frag create mode 100644 src/plugins/videonode/imx6/shaders/rgba.frag.qsb create mode 100644 src/plugins/videonode/imx6/shaders/rgba.vert create mode 100644 src/plugins/videonode/imx6/shaders/rgba.vert.qsb diff --git a/src/plugins/videonode/imx6/imx6.pro b/src/plugins/videonode/imx6/imx6.pro index 0e9ed8b73..4b2a2e720 100644 --- a/src/plugins/videonode/imx6/imx6.pro +++ b/src/plugins/videonode/imx6/imx6.pro @@ -19,6 +19,9 @@ SOURCES += \ OTHER_FILES += \ imx6.json +RESOURCES += \ + imx6.qrc + PLUGIN_TYPE = video/videonode PLUGIN_EXTENDS = quick PLUGIN_CLASS_NAME = QSGVivanteVideoNodeFactory diff --git a/src/plugins/videonode/imx6/imx6.qrc b/src/plugins/videonode/imx6/imx6.qrc new file mode 100644 index 000000000..c64fa4c64 --- /dev/null +++ b/src/plugins/videonode/imx6/imx6.qrc @@ -0,0 +1,6 @@ + + + shaders/rgba.vert.qsb + shaders/rgba.frag.qsb + + diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp index e200e8d16..2e6c712e3 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp @@ -43,6 +43,7 @@ #include "qsgvivantevideomaterial.h" #include "qsgvivantevideomaterialshader.h" #include "qsgvivantevideonode.h" +#include "private/qsgvideotexture_p.h" #include #include @@ -83,7 +84,7 @@ QSGMaterialType *QSGVivanteVideoMaterial::type() const { return &theType; } -QSGMaterialShader *QSGVivanteVideoMaterial::createShader() const { +QSGMaterialShader *QSGVivanteVideoMaterial::createShader(QSGRendererInterface::RenderMode) const { return mShader; } diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.h b/src/plugins/videonode/imx6/qsgvivantevideomaterial.h index db59e8fc7..10fd5447f 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterial.h +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.h @@ -50,16 +50,16 @@ #include class QSGVivanteVideoMaterialShader; - +class QSGVideoTexture; class QSGVivanteVideoMaterial : public QSGMaterial { public: QSGVivanteVideoMaterial(); ~QSGVivanteVideoMaterial(); - virtual QSGMaterialType *type() const; - virtual QSGMaterialShader *createShader() const; - virtual int compare(const QSGMaterial *other) const; + QSGMaterialType *type() const override; + QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override; + int compare(const QSGMaterial *other) const override; void updateBlending(); void setCurrentFrame(const QVideoFrame &frame, QSGVideoNode::FrameFlags flags); @@ -81,6 +81,7 @@ private: QVideoFrame mCurrentFrame; GLuint mCurrentTexture; bool mMappable; + QScopedPointer mTexture; GLenum mMapError = GL_NO_ERROR; QMutex mFrameMutex; @@ -89,6 +90,7 @@ private: GLvoid *mTexDirectPlanes[3]; QSGVivanteVideoMaterialShader *mShader; + friend class QSGVivanteVideoMaterialShader; }; #endif // QSGVIDEOMATERIAL_VIVMAP_H diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp index 0d5467c6f..9e529c3df 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.cpp @@ -40,42 +40,63 @@ #include "qsgvivantevideomaterialshader.h" #include "qsgvivantevideonode.h" #include "qsgvivantevideomaterial.h" +#include "private/qsgvideotexture_p.h" QSGVivanteVideoMaterialShader::QSGVivanteVideoMaterialShader() : mUScale(1), mVScale(1), mNewUVScale(true) { + setShaderFileName(VertexStage, QStringLiteral(":/imx6/shaders/rgba.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/imx6/shaders/rgba.frag.qsb")); } -void QSGVivanteVideoMaterialShader::updateState(const RenderState &state, - QSGMaterial *newMaterial, - QSGMaterial *oldMaterial) +bool QSGVivanteVideoMaterialShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) { Q_UNUSED(oldMaterial); - QSGVivanteVideoMaterial *mat = static_cast(newMaterial); - program()->setUniformValue(mIdTexture, 0); - mat->bind(); + bool changed = false; + QByteArray *buf = state.uniformData(); + + if (state.isMatrixDirty()) { + memcpy(buf->data(), state.combinedMatrix().constData(), 64); + changed = true; + } + if (state.isOpacityDirty()) { - mat->setOpacity(state.opacity()); - program()->setUniformValue(mIdOpacity, state.opacity()); + auto m = static_cast(newMaterial); + m->mOpacity = state.opacity(); + memcpy(buf->data() + 64, &m->mOpacity, 4); + changed = true; } + if (mNewUVScale) { - program()->setUniformValue(mIdUVScale, mUScale, mVScale); + memcpy(buf->data() + 64 + 4, &mUScale, 4); + memcpy(buf->data() + 64 + 4 + 4, &mVScale, 4); + changed = true; mNewUVScale = false; } - if (state.isMatrixDirty()) - program()->setUniformValue(mIdMatrix, state.combinedMatrix()); + + return changed; } -const char * const *QSGVivanteVideoMaterialShader::attributeNames() const { - static const char *names[] = { - "qt_VertexPosition", - "qt_VertexTexCoord", - 0 - }; - return names; +void QSGVivanteVideoMaterialShader::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + + if (binding < 1) + return; + + auto m = static_cast(newMaterial); + if (!m->mTexture) + m->mTexture.reset(new QSGVideoTexture); + + m->bind(); + m->mTexture->setNativeObject(m->mCurrentTexture, m->mCurrentFrame.size()); + m->mTexture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); + *texture = m->mTexture.data(); } void QSGVivanteVideoMaterialShader::setUVScale(float uScale, float vScale) @@ -84,39 +105,3 @@ void QSGVivanteVideoMaterialShader::setUVScale(float uScale, float vScale) mVScale = vScale; mNewUVScale = true; } - -const char *QSGVivanteVideoMaterialShader::vertexShader() const { - static const char *shader = - "uniform highp mat4 qt_Matrix; \n" - "attribute highp vec4 qt_VertexPosition; \n" - "attribute highp vec2 qt_VertexTexCoord; \n" - "varying highp vec2 qt_TexCoord; \n" - "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" - " gl_Position = qt_Matrix * qt_VertexPosition; \n" - "}"; - return shader; -} - -const char *QSGVivanteVideoMaterialShader::fragmentShader() const { - static const char *shader = - "uniform sampler2D texture;" - "uniform lowp float opacity;" - "uniform highp vec2 uvScale;" - "" - "varying highp vec2 qt_TexCoord;" - "" - "void main()" - "{" - " gl_FragColor = vec4(texture2D( texture, qt_TexCoord * uvScale ).rgb, 1.0) * opacity;\n" - "}"; - return shader; -} - - -void QSGVivanteVideoMaterialShader::initialize() { - mIdMatrix = program()->uniformLocation("qt_Matrix"); - mIdTexture = program()->uniformLocation("texture"); - mIdOpacity = program()->uniformLocation("opacity"); - mIdUVScale = program()->uniformLocation("uvScale"); -} diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h index 2be8ec55f..b0e19d28e 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterialshader.h @@ -47,22 +47,14 @@ class QSGVivanteVideoMaterialShader : public QSGMaterialShader public: QSGVivanteVideoMaterialShader(); - void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial); - virtual char const *const *attributeNames() const; + bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) override; + void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; void setUVScale(float uScale, float vScale); -protected: - virtual const char *vertexShader() const; - virtual const char *fragmentShader() const; - virtual void initialize(); - private: - int mIdMatrix; - int mIdTexture; - int mIdOpacity; - int mIdUVScale; - float mUScale; float mVScale; bool mNewUVScale; diff --git a/src/plugins/videonode/imx6/shaders/compile.bat b/src/plugins/videonode/imx6/shaders/compile.bat new file mode 100755 index 000000000..712bee6c5 --- /dev/null +++ b/src/plugins/videonode/imx6/shaders/compile.bat @@ -0,0 +1,41 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2020 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$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +qsb -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o rgba.vert.qsb rgba.vert +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o rgba.frag.qsb rgba.frag diff --git a/src/plugins/videonode/imx6/shaders/rgba.frag b/src/plugins/videonode/imx6/shaders/rgba.frag new file mode 100644 index 000000000..0368520a6 --- /dev/null +++ b/src/plugins/videonode/imx6/shaders/rgba.frag @@ -0,0 +1,18 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + float opacity; + float u_scale; + float v_scale; +} ubuf; + +layout(binding = 1) uniform sampler2D rgbTexture; + +void main() +{ + fragColor = vec4(texture(rgbTexture, qt_TexCoord * vec2(ubuf.u_scale, ubuf.v_scale)).rgb, 1.0) * ubuf.opacity; +} diff --git a/src/plugins/videonode/imx6/shaders/rgba.frag.qsb b/src/plugins/videonode/imx6/shaders/rgba.frag.qsb new file mode 100644 index 000000000..6d04ace3f Binary files /dev/null and b/src/plugins/videonode/imx6/shaders/rgba.frag.qsb differ diff --git a/src/plugins/videonode/imx6/shaders/rgba.vert b/src/plugins/videonode/imx6/shaders/rgba.vert new file mode 100644 index 000000000..358f39e01 --- /dev/null +++ b/src/plugins/videonode/imx6/shaders/rgba.vert @@ -0,0 +1,20 @@ +#version 440 + +layout(location = 0) in vec4 qt_VertexPosition; +layout(location = 1) in vec2 qt_VertexTexCoord; + +layout(location = 0) out vec2 qt_TexCoord; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + float opacity; + float u_scale; + float v_scale; +} ubuf; + +out gl_PerVertex { vec4 gl_Position; }; + +void main() { + qt_TexCoord = qt_VertexTexCoord; + gl_Position = ubuf.matrix * qt_VertexPosition; +} diff --git a/src/plugins/videonode/imx6/shaders/rgba.vert.qsb b/src/plugins/videonode/imx6/shaders/rgba.vert.qsb new file mode 100644 index 000000000..9eed9b60c Binary files /dev/null and b/src/plugins/videonode/imx6/shaders/rgba.vert.qsb differ diff --git a/src/qtmultimediaquicktools/qsgvideotexture_p.h b/src/qtmultimediaquicktools/qsgvideotexture_p.h index 6201264b6..46203d405 100644 --- a/src/qtmultimediaquicktools/qsgvideotexture_p.h +++ b/src/qtmultimediaquicktools/qsgvideotexture_p.h @@ -54,11 +54,12 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QSGVideoTexturePrivate; -class QSGVideoTexture : public QSGTexture +class Q_MULTIMEDIAQUICK_EXPORT QSGVideoTexture : public QSGTexture { Q_DECLARE_PRIVATE(QSGVideoTexture) public: -- cgit v1.2.3