diff options
Diffstat (limited to 'src/opengl/gl2paintengineex')
5 files changed, 74 insertions, 46 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 27636f4..d7c91b8 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -49,6 +49,28 @@ QT_BEGIN_NAMESPACE +static void QGLEngineShaderManager_free(void *ptr) +{ + delete reinterpret_cast<QGLEngineShaderManager *>(ptr); +} + +Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shader_managers, (QGLEngineShaderManager_free)) + +QGLEngineShaderManager *QGLEngineShaderManager::managerForContext(const QGLContext *context) +{ + QGLEngineShaderManager *p = reinterpret_cast<QGLEngineShaderManager *>(qt_shader_managers()->value(context)); + if (!p) { + QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext()); + if (oldContext != context) + const_cast<QGLContext *>(context)->makeCurrent(); + p = new QGLEngineShaderManager(const_cast<QGLContext *>(context)); + qt_shader_managers()->insert(context, p); + if (oldContext && oldContext != context) + oldContext->makeCurrent(); + } + return p; +} + const char* QGLEngineShaderManager::qglEngineShaderSourceCode[] = { 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 442edfe..99711bd40 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -220,6 +220,7 @@ #include <QGLShader> #include <QGLShaderProgram> #include <QPainter> +#include <private/qgl_p.h> QT_BEGIN_HEADER @@ -314,6 +315,8 @@ public: QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer + static QGLEngineShaderManager *managerForContext(const QGLContext *context); + enum ShaderName { MainVertexShader, MainWithTexCoordsVertexShader, diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index 8c6b4f0..7c54bb9 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -46,6 +46,28 @@ QT_BEGIN_NAMESPACE +static void QGL2GradientCache_free(void *ptr) +{ + delete reinterpret_cast<QGL2GradientCache *>(ptr); +} + +Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_gradient_caches, (QGL2GradientCache_free)) + +QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context) +{ + QGL2GradientCache *p = reinterpret_cast<QGL2GradientCache *>(qt_gradient_caches()->value(context)); + if (!p) { + QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext()); + if (oldContext != context) + const_cast<QGLContext *>(context)->makeCurrent(); + p = new QGL2GradientCache; + qt_gradient_caches()->insert(context, p); + if (oldContext && oldContext != context) + oldContext->makeCurrent(); + } + return p; +} + void QGL2GradientCache::cleanCache() { QGLGradientColorTableHash::const_iterator it = cache.constBegin(); for (; it != cache.constEnd(); ++it) { @@ -55,13 +77,8 @@ void QGL2GradientCache::cleanCache() { cache.clear(); } -GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity, const QGLContext *ctx) +GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity) { - if (buffer_ctx && !qgl_share_reg()->checkSharing(buffer_ctx, ctx)) - cleanCache(); - - buffer_ctx = ctx; - quint64 hash_val = 0; QGradientStops stops = gradient.stops(); diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h index 55c7b65..ba698bc 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache_p.h +++ b/src/opengl/gl2paintengineex/qglgradientcache_p.h @@ -53,12 +53,12 @@ #include <QMultiHash> #include <QObject> #include <QtOpenGL/QtOpenGL> +#include <private/qgl_p.h> QT_BEGIN_NAMESPACE -class QGL2GradientCache : public QObject +class QGL2GradientCache { - Q_OBJECT struct CacheInfo { inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) : @@ -73,16 +73,12 @@ class QGL2GradientCache : public QObject typedef QMultiHash<quint64, CacheInfo> QGLGradientColorTableHash; public: - QGL2GradientCache() : QObject(), buffer_ctx(0) - { -/* - connect(QGLSignalProxy::instance(), - SIGNAL(aboutToDestroyContext(const QGLContext *)), - SLOT(cleanupGLContextRefs(const QGLContext *))); -*/ - } + static QGL2GradientCache *cacheForContext(const QGLContext *context); + + QGL2GradientCache() { } + ~QGL2GradientCache() {cleanCache();} - GLuint getBuffer(const QGradient &gradient, qreal opacity, const QGLContext *ctx); + GLuint getBuffer(const QGradient &gradient, qreal opacity); inline int paletteSize() const { return 1024; } protected: @@ -95,15 +91,6 @@ protected: void cleanCache(); QGLGradientColorTableHash cache; - const QGLContext *buffer_ctx; - -public slots: - void cleanupGLContextRefs(const QGLContext *context) { - if (context == buffer_ctx) { - cleanCache(); - buffer_ctx = 0; - } - } }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2bfbf4a..7e8a281 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -115,6 +115,7 @@ public Q_SLOTS: glDeleteFramebuffers(1, &m_fbo); if (m_width || m_height) glDeleteTextures(1, &m_texture); + ctx = 0; } else { // since the context holding the texture is shared, and // about to be destroyed, we have to transfer ownership @@ -151,10 +152,17 @@ QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyph QGLTextureGlyphCache::~QGLTextureGlyphCache() { - glDeleteFramebuffers(1, &m_fbo); - - if (m_width || m_height) - glDeleteTextures(1, &m_texture); + if (ctx) { + QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext()); + if (oldContext != ctx) + ctx->makeCurrent(); + glDeleteFramebuffers(1, &m_fbo); + + if (m_width || m_height) + glDeleteTextures(1, &m_texture); + if (oldContext && oldContext != ctx) + oldContext->makeCurrent(); + } } void QGLTextureGlyphCache::createTextureData(int width, int height) @@ -266,10 +274,6 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() { - if (shaderManager) { - delete shaderManager; - shaderManager = 0; - } } void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) @@ -295,6 +299,7 @@ void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMod QColor QGL2PaintEngineExPrivate::premultiplyColor(QColor c, GLfloat opacity) { qreal alpha = c.alphaF() * opacity; + c.setAlphaF(alpha); c.setRedF(c.redF() * alpha); c.setGreenF(c.greenF() * alpha); c.setBlueF(c.blueF() * alpha); @@ -338,9 +343,6 @@ void QGL2PaintEngineExPrivate::useSimpleShader() } } - -Q_GLOBAL_STATIC(QGL2GradientCache, qt_opengl_gradient_cache) - void QGL2PaintEngineExPrivate::updateBrushTexture() { // qDebug("QGL2PaintEngineExPrivate::updateBrushTexture()"); @@ -361,7 +363,10 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() // We apply global opacity in the fragment shaders, so we always pass 1.0 // for opacity to the cache. - GLuint texId = qt_opengl_gradient_cache()->getBuffer(*g, 1.0, ctx); + GLuint texId = QGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); + + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); + glBindTexture(GL_TEXTURE_2D, texId); if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true); @@ -369,9 +374,6 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT_IBM, true); else updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, true); - - glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, texId); } else if (style == Qt::TexturePattern) { const QPixmap& texPixmap = currentBrush->texture(); @@ -1209,11 +1211,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) qt_resolve_version_2_0_functions(d->ctx); #endif - if (d->shaderManager) { - d->shaderManager->setDirty(); - } else { - d->shaderManager = new QGLEngineShaderManager(d->ctx); - } + d->shaderManager = QGLEngineShaderManager::managerForContext(d->ctx); + d->shaderManager->setDirty(); glViewport(0, 0, d->width, d->height); |