diff options
Diffstat (limited to 'src/quick/scenegraph')
28 files changed, 176 insertions, 125 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index 4da188bbfe..0c0ee5e579 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -107,6 +107,18 @@ void QSGSoftwareRenderContext::initializeIfNeeded() void QSGSoftwareRenderContext::invalidate() { + qDeleteAll(m_texturesToDelete); + m_texturesToDelete.clear(); + + qDeleteAll(m_textures); + m_textures.clear(); + + qDeleteAll(m_fontEnginesToClean); + m_fontEnginesToClean.clear(); + + qDeleteAll(m_glyphCaches); + m_glyphCaches.clear(); + m_sg->renderContextInvalidated(this); emit invalidated(); } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp index 71e9c7b2aa..488f622dce 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp @@ -84,7 +84,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st { //normalize stops bool needsNormalization = false; - for (const QGradientStop &stop : qAsConst(stops)) { + for (const QGradientStop &stop : std::as_const(stops)) { if (stop.first < 0.0 || stop.first > 1.0) { needsNormalization = true; break; @@ -93,7 +93,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st if (needsNormalization) { QGradientStops normalizedStops; - if (stops.count() == 1) { + if (stops.size() == 1) { //If there is only one stop, then the position does not matter //It is just treated as a color QGradientStop stop = stops.at(0); @@ -104,7 +104,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st int below = -1; int above = -1; QVector<int> between; - for (int i = 0; i < stops.count(); ++i) { + for (int i = 0; i < stops.size(); ++i) { if (stops.at(i).first < 0.0) { below = i; } else if (stops.at(i).first > 1.0) { @@ -118,7 +118,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st //Interpoloate new color values for above and below if (below != -1 ) { //If there are more than one stops left, interpolate - if (below + 1 < stops.count()) { + if (below + 1 < stops.size()) { normalizedStops.append(interpolateStop(stops.at(below), stops.at(below + 1), 0.0)); } else { QGradientStop singleStop; @@ -128,7 +128,7 @@ void QSGSoftwareInternalRectangleNode::setGradientStops(const QGradientStops &st } } - for (int i = 0; i < between.count(); ++i) + for (int i = 0; i < between.size(); ++i) normalizedStops.append(stops.at(between.at(i))); if (above != -1) { @@ -249,8 +249,8 @@ bool QSGSoftwareInternalRectangleNode::isOpaque() const return false; if (m_penWidth > 0.0f && m_penColor.alpha() < 255) return false; - if (m_stops.count() > 0) { - for (const QGradientStop &stop : qAsConst(m_stops)) { + if (m_stops.size() > 0) { + for (const QGradientStop &stop : std::as_const(m_stops)) { if (stop.second.alpha() < 255) return false; } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp index 56400161bb..20e1ca5b8b 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp @@ -47,7 +47,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGTransformNode *) bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node) { // Make sure to translate the clip rect into world coordinates - if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) { + if (m_clipState.size() == 0 || (m_clipState.size() == 1 && m_clipState.top().isNull())) { m_clipState.push(m_transformState.top().map(QRegion(node->clipRect().toRect()))); m_hasClip = true; } else { @@ -61,7 +61,7 @@ bool QSGSoftwareRenderableNodeUpdater::visit(QSGClipNode *node) void QSGSoftwareRenderableNodeUpdater::endVisit(QSGClipNode *) { m_clipState.pop(); - if (m_clipState.count() == 0 || (m_clipState.count() == 1 && m_clipState.top().isNull())) + if (m_clipState.size() == 0 || (m_clipState.size() == 1 && m_clipState.top().isNull())) m_hasClip = false; } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index fa709deea2..d12deec9f6 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -754,7 +754,7 @@ void QSGSoftwareThreadedRenderLoop::onAnimationStarted() { startOrStopAnimationTimer(); - for (const WindowData &w : qAsConst(m_windows)) + for (const WindowData &w : std::as_const(m_windows)) w.window->requestUpdate(); } diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h index 8ae245f07e..46c2c1022f 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h @@ -63,7 +63,7 @@ public: QSGTexture *removedFromAtlas(QRhiResourceUpdateBatch *) const override; const QByteArray &data() const { return m_data; } - int sizeInBytes() const { return m_data.length(); } + int sizeInBytes() const { return m_data.size(); } private: QRectF m_texture_coords_rect; diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index df7575a33e..29d507a8fb 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -272,14 +272,14 @@ void ShaderManager::invalidated() void ShaderManager::clearCachedRendererData() { - for (ShaderManager::Shader *sms : qAsConst(stockShaders)) { + for (ShaderManager::Shader *sms : std::as_const(stockShaders)) { QSGMaterialShader *s = sms->programRhi.program; if (s) { QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s); sd->clearCachedRendererData(); } } - for (ShaderManager::Shader *sms : qAsConst(rewrittenShaders)) { + for (ShaderManager::Shader *sms : std::as_const(rewrittenShaders)) { QSGMaterialShader *s = sms->programRhi.program; if (s) { QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s); @@ -915,8 +915,14 @@ Renderer::~Renderer() qsg_wipeBatch(m_batchPool.at(i)); } - for (Node *n : qAsConst(m_nodes)) + for (Node *n : std::as_const(m_nodes)) { + if (n->type() == QSGNode::GeometryNodeType) { + Element *e = n->element(); + if (!e->removed) + m_elementsToDelete.add(e); + } m_nodeAllocator.release(n); + } // Remaining elements... for (int i=0; i<m_elementsToDelete.size(); ++i) @@ -1980,7 +1986,7 @@ void Renderer::uploadBatch(Batch *b) bool canMerge = (g->drawingMode() == QSGGeometry::DrawTriangles || g->drawingMode() == QSGGeometry::DrawTriangleStrip || g->drawingMode() == QSGGeometry::DrawLines || g->drawingMode() == QSGGeometry::DrawPoints) && b->positionAttribute >= 0 - && g->indexType() == QSGGeometry::UnsignedShortType + && (g->indexType() == QSGGeometry::UnsignedShortType && g->indexCount() > 0) && (flags & (QSGMaterial::NoBatching | QSGMaterial_FullMatrix)) == 0 && ((flags & QSGMaterial::RequiresFullMatrixExceptTranslate) == 0 || b->isTranslateOnlyToRoot()) && b->isSafeToBatch(); @@ -2869,11 +2875,11 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms, pd->samplerBindingTable[binding] = samplers; // does not own } - if (pd->textureBindingTable[binding].count() == pd->samplerBindingTable[binding].count()) { + if (pd->textureBindingTable[binding].size() == pd->samplerBindingTable[binding].size()) { QVarLengthArray<QRhiShaderResourceBinding::TextureAndSampler, 4> textureSamplers; - for (int i = 0; i < pd->textureBindingTable[binding].count(); ++i) { + for (int i = 0; i < pd->textureBindingTable[binding].size(); ++i) { QRhiTexture *texture = pd->textureBindingTable[binding].at(i)->rhiTexture(); @@ -2960,7 +2966,7 @@ void Renderer::updateMaterialDynamicData(ShaderManager::Shader *sms, // with increasing binding points afterwards, so the list is already sorted based // on the binding points, thus we can save some time by telling the QRhi backend // not to sort again. - if (pd->ubufBinding <= 0 || bindings.count() <= 1) + if (pd->ubufBinding <= 0 || bindings.size() <= 1) flags |= QRhiShaderResourceBindings::BindingsAreSorted; e->srb->updateResources(flags); @@ -3440,7 +3446,7 @@ void Renderer::releaseElement(Element *e, bool inDestructor) } else { if (e->srb) { if (!inDestructor) { - if (m_shaderManager->srbPool.count() < m_srbPoolThreshold) + if (m_shaderManager->srbPool.size() < m_srbPoolThreshold) m_shaderManager->srbPool.insert(e->srb->serializedLayoutDescription(), e->srb); else delete e->srb; @@ -3783,7 +3789,7 @@ void Renderer::recordRenderPass(RenderPassContext *ctx) QRhiCommandBuffer *cb = commandBuffer(); cb->debugMarkBegin(QByteArrayLiteral("Qt Quick scene render")); - for (int i = 0, ie = ctx->opaqueRenderBatches.count(); i != ie; ++i) { + for (int i = 0, ie = ctx->opaqueRenderBatches.size(); i != ie; ++i) { PreparedRenderBatch *renderBatch = &ctx->opaqueRenderBatches[i]; if (renderBatch->batch->merged) renderMergedBatch(renderBatch); @@ -3791,7 +3797,7 @@ void Renderer::recordRenderPass(RenderPassContext *ctx) renderUnmergedBatch(renderBatch); } - for (int i = 0, ie = ctx->alphaRenderBatches.count(); i != ie; ++i) { + for (int i = 0, ie = ctx->alphaRenderBatches.size(); i != ie; ++i) { PreparedRenderBatch *renderBatch = &ctx->alphaRenderBatches[i]; if (renderBatch->batch->merged) renderMergedBatch(renderBatch); @@ -3803,7 +3809,7 @@ void Renderer::recordRenderPass(RenderPassContext *ctx) if (m_renderMode == QSGRendererInterface::RenderMode3D) { // depth post-pass - for (int i = 0, ie = ctx->alphaRenderBatches.count(); i != ie; ++i) { + for (int i = 0, ie = ctx->alphaRenderBatches.size(); i != ie; ++i) { PreparedRenderBatch *renderBatch = &ctx->alphaRenderBatches[i]; if (renderBatch->batch->merged) renderMergedBatch(renderBatch, true); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 06771d2686..5b0c024466 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -115,7 +115,7 @@ public: // one. when an item is released, we'll reset m_freePage anyway. if (!p) { p = new AllocatorPage<Type, PageSize>(); - m_freePage = pages.count(); + m_freePage = pages.size(); pages.push_back(p); } uint pos = p->blocks[PageSize - p->available]; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index bd082a8d79..9541107b78 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -370,8 +370,10 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() Geometry objects are constructed by default with DrawTriangleStrip as the drawing mode. - The attribute structure is assumed to be POD and the geometry object - assumes this will not go away. There is no memory management involved. + \note \a attributes and the \l Attribute objects referenced by it must + stay valid for the entire lifetime of the QSGGeometry. + QSGGeometry stores a reference to \a attributes and does not delete + the \l Attribute objects. */ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, @@ -494,13 +496,18 @@ const void *QSGGeometry::indexData() const Specifies the drawing mode, also called primitive topology. + \note Starting with Qt 6 the scene graph only exposes topologies that are + supported across all the supported 3D graphics APIs. As a result, the + values \c DrawLineLoop and \c DrawTriangleFan are no longer supported at + run time in Qt 6, even though the enum values themselves are still present. + \value DrawPoints \value DrawLines - \value DrawLineLoop + \omitvalue DrawLineLoop \value DrawLineStrip \value DrawTriangles \value DrawTriangleStrip - \value DrawTriangleFan + \omitvalue DrawTriangleFan */ /*! @@ -534,10 +541,10 @@ void QSGGeometry::setDrawingMode(unsigned int mode) } /*! - Gets the current line or point width or to be used for this - geometry. This property only applies to line width when the drawingMode - is DrawLines, DarwLineStrip, or DrawLineLoop. When supported, it also - applies to point size when the drawingMode is DrawPoints. + Gets the current line or point width or to be used for this geometry. This + property only applies to line width when the drawingMode is DrawLines or + DrawLineStrip. When supported, it also applies to point size when the + drawingMode is DrawPoints. The default value is \c 1.0 @@ -556,10 +563,10 @@ float QSGGeometry::lineWidth() const } /*! - Sets the line or point width to be used for this geometry to \a - width. This property only applies to line width when the drawingMode is - DrawLines, DrawLineStrip, or DrawLineLoop. When supported, it also - applies to point size when the drawingMode is DrawPoints. + Sets the line or point width to be used for this geometry to \a width. This + property only applies to line width when the drawingMode is DrawLines or + DrawLineStrip. When supported, it also applies to point size when the + drawingMode is DrawPoints. \note Support for point and line drawing may be limited at run time, depending on the platform and graphics API. For example, some APIs do diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h index 1583bfd5b2..4392070b6e 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.h +++ b/src/quick/scenegraph/coreapi/qsggeometry.h @@ -165,6 +165,7 @@ public: void setLineWidth(float w); private: + Q_DISABLE_COPY_MOVE(QSGGeometry) friend class QSGGeometryData; int m_drawing_mode; diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp index e1edbc2445..a3e8b179b3 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterialshader.cpp @@ -247,7 +247,7 @@ void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant) const QShaderDescription desc = it->shader.description(); const QVector<QShaderDescription::UniformBlock> ubufs = desc.uniformBlocks(); - const int ubufCount = ubufs.count(); + const int ubufCount = ubufs.size(); if (ubufCount > 1) { qWarning("Multiple uniform blocks found in shader. " "This should be avoided as Qt Quick supports only one."); @@ -272,7 +272,7 @@ void QSGMaterialShaderPrivate::prepare(QShader::Variant vertexShaderVariant) } const QVector<QShaderDescription::InOutVariable> imageSamplers = desc.combinedImageSamplers(); - const int imageSamplersCount = imageSamplers.count(); + const int imageSamplersCount = imageSamplers.size(); for (int i = 0; i < imageSamplersCount; ++i) { const QShaderDescription::InOutVariable &var(imageSamplers[i]); diff --git a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp index 4352b9e795..9183de29d9 100644 --- a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp @@ -275,7 +275,7 @@ QRhiGraphicsPipeline *RhiVisualizer::PipelineCache::pipeline(RhiVisualizer *visu quint32 vertexStride, bool blendOneOne) { - for (int i = 0, ie = pipelines.count(); i != ie; ++i) { + for (int i = 0, ie = pipelines.size(); i != ie; ++i) { const Pipeline &p(pipelines.at(i)); if (p.topology == topology && p.format == vertexFormat && p.stride == vertexStride) return p.ps; @@ -316,7 +316,7 @@ QRhiGraphicsPipeline *RhiVisualizer::PipelineCache::pipeline(RhiVisualizer *visu void RhiVisualizer::PipelineCache::releaseResources() { - for (int i = 0, ie = pipelines.count(); i != ie; ++i) + for (int i = 0, ie = pipelines.size(); i != ie; ++i) delete pipelines.at(i).ps; pipelines.clear(); diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp index 15167f8ae5..f9c1f86436 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.cpp +++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp @@ -686,6 +686,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting OpenGL texture objects. \since 6.0 */ @@ -786,6 +787,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting Direct3D 11 texture objects. \since 6.0 */ @@ -846,6 +848,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting Metal texture objects. \since 6.0 */ @@ -893,6 +896,7 @@ namespace QNativeInterface { \inmodule QtQuick \ingroup native-interfaces \ingroup native-interfaces-qsgtexture + \inheaderfile QSGTexture \brief Provides access to and enables adopting Vulkan image objects. \since 6.0 */ diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index b2932a12ea..c20a126dce 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -91,7 +91,7 @@ void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs) { QSet<glyph_t> referencedGlyphs; QSet<glyph_t> newGlyphs; - int count = glyphs.count(); + int count = glyphs.size(); for (int i = 0; i < count; ++i) { glyph_t glyphIndex = glyphs.at(i); if ((int) glyphIndex >= glyphCount() && glyphCount() > 0) { @@ -124,7 +124,7 @@ void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs) void QSGDistanceFieldGlyphCache::release(const QVector<glyph_t> &glyphs) { QSet<glyph_t> unusedGlyphs; - int count = glyphs.count(); + int count = glyphs.size(); for (int i = 0; i < count; ++i) { glyph_t glyphIndex = glyphs.at(i); GlyphData &gd = glyphData(glyphIndex); @@ -180,7 +180,7 @@ void QSGDistanceFieldGlyphCache::update() storeGlyphs(distanceFields); #if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) - for (Texture texture : qAsConst(m_textures)) + for (Texture texture : std::as_const(m_textures)) saveTexture(texture.texture, m_referenceFont.familyName()); #endif @@ -203,7 +203,7 @@ void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &g { QVector<quint32> invalidatedGlyphs; - int count = glyphs.count(); + int count = glyphs.size(); for (int i = 0; i < count; ++i) { GlyphPosition glyph = glyphs.at(i); GlyphData &gd = glyphData(glyph.glyph); @@ -254,7 +254,7 @@ void QSGDistanceFieldGlyphCache::setGlyphsTexture(const QVector<glyph_t> &glyphs QVector<quint32> invalidatedGlyphs; - int count = glyphs.count(); + int count = glyphs.size(); for (int j = 0; j < count; ++j) { glyph_t glyphIndex = glyphs.at(j); GlyphData &gd = glyphData(glyphIndex); @@ -272,14 +272,14 @@ void QSGDistanceFieldGlyphCache::setGlyphsTexture(const QVector<glyph_t> &glyphs void QSGDistanceFieldGlyphCache::markGlyphsToRender(const QVector<glyph_t> &glyphs) { - int count = glyphs.count(); + int count = glyphs.size(); for (int i = 0; i < count; ++i) m_pendingGlyphs.add(glyphs.at(i)); } void QSGDistanceFieldGlyphCache::updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize) { - int count = m_textures.count(); + int count = m_textures.size(); for (int i = 0; i < count; ++i) { Texture &tex = m_textures[i]; if (tex.texture == oldTex) { diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index c20a99a8a9..a1edc97f52 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -256,7 +256,6 @@ public: Texture // for APIs with separate texture and sampler objects }; struct Variable { - Variable() {} VariableType type = Constant; QByteArray name; uint offset = 0; // for cbuffer members @@ -337,6 +336,7 @@ public: }; ShaderSyncData vertex; ShaderSyncData fragment; + void *materialTypeCacheKey; }; // Each ShaderEffect item has one node (render thread) and one manager (gui thread). diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index 192bd565a9..e21f2fbb6f 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -81,7 +81,7 @@ QSGAdaptationBackendData *contextFactory() const QStringList args = QGuiApplication::arguments(); QString requestedBackend = backendData->quickWindowBackendRequest; // empty or set via QQuickWindow::setSceneGraphBackend() - for (int index = 0; index < args.count(); ++index) { + for (int index = 0; index < args.size(); ++index) { if (args.at(index).startsWith(QLatin1String("--device="))) { requestedBackend = args.at(index).mid(9); break; @@ -129,7 +129,7 @@ QSGAdaptationBackendData *contextFactory() qCDebug(QSG_LOG_INFO, "Loading backend %s", qUtf8Printable(requestedBackend)); // First look for a built-in adaptation. - for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) { + for (QSGContextFactoryInterface *builtInBackend : std::as_const(backendData->builtIns)) { if (builtInBackend->keys().contains(requestedBackend)) { backendData->factory = builtInBackend; backendData->name = requestedBackend; diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 429d7ad4e1..43a7e919bc 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -472,9 +472,11 @@ void QSGTextMaskMaterial::populate(const QPointF &p, bool supportsSubPixelPositions = fontD->fontEngine->supportsHorizontalSubPixelPositions(); for (int i=0; i<glyphIndexes.size(); ++i) { QPointF glyphPosition = glyphPositions.at(i) + position; + QFixedPoint fixedPointPosition = fixedPointPositions.at(i); + QFixed subPixelPosition; if (supportsSubPixelPositions) - subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x() * glyphCacheScaleX)); + subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(fixedPointPosition.x.toReal() * glyphCacheScaleX)); QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), QFixedPoint(subPixelPosition, 0)); diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 3fee9d9faf..cd0a5b6d28 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -119,7 +119,7 @@ void QSGDefaultRenderContext::invalidate() qDeleteAll(m_glyphCaches); m_glyphCaches.clear(); - releaseGlyphCacheResourceUpdates(); + resetGlyphCacheResources(); m_rhi = nullptr; @@ -264,12 +264,23 @@ QRhiResourceUpdateBatch *QSGDefaultRenderContext::glyphCacheResourceUpdates() return m_glyphCacheResourceUpdates; } -void QSGDefaultRenderContext::releaseGlyphCacheResourceUpdates() +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 diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h index 448255a594..580a973e85 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -24,6 +24,7 @@ class QRhi; class QRhiCommandBuffer; class QRhiRenderPassDescriptor; class QRhiResourceUpdateBatch; +class QRhiTexture; class QSGMaterialShader; class QSurface; @@ -102,7 +103,8 @@ public: QRhiResourceUpdateBatch *maybeGlyphCacheResourceUpdates(); QRhiResourceUpdateBatch *glyphCacheResourceUpdates(); - void releaseGlyphCacheResourceUpdates(); + void deferredReleaseGlyphCacheTexture(QRhiTexture *texture); + void resetGlyphCacheResources(); protected: static QString fontKey(const QRawFont &font, int renderTypeQuality); @@ -116,6 +118,7 @@ protected: qreal m_currentDevicePixelRatio; bool m_useDepthBufferFor2D; QRhiResourceUpdateBatch *m_glyphCacheResourceUpdates; + QSet<QRhiTexture *> m_pendingGlyphCacheTextures; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp index bff5d0404d..64f862f948 100644 --- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp +++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp @@ -101,11 +101,11 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR m_glyph_cache->populate(glyphs.glyphIndexes()); const QVector<quint32> glyphIndexes = m_glyphs.glyphIndexes(); - for (int i = 0; i < glyphIndexes.count(); ++i) + for (int i = 0; i < glyphIndexes.size(); ++i) m_allGlyphIndexesLookup.insert(glyphIndexes.at(i)); qCDebug(lcSgText, "inserting %" PRIdQSIZETYPE " glyphs, %" PRIdQSIZETYPE " unique", - glyphIndexes.count(), - m_allGlyphIndexesLookup.count()); + glyphIndexes.size(), + m_allGlyphIndexesLookup.size()); #ifdef QSG_RUNTIME_DESCRIPTION qsgnode_set_description(this, QString::number(glyphs.glyphIndexes().count()) + QStringLiteral(" DF glyphs: ") + m_glyphs.rawFont().familyName() + QStringLiteral(" ") + QString::number(m_glyphs.rawFont().pixelSize())); @@ -147,7 +147,7 @@ void QSGDistanceFieldGlyphNode::invalidateGlyphs(const QVector<quint32> &glyphs) if (m_dirtyGeometry) return; - for (int i = 0; i < glyphs.count(); ++i) { + for (int i = 0; i < glyphs.size(); ++i) { if (m_allGlyphIndexesLookup.contains(glyphs.at(i))) { m_dirtyGeometry = true; setFlag(UsePreprocess); @@ -289,12 +289,12 @@ void QSGDistanceFieldGlyphNode::updateGeometry() Q_ASSERT(m_glyphsInOtherTextures.isEmpty()); } else { if (!m_glyphsInOtherTextures.isEmpty()) - qCDebug(lcSgText, "%" PRIdQSIZETYPE " 'other' textures", m_glyphsInOtherTextures.count()); + qCDebug(lcSgText, "%" PRIdQSIZETYPE " 'other' textures", m_glyphsInOtherTextures.size()); QHash<const QSGDistanceFieldGlyphCache::Texture *, GlyphInfo>::const_iterator ite = m_glyphsInOtherTextures.constBegin(); while (ite != m_glyphsInOtherTextures.constEnd()) { QGlyphRun subNodeGlyphRun(m_glyphs); - for (int i = 0; i < ite->indexes.count(); i += maxIndexCount) { - int len = qMin(maxIndexCount, ite->indexes.count() - i); + for (int i = 0; i < ite->indexes.size(); i += maxIndexCount) { + int len = qMin(maxIndexCount, ite->indexes.size() - i); subNodeGlyphRun.setRawData(ite->indexes.constData() + i, ite->positions.constData() + i, len); qCDebug(lcSgText) << "subNodeGlyphRun has" << len << "positions:" << *(ite->positions.constData() + i) << "->" << *(ite->positions.constData() + i + len - 1); diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 5545ea05d9..6dee0304ab 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -329,7 +329,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) d->cleanupNodesOnShutdown(); #if QT_CONFIG(quick_shadereffect) - QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); + QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window); #endif if (m_windows.size() == 0) { diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp index abd0f9c790..54cf298943 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp @@ -32,19 +32,10 @@ QSGRhiDistanceFieldGlyphCache::QSGRhiDistanceFieldGlyphCache(QSGDefaultRenderCon QSGRhiDistanceFieldGlyphCache::~QSGRhiDistanceFieldGlyphCache() { - // A plain delete should work, but just in case commitResourceUpdates was - // not called and something is enqueued on the update batch for a texture, - // defer until the end of the frame. - for (int i = 0; i < m_textures.count(); ++i) { - if (m_textures[i].texture) - m_textures[i].texture->deleteLater(); - } + for (const TextureInfo &t : std::as_const(m_textures)) + m_rc->deferredReleaseGlyphCacheTexture(t.texture); delete m_areaAllocator; - - // should be empty, but just in case - for (QRhiTexture *t : qAsConst(m_pendingDispose)) - t->deleteLater(); } void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) @@ -113,7 +104,7 @@ void QSGRhiDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs) bool QSGRhiDistanceFieldGlyphCache::isActive() const { - return m_unusedGlyphs.size() != m_glyphsTexture.size(); + return !m_referencedGlyphs.empty(); } void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyphs) @@ -176,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; } @@ -241,7 +234,7 @@ void QSGRhiDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int widt resourceUpdates->copyTexture(texInfo->texture, oldTexture); } - m_pendingDispose.insert(oldTexture); + m_rc->deferredReleaseGlyphCacheTexture(oldTexture); } bool QSGRhiDistanceFieldGlyphCache::useTextureResizeWorkaround() const @@ -520,14 +513,8 @@ void QSGRhiDistanceFieldGlyphCache::commitResourceUpdates(QRhiResourceUpdateBatc { if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) { mergeInto->merge(resourceUpdates); - m_rc->releaseGlyphCacheResourceUpdates(); + m_rc->resetGlyphCacheResources(); } - - // now let's assume the resource updates will be committed in this frame - for (QRhiTexture *t : qAsConst(m_pendingDispose)) - t->deleteLater(); // will be deleted after the frame is submitted -> safe - - m_pendingDispose.clear(); } bool QSGRhiDistanceFieldGlyphCache::eightBitFormatIsAlphaSwizzled() const diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h index aed2739c89..b7653881f5 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h @@ -71,7 +71,7 @@ private: TextureInfo *textureInfo(int index) { - for (int i = m_textures.count(); i <= index; ++i) { + for (int i = m_textures.size(); i <= index; ++i) { if (createFullSizeTextures()) m_textures.append(QRect(0, 0, maxTextureSize(), maxTextureSize())); else @@ -89,6 +89,7 @@ private: QList<TextureInfo> m_textures; QHash<glyph_t, TextureInfo *> m_glyphsTexture; QSet<glyph_t> m_unusedGlyphs; + QSet<glyph_t> m_referencedGlyphs; QSet<QRhiTexture *> m_pendingDispose; }; diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp index e831c97a80..e7c2b0fb0d 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp +++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp @@ -11,6 +11,7 @@ #include <QQmlFile> #include <QFile> #include <QFileSelector> +#include <QMutexLocker> QT_BEGIN_NAMESPACE @@ -27,14 +28,18 @@ void QSGRhiShaderLinker::reset(const QShader &vs, const QShader &fs) m_samplers.clear(); m_samplerNameMap.clear(); m_subRectBindings.clear(); + + m_constants.reserve(8); + m_samplers.reserve(4); + m_samplerNameMap.reserve(4); } void QSGRhiShaderLinker::feedConstants(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices) { - Q_ASSERT(shader.shaderInfo.variables.count() == shader.varData.count()); + Q_ASSERT(shader.shaderInfo.variables.size() == shader.varData.size()); if (!dirtyIndices) { m_constantBufferSize = qMax(m_constantBufferSize, shader.shaderInfo.constantDataSize); - for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) { + for (int i = 0; i < shader.shaderInfo.variables.size(); ++i) { const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(i)); if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Constant) { const QSGShaderEffectNode::VariableData &vd(shader.varData.at(i)); @@ -75,11 +80,17 @@ void QSGRhiShaderLinker::feedConstants(const QSGShaderEffectNode::ShaderData &sh void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &shader, const QSet<int> *dirtyIndices) { if (!dirtyIndices) { - for (int i = 0; i < shader.shaderInfo.variables.count(); ++i) { + for (int i = 0; i < shader.shaderInfo.variables.size(); ++i) { const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(i)); const QSGShaderEffectNode::VariableData &vd(shader.varData.at(i)); if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler) { Q_ASSERT(vd.specialType == QSGShaderEffectNode::VariableData::Source); + +#ifndef QT_NO_DEBUG + int existingBindPoint = m_samplerNameMap.value(var.name, -1); + Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint); +#endif + m_samplers.insert(var.bindPoint, vd.value); m_samplerNameMap.insert(var.name, var.bindPoint); } @@ -88,6 +99,12 @@ void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &sha for (int idx : *dirtyIndices) { const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(idx)); const QSGShaderEffectNode::VariableData &vd(shader.varData.at(idx)); + +#ifndef QT_NO_DEBUG + int existingBindPoint = m_samplerNameMap.value(var.name, -1); + Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint); +#endif + m_samplers.insert(var.bindPoint, vd.value); m_samplerNameMap.insert(var.name, var.bindPoint); } @@ -142,11 +159,18 @@ struct QSGRhiShaderMaterialTypeCache void reset() { qDeleteAll(m_types); m_types.clear(); } struct Key { - QShader blob[2]; - Key() { } - Key(const QShader &vs, const QShader &fs) { blob[0] = vs; blob[1] = fs; } + QShader vs; + QShader fs; + size_t hash; + Key(const QShader &vs, const QShader &fs) + : vs(vs), + fs(fs) + { + QtPrivate::QHashCombine hashGen; + hash = hashGen(hashGen(0, vs), fs); + } bool operator==(const Key &other) const { - return blob[0] == other.blob[0] && blob[1] == other.blob[1]; + return vs == other.vs && fs == other.fs; } }; QHash<Key, QSGMaterialType *> m_types; @@ -154,10 +178,7 @@ struct QSGRhiShaderMaterialTypeCache size_t qHash(const QSGRhiShaderMaterialTypeCache::Key &key, size_t seed = 0) { - size_t hash = seed; - for (int i = 0; i < 2; ++i) - hash = hash * 31337 + qHash(key.blob[i]); - return hash; + return seed ^ key.hash; } QSGMaterialType *QSGRhiShaderMaterialTypeCache::get(const QShader &vs, const QShader &fs) @@ -171,7 +192,8 @@ QSGMaterialType *QSGRhiShaderMaterialTypeCache::get(const QShader &vs, const QSh return t; } -static QSGRhiShaderMaterialTypeCache shaderMaterialTypeCache; +static QHash<void *, QSGRhiShaderMaterialTypeCache> shaderMaterialTypeCache; +static QMutex shaderMaterialTypeCacheMutex; class QSGRhiShaderEffectMaterialShader : public QSGMaterialShader { @@ -447,7 +469,7 @@ int QSGRhiShaderEffectMaterial::compare(const QSGMaterial *other) const if (int diff = m_cullMode - o->m_cullMode) return diff; - if (int diff = m_textureProviders.count() - o->m_textureProviders.count()) + if (int diff = m_textureProviders.size() - o->m_textureProviders.size()) return diff; if (m_linker.m_constants != o->m_linker.m_constants) @@ -459,7 +481,7 @@ int QSGRhiShaderEffectMaterial::compare(const QSGMaterial *other) const if (hasAtlasTexture(o->m_textureProviders) && !o->m_geometryUsesTextureSubRect) return 1; - for (int binding = 0, count = m_textureProviders.count(); binding != count; ++binding) { + for (int binding = 0, count = m_textureProviders.size(); binding != count; ++binding) { QSGTextureProvider *tp1 = m_textureProviders.at(binding); QSGTextureProvider *tp2 = o->m_textureProviders.at(binding); if (tp1 && tp2) { @@ -559,7 +581,7 @@ QRectF QSGRhiShaderEffectNode::updateNormalizedTextureSubRect(bool supportsAtlas bool geometryUsesTextureSubRect = false; if (supportsAtlasTextures) { QSGTextureProvider *tp = nullptr; - for (int binding = 0, count = m_material.m_textureProviders.count(); binding != count; ++binding) { + for (int binding = 0, count = m_material.m_textureProviders.size(); binding != count; ++binding) { if (QSGTextureProvider *candidate = m_material.m_textureProviders.at(binding)) { if (!tp) { tp = candidate; @@ -627,7 +649,12 @@ void QSGRhiShaderEffectNode::syncMaterial(SyncData *syncData) m_material.m_fragmentShader = defaultFragmentShader; } - m_material.m_materialType = shaderMaterialTypeCache.get(m_material.m_vertexShader, m_material.m_fragmentShader); + { + QMutexLocker lock(&shaderMaterialTypeCacheMutex); + m_material.m_materialType = shaderMaterialTypeCache[syncData->materialTypeCacheKey].get(m_material.m_vertexShader, + m_material.m_fragmentShader); + } + m_material.m_linker.reset(m_material.m_vertexShader, m_material.m_fragmentShader); if (m_material.m_hasCustomVertexShader) { @@ -675,7 +702,7 @@ void QSGRhiShaderEffectNode::syncMaterial(SyncData *syncData) v.bindPoint = 1; v.type = QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler; defaultSD.shaderInfo.variables.append(v); - for (const QSGShaderEffectNode::VariableData &extVarData : qAsConst(syncData->fragment.shader->varData)) { + for (const QSGShaderEffectNode::VariableData &extVarData : std::as_const(syncData->fragment.shader->varData)) { if (extVarData.specialType == QSGShaderEffectNode::VariableData::Source) { vd.value = extVarData.value; break; @@ -745,9 +772,10 @@ void QSGRhiShaderEffectNode::preprocess() } } -void QSGRhiShaderEffectNode::cleanupMaterialTypeCache() +void QSGRhiShaderEffectNode::cleanupMaterialTypeCache(void *materialTypeCacheKey) { - shaderMaterialTypeCache.reset(); + QMutexLocker lock(&shaderMaterialTypeCacheMutex); + shaderMaterialTypeCache[materialTypeCacheKey].reset(); } bool QSGRhiGuiThreadShaderEffectManager::hasSeparateSamplerAndTextureObjects() const @@ -818,7 +846,7 @@ bool QSGRhiGuiThreadShaderEffectManager::reflect(ShaderInfo *result) int ubufBinding = -1; const QVector<QShaderDescription::UniformBlock> ubufs = desc.uniformBlocks(); - const int ubufCount = ubufs.count(); + const int ubufCount = ubufs.size(); for (int i = 0; i < ubufCount; ++i) { const QShaderDescription::UniformBlock &ubuf(ubufs[i]); if (ubufBinding == -1 && ubuf.binding >= 0) { @@ -839,7 +867,7 @@ bool QSGRhiGuiThreadShaderEffectManager::reflect(ShaderInfo *result) } const QVector<QShaderDescription::InOutVariable> combinedImageSamplers = desc.combinedImageSamplers(); - const int samplerCount = combinedImageSamplers.count(); + const int samplerCount = combinedImageSamplers.size(); for (int i = 0; i < samplerCount; ++i) { const QShaderDescription::InOutVariable &combinedImageSampler(combinedImageSamplers[i]); ShaderInfo::Variable v; diff --git a/src/quick/scenegraph/qsgrhishadereffectnode_p.h b/src/quick/scenegraph/qsgrhishadereffectnode_p.h index a901a6651e..b606871af6 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode_p.h +++ b/src/quick/scenegraph/qsgrhishadereffectnode_p.h @@ -99,7 +99,7 @@ public: void syncMaterial(SyncData *syncData) override; void preprocess() override; - static void cleanupMaterialTypeCache(); + static void cleanupMaterialTypeCache(void *materialTypeCacheKey); private Q_SLOTS: void handleTextureChange(); diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp index ede98e865a..d37786901c 100644 --- a/src/quick/scenegraph/qsgrhisupport.cpp +++ b/src/quick/scenegraph/qsgrhisupport.cpp @@ -883,7 +883,7 @@ int QSGRhiSupport::chooseSampleCount(int samples, QRhi *rhi) const QVector<int> supportedSampleCounts = rhi->supportedSampleCounts(); if (!supportedSampleCounts.contains(msaaSampleCount)) { int reducedSampleCount = 1; - for (int i = supportedSampleCounts.count() - 1; i >= 0; --i) { + for (int i = supportedSampleCounts.size() - 1; i >= 0; --i) { if (supportedSampleCounts[i] <= msaaSampleCount) { reducedSampleCount = supportedSampleCounts[i]; break; diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp index a2d7de9a0a..9fe1b2ad01 100644 --- a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp @@ -23,15 +23,7 @@ QSGRhiTextureGlyphCache::QSGRhiTextureGlyphCache(QSGDefaultRenderContext *rc, QSGRhiTextureGlyphCache::~QSGRhiTextureGlyphCache() { - // A plain delete should work, but just in case commitResourceUpdates was - // not called and something is enqueued on the update batch for m_texture, - // defer until the end of the frame. - if (m_texture) - m_texture->deleteLater(); - - // should be empty, but just in case - for (QRhiTexture *t : qAsConst(m_pendingDispose)) - t->deleteLater(); + m_rc->deferredReleaseGlyphCacheTexture(m_texture); } QRhiTexture *QSGRhiTextureGlyphCache::createEmptyTexture(QRhiTexture::Format format) @@ -97,7 +89,7 @@ void QSGRhiTextureGlyphCache::resizeTextureData(int width, int height) resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc)); } - m_pendingDispose.insert(m_texture); + m_rc->deferredReleaseGlyphCacheTexture(m_texture); m_texture = t; } } @@ -197,7 +189,10 @@ void QSGRhiTextureGlyphCache::endFillTexture() int QSGRhiTextureGlyphCache::glyphPadding() const { - return 1; + if (m_format == QFontEngine::Format_Mono) + return 8; + else + return 1; } int QSGRhiTextureGlyphCache::maxTextureWidth() const @@ -217,14 +212,8 @@ void QSGRhiTextureGlyphCache::commitResourceUpdates(QRhiResourceUpdateBatch *mer { if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) { mergeInto->merge(resourceUpdates); - m_rc->releaseGlyphCacheResourceUpdates(); + m_rc->resetGlyphCacheResources(); } - - // now let's assume the resource updates will be committed in this frame - for (QRhiTexture *t : qAsConst(m_pendingDispose)) - t->deleteLater(); // will be deleted after the frame is submitted -> safe - - m_pendingDispose.clear(); } bool QSGRhiTextureGlyphCache::eightBitFormatIsAlphaSwizzled() const diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h index 2960c91b01..3c6b99bc9f 100644 --- a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h +++ b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h @@ -60,7 +60,6 @@ private: QSize m_size; bool m_bgra = false; QVarLengthArray<QRhiTextureUploadEntry, 16> m_uploads; - QSet<QRhiTexture *> m_pendingDispose; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index e20ded6c5a..c9b7ca2084 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -476,7 +476,7 @@ void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor if (wipeSG) { dd->cleanupNodesOnShutdown(); #if QT_CONFIG(quick_shadereffect) - QSGRhiShaderEffectNode::cleanupMaterialTypeCache(); + QSGRhiShaderEffectNode::cleanupMaterialTypeCache(window); #endif } else { qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent SG, avoiding cleanup"); @@ -505,6 +505,7 @@ void QSGRenderThread::invalidateGraphics(QQuickWindow *window, bool inDestructor if (ownRhi) QSGRhiSupport::instance()->destroyRhi(rhi); rhi = nullptr; + dd->rhi = nullptr; qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- QRhi destroyed"); } else { qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent GL, avoiding cleanup"); |