Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qopenglwindow.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qopenglwindow.h"
5#include <QtGui/QOpenGLFunctions>
6#include <QtGui/private/qpaintdevicewindow_p.h>
7#include <QtGui/private/qopenglextensions_p.h>
8#include <QtGui/private/qopenglcontext_p.h>
9#include <QtGui/QMatrix4x4>
10#include <QtGui/QOffscreenSurface>
11
12#include <QtOpenGL/private/qopenglframebufferobject_p.h>
13#include <QtOpenGL/QOpenGLFramebufferObject>
14#include <QtOpenGL/QOpenGLTextureBlitter>
15#include <QtOpenGL/QOpenGLPaintDevice>
16
18
137// GLES2 builds won't have these constants with the suffixless names
138#ifndef GL_READ_FRAMEBUFFER
139#define GL_READ_FRAMEBUFFER 0x8CA8
140#endif
141#ifndef GL_DRAW_FRAMEBUFFER
142#define GL_DRAW_FRAMEBUFFER 0x8CA9
143#endif
144
153
155{
156 Q_DECLARE_PUBLIC(QOpenGLWindow)
157public:
166
168
169 static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); }
170
171 void bindFBO();
172 void initialize();
173
174 void beginPaint(const QRegion &region) override;
175 void endPaint() override;
176 void flush(const QRegion &region) override;
177
180 QScopedPointer<QOpenGLContext> context;
182 QScopedPointer<QOpenGLFramebufferObject> fbo;
183 QScopedPointer<QOpenGLWindowPaintDevice> paintDevice;
186 QScopedPointer<QOffscreenSurface> offscreenSurface;
187};
188
190{
191 Q_Q(QOpenGLWindow);
192 if (q->isValid()) {
193 q->makeCurrent(); // this works even when the platformwindow is destroyed
194 paintDevice.reset(nullptr);
195 fbo.reset(nullptr);
197 q->doneCurrent();
198 }
199}
200
202{
203 Q_Q(QOpenGLWindow);
204
205 if (context)
206 return;
207
208 if (!q->handle())
209 qWarning("Attempted to initialize QOpenGLWindow without a platform window");
210
213 context->setFormat(q->requestedFormat());
214 if (!context->create())
215 qWarning("QOpenGLWindow::beginPaint: Failed to create context");
216 if (!context->makeCurrent(q))
217 qWarning("QOpenGLWindow::beginPaint: Failed to make context current");
218
222
223 q->initializeGL();
224}
225
227{
228 Q_UNUSED(region);
229 Q_Q(QOpenGLWindow);
230
231 initialize();
233
234 const int deviceWidth = q->width() * q->devicePixelRatio();
235 const int deviceHeight = q->height() * q->devicePixelRatio();
236 const QSize deviceSize(deviceWidth, deviceHeight);
238 if (!fbo || fbo->size() != deviceSize) {
241 const int samples = q->requestedFormat().samples();
242 if (samples > 0) {
244 fboFormat.setSamples(samples);
245 else
246 qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling");
247 }
248 fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat));
250 }
251 } else {
253 }
254
255 paintDevice->setSize(QSize(deviceWidth, deviceHeight));
256 paintDevice->setDevicePixelRatio(q->devicePixelRatio());
257 context->functions()->glViewport(0, 0, deviceWidth, deviceHeight);
258
260
261 q->paintUnderGL();
262
264 fbo->bind();
265}
266
268{
269 Q_Q(QOpenGLWindow);
270
272 fbo->release();
273
275
277 const int deviceWidth = q->width() * q->devicePixelRatio();
278 const int deviceHeight = q->height() * q->devicePixelRatio();
279 QOpenGLExtensions extensions(context.data());
282 extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight,
283 0, 0, deviceWidth, deviceHeight,
284 GL_COLOR_BUFFER_BIT, GL_NEAREST);
287 context->functions()->glEnable(GL_BLEND);
288 context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
289 }
290 if (!blitter.isCreated())
291 blitter.create();
292
293 QRect windowRect(QPoint(0, 0), fbo->size());
295 blitter.bind();
298
300 context->functions()->glDisable(GL_BLEND);
301 }
302
303 q->paintOverGL();
304}
305
313
315{
316 Q_UNUSED(region);
317 Q_Q(QOpenGLWindow);
319 emit q->frameSwapped();
320}
321
326
333 : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(nullptr, updateBehavior)), parent)
334{
335 setSurfaceType(QSurface::OpenGLSurface);
336}
337
344 : QPaintDeviceWindow(*(new QOpenGLWindowPrivate(shareContext, updateBehavior)), parent)
345{
346 setSurfaceType(QSurface::OpenGLSurface);
347}
348
372
377{
378 Q_D(const QOpenGLWindow);
379 return d->updateBehavior;
380}
381
388{
389 Q_D(const QOpenGLWindow);
390 return d->context && d->context->isValid();
391}
392
414{
415 Q_D(QOpenGLWindow);
416
417 if (!isValid())
418 return;
419
420 // The platform window may be destroyed at this stage and therefore
421 // makeCurrent() may not safely be called with 'this'.
422 if (handle()) {
423 d->context->makeCurrent(this);
424 } else {
425 if (!d->offscreenSurface) {
426 d->offscreenSurface.reset(new QOffscreenSurface(screen()));
427 d->offscreenSurface->setFormat(d->context->format());
428 d->offscreenSurface->create();
429 }
430 d->context->makeCurrent(d->offscreenSurface.data());
431 }
432
433 d->bindFBO();
434}
435
446{
447 Q_D(QOpenGLWindow);
448
449 if (!isValid())
450 return;
451
452 d->context->doneCurrent();
453}
454
459{
460 Q_D(const QOpenGLWindow);
461 return d->context.data();
462}
463
468{
469 Q_D(const QOpenGLWindow);
470 return d->shareContext;
471}
472
484{
485 Q_D(const QOpenGLWindow);
486 if (d->updateBehavior > NoPartialUpdate && d->fbo)
487 return d->fbo->handle();
489 return ctx->defaultFramebufferObject();
490 else
491 return 0;
492}
493
510{
511 if (!isValid())
512 return QImage();
513
514 makeCurrent();
515
516 const bool hasAlpha = format().hasAlpha();
518 img.setDevicePixelRatio(devicePixelRatio());
519 return img;
520}
521
538
556{
557 Q_UNUSED(w);
558 Q_UNUSED(h);
559}
560
581{
582}
583
607
625
636
643{
645 Q_D(QOpenGLWindow);
646 d->initialize();
647 resizeGL(width(), height());
648}
649
654{
655 Q_D(const QOpenGLWindow);
656
657 switch (metric) {
658 case PdmDepth:
659 if (d->paintDevice)
660 return d->paintDevice->depth();
661 break;
662 default:
663 break;
664 }
666}
667
672{
673 Q_D(const QOpenGLWindow);
674 if (QOpenGLContext::currentContext() == d->context.data())
675 return d->paintDevice.data();
676 return nullptr;
677}
678
680
681#include "moc_qopenglwindow.cpp"
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtGui
Definition qimage.h:37
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
\inmodule QtGui
\inmodule QtGui
bool create()
Attempts to create the OpenGL context with the current configuration.
bool makeCurrent(QSurface *surface)
Makes the context current in the current thread, against the given surface.
void setShareContext(QOpenGLContext *shareContext)
Makes this context share textures, shaders, and other OpenGL resources with shareContext.
GLuint defaultFramebufferObject() const
Call this to get the default framebuffer object for the current surface.
void setFormat(const QSurfaceFormat &format)
Sets the format the OpenGL context should be compatible with.
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
QOpenGLFunctions * functions() const
Get the QOpenGLFunctions instance for this context.
void swapBuffers(QSurface *surface)
Swap the back and front buffers of surface.
void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
Convenience function that calls glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0,...
The QOpenGLFramebufferObjectFormat class specifies the format of an OpenGL framebuffer object.
void setAttachment(QOpenGLFramebufferObject::Attachment attachment)
Sets the attachment configuration of a framebuffer object to attachment.
The QOpenGLFramebufferObject class encapsulates an OpenGL framebuffer object.
static bool bindDefault()
Switches rendering back to the default, windowing system provided framebuffer.
static bool hasOpenGLFramebufferBlit()
Returns true if the OpenGL {GL_EXT_framebuffer_blit} extension is present on this system; otherwise r...
bool release()
Switches rendering back to the default, windowing system provided framebuffer.
GLuint handle() const
Returns the OpenGL framebuffer object handle for this framebuffer object (returned by the {glGenFrame...
GLuint texture() const
Returns the texture id for the texture attached as the default rendering target in this framebuffer o...
bool bind()
Switches rendering from the default, windowing system provided framebuffer to this framebuffer object...
void glBlendFunc(GLenum sfactor, GLenum dfactor)
Convenience function that calls glBlendFunc(sfactor, dfactor).
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
Convenience function that calls glViewport(x, y, width, height).
void glBindFramebuffer(GLenum target, GLuint framebuffer)
Convenience function that calls glBindFramebuffer(target, framebuffer).
void glDisable(GLenum cap)
Convenience function that calls glDisable(cap).
void glEnable(GLenum cap)
Convenience function that calls glEnable(cap).
The QOpenGLPaintDevice class enables painting to an OpenGL context using QPainter.
void setDevicePixelRatio(qreal devicePixelRatio)
Sets the device pixel ratio for the paint device to devicePixelRatio.
void setSize(const QSize &size)
Sets the pixel size of the paint device to size.
The QOpenGLTextureBlitter class provides a convenient way to draw textured quads via OpenGL.
bool create()
Initializes the graphics resources used by the blitter.
void destroy()
Frees all graphics resources held by the blitter.
void blit(GLuint texture, const QMatrix4x4 &targetTransform, Origin sourceOrigin)
Performs the blit with the source texture texture.
void release()
Unbinds the graphics resources used by the blitter.
static QMatrix4x4 targetTransform(const QRectF &target, const QRect &viewport)
Calculates a target transform suitable for blit().
void bind(GLenum target=GL_TEXTURE_2D)
Binds the graphics resources used by the blitter.
QOpenGLWindowPaintDevice(QOpenGLWindow *window)
void ensureActiveTarget() override
This virtual method is provided as a callback to allow re-binding a target frame buffer object or con...
QScopedPointer< QOffscreenSurface > offscreenSurface
QOpenGLTextureBlitter blitter
QScopedPointer< QOpenGLContext > context
void endPaint() override
static QOpenGLWindowPrivate * get(QOpenGLWindow *w)
QScopedPointer< QOpenGLWindowPaintDevice > paintDevice
QScopedPointer< QOpenGLFramebufferObject > fbo
QOpenGLContext * shareContext
QOpenGLWindow::UpdateBehavior updateBehavior
void flush(const QRegion &region) override
void beginPaint(const QRegion &region) override
QOpenGLWindowPrivate(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior)
\inmodule QtOpenGL
bool isValid() const
GLuint defaultFramebufferObject() const
The framebuffer object handle used by this window.
virtual void paintUnderGL()
The virtual function is called before each invocation of paintGL().
~QOpenGLWindow()
Destroys the QOpenGLWindow instance, freeing its resources.
virtual void initializeGL()
This virtual function is called once before the first call to paintGL() or resizeGL().
QOpenGLContext * shareContext() const
void resizeEvent(QResizeEvent *event) override
Resize event handler.
void paintEvent(QPaintEvent *event) override
Paint event handler.
QPaintDevice * redirected(QPoint *) const override
void makeCurrent()
Prepares for rendering OpenGL content for this window by making the corresponding context current and...
UpdateBehavior
This enum describes the update strategy of the QOpenGLWindow.
UpdateBehavior updateBehavior() const
int metric(PaintDeviceMetric metric) const override
virtual void paintGL()
This virtual function is called whenever the window contents needs to be painted.
virtual void paintOverGL()
This virtual function is called after each invocation of paintGL().
QOpenGLContext * context() const
virtual void resizeGL(int w, int h)
This virtual function is called whenever the widget has been resized.
void doneCurrent()
Releases the context.
QOpenGLWindow(UpdateBehavior updateBehavior=NoPartialUpdate, QWindow *parent=nullptr)
Constructs a new QOpenGLWindow with the given parent and updateBehavior.
QImage grabFramebuffer()
Returns a copy of the framebuffer.
int width
the width of the window's geometry
Definition qwindow.h:82
int metric(PaintDeviceMetric metric) const override
int height
the height of the window's geometry
Definition qwindow.h:83
qreal devicePixelRatio() const
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:548
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\inmodule QtCore
Definition qsize.h:25
bool hasAlpha() const
Returns true if the alpha buffer size is greater than zero.
@ OpenGLSurface
Definition qsurface.h:32
\inmodule QtGui
Definition qwindow.h:63
QSurfaceFormat format() const override
Returns the actual format of this window.
Definition qwindow.cpp:946
QSize size() const override
Returns the size of the window excluding any window frame.
Definition qwindow.h:210
EGLContext ctx
Combined button and popup list for selecting options.
#define qWarning
Definition qlogging.h:166
QOpenGLContext * qt_gl_global_share_context()
GLuint64 GLenum void * handle
GLsizei samples
GLfloat GLfloat GLfloat w
[0]
GLenum target
GLfloat GLfloat GLfloat GLfloat h
struct _cl_event * event
GLint void * img
Definition qopenglext.h:233
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define GL_FRAMEBUFFER
static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format, bool include_alpha, bool flip)
#define GL_DRAW_FRAMEBUFFER
#define GL_READ_FRAMEBUFFER
static bool hasAlpha(const QImage &image)
#define GLuint
QScreen * screen
[1]
Definition main.cpp:29
#define emit
#define Q_UNUSED(x)
QObject::connect nullptr
aWidget window() -> setWindowTitle("New Window Title")
[2]