summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@trolltech.com>2009-10-02 09:40:07 (GMT)
committerGunnar Sletta <gunnar@trolltech.com>2009-10-02 09:40:07 (GMT)
commitcfd31c28f2e30ee725d23c36ea8349f984b57047 (patch)
tree5fcf867475a6fde5b884c9236350460cee0ed95f /src/opengl
parent46c17756dfa231d5ce7a8907330d97807880a04c (diff)
parentfe85e470d76f6e53759d0fd508e858add5de1eb0 (diff)
downloadQt-cfd31c28f2e30ee725d23c36ea8349f984b57047.zip
Qt-cfd31c28f2e30ee725d23c36ea8349f984b57047.tar.gz
Qt-cfd31c28f2e30ee725d23c36ea8349f984b57047.tar.bz2
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into 4.6
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.cpp73
-rw-r--r--src/opengl/qgl.h2
-rw-r--r--src/opengl/qgl_egl.cpp17
-rw-r--r--src/opengl/qgl_p.h19
-rw-r--r--src/opengl/qgl_x11.cpp92
-rw-r--r--src/opengl/qgl_x11egl.cpp333
-rw-r--r--src/opengl/qglframebufferobject.cpp58
-rw-r--r--src/opengl/qglframebufferobject_p.h7
-rw-r--r--src/opengl/qglpixelbuffer_x11.cpp33
-rw-r--r--src/opengl/qglpixmapfilter.cpp197
-rw-r--r--src/opengl/qglshaderprogram.cpp8
-rw-r--r--src/opengl/qpaintengine_opengl.cpp26
-rw-r--r--src/opengl/qpixmapdata_gl.cpp2
16 files changed, 440 insertions, 438 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 77dc9ae..2327d7a 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1626,9 +1626,8 @@ void QGLTextureCache::pixmapCleanupHook(QPixmap* pixmap)
}
#if defined(Q_WS_X11)
QPixmapData *pd = pixmap->data_ptr().data();
- // Only need to delete the gl surface if the pixmap is about to be deleted
- if (pd->ref == 0)
- QGLContextPrivate::destroyGlSurfaceForPixmap(pd);
+ Q_ASSERT(pd->ref == 1); // Make sure reference counting isn't broken
+ QGLContextPrivate::destroyGlSurfaceForPixmap(pd);
#endif
}
@@ -1721,7 +1720,7 @@ Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg()
the top left corner. Inverting the texture implies a deep copy
prior to upload.
- \value MipmapBindOption Specifies that bindTexture should try
+ \value MipmapBindOption Specifies that bindTexture() should try
to generate mipmaps. If the GL implementation supports the \c
GL_SGIS_generate_mipmap extension, mipmaps will be automatically
generated for the texture. Mipmap generation is only supported for
@@ -2267,7 +2266,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;
}
@@ -2374,6 +2373,8 @@ GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format)
}
/*!
+ \since 4.6
+
Generates and binds a 2D GL texture to the current context, based
on \a image. The generated texture id is returned and can be used
in later \c glBindTexture() calls.
@@ -2435,6 +2436,7 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint forma
/*!
\overload
+ \since 4.6
Generates and binds a 2D GL texture to the current context, based
on \a pixmap.
@@ -2768,6 +2770,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;
@@ -4502,6 +4518,7 @@ GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format)
/*!
\overload
+ \since 4.6
The binding \a options are a set of options used to decide how to
bind the texture to the context.
@@ -4543,6 +4560,7 @@ GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format
/*!
\overload
+ \since 4.6
Generates and binds a 2D GL texture to the current context, based
on \a pixmap. The generated texture id is returned and can be used in
@@ -4848,55 +4866,46 @@ 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)
return;
// Make sure 'context' is not already shared with another group of contexts.
- Q_ASSERT(reg.find(context->d_ptr->group) == reg.end());
Q_ASSERT(context->d_ptr->group->m_refs == 1);
// Free 'context' group resources and make it use the same resources as 'share'.
+ QGLContextGroup *group = share->d_ptr->group;
delete context->d_ptr->group;
- context->d_ptr->group = share->d_ptr->group;
- context->d_ptr->group->m_refs.ref();
+ context->d_ptr->group = group;
+ group->m_refs.ref();
// Maintain a list of all the contexts in each group of sharing contexts.
- SharingHash::iterator it = reg.find(share->d_ptr->group);
- if (it == reg.end())
- it = reg.insert(share->d_ptr->group, ContextList() << share);
- it.value() << context;
+ // The list is empty if the "share" context wasn't sharing already.
+ if (group->m_shares.isEmpty())
+ group->m_shares.append(share);
+ group->m_shares.append(context);
}
QList<const QGLContext *> QGLShareRegister::shares(const QGLContext *context) {
- SharingHash::const_iterator it = reg.find(context->d_ptr->group);
- if (it == reg.end())
- return ContextList();
- return it.value();
+ return context->d_ptr->group->m_shares;
}
void QGLShareRegister::removeShare(const QGLContext *context) {
- SharingHash::iterator it = reg.find(context->d_ptr->group);
- if (it == reg.end())
+ // Remove the context from the group.
+ QGLContextGroup *group = context->d_ptr->group;
+ if (group->m_shares.isEmpty())
return;
-
- int count = it.value().removeAll(context);
- Q_ASSERT(count == 1);
- Q_UNUSED(count);
+ group->m_shares.removeAll(context);
// Update context group representative.
- if (context->d_ptr->group->m_context == context)
- context->d_ptr->group->m_context = it.value().first();
+ Q_ASSERT(group->m_shares.size() != 0);
+ if (group->m_context == context)
+ group->m_context = group->m_shares[0];
- Q_ASSERT(it.value().size() != 0);
- if (it.value().size() == 1)
- reg.erase(it);
+ // If there is only one context left, then make the list empty.
+ if (group->m_shares.size() == 1)
+ group->m_shares.clear();
}
QGLContextResource::QGLContextResource(FreeFunc f, QObject *parent)
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_egl.cpp b/src/opengl/qgl_egl.cpp
index 5ce1a45..fa876c7 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -142,10 +142,23 @@ void QGLContext::reset()
d->cleanup();
doneCurrent();
if (d->eglContext) {
+ if (d->eglSurface != EGL_NO_SURFACE) {
+#ifdef Q_WS_X11
+ // Make sure we don't call eglDestroySurface on a surface which
+ // was created for a different winId:
+ if (d->paintDevice->devType() == QInternal::Widget) {
+ QGLWidget* w = static_cast<QGLWidget*>(d->paintDevice);
+
+ if (w->d_func()->eglSurfaceWindowId == w->winId())
+ eglDestroySurface(d->eglContext->display(), d->eglSurface);
+ } else
+#endif
+ eglDestroySurface(d->eglContext->display(), d->eglSurface);
+ }
delete d->eglContext;
- d->eglContext = 0;
}
- d->eglSurface = EGL_NO_SURFACE; // XXX - probably need to destroy surface
+ d->eglContext = 0;
+ d->eglSurface = EGL_NO_SURFACE;
d->crWin = false;
d->sharing = false;
d->valid = false;
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 2e8ac88..1957429 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -233,6 +233,7 @@ private:
QGLExtensionFuncs m_extensionFuncs;
const QGLContext *m_context; // context group's representative
+ QList<const QGLContext *> m_shares;
QAtomicInt m_refs;
friend class QGLShareRegister;
@@ -343,13 +344,11 @@ public:
#ifdef Q_WS_WIN
static inline QGLExtensionFuncs& extensionFuncs(const QGLContext *ctx) { return ctx->d_ptr->group->extensionFuncs(); }
- static inline QGLExtensionFuncs& extensionFuncs(QGLContextGroup *ctx) { return ctx->extensionFuncs(); }
#endif
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
static QGLExtensionFuncs qt_extensionFuncs;
static inline QGLExtensionFuncs& extensionFuncs(const QGLContext *) { return qt_extensionFuncs; }
- static inline QGLExtensionFuncs& extensionFuncs(QGLContextGroup *) { return qt_extensionFuncs; }
#endif
static void setCurrentContext(QGLContext *context);
@@ -399,21 +398,15 @@ public:
Q_DECLARE_OPERATORS_FOR_FLAGS(QGLExtensions::Extensions)
-class QGLShareRegister
+class Q_AUTOTEST_EXPORT QGLShareRegister
{
public:
QGLShareRegister() {}
- ~QGLShareRegister() { reg.clear(); }
+ ~QGLShareRegister() {}
- 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);
-private:
- // Use a context's 'group' pointer to uniquely identify a group.
- typedef QList<const QGLContext *> ContextList;
- typedef QHash<const QGLContextGroup *, ContextList> SharingHash;
- SharingHash reg;
};
extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg();
@@ -436,7 +429,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)
@@ -491,8 +484,6 @@ private:
#ifdef Q_WS_QWS
extern QPaintEngine* qt_qgl_paint_engine();
-
-extern EGLDisplay qt_qgl_egl_display();
#endif
bool qt_gl_preferGL2Engine();
@@ -547,7 +538,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_x11.cpp b/src/opengl/qgl_x11.cpp
index da7972d..86e593d 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -331,6 +331,62 @@ static void find_trans_colors()
QGLFormat UNIX/GLX-specific code
*****************************************************************************/
+void* qglx_getProcAddress(const char* procName)
+{
+ // On systems where the GL driver is pluggable (like Mesa), we have to use
+ // the glXGetProcAddressARB extension to resolve other function pointers as
+ // the symbols wont be in the GL library, but rather in a plugin loaded by
+ // the GL library.
+ typedef void* (*qt_glXGetProcAddressARB)(const char *);
+ static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
+ static bool triedResolvingGlxGetProcAddress = false;
+ if (!triedResolvingGlxGetProcAddress) {
+ triedResolvingGlxGetProcAddress = true;
+ QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
+ if (glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) {
+#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
+ void *handle = dlopen(NULL, RTLD_LAZY);
+ if (handle) {
+ glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
+ dlclose(handle);
+ }
+ if (!glXGetProcAddressARB)
+#endif
+ {
+#if !defined(QT_NO_LIBRARY)
+ extern const QString qt_gl_library_name();
+ QLibrary lib(qt_gl_library_name());
+ glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
+#endif
+ }
+ }
+ }
+
+ void *procAddress = 0;
+ if (glXGetProcAddressARB)
+ procAddress = glXGetProcAddressARB(procName);
+
+ // If glXGetProcAddress didn't work, try looking the symbol up in the GL library
+#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
+ if (!procAddress) {
+ void *handle = dlopen(NULL, RTLD_LAZY);
+ if (handle) {
+ procAddress = dlsym(handle, procName);
+ dlclose(handle);
+ }
+ }
+#endif
+#if !defined(QT_NO_LIBRARY)
+ if (!procAddress) {
+ extern const QString qt_gl_library_name();
+ QLibrary lib(qt_gl_library_name());
+ procAddress = lib.resolve(procName);
+ }
+#endif
+
+ return procAddress;
+}
+
bool QGLFormat::hasOpenGL()
{
return glXQueryExtension(X11->display, 0, 0) != 0;
@@ -819,23 +875,8 @@ void QGLContext::swapBuffers() const
if (!resolved) {
QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) dlsym(handle, "glXGetVideoSyncSGI");
- glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) dlsym(handle, "glXWaitVideoSyncSGI");
- dlclose(handle);
- }
- if (!glXGetVideoSyncSGI)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI");
- glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI");
-#endif
- }
+ glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
+ glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
}
resolved = true;
}
@@ -1568,21 +1609,8 @@ bool qt_resolveTextureFromPixmap()
QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
if (glxExt.contains(QLatin1String("GLX_EXT_texture_from_pixmap"))) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXBindTexImageEXT = (qt_glXBindTexImageEXT) dlsym(handle, "glXBindTexImageEXT");
- glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) dlsym(handle, "glXReleaseTexImageEXT");
- dlclose(handle);
- }
- if (!glXBindTexImageEXT)
-#endif
- {
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXBindTexImageEXT = (qt_glXBindTexImageEXT) lib.resolve("glXBindTexImageEXT");
- glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) lib.resolve("glXReleaseTexImageEXT");
- }
+ glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
+ glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
}
}
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index 70b2013..971a660 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -150,85 +150,36 @@ void QGLWidget::updateOverlayGL()
//handle overlay
}
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
+bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual)
{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- if (parentWidget()) {
- // force creation of delay-created widgets
- parentWidget()->winId();
- if (parentWidget()->x11Info().screen() != x11Info().screen())
- d_func()->xinfo = parentWidget()->d_func()->xinfo;
- }
-
- // If the application has set WA_TranslucentBackground and not explicitly set
- // the alpha buffer size to zero, modify the format so it have an alpha channel
- QGLFormat& fmt = d->glcx->d_func()->glFormat;
- const bool useArgbVisual = testAttribute(Qt::WA_TranslucentBackground);
- if (useArgbVisual && fmt.alphaBufferSize() == -1)
- fmt.setAlphaBufferSize(1);
-
- bool createFailed = false;
- if (!d->glcx->isValid()) {
- if (!d->glcx->create(shareContext ? shareContext : oldcx))
- createFailed = true;
- }
- if (createFailed) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
+ bool foundVisualIsArgb = useArgbVisual;
- if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
- bool visible = isVisible();
- if (visible)
- hide();
-
- XVisualInfo vi;
memset(&vi, 0, sizeof(XVisualInfo));
// Check to see if EGL is suggesting an appropriate visual id:
EGLint nativeVisualId;
- QEglContext* qeglCtx = d->glcx->d_func()->eglContext;
- qeglCtx->configAttrib(EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId);
vi.visualid = nativeVisualId;
if (vi.visualid) {
// EGL has suggested a visual id, so get the rest of the visual info for that id:
XVisualInfo *chosenVisualInfo;
int matchingCount = 0;
- chosenVisualInfo = XGetVisualInfo(x11Info().display(), VisualIDMask, &vi, &matchingCount);
+ chosenVisualInfo = XGetVisualInfo(x11Info.display(), VisualIDMask, &vi, &matchingCount);
if (chosenVisualInfo) {
#if !defined(QT_NO_XRENDER)
if (useArgbVisual) {
// Check to make sure the visual provided by EGL is ARGB
XRenderPictFormat *format;
- format = XRenderFindVisualFormat(x11Info().display(), chosenVisualInfo->visual);
+ format = XRenderFindVisualFormat(x11Info.display(), chosenVisualInfo->visual);
if (format->type == PictTypeDirect && format->direct.alphaMask) {
-// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid);
+// qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid);
+ foundVisualIsArgb = true;
vi = *chosenVisualInfo;
}
else {
qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this is not ARGB",
- nativeVisualId, (int)qeglCtx->config());
+ nativeVisualId, (int)config);
vi.visualid = 0;
}
} else
@@ -241,32 +192,32 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
}
else {
qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this seems to be invalid!",
- nativeVisualId, (int)qeglCtx->config());
+ nativeVisualId, (int)config);
vi.visualid = 0;
}
}
// If EGL does not know the visual ID, so try to select an appropriate one ourselves, first
// using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo
-
- bool useArgb = context->format().alpha() && !context->deviceIsPixmap();
+
#if !defined(QT_NO_XRENDER)
- if (vi.visualid == 0 && useArgb) {
+ if (vi.visualid == 0 && useArgbVisual) {
// Try to use XRender to find an ARGB visual we can use
- vi.screen = x11Info().screen();
- vi.depth = 32;
+ vi.screen = x11Info.screen();
+ vi.depth = 32; //### We might at some point (soon) get ARGB4444
vi.c_class = TrueColor;
XVisualInfo *matchingVisuals;
int matchingCount = 0;
- matchingVisuals = XGetVisualInfo(x11Info().display(),
+ matchingVisuals = XGetVisualInfo(x11Info.display(),
VisualScreenMask|VisualDepthMask|VisualClassMask,
&vi, &matchingCount);
for (int i = 0; i < matchingCount; ++i) {
XRenderPictFormat *format;
- format = XRenderFindVisualFormat(x11Info().display(), matchingVisuals[i].visual);
+ format = XRenderFindVisualFormat(x11Info.display(), matchingVisuals[i].visual);
if (format->type == PictTypeDirect && format->direct.alphaMask) {
vi = matchingVisuals[i];
+ foundVisualIsArgb = true;
// qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid);
break;
}
@@ -277,17 +228,17 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
if (vi.visualid == 0) {
EGLint depth;
- qeglCtx->configAttrib(EGL_BUFFER_SIZE, &depth);
+ eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &depth);
int err;
- err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), depth, TrueColor, &vi);
+ err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi);
if (err == 0) {
qWarning("Warning: Can't find an X visual which matches the EGL config(%d)'s depth (%d)!",
- (int)qeglCtx->config(), depth);
- depth = x11Info().depth();
- err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), depth, TrueColor, &vi);
+ (int)config, depth);
+ depth = x11Info.depth();
+ err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi);
if (err == 0) {
qWarning("Error: Couldn't get any matching X visual!");
- return;
+ return false;
} else
qWarning(" - Falling back to X11 suggested depth (%d)", depth);
}
@@ -295,8 +246,8 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
// qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth);
// Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-(
- if (useArgb)
- useArgb = vi.depth == 32;
+ if (useArgbVisual)
+ foundVisualIsArgb = vi.depth == 32; //### We might at some point (soon) get ARGB4444
}
// qDebug("Visual Info:");
@@ -309,6 +260,65 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
// qDebug(" depth=%d", vi.depth);
// qDebug(" screen=%d", vi.screen);
// qDebug(" visualid=%d", vi.visualid);
+ return foundVisualIsArgb;
+}
+
+void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
+{
+ Q_D(QGLWidget);
+ if (context == 0) {
+ qWarning("QGLWidget::setContext: Cannot set null context");
+ return;
+ }
+ if (!context->deviceIsPixmap() && context->device() != this) {
+ qWarning("QGLWidget::setContext: Context must refer to this widget");
+ return;
+ }
+
+ if (d->glcx)
+ d->glcx->doneCurrent();
+ QGLContext* oldcx = d->glcx;
+ d->glcx = context;
+
+ if (parentWidget()) {
+ // force creation of delay-created widgets
+ parentWidget()->winId();
+ if (parentWidget()->x11Info().screen() != x11Info().screen())
+ d_func()->xinfo = parentWidget()->d_func()->xinfo;
+ }
+
+ // If the application has set WA_TranslucentBackground and not explicitly set
+ // the alpha buffer size to zero, modify the format so it have an alpha channel
+ QGLFormat& fmt = d->glcx->d_func()->glFormat;
+ const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground);
+ if (tryArgbVisual && fmt.alphaBufferSize() == -1)
+ fmt.setAlphaBufferSize(1);
+
+ bool createFailed = false;
+ if (!d->glcx->isValid()) {
+ if (!d->glcx->create(shareContext ? shareContext : oldcx))
+ createFailed = true;
+ }
+ if (createFailed) {
+ if (deleteOldContext)
+ delete oldcx;
+ return;
+ }
+
+ if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) {
+ if (deleteOldContext)
+ delete oldcx;
+ return;
+ }
+
+ bool visible = isVisible();
+ if (visible)
+ hide();
+
+ XVisualInfo vi;
+ QEglContext *eglContext = d->glcx->d_func()->eglContext;
+ bool usingArgbVisual = qt_egl_setup_x11_visual(vi, eglContext->display(), eglContext->config(),
+ x11Info(), tryArgbVisual);
XSetWindowAttributes a;
@@ -321,7 +331,7 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
a.border_pixel = colmap.pixel(Qt::black);
unsigned int valueMask = CWBackPixel|CWBorderPixel;
- if(useArgb) {
+ if (usingArgbVisual) {
a.colormap = XCreateColormap(x11Info().display(), p, vi.visual, AllocNone);
valueMask |= CWColormap;
}
@@ -418,6 +428,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)
@@ -459,82 +566,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;
@@ -544,10 +583,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/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp
index 793471d..6971133 100644
--- a/src/opengl/qglpixelbuffer_x11.cpp
+++ b/src/opengl/qglpixelbuffer_x11.cpp
@@ -93,6 +93,8 @@ static _glXMakeContextCurrent qt_glXMakeContextCurrent = 0;
#define glXGetFBConfigAttrib qt_glXGetFBConfigAttrib
#define glXMakeContextCurrent qt_glXMakeContextCurrent
+extern void* qglx_getProcAddress(const char* procName); // in qgl_x11.cpp
+
static bool qt_resolve_pbuffer_extensions()
{
static int resolved = false;
@@ -101,31 +103,12 @@ static bool qt_resolve_pbuffer_extensions()
else if (resolved)
return false;
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- qt_glXChooseFBConfig = (_glXChooseFBConfig) dlsym(handle, "glXChooseFBConfig");
- qt_glXCreateNewContext = (_glXCreateNewContext) dlsym(handle, "glXCreateNewContext");
- qt_glXCreatePbuffer = (_glXCreatePbuffer) dlsym(handle, "glXCreatePbuffer");
- qt_glXDestroyPbuffer = (_glXDestroyPbuffer) dlsym(handle, "glXDestroyPbuffer");
- qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) dlsym(handle, "glXGetFBConfigAttrib");
- qt_glXMakeContextCurrent = (_glXMakeContextCurrent) dlsym(handle, "glXMakeContextCurrent");
- dlclose(handle);
- }
- if (!qt_glXChooseFBConfig)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary gl(qt_gl_library_name());
- qt_glXChooseFBConfig = (_glXChooseFBConfig) gl.resolve("glXChooseFBConfig");
- qt_glXCreateNewContext = (_glXCreateNewContext) gl.resolve("glXCreateNewContext");
- qt_glXCreatePbuffer = (_glXCreatePbuffer) gl.resolve("glXCreatePbuffer");
- qt_glXDestroyPbuffer = (_glXDestroyPbuffer) gl.resolve("glXDestroyPbuffer");
- qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) gl.resolve("glXGetFBConfigAttrib");
- qt_glXMakeContextCurrent = (_glXMakeContextCurrent) gl.resolve("glXMakeContextCurrent");
-#endif
- }
+ qt_glXChooseFBConfig = (_glXChooseFBConfig) qglx_getProcAddress("glXChooseFBConfig");
+ qt_glXCreateNewContext = (_glXCreateNewContext) qglx_getProcAddress("glXCreateNewContext");
+ qt_glXCreatePbuffer = (_glXCreatePbuffer) qglx_getProcAddress("glXCreatePbuffer");
+ qt_glXDestroyPbuffer = (_glXDestroyPbuffer) qglx_getProcAddress("glXDestroyPbuffer");
+ qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) qglx_getProcAddress("glXGetFBConfigAttrib");
+ qt_glXMakeContextCurrent = (_glXMakeContextCurrent) qglx_getProcAddress("glXMakeContextCurrent");
resolved = qt_glXMakeContextCurrent ? true : false;
return resolved;
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index bb3cb5d..1ae3866 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -79,34 +79,28 @@ protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const;
};
-#ifndef QT_OPENGL_ES_2
-
-class QGLPixmapConvolutionFilter: public QGLPixmapFilter<QPixmapConvolutionFilter>
+class QGLPixmapConvolutionFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapConvolutionFilter>
{
public:
QGLPixmapConvolutionFilter();
~QGLPixmapConvolutionFilter();
+ void setUniforms(QGLShaderProgram *program);
+
protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
private:
QByteArray generateConvolutionShader() const;
- mutable QGLShaderProgram *m_program;
- mutable int m_scaleUniform;
- mutable int m_matrixUniform;
-
- mutable int m_kernelWidth;
- mutable int m_kernelHeight;
+ mutable QSize m_srcSize;
+ mutable int m_prevKernelSize;
};
-#endif
-
class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
{
public:
- QGLPixmapBlurFilter(QPixmapBlurFilter::BlurHint hint);
+ QGLPixmapBlurFilter(Qt::RenderHint hint);
void setUniforms(QGLShaderProgram *program);
@@ -121,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();
@@ -137,67 +131,26 @@ 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();
}
-#ifndef QT_OPENGL_ES_2
case QPixmapFilter::ConvolutionFilter:
if (!d->convolutionFilter)
d->convolutionFilter.reset(new QGLPixmapConvolutionFilter);
return d->convolutionFilter.data();
-#endif
default: break;
}
return QPaintEngineEx::pixmapFilter(type, prototype);
}
-#ifndef QT_OPENGL_ES_2 // XXX: needs to be ported
-
-extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array);
-extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array);
-
-static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, const QRectF & src)
-{
-#ifndef QT_OPENGL_ES
- glPushAttrib(GL_CURRENT_BIT);
-#endif
- qreal x1, x2, y1, y2;
-
- x1 = src.x() / tx_width;
- x2 = x1 + src.width() / tx_width;
- y1 = 1.0 - ((src.y() / tx_height) + (src.height() / tx_height));
- y2 = 1.0 - (src.y() / tx_height);
-
- q_vertexType vertexArray[4*2];
- q_vertexType texCoordArray[4*2];
-
- qt_add_rect_to_array(rect, vertexArray);
- qt_add_texcoords_to_array(x1, y2, x2, y1, texCoordArray);
-
- glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);
- glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
-#ifndef QT_OPENGL_ES
- glPopAttrib();
-#endif
-}
-
-#endif // !QT_OPENGL_ES_2
-
static const char *qt_gl_colorize_filter =
"uniform lowp vec4 colorizeColor;"
"uniform lowp float colorizeStrength;"
@@ -231,102 +184,88 @@ void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program)
program->setUniformValue("colorizeStrength", float(strength()));
}
-#ifndef QT_OPENGL_ES_2
+void QGLPixmapConvolutionFilter::setUniforms(QGLShaderProgram *program)
+{
+ const qreal *kernel = convolutionKernel();
+ int kernelWidth = columns();
+ int kernelHeight = rows();
+ int kernelSize = kernelWidth * kernelHeight;
+
+ QVarLengthArray<GLfloat> matrix(kernelSize);
+ QVarLengthArray<GLfloat> offset(kernelSize * 2);
+
+ for(int i = 0; i < kernelSize; ++i)
+ matrix[i] = kernel[i];
+
+ for(int y = 0; y < kernelHeight; ++y) {
+ for(int x = 0; x < kernelWidth; ++x) {
+ offset[(y * kernelWidth + x) * 2] = x - (kernelWidth / 2);
+ offset[(y * kernelWidth + x) * 2 + 1] = (kernelHeight / 2) - y;
+ }
+ }
+
+ const qreal iw = 1.0 / m_srcSize.width();
+ const qreal ih = 1.0 / m_srcSize.height();
+ program->setUniformValue("inv_texture_size", iw, ih);
+ program->setUniformValueArray("matrix", matrix.constData(), kernelSize, 1);
+ program->setUniformValueArray("offset", offset.constData(), kernelSize, 2);
+}
// generates convolution filter code for arbitrary sized kernel
QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const {
QByteArray code;
- code.append("uniform sampler2D texture;\n"
- "uniform vec2 inv_texture_size;\n"
- "uniform float matrix[");
- code.append(QByteArray::number(m_kernelWidth * m_kernelHeight));
- code.append("];\n"
- "vec2 offset[");
- code.append(QByteArray::number(m_kernelWidth*m_kernelHeight));
+ int kernelWidth = columns();
+ int kernelHeight = rows();
+ int kernelSize = kernelWidth * kernelHeight;
+ code.append("uniform highp vec2 inv_texture_size;\n"
+ "uniform mediump float matrix[");
+ code.append(QByteArray::number(kernelSize));
code.append("];\n"
- "void main(void) {\n");
-
- for(int y = 0; y < m_kernelHeight; y++) {
- for(int x = 0; x < m_kernelWidth; x++) {
- code.append(" offset[");
- code.append(QByteArray::number(y * m_kernelWidth + x));
- code.append("] = vec2(inv_texture_size.x * ");
- code.append(QByteArray::number(x-(int)(m_kernelWidth/2)));
- code.append(".0, inv_texture_size.y * ");
- code.append(QByteArray::number((int)(m_kernelHeight/2)-y));
- code.append(".0);\n");
- }
- }
+ "uniform highp vec2 offset[");
+ code.append(QByteArray::number(kernelSize));
+ code.append("];\n");
+ code.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n");
code.append(" int i = 0;\n"
- " vec2 coords = gl_TexCoord[0].st;\n"
- " vec4 sum = vec4(0.0);\n"
+ " lowp vec4 sum = vec4(0.0);\n"
" for (i = 0; i < ");
- code.append(QByteArray::number(m_kernelWidth * m_kernelHeight));
+ code.append(QByteArray::number(kernelSize));
code.append("; i++) {\n"
- " vec4 tmp = texture2D(texture,coords+offset[i]);\n"
- " sum += matrix[i] * tmp;\n"
+ " sum += matrix[i] * texture2D(src,srcCoords+inv_texture_size*offset[i]);\n"
" }\n"
- " gl_FragColor = sum;\n"
+ " return sum;\n"
"}");
return code;
}
QGLPixmapConvolutionFilter::QGLPixmapConvolutionFilter()
- : m_program(0)
- , m_scaleUniform(0)
- , m_matrixUniform(0)
- , m_kernelWidth(0)
- , m_kernelHeight(0)
+ : m_prevKernelSize(-1)
{
}
QGLPixmapConvolutionFilter::~QGLPixmapConvolutionFilter()
{
- delete m_program;
}
-bool QGLPixmapConvolutionFilter::processGL(QPainter *, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
+bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
{
- QRectF target = (srcRect.isNull() ? QRectF(src.rect()) : srcRect).translated(pos);
-
- bindTexture(src);
-#ifdef GL_CLAMP
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-#endif
- if (!m_program || m_kernelWidth != columns() || m_kernelHeight != rows()) {
- delete m_program;
-
- m_kernelWidth = columns();
- m_kernelHeight = rows();
-
- QByteArray code = generateConvolutionShader();
- m_program = new QGLShaderProgram();
- m_program->addShader(QGLShader::FragmentShader, code);
- m_program->link();
- m_scaleUniform = m_program->uniformLocation("inv_texture_size");
- m_matrixUniform = m_program->uniformLocation("matrix");
+ QGLPixmapConvolutionFilter *filter = const_cast<QGLPixmapConvolutionFilter *>(this);
+
+ m_srcSize = src.size();
+
+ int kernelSize = rows() * columns();
+ if (m_prevKernelSize == -1 || m_prevKernelSize != kernelSize) {
+ filter->setSource(generateConvolutionShader());
+ m_prevKernelSize = kernelSize;
}
- const qreal *kernel = convolutionKernel();
- GLfloat *conv = new GLfloat[m_kernelWidth * m_kernelHeight];
- for(int i = 0; i < m_kernelWidth * m_kernelHeight; ++i)
- conv[i] = kernel[i];
-
- const qreal iw = 1.0 / src.width();
- const qreal ih = 1.0 / src.height();
- m_program->enable();
- m_program->setUniformValue(m_scaleUniform, iw, ih);
- m_program->setUniformValueArray(m_matrixUniform, conv, m_kernelWidth * m_kernelHeight, 1);
-
- qgl_drawTexture(target, src.width(), src.height(), boundingRectFor(srcRect));
- m_program->disable();
+ filter->setOnPainter(painter);
+ painter->drawPixmap(pos, src, srcRect);
+ filter->removeFromPainter(painter);
+
return true;
}
-#endif // !QT_OPENGL_ES_2
-
static const char *qt_gl_blur_filter_fast =
"const int samples = 9;"
"uniform mediump vec2 delta;"
@@ -340,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;
@@ -357,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;
@@ -419,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 bd3883a..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;
@@ -4791,22 +4791,6 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, const QTextItemInt &ti,
}
QImage glyph_im(ti.fontEngine->alphaMapForGlyph(glyphs[i]));
-
- // The QPF implementation of alphaMapForGlyph() uses the color
- // RGBA = (value, value, value, 255) instead of the color
- // RGBA = (0, 0, 0, value) that the other font engines use.
- // We modify the image colors to rectify this situation.
- QFontEngine::Type type = ti.fontEngine->type();
- if (type == QFontEngine::QPF1 || type == QFontEngine::QPF2) {
- if (glyph_im.format() == QImage::Format_Indexed8) {
- for (int i = 0; i < 256; ++i)
- glyph_im.setColor(i, qRgba(0, 0, 0, i));
- } else if (glyph_im.format() == QImage::Format_Mono) {
- glyph_im.setColor(0, qRgba(0, 0, 0, 0));
- glyph_im.setColor(1, qRgba(0, 0, 0, 255));
- }
- }
-
glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8);
glyph_width = glyph_im.width();
Q_ASSERT(glyph_width >= 0);
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index dc7aa81..ae4bed0 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -251,7 +251,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)