aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp')
-rw-r--r--src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp114
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