Merge lp:~loic.molinari/ubuntu-ui-toolkit/ubuntu-ui-toolkit-shape-texture-ref-counting into lp:ubuntu-ui-toolkit/staging
- ubuntu-ui-toolkit-shape-texture-ref-counting
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Tim Peeters |
Approved revision: | 1846 |
Merged at revision: | 2014 |
Proposed branch: | lp:~loic.molinari/ubuntu-ui-toolkit/ubuntu-ui-toolkit-shape-texture-ref-counting |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Diff against target: |
373 lines (+108/-104) 5 files modified
src/Ubuntu/Components/plugin/plugin.pri (+2/-1) src/Ubuntu/Components/plugin/ucubuntushape.cpp (+77/-90) src/Ubuntu/Components/plugin/ucubuntushape.h (+7/-2) src/Ubuntu/Components/plugin/ucubuntushapetextures.cpp (+5/-11) src/Ubuntu/Components/plugin/ucubuntushapetextures.h (+17/-0) |
To merge this branch: | bzr merge lp:~loic.molinari/ubuntu-ui-toolkit/ubuntu-ui-toolkit-shape-texture-ref-counting |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
ubuntu-sdk-build-bot | continuous-integration | Approve | |
Tim Peeters | Approve | ||
Gerry Boland (community) | Needs Information | ||
Review via email: mp+285643@code.launchpad.net |
Commit message
[UbuntuShape] Use reference counting to handle shape textures.
The current shape textures handling system requires to search for the textures associated to the current graphics context by doing a search in an array for each item at each updatePaintNode() call. It also deletes the textures on OpenGLContext:
We propose an alternative to create and destroy shape textures per material creation and destruction with a reference counting mechanism to minimise costly calls. We search for the shape textures (hash lookup with an OpenGL context pointer as the key) only when a texture material is created or deleted, which is much more occasional compared to updatePaintNode() calls. That also ensures textures are deleted with the proper OpenGL context bound.
The only drawback is that shape textures are deleted when there is no shape items anymore in a scene and recreated when there is a new one appearing. These operations being quite uncommon and relatively fast, the advantages seem to be higher than the drawbacks.
Description of the change
[UbuntuShape] Use reference counting to handle shape textures.
The current shape textures handling system requires to search for the textures associated to the current graphics context by doing a search in an array for each item at each updatePaintNode() call. It also deletes the textures on OpenGLContext:
We propose an alternative to create and destroy shape textures per material creation and destruction with a reference counting mechanism to minimise costly calls. We search for the shape textures (hash lookup with an OpenGL context pointer as the key) only when a texture material is created or deleted, which is much more occasional compared to updatePaintNode() calls. That also ensures textures are deleted with the proper OpenGL context bound.
The only drawback is that shape textures are deleted when there is no shape items anymore in a scene and recreated when there is a new one appearing. These operations being quite uncommon and relatively fast, the advantages seem to be higher than the drawbacks.
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1844
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1844
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1844
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1844
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1845
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1845
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1845
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1845
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1845
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Gerry Boland (gerboland) wrote : | # |
Approach looks reasonable.
However this won't release the textures on invalidateScene
Loïc Molinari (loic.molinari) wrote : | # |
> Approach looks reasonable.
>
> However this won't release the textures on invalidateScene
> releaseResources() call, which are also correct times to release. Waiting for
> later MP?
Apart from ensuring that a material is bound to a graphics context at construction and destruction, there is a nice side effect of managing the textures in QSGMaterial's constructor and destructor: we can rely on QtQuick to manage the lifetime of the materials it creates. It guarantees that all the materials created will be destroyed (and at the right time)!
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
Click here to trigger a rebuild:
https:/
Tim Peeters (tpeeters) wrote : | # |
"
The only drawback is that shape textures are deleted when there is no shape items anymore in a scene and recreated when there is a new one appearing. These operations being quite uncommon and relatively fast, the advantages seem to be higher than the drawbacks.
"
If that worries you, I am sure there are ways to postpone the deletion until the context is destroyed.
Also one inline comment below.
Loïc Molinari (loic.molinari) : | # |
Loïc Molinari (loic.molinari) wrote : | # |
> "
> The only drawback is that shape textures are deleted when there is no shape
> items anymore in a scene and recreated when there is a new one appearing.
> These operations being quite uncommon and relatively fast, the advantages seem
> to be higher than the drawbacks.
> "
>
> If that worries you, I am sure there are ways to postpone the deletion until
> the context is destroyed.
The destruction and recreation are sparse enough not to scare me at all :) I'm actually much happier with this design. Also, postponing deletion to when the context is destroyed would put us back to square one, this change (which I think is easier to understand and in less lines of code) has been especially made to not have to deal with context tracking, which appeared to be a pain to deal with.
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
ubuntu-sdk-build-bot (ubuntu-sdk-build-bot) wrote : | # |
PASSED: Continuous integration, rev:1846
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'src/Ubuntu/Components/plugin/plugin.pri' |
2 | --- src/Ubuntu/Components/plugin/plugin.pri 2016-06-02 12:50:02 +0000 |
3 | +++ src/Ubuntu/Components/plugin/plugin.pri 2016-06-16 09:57:12 +0000 |
4 | @@ -28,7 +28,7 @@ |
5 | $$PWD/ucunits.h \ |
6 | $$PWD/ucqquickimageextension.h \ |
7 | $$PWD/quickutils.h \ |
8 | - $$PWD/ucubuntushapetexture.h \ |
9 | + $$PWD/ucubuntushapetextures.h \ |
10 | $$PWD/ucubuntushape.h \ |
11 | $$PWD/ucubuntushapeoverlay.h \ |
12 | $$PWD/ucproportionalshape.h \ |
13 | @@ -126,6 +126,7 @@ |
14 | $$PWD/ucunits.cpp \ |
15 | $$PWD/ucqquickimageextension.cpp \ |
16 | $$PWD/quickutils.cpp \ |
17 | + $$PWD/ucubuntushapetextures.cpp \ |
18 | $$PWD/ucubuntushape.cpp \ |
19 | $$PWD/ucubuntushapeoverlay.cpp \ |
20 | $$PWD/ucproportionalshape.cpp \ |
21 | |
22 | === modified file 'src/Ubuntu/Components/plugin/ucubuntushape.cpp' |
23 | --- src/Ubuntu/Components/plugin/ucubuntushape.cpp 2016-05-25 12:48:10 +0000 |
24 | +++ src/Ubuntu/Components/plugin/ucubuntushape.cpp 2016-06-16 09:57:12 +0000 |
25 | @@ -26,7 +26,6 @@ |
26 | // evaluated. |
27 | |
28 | #include "ucubuntushape.h" |
29 | -#include "ucubuntushapetexture.h" |
30 | #include "ucunits.h" |
31 | #include "ucnamespace.h" |
32 | #include <QtCore/QPointer> |
33 | @@ -90,10 +89,11 @@ |
34 | { |
35 | Q_UNUSED(oldEffect); |
36 | |
37 | - const ShapeMaterial::Data* data = static_cast<ShapeMaterial*>(newEffect)->constData(); |
38 | + ShapeMaterial* material = static_cast<ShapeMaterial*>(newEffect); |
39 | + const ShapeMaterial::Data* data = material->constData(); |
40 | |
41 | // Bind shape texture. |
42 | - glBindTexture(GL_TEXTURE_2D, data->shapeTextureId); |
43 | + glBindTexture(GL_TEXTURE_2D, material->textureIds()[data->shapeTextureIndex]); |
44 | |
45 | // Bind source texture on the 2nd texture unit and update uniforms. |
46 | bool textured = false; |
47 | @@ -151,12 +151,82 @@ |
48 | |
49 | // --- Scene graph material --- |
50 | |
51 | +// Create and setup shape textures. |
52 | +static void createShapeTextures(QOpenGLContext* openglContext, quint32* ids) |
53 | +{ |
54 | + glGenTextures(shapeTextureCount, ids); |
55 | + |
56 | + if (UCUbuntuShape::useDistanceFields(openglContext)) { |
57 | + // Create distance field textures. |
58 | + for (int i = 0; i < shapeTextureCount; i++) { |
59 | + glBindTexture(GL_TEXTURE_2D, ids[i]); |
60 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
61 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
62 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
63 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
64 | + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shapeTextureWidth, shapeTextureHeight, 0, |
65 | + GL_RGBA, GL_UNSIGNED_BYTE, shapeTextureData[i]); |
66 | + } |
67 | + } else { |
68 | + // Create mipmap textures. |
69 | + for (int i = 0; i < shapeTextureCount; i++) { |
70 | + glBindTexture(GL_TEXTURE_2D, ids[i]); |
71 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
72 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
73 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
74 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
75 | + for (int j = 0; j < shapeTextureMipmapCount; j++) { |
76 | + glTexImage2D(GL_TEXTURE_2D, j, GL_RGBA, shapeTextureMipmapWidth >> j, |
77 | + shapeTextureMipmapHeight >> j, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
78 | + &shapeTextureMipmapData[i][shapeTextureMipmapOffset[j]]); |
79 | + } |
80 | + } |
81 | + } |
82 | +} |
83 | + |
84 | +class ShapeTextures { |
85 | +public: |
86 | + ShapeTextures() : m_refCount(0) {} |
87 | + quint32* ids() { return m_ids; } |
88 | + quint32 ref() { Q_ASSERT(m_refCount < UINT_MAX); return ++m_refCount; } |
89 | + quint32 unref() { Q_ASSERT(m_refCount > 0); return --m_refCount; } |
90 | +private: |
91 | + quint32 m_refCount; |
92 | + quint32 m_ids[shapeTextureCount]; |
93 | +}; |
94 | + |
95 | +static QHash<QOpenGLContext*, ShapeTextures> shapeTexturesHash; |
96 | +static QMutex shapeTexturesHashMutex; |
97 | + |
98 | ShapeMaterial::ShapeMaterial() |
99 | { |
100 | // The whole struct (with the padding bytes) must be initialized for memcmp() to work as |
101 | // expected in ShapeMaterial::compare(). |
102 | memset(&m_data, 0x00, sizeof(Data)); |
103 | setFlag(Blending); |
104 | + |
105 | + // Get or create the set of textures associated with the current context. We assume that QtQuick |
106 | + // associates the same graphics context to a material for its entire lifetime. |
107 | + QOpenGLContext* context = QOpenGLContext::currentContext(); |
108 | + shapeTexturesHashMutex.lock(); |
109 | + ShapeTextures& textures = shapeTexturesHash[context]; |
110 | + if (textures.ref() == 1) { |
111 | + createShapeTextures(context, textures.ids()); |
112 | + } |
113 | + memcpy(m_shapeTexturesId, textures.ids(), shapeTextureCount * sizeof(quint32)); |
114 | + shapeTexturesHashMutex.unlock(); |
115 | +} |
116 | + |
117 | +ShapeMaterial::~ShapeMaterial() |
118 | +{ |
119 | + shapeTexturesHashMutex.lock(); |
120 | + auto it = shapeTexturesHash.find(QOpenGLContext::currentContext()); |
121 | + Q_ASSERT(it != shapeTexturesHash.end()); |
122 | + if (it.value().unref() == 0) { |
123 | + glDeleteTextures(shapeTextureCount, it.value().ids()); |
124 | + shapeTexturesHash.erase(it); |
125 | + } |
126 | + shapeTexturesHashMutex.unlock(); |
127 | } |
128 | |
129 | QSGMaterialType* ShapeMaterial::type() const |
130 | @@ -246,12 +316,6 @@ |
131 | const float implicitWidthGU = 8.0f; |
132 | const float implicitHeightGU = 8.0f; |
133 | const float radiusGuMap[3] = { 1.45f, 2.55f, 3.65f }; |
134 | -const int maxShapeTextures = 16; |
135 | - |
136 | -static struct { QOpenGLContext* openglContext; quint32 textureId[shapeTextureCount]; } |
137 | - shapeTextures[maxShapeTextures]; |
138 | - |
139 | -static int getShapeTexturesIndex(const QOpenGLContext* openglContext); |
140 | |
141 | /*! \qmltype UbuntuShape |
142 | \instantiates UCUbuntuShape |
143 | @@ -1041,67 +1105,6 @@ |
144 | m_flags |= DirtySourceTransform; |
145 | } |
146 | |
147 | -// Gets the shapeTextures' slot used by the given context, or -1 if not stored. |
148 | -static int getShapeTexturesIndex(const QOpenGLContext* openglContext) |
149 | -{ |
150 | - int index = 0; |
151 | - while (shapeTextures[index].openglContext != openglContext) { |
152 | - index++; |
153 | - if (index == maxShapeTextures) { |
154 | - return -1; |
155 | - } |
156 | - } |
157 | - return index; |
158 | -} |
159 | - |
160 | -// Gets an empty shapeTextures' slot. |
161 | -static int getEmptyShapeTexturesIndex() |
162 | -{ |
163 | - int index = 0; |
164 | - while (shapeTextures[index].openglContext) { |
165 | - index++; |
166 | - if (index == maxShapeTextures) { |
167 | - // Don't bother with a dynamic array, let's just set a high enough maxShapeTextures and |
168 | - // increase the static array size if ever needed. |
169 | - qFatal("reached maximum number of OpenGL contexts supported by UbuntuShape"); |
170 | - } |
171 | - } |
172 | - return index; |
173 | -} |
174 | - |
175 | -// Create and setup shape textures. |
176 | -static void createShapeTextures(QOpenGLContext* openglContext, int index) |
177 | -{ |
178 | - glGenTextures(shapeTextureCount, shapeTextures[index].textureId); |
179 | - |
180 | - if (UCUbuntuShape::useDistanceFields(openglContext)) { |
181 | - // Create distance field textures. |
182 | - for (int i = 0; i < shapeTextureCount; i++) { |
183 | - glBindTexture(GL_TEXTURE_2D, shapeTextures[index].textureId[i]); |
184 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
185 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
186 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
187 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
188 | - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shapeTextureWidth, shapeTextureHeight, 0, |
189 | - GL_RGBA, GL_UNSIGNED_BYTE, shapeTextureData[i]); |
190 | - } |
191 | - } else { |
192 | - // Create mipmap textures. |
193 | - for (int i = 0; i < shapeTextureCount; i++) { |
194 | - glBindTexture(GL_TEXTURE_2D, shapeTextures[index].textureId[i]); |
195 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
196 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
197 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
198 | - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
199 | - for (int j = 0; j < shapeTextureMipmapCount; j++) { |
200 | - glTexImage2D(GL_TEXTURE_2D, j, GL_RGBA, shapeTextureMipmapWidth >> j, |
201 | - shapeTextureMipmapHeight >> j, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
202 | - &shapeTextureMipmapData[i][shapeTextureMipmapOffset[j]]); |
203 | - } |
204 | - } |
205 | - } |
206 | -} |
207 | - |
208 | // Gets the nearest boundary to coord in the texel grid of the given size. |
209 | static Q_DECL_CONSTEXPR float roundTextureCoord(float coord, float size) |
210 | { |
211 | @@ -1182,22 +1185,6 @@ |
212 | QSGNode* node = oldNode ? oldNode : createSceneGraphNode(); |
213 | Q_ASSERT(node); |
214 | |
215 | - // Get or create the shape texture that's stored per context and shared by all the shape items. |
216 | - Q_ASSERT(window()); |
217 | - QOpenGLContext* openglContext = window()->openglContext(); |
218 | - Q_ASSERT(openglContext); |
219 | - int index = getShapeTexturesIndex(openglContext); |
220 | - if (index < 0) { |
221 | - index = getEmptyShapeTexturesIndex(); |
222 | - shapeTextures[index].openglContext = openglContext; |
223 | - createShapeTextures(openglContext, index); |
224 | - connect(openglContext, &QOpenGLContext::aboutToBeDestroyed, [index] { |
225 | - shapeTextures[index].openglContext = NULL; |
226 | - glDeleteTextures(shapeTextureCount, shapeTextures[index].textureId); |
227 | - } ); |
228 | - } |
229 | - const quint32 shapeTextureId = shapeTextures[index].textureId[m_aspect != DropShadow ? 0 : 1]; |
230 | - |
231 | // Get the source texture info and update the source transform if needed. |
232 | QSGTextureProvider* provider = m_source ? m_source->textureProvider() : NULL; |
233 | QSGTexture* sourceTexture = provider ? provider->texture() : NULL; |
234 | @@ -1256,7 +1243,7 @@ |
235 | / qGuiApp->devicePixelRatio(); |
236 | } |
237 | |
238 | - updateMaterial(node, radius, shapeTextureId, sourceTexture && m_sourceOpacity); |
239 | + updateMaterial(node, radius, m_aspect != DropShadow ? 0 : 1, sourceTexture && m_sourceOpacity); |
240 | |
241 | // Get the affine transformation for the source texture coordinates. |
242 | const QVector4D sourceCoordTransform( |
243 | @@ -1312,12 +1299,12 @@ |
244 | } |
245 | |
246 | void UCUbuntuShape::updateMaterial( |
247 | - QSGNode* node, float radius, quint32 shapeTextureId, bool textured) |
248 | + QSGNode* node, float radius, quint8 shapeTextureIndex, bool textured) |
249 | { |
250 | ShapeMaterial::Data* materialData = static_cast<ShapeNode*>(node)->material()->data(); |
251 | quint8 flags = 0; |
252 | |
253 | - materialData->shapeTextureId = shapeTextureId; |
254 | + materialData->shapeTextureIndex = shapeTextureIndex; |
255 | if (textured) { |
256 | materialData->sourceTextureProvider = m_sourceTextureProvider; |
257 | materialData->sourceOpacity = m_sourceOpacity; |
258 | @@ -1364,7 +1351,7 @@ |
259 | const QVector4D& sourceCoordTransform, const QVector4D& sourceMaskTransform, |
260 | const quint32 backgroundColor[3]) |
261 | { |
262 | - // Used by subclasses, using the shapeTextureInfo.offset constant directly allows slightly |
263 | + // Used by subclasses, using the shapeTextureOffset constant directly allows slightly |
264 | // better optimization here. |
265 | Q_UNUSED(shapeOffset); |
266 | |
267 | |
268 | === modified file 'src/Ubuntu/Components/plugin/ucubuntushape.h' |
269 | --- src/Ubuntu/Components/plugin/ucubuntushape.h 2016-04-28 11:19:46 +0000 |
270 | +++ src/Ubuntu/Components/plugin/ucubuntushape.h 2016-06-16 09:57:12 +0000 |
271 | @@ -23,6 +23,7 @@ |
272 | #include <QtQuick/QSGNode> |
273 | #include <QtQuick/qsgmaterial.h> |
274 | #include <QtGui/QOpenGLFunctions> |
275 | +#include "ucubuntushapetextures.h" |
276 | #include "ucimportversionchecker_p.h" |
277 | |
278 | // --- Scene graph shader --- |
279 | @@ -66,22 +67,25 @@ |
280 | Pressed = (1 << 6) |
281 | }; |
282 | QSGTextureProvider* sourceTextureProvider; |
283 | - quint32 shapeTextureId; |
284 | + quint8 shapeTextureIndex; |
285 | quint8 distanceAAFactor; |
286 | quint8 sourceOpacity; |
287 | quint8 flags; |
288 | }; |
289 | |
290 | ShapeMaterial(); |
291 | + ~ShapeMaterial(); |
292 | QSGMaterialType* type() const override; |
293 | QSGMaterialShader* createShader() const override; |
294 | int compare(const QSGMaterial* other) const override; |
295 | virtual void updateTextures(); |
296 | const Data* constData() const { return &m_data; } |
297 | Data* data() { return &m_data; } |
298 | + quint32* textureIds() { return m_shapeTexturesId; } |
299 | |
300 | private: |
301 | Data m_data; |
302 | + quint32 m_shapeTexturesId[shapeTextureCount]; |
303 | }; |
304 | |
305 | // --- Scene graph node --- |
306 | @@ -293,7 +297,8 @@ |
307 | |
308 | // Virtual functions for extended shapes. |
309 | virtual QSGNode* createSceneGraphNode() const; |
310 | - virtual void updateMaterial(QSGNode* node, float radius, quint32 shapeTextureId, bool textured); |
311 | + virtual void updateMaterial( |
312 | + QSGNode* node, float radius, quint8 shapeTextureIndex, bool textured); |
313 | virtual void updateGeometry( |
314 | QSGNode* node, const QSizeF& itemSize, float radius, float shapeOffset, |
315 | const QVector4D& sourceCoordTransform, const QVector4D& sourceMaskTransform, |
316 | |
317 | === renamed file 'src/Ubuntu/Components/plugin/ucubuntushapetexture.h' => 'src/Ubuntu/Components/plugin/ucubuntushapetextures.cpp' |
318 | --- src/Ubuntu/Components/plugin/ucubuntushapetexture.h 2015-10-12 17:20:30 +0000 |
319 | +++ src/Ubuntu/Components/plugin/ucubuntushapetextures.cpp 2016-06-16 09:57:12 +0000 |
320 | @@ -1,12 +1,9 @@ |
321 | // Copyright 2015 Canonical Ltd. |
322 | // Automatically generated by the createshapetextures tool. |
323 | |
324 | -const int shapeTextureCount = 2; |
325 | -const int shapeTextureWidth = 32; |
326 | -const int shapeTextureHeight = 32; |
327 | -const float shapeTextureOffset = 0.0625; |
328 | -const int shapeTextureDistanceAA = 4; |
329 | -static const unsigned char shapeTextureData[2][4097] = { |
330 | +#include "ucubuntushapetextures.h" |
331 | + |
332 | +const unsigned char shapeTextureData[2][4097] = { |
333 | "\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00" |
334 | "\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00" |
335 | "\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x06\x00" |
336 | @@ -522,13 +519,10 @@ |
337 | "\xff\xff\xcc\x00\xff\xff\xcc\x00\xff\xff\xcc\x00\xff\xff\xcc\x00" |
338 | }; |
339 | |
340 | -const int shapeTextureMipmapWidth = 256; |
341 | -const int shapeTextureMipmapHeight = 256; |
342 | -const int shapeTextureMipmapCount = 9; |
343 | -static const int shapeTextureMipmapOffset[9] = { |
344 | +const int shapeTextureMipmapOffset[9] = { |
345 | 0, 262144, 327680, 344064, 348160, 349184, 349440, 349504, 349520 |
346 | }; |
347 | -static const unsigned char shapeTextureMipmapData[2][349525] = { |
348 | +const unsigned char shapeTextureMipmapData[2][349525] = { |
349 | // Mipmap level 0. |
350 | "\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00" |
351 | "\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00\x5e\x5e\x00\x00" |
352 | |
353 | === added file 'src/Ubuntu/Components/plugin/ucubuntushapetextures.h' |
354 | --- src/Ubuntu/Components/plugin/ucubuntushapetextures.h 1970-01-01 00:00:00 +0000 |
355 | +++ src/Ubuntu/Components/plugin/ucubuntushapetextures.h 2016-06-16 09:57:12 +0000 |
356 | @@ -0,0 +1,17 @@ |
357 | +// Copyright 2015 Canonical Ltd. |
358 | +// Automatically generated by the createshapetextures tool. |
359 | + |
360 | +const int shapeTextureCount = 2; |
361 | +const int shapeTextureWidth = 32; |
362 | +const int shapeTextureHeight = 32; |
363 | +const float shapeTextureOffset = 0.0625; |
364 | +const int shapeTextureDistanceAA = 4; |
365 | + |
366 | +extern const unsigned char shapeTextureData[2][4097]; |
367 | + |
368 | +const int shapeTextureMipmapWidth = 256; |
369 | +const int shapeTextureMipmapHeight = 256; |
370 | +const int shapeTextureMipmapCount = 9; |
371 | + |
372 | +extern const int shapeTextureMipmapOffset[9]; |
373 | +extern const unsigned char shapeTextureMipmapData[2][349525]; |
PASSED: Continuous integration, rev:1844 /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-amd64- stable/ 285/ /jenkins. ubuntu. com/ubuntu- sdk/job/ generic- update- mp/750/ console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /jenkins. ubuntu. com/ubuntu- sdk/job/ ubuntu- ui-toolkit- ci-amd64- stable/ 285/rebuild
https:/