summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp8
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h2
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp1
-rw-r--r--src/opengl/qgl.cpp21
-rw-r--r--src/opengl/qgl.h2
-rw-r--r--src/opengl/qgl_p.h7
-rw-r--r--src/opengl/qgl_x11egl.cpp175
-rw-r--r--src/opengl/qglframebufferobject.cpp58
-rw-r--r--src/opengl/qglframebufferobject_p.h7
-rw-r--r--src/opengl/qglpixmapfilter.cpp18
-rw-r--r--src/opengl/qglshaderprogram.cpp8
-rw-r--r--src/opengl/qpaintengine_opengl.cpp10
-rw-r--r--src/opengl/qpixmapdata_gl.cpp2
13 files changed, 186 insertions, 133 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index eceed06..fcb20b4 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -78,7 +78,7 @@ const char* QGLEngineSharedShaders::qglEngineShaderSourceCode[] = {
};
QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
- : ctx(QGLContextPrivate::contextGroup(context))
+ : ctxGuard(context)
, blitShaderProg(0)
, simpleShaderProg(0)
{
@@ -223,7 +223,7 @@ QGLShader *QGLEngineSharedShaders::compileNamedShader(ShaderName name, QGLShader
return compiledShaders[name];
QByteArray source = qglEngineShaderSourceCode[name];
- QGLShader *newShader = new QGLShader(type, ctx->context(), this);
+ QGLShader *newShader = new QGLShader(type, ctxGuard.context(), this);
newShader->compile(source);
#if defined(QT_DEBUG)
@@ -245,7 +245,7 @@ QGLShader *QGLEngineSharedShaders::compileCustomShader(QGLCustomShaderStage *sta
if (newShader)
return newShader;
- newShader = new QGLShader(type, ctx->context(), this);
+ newShader = new QGLShader(type, ctxGuard.context(), this);
newShader->compile(source);
customShaderCache.insert(source, newShader);
@@ -273,7 +273,7 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
QGLEngineShaderProg &cached = cachedPrograms.last();
// If the shader program's not found in the cache, create it now.
- cached.program = new QGLShaderProgram(ctx->context(), this);
+ cached.program = new QGLShaderProgram(ctxGuard.context(), this);
cached.program->addShader(cached.mainVertexShader);
cached.program->addShader(cached.positionVertexShader);
cached.program->addShader(cached.mainFragShader);
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 47d9a2a..fbb6d9c 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -361,7 +361,7 @@ private slots:
void shaderDestroyed(QObject *shader);
private:
- QGLContextGroup *ctx;
+ QGLSharedResourceGuard ctxGuard;
QGLShaderProgram *blitShaderProg;
QGLShaderProgram *simpleShaderProg;
QList<QGLEngineShaderProg> cachedPrograms;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 7e45fd9..f612bc0 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1452,6 +1452,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
#if !defined(QT_OPENGL_ES_2)
bool success = qt_resolve_version_2_0_functions(d->ctx);
Q_ASSERT(success);
+ Q_UNUSED(success);
#endif
d->shaderManager = new QGLEngineShaderManager(d->ctx);
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 1276443..bfb004e 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2254,7 +2254,7 @@ QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum targe
Q_Q(QGLContext);
QGLTexture *texture = QGLTextureCache::instance()->getTexture(key);
if (texture && texture->target == target
- && (texture->context == q || qgl_share_reg()->checkSharing(q, texture->context)))
+ && (texture->context == q || QGLContext::areSharing(q, texture->context)))
{
return texture;
}
@@ -2755,6 +2755,20 @@ void QGLContext::setDevice(QPaintDevice *pDev)
*/
/*!
+ Returns true if \a context1 and \a context2 are sharing their
+ GL resources such as textures, shader programs, etc;
+ otherwise returns false.
+
+ \since 4.6
+*/
+bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *context2)
+{
+ if (!context1 || !context2)
+ return false;
+ return context1->d_ptr->group == context2->d_ptr->group;
+}
+
+/*!
\fn bool QGLContext::deviceIsPixmap() const
Returns true if the paint device of this context is a pixmap;
@@ -4835,11 +4849,6 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name()
}
#endif
-bool QGLShareRegister::checkSharing(const QGLContext *context1, const QGLContext *context2) {
- bool sharing = (context1 && context2 && context1->d_ptr->group == context2->d_ptr->group);
- return sharing;
-}
-
void QGLShareRegister::addShare(const QGLContext *context, const QGLContext *share) {
Q_ASSERT(context && share);
if (context->d_ptr->group == share->d_ptr->group)
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 1776004..b1c1317 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -282,6 +282,8 @@ public:
bool isSharing() const;
void reset();
+ static bool areSharing(const QGLContext *context1, const QGLContext *context2);
+
QGLFormat format() const;
QGLFormat requestedFormat() const;
void setFormat(const QGLFormat& format);
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 2e8ac88..9b09c7c 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -399,13 +399,12 @@ public:
Q_DECLARE_OPERATORS_FOR_FLAGS(QGLExtensions::Extensions)
-class QGLShareRegister
+class Q_AUTOTEST_EXPORT QGLShareRegister
{
public:
QGLShareRegister() {}
~QGLShareRegister() { reg.clear(); }
- bool checkSharing(const QGLContext *context1, const QGLContext *context2);
void addShare(const QGLContext *context, const QGLContext *share);
QList<const QGLContext *> shares(const QGLContext *context);
void removeShare(const QGLContext *context);
@@ -436,7 +435,7 @@ public:
QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext());
QGLContext *ctx = const_cast<QGLContext *>(context);
Q_ASSERT(ctx);
- bool switch_context = current != ctx && !qgl_share_reg()->checkSharing(current, ctx);
+ bool switch_context = current != ctx && !QGLContext::areSharing(current, ctx);
if (switch_context)
ctx->makeCurrent();
#if defined(Q_WS_X11)
@@ -547,7 +546,7 @@ public:
: m_oldContext(0)
{
QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
- if (currentContext != ctx && !qgl_share_reg()->checkSharing(ctx, currentContext)) {
+ if (currentContext != ctx && !QGLContext::areSharing(ctx, currentContext)) {
m_oldContext = currentContext;
m_ctx = const_cast<QGLContext *>(ctx);
m_ctx->makeCurrent();
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index 67f391b..d4bf4da 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -408,6 +408,103 @@ void QGLWidgetPrivate::recreateEglSurface(bool force)
}
}
+// Selects which configs should be used
+EGLConfig Q_OPENGL_EXPORT qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOnly)
+{
+ // Cache the configs we select as they wont change:
+ static EGLConfig roPixmapRGBConfig = 0;
+ static EGLConfig roPixmapRGBAConfig = 0;
+ static EGLConfig rwPixmapRGBConfig = 0;
+ static EGLConfig rwPixmapRGBAConfig = 0;
+
+ EGLConfig* targetConfig;
+
+ if (hasAlpha) {
+ if (readOnly)
+ targetConfig = &roPixmapRGBAConfig;
+ else
+ targetConfig = &rwPixmapRGBAConfig;
+ }
+ else {
+ if (readOnly)
+ targetConfig = &roPixmapRGBConfig;
+ else
+ targetConfig = &rwPixmapRGBConfig;
+ }
+
+ if (*targetConfig == 0) {
+ QEglProperties configAttribs;
+ configAttribs.setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT);
+ configAttribs.setRenderableType(QEgl::OpenGL);
+ if (hasAlpha)
+ configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
+ else
+ configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
+
+ // If this is going to be a render target, it needs to have a depth, stencil & sample buffer
+ if (!readOnly) {
+ configAttribs.setValue(EGL_DEPTH_SIZE, 1);
+ configAttribs.setValue(EGL_STENCIL_SIZE, 1);
+ configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1);
+ }
+
+ EGLint configCount = 0;
+ do {
+ eglChooseConfig(QEglContext::defaultDisplay(0), configAttribs.properties(), targetConfig, 1, &configCount);
+ if (configCount > 0) {
+ // Got one
+ qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" )
+ << "config (" << int(*targetConfig) << ") to create a pixmap surface:";
+
+// QEglProperties configProps(*targetConfig);
+// qDebug() << configProps.toString();
+ break;
+ }
+ qWarning("choosePixmapConfig() - No suitible config found, reducing requirements");
+ } while (configAttribs.reduceConfiguration());
+ }
+
+ if (*targetConfig == 0)
+ qWarning("choosePixmapConfig() - Couldn't find a suitable config");
+
+ return *targetConfig;
+}
+
+bool Q_OPENGL_EXPORT qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnly)
+{
+ Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
+ QX11PixmapData* pixmapData = static_cast<QX11PixmapData*>(pmd);
+
+ bool hasAlpha = pixmapData->hasAlphaChannel();
+
+ EGLConfig pixmapConfig = qt_chooseEGLConfigForPixmap(hasAlpha, readOnly);
+
+ QEglProperties pixmapAttribs;
+
+ // If the pixmap can't be bound to a texture, it's pretty useless
+ pixmapAttribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D);
+ if (hasAlpha)
+ pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA);
+ else
+ pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB);
+
+ EGLSurface pixmapSurface;
+ pixmapSurface = eglCreatePixmapSurface(QEglContext::defaultDisplay(0),
+ pixmapConfig,
+ (EGLNativePixmapType) pixmapData->handle(),
+ pixmapAttribs.properties());
+ if (pixmapSurface == EGL_NO_SURFACE) {
+ qWarning("Failed to create a pixmap surface using config %d", (int)pixmapConfig);
+ return false;
+ }
+
+ Q_ASSERT(sizeof(Qt::HANDLE) >= sizeof(EGLSurface)); // Just to make totally sure!
+ pixmapData->gl_surface = (Qt::HANDLE)pixmapSurface;
+ pixmapData->is_cached = true; // Make sure the cleanup hook gets called
+
+ return true;
+}
+
QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, const qint64 key,
QGLContext::BindOptions options)
@@ -449,82 +546,14 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons
destroyGlSurfaceForPixmap(pixmapData);
}
- EGLint pixmapAttribs[] = {
- EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
- EGL_TEXTURE_FORMAT, hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
- EGL_NONE
- };
- Q_ASSERT(sizeof(Qt::HANDLE) >= sizeof(EGLSurface)); // Just to make totally sure!
- if (pixmapData->gl_surface == 0)
- pixmapData->gl_surface = (Qt::HANDLE)EGL_NO_SURFACE;
- EGLSurface pixmapSurface = (EGLSurface)pixmapData->gl_surface;
- static EGLConfig pixmapRGBConfig = 0;
- static EGLConfig pixmapRGBAConfig = 0;
-
- // Check to see if we need to find a config
- if ((hasAlpha && !pixmapRGBAConfig) || (!hasAlpha && !pixmapRGBConfig) ) {
- const EGLint configAttribs[] = {
- EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_DEPTH_SIZE, 0,
- hasAlpha ? EGL_BIND_TO_TEXTURE_RGBA : EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE,
- EGL_NONE
- };
-
- EGLint configCount = 0;
- eglChooseConfig(eglContext->display(), configAttribs, 0, 256, &configCount);
- if (configCount == 0) {
- haveTFP = false;
- qWarning("bindTextureFromNativePixmap() - Couldn't find a suitable config");
- return 0;
- }
-
- EGLConfig *configList = new EGLConfig[configCount];
- eglChooseConfig(eglContext->display(), configAttribs, configList, configCount, &configCount);
- Q_ASSERT(configCount);
-
- // Try to create a pixmap surface for each config until one works
- for (int i = 0; i < configCount; ++i) {
- pixmapSurface = eglCreatePixmapSurface(eglContext->display(), configList[i],
- (EGLNativePixmapType) pixmapData->handle(),
- pixmapAttribs);
- if (pixmapSurface != EGL_NO_SURFACE) {
- // Got one!
- qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB")
- << "config (" << int(configList[i]) << ") to create a pixmap surface";
- if (hasAlpha)
- pixmapRGBAConfig = configList[i];
- else
- pixmapRGBConfig = configList[i];
- pixmapData->gl_surface = (Qt::HANDLE)pixmapSurface;
- break;
- }
- }
- delete configList;
-
- if ((hasAlpha && !pixmapRGBAConfig) || (!hasAlpha && !pixmapRGBConfig) ) {
- qDebug("Couldn't create a pixmap surface with any of the provided configs");
- haveTFP = false;
- return 0;
- }
- }
-
- if (pixmapSurface == EGL_NO_SURFACE) {
- pixmapSurface = eglCreatePixmapSurface(eglContext->display(),
- hasAlpha? pixmapRGBAConfig : pixmapRGBConfig,
- (EGLNativePixmapType) pixmapData->handle(),
- pixmapAttribs);
- if (pixmapSurface == EGL_NO_SURFACE) {
- qWarning("Failed to create a pixmap surface using config %d",
- (int)(hasAlpha? pixmapRGBAConfig : pixmapRGBConfig));
+ if (pixmapData->gl_surface == 0) {
+ bool success = qt_createEGLSurfaceForPixmap(pixmapData, true);
+ if (!success) {
haveTFP = false;
return 0;
}
- pixmapData->gl_surface = (Qt::HANDLE)pixmapSurface;
}
- // Make sure the cleanup hook gets called so we can delete the glx pixmap
- pixmapData->is_cached = true;
Q_ASSERT(pixmapData->gl_surface);
GLuint textureId;
@@ -534,10 +563,10 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons
// bind the egl pixmap surface to a texture
EGLBoolean success;
- success = eglBindTexImage(eglContext->display(), pixmapSurface, EGL_BACK_BUFFER);
+ success = eglBindTexImage(eglContext->display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER);
if (success == EGL_FALSE) {
qWarning() << "eglBindTexImage() failed:" << eglContext->errorString(eglGetError());
- eglDestroySurface(eglContext->display(), pixmapSurface);
+ eglDestroySurface(eglContext->display(), (EGLSurface)pixmapData->gl_surface);
pixmapData->gl_surface = (Qt::HANDLE)EGL_NO_SURFACE;
haveTFP = false;
return 0;
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index c728902..3e54b35 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -64,7 +64,8 @@ QT_BEGIN_NAMESPACE
extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
-#define QGL_FUNC_CONTEXT QGLContextGroup *ctx = d_ptr->ctx;
+#define QGL_FUNC_CONTEXT const QGLContext *ctx = d_ptr->fbo_guard.context();
+#define QGL_FUNCP_CONTEXT const QGLContext *ctx = fbo_guard.context();
#ifndef QT_NO_DEBUG
#define QT_RESET_GLERROR() \
@@ -317,7 +318,7 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
QGLFramebufferObject::Attachment attachment)
{
fbo = f;
- m_thisFBO = fbo->d_func()->fbo; // This shouldn't be needed
+ m_thisFBO = fbo->d_func()->fbo(); // This shouldn't be needed
// The context that the fbo was created in may not have depth
// and stencil buffers, but the fbo itself might.
@@ -334,7 +335,7 @@ void QGLFBOGLPaintDevice::ensureActiveTarget()
{
QGLContext* ctx = const_cast<QGLContext*>(QGLContext::currentContext());
Q_ASSERT(ctx);
- const GLuint fboId = fbo->d_func()->fbo;
+ const GLuint fboId = fbo->d_func()->fbo();
if (ctx->d_func()->current_fbo != fboId) {
ctx->d_func()->current_fbo = fboId;
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId);
@@ -359,6 +360,9 @@ void QGLFBOGLPaintDevice::endPaint()
bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
{
+ QGL_FUNCP_CONTEXT;
+ if (!ctx)
+ return false; // Context no longer exists.
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_NO_ERROR:
@@ -405,11 +409,11 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
QGLFramebufferObject::Attachment attachment,
GLenum texture_target, GLenum internal_format, GLint samples)
{
- QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
- ctx = QGLContextPrivate::contextGroup(currentContext);
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
+ fbo_guard.setContext(ctx);
bool ext_detected = (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject);
- if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(currentContext)))
+ if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
return;
size = sz;
@@ -417,8 +421,10 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
// texture dimensions
QT_RESET_GLERROR(); // reset error state
+ GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
+ fbo_guard.setId(fbo);
glDevice.setFBO(q, attachment);
@@ -535,13 +541,14 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
fbo_attachment = QGLFramebufferObject::NoAttachment;
}
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, currentContext->d_ptr->current_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
if (!valid) {
if (color_buffer)
glDeleteRenderbuffers(1, &color_buffer);
else
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &fbo);
+ fbo_guard.setId(0);
}
QT_CHECK_GLERROR();
@@ -810,19 +817,15 @@ QGLFramebufferObject::~QGLFramebufferObject()
delete d->engine;
- if (isValid()) {
- const QGLContext *oldContext = QGLContext::currentContext();
- bool switchContext = !oldContext || QGLContextPrivate::contextGroup(oldContext) != ctx;
- if (switchContext)
- const_cast<QGLContext *>(ctx->context())->makeCurrent();
+ if (isValid() && ctx) {
+ QGLShareContextScope scope(ctx);
glDeleteTextures(1, &d->texture);
if (d->color_buffer)
glDeleteRenderbuffers(1, &d->color_buffer);
if (d->depth_stencil_buffer)
glDeleteRenderbuffers(1, &d->depth_stencil_buffer);
- glDeleteFramebuffers(1, &d->fbo);
- if (oldContext && switchContext)
- const_cast<QGLContext *>(oldContext)->makeCurrent();
+ GLuint fbo = d->fbo();
+ glDeleteFramebuffers(1, &fbo);
}
}
@@ -838,11 +841,16 @@ QGLFramebufferObject::~QGLFramebufferObject()
The non-power of two limitation does not apply if the OpenGL version
is 2.0 or higher, or if the GL_ARB_texture_non_power_of_two extension
is present.
+
+ The framebuffer can also become invalid if the QGLContext that
+ the framebuffer was created within is destroyed and there are
+ no other shared contexts that can take over ownership of the
+ framebuffer.
*/
bool QGLFramebufferObject::isValid() const
{
Q_D(const QGLFramebufferObject);
- return d->valid;
+ return d->valid && d->fbo_guard.context();
}
/*!
@@ -867,15 +875,17 @@ bool QGLFramebufferObject::bind()
return false;
Q_D(QGLFramebufferObject);
QGL_FUNC_CONTEXT;
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, d->fbo);
+ if (!ctx)
+ return false; // Context no longer exists.
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, d->fbo());
d->valid = d->checkFramebufferStatus();
const QGLContext *context = QGLContext::currentContext();
if (d->valid && context) {
- Q_ASSERT(QGLContextPrivate::contextGroup(context) == ctx);
+ Q_ASSERT(QGLContextPrivate::contextGroup(context) == QGLContextPrivate::contextGroup(ctx));
// Save the previous setting to automatically restore in release().
- if (context->d_ptr->current_fbo != d->fbo) {
+ if (context->d_ptr->current_fbo != d->fbo()) {
d->previous_fbo = context->d_ptr->current_fbo;
- context->d_ptr->current_fbo = d->fbo;
+ context->d_ptr->current_fbo = d->fbo();
}
}
return d->valid;
@@ -900,10 +910,12 @@ bool QGLFramebufferObject::release()
return false;
Q_D(QGLFramebufferObject);
QGL_FUNC_CONTEXT;
+ if (!ctx)
+ return false; // Context no longer exists.
const QGLContext *context = QGLContext::currentContext();
if (context) {
- Q_ASSERT(QGLContextPrivate::contextGroup(context) == ctx);
+ Q_ASSERT(QGLContextPrivate::contextGroup(context) == QGLContextPrivate::contextGroup(ctx));
// Restore the previous setting for stacked framebuffer objects.
if (d->previous_fbo != context->d_ptr->current_fbo) {
context->d_ptr->current_fbo = d->previous_fbo;
@@ -1144,7 +1156,7 @@ int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
GLuint QGLFramebufferObject::handle() const
{
Q_D(const QGLFramebufferObject);
- return d->fbo;
+ return d->fbo();
}
/*! \fn int QGLFramebufferObject::devType() const
@@ -1175,7 +1187,7 @@ QGLFramebufferObject::Attachment QGLFramebufferObject::attachment() const
bool QGLFramebufferObject::isBound() const
{
Q_D(const QGLFramebufferObject);
- return QGLContext::currentContext()->d_ptr->current_fbo == d->fbo;
+ return QGLContext::currentContext()->d_ptr->current_fbo == d->fbo();
}
/*!
diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h
index f80209d..055a752 100644
--- a/src/opengl/qglframebufferobject_p.h
+++ b/src/opengl/qglframebufferobject_p.h
@@ -127,15 +127,15 @@ private:
class QGLFramebufferObjectPrivate
{
public:
- QGLFramebufferObjectPrivate() : depth_stencil_buffer(0), valid(false), ctx(0), previous_fbo(0), engine(0) {}
+ QGLFramebufferObjectPrivate() : fbo_guard(0), depth_stencil_buffer(0), valid(false), previous_fbo(0), engine(0) {}
~QGLFramebufferObjectPrivate() {}
void init(QGLFramebufferObject *q, const QSize& sz,
QGLFramebufferObject::Attachment attachment,
GLenum internal_format, GLenum texture_target, GLint samples = 0);
bool checkFramebufferStatus() const;
+ QGLSharedResourceGuard fbo_guard;
GLuint texture;
- GLuint fbo;
GLuint depth_stencil_buffer;
GLuint color_buffer;
GLenum target;
@@ -143,10 +143,11 @@ public:
QGLFramebufferObjectFormat format;
uint valid : 1;
QGLFramebufferObject::Attachment fbo_attachment;
- QGLContextGroup *ctx; // for Windows extension ptrs
GLuint previous_fbo;
mutable QPaintEngine *engine;
QGLFBOGLPaintDevice glDevice;
+
+ inline GLuint fbo() const { return fbo_guard.id(); }
};
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index 15714c2..1ae3866 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -100,7 +100,7 @@ private:
class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
{
public:
- QGLPixmapBlurFilter(QPixmapBlurFilter::BlurHint hint);
+ QGLPixmapBlurFilter(Qt::RenderHint hint);
void setUniforms(QGLShaderProgram *program);
@@ -115,7 +115,7 @@ private:
mutable bool m_haveCached;
mutable int m_cachedRadius;
- mutable QPixmapBlurFilter::BlurHint m_hint;
+ mutable Qt::RenderHint m_hint;
};
extern QGLWidget *qt_gl_share_widget();
@@ -131,13 +131,13 @@ QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *pr
case QPixmapFilter::BlurFilter: {
const QPixmapBlurFilter *proto = static_cast<const QPixmapBlurFilter *>(prototype);
- if (proto->blurHint() == QPixmapBlurFilter::PerformanceHint || proto->radius() <= 5) {
+ if (proto->blurHint() == Qt::PerformanceHint || proto->radius() <= 5) {
if (!d->fastBlurFilter)
- d->fastBlurFilter.reset(new QGLPixmapBlurFilter(QPixmapBlurFilter::PerformanceHint));
+ d->fastBlurFilter.reset(new QGLPixmapBlurFilter(Qt::PerformanceHint));
return d->fastBlurFilter.data();
}
if (!d->blurFilter)
- d->blurFilter.reset(new QGLPixmapBlurFilter(QPixmapBlurFilter::QualityHint));
+ d->blurFilter.reset(new QGLPixmapBlurFilter(Qt::QualityHint));
return d->blurFilter.data();
}
@@ -279,12 +279,12 @@ static const char *qt_gl_blur_filter_fast =
" return color * (1.0 / float(samples));"
"}";
-QGLPixmapBlurFilter::QGLPixmapBlurFilter(QPixmapBlurFilter::BlurHint hint)
+QGLPixmapBlurFilter::QGLPixmapBlurFilter(Qt::RenderHint hint)
: m_haveCached(false)
, m_cachedRadius(5)
, m_hint(hint)
{
- if (hint == PerformanceHint) {
+ if (hint == Qt::PerformanceHint) {
QGLPixmapBlurFilter *filter = const_cast<QGLPixmapBlurFilter *>(this);
filter->setSource(qt_gl_blur_filter_fast);
m_haveCached = true;
@@ -296,7 +296,7 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const
QGLPixmapBlurFilter *filter = const_cast<QGLPixmapBlurFilter *>(this);
int radius = this->radius();
- if (!m_haveCached || (m_hint == QualityHint && radius != m_cachedRadius)) {
+ if (!m_haveCached || (m_hint == Qt::QualityHint && radius != m_cachedRadius)) {
// Only regenerate the shader from source if parameters have changed.
m_haveCached = true;
m_cachedRadius = radius;
@@ -358,7 +358,7 @@ bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const
void QGLPixmapBlurFilter::setUniforms(QGLShaderProgram *program)
{
- if (m_hint == QualityHint) {
+ if (m_hint == Qt::QualityHint) {
if (m_horizontalBlur)
program->setUniformValue("delta", 1.0 / m_textureSize.width(), 0.0);
else
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index ebcd723..dfa6c40 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -349,7 +349,7 @@ QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObj
context = QGLContext::currentContext();
d = new QGLShaderPrivate(context, type);
#ifndef QT_NO_DEBUG
- if (context && !qgl_share_reg()->checkSharing(context, QGLContext::currentContext())) {
+ if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) {
qWarning("QGLShader::QGLShader: \'context\' must be the currect context or sharing with it.");
return;
}
@@ -374,7 +374,7 @@ QGLShader::QGLShader
context = QGLContext::currentContext();
d = new QGLShaderPrivate(context, type);
#ifndef QT_NO_DEBUG
- if (context && !qgl_share_reg()->checkSharing(context, QGLContext::currentContext())) {
+ if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) {
qWarning("QGLShader::QGLShader: \'context\' must be currect context or sharing with it.");
return;
}
@@ -806,8 +806,8 @@ bool QGLShaderProgram::addShader(QGLShader *shader)
if (d->shaders.contains(shader))
return true; // Already added to this shader program.
if (d->programGuard.id() && shader) {
- if (!qgl_share_reg()->checkSharing(shader->d->shaderGuard.context(),
- d->programGuard.context())) {
+ if (!QGLContext::areSharing(shader->d->shaderGuard.context(),
+ d->programGuard.context())) {
qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
return false;
}
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index a904064..da490c0 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -338,7 +338,7 @@ void QGLOffscreen::initialize()
int dim = qMax(2048, static_cast<int>(qt_next_power_of_two(qMax(device->size().width(), device->size().height()))));
- bool shared_context = qgl_share_reg()->checkSharing(device->context(), ctx);
+ bool shared_context = QGLContext::areSharing(device->context(), ctx);
bool would_fail = last_failed_size.isValid() &&
(device->size().width() >= last_failed_size.width() ||
device->size().height() >= last_failed_size.height());
@@ -555,7 +555,7 @@ public:
QList<const QGLContext *> contexts = programs.uniqueKeys();
for (int i=0; i<contexts.size(); ++i) {
const QGLContext *cx = contexts.at(i);
- if (cx != ctx && qgl_share_reg()->checkSharing(cx, ctx)) {
+ if (cx != ctx && QGLContext::areSharing(cx, ctx)) {
QList<GLProgram> progs = programs.values(cx);
for (int k=0; k<progs.size(); ++k) {
const GLProgram &prg = progs.at(k);
@@ -1015,7 +1015,7 @@ public:
}
inline GLuint getBuffer(const QGradient &gradient, qreal opacity, QGLContext *ctx) {
- if (buffer_ctx && !qgl_share_reg()->checkSharing(buffer_ctx, ctx))
+ if (buffer_ctx && !QGLContext::areSharing(buffer_ctx, ctx))
cleanCache();
buffer_ctx = ctx;
@@ -1365,7 +1365,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
#ifdef QT_OPENGL_ES
d->max_texture_size = ctx->d_func()->maxTextureSize();
#else
- bool shared_ctx = qgl_share_reg()->checkSharing(d->device->context(), d->shader_ctx);
+ bool shared_ctx = QGLContext::areSharing(d->device->context(), d->shader_ctx);
if (shared_ctx) {
d->max_texture_size = d->shader_ctx->d_func()->maxTextureSize();
@@ -4683,7 +4683,7 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti,
QList<const QGLContext *> contexts = qt_context_cache.keys();
for (int i=0; i<contexts.size(); ++i) {
const QGLContext *ctx = contexts.at(i);
- if (ctx != context && qgl_share_reg()->checkSharing(context, ctx)) {
+ if (ctx != context && QGLContext::areSharing(context, ctx)) {
context_key = ctx;
dev_it = qt_context_cache.constFind(context_key);
break;
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 2331c6d..1ee3bbf 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -248,7 +248,7 @@ bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
return true;
const QGLContext *share_ctx = qt_gl_share_widget()->context();
- return ctx == share_ctx || qgl_share_reg()->checkSharing(ctx, share_ctx);
+ return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
}
void QGLPixmapData::resize(int width, int height)