Remove tracking of the current fbo
When binding an FBO directly via glBindFramebuffer, the QOpenGLContext's internal current_fbo, that is maintained by QOpenGLFramebufferObject, becomes out of sync. This will lead to QOpenGLFramebufferObjects thinking they are still bound. Such state tracking should be avoided since it is becoming increasingly difficult to keep it consistent between the various OpenGL API wrappers and will never be robust enough when the application changes the state by directly calling OpenGL functions. current_fbo is now removed in QtGui. QtOpenGL is not touched. Change-Id: Id809aab1306c9486d1e2ba3bb5aa93593659e920 Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
This commit is contained in:
parent
46959875cf
commit
f7ddbcb3d5
@ -205,7 +205,6 @@ public:
|
|||||||
, surface(0)
|
, surface(0)
|
||||||
, functions(0)
|
, functions(0)
|
||||||
, textureFunctions(0)
|
, textureFunctions(0)
|
||||||
, current_fbo(0)
|
|
||||||
, max_texture_size(-1)
|
, max_texture_size(-1)
|
||||||
, workaround_brokenFBOReadBack(false)
|
, workaround_brokenFBOReadBack(false)
|
||||||
, workaround_brokenTexSubImage(false)
|
, workaround_brokenTexSubImage(false)
|
||||||
@ -236,7 +235,6 @@ public:
|
|||||||
mutable QSet<QByteArray> extensionNames;
|
mutable QSet<QByteArray> extensionNames;
|
||||||
QOpenGLTextureHelper* textureFunctions;
|
QOpenGLTextureHelper* textureFunctions;
|
||||||
|
|
||||||
GLuint current_fbo;
|
|
||||||
GLint max_texture_size;
|
GLint max_texture_size;
|
||||||
|
|
||||||
bool workaround_brokenFBOReadBack;
|
bool workaround_brokenFBOReadBack;
|
||||||
|
@ -475,7 +475,6 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
|
|||||||
|
|
||||||
initAttachments(ctx, attachment);
|
initAttachments(ctx, attachment);
|
||||||
|
|
||||||
funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
|
fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
|
||||||
} else {
|
} else {
|
||||||
@ -959,8 +958,6 @@ bool QOpenGLFramebufferObject::bind()
|
|||||||
d->valid = d->checkFramebufferStatus(current);
|
d->valid = d->checkFramebufferStatus(current);
|
||||||
else
|
else
|
||||||
d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap());
|
d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap());
|
||||||
if (d->valid && current)
|
|
||||||
current->d_func()->current_fbo = d->fbo();
|
|
||||||
return d->valid;
|
return d->valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -988,10 +985,8 @@ bool QOpenGLFramebufferObject::release()
|
|||||||
qWarning("QOpenGLFramebufferObject::release() called from incompatible context");
|
qWarning("QOpenGLFramebufferObject::release() called from incompatible context");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (current) {
|
if (current)
|
||||||
current->d_func()->current_fbo = current->defaultFramebufferObject();
|
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->defaultFramebufferObject());
|
||||||
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_func()->current_fbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1038,7 +1033,7 @@ GLuint QOpenGLFramebufferObject::takeTexture()
|
|||||||
GLuint id = 0;
|
GLuint id = 0;
|
||||||
if (isValid() && d->texture_guard) {
|
if (isValid() && d->texture_guard) {
|
||||||
QOpenGLContext *current = QOpenGLContext::currentContext();
|
QOpenGLContext *current = QOpenGLContext::currentContext();
|
||||||
if (current && current->shareGroup() == d->fbo_guard->group() && current->d_func()->current_fbo == d->fbo())
|
if (current && current->shareGroup() == d->fbo_guard->group() && isBound())
|
||||||
release();
|
release();
|
||||||
id = d->texture_guard->id();
|
id = d->texture_guard->id();
|
||||||
// Do not call free() on texture_guard, just null it out.
|
// Do not call free() on texture_guard, just null it out.
|
||||||
@ -1154,16 +1149,13 @@ QImage QOpenGLFramebufferObject::toImage() const
|
|||||||
bool QOpenGLFramebufferObject::bindDefault()
|
bool QOpenGLFramebufferObject::bindDefault()
|
||||||
{
|
{
|
||||||
QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
|
QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
|
||||||
QOpenGLFunctions functions(ctx);
|
|
||||||
|
|
||||||
if (ctx) {
|
if (ctx)
|
||||||
ctx->d_func()->current_fbo = ctx->defaultFramebufferObject();
|
ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
|
||||||
functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
|
|
||||||
#ifdef QT_DEBUG
|
#ifdef QT_DEBUG
|
||||||
} else {
|
else
|
||||||
qWarning("QOpenGLFramebufferObject::bindDefault() called without current context.");
|
qWarning("QOpenGLFramebufferObject::bindDefault() called without current context.");
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return ctx != 0;
|
return ctx != 0;
|
||||||
}
|
}
|
||||||
@ -1176,7 +1168,7 @@ bool QOpenGLFramebufferObject::bindDefault()
|
|||||||
*/
|
*/
|
||||||
bool QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()
|
bool QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()
|
||||||
{
|
{
|
||||||
return QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
|
return QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1227,20 +1219,21 @@ void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachmen
|
|||||||
#endif
|
#endif
|
||||||
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
|
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
|
||||||
d->initAttachments(current, attachment);
|
d->initAttachments(current, attachment);
|
||||||
if (current->d_func()->current_fbo != d->fbo())
|
|
||||||
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_func()->current_fbo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns \c true if the framebuffer object is currently bound to a context,
|
Returns \c true if the framebuffer object is currently bound to the current context,
|
||||||
otherwise false is returned.
|
otherwise false is returned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool QOpenGLFramebufferObject::isBound() const
|
bool QOpenGLFramebufferObject::isBound() const
|
||||||
{
|
{
|
||||||
Q_D(const QOpenGLFramebufferObject);
|
Q_D(const QOpenGLFramebufferObject);
|
||||||
QOpenGLContext *current = QOpenGLContext::currentContext();
|
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
||||||
return current ? current->d_func()->current_fbo == d->fbo() : false;
|
if (!ctx)
|
||||||
|
return false;
|
||||||
|
GLint fbo = 0;
|
||||||
|
ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
|
||||||
|
return GLuint(fbo) == d->fbo();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1346,8 +1339,6 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
|
|||||||
extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1,
|
extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1,
|
||||||
tx0, ty0, tx1, ty1,
|
tx0, ty0, tx1, ty1,
|
||||||
buffers, filter);
|
buffers, filter);
|
||||||
|
|
||||||
extensions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -338,7 +338,7 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
|
|||||||
if (d->invalid || !d->fbo)
|
if (d->invalid || !d->fbo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
const QGLContext *ctx = QGLContext::currentContext();
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -352,19 +352,19 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
|
|||||||
#define GL_DRAW_FRAMEBUFFER 0x8CA9
|
#define GL_DRAW_FRAMEBUFFER 0x8CA9
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QOpenGLExtensions extensions(ctx);
|
QOpenGLExtensions extensions(ctx->contextHandle());
|
||||||
|
|
||||||
if (d->blit_fbo) {
|
if (d->blit_fbo) {
|
||||||
QOpenGLFramebufferObject::blitFramebuffer(d->blit_fbo, d->fbo);
|
QOpenGLFramebufferObject::blitFramebuffer(d->blit_fbo, d->fbo);
|
||||||
extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle());
|
extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture_id);
|
extensions.glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
#ifndef QT_OPENGL_ES
|
#ifndef QT_OPENGL_ES
|
||||||
GLenum format = ctx->isOpenGLES() ? GL_RGBA : GL_RGBA8;
|
GLenum format = ctx->contextHandle()->isOpenGLES() ? GL_RGBA : GL_RGBA8;
|
||||||
ctx->functions()->glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
extensions.glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||||
#else
|
#else
|
||||||
ctx->functions()->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
extensions.glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (d->blit_fbo)
|
if (d->blit_fbo)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user