qopenglwidget.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/kernel/qopenglwidget.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3class QOpenGLWidgetPaintDevicePrivate : public QOpenGLPaintDevicePrivate-
4{-
5public:-
6 QOpenGLWidgetPaintDevicePrivate(QOpenGLWidget *widget)-
7 : QOpenGLPaintDevicePrivate(QSize()),-
8 w(widget) { }-
9-
10 void beginPaint() override;-
11-
12 QOpenGLWidget *w;-
13};-
14-
15class QOpenGLWidgetPaintDevice : public QOpenGLPaintDevice-
16{-
17public:-
18 QOpenGLWidgetPaintDevice(QOpenGLWidget *widget)-
19 : QOpenGLPaintDevice(*new QOpenGLWidgetPaintDevicePrivate(widget)) { }-
20 void ensureActiveTarget() override;-
21};-
22-
23class QOpenGLWidgetPrivate : public QWidgetPrivate-
24{-
25 inline QOpenGLWidget* q_func() { return static_cast<QOpenGLWidget *>(q_ptr); } inline const QOpenGLWidget* q_func() const { return static_cast<const QOpenGLWidget *>(q_ptr); } friend class QOpenGLWidget;-
26public:-
27 QOpenGLWidgetPrivate()-
28 : context(0),-
29 fbo(0),-
30 resolvedFbo(0),-
31 surface(0),-
32 initialized(false),-
33 fakeHidden(false),-
34 inBackingStorePaint(false),-
35 hasBeenComposed(false),-
36 flushPending(false),-
37 paintDevice(0),-
38 updateBehavior(QOpenGLWidget::NoPartialUpdate),-
39 requestedSamples(0),-
40 inPaintGL(false)-
41 {-
42 requestedFormat = QSurfaceFormat::defaultFormat();-
43 }-
44-
45 ~QOpenGLWidgetPrivate()-
46 {-
47 reset();-
48 }
never executed: end of block
0
49-
50 void reset();-
51 void recreateFbo();-
52-
53 GLuint textureId() const override;-
54-
55 void initialize();-
56 void invokeUserPaint();-
57 void render();-
58-
59 void invalidateFbo();-
60-
61 QImage grabFramebuffer() override;-
62 void beginBackingStorePainting() override { inBackingStorePaint = true; }-
63 void endBackingStorePainting() override { inBackingStorePaint = false; }-
64 void beginCompose() override;-
65 void endCompose() override;-
66 void initializeViewportFramebuffer() override;-
67 void resizeViewportFramebuffer() override;-
68 void resolveSamples() override;-
69-
70 QOpenGLContext *context;-
71 QOpenGLFramebufferObject *fbo;-
72 QOpenGLFramebufferObject *resolvedFbo;-
73 QOffscreenSurface *surface;-
74 bool initialized;-
75 bool fakeHidden;-
76 bool inBackingStorePaint;-
77 bool hasBeenComposed;-
78 bool flushPending;-
79 QOpenGLPaintDevice *paintDevice;-
80 QSurfaceFormat requestedFormat;-
81 QOpenGLWidget::UpdateBehavior updateBehavior;-
82 int requestedSamples;-
83 bool inPaintGL;-
84};-
85-
86void QOpenGLWidgetPaintDevicePrivate::beginPaint()-
87{-
88-
89-
90-
91-
92 if (w->autoFillBackground()) {-
93 QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();-
94 if (w->format().hasAlpha()) {-
95 f->glClearColor(0, 0, 0, 0);-
96 } else {-
97 QColor c = w->palette().brush(w->backgroundRole()).color();-
98 float alpha = c.alphaF();-
99 f->glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);-
100 }-
101 f->glClear(0x00004000 | 0x00000100 | 0x00000400);-
102 }-
103}-
104-
105void QOpenGLWidgetPaintDevice::ensureActiveTarget()-
106{-
107 QOpenGLWidgetPaintDevicePrivate *d = static_cast<QOpenGLWidgetPaintDevicePrivate *>(d_ptr.data());-
108 QOpenGLWidgetPrivate *wd = static_cast<QOpenGLWidgetPrivate *>(QWidgetPrivate::get(d->w));-
109 if (!wd->initialized)-
110 return;-
111-
112 if (QOpenGLContext::currentContext() != wd->context)-
113 d->w->makeCurrent();-
114 else-
115 wd->fbo->bind();-
116-
117-
118-
119-
120 wd->flushPending = true;-
121}-
122-
123GLuint QOpenGLWidgetPrivate::textureId() const-
124{-
125 return resolvedFbo ? resolvedFbo->texture() : (fbo ? fbo->texture() : 0);-
126}-
127-
128void QOpenGLWidgetPrivate::reset()-
129{-
130 QOpenGLWidget * const q = q_func();-
131-
132-
133 if (initialized)-
134 q->makeCurrent();-
135-
136 delete paintDevice;-
137 paintDevice = 0;-
138 delete fbo;-
139 fbo = 0;-
140 delete resolvedFbo;-
141 resolvedFbo = 0;-
142-
143 if (initialized)-
144 q->doneCurrent();-
145-
146-
147-
148-
149 delete context;-
150 context = 0;-
151 delete surface;-
152 surface = 0;-
153 initialized = fakeHidden = inBackingStorePaint = false;-
154}-
155-
156void QOpenGLWidgetPrivate::recreateFbo()-
157{-
158 QOpenGLWidget * const q = q_func();-
159-
160 q->aboutToResize();-
161-
162 context->makeCurrent(surface);-
163-
164 delete fbo;-
165 fbo = 0;-
166 delete resolvedFbo;-
167 resolvedFbo = 0;-
168-
169 int samples = requestedSamples;-
170 QOpenGLExtensions *extfuncs = static_cast<QOpenGLExtensions *>(context->functions());-
171 if (!extfuncs->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))-
172 samples = 0;-
173-
174 QOpenGLFramebufferObjectFormat format;-
175 format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);-
176 format.setSamples(samples);-
177-
178 const QSize deviceSize = q->size() * q->devicePixelRatioF();-
179 fbo = new QOpenGLFramebufferObject(deviceSize, format);-
180 if (samples > 0)-
181 resolvedFbo = new QOpenGLFramebufferObject(deviceSize);-
182-
183 fbo->bind();-
184 context->functions()->glClear(0x00004000 | 0x00000100 | 0x00000400);-
185-
186 paintDevice->setSize(deviceSize);-
187 paintDevice->setDevicePixelRatio(q->devicePixelRatioF());-
188-
189 q->resized();-
190}-
191-
192void QOpenGLWidgetPrivate::beginCompose()-
193{-
194 QOpenGLWidget * const q = q_func();-
195 if (flushPending) {-
196 flushPending = false;-
197 q->makeCurrent();-
198 static_cast<QOpenGLExtensions *>(context->functions())->flushShared();-
199 }-
200 hasBeenComposed = true;-
201 q->aboutToCompose();-
202}-
203-
204void QOpenGLWidgetPrivate::endCompose()-
205{-
206 QOpenGLWidget * const q = q_func();-
207 q->frameSwapped();-
208}-
209-
210void QOpenGLWidgetPrivate::initialize()-
211{-
212 QOpenGLWidget * const q = q_func();-
213 if (initialized
initializedDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
214 return;
never executed: return;
0
215-
216-
217-
218 QWidget *tlw = q->window();-
219 QOpenGLContext *shareContext = get(tlw)->shareContext();-
220 if (!(__builtin_expect(!!(!
__builtin_expe...ntext), false)Description
TRUEnever evaluated
FALSEnever evaluated
shareContext)), false)
__builtin_expe...ntext), false)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
221 QMessageLogger(__FILE__, 739750, __PRETTY_FUNCTION__).warning("QOpenGLWidget: Cannot be used without a context shared with the toplevel.");-
222 return;
never executed: return;
0
223 }-
224-
225-
226-
227-
228-
229 requestedSamples = requestedFormat.samples();-
230 requestedFormat.setSamples(0);-
231-
232 QScopedPointer<QOpenGLContext> ctx(new QOpenGLContext);-
233 ctx->setShareContext(shareContext);-
234 ctx->setFormat(requestedFormat);-
235 ctx->setScreen(shareContext->screen());-
236 if (!(__builtin_expect(!!(!
__builtin_expe...ate()), false)Description
TRUEnever evaluated
FALSEnever evaluated
ctx->create())()), false)
__builtin_expe...ate()), false)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
237 QMessageLogger(__FILE__, 755766, __PRETTY_FUNCTION__).warning("QOpenGLWidget: Failed to create context");-
238 return;
never executed: return;
0
239 }-
240-
241-
242 QSurfaceFormat tlwFormat = tlw->windowHandle()->format();-
243 if (requestedFormat.swapInterval() != tlwFormat.swapInterval()
requestedForma...swapInterval()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
244-
245-
246 tlwFormat.setSwapInterval(requestedFormat.swapInterval());-
247 tlw->windowHandle()->setFormat(tlwFormat);-
248 }
never executed: end of block
0
249 if (requestedFormat.swapBehavior() != tlwFormat.swapBehavior()
requestedForma...swapBehavior()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
250 tlwFormat.setSwapBehavior(requestedFormat.swapBehavior());-
251 tlw->windowHandle()->setFormat(tlwFormat);-
252 }
never executed: end of block
0
253-
254-
255-
256-
257 surface = new QOffscreenSurface;-
258 surface->setFormat(ctx->format());-
259 surface->setScreen(ctx->screen());-
260 surface->create();-
261-
262 if (!(__builtin_expect(!!(!
__builtin_expe...face)), false)Description
TRUEnever evaluated
FALSEnever evaluated
ctx->makeCurrent(surface)), false)
__builtin_expe...face)), false)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
263 QMessageLogger(__FILE__, 781792, __PRETTY_FUNCTION__).warning("QOpenGLWidget: Failed to make context current");-
264 return;
never executed: return;
0
265 }-
266-
267 paintDevice = new QOpenGLWidgetPaintDevice(q);-
268 paintDevice->setSize(q->size() * q->devicePixelRatioF());-
269 paintDevice->setDevicePixelRatio(q->devicePixelRatioF());-
270-
271 context = ctx.take();-
272 initialized = true;-
273-
274 q->initializeGL();-
275}
never executed: end of block
0
276-
277void QOpenGLWidgetPrivate::resolveSamples()-
278{-
279 QOpenGLWidget * const q = q_func();-
280 if (resolvedFbo) {-
281 q->makeCurrent();-
282 QRect rect(QPoint(0, 0), fbo->size());-
283 QOpenGLFramebufferObject::blitFramebuffer(resolvedFbo, rect, fbo, rect);-
284 flushPending = true;-
285 }-
286}-
287-
288void QOpenGLWidgetPrivate::invokeUserPaint()-
289{-
290 QOpenGLWidget * const q = q_func();-
291-
292 QOpenGLContext *ctx = QOpenGLContext::currentContext();-
293 ((!(ctx && fbo)) ? qt_assert("ctx && fbo",__FILE__,811822) : qt_noop());-
294-
295 QOpenGLFunctions *f = ctx->functions();-
296 QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbo->handle();-
297-
298 f->glViewport(0, 0, q->width() * q->devicePixelRatioF(), q->height() * q->devicePixelRatioF());-
299 inPaintGL = true;-
300 q->paintGL();-
301 inPaintGL = false;-
302 flushPending = true;-
303-
304 QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = 0;-
305}-
306-
307void QOpenGLWidgetPrivate::render()-
308{-
309 QOpenGLWidget * const q = q_func();-
310-
311 if (fakeHidden || !initialized)-
312 return;-
313-
314 q->makeCurrent();-
315-
316 if (updateBehavior == QOpenGLWidget::NoPartialUpdate && hasBeenComposed) {-
317 invalidateFbo();-
318 hasBeenComposed = false;-
319 }-
320-
321 invokeUserPaint();-
322}-
323-
324void QOpenGLWidgetPrivate::invalidateFbo()-
325{-
326 QOpenGLExtensions *f = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions());-
327 if (f->hasOpenGLExtension(QOpenGLExtensions::DiscardFramebuffer)) {-
328 const int gl_color_attachment0 = 0x8CE0;-
329 const int gl_depth_attachment = 0x8D00;-
330 const int gl_stencil_attachment = 0x8D20;-
331 const GLenum attachments[] = {-
332 gl_color_attachment0, gl_depth_attachment, gl_stencil_attachment-
333 };-
334 f->glDiscardFramebufferEXT(0x8D40, sizeof attachments / sizeof *attachments, attachments);-
335 } else {-
336 f->glClear(0x00004000 | 0x00000100 | 0x00000400);-
337 }-
338}-
339-
340extern __attribute__((visibility("default"))) QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);-
341-
342QImage QOpenGLWidgetPrivate::grabFramebuffer()-
343{-
344 QOpenGLWidget * const q = q_func();-
345 if (!initialized)-
346 return QImage();-
347-
348 if (!inPaintGL)-
349 render();-
350-
351 if (resolvedFbo) {-
352 resolveSamples();-
353 resolvedFbo->bind();-
354 } else {-
355 q->makeCurrent();-
356 }-
357-
358 QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatioF(), false, false);-
359 res.setDevicePixelRatio(q->devicePixelRatioF());-
360-
361-
362-
363-
364 if (resolvedFbo)-
365 q->makeCurrent();-
366-
367 return res;-
368}-
369-
370void QOpenGLWidgetPrivate::initializeViewportFramebuffer()-
371{-
372 QOpenGLWidget * const q = q_func();-
373-
374-
375 q->setAutoFillBackground(true);-
376}-
377-
378void QOpenGLWidgetPrivate::resizeViewportFramebuffer()-
379{-
380 QOpenGLWidget * const q = q_func();-
381 if (!initialized)-
382 return;-
383-
384 if (!fbo || q->size() * q->devicePixelRatioF() != fbo->size()) {-
385 recreateFbo();-
386 q->update();-
387 }-
388}-
389-
390-
391-
392-
393QOpenGLWidget::QOpenGLWidget(QWidget *parent, Qt::WindowFlags f)-
394 : QWidget(*(new QOpenGLWidgetPrivate), parent, f)-
395{-
396 QOpenGLWidgetPrivate * const d = d_func();-
397 if (__builtin_expect(!!(!
__builtin_expe...face)), false)Description
TRUEnever evaluated
FALSEnever evaluated
QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RasterGLSurface)), false)
__builtin_expe...face)), false)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
398 d->setRenderToTexture();0
elseQMessageLogger(__FILE__, 918927, __PRETTY_FUNCTION__).warning("QOpenGLWidget is not supported on this platform.");
never executed: QMessageLogger(__FILE__, 927, __PRETTY_FUNCTION__).warning("QOpenGLWidget is not supported on this platform.");
399 else-
400 d->setRenderToTexture();
never executed: d->setRenderToTexture();
0
401}-
402QOpenGLWidget::~QOpenGLWidget()-
403{-
404 QOpenGLWidgetPrivate * const d = d_func();-
d->resetmakeCurrent();
405}
never executed: end of block
0
406-
407-
408-
409-
410-
411void QOpenGLWidget::setUpdateBehavior(UpdateBehavior updateBehavior)-
412{-
413 QOpenGLWidgetPrivate * const d = d_func();-
414 d->updateBehavior = updateBehavior;-
415}-
416-
417-
418-
419-
420-
421QOpenGLWidget::UpdateBehavior QOpenGLWidget::updateBehavior() const-
422{-
423 const QOpenGLWidgetPrivate * const d = d_func();-
424 return d->updateBehavior;-
425}-
426void QOpenGLWidget::setFormat(const QSurfaceFormat &format)-
427{-
428 (void)format;;-
429 QOpenGLWidgetPrivate * const d = d_func();-
430 if (__builtin_expect(!!(
__builtin_expe...lized), false)Description
TRUEnever evaluated
FALSEnever evaluated
d->initialized)), false)
__builtin_expe...lized), false)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
431 QMessageLogger(__FILE__, 986996, __PRETTY_FUNCTION__).warning("QOpenGLWidget: Already initialized, setting the format has no effect");-
432 return;
never executed: return;
0
433 }-
434-
435 d->requestedFormat = format;-
436}
never executed: end of block
0
437QSurfaceFormat QOpenGLWidget::format() const-
438{-
439 const QOpenGLWidgetPrivate * const d = d_func();-
440 return d->initialized ? d->context->format() : d->requestedFormat;-
441}-
442-
443-
444-
445-
446-
447-
448bool QOpenGLWidget::isValid() const-
449{-
450 const QOpenGLWidgetPrivate * const d = d_func();-
451 return d->initialized && d->context->isValid();-
452}-
453void QOpenGLWidget::makeCurrent()-
454{-
455 QOpenGLWidgetPrivate * const d = d_func();-
456 if (!d->initialized)-
457 return;-
458-
459 d->context->makeCurrent(d->surface);-
460-
461 if (d->fbo)-
462 d->fbo->bind();-
463}-
464void QOpenGLWidget::doneCurrent()-
465{-
466 QOpenGLWidgetPrivate * const d = d_func();-
467 if (!d->initialized)-
468 return;-
469-
470 d->context->doneCurrent();-
471}-
472QOpenGLContext *QOpenGLWidget::context() const-
473{-
474 const QOpenGLWidgetPrivate * const d = d_func();-
475 return d->context;-
476}-
477GLuint QOpenGLWidget::defaultFramebufferObject() const-
478{-
479 const QOpenGLWidgetPrivate * const d = d_func();-
480 return d->fbo ? d->fbo->handle() : 0;-
481}-
482void QOpenGLWidget::initializeGL()-
483{-
484}-
485void QOpenGLWidget::resizeGL(int w, int h)-
486{-
487 (void)w;;-
488 (void)h;;-
489}-
490void QOpenGLWidget::paintGL()-
491{-
492}-
493void QOpenGLWidget::resizeEvent(QResizeEvent *e)-
494{-
495 QOpenGLWidgetPrivate * const d = d_func();-
496-
497 if (e->size().isEmpty()) {-
498 d->fakeHidden = true;-
499 return;-
500 }-
501 d->fakeHidden = false;-
502-
503 d->initialize();-
504 if (!d->initialized)-
505 return;-
506-
507 d->recreateFbo();-
508 resizeGL(width(), height());-
509 d->sendPaintEvent(QRect(QPoint(0, 0), size()));-
510}-
511void QOpenGLWidget::paintEvent(QPaintEvent *e)-
512{-
513 (void)e;;-
514 QOpenGLWidgetPrivate * const d = d_func();-
515 if (!d->initialized)-
516 return;-
517-
518 if (updatesEnabled())-
519 d->render();-
520}-
521-
522-
523-
524-
525-
526-
527-
528QImage QOpenGLWidget::grabFramebuffer()-
529{-
530 QOpenGLWidgetPrivate * const d = d_func();-
531 return d->grabFramebuffer();-
532}-
533-
534-
535-
536-
537int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const-
538{-
539 const QOpenGLWidgetPrivate * const d = d_func();-
540 if (d->inBackingStorePaint)-
541 return QWidget::metric(metric);-
542-
543 QWidget *tlw = window();-
544 QWindow *window = tlw ? tlw->windowHandle() : 0;-
545 QScreen *screen = tlw && tlw->windowHandle() ? tlw->windowHandle()->screen() : 0;-
546 if (!screen && QGuiApplication::primaryScreen())-
547 screen = QGuiApplication::primaryScreen();-
548-
549 const float dpmx = qt_defaultDpiX() * 100. / 2.54;-
550 const float dpmy = qt_defaultDpiY() * 100. / 2.54;-
551-
552 switch (metric) {-
553 case PdmWidth:-
554 return width();-
555 case PdmHeight:-
556 return height();-
557 case PdmDepth:-
558 return 32;-
559 case PdmWidthMM:-
560 if (screen)-
561 return width() * screen->physicalSize().width() / screen->geometry().width();-
562 else-
563 return width() * 1000 / dpmx;-
564 case PdmHeightMM:-
565 if (screen)-
566 return height() * screen->physicalSize().height() / screen->geometry().height();-
567 else-
568 return height() * 1000 / dpmy;-
569 case PdmNumColors:-
570 return 0;-
571 case PdmDpiX:-
572 if (screen)-
573 return qRound(screen->logicalDotsPerInchX());-
574 else-
575 return qRound(dpmx * 0.0254);-
576 case PdmDpiY:-
577 if (screen)-
578 return qRound(screen->logicalDotsPerInchY());-
579 else-
580 return qRound(dpmy * 0.0254);-
581 case PdmPhysicalDpiX:-
582 if (screen)-
583 return qRound(screen->physicalDotsPerInchX());-
584 else-
585 return qRound(dpmx * 0.0254);-
586 case PdmPhysicalDpiY:-
587 if (screen)-
588 return qRound(screen->physicalDotsPerInchY());-
589 else-
590 return qRound(dpmy * 0.0254);-
591 case PdmDevicePixelRatio:-
592 if (window)-
593 return int(window->devicePixelRatio());-
594 else-
595 return 1.0;-
596 case PdmDevicePixelRatioScaled:-
597 if (window)-
598 return int(window->devicePixelRatio() * devicePixelRatioFScale());-
599 else-
600 return 1.0;-
601 default:-
602 QMessageLogger(__FILE__, 12781288, __PRETTY_FUNCTION__).warning("QOpenGLWidget::metric(): unknown metric %d", metric);-
603 return 0;-
604 }-
605}-
606-
607-
608-
609-
610QPaintDevice *QOpenGLWidget::redirected(QPoint *p) const-
611{-
612 const QOpenGLWidgetPrivate * const d = d_func();-
613 if (d->inBackingStorePaint)-
614 return QWidget::redirected(p);-
615-
616 return d->paintDevice;-
617}-
618-
619-
620-
621-
622QPaintEngine *QOpenGLWidget::paintEngine() const-
623{-
624 const QOpenGLWidgetPrivate * const d = d_func();-
625-
626-
627-
628 if (d->inBackingStorePaint)-
629 return QWidget::paintEngine();-
630-
631 if (!d->initialized)-
632 return 0;-
633-
634 return d->paintDevice->paintEngine();-
635}-
636-
637-
638-
639-
640bool QOpenGLWidget::event(QEvent *e)-
641{-
642 QOpenGLWidgetPrivate * const d = d_func();-
643 switch (e->type()) {-
644 case QEvent::WindowChangeInternal:-
645 if ((static_cast<QGuiApplication *>(QCoreApplication::instance()))->testAttribute(Qt::AA_ShareOpenGLContexts))-
646 break;-
647 if (d->initialized)-
648 d->reset();-
649-
650 case QEvent::Show:-
651 if (!d->initialized && !size().isEmpty() && window() && window()->windowHandle()) {-
652 d->initialize();-
653 if (d->initialized)-
654 d->recreateFbo();-
655 }-
656 break;-
657 case QEvent::ScreenChangeInternal:-
658 if (d->initialized && d->paintDevice->devicePixelRatioF() != devicePixelRatioF())-
659 d->recreateFbo();-
660 break;-
661 default:-
662 break;-
663 }-
664 return QWidget::event(e);-
665}-
666-
667-
668-
Switch to Source codePreprocessed file

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