diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-06-10 17:14:09 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-06-11 12:42:26 +0200 |
commit | ad21c33475ce9e033fc79140908c641d1424fa3f (patch) | |
tree | 92714985500985e9a12160813a14fbd2fc7df7ad | |
parent | 6096467b5d9025d936389483566ae01996a4b749 (diff) |
Initial work to port the quick item material
It should be possible to make this working on RHI-on-OpenGL, except
maybe for the external OES sampler case.
This is a not a complete fix, because it breaks the texture sharing
extension for now. It allows us to proceed with building and integrating
in the CI however.
The rest will be handled in follow up patches.
Change-Id: I96e128166e9bb5cd30809807dd0dccee1fe9be4c
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
19 files changed, 211 insertions, 134 deletions
diff --git a/src/compositor/compositor.qrc b/src/compositor/compositor.qrc index 5dc7a70a5..1b8c0f5d3 100644 --- a/src/compositor/compositor.qrc +++ b/src/compositor/compositor.qrc @@ -1,11 +1,10 @@ <RCC> <qresource prefix="/qt-project.org/wayland/compositor"> - <file>shaders/surface.vert</file> - <file>shaders/surface_oes_external.frag</file> - <file>shaders/surface_rgba.frag</file> - <file>shaders/surface_rgbx.frag</file> - <file>shaders/surface_y_u_v.frag</file> - <file>shaders/surface_y_uv.frag</file> - <file>shaders/surface_y_xuxv.frag</file> + <file>shaders/surface.vert.qsb</file> + <file>shaders/surface_rgba.frag.qsb</file> + <file>shaders/surface_rgbx.frag.qsb</file> + <file>shaders/surface_y_u_v.frag.qsb</file> + <file>shaders/surface_y_uv.frag.qsb</file> + <file>shaders/surface_y_xuxv.frag.qsb</file> </qresource> </RCC> diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index e6883335c..9685aa455 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -79,8 +79,8 @@ static const struct { // BufferFormatEgl_RGB { - ":/qt-project.org/wayland/compositor/shaders/surface.vert", - ":/qt-project.org/wayland/compositor/shaders/surface_rgbx.frag", + ":/qt-project.org/wayland/compositor/shaders/surface.vert.qsb", + ":/qt-project.org/wayland/compositor/shaders/surface_rgbx.frag.qsb", GL_TEXTURE_2D, 1, true, QSGMaterial::Blending, {} @@ -88,8 +88,8 @@ static const struct { // BufferFormatEgl_RGBA { - ":/qt-project.org/wayland/compositor/shaders/surface.vert", - ":/qt-project.org/wayland/compositor/shaders/surface_rgba.frag", + ":/qt-project.org/wayland/compositor/shaders/surface.vert.qsb", + ":/qt-project.org/wayland/compositor/shaders/surface_rgba.frag.qsb", GL_TEXTURE_2D, 1, true, QSGMaterial::Blending, {} @@ -97,8 +97,8 @@ static const struct { // BufferFormatEgl_EXTERNAL_OES { - ":/qt-project.org/wayland/compositor/shaders/surface.vert", - ":/qt-project.org/wayland/compositor/shaders/surface_oes_external.frag", + ":/qt-project.org/wayland/compositor/shaders/surface.vert.qsb", + ":/qt-project.org/wayland/compositor/shaders/surface_oes_external.frag.qsb", GL_TEXTURE_EXTERNAL_OES, 1, false, QSGMaterial::Blending, {} @@ -106,8 +106,8 @@ static const struct { // BufferFormatEgl_Y_U_V { - ":/qt-project.org/wayland/compositor/shaders/surface.vert", - ":/qt-project.org/wayland/compositor/shaders/surface_y_u_v.frag", + ":/qt-project.org/wayland/compositor/shaders/surface.vert.qsb", + ":/qt-project.org/wayland/compositor/shaders/surface_y_u_v.frag.qsb", GL_TEXTURE_2D, 3, false, QSGMaterial::Blending, {} @@ -115,8 +115,8 @@ static const struct { // BufferFormatEgl_Y_UV { - ":/qt-project.org/wayland/compositor/shaders/surface.vert", - ":/qt-project.org/wayland/compositor/shaders/surface_y_uv.frag", + ":/qt-project.org/wayland/compositor/shaders/surface.vert.qsb", + ":/qt-project.org/wayland/compositor/shaders/surface_y_uv.frag.qsb", GL_TEXTURE_2D, 2, false, QSGMaterial::Blending, {} @@ -124,8 +124,8 @@ static const struct { // BufferFormatEgl_Y_XUXV { - ":/qt-project.org/wayland/compositor/shaders/surface.vert", - ":/qt-project.org/wayland/compositor/shaders/surface_y_xuxv.frag", + ":/qt-project.org/wayland/compositor/shaders/surface.vert.qsb", + ":/qt-project.org/wayland/compositor/shaders/surface_y_xuxv.frag.qsb", GL_TEXTURE_2D, 2, false, QSGMaterial::Blending, {} @@ -135,51 +135,62 @@ static const struct { QWaylandBufferMaterialShader::QWaylandBufferMaterialShader(QWaylandBufferRef::BufferFormatEgl format) : m_format(format) { - setShaderSourceFile(QOpenGLShader::Vertex, QString::fromLatin1(bufferTypes[format].vertexShaderSourceFile)); - setShaderSourceFile(QOpenGLShader::Fragment, QString::fromLatin1(bufferTypes[format].fragmentShaderSourceFile)); + setShaderFileName(VertexStage, QString::fromLatin1(bufferTypes[format].vertexShaderSourceFile)); + setShaderFileName(FragmentStage, QString::fromLatin1(bufferTypes[format].fragmentShaderSourceFile)); } -void QWaylandBufferMaterialShader::updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +bool QWaylandBufferMaterialShader::updateUniformData(RenderState &state, QSGMaterial *, QSGMaterial *) { - QSGMaterialShader::updateState(state, newEffect, oldEffect); + bool changed = false; + QByteArray *buf = state.uniformData(); + Q_ASSERT(buf->size() >= 68); - QWaylandBufferMaterial *material = static_cast<QWaylandBufferMaterial *>(newEffect); - material->bind(); + if (state.isMatrixDirty()) { + const QMatrix4x4 m = state.combinedMatrix(); + memcpy(buf->data(), m.constData(), 64); + changed = true; + } - if (state.isMatrixDirty()) - program()->setUniformValue(m_id_matrix, state.combinedMatrix()); + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 64, &opacity, 4); + changed = true; + } - if (state.isOpacityDirty()) - program()->setUniformValue(m_id_opacity, state.opacity()); + return changed; } -const char * const *QWaylandBufferMaterialShader::attributeNames() const +void QWaylandBufferMaterialShader::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *) { - static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", nullptr }; - return attr; -} + Q_UNUSED(state); -void QWaylandBufferMaterialShader::initialize() -{ - QSGMaterialShader::initialize(); - - m_id_matrix = program()->uniformLocation("qt_Matrix"); - m_id_opacity = program()->uniformLocation("qt_Opacity"); - - for (int i = 0; i < bufferTypes[m_format].planeCount; i++) { - m_id_tex << program()->uniformLocation("tex" + QByteArray::number(i)); - program()->setUniformValue(m_id_tex[i], i); + QWaylandBufferMaterial *material = static_cast<QWaylandBufferMaterial *>(newMaterial); //###@@@??? + Q_UNUSED(material); + switch (binding) { + case 1: + // *texture = ?? where do we get a QSGTexture wrapping the QOpenGLTexture's underlying texture from? + break; + case 2: + // *texture = ?? + break; + case 3: + // *texture = ?? + break; + default: + return; } - Q_ASSERT(m_id_tex.size() == bufferTypes[m_format].planeCount); + // This is for the shared memory case, and is a no-op for others, + // this is where the upload from the QImage happens when not yet done. + // ### or is this too late? (if buffer.image() disappears in the meantime then this is the wrong...) + if (*texture) + (*texture)->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); } QWaylandBufferMaterial::QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEgl format) : m_format(format) { - QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); - - gl->glBindTexture(bufferTypes[m_format].textureTarget, 0); setFlag(bufferTypes[m_format].materialFlags); } @@ -277,10 +288,6 @@ public: if (m_ref.hasBuffer()) { if (buffer.isSharedMemory()) { m_sgTex = surfaceItem->window()->createTextureFromImage(buffer.image()); -#if QT_CONFIG(opengl) - if (m_sgTex) - m_sgTex->bind(); -#endif } else { #if QT_CONFIG(opengl) QQuickWindow::CreateTextureOptions opt; diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h index ce2edf183..ed9e13761 100644 --- a/src/compositor/compositor_api/qwaylandquickitem_p.h +++ b/src/compositor/compositor_api/qwaylandquickitem_p.h @@ -60,17 +60,13 @@ class QWaylandBufferMaterialShader : public QSGMaterialShader public: QWaylandBufferMaterialShader(QWaylandBufferRef::BufferFormatEgl format); - void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override; - char const *const *attributeNames() const override; - -protected: - void initialize() override; + bool updateUniformData(RenderState &state, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; + void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; private: const QWaylandBufferRef::BufferFormatEgl m_format; - int m_id_matrix; - int m_id_opacity; - QVarLengthArray<int, 3> m_id_tex; }; class QWaylandBufferMaterial : public QSGMaterial diff --git a/src/compositor/extensions/qwltexturesharingextension.cpp b/src/compositor/extensions/qwltexturesharingextension.cpp index 09e65a371..ef1d82fe2 100644 --- a/src/compositor/extensions/qwltexturesharingextension.cpp +++ b/src/compositor/extensions/qwltexturesharingextension.cpp @@ -56,13 +56,15 @@ class SharedTexture : public QSGTexture public: SharedTexture(QtWayland::ServerBuffer *buffer); - int textureId() const override; + //TODO: QRhiTexture + + int textureId() const;//######### override; qint64 comparisonKey() const override; QSize textureSize() const override; bool hasAlphaChannel() const override; bool hasMipmaps() const override; - void bind() override; + void bind(); //###### override; private: void updateGLTexture() const; diff --git a/src/compositor/shaders/compile b/src/compositor/shaders/compile new file mode 100644 index 000000000..e7981b1fe --- /dev/null +++ b/src/compositor/shaders/compile @@ -0,0 +1,10 @@ +qsb -b --glsl "100 es,120,150" -o surface.vert.qsb surface.vert +qsb --glsl "100 es,120,150" -o surface_rgba.frag.qsb surface_rgba.frag +qsb --glsl "100 es,120,150" -o surface_rgbx.frag.qsb surface_rgbx.frag +qsb --glsl "100 es,120,150" -o surface_y_uv.frag.qsb surface_y_uv.frag +qsb --glsl "100 es,120,150" -o surface_y_u_v.frag.qsb surface_y_u_v.frag +qsb --glsl "100 es,120,150" -o surface_y_xuxv.frag.qsb surface_y_xuxv.frag + +# Does not compile for whatever reason. We may not support that externalOES +# thing at run time either, so skip for now. +# qsb --glsl "100 es,120,150" -o surface_oes_external.frag.qsb surface_oes_external.frag diff --git a/src/compositor/shaders/surface.vert b/src/compositor/shaders/surface.vert index 848b334f3..7b891c77d 100644 --- a/src/compositor/shaders/surface.vert +++ b/src/compositor/shaders/surface.vert @@ -1,9 +1,18 @@ -uniform highp mat4 qt_Matrix; -attribute highp vec2 qt_VertexPosition; -attribute highp vec2 qt_VertexTexCoord; -varying highp vec2 v_texcoord; - -void main() { - gl_Position = qt_Matrix * vec4(qt_VertexPosition, 0.0, 1.0); - v_texcoord = qt_VertexTexCoord; +#version 440 + +layout(location = 0) in vec2 qt_VertexPosition; +layout(location = 1) in vec2 qt_VertexTexCoord; +layout(location = 0) out vec2 v_texcoord; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + +out gl_PerVertex { vec4 gl_Position; }; + +void main() +{ + gl_Position = qt_Matrix * vec4(qt_VertexPosition, 0.0, 1.0); + v_texcoord = qt_VertexTexCoord; } diff --git a/src/compositor/shaders/surface.vert.qsb b/src/compositor/shaders/surface.vert.qsb Binary files differnew file mode 100644 index 000000000..596dce513 --- /dev/null +++ b/src/compositor/shaders/surface.vert.qsb diff --git a/src/compositor/shaders/surface_oes_external.frag b/src/compositor/shaders/surface_oes_external.frag index 724d06a85..37ae36680 100644 --- a/src/compositor/shaders/surface_oes_external.frag +++ b/src/compositor/shaders/surface_oes_external.frag @@ -1,8 +1,17 @@ -#extension GL_OES_EGL_image_external : require -varying highp vec2 v_texcoord; -uniform highp samplerExternalOES tex0; -uniform lowp float qt_Opacity; +#version 440 +#extension GL_OES_EGL_image_external_essl3 : require -void main() { - gl_FragColor = qt_Opacity * texture2D(tex0, v_texcoord); +layout(location = 0) in vec2 v_texcoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + +layout(binding = 1) uniform samplerExternalOES tex0; + +void main() +{ + fragColor = qt_Opacity * texture(tex0, v_texcoord); } diff --git a/src/compositor/shaders/surface_rgba.frag b/src/compositor/shaders/surface_rgba.frag index f896051ba..f6a7732a4 100644 --- a/src/compositor/shaders/surface_rgba.frag +++ b/src/compositor/shaders/surface_rgba.frag @@ -1,7 +1,16 @@ -varying highp vec2 v_texcoord; -uniform highp sampler2D tex0; -uniform lowp float qt_Opacity; +#version 440 -void main() { - gl_FragColor = qt_Opacity * texture2D(tex0, v_texcoord); +layout(location = 0) in vec2 v_texcoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + +layout(binding = 1) uniform sampler2D tex0; + +void main() +{ + fragColor = qt_Opacity * texture(tex0, v_texcoord); } diff --git a/src/compositor/shaders/surface_rgba.frag.qsb b/src/compositor/shaders/surface_rgba.frag.qsb Binary files differnew file mode 100644 index 000000000..72abc0f1b --- /dev/null +++ b/src/compositor/shaders/surface_rgba.frag.qsb diff --git a/src/compositor/shaders/surface_rgbx.frag b/src/compositor/shaders/surface_rgbx.frag index 8fb78498c..37ad3fd21 100644 --- a/src/compositor/shaders/surface_rgbx.frag +++ b/src/compositor/shaders/surface_rgbx.frag @@ -1,8 +1,17 @@ -varying highp vec2 v_texcoord; -uniform highp sampler2D tex0; -uniform lowp float qt_Opacity; +#version 440 -void main() { - gl_FragColor.rgb = qt_Opacity * texture2D(tex0, v_texcoord).rgb; - gl_FragColor.a = qt_Opacity; +layout(location = 0) in vec2 v_texcoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + +layout(binding = 1) uniform sampler2D tex0; + +void main() +{ + fragColor.rgb = qt_Opacity * texture(tex0, v_texcoord).rgb; + fragColor.a = qt_Opacity; } diff --git a/src/compositor/shaders/surface_rgbx.frag.qsb b/src/compositor/shaders/surface_rgbx.frag.qsb Binary files differnew file mode 100644 index 000000000..5fd9a21ac --- /dev/null +++ b/src/compositor/shaders/surface_rgbx.frag.qsb diff --git a/src/compositor/shaders/surface_y_u_v.frag b/src/compositor/shaders/surface_y_u_v.frag index e739f6fff..f8fa1010d 100644 --- a/src/compositor/shaders/surface_y_u_v.frag +++ b/src/compositor/shaders/surface_y_u_v.frag @@ -1,18 +1,27 @@ -uniform highp sampler2D tex0; -uniform highp sampler2D tex1; -uniform highp sampler2D tex2; -varying highp vec2 v_texcoord; -uniform lowp float qt_Opacity; +#version 440 -void main() { - float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625); - float u = texture2D(tex1, v_texcoord).x - 0.5; - float v = texture2D(tex2, v_texcoord).x - 0.5; - y *= qt_Opacity; - u *= qt_Opacity; - v *= qt_Opacity; - gl_FragColor.r = y + 1.59602678 * v; - gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v; - gl_FragColor.b = y + 2.01723214 * u; - gl_FragColor.a = qt_Opacity; +layout(location = 0) in vec2 v_texcoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + +layout(binding = 1) uniform sampler2D tex0; +layout(binding = 2) uniform sampler2D tex1; +layout(binding = 3) uniform sampler2D tex2; + +void main() +{ + float y = 1.16438356 * (texture(tex0, v_texcoord).x - 0.0625); + float u = texture(tex1, v_texcoord).x - 0.5; + float v = texture(tex2, v_texcoord).x - 0.5; + y *= qt_Opacity; + u *= qt_Opacity; + v *= qt_Opacity; + fragColor.r = y + 1.59602678 * v; + fragColor.g = y - 0.39176229 * u - 0.81296764 * v; + fragColor.b = y + 2.01723214 * u; + fragColor.a = qt_Opacity; } diff --git a/src/compositor/shaders/surface_y_u_v.frag.qsb b/src/compositor/shaders/surface_y_u_v.frag.qsb Binary files differnew file mode 100644 index 000000000..72da0fe85 --- /dev/null +++ b/src/compositor/shaders/surface_y_u_v.frag.qsb diff --git a/src/compositor/shaders/surface_y_uv.frag b/src/compositor/shaders/surface_y_uv.frag index e3fbcdf8d..107c30009 100644 --- a/src/compositor/shaders/surface_y_uv.frag +++ b/src/compositor/shaders/surface_y_uv.frag @@ -1,17 +1,26 @@ -uniform highp sampler2D tex0; -uniform highp sampler2D tex1; -varying highp vec2 v_texcoord; -uniform lowp float qt_Opacity; +#version 440 -void main() { - float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625); - float u = texture2D(tex1, v_texcoord).r - 0.5; - float v = texture2D(tex1, v_texcoord).g - 0.5; - y *= qt_Opacity; - u *= qt_Opacity; - v *= qt_Opacity; - gl_FragColor.r = y + 1.59602678 * v; - gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v; - gl_FragColor.b = y + 2.01723214 * u; - gl_FragColor.a = qt_Opacity; +layout(location = 0) in vec2 v_texcoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + +layout(binding = 1) uniform sampler2D tex0; +layout(binding = 2) uniform sampler2D tex1; + +void main() +{ + float y = 1.16438356 * (texture(tex0, v_texcoord).x - 0.0625); + float u = texture(tex1, v_texcoord).r - 0.5; + float v = texture(tex1, v_texcoord).g - 0.5; + y *= qt_Opacity; + u *= qt_Opacity; + v *= qt_Opacity; + fragColor.r = y + 1.59602678 * v; + fragColor.g = y - 0.39176229 * u - 0.81296764 * v; + fragColor.b = y + 2.01723214 * u; + fragColor.a = qt_Opacity; } diff --git a/src/compositor/shaders/surface_y_uv.frag.qsb b/src/compositor/shaders/surface_y_uv.frag.qsb Binary files differnew file mode 100644 index 000000000..4cea4838d --- /dev/null +++ b/src/compositor/shaders/surface_y_uv.frag.qsb diff --git a/src/compositor/shaders/surface_y_xuxv.frag b/src/compositor/shaders/surface_y_xuxv.frag index 79f8600e8..cf554db7c 100644 --- a/src/compositor/shaders/surface_y_xuxv.frag +++ b/src/compositor/shaders/surface_y_xuxv.frag @@ -1,17 +1,26 @@ -uniform highp sampler2D tex0; -uniform highp sampler2D tex1; -varying highp vec2 v_texcoord; -uniform lowp float qt_Opacity; +#version 440 -void main() { - float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625); - float u = texture2D(tex1, v_texcoord).g - 0.5; - float v = texture2D(tex1, v_texcoord).a - 0.5; - y *= qt_Opacity; - u *= qt_Opacity; - v *= qt_Opacity; - gl_FragColor.r = y + 1.59602678 * v; - gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v; - gl_FragColor.b = y + 2.01723214 * u; - gl_FragColor.a = qt_Opacity; +layout(location = 0) in vec2 v_texcoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + +layout(binding = 1) uniform sampler2D tex0; +layout(binding = 2) uniform sampler2D tex1; + +void main() +{ + float y = 1.16438356 * (texture(tex0, v_texcoord).x - 0.0625); + float u = texture(tex1, v_texcoord).g - 0.5; + float v = texture(tex1, v_texcoord).a - 0.5; + y *= qt_Opacity; + u *= qt_Opacity; + v *= qt_Opacity; + fragColor.r = y + 1.59602678 * v; + fragColor.g = y - 0.39176229 * u - 0.81296764 * v; + fragColor.b = y + 2.01723214 * u; + fragColor.a = qt_Opacity; } diff --git a/src/compositor/shaders/surface_y_xuxv.frag.qsb b/src/compositor/shaders/surface_y_xuxv.frag.qsb Binary files differnew file mode 100644 index 000000000..5450935bd --- /dev/null +++ b/src/compositor/shaders/surface_y_xuxv.frag.qsb diff --git a/src/imports/texture-sharing/sharedtextureprovider.h b/src/imports/texture-sharing/sharedtextureprovider.h index 5a4c4de88..d200315e0 100644 --- a/src/imports/texture-sharing/sharedtextureprovider.h +++ b/src/imports/texture-sharing/sharedtextureprovider.h @@ -99,13 +99,13 @@ class SharedTexture : public QSGTexture public: SharedTexture(QtWaylandClient::QWaylandServerBuffer *buffer); - int textureId() const override; + int textureId() const; //###### override; qint64 comparisonKey() const override; QSize textureSize() const override; bool hasAlphaChannel() const override; bool hasMipmaps() const override; - void bind() override; + void bind(); //######## override; private: void updateGLTexture() const; |