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

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