OpenCoverage

qopengltextureblitter.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/opengl/qopengltextureblitter.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4-
5-
6-
7-
8-
9static const char vertex_shader150[] =-
10 "#version 150 core\n"-
11 "in vec3 vertexCoord;"-
12 "in vec2 textureCoord;"-
13 "out vec2 uv;"-
14 "uniform mat4 vertexTransform;"-
15 "uniform mat3 textureTransform;"-
16 "void main() {"-
17 " uv = (textureTransform * vec3(textureCoord,1.0)).xy;"-
18 " gl_Position = vertexTransform * vec4(vertexCoord,1.0);"-
19 "}";-
20-
21static const char fragment_shader150[] =-
22 "#version 150 core\n"-
23 "in vec2 uv;"-
24 "out vec4 fragcolor;"-
25 "uniform sampler2D textureSampler;"-
26 "uniform bool swizzle;"-
27 "uniform float opacity;"-
28 "void main() {"-
29 " vec4 tmpFragColor = texture(textureSampler, uv);"-
30 " tmpFragColor.a *= opacity;"-
31 " fragcolor = swizzle ? tmpFragColor.bgra : tmpFragColor;"-
32 "}";-
33-
34static const char vertex_shader[] =-
35 "attribute highp vec3 vertexCoord;"-
36 "attribute highp vec2 textureCoord;"-
37 "varying highp vec2 uv;"-
38 "uniform highp mat4 vertexTransform;"-
39 "uniform highp mat3 textureTransform;"-
40 "void main() {"-
41 " uv = (textureTransform * vec3(textureCoord,1.0)).xy;"-
42 " gl_Position = vertexTransform * vec4(vertexCoord,1.0);"-
43 "}";-
44-
45static const char fragment_shader[] =-
46 "varying highp vec2 uv;"-
47 "uniform sampler2D textureSampler;"-
48 "uniform bool swizzle;"-
49 "uniform highp float opacity;"-
50 "void main() {"-
51 " highp vec4 tmpFragColor = texture2D(textureSampler,uv);"-
52 " tmpFragColor.a *= opacity;"-
53 " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"-
54 "}";-
55-
56static const char fragment_shader_external_oes[] =-
57 "#extension GL_OES_EGL_image_external : require\n"-
58 "varying highp vec2 uv;"-
59 "uniform samplerExternalOES textureSampler;\n"-
60 "uniform bool swizzle;"-
61 "uniform highp float opacity;"-
62 "void main() {"-
63 " highp vec4 tmpFragColor = texture2D(textureSampler, uv);"-
64 " tmpFragColor.a *= opacity;"-
65 " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"-
66 "}";-
67-
68static const GLfloat vertex_buffer_data[] = {-
69 -1,-1, 0,-
70 -1, 1, 0,-
71 1,-1, 0,-
72 -1, 1, 0,-
73 1,-1, 0,-
74 1, 1, 0-
75};-
76-
77static const GLfloat texture_buffer_data[] = {-
78 0, 0,-
79 0, 1,-
80 1, 0,-
81 0, 1,-
82 1, 0,-
83 1, 1-
84};-
85-
86class TextureBinder-
87{-
88public:-
89 TextureBinder(GLenum target, GLuint textureId) : m_target(target)-
90 {-
91 QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, textureId);-
92 }
never executed: end of block
0
93 ~TextureBinder()-
94 {-
95 QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, 0);-
96 }
never executed: end of block
0
97-
98private:-
99 GLenum m_target;-
100};-
101-
102class QOpenGLTextureBlitterPrivate-
103{-
104public:-
105 enum TextureMatrixUniform {-
106 User,-
107 Identity,-
108 IdentityFlipped-
109 };-
110-
111 enum ProgramIndex {-
112 TEXTURE_2D,-
113 TEXTURE_EXTERNAL_OES-
114 };-
115-
116 QOpenGLTextureBlitterPrivate() :-
117 swizzle(false),-
118 opacity(1.0f),-
119 vao(new QOpenGLVertexArrayObject),-
120 currentTarget(TEXTURE_2D)-
121 { }
never executed: end of block
0
122-
123 bool buildProgram(ProgramIndex idx, const char *vs, const char *fs);-
124-
125 void blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform);-
126 void blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin);-
127-
128 void prepareProgram(const QMatrix4x4 &vertexTransform);-
129-
130 QOpenGLBuffer vertexBuffer;-
131 QOpenGLBuffer textureBuffer;-
132 struct Program {-
133 Program() :-
134 vertexCoordAttribPos(0),-
135 vertexTransformUniformPos(0),-
136 textureCoordAttribPos(0),-
137 textureTransformUniformPos(0),-
138 swizzleUniformPos(0),-
139 opacityUniformPos(0),-
140 swizzle(false),-
141 opacity(0.0f),-
142 textureMatrixUniformState(User)-
143 { }
never executed: end of block
0
144 QScopedPointer<QOpenGLShaderProgram> glProgram;-
145 GLuint vertexCoordAttribPos;-
146 GLuint vertexTransformUniformPos;-
147 GLuint textureCoordAttribPos;-
148 GLuint textureTransformUniformPos;-
149 GLuint swizzleUniformPos;-
150 GLuint opacityUniformPos;-
151 bool swizzle;-
152 float opacity;-
153 TextureMatrixUniform textureMatrixUniformState;-
154 } programs[2];-
155 bool swizzle;-
156 float opacity;-
157 QScopedPointer<QOpenGLVertexArrayObject> vao;-
158 GLenum currentTarget;-
159};-
160-
161static inline QOpenGLTextureBlitterPrivate::ProgramIndex targetToProgramIndex(GLenum target)-
162{-
163 switch (target) {-
164 case
never executed: case 0x0DE1:
0x0DE1:
never executed: case 0x0DE1:
0
165 return
never executed: return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
QOpenGLTextureBlitterPrivate::TEXTURE_2D;
never executed: return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
0
166 case
never executed: case 0x8D65:
0x8D65:
never executed: case 0x8D65:
0
167 return
never executed: return QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES;
QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES;
never executed: return QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES;
0
168 default
never executed: default:
:
never executed: default:
0
169 QMessageLogger(__FILE__, 214, __PRETTY_FUNCTION__).warning("Unsupported texture target 0x%x", target);-
170 return
never executed: return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
QOpenGLTextureBlitterPrivate::TEXTURE_2D;
never executed: return QOpenGLTextureBlitterPrivate::TEXTURE_2D;
0
171 }-
172}-
173-
174void QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransform)-
175{-
176 Program *program = &programs[targetToProgramIndex(currentTarget)];-
177-
178 vertexBuffer.bind();-
179 program->glProgram->setAttributeBuffer(program->vertexCoordAttribPos, 0x1406, 0, 3, 0);-
180 program->glProgram->enableAttributeArray(program->vertexCoordAttribPos);-
181 vertexBuffer.release();-
182-
183 program->glProgram->setUniformValue(program->vertexTransformUniformPos, vertexTransform);-
184-
185 textureBuffer.bind();-
186 program->glProgram->setAttributeBuffer(program->textureCoordAttribPos, 0x1406, 0, 2, 0);-
187 program->glProgram->enableAttributeArray(program->textureCoordAttribPos);-
188 textureBuffer.release();-
189-
190 if (swizzle != program->swizzle
swizzle != program->swizzleDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
191 program->glProgram->setUniformValue(program->swizzleUniformPos, swizzle);-
192 program->swizzle = swizzle;-
193 }
never executed: end of block
0
194-
195 if (opacity != program->opacity
opacity != program->opacityDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
196 program->glProgram->setUniformValue(program->opacityUniformPos, opacity);-
197 program->opacity = opacity;-
198 }
never executed: end of block
0
199}
never executed: end of block
0
200-
201void QOpenGLTextureBlitterPrivate::blit(GLuint texture,-
202 const QMatrix4x4 &vertexTransform,-
203 const QMatrix3x3 &textureTransform)-
204{-
205 TextureBinder binder(currentTarget, texture);-
206 prepareProgram(vertexTransform);-
207-
208 Program *program = &programs[targetToProgramIndex(currentTarget)];-
209 program->glProgram->setUniformValue(program->textureTransformUniformPos, textureTransform);-
210 program->textureMatrixUniformState = User;-
211-
212 QOpenGLContext::currentContext()->functions()->glDrawArrays(0x0004, 0, 6);-
213}
never executed: end of block
0
214-
215void QOpenGLTextureBlitterPrivate::blit(GLuint texture,-
216 const QMatrix4x4 &vertexTransform,-
217 QOpenGLTextureBlitter::Origin origin)-
218{-
219 TextureBinder binder(currentTarget, texture);-
220 prepareProgram(vertexTransform);-
221-
222 Program *program = &programs[targetToProgramIndex(currentTarget)];-
223 if (origin == QOpenGLTextureBlitter::OriginTopLeft
origin == QOpe...:OriginTopLeftDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
224 if (program->textureMatrixUniformState != IdentityFlipped
program->textu...dentityFlippedDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
225 QMatrix3x3 flipped;-
226 flipped(1,1) = -1;-
227 flipped(1,2) = 1;-
228 program->glProgram->setUniformValue(program->textureTransformUniformPos, flipped);-
229 program->textureMatrixUniformState = IdentityFlipped;-
230 }
never executed: end of block
0
231 }
never executed: end of block
else if (program->textureMatrixUniformState != Identity
program->textu...te != IdentityDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
232 program->glProgram->setUniformValue(program->textureTransformUniformPos, QMatrix3x3());-
233 program->textureMatrixUniformState = Identity;-
234 }
never executed: end of block
0
235-
236 QOpenGLContext::currentContext()->functions()->glDrawArrays(0x0004, 0, 6);-
237}
never executed: end of block
0
238-
239bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs, const char *fs)-
240{-
241 Program *p = &programs[idx];-
242-
243 p->glProgram.reset(new QOpenGLShaderProgram);-
244-
245 p->glProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vs);-
246 p->glProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fs);-
247 p->glProgram->link();-
248 if (!p->glProgram->isLinked()
!p->glProgram->isLinked()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
249 QMessageLogger(__FILE__, 294, __PRETTY_FUNCTION__).warning() << "Could not link shader program:\n" << p->glProgram->log();-
250 return
never executed: return false;
false;
never executed: return false;
0
251 }-
252-
253 p->glProgram->bind();-
254-
255 p->vertexCoordAttribPos = p->glProgram->attributeLocation("vertexCoord");-
256 p->vertexTransformUniformPos = p->glProgram->uniformLocation("vertexTransform");-
257 p->textureCoordAttribPos = p->glProgram->attributeLocation("textureCoord");-
258 p->textureTransformUniformPos = p->glProgram->uniformLocation("textureTransform");-
259 p->swizzleUniformPos = p->glProgram->uniformLocation("swizzle");-
260 p->opacityUniformPos = p->glProgram->uniformLocation("opacity");-
261-
262 p->glProgram->setUniformValue(p->swizzleUniformPos, false);-
263-
264 return
never executed: return true;
true;
never executed: return true;
0
265}-
266-
267QOpenGLTextureBlitter::QOpenGLTextureBlitter()-
268 : d_ptr(new QOpenGLTextureBlitterPrivate)-
269{-
270}
never executed: end of block
0
271-
272QOpenGLTextureBlitter::~QOpenGLTextureBlitter()-
273{-
274 destroy();-
275}
never executed: end of block
0
276-
277bool QOpenGLTextureBlitter::create()-
278{-
279 QOpenGLContext *currentContext = QOpenGLContext::currentContext();-
280 if (!currentContext
!currentContextDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
281 return
never executed: return false;
false;
never executed: return false;
0
282-
283 QOpenGLTextureBlitterPrivate * const d = d_func();-
284-
285 if (d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram
d->programs[QO..._2D].glProgramDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
286 return
never executed: return true;
true;
never executed: return true;
0
287-
288 QSurfaceFormat format = currentContext->format();-
289 if (format.profile() == QSurfaceFormat::CoreProfile
format.profile...t::CoreProfileDescription
TRUEnever evaluated
FALSEnever evaluated
&& format.version() >= qMakePair(3,2)
format.version...qMakePair(3,2)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
290 if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader150, fragment_shader150)
!d->buildProgr...ent_shader150)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
291 return
never executed: return false;
false;
never executed: return false;
0
292 }
never executed: end of block
else {
0
293 if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader, fragment_shader)
!d->buildProgr...agment_shader)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
294 return
never executed: return false;
false;
never executed: return false;
0
295 if (supportsExternalOESTarget()
supportsExternalOESTarget()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
296 if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES, vertex_shader, fragment_shader_external_oes)
!d->buildProgr..._external_oes)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
297 return
never executed: return false;
false;
never executed: return false;
0
298 }
never executed: end of block
0
299-
300-
301 QOpenGLVertexArrayObject::Binder vaoBinder(d->vao.data());-
302-
303 d->vertexBuffer.create();-
304 d->vertexBuffer.bind();-
305 d->vertexBuffer.allocate(vertex_buffer_data, sizeof(vertex_buffer_data));-
306 d->vertexBuffer.release();-
307-
308 d->textureBuffer.create();-
309 d->textureBuffer.bind();-
310 d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data));-
311 d->textureBuffer.release();-
312-
313 return
never executed: return true;
true;
never executed: return true;
0
314}-
315-
316bool QOpenGLTextureBlitter::isCreated() const-
317{-
318 const QOpenGLTextureBlitterPrivate * const d = d_func();-
319 return
never executed: return d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram;
d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram;
never executed: return d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram;
0
320}-
321-
322void QOpenGLTextureBlitter::destroy()-
323{-
324 if (!isCreated()
!isCreated()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
325 return;
never executed: return;
0
326 QOpenGLTextureBlitterPrivate * const d = d_func();-
327 d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram.reset();-
328 d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES].glProgram.reset();-
329 d->vertexBuffer.destroy();-
330 d->textureBuffer.destroy();-
331 d->vao.reset();-
332}
never executed: end of block
0
333-
334bool QOpenGLTextureBlitter::supportsExternalOESTarget() const-
335{-
336 QOpenGLContext *ctx = QOpenGLContext::currentContext();-
337 return
never executed: return ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external");
ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external");
never executed: return ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external");
0
338}-
339-
340void QOpenGLTextureBlitter::bind(GLenum target)-
341{-
342 QOpenGLTextureBlitterPrivate * const d = d_func();-
343-
344 if (d->vao->isCreated()
d->vao->isCreated()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
345 d->vao->bind();
never executed: d->vao->bind();
0
346-
347 d->currentTarget = target;-
348 QOpenGLTextureBlitterPrivate::Program *p = &d->programs[targetToProgramIndex(target)];-
349 p->glProgram->bind();-
350-
351 d->vertexBuffer.bind();-
352 p->glProgram->setAttributeBuffer(p->vertexCoordAttribPos, 0x1406, 0, 3, 0);-
353 p->glProgram->enableAttributeArray(p->vertexCoordAttribPos);-
354 d->vertexBuffer.release();-
355-
356 d->textureBuffer.bind();-
357 p->glProgram->setAttributeBuffer(p->textureCoordAttribPos, 0x1406, 0, 2, 0);-
358 p->glProgram->enableAttributeArray(p->textureCoordAttribPos);-
359 d->textureBuffer.release();-
360}
never executed: end of block
0
361-
362void QOpenGLTextureBlitter::release()-
363{-
364 QOpenGLTextureBlitterPrivate * const d = d_func();-
365 d->programs[targetToProgramIndex(d->currentTarget)].glProgram->release();-
366 if (d->vao->isCreated()
d->vao->isCreated()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
367 d->vao->release();
never executed: d->vao->release();
0
368}
never executed: end of block
0
369-
370void QOpenGLTextureBlitter::setSwizzleRB(bool swizzle)-
371{-
372 QOpenGLTextureBlitterPrivate * const d = d_func();-
373 d->swizzle = swizzle;-
374}
never executed: end of block
0
375-
376void QOpenGLTextureBlitter::setOpacity(float opacity)-
377{-
378 QOpenGLTextureBlitterPrivate * const d = d_func();-
379 d->opacity = opacity;-
380}
never executed: end of block
0
381-
382void QOpenGLTextureBlitter::blit(GLuint texture,-
383 const QMatrix4x4 &targetTransform,-
384 Origin sourceOrigin)-
385{-
386 QOpenGLTextureBlitterPrivate * const d = d_func();-
387 d->blit(texture,targetTransform, sourceOrigin);-
388}
never executed: end of block
0
389-
390void QOpenGLTextureBlitter::blit(GLuint texture,-
391 const QMatrix4x4 &targetTransform,-
392 const QMatrix3x3 &sourceTransform)-
393{-
394 QOpenGLTextureBlitterPrivate * const d = d_func();-
395 d->blit(texture, targetTransform, sourceTransform);-
396}
never executed: end of block
0
397-
398QMatrix4x4 QOpenGLTextureBlitter::targetTransform(const QRectF &target,-
399 const QRect &viewport)-
400{-
401 qreal x_scale = target.width() / viewport.width();-
402 qreal y_scale = target.height() / viewport.height();-
403-
404 const QPointF relative_to_viewport = target.topLeft() - viewport.topLeft();-
405 qreal x_translate = x_scale - 1 + ((relative_to_viewport.x() / viewport.width()) * 2);-
406 qreal y_translate = -y_scale + 1 - ((relative_to_viewport.y() / viewport.height()) * 2);-
407-
408 QMatrix4x4 matrix;-
409 matrix(0,3) = x_translate;-
410 matrix(1,3) = y_translate;-
411-
412 matrix(0,0) = x_scale;-
413 matrix(1,1) = y_scale;-
414-
415 return
never executed: return matrix;
matrix;
never executed: return matrix;
0
416}-
417-
418QMatrix3x3 QOpenGLTextureBlitter::sourceTransform(const QRectF &subTexture,-
419 const QSize &textureSize,-
420 Origin origin)-
421{-
422 qreal x_scale = subTexture.width() / textureSize.width();-
423 qreal y_scale = subTexture.height() / textureSize.height();-
424-
425 const QPointF topLeft = subTexture.topLeft();-
426 qreal x_translate = topLeft.x() / textureSize.width();-
427 qreal y_translate = topLeft.y() / textureSize.height();-
428-
429 if (origin == OriginTopLeft
origin == OriginTopLeftDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
430 y_scale = -y_scale;-
431 y_translate = 1 - y_translate;-
432 }
never executed: end of block
0
433-
434 QMatrix3x3 matrix;-
435 matrix(0,2) = x_translate;-
436 matrix(1,2) = y_translate;-
437-
438 matrix(0,0) = x_scale;-
439 matrix(1,1) = y_scale;-
440-
441 return
never executed: return matrix;
matrix;
never executed: return matrix;
0
442}-
443-
444-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9