diff options
Diffstat (limited to 'src/quick/scenegraph/qsgdefaultrendercontext.cpp')
-rw-r--r-- | src/quick/scenegraph/qsgdefaultrendercontext.cpp | 203 |
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" |