1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QGRAPHICSCONTEXT_OPENGL2_P_H
43 #define QGRAPHICSCONTEXT_OPENGL2_P_H
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
58 #include <private/qpaintengineex_p.h>
59 #include <private/qopenglengineshadermanager_p.h>
60 #include <private/qopengl2pexvertexarray_p.h>
61 #include <private/qopenglpaintdevice_p.h>
62 #include <private/qfontengine_p.h>
63 #include <private/qdatabuffer_p.h>
64 #include <private/qtriangulatingstroker_p.h>
66 #include <private/qopenglextensions_p.h>
77 #define GL_STENCIL_HIGH_BIT GLuint(0x80)
78 #define QT_BRUSH_TEXTURE_UNIT GLuint(0)
79 #define QT_IMAGE_TEXTURE_UNIT GLuint(0) //Can be the same as brush texture unit
80 #define QT_MASK_TEXTURE_UNIT GLuint(1)
81 #define QT_BACKGROUND_TEXTURE_UNIT GLuint(2)
83 class QOpenGL2PaintEngineExPrivate;
85 class QOpenGL2PaintEngineState : public QPainterState
88 QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other);
89 QOpenGL2PaintEngineState();
90 ~QOpenGL2PaintEngineState();
93 uint needsClipBufferClear : 1;
94 uint clipTestEnabled : 1;
95 uint canRestoreClip : 1;
96 uint matrixChanged : 1;
97 uint compositionModeChanged : 1;
98 uint opacityChanged : 1;
99 uint renderHintsChanged : 1;
100 uint clipChanged : 1;
101 uint currentClip : 8;
106 class Q_GUI_EXPORT QOpenGL2PaintEngineEx : public QPaintEngineEx
108 Q_DECLARE_PRIVATE(QOpenGL2PaintEngineEx)
110 QOpenGL2PaintEngineEx();
111 ~QOpenGL2PaintEngineEx();
113 bool begin(QPaintDevice *device);
117 virtual void clipEnabledChanged();
118 virtual void penChanged();
119 virtual void brushChanged();
120 virtual void brushOriginChanged();
121 virtual void opacityChanged();
122 virtual void compositionModeChanged();
123 virtual void renderHintsChanged();
124 virtual void transformChanged();
126 virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
127 virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
128 QPainter::PixmapFragmentHints hints);
129 virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
130 Qt::ImageConversionFlags flags = Qt::AutoColor);
131 virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
132 virtual void fill(const QVectorPath &path, const QBrush &brush);
133 virtual void stroke(const QVectorPath &path, const QPen &pen);
134 virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
136 virtual void drawStaticTextItem(QStaticTextItem *textItem);
138 bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
140 Type type() const { return OpenGL2; }
142 virtual void setState(QPainterState *s);
143 virtual QPainterState *createState(QPainterState *orig) const;
144 inline QOpenGL2PaintEngineState *state() {
145 return static_cast<QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
147 inline const QOpenGL2PaintEngineState *state() const {
148 return static_cast<const QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
151 void beginNativePainting();
152 void endNativePainting();
154 void invalidateState();
156 void setRenderTextActive(bool);
158 bool isNativePaintingActive() const;
159 bool supportsTransformations(qreal, const QTransform &) const { return true; }
162 Q_DISABLE_COPY(QOpenGL2PaintEngineEx)
164 friend class QOpenGLEngineShaderManager;
167 // This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's
168 // all the GL2 engine uses:
169 #define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
171 class QOpenGL2PaintEngineExPrivate : public QPaintEngineExPrivate
173 Q_DECLARE_PUBLIC(QOpenGL2PaintEngineEx)
175 enum StencilFillMode {
178 TriStripStrokeFillMode
181 QOpenGL2PaintEngineExPrivate(QOpenGL2PaintEngineEx *q_ptr) :
187 elementIndicesVBOId(0),
189 snapToPixelGrid(false),
190 nativePaintingActive(false),
192 lastMaskTextureUsed(0)
195 ~QOpenGL2PaintEngineExPrivate();
197 void updateBrushTexture();
198 void updateBrushUniforms();
200 void updateCompositionMode();
201 void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = -1);
205 // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points,
206 // however writeClip can also be thought of as en entry point as it does similar things.
207 void fill(const QVectorPath &path);
208 void stroke(const QVectorPath &path, const QPen &pen);
209 void drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false);
210 void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
211 QPainter::PixmapFragmentHints hints);
212 void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem);
214 // Calls glVertexAttributePointer if the pointer has changed
215 inline void setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer);
217 // draws whatever is in the vertex array:
218 void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive);
219 void drawVertexArrays(QOpenGL2PEXVertexArray &vertexArray, GLenum primitive) {
220 drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive);
223 // Composites the bounding rect onto dest buffer:
224 void composite(const QOpenGLRect& boundingRect);
226 // Calls drawVertexArrays to render into stencil buffer:
227 void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QOpenGLRect &bounds, StencilFillMode mode);
228 void fillStencilWithVertexArray(QOpenGL2PEXVertexArray& vertexArray, bool useWindingFill) {
229 fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(),
230 vertexArray.boundingRect(),
231 useWindingFill ? WindingFillMode : OddEvenFillMode);
234 void setBrush(const QBrush& brush);
235 void transferMode(EngineMode newMode);
236 bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed
237 inline void useSimpleShader();
238 inline GLuint location(const QOpenGLEngineShaderManager::Uniform uniform) {
239 return shaderManager->getUniformLocation(uniform);
242 void clearClip(uint value);
243 void writeClip(const QVectorPath &path, uint value);
244 void resetClipIfNeeded();
246 void updateClipScissorTest();
247 void setScissor(const QRect &rect);
248 void regenerateClip();
249 void systemStateChanged();
251 void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
254 static QOpenGLEngineShaderManager* shaderManagerForEngine(QOpenGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; }
255 static QOpenGL2PaintEngineExPrivate *getData(QOpenGL2PaintEngineEx *engine) { return engine->d_func(); }
256 static void cleanupVectorPath(QPaintEngineEx *engine, void *data);
258 QOpenGLExtensions funcs;
260 QOpenGL2PaintEngineEx* q;
261 QOpenGLEngineShaderManager* shaderManager;
262 QOpenGLPaintDevice* device;
266 QFontEngineGlyphCache::Type glyphCacheType;
268 bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
271 bool matrixDirty; // Implies matrix uniforms are also dirty
272 bool compositionModeDirty;
273 bool brushTextureDirty;
274 bool brushUniformsDirty;
275 bool opacityUniformDirty;
276 bool matrixUniformDirty;
278 bool stencilClean; // Has the stencil not been used for clipping so far?
280 QRegion dirtyStencilRegion;
281 QRect currentScissorBounds;
284 QBrush currentBrush; // May not be the state's brush!
285 const QBrush noBrush;
287 QPixmap currentBrushPixmap;
289 QOpenGL2PEXVertexArray vertexCoordinateArray;
290 QOpenGL2PEXVertexArray textureCoordinateArray;
291 QVector<GLushort> elementIndices;
292 GLuint elementIndicesVBOId;
293 QDataBuffer<GLfloat> opacityArray;
294 GLfloat staticVertexCoordinateArray[8];
295 GLfloat staticTextureCoordinateArray[8];
297 bool snapToPixelGrid;
298 bool nativePaintingActive;
299 GLfloat pmvMatrix[3][3];
300 GLfloat inverseScale;
302 GLuint lastTextureUsed;
303 GLuint lastMaskTextureUsed;
306 bool multisamplingAlwaysEnabled;
308 GLfloat depthRange[2];
310 float textureInvertedY;
312 QTriangulatingStroker stroker;
313 QDashedStrokeProcessor dasher;
315 QSet<QVectorPath::CacheEntry *> pathCaches;
316 QVector<GLuint> unusedVBOSToClean;
317 QVector<GLuint> unusedIBOSToClean;
319 const GLfloat *vertexAttribPointers[3];
323 void QOpenGL2PaintEngineExPrivate::setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer)
325 Q_ASSERT(arrayIndex < 3);
326 if (pointer == vertexAttribPointers[arrayIndex])
329 vertexAttribPointers[arrayIndex] = pointer;
330 if (arrayIndex == QT_OPACITY_ATTR)
331 funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer);
333 funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer);