Remove duplicate triangulating stroker implementation.
[profile/ivi/qtbase.git] / src / gui / opengl / qopenglpaintengine_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QOPENGLPAINTENGINE_P_H
43 #define QOPENGLPAINTENGINE_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
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.
52 //
53 // We mean it.
54 //
55
56 #include <QDebug>
57
58 #include <qopenglpaintdevice.h>
59
60 #include <private/qpaintengineex_p.h>
61 #include <private/qopenglengineshadermanager_p.h>
62 #include <private/qopengl2pexvertexarray_p.h>
63 #include <private/qfontengine_p.h>
64 #include <private/qdatabuffer_p.h>
65 #include <private/qtriangulatingstroker_p.h>
66
67 #include <private/qopenglextensions_p.h>
68
69 enum EngineMode {
70     ImageDrawingMode,
71     TextDrawingMode,
72     BrushDrawingMode,
73     ImageArrayDrawingMode
74 };
75
76 QT_BEGIN_NAMESPACE
77
78 #define GL_STENCIL_HIGH_BIT         GLuint(0x80)
79 #define QT_BRUSH_TEXTURE_UNIT       GLuint(0)
80 #define QT_IMAGE_TEXTURE_UNIT       GLuint(0) //Can be the same as brush texture unit
81 #define QT_MASK_TEXTURE_UNIT        GLuint(1)
82 #define QT_BACKGROUND_TEXTURE_UNIT  GLuint(2)
83
84 class QOpenGL2PaintEngineExPrivate;
85
86 class QOpenGL2PaintEngineState : public QPainterState
87 {
88 public:
89     QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other);
90     QOpenGL2PaintEngineState();
91     ~QOpenGL2PaintEngineState();
92
93     uint isNew : 1;
94     uint needsClipBufferClear : 1;
95     uint clipTestEnabled : 1;
96     uint canRestoreClip : 1;
97     uint matrixChanged : 1;
98     uint compositionModeChanged : 1;
99     uint opacityChanged : 1;
100     uint renderHintsChanged : 1;
101     uint clipChanged : 1;
102     uint currentClip : 8;
103
104     QRect rectangleClip;
105 };
106
107 class Q_GUI_EXPORT QOpenGL2PaintEngineEx : public QPaintEngineEx
108 {
109     Q_DECLARE_PRIVATE(QOpenGL2PaintEngineEx)
110 public:
111     QOpenGL2PaintEngineEx();
112     ~QOpenGL2PaintEngineEx();
113
114     bool begin(QPaintDevice *device);
115     void ensureActive();
116     bool end();
117
118     virtual void clipEnabledChanged();
119     virtual void penChanged();
120     virtual void brushChanged();
121     virtual void brushOriginChanged();
122     virtual void opacityChanged();
123     virtual void compositionModeChanged();
124     virtual void renderHintsChanged();
125     virtual void transformChanged();
126
127     virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
128     virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
129                                      QPainter::PixmapFragmentHints hints);
130     virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
131                            Qt::ImageConversionFlags flags = Qt::AutoColor);
132     virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
133     virtual void fill(const QVectorPath &path, const QBrush &brush);
134     virtual void stroke(const QVectorPath &path, const QPen &pen);
135     virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
136
137     virtual void drawStaticTextItem(QStaticTextItem *textItem);
138
139     bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
140
141     Type type() const { return OpenGL2; }
142
143     virtual void setState(QPainterState *s);
144     virtual QPainterState *createState(QPainterState *orig) const;
145     inline QOpenGL2PaintEngineState *state() {
146         return static_cast<QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
147     }
148     inline const QOpenGL2PaintEngineState *state() const {
149         return static_cast<const QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
150     }
151
152     void beginNativePainting();
153     void endNativePainting();
154
155     void invalidateState();
156
157     void setRenderTextActive(bool);
158
159     bool isNativePaintingActive() const;
160     bool supportsTransformations(QFontEngine *, const QTransform &) const { return true; }
161
162 private:
163     Q_DISABLE_COPY(QOpenGL2PaintEngineEx)
164
165     friend class QOpenGLEngineShaderManager;
166 };
167
168 // This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's
169 // all the GL2 engine uses:
170 #define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
171
172 class QOpenGL2PaintEngineExPrivate : public QPaintEngineExPrivate
173 {
174     Q_DECLARE_PUBLIC(QOpenGL2PaintEngineEx)
175 public:
176     enum StencilFillMode {
177         OddEvenFillMode,
178         WindingFillMode,
179         TriStripStrokeFillMode
180     };
181
182     QOpenGL2PaintEngineExPrivate(QOpenGL2PaintEngineEx *q_ptr) :
183             q(q_ptr),
184             shaderManager(0),
185             width(0), height(0),
186             ctx(0),
187             useSystemClip(true),
188             elementIndicesVBOId(0),
189             opacityArray(0),
190             snapToPixelGrid(false),
191             nativePaintingActive(false),
192             inverseScale(1),
193             lastMaskTextureUsed(0)
194     { }
195
196     ~QOpenGL2PaintEngineExPrivate();
197
198     void updateBrushTexture();
199     void updateBrushUniforms();
200     void updateMatrix();
201     void updateCompositionMode();
202     void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
203
204     void resetGLState();
205
206     // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points,
207     // however writeClip can also be thought of as en entry point as it does similar things.
208     void fill(const QVectorPath &path);
209     void stroke(const QVectorPath &path, const QPen &pen);
210     void drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false);
211     void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
212                              QPainter::PixmapFragmentHints hints);
213     void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem);
214
215     // Calls glVertexAttributePointer if the pointer has changed
216     inline void setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer);
217
218     // draws whatever is in the vertex array:
219     void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive);
220     void drawVertexArrays(QOpenGL2PEXVertexArray &vertexArray, GLenum primitive) {
221         drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive);
222     }
223
224     // Composites the bounding rect onto dest buffer:
225     void composite(const QOpenGLRect& boundingRect);
226
227     // Calls drawVertexArrays to render into stencil buffer:
228     void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QOpenGLRect &bounds, StencilFillMode mode);
229     void fillStencilWithVertexArray(QOpenGL2PEXVertexArray& vertexArray, bool useWindingFill) {
230         fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(),
231                                    vertexArray.boundingRect(),
232                                    useWindingFill ? WindingFillMode : OddEvenFillMode);
233     }
234
235     void setBrush(const QBrush& brush);
236     void transferMode(EngineMode newMode);
237     bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed
238     inline void useSimpleShader();
239     inline GLuint location(const QOpenGLEngineShaderManager::Uniform uniform) {
240         return shaderManager->getUniformLocation(uniform);
241     }
242
243     void clearClip(uint value);
244     void writeClip(const QVectorPath &path, uint value);
245     void resetClipIfNeeded();
246
247     void updateClipScissorTest();
248     void setScissor(const QRect &rect);
249     void regenerateClip();
250     void systemStateChanged();
251
252     void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
253     void syncGlState();
254
255     static QOpenGLEngineShaderManager* shaderManagerForEngine(QOpenGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; }
256     static QOpenGL2PaintEngineExPrivate *getData(QOpenGL2PaintEngineEx *engine) { return engine->d_func(); }
257     static void cleanupVectorPath(QPaintEngineEx *engine, void *data);
258
259     QOpenGLExtensions funcs;
260
261     QOpenGL2PaintEngineEx* q;
262     QOpenGLEngineShaderManager* shaderManager;
263     QOpenGLPaintDevice* device;
264     int width, height;
265     QOpenGLContext *ctx;
266     EngineMode mode;
267     QFontEngineGlyphCache::Type glyphCacheType;
268
269     bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
270
271     // Dirty flags
272     bool matrixDirty; // Implies matrix uniforms are also dirty
273     bool compositionModeDirty;
274     bool brushTextureDirty;
275     bool brushUniformsDirty;
276     bool opacityUniformDirty;
277     bool matrixUniformDirty;
278
279     bool stencilClean; // Has the stencil not been used for clipping so far?
280     bool useSystemClip;
281     QRegion dirtyStencilRegion;
282     QRect currentScissorBounds;
283     uint maxClip;
284
285     QBrush currentBrush; // May not be the state's brush!
286     const QBrush noBrush;
287
288     QPixmap currentBrushPixmap;
289
290     QOpenGL2PEXVertexArray vertexCoordinateArray;
291     QOpenGL2PEXVertexArray textureCoordinateArray;
292     QVector<GLushort> elementIndices;
293     GLuint elementIndicesVBOId;
294     QDataBuffer<GLfloat> opacityArray;
295     GLfloat staticVertexCoordinateArray[8];
296     GLfloat staticTextureCoordinateArray[8];
297
298     bool snapToPixelGrid;
299     bool nativePaintingActive;
300     GLfloat pmvMatrix[3][3];
301     GLfloat inverseScale;
302
303     GLuint lastTextureUsed;
304     GLuint lastMaskTextureUsed;
305
306     bool needsSync;
307     bool multisamplingAlwaysEnabled;
308
309     GLfloat depthRange[2];
310
311     float textureInvertedY;
312
313     QTriangulatingStroker stroker;
314     QDashedStrokeProcessor dasher;
315
316     QSet<QVectorPath::CacheEntry *> pathCaches;
317     QVector<GLuint> unusedVBOSToClean;
318     QVector<GLuint> unusedIBOSToClean;
319
320     const GLfloat *vertexAttribPointers[3];
321 };
322
323
324 void QOpenGL2PaintEngineExPrivate::setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer)
325 {
326     Q_ASSERT(arrayIndex < 3);
327     if (pointer == vertexAttribPointers[arrayIndex])
328         return;
329
330     vertexAttribPointers[arrayIndex] = pointer;
331     if (arrayIndex == QT_OPACITY_ATTR)
332         funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer);
333     else
334         funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer);
335 }
336
337 QT_END_NAMESPACE
338
339 #endif