diff options
author | VaL Doroshchuk <valentyn.doroshchuk@qt.io> | 2020-05-21 15:17:07 +0200 |
---|---|---|
committer | Val Doroshchuk <valentyn.doroshchuk@qt.io> | 2020-05-29 16:46:42 +0200 |
commit | f60c028d522ce3e4ed01cf00e6601956a1f0ed01 (patch) | |
tree | 82e33543e766cdf1dc95d4a1cfad596f479b7a47 /src/qtmultimediaquicktools/qsgvideonode_texture.cpp | |
parent | 5238ce8fdc5dd357dc96e351ba8baea73ce9fb55 (diff) |
Quick: Add support of RHI for video frames
Added RHI shaders for RGB*, YUV* and opengl texture video frames.
Task-number: QTBUG-78678
Change-Id: I045d6a806fea059a80b8e5d9817b6997af8d0f41
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/qtmultimediaquicktools/qsgvideonode_texture.cpp')
-rw-r--r-- | src/qtmultimediaquicktools/qsgvideonode_texture.cpp | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp index d89a36ee8..a5206eefb 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp @@ -37,6 +37,7 @@ ** ****************************************************************************/ #include "qsgvideonode_texture_p.h" +#include "qsgvideotexture_p.h" #include <QtQuick/qsgtexturematerial.h> #include <QtQuick/qsgmaterial.h> #include <QtCore/qmutex.h> @@ -126,6 +127,30 @@ protected: int m_hasAlpha; }; +class QSGVideoMaterialRhiShader_Texture : public QSGMaterialRhiShader +{ +public: + QSGVideoMaterialRhiShader_Texture() + { + setShaderFileName(VertexStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/rgba.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/rgba.frag.qsb")); + } + + bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) override; + + void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; +}; + +class QSGVideoMaterialRhiShader_Texture_swizzle : public QSGVideoMaterialRhiShader_Texture +{ +public: + QSGVideoMaterialRhiShader_Texture_swizzle() + { + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/bgra.frag.qsb")); + } +}; class QSGVideoMaterial_Texture : public QSGMaterial { @@ -136,6 +161,7 @@ public: m_opacity(1.0) { setFlag(Blending, false); + setFlag(SupportsRhiShader, true); } ~QSGVideoMaterial_Texture() @@ -149,6 +175,10 @@ public: } QSGMaterialShader *createShader() const override { + if (flags().testFlag(RhiShaderWanted)) + return needsSwizzling() ? new QSGVideoMaterialRhiShader_Texture_swizzle + : new QSGVideoMaterialRhiShader_Texture; + const bool hasAlpha = m_format.pixelFormat() == QVideoFrame::Format_ARGB32; return needsSwizzling() ? new QSGVideoMaterialShader_Texture_swizzle(hasAlpha) : new QSGVideoMaterialShader_Texture; @@ -201,8 +231,9 @@ public: QMutex m_frameMutex; QSize m_textureSize; QVideoSurfaceFormat m_format; - GLuint m_textureId; + quint64 m_textureId; qreal m_opacity; + QScopedPointer<QSGVideoTexture> m_texture; private: bool needsSwizzling() const { @@ -211,6 +242,51 @@ private: } }; +bool QSGVideoMaterialRhiShader_Texture::updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) +{ + Q_UNUSED(newMaterial); + Q_UNUSED(oldMaterial); + + bool changed = false; + QByteArray *buf = state.uniformData(); + + if (state.isMatrixDirty()) { + memcpy(buf->data(), state.combinedMatrix().constData(), 64); + changed = true; + } + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 64, &opacity, 4); + changed = true; + } + + return changed; +} + +void QSGVideoMaterialRhiShader_Texture::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + + if (binding < 1) + return; + + auto m = static_cast<QSGVideoMaterial_Texture *>(newMaterial); + if (!m->m_texture) + m->m_texture.reset(new QSGVideoTexture); + + m->m_frameMutex.lock(); + auto size = m->m_frame.size(); + if (m->m_frame.isValid()) + m->m_textureId = m->m_frame.handle().toULongLong(); + m->m_frameMutex.unlock(); + + m->m_texture->setNativeObject(m->m_textureId, size); + m->m_texture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); + *texture = m->m_texture.data(); +} QSGVideoNode_Texture::QSGVideoNode_Texture(const QVideoSurfaceFormat &format) : m_format(format) |