diff options
Diffstat (limited to 'src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp')
-rw-r--r-- | src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp | 114 |
1 files changed, 36 insertions, 78 deletions
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp index a715092b19..54cf298943 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp @@ -1,44 +1,9 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qsgrhidistancefieldglyphcache_p.h" #include "qsgcontext_p.h" +#include "qsgdefaultrendercontext_p.h" #include <QtGui/private/qdistancefield_p.h> #include <QtCore/qelapsedtimer.h> #include <QtQml/private/qqmlglobal_p.h> @@ -54,11 +19,12 @@ DEFINE_BOOL_CONFIG_OPTION(qsgPreferFullSizeGlyphCacheTextures, QSG_PREFER_FULLSI # define QSG_RHI_DISTANCEFIELD_GLYPH_CACHE_PADDING 2 #endif -QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QRhi *rhi, +QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QSGDefaultRenderContext *rc, const QRawFont &font, int renderTypeQuality) : QSGDistanceFieldGlyphCache(font, renderTypeQuality) - , m_rhi(rhi) + , m_rc(rc) + , m_rhi(rc->rhi()) { // Load a pregenerated cache if the font contains one loadPregeneratedCache(font); @@ -66,13 +32,10 @@ QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QRhi *rhi, QSGRhiDistanceFieldGlyphCache::~QSGRhiDistanceFieldGlyphCache() { - for (int i = 0; i < m_textures.count(); ++i) - delete m_textures[i].texture; + for (const TextureInfo &t : std::as_const(m_textures)) + m_rc->deferredReleaseGlyphCacheTexture(t.texture); delete m_areaAllocator; - - // should be empty, but just in case - qDeleteAll(m_pendingDispose); } void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) @@ -88,8 +51,8 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) int padding = QSG_RHI_DISTANCEFIELD_GLYPH_CACHE_PADDING; QRectF boundingRect = glyphData(glyphIndex).boundingRect; - int glyphWidth = qCeil(boundingRect.width()) + distanceFieldRadius() * 2; - int glyphHeight = qCeil(boundingRect.height()) + distanceFieldRadius() * 2; + int glyphWidth = qCeil(boundingRect.width() + distanceFieldRadius() * 2); + int glyphHeight = qCeil(boundingRect.height() + distanceFieldRadius() * 2); QSize glyphSize(glyphWidth + padding * 2, glyphHeight + padding * 2); QRect alloc = m_areaAllocator->allocate(glyphSize); @@ -100,8 +63,8 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) TexCoord unusedCoord = glyphTexCoord(unusedGlyph); QRectF unusedGlyphBoundingRect = glyphData(unusedGlyph).boundingRect; - int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width()) + distanceFieldRadius() * 2; - int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height()) + distanceFieldRadius() * 2; + int unusedGlyphWidth = qCeil(unusedGlyphBoundingRect.width() + distanceFieldRadius() * 2); + int unusedGlyphHeight = qCeil(unusedGlyphBoundingRect.height() + distanceFieldRadius() * 2); m_areaAllocator->deallocate(QRect(unusedCoord.x - padding, unusedCoord.y - padding, padding * 2 + unusedGlyphWidth, @@ -139,6 +102,11 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) markGlyphsToRender(glyphsToRender); } +bool QSGRhiDistanceFieldGlyphCache::isActive() const +{ + return !m_referencedGlyphs.empty(); +} + void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyphs) { typedef QHash<TextureInfo *, QVector<glyph_t> > GlyphTextureHash; @@ -178,15 +146,13 @@ void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &gly texInfo->uploads.append(QRhiTextureUploadEntry(0, 0, subresDesc)); } - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); for (int i = 0; i < glyphs.size(); ++i) { TextureInfo *texInfo = m_glyphsTexture.value(glyphs.at(i).glyph()); if (!texInfo->uploads.isEmpty()) { QRhiTextureUploadDescription desc; desc.setEntries(texInfo->uploads.cbegin(), texInfo->uploads.cend()); - m_resourceUpdates->uploadTexture(texInfo->texture, desc); + resourceUpdates->uploadTexture(texInfo->texture, desc); texInfo->uploads.clear(); } } @@ -201,11 +167,13 @@ void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &gly void QSGRhiDistanceFieldGlyphCache::referenceGlyphs(const QSet<glyph_t> &glyphs) { + m_referencedGlyphs += glyphs; m_unusedGlyphs -= glyphs; } void QSGRhiDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs) { + m_referencedGlyphs -= glyphs; m_unusedGlyphs += glyphs; } @@ -229,12 +197,10 @@ void QSGRhiDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, texInfo->texture = m_rhi->newTexture(QRhiTexture::RED_OR_ALPHA8, QSize(width, height), 1, QRhiTexture::UsedAsTransferSource); if (texInfo->texture->create()) { - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); QRhiTextureSubresourceUploadDescription subresDesc(pixels, width * height); subresDesc.setSourceSize(QSize(width, height)); - m_resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); + resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); } else { qWarning("Failed to create distance field glyph cache"); } @@ -257,20 +223,18 @@ void QSGRhiDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int widt updateRhiTexture(oldTexture, texInfo->texture, texInfo->size); - if (!m_resourceUpdates) - m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); if (useTextureResizeWorkaround()) { QRhiTextureSubresourceUploadDescription subresDesc(texInfo->image.constBits(), oldWidth * oldHeight); subresDesc.setSourceSize(QSize(oldWidth, oldHeight)); - m_resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); + resourceUpdates->uploadTexture(texInfo->texture, QRhiTextureUploadEntry(0, 0, subresDesc)); texInfo->image = texInfo->image.copy(0, 0, width, height); } else { - m_resourceUpdates->copyTexture(texInfo->texture, oldTexture); + resourceUpdates->copyTexture(texInfo->texture, oldTexture); } - m_pendingDispose.insert(oldTexture); + m_rc->deferredReleaseGlyphCacheTexture(oldTexture); } bool QSGRhiDistanceFieldGlyphCache::useTextureResizeWorkaround() const @@ -447,7 +411,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) const char *textureRecord = allocatorData; for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) { - if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) { + if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) { qWarning("qtdf table too small in font '%s'.", qPrintable(font.familyName())); return false; @@ -463,7 +427,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) const char *glyphRecord = textureRecord; for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) { - if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) { + if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) { qWarning("qtdf table too small in font '%s'.", qPrintable(font.familyName())); return false; @@ -513,8 +477,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) int width = texInfo->allocatedArea.width(); int height = texInfo->allocatedArea.height(); - qint64 size = width * height; - if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) { + qint64 size = qint64(width) * height; + if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) { qWarning("qtdf table too small in font '%s'.", qPrintable(font.familyName())); return false; @@ -547,17 +511,10 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font) void QSGRhiDistanceFieldGlyphCache::commitResourceUpdates(QRhiResourceUpdateBatch *mergeInto) { - if (m_resourceUpdates) { - mergeInto->merge(m_resourceUpdates); - m_resourceUpdates->release(); - m_resourceUpdates = nullptr; + if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) { + mergeInto->merge(resourceUpdates); + m_rc->resetGlyphCacheResources(); } - - // now let's assume the resource updates will be committed in this frame - for (QRhiTexture *t : m_pendingDispose) - t->deleteLater(); // will be deleted after the frame is submitted -> safe - - m_pendingDispose.clear(); } bool QSGRhiDistanceFieldGlyphCache::eightBitFormatIsAlphaSwizzled() const @@ -604,7 +561,8 @@ void QSGRhiDistanceFieldGlyphCache::saveTexture(QRhiTexture *texture, const QStr }; QRhiReadbackDescription rb(texture); - m_resourceUpdates->readBackTexture(rb, rbResult); + QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates(); + resourceUpdates->readBackTexture(rb, rbResult); } #endif |