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 Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29//TESTED_COMPONENT=src/multimedia
30
31#include <private/qpaintervideosurface_p.h>
32#include <QtTest/QtTest>
33
34#include <QtWidgets/qapplication.h>
35#include <qvideosurfaceformat.h>
36
37#if QT_CONFIG(opengl)
38#include <QOpenGLContext>
39#include <QOpenGLFunctions>
40#include <QOpenGLWidget>
41#endif
42
43QT_USE_NAMESPACE
44class tst_QPainterVideoSurface : public QObject
45{
46 Q_OBJECT
47private slots:
48 void cleanup() {}
49 void cleanupTestCase() {}
50
51 void colors();
52
53 void supportedFormat_data();
54 void supportedFormat();
55
56 void present_data();
57 void present();
58 void presentOpaqueFrame();
59
60#if QT_CONFIG(opengl)
61
62 void shaderType();
63
64 void shaderTypeStarted_data();
65 void shaderTypeStarted();
66
67 void shaderSupportedFormat_data();
68 void shaderSupportedFormat();
69
70 void shaderPresent_data();
71 void shaderPresent();
72 void shaderPresentOpaqueFrame_data();
73 void shaderPresentOpaqueFrame();
74 void shaderPresentGLFrame_data();
75 void shaderPresentGLFrame();
76#endif
77private:
78 bool m_libGL = QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL;
79};
80
81Q_DECLARE_METATYPE(const uchar *)
82
83#if QT_CONFIG(opengl)
84Q_DECLARE_METATYPE(QPainterVideoSurface::ShaderType);
85
86class QtTestGLVideoBuffer : public QAbstractVideoBuffer
87{
88public:
89 QtTestGLVideoBuffer()
90 : QAbstractVideoBuffer(GLTextureHandle)
91 , m_textureId(0)
92 {
93 QOpenGLContext::currentContext()->functions()->glGenTextures(n: 1, textures: &m_textureId);
94 }
95
96 ~QtTestGLVideoBuffer()
97 {
98 QOpenGLContext::currentContext()->functions()->glDeleteTextures(n: 1, textures: &m_textureId);
99 }
100
101 GLuint textureId() const { return m_textureId; }
102
103 QVariant handle() const { return m_textureId; }
104
105 uchar *map(MapMode, int *, int *) { return 0; }
106 void unmap() {}
107 MapMode mapMode() const { return NotMapped; }
108
109private:
110 GLuint m_textureId;
111};
112
113#endif
114
115class QtTestOpaqueVideoBuffer : public QAbstractVideoBuffer
116{
117public:
118 QtTestOpaqueVideoBuffer()
119 : QAbstractVideoBuffer(UserHandle)
120 {}
121
122 uchar *map(MapMode, int *, int *) { return 0; }
123 void unmap() {}
124 MapMode mapMode() const { return NotMapped; }
125};
126
127void tst_QPainterVideoSurface::colors()
128{
129 QPainterVideoSurface surface;
130
131 QCOMPARE(surface.brightness(), 0);
132 QCOMPARE(surface.contrast(), 0);
133 QCOMPARE(surface.hue(), 0);
134 QCOMPARE(surface.saturation(), 0);
135
136 surface.setBrightness(56);
137 QCOMPARE(surface.brightness(), 56);
138
139 surface.setContrast(43);
140 QCOMPARE(surface.contrast(), 43);
141
142 surface.setHue(-84);
143 QCOMPARE(surface.hue(), -84);
144
145 surface.setSaturation(100);
146 QCOMPARE(surface.saturation(), 100);
147}
148
149static const uchar rgb32ImageData[] =
150{
151 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
152 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00
153};
154
155static const uchar argb32ImageData[] =
156{
157 0x00, 0xff, 0x00, 0x00, 0xcc, 0x00, 0xff, 0xcc,
158 0x77, 0x00, 0x00, 0x77, 0x00, 0xff, 0xff, 0x00
159};
160
161static const uchar rgb24ImageData[] =
162{
163 0x00, 0xff, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00,
164 0xcc, 0x00, 0xcc, 0x77, 0xff, 0x77, 0x00, 0x00
165};
166
167static const uchar rgb565ImageData[] =
168{
169 0xff, 0xff, 0xff, 0xff,
170 0x00, 0x00, 0x00, 0x00
171};
172
173static const uchar yuvPlanarImageData[] =
174{
175 0x00, 0x00, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0x00,
176 0x00, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0x00,
177 0x00, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0x00,
178 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff,
179 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff,
180 0x0f, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0x0f,
181 0x00, 0x0f, 0xff, 0x0f, 0x0f, 0xff, 0x0f, 0x00,
182 0x00, 0x00, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0x00,
183 0x00, 0x0f, 0x0f, 0x00,
184 0x0f, 0x00, 0x00, 0x0f,
185 0x0f, 0x00, 0x00, 0x0f,
186 0x00, 0x0f, 0x0f, 0x00,
187 0x00, 0x0f, 0x0f, 0x00,
188 0x0f, 0x00, 0x00, 0x0f,
189 0x0f, 0x00, 0x00, 0x0f,
190 0x00, 0x0f, 0x0f, 0x00,
191};
192
193void tst_QPainterVideoSurface::supportedFormat_data()
194{
195 QTest::addColumn<QAbstractVideoBuffer::HandleType>(name: "handleType");
196 QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat");
197 QTest::addColumn<QSize>(name: "frameSize");
198 QTest::addColumn<bool>(name: "supportedPixelFormat");
199 QTest::addColumn<bool>(name: "supportedFormat");
200
201 QTest::newRow(dataTag: "rgb32 640x480")
202 << QAbstractVideoBuffer::NoHandle
203 << QVideoFrame::Format_RGB32
204 << QSize(640, 480)
205 << true
206 << true;
207 QTest::newRow(dataTag: "rgb32 -640x480")
208 << QAbstractVideoBuffer::NoHandle
209 << QVideoFrame::Format_RGB32
210 << QSize(-640, 480)
211 << true
212 << false;
213 QTest::newRow(dataTag: "rgb24 1024x768")
214 << QAbstractVideoBuffer::NoHandle
215 << QVideoFrame::Format_RGB24
216 << QSize(1024, 768)
217#if !defined(QT_OPENGL_ES)
218 << m_libGL
219 << m_libGL;
220#else
221 << false
222 << false;
223#endif
224 QTest::newRow(dataTag: "rgb24 -1024x-768")
225 << QAbstractVideoBuffer::NoHandle
226 << QVideoFrame::Format_RGB24
227 << QSize(-1024, -768)
228#if !defined(QT_OPENGL_ES)
229 << m_libGL
230#else
231 << false
232#endif
233 << false;
234 QTest::newRow(dataTag: "rgb565 0x0")
235 << QAbstractVideoBuffer::NoHandle
236 << QVideoFrame::Format_RGB565
237 << QSize(0, 0)
238 << true
239 << false;
240 QTest::newRow(dataTag: "YUV420P 640x480")
241 << QAbstractVideoBuffer::NoHandle
242 << QVideoFrame::Format_YUV420P
243 << QSize(640, 480)
244 << false
245 << false;
246 QTest::newRow(dataTag: "YUV420P 640x-480")
247 << QAbstractVideoBuffer::NoHandle
248 << QVideoFrame::Format_YUV420P
249 << QSize(640, -480)
250 << false
251 << false;
252 QTest::newRow(dataTag: "Y8 640x480")
253 << QAbstractVideoBuffer::NoHandle
254 << QVideoFrame::Format_Y8
255 << QSize(640, 480)
256 << false
257 << false;
258 QTest::newRow(dataTag: "Texture: rgb32 640x480")
259 << QAbstractVideoBuffer::GLTextureHandle
260 << QVideoFrame::Format_RGB32
261 << QSize(640, 480)
262 << false
263 << false;
264 QTest::newRow(dataTag: "Texture: rgb32 -640x480")
265 << QAbstractVideoBuffer::GLTextureHandle
266 << QVideoFrame::Format_RGB32
267 << QSize(-640, 480)
268 << false
269 << false;
270 QTest::newRow(dataTag: "rgb565 32x32")
271 << QAbstractVideoBuffer::NoHandle
272 << QVideoFrame::Format_RGB565
273 << QSize(32, 32)
274 << true
275 << true;
276 QTest::newRow(dataTag: "rgb565 0x0")
277 << QAbstractVideoBuffer::NoHandle
278 << QVideoFrame::Format_RGB565
279 << QSize(0, 0)
280 << true
281 << false;
282 QTest::newRow(dataTag: "argb32 256x256")
283 << QAbstractVideoBuffer::NoHandle
284 << QVideoFrame::Format_ARGB32
285 << QSize(256, 256)
286 << true
287 << true;
288 QTest::newRow(dataTag: "Texture: rgb24 1024x768")
289 << QAbstractVideoBuffer::GLTextureHandle
290 << QVideoFrame::Format_RGB24
291 << QSize(1024, 768)
292 << false
293 << false;
294 QTest::newRow(dataTag: "Texture: rgb24 -1024x-768")
295 << QAbstractVideoBuffer::GLTextureHandle
296 << QVideoFrame::Format_RGB24
297 << QSize(-1024, -768)
298 << false
299 << false;
300 QTest::newRow(dataTag: "Texture: YUV420P 640x480")
301 << QAbstractVideoBuffer::GLTextureHandle
302 << QVideoFrame::Format_YUV420P
303 << QSize(640, 480)
304 << false
305 << false;
306 QTest::newRow(dataTag: "Texture: YUV420P 640x-480")
307 << QAbstractVideoBuffer::GLTextureHandle
308 << QVideoFrame::Format_YUV420P
309 << QSize(640, -480)
310 << false
311 << false;
312 QTest::newRow(dataTag: "User Buffer: rgb32 256x256")
313 << QAbstractVideoBuffer::UserHandle
314 << QVideoFrame::Format_RGB32
315 << QSize(256, 256)
316 << false
317 << false;
318#if !defined(Q_OS_MAC)
319 QTest::newRow(dataTag: "Pixmap: rgb32 640x480")
320 << QAbstractVideoBuffer::QPixmapHandle
321 << QVideoFrame::Format_RGB32
322 << QSize(640, 480)
323 << true
324 << true;
325 QTest::newRow(dataTag: "Pixmap: YUV420P 640x480")
326 << QAbstractVideoBuffer::QPixmapHandle
327 << QVideoFrame::Format_YUV420P
328 << QSize(640, 480)
329 << false
330 << true;
331#endif
332}
333
334void tst_QPainterVideoSurface::supportedFormat()
335{
336 QFETCH(QAbstractVideoBuffer::HandleType, handleType);
337 QFETCH(QVideoFrame::PixelFormat, pixelFormat);
338 QFETCH(QSize, frameSize);
339 QFETCH(bool, supportedPixelFormat);
340 QFETCH(bool, supportedFormat);
341
342 QPainterVideoSurface surface;
343
344 const QList<QVideoFrame::PixelFormat> pixelFormats = surface.supportedPixelFormats(handleType);
345
346 QCOMPARE(pixelFormats.contains(pixelFormat), supportedPixelFormat);
347
348 QVideoSurfaceFormat format(frameSize, pixelFormat, handleType);
349
350 QCOMPARE(surface.isFormatSupported(format), supportedFormat);
351 QCOMPARE(surface.start(format), supportedFormat);
352}
353
354void tst_QPainterVideoSurface::present_data()
355{
356 QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormatA");
357 QTest::addColumn<QSize>(name: "frameSizeA");
358 QTest::addColumn<const uchar *>(name: "frameDataA");
359 QTest::addColumn<int>(name: "bytesA");
360 QTest::addColumn<int>(name: "bytesPerLineA");
361 QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormatB");
362 QTest::addColumn<QSize>(name: "frameSizeB");
363 QTest::addColumn<const uchar *>(name: "frameDataB");
364 QTest::addColumn<int>(name: "bytesB");
365 QTest::addColumn<int>(name: "bytesPerLineB");
366
367 QTest::newRow(dataTag: "rgb32 -> argb32")
368 << QVideoFrame::Format_RGB32
369 << QSize(2, 2)
370 << static_cast<const uchar *>(rgb32ImageData)
371 << int(sizeof(rgb32ImageData))
372 << 8
373 << QVideoFrame::Format_ARGB32
374 << QSize(2, 2)
375 << static_cast<const uchar *>(argb32ImageData)
376 << int(sizeof(argb32ImageData))
377 << 8;
378
379#if !defined(QT_OPENGL_ES)
380 if (m_libGL)
381 QTest::newRow(dataTag: "rgb32 -> rgb24")
382 << QVideoFrame::Format_RGB32
383 << QSize(2, 2)
384 << static_cast<const uchar *>(rgb32ImageData)
385 << int(sizeof(rgb32ImageData))
386 << 8
387 << QVideoFrame::Format_RGB24
388 << QSize(2, 2)
389 << static_cast<const uchar *>(rgb24ImageData)
390 << int(sizeof(rgb24ImageData))
391 << 8;
392#endif
393
394 QTest::newRow(dataTag: "rgb32 -> rgb565")
395 << QVideoFrame::Format_RGB32
396 << QSize(2, 2)
397 << static_cast<const uchar *>(rgb32ImageData)
398 << int(sizeof(rgb32ImageData))
399 << 8
400 << QVideoFrame::Format_RGB565
401 << QSize(2, 2)
402 << static_cast<const uchar *>(rgb565ImageData)
403 << int(sizeof(rgb565ImageData))
404 << 4;
405
406#if !defined(QT_OPENGL_ES)
407 if (m_libGL)
408 QTest::newRow(dataTag: "rgb24 -> rgb565")
409 << QVideoFrame::Format_RGB24
410 << QSize(2, 2)
411 << static_cast<const uchar *>(rgb24ImageData)
412 << int(sizeof(rgb24ImageData))
413 << 8
414 << QVideoFrame::Format_RGB565
415 << QSize(2, 2)
416 << static_cast<const uchar *>(rgb565ImageData)
417 << int(sizeof(rgb565ImageData))
418 << 4;
419#endif
420}
421
422void tst_QPainterVideoSurface::present()
423{
424 QFETCH(QVideoFrame::PixelFormat, pixelFormatA);
425 QFETCH(QSize, frameSizeA);
426 QFETCH(const uchar *, frameDataA);
427 QFETCH(int, bytesA);
428 QFETCH(int, bytesPerLineA);
429 QFETCH(QVideoFrame::PixelFormat, pixelFormatB);
430 QFETCH(QSize, frameSizeB);
431 QFETCH(const uchar *, frameDataB);
432 QFETCH(int, bytesB);
433 QFETCH(int, bytesPerLineB);
434
435 QPainterVideoSurface surface;
436
437 QImage image(320, 240, QImage::Format_RGB32);
438
439 QSignalSpy frameSpy(&surface, SIGNAL(frameChanged()));
440
441 const QList<QVideoFrame::PixelFormat> pixelFormats = surface.supportedPixelFormats();
442
443 { // Test painting before started.
444 QPainter painter(&image);
445 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
446 }
447
448 QVideoSurfaceFormat formatA(frameSizeA, pixelFormatA);
449
450 QVERIFY(surface.start(formatA));
451 QCOMPARE(surface.isActive(), true);
452 QCOMPARE(surface.isReady(), true);
453
454 { // Test painting before receiving a frame.
455 QPainter painter(&image);
456 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
457 }
458 QCOMPARE(surface.error(), QAbstractVideoSurface::NoError);
459
460 QVideoFrame frameA(bytesA, frameSizeA, bytesPerLineA, pixelFormatA);
461
462 frameA.map(mode: QAbstractVideoBuffer::WriteOnly);
463 memcpy(dest: frameA.bits(), src: frameDataA, n: frameA.mappedBytes());
464 frameA.unmap();
465
466 QVERIFY(surface.present(frameA));
467 QCOMPARE(surface.isReady(), false);
468 QCOMPARE(frameSpy.count(), 1);
469
470 {
471 QPainter painter(&image);
472 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
473 }
474 QCOMPARE(surface.isActive(), true);
475 QCOMPARE(surface.isReady(), false);
476
477 { // Test repainting before receiving another frame.
478 QPainter painter(&image);
479 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
480 }
481 QCOMPARE(surface.isActive(), true);
482 QCOMPARE(surface.isReady(), false);
483
484 QVERIFY(surface.present(frameA));
485 QCOMPARE(frameSpy.count(), 1);
486
487 surface.setReady(true);
488 QCOMPARE(surface.isReady(), true);
489 QVERIFY(surface.present(frameA));
490 QCOMPARE(frameSpy.count(), 2);
491
492 // Try switching to a different format after starting.
493 QVideoSurfaceFormat formatB(frameSizeB, pixelFormatB);
494
495 QVERIFY(surface.start(formatB));
496 QCOMPARE(surface.isActive(), true);
497 QCOMPARE(surface.isReady(), true);
498
499 QVideoFrame frameB(bytesB, frameSizeB, bytesPerLineB, pixelFormatB);
500
501 frameB.map(mode: QAbstractVideoBuffer::WriteOnly);
502 memcpy(dest: frameB.bits(), src: frameDataB, n: frameB.mappedBytes());
503 frameB.unmap();
504
505 QVERIFY(surface.present(frameB));
506 QCOMPARE(surface.isReady(), false);
507 QCOMPARE(frameSpy.count(), 3);
508
509 {
510 QPainter painter(&image);
511 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
512 }
513 QVERIFY(surface.isActive());
514
515 surface.stop();
516
517 QCOMPARE(surface.isActive(), false);
518 QCOMPARE(surface.isReady(), false);
519
520 // Try presenting a frame while stopped.
521 QVERIFY(!surface.present(frameB));
522 QCOMPARE(surface.isReady(), false);
523 QCOMPARE(surface.error(), QAbstractVideoSurface::StoppedError);
524
525 // Try presenting a frame with a different format.
526 QVERIFY(surface.start(formatB));
527 QVERIFY(!surface.present(frameA));
528 QCOMPARE(surface.isActive(), false);
529 QCOMPARE(surface.isReady(), false);
530 QCOMPARE(surface.error(), QAbstractVideoSurface::IncorrectFormatError);
531}
532
533void tst_QPainterVideoSurface::presentOpaqueFrame()
534{
535 QPainterVideoSurface surface;
536
537 QImage image(320, 240, QImage::Format_RGB32);
538
539 QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
540
541 QVERIFY(surface.start(format));
542 QCOMPARE(surface.isActive(), true);
543 QCOMPARE(surface.isReady(), true);
544
545 QVideoFrame frame(new QtTestOpaqueVideoBuffer, QSize(64, 64), QVideoFrame::Format_RGB32);
546
547 if (surface.present(frame)) {
548 QPainter painter(&image);
549 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
550 }
551
552 QCOMPARE(surface.isActive(), false);
553 QCOMPARE(surface.isReady(), false);
554 QCOMPARE(surface.error(), QAbstractVideoSurface::IncorrectFormatError);
555}
556
557#if QT_CONFIG(opengl)
558
559void tst_QPainterVideoSurface::shaderType()
560{
561 QPainterVideoSurface surface;
562 QOpenGLWidget widget;
563 widget.show();
564
565 QVERIFY(QTest::qWaitForWindowExposed(&widget));
566
567 if (!widget.context() || !widget.context()->isValid())
568 QSKIP("Platform does not support OpenGLContext");
569
570 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
571 QCOMPARE(surface.supportedShaderTypes(), QPainterVideoSurface::NoShaders);
572
573 widget.makeCurrent();
574 surface.updateGLContext();
575 QCOMPARE(surface.glContext(), widget.context());
576
577 {
578 QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged()));
579
580 surface.setShaderType(QPainterVideoSurface::NoShaders);
581 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
582 QCOMPARE(spy.count(), 0);
583 }
584
585#if !defined(QT_OPENGL_ES)
586 if (surface.supportedShaderTypes() & QPainterVideoSurface::FragmentProgramShader) {
587 QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged()));
588
589 surface.setShaderType(QPainterVideoSurface::FragmentProgramShader);
590 QCOMPARE(surface.shaderType(), QPainterVideoSurface::FragmentProgramShader);
591 QCOMPARE(spy.count(), 1);
592
593 surface.setShaderType(QPainterVideoSurface::FragmentProgramShader);
594 QCOMPARE(surface.shaderType(), QPainterVideoSurface::FragmentProgramShader);
595 QCOMPARE(spy.count(), 1);
596 }
597#endif
598
599 if (surface.supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
600 QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged()));
601
602 surface.setShaderType(QPainterVideoSurface::GlslShader);
603 QCOMPARE(surface.shaderType(), QPainterVideoSurface::GlslShader);
604 QCOMPARE(spy.count(), 1);
605
606 surface.setShaderType(QPainterVideoSurface::GlslShader);
607 QCOMPARE(surface.shaderType(), QPainterVideoSurface::GlslShader);
608 QCOMPARE(spy.count(), 1);
609 }
610
611 {
612 QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged()));
613
614 widget.makeCurrent();
615 surface.updateGLContext();
616 QCOMPARE(surface.glContext(), widget.context());
617 QCOMPARE(spy.count(), 0);
618 }
619
620 widget.doneCurrent();
621 surface.updateGLContext();
622 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
623 QCOMPARE(surface.supportedShaderTypes(), QPainterVideoSurface::NoShaders);
624
625 {
626 QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged()));
627
628 surface.setShaderType(QPainterVideoSurface::NoShaders);
629 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
630 QCOMPARE(spy.count(), 0);
631
632#if !defined(QT_OPENGL_ES)
633 surface.setShaderType(QPainterVideoSurface::FragmentProgramShader);
634 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
635 QCOMPARE(spy.count(), 0);
636#endif
637
638 surface.setShaderType(QPainterVideoSurface::GlslShader);
639 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
640 QCOMPARE(spy.count(), 0);
641 }
642}
643
644void tst_QPainterVideoSurface::shaderTypeStarted_data()
645{
646 QTest::addColumn<QPainterVideoSurface::ShaderType>(name: "shaderType");
647
648#if !defined(QT_OPENGL_ES)
649 QTest::newRow(dataTag: "ARBfp")
650 << QPainterVideoSurface::FragmentProgramShader;
651#endif
652 QTest::newRow(dataTag: "GLSL")
653 << QPainterVideoSurface::GlslShader;
654}
655
656void tst_QPainterVideoSurface::shaderTypeStarted()
657{
658 QFETCH(QPainterVideoSurface::ShaderType, shaderType);
659
660 QOpenGLWidget widget;
661 widget.show();
662
663 QVERIFY(QTest::qWaitForWindowExposed(&widget));
664
665 if (!widget.context() || !widget.context()->isValid())
666 QSKIP("Platform does not support OpenGLContext");
667
668 QPainterVideoSurface surface;
669
670 widget.makeCurrent();
671 surface.updateGLContext();
672
673 if (!(surface.supportedShaderTypes() & shaderType))
674 QSKIP("Shader type unsupported on this platform");
675
676 surface.setShaderType(shaderType);
677 QCOMPARE(surface.shaderType(), shaderType);
678
679 QVERIFY(surface.start(QVideoSurfaceFormat(QSize(640, 480), QVideoFrame::Format_RGB32)));
680 {
681 QSignalSpy spy(&surface, SIGNAL(activeChanged(bool)));
682
683 surface.setShaderType(QPainterVideoSurface::NoShaders);
684 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
685 QCOMPARE(surface.isActive(), false);
686 QCOMPARE(spy.count(), 1);
687 QCOMPARE(spy.last().value(0).toBool(), false);
688 }
689
690 QVERIFY(surface.start(QVideoSurfaceFormat(QSize(640, 480), QVideoFrame::Format_RGB32)));
691 {
692 QSignalSpy spy(&surface, SIGNAL(activeChanged(bool)));
693
694 surface.setShaderType(QPainterVideoSurface::NoShaders);
695 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
696 QCOMPARE(surface.isActive(), true);
697 QCOMPARE(spy.count(), 0);
698
699 surface.setShaderType(shaderType);
700 QCOMPARE(surface.shaderType(), shaderType);
701 QCOMPARE(surface.isActive(), false);
702 QCOMPARE(spy.count(), 1);
703 QCOMPARE(spy.last().value(0).toBool(), false);
704 }
705
706 QVERIFY(surface.start(QVideoSurfaceFormat(QSize(640, 480), QVideoFrame::Format_RGB32)));
707 {
708 QSignalSpy spy(&surface, SIGNAL(activeChanged(bool)));
709
710 surface.setShaderType(shaderType);
711 QCOMPARE(surface.shaderType(), shaderType);
712 QCOMPARE(surface.isActive(), true);
713 QCOMPARE(spy.count(), 0);
714
715 widget.doneCurrent();
716 surface.updateGLContext();
717 QCOMPARE(surface.shaderType(), QPainterVideoSurface::NoShaders);
718 QCOMPARE(surface.isActive(), false);
719 QCOMPARE(spy.count(), 1);
720 QCOMPARE(spy.last().value(0).toBool(), false);
721 }
722}
723
724void tst_QPainterVideoSurface::shaderSupportedFormat_data()
725{
726 QTest::addColumn<QPainterVideoSurface::ShaderType>(name: "shaderType");
727 QTest::addColumn<QAbstractVideoBuffer::HandleType>(name: "handleType");
728 QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat");
729 QTest::addColumn<QSize>(name: "frameSize");
730 QTest::addColumn<bool>(name: "supportedPixelFormat");
731 QTest::addColumn<bool>(name: "supportedFormat");
732
733 const QPair<QPainterVideoSurface::ShaderType, QByteArray> types[] = {
734#if !defined(QT_OPENGL_ES)
735 qMakePair(x: QPainterVideoSurface::FragmentProgramShader, y: QByteArray("ARBfp: ")),
736#endif
737 qMakePair(x: QPainterVideoSurface::GlslShader, y: QByteArray("GLSL: ")),
738 };
739
740 for (const auto &type : types) {
741 QTest::newRow(dataTag: (type.second + "rgb32 640x480").constData())
742 << type.first
743 << QAbstractVideoBuffer::NoHandle
744 << QVideoFrame::Format_RGB32
745 << QSize(640, 480)
746 << true
747 << true;
748 QTest::newRow(dataTag: (type.second + "rgb32 -640x480").constData())
749 << type.first
750 << QAbstractVideoBuffer::NoHandle
751 << QVideoFrame::Format_RGB32
752 << QSize(-640, 480)
753 << true
754 << false;
755 QTest::newRow(dataTag: (type.second + "rgb565 32x32").constData())
756 << type.first
757 << QAbstractVideoBuffer::NoHandle
758 << QVideoFrame::Format_RGB565
759 << QSize(32, 32)
760 << true
761 << true;
762 QTest::newRow(dataTag: (type.second + "rgb565 0x0").constData())
763 << type.first
764 << QAbstractVideoBuffer::NoHandle
765 << QVideoFrame::Format_RGB565
766 << QSize(0, 0)
767 << true
768 << false;
769 QTest::newRow(dataTag: (type.second + "argb32 256x256").constData())
770 << type.first
771 << QAbstractVideoBuffer::NoHandle
772 << QVideoFrame::Format_ARGB32
773 << QSize(256, 256)
774 << true
775 << true;
776 QTest::newRow(dataTag: (type.second + "rgb24 1024x768").constData())
777 << type.first
778 << QAbstractVideoBuffer::NoHandle
779 << QVideoFrame::Format_RGB24
780 << QSize(1024, 768)
781#if !defined(QT_OPENGL_ES)
782 << m_libGL
783 << m_libGL;
784#else
785 << false
786 << false;
787#endif
788 QTest::newRow(dataTag: (type.second + "rgb24 -1024x-768").constData())
789 << type.first
790 << QAbstractVideoBuffer::NoHandle
791 << QVideoFrame::Format_RGB24
792 << QSize(-1024, -768)
793#if !defined(QT_OPENGL_ES)
794 << m_libGL
795#else
796 << false
797#endif
798 << false;
799#ifndef Q_OS_MAC
800 QTest::newRow(dataTag: (type.second + "YUV420P 640x480").constData())
801 << type.first
802 << QAbstractVideoBuffer::NoHandle
803 << QVideoFrame::Format_YUV420P
804 << QSize(640, 480)
805 << true
806 << true;
807 QTest::newRow(dataTag: (type.second + "YUV420P 640x-480").constData())
808 << type.first
809 << QAbstractVideoBuffer::NoHandle
810 << QVideoFrame::Format_YUV420P
811 << QSize(640, -480)
812 << true
813 << false;
814#endif
815 QTest::newRow(dataTag: (type.second + "Y8 640x480").constData())
816 << type.first
817 << QAbstractVideoBuffer::NoHandle
818 << QVideoFrame::Format_Y8
819 << QSize(640, 480)
820 << false
821 << false;
822 QTest::newRow(dataTag: (type.second + "Texture: rgb32 640x480").constData())
823 << type.first
824 << QAbstractVideoBuffer::GLTextureHandle
825 << QVideoFrame::Format_RGB32
826 << QSize(640, 480)
827 << true
828 << true;
829 QTest::newRow(dataTag: (type.second + "Texture: rgb32 -640x480").constData())
830 << type.first
831 << QAbstractVideoBuffer::GLTextureHandle
832 << QVideoFrame::Format_RGB32
833 << QSize(-640, 480)
834 << true
835 << false;
836#ifndef Q_OS_MAC
837 QTest::newRow(dataTag: (type.second + "Texture: rgb565 32x32").constData())
838 << type.first
839 << QAbstractVideoBuffer::GLTextureHandle
840 << QVideoFrame::Format_RGB565
841 << QSize(32, 32)
842 << false
843 << false;
844 QTest::newRow(dataTag: (type.second + "Texture: rgb565 0x0").constData())
845 << type.first
846 << QAbstractVideoBuffer::GLTextureHandle
847 << QVideoFrame::Format_RGB565
848 << QSize(0, 0)
849 << false
850 << false;
851#endif
852 QTest::newRow(dataTag: (type.second + "Texture argb32 256x256").constData())
853 << type.first
854 << QAbstractVideoBuffer::GLTextureHandle
855 << QVideoFrame::Format_ARGB32
856 << QSize(256, 256)
857 << true
858 << true;
859#ifndef Q_OS_MAC
860 QTest::newRow(dataTag: (type.second + "Texture: rgb24 1024x768").constData())
861 << type.first
862 << QAbstractVideoBuffer::GLTextureHandle
863 << QVideoFrame::Format_RGB24
864 << QSize(1024, 768)
865 << false
866 << false;
867 QTest::newRow(dataTag: (type.second + "Texture: rgb24 -1024x-768").constData())
868 << type.first
869 << QAbstractVideoBuffer::GLTextureHandle
870 << QVideoFrame::Format_RGB24
871 << QSize(-1024, -768)
872 << false
873 << false;
874 QTest::newRow(dataTag: (type.second + "Texture: YUV420P 640x480").constData())
875 << type.first
876 << QAbstractVideoBuffer::GLTextureHandle
877 << QVideoFrame::Format_YUV420P
878 << QSize(640, 480)
879 << false
880 << false;
881 QTest::newRow(dataTag: (type.second + "Texture: YUV420P 640x-480").constData())
882 << type.first
883 << QAbstractVideoBuffer::GLTextureHandle
884 << QVideoFrame::Format_YUV420P
885 << QSize(640, -480)
886 << false
887 << false;
888#endif
889 QTest::newRow(dataTag: type.second + "User Buffer: rgb32 256x256")
890 << type.first
891 << QAbstractVideoBuffer::UserHandle
892 << QVideoFrame::Format_RGB32
893 << QSize(256, 256)
894 << false
895 << false;
896 }
897}
898
899void tst_QPainterVideoSurface::shaderSupportedFormat()
900{
901 QFETCH(QPainterVideoSurface::ShaderType, shaderType);
902 QFETCH(QAbstractVideoBuffer::HandleType, handleType);
903 QFETCH(QVideoFrame::PixelFormat, pixelFormat);
904 QFETCH(QSize, frameSize);
905 QFETCH(bool, supportedPixelFormat);
906 QFETCH(bool, supportedFormat);
907
908 QOpenGLWidget widget;
909 widget.show();
910
911 QVERIFY(QTest::qWaitForWindowExposed(&widget));
912
913 if (!widget.context() || !widget.context()->isValid())
914 QSKIP("Platform does not support GLContext");
915
916 QPainterVideoSurface surface;
917 widget.makeCurrent();
918 surface.updateGLContext();
919
920
921 if (!(surface.supportedShaderTypes() & shaderType))
922 QSKIP("Shader type not supported on this platform");
923
924 surface.setShaderType(shaderType);
925 if (surface.shaderType() != shaderType)
926 QSKIP("Shader type couldn't be set");
927
928 const QList<QVideoFrame::PixelFormat> pixelFormats = surface.supportedPixelFormats(handleType);
929
930 QCOMPARE(pixelFormats.contains(pixelFormat), supportedPixelFormat);
931
932 QVideoSurfaceFormat format(frameSize, pixelFormat, handleType);
933
934 QCOMPARE(surface.isFormatSupported(format), supportedFormat);
935 QCOMPARE(surface.start(format), supportedFormat);
936}
937
938void tst_QPainterVideoSurface::shaderPresent_data()
939{
940 QTest::addColumn<QPainterVideoSurface::ShaderType>(name: "shaderType");
941 QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormatA");
942 QTest::addColumn<QSize>(name: "frameSizeA");
943 QTest::addColumn<const uchar *>(name: "frameDataA");
944 QTest::addColumn<int>(name: "bytesA");
945 QTest::addColumn<int>(name: "bytesPerLineA");
946 QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormatB");
947 QTest::addColumn<QSize>(name: "frameSizeB");
948 QTest::addColumn<const uchar *>(name: "frameDataB");
949 QTest::addColumn<int>(name: "bytesB");
950 QTest::addColumn<int>(name: "bytesPerLineB");
951
952 const QPair<QPainterVideoSurface::ShaderType, QByteArray> types[] = {
953#if !defined(QT_OPENGL_ES)
954 qMakePair(x: QPainterVideoSurface::FragmentProgramShader, y: QByteArray("ARBfp: ")),
955#endif
956 qMakePair(x: QPainterVideoSurface::GlslShader, y: QByteArray("GLSL: ")),
957 };
958
959 for (const auto &type : types) {
960 QTest::newRow(dataTag: (type.second + "rgb32 -> argb32").constData())
961 << type.first
962 << QVideoFrame::Format_RGB32
963 << QSize(2, 2)
964 << static_cast<const uchar *>(rgb32ImageData)
965 << int(sizeof(rgb32ImageData))
966 << 8
967 << QVideoFrame::Format_ARGB32
968 << QSize(2, 2)
969 << static_cast<const uchar *>(argb32ImageData)
970 << int(sizeof(argb32ImageData))
971 << 8;
972
973 QTest::newRow(dataTag: (type.second + "rgb32 -> rgb565").constData())
974 << type.first
975 << QVideoFrame::Format_RGB32
976 << QSize(2, 2)
977 << static_cast<const uchar *>(rgb32ImageData)
978 << int(sizeof(rgb32ImageData))
979 << 8
980 << QVideoFrame::Format_RGB565
981 << QSize(2, 2)
982 << static_cast<const uchar *>(rgb565ImageData)
983 << int(sizeof(rgb565ImageData))
984 << 4;
985#ifndef Q_OS_MAC
986 QTest::newRow(dataTag: (type.second + "rgb32 -> yuv420p").constData())
987 << type.first
988 << QVideoFrame::Format_RGB32
989 << QSize(2, 2)
990 << static_cast<const uchar *>(rgb32ImageData)
991 << int(sizeof(rgb32ImageData))
992 << 8
993 << QVideoFrame::Format_YUV420P
994 << QSize(8, 8)
995 << static_cast<const uchar *>(yuvPlanarImageData)
996 << int(sizeof(yuvPlanarImageData))
997 << 8;
998
999 QTest::newRow(dataTag: (type.second + "yv12 -> rgb32").constData())
1000 << type.first
1001 << QVideoFrame::Format_YV12
1002 << QSize(8, 8)
1003 << static_cast<const uchar *>(yuvPlanarImageData)
1004 << int(sizeof(yuvPlanarImageData))
1005 << 8
1006 << QVideoFrame::Format_RGB32
1007 << QSize(2, 2)
1008 << static_cast<const uchar *>(rgb32ImageData)
1009 << int(sizeof(rgb32ImageData))
1010 << 8;
1011#endif
1012 }
1013}
1014
1015void tst_QPainterVideoSurface::shaderPresent()
1016{
1017 QFETCH(QPainterVideoSurface::ShaderType, shaderType);
1018 QFETCH(QVideoFrame::PixelFormat, pixelFormatA);
1019 QFETCH(QSize, frameSizeA);
1020 QFETCH(const uchar *, frameDataA);
1021 QFETCH(int, bytesA);
1022 QFETCH(int, bytesPerLineA);
1023 QFETCH(QVideoFrame::PixelFormat, pixelFormatB);
1024 QFETCH(QSize, frameSizeB);
1025 QFETCH(const uchar *, frameDataB);
1026 QFETCH(int, bytesB);
1027 QFETCH(int, bytesPerLineB);
1028
1029 QOpenGLWidget widget;
1030 widget.show();
1031
1032 QVERIFY(QTest::qWaitForWindowExposed(&widget));
1033
1034 if (!widget.context() || !widget.context()->isValid())
1035 QSKIP("Platform does not support GLContext");
1036
1037 QPainterVideoSurface surface;
1038 widget.makeCurrent();
1039 surface.updateGLContext();
1040
1041 if (!(surface.supportedShaderTypes() & shaderType))
1042 QSKIP("Shader type unsupported on this platform");
1043
1044 surface.setShaderType(shaderType);
1045 if (surface.shaderType() != shaderType)
1046 QSKIP("Shader type couldn't be set");
1047
1048 QSignalSpy frameSpy(&surface, SIGNAL(frameChanged()));
1049
1050 { // Test painting before starting the surface.
1051 QPainter painter(&widget);
1052 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1053 }
1054 QCOMPARE(surface.error(), QAbstractVideoSurface::NoError);
1055
1056 QVideoSurfaceFormat formatA(frameSizeA, pixelFormatA);
1057
1058 QVERIFY(surface.start(formatA));
1059 QCOMPARE(surface.isActive(), true);
1060 QCOMPARE(surface.isReady(), true);
1061
1062 // Test painting before receiving a frame.
1063 {
1064 QPainter painter(&widget);
1065 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1066 }
1067 QCOMPARE(surface.isActive(), true);
1068 QCOMPARE(surface.isReady(), true);
1069
1070 QVideoFrame frameA(bytesA, frameSizeA, bytesPerLineA, pixelFormatA);
1071
1072 frameA.map(mode: QAbstractVideoBuffer::WriteOnly);
1073 memcpy(dest: frameA.bits(), src: frameDataA, n: frameA.mappedBytes());
1074 frameA.unmap();
1075
1076 QVERIFY(surface.present(frameA));
1077 QCOMPARE(surface.isReady(), false);
1078 QCOMPARE(frameSpy.count(), 1);
1079
1080 {
1081 QPainter painter(&widget);
1082 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1083 }
1084 QCOMPARE(surface.isActive(), true);
1085 QCOMPARE(surface.isReady(), false);
1086
1087 { // Test repainting before receiving another frame.
1088 QPainter painter(&widget);
1089 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1090 }
1091 QCOMPARE(surface.isActive(), true);
1092 QCOMPARE(surface.isReady(), false);
1093
1094 // If present() fails for any other reason the surface should immediately enter the stopped state
1095 // and an error() value will be set.
1096 QVERIFY(surface.present(frameA));
1097 QCOMPARE(frameSpy.count(), 1);
1098
1099 surface.setReady(true);
1100 QCOMPARE(surface.isReady(), true);
1101 QVERIFY(surface.present(frameA));
1102 QCOMPARE(frameSpy.count(), 2);
1103
1104 // Try switching to a different format after starting.
1105 QVideoSurfaceFormat formatB(frameSizeB, pixelFormatB);
1106
1107 QVERIFY(surface.start(formatB));
1108 QCOMPARE(surface.isActive(), true);
1109 QCOMPARE(surface.isReady(), true);
1110
1111 QVideoFrame frameB(bytesB, frameSizeB, bytesPerLineB, pixelFormatB);
1112
1113 frameB.map(mode: QAbstractVideoBuffer::WriteOnly);
1114 memcpy(dest: frameB.bits(), src: frameDataB, n: frameB.mappedBytes());
1115 frameB.unmap();
1116
1117 QVERIFY(surface.present(frameB));
1118 QCOMPARE(surface.isReady(), false);
1119 QCOMPARE(frameSpy.count(), 3);
1120
1121 {
1122 QPainter painter(&widget);
1123 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1124 }
1125 QCOMPARE(surface.isActive(), true);
1126
1127 surface.stop();
1128 QCOMPARE(surface.isActive(), false);
1129 QCOMPARE(surface.isReady(), false);
1130
1131 // Try presenting a frame while stopped.
1132 QVERIFY(!surface.present(frameB));
1133 QCOMPARE(surface.isReady(), false);
1134 QCOMPARE(surface.error(), QAbstractVideoSurface::StoppedError);
1135
1136 // Try stopping while already stopped.
1137 surface.stop();
1138 QCOMPARE(surface.isActive(), false);
1139 QCOMPARE(surface.isReady(), false);
1140
1141 // Try presenting a frame with a different format.
1142 QVERIFY(surface.start(formatB));
1143 QVERIFY(!surface.present(frameA));
1144 QCOMPARE(surface.isActive(), false);
1145 QCOMPARE(surface.isReady(), false);
1146 QCOMPARE(surface.error(), QAbstractVideoSurface::IncorrectFormatError);
1147}
1148
1149void tst_QPainterVideoSurface::shaderPresentOpaqueFrame_data()
1150{
1151 QTest::addColumn<QPainterVideoSurface::ShaderType>(name: "shaderType");
1152
1153#if !defined(QT_OPENGL_ES)
1154 QTest::newRow(dataTag: "ARBfp")
1155 << QPainterVideoSurface::FragmentProgramShader;
1156#endif
1157 QTest::newRow(dataTag: "GLSL")
1158 << QPainterVideoSurface::GlslShader;
1159}
1160
1161void tst_QPainterVideoSurface::shaderPresentOpaqueFrame()
1162{
1163 QFETCH(QPainterVideoSurface::ShaderType, shaderType);
1164
1165 QOpenGLWidget widget;
1166 widget.show();
1167
1168 QVERIFY(QTest::qWaitForWindowExposed(&widget));
1169
1170 if (!widget.context() || !widget.context()->isValid())
1171 QSKIP("Platform does not support GLContext");
1172
1173 QPainterVideoSurface surface;
1174 widget.makeCurrent();
1175 surface.updateGLContext();
1176
1177 if (!(surface.supportedShaderTypes() & shaderType))
1178 QSKIP("Shader type unsupported on this platform");
1179
1180 surface.setShaderType(shaderType);
1181 if (surface.shaderType() != shaderType)
1182 QSKIP("Shader type couldn't be set");
1183
1184 QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
1185
1186 QVERIFY(surface.start(format));
1187 QCOMPARE(surface.isActive(), true);
1188 QCOMPARE(surface.isReady(), true);
1189
1190 QVideoFrame frame(new QtTestOpaqueVideoBuffer, QSize(64, 64), QVideoFrame::Format_RGB32);
1191
1192 if (surface.present(frame)) {
1193 QPainter painter(&widget);
1194 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1195 }
1196
1197 QCOMPARE(surface.isActive(), false);
1198 QCOMPARE(surface.isReady(), false);
1199 QCOMPARE(surface.error(), QAbstractVideoSurface::IncorrectFormatError);
1200}
1201
1202void tst_QPainterVideoSurface::shaderPresentGLFrame_data()
1203{
1204 QTest::addColumn<QPainterVideoSurface::ShaderType>(name: "shaderType");
1205
1206#if !defined(QT_OPENGL_ES)
1207 QTest::newRow(dataTag: "ARBfp")
1208 << QPainterVideoSurface::FragmentProgramShader;
1209#endif
1210 QTest::newRow(dataTag: "GLSL")
1211 << QPainterVideoSurface::GlslShader;
1212}
1213
1214void tst_QPainterVideoSurface::shaderPresentGLFrame()
1215{
1216 QFETCH(QPainterVideoSurface::ShaderType, shaderType);
1217
1218 QOpenGLWidget widget;
1219 widget.show();
1220
1221 QVERIFY(QTest::qWaitForWindowExposed(&widget));
1222
1223 if (!widget.context() || !widget.context()->isValid())
1224 QSKIP("Platform does not support GLContext");
1225
1226 QPainterVideoSurface surface;
1227 widget.makeCurrent();
1228 surface.updateGLContext();
1229
1230 if (!(surface.supportedShaderTypes() & shaderType))
1231 QSKIP("Shader type unsupported on this platform");
1232
1233 surface.setShaderType(shaderType);
1234 if (surface.shaderType() != shaderType)
1235 QSKIP("Shader type couldn't be set");
1236
1237 QVideoSurfaceFormat format(
1238 QSize(2, 2), QVideoFrame::Format_RGB32, QAbstractVideoBuffer::GLTextureHandle);
1239
1240 QVERIFY(surface.start(format));
1241 QCOMPARE(surface.isActive(), true);
1242 QCOMPARE(surface.isReady(), true);
1243
1244 QtTestGLVideoBuffer *buffer = new QtTestGLVideoBuffer;
1245
1246 QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
1247 f->glBindTexture(GL_TEXTURE_2D, texture: buffer->textureId());
1248 f->glTexImage2D(GL_TEXTURE_2D, level: 0, GL_RGB, width: 2, height: 2, border: 0, GL_RGB, GL_UNSIGNED_BYTE, pixels: rgb32ImageData);
1249 f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1250 f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1251 f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1252 f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1253
1254 QVideoFrame frame(buffer, QSize(2, 2), QVideoFrame::Format_RGB32);
1255
1256 QVERIFY(surface.present(frame));
1257
1258 {
1259 QPainter painter(&widget);
1260 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1261 }
1262
1263 QCOMPARE(surface.isActive(), true);
1264 QCOMPARE(surface.isReady(), false);
1265
1266 {
1267 QPainter painter(&widget);
1268 surface.paint(painter: &painter, target: QRect(0, 0, 320, 240));
1269 }
1270
1271 QCOMPARE(surface.isActive(), true);
1272 QCOMPARE(surface.isReady(), false);
1273}
1274
1275#endif
1276
1277QTEST_MAIN(tst_QPainterVideoSurface)
1278
1279#include "tst_qpaintervideosurface.moc"
1280

source code of qtmultimedia/tests/auto/unit/qpaintervideosurface/tst_qpaintervideosurface.cpp