OpenCoverage

qopenglpaintengine.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/opengl/qopenglpaintengine.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 QtGui 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/*-
41 When the active program changes, we need to update it's uniforms.-
42 We could track state for each program and only update stale uniforms-
43 - Could lead to lots of overhead if there's a lot of programs-
44 We could update all the uniforms when the program changes-
45 - Could end up updating lots of uniforms which don't need updating-
46-
47 Updating uniforms should be cheap, so the overhead of updating up-to-date-
48 uniforms should be minimal. It's also less complex.-
49-
50 Things which _may_ cause a different program to be used:-
51 - Change in brush/pen style-
52 - Change in painter opacity-
53 - Change in composition mode-
54-
55 Whenever we set a mode on the shader manager - it needs to tell us if it had-
56 to switch to a different program.-
57-
58 The shader manager should only switch when we tell it to. E.g. if we set a new-
59 brush style and then switch to transparent painter, we only want it to compile-
60 and use the correct program when we really need it.-
61*/-
62-
63// #define QT_OPENGL_CACHE_AS_VBOS-
64-
65#include "qopenglgradientcache_p.h"-
66#include "qopengltexturecache_p.h"-
67#include "qopenglpaintengine_p.h"-
68#include "qopenglpaintdevice_p.h"-
69-
70#include <string.h> //for memcpy-
71#include <qmath.h>-
72-
73#include <private/qopengl_p.h>-
74#include <private/qopenglcontext_p.h>-
75#include <private/qopenglextensions_p.h>-
76#include <private/qpaintengineex_p.h>-
77#include <QPaintEngine>-
78#include <private/qpainter_p.h>-
79#include <private/qfontengine_p.h>-
80#include <private/qdatabuffer_p.h>-
81#include <private/qstatictext_p.h>-
82#include <private/qtriangulator_p.h>-
83-
84#include "qopenglengineshadermanager_p.h"-
85#include "qopengl2pexvertexarray_p.h"-
86#include "qopengltextureglyphcache_p.h"-
87-
88#include <QDebug>-
89-
90QT_BEGIN_NAMESPACE-
91-
92-
93-
94Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);-
95-
96////////////////////////////////// Private Methods //////////////////////////////////////////-
97-
98QOpenGL2PaintEngineExPrivate::~QOpenGL2PaintEngineExPrivate()-
99{-
100 delete shaderManager;-
101-
102 if (elementIndicesVBOId != 0) {
elementIndicesVBOId != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
103 funcs.glDeleteBuffers(1, &elementIndicesVBOId);-
104 elementIndicesVBOId = 0;-
105 }
never executed: end of block
0
106}
never executed: end of block
0
107-
108inline QColor qt_premultiplyColor(QColor c, GLfloat opacity)-
109{-
110 qreal alpha = c.alphaF() * opacity;-
111 c.setAlphaF(alpha);-
112 c.setRedF(c.redF() * alpha);-
113 c.setGreenF(c.greenF() * alpha);-
114 c.setBlueF(c.blueF() * alpha);-
115 return c;
never executed: return c;
0
116}-
117-
118-
119void QOpenGL2PaintEngineExPrivate::setBrush(const QBrush& brush)-
120{-
121 if (qbrush_fast_equals(currentBrush, brush))
qbrush_fast_eq...tBrush, brush)Description
TRUEnever evaluated
FALSEnever evaluated
0
122 return;
never executed: return;
0
123-
124 const Qt::BrushStyle newStyle = qbrush_style(brush);-
125 Q_ASSERT(newStyle != Qt::NoBrush);-
126-
127 currentBrush = brush;-
128 if (!currentBrushImage.isNull())
!currentBrushImage.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
129 currentBrushImage = QImage();
never executed: currentBrushImage = QImage();
0
130 brushUniformsDirty = true; // All brushes have at least one uniform-
131-
132 if (newStyle > Qt::SolidPattern)
newStyle > Qt::SolidPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
133 brushTextureDirty = true;
never executed: brushTextureDirty = true;
0
134-
135 if (currentBrush.style() == Qt::TexturePattern
currentBrush.s...TexturePatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
136 && qHasPixmapTexture(brush) && brush.texture().isQBitmap())
qHasPixmapTexture(brush)Description
TRUEnever evaluated
FALSEnever evaluated
brush.texture().isQBitmap()Description
TRUEnever evaluated
FALSEnever evaluated
0
137 {-
138 shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::TextureSrcWithPattern);-
139 } else {
never executed: end of block
0
140 shaderManager->setSrcPixelType(newStyle);-
141 }
never executed: end of block
0
142 shaderManager->optimiseForBrushTransform(currentBrush.transform().type());-
143}
never executed: end of block
0
144-
145-
146void QOpenGL2PaintEngineExPrivate::useSimpleShader()-
147{-
148 shaderManager->useSimpleProgram();-
149-
150 if (matrixDirty)
matrixDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
151 updateMatrix();
never executed: updateMatrix();
0
152}
never executed: end of block
0
153-
154/*-
155 Single entry-point for activating, binding, and setting properties.-
156-
157 Allows keeping track of (caching) the latest texture unit and bound-
158 texture in a central place, so that we can skip re-binding unless-
159 needed.-
160-
161 \note Any code or Qt API that internally activates or binds will-
162 not affect the cache used by this function, which means they will-
163 lead to inconsisent state. QPainter::beginNativePainting() takes-
164 care of resetting the cache, so for user–code this is fine, but-
165 internally in the paint engine care must be taken to not call-
166 functions that may activate or bind under our feet.-
167*/-
168template<typename T>-
169void QOpenGL2PaintEngineExPrivate::updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode)-
170{-
171 static const GLenum target = GL_TEXTURE_2D;-
172-
173 activateTextureUnit(textureUnit);-
174-
175 GLuint textureId = bindTexture(texture);-
176-
177 if (updateMode == UpdateIfNeeded && textureId == lastTextureUsed)
updateMode == UpdateIfNeededDescription
TRUEnever evaluated
FALSEnever evaluated
textureId == lastTextureUsedDescription
TRUEnever evaluated
FALSEnever evaluated
0
178 return;
never executed: return;
0
179-
180 lastTextureUsed = textureId;-
181-
182 funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode);-
183 funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode);-
184-
185 funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filterMode);-
186 funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filterMode);-
187}
never executed: end of block
0
188-
189void QOpenGL2PaintEngineExPrivate::activateTextureUnit(GLenum textureUnit)-
190{-
191 if (textureUnit != lastTextureUnitUsed) {
textureUnit !=...extureUnitUsedDescription
TRUEnever evaluated
FALSEnever evaluated
0
192 funcs.glActiveTexture(GL_TEXTURE0 + textureUnit);-
193 lastTextureUnitUsed = textureUnit;-
194-
195 // We simplify things by keeping a single cached value of the last-
196 // texture that was bound, instead of one per texture unit. This-
197 // means that switching texture units could potentially mean we-
198 // need a re-bind and corresponding parameter updates.-
199 lastTextureUsed = GLuint(-1);-
200 }
never executed: end of block
0
201}
never executed: end of block
0
202-
203template<>-
204GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId)-
205{-
206 if (textureId != lastTextureUsed)
textureId != lastTextureUsedDescription
TRUEnever evaluated
FALSEnever evaluated
0
207 funcs.glBindTexture(GL_TEXTURE_2D, textureId);
never executed: funcs.glBindTexture(0x0DE1, textureId);
0
208-
209 return textureId;
never executed: return textureId;
0
210}-
211-
212template<>-
213GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QImage &image)-
214{-
215 return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image);
never executed: return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image);
0
216}-
217-
218template<>-
219GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap)-
220{-
221 return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
never executed: return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
0
222}-
223-
224template<>-
225GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient)-
226{-
227 // We apply global opacity in the fragment shaders, so we always pass 1.0-
228 // for opacity to the cache.-
229 GLuint textureId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(gradient, 1.0);-
230-
231 // QOpenGL2GradientCache::getBuffer() may bind and generate a new texture if it-
232 // hasn't been cached yet, but will otherwise return an unbound texture id. To-
233 // be sure that the texture is bound, we unfortunately have to bind again,-
234 // which results in the initial generation of the texture doing two binds.-
235 return bindTexture(textureId);
never executed: return bindTexture(textureId);
0
236}-
237-
238struct ImageWithBindOptions-
239{-
240 const QImage &image;-
241 QOpenGLTextureCache::BindOptions options;-
242};-
243-
244template<>-
245GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const ImageWithBindOptions &imageWithOptions)-
246{-
247 return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, imageWithOptions.image, imageWithOptions.options);
never executed: return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, imageWithOptions.image, imageWithOptions.options);
0
248}-
249-
250void QOpenGL2PaintEngineExPrivate::updateBrushTexture()-
251{-
252 Q_Q(QOpenGL2PaintEngineEx);-
253// qDebug("QOpenGL2PaintEngineExPrivate::updateBrushTexture()");-
254 Qt::BrushStyle style = currentBrush.style();-
255-
256 bool smoothPixmapTransform = q->state()->renderHints & QPainter::SmoothPixmapTransform;-
257 GLenum filterMode = smoothPixmapTransform ? GL_LINEAR : GL_NEAREST;
smoothPixmapTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
258-
259 if ( (style >= Qt::Dense1Pattern) && (style <= Qt::DiagCrossPattern) ) {
(style >= Qt::Dense1Pattern)Description
TRUEnever evaluated
FALSEnever evaluated
(style <= Qt::...gCrossPattern)Description
TRUEnever evaluated
FALSEnever evaluated
0
260 // Get the image data for the pattern-
261 QImage textureImage = qt_imageForBrush(style, false);-
262-
263 updateTexture(QT_BRUSH_TEXTURE_UNIT, textureImage, GL_REPEAT, filterMode, ForceUpdate);-
264 }
never executed: end of block
0
265 else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
style >= Qt::L...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
style <= Qt::C...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
266 // Gradiant brush: All the gradiants use the same texture-
267-
268 const QGradient *gradient = currentBrush.gradient();-
269-
270 GLenum wrapMode = GL_CLAMP_TO_EDGE;-
271 if (gradient->spread() == QGradient::RepeatSpread || gradient->type() == QGradient::ConicalGradient)
gradient->spre...::RepeatSpreadDescription
TRUEnever evaluated
FALSEnever evaluated
gradient->type...onicalGradientDescription
TRUEnever evaluated
FALSEnever evaluated
0
272 wrapMode = GL_REPEAT;
never executed: wrapMode = 0x2901;
0
273 else if (gradient->spread() == QGradient::ReflectSpread)
gradient->spre...:ReflectSpreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
274 wrapMode = GL_MIRRORED_REPEAT;
never executed: wrapMode = 0x8370;
0
275-
276 updateTexture(QT_BRUSH_TEXTURE_UNIT, *gradient, wrapMode, filterMode, ForceUpdate);-
277 }
never executed: end of block
0
278 else if (style == Qt::TexturePattern) {
style == Qt::TexturePatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
279 currentBrushImage = currentBrush.textureImage();-
280-
281 int max_texture_size = ctx->d_func()->maxTextureSize();-
282 if (currentBrushImage.width() > max_texture_size || currentBrushImage.height() > max_texture_size)
currentBrushIm...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
currentBrushIm...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
283 currentBrushImage = currentBrushImage.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
never executed: currentBrushImage = currentBrushImage.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
0
284-
285 GLuint wrapMode = GL_REPEAT;-
286 if (QOpenGLContext::currentContext()->isOpenGLES()) {
QOpenGLContext...->isOpenGLES()Description
TRUEnever evaluated
FALSEnever evaluated
0
287 // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,-
288 // we emulate GL_REPEAT by only taking the fractional part of the texture coords-
289 // in the qopenglslTextureBrushSrcFragmentShader program.-
290 wrapMode = GL_CLAMP_TO_EDGE;-
291 }
never executed: end of block
0
292-
293 updateTexture(QT_BRUSH_TEXTURE_UNIT, currentBrushImage, wrapMode, filterMode, ForceUpdate);-
294 }
never executed: end of block
0
295 brushTextureDirty = false;-
296}
never executed: end of block
0
297-
298-
299void QOpenGL2PaintEngineExPrivate::updateBrushUniforms()-
300{-
301// qDebug("QOpenGL2PaintEngineExPrivate::updateBrushUniforms()");-
302 Qt::BrushStyle style = currentBrush.style();-
303-
304 if (style == Qt::NoBrush)
style == Qt::NoBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
305 return;
never executed: return;
0
306-
307 QTransform brushQTransform = currentBrush.transform();-
308-
309 if (style == Qt::SolidPattern) {
style == Qt::SolidPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
310 QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);-
311 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::FragmentColor), col);-
312 }
never executed: end of block
0
313 else {-
314 // All other brushes have a transform and thus need the translation point:-
315 QPointF translationPoint;-
316-
317 if (style <= Qt::DiagCrossPattern) {
style <= Qt::DiagCrossPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
318 QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);-
319-
320 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);-
321-
322 QVector2D halfViewportSize(width*0.5, height*0.5);-
323 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);-
324 }
never executed: end of block
0
325 else if (style == Qt::LinearGradientPattern) {
style == Qt::L...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
326 const QLinearGradient *g = static_cast<const QLinearGradient *>(currentBrush.gradient());-
327-
328 QPointF realStart = g->start();-
329 QPointF realFinal = g->finalStop();-
330 translationPoint = realStart;-
331-
332 QPointF l = realFinal - realStart;-
333-
334 QVector3D linearData(-
335 l.x(),-
336 l.y(),-
337 1.0f / (l.x() * l.x() + l.y() * l.y())-
338 );-
339-
340 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::LinearData), linearData);-
341-
342 QVector2D halfViewportSize(width*0.5, height*0.5);-
343 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);-
344 }
never executed: end of block
0
345 else if (style == Qt::ConicalGradientPattern) {
style == Qt::C...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
346 const QConicalGradient *g = static_cast<const QConicalGradient *>(currentBrush.gradient());-
347 translationPoint = g->center();-
348-
349 GLfloat angle = -qDegreesToRadians(g->angle());-
350-
351 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Angle), angle);-
352-
353 QVector2D halfViewportSize(width*0.5, height*0.5);-
354 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);-
355 }
never executed: end of block
0
356 else if (style == Qt::RadialGradientPattern) {
style == Qt::R...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
357 const QRadialGradient *g = static_cast<const QRadialGradient *>(currentBrush.gradient());-
358 QPointF realCenter = g->center();-
359 QPointF realFocal = g->focalPoint();-
360 qreal realRadius = g->centerRadius() - g->focalRadius();-
361 translationPoint = realFocal;-
362-
363 QPointF fmp = realCenter - realFocal;-
364 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Fmp), fmp);-
365-
366 GLfloat fmp2_m_radius2 = -fmp.x() * fmp.x() - fmp.y() * fmp.y() + realRadius*realRadius;-
367 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Fmp2MRadius2), fmp2_m_radius2);-
368 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Inverse2Fmp2MRadius2),-
369 GLfloat(1.0 / (2.0*fmp2_m_radius2)));-
370 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::SqrFr),-
371 GLfloat(g->focalRadius() * g->focalRadius()));-
372 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BRadius),-
373 GLfloat(2 * (g->centerRadius() - g->focalRadius()) * g->focalRadius()),-
374 g->focalRadius(),-
375 g->centerRadius() - g->focalRadius());-
376-
377 QVector2D halfViewportSize(width*0.5, height*0.5);-
378 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);-
379 }
never executed: end of block
0
380 else if (style == Qt::TexturePattern) {
style == Qt::TexturePatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
381 const QPixmap& texPixmap = currentBrush.texture();-
382-
383 if (qHasPixmapTexture(currentBrush) && currentBrush.texture().isQBitmap()) {
qHasPixmapText...(currentBrush)Description
TRUEnever evaluated
FALSEnever evaluated
currentBrush.t...().isQBitmap()Description
TRUEnever evaluated
FALSEnever evaluated
0
384 QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);-
385 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);-
386 }
never executed: end of block
0
387-
388 QSizeF invertedTextureSize(1.0 / texPixmap.width(), 1.0 / texPixmap.height());-
389 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::InvertedTextureSize), invertedTextureSize);-
390-
391 QVector2D halfViewportSize(width*0.5, height*0.5);-
392 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);-
393 }
never executed: end of block
0
394 else-
395 qWarning("QOpenGL2PaintEngineEx: Unimplemented fill style");
never executed: QMessageLogger(__FILE__, 395, __PRETTY_FUNCTION__).warning("QOpenGL2PaintEngineEx: Unimplemented fill style");
0
396-
397 const QPointF &brushOrigin = q->state()->brushOrigin;-
398 QTransform matrix = q->state()->matrix;-
399 matrix.translate(brushOrigin.x(), brushOrigin.y());-
400-
401 QTransform translate(1, 0, 0, 1, -translationPoint.x(), -translationPoint.y());-
402 qreal m22 = -1;-
403 qreal dy = height;-
404 if (device->paintFlipped()) {
device->paintFlipped()Description
TRUEnever evaluated
FALSEnever evaluated
0
405 m22 = 1;-
406 dy = 0;-
407 }
never executed: end of block
0
408 QTransform gl_to_qt(1, 0, 0, m22, 0, dy);-
409 QTransform inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate;-
410-
411 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BrushTransform), inv_matrix);-
412 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BrushTexture), QT_BRUSH_TEXTURE_UNIT);-
413 }
never executed: end of block
0
414 brushUniformsDirty = false;-
415}
never executed: end of block
0
416-
417-
418// This assumes the shader manager has already setup the correct shader program-
419void QOpenGL2PaintEngineExPrivate::updateMatrix()-
420{-
421// qDebug("QOpenGL2PaintEngineExPrivate::updateMatrix()");-
422-
423 const QTransform& transform = q->state()->matrix;-
424-
425 // The projection matrix converts from Qt's coordinate system to GL's coordinate system-
426 // * GL's viewport is 2x2, Qt's is width x height-
427 // * GL has +y -> -y going from bottom -> top, Qt is the other way round-
428 // * GL has [0,0] in the center, Qt has it in the top-left-
429 //-
430 // This results in the Projection matrix below, which is multiplied by the painter's-
431 // transformation matrix, as shown below:-
432 //-
433 // Projection Matrix Painter Transform-
434 // ------------------------------------------------ -------------------------
435 // | 2.0 / width | 0.0 | -1.0 | | m11 | m21 | dx |-
436 // | 0.0 | -2.0 / height | 1.0 | * | m12 | m22 | dy |-
437 // | 0.0 | 0.0 | 1.0 | | m13 | m23 | m33 |-
438 // ------------------------------------------------ -------------------------
439 //-
440 // NOTE: The resultant matrix is also transposed, as GL expects column-major matracies-
441-
442 const GLfloat wfactor = 2.0f / width;-
443 GLfloat hfactor = -2.0f / height;-
444-
445 GLfloat dx = transform.dx();-
446 GLfloat dy = transform.dy();-
447-
448 if (device->paintFlipped()) {
device->paintFlipped()Description
TRUEnever evaluated
FALSEnever evaluated
0
449 hfactor *= -1;-
450 dy -= height;-
451 }
never executed: end of block
0
452-
453 // Non-integer translates can have strange effects for some rendering operations such as-
454 // anti-aliased text rendering. In such cases, we snap the translate to the pixel grid.-
455 if (snapToPixelGrid && transform.type() == QTransform::TxTranslate) {
snapToPixelGridDescription
TRUEnever evaluated
FALSEnever evaluated
transform.type...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
456 // 0.50 needs to rounded down to 0.0 for consistency with raster engine:-
457 dx = std::ceil(dx - 0.5f);-
458 dy = std::ceil(dy - 0.5f);-
459 }
never executed: end of block
0
460 pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13();-
461 pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23();-
462 pmvMatrix[2][0] = (wfactor * dx) - transform.m33();-
463 pmvMatrix[0][1] = (hfactor * transform.m12()) + transform.m13();-
464 pmvMatrix[1][1] = (hfactor * transform.m22()) + transform.m23();-
465 pmvMatrix[2][1] = (hfactor * dy) + transform.m33();-
466 pmvMatrix[0][2] = transform.m13();-
467 pmvMatrix[1][2] = transform.m23();-
468 pmvMatrix[2][2] = transform.m33();-
469-
470 // 1/10000 == 0.0001, so we have good enough res to cover curves-
471 // that span the entire widget...-
472 inverseScale = qMax(1 / qMax( qMax(qAbs(transform.m11()), qAbs(transform.m22())),-
473 qMax(qAbs(transform.m12()), qAbs(transform.m21())) ),-
474 qreal(0.0001));-
475-
476 matrixDirty = false;-
477 matrixUniformDirty = true;-
478-
479 // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only-
480 // need to do this once for every matrix change and persists across all shader programs.-
481 funcs.glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]);-
482 funcs.glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]);-
483 funcs.glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]);-
484-
485 dasher.setInvScale(inverseScale);-
486 stroker.setInvScale(inverseScale);-
487}
never executed: end of block
0
488-
489-
490void QOpenGL2PaintEngineExPrivate::updateCompositionMode()-
491{-
492 // NOTE: The entire paint engine works on pre-multiplied data - which is why some of these-
493 // composition modes look odd.-
494// qDebug() << "QOpenGL2PaintEngineExPrivate::updateCompositionMode() - Setting GL composition mode for " << q->state()->composition_mode;-
495 switch(q->state()->composition_mode) {-
496 case QPainter::CompositionMode_SourceOver:
never executed: case QPainter::CompositionMode_SourceOver:
0
497 funcs.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);-
498 break;
never executed: break;
0
499 case QPainter::CompositionMode_DestinationOver:
never executed: case QPainter::CompositionMode_DestinationOver:
0
500 funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);-
501 break;
never executed: break;
0
502 case QPainter::CompositionMode_Clear:
never executed: case QPainter::CompositionMode_Clear:
0
503 funcs.glBlendFunc(GL_ZERO, GL_ZERO);-
504 break;
never executed: break;
0
505 case QPainter::CompositionMode_Source:
never executed: case QPainter::CompositionMode_Source:
0
506 funcs.glBlendFunc(GL_ONE, GL_ZERO);-
507 break;
never executed: break;
0
508 case QPainter::CompositionMode_Destination:
never executed: case QPainter::CompositionMode_Destination:
0
509 funcs.glBlendFunc(GL_ZERO, GL_ONE);-
510 break;
never executed: break;
0
511 case QPainter::CompositionMode_SourceIn:
never executed: case QPainter::CompositionMode_SourceIn:
0
512 funcs.glBlendFunc(GL_DST_ALPHA, GL_ZERO);-
513 break;
never executed: break;
0
514 case QPainter::CompositionMode_DestinationIn:
never executed: case QPainter::CompositionMode_DestinationIn:
0
515 funcs.glBlendFunc(GL_ZERO, GL_SRC_ALPHA);-
516 break;
never executed: break;
0
517 case QPainter::CompositionMode_SourceOut:
never executed: case QPainter::CompositionMode_SourceOut:
0
518 funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);-
519 break;
never executed: break;
0
520 case QPainter::CompositionMode_DestinationOut:
never executed: case QPainter::CompositionMode_DestinationOut:
0
521 funcs.glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);-
522 break;
never executed: break;
0
523 case QPainter::CompositionMode_SourceAtop:
never executed: case QPainter::CompositionMode_SourceAtop:
0
524 funcs.glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);-
525 break;
never executed: break;
0
526 case QPainter::CompositionMode_DestinationAtop:
never executed: case QPainter::CompositionMode_DestinationAtop:
0
527 funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA);-
528 break;
never executed: break;
0
529 case QPainter::CompositionMode_Xor:
never executed: case QPainter::CompositionMode_Xor:
0
530 funcs.glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);-
531 break;
never executed: break;
0
532 case QPainter::CompositionMode_Plus:
never executed: case QPainter::CompositionMode_Plus:
0
533 funcs.glBlendFunc(GL_ONE, GL_ONE);-
534 break;
never executed: break;
0
535 default:
never executed: default:
0
536 qWarning("Unsupported composition mode");-
537 break;
never executed: break;
0
538 }-
539-
540 compositionModeDirty = false;-
541}
never executed: end of block
0
542-
543static inline void setCoords(GLfloat *coords, const QOpenGLRect &rect)-
544{-
545 coords[0] = rect.left;-
546 coords[1] = rect.top;-
547 coords[2] = rect.right;-
548 coords[3] = rect.top;-
549 coords[4] = rect.right;-
550 coords[5] = rect.bottom;-
551 coords[6] = rect.left;-
552 coords[7] = rect.bottom;-
553}
never executed: end of block
0
554-
555void QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern)-
556{-
557 // Setup for texture drawing-
558 currentBrush = noBrush;-
559-
560 if (snapToPixelGrid) {
snapToPixelGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
561 snapToPixelGrid = false;-
562 matrixDirty = true;-
563 }
never executed: end of block
0
564-
565 if (prepareForDraw(opaque))
prepareForDraw(opaque)Description
TRUEnever evaluated
FALSEnever evaluated
0
566 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
never executed: shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), GLuint(0));
0
567-
568 if (pattern) {
patternDescription
TRUEnever evaluated
FALSEnever evaluated
0
569 QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity);-
570 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);-
571 }
never executed: end of block
0
572-
573 GLfloat dx = 1.0 / textureSize.width();-
574 GLfloat dy = 1.0 / textureSize.height();-
575-
576 QOpenGLRect srcTextureRect(src.left*dx, src.top*dy, src.right*dx, src.bottom*dy);-
577-
578 setCoords(staticVertexCoordinateArray, dest);-
579 setCoords(staticTextureCoordinateArray, srcTextureRect);-
580-
581 funcs.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);-
582}
never executed: end of block
0
583-
584void QOpenGL2PaintEngineEx::beginNativePainting()-
585{-
586 Q_D(QOpenGL2PaintEngineEx);-
587 ensureActive();-
588 d->transferMode(BrushDrawingMode);-
589-
590 d->nativePaintingActive = true;-
591-
592 d->funcs.glUseProgram(0);-
593-
594 // Disable all the vertex attribute arrays:-
595 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
i < 3Description
TRUEnever evaluated
FALSEnever evaluated
0
596 d->funcs.glDisableVertexAttribArray(i);
never executed: d->funcs.glDisableVertexAttribArray(i);
0
597-
598#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC)-
599 Q_ASSERT(QOpenGLContext::currentContext());-
600 const QOpenGLContext *ctx = d->ctx;-
601 const QSurfaceFormat &fmt = d->device->context()->format();-
602 if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
fmt.majorVersion() < 3Description
TRUEnever evaluated
FALSEnever evaluated
fmt.majorVersion() == 3Description
TRUEnever evaluated
FALSEnever evaluated
fmt.minorVersion() < 1Description
TRUEnever evaluated
FALSEnever evaluated
0
603 || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
never executed: return ba;
fmt.majorVersion() == 3Description
TRUEnever evaluated
FALSEnever evaluated
fmt.minorVersion() == 1Description
TRUEnever evaluated
FALSEnever evaluated
ctx->hasExtens...turn ba; }()))Description
TRUEnever evaluated
FALSEnever evaluated
0
604 || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
fmt.profile() ...ibilityProfileDescription
TRUEnever evaluated
FALSEnever evaluated
0
605 {-
606 // be nice to people who mix OpenGL 1.x code with QPainter commands-
607 // by setting modelview and projection matrices to mirror the GL 1-
608 // paint engine-
609 const QTransform& mtx = state()->matrix;-
610-
611 float mv_matrix[4][4] =-
612 {-
613 { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },-
614 { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },-
615 { 0, 0, 1, 0 },-
616 { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }-
617 };-
618-
619 const QSize sz = d->device->size();-
620-
621 glMatrixMode(GL_PROJECTION);-
622 glLoadIdentity();-
623 glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);-
624-
625 glMatrixMode(GL_MODELVIEW);-
626 glLoadMatrixf(&mv_matrix[0][0]);-
627 }
never executed: end of block
0
628#endif // QT_OPENGL_ES_2-
629-
630 d->resetGLState();-
631-
632 // We don't know what texture units and textures the native painting-
633 // will activate and bind, so we can't assume anything when we return-
634 // from the native painting.-
635 d->lastTextureUnitUsed = QT_UNKNOWN_TEXTURE_UNIT;-
636 d->lastTextureUsed = GLuint(-1);-
637-
638 d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);-
639-
640 d->shaderManager->setDirty();-
641-
642 d->needsSync = true;-
643}
never executed: end of block
0
644-
645void QOpenGL2PaintEngineExPrivate::resetGLState()-
646{-
647 activateTextureUnit(QT_DEFAULT_TEXTURE_UNIT);-
648-
649 funcs.glDisable(GL_BLEND);-
650 funcs.glDisable(GL_STENCIL_TEST);-
651 funcs.glDisable(GL_DEPTH_TEST);-
652 funcs.glDisable(GL_SCISSOR_TEST);-
653 funcs.glDepthMask(true);-
654 funcs.glDepthFunc(GL_LESS);-
655 funcs.glClearDepthf(1);-
656 funcs.glStencilMask(0xff);-
657 funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);-
658 funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);-
659 setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);-
660 setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);-
661 setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);-
662 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
!QOpenGLContex...->isOpenGLES()Description
TRUEnever evaluated
FALSEnever evaluated
0
663 // gl_Color, corresponding to vertex attribute 3, may have been changed-
664 float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };-
665 funcs.glVertexAttrib4fv(3, color);-
666 }
never executed: end of block
0
667}
never executed: end of block
0
668-
669void QOpenGL2PaintEngineEx::endNativePainting()-
670{-
671 Q_D(QOpenGL2PaintEngineEx);-
672 d->needsSync = true;-
673 d->nativePaintingActive = false;-
674}
never executed: end of block
0
675-
676void QOpenGL2PaintEngineEx::invalidateState()-
677{-
678 Q_D(QOpenGL2PaintEngineEx);-
679 d->needsSync = true;-
680}
never executed: end of block
0
681-
682bool QOpenGL2PaintEngineEx::isNativePaintingActive() const {-
683 Q_D(const QOpenGL2PaintEngineEx);-
684 return d->nativePaintingActive;
never executed: return d->nativePaintingActive;
0
685}-
686-
687void QOpenGL2PaintEngineExPrivate::transferMode(EngineMode newMode)-
688{-
689 if (newMode == mode)
newMode == modeDescription
TRUEnever evaluated
FALSEnever evaluated
0
690 return;
never executed: return;
0
691-
692 if (newMode == TextDrawingMode) {
newMode == TextDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
693 shaderManager->setHasComplexGeometry(true);-
694 } else {
never executed: end of block
0
695 shaderManager->setHasComplexGeometry(false);-
696 }
never executed: end of block
0
697-
698 if (newMode == ImageDrawingMode) {
newMode == ImageDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
699 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray);-
700 setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, staticTextureCoordinateArray);-
701 }
never executed: end of block
0
702-
703 if (newMode == ImageArrayDrawingMode || newMode == ImageOpacityArrayDrawingMode) {
newMode == Ima...rayDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
newMode == Ima...rayDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
704 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data());-
705 setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data());-
706-
707 if (newMode == ImageOpacityArrayDrawingMode)
newMode == Ima...rayDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
708 setVertexAttributePointer(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data());
never executed: setVertexAttributePointer(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data());
0
709 }
never executed: end of block
0
710-
711 // This needs to change when we implement high-quality anti-aliasing...-
712 if (newMode != TextDrawingMode)
newMode != TextDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
713 shaderManager->setMaskType(QOpenGLEngineShaderManager::NoMask);
never executed: shaderManager->setMaskType(QOpenGLEngineShaderManager::NoMask);
0
714-
715 mode = newMode;-
716}
never executed: end of block
0
717-
718struct QOpenGL2PEVectorPathCache-
719{-
720#ifdef QT_OPENGL_CACHE_AS_VBOS-
721 GLuint vbo;-
722 GLuint ibo;-
723#else-
724 float *vertices;-
725 void *indices;-
726#endif-
727 int vertexCount;-
728 int indexCount;-
729 GLenum primitiveType;-
730 qreal iscale;-
731 QVertexIndexVector::Type indexType;-
732};-
733-
734void QOpenGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, void *data)-
735{-
736 QOpenGL2PEVectorPathCache *c = (QOpenGL2PEVectorPathCache *) data;-
737#ifdef QT_OPENGL_CACHE_AS_VBOS-
738 Q_ASSERT(engine->type() == QPaintEngine::OpenGL2);-
739 static_cast<QOpenGL2PaintEngineEx *>(engine)->d_func()->unusedVBOSToClean << c->vbo;-
740 if (c->ibo)-
741 d->unusedIBOSToClean << c->ibo;-
742#else-
743 Q_UNUSED(engine);-
744 free(c->vertices);-
745 free(c->indices);-
746#endif-
747 delete c;-
748}
never executed: end of block
0
749-
750// Assumes everything is configured for the brush you want to use-
751void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path)-
752{-
753 transferMode(BrushDrawingMode);-
754-
755 if (snapToPixelGrid) {
snapToPixelGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
756 snapToPixelGrid = false;-
757 matrixDirty = true;-
758 }
never executed: end of block
0
759-
760 // Might need to call updateMatrix to re-calculate inverseScale-
761 if (matrixDirty)
matrixDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
762 updateMatrix();
never executed: updateMatrix();
0
763-
764 const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());-
765-
766 // Check to see if there's any hints-
767 if (path.shape() == QVectorPath::RectangleHint) {
path.shape() =...:RectangleHintDescription
TRUEnever evaluated
FALSEnever evaluated
0
768 QOpenGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y());-
769 prepareForDraw(currentBrush.isOpaque());-
770 composite(rect);-
771 } else if (path.isConvex()) {
never executed: end of block
path.isConvex()Description
TRUEnever evaluated
FALSEnever evaluated
0
772-
773 if (path.isCacheable()) {
path.isCacheable()Description
TRUEnever evaluated
FALSEnever evaluated
0
774 QVectorPath::CacheEntry *data = path.lookupCacheData(q);-
775 QOpenGL2PEVectorPathCache *cache;-
776-
777 bool updateCache = false;-
778-
779 if (data) {
dataDescription
TRUEnever evaluated
FALSEnever evaluated
0
780 cache = (QOpenGL2PEVectorPathCache *) data->data;-
781 // Check if scale factor is exceeded for curved paths and generate curves if so...-
782 if (path.isCurved()) {
path.isCurved()Description
TRUEnever evaluated
FALSEnever evaluated
0
783 qreal scaleFactor = cache->iscale / inverseScale;-
784 if (scaleFactor < 0.5 || scaleFactor > 2.0) {
scaleFactor < 0.5Description
TRUEnever evaluated
FALSEnever evaluated
scaleFactor > 2.0Description
TRUEnever evaluated
FALSEnever evaluated
0
785#ifdef QT_OPENGL_CACHE_AS_VBOS-
786 glDeleteBuffers(1, &cache->vbo);-
787 cache->vbo = 0;-
788 Q_ASSERT(cache->ibo == 0);-
789#else-
790 free(cache->vertices);-
791 Q_ASSERT(cache->indices == 0);-
792#endif-
793 updateCache = true;-
794 }
never executed: end of block
0
795 }
never executed: end of block
0
796 } else {
never executed: end of block
0
797 cache = new QOpenGL2PEVectorPathCache;-
798 data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath);-
799 updateCache = true;-
800 }
never executed: end of block
0
801-
802 // Flatten the path at the current scale factor and fill it into the cache struct.-
803 if (updateCache) {
updateCacheDescription
TRUEnever evaluated
FALSEnever evaluated
0
804 vertexCoordinateArray.clear();-
805 vertexCoordinateArray.addPath(path, inverseScale, false);-
806 int vertexCount = vertexCoordinateArray.vertexCount();-
807 int floatSizeInBytes = vertexCount * 2 * sizeof(float);-
808 cache->vertexCount = vertexCount;-
809 cache->indexCount = 0;-
810 cache->primitiveType = GL_TRIANGLE_FAN;-
811 cache->iscale = inverseScale;-
812#ifdef QT_OPENGL_CACHE_AS_VBOS-
813 funcs.glGenBuffers(1, &cache->vbo);-
814 funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);-
815 funcs.glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW);-
816 cache->ibo = 0;-
817#else-
818 cache->vertices = (float *) malloc(floatSizeInBytes);-
819 memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes);-
820 cache->indices = 0;-
821#endif-
822 }
never executed: end of block
0
823-
824 prepareForDraw(currentBrush.isOpaque());-
825#ifdef QT_OPENGL_CACHE_AS_VBOS-
826 funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);-
827 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);-
828#else-
829 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);-
830#endif-
831 funcs.glDrawArrays(cache->primitiveType, 0, cache->vertexCount);-
832-
833 } else {
never executed: end of block
0
834 // printf(" - Marking path as cachable...\n");-
835 // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable-
836 path.makeCacheable();-
837 vertexCoordinateArray.clear();-
838 vertexCoordinateArray.addPath(path, inverseScale, false);-
839 prepareForDraw(currentBrush.isOpaque());-
840 drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN);-
841 }
never executed: end of block
0
842-
843 } else {-
844 bool useCache = path.isCacheable();-
845 if (useCache) {
useCacheDescription
TRUEnever evaluated
FALSEnever evaluated
0
846 QRectF bbox = path.controlPointRect();-
847 // If the path doesn't fit within these limits, it is possible that the triangulation will fail.-
848 useCache &= (bbox.left() > -0x8000 * inverseScale)
(bbox.left() >... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
849 && (bbox.right() < 0x8000 * inverseScale)
(bbox.right() ... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
850 && (bbox.top() > -0x8000 * inverseScale)
(bbox.top() > ... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
851 && (bbox.bottom() < 0x8000 * inverseScale);
(bbox.bottom()... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
852 }
never executed: end of block
0
853-
854 if (useCache) {
useCacheDescription
TRUEnever evaluated
FALSEnever evaluated
0
855 QVectorPath::CacheEntry *data = path.lookupCacheData(q);-
856 QOpenGL2PEVectorPathCache *cache;-
857-
858 bool updateCache = false;-
859-
860 if (data) {
dataDescription
TRUEnever evaluated
FALSEnever evaluated
0
861 cache = (QOpenGL2PEVectorPathCache *) data->data;-
862 // Check if scale factor is exceeded for curved paths and generate curves if so...-
863 if (path.isCurved()) {
path.isCurved()Description
TRUEnever evaluated
FALSEnever evaluated
0
864 qreal scaleFactor = cache->iscale / inverseScale;-
865 if (scaleFactor < 0.5 || scaleFactor > 2.0) {
scaleFactor < 0.5Description
TRUEnever evaluated
FALSEnever evaluated
scaleFactor > 2.0Description
TRUEnever evaluated
FALSEnever evaluated
0
866#ifdef QT_OPENGL_CACHE_AS_VBOS-
867 glDeleteBuffers(1, &cache->vbo);-
868 glDeleteBuffers(1, &cache->ibo);-
869#else-
870 free(cache->vertices);-
871 free(cache->indices);-
872#endif-
873 updateCache = true;-
874 }
never executed: end of block
0
875 }
never executed: end of block
0
876 } else {
never executed: end of block
0
877 cache = new QOpenGL2PEVectorPathCache;-
878 data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath);-
879 updateCache = true;-
880 }
never executed: end of block
0
881-
882 // Flatten the path at the current scale factor and fill it into the cache struct.-
883 if (updateCache) {
updateCacheDescription
TRUEnever evaluated
FALSEnever evaluated
0
884 QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale));-
885 cache->vertexCount = polys.vertices.size() / 2;-
886 cache->indexCount = polys.indices.size();-
887 cache->primitiveType = GL_TRIANGLES;-
888 cache->iscale = inverseScale;-
889 cache->indexType = polys.indices.type();-
890#ifdef QT_OPENGL_CACHE_AS_VBOS-
891 funcs.glGenBuffers(1, &cache->vbo);-
892 funcs.glGenBuffers(1, &cache->ibo);-
893 funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);-
894 funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);-
895-
896 if (polys.indices.type() == QVertexIndexVector::UnsignedInt)-
897 funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);-
898 else-
899 funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint16) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);-
900-
901 QVarLengthArray<float> vertices(polys.vertices.size());-
902 for (int i = 0; i < polys.vertices.size(); ++i)-
903 vertices[i] = float(inverseScale * polys.vertices.at(i));-
904 funcs.glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);-
905#else-
906 cache->vertices = (float *) malloc(sizeof(float) * polys.vertices.size());-
907 if (polys.indices.type() == QVertexIndexVector::UnsignedInt) {
polys.indices....r::UnsignedIntDescription
TRUEnever evaluated
FALSEnever evaluated
0
908 cache->indices = (quint32 *) malloc(sizeof(quint32) * polys.indices.size());-
909 memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size());-
910 } else {
never executed: end of block
0
911 cache->indices = (quint16 *) malloc(sizeof(quint16) * polys.indices.size());-
912 memcpy(cache->indices, polys.indices.data(), sizeof(quint16) * polys.indices.size());-
913 }
never executed: end of block
0
914 for (int i = 0; i < polys.vertices.size(); ++i)
i < polys.vertices.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
915 cache->vertices[i] = float(inverseScale * polys.vertices.at(i));
never executed: cache->vertices[i] = float(inverseScale * polys.vertices.at(i));
0
916#endif-
917 }
never executed: end of block
0
918-
919 prepareForDraw(currentBrush.isOpaque());-
920#ifdef QT_OPENGL_CACHE_AS_VBOS-
921 funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);-
922 funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);-
923 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);-
924 if (cache->indexType == QVertexIndexVector::UnsignedInt)-
925 funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);-
926 else-
927 funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0);-
928 funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);-
929 funcs.glBindBuffer(GL_ARRAY_BUFFER, 0);-
930#else-
931 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);-
932 if (cache->indexType == QVertexIndexVector::UnsignedInt)
cache->indexTy...r::UnsignedIntDescription
TRUEnever evaluated
FALSEnever evaluated
0
933 funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices);
never executed: funcs.glDrawElements(cache->primitiveType, cache->indexCount, 0x1405, (qint32 *)cache->indices);
0
934 else-
935 funcs.glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices);
never executed: funcs.glDrawElements(cache->primitiveType, cache->indexCount, 0x1403, (qint16 *)cache->indices);
0
936#endif-
937-
938 } else {-
939 // printf(" - Marking path as cachable...\n");-
940 // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable-
941 path.makeCacheable();-
942-
943 if (device->context()->format().stencilBufferSize() <= 0) {
device->contex...ferSize() <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
944 // If there is no stencil buffer, triangulate the path instead.-
945-
946 QRectF bbox = path.controlPointRect();-
947 // If the path doesn't fit within these limits, it is possible that the triangulation will fail.-
948 bool withinLimits = (bbox.left() > -0x8000 * inverseScale)
(bbox.left() >... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
949 && (bbox.right() < 0x8000 * inverseScale)
(bbox.right() ... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
950 && (bbox.top() > -0x8000 * inverseScale)
(bbox.top() > ... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
951 && (bbox.bottom() < 0x8000 * inverseScale);
(bbox.bottom()... inverseScale)Description
TRUEnever evaluated
FALSEnever evaluated
0
952 if (withinLimits) {
withinLimitsDescription
TRUEnever evaluated
FALSEnever evaluated
0
953 QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale));-
954-
955 QVarLengthArray<float> vertices(polys.vertices.size());-
956 for (int i = 0; i < polys.vertices.size(); ++i)
i < polys.vertices.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
957 vertices[i] = float(inverseScale * polys.vertices.at(i));
never executed: vertices[i] = float(inverseScale * polys.vertices.at(i));
0
958-
959 prepareForDraw(currentBrush.isOpaque());-
960 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData());-
961 if (funcs.hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint))
funcs.hasOpenG...mentIndexUint)Description
TRUEnever evaluated
FALSEnever evaluated
0
962 funcs.glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data());
never executed: funcs.glDrawElements(0x0004, polys.indices.size(), 0x1405, polys.indices.data());
0
963 else-
964 funcs.glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data());
never executed: funcs.glDrawElements(0x0004, polys.indices.size(), 0x1403, polys.indices.data());
0
965 } else {-
966 // We can't handle big, concave painter paths with OpenGL without stencil buffer.-
967 qWarning("Painter path exceeds +/-32767 pixels.");-
968 }
never executed: end of block
0
969 return;
never executed: return;
0
970 }-
971-
972 // The path is too complicated & needs the stencil technique-
973 vertexCoordinateArray.clear();-
974 vertexCoordinateArray.addPath(path, inverseScale, false);-
975-
976 fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());-
977-
978 funcs.glStencilMask(0xff);-
979 funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);-
980-
981 if (q->state()->clipTestEnabled) {
q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
982 // Pass when high bit is set, replace stencil value with current clip-
983 funcs.glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT);-
984 } else if (path.hasWindingFill()) {
never executed: end of block
path.hasWindingFill()Description
TRUEnever evaluated
FALSEnever evaluated
0
985 // Pass when any bit is set, replace stencil value with 0-
986 funcs.glStencilFunc(GL_NOTEQUAL, 0, 0xff);-
987 } else {
never executed: end of block
0
988 // Pass when high bit is set, replace stencil value with 0-
989 funcs.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);-
990 }
never executed: end of block
0
991 prepareForDraw(currentBrush.isOpaque());-
992-
993 // Stencil the brush onto the dest buffer-
994 composite(vertexCoordinateArray.boundingRect());-
995 funcs.glStencilMask(0);-
996 updateClipScissorTest();-
997 }
never executed: end of block
0
998 }-
999}-
1000-
1001-
1002void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data,-
1003 int count,-
1004 int *stops,-
1005 int stopCount,-
1006 const QOpenGLRect &bounds,-
1007 StencilFillMode mode)-
1008{-
1009 Q_ASSERT(count || stops);-
1010-
1011// qDebug("QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray()");-
1012 funcs.glStencilMask(0xff); // Enable stencil writes-
1013-
1014 if (dirtyStencilRegion.intersects(currentScissorBounds)) {
dirtyStencilRe...ScissorBounds)Description
TRUEnever evaluated
FALSEnever evaluated
0
1015 QVector<QRect> clearRegion = dirtyStencilRegion.intersected(currentScissorBounds).rects();-
1016 funcs.glClearStencil(0); // Clear to zero-
1017 for (int i = 0; i < clearRegion.size(); ++i) {
i < clearRegion.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1018#ifndef QT_GL_NO_SCISSOR_TEST-
1019 setScissor(clearRegion.at(i));-
1020#endif-
1021 funcs.glClear(GL_STENCIL_BUFFER_BIT);-
1022 }
never executed: end of block
0
1023-
1024 dirtyStencilRegion -= currentScissorBounds;-
1025-
1026#ifndef QT_GL_NO_SCISSOR_TEST-
1027 updateClipScissorTest();-
1028#endif-
1029 }
never executed: end of block
0
1030-
1031 funcs.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes-
1032 useSimpleShader();-
1033 funcs.glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d-
1034-
1035 if (mode == WindingFillMode) {
mode == WindingFillModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1036 Q_ASSERT(stops && !count);-
1037 if (q->state()->clipTestEnabled) {
q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
1038 // Flatten clip values higher than current clip, and set high bit to match current clip-
1039 funcs.glStencilFunc(GL_LEQUAL, GL_STENCIL_HIGH_BIT | q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);-
1040 funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);-
1041 composite(bounds);-
1042-
1043 funcs.glStencilFunc(GL_EQUAL, GL_STENCIL_HIGH_BIT, GL_STENCIL_HIGH_BIT);-
1044 } else if (!stencilClean) {
never executed: end of block
!stencilCleanDescription
TRUEnever evaluated
FALSEnever evaluated
0
1045 // Clear stencil buffer within bounding rect-
1046 funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);-
1047 funcs.glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);-
1048 composite(bounds);-
1049 }
never executed: end of block
0
1050-
1051 // Inc. for front-facing triangle-
1052 funcs.glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP);-
1053 // Dec. for back-facing "holes"-
1054 funcs.glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP);-
1055 funcs.glStencilMask(~GL_STENCIL_HIGH_BIT);-
1056 drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);-
1057-
1058 if (q->state()->clipTestEnabled) {
q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
1059 // Clear high bit of stencil outside of path-
1060 funcs.glStencilFunc(GL_EQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);-
1061 funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);-
1062 funcs.glStencilMask(GL_STENCIL_HIGH_BIT);-
1063 composite(bounds);-
1064 }
never executed: end of block
0
1065 } else if (mode == OddEvenFillMode) {
never executed: end of block
mode == OddEvenFillModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1066 funcs.glStencilMask(GL_STENCIL_HIGH_BIT);-
1067 funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit-
1068 drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);-
1069-
1070 } else { // TriStripStrokeFillMode
never executed: end of block
0
1071 Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops-
1072 funcs.glStencilMask(GL_STENCIL_HIGH_BIT);-
1073#if 0-
1074 funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit-
1075 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);-
1076 funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, count);-
1077#else-
1078-
1079 funcs.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);-
1080 if (q->state()->clipTestEnabled) {
q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
1081 funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip | GL_STENCIL_HIGH_BIT,-
1082 ~GL_STENCIL_HIGH_BIT);-
1083 } else {
never executed: end of block
0
1084 funcs.glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff);-
1085 }
never executed: end of block
0
1086 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);-
1087 funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, count);-
1088#endif-
1089 }
never executed: end of block
0
1090-
1091 // Enable color writes & disable stencil writes-
1092 funcs.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);-
1093}
never executed: end of block
0
1094-
1095/*-
1096 If the maximum value in the stencil buffer is GL_STENCIL_HIGH_BIT - 1,-
1097 restore the stencil buffer to a pristine state. The current clip region-
1098 is set to 1, and the rest to 0.-
1099*/-
1100void QOpenGL2PaintEngineExPrivate::resetClipIfNeeded()-
1101{-
1102 if (maxClip != (GL_STENCIL_HIGH_BIT - 1))
maxClip != (GLuint(0x80) - 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1103 return;
never executed: return;
0
1104-
1105 Q_Q(QOpenGL2PaintEngineEx);-
1106-
1107 useSimpleShader();-
1108 funcs.glEnable(GL_STENCIL_TEST);-
1109 funcs.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);-
1110-
1111 QRectF bounds = q->state()->matrix.inverted().mapRect(QRectF(0, 0, width, height));-
1112 QOpenGLRect rect(bounds.left(), bounds.top(), bounds.right(), bounds.bottom());-
1113-
1114 // Set high bit on clip region-
1115 funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, 0xff);-
1116 funcs.glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);-
1117 funcs.glStencilMask(GL_STENCIL_HIGH_BIT);-
1118 composite(rect);-
1119-
1120 // Reset clipping to 1 and everything else to zero-
1121 funcs.glStencilFunc(GL_NOTEQUAL, 0x01, GL_STENCIL_HIGH_BIT);-
1122 funcs.glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE);-
1123 funcs.glStencilMask(0xff);-
1124 composite(rect);-
1125-
1126 q->state()->currentClip = 1;-
1127 q->state()->canRestoreClip = false;-
1128-
1129 maxClip = 1;-
1130-
1131 funcs.glStencilMask(0x0);-
1132 funcs.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);-
1133}
never executed: end of block
0
1134-
1135bool QOpenGL2PaintEngineExPrivate::prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache)-
1136{-
1137 Q_Q(QOpenGL2PaintEngineEx);-
1138-
1139 Q_ASSERT(cache.transform().type() <= QTransform::TxScale);-
1140-
1141 QTransform &transform = q->state()->matrix;-
1142 transform.scale(1.0 / cache.transform().m11(), 1.0 / cache.transform().m22());-
1143 bool ret = prepareForDraw(false);-
1144 transform.scale(cache.transform().m11(), cache.transform().m22());-
1145-
1146 return ret;
never executed: return ret;
0
1147}-
1148-
1149bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)-
1150{-
1151 if (brushTextureDirty && (mode == TextDrawingMode || mode == BrushDrawingMode))
brushTextureDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
mode == TextDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
mode == BrushDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1152 updateBrushTexture();
never executed: updateBrushTexture();
0
1153-
1154 if (compositionModeDirty)
compositionModeDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1155 updateCompositionMode();
never executed: updateCompositionMode();
0
1156-
1157 if (matrixDirty)
matrixDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1158 updateMatrix();
never executed: updateMatrix();
0
1159-
1160 const bool stateHasOpacity = q->state()->opacity < 0.99f;-
1161 if (q->state()->composition_mode == QPainter::CompositionMode_Source
q->state()->co...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1162 || (q->state()->composition_mode == QPainter::CompositionMode_SourceOver
q->state()->co...ode_SourceOverDescription
TRUEnever evaluated
FALSEnever evaluated
0
1163 && srcPixelsAreOpaque && !stateHasOpacity))
srcPixelsAreOpaqueDescription
TRUEnever evaluated
FALSEnever evaluated
!stateHasOpacityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1164 {-
1165 funcs.glDisable(GL_BLEND);-
1166 } else {
never executed: end of block
0
1167 funcs.glEnable(GL_BLEND);-
1168 }
never executed: end of block
0
1169-
1170 QOpenGLEngineShaderManager::OpacityMode opacityMode;-
1171 if (mode == ImageOpacityArrayDrawingMode) {
mode == ImageO...rayDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1172 opacityMode = QOpenGLEngineShaderManager::AttributeOpacity;-
1173 } else {
never executed: end of block
0
1174 opacityMode = stateHasOpacity ? QOpenGLEngineShaderManager::UniformOpacity
stateHasOpacityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1175 : QOpenGLEngineShaderManager::NoOpacity;-
1176 if (stateHasOpacity && (mode != ImageDrawingMode && mode != ImageArrayDrawingMode)) {
stateHasOpacityDescription
TRUEnever evaluated
FALSEnever evaluated
mode != ImageDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
mode != ImageArrayDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1177 // Using a brush-
1178 bool brushIsPattern = (currentBrush.style() >= Qt::Dense1Pattern) &&
(currentBrush....Dense1Pattern)Description
TRUEnever evaluated
FALSEnever evaluated
0
1179 (currentBrush.style() <= Qt::DiagCrossPattern);
(currentBrush....gCrossPattern)Description
TRUEnever evaluated
FALSEnever evaluated
0
1180-
1181 if ((currentBrush.style() == Qt::SolidPattern) || brushIsPattern)
(currentBrush....:SolidPattern)Description
TRUEnever evaluated
FALSEnever evaluated
brushIsPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
1182 opacityMode = QOpenGLEngineShaderManager::NoOpacity; // Global opacity handled by srcPixel shader
never executed: opacityMode = QOpenGLEngineShaderManager::NoOpacity;
0
1183 }
never executed: end of block
0
1184 }
never executed: end of block
0
1185 shaderManager->setOpacityMode(opacityMode);-
1186-
1187 bool changed = shaderManager->useCorrectShaderProg();-
1188 // If the shader program needs changing, we change it and mark all uniforms as dirty-
1189 if (changed) {
changedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1190 // The shader program has changed so mark all uniforms as dirty:-
1191 brushUniformsDirty = true;-
1192 opacityUniformDirty = true;-
1193 matrixUniformDirty = true;-
1194 }
never executed: end of block
0
1195-
1196 if (brushUniformsDirty && (mode == TextDrawingMode || mode == BrushDrawingMode))
brushUniformsDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
mode == TextDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
mode == BrushDrawingModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1197 updateBrushUniforms();
never executed: updateBrushUniforms();
0
1198-
1199 if (opacityMode == QOpenGLEngineShaderManager::UniformOpacity && opacityUniformDirty) {
opacityMode ==...UniformOpacityDescription
TRUEnever evaluated
FALSEnever evaluated
opacityUniformDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1200 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity);-
1201 opacityUniformDirty = false;-
1202 }
never executed: end of block
0
1203-
1204 if (matrixUniformDirty && shaderManager->hasComplexGeometry()) {
matrixUniformDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
shaderManager-...plexGeometry()Description
TRUEnever evaluated
FALSEnever evaluated
0
1205 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Matrix),-
1206 pmvMatrix);-
1207 matrixUniformDirty = false;-
1208 }
never executed: end of block
0
1209-
1210 return changed;
never executed: return changed;
0
1211}-
1212-
1213void QOpenGL2PaintEngineExPrivate::composite(const QOpenGLRect& boundingRect)-
1214{-
1215 setCoords(staticVertexCoordinateArray, boundingRect);-
1216 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray);-
1217 funcs.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);-
1218}
never executed: end of block
0
1219-
1220// Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans.-
1221void QOpenGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, int stopCount,-
1222 GLenum primitive)-
1223{-
1224 // Now setup the pointer to the vertex array:-
1225 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);-
1226-
1227 int previousStop = 0;-
1228 for (int i=0; i<stopCount; ++i) {
i<stopCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
1229 int stop = stops[i];-
1230/*-
1231 qDebug("Drawing triangle fan for vertecies %d -> %d:", previousStop, stop-1);-
1232 for (int i=previousStop; i<stop; ++i)-
1233 qDebug(" %02d: [%.2f, %.2f]", i, vertexArray.data()[i].x, vertexArray.data()[i].y);-
1234*/-
1235 funcs.glDrawArrays(primitive, previousStop, stop - previousStop);-
1236 previousStop = stop;-
1237 }
never executed: end of block
0
1238}
never executed: end of block
0
1239-
1240/////////////////////////////////// Public Methods //////////////////////////////////////////-
1241-
1242QOpenGL2PaintEngineEx::QOpenGL2PaintEngineEx()-
1243 : QPaintEngineEx(*(new QOpenGL2PaintEngineExPrivate(this)))-
1244{-
1245}
never executed: end of block
0
1246-
1247QOpenGL2PaintEngineEx::~QOpenGL2PaintEngineEx()-
1248{-
1249}-
1250-
1251void QOpenGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush)-
1252{-
1253 Q_D(QOpenGL2PaintEngineEx);-
1254-
1255 if (qbrush_style(brush) == Qt::NoBrush)
qbrush_style(b...== Qt::NoBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
1256 return;
never executed: return;
0
1257 ensureActive();-
1258 d->setBrush(brush);-
1259 d->fill(path);-
1260}
never executed: end of block
0
1261-
1262Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp-
1263-
1264-
1265void QOpenGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)-
1266{-
1267 Q_D(QOpenGL2PaintEngineEx);-
1268-
1269 const QBrush &penBrush = qpen_brush(pen);-
1270 if (qpen_style(pen) == Qt::NoPen || qbrush_style(penBrush) == Qt::NoBrush)
qpen_style(pen) == Qt::NoPenDescription
TRUEnever evaluated
FALSEnever evaluated
qbrush_style(p...== Qt::NoBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
1271 return;
never executed: return;
0
1272-
1273 QOpenGL2PaintEngineState *s = state();-
1274 if (qt_pen_is_cosmetic(pen, state()->renderHints) && !qt_scaleForTransform(s->transform(), 0)) {
qt_pen_is_cosm...->renderHints)Description
TRUEnever evaluated
FALSEnever evaluated
!qt_scaleForTr...ransform(), 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1275 // QTriangulatingStroker class is not meant to support cosmetically sheared strokes.-
1276 QPaintEngineEx::stroke(path, pen);-
1277 return;
never executed: return;
0
1278 }-
1279-
1280 ensureActive();-
1281 d->setBrush(penBrush);-
1282 d->stroke(path, pen);-
1283}
never executed: end of block
0
1284-
1285void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen)-
1286{-
1287 const QOpenGL2PaintEngineState *s = q->state();-
1288 if (snapToPixelGrid) {
snapToPixelGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
1289 snapToPixelGrid = false;-
1290 matrixDirty = true;-
1291 }
never executed: end of block
0
1292-
1293 const Qt::PenStyle penStyle = qpen_style(pen);-
1294 const QBrush &penBrush = qpen_brush(pen);-
1295 const bool opaque = penBrush.isOpaque() && s->opacity > 0.99;
penBrush.isOpaque()Description
TRUEnever evaluated
FALSEnever evaluated
s->opacity > 0.99Description
TRUEnever evaluated
FALSEnever evaluated
0
1296-
1297 transferMode(BrushDrawingMode);-
1298-
1299 // updateMatrix() is responsible for setting the inverse scale on-
1300 // the strokers, so we need to call it here and not wait for-
1301 // prepareForDraw() down below.-
1302 updateMatrix();-
1303-
1304 QRectF clip = q->state()->matrix.inverted().mapRect(q->state()->clipEnabled-
1305 ? q->state()->rectangleClip-
1306 : QRectF(0, 0, width, height));-
1307-
1308 if (penStyle == Qt::SolidLine) {
penStyle == Qt::SolidLineDescription
TRUEnever evaluated
FALSEnever evaluated
0
1309 stroker.process(path, pen, clip, s->renderHints);-
1310-
1311 } else { // Some sort of dash
never executed: end of block
0
1312 dasher.process(path, pen, clip, s->renderHints);-
1313-
1314 QVectorPath dashStroke(dasher.points(),-
1315 dasher.elementCount(),-
1316 dasher.elementTypes(),-
1317 s->renderHints);-
1318 stroker.process(dashStroke, pen, clip, s->renderHints);-
1319 }
never executed: end of block
0
1320-
1321 if (!stroker.vertexCount())
!stroker.vertexCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
1322 return;
never executed: return;
0
1323-
1324 if (opaque) {
opaqueDescription
TRUEnever evaluated
FALSEnever evaluated
0
1325 prepareForDraw(opaque);-
1326 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, stroker.vertices());-
1327 funcs.glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2);-
1328-
1329// QBrush b(Qt::green);-
1330// d->setBrush(&b);-
1331// d->prepareForDraw(true);-
1332// glDrawArrays(GL_LINE_STRIP, 0, d->stroker.vertexCount() / 2);-
1333-
1334 } else {
never executed: end of block
0
1335 qreal width = qpen_widthf(pen) / 2;-
1336 if (width == 0)
width == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1337 width = 0.5;
never executed: width = 0.5;
0
1338 qreal extra = pen.joinStyle() == Qt::MiterJoin
pen.joinStyle(... Qt::MiterJoinDescription
TRUEnever evaluated
FALSEnever evaluated
0
1339 ? qMax(pen.miterLimit() * width, width)-
1340 : width;-
1341-
1342 if (qt_pen_is_cosmetic(pen, q->state()->renderHints))
qt_pen_is_cosm...->renderHints)Description
TRUEnever evaluated
FALSEnever evaluated
0
1343 extra = extra * inverseScale;
never executed: extra = extra * inverseScale;
0
1344-
1345 QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra);-
1346-
1347 fillStencilWithVertexArray(stroker.vertices(), stroker.vertexCount() / 2,-
1348 0, 0, bounds, QOpenGL2PaintEngineExPrivate::TriStripStrokeFillMode);-
1349-
1350 funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);-
1351-
1352 // Pass when any bit is set, replace stencil value with 0-
1353 funcs.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);-
1354 prepareForDraw(false);-
1355-
1356 // Stencil the brush onto the dest buffer-
1357 composite(bounds);-
1358-
1359 funcs.glStencilMask(0);-
1360-
1361 updateClipScissorTest();-
1362 }
never executed: end of block
0
1363}-
1364-
1365void QOpenGL2PaintEngineEx::penChanged() { }-
1366void QOpenGL2PaintEngineEx::brushChanged() { }-
1367void QOpenGL2PaintEngineEx::brushOriginChanged() { }-
1368-
1369void QOpenGL2PaintEngineEx::opacityChanged()-
1370{-
1371// qDebug("QOpenGL2PaintEngineEx::opacityChanged()");-
1372 Q_D(QOpenGL2PaintEngineEx);-
1373 state()->opacityChanged = true;-
1374-
1375 Q_ASSERT(d->shaderManager);-
1376 d->brushUniformsDirty = true;-
1377 d->opacityUniformDirty = true;-
1378}
never executed: end of block
0
1379-
1380void QOpenGL2PaintEngineEx::compositionModeChanged()-
1381{-
1382// qDebug("QOpenGL2PaintEngineEx::compositionModeChanged()");-
1383 Q_D(QOpenGL2PaintEngineEx);-
1384 state()->compositionModeChanged = true;-
1385 d->compositionModeDirty = true;-
1386}
never executed: end of block
0
1387-
1388void QOpenGL2PaintEngineEx::renderHintsChanged()-
1389{-
1390 state()->renderHintsChanged = true;-
1391-
1392#ifndef QT_OPENGL_ES_2-
1393 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
!QOpenGLContex...->isOpenGLES()Description
TRUEnever evaluated
FALSEnever evaluated
0
1394 Q_D(QOpenGL2PaintEngineEx);-
1395 if ((state()->renderHints & QPainter::Antialiasing)
(state()->rend...:Antialiasing)Description
TRUEnever evaluated
FALSEnever evaluated
0
1396 || (state()->renderHints & QPainter::HighQualityAntialiasing))
(state()->rend...yAntialiasing)Description
TRUEnever evaluated
FALSEnever evaluated
0
1397 d->funcs.glEnable(GL_MULTISAMPLE);
never executed: d->funcs.glEnable(0x809D);
0
1398 else-
1399 d->funcs.glDisable(GL_MULTISAMPLE);
never executed: d->funcs.glDisable(0x809D);
0
1400 }-
1401#endif // QT_OPENGL_ES_2-
1402-
1403 Q_D(QOpenGL2PaintEngineEx);-
1404-
1405 // This is a somewhat sneaky way of conceptually making the next call to-
1406 // updateTexture() use FoceUpdate for the TextureUpdateMode. We need this-
1407 // as new render hints may require updating the filter mode.-
1408 d->lastTextureUsed = GLuint(-1);-
1409-
1410 d->brushTextureDirty = true;-
1411// qDebug("QOpenGL2PaintEngineEx::renderHintsChanged() not implemented!");-
1412}
never executed: end of block
0
1413-
1414void QOpenGL2PaintEngineEx::transformChanged()-
1415{-
1416 Q_D(QOpenGL2PaintEngineEx);-
1417 d->matrixDirty = true;-
1418 state()->matrixChanged = true;-
1419}
never executed: end of block
0
1420-
1421-
1422static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy)-
1423{-
1424 return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy);
never executed: return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy);
0
1425}-
1426-
1427void QOpenGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src)-
1428{-
1429 Q_D(QOpenGL2PaintEngineEx);-
1430 QOpenGLContext *ctx = d->ctx;-
1431-
1432 // Draw pixmaps that are really images as images since drawImage has-
1433 // better handling of non-default image formats.-
1434 if (pixmap.paintEngine()->type() == QPaintEngine::Raster && !pixmap.isQBitmap())
pixmap.paintEn...Engine::RasterDescription
TRUEnever evaluated
FALSEnever evaluated
!pixmap.isQBitmap()Description
TRUEnever evaluated
FALSEnever evaluated
0
1435 return drawImage(dest, pixmap.toImage(), src);
never executed: return drawImage(dest, pixmap.toImage(), src);
0
1436-
1437 int max_texture_size = ctx->d_func()->maxTextureSize();-
1438 if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) {
pixmap.width()...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
pixmap.height(...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1439 QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);-
1440-
1441 const qreal sx = scaled.width() / qreal(pixmap.width());-
1442 const qreal sy = scaled.height() / qreal(pixmap.height());-
1443-
1444 drawPixmap(dest, scaled, scaleRect(src, sx, sy));-
1445 return;
never executed: return;
0
1446 }-
1447-
1448 ensureActive();-
1449 d->transferMode(ImageDrawingMode);-
1450-
1451 GLenum filterMode = state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST;
state()->rende...ixmapTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
1452 d->updateTexture(QT_IMAGE_TEXTURE_UNIT, pixmap, GL_CLAMP_TO_EDGE, filterMode);-
1453-
1454 bool isBitmap = pixmap.isQBitmap();-
1455 bool isOpaque = !isBitmap && !pixmap.hasAlpha();
!isBitmapDescription
TRUEnever evaluated
FALSEnever evaluated
!pixmap.hasAlpha()Description
TRUEnever evaluated
FALSEnever evaluated
0
1456-
1457 d->shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc : QOpenGLEngineShaderManager::ImageSrc);-
1458-
1459 QOpenGLRect srcRect(src.left(), src.top(), src.right(), src.bottom());-
1460 d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);-
1461}
never executed: end of block
0
1462-
1463void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src,-
1464 Qt::ImageConversionFlags)-
1465{-
1466 Q_D(QOpenGL2PaintEngineEx);-
1467 QOpenGLContext *ctx = d->ctx;-
1468-
1469 int max_texture_size = ctx->d_func()->maxTextureSize();-
1470 if (image.width() > max_texture_size || image.height() > max_texture_size) {
image.width() ...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
image.height()...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1471 QImage scaled = image.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);-
1472-
1473 const qreal sx = scaled.width() / qreal(image.width());-
1474 const qreal sy = scaled.height() / qreal(image.height());-
1475-
1476 drawImage(dest, scaled, scaleRect(src, sx, sy));-
1477 return;
never executed: return;
0
1478 }-
1479-
1480 ensureActive();-
1481 d->transferMode(ImageDrawingMode);-
1482-
1483 QOpenGLTextureCache::BindOptions bindOption = QOpenGLTextureCache::PremultipliedAlphaBindOption;-
1484 // Use specialized bind for formats we have specialized shaders for.-
1485 switch (image.format()) {-
1486 case QImage::Format_RGBA8888:
never executed: case QImage::Format_RGBA8888:
0
1487 case QImage::Format_ARGB32:
never executed: case QImage::Format_ARGB32:
0
1488 d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::NonPremultipliedImageSrc);-
1489 bindOption = 0;-
1490 break;
never executed: break;
0
1491 case QImage::Format_Alpha8:
never executed: case QImage::Format_Alpha8:
0
1492 if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) {
ctx->functions...tureRGFormats)Description
TRUEnever evaluated
FALSEnever evaluated
0
1493 d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::AlphaImageSrc);-
1494 bindOption = QOpenGLTextureCache::UseRedFor8BitBindOption;-
1495 } else
never executed: end of block
0
1496 d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
never executed: d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
0
1497 break;
never executed: break;
0
1498 case QImage::Format_Grayscale8:
never executed: case QImage::Format_Grayscale8:
0
1499 if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) {
ctx->functions...tureRGFormats)Description
TRUEnever evaluated
FALSEnever evaluated
0
1500 d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::GrayscaleImageSrc);-
1501 bindOption = QOpenGLTextureCache::UseRedFor8BitBindOption;-
1502 } else
never executed: end of block
0
1503 d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
never executed: d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
0
1504 break;
never executed: break;
0
1505 default:
never executed: default:
0
1506 d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);-
1507 break;
never executed: break;
0
1508 }-
1509-
1510 ImageWithBindOptions imageWithOptions = { image, bindOption };-
1511 GLenum filterMode = state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST;
state()->rende...ixmapTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
1512 d->updateTexture(QT_IMAGE_TEXTURE_UNIT, imageWithOptions, GL_CLAMP_TO_EDGE, filterMode);-
1513-
1514 d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());-
1515}
never executed: end of block
0
1516-
1517void QOpenGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)-
1518{-
1519 Q_D(QOpenGL2PaintEngineEx);-
1520-
1521 ensureActive();-
1522-
1523 QPainterState *s = state();-
1524-
1525 QFontEngine *fontEngine = textItem->fontEngine();-
1526 if (shouldDrawCachedGlyphs(fontEngine, s->matrix)) {
shouldDrawCach...ne, s->matrix)Description
TRUEnever evaluated
FALSEnever evaluated
0
1527 QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None
fontEngine->gl...e::Format_NoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
1528 ? fontEngine->glyphFormat : d->glyphCacheFormat;-
1529 if (glyphFormat == QFontEngine::Format_A32) {
glyphFormat ==...ne::Format_A32Description
TRUEnever evaluated
FALSEnever evaluated
0
1530 if (d->device->context()->format().alphaBufferSize() > 0 || s->matrix.type() > QTransform::TxTranslate
d->device->con...fferSize() > 0Description
TRUEnever evaluated
FALSEnever evaluated
s->matrix.type...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1531 || (s->composition_mode != QPainter::CompositionMode_Source
s->composition...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1532 && s->composition_mode != QPainter::CompositionMode_SourceOver))
s->composition...ode_SourceOverDescription
TRUEnever evaluated
FALSEnever evaluated
0
1533 {-
1534 glyphFormat = QFontEngine::Format_A8;-
1535 }
never executed: end of block
0
1536 }
never executed: end of block
0
1537-
1538 d->drawCachedGlyphs(glyphFormat, textItem);-
1539 } else {
never executed: end of block
0
1540 QPaintEngineEx::drawStaticTextItem(textItem);-
1541 }
never executed: end of block
0
1542}-
1543-
1544bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)-
1545{-
1546 Q_D(QOpenGL2PaintEngineEx);-
1547 if (!d->shaderManager)
!d->shaderManagerDescription
TRUEnever evaluated
FALSEnever evaluated
0
1548 return false;
never executed: return false;
0
1549-
1550 ensureActive();-
1551 d->transferMode(ImageDrawingMode);-
1552-
1553 GLenum filterMode = state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST;
state()->rende...ixmapTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
1554 d->updateTexture(QT_IMAGE_TEXTURE_UNIT, textureId, GL_CLAMP_TO_EDGE, filterMode);-
1555-
1556 d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);-
1557-
1558 QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());-
1559 d->drawTexture(dest, srcRect, size, false);-
1560-
1561 return true;
never executed: return true;
0
1562}-
1563-
1564void QOpenGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem)-
1565{-
1566 Q_D(QOpenGL2PaintEngineEx);-
1567-
1568 ensureActive();-
1569 QOpenGL2PaintEngineState *s = state();-
1570-
1571 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);-
1572-
1573 QTransform::TransformationType txtype = s->matrix.type();-
1574-
1575 QFontEngine::GlyphFormat glyphFormat = ti.fontEngine->glyphFormat != QFontEngine::Format_None
ti.fontEngine-...e::Format_NoneDescription
TRUEnever evaluated
FALSEnever evaluated
0
1576 ? ti.fontEngine->glyphFormat : d->glyphCacheFormat;-
1577-
1578 if (glyphFormat == QFontEngine::Format_A32) {
glyphFormat ==...ne::Format_A32Description
TRUEnever evaluated
FALSEnever evaluated
0
1579 if (d->device->context()->format().alphaBufferSize() > 0 || txtype > QTransform::TxTranslate
d->device->con...fferSize() > 0Description
TRUEnever evaluated
FALSEnever evaluated
txtype > QTran...m::TxTranslateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1580 || (state()->composition_mode != QPainter::CompositionMode_Source
state()->compo...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1581 && state()->composition_mode != QPainter::CompositionMode_SourceOver))
state()->compo...ode_SourceOverDescription
TRUEnever evaluated
FALSEnever evaluated
0
1582 {-
1583 glyphFormat = QFontEngine::Format_A8;-
1584 }
never executed: end of block
0
1585 }
never executed: end of block
0
1586-
1587 if (shouldDrawCachedGlyphs(ti.fontEngine, s->matrix)) {
shouldDrawCach...ne, s->matrix)Description
TRUEnever evaluated
FALSEnever evaluated
0
1588 QVarLengthArray<QFixedPoint> positions;-
1589 QVarLengthArray<glyph_t> glyphs;-
1590 QTransform matrix = QTransform::fromTranslate(p.x(), p.y());-
1591 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);-
1592-
1593 {-
1594 QStaticTextItem staticTextItem;-
1595 staticTextItem.setFontEngine(ti.fontEngine);-
1596 staticTextItem.glyphs = glyphs.data();-
1597 staticTextItem.numGlyphs = glyphs.size();-
1598 staticTextItem.glyphPositions = positions.data();-
1599-
1600 d->drawCachedGlyphs(glyphFormat, &staticTextItem);-
1601 }-
1602 return;
never executed: return;
0
1603 }-
1604-
1605 QPaintEngineEx::drawTextItem(p, ti);-
1606}
never executed: end of block
0
1607-
1608namespace {-
1609-
1610 class QOpenGLStaticTextUserData: public QStaticTextUserData-
1611 {-
1612 public:-
1613 QOpenGLStaticTextUserData()-
1614 : QStaticTextUserData(OpenGLUserData), cacheSize(0, 0), cacheSerialNumber(0)-
1615 {-
1616 }
never executed: end of block
0
1617-
1618 ~QOpenGLStaticTextUserData()-
1619 {-
1620 }-
1621-
1622 QSize cacheSize;-
1623 QOpenGL2PEXVertexArray vertexCoordinateArray;-
1624 QOpenGL2PEXVertexArray textureCoordinateArray;-
1625 QFontEngine::GlyphFormat glyphFormat;-
1626 int cacheSerialNumber;-
1627 };-
1628-
1629}-
1630-
1631-
1632// #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO-
1633-
1634bool QOpenGL2PaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &t) const-
1635{-
1636 // The paint engine does not support projected cached glyph drawing-
1637 if (t.type() == QTransform::TxProject)
t.type() == QT...orm::TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1638 return false;
never executed: return false;
0
1639-
1640 // The font engine might not support filling the glyph cache-
1641 // with the given transform applied, in which case we need to-
1642 // fall back to the QPainterPath code-path.-
1643 if (!fontEngine->supportsTransformation(t)) {
!fontEngine->s...nsformation(t)Description
TRUEnever evaluated
FALSEnever evaluated
0
1644 // Except that drawing paths is slow, so for scales between-
1645 // 0.5 and 2.0 we leave the glyph cache untransformed and deal-
1646 // with the transform ourselves when painting, resulting in-
1647 // drawing 1x cached glyphs with a smooth-scale.-
1648 float det = t.determinant();-
1649 if (det >= 0.25f && det <= 4.f) {
det >= 0.25fDescription
TRUEnever evaluated
FALSEnever evaluated
det <= 4.fDescription
TRUEnever evaluated
FALSEnever evaluated
0
1650 // Assuming the baseclass still agrees-
1651 return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, t);
never executed: return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, t);
0
1652 }-
1653-
1654 return false; // Fall back to path-drawing
never executed: return false;
0
1655 }-
1656-
1657 return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, t);
never executed: return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, t);
0
1658}-
1659-
1660void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFormat,-
1661 QStaticTextItem *staticTextItem)-
1662{-
1663 Q_Q(QOpenGL2PaintEngineEx);-
1664-
1665 QOpenGL2PaintEngineState *s = q->state();-
1666-
1667 void *cacheKey = ctx->shareGroup();-
1668 bool recreateVertexArrays = false;-
1669-
1670 QTransform glyphCacheTransform;-
1671 QFontEngine *fe = staticTextItem->fontEngine();-
1672 if (fe->supportsTransformation(s->matrix)) {
fe->supportsTr...ion(s->matrix)Description
TRUEnever evaluated
FALSEnever evaluated
0
1673 // The font-engine supports rendering glyphs with the current transform, so we-
1674 // build a glyph-cache with the scale pre-applied, so that the cache contains-
1675 // glyphs with the appropriate resolution in the case of retina displays.-
1676 glyphCacheTransform = s->matrix.type() < QTransform::TxRotate ?
s->matrix.type...form::TxRotateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1677 QTransform::fromScale(qAbs(s->matrix.m11()), qAbs(s->matrix.m22())) :-
1678 QTransform::fromScale(-
1679 QVector2D(s->matrix.m11(), s->matrix.m12()).length(),-
1680 QVector2D(s->matrix.m21(), s->matrix.m22()).length());-
1681 }
never executed: end of block
0
1682-
1683 QOpenGLTextureGlyphCache *cache =-
1684 (QOpenGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphFormat, glyphCacheTransform);-
1685 if (!cache || cache->glyphFormat() != glyphFormat || cache->contextGroup() == 0) {
!cacheDescription
TRUEnever evaluated
FALSEnever evaluated
cache->glyphFo...!= glyphFormatDescription
TRUEnever evaluated
FALSEnever evaluated
cache->contextGroup() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1686 cache = new QOpenGLTextureGlyphCache(glyphFormat, glyphCacheTransform);-
1687 fe->setGlyphCache(cacheKey, cache);-
1688 recreateVertexArrays = true;-
1689 }
never executed: end of block
0
1690-
1691 if (staticTextItem->userDataNeedsUpdate) {
staticTextItem...ataNeedsUpdateDescription
TRUEnever evaluated
FALSEnever evaluated
0
1692 recreateVertexArrays = true;-
1693 } else if (staticTextItem->userData() == 0) {
never executed: end of block
staticTextItem...serData() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1694 recreateVertexArrays = true;-
1695 } else if (staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) {
never executed: end of block
staticTextItem...OpenGLUserDataDescription
TRUEnever evaluated
FALSEnever evaluated
0
1696 recreateVertexArrays = true;-
1697 } else {
never executed: end of block
0
1698 QOpenGLStaticTextUserData *userData = static_cast<QOpenGLStaticTextUserData *>(staticTextItem->userData());-
1699 if (userData->glyphFormat != glyphFormat) {
userData->glyp...!= glyphFormatDescription
TRUEnever evaluated
FALSEnever evaluated
0
1700 recreateVertexArrays = true;-
1701 } else if (userData->cacheSerialNumber != cache->serialNumber()) {
never executed: end of block
userData->cach...serialNumber()Description
TRUEnever evaluated
FALSEnever evaluated
0
1702 recreateVertexArrays = true;-
1703 }
never executed: end of block
0
1704 }
never executed: end of block
0
1705-
1706 // We only need to update the cache with new glyphs if we are actually going to recreate the vertex arrays.-
1707 // If the cache size has changed, we do need to regenerate the vertices, but we don't need to repopulate the-
1708 // cache so this text is performed before we test if the cache size has changed.-
1709 if (recreateVertexArrays) {
recreateVertexArraysDescription
TRUEnever evaluated
FALSEnever evaluated
0
1710 cache->setPaintEnginePrivate(this);-
1711 if (!cache->populate(fe, staticTextItem->numGlyphs,
!cache->popula...lyphPositions)Description
TRUEnever evaluated
FALSEnever evaluated
0
1712 staticTextItem->glyphs, staticTextItem->glyphPositions)) {
!cache->popula...lyphPositions)Description
TRUEnever evaluated
FALSEnever evaluated
0
1713 // No space for glyphs in cache. We need to reset it and try again.-
1714 cache->clear();-
1715 cache->populate(fe, staticTextItem->numGlyphs,-
1716 staticTextItem->glyphs, staticTextItem->glyphPositions);-
1717 }
never executed: end of block
0
1718-
1719 if (cache->hasPendingGlyphs()) {
cache->hasPendingGlyphs()Description
TRUEnever evaluated
FALSEnever evaluated
0
1720 // Filling in the glyphs binds and sets parameters, so we need to-
1721 // ensure that the glyph cache doesn't mess with whatever unit-
1722 // is currently active. Note that the glyph cache internally-
1723 // uses the image texture unit for blitting to the cache, while-
1724 // we switch between image and mask units when drawing.-
1725 static const GLenum glypchCacheTextureUnit = QT_IMAGE_TEXTURE_UNIT;-
1726 activateTextureUnit(glypchCacheTextureUnit);-
1727-
1728 cache->fillInPendingGlyphs();-
1729-
1730 // We assume the cache can be trusted on which texture was bound-
1731 lastTextureUsed = cache->texture();-
1732-
1733 // But since the brush and image texture units are possibly shared-
1734 // we may have to re-bind brush textures after filling in the cache.-
1735 brushTextureDirty = (QT_BRUSH_TEXTURE_UNIT == glypchCacheTextureUnit);-
1736 }
never executed: end of block
0
1737 }
never executed: end of block
0
1738-
1739 if (cache->width() == 0 || cache->height() == 0)
cache->width() == 0Description
TRUEnever evaluated
FALSEnever evaluated
cache->height() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1740 return;
never executed: return;
0
1741-
1742 if (glyphFormat == QFontEngine::Format_ARGB)
glyphFormat ==...e::Format_ARGBDescription
TRUEnever evaluated
FALSEnever evaluated
0
1743 transferMode(ImageArrayDrawingMode);
never executed: transferMode(ImageArrayDrawingMode);
0
1744 else-
1745 transferMode(TextDrawingMode);
never executed: transferMode(TextDrawingMode);
0
1746-
1747 int margin = fe->glyphMargin(glyphFormat);-
1748-
1749 GLfloat dx = 1.0 / cache->width();-
1750 GLfloat dy = 1.0 / cache->height();-
1751-
1752 // Use global arrays by default-
1753 QOpenGL2PEXVertexArray *vertexCoordinates = &vertexCoordinateArray;-
1754 QOpenGL2PEXVertexArray *textureCoordinates = &textureCoordinateArray;-
1755-
1756 if (staticTextItem->useBackendOptimizations) {
staticTextItem...dOptimizationsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1757 QOpenGLStaticTextUserData *userData = 0;-
1758-
1759 if (staticTextItem->userData() == 0
staticTextItem...serData() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1760 || staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) {
staticTextItem...OpenGLUserDataDescription
TRUEnever evaluated
FALSEnever evaluated
0
1761-
1762 userData = new QOpenGLStaticTextUserData();-
1763 staticTextItem->setUserData(userData);-
1764-
1765 } else {
never executed: end of block
0
1766 userData = static_cast<QOpenGLStaticTextUserData*>(staticTextItem->userData());-
1767 }
never executed: end of block
0
1768-
1769 userData->glyphFormat = glyphFormat;-
1770 userData->cacheSerialNumber = cache->serialNumber();-
1771-
1772 // Use cache if backend optimizations is turned on-
1773 vertexCoordinates = &userData->vertexCoordinateArray;-
1774 textureCoordinates = &userData->textureCoordinateArray;-
1775-
1776 QSize size(cache->width(), cache->height());-
1777 if (userData->cacheSize != size) {
userData->cacheSize != sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1778 recreateVertexArrays = true;-
1779 userData->cacheSize = size;-
1780 }
never executed: end of block
0
1781 }
never executed: end of block
0
1782-
1783 if (recreateVertexArrays) {
recreateVertexArraysDescription
TRUEnever evaluated
FALSEnever evaluated
0
1784 vertexCoordinates->clear();-
1785 textureCoordinates->clear();-
1786-
1787 bool supportsSubPixelPositions = fe->supportsSubPixelPositions();-
1788 for (int i=0; i<staticTextItem->numGlyphs; ++i) {
i<staticTextItem->numGlyphsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1789 QFixed subPixelPosition;-
1790 if (supportsSubPixelPositions)
supportsSubPixelPositionsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1791 subPixelPosition = fe->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
never executed: subPixelPosition = fe->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
0
1792-
1793 QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);-
1794-
1795 const QTextureGlyphCache::Coord &c = cache->coords[glyph];-
1796 if (c.isNull())
c.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
1797 continue;
never executed: continue;
0
1798-
1799 int x = qFloor(staticTextItem->glyphPositions[i].x.toReal() * cache->transform().m11()) + c.baseLineX - margin;-
1800 int y = qRound(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22()) - c.baseLineY - margin;-
1801-
1802 vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h));-
1803 textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy));-
1804 }
never executed: end of block
0
1805-
1806 staticTextItem->userDataNeedsUpdate = false;-
1807 }
never executed: end of block
0
1808-
1809 int numGlyphs = vertexCoordinates->vertexCount() / 4;-
1810 if (numGlyphs == 0)
numGlyphs == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1811 return;
never executed: return;
0
1812-
1813 if (elementIndices.size() < numGlyphs*6) {
elementIndices... < numGlyphs*6Description
TRUEnever evaluated
FALSEnever evaluated
0
1814 Q_ASSERT(elementIndices.size() % 6 == 0);-
1815 int j = elementIndices.size() / 6 * 4;-
1816 while (j < numGlyphs*4) {
j < numGlyphs*4Description
TRUEnever evaluated
FALSEnever evaluated
0
1817 elementIndices.append(j + 0);-
1818 elementIndices.append(j + 0);-
1819 elementIndices.append(j + 1);-
1820 elementIndices.append(j + 2);-
1821 elementIndices.append(j + 3);-
1822 elementIndices.append(j + 3);-
1823-
1824 j += 4;-
1825 }
never executed: end of block
0
1826-
1827#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)-
1828 if (elementIndicesVBOId == 0)-
1829 funcs.glGenBuffers(1, &elementIndicesVBOId);-
1830-
1831 funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);-
1832 funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort),-
1833 elementIndices.constData(), GL_STATIC_DRAW);-
1834#endif-
1835 } else {
never executed: end of block
0
1836#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)-
1837 funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);-
1838#endif-
1839 }
never executed: end of block
0
1840-
1841 if (glyphFormat != QFontEngine::Format_ARGB || recreateVertexArrays) {
glyphFormat !=...e::Format_ARGBDescription
TRUEnever evaluated
FALSEnever evaluated
recreateVertexArraysDescription
TRUEnever evaluated
FALSEnever evaluated
0
1842 setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data());-
1843 setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data());-
1844 }
never executed: end of block
0
1845-
1846 if (!snapToPixelGrid) {
!snapToPixelGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
1847 snapToPixelGrid = true;-
1848 matrixDirty = true;-
1849 }
never executed: end of block
0
1850-
1851 QBrush pensBrush = q->state()->pen.brush();-
1852 setBrush(pensBrush);-
1853-
1854 if (glyphFormat == QFontEngine::Format_A32) {
glyphFormat ==...ne::Format_A32Description
TRUEnever evaluated
FALSEnever evaluated
0
1855-
1856 // Subpixel antialiasing without gamma correction-
1857-
1858 QPainter::CompositionMode compMode = q->state()->composition_mode;-
1859 Q_ASSERT(compMode == QPainter::CompositionMode_Source-
1860 || compMode == QPainter::CompositionMode_SourceOver);-
1861-
1862 shaderManager->setMaskType(QOpenGLEngineShaderManager::SubPixelMaskPass1);-
1863-
1864 if (pensBrush.style() == Qt::SolidPattern) {
pensBrush.styl...::SolidPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
1865 // Solid patterns can get away with only one pass.-
1866 QColor c = pensBrush.color();-
1867 qreal oldOpacity = q->state()->opacity;-
1868 if (compMode == QPainter::CompositionMode_Source) {
compMode == QP...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1869 c = qt_premultiplyColor(c, q->state()->opacity);-
1870 q->state()->opacity = 1;-
1871 opacityUniformDirty = true;-
1872 }
never executed: end of block
0
1873-
1874 compositionModeDirty = false; // I can handle this myself, thank you very much-
1875 prepareForCachedGlyphDraw(*cache);-
1876-
1877 // prepareForCachedGlyphDraw() have set the opacity on the current shader, so the opacity state can now be reset.-
1878 if (compMode == QPainter::CompositionMode_Source) {
compMode == QP...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1879 q->state()->opacity = oldOpacity;-
1880 opacityUniformDirty = true;-
1881 }
never executed: end of block
0
1882-
1883 funcs.glEnable(GL_BLEND);-
1884 funcs.glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);-
1885 funcs.glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());-
1886 } else {
never executed: end of block
0
1887 // Other brush styles need two passes.-
1888-
1889 qreal oldOpacity = q->state()->opacity;-
1890 if (compMode == QPainter::CompositionMode_Source) {
compMode == QP...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1891 q->state()->opacity = 1;-
1892 opacityUniformDirty = true;-
1893 pensBrush = Qt::white;-
1894 setBrush(pensBrush);-
1895 }
never executed: end of block
0
1896-
1897 compositionModeDirty = false; // I can handle this myself, thank you very much-
1898 prepareForCachedGlyphDraw(*cache);-
1899 funcs.glEnable(GL_BLEND);-
1900 funcs.glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);-
1901-
1902 updateTexture(QT_MASK_TEXTURE_UNIT, cache->texture(), GL_REPEAT, GL_NEAREST, ForceUpdate);-
1903-
1904#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)-
1905 funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);-
1906#else-
1907 funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());-
1908#endif-
1909-
1910 shaderManager->setMaskType(QOpenGLEngineShaderManager::SubPixelMaskPass2);-
1911-
1912 if (compMode == QPainter::CompositionMode_Source) {
compMode == QP...ionMode_SourceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1913 q->state()->opacity = oldOpacity;-
1914 opacityUniformDirty = true;-
1915 pensBrush = q->state()->pen.brush();-
1916 setBrush(pensBrush);-
1917 }
never executed: end of block
0
1918-
1919 compositionModeDirty = false;-
1920 prepareForCachedGlyphDraw(*cache);-
1921 funcs.glEnable(GL_BLEND);-
1922 funcs.glBlendFunc(GL_ONE, GL_ONE);-
1923 }
never executed: end of block
0
1924 compositionModeDirty = true;-
1925 } else if (glyphFormat == QFontEngine::Format_ARGB) {
never executed: end of block
glyphFormat ==...e::Format_ARGBDescription
TRUEnever evaluated
FALSEnever evaluated
0
1926 currentBrush = noBrush;-
1927 shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);-
1928 if (prepareForCachedGlyphDraw(*cache))
prepareForCach...phDraw(*cache)Description
TRUEnever evaluated
FALSEnever evaluated
0
1929 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
never executed: shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), GLuint(0));
0
1930 } else {
never executed: end of block
0
1931 // Grayscale/mono glyphs-
1932-
1933 shaderManager->setMaskType(QOpenGLEngineShaderManager::PixelMask);-
1934 prepareForCachedGlyphDraw(*cache);-
1935 }
never executed: end of block
0
1936-
1937 GLenum textureUnit = QT_MASK_TEXTURE_UNIT;-
1938 if (glyphFormat == QFontEngine::Format_ARGB)
glyphFormat ==...e::Format_ARGBDescription
TRUEnever evaluated
FALSEnever evaluated
0
1939 textureUnit = QT_IMAGE_TEXTURE_UNIT;
never executed: textureUnit = GLuint(0);
0
1940-
1941 QOpenGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate) ?
(s->matrix.typ...::TxTranslate)Description
TRUEnever evaluated
FALSEnever evaluated
0
1942 QOpenGLTextureGlyphCache::Linear : QOpenGLTextureGlyphCache::Nearest;-
1943-
1944 GLenum glFilterMode = filterMode == QOpenGLTextureGlyphCache::Linear ? GL_LINEAR : GL_NEAREST;
filterMode == ...hCache::LinearDescription
TRUEnever evaluated
FALSEnever evaluated
0
1945-
1946 TextureUpdateMode updateMode = UpdateIfNeeded;-
1947 if (cache->filterMode() != filterMode) {
cache->filterM... != filterModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1948 updateMode = ForceUpdate;-
1949 cache->setFilterMode(filterMode);-
1950 }
never executed: end of block
0
1951-
1952 updateTexture(textureUnit, cache->texture(), GL_REPEAT, glFilterMode, updateMode);-
1953-
1954#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)-
1955 funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);-
1956 funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);-
1957#else-
1958 funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());-
1959#endif-
1960}
never executed: end of block
0
1961-
1962void QOpenGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,-
1963 QPainter::PixmapFragmentHints hints)-
1964{-
1965 Q_D(QOpenGL2PaintEngineEx);-
1966 // Use fallback for extended composition modes.-
1967 if (state()->composition_mode > QPainter::CompositionMode_Plus) {
state()->compo...itionMode_PlusDescription
TRUEnever evaluated
FALSEnever evaluated
0
1968 QPaintEngineEx::drawPixmapFragments(fragments, fragmentCount, pixmap, hints);-
1969 return;
never executed: return;
0
1970 }-
1971-
1972 ensureActive();-
1973 int max_texture_size = d->ctx->d_func()->maxTextureSize();-
1974 if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) {
pixmap.width()...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
pixmap.height(...x_texture_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1975 QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);-
1976 d->drawPixmapFragments(fragments, fragmentCount, scaled, hints);-
1977 } else {
never executed: end of block
0
1978 d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);-
1979 }
never executed: end of block
0
1980}-
1981-
1982-
1983void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragment *fragments,-
1984 int fragmentCount, const QPixmap &pixmap,-
1985 QPainter::PixmapFragmentHints hints)-
1986{-
1987 GLfloat dx = 1.0f / pixmap.size().width();-
1988 GLfloat dy = 1.0f / pixmap.size().height();-
1989-
1990 vertexCoordinateArray.clear();-
1991 textureCoordinateArray.clear();-
1992 opacityArray.reset();-
1993-
1994 if (snapToPixelGrid) {
snapToPixelGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
1995 snapToPixelGrid = false;-
1996 matrixDirty = true;-
1997 }
never executed: end of block
0
1998-
1999 bool allOpaque = true;-
2000-
2001 for (int i = 0; i < fragmentCount; ++i) {
i < fragmentCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
2002 qreal s = 0;-
2003 qreal c = 1;-
2004 if (fragments[i].rotation != 0) {
fragments[i].rotation != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2005 s = qFastSin(qDegreesToRadians(fragments[i].rotation));-
2006 c = qFastCos(qDegreesToRadians(fragments[i].rotation));-
2007 }
never executed: end of block
0
2008-
2009 qreal right = 0.5 * fragments[i].scaleX * fragments[i].width;-
2010 qreal bottom = 0.5 * fragments[i].scaleY * fragments[i].height;-
2011 QOpenGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c);-
2012 QOpenGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c);-
2013-
2014 vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);-
2015 vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y);-
2016 vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);-
2017 vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);-
2018 vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y);-
2019 vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);-
2020-
2021 QOpenGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy,-
2022 (fragments[i].sourceLeft + fragments[i].width) * dx,-
2023 (fragments[i].sourceTop + fragments[i].height) * dy);-
2024-
2025 textureCoordinateArray.addVertex(src.right, src.bottom);-
2026 textureCoordinateArray.addVertex(src.right, src.top);-
2027 textureCoordinateArray.addVertex(src.left, src.top);-
2028 textureCoordinateArray.addVertex(src.left, src.top);-
2029 textureCoordinateArray.addVertex(src.left, src.bottom);-
2030 textureCoordinateArray.addVertex(src.right, src.bottom);-
2031-
2032 qreal opacity = fragments[i].opacity * q->state()->opacity;-
2033 opacityArray << opacity << opacity << opacity << opacity << opacity << opacity;-
2034 allOpaque &= (opacity >= 0.99f);-
2035 }
never executed: end of block
0
2036-
2037 transferMode(ImageOpacityArrayDrawingMode);-
2038-
2039 GLenum filterMode = q->state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST;
q->state()->re...ixmapTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
2040 updateTexture(QT_IMAGE_TEXTURE_UNIT, pixmap, GL_CLAMP_TO_EDGE, filterMode);-
2041-
2042 bool isBitmap = pixmap.isQBitmap();-
2043 bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque;
!isBitmapDescription
TRUEnever evaluated
FALSEnever evaluated
!pixmap.hasAlpha()Description
TRUEnever evaluated
FALSEnever evaluated
(hints & QPainter::OpaqueHint)Description
TRUEnever evaluated
FALSEnever evaluated
allOpaqueDescription
TRUEnever evaluated
FALSEnever evaluated
0
2044-
2045 // Setup for texture drawing-
2046 currentBrush = noBrush;-
2047 shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc-
2048 : QOpenGLEngineShaderManager::ImageSrc);-
2049 if (prepareForDraw(isOpaque))
prepareForDraw(isOpaque)Description
TRUEnever evaluated
FALSEnever evaluated
0
2050 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
never executed: shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), GLuint(0));
0
2051-
2052 if (isBitmap) {
isBitmapDescription
TRUEnever evaluated
FALSEnever evaluated
0
2053 QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity);-
2054 shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);-
2055 }
never executed: end of block
0
2056-
2057 funcs.glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount);-
2058}
never executed: end of block
0
2059-
2060bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)-
2061{-
2062 Q_D(QOpenGL2PaintEngineEx);-
2063-
2064 Q_ASSERT(pdev->devType() == QInternal::OpenGL);-
2065 d->device = static_cast<QOpenGLPaintDevice*>(pdev);-
2066-
2067 if (!d->device)
!d->deviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
2068 return false;
never executed: return false;
0
2069-
2070 d->device->ensureActiveTarget();-
2071-
2072 if (d->device->context() != QOpenGLContext::currentContext() || !d->device->context()) {
d->device->con...rrentContext()Description
TRUEnever evaluated
FALSEnever evaluated
!d->device->context()Description
TRUEnever evaluated
FALSEnever evaluated
0
2073 qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current");-
2074 return false;
never executed: return false;
0
2075 }-
2076-
2077 d->ctx = QOpenGLContext::currentContext();-
2078 d->ctx->d_func()->active_engine = this;-
2079-
2080 QOpenGLPaintDevicePrivate::get(d->device)->beginPaint();-
2081-
2082 d->funcs.initializeOpenGLFunctions();-
2083-
2084 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
i < 3Description
TRUEnever evaluated
FALSEnever evaluated
0
2085 d->vertexAttributeArraysEnabledState[i] = false;
never executed: d->vertexAttributeArraysEnabledState[i] = false;
0
2086-
2087 const QSize sz = d->device->size();-
2088 d->width = sz.width();-
2089 d->height = sz.height();-
2090 d->mode = BrushDrawingMode;-
2091 d->brushTextureDirty = true;-
2092 d->brushUniformsDirty = true;-
2093 d->matrixUniformDirty = true;-
2094 d->matrixDirty = true;-
2095 d->compositionModeDirty = true;-
2096 d->opacityUniformDirty = true;-
2097 d->needsSync = true;-
2098 d->useSystemClip = !systemClip().isEmpty();-
2099 d->currentBrush = QBrush();-
2100-
2101 d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);-
2102 d->stencilClean = true;-
2103-
2104 d->shaderManager = new QOpenGLEngineShaderManager(d->ctx);-
2105-
2106 d->funcs.glDisable(GL_STENCIL_TEST);-
2107 d->funcs.glDisable(GL_DEPTH_TEST);-
2108 d->funcs.glDisable(GL_SCISSOR_TEST);-
2109-
2110 d->glyphCacheFormat = QFontEngine::Format_A8;-
2111-
2112#ifndef QT_OPENGL_ES_2-
2113 if (!QOpenGLContext::currentContext()->isOpenGLES()) {
!QOpenGLContex...->isOpenGLES()Description
TRUEnever evaluated
FALSEnever evaluated
0
2114 d->funcs.glDisable(GL_MULTISAMPLE);-
2115 d->glyphCacheFormat = QFontEngine::Format_A32;-
2116 d->multisamplingAlwaysEnabled = false;-
2117 } else
never executed: end of block
0
2118#endif // QT_OPENGL_ES_2-
2119 {-
2120 // OpenGL ES can't switch MSAA off, so if the gl paint device is-
2121 // multisampled, it's always multisampled.-
2122 d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;-
2123 }
never executed: end of block
0
2124-
2125 return true;
never executed: return true;
0
2126}-
2127-
2128bool QOpenGL2PaintEngineEx::end()-
2129{-
2130 Q_D(QOpenGL2PaintEngineEx);-
2131-
2132 QOpenGLPaintDevicePrivate::get(d->device)->endPaint();-
2133-
2134 QOpenGLContext *ctx = d->ctx;-
2135 d->funcs.glUseProgram(0);-
2136 d->transferMode(BrushDrawingMode);-
2137-
2138 ctx->d_func()->active_engine = 0;-
2139-
2140 d->resetGLState();-
2141-
2142 delete d->shaderManager;-
2143 d->shaderManager = 0;-
2144 d->currentBrush = QBrush();-
2145-
2146#ifdef QT_OPENGL_CACHE_AS_VBOS-
2147 if (!d->unusedVBOSToClean.isEmpty()) {-
2148 glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData());-
2149 d->unusedVBOSToClean.clear();-
2150 }-
2151 if (!d->unusedIBOSToClean.isEmpty()) {-
2152 glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData());-
2153 d->unusedIBOSToClean.clear();-
2154 }-
2155#endif-
2156-
2157 return false;
never executed: return false;
0
2158}-
2159-
2160void QOpenGL2PaintEngineEx::ensureActive()-
2161{-
2162 Q_D(QOpenGL2PaintEngineEx);-
2163 QOpenGLContext *ctx = d->ctx;-
2164-
2165 if (isActive() && ctx->d_func()->active_engine != this) {
isActive()Description
TRUEnever evaluated
FALSEnever evaluated
ctx->d_func()-...engine != thisDescription
TRUEnever evaluated
FALSEnever evaluated
0
2166 ctx->d_func()->active_engine = this;-
2167 d->needsSync = true;-
2168 }
never executed: end of block
0
2169-
2170 if (d->needsSync) {
d->needsSyncDescription
TRUEnever evaluated
FALSEnever evaluated
0
2171 d->device->ensureActiveTarget();-
2172-
2173 d->transferMode(BrushDrawingMode);-
2174 d->funcs.glViewport(0, 0, d->width, d->height);-
2175 d->needsSync = false;-
2176 d->shaderManager->setDirty();-
2177 d->syncGlState();-
2178 for (int i = 0; i < 3; ++i)
i < 3Description
TRUEnever evaluated
FALSEnever evaluated
0
2179 d->vertexAttribPointers[i] = (GLfloat*)-1; // Assume the pointers are clobbered
never executed: d->vertexAttribPointers[i] = (GLfloat*)-1;
0
2180 setState(state());-
2181 }
never executed: end of block
0
2182}
never executed: end of block
0
2183-
2184void QOpenGL2PaintEngineExPrivate::updateClipScissorTest()-
2185{-
2186 Q_Q(QOpenGL2PaintEngineEx);-
2187 if (q->state()->clipTestEnabled) {
q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
2188 funcs.glEnable(GL_STENCIL_TEST);-
2189 funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);-
2190 } else {
never executed: end of block
0
2191 funcs.glDisable(GL_STENCIL_TEST);-
2192 funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);-
2193 }
never executed: end of block
0
2194-
2195#ifdef QT_GL_NO_SCISSOR_TEST-
2196 currentScissorBounds = QRect(0, 0, width, height);-
2197#else-
2198 QRect bounds = q->state()->rectangleClip;-
2199 if (!q->state()->clipEnabled) {
!q->state()->clipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
2200 if (useSystemClip)
useSystemClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
2201 bounds = systemClip.boundingRect();
never executed: bounds = systemClip.boundingRect();
0
2202 else-
2203 bounds = QRect(0, 0, width, height);
never executed: bounds = QRect(0, 0, width, height);
0
2204 } else {-
2205 if (useSystemClip)
useSystemClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
2206 bounds = bounds.intersected(systemClip.boundingRect());
never executed: bounds = bounds.intersected(systemClip.boundingRect());
0
2207 else-
2208 bounds = bounds.intersected(QRect(0, 0, width, height));
never executed: bounds = bounds.intersected(QRect(0, 0, width, height));
0
2209 }-
2210-
2211 currentScissorBounds = bounds;-
2212-
2213 if (bounds == QRect(0, 0, width, height)) {
bounds == QRec...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
0
2214 funcs.glDisable(GL_SCISSOR_TEST);-
2215 } else {
never executed: end of block
0
2216 funcs.glEnable(GL_SCISSOR_TEST);-
2217 setScissor(bounds);-
2218 }
never executed: end of block
0
2219#endif-
2220}-
2221-
2222void QOpenGL2PaintEngineExPrivate::setScissor(const QRect &rect)-
2223{-
2224 const int left = rect.left();-
2225 const int width = rect.width();-
2226 int bottom = height - (rect.top() + rect.height());-
2227 if (device->paintFlipped()) {
device->paintFlipped()Description
TRUEnever evaluated
FALSEnever evaluated
0
2228 bottom = rect.top();-
2229 }
never executed: end of block
0
2230 const int height = rect.height();-
2231-
2232 funcs.glScissor(left, bottom, width, height);-
2233}
never executed: end of block
0
2234-
2235void QOpenGL2PaintEngineEx::clipEnabledChanged()-
2236{-
2237 Q_D(QOpenGL2PaintEngineEx);-
2238-
2239 state()->clipChanged = true;-
2240-
2241 if (painter()->hasClipping())
painter()->hasClipping()Description
TRUEnever evaluated
FALSEnever evaluated
0
2242 d->regenerateClip();
never executed: d->regenerateClip();
0
2243 else-
2244 d->systemStateChanged();
never executed: d->systemStateChanged();
0
2245}-
2246-
2247void QOpenGL2PaintEngineExPrivate::clearClip(uint value)-
2248{-
2249 dirtyStencilRegion -= currentScissorBounds;-
2250-
2251 funcs.glStencilMask(0xff);-
2252 funcs.glClearStencil(value);-
2253 funcs.glClear(GL_STENCIL_BUFFER_BIT);-
2254 funcs.glStencilMask(0x0);-
2255-
2256 q->state()->needsClipBufferClear = false;-
2257}
never executed: end of block
0
2258-
2259void QOpenGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value)-
2260{-
2261 transferMode(BrushDrawingMode);-
2262-
2263 if (snapToPixelGrid) {
snapToPixelGridDescription
TRUEnever evaluated
FALSEnever evaluated
0
2264 snapToPixelGrid = false;-
2265 matrixDirty = true;-
2266 }
never executed: end of block
0
2267-
2268 if (matrixDirty)
matrixDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
2269 updateMatrix();
never executed: updateMatrix();
0
2270-
2271 stencilClean = false;-
2272-
2273 const bool singlePass = !path.hasWindingFill()
!path.hasWindingFill()Description
TRUEnever evaluated
FALSEnever evaluated
0
2274 && (((q->state()->currentClip == maxClip - 1) && q->state()->clipTestEnabled)
(q->state()->c...= maxClip - 1)Description
TRUEnever evaluated
FALSEnever evaluated
q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
2275 || q->state()->needsClipBufferClear);
q->state()->ne...lipBufferClearDescription
TRUEnever evaluated
FALSEnever evaluated
0
2276 const uint referenceClipValue = q->state()->needsClipBufferClear ? 1 : q->state()->currentClip;
q->state()->ne...lipBufferClearDescription
TRUEnever evaluated
FALSEnever evaluated
0
2277-
2278 if (q->state()->needsClipBufferClear)
q->state()->ne...lipBufferClearDescription
TRUEnever evaluated
FALSEnever evaluated
0
2279 clearClip(1);
never executed: clearClip(1);
0
2280-
2281 if (path.isEmpty()) {
path.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2282 funcs.glEnable(GL_STENCIL_TEST);-
2283 funcs.glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);-
2284 return;
never executed: return;
0
2285 }-
2286-
2287 if (q->state()->clipTestEnabled)
q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
2288 funcs.glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
never executed: funcs.glStencilFunc(0x0203, q->state()->currentClip, ~GLuint(0x80));
0
2289 else-
2290 funcs.glStencilFunc(GL_ALWAYS, 0, 0xff);
never executed: funcs.glStencilFunc(0x0207, 0, 0xff);
0
2291-
2292 vertexCoordinateArray.clear();-
2293 vertexCoordinateArray.addPath(path, inverseScale, false);-
2294-
2295 if (!singlePass)
!singlePassDescription
TRUEnever evaluated
FALSEnever evaluated
0
2296 fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
never executed: fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
0
2297-
2298 funcs.glColorMask(false, false, false, false);-
2299 funcs.glEnable(GL_STENCIL_TEST);-
2300 useSimpleShader();-
2301-
2302 if (singlePass) {
singlePassDescription
TRUEnever evaluated
FALSEnever evaluated
0
2303 // Under these conditions we can set the new stencil value in a single-
2304 // pass, by using the current value and the "new value" as the toggles-
2305-
2306 funcs.glStencilFunc(GL_LEQUAL, referenceClipValue, ~GL_STENCIL_HIGH_BIT);-
2307 funcs.glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);-
2308 funcs.glStencilMask(value ^ referenceClipValue);-
2309-
2310 drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN);-
2311 } else {
never executed: end of block
0
2312 funcs.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);-
2313 funcs.glStencilMask(0xff);-
2314-
2315 if (!q->state()->clipTestEnabled && path.hasWindingFill()) {
!q->state()->clipTestEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
path.hasWindingFill()Description
TRUEnever evaluated
FALSEnever evaluated
0
2316 // Pass when any clip bit is set, set high bit-
2317 funcs.glStencilFunc(GL_NOTEQUAL, GL_STENCIL_HIGH_BIT, ~GL_STENCIL_HIGH_BIT);-
2318 composite(vertexCoordinateArray.boundingRect());-
2319 }
never executed: end of block
0
2320-
2321 // Pass when high bit is set, replace stencil value with new clip value-
2322 funcs.glStencilFunc(GL_NOTEQUAL, value, GL_STENCIL_HIGH_BIT);-
2323-
2324 composite(vertexCoordinateArray.boundingRect());-
2325 }
never executed: end of block
0
2326-
2327 funcs.glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);-
2328 funcs.glStencilMask(0);-
2329-
2330 funcs.glColorMask(true, true, true, true);-
2331}
never executed: end of block
0
2332-
2333void QOpenGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)-
2334{-
2335// qDebug("QOpenGL2PaintEngineEx::clip()");-
2336 Q_D(QOpenGL2PaintEngineEx);-
2337-
2338 state()->clipChanged = true;-
2339-
2340 ensureActive();-
2341-
2342 if (op == Qt::ReplaceClip) {
op == Qt::ReplaceClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
2343 op = Qt::IntersectClip;-
2344 if (d->hasClipOperations()) {
d->hasClipOperations()Description
TRUEnever evaluated
FALSEnever evaluated
0
2345 d->systemStateChanged();-
2346 state()->canRestoreClip = false;-
2347 }
never executed: end of block
0
2348 }
never executed: end of block
0
2349-
2350#ifndef QT_GL_NO_SCISSOR_TEST-
2351 if (!path.isEmpty() && op == Qt::IntersectClip && (path.shape() == QVectorPath::RectangleHint)) {
!path.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
op == Qt::IntersectClipDescription
TRUEnever evaluated
FALSEnever evaluated
(path.shape() ...RectangleHint)Description
TRUEnever evaluated
FALSEnever evaluated
0
2352 const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());-
2353 QRectF rect(points[0], points[2]);-
2354-
2355 if (state()->matrix.type() <= QTransform::TxScale
state()->matri...sform::TxScaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2356 || (state()->matrix.type() == QTransform::TxRotate
state()->matri...form::TxRotateDescription
TRUEnever evaluated
FALSEnever evaluated
0
2357 && qFuzzyIsNull(state()->matrix.m11())
qFuzzyIsNull(s...>matrix.m11())Description
TRUEnever evaluated
FALSEnever evaluated
0
2358 && qFuzzyIsNull(state()->matrix.m22())))
qFuzzyIsNull(s...>matrix.m22())Description
TRUEnever evaluated
FALSEnever evaluated
0
2359 {-
2360 state()->rectangleClip = state()->rectangleClip.intersected(state()->matrix.mapRect(rect).toRect());-
2361 d->updateClipScissorTest();-
2362 return;
never executed: return;
0
2363 }-
2364 }
never executed: end of block
0
2365#endif-
2366-
2367 const QRect pathRect = state()->matrix.mapRect(path.controlPointRect()).toAlignedRect();-
2368-
2369 switch (op) {-
2370 case Qt::NoClip:
never executed: case Qt::NoClip:
0
2371 if (d->useSystemClip) {
d->useSystemClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
2372 state()->clipTestEnabled = true;-
2373 state()->currentClip = 1;-
2374 } else {
never executed: end of block
0
2375 state()->clipTestEnabled = false;-
2376 }
never executed: end of block
0
2377 state()->rectangleClip = QRect(0, 0, d->width, d->height);-
2378 state()->canRestoreClip = false;-
2379 d->updateClipScissorTest();-
2380 break;
never executed: break;
0
2381 case Qt::IntersectClip:
never executed: case Qt::IntersectClip:
0
2382 state()->rectangleClip = state()->rectangleClip.intersected(pathRect);-
2383 d->updateClipScissorTest();-
2384 d->resetClipIfNeeded();-
2385 ++d->maxClip;-
2386 d->writeClip(path, d->maxClip);-
2387 state()->currentClip = d->maxClip;-
2388 state()->clipTestEnabled = true;-
2389 break;
never executed: break;
0
2390 default:
never executed: default:
0
2391 break;
never executed: break;
0
2392 }-
2393}-
2394-
2395void QOpenGL2PaintEngineExPrivate::regenerateClip()-
2396{-
2397 systemStateChanged();-
2398 replayClipOperations();-
2399}
never executed: end of block
0
2400-
2401void QOpenGL2PaintEngineExPrivate::systemStateChanged()-
2402{-
2403 Q_Q(QOpenGL2PaintEngineEx);-
2404-
2405 q->state()->clipChanged = true;-
2406-
2407 if (systemClip.isEmpty()) {
systemClip.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2408 useSystemClip = false;-
2409 } else {
never executed: end of block
0
2410 if (q->paintDevice()->devType() == QInternal::Widget && currentClipDevice) {
q->paintDevice...ternal::WidgetDescription
TRUEnever evaluated
FALSEnever evaluated
currentClipDeviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
2411 //QWidgetPrivate *widgetPrivate = qt_widget_private(static_cast<QWidget *>(currentClipDevice)->window());-
2412 //useSystemClip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;-
2413 useSystemClip = true;-
2414 } else {
never executed: end of block
0
2415 useSystemClip = true;-
2416 }
never executed: end of block
0
2417 }-
2418-
2419 q->state()->clipTestEnabled = false;-
2420 q->state()->needsClipBufferClear = true;-
2421-
2422 q->state()->currentClip = 1;-
2423 maxClip = 1;-
2424-
2425 q->state()->rectangleClip = useSystemClip ? systemClip.boundingRect() : QRect(0, 0, width, height);
useSystemClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
2426 updateClipScissorTest();-
2427-
2428 if (systemClip.rectCount() == 1) {
systemClip.rectCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2429 if (systemClip.boundingRect() == QRect(0, 0, width, height))
systemClip.bou...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
0
2430 useSystemClip = false;
never executed: useSystemClip = false;
0
2431#ifndef QT_GL_NO_SCISSOR_TEST-
2432 // scissoring takes care of the system clip-
2433 return;
never executed: return;
0
2434#endif-
2435 }-
2436-
2437 if (useSystemClip) {
useSystemClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
2438 clearClip(0);-
2439-
2440 QPainterPath path;-
2441 path.addRegion(systemClip);-
2442-
2443 q->state()->currentClip = 0;-
2444 writeClip(qtVectorPathForPath(q->state()->matrix.inverted().map(path)), 1);-
2445 q->state()->currentClip = 1;-
2446 q->state()->clipTestEnabled = true;-
2447 }
never executed: end of block
0
2448}
never executed: end of block
0
2449-
2450void QOpenGL2PaintEngineEx::setState(QPainterState *new_state)-
2451{-
2452 // qDebug("QOpenGL2PaintEngineEx::setState()");-
2453-
2454 Q_D(QOpenGL2PaintEngineEx);-
2455-
2456 QOpenGL2PaintEngineState *s = static_cast<QOpenGL2PaintEngineState *>(new_state);-
2457 QOpenGL2PaintEngineState *old_state = state();-
2458-
2459 QPaintEngineEx::setState(s);-
2460-
2461 if (s->isNew) {
s->isNewDescription
TRUEnever evaluated
FALSEnever evaluated
0
2462 // Newly created state object. The call to setState()-
2463 // will either be followed by a call to begin(), or we are-
2464 // setting the state as part of a save().-
2465 s->isNew = false;-
2466 return;
never executed: return;
0
2467 }-
2468-
2469 // Setting the state as part of a restore().-
2470-
2471 if (old_state == s || old_state->renderHintsChanged)
old_state == sDescription
TRUEnever evaluated
FALSEnever evaluated
old_state->renderHintsChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
2472 renderHintsChanged();
never executed: renderHintsChanged();
0
2473-
2474 if (old_state == s || old_state->matrixChanged)
old_state == sDescription
TRUEnever evaluated
FALSEnever evaluated
old_state->matrixChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
2475 d->matrixDirty = true;
never executed: d->matrixDirty = true;
0
2476-
2477 if (old_state == s || old_state->compositionModeChanged)
old_state == sDescription
TRUEnever evaluated
FALSEnever evaluated
old_state->com...ionModeChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
2478 d->compositionModeDirty = true;
never executed: d->compositionModeDirty = true;
0
2479-
2480 if (old_state == s || old_state->opacityChanged)
old_state == sDescription
TRUEnever evaluated
FALSEnever evaluated
old_state->opacityChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
2481 d->opacityUniformDirty = true;
never executed: d->opacityUniformDirty = true;
0
2482-
2483 if (old_state == s || old_state->clipChanged) {
old_state == sDescription
TRUEnever evaluated
FALSEnever evaluated
old_state->clipChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
2484 if (old_state && old_state != s && old_state->canRestoreClip) {
old_stateDescription
TRUEnever evaluated
FALSEnever evaluated
old_state != sDescription
TRUEnever evaluated
FALSEnever evaluated
old_state->canRestoreClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
2485 d->updateClipScissorTest();-
2486 d->funcs.glDepthFunc(GL_LEQUAL);-
2487 } else {
never executed: end of block
0
2488 d->regenerateClip();-
2489 }
never executed: end of block
0
2490 }-
2491}
never executed: end of block
0
2492-
2493QPainterState *QOpenGL2PaintEngineEx::createState(QPainterState *orig) const-
2494{-
2495 if (orig)
origDescription
TRUEnever evaluated
FALSEnever evaluated
0
2496 const_cast<QOpenGL2PaintEngineEx *>(this)->ensureActive();
never executed: const_cast<QOpenGL2PaintEngineEx *>(this)->ensureActive();
0
2497-
2498 QOpenGL2PaintEngineState *s;-
2499 if (!orig)
!origDescription
TRUEnever evaluated
FALSEnever evaluated
0
2500 s = new QOpenGL2PaintEngineState();
never executed: s = new QOpenGL2PaintEngineState();
0
2501 else-
2502 s = new QOpenGL2PaintEngineState(*static_cast<QOpenGL2PaintEngineState *>(orig));
never executed: s = new QOpenGL2PaintEngineState(*static_cast<QOpenGL2PaintEngineState *>(orig));
0
2503-
2504 s->matrixChanged = false;-
2505 s->compositionModeChanged = false;-
2506 s->opacityChanged = false;-
2507 s->renderHintsChanged = false;-
2508 s->clipChanged = false;-
2509-
2510 return s;
never executed: return s;
0
2511}-
2512-
2513QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other)-
2514 : QPainterState(other)-
2515{-
2516 isNew = true;-
2517 needsClipBufferClear = other.needsClipBufferClear;-
2518 clipTestEnabled = other.clipTestEnabled;-
2519 currentClip = other.currentClip;-
2520 canRestoreClip = other.canRestoreClip;-
2521 rectangleClip = other.rectangleClip;-
2522}
never executed: end of block
0
2523-
2524QOpenGL2PaintEngineState::QOpenGL2PaintEngineState()-
2525{-
2526 isNew = true;-
2527 needsClipBufferClear = true;-
2528 clipTestEnabled = false;-
2529 canRestoreClip = true;-
2530}
never executed: end of block
0
2531-
2532QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState()-
2533{-
2534}-
2535-
2536void QOpenGL2PaintEngineExPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)-
2537{-
2538 Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);-
2539-
2540 if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
vertexAttribut...te[arrayIndex]Description
TRUEnever evaluated
FALSEnever evaluated
!enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
2541 funcs.glDisableVertexAttribArray(arrayIndex);
never executed: funcs.glDisableVertexAttribArray(arrayIndex);
0
2542-
2543 if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
!vertexAttribu...te[arrayIndex]Description
TRUEnever evaluated
FALSEnever evaluated
enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
2544 funcs.glEnableVertexAttribArray(arrayIndex);
never executed: funcs.glEnableVertexAttribArray(arrayIndex);
0
2545-
2546 vertexAttributeArraysEnabledState[arrayIndex] = enabled;-
2547}
never executed: end of block
0
2548-
2549void QOpenGL2PaintEngineExPrivate::syncGlState()-
2550{-
2551 for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
i < 3Description
TRUEnever evaluated
FALSEnever evaluated
0
2552 if (vertexAttributeArraysEnabledState[i])
vertexAttribut...nabledState[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
2553 funcs.glEnableVertexAttribArray(i);
never executed: funcs.glEnableVertexAttribArray(i);
0
2554 else-
2555 funcs.glDisableVertexAttribArray(i);
never executed: funcs.glDisableVertexAttribArray(i);
0
2556 }-
2557}
never executed: end of block
0
2558-
2559-
2560QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9