summaryrefslogtreecommitdiffstats
path: root/src/opengl/qopenglframebufferobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qopenglframebufferobject.cpp')
-rw-r--r--src/opengl/qopenglframebufferobject.cpp71
1 files changed, 50 insertions, 21 deletions
diff --git a/src/opengl/qopenglframebufferobject.cpp b/src/opengl/qopenglframebufferobject.cpp
index 7bb4f49f6e..5c8f769d39 100644
--- a/src/opengl/qopenglframebufferobject.cpp
+++ b/src/opengl/qopenglframebufferobject.cpp
@@ -18,6 +18,15 @@
QT_BEGIN_NAMESPACE
+Q_TRACE_PREFIX(qtopengl,
+ "#include <private/qopengl2pexvertexarray_p.h>" \
+ "#include <private/qopengltextureuploader_p.h>" \
+ "#include <qopenglframebufferobject.h>"
+);
+Q_TRACE_PARAM_REPLACE(GLenum, int);
+Q_TRACE_PARAM_REPLACE(GLint, int);
+Q_TRACE_METADATA(qtopengl, "ENUM { } QOpenGLFramebufferObject::Attachment; ");
+
#ifndef QT_NO_DEBUG
#define QT_RESET_GLERROR() \
{ \
@@ -452,10 +461,11 @@ namespace
}
}
-void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *qfbo, const QSize &size,
- QOpenGLFramebufferObject::Attachment attachment,
- GLenum texture_target, GLenum internal_format,
- GLint samples, bool mipmap)
+void Q_TRACE_INSTRUMENT(qtopengl) QOpenGLFramebufferObjectPrivate::init(
+ QOpenGLFramebufferObject *qfbo, const QSize &size,
+ QOpenGLFramebufferObject::Attachment attachment,
+ GLenum texture_target, GLenum internal_format,
+ GLint samples, bool mipmap)
{
Q_TRACE_SCOPE(QOpenGLFramebufferObjectPrivate_init, qfbo, size, attachment, texture_target, internal_format, samples, mipmap);
Q_UNUSED(qfbo);
@@ -540,8 +550,22 @@ void QOpenGLFramebufferObjectPrivate::initTexture(int idx)
else if (color.internalFormat == GL_RGB16F || color.internalFormat == GL_RGBA16F)
pixelType = GL_HALF_FLOAT;
+ bool isOpaque = false;
+ switch (color.internalFormat) {
+ case GL_RGB8:
+ case GL_RGB16:
+ case GL_RGB16F:
+ case GL_RGB32F:
+ isOpaque = true;
+ break;
+ case GL_RGB10:
+ // opaque but the pixel type (INT_2_10_10_10) has alpha and so requires RGBA texture format
+ break;
+ }
+ const GLuint textureFormat = isOpaque ? GL_RGB : GL_RGBA;
+
funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0,
- GL_RGBA, pixelType, nullptr);
+ textureFormat, pixelType, nullptr);
if (format.mipmap()) {
int width = color.size.width();
int height = color.size.height();
@@ -550,8 +574,8 @@ void QOpenGLFramebufferObjectPrivate::initTexture(int idx)
width = qMax(1, width >> 1);
height = qMax(1, height >> 1);
++level;
- funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0,
- GL_RGBA, pixelType, nullptr);
+ funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0, textureFormat,
+ pixelType, nullptr);
}
}
funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx,
@@ -993,7 +1017,7 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
if (isBound())
release();
- for (const auto &color : qAsConst(d->colorAttachments)) {
+ for (const auto &color : std::as_const(d->colorAttachments)) {
if (color.guard)
color.guard->free();
}
@@ -1053,7 +1077,7 @@ void QOpenGLFramebufferObject::addColorAttachment(const QSize &size, GLenum inte
QOpenGLFramebufferObjectPrivate::ColorAttachment color(size, effectiveInternalFormat(internalFormat));
d->colorAttachments.append(color);
- const int idx = d->colorAttachments.count() - 1;
+ const int idx = d->colorAttachments.size() - 1;
if (d->requestedSamples == 0) {
d->initTexture(idx);
@@ -1134,7 +1158,7 @@ bool QOpenGLFramebufferObject::bind()
if (d->format.samples() == 0) {
// Create new textures to replace the ones stolen via takeTexture().
- for (int i = 0; i < d->colorAttachments.count(); ++i) {
+ for (int i = 0; i < d->colorAttachments.size(); ++i) {
if (!d->colorAttachments.at(i).guard)
d->initTexture(i);
}
@@ -1214,7 +1238,7 @@ QList<GLuint> QOpenGLFramebufferObject::textures() const
QList<GLuint> ids;
if (d->format.samples() != 0)
return ids;
- ids.reserve(d->colorAttachments.count());
+ ids.reserve(d->colorAttachments.size());
for (const auto &color : d->colorAttachments)
ids.append(color.guard ? color.guard->id() : 0);
return ids;
@@ -1266,7 +1290,7 @@ GLuint QOpenGLFramebufferObject::takeTexture(int colorAttachmentIndex)
{
Q_D(QOpenGLFramebufferObject);
GLuint id = 0;
- if (isValid() && d->format.samples() == 0 && d->colorAttachments.count() > colorAttachmentIndex) {
+ if (isValid() && d->format.samples() == 0 && d->colorAttachments.size() > colorAttachmentIndex) {
QOpenGLContext *current = QOpenGLContext::currentContext();
if (current && current->shareGroup() == d->fbo_guard->group() && isBound())
release();
@@ -1334,7 +1358,8 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ
bool isOpenGL12orBetter = !context->isOpenGLES() && (context->format().majorVersion() >= 2 || context->format().minorVersion() >= 2);
if (isOpenGL12orBetter) {
QImage img(size, include_alpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
- funcs->glReadPixels(0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, img.bits());
+ if (!img.isNull())
+ funcs->glReadPixels(0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, img.bits());
return img;
}
@@ -1344,7 +1369,8 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ
// BGRA capable impl would return BGRA from there)
QImage rgbaImage(size, include_alpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888);
- funcs->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits());
+ if (!rgbaImage.isNull())
+ funcs->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits());
return rgbaImage;
}
@@ -1352,7 +1378,8 @@ static inline QImage qt_gl_read_framebuffer_rgb10a2(const QSize &size, bool incl
{
// We assume OpenGL 1.2+ or ES 3.0+ here.
QImage img(size, include_alpha ? QImage::Format_A2BGR30_Premultiplied : QImage::Format_BGR30);
- context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, img.bits());
+ if (!img.isNull())
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, img.bits());
return img;
}
@@ -1360,7 +1387,8 @@ static inline QImage qt_gl_read_framebuffer_rgba16(const QSize &size, bool inclu
{
// We assume OpenGL 1.2+ or ES 3.0+ here.
QImage img(size, include_alpha ? QImage::Format_RGBA64_Premultiplied : QImage::Format_RGBX64);
- context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_SHORT, img.bits());
+ if (!img.isNull())
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_SHORT, img.bits());
return img;
}
@@ -1368,14 +1396,16 @@ static inline QImage qt_gl_read_framebuffer_rgba16f(const QSize &size, bool incl
{
// We assume OpenGL (ES) 3.0+ here.
QImage img(size, include_alpha ? QImage::Format_RGBA16FPx4_Premultiplied : QImage::Format_RGBX16FPx4);
- context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_HALF_FLOAT, img.bits());
+ if (!img.isNull())
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_HALF_FLOAT, img.bits());
return img;
}
static inline QImage qt_gl_read_framebuffer_rgba32f(const QSize &size, bool include_alpha, QOpenGLContext *context)
{
QImage img(size, include_alpha ? QImage::Format_RGBA32FPx4_Premultiplied : QImage::Format_RGBX32FPx4);
- context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_FLOAT, img.bits());
+ if (!img.isNull())
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_FLOAT, img.bits());
return img;
}
@@ -1414,8 +1444,7 @@ static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format,
return qt_gl_read_framebuffer_rgba8(size, include_alpha, ctx).mirrored(false, flip);
}
- Q_UNREACHABLE();
- return QImage();
+ Q_UNREACHABLE_RETURN(QImage());
}
Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
@@ -1491,7 +1520,7 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped, int colorAttachmentIndex)
return QImage();
}
- if (d->colorAttachments.count() <= colorAttachmentIndex) {
+ if (d->colorAttachments.size() <= colorAttachmentIndex) {
qWarning("QOpenGLFramebufferObject::toImage() called for missing color attachment");
return QImage();
}