qopenglwindow.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/kernel/qopenglwindow.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
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 http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://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 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qopenglwindow.h"-
35#include "qpaintdevicewindow_p.h"-
36#include <QtGui/QOpenGLFramebufferObject>-
37#include <QtGui/QOpenGLPaintDevice>-
38#include <QtGui/QOpenGLFunctions>-
39#include <QtGui/private/qopengltextureblitter_p.h>-
40#include <QtGui/private/qopenglextensions_p.h>-
41#include <QtGui/private/qopenglcontext_p.h>-
42#include <QtGui/QMatrix4x4>-
43#include <QtGui/QOffscreenSurface>-
44-
45QT_BEGIN_NAMESPACE-
46-
47/*!-
48 \class QOpenGLWindow-
49 \inmodule QtGui-
50 \since 5.4-
51 \brief The QOpenGLWindow class is a convenience subclass of QWindow to perform OpenGL painting.-
52-
53 QOpenGLWindow is an enhanced QWindow that allows easily creating windows that-
54 perform OpenGL rendering using an API that is compatible with QOpenGLWidget-
55 and is similar to the legacy QGLWidget. Unlike QOpenGLWidget, QOpenGLWindow-
56 has no dependency on the widgets module and offers better performance.-
57-
58 A typical application will subclass QOpenGLWindow and reimplement the following-
59 virtual functions:-
60-
61 \list-
62-
63 \li initializeGL() to perform OpenGL resource initialization-
64-
65 \li resizeGL() to set up the transformation matrices and other window size dependent resources-
66-
67 \li paintGL() to issue OpenGL commands or draw using QPainter-
68-
69 \endlist-
70-
71 To schedule a repaint, call the update() function. Note that this will not-
72 immediately result in a call to paintGL(). Calling update() multiple times in-
73 a row will not change the behavior in any way.-
74-
75 This is a slot so it can be connected to a \l QTimer::timeout() signal to-
76 perform animation. Note however that in the modern OpenGL world it is a much-
77 better choice to rely on synchronization to the vertical refresh rate of the-
78 display. See \l{QSurfaceFormat::setSwapInterval()}{setSwapInterval()} on a-
79 description of the swap interval. With a swap interval of \c 1, which is the-
80 case on most systems by default, the-
81 \l{QOpenGLContext::swapBuffers()}{swapBuffers()} call, that is executed-
82 internally by QOpenGLWindow after each repaint, will block and wait for-
83 vsync. This means that whenever the swap is done, an update can be scheduled-
84 again by calling update(), without relying on timers.-
85-
86 To request a specific configuration for the context, use setFormat()-
87 like for any other QWindow. This allows, among others, requesting a-
88 given OpenGL version and profile, or enabling depth and stencil-
89 buffers.-
90-
91 Unlike QWindow, QOpenGLWindow allows opening a painter on itself and perform-
92 QPainter-based drawing.-
93-
94 QOpenGLWindow supports multiple update behaviors. The default,-
95 \c NoPartialUpdate is equivalent to a regular, OpenGL-based QWindow or the-
96 legacy QGLWidget. In contrast, \c PartialUpdateBlit and \c PartialUpdateBlend are-
97 more in line with QOpenGLWidget's way of working, where there is always an-
98 extra, dedicated framebuffer object present. These modes allow, by-
99 sacrificing some performance, redrawing only a smaller area on each paint and-
100 having the rest of the content preserved from of the previous frame. This is-
101 useful for applications than render incrementally using QPainter, because-
102 this way they do not have to redraw the entire window content on each-
103 paintGL() call.-
104-
105 Similarly to QOpenGLWidget, QOpenGLWindow supports the Qt::AA_ShareOpenGLContexts-
106 attribute. When enabled, the OpenGL contexts of all QOpenGLWindow instances will share-
107 with each other. This allows accessing each other's shareable OpenGL resources.-
108-
109 For more information on graphics in Qt, see \l {Graphics}.-
110 */-
111-
112/*!-
113 \enum QOpenGLWindow::UpdateBehavior-
114-
115 This enum describes the update strategy of the QOpenGLWindow.-
116-
117 \value NoPartialUpdate Indicates that the entire window surface will-
118 redrawn on each update and so no additional framebuffers are needed.-
119 This is the setting used in most cases and is equivalent to how drawing-
120 directly via QWindow would function.-
121-
122 \value PartialUpdateBlit Indicates that the drawing performed in paintGL()-
123 does not cover the entire window. In this case an extra framebuffer object-
124 is created under the hood, and rendering performed in paintGL() will target-
125 this framebuffer. This framebuffer is then blitted onto the window surface's-
126 default framebuffer after each paint. This allows having QPainter-based drawing-
127 code in paintGL() which only repaints a smaller area at a time, because, unlike-
128 NoPartialUpdate, the previous content is preserved.-
129-
130 \value PartialUpdateBlend Similar to PartialUpdateBlit, but instead of using-
131 framebuffer blits, the contents of the extra framebuffer is rendered by-
132 drawing a textured quad with blending enabled. This, unlike PartialUpdateBlit,-
133 allows alpha blended content and works even when the glBlitFramebuffer is-
134 not available. Performance-wise this setting is likely to be somewhat slower-
135 than PartialUpdateBlit.-
136 */-
137-
138/*!-
139 \fn void QOpenGLWindow::frameSwapped()-
140-
141 This signal is emitted after the potentially blocking-
142 \l{QOpenGLContext::swapBuffers()}{buffer swap} has been done. Applications-
143 that wish to continuously repaint synchronized to the vertical refresh,-
144 should issue an update() upon this signal. This allows for a much smoother-
145 experience compared to the traditional usage of timers.-
146*/-
147-
148// GLES2 builds won't have these constants with the suffixless names-
149#ifndef GL_READ_FRAMEBUFFER-
150#define GL_READ_FRAMEBUFFER 0x8CA8-
151#endif-
152#ifndef GL_DRAW_FRAMEBUFFER-
153#define GL_DRAW_FRAMEBUFFER 0x8CA9-
154#endif-
155-
156class QOpenGLWindowPaintDevice : public QOpenGLPaintDevice-
157{-
158public:-
159 QOpenGLWindowPaintDevice(QOpenGLWindow *window) : m_window(window) { }
never executed: end of block
0
160 void ensureActiveTarget() Q_DECL_OVERRIDE;-
161-
162 QOpenGLWindow *m_window;-
163};-
164-
165class QOpenGLWindowPrivate : public QPaintDeviceWindowPrivate-
166{-
167 Q_DECLARE_PUBLIC(QOpenGLWindow)-
168public:-
169 QOpenGLWindowPrivate(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior)-
170 : updateBehavior(updateBehavior)-
171 , hasFboBlit(false)-
172 , shareContext(shareContext)-
173 {-
174 if (!shareContext)
!shareContextDescription
TRUEnever evaluated
FALSEnever evaluated
0
175 this->shareContext = qt_gl_global_share_context();
never executed: this->shareContext = qt_gl_global_share_context();
0
176 }
never executed: end of block
0
177-
178 ~QOpenGLWindowPrivate();-
179-
180 static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); }
never executed: return w->d_func();
0
181-
182 void bindFBO();-
183 void initialize();-
184-
185 void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;-
186 void endPaint() Q_DECL_OVERRIDE;-
187 void flush(const QRegion &region) Q_DECL_OVERRIDE;-
188-
189 QOpenGLWindow::UpdateBehavior updateBehavior;-
190 bool hasFboBlit;-
191 QScopedPointer<QOpenGLContext> context;-
192 QOpenGLContext *shareContext;-
193 QScopedPointer<QOpenGLFramebufferObject> fbo;-
194 QScopedPointer<QOpenGLWindowPaintDevice> paintDevice;-
195 QOpenGLTextureBlitter blitter;-
196 QColor backgroundColor;-
197 QScopedPointer<QOffscreenSurface> offscreenSurface;-
198};-
199-
200QOpenGLWindowPrivate::~QOpenGLWindowPrivate()-
201{-
202 Q_Q(QOpenGLWindow);-
203 if (q->isValid()) {
q->isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
204 q->makeCurrent(); // this works even when the platformwindow is destroyed-
205 paintDevice.reset(0);-
206 fbo.reset(0);-
207 blitter.destroy();-
208 q->doneCurrent();-
209 }
never executed: end of block
0
210}
never executed: end of block
0
211-
212void QOpenGLWindowPrivate::initialize()-
213{-
214 Q_Q(QOpenGLWindow);-
215-
216 if (context)
contextDescription
TRUEnever evaluated
FALSEnever evaluated
0
217 return;
never executed: return;
0
218-
219 context.reset(new QOpenGLContext);-
220 context->setShareContext(shareContext);-
221 context->setFormat(q->requestedFormat());-
222 if (!context->create())
!context->create()Description
TRUEnever evaluated
FALSEnever evaluated
0
223 qWarning("QOpenGLWindow::beginPaint: Failed to create context");
never executed: QMessageLogger(__FILE__, 223, __PRETTY_FUNCTION__).warning("QOpenGLWindow::beginPaint: Failed to create context");
0
224 if (!context->makeCurrent(q))
!context->makeCurrent(q)Description
TRUEnever evaluated
FALSEnever evaluated
0
225 qWarning("QOpenGLWindow::beginPaint: Failed to make context current");
never executed: QMessageLogger(__FILE__, 225, __PRETTY_FUNCTION__).warning("QOpenGLWindow::beginPaint: Failed to make context current");
0
226-
227 paintDevice.reset(new QOpenGLWindowPaintDevice(q));-
228 if (updateBehavior == QOpenGLWindow::PartialUpdateBlit)
updateBehavior...tialUpdateBlitDescription
TRUEnever evaluated
FALSEnever evaluated
0
229 hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit();
never executed: hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit();
0
230-
231 q->initializeGL();-
232}
never executed: end of block
0
233-
234void QOpenGLWindowPrivate::beginPaint(const QRegion &region)-
235{-
236 Q_UNUSED(region);-
237 Q_Q(QOpenGLWindow);-
238-
239 initialize();-
240 context->makeCurrent(q);-
241-
242 const int deviceWidth = q->width() * q->devicePixelRatio();-
243 const int deviceHeight = q->height() * q->devicePixelRatio();-
244 const QSize deviceSize(deviceWidth, deviceHeight);-
245 if (updateBehavior > QOpenGLWindow::NoPartialUpdate) {
updateBehavior...oPartialUpdateDescription
TRUEnever evaluated
FALSEnever evaluated
0
246 if (!fbo || fbo->size() != deviceSize) {
!fboDescription
TRUEnever evaluated
FALSEnever evaluated
fbo->size() != deviceSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
247 QOpenGLFramebufferObjectFormat fboFormat;-
248 fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);-
249 if (q->requestedFormat().samples() > 0) {
q->requestedFo....samples() > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
250 if (updateBehavior != QOpenGLWindow::PartialUpdateBlend)
updateBehavior...ialUpdateBlendDescription
TRUEnever evaluated
FALSEnever evaluated
0
251 fboFormat.setSamples(q->requestedFormat().samples());
never executed: fboFormat.setSamples(q->requestedFormat().samples());
0
252 else-
253 qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling");
never executed: QMessageLogger(__FILE__, 253, __PRETTY_FUNCTION__).warning("QOpenGLWindow: PartialUpdateBlend does not support multisampling");
0
254 }-
255 fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat));-
256 markWindowAsDirty();-
257 }
never executed: end of block
0
258 } else {
never executed: end of block
0
259 markWindowAsDirty();-
260 }
never executed: end of block
0
261-
262 paintDevice->setSize(QSize(deviceWidth, deviceHeight));-
263 paintDevice->setDevicePixelRatio(q->devicePixelRatio());-
264 context->functions()->glViewport(0, 0, deviceWidth, deviceHeight);-
265-
266 context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());-
267-
268 q->paintUnderGL();-
269-
270 if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
updateBehavior...oPartialUpdateDescription
TRUEnever evaluated
FALSEnever evaluated
0
271 fbo->bind();
never executed: fbo->bind();
0
272}
never executed: end of block
0
273-
274void QOpenGLWindowPrivate::endPaint()-
275{-
276 Q_Q(QOpenGLWindow);-
277-
278 if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
updateBehavior...oPartialUpdateDescription
TRUEnever evaluated
FALSEnever evaluated
0
279 fbo->release();
never executed: fbo->release();
0
280-
281 context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());-
282-
283 if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) {
updateBehavior...tialUpdateBlitDescription
TRUEnever evaluated
FALSEnever evaluated
hasFboBlitDescription
TRUEnever evaluated
FALSEnever evaluated
0
284 const int deviceWidth = q->width() * q->devicePixelRatio();-
285 const int deviceHeight = q->height() * q->devicePixelRatio();-
286 QOpenGLExtensions extensions(context.data());-
287 extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle());-
288 extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject());-
289 extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight,-
290 0, 0, deviceWidth, deviceHeight,-
291 GL_COLOR_BUFFER_BIT, GL_NEAREST);-
292 } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) {
never executed: end of block
updateBehavior...oPartialUpdateDescription
TRUEnever evaluated
FALSEnever evaluated
0
293 if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) {
updateBehavior...ialUpdateBlendDescription
TRUEnever evaluated
FALSEnever evaluated
0
294 context->functions()->glEnable(GL_BLEND);-
295 context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);-
296 }
never executed: end of block
0
297 if (!blitter.isCreated())
!blitter.isCreated()Description
TRUEnever evaluated
FALSEnever evaluated
0
298 blitter.create();
never executed: blitter.create();
0
299-
300 QRect windowRect(QPoint(0, 0), fbo->size());-
301 QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);-
302 blitter.bind();-
303 blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft);-
304 blitter.release();-
305-
306 if (updateBehavior == QOpenGLWindow::PartialUpdateBlend)
updateBehavior...ialUpdateBlendDescription
TRUEnever evaluated
FALSEnever evaluated
0
307 context->functions()->glDisable(GL_BLEND);
never executed: context->functions()->glDisable(0x0BE2);
0
308 }
never executed: end of block
0
309-
310 q->paintOverGL();-
311}
never executed: end of block
0
312-
313void QOpenGLWindowPrivate::bindFBO()-
314{-
315 if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
updateBehavior...oPartialUpdateDescription
TRUEnever evaluated
FALSEnever evaluated
0
316 fbo->bind();
never executed: fbo->bind();
0
317 else-
318 QOpenGLFramebufferObject::bindDefault();
never executed: QOpenGLFramebufferObject::bindDefault();
0
319}-
320-
321void QOpenGLWindowPrivate::flush(const QRegion &region)-
322{-
323 Q_UNUSED(region);-
324 Q_Q(QOpenGLWindow);-
325 context->swapBuffers(q);-
326 emit q->frameSwapped();-
327}
never executed: end of block
0
328-
329void QOpenGLWindowPaintDevice::ensureActiveTarget()-
330{-
331 QOpenGLWindowPrivate::get(m_window)->bindFBO();-
332}
never executed: end of block
0
333-
334/*!-
335 Constructs a new QOpenGLWindow with the given \a parent and \a updateBehavior.-
336-
337 \sa QOpenGLWindow::UpdateBehavior-
338 */-
339QOpenGLWindow::QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior, QWindow *parent)-
340 : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(Q_NULLPTR, updateBehavior)), parent)-
341{-
342 setSurfaceType(QSurface::OpenGLSurface);-
343}
never executed: end of block
0
344-
345/*!-
346 Constructs a new QOpenGLWindow with the given \a parent and \a updateBehavior. The QOpenGLWindow's context will share with \a shareContext.-
347-
348 \sa QOpenGLWindow::UpdateBehavior shareContext-
349*/-
350QOpenGLWindow::QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior, QWindow *parent)-
351 : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(shareContext, updateBehavior)), parent)-
352{-
353 setSurfaceType(QSurface::OpenGLSurface);-
354}
never executed: end of block
0
355-
356/*!-
357 Destroys the QOpenGLWindow instance, freeing its resources.-
358-
359 The OpenGLWindow's context is made current in the destructor, allowing for-
360 safe destruction of any child object that may need to release OpenGL-
361 resources belonging to the context provided by this window.-
362-
363 \warning if you have objects wrapping OpenGL resources (such as-
364 QOpenGLBuffer, QOpenGLShaderProgram, etc.) as members of a QOpenGLWindow-
365 subclass, you may need to add a call to makeCurrent() in that subclass'-
366 destructor as well. Due to the rules of C++ object destruction, those objects-
367 will be destroyed \e{before} calling this function (but after that the-
368 destructor of the subclass has run), therefore making the OpenGL context-
369 current in this function happens too late for their safe disposal.-
370-
371 \sa makeCurrent-
372-
373 \since 5.5-
374*/-
375QOpenGLWindow::~QOpenGLWindow()-
376{-
377 makeCurrent();-
378}
never executed: end of block
0
379-
380/*!-
381 \return the update behavior for this QOpenGLWindow.-
382*/-
383QOpenGLWindow::UpdateBehavior QOpenGLWindow::updateBehavior() const-
384{-
385 Q_D(const QOpenGLWindow);-
386 return d->updateBehavior;
never executed: return d->updateBehavior;
0
387}-
388-
389/*!-
390 \return \c true if the window's OpenGL resources, like the context, have-
391 been successfully initialized. Note that the return value is always \c false-
392 until the window becomes exposed (shown).-
393*/-
394bool QOpenGLWindow::isValid() const-
395{-
396 Q_D(const QOpenGLWindow);-
397 return d->context && d->context->isValid();
never executed: return d->context && d->context->isValid();
d->contextDescription
TRUEnever evaluated
FALSEnever evaluated
d->context->isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
398}-
399-
400/*!-
401 Prepares for rendering OpenGL content for this window by making the-
402 corresponding context current and binding the framebuffer object, if there is-
403 one, in that context context.-
404-
405 It is not necessary to call this function in most cases, because it is called-
406 automatically before invoking paintGL(). It is provided nonetheless to support-
407 advanced, multi-threaded scenarios where a thread different than the GUI or main-
408 thread may want to update the surface or framebuffer contents. See QOpenGLContext-
409 for more information on threading related issues.-
410-
411 This function is suitable for calling also when the underlying platform window-
412 is already destroyed. This means that it is safe to call this function from-
413 a QOpenGLWindow subclass' destructor. If there is no native window anymore,-
414 an offscreen surface is used instead. This ensures that OpenGL resource-
415 cleanup operations in the destructor will always work, as long as-
416 this function is called first.-
417-
418 \sa QOpenGLContext, context(), paintGL(), doneCurrent()-
419 */-
420void QOpenGLWindow::makeCurrent()-
421{-
422 Q_D(QOpenGLWindow);-
423-
424 if (!isValid())
!isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
425 return;
never executed: return;
0
426-
427 // The platform window may be destroyed at this stage and therefore-
428 // makeCurrent() may not safely be called with 'this'.-
429 if (handle()) {
handle()Description
TRUEnever evaluated
FALSEnever evaluated
0
430 d->context->makeCurrent(this);-
431 } else {
never executed: end of block
0
432 if (!d->offscreenSurface) {
!d->offscreenSurfaceDescription
TRUEnever evaluated
FALSEnever evaluated
0
433 d->offscreenSurface.reset(new QOffscreenSurface);-
434 d->offscreenSurface->setFormat(d->context->format());-
435 d->offscreenSurface->create();-
436 }
never executed: end of block
0
437 d->context->makeCurrent(d->offscreenSurface.data());-
438 }
never executed: end of block
0
439-
440 d->bindFBO();-
441}
never executed: end of block
0
442-
443/*!-
444 Releases the context.-
445-
446 It is not necessary to call this function in most cases, since the widget-
447 will make sure the context is bound and released properly when invoking-
448 paintGL().-
449-
450 \sa makeCurrent()-
451 */-
452void QOpenGLWindow::doneCurrent()-
453{-
454 Q_D(QOpenGLWindow);-
455-
456 if (!isValid())
!isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
457 return;
never executed: return;
0
458-
459 d->context->doneCurrent();-
460}
never executed: end of block
0
461-
462/*!-
463 \return The QOpenGLContext used by this window or \c 0 if not yet initialized.-
464 */-
465QOpenGLContext *QOpenGLWindow::context() const-
466{-
467 Q_D(const QOpenGLWindow);-
468 return d->context.data();
never executed: return d->context.data();
0
469}-
470-
471/*!-
472 \return The QOpenGLContext requested to be shared with this window's QOpenGLContext.-
473*/-
474QOpenGLContext *QOpenGLWindow::shareContext() const-
475{-
476 Q_D(const QOpenGLWindow);-
477 return d->shareContext;
never executed: return d->shareContext;
0
478}-
479-
480/*!-
481 The framebuffer object handle used by this window.-
482-
483 When the update behavior is set to \c NoPartialUpdate, there is no separate-
484 framebuffer object. In this case the returned value is the ID of the-
485 default framebuffer.-
486-
487 Otherwise the value of the ID of the framebuffer object or \c 0 if not-
488 yet initialized.-
489 */-
490GLuint QOpenGLWindow::defaultFramebufferObject() const-
491{-
492 Q_D(const QOpenGLWindow);-
493 if (d->updateBehavior > NoPartialUpdate && d->fbo)
d->updateBehav...oPartialUpdateDescription
TRUEnever evaluated
FALSEnever evaluated
d->fboDescription
TRUEnever evaluated
FALSEnever evaluated
0
494 return d->fbo->handle();
never executed: return d->fbo->handle();
0
495 else if (QOpenGLContext *ctx = QOpenGLContext::currentContext())
QOpenGLContext...rrentContext()Description
TRUEnever evaluated
FALSEnever evaluated
0
496 return ctx->defaultFramebufferObject();
never executed: return ctx->defaultFramebufferObject();
0
497 else-
498 return 0;
never executed: return 0;
0
499}-
500-
501extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);-
502-
503/*!-
504 Returns a 32-bit RGB image of the framebuffer.-
505-
506 \note This is a potentially expensive operation because it relies on-
507 glReadPixels() to read back the pixels. This may be slow and can stall the-
508 GPU pipeline.-
509-
510 \note When used together with update behavior \c NoPartialUpdate, the returned-
511 image may not contain the desired content when called after the front and back-
512 buffers have been swapped (unless preserved swap is enabled in the underlying-
513 windowing system interface). In this mode the function reads from the back-
514 buffer and the contents of that may not match the content on the screen (the-
515 front buffer). In this case the only place where this function can safely be-
516 used is paintGL() or paintOverGL().-
517 */-
518QImage QOpenGLWindow::grabFramebuffer()-
519{-
520 if (!isValid())
!isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
521 return QImage();
never executed: return QImage();
0
522-
523 makeCurrent();-
524 return qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false);
never executed: return qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false);
0
525}-
526-
527/*!-
528 This virtual function is called once before the first call to paintGL() or-
529 resizeGL(). Reimplement it in a subclass.-
530-
531 This function should set up any required OpenGL resources and state.-
532-
533 There is no need to call makeCurrent() because this has already been done-
534 when this function is called. Note however that the framebuffer, in case-
535 partial update mode is used, is not yet available at this stage, so avoid-
536 issuing draw calls from here. Defer such calls to paintGL() instead.-
537-
538 \sa paintGL(), resizeGL()-
539 */-
540void QOpenGLWindow::initializeGL()-
541{-
542}-
543-
544/*!-
545 This virtual function is called whenever the widget has been resized.-
546 Reimplement it in a subclass. The new size is passed in \a w and \a h.-
547-
548 \note This is merely a convenience function in order to provide an API that is-
549 compatible with QOpenGLWidget. Unlike with QOpenGLWidget, derived classes are-
550 free to choose to override resizeEvent() instead of this function.-
551-
552 \note Avoid issuing OpenGL commands from this function as there may not be a-
553 context current when it is invoked. If it cannot be avoided, call makeCurrent().-
554-
555 \note Scheduling updates from here is not necessary. The windowing systems-
556 will send expose events that trigger an update automatically.-
557-
558 \sa initializeGL(), paintGL()-
559 */-
560void QOpenGLWindow::resizeGL(int w, int h)-
561{-
562 Q_UNUSED(w);-
563 Q_UNUSED(h);-
564}
never executed: end of block
0
565-
566/*!-
567 This virtual function is called whenever the window contents needs to be-
568 painted. Reimplement it in a subclass.-
569-
570 There is no need to call makeCurrent() because this has already-
571 been done when this function is called.-
572-
573 Before invoking this function, the context and the framebuffer, if there is-
574 one, are bound, and the viewport is set up by a call to glViewport(). No-
575 other state is set and no clearing or drawing is performed by the framework.-
576-
577 \note When using a partial update behavior, like \c PartialUpdateBlend, the-
578 output of the previous paintGL() call is preserved and, after the additional-
579 drawing perfomed in the current invocation of the function, the content is-
580 blitted or blended over the content drawn directly to the window in-
581 paintUnderGL().-
582-
583 \sa initializeGL(), resizeGL(), paintUnderGL(), paintOverGL(), UpdateBehavior-
584 */-
585void QOpenGLWindow::paintGL()-
586{-
587}-
588-
589/*!-
590 The virtual function is called before each invocation of paintGL().-
591-
592 When the update mode is set to \c NoPartialUpdate, there is no difference-
593 between this function and paintGL(), performing rendering in either of them-
594 leads to the same result.-
595-
596 The difference becomes significant when using \c PartialUpdateBlend, where an-
597 extra framebuffer object is used. There, paintGL() targets this additional-
598 framebuffer object, which preserves its contents, while paintUnderGL() and-
599 paintOverGL() target the default framebuffer, i.e. directly the window-
600 surface, the contents of which is lost after each displayed frame.-
601-
602 \note Avoid relying on this function when the update behavior is-
603 \c PartialUpdateBlit. This mode involves blitting the extra framebuffer used by-
604 paintGL() onto the default framebuffer after each invocation of paintGL(),-
605 thus overwriting all drawing generated in this function.-
606-
607 \sa paintGL(), paintOverGL(), UpdateBehavior-
608 */-
609void QOpenGLWindow::paintUnderGL()-
610{-
611}-
612-
613/*!-
614 This virtual function is called after each invocation of paintGL().-
615-
616 When the update mode is set to NoPartialUpdate, there is no difference-
617 between this function and paintGL(), performing rendering in either of them-
618 leads to the same result.-
619-
620 Like paintUnderGL(), rendering in this function targets the default-
621 framebuffer of the window, regardless of the update behavior. It gets called-
622 after paintGL() has returned and the blit (PartialUpdateBlit) or quad drawing-
623 (PartialUpdateBlend) has been done.-
624-
625 \sa paintGL(), paintUnderGL(), UpdateBehavior-
626 */-
627void QOpenGLWindow::paintOverGL()-
628{-
629}-
630-
631/*!-
632 Paint \a event handler. Calls paintGL().-
633-
634 \sa paintGL()-
635 */-
636void QOpenGLWindow::paintEvent(QPaintEvent *event)-
637{-
638 Q_UNUSED(event);-
639 paintGL();-
640}
never executed: end of block
0
641-
642/*!-
643 Resize \a event handler. Calls resizeGL().-
644-
645 \sa resizeGL()-
646 */-
647void QOpenGLWindow::resizeEvent(QResizeEvent *event)-
648{-
649 Q_UNUSED(event);-
650 Q_D(QOpenGLWindow);-
651 d->initialize();-
652 resizeGL(width(), height());-
653}
never executed: end of block
0
654-
655/*!-
656 \internal-
657 */-
658int QOpenGLWindow::metric(PaintDeviceMetric metric) const-
659{-
660 Q_D(const QOpenGLWindow);-
661-
662 switch (metric) {-
663 case PdmDepth:
never executed: case PdmDepth:
0
664 if (d->paintDevice)
d->paintDeviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
665 return d->paintDevice->depth();
never executed: return d->paintDevice->depth();
0
666 break;
never executed: break;
0
667 default:
never executed: default:
0
668 break;
never executed: break;
0
669 }-
670 return QPaintDeviceWindow::metric(metric);
never executed: return QPaintDeviceWindow::metric(metric);
0
671}-
672-
673/*!-
674 \internal-
675 */-
676QPaintDevice *QOpenGLWindow::redirected(QPoint *) const-
677{-
678 Q_D(const QOpenGLWindow);-
679 if (QOpenGLContext::currentContext() == d->context.data())
QOpenGLContext...context.data()Description
TRUEnever evaluated
FALSEnever evaluated
0
680 return d->paintDevice.data();
never executed: return d->paintDevice.data();
0
681 return 0;
never executed: return 0;
0
682}-
683-
684QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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