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