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 "qsgdefaultinternalimagenode_p.h"
5#include <private/qsgdefaultrendercontext_p.h>
6#include <private/qsgmaterialshader_p.h>
7#include <private/qsgtexturematerial_p.h>
8#include <qopenglfunctions.h>
9#include <QtCore/qmath.h>
10#include <rhi/qrhi.h>
11
12QT_BEGIN_NAMESPACE
13
14class SmoothTextureMaterialRhiShader : public QSGTextureMaterialRhiShader
15{
16public:
17 SmoothTextureMaterialRhiShader(int viewCount);
18
19 bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
20};
21
22
23QSGSmoothTextureMaterial::QSGSmoothTextureMaterial()
24{
25 setFlag(flags: RequiresFullMatrixExceptTranslate, on: true);
26 setFlag(flags: Blending, on: true);
27}
28
29void QSGSmoothTextureMaterial::setTexture(QSGTexture *texture)
30{
31 m_texture = texture;
32}
33
34QSGMaterialType *QSGSmoothTextureMaterial::type() const
35{
36 static QSGMaterialType type;
37 return &type;
38}
39
40QSGMaterialShader *QSGSmoothTextureMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
41{
42 Q_UNUSED(renderMode);
43 return new SmoothTextureMaterialRhiShader(viewCount());
44}
45
46SmoothTextureMaterialRhiShader::SmoothTextureMaterialRhiShader(int viewCount)
47 : QSGTextureMaterialRhiShader(viewCount)
48{
49 setShaderFileName(stage: VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/smoothtexture.vert.qsb"), viewCount);
50 setShaderFileName(stage: FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/smoothtexture.frag.qsb"), viewCount);
51}
52
53bool SmoothTextureMaterialRhiShader::updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
54{
55 bool changed = false;
56 QByteArray *buf = state.uniformData();
57 const int shaderMatrixCount = newMaterial->viewCount();
58
59 if (!oldMaterial) {
60 // The viewport is constant, so set the pixel size uniform only once (per batches with the same material).
61 const QRect r = state.viewportRect();
62 const QVector2D v(2.0f / r.width(), 2.0f / r.height());
63 // mat4 matrix, float opacity, vec2 pixelSize, and the vec2 must be 2*4 aligned
64 memcpy(dest: buf->data() + 64 * shaderMatrixCount + 8, src: &v, n: 8);
65 changed = true;
66 }
67
68 changed |= QSGTextureMaterialRhiShader::updateUniformData(state, newMaterial, oldMaterial);
69
70 return changed;
71}
72
73
74QSGDefaultInternalImageNode::QSGDefaultInternalImageNode(QSGDefaultRenderContext *rc)
75 : m_rc(rc)
76{
77 setMaterial(&m_materialO);
78 setOpaqueMaterial(&m_material);
79}
80
81void QSGDefaultInternalImageNode::setFiltering(QSGTexture::Filtering filtering)
82{
83 if (m_material.filtering() == filtering)
84 return;
85
86 m_material.setFiltering(filtering);
87 m_materialO.setFiltering(filtering);
88 m_smoothMaterial.setFiltering(filtering);
89 markDirty(bits: DirtyMaterial);
90}
91
92void QSGDefaultInternalImageNode::setMipmapFiltering(QSGTexture::Filtering filtering)
93{
94 if (m_material.mipmapFiltering() == filtering)
95 return;
96
97 m_material.setMipmapFiltering(filtering);
98 m_materialO.setMipmapFiltering(filtering);
99 m_smoothMaterial.setMipmapFiltering(filtering);
100 markDirty(bits: DirtyMaterial);
101}
102
103void QSGDefaultInternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode)
104{
105 if (m_material.verticalWrapMode() == wrapMode)
106 return;
107
108 m_material.setVerticalWrapMode(wrapMode);
109 m_materialO.setVerticalWrapMode(wrapMode);
110 m_smoothMaterial.setVerticalWrapMode(wrapMode);
111 markDirty(bits: DirtyMaterial);
112}
113
114void QSGDefaultInternalImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)
115{
116 if (m_material.horizontalWrapMode() == wrapMode)
117 return;
118
119 m_material.setHorizontalWrapMode(wrapMode);
120 m_materialO.setHorizontalWrapMode(wrapMode);
121 m_smoothMaterial.setHorizontalWrapMode(wrapMode);
122 markDirty(bits: DirtyMaterial);
123}
124
125void QSGDefaultInternalImageNode::updateMaterialAntialiasing()
126{
127 if (m_antialiasing) {
128 setMaterial(&m_smoothMaterial);
129 setOpaqueMaterial(nullptr);
130 } else {
131 setMaterial(&m_materialO);
132 setOpaqueMaterial(&m_material);
133 }
134}
135
136void QSGDefaultInternalImageNode::setMaterialTexture(QSGTexture *texture)
137{
138 m_material.setTexture(texture);
139 m_materialO.setTexture(texture);
140 m_smoothMaterial.setTexture(texture);
141}
142
143QSGTexture *QSGDefaultInternalImageNode::materialTexture() const
144{
145 return m_material.texture();
146}
147
148bool QSGDefaultInternalImageNode::updateMaterialBlending()
149{
150 const bool alpha = m_material.flags() & QSGMaterial::Blending;
151 if (materialTexture() && alpha != materialTexture()->hasAlphaChannel()) {
152 m_material.setFlag(flags: QSGMaterial::Blending, on: !alpha);
153 return true;
154 }
155 return false;
156}
157
158inline static bool isPowerOfTwo(int x)
159{
160 // Assumption: x >= 1
161 return x == (x & -x);
162}
163
164bool QSGDefaultInternalImageNode::supportsWrap(const QSize &size) const
165{
166 bool npotSupported = m_rc->rhi() && m_rc->rhi()->isFeatureSupported(feature: QRhi::NPOTTextureRepeat);
167 return npotSupported || (isPowerOfTwo(x: size.width()) && isPowerOfTwo(x: size.height()));
168}
169
170QT_END_NAMESPACE
171

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtdeclarative/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp