Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quickshapes/qquicknvprfunctions.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||
---|---|---|---|---|---|---|---|---|
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 QtQuick 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 | #include "qquicknvprfunctions_p.h" | - | ||||||
41 | - | |||||||
42 | #if QT_CONFIG(opengl) | - | ||||||
43 | - | |||||||
44 | #include <QOpenGLContext> | - | ||||||
45 | #include <QOffscreenSurface> | - | ||||||
46 | #include <QOpenGLExtraFunctions> | - | ||||||
47 | #include "qquicknvprfunctions_p_p.h" | - | ||||||
48 | - | |||||||
49 | QT_BEGIN_NAMESPACE | - | ||||||
50 | - | |||||||
51 | /*! | - | ||||||
52 | \class QQuickNvprFunctions | - | ||||||
53 | - | |||||||
54 | \brief Function resolvers and other helpers for GL_NV_path_rendering | - | ||||||
55 | for both desktop (GL 4.3+) and mobile/embedded (GLES 3.1+) in a manner | - | ||||||
56 | that does not distract builds that do not have NVPR support either at | - | ||||||
57 | compile or run time. | - | ||||||
58 | - | |||||||
59 | \internal | - | ||||||
60 | */ | - | ||||||
61 | - | |||||||
62 | QQuickNvprFunctions::QQuickNvprFunctions() | - | ||||||
63 | : d(new QQuickNvprFunctionsPrivate(this)) | - | ||||||
64 | { | - | ||||||
65 | } executed 6 times by 3 tests: end of block Executed by:
| 6 | ||||||
66 | - | |||||||
67 | QQuickNvprFunctions::~QQuickNvprFunctions() | - | ||||||
68 | { | - | ||||||
69 | delete d; | - | ||||||
70 | } executed 6 times by 3 tests: end of block Executed by:
| 6 | ||||||
71 | - | |||||||
72 | /*! | - | ||||||
73 | \return a recommended QSurfaceFormat suitable for GL_NV_path_rendering on top | - | ||||||
74 | of OpenGL 4.3 or OpenGL ES 3.1. | - | ||||||
75 | */ | - | ||||||
76 | QSurfaceFormat QQuickNvprFunctions::format() | - | ||||||
77 | { | - | ||||||
78 | QSurfaceFormat fmt; | - | ||||||
79 | fmt.setDepthBufferSize(24); | - | ||||||
80 | fmt.setStencilBufferSize(8); | - | ||||||
81 | if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
| 0 | ||||||
82 | fmt.setVersion(4, 3); | - | ||||||
83 | fmt.setProfile(QSurfaceFormat::CompatibilityProfile); | - | ||||||
84 | } else if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { never executed: end of block
| 0 | ||||||
85 | fmt.setVersion(3, 1); | - | ||||||
86 | } never executed: end of block | 0 | ||||||
87 | return fmt; never executed: return fmt; | 0 | ||||||
88 | } | - | ||||||
89 | - | |||||||
90 | #define PROC(type, name) reinterpret_cast<type>(ctx->getProcAddress(#name)) | - | ||||||
91 | - | |||||||
92 | /*! | - | ||||||
93 | \return true if GL_NV_path_rendering is supported with the current OpenGL | - | ||||||
94 | context. | - | ||||||
95 | - | |||||||
96 | When there is no current context, a temporary dummy one will be created and | - | ||||||
97 | made current. | - | ||||||
98 | */ | - | ||||||
99 | bool QQuickNvprFunctions::isSupported() | - | ||||||
100 | { | - | ||||||
101 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||
102 | QScopedPointer<QOpenGLContext> tempContext; | - | ||||||
103 | QScopedPointer<QOffscreenSurface> tempSurface; | - | ||||||
104 | if (!ctx) {
| 0-166 | ||||||
105 | tempContext.reset(new QOpenGLContext); | - | ||||||
106 | if (!tempContext->create())
| 0 | ||||||
107 | return false; never executed: return false; | 0 | ||||||
108 | ctx = tempContext.data(); | - | ||||||
109 | tempSurface.reset(new QOffscreenSurface); | - | ||||||
110 | tempSurface->setFormat(ctx->format()); | - | ||||||
111 | tempSurface->create(); | - | ||||||
112 | if (!ctx->makeCurrent(tempSurface.data()))
| 0 | ||||||
113 | return false; never executed: return false; | 0 | ||||||
114 | } never executed: end of block | 0 | ||||||
115 | - | |||||||
116 | if (!ctx->hasExtension(QByteArrayLiteral("GL_NV_path_rendering"))) executed 166 times by 1 test: return ba; Executed by:
| 0-166 | ||||||
117 | return false; executed 166 times by 1 test: return false; Executed by:
| 166 | ||||||
118 | - | |||||||
119 | // Check that GL_NV_Path_rendering extension is at least API revision 1.3 | - | ||||||
120 | if (!PROC(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glProgramPathFragmentInputGenNV))
| 0 | ||||||
121 | return false; never executed: return false; | 0 | ||||||
122 | - | |||||||
123 | // Do not check for DSA as the string may not be exposed on ES | - | ||||||
124 | // drivers, yet the functions we need are resolvable. | - | ||||||
125 | #if 0 | - | ||||||
126 | if (!ctx->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) { | - | ||||||
127 | qWarning("QtQuickPath/NVPR: GL_EXT_direct_state_access not supported"); | - | ||||||
128 | return false; | - | ||||||
129 | } | - | ||||||
130 | #endif | - | ||||||
131 | - | |||||||
132 | return true; never executed: return true; | 0 | ||||||
133 | } | - | ||||||
134 | - | |||||||
135 | /*! | - | ||||||
136 | Initializes using the current OpenGL context. | - | ||||||
137 | - | |||||||
138 | \return true when GL_NV_path_rendering is supported and initialization was | - | ||||||
139 | successful. | - | ||||||
140 | */ | - | ||||||
141 | bool QQuickNvprFunctions::create() | - | ||||||
142 | { | - | ||||||
143 | return isSupported() && d->resolve(); never executed: return isSupported() && d->resolve(); | 0 | ||||||
144 | } | - | ||||||
145 | - | |||||||
146 | /*! | - | ||||||
147 | Creates a program pipeline consisting of a separable fragment shader program. | - | ||||||
148 | - | |||||||
149 | This is essential for using NVPR with OpenGL ES 3.1+ since normal, | - | ||||||
150 | GLES2-style programs would not work without a vertex shader. | - | ||||||
151 | - | |||||||
152 | \note \a fragmentShaderSource should be a \c{version 310 es} shader since | - | ||||||
153 | this works both on desktop and embedded NVIDIA drivers, thus avoiding the | - | ||||||
154 | need to fight GLSL and GLSL ES differences. | - | ||||||
155 | - | |||||||
156 | The pipeline object is stored into \a pipeline, the fragment shader program | - | ||||||
157 | into \a program. | - | ||||||
158 | - | |||||||
159 | Use QOpenGLExtraFunctions to set uniforms, bind the pipeline, etc. | - | ||||||
160 | - | |||||||
161 | \return \c false on failure in which case the error log is printed on the | - | ||||||
162 | debug output. \c true on success. | - | ||||||
163 | */ | - | ||||||
164 | bool QQuickNvprFunctions::createFragmentOnlyPipeline(const char *fragmentShaderSource, GLuint *pipeline, GLuint *program) | - | ||||||
165 | { | - | ||||||
166 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||
167 | if (!ctx)
| 0 | ||||||
168 | return false; never executed: return false; | 0 | ||||||
169 | - | |||||||
170 | QOpenGLExtraFunctions *f = ctx->extraFunctions(); | - | ||||||
171 | *program = f->glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentShaderSource); | - | ||||||
172 | GLint status = 0; | - | ||||||
173 | f->glGetProgramiv(*program, GL_LINK_STATUS, &status); | - | ||||||
174 | if (!status) {
| 0 | ||||||
175 | GLint len = 0; | - | ||||||
176 | f->glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &len); | - | ||||||
177 | if (len) {
| 0 | ||||||
178 | QByteArray s; | - | ||||||
179 | s.resize(len); | - | ||||||
180 | f->glGetProgramInfoLog(*program, s.count(), nullptr, s.data()); | - | ||||||
181 | qWarning("Failed to create separable shader program:\n%s", s.constData()); | - | ||||||
182 | } never executed: end of block | 0 | ||||||
183 | return false; never executed: return false; | 0 | ||||||
184 | } | - | ||||||
185 | - | |||||||
186 | f->glGenProgramPipelines(1, pipeline); | - | ||||||
187 | f->glUseProgramStages(*pipeline, GL_FRAGMENT_SHADER_BIT, *program); | - | ||||||
188 | f->glActiveShaderProgram(*pipeline, *program); | - | ||||||
189 | - | |||||||
190 | f->glValidateProgramPipeline(*pipeline); | - | ||||||
191 | status = 0; | - | ||||||
192 | f->glGetProgramPipelineiv(*pipeline, GL_VALIDATE_STATUS, &status); | - | ||||||
193 | if (!status) {
| 0 | ||||||
194 | GLint len = 0; | - | ||||||
195 | f->glGetProgramPipelineiv(*pipeline, GL_INFO_LOG_LENGTH, &len); | - | ||||||
196 | if (len) {
| 0 | ||||||
197 | QByteArray s; | - | ||||||
198 | s.resize(len); | - | ||||||
199 | f->glGetProgramPipelineInfoLog(*pipeline, s.count(), nullptr, s.data()); | - | ||||||
200 | qWarning("Program pipeline validation failed:\n%s", s.constData()); | - | ||||||
201 | } never executed: end of block | 0 | ||||||
202 | return false; never executed: return false; | 0 | ||||||
203 | } | - | ||||||
204 | - | |||||||
205 | return true; never executed: return true; | 0 | ||||||
206 | } | - | ||||||
207 | - | |||||||
208 | bool QQuickNvprFunctionsPrivate::resolve() | - | ||||||
209 | { | - | ||||||
210 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); | - | ||||||
211 | - | |||||||
212 | q->genPaths = PROC(PFNGLGENPATHSNVPROC, glGenPathsNV); | - | ||||||
213 | q->deletePaths = PROC(PFNGLDELETEPATHSNVPROC, glDeletePathsNV); | - | ||||||
214 | q->isPath = PROC(PFNGLISPATHNVPROC, glIsPathNV); | - | ||||||
215 | q->pathCommands = PROC(PFNGLPATHCOMMANDSNVPROC, glPathCommandsNV); | - | ||||||
216 | q->pathCoords = PROC(PFNGLPATHCOORDSNVPROC, glPathCoordsNV); | - | ||||||
217 | q->pathSubCommands = PROC(PFNGLPATHSUBCOMMANDSNVPROC, glPathSubCommandsNV); | - | ||||||
218 | q->pathSubCoords = PROC(PFNGLPATHSUBCOORDSNVPROC, glPathSubCoordsNV); | - | ||||||
219 | q->pathString = PROC(PFNGLPATHSTRINGNVPROC, glPathStringNV); | - | ||||||
220 | q->pathGlyphs = PROC(PFNGLPATHGLYPHSNVPROC, glPathGlyphsNV); | - | ||||||
221 | q->pathGlyphRange = PROC(PFNGLPATHGLYPHRANGENVPROC, glPathGlyphRangeNV); | - | ||||||
222 | q->weightPaths = PROC(PFNGLWEIGHTPATHSNVPROC, glWeightPathsNV); | - | ||||||
223 | q->copyPath = PROC(PFNGLCOPYPATHNVPROC, glCopyPathNV); | - | ||||||
224 | q->interpolatePaths = PROC(PFNGLINTERPOLATEPATHSNVPROC, glInterpolatePathsNV); | - | ||||||
225 | q->transformPath = PROC(PFNGLTRANSFORMPATHNVPROC, glTransformPathNV); | - | ||||||
226 | q->pathParameteriv = PROC(PFNGLPATHPARAMETERIVNVPROC, glPathParameterivNV); | - | ||||||
227 | q->pathParameteri = PROC(PFNGLPATHPARAMETERINVPROC, glPathParameteriNV); | - | ||||||
228 | q->pathParameterfv = PROC(PFNGLPATHPARAMETERFVNVPROC, glPathParameterfvNV); | - | ||||||
229 | q->pathParameterf = PROC(PFNGLPATHPARAMETERFNVPROC, glPathParameterfNV); | - | ||||||
230 | q->pathDashArray = PROC(PFNGLPATHDASHARRAYNVPROC, glPathDashArrayNV); | - | ||||||
231 | q->pathStencilFunc = PROC(PFNGLPATHSTENCILFUNCNVPROC, glPathStencilFuncNV); | - | ||||||
232 | q->pathStencilDepthOffset = PROC(PFNGLPATHSTENCILDEPTHOFFSETNVPROC, glPathStencilDepthOffsetNV); | - | ||||||
233 | q->stencilFillPath = PROC(PFNGLSTENCILFILLPATHNVPROC, glStencilFillPathNV); | - | ||||||
234 | q->stencilStrokePath = PROC(PFNGLSTENCILSTROKEPATHNVPROC, glStencilStrokePathNV); | - | ||||||
235 | q->stencilFillPathInstanced = PROC(PFNGLSTENCILFILLPATHINSTANCEDNVPROC, glStencilFillPathInstancedNV); | - | ||||||
236 | q->stencilStrokePathInstanced = PROC(PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC, glStencilStrokePathInstancedNV); | - | ||||||
237 | q->pathCoverDepthFunc = PROC(PFNGLPATHCOVERDEPTHFUNCNVPROC, glPathCoverDepthFuncNV); | - | ||||||
238 | q->coverFillPath = PROC(PFNGLCOVERFILLPATHNVPROC, glCoverFillPathNV); | - | ||||||
239 | q->coverStrokePath = PROC(PFNGLCOVERSTROKEPATHNVPROC, glCoverStrokePathNV); | - | ||||||
240 | q->coverFillPathInstanced = PROC(PFNGLCOVERFILLPATHINSTANCEDNVPROC, glCoverFillPathInstancedNV); | - | ||||||
241 | q->coverStrokePathInstanced = PROC(PFNGLCOVERSTROKEPATHINSTANCEDNVPROC, glCoverStrokePathInstancedNV); | - | ||||||
242 | q->getPathParameteriv = PROC(PFNGLGETPATHPARAMETERIVNVPROC, glGetPathParameterivNV); | - | ||||||
243 | q->getPathParameterfv = PROC(PFNGLGETPATHPARAMETERFVNVPROC, glGetPathParameterfvNV); | - | ||||||
244 | q->getPathCommands = PROC(PFNGLGETPATHCOMMANDSNVPROC, glGetPathCommandsNV); | - | ||||||
245 | q->getPathCoords = PROC(PFNGLGETPATHCOORDSNVPROC, glGetPathCoordsNV); | - | ||||||
246 | q->getPathDashArray = PROC(PFNGLGETPATHDASHARRAYNVPROC, glGetPathDashArrayNV); | - | ||||||
247 | q->getPathMetrics = PROC(PFNGLGETPATHMETRICSNVPROC, glGetPathMetricsNV); | - | ||||||
248 | q->getPathMetricRange = PROC(PFNGLGETPATHMETRICRANGENVPROC, glGetPathMetricRangeNV); | - | ||||||
249 | q->getPathSpacing = PROC(PFNGLGETPATHSPACINGNVPROC, glGetPathSpacingNV); | - | ||||||
250 | q->isPointInFillPath = PROC(PFNGLISPOINTINFILLPATHNVPROC, glIsPointInFillPathNV); | - | ||||||
251 | q->isPointInStrokePath = PROC(PFNGLISPOINTINSTROKEPATHNVPROC, glIsPointInStrokePathNV); | - | ||||||
252 | q->getPathLength = PROC(PFNGLGETPATHLENGTHNVPROC, glGetPathLengthNV); | - | ||||||
253 | q->getPointAlongPath = PROC(PFNGLPOINTALONGPATHNVPROC, glPointAlongPathNV); | - | ||||||
254 | q->matrixLoad3x2f = PROC(PFNGLMATRIXLOAD3X2FNVPROC, glMatrixLoad3x2fNV); | - | ||||||
255 | q->matrixLoad3x3f = PROC(PFNGLMATRIXLOAD3X3FNVPROC, glMatrixLoad3x3fNV); | - | ||||||
256 | q->matrixLoadTranspose3x3f = PROC(PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC, glMatrixLoadTranspose3x3fNV); | - | ||||||
257 | q->matrixMult3x2f = PROC(PFNGLMATRIXMULT3X2FNVPROC, glMatrixMult3x2fNV); | - | ||||||
258 | q->matrixMult3x3f = PROC(PFNGLMATRIXMULT3X3FNVPROC, glMatrixMult3x3fNV); | - | ||||||
259 | q->matrixMultTranspose3x3f = PROC(PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC, glMatrixMultTranspose3x3fNV); | - | ||||||
260 | q->stencilThenCoverFillPath = PROC(PFNGLSTENCILTHENCOVERFILLPATHNVPROC, glStencilThenCoverFillPathNV); | - | ||||||
261 | q->stencilThenCoverStrokePath = PROC(PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC, glStencilThenCoverStrokePathNV); | - | ||||||
262 | q->stencilThenCoverFillPathInstanced = PROC(PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC, glStencilThenCoverFillPathInstancedNV); | - | ||||||
263 | q->stencilThenCoverStrokePathInstanced = PROC(PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC, glStencilThenCoverStrokePathInstancedNV); | - | ||||||
264 | q->pathGlyphIndexRange = PROC(PFNGLPATHGLYPHINDEXRANGENVPROC, glPathGlyphIndexRangeNV); | - | ||||||
265 | q->pathGlyphIndexArray = PROC(PFNGLPATHGLYPHINDEXARRAYNVPROC, glPathGlyphIndexArrayNV); | - | ||||||
266 | q->pathMemoryGlyphIndexArray = PROC(PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC, glPathMemoryGlyphIndexArrayNV); | - | ||||||
267 | q->programPathFragmentInputGen = PROC(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glProgramPathFragmentInputGenNV); | - | ||||||
268 | q->getProgramResourcefv = PROC(PFNGLGETPROGRAMRESOURCEFVNVPROC, glGetProgramResourcefvNV); | - | ||||||
269 | - | |||||||
270 | q->matrixLoadf = PROC(PFNGLMATRIXLOADFEXTPROC, glMatrixLoadfEXT); | - | ||||||
271 | q->matrixLoadIdentity = PROC(PFNGLMATRIXLOADIDENTITYEXTPROC, glMatrixLoadIdentityEXT); | - | ||||||
272 | - | |||||||
273 | return q->genPaths != nullptr // base path rendering ext never executed: return q->genPaths != nullptr && q->programPathFragmentInputGen != nullptr && q->matrixLoadf != nullptr && q->matrixLoadIdentity != nullptr; | 0 | ||||||
274 | && q->programPathFragmentInputGen != nullptr // updated path rendering ext never executed: return q->genPaths != nullptr && q->programPathFragmentInputGen != nullptr && q->matrixLoadf != nullptr && q->matrixLoadIdentity != nullptr; | 0 | ||||||
275 | && q->matrixLoadf != nullptr // direct state access ext never executed: return q->genPaths != nullptr && q->programPathFragmentInputGen != nullptr && q->matrixLoadf != nullptr && q->matrixLoadIdentity != nullptr; | 0 | ||||||
276 | && q->matrixLoadIdentity != nullptr; never executed: return q->genPaths != nullptr && q->programPathFragmentInputGen != nullptr && q->matrixLoadf != nullptr && q->matrixLoadIdentity != nullptr; | 0 | ||||||
277 | } | - | ||||||
278 | - | |||||||
279 | QT_END_NAMESPACE | - | ||||||
280 | - | |||||||
281 | #endif // QT_CONFIG(opengl) | - | ||||||
Source code | Switch to Preprocessed file |