diff options
Diffstat (limited to 'src/quick/scenegraph/qsgcontext.cpp')
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 140 |
1 files changed, 96 insertions, 44 deletions
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 02fbaa1a7f..da1c8e6ee9 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -54,6 +54,7 @@ #include <QGuiApplication> #include <QOpenGLContext> +#include <QtGui/qopenglframebufferobject.h> #include <private/qqmlglobal_p.h> @@ -95,7 +96,13 @@ class QSGContextPrivate : public QObjectPrivate public: QSGContextPrivate() : gl(0) + , depthStencilBufferManager(0) , distanceFieldCacheManager(0) + #ifndef QT_OPENGL_ES + , distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing) + #else + , distanceFieldAntialiasing(QSGGlyphNode::GrayAntialiasing) + #endif , flashMode(qmlFlashMode()) , distanceFieldDisabled(qmlDisableDistanceField()) { @@ -111,9 +118,11 @@ public: QHash<QSGMaterialType *, QSGMaterialShader *> materials; QMutex textureMutex; QHash<QQuickTextureFactory *, QSGTexture *> textures; - + QSGDepthStencilBufferManager *depthStencilBufferManager; QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager; + QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing; + bool flashMode; float renderAlpha; bool distanceFieldDisabled; @@ -141,6 +150,17 @@ public: QSGContext::QSGContext(QObject *parent) : QObject(*(new QSGContextPrivate), parent) { + Q_D(QSGContext); + // ### Do something with these before final release... + static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing")); + static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq")); + static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing")); + if (doSubpixel) + d->distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing; + else if (doLowQualSubpixel) + d->distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing; + else if (doGray) + d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; } @@ -160,6 +180,8 @@ void QSGContext::invalidate() d->textureMutex.unlock(); qDeleteAll(d->materials.values()); d->materials.clear(); + delete d->depthStencilBufferManager; + d->depthStencilBufferManager = 0; delete d->distanceFieldCacheManager; d->distanceFieldCacheManager = 0; @@ -270,39 +292,47 @@ QSGImageNode *QSGContext::createImageNode() /*! Factory function for scene graph backends of the distance-field glyph cache. */ -QSGDistanceFieldGlyphCache *QSGContext::createDistanceFieldGlyphCache(const QRawFont &font) +QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont &font) { Q_D(QSGContext); - QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration(); - if (platformIntegration != 0 - && platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) { - QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine; - if (!fe->faceId().filename.isEmpty()) { - QByteArray keyName = fe->faceId().filename; - if (font.style() != QFont::StyleNormal) - keyName += QByteArray(" I"); - if (font.weight() != QFont::Normal) - keyName += " " + QByteArray::number(font.weight()); - keyName += QByteArray(" DF"); - QPlatformSharedGraphicsCache *sharedGraphicsCache = - platformIntegration->createPlatformSharedGraphicsCache(keyName); - - if (sharedGraphicsCache != 0) { - sharedGraphicsCache->ensureCacheInitialized(keyName, - QPlatformSharedGraphicsCache::OpenGLTexture, - QPlatformSharedGraphicsCache::Alpha8); - - return new QSGSharedDistanceFieldGlyphCache(keyName, - sharedGraphicsCache, - d->distanceFieldCacheManager, - glContext(), - font); + if (!d->distanceFieldCacheManager) + d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager; + + QSGDistanceFieldGlyphCache *cache = d->distanceFieldCacheManager->cache(font); + if (!cache) { + QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration(); + if (platformIntegration != 0 + && platformIntegration->hasCapability(QPlatformIntegration::SharedGraphicsCache)) { + QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine; + if (!fe->faceId().filename.isEmpty()) { + QByteArray keyName = fe->faceId().filename; + if (font.style() != QFont::StyleNormal) + keyName += QByteArray(" I"); + if (font.weight() != QFont::Normal) + keyName += " " + QByteArray::number(font.weight()); + keyName += QByteArray(" DF"); + QPlatformSharedGraphicsCache *sharedGraphicsCache = + platformIntegration->createPlatformSharedGraphicsCache(keyName); + + if (sharedGraphicsCache != 0) { + sharedGraphicsCache->ensureCacheInitialized(keyName, + QPlatformSharedGraphicsCache::OpenGLTexture, + QPlatformSharedGraphicsCache::Alpha8); + + cache = new QSGSharedDistanceFieldGlyphCache(keyName, + sharedGraphicsCache, + d->distanceFieldCacheManager, + glContext(), + font); + } } } + if (!cache) + cache = new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font); + d->distanceFieldCacheManager->insertCache(font, cache); } - - return new QSGDefaultDistanceFieldGlyphCache(d->distanceFieldCacheManager, glContext(), font); + return cache; } /*! @@ -312,25 +342,11 @@ QSGGlyphNode *QSGContext::createGlyphNode() { Q_D(QSGContext); - // ### Do something with these before final release... - static bool doSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing")); - static bool doLowQualSubpixel = qApp->arguments().contains(QLatin1String("--text-subpixel-antialiasing-lowq")); - static bool doGray = qApp->arguments().contains(QLatin1String("--text-gray-antialiasing")); - if (d->distanceFieldDisabled) { return new QSGDefaultGlyphNode; } else { - if (!d->distanceFieldCacheManager) { - d->distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager(this); - if (doSubpixel) - d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::HighQualitySubPixelAntialiasing); - else if (doLowQualSubpixel) - d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::LowQualitySubPixelAntialiasing); - else if (doGray) - d->distanceFieldCacheManager->setDefaultAntialiasingMode(QSGGlyphNode::GrayAntialiasing); - } - - QSGGlyphNode *node = new QSGDistanceFieldGlyphNode(d->distanceFieldCacheManager); + QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(this); + node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing); return node; } } @@ -399,6 +415,42 @@ QSize QSGContext::minimumFBOSize() const /*! + Returns a shared pointer to a depth stencil buffer that can be used with \a fbo. + */ +QSharedPointer<QSGDepthStencilBuffer> QSGContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo) +{ + Q_D(QSGContext); + if (!d->gl) + return QSharedPointer<QSGDepthStencilBuffer>(); + QSGDepthStencilBufferManager *manager = depthStencilBufferManager(); + QSGDepthStencilBuffer::Format format; + format.size = fbo->size(); + format.samples = fbo->format().samples(); + format.attachments = QSGDepthStencilBuffer::DepthAttachment | QSGDepthStencilBuffer::StencilAttachment; + QSharedPointer<QSGDepthStencilBuffer> buffer = manager->bufferForFormat(format); + if (buffer.isNull()) { + buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(d->gl, format)); + manager->insertBuffer(buffer); + } + return buffer; +} + +/*! + Returns a pointer to the context's depth/stencil buffer manager. This is useful for custom + implementations of \l depthStencilBufferForFbo(). + */ +QSGDepthStencilBufferManager *QSGContext::depthStencilBufferManager() +{ + Q_D(QSGContext); + if (!d->gl) + return 0; + if (!d->depthStencilBufferManager) + d->depthStencilBufferManager = new QSGDepthStencilBufferManager(d->gl); + return d->depthStencilBufferManager; +} + + +/*! Returns a material shader for the given material. */ |