aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph/qsgdefaultrendercontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph/qsgdefaultrendercontext.cpp')
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp203
1 files changed, 98 insertions, 105 deletions
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 1b2dbab84f..1b0753e9ae 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -1,43 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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) 2016 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 "qsgdefaultrendercontext_p.h"
+#include "qsgcurveglyphatlas_p.h"
#include <QtGui/QGuiApplication>
@@ -58,12 +23,11 @@ QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context)
: QSGRenderContext(context)
, m_rhi(nullptr)
, m_maxTextureSize(0)
- , m_serializedRender(false)
, m_rhiAtlasManager(nullptr)
, m_currentFrameCommandBuffer(nullptr)
, m_currentFrameRenderPass(nullptr)
- , m_separateIndexBuffer(false)
, m_useDepthBufferFor2D(true)
+ , m_glyphCacheResourceUpdates(nullptr)
{
}
@@ -86,14 +50,46 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par
m_maxTextureSize = m_rhi->resourceLimit(QRhi::TextureSizeMax);
if (!m_rhiAtlasManager)
m_rhiAtlasManager = new QSGRhiAtlasTexture::Manager(this, m_initParams.initialSurfacePixelSize, m_initParams.maybeSurface);
- // unlike OpenGL (and like WebGL), QRhi does not guarantee buffer usage types can be mixed
- m_separateIndexBuffer = true;
+
+ m_glyphCacheResourceUpdates = nullptr;
m_sg->renderContextInitialized(this);
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;
+ }
+ }
+ }
+
+ qDeleteAll(m_curveGlyphAtlases);
+ m_curveGlyphAtlases.clear();
+
+ {
+ auto it = m_fontEnginesToClean.begin();
+ while (it != m_fontEnginesToClean.end()) {
+ if (it.value() == 0) {
+ it.key()->clearGlyphCache(this);
+ if (!it.key()->ref.deref())
+ delete it.key();
+ it = m_fontEnginesToClean.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+}
+
void QSGDefaultRenderContext::invalidate()
{
if (!m_rhi)
@@ -132,18 +128,21 @@ void QSGDefaultRenderContext::invalidate()
// code is only called from QQuickWindow's shutdown which is called
// only when the GUI is blocked, and multiple threads will call it in
// sequence. (see qsgdefaultglyphnode_p.cpp's init())
- for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(),
- end = m_fontEnginesToClean.constEnd(); it != end; ++it) {
- (*it)->clearGlyphCache(m_rhi);
- if (!(*it)->ref.deref())
- delete *it;
+ for (auto it = m_fontEnginesToClean.constBegin(); it != m_fontEnginesToClean.constEnd(); ++it) {
+ it.key()->clearGlyphCache(this);
+ if (!it.key()->ref.deref())
+ delete it.key();
}
m_fontEnginesToClean.clear();
+ qDeleteAll(m_curveGlyphAtlases);
+ m_curveGlyphAtlases.clear();
qDeleteAll(m_glyphCaches);
m_glyphCaches.clear();
+ resetGlyphCacheResources();
+
m_rhi = nullptr;
if (m_sg)
@@ -165,55 +164,26 @@ void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio,
m_currentFrameCommandBuffer = cb;
}
-static QBasicMutex qsg_framerender_mutex;
-
-void QSGDefaultRenderContext::beginNextFrame(QSGRenderer *renderer,
+void QSGDefaultRenderContext::beginNextFrame(QSGRenderer *renderer, const QSGRenderTarget &renderTarget,
RenderPassCallback mainPassRecordingStart,
RenderPassCallback mainPassRecordingEnd,
void *callbackUserData)
{
+ renderer->setRenderTarget(renderTarget);
renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
+
+ m_currentFrameCommandBuffer = renderTarget.cb; // usually the same as what was passed to prepareSync() but cannot count on that having been called
+ m_currentFrameRenderPass = renderTarget.rpDesc;
}
void QSGDefaultRenderContext::renderNextFrame(QSGRenderer *renderer)
{
- if (m_serializedRender)
- qsg_framerender_mutex.lock();
-
renderer->renderScene();
-
- if (m_serializedRender)
- qsg_framerender_mutex.unlock();
}
void QSGDefaultRenderContext::endNextFrame(QSGRenderer *renderer)
{
Q_UNUSED(renderer);
-}
-
-void QSGDefaultRenderContext::beginNextRhiFrame(QSGRenderer *renderer, QRhiRenderTarget *rt, QRhiRenderPassDescriptor *rp,
- QRhiCommandBuffer *cb,
- RenderPassCallback mainPassRecordingStart,
- RenderPassCallback mainPassRecordingEnd,
- void *callbackUserData)
-{
- renderer->setRenderTarget(rt);
- renderer->setRenderPassDescriptor(rp);
- renderer->setCommandBuffer(cb);
- renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
-
- m_currentFrameCommandBuffer = cb; // usually the same as what was passed to prepareSync() but cannot count on that having been called
- m_currentFrameRenderPass = rp;
-}
-
-void QSGDefaultRenderContext::renderNextRhiFrame(QSGRenderer *renderer)
-{
- renderer->renderScene();
-}
-
-void QSGDefaultRenderContext::endNextRhiFrame(QSGRenderer *renderer)
-{
- Q_UNUSED(renderer);
m_currentFrameCommandBuffer = nullptr;
m_currentFrameRenderPass = nullptr;
}
@@ -257,27 +227,6 @@ QSGTexture *QSGDefaultRenderContext::compressedTextureForFactory(const QSGCompre
return nullptr;
}
-QString QSGDefaultRenderContext::fontKey(const QRawFont &font, int renderTypeQuality)
-{
- QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
- if (!fe->faceId().filename.isEmpty()) {
- QByteArray keyName =
- fe->faceId().filename + ' ' + QByteArray::number(fe->faceId().index)
- + (font.style() != QFont::StyleNormal ? QByteArray(" I") : QByteArray())
- + (font.weight() != QFont::Normal ? ' ' + QByteArray::number(font.weight()) : QByteArray())
- + ' ' + QByteArray::number(renderTypeQuality)
- + QByteArray(" DF");
- return QString::fromUtf8(keyName);
- } else {
- return QString::fromLatin1("%1_%2_%3_%4_%5")
- .arg(font.familyName())
- .arg(font.styleName())
- .arg(font.weight())
- .arg(font.style())
- .arg(renderTypeQuality);
- }
-}
-
void QSGDefaultRenderContext::initializeRhiShader(QSGMaterialShader *shader, QShader::Variant shaderVariant)
{
QSGMaterialShaderPrivate::get(shader)->prepare(shaderVariant);
@@ -291,18 +240,62 @@ void QSGDefaultRenderContext::preprocess()
}
}
+QSGCurveGlyphAtlas *QSGDefaultRenderContext::curveGlyphAtlas(const QRawFont &font)
+{
+ FontKey key = FontKey(font, 0);
+ QSGCurveGlyphAtlas *atlas = m_curveGlyphAtlases.value(key, nullptr);
+ if (atlas == nullptr) {
+ atlas = new QSGCurveGlyphAtlas(font);
+ m_curveGlyphAtlases.insert(key, atlas);
+ }
+
+ return atlas;
+}
+
QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality)
{
- QString key = fontKey(font, renderTypeQuality);
+ FontKey key(font, renderTypeQuality);
QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
- if (!cache) {
- cache = new QSGRhiDistanceFieldGlyphCache(m_rhi, font, renderTypeQuality);
+ if (!cache && font.isValid()) {
+ cache = new QSGRhiDistanceFieldGlyphCache(this, font, renderTypeQuality);
m_glyphCaches.insert(key, cache);
}
return cache;
}
+QRhiResourceUpdateBatch *QSGDefaultRenderContext::maybeGlyphCacheResourceUpdates()
+{
+ return m_glyphCacheResourceUpdates;
+}
+
+QRhiResourceUpdateBatch *QSGDefaultRenderContext::glyphCacheResourceUpdates()
+{
+ if (!m_glyphCacheResourceUpdates)
+ m_glyphCacheResourceUpdates = m_rhi->nextResourceUpdateBatch();
+
+ return m_glyphCacheResourceUpdates;
+}
+
+void QSGDefaultRenderContext::deferredReleaseGlyphCacheTexture(QRhiTexture *texture)
+{
+ if (texture)
+ m_pendingGlyphCacheTextures.insert(texture);
+}
+
+void QSGDefaultRenderContext::resetGlyphCacheResources()
+{
+ if (m_glyphCacheResourceUpdates) {
+ m_glyphCacheResourceUpdates->release();
+ m_glyphCacheResourceUpdates = nullptr;
+ }
+
+ for (QRhiTexture *t : std::as_const(m_pendingGlyphCacheTextures))
+ t->deleteLater(); // the QRhiTexture object stays valid for the current frame
+
+ m_pendingGlyphCacheTextures.clear();
+}
+
QT_END_NAMESPACE
#include "moc_qsgdefaultrendercontext_p.cpp"