Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qopenglpaintengine_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QOPENGLPAINTENGINE_P_H
6#define QOPENGLPAINTENGINE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <qopenglpaintdevice.h>
20
21#include <private/qpaintengineex_p.h>
22#include <private/qopenglengineshadermanager_p.h>
23#include <private/qopengl2pexvertexarray_p.h>
24#include <private/qfontengine_p.h>
25#include <private/qdatabuffer_p.h>
26#include <private/qtriangulatingstroker_p.h>
27
28#include <private/qopenglextensions_p.h>
29
30#include <QOpenGLVertexArrayObject>
31#include <QOpenGLBuffer>
32
33enum EngineMode {
34 ImageDrawingMode,
35 TextDrawingMode,
36 BrushDrawingMode,
37 ImageArrayDrawingMode,
38 ImageOpacityArrayDrawingMode
39};
40
41QT_BEGIN_NAMESPACE
42
43#define GL_STENCIL_HIGH_BIT GLuint(0x80)
44#define QT_UNKNOWN_TEXTURE_UNIT GLuint(-1)
45#define QT_DEFAULT_TEXTURE_UNIT GLuint(0)
46#define QT_BRUSH_TEXTURE_UNIT GLuint(0)
47#define QT_IMAGE_TEXTURE_UNIT GLuint(0) //Can be the same as brush texture unit
48#define QT_MASK_TEXTURE_UNIT GLuint(1)
49#define QT_BACKGROUND_TEXTURE_UNIT GLuint(2)
50
51class QOpenGL2PaintEngineExPrivate;
52
73
74class Q_OPENGL_EXPORT QOpenGL2PaintEngineEx : public QPaintEngineEx
75{
76 Q_DECLARE_PRIVATE(QOpenGL2PaintEngineEx)
77public:
78 QOpenGL2PaintEngineEx();
79 ~QOpenGL2PaintEngineEx();
80
81 bool begin(QPaintDevice *device) override;
82 void ensureActive();
83 bool end() override;
84
85 virtual void clipEnabledChanged() override;
86 virtual void penChanged() override;
87 virtual void brushChanged() override;
88 virtual void brushOriginChanged() override;
89 virtual void opacityChanged() override;
90 virtual void compositionModeChanged() override;
91 virtual void renderHintsChanged() override;
92 virtual void transformChanged() override;
93
94 virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override;
95 virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
96 QPainter::PixmapFragmentHints hints) override;
97 virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
98 Qt::ImageConversionFlags flags = Qt::AutoColor) override;
99 virtual void drawTextItem(const QPointF &p, const QTextItem &textItem) override;
100 virtual void fill(const QVectorPath &path, const QBrush &brush) override;
101 virtual void stroke(const QVectorPath &path, const QPen &pen) override;
102 virtual void clip(const QVectorPath &path, Qt::ClipOperation op) override;
103
104 virtual void drawStaticTextItem(QStaticTextItem *textItem) override;
105
106 bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
107
108 Type type() const override { return OpenGL2; }
109
110 virtual void setState(QPainterState *s) override;
111 virtual QPainterState *createState(QPainterState *orig) const override;
112 inline QOpenGL2PaintEngineState *state() {
113 return static_cast<QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
114 }
115 inline const QOpenGL2PaintEngineState *state() const {
116 return static_cast<const QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
117 }
118
119 void beginNativePainting() override;
120 void endNativePainting() override;
121
122 void invalidateState();
123
124 void setRenderTextActive(bool);
125
126 bool isNativePaintingActive() const;
127 bool requiresPretransformedGlyphPositions(QFontEngine *, const QTransform &) const override { return false; }
128 bool shouldDrawCachedGlyphs(QFontEngine *, const QTransform &) const override;
129
130private:
131 Q_DISABLE_COPY_MOVE(QOpenGL2PaintEngineEx)
132
133 friend class QOpenGLEngineShaderManager;
134};
135
136// This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's
137// all the GL2 engine uses:
138#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
139
141{
142 Q_DECLARE_PUBLIC(QOpenGL2PaintEngineEx)
143public:
149
167
169
170 void updateBrushTexture();
171 void updateBrushUniforms();
172 void updateMatrix();
174
176 template<typename T>
177 void updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode = UpdateIfNeeded);
178 template<typename T>
179 GLuint bindTexture(const T &texture, bool *newTextureCreated);
180 void activateTextureUnit(GLenum textureUnit);
181
182 void resetGLState();
183
184 // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points,
185 // however writeClip can also be thought of as en entry point as it does similar things.
186 void fill(const QVectorPath &path);
187 void stroke(const QVectorPath &path, const QPen &pen);
188 void drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false);
189 void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
190 QPainter::PixmapFragmentHints hints);
191 void drawCachedGlyphs(QFontEngine::GlyphFormat glyphFormat, QStaticTextItem *staticTextItem);
192
193 // Calls glVertexAttributePointer if the pointer has changed
194 inline void uploadData(unsigned int arrayIndex, const GLfloat *data, GLuint count);
195 inline bool uploadIndexData(const void *data, GLenum indexValueType, GLuint count);
196
197 // draws whatever is in the vertex array:
198 void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive);
199 void drawVertexArrays(QOpenGL2PEXVertexArray &vertexArray, GLenum primitive) {
200 drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive);
201 }
202
203 // Composites the bounding rect onto dest buffer:
204 void composite(const QOpenGLRect& boundingRect);
205
206 // Calls drawVertexArrays to render into stencil buffer:
207 void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QOpenGLRect &bounds, StencilFillMode mode);
208 void fillStencilWithVertexArray(QOpenGL2PEXVertexArray& vertexArray, bool useWindingFill) {
209 fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(),
210 vertexArray.boundingRect(),
211 useWindingFill ? WindingFillMode : OddEvenFillMode);
212 }
213
214 void setBrush(const QBrush& brush);
215 void transferMode(EngineMode newMode);
216 bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed
217 bool prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache);
218 inline void useSimpleShader();
219 inline GLuint location(const QOpenGLEngineShaderManager::Uniform uniform) {
220 return shaderManager->getUniformLocation(uniform);
221 }
222
223 void clearClip(uint value);
224 void writeClip(const QVectorPath &path, uint value);
225 void resetClipIfNeeded();
226
228 void setScissor(const QRect &rect);
229 void regenerateClip();
231
232 void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
233 void syncGlState();
234
235 static QOpenGLEngineShaderManager* shaderManagerForEngine(QOpenGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; }
236 static QOpenGL2PaintEngineExPrivate *getData(QOpenGL2PaintEngineEx *engine) { return engine->d_func(); }
237 static void cleanupVectorPath(QPaintEngineEx *engine, void *data);
238
240
246 EngineMode mode;
248
250
251 // Dirty flags
252 bool matrixDirty; // Implies matrix uniforms are also dirty
258
259 bool stencilClean; // Has the stencil not been used for clipping so far?
264
265 QBrush currentBrush; // May not be the state's brush!
267
269
277
282
285
291
294
297
300
302};
303
304
305void QOpenGL2PaintEngineExPrivate::uploadData(unsigned int arrayIndex, const GLfloat *data, GLuint count)
306{
307 Q_ASSERT(arrayIndex < 3);
308
309 if (arrayIndex == QT_VERTEX_COORDS_ATTR) {
310 vertexBuffer.bind();
311 vertexBuffer.allocate(data, count * sizeof(float));
312 }
313 if (arrayIndex == QT_TEXTURE_COORDS_ATTR) {
314 texCoordBuffer.bind();
315 texCoordBuffer.allocate(data, count * sizeof(float));
316 }
317 if (arrayIndex == QT_OPACITY_ATTR) {
318 opacityBuffer.bind();
319 opacityBuffer.allocate(data, count * sizeof(float));
320
321 funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
322 } else {
323 funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
324 }
325}
326
327bool QOpenGL2PaintEngineExPrivate::uploadIndexData(const void *data, GLenum indexValueType, GLuint count)
328{
329 Q_ASSERT(indexValueType == GL_UNSIGNED_SHORT || indexValueType == GL_UNSIGNED_INT);
330 indexBuffer.bind();
331 indexBuffer.allocate(
332 data,
333 count * (indexValueType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)));
334 return true;
335}
336
337QT_END_NAMESPACE
338
339#endif
QOpenGLEngineShaderManager * shaderManager
void drawVertexArrays(QOpenGL2PEXVertexArray &vertexArray, GLenum primitive)
bool uploadIndexData(const void *data, GLenum indexValueType, GLuint count)
static void cleanupVectorPath(QPaintEngineEx *engine, void *data)
void writeClip(const QVectorPath &path, uint value)
void updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode=UpdateIfNeeded)
QOpenGL2PaintEngineExPrivate(QOpenGL2PaintEngineEx *q_ptr)
QOpenGL2PEXVertexArray vertexCoordinateArray
QFontEngine::GlyphFormat glyphCacheFormat
QVarLengthArray< GLuint, 8 > unusedVBOSToClean
void transferMode(EngineMode newMode)
void composite(const QOpenGLRect &boundingRect)
GLuint bindTexture(const T &texture, bool *newTextureCreated)
bool prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache)
void stroke(const QVectorPath &path, const QPen &pen)
QOpenGL2PEXVertexArray textureCoordinateArray
void drawTexture(const QOpenGLRect &dest, const QOpenGLRect &src, const QSize &textureSize, bool opaque, bool pattern=false)
void activateTextureUnit(GLenum textureUnit)
static QOpenGLEngineShaderManager * shaderManagerForEngine(QOpenGL2PaintEngineEx *engine)
void setVertexAttribArrayEnabled(int arrayIndex, bool enabled=true)
void uploadData(unsigned int arrayIndex, const GLfloat *data, GLuint count)
void fill(const QVectorPath &path)
void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::PixmapFragmentHints hints)
bool prepareForDraw(bool srcPixelsAreOpaque)
void drawCachedGlyphs(QFontEngine::GlyphFormat glyphFormat, QStaticTextItem *staticTextItem)
void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QOpenGLRect &bounds, StencilFillMode mode)
void setBrush(const QBrush &brush)
void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive)
void fillStencilWithVertexArray(QOpenGL2PEXVertexArray &vertexArray, bool useWindingFill)
void setScissor(const QRect &rect)
bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT]
QDataBuffer< GLfloat > opacityArray
QPointer< QOpenGLContext > ctx
GLuint location(const QOpenGLEngineShaderManager::Uniform uniform)
static QOpenGL2PaintEngineExPrivate * getData(QOpenGL2PaintEngineEx *engine)
QVarLengthArray< GLuint, 8 > unusedIBOSToClean
QOpenGL2PaintEngineState(const QOpenGL2PaintEngineState &other)
QPointer< QOpenGLEngineShaderManager > m_manager
virtual void setUniforms(QOpenGLShaderProgram *)
bool operator==(const QOpenGLEngineShaderProg &other) const
friend class QPainter
Combined button and popup list for selecting options.
static const GLuint QT_TEXTURE_COORDS_ATTR
static const GLuint QT_PMV_MATRIX_2_ATTR
static const GLuint QT_OPACITY_ATTR
static const GLuint QT_PMV_MATRIX_1_ATTR
static QT_BEGIN_NAMESPACE const GLuint QT_VERTEX_COORDS_ATTR
static const GLuint QT_PMV_MATRIX_3_ATTR
#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT
#define QT_UNKNOWN_TEXTURE_UNIT