diff --git a/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp b/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp index d19c9f6..a909fb4 100644 --- a/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp +++ b/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE // Should work on most hardware. Used as stop gap until Qt 3D provides a // way to retrieve the system value #ifndef Q3DSDISTANCEFIELDGLYPHCACHE_MAXIMUM_TEXURE_SIZE -# define Q3DSDISTANCEFIELDGLYPHCACHE_MAXIMUM_TEXURE_SIZE 2048 +# define Q3DSDISTANCEFIELDGLYPHCACHE_MAXIMUM_TEXURE_SIZE 256 #endif #if !defined(Q3DSDISTANCEFIELDGLYPHCACHE_PADDING) @@ -57,11 +57,12 @@ QT_BEGIN_NAMESPACE Q3DSDistanceFieldGlyphCache::Q3DSDistanceFieldGlyphCache( const QRawFont &font, qt3ds::render::IQt3DSRenderContext &context) : QSGDistanceFieldGlyphCache(font) + , m_maxTextureWidth(Q3DSDISTANCEFIELDGLYPHCACHE_MAXIMUM_TEXURE_SIZE) + , m_maxTextureHeight(0) + , m_maxTextureCount(3) , m_context(context) { - m_maxTextureSize = Q3DSDISTANCEFIELDGLYPHCACHE_MAXIMUM_TEXURE_SIZE; - - loadPregeneratedCache(font); + loadPregeneratedCache(font); } Q3DSDistanceFieldGlyphCache::~Q3DSDistanceFieldGlyphCache() @@ -71,11 +72,6 @@ Q3DSDistanceFieldGlyphCache::~Q3DSDistanceFieldGlyphCache() delete m_areaAllocator; } -int Q3DSDistanceFieldGlyphCache::maxTextureSize() const -{ - return m_maxTextureSize; -} - Q3DSDistanceFieldGlyphCache::TextureInfo *Q3DSDistanceFieldGlyphCache::textureInfo(int index) const { while (index >= m_textures.size()) @@ -145,7 +141,7 @@ void Q3DSDistanceFieldGlyphCache::storeGlyphs(const QList &glyph TexCoord c = glyphTexCoord(glyphIndex); TextureInfo *texInfo = m_glyphsTexture.value(glyphIndex); - resizeTexture(texInfo, maxTextureSize(), texInfo->allocatedArea.height()); + resizeTexture(texInfo, m_maxTextureWidth, texInfo->allocatedArea.height()); Q_ASSERT(!glyphTextures[texInfo].contains(glyphIndex)); glyphTextures[texInfo].append(glyphIndex); @@ -187,15 +183,18 @@ void Q3DSDistanceFieldGlyphCache::requestGlyphs(const QSet &glyphs) QList glyphPositions; QVector glyphsToRender; - if (m_areaAllocator == nullptr) { - m_areaAllocator = new QSGAreaAllocator(QSize(maxTextureSize(), - m_maxTextureCount * maxTextureSize())); + const int padding = Q3DSDISTANCEFIELDGLYPHCACHE_PADDING; + const qreal scaleFactor = qreal(1) / QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution); + + if (m_maxTextureHeight == 0) { + m_maxTextureHeight = m_maxTextureWidth - (qCeil(m_referenceFont.pixelSize() * scaleFactor) + distanceFieldRadius() * 2 + padding * 2); } + if (m_areaAllocator == nullptr) + m_areaAllocator = new QSGAreaAllocator(QSize(m_maxTextureWidth, m_maxTextureCount * m_maxTextureHeight)); for (QSet::const_iterator it = glyphs.constBegin(); it != glyphs.constEnd() ; ++it) { glyph_t glyphIndex = *it; - int padding = Q3DSDISTANCEFIELDGLYPHCACHE_PADDING; QRectF boundingRect = glyphData(glyphIndex).boundingRect; int glyphWidth = qCeil(boundingRect.width()) + distanceFieldRadius() * 2; int glyphHeight = qCeil(boundingRect.height()) + distanceFieldRadius() * 2; @@ -230,8 +229,8 @@ void Q3DSDistanceFieldGlyphCache::requestGlyphs(const QSet &glyphs) continue; } - TextureInfo *tex = textureInfo(alloc.y() / maxTextureSize()); - alloc = QRect(alloc.x(), alloc.y() % maxTextureSize(), alloc.width(), alloc.height()); + TextureInfo *tex = textureInfo(alloc.y() / m_maxTextureHeight); + alloc = QRect(alloc.x(), alloc.y() % m_maxTextureHeight, alloc.width(), alloc.height()); tex->allocatedArea |= alloc; Q_ASSERT(tex->padding == padding || tex->padding < 0); @@ -361,7 +360,7 @@ bool Q3DSDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) } qreal pixelSize = qreal(Qtdf::fetch(qtdfTableStart, Qtdf::pixelSize)); - m_maxTextureSize = int(Qtdf::fetch(qtdfTableStart, Qtdf::textureSize)); + m_maxTextureWidth = m_maxTextureHeight = Qtdf::fetch(qtdfTableStart, Qtdf::textureSize); m_doubleGlyphResolution = Qtdf::fetch(qtdfTableStart, Qtdf::flags) == 1; padding = Qtdf::fetch(qtdfTableStart, Qtdf::headerPadding); @@ -370,11 +369,21 @@ bool Q3DSDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) return false; } - if (m_maxTextureSize <= 0) { + if (m_maxTextureWidth <= 0) { qWarning("Invalid texture size in '%s'", qPrintable(font.familyName())); return false; } - +/* + * TODO: check we can't do while no access to gl. + int systemMaxTextureSize; + m_funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &systemMaxTextureSize); + if (m_maxTextureWidth > systemMaxTextureSize) { + qWarning("System maximum texture size is %d. This is lower than the value in '%s', which is %d", + systemMaxTextureSize, + qPrintable(font.familyName()), + m_maxTextureWidth); + } + */ if (padding != Q3DSDISTANCEFIELDGLYPHCACHE_PADDING) { qWarning("Padding mismatch in '%s'. Font requires %d, but Qt is compiled with %d.", qPrintable(font.familyName()), @@ -396,12 +405,16 @@ bool Q3DSDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) return false; } - if (m_areaAllocator->size().height() % m_maxTextureSize != 0) { - qWarning("Area allocator size mismatch in '%s'", qPrintable(font.familyName())); + if (m_areaAllocator->size().height() % m_maxTextureHeight != 0) { + qWarning("Area allocator height mismatch in '%s'", qPrintable(font.familyName())); + return false; + } + if (m_areaAllocator->size().width() % m_maxTextureWidth != 0) { + qWarning("Area allocator width mismatch in '%s'", qPrintable(font.familyName())); return false; } - textureCount = m_areaAllocator->size().height() / m_maxTextureSize; + textureCount = m_areaAllocator->size().height() / m_maxTextureHeight; m_maxTextureCount = qMax(m_maxTextureCount, textureCount); const char *textureRecord = allocatorData; diff --git a/src/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h b/src/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h index fb4826e..00b3498 100644 --- a/src/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h +++ b/src/runtimerender/Qt3DSDistanceFieldGlyphCache_p.h @@ -84,13 +84,13 @@ private: bool loadPregeneratedCache(const QRawFont &font); TextureInfo *textureInfo(int index) const; - int maxTextureSize() const; void resizeTexture(TextureInfo *info, int width, int height); void setTextureData(qt3ds::render::NVRenderTexture2D *texture, QImage &image); QSGAreaAllocator *m_areaAllocator = nullptr; - int m_maxTextureSize = 0; - int m_maxTextureCount = 3; + int m_maxTextureWidth; + int m_maxTextureHeight; + int m_maxTextureCount; mutable QVector m_textures; QHash m_glyphsTexture;