8#include <private/qopengl_p.h>
9#include <private/qopenglcontext_p.h>
10#include <private/qopenglextensions_p.h>
11#include <private/qfont_p.h>
15#include <QtCore/qbytearray.h>
17#include <qtopengl_tracepoints_p.h>
22 "#include <private/qopengl2pexvertexarray_p.h>" \
23 "#include <private/qopengltextureuploader_p.h>" \
24 "#include <qopenglframebufferobject.h>"
31#define QT_RESET_GLERROR() \
34 GLenum error = QOpenGLContext::currentContext()->functions()->glGetError(); \
35 if (error == GL_NO_ERROR || error == GL_CONTEXT_LOST) \
39#define QT_CHECK_GLERROR() \
41 GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); \
42 if (err != GL_NO_ERROR && err != GL_CONTEXT_LOST) { \
43 qDebug("[%s line %d] OpenGL Error: %d", \
44 __FILE__, __LINE__, (int)err); \
48#define QT_RESET_GLERROR() {}
49#define QT_CHECK_GLERROR() {}
53#define GL_MAX_SAMPLES 0x8D57
56#ifndef GL_RENDERBUFFER_SAMPLES
57#define GL_RENDERBUFFER_SAMPLES 0x8CAB
60#ifndef GL_DEPTH24_STENCIL8
61#define GL_DEPTH24_STENCIL8 0x88F0
64#ifndef GL_DEPTH_COMPONENT24
65#define GL_DEPTH_COMPONENT24 0x81A6
68#ifndef GL_DEPTH_COMPONENT24_OES
69#define GL_DEPTH_COMPONENT24_OES 0x81A6
72#ifndef GL_READ_FRAMEBUFFER
73#define GL_READ_FRAMEBUFFER 0x8CA8
76#ifndef GL_DRAW_FRAMEBUFFER
77#define GL_DRAW_FRAMEBUFFER 0x8CA9
85#define GL_RGB10 0x8052
89#define GL_RGB16 0x8054
93#define GL_RGBA8 0x8058
97#define GL_RGB10_A2 0x8059
101#define GL_RGBA16 0x805B
105#define GL_BGRA 0x80E1
108#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
109#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
112#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
113#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
116#ifndef GL_CONTEXT_LOST
117#define GL_CONTEXT_LOST 0x0507
120#ifndef GL_DEPTH_STENCIL_ATTACHMENT
121#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
124#ifndef GL_DEPTH_STENCIL
125#define GL_DEPTH_STENCIL 0x84F9
129#define GL_HALF_FLOAT 0x140B
133#define GL_RGBA32F 0x8814
137#define GL_RGB32F 0x8815
141#define GL_RGBA16F 0x881A
145#define GL_RGB16F 0x881B
178void QOpenGLFramebufferObjectFormat::detach()
388 return !(*
this ==
other);
401 qDebug(
"QOpenGLFramebufferObject: Unsupported framebuffer format.");
404 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete attachment.");
407 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete, missing attachment.");
409#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT
410 case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
411 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete, duplicate attachment.");
414#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
415 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
416 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions.");
419#ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
420 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
421 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete, attached images must have same format.");
424#ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
426 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete, missing draw buffer.");
429#ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
431 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
434#ifdef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
436 qDebug(
"QOpenGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel.");
440 qDebug() <<
"QOpenGLFramebufferObject: An undefined error has occurred: "<< status;
450 funcs->glDeleteFramebuffers(1, &
id);
455 funcs->glDeleteRenderbuffers(1, &
id);
460 funcs->glDeleteTextures(1, &
id);
484 }
else if (!
ctx->isOpenGLES() ||
ctx->format().majorVersion() >= 3) {
510 format.setInternalTextureFormat(internal_format);
549 pixelType = GL_UNSIGNED_SHORT;
589 if (
ctx->isOpenGLES()) {
594 storageFormat = GL_RGBA4;
647 GLuint stencil_buffer = 0;
693 stencil_buffer = depth_buffer;
702 stencil_buffer = depth_buffer = 0;
713 if (
ctx->isOpenGLES()) {
725 if (
ctx->isOpenGLES()) {
751#if QT_CONFIG(opengles2)
778 if (depth_buffer && stencil_buffer) {
781 }
else if (depth_buffer) {
790 if (stencil_buffer) {
791 if (stencil_buffer == depth_buffer)
799 if (stencil_buffer && depth_buffer != stencil_buffer)
878#if QT_CONFIG(opengles2)
1006 for (
const auto &
color : std::as_const(
d->colorAttachments)) {
1008 color.guard->free();
1010 d->colorAttachments.clear();
1012 if (
d->depth_buffer_guard)
1013 d->depth_buffer_guard->free();
1014 if (
d->stencil_buffer_guard &&
d->stencil_buffer_guard !=
d->depth_buffer_guard)
1015 d->stencil_buffer_guard->free();
1017 d->fbo_guard->free();
1060 qWarning(
"Multiple render targets not supported, ignoring extra color attachment request");
1065 d->colorAttachments.append(
color);
1066 const int idx =
d->colorAttachments.size() - 1;
1068 if (
d->requestedSamples == 0) {
1069 d->initTexture(idx);
1111 return d->valid &&
d->fbo_guard &&
d->fbo_guard->id();
1136 if (current->
shareGroup() !=
d->fbo_guard->group())
1137 qWarning(
"QOpenGLFramebufferObject::bind() called from incompatible context");
1145 if (
d->format.samples() == 0) {
1147 for (
int i = 0;
i <
d->colorAttachments.size(); ++
i) {
1148 if (!
d->colorAttachments.at(
i).guard)
1176 if (current->
shareGroup() !=
d->fbo_guard->group())
1177 qWarning(
"QOpenGLFramebufferObject::release() called from incompatible context");
1209 return d->colorAttachments[0].guard ?
d->colorAttachments[0].guard->id() : 0;
1225 if (
d->format.samples() != 0)
1227 ids.reserve(
d->colorAttachments.size());
1228 for (
const auto &
color :
d->colorAttachments)
1279 if (
isValid() &&
d->format.samples() == 0 &&
d->colorAttachments.size() > colorAttachmentIndex) {
1283 auto &guard =
d->colorAttachments[colorAttachmentIndex].guard;
1284 id = guard ? guard->id() : 0;
1312 sz.
reserve(
d->colorAttachments.size());
1313 for (
const auto &
color :
d->colorAttachments)
1342 const int w =
size.width();
1343 const int h =
size.height();
1344 bool isOpenGL12orBetter = !
context->isOpenGLES() && (
context->format().majorVersion() >= 2 ||
context->format().minorVersion() >= 2);
1345 if (isOpenGL12orBetter) {
1407 switch (internal_format) {
1433 Q_UNREACHABLE_RETURN(
QImage());
1505 qWarning(
"QOpenGLFramebufferObject::toImage() called without a current context");
1509 if (
d->colorAttachments.size() <= colorAttachmentIndex) {
1510 qWarning(
"QOpenGLFramebufferObject::toImage() called for missing color attachment");
1517 if (prevFbo !=
d->fbo())
1527 fmt.setInternalTextureFormat(
d->colorAttachments[colorAttachmentIndex].internalFormat);
1530 GL_COLOR_BUFFER_BIT, GL_NEAREST,
1531 colorAttachmentIndex, 0);
1534 fmt.setInternalTextureFormat(
d->colorAttachments[0].internalFormat);
1543 d->colorAttachments[colorAttachmentIndex].internalFormat,
1548 d->colorAttachments[0].internalFormat,
1553 if (prevFbo !=
d->fbo())
1579 qWarning(
"QOpenGLFramebufferObject::bindDefault() called without current context.");
1582 return ctx !=
nullptr;
1620 return d->fbo_attachment;
1641 if (current->
shareGroup() !=
d->fbo_guard->group())
1642 qWarning(
"QOpenGLFramebufferObject::setAttachment() called from incompatible context");
1646 d->initDepthStencilAttachments(current,
attachment);
1661 return GLuint(fbo) ==
d->fbo();
1694 targetSize =
target->size();
1696 sourceSize =
source->size();
1699 targetSize = sourceSize;
1700 else if (sourceSize.
isEmpty())
1701 sourceSize = targetSize;
1788 int readColorAttachmentIndex,
1789 int drawColorAttachmentIndex,
1804 const int sx0 = sourceRect.
left();
1805 const int sx1 = sourceRect.
left() + sourceRect.
width();
1806 const int sy0 = sourceRect.
top();
1807 const int sy1 = sourceRect.
top() + sourceRect.
height();
1809 const int tx0 = targetRect.
left();
1810 const int tx1 = targetRect.
left() + targetRect.
width();
1811 const int ty0 = targetRect.
top();
1812 const int ty1 = targetRect.
top() + targetRect.
height();
1814 const GLuint defaultFboId =
ctx->defaultFramebufferObject();
1835 switch (restorePolicy) {
1862 int readColorAttachmentIndex,
1863 int drawColorAttachmentIndex)
1867 readColorAttachmentIndex,
1868 drawColorAttachmentIndex,
T loadRelaxed() const noexcept
uchar * bits()
Returns a pointer to the first pixel data.
bool isNull() const
Returns true if it is a null image, otherwise returns false.
@ Format_RGBA32FPx4_Premultiplied
@ Format_RGBA64_Premultiplied
@ Format_RGBA8888_Premultiplied
@ Format_RGBA16FPx4_Premultiplied
@ Format_A2BGR30_Premultiplied
@ Format_ARGB32_Premultiplied
QImage mirrored(bool horizontally=false, bool vertically=true) const &
void reserve(qsizetype size)
void append(parameter_type t)
QOpenGLFramebufferObject * qgl_current_fbo
bool qgl_current_fbo_invalid
static QOpenGLContextPrivate * get(QOpenGLContext *context)
QOpenGLContextGroup * shareGroup() const
Returns the share group this context belongs to.
GLuint defaultFramebufferObject() const
Call this to get the default framebuffer object for the current surface.
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.
bool isOpenGLES() const
Returns true if the context is an OpenGL ES context.
bool hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const
Returns true if extension is present on this system's OpenGL implementation; false otherwise.
bool checkFramebufferStatus(QOpenGLContext *ctx) const
void initDepthStencilAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment)
QOpenGLSharedResourceGuard * fbo_guard
QOpenGLFramebufferObject::Attachment fbo_attachment
void init(QOpenGLFramebufferObject *q, const QSize &size, QOpenGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples=0, bool mipmap=false)
void initColorBuffer(int idx, GLint *samples)
void initTexture(int idx)
QOpenGLSharedResourceGuard * depth_buffer_guard
QVarLengthArray< ColorAttachment, 8 > colorAttachments
QOpenGLSharedResourceGuard * stencil_buffer_guard
The QOpenGLFramebufferObject class encapsulates an OpenGL framebuffer object.
Attachment attachment() const
Returns the status of the depth and stencil buffers attached to this framebuffer object.
static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, QOpenGLFramebufferObject *source, const QRect &sourceRect, GLbitfield buffers, GLenum filter, int readColorAttachmentIndex, int drawColorAttachmentIndex, FramebufferRestorePolicy restorePolicy)
QList< QSize > sizes() const
virtual ~QOpenGLFramebufferObject()
Destroys the framebuffer object and frees any allocated resources.
Attachment
This enum type is used to configure the depth and stencil buffers attached to the framebuffer object ...
static bool bindDefault()
Switches rendering back to the default, windowing system provided framebuffer.
void setAttachment(Attachment attachment)
Sets the attachments of the framebuffer object to attachment.
GLuint takeTexture()
Returns the texture id for the texture attached to this framebuffer object.
@ RestoreFramebufferBindingToDefault
@ RestoreFrameBufferBinding
@ DontRestoreFramebufferBinding
static bool hasOpenGLFramebufferBlit()
Returns true if the OpenGL {GL_EXT_framebuffer_blit} extension is present on this system; otherwise r...
void addColorAttachment(const QSize &size, GLenum internalFormat=0)
Creates and attaches an additional texture or renderbuffer of size width and height.
QOpenGLFramebufferObjectFormat format() const
Returns the format of this framebuffer object.
bool release()
Switches rendering back to the default, windowing system provided framebuffer.
QOpenGLFramebufferObject(const QSize &size, GLenum target=GL_TEXTURE_2D)
Constructs an OpenGL framebuffer object and binds a 2D OpenGL texture to the buffer of the size size.
bool isBound() const
Returns true if the framebuffer object is currently bound to the current context, otherwise false is ...
GLuint handle() const
Returns the OpenGL framebuffer object handle for this framebuffer object (returned by the {glGenFrame...
QImage toImage(bool flipped=true) const
Returns the contents of this framebuffer object as a QImage.
static bool hasOpenGLFramebufferObjects()
Returns true if the OpenGL {GL_EXT_framebuffer_object} extension is present on this system; otherwise...
GLuint texture() const
Returns the texture id for the texture attached as the default rendering target in this framebuffer o...
QList< GLuint > textures() const
Returns the texture id for all attached textures.
bool bind()
Switches rendering from the default, windowing system provided framebuffer to this framebuffer object...
bool isValid() const
Returns true if the framebuffer object is valid.
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
GLboolean glIsRenderbuffer(GLuint renderbuffer)
Convenience function that calls glIsRenderbuffer(renderbuffer).
void glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
Convenience function that calls glDeleteFramebuffers(n, framebuffers).
void glGenTextures(GLsizei n, GLuint *textures)
Convenience function that calls glGenTextures(n, textures).
void glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
Convenience function that calls glDeleteRenderbuffers(n, renderbuffers).
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
Convenience function that calls glTexImage2D(target, level, internalformat, width,...
void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
Convenience function that calls glGetRenderbufferParameteriv(target, pname, params).
void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
Convenience function that calls glGenRenderbuffers(n, renderbuffers).
void glBindRenderbuffer(GLenum target, GLuint renderbuffer)
Convenience function that calls glBindRenderbuffer(target, renderbuffer).
void glTexParameteri(GLenum target, GLenum pname, GLint param)
Convenience function that calls glTexParameteri(target, pname, param).
void glBindTexture(GLenum target, GLuint texture)
Convenience function that calls glBindTexture(target, texture).
void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
Convenience function that calls glFramebufferTexture2D(target, attachment, textarget,...
void glDeleteTextures(GLsizei n, const GLuint *textures)
Convenience function that calls glDeleteTextures(n, textures).
void glBindFramebuffer(GLenum target, GLuint framebuffer)
Convenience function that calls glBindFramebuffer(target, framebuffer).
void initializeOpenGLFunctions()
Initializes OpenGL function resolution for the current context.
void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
Convenience function that calls glFramebufferRenderbuffer(target, attachment, renderbuffertarget,...
void glGenFramebuffers(GLsizei n, GLuint *framebuffers)
Convenience function that calls glGenFramebuffers(n, framebuffers).
bool hasOpenGLFeature(QOpenGLFunctions::OpenGLFeature feature) const
Returns true if feature is present on this system's OpenGL implementation; false otherwise.
void glGetIntegerv(GLenum pname, GLint *params)
Convenience function that calls glGetIntegerv(pname, params).
void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
Convenience function that calls glRenderbufferStorage(target, internalformat, width,...
The QOpenGLSharedResourceGuard class is a convenience sub-class of QOpenGLSharedResource to be used t...
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr int width() const noexcept
Returns the width of the rectangle.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
static VulkanServerBufferGlFunctions * funcs
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
GLuint const GLuint * buffers
GLenum GLuint GLint level
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei const GLuint * ids
GLenum GLenum GLsizei const GLuint GLboolean enabled
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum format
GLsizei GLenum internalFormat
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
#define GL_RENDERBUFFER_SAMPLES
#define GL_DEPTH24_STENCIL8
#define GL_DEPTH_COMPONENT16
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
#define GL_COLOR_ATTACHMENT0
#define GL_DEPTH_STENCIL_ATTACHMENT
#define GL_STENCIL_INDEX8
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
typedef GLbitfield(APIENTRYP PFNGLQUERYMATRIXXOESPROC)(GLfixed *mantissa
#define GL_FRAMEBUFFER_COMPLETE
#define GL_DRAW_FRAMEBUFFER
#define GL_FRAMEBUFFER_UNSUPPORTED
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
#define GL_FRAMEBUFFER_BINDING
#define GL_READ_FRAMEBUFFER
#define GL_DEPTH_ATTACHMENT
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
#define GL_DEPTH_COMPONENT24
#define GL_STENCIL_ATTACHMENT
static QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool include_alpha, QOpenGLContext *context)
static QImage qt_gl_read_framebuffer_rgb10a2(const QSize &size, bool include_alpha, QOpenGLContext *context)
static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format, bool include_alpha, bool flip)
static QImage qt_gl_read_framebuffer_rgba16f(const QSize &size, bool include_alpha, QOpenGLContext *context)
#define QT_RESET_GLERROR()
static GLenum effectiveInternalFormat(GLenum internalFormat)
#define QT_CHECK_GLERROR()
static QImage qt_gl_read_framebuffer_rgba16(const QSize &size, bool include_alpha, QOpenGLContext *context)
static QImage qt_gl_read_framebuffer_rgba32f(const QSize &size, bool include_alpha, QOpenGLContext *context)
#define GL_UNSIGNED_INT_8_8_8_8_REV
#define GL_UNSIGNED_INT_2_10_10_10_REV
#define Q_TRACE_PARAM_REPLACE(in, out)
#define Q_TRACE_METADATA(provider, metadata)
#define Q_TRACE_PREFIX(provider, prefix)
#define Q_TRACE_SCOPE(x,...)
#define Q_TRACE_INSTRUMENT(provider)
QVideoFrameFormat::PixelFormat fmt