1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qsgdefaultinternalrectanglenode_p.h" |
5 | |
6 | #include <QtQuick/qsgvertexcolormaterial.h> |
7 | #include <QtQuick/qsgtexturematerial.h> |
8 | |
9 | #include <QtQuick/private/qsgcontext_p.h> |
10 | |
11 | #include <QtCore/qmath.h> |
12 | #include <QtCore/qvarlengtharray.h> |
13 | |
14 | QT_BEGIN_NAMESPACE |
15 | |
16 | class SmoothColorMaterialRhiShader : public QSGMaterialShader |
17 | { |
18 | public: |
19 | SmoothColorMaterialRhiShader(int viewCount); |
20 | |
21 | bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; |
22 | }; |
23 | |
24 | SmoothColorMaterialRhiShader::SmoothColorMaterialRhiShader(int viewCount) |
25 | { |
26 | setShaderFileName(stage: VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/smoothcolor.vert.qsb" ), viewCount); |
27 | setShaderFileName(stage: FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/smoothcolor.frag.qsb" ), viewCount); |
28 | } |
29 | |
30 | bool SmoothColorMaterialRhiShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) |
31 | { |
32 | bool changed = false; |
33 | QByteArray *buf = state.uniformData(); |
34 | const int shaderMatrixCount = newMaterial->viewCount(); |
35 | const int matrixCount = qMin(a: state.projectionMatrixCount(), b: shaderMatrixCount); |
36 | |
37 | for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) { |
38 | if (state.isMatrixDirty()) { |
39 | const QMatrix4x4 m = state.combinedMatrix(index: viewIndex); |
40 | memcpy(dest: buf->data() + 64 * viewIndex, src: m.constData(), n: 64); |
41 | changed = true; |
42 | } |
43 | } |
44 | |
45 | if (oldMaterial == nullptr) { |
46 | // The viewport is constant, so set the pixel size uniform only once. |
47 | const QRect r = state.viewportRect(); |
48 | const QVector2D v(2.0f / r.width(), 2.0f / r.height()); |
49 | Q_ASSERT(sizeof(v) == 8); |
50 | memcpy(dest: buf->data() + 64 * shaderMatrixCount, src: &v, n: 8); |
51 | changed = true; |
52 | } |
53 | |
54 | if (state.isOpacityDirty()) { |
55 | const float opacity = state.opacity(); |
56 | memcpy(dest: buf->data() + 64 * shaderMatrixCount + 8, src: &opacity, n: 4); |
57 | changed = true; |
58 | } |
59 | |
60 | return changed; |
61 | } |
62 | |
63 | |
64 | QSGSmoothColorMaterial::QSGSmoothColorMaterial() |
65 | { |
66 | setFlag(flags: RequiresFullMatrixExceptTranslate, on: true); |
67 | setFlag(flags: Blending, on: true); |
68 | } |
69 | |
70 | int QSGSmoothColorMaterial::compare(const QSGMaterial *) const |
71 | { |
72 | // all state in vertex attributes -> all smoothcolor materials are equal |
73 | return 0; |
74 | } |
75 | |
76 | QSGMaterialType *QSGSmoothColorMaterial::type() const |
77 | { |
78 | static QSGMaterialType type; |
79 | return &type; |
80 | } |
81 | |
82 | QSGMaterialShader *QSGSmoothColorMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const |
83 | { |
84 | Q_UNUSED(renderMode); |
85 | return new SmoothColorMaterialRhiShader(viewCount()); |
86 | } |
87 | |
88 | QSGDefaultInternalRectangleNode::QSGDefaultInternalRectangleNode() |
89 | { |
90 | setMaterial(&m_material); |
91 | } |
92 | |
93 | void QSGDefaultInternalRectangleNode::updateMaterialAntialiasing() |
94 | { |
95 | if (m_antialiasing) |
96 | setMaterial(&m_smoothMaterial); |
97 | else |
98 | setMaterial(&m_material); |
99 | } |
100 | |
101 | void QSGDefaultInternalRectangleNode::updateMaterialBlending(QSGNode::DirtyState *state) |
102 | { |
103 | // smoothed material is always blended, so no change in material state |
104 | if (material() == &m_material) { |
105 | bool wasBlending = (m_material.flags() & QSGMaterial::Blending); |
106 | bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque) |
107 | || (m_color.alpha() < 255 && m_color.alpha() != 0) |
108 | || (m_pen_width > 0 && m_border_color.alpha() < 255); |
109 | if (wasBlending != isBlending) { |
110 | m_material.setFlag(flags: QSGMaterial::Blending, on: isBlending); |
111 | *state |= QSGNode::DirtyMaterial; |
112 | } |
113 | } |
114 | } |
115 | |
116 | QT_END_NAMESPACE |
117 | |