1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtQuick module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qsgdefaultimagenode_p.h" |
41 | #include <private/qsgnode_p.h> |
42 | |
43 | QT_BEGIN_NAMESPACE |
44 | |
45 | QSGDefaultImageNode::QSGDefaultImageNode() |
46 | : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) |
47 | , m_texCoordMode(QSGDefaultImageNode::NoTransform) |
48 | , m_isAtlasTexture(false) |
49 | , m_ownsTexture(false) |
50 | { |
51 | setGeometry(&m_geometry); |
52 | setMaterial(&m_material); |
53 | setOpaqueMaterial(&m_opaque_material); |
54 | m_material.setMipmapFiltering(QSGTexture::None); |
55 | m_opaque_material.setMipmapFiltering(QSGTexture::None); |
56 | #ifdef QSG_RUNTIME_DESCRIPTION |
57 | qsgnode_set_description(node: this, description: QLatin1String("image" )); |
58 | #endif |
59 | } |
60 | |
61 | QSGDefaultImageNode::~QSGDefaultImageNode() |
62 | { |
63 | if (m_ownsTexture) |
64 | delete m_material.texture(); |
65 | } |
66 | |
67 | void QSGDefaultImageNode::setFiltering(QSGTexture::Filtering filtering) |
68 | { |
69 | if (m_material.filtering() == filtering) |
70 | return; |
71 | |
72 | m_material.setFiltering(filtering); |
73 | m_opaque_material.setFiltering(filtering); |
74 | markDirty(bits: DirtyMaterial); |
75 | } |
76 | |
77 | QSGTexture::Filtering QSGDefaultImageNode::filtering() const |
78 | { |
79 | return m_material.filtering(); |
80 | } |
81 | |
82 | void QSGDefaultImageNode::setMipmapFiltering(QSGTexture::Filtering filtering) |
83 | { |
84 | if (m_material.mipmapFiltering() == filtering) |
85 | return; |
86 | |
87 | m_material.setMipmapFiltering(filtering); |
88 | m_opaque_material.setMipmapFiltering(filtering); |
89 | markDirty(bits: DirtyMaterial); |
90 | } |
91 | |
92 | QSGTexture::Filtering QSGDefaultImageNode::mipmapFiltering() const |
93 | { |
94 | return m_material.mipmapFiltering(); |
95 | } |
96 | |
97 | void QSGDefaultImageNode::setAnisotropyLevel(QSGTexture::AnisotropyLevel level) |
98 | { |
99 | if (m_material.anisotropyLevel() == level) |
100 | return; |
101 | |
102 | m_material.setAnisotropyLevel(level); |
103 | m_opaque_material.setAnisotropyLevel(level); |
104 | markDirty(bits: DirtyMaterial); |
105 | } |
106 | |
107 | QSGTexture::AnisotropyLevel QSGDefaultImageNode::anisotropyLevel() const |
108 | { |
109 | return m_material.anisotropyLevel(); |
110 | } |
111 | |
112 | void QSGDefaultImageNode::setRect(const QRectF &r) |
113 | { |
114 | if (m_rect == r) |
115 | return; |
116 | |
117 | m_rect = r; |
118 | rebuildGeometry(g: &m_geometry, texture: texture(), rect: m_rect, sourceRect: m_sourceRect, texCoordMode: m_texCoordMode); |
119 | markDirty(bits: DirtyGeometry); |
120 | } |
121 | |
122 | QRectF QSGDefaultImageNode::rect() const |
123 | { |
124 | return m_rect; |
125 | } |
126 | |
127 | void QSGDefaultImageNode::setSourceRect(const QRectF &r) |
128 | { |
129 | if (m_sourceRect == r) |
130 | return; |
131 | |
132 | m_sourceRect = r; |
133 | rebuildGeometry(g: &m_geometry, texture: texture(), rect: m_rect, sourceRect: m_sourceRect, texCoordMode: m_texCoordMode); |
134 | markDirty(bits: DirtyGeometry); |
135 | } |
136 | |
137 | QRectF QSGDefaultImageNode::sourceRect() const |
138 | { |
139 | return m_sourceRect; |
140 | } |
141 | |
142 | void QSGDefaultImageNode::setTexture(QSGTexture *texture) |
143 | { |
144 | Q_ASSERT(texture); |
145 | if (m_ownsTexture) |
146 | delete m_material.texture(); |
147 | m_material.setTexture(texture); |
148 | m_opaque_material.setTexture(texture); |
149 | rebuildGeometry(g: &m_geometry, texture, rect: m_rect, sourceRect: m_sourceRect, texCoordMode: m_texCoordMode); |
150 | |
151 | DirtyState dirty = DirtyMaterial; |
152 | // It would be tempting to skip the extra bit here and instead use |
153 | // m_material.texture to get the old state, but that texture could |
154 | // have been deleted in the mean time. |
155 | bool wasAtlas = m_isAtlasTexture; |
156 | m_isAtlasTexture = texture->isAtlasTexture(); |
157 | if (wasAtlas || m_isAtlasTexture) |
158 | dirty |= DirtyGeometry; |
159 | // The geometry has also changed if the texture size changed. |
160 | if (m_textureSize != texture->textureSize()) |
161 | dirty |= DirtyGeometry; |
162 | m_textureSize = texture->textureSize(); |
163 | markDirty(bits: dirty); |
164 | } |
165 | |
166 | QSGTexture *QSGDefaultImageNode::texture() const |
167 | { |
168 | return m_material.texture(); |
169 | } |
170 | |
171 | void QSGDefaultImageNode::setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode) |
172 | { |
173 | if (m_texCoordMode == mode) |
174 | return; |
175 | m_texCoordMode = mode; |
176 | rebuildGeometry(g: &m_geometry, texture: texture(), rect: m_rect, sourceRect: m_sourceRect, texCoordMode: m_texCoordMode); |
177 | markDirty(bits: DirtyMaterial); |
178 | } |
179 | |
180 | QSGDefaultImageNode::TextureCoordinatesTransformMode QSGDefaultImageNode::textureCoordinatesTransform() const |
181 | { |
182 | return m_texCoordMode; |
183 | } |
184 | |
185 | void QSGDefaultImageNode::setOwnsTexture(bool owns) |
186 | { |
187 | m_ownsTexture = owns; |
188 | } |
189 | |
190 | bool QSGDefaultImageNode::ownsTexture() const |
191 | { |
192 | return m_ownsTexture; |
193 | } |
194 | |
195 | QT_END_NAMESPACE |
196 | |