1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCanvas3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40//
41// W A R N I N G
42// -------------
43//
44// This file is not part of the QtCanvas3D API. It exists purely as an
45// implementation detail. This header file may change from version to
46// version without notice, or even be removed.
47//
48// We mean it.
49
50#ifndef GLCOMMANDQUEUE_P_H
51#define GLCOMMANDQUEUE_P_H
52
53#include "canvas3dcommon_p.h"
54#include "canvastextureprovider_p.h"
55
56#include <QtCore/QVariantList>
57#include <QtCore/QMutex>
58#include <QtCore/QPointer>
59#include <QtGui/qopengl.h>
60#include <QtGui/QOpenGLShader>
61#include <QtGui/QOpenGLShaderProgram>
62#include <QtQuick/QQuickItem>
63#include <QtQuick/QSGTextureProvider>
64
65QT_BEGIN_NAMESPACE
66QT_CANVAS3D_BEGIN_NAMESPACE
67
68class GlCommand;
69
70class CanvasGlCommandQueue : public QObject
71{
72 Q_OBJECT
73 Q_DISABLE_COPY(CanvasGlCommandQueue)
74
75public:
76 Q_ENUMS(GlCommandId)
77
78 enum GlCommandId {
79 internalNoCommand = 0,
80 glActiveTexture,
81 glAttachShader,
82 glBindAttribLocation,
83 glBindBuffer,
84 glBindFramebuffer,
85 glBindRenderbuffer,
86 glBindTexture,
87 glBlendColor,
88 glBlendEquation,
89 glBlendEquationSeparate,
90 glBlendFunc,
91 glBlendFuncSeparate,
92 glBufferData,
93 glBufferSubData,
94 glCheckFramebufferStatus,
95 glClear,
96 glClearColor,
97 glClearDepthf,
98 glClearStencil,
99 glColorMask,
100 glCompileShader,
101 glCompressedTexImage2D,
102 glCompressedTexSubImage2D,
103 glCopyTexImage2D,
104 glCopyTexSubImage2D,
105 glCreateProgram,
106 glCreateShader,
107 glCullFace,
108 glDeleteBuffers,
109 glDeleteFramebuffers,
110 glDeleteProgram,
111 glDeleteRenderbuffers,
112 glDeleteShader,
113 glDeleteTextures,
114 glDepthFunc,
115 glDepthMask,
116 glDepthRangef,
117 glDetachShader,
118 glDisable,
119 glDisableVertexAttribArray,
120 glDrawArrays,
121 glDrawElements,
122 glEnable,
123 glEnableVertexAttribArray,
124 glFlush,
125 glFinish,
126 glFramebufferRenderbuffer,
127 glFramebufferTexture2D,
128 glFrontFace,
129 glGenBuffers,
130 glGenerateMipmap,
131 glGenFramebuffers,
132 glGenRenderbuffers,
133 glGenTextures,
134 glGetActiveAttrib,
135 glGetActiveUniform,
136 glGetAttribLocation,
137 glGetBooleanv,
138 glGetBufferParameteriv,
139 glGetError,
140 glGetFloatv,
141 glGetFramebufferAttachmentParameteriv,
142 glGetIntegerv,
143 glGetProgramInfoLog,
144 glGetProgramiv,
145 glGetRenderbufferParameteriv,
146 glGetShaderInfoLog,
147 glGetShaderiv,
148 glGetShaderPrecisionFormat,
149 glGetString,
150 glGetTexParameteriv,
151 glGetUniformfv,
152 glGetUniformiv,
153 glGetUniformLocation,
154 glGetVertexAttribPointerv,
155 glGetVertexAttribfv,
156 glGetVertexAttribiv,
157 glHint,
158 glIsBuffer,
159 glIsEnabled,
160 glIsFramebuffer,
161 glIsProgram,
162 glIsRenderbuffer,
163 glIsShader,
164 glIsTexture,
165 glLineWidth,
166 glLinkProgram,
167 glPixelStorei,
168 glPolygonOffset,
169 glReadPixels,
170 glRenderbufferStorage,
171 glSampleCoverage,
172 glScissor,
173 glStencilFunc,
174 glStencilFuncSeparate,
175 glStencilMask,
176 glStencilMaskSeparate,
177 glStencilOp,
178 glStencilOpSeparate,
179 glTexImage2D,
180 glTexParameterf,
181 glTexParameteri,
182 glTexSubImage2D,
183 glUniform1f,
184 glUniform2f,
185 glUniform3f,
186 glUniform4f,
187 glUniform1i,
188 glUniform2i,
189 glUniform3i,
190 glUniform4i,
191 glUniform1fv,
192 glUniform2fv,
193 glUniform3fv,
194 glUniform4fv,
195 glUniform1iv,
196 glUniform2iv,
197 glUniform3iv,
198 glUniform4iv,
199 glUniformMatrix2fv,
200 glUniformMatrix3fv,
201 glUniformMatrix4fv,
202 glUseProgram,
203 glValidateProgram,
204 glVertexAttrib1f,
205 glVertexAttrib2f,
206 glVertexAttrib3f,
207 glVertexAttrib4f,
208 glVertexAttrib1fv,
209 glVertexAttrib2fv,
210 glVertexAttrib3fv,
211 glVertexAttrib4fv,
212 glVertexAttribPointer,
213 glViewport,
214 internalGetUniformType,
215 internalClearLocation, // Used to clear a mapped uniform location from map when no longer needed
216 internalBeginPaint, // Indicates the beginning of the paintGL(). Needed when rendering to Qt context.
217 internalTextureComplete, // Indicates texture is complete and needs to be updated to screen at this point
218 internalClearQuickItemAsTexture, // Used to clear mapped quick item texture ids when no longer needed
219 extStateDump
220 };
221
222 class GlResource
223 {
224 public:
225 GlResource() : glId(0), commandId(internalNoCommand) {}
226 GlResource(GLuint id, GlCommandId command)
227 : glId(id), commandId(command) {}
228 GLuint glId;
229 GlCommandId commandId; // Command that allocated this resource
230
231 };
232
233 CanvasGlCommandQueue(int initialSize, int maxSize, QObject *parent = 0);
234 ~CanvasGlCommandQueue();
235
236 int queuedCount() const { return m_queuedCount; }
237
238 GlCommand &queueCommand(GlCommandId id);
239 GlCommand &queueCommand(GlCommandId id,
240 GLint p1, GLint p2 = 0, GLint p3 = 0, GLint p4 = 0,
241 GLint p5 = 0, GLint p6 = 0, GLint p7 = 0, GLint p8 = 0);
242 GlCommand &queueCommand(GlCommandId id,
243 GLfloat p1, GLfloat p2 = 0.0f, GLfloat p3 = 0.0f, GLfloat p4 = 0.0f);
244 GlCommand &queueCommand(GlCommandId id,
245 GLint i1, GLfloat p1, GLfloat p2 = 0.0f, GLfloat p3 = 0.0f,
246 GLfloat p4 = 0.0f);
247 GlCommand &queueCommand(GlCommandId id,
248 GLint i1, GLint i2, GLfloat p1, GLfloat p2 = 0.0f, GLfloat p3 = 0.0f,
249 GLfloat p4 = 0.0f);
250
251 void transferCommands(GlCommand executeQueue[]);
252 void resetQueue(int size);
253 void deleteUntransferedCommandData();
254
255 // Id map manipulation
256 GLint createResourceId();
257 void setGlIdToMap(GLint id, GLuint glId, GlCommandId commandId);
258 void removeResourceIdFromMap(GLint id);
259 GLuint getGlId(GLint id);
260 GLint getCanvasId(GLuint glId, GlCommandId type);
261
262 void setShaderToMap(GLint id, QOpenGLShader *shader);
263 void setProgramToMap(GLint id, QOpenGLShaderProgram *program);
264 QOpenGLShader *takeShaderFromMap(GLint id);
265 QOpenGLShaderProgram *takeProgramFromMap(GLint id);
266 QOpenGLShader *getShader(GLint id);
267 QOpenGLShaderProgram *getProgram(GLint id);
268
269 void clearResourceMaps();
270
271 GLuint takeSingleIdParam(const GlCommand &command);
272 void handleGenerateCommand(const GlCommand &command, GLuint glId);
273
274 QMutex *resourceMutex() { return &m_resourceMutex; }
275
276 void addQuickItemAsTexture(QQuickItem *quickItem, GLint textureId);
277 void clearQuickItemAsTextureList();
278
279 void removeFromClearMask(GLbitfield mask);
280 GLbitfield resetClearMask();
281
282 struct ProviderCacheItem {
283 ProviderCacheItem(QSGTextureProvider *provider, QQuickItem *item) :
284 providerPtr(provider),
285 quickItem(item) {}
286
287 QPointer<QSGTextureProvider> providerPtr;
288 QQuickItem *quickItem; // Not owned, nor accessed - only used as identifier
289 };
290 QMap<GLint, ProviderCacheItem *> &providerCache() { return m_providerCache; }
291
292signals:
293 void queueFull();
294
295private:
296 QVector<GlCommand> m_queue;
297 int m_maxSize;
298 int m_size;
299 int m_queuedCount;
300
301 QMap<GLint, GlResource> m_resourceIdMap;
302 QMap<GLint, QOpenGLShader *> m_shaderMap;
303 QMap<GLint, QOpenGLShaderProgram *> m_programMap;
304 GLint m_nextResourceId;
305 bool m_resourceIdOverflow;
306 QMutex m_resourceMutex;
307
308 struct ItemAndId {
309 ItemAndId(QQuickItem *item, GLint itemId) :
310 itemPtr(item),
311 id(itemId) {}
312
313 QPointer<QQuickItem> itemPtr;
314 GLint id;
315 };
316 QList<ItemAndId *> m_quickItemsAsTextureList;
317
318 QMap<GLint, ProviderCacheItem *> m_providerCache;
319 GLbitfield m_clearMask;
320};
321
322inline bool operator==(CanvasGlCommandQueue::GlResource lhs, CanvasGlCommandQueue::GlResource rhs) Q_DECL_NOTHROW
323{
324 return lhs.glId == rhs.glId && lhs.commandId == rhs.commandId;
325}
326inline bool operator!=(CanvasGlCommandQueue::GlResource lhs, CanvasGlCommandQueue::GlResource rhs) Q_DECL_NOTHROW
327{
328 return !operator==(lhs, rhs);
329}
330
331class GlCommand
332{
333public:
334 Q_DECL_CONSTEXPR GlCommand()
335 : data(0),
336 id(CanvasGlCommandQueue::internalNoCommand),
337 i1(0), i2(0), i3(0), i4(0), i5(0), i6(0), i7(0), i8(0)
338 {}
339 Q_DECL_CONSTEXPR GlCommand(CanvasGlCommandQueue::GlCommandId command)
340 : data(0),
341 id(command),
342 i1(0), i2(0), i3(0), i4(0), i5(0), i6(0), i7(0), i8(0)
343 {}
344 Q_DECL_CONSTEXPR GlCommand(CanvasGlCommandQueue::GlCommandId command,
345 GLint p1, GLint p2 = 0, GLint p3 = 0, GLint p4 = 0, GLint p5 = 0, GLint p6 = 0,
346 GLint p7 = 0, GLint p8 = 0)
347 : data(0),
348 id(command),
349 i1(p1), i2(p2), i3(p3), i4(p4), i5(p5), i6(p6), i7(p7), i8(p8)
350 {}
351 Q_DECL_CONSTEXPR GlCommand(CanvasGlCommandQueue::GlCommandId command,
352 GLfloat p1, GLfloat p2 = 0.0f, GLfloat p3 = 0.0f, GLfloat p4 = 0.0f)
353 : data(0),
354 id(command),
355 i1(0), i2(0), i3(0), i4(0),
356 f1(p1), f2(p2), f3(p3), f4(p4)
357 {}
358
359 void deleteData() {
360 delete data;
361 data = 0;
362 }
363
364 // Optional extra data such as buffer contents for commands that need it. The data is deleted
365 // after the command is handled. Not owned by command itself.
366 // Queue owns the data before it is transferred to execution, after which the CanvasRenderer
367 // owns it. In case of unqueued commands (i.e. synchronous commands), the data is owned by
368 // whoever owns the command object.
369 QByteArray *data;
370
371 CanvasGlCommandQueue::GlCommandId id;
372
373 GLint i1;
374 GLint i2;
375 GLint i3;
376 GLint i4;
377
378 // Commands that use both ints and floats are limited to four ints.
379 // In practice maximum of two ints are used by such commands.
380 union {
381 GLint i5;
382 GLfloat f1;
383 };
384 union {
385 GLint i6;
386 GLfloat f2;
387 };
388 union {
389 GLint i7;
390 GLfloat f3;
391 };
392 union {
393 GLint i8;
394 GLfloat f4;
395 };
396};
397
398class GlSyncCommand : public GlCommand
399{
400public:
401 GlSyncCommand()
402 : GlCommand(CanvasGlCommandQueue::internalNoCommand),
403 returnValue(0),
404 glError(false)
405 {}
406 GlSyncCommand(CanvasGlCommandQueue::GlCommandId command)
407 : GlCommand(command),
408 returnValue(0),
409 glError(false)
410 {}
411 GlSyncCommand(CanvasGlCommandQueue::GlCommandId command,
412 GLint p1, GLint p2 = 0, GLint p3 = 0, GLint p4 = 0, GLint p5 = 0, GLint p6 = 0,
413 GLint p7 = 0, GLint p8 = 0)
414 : GlCommand(command, p1, p2, p3, p4, p5, p6, p7, p8),
415 returnValue(0),
416 glError(false)
417 {}
418 GlSyncCommand(CanvasGlCommandQueue::GlCommandId command,
419 GLfloat p1, GLfloat p2 = 0.0f, GLfloat p3 = 0.0f, GLfloat p4 = 0.0f)
420 : GlCommand(command, p1, p2, p3, p4),
421 returnValue(0),
422 glError(false)
423 {}
424 ~GlSyncCommand() {}
425
426 // Optional return value for synchronous commands. Not owned.
427 void *returnValue;
428
429 // Indicates if an OpenGL error occurred during command execution.
430 bool glError;
431};
432
433QT_CANVAS3D_END_NAMESPACE
434QT_END_NAMESPACE
435
436#endif // GLCOMMANDQUEUE_P_H
437

source code of qtcanvas3d/src/imports/qtcanvas3d/glcommandqueue_p.h