diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-06-10 21:12:28 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-06-10 21:12:28 +0200 |
commit | 0c5a9ff9876cb1af53317720d1de8baae003e21d (patch) | |
tree | 333235a9873df74b8e9b3c4232e0f8f87854df11 | |
parent | c9d8b85ec9efd90f9bd8071a58dc04f54c2c365d (diff) | |
parent | 2a999f870e791d99c5c0463a11be05fc5a14dfcc (diff) |
Merge branch 'wip/scenegraphng' into dev
Change-Id: If8577edb361748535159375c68238845220921a8
26 files changed, 325 insertions, 110 deletions
diff --git a/examples/quick/quick.pro b/examples/quick/quick.pro index 1b53620c89..b164bf4f5b 100644 --- a/examples/quick/quick.pro +++ b/examples/quick/quick.pro @@ -16,7 +16,6 @@ SUBDIRS = quick-accessibility \ scenegraph \ shadereffects \ text \ - textureprovider \ threading \ touchinteraction \ tutorials \ @@ -29,7 +28,9 @@ SUBDIRS = quick-accessibility \ #OpenGL Support Required contains(QT_CONFIG, opengl(es1|es2)?) { - SUBDIRS += rendercontrol + SUBDIRS += \ + textureprovider \ + rendercontrol } # Widget dependent examples diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp index 3694c6ae75..bc03720407 100644 --- a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp +++ b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp @@ -83,7 +83,7 @@ void D3D12RenderNode::init() D3D12_ROOT_PARAMETER rootParameter; rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; - rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; rootParameter.Descriptor.ShaderRegister = 0; // b0 rootParameter.Descriptor.RegisterSpace = 0; @@ -123,11 +123,19 @@ void D3D12RenderNode::init() rastDesc.CullMode = D3D12_CULL_MODE_BACK; rastDesc.FrontCounterClockwise = TRUE; // Vertices are given CCW - // No blending, just enable color write. - D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = {}; - defaultRenderTargetBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + // Enable color write and blending (premultiplied alpha). The latter is + // needed because the example changes the item's opacity and we pass + // inheritedOpacity() into the pixel shader. If that wasn't the case, + // blending could have stayed disabled. + const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = { + TRUE, FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL + }; D3D12_BLEND_DESC blendDesc = {}; - blendDesc.RenderTarget[0] = defaultRenderTargetBlendDesc; + blendDesc.RenderTarget[0] = premulBlendDesc; D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; @@ -177,7 +185,7 @@ void D3D12RenderNode::init() } vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); - vertexBufferView.StrideInBytes = (2 + 3) * sizeof(float); + vertexBufferView.StrideInBytes = vertexBufferSize / 3; vertexBufferView.SizeInBytes = vertexBufferSize; bufDesc.Width = 256; @@ -198,6 +206,14 @@ void D3D12RenderNode::init() qWarning("Map failed (constant buffer)"); return; } + + float *vp = reinterpret_cast<float *>(vbPtr); + vp += 2; + *vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f; + vp += 2; + *vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f; + vp += 2; + *vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f; } void D3D12RenderNode::render(const RenderState *state) @@ -212,6 +228,8 @@ void D3D12RenderNode::render(const RenderState *state) const int msize = 16 * sizeof(float); memcpy(cbPtr, matrix()->constData(), msize); memcpy(cbPtr + msize, state->projectionMatrix()->constData(), msize); + const float opacity = inheritedOpacity(); + memcpy(cbPtr + 2 * msize, &opacity, sizeof(float)); const QPointF p0(m_item->width() - 1, m_item->height() - 1); const QPointF p1(0, 0); @@ -220,15 +238,12 @@ void D3D12RenderNode::render(const RenderState *state) float *vp = reinterpret_cast<float *>(vbPtr); *vp++ = p0.x(); *vp++ = p0.y(); - *vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f; - + vp += 3; *vp++ = p1.x(); *vp++ = p1.y(); - *vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f; - + vp += 3; *vp++ = p2.x(); *vp++ = p2.y(); - *vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f; commandList->SetPipelineState(pipelineState.Get()); commandList->SetGraphicsRootSignature(rootSignature.Get()); @@ -237,8 +252,9 @@ void D3D12RenderNode::render(const RenderState *state) commandList->IASetVertexBuffers(0, 1, &vertexBufferView); commandList->DrawInstanced(3, 1, 0, 0); - - // we won't implement changedStates() since no viewport/scissor/stencil/blend related commands were added } +// No need to reimplement changedStates() because no relevant commands are +// added to the command list in render(). + #endif // HAS_D3D12 diff --git a/examples/quick/scenegraph/rendernode/main.qml b/examples/quick/scenegraph/rendernode/main.qml index c647aab88d..a91656dfaa 100644 --- a/examples/quick/scenegraph/rendernode/main.qml +++ b/examples/quick/scenegraph/rendernode/main.qml @@ -71,9 +71,9 @@ Item { NumberAnimation { target: rotation; property: "angle"; to: 80; duration: 1000; easing.type: Easing.InOutCubic } NumberAnimation { target: rotation; property: "angle"; to: -80; duration: 1000; easing.type: Easing.InOutCubic } NumberAnimation { target: rotation; property: "angle"; to: 0; duration: 1000; easing.type: Easing.InOutCubic } - NumberAnimation { target: renderer; property: "opacity"; to: 0.5; duration: 1000; easing.type: Easing.InOutCubic } + NumberAnimation { target: renderer; property: "opacity"; to: 0.1; duration: 1000; easing.type: Easing.InOutCubic } PauseAnimation { duration: 1000 } - NumberAnimation { target: renderer; property: "opacity"; to: 0.8; duration: 1000; easing.type: Easing.InOutCubic } + NumberAnimation { target: renderer; property: "opacity"; to: 1.0; duration: 1000; easing.type: Easing.InOutCubic } ParallelAnimation { NumberAnimation { target: scale; property: "xScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack } NumberAnimation { target: scale; property: "yScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack } diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.cpp b/examples/quick/scenegraph/rendernode/openglrenderer.cpp index 27712e13b2..3eff70cb42 100644 --- a/examples/quick/scenegraph/rendernode/openglrenderer.cpp +++ b/examples/quick/scenegraph/rendernode/openglrenderer.cpp @@ -57,9 +57,6 @@ OpenGLRenderNode::~OpenGLRenderNode() releaseResources(); } -// No need to reimplement changedStates() since our rendering is so simple, -// without involving any state changes. - void OpenGLRenderNode::releaseResources() { delete m_program; @@ -84,8 +81,9 @@ void OpenGLRenderNode::init() static const char *fragmentShaderSource = "varying lowp vec4 col;\n" + "uniform lowp float opacity;\n" "void main() {\n" - " gl_FragColor = col;\n" + " gl_FragColor = col * opacity;\n" "}\n"; m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource); @@ -95,6 +93,7 @@ void OpenGLRenderNode::init() m_program->link(); m_matrixUniform = m_program->uniformLocation("matrix"); + m_opacityUniform = m_program->uniformLocation("opacity"); const int VERTEX_SIZE = 6 * sizeof(GLfloat); @@ -123,6 +122,7 @@ void OpenGLRenderNode::render(const RenderState *state) m_program->bind(); m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *matrix()); + m_program->setUniformValue(m_opacityUniform, float(inheritedOpacity())); m_vbo->bind(); @@ -140,7 +140,15 @@ void OpenGLRenderNode::render(const RenderState *state) m_program->enableAttributeArray(0); m_program->enableAttributeArray(1); + f->glEnable(GL_BLEND); + f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + f->glDrawArrays(GL_TRIANGLES, 0, 3); } +QSGRenderNode::StateFlags OpenGLRenderNode::changedStates() const +{ + return BlendState; +} + #endif // QT_NO_OPENGL diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.h b/examples/quick/scenegraph/rendernode/openglrenderer.h index 3f38faf458..28d528e617 100644 --- a/examples/quick/scenegraph/rendernode/openglrenderer.h +++ b/examples/quick/scenegraph/rendernode/openglrenderer.h @@ -57,6 +57,7 @@ public: void render(const RenderState *state) override; void releaseResources() override; + StateFlags changedStates() const override; private: void init(); @@ -64,6 +65,7 @@ private: QQuickItem *m_item; QOpenGLShaderProgram *m_program = nullptr; int m_matrixUniform; + int m_opacityUniform; QOpenGLBuffer *m_vbo = nullptr; }; diff --git a/examples/quick/scenegraph/rendernode/shader.hlsl b/examples/quick/scenegraph/rendernode/shader.hlsl index 8b9b9ff9d8..f300fe7aa5 100644 --- a/examples/quick/scenegraph/rendernode/shader.hlsl +++ b/examples/quick/scenegraph/rendernode/shader.hlsl @@ -2,15 +2,16 @@ cbuffer ConstantBuffer : register(b0) { float4x4 modelview; float4x4 projection; + float opacity; }; struct PSInput { float4 position : SV_POSITION; - float4 color : COLOR; + float3 color : COLOR; }; -PSInput VS_Simple(float4 position : POSITION, float4 color : COLOR) +PSInput VS_Simple(float4 position : POSITION, float3 color : COLOR) { PSInput result; @@ -23,5 +24,5 @@ PSInput VS_Simple(float4 position : POSITION, float4 color : COLOR) float4 PS_Simple(PSInput input) : SV_TARGET { - return input.color; + return float4(input.color, 1.0) * opacity; } diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp index f51130deb7..ca92062120 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp +++ b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp @@ -45,6 +45,8 @@ #include "vs_vertexcolor.hlslh" #include "ps_vertexcolor.hlslh" +#include "vs_flatcolor.hlslh" +#include "ps_flatcolor.hlslh" #include "vs_smoothcolor.hlslh" #include "ps_smoothcolor.hlslh" #include "vs_texture.hlslh" @@ -66,6 +68,31 @@ QT_BEGIN_NAMESPACE // importantly, it is packed so that it does not cross a 16-byte (float4) // boundary. Hence the need for padding in some cases. +static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity) +{ + const float o = c.w() * globalOpacity; + return QVector4D(c.x() * o, c.y() * o, c.z() * o, o); +} + +static inline QVector4D qsg_premultiply(const QColor &c, float globalOpacity) +{ + const float o = c.alphaF() * globalOpacity; + return QVector4D(c.redF() * o, c.greenF() * o, c.blueF() * o, o); +} + +static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b) +{ + if (a.x() != b.x()) + return a.x() > b.x() ? 1 : -1; + if (a.y() != b.y()) + return a.y() > b.y() ? 1 : -1; + if (a.z() != b.z()) + return a.z() > b.z() ? 1 : -1; + if (a.w() != b.w()) + return a.w() > b.w() ? 1 : -1; + return 0; +} + QSGMaterialType QSGD3D12VertexColorMaterial::mtype; QSGMaterialType *QSGD3D12VertexColorMaterial::type() const @@ -121,6 +148,67 @@ QSGD3D12Material::UpdateResults QSGD3D12VertexColorMaterial::updatePipeline(cons return r; } +QSGMaterialType QSGD3D12FlatColorMaterial::mtype; + +QSGMaterialType *QSGD3D12FlatColorMaterial::type() const +{ + return &QSGD3D12FlatColorMaterial::mtype; +} + +int QSGD3D12FlatColorMaterial::compare(const QSGMaterial *other) const +{ + Q_ASSERT(other && type() == other->type()); + const QSGD3D12FlatColorMaterial *o = static_cast<const QSGD3D12FlatColorMaterial *>(other); + return m_color.rgba() - o->color().rgba(); +} + +static const int FLAT_COLOR_CB_SIZE_0 = 16 * sizeof(float); // float4x4 +static const int FLAT_COLOR_CB_SIZE_1 = 4 * sizeof(float); // float4 +static const int FLAT_COLOR_CB_SIZE = FLAT_COLOR_CB_SIZE_0 + FLAT_COLOR_CB_SIZE_1; + +int QSGD3D12FlatColorMaterial::constantBufferSize() const +{ + return QSGD3D12Engine::alignedConstantBufferSize(FLAT_COLOR_CB_SIZE); +} + +void QSGD3D12FlatColorMaterial::preparePipeline(QSGD3D12PipelineState *pipelineState) +{ + pipelineState->shaders.vs = g_VS_FlatColor; + pipelineState->shaders.vsSize = sizeof(g_VS_FlatColor); + pipelineState->shaders.ps = g_PS_FlatColor; + pipelineState->shaders.psSize = sizeof(g_PS_FlatColor); +} + +QSGD3D12Material::UpdateResults QSGD3D12FlatColorMaterial::updatePipeline(const QSGD3D12MaterialRenderState &state, + QSGD3D12PipelineState *, + ExtraState *, + quint8 *constantBuffer) +{ + QSGD3D12Material::UpdateResults r = 0; + quint8 *p = constantBuffer; + + if (state.isMatrixDirty()) { + memcpy(p, state.combinedMatrix().constData(), FLAT_COLOR_CB_SIZE_0); + r |= UpdatedConstantBuffer; + } + p += FLAT_COLOR_CB_SIZE_0; + + const QVector4D color = qsg_premultiply(m_color, state.opacity()); + const float f[] = { color.x(), color.y(), color.z(), color.w() }; + if (state.isOpacityDirty() || memcmp(p, f, FLAT_COLOR_CB_SIZE_1)) { + memcpy(p, f, FLAT_COLOR_CB_SIZE_1); + r |= UpdatedConstantBuffer; + } + + return r; +} + +void QSGD3D12FlatColorMaterial::setColor(const QColor &color) +{ + m_color = color; + setFlag(Blending, m_color.alpha() != 0xFF); +} + QSGD3D12SmoothColorMaterial::QSGD3D12SmoothColorMaterial() { setFlag(RequiresFullMatrixExceptTranslate, true); @@ -356,25 +444,6 @@ QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(co return r; } -static inline QVector4D qsg_premultiply(const QVector4D &c, float globalOpacity) -{ - float o = c.w() * globalOpacity; - return QVector4D(c.x() * o, c.y() * o, c.z() * o, o); -} - -static inline int qsg_colorDiff(const QVector4D &a, const QVector4D &b) -{ - if (a.x() != b.x()) - return a.x() > b.x() ? 1 : -1; - if (a.y() != b.y()) - return a.y() > b.y() ? 1 : -1; - if (a.z() != b.z()) - return a.z() > b.z() ? 1 : -1; - if (a.w() != b.w()) - return a.w() > b.w() ? 1 : -1; - return 0; -} - QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc, const QRawFont &font, QFontEngine::GlyphFormat glyphFormat) : m_styleType(styleType), @@ -503,56 +572,60 @@ QSGD3D12Material::UpdateResults QSGD3D12TextMaterial::updatePipeline(const QSGD3 } p += TEXT_CB_SIZE_0; - if (state.isCachedMaterialDataDirty() || m_lastGlyphCacheSize != glyphCache()->currentSize()) { - m_lastGlyphCacheSize = glyphCache()->currentSize(); - const float textureScale[2] = { 1.0f / m_lastGlyphCacheSize.width(), - 1.0f / m_lastGlyphCacheSize.height() }; + const QSize sz = glyphCache()->currentSize(); + const float textureScale[] = { 1.0f / sz.width(), 1.0f / sz.height() }; + if (state.isCachedMaterialDataDirty() || memcmp(p, textureScale, TEXT_CB_SIZE_1)) { memcpy(p, textureScale, TEXT_CB_SIZE_1); r |= UpdatedConstantBuffer; } p += TEXT_CB_SIZE_1; const float dpr = m_rc->engine()->windowDevicePixelRatio(); - if (state.isCachedMaterialDataDirty() || m_lastDpr != dpr) { - m_lastDpr = dpr; + if (state.isCachedMaterialDataDirty() || memcmp(p, &dpr, TEXT_CB_SIZE_2)) { memcpy(p, &dpr, TEXT_CB_SIZE_2); r |= UpdatedConstantBuffer; } p += TEXT_CB_SIZE_2; - if (state.isOpacityDirty() || m_lastColor != m_color) { - m_lastColor = m_color; - if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) { - const QVector4D color = qsg_premultiply(m_color, state.opacity()); - const float alpha = color.w(); + if (glyphCache()->glyphFormat() == QFontEngine::Format_A32) { + const QVector4D color = qsg_premultiply(m_color, state.opacity()); + const float alpha = color.w(); + if (state.isOpacityDirty() || memcmp(p, &alpha, TEXT_CB_SIZE_3)) { memcpy(p, &alpha, TEXT_CB_SIZE_3); - } else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) { - const float opacity = m_color.w() * state.opacity(); + r |= UpdatedConstantBuffer; + } + } else if (glyphCache()->glyphFormat() == QFontEngine::Format_ARGB) { + const float opacity = m_color.w() * state.opacity(); + if (state.isOpacityDirty() || memcmp(p, &opacity, TEXT_CB_SIZE_3)) { memcpy(p, &opacity, TEXT_CB_SIZE_3); - } else { - const QVector4D color = qsg_premultiply(m_color, state.opacity()); - const float f[4] = { color.x(), color.y(), color.z(), color.w() }; + r |= UpdatedConstantBuffer; + } + } else { + const QVector4D color = qsg_premultiply(m_color, state.opacity()); + const float f[] = { color.x(), color.y(), color.z(), color.w() }; + if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_4)) { memcpy(p + TEXT_CB_SIZE_3, f, TEXT_CB_SIZE_4); + r |= UpdatedConstantBuffer; } - r |= UpdatedConstantBuffer; } p += TEXT_CB_SIZE_3 + TEXT_CB_SIZE_4; - if (m_styleType == Styled && (state.isCachedMaterialDataDirty() || m_lastStyleShift != m_styleShift)) { - m_lastStyleShift = m_styleShift; - const float f[2] = { m_styleShift.x(), m_styleShift.y() }; - memcpy(p, f, TEXT_CB_SIZE_5); - r |= UpdatedConstantBuffer; + if (m_styleType == Styled) { + const float f[] = { m_styleShift.x(), m_styleShift.y() }; + if (state.isCachedMaterialDataDirty() || memcmp(p, f, TEXT_CB_SIZE_5)) { + memcpy(p, f, TEXT_CB_SIZE_5); + r |= UpdatedConstantBuffer; + } } p += TEXT_CB_SIZE_5 + TEXT_CB_SIZE_5_PADDING; - if ((m_styleType == Styled || m_styleType == Outlined) - && (state.isOpacityDirty() || m_lastStyleColor != m_styleColor)) { - m_lastStyleColor = m_styleColor; + if (m_styleType == Styled || m_styleType == Outlined) { const QVector4D color = qsg_premultiply(m_styleColor, state.opacity()); - const float f[4] = { color.x(), color.y(), color.z(), color.w() }; - memcpy(p, f, TEXT_CB_SIZE_6); - r |= UpdatedConstantBuffer; + const float f[] = { color.x(), color.y(), color.z(), color.w() }; + if (state.isOpacityDirty() || memcmp(p, f, TEXT_CB_SIZE_6)) { + memcpy(p, f, TEXT_CB_SIZE_6); + r |= UpdatedConstantBuffer; + } } QSGD3D12TextureView &tv(pipelineState->shaders.rootSig.textureViews[0]); diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h index c64ff52ab0..34ae73d2d6 100644 --- a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h +++ b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials_p.h @@ -77,6 +77,27 @@ private: static QSGMaterialType mtype; }; +class QSGD3D12FlatColorMaterial : public QSGD3D12Material +{ +public: + QSGMaterialType *type() const override; + int compare(const QSGMaterial *other) const override; + + int constantBufferSize() const override; + void preparePipeline(QSGD3D12PipelineState *pipelineState) override; + UpdateResults updatePipeline(const QSGD3D12MaterialRenderState &state, + QSGD3D12PipelineState *pipelineState, + ExtraState *extraState, + quint8 *constantBuffer) override; + + void setColor(const QColor &color); + QColor color() const { return m_color; } + +private: + static QSGMaterialType mtype; + QColor m_color; +}; + class QSGD3D12SmoothColorMaterial : public QSGD3D12Material { public: @@ -224,11 +245,6 @@ private: QVector4D m_styleColor; QRawFont m_font; QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache; - QSize m_lastGlyphCacheSize; - float m_lastDpr = 0; - QVector4D m_lastColor; - QVector2D m_lastStyleShift; - QVector4D m_lastStyleColor; }; QT_END_NAMESPACE diff --git a/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl b/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl new file mode 100644 index 0000000000..034b51435a --- /dev/null +++ b/src/plugins/scenegraph/d3d12/shaders/flatcolor.hlsl @@ -0,0 +1,27 @@ +struct VSInput +{ + float4 position : POSITION; +}; + +cbuffer ConstantBuffer : register(b0) +{ + float4x4 mvp; + float4 color; +}; + +struct PSInput +{ + float4 position : SV_POSITION; +}; + +PSInput VS_FlatColor(VSInput input) +{ + PSInput result; + result.position = mul(mvp, input.position); + return result; +} + +float4 PS_FlatColor(PSInput input) : SV_TARGET +{ + return color; +} diff --git a/src/plugins/scenegraph/d3d12/shaders/shaders.pri b/src/plugins/scenegraph/d3d12/shaders/shaders.pri index 41bac334de..41f0ee80f7 100644 --- a/src/plugins/scenegraph/d3d12/shaders/shaders.pri +++ b/src/plugins/scenegraph/d3d12/shaders/shaders.pri @@ -8,6 +8,16 @@ vertexcolor_pshader.header = ps_vertexcolor.hlslh vertexcolor_pshader.entry = PS_VertexColor vertexcolor_pshader.type = ps_5_0 +flatcolor_VSPS = $$PWD/flatcolor.hlsl +flatcolor_vshader.input = flatcolor_VSPS +flatcolor_vshader.header = vs_flatcolor.hlslh +flatcolor_vshader.entry = VS_FlatColor +flatcolor_vshader.type = vs_5_0 +flatcolor_pshader.input = flatcolor_VSPS +flatcolor_pshader.header = ps_flatcolor.hlslh +flatcolor_pshader.entry = PS_FlatColor +flatcolor_pshader.type = ps_5_0 + stencilclip_VSPS = $$PWD/stencilclip.hlsl stencilclip_vshader.input = stencilclip_VSPS stencilclip_vshader.header = vs_stencilclip.hlslh @@ -106,6 +116,7 @@ tdr_cshader.type = cs_5_0 HLSL_SHADERS = \ vertexcolor_vshader vertexcolor_pshader \ + flatcolor_vshader flatcolor_pshader \ stencilclip_vshader stencilclip_pshader \ smoothcolor_vshader smoothcolor_pshader \ texture_vshader texture_pshader \ diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp index 2dbad82acf..79b0edf031 100644 --- a/src/quick/items/qquickgraphicsinfo.cpp +++ b/src/quick/items/qquickgraphicsinfo.cpp @@ -70,7 +70,7 @@ QQuickGraphicsInfo::QQuickGraphicsInfo(QQuickItem *item) , m_shaderSourceType(ShaderSourceType(0)) , m_majorVersion(2) , m_minorVersion(0) - , m_profile(NoProfile) + , m_profile(OpenGLNoProfile) , m_renderableType(SurfaceFormatUnspecified) { connect(item, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(setWindow(QQuickWindow*))); @@ -211,9 +211,9 @@ QQuickGraphicsInfo *QQuickGraphicsInfo::qmlAttachedProperties(QObject *object) The possible values are: \list - \li GraphicsInfo.NoProfile (default) - OpenGL version is lower than 3.2 or OpenGL is not in use. - \li GraphicsInfo.CoreProfile - Functionality deprecated in OpenGL version 3.0 is not available. - \li GraphicsInfo.CompatibilityProfile - Functionality from earlier OpenGL versions is available. + \li GraphicsInfo.OpenGLNoProfile (default) - OpenGL version is lower than 3.2 or OpenGL is not in use. + \li GraphicsInfo.OpenGLCoreProfile - Functionality deprecated in OpenGL version 3.0 is not available. + \li GraphicsInfo.OpenGLCompatibilityProfile - Functionality from earlier OpenGL versions is available. \endlist Reusable QML components will typically use this property in bindings in order to @@ -275,7 +275,7 @@ void QQuickGraphicsInfo::updateInfo() m_minorVersion = format.minorVersion(); emit minorVersionChanged(); } - ContextProfile profile = static_cast<ContextProfile>(format.profile()); + OpenGLContextProfile profile = static_cast<OpenGLContextProfile>(format.profile()); if (m_profile != profile) { m_profile = profile; emit profileChanged(); diff --git a/src/quick/items/qquickgraphicsinfo_p.h b/src/quick/items/qquickgraphicsinfo_p.h index 0cbfbbddba..9ef7bacb3e 100644 --- a/src/quick/items/qquickgraphicsinfo_p.h +++ b/src/quick/items/qquickgraphicsinfo_p.h @@ -72,7 +72,7 @@ class QQuickGraphicsInfo : public QObject Q_PROPERTY(int majorVersion READ majorVersion NOTIFY majorVersionChanged FINAL) Q_PROPERTY(int minorVersion READ minorVersion NOTIFY minorVersionChanged FINAL) - Q_PROPERTY(ContextProfile profile READ profile NOTIFY profileChanged FINAL) + Q_PROPERTY(OpenGLContextProfile profile READ profile NOTIFY profileChanged FINAL) Q_PROPERTY(RenderableType renderableType READ renderableType NOTIFY renderableTypeChanged FINAL) public: @@ -104,12 +104,12 @@ public: }; Q_ENUM(ShaderSourceType) - enum ContextProfile { - NoProfile = QSurfaceFormat::NoProfile, - CoreProfile = QSurfaceFormat::CoreProfile, - CompatibilityProfile = QSurfaceFormat::CompatibilityProfile + enum OpenGLContextProfile { + OpenGLNoProfile = QSurfaceFormat::NoProfile, + OpenGLCoreProfile = QSurfaceFormat::CoreProfile, + OpenGLCompatibilityProfile = QSurfaceFormat::CompatibilityProfile }; - Q_ENUM(ContextProfile) + Q_ENUM(OpenGLContextProfile) enum RenderableType { SurfaceFormatUnspecified = QSurfaceFormat::DefaultRenderableType, @@ -129,7 +129,7 @@ public: int majorVersion() const { return m_majorVersion; } int minorVersion() const { return m_minorVersion; } - ContextProfile profile() const { return m_profile; } + OpenGLContextProfile profile() const { return m_profile; } RenderableType renderableType() const { return m_renderableType; } Q_SIGNALS: @@ -155,7 +155,7 @@ private: ShaderSourceType m_shaderSourceType; int m_majorVersion; int m_minorVersion; - ContextProfile m_profile; + OpenGLContextProfile m_profile; RenderableType m_renderableType; }; diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 5d7ed2ad2d..680ba85aa1 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -93,19 +93,12 @@ public: Repeat }; Q_ENUM(WrapMode) -#ifndef QT_NO_OPENGL - enum Format { - Alpha = GL_ALPHA, - RGB = GL_RGB, - RGBA = GL_RGBA - }; -#else + // Equivalents to GL_ALPHA and similar type constants. enum Format { Alpha = 0x1906, - RGB, - RGBA + RGB = 0x1907, + RGBA = 0x1908 }; -#endif Q_ENUM(Format) enum TextureMirroring { diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index dee1ac8954..ce726e342b 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -153,8 +153,7 @@ void QSGSoftwareRenderContext::invalidate() QSGTexture *QSGSoftwareRenderContext::createTexture(const QImage &image, uint flags) const { - Q_UNUSED(flags) - return new QSGSoftwarePixmapTexture(image); + return new QSGSoftwarePixmapTexture(image, flags); } QSGRenderer *QSGSoftwareRenderContext::createRenderer() diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode_p.h index 62559c933c..bc7aec1b5a 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareninepatchnode_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE class QSGSoftwareNinePatchNode : public QSGNinePatchNode { -public: +public: QSGSoftwareNinePatchNode(); void setTexture(QSGTexture *texture) override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp index e04c400af3..534a0a4ec6 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp @@ -41,11 +41,17 @@ QT_BEGIN_NAMESPACE -QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QImage &image) +QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QImage &image, uint flags) +{ // Prevent pixmap format conversion to reduce memory consumption // and surprises in calling code. (See QTBUG-47328) - : m_pixmap(QPixmap::fromImage(image, Qt::NoFormatConversion)) -{ + if (flags & QSGRenderContext::CreateTexture_Alpha) { + //If texture should have an alpha + m_pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion); + } else { + //Force opaque texture + m_pixmap = QPixmap::fromImage(image.convertToFormat(QImage::Format_RGB32), Qt::NoFormatConversion); + } } QSGSoftwarePixmapTexture::QSGSoftwarePixmapTexture(const QPixmap &pixmap) diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h index 01bfe19471..034fa25da9 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture_p.h @@ -59,7 +59,7 @@ class QSGSoftwarePixmapTexture : public QSGTexture { Q_OBJECT public: - QSGSoftwarePixmapTexture(const QImage &image); + QSGSoftwarePixmapTexture(const QImage &image, uint flags); QSGSoftwarePixmapTexture(const QPixmap &pixmap); int textureId() const override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index 300ce6920c..5292e1371f 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -229,6 +229,7 @@ QImage QSGSoftwareRenderLoop::grab(QQuickWindow *window) renderWindow(window); QImage grabbed = grabContent; + grabbed.detach(); grabContent = QImage(); return grabbed; } diff --git a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp index b9986c3d11..5d7817163e 100644 --- a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp @@ -125,6 +125,9 @@ void FlatColorMaterialShader::initialize() \inmodule QtQuick \ingroup qtquick-scenegraph-materials + \warning This utility class is only functional when running with the OpenGL + backend of the Qt Quick scenegraph. + The flat color material will fill every pixel in a geometry using a solid color. The color can contain transparency. diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp index 923179071b..7214a255df 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.cpp +++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp @@ -41,11 +41,14 @@ \class QSGSimpleMaterialShader \brief The QSGSimpleMaterialShader class provides a convenient way of - building custom materials for the scene graph. + building custom OpenGL-based materials for the scene graph. \inmodule QtQuick \ingroup qtquick-scenegraph-materials + \warning This utility class is only functional when running with the OpenGL + backend of the Qt Quick scenegraph. + Where the QSGMaterial and QSGMaterialShader API requires a bit of boilerplate code to create a functioning material, the QSGSimpleMaterialShader tries to hide some of this through the use diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp index 744df5e143..3db8163376 100644 --- a/src/quick/scenegraph/util/qsgtexturematerial.cpp +++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp @@ -127,6 +127,9 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa \inmodule QtQuick \ingroup qtquick-scenegraph-materials + \warning This utility class is only functional when running with the OpenGL + backend of the Qt Quick scenegraph. + The opaque textured material will fill every pixel in a geometry with the supplied texture. The material does not respect the opacity of the QSGMaterialShader::RenderState, so opacity nodes in the parent chain @@ -321,6 +324,9 @@ int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const \inmodule QtQuick \ingroup qtquick-scenegraph-materials + \warning This utility class is only functional when running with the OpenGL + backend of the Qt Quick scenegraph. + The textured material will fill every pixel in a geometry with the supplied texture. diff --git a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp index 18de19b04e..dedbc86385 100644 --- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp @@ -107,6 +107,9 @@ void QSGVertexColorMaterialShader::initialize() \inmodule QtQuick \ingroup qtquick-scenegraph-materials + \warning This utility class is only functional when running with the OpenGL + backend of the Qt Quick scenegraph. + The vertex color material will give each vertex in a geometry a color. Pixels between vertices will be linearly interpolated. The colors can contain transparency. diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp index b34f58f7c4..34b9fb6b07 100644 --- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp +++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp @@ -179,7 +179,11 @@ void tst_qquickanimatedimage::mirror_running() QImage frame0_expected = frame0.transformed(transform); QImage frame1_expected = frame1.transformed(transform); + if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(frame0_flipped, frame0_expected); + if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(frame1_flipped, frame1_expected); delete anim; @@ -212,6 +216,8 @@ void tst_qquickanimatedimage::mirror_notRunning() screenshot = window.grabWindow(); screenshot.save("screen.png"); + if (window.devicePixelRatio() != 1.0 && window.rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(screenshot, expected); // mirroring should not change the current frame or playing status diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp index 40cead6ac0..5d242fab9e 100644 --- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp +++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp @@ -246,6 +246,11 @@ void tst_qquickborderimage::mirror() image->setProperty("mirror", true); screenshot = window->grabWindow(); + + window->show(); + QTest::qWaitForWindowExposed(window); + if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) + QSKIP("QTBUG-53823"); QCOMPARE(screenshot, srcPixmap); delete window; diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index d991f189fc..2576a1b0fc 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -30,6 +30,7 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> +#include <QtQuick/qsgrendererinterface.h> #include <QtGui/qopenglcontext.h> #include <QtGui/qopenglfunctions.h> @@ -91,19 +92,21 @@ private: bool m_isMesaSoftwareRasterizer; int m_mesaVersion; + bool m_isOpenGLRenderer; }; tst_QQuickItemLayer::tst_QQuickItemLayer() : m_isMesaSoftwareRasterizer(false) , m_mesaVersion(0) + , m_isOpenGLRenderer(true) { } void tst_QQuickItemLayer::initTestCase() { QQmlDataTest::initTestCase(); - QWindow window; #ifndef QT_NO_OPENGL + QWindow window; QOpenGLContext context; window.setSurfaceType(QWindow::OpenGLSurface); window.create(); @@ -131,9 +134,13 @@ void tst_QQuickItemLayer::initTestCase() m_mesaVersion = QT_VERSION_CHECK(major, minor, patch); } } -#else window.create(); #endif + QQuickView view; + view.showNormal(); + QTest::qWaitForWindowExposed(&view); + if (view.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL) + m_isOpenGLRenderer = false; } // The test draws a red and a blue box next to each other and tests that the @@ -206,6 +213,9 @@ void tst_QQuickItemLayer::layerSourceRect() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("SourceRect.qml"); // Check that the edges are converted to blue @@ -226,6 +236,10 @@ void tst_QQuickItemLayer::layerIsTextureProvider() { if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("TextureProvider.qml"); QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0)); QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0)); @@ -259,6 +273,9 @@ void tst_QQuickItemLayer::layerVisibility() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QFETCH(bool, visible); QFETCH(bool, effect); QFETCH(qreal, opacity); @@ -307,6 +324,9 @@ void tst_QQuickItemLayer::layerZOrder() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QFETCH(bool, effect); QQuickView view; @@ -341,6 +361,9 @@ void tst_QQuickItemLayer::changeZOrder() if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QFETCH(bool, layered); QFETCH(bool, effect); @@ -408,6 +431,10 @@ void tst_QQuickItemLayer::changeSamplerName() { if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("SamplerNameChange.qml"); QCOMPARE(fb.pixel(0, 0), qRgb(0, 0, 0xff)); } @@ -416,6 +443,9 @@ void tst_QQuickItemLayer::itemEffect() { if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0)) QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly."); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QImage fb = runTest("ItemEffect.qml"); QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0)); QCOMPARE(fb.pixel(199, 0), qRgb(0xff, 0, 0)); @@ -451,6 +481,9 @@ void tst_QQuickItemLayer::textureMirroring() { QFETCH(int, mirroring); + if (!m_isOpenGLRenderer) + QSKIP("Only OpenGL Renderer supports GLSL ShaderEffects"); + QQuickView view; view.setSource(testFileUrl("TextureMirroring.qml")); diff --git a/tests/benchmarks/qml/compilation/tst_compilation.cpp b/tests/benchmarks/qml/compilation/tst_compilation.cpp index 3f2cb5b94f..690e193b53 100644 --- a/tests/benchmarks/qml/compilation/tst_compilation.cpp +++ b/tests/benchmarks/qml/compilation/tst_compilation.cpp @@ -75,7 +75,9 @@ void tst_compilation::boomblock() QQmlComponent c(&engine); c.setData(data, QUrl()); } - +#ifdef QT_NO_OPENGL + QSKIP("boomblock imports Particles which requires OpenGL Support"); +#endif QBENCHMARK { QQmlComponent c(&engine); c.setData(data, QUrl()); |