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(); |
20 | |
21 | bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; |
22 | }; |
23 | |
24 | SmoothColorMaterialRhiShader::SmoothColorMaterialRhiShader() |
25 | { |
26 | setShaderFileName(stage: VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/smoothcolor.vert.qsb" )); |
27 | setShaderFileName(stage: FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/smoothcolor.frag.qsb" )); |
28 | } |
29 | |
30 | bool SmoothColorMaterialRhiShader::updateUniformData(RenderState &state, QSGMaterial *, QSGMaterial *oldMaterial) |
31 | { |
32 | bool changed = false; |
33 | QByteArray *buf = state.uniformData(); |
34 | |
35 | if (state.isMatrixDirty()) { |
36 | const QMatrix4x4 m = state.combinedMatrix(); |
37 | memcpy(dest: buf->data(), src: m.constData(), n: 64); |
38 | changed = true; |
39 | } |
40 | |
41 | if (oldMaterial == nullptr) { |
42 | // The viewport is constant, so set the pixel size uniform only once. |
43 | const QRect r = state.viewportRect(); |
44 | const QVector2D v(2.0f / r.width(), 2.0f / r.height()); |
45 | Q_ASSERT(sizeof(v) == 8); |
46 | memcpy(dest: buf->data() + 64, src: &v, n: 8); |
47 | changed = true; |
48 | } |
49 | |
50 | if (state.isOpacityDirty()) { |
51 | const float opacity = state.opacity(); |
52 | memcpy(dest: buf->data() + 72, src: &opacity, n: 4); |
53 | changed = true; |
54 | } |
55 | |
56 | return changed; |
57 | } |
58 | |
59 | |
60 | QSGSmoothColorMaterial::QSGSmoothColorMaterial() |
61 | { |
62 | setFlag(flags: RequiresFullMatrixExceptTranslate, on: true); |
63 | setFlag(flags: Blending, on: true); |
64 | } |
65 | |
66 | int QSGSmoothColorMaterial::compare(const QSGMaterial *) const |
67 | { |
68 | // all state in vertex attributes -> all smoothcolor materials are equal |
69 | return 0; |
70 | } |
71 | |
72 | QSGMaterialType *QSGSmoothColorMaterial::type() const |
73 | { |
74 | static QSGMaterialType type; |
75 | return &type; |
76 | } |
77 | |
78 | QSGMaterialShader *QSGSmoothColorMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const |
79 | { |
80 | Q_UNUSED(renderMode); |
81 | return new SmoothColorMaterialRhiShader; |
82 | } |
83 | |
84 | QSGDefaultInternalRectangleNode::QSGDefaultInternalRectangleNode() |
85 | { |
86 | setMaterial(&m_material); |
87 | } |
88 | |
89 | void QSGDefaultInternalRectangleNode::updateMaterialAntialiasing() |
90 | { |
91 | if (m_antialiasing) |
92 | setMaterial(&m_smoothMaterial); |
93 | else |
94 | setMaterial(&m_material); |
95 | } |
96 | |
97 | void QSGDefaultInternalRectangleNode::updateMaterialBlending(QSGNode::DirtyState *state) |
98 | { |
99 | // smoothed material is always blended, so no change in material state |
100 | if (material() == &m_material) { |
101 | bool wasBlending = (m_material.flags() & QSGMaterial::Blending); |
102 | bool isBlending = (m_gradient_stops.size() > 0 && !m_gradient_is_opaque) |
103 | || (m_color.alpha() < 255 && m_color.alpha() != 0) |
104 | || (m_pen_width > 0 && m_border_color.alpha() < 255); |
105 | if (wasBlending != isBlending) { |
106 | m_material.setFlag(flags: QSGMaterial::Blending, on: isBlending); |
107 | *state |= QSGNode::DirtyMaterial; |
108 | } |
109 | } |
110 | } |
111 | |
112 | QT_END_NAMESPACE |
113 | |