Invalidate text when application fonts are added or removed
We had multiple related issues due to application fonts being added or removed during the application lifetime. 1. If a text had font family "foo" set, and this font did not exist at the time, then loading "foo" at a later stage would not update the text to use the correct font, since the result of the previous request had been cached. 2. A variation of #1 was if the font "foo" was loaded by a FontLoader in the scene and referred to by name in the text component. In this case, there was a race condition, where the font lookup would sometimes yield different results on the main thread and on the render thread, and text would be garbled. 3. When a font was removed from the font database, then references to it would remain in the caches (glyph cache + font cache) in the render thread. With certain backends (DirectWrite, CoreText) this caused errors or even crashes, as the cached font engines would be referring to data that had been removed. The work-around for #1 and #2 was merely to avoid hardcoding names for fonts, but instead getting them from the FontLoader. This way, you can avoid requesting the font family before it is available (and thus avoid caching the wrong result). However, for #3 there is no known work-around. This patch fixes all three (together with a smaller patch for qtbase) by invalidating all text and related caches in Qt Quick when fonts are either added or removed from the font database. This does add some overhead if font loading happens during runtime, but the alternative is broken behavior and dangling pointers. This is done during the synchronization step. Before synchronization, the font cache is flushed and all text components are marked for update, so that fonts are re-requested against the new font database. After synchronization, we delete all distance field glyph caches which are not currently in use, to avoid having references to stale application font data in the list. [ChangeLog][Text] Fix multiple issues with usage of application fonts when they are added or removed during the lifetime of the application. Task-number: QTBUG-100697 Task-number: QDS-1142 Change-Id: Ib309e54e0ee97b6be6d2a7211964043fd51c9ec5 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
54a71e8c83
commit
2fb43a35df
|
@ -78,6 +78,7 @@ qt_internal_add_qml_module(Quick
|
||||||
items/qquickstateoperations.cpp items/qquickstateoperations_p.h
|
items/qquickstateoperations.cpp items/qquickstateoperations_p.h
|
||||||
items/qquicktext.cpp items/qquicktext_p.h
|
items/qquicktext.cpp items/qquicktext_p.h
|
||||||
items/qquicktext_p_p.h
|
items/qquicktext_p_p.h
|
||||||
|
items/qquicktextinterface_p.h
|
||||||
items/qquicktextcontrol.cpp items/qquicktextcontrol_p.h
|
items/qquicktextcontrol.cpp items/qquicktextcontrol_p.h
|
||||||
items/qquicktextcontrol_p_p.h
|
items/qquicktextcontrol_p_p.h
|
||||||
items/qquicktextdocument.cpp items/qquicktextdocument.h items/qquicktextdocument_p.h
|
items/qquicktextdocument.cpp items/qquicktextdocument.h items/qquicktextdocument_p.h
|
||||||
|
|
|
@ -3008,6 +3008,13 @@ void QQuickText::hoverLeaveEvent(QHoverEvent *event)
|
||||||
d->processHoverEvent(event);
|
d->processHoverEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQuickText::invalidate()
|
||||||
|
{
|
||||||
|
Q_D(QQuickText);
|
||||||
|
d->textHasChanged = true;
|
||||||
|
d->updateLayout();
|
||||||
|
}
|
||||||
|
|
||||||
bool QQuickTextPrivate::transformChanged(QQuickItem *transformedItem)
|
bool QQuickTextPrivate::transformChanged(QQuickItem *transformedItem)
|
||||||
{
|
{
|
||||||
// If there's a lot of text, we may need QQuickText::updatePaintNode() to call
|
// If there's a lot of text, we may need QQuickText::updatePaintNode() to call
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "qquickimplicitsizeitem_p.h"
|
#include "qquickimplicitsizeitem_p.h"
|
||||||
|
#include "qquicktextinterface_p.h"
|
||||||
#include <private/qtquickglobal_p.h>
|
#include <private/qtquickglobal_p.h>
|
||||||
#include <QtGui/qtextoption.h>
|
#include <QtGui/qtextoption.h>
|
||||||
|
|
||||||
|
@ -59,9 +60,10 @@ QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QQuickTextPrivate;
|
class QQuickTextPrivate;
|
||||||
class QQuickTextLine;
|
class QQuickTextLine;
|
||||||
class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
|
class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem, public QQuickTextInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QQuickTextInterface)
|
||||||
|
|
||||||
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
||||||
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
|
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
|
||||||
|
@ -274,6 +276,8 @@ public:
|
||||||
QJSValue fontInfo() const;
|
QJSValue fontInfo() const;
|
||||||
QSizeF advance() const;
|
QSizeF advance() const;
|
||||||
|
|
||||||
|
void invalidate() override;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void textChanged(const QString &text);
|
void textChanged(const QString &text);
|
||||||
void linkActivated(const QString &link);
|
void linkActivated(const QString &link);
|
||||||
|
|
|
@ -435,6 +435,18 @@ void QQuickTextEdit::setText(const QString &text)
|
||||||
setFlag(QQuickItem::ItemObservesViewport, text.size() > QQuickTextEditPrivate::largeTextSizeThreshold);
|
setFlag(QQuickItem::ItemObservesViewport, text.size() > QQuickTextEditPrivate::largeTextSizeThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQuickTextEdit::invalidate()
|
||||||
|
{
|
||||||
|
Q_D(QQuickTextEdit);
|
||||||
|
if (isComponentComplete()) {
|
||||||
|
if (d->document != nullptr)
|
||||||
|
d->document->markContentsDirty(0, d->document->characterCount());
|
||||||
|
invalidateFontCaches();
|
||||||
|
d->updateType = QQuickTextEditPrivate::UpdateAll;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty string QtQuick::TextEdit::preeditText
|
\qmlproperty string QtQuick::TextEdit::preeditText
|
||||||
\readonly
|
\readonly
|
||||||
|
@ -2078,20 +2090,25 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
|
||||||
Q_UNUSED(updatePaintNodeData);
|
Q_UNUSED(updatePaintNodeData);
|
||||||
Q_D(QQuickTextEdit);
|
Q_D(QQuickTextEdit);
|
||||||
|
|
||||||
if (d->updateType != QQuickTextEditPrivate::UpdatePaintNode && oldNode != nullptr) {
|
if (d->updateType != QQuickTextEditPrivate::UpdatePaintNode
|
||||||
|
&& d->updateType != QQuickTextEditPrivate::UpdateAll
|
||||||
|
&& oldNode != nullptr) {
|
||||||
// Update done in preprocess() in the nodes
|
// Update done in preprocess() in the nodes
|
||||||
d->updateType = QQuickTextEditPrivate::UpdateNone;
|
d->updateType = QQuickTextEditPrivate::UpdateNone;
|
||||||
return oldNode;
|
return oldNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->updateType = QQuickTextEditPrivate::UpdateNone;
|
if (!oldNode || d->updateType == QQuickTextEditPrivate::UpdateAll) {
|
||||||
|
delete oldNode;
|
||||||
|
oldNode = nullptr;
|
||||||
|
|
||||||
if (!oldNode) {
|
|
||||||
// If we had any QQuickTextNode node references, they were deleted along with the root node
|
// If we had any QQuickTextNode node references, they were deleted along with the root node
|
||||||
// But here we must delete the Node structures in textNodeMap
|
// But here we must delete the Node structures in textNodeMap
|
||||||
d->textNodeMap.clear();
|
d->textNodeMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d->updateType = QQuickTextEditPrivate::UpdateNone;
|
||||||
|
|
||||||
RootNode *rootNode = static_cast<RootNode *>(oldNode);
|
RootNode *rootNode = static_cast<RootNode *>(oldNode);
|
||||||
TextNodeIterator nodeIterator = d->textNodeMap.begin();
|
TextNodeIterator nodeIterator = d->textNodeMap.begin();
|
||||||
while (nodeIterator != d->textNodeMap.end() && !nodeIterator->dirty())
|
while (nodeIterator != d->textNodeMap.end() && !nodeIterator->dirty())
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "qquickimplicitsizeitem_p.h"
|
#include "qquickimplicitsizeitem_p.h"
|
||||||
|
#include "qquicktextinterface_p.h"
|
||||||
|
|
||||||
#include <QtGui/qtextoption.h>
|
#include <QtGui/qtextoption.h>
|
||||||
|
|
||||||
|
@ -61,9 +62,10 @@ class QQuickTextDocument;
|
||||||
class QQuickTextEditPrivate;
|
class QQuickTextEditPrivate;
|
||||||
class QTextBlock;
|
class QTextBlock;
|
||||||
|
|
||||||
class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
|
class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem, public QQuickTextInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QQuickTextInterface)
|
||||||
|
|
||||||
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
||||||
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
|
||||||
|
@ -303,6 +305,8 @@ public:
|
||||||
int tabStopDistance() const;
|
int tabStopDistance() const;
|
||||||
void setTabStopDistance(qreal distance);
|
void setTabStopDistance(qreal distance);
|
||||||
|
|
||||||
|
void invalidate() override;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void textChanged();
|
void textChanged();
|
||||||
Q_REVISION(2, 7) void preeditTextChanged();
|
Q_REVISION(2, 7) void preeditTextChanged();
|
||||||
|
|
|
@ -197,7 +197,8 @@ public:
|
||||||
enum UpdateType {
|
enum UpdateType {
|
||||||
UpdateNone,
|
UpdateNone,
|
||||||
UpdateOnlyPreprocess,
|
UpdateOnlyPreprocess,
|
||||||
UpdatePaintNode
|
UpdatePaintNode,
|
||||||
|
UpdateAll
|
||||||
};
|
};
|
||||||
|
|
||||||
QQuickTextEdit::HAlignment hAlign;
|
QQuickTextEdit::HAlignment hAlign;
|
||||||
|
|
|
@ -136,6 +136,13 @@ QString QQuickTextInput::text() const
|
||||||
return (res.isNull() ? QString::fromLatin1("") : res);
|
return (res.isNull() ? QString::fromLatin1("") : res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQuickTextInput::invalidate()
|
||||||
|
{
|
||||||
|
Q_D(QQuickTextInput);
|
||||||
|
d->updateLayout();
|
||||||
|
invalidateFontCaches();
|
||||||
|
}
|
||||||
|
|
||||||
void QQuickTextInput::setText(const QString &s)
|
void QQuickTextInput::setText(const QString &s)
|
||||||
{
|
{
|
||||||
Q_D(QQuickTextInput);
|
Q_D(QQuickTextInput);
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "qquickimplicitsizeitem_p.h"
|
#include "qquickimplicitsizeitem_p.h"
|
||||||
|
#include "qquicktextinterface_p.h"
|
||||||
#include <QtGui/qtextoption.h>
|
#include <QtGui/qtextoption.h>
|
||||||
#include <QtGui/qvalidator.h>
|
#include <QtGui/qvalidator.h>
|
||||||
|
|
||||||
|
@ -59,9 +60,10 @@ QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QQuickTextInputPrivate;
|
class QQuickTextInputPrivate;
|
||||||
class QValidator;
|
class QValidator;
|
||||||
class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
|
class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem, public QQuickTextInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QQuickTextInterface)
|
||||||
|
|
||||||
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
||||||
Q_PROPERTY(int length READ length NOTIFY textChanged)
|
Q_PROPERTY(int length READ length NOTIFY textChanged)
|
||||||
|
@ -311,6 +313,8 @@ public:
|
||||||
void setBottomPadding(qreal padding);
|
void setBottomPadding(qreal padding);
|
||||||
void resetBottomPadding();
|
void resetBottomPadding();
|
||||||
|
|
||||||
|
void invalidate() override;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void textChanged();
|
void textChanged();
|
||||||
void cursorPositionChanged();
|
void cursorPositionChanged();
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 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$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QQUICKTEXTINTERFACE_P_H
|
||||||
|
#define QQUICKTEXTINTERFACE_P_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Qt API. It exists purely as an
|
||||||
|
// implementation detail. This header file may change from version to
|
||||||
|
// version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class Q_QUICK_PRIVATE_EXPORT QQuickTextInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void invalidate() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define QQuickTextInterface_iid "org.qt-project.Qt.QQuickTextInterface"
|
||||||
|
Q_DECLARE_INTERFACE(QQuickTextInterface, QQuickTextInterface_iid)
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QQUICKTEXTINTERFACE_P_H
|
|
@ -53,6 +53,7 @@
|
||||||
#include <private/qquickrendercontrol_p.h>
|
#include <private/qquickrendercontrol_p.h>
|
||||||
#include <private/qquickanimatorcontroller_p.h>
|
#include <private/qquickanimatorcontroller_p.h>
|
||||||
#include <private/qquickprofiler_p.h>
|
#include <private/qquickprofiler_p.h>
|
||||||
|
#include <private/qquicktextinterface_p.h>
|
||||||
|
|
||||||
#include <private/qguiapplication_p.h>
|
#include <private/qguiapplication_p.h>
|
||||||
|
|
||||||
|
@ -436,6 +437,12 @@ void QQuickWindow::physicalDpiChanged()
|
||||||
updatePixelRatioHelper(d->contentItem, newPixelRatio);
|
updatePixelRatioHelper(d->contentItem, newPixelRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQuickWindow::handleFontDatabaseChanged()
|
||||||
|
{
|
||||||
|
Q_D(QQuickWindow);
|
||||||
|
d->pendingFontUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
void QQuickWindow::handleScreenChanged(QScreen *screen)
|
void QQuickWindow::handleScreenChanged(QScreen *screen)
|
||||||
{
|
{
|
||||||
Q_D(QQuickWindow);
|
Q_D(QQuickWindow);
|
||||||
|
@ -504,6 +511,17 @@ void QQuickWindowRenderTarget::reset(QRhi *rhi)
|
||||||
owns = false;
|
owns = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQuickWindowPrivate::invalidateFontData(QQuickItem *item)
|
||||||
|
{
|
||||||
|
QQuickTextInterface *textItem = qobject_cast<QQuickTextInterface *>(item);
|
||||||
|
if (textItem != nullptr)
|
||||||
|
textItem->invalidate();
|
||||||
|
|
||||||
|
QList<QQuickItem *> children = item->childItems();
|
||||||
|
for (QQuickItem *child : children)
|
||||||
|
invalidateFontData(child);
|
||||||
|
}
|
||||||
|
|
||||||
void QQuickWindowPrivate::ensureCustomRenderTarget()
|
void QQuickWindowPrivate::ensureCustomRenderTarget()
|
||||||
{
|
{
|
||||||
// resolve() can be expensive when importing an existing native texture, so
|
// resolve() can be expensive when importing an existing native texture, so
|
||||||
|
@ -547,6 +565,12 @@ void QQuickWindowPrivate::syncSceneGraph()
|
||||||
|
|
||||||
emit q->beforeSynchronizing();
|
emit q->beforeSynchronizing();
|
||||||
runAndClearJobs(&beforeSynchronizingJobs);
|
runAndClearJobs(&beforeSynchronizingJobs);
|
||||||
|
|
||||||
|
if (pendingFontUpdate) {
|
||||||
|
QFont::cleanup();
|
||||||
|
invalidateFontData(contentItem);
|
||||||
|
}
|
||||||
|
|
||||||
if (!renderer) {
|
if (!renderer) {
|
||||||
forceUpdate(contentItem);
|
forceUpdate(contentItem);
|
||||||
|
|
||||||
|
@ -573,6 +597,11 @@ void QQuickWindowPrivate::syncSceneGraph()
|
||||||
|
|
||||||
renderer->setVisualizationMode(visualizationMode);
|
renderer->setVisualizationMode(visualizationMode);
|
||||||
|
|
||||||
|
if (pendingFontUpdate) {
|
||||||
|
context->invalidateGlyphCaches();
|
||||||
|
pendingFontUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
emit q->afterSynchronizing();
|
emit q->afterSynchronizing();
|
||||||
runAndClearJobs(&afterSynchronizingJobs);
|
runAndClearJobs(&afterSynchronizingJobs);
|
||||||
}
|
}
|
||||||
|
@ -748,6 +777,11 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
|
||||||
|
|
||||||
Q_ASSERT(windowManager || renderControl);
|
Q_ASSERT(windowManager || renderControl);
|
||||||
|
|
||||||
|
QObject::connect(static_cast<QGuiApplication *>(QGuiApplication::instance()),
|
||||||
|
&QGuiApplication::fontDatabaseChanged,
|
||||||
|
q,
|
||||||
|
&QQuickWindow::handleFontDatabaseChanged);
|
||||||
|
|
||||||
if (QScreen *screen = q->screen()) {
|
if (QScreen *screen = q->screen()) {
|
||||||
lastReportedItemDevicePixelRatio = q->effectiveDevicePixelRatio();
|
lastReportedItemDevicePixelRatio = q->effectiveDevicePixelRatio();
|
||||||
// if the screen changes, then QQuickWindow::handleScreenChanged disconnects
|
// if the screen changes, then QQuickWindow::handleScreenChanged disconnects
|
||||||
|
|
|
@ -259,6 +259,7 @@ private Q_SLOTS:
|
||||||
void setTransientParent_helper(QQuickWindow *window);
|
void setTransientParent_helper(QQuickWindow *window);
|
||||||
void runJobsAfterSwap();
|
void runJobsAfterSwap();
|
||||||
void handleApplicationStateChanged(Qt::ApplicationState state);
|
void handleApplicationStateChanged(Qt::ApplicationState state);
|
||||||
|
void handleFontDatabaseChanged();
|
||||||
private:
|
private:
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
inline friend QQmlInfo operator<<(QQmlInfo info, const QQuickWindow *window)
|
inline friend QQmlInfo operator<<(QQmlInfo info, const QQuickWindow *window)
|
||||||
|
|
|
@ -168,6 +168,7 @@ public:
|
||||||
|
|
||||||
void polishItems();
|
void polishItems();
|
||||||
void forcePolish();
|
void forcePolish();
|
||||||
|
void invalidateFontData(QQuickItem *item);
|
||||||
void syncSceneGraph();
|
void syncSceneGraph();
|
||||||
void renderSceneGraph(const QSize &size, const QSize &surfaceSize = QSize());
|
void renderSceneGraph(const QSize &size, const QSize &surfaceSize = QSize());
|
||||||
|
|
||||||
|
@ -295,6 +296,7 @@ public:
|
||||||
uint hasActiveSwapchain : 1;
|
uint hasActiveSwapchain : 1;
|
||||||
uint hasRenderableSwapchain : 1;
|
uint hasRenderableSwapchain : 1;
|
||||||
uint swapchainJustBecameRenderable : 1;
|
uint swapchainJustBecameRenderable : 1;
|
||||||
|
bool pendingFontUpdate = false;
|
||||||
bool windowEventDispatch = false;
|
bool windowEventDispatch = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -170,6 +170,11 @@ void QSGDistanceFieldGlyphCache::release(const QVector<glyph_t> &glyphs)
|
||||||
releaseGlyphs(unusedGlyphs);
|
releaseGlyphs(unusedGlyphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QSGDistanceFieldGlyphCache::isActive() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void QSGDistanceFieldGlyphCache::update()
|
void QSGDistanceFieldGlyphCache::update()
|
||||||
{
|
{
|
||||||
m_populatingGlyphs.clear();
|
m_populatingGlyphs.clear();
|
||||||
|
|
|
@ -495,6 +495,7 @@ public:
|
||||||
|
|
||||||
virtual bool eightBitFormatIsAlphaSwizzled() const = 0;
|
virtual bool eightBitFormatIsAlphaSwizzled() const = 0;
|
||||||
virtual bool screenSpaceDerivativesSupported() const = 0;
|
virtual bool screenSpaceDerivativesSupported() const = 0;
|
||||||
|
virtual bool isActive() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct GlyphPosition {
|
struct GlyphPosition {
|
||||||
|
|
|
@ -432,6 +432,10 @@ QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRaw
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QSGRenderContext::invalidateGlyphCaches()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
|
void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
|
||||||
{
|
{
|
||||||
|
|
|
@ -198,6 +198,7 @@ public:
|
||||||
virtual void endSync();
|
virtual void endSync();
|
||||||
|
|
||||||
virtual void preprocess();
|
virtual void preprocess();
|
||||||
|
virtual void invalidateGlyphCaches();
|
||||||
virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality);
|
virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality);
|
||||||
QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window);
|
QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window);
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,19 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par
|
||||||
emit initialized();
|
emit initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QSGDefaultRenderContext::invalidateGlyphCaches()
|
||||||
|
{
|
||||||
|
auto it = m_glyphCaches.begin();
|
||||||
|
while (it != m_glyphCaches.end()) {
|
||||||
|
if (!(*it)->isActive()) {
|
||||||
|
delete *it;
|
||||||
|
it = m_glyphCaches.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QSGDefaultRenderContext::invalidate()
|
void QSGDefaultRenderContext::invalidate()
|
||||||
{
|
{
|
||||||
if (!m_rhi)
|
if (!m_rhi)
|
||||||
|
|
|
@ -111,6 +111,7 @@ public:
|
||||||
void endNextRhiFrame(QSGRenderer *renderer) override;
|
void endNextRhiFrame(QSGRenderer *renderer) override;
|
||||||
|
|
||||||
void preprocess() override;
|
void preprocess() override;
|
||||||
|
void invalidateGlyphCaches() override;
|
||||||
QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality) override;
|
QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality) override;
|
||||||
|
|
||||||
QSGTexture *createTexture(const QImage &image, uint flags) const override;
|
QSGTexture *createTexture(const QImage &image, uint flags) const override;
|
||||||
|
|
|
@ -147,6 +147,11 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
|
||||||
markGlyphsToRender(glyphsToRender);
|
markGlyphsToRender(glyphsToRender);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QSGRhiDistanceFieldGlyphCache::isActive() const
|
||||||
|
{
|
||||||
|
return m_unusedGlyphs.size() != m_glyphsTexture.size();
|
||||||
|
}
|
||||||
|
|
||||||
void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyphs)
|
void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyphs)
|
||||||
{
|
{
|
||||||
typedef QHash<TextureInfo *, QVector<glyph_t> > GlyphTextureHash;
|
typedef QHash<TextureInfo *, QVector<glyph_t> > GlyphTextureHash;
|
||||||
|
|
|
@ -72,6 +72,7 @@ public:
|
||||||
|
|
||||||
bool useTextureResizeWorkaround() const;
|
bool useTextureResizeWorkaround() const;
|
||||||
bool createFullSizeTextures() const;
|
bool createFullSizeTextures() const;
|
||||||
|
bool isActive() const override;
|
||||||
int maxTextureSize() const;
|
int maxTextureSize() const;
|
||||||
|
|
||||||
void setMaxTextureCount(int max) { m_maxTextureCount = max; }
|
void setMaxTextureCount(int max) { m_maxTextureCount = max; }
|
||||||
|
|
Loading…
Reference in New Issue