diff options
Diffstat (limited to 'src/quick/scenegraph')
94 files changed, 584 insertions, 432 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index 7b5ee66df6..f1d0e28fc8 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -206,12 +206,12 @@ QSGRendererInterface::ShaderType QSGSoftwareContext::shaderType() const QSGRendererInterface::ShaderCompilationTypes QSGSoftwareContext::shaderCompilationType() const { - return nullptr; + return {}; } QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() const { - return nullptr; + return {}; } void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp index dd789b78c7..04e9b361ca 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qsgsoftwareglyphnode_p.h" +#include <QtGui/private/qrawfont_p.h> QT_BEGIN_NAMESPACE @@ -52,28 +53,38 @@ QSGSoftwareGlyphNode::QSGSoftwareGlyphNode() namespace { QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs) { - qreal minX = 0; - qreal minY = 0; - qreal maxX = 0; - qreal maxY = 0; + QFixed minX; + QFixed minY; + QFixed maxX; + QFixed maxY; - for (int i = 0, n = qMin(glyphs.glyphIndexes().size(), glyphs.positions().size()); i < n; ++i) { - QRectF glyphRect = glyphs.rawFont().boundingRect(glyphs.glyphIndexes()[i]); - glyphRect.translate(glyphs.positions()[i]); + QRawFontPrivate *rawFontD = QRawFontPrivate::get(glyphs.rawFont()); + QFontEngine *fontEngine = rawFontD->fontEngine; + + QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : QFontEngine::Format_A32; + + const QVector<uint> glyphIndexes = glyphs.glyphIndexes(); + const QVector<QPointF> glyphPositions = glyphs.positions(); + for (int i = 0, n = qMin(glyphIndexes.size(), glyphPositions.size()); i < n; ++i) { + glyph_metrics_t gm = fontEngine->alphaMapBoundingBox(glyphIndexes.at(i), QFixed(), QTransform(), glyphFormat); + + gm.x += QFixed::fromReal(glyphPositions.at(i).x()); + gm.y += QFixed::fromReal(glyphPositions.at(i).y()); if (i == 0) { - minX = glyphRect.left(); - minY = glyphRect.top(); - maxX = glyphRect.right(); - maxY = glyphRect.bottom(); + minX = gm.x; + minY = gm.y; + maxX = gm.x + gm.width; + maxY = gm.y + gm.height; } else { - minX = qMin(glyphRect.left(), minX); - minY = qMin(glyphRect.top(), minY); - maxX = qMax(glyphRect.right(),maxX); - maxY = qMax(glyphRect.bottom(), maxY); + minX = qMin(gm.x, minX); + minY = qMin(gm.y, minY); + maxX = qMax(gm.x + gm.width, maxX); + maxY = qMax(gm.y + gm.height, maxY); } } - QRectF boundingRect(QPointF(minX, minY), QPointF(maxX, maxY)); + + QRectF boundingRect(QPointF(minX.toReal(), minY.toReal()), QPointF(maxX.toReal(), maxY.toReal())); return boundingRect.translated(position - QPointF(0.0, glyphs.rawFont().ascent())); } } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp index da5d39db20..214f7d790b 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp @@ -465,7 +465,7 @@ void QSGSoftwareInternalImageNode::paint(QPainter *painter) m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom()); QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height())); QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()), - margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr)); + margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{}); return; } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp index 141d8f3c6d..a10a94125c 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp @@ -205,7 +205,7 @@ void QSGSoftwareNinePatchNode::paint(QPainter *painter) painter->drawPixmap(m_bounds, m_pixmap, QRectF(0, 0, m_pixmap.width(), m_pixmap.height())); else QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_bounds.toRect(), m_margins, m_pixmap, QRect(0, 0, m_pixmap.width(), m_pixmap.height()), - m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints(nullptr)); + m_margins, Qt::StretchTile, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{}); } QRectF QSGSoftwareNinePatchNode::bounds() const diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index c97dcb9326..c010e0cae5 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -52,6 +52,8 @@ #include <QtGui/QBackingStore> +#include <qtquick_tracepoints_p.h> + QT_BEGIN_NAMESPACE QSGSoftwareRenderLoop::QSGSoftwareRenderLoop() @@ -133,20 +135,25 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) if (!m_windows.contains(window)) return; } + + Q_TRACE_SCOPE(QSG_renderWindow) QElapsedTimer renderTimer; qint64 renderTime = 0, syncTime = 0, polishTime = 0; bool profileFrames = QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled(); if (profileFrames) renderTimer.start(); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame); + Q_TRACE(QSG_polishItems_entry); cd->polishItems(); if (profileFrames) polishTime = renderTimer.nsecsElapsed(); + Q_TRACE(QSG_polishItems_exit); Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame, QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphPolishPolish); + Q_TRACE(QSG_sync_entry); emit window->afterAnimating(); @@ -155,8 +162,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) if (profileFrames) syncTime = renderTimer.nsecsElapsed(); + Q_TRACE(QSG_sync_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSync); + Q_TRACE(QSG_render_entry); //Tell the renderer about the windows backing store auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer); @@ -167,8 +176,10 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) if (profileFrames) renderTime = renderTimer.nsecsElapsed(); + Q_TRACE(QSG_render_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopRender); + Q_TRACE(QSG_swap_entry); if (data.grabOnly) { grabContent = m_backingStores[window]->handle()->toImage(); @@ -187,6 +198,7 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window, bool isNewExpose) qint64 swapTime = 0; if (profileFrames) swapTime = renderTimer.nsecsElapsed(); + Q_TRACE(QSG_swap_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSwap); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index c6b463bb02..f07cc28827 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -60,6 +60,8 @@ #include <QtGui/QBackingStore> #include <QtQuick/QQuickWindow> +#include <qtquick_tracepoints_p.h> + QT_BEGIN_NAMESPACE // Passed from the RL to the RT when a window is removed obscured and should be @@ -457,6 +459,8 @@ void QSGSoftwareRenderThread::sync(bool inExpose) void QSGSoftwareRenderThread::syncAndRender() { + Q_TRACE_SCOPE(QSG_syncAndRender); + Q_TRACE(QSG_sync_entry); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame); QElapsedTimer waitTimer; @@ -475,6 +479,7 @@ void QSGSoftwareRenderThread::syncAndRender() if (syncRequested) sync(exposeRequested); + Q_TRACE(QSG_sync_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSync); @@ -487,6 +492,7 @@ void QSGSoftwareRenderThread::syncAndRender() } qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - rendering started"); + Q_TRACE(QSG_render_entry); if (rtAnim->isRunning()) { wd->animationController->lock(); @@ -502,8 +508,10 @@ void QSGSoftwareRenderThread::syncAndRender() softwareRenderer->setBackingStore(backingStore); wd->renderSceneGraph(exposedWindow->size()); + Q_TRACE(QSG_render_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopRender); + Q_TRACE(QSG_swap_entry); if (softwareRenderer && (!wd->customRenderStage || !wd->customRenderStage->swap())) backingStore->flush(softwareRenderer->flushRegion()); @@ -519,8 +527,10 @@ void QSGSoftwareRenderThread::syncAndRender() wd->fireFrameSwapped(); } else { + Q_TRACE(QSG_render_exit); Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSync, 1); + Q_TRACE(QSG_swap_entry); qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - window not ready, skipping render"); } @@ -532,6 +542,7 @@ void QSGSoftwareRenderThread::syncAndRender() mutex.unlock(); } + Q_TRACE(QSG_swap_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSwap); } @@ -947,13 +958,18 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop: return; } + Q_TRACE_SCOPE(QSG_polishAndSync); + + Q_TRACE(QSG_polishItems_entry); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync); QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window); wd->polishItems(); + Q_TRACE(QSG_polishItems_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncPolish); + Q_TRACE(QSG_sync_entry); w->updateDuringSync = false; @@ -967,15 +983,19 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop: qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - wait for sync"); + Q_TRACE(QSG_sync_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncWait); + Q_TRACE(QSG_wait_entry); w->thread->waitCondition.wait(&w->thread->mutex); lockedForSync = false; w->thread->mutex.unlock(); qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - unlock after sync"); + Q_TRACE(QSG_wait_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncSync); + Q_TRACE(QSG_animations_entry); if (!animationTimer && m_anim->isRunning()) { qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - advancing animations"); @@ -987,6 +1007,7 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop: w->window->requestUpdate(); } + Q_TRACE(QSG_animations_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncAnimations); } diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp index 1a8bddaa6e..65abb2a1af 100644 --- a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp +++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp @@ -296,7 +296,7 @@ void QSGCompressedTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdate return; } - QRhiTexture::Flags texFlags = 0; + QRhiTexture::Flags texFlags; if (fmt.second) texFlags |= QRhiTexture::sRGB; diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h index 1594352dab..258a5fed14 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h @@ -72,6 +72,10 @@ public: ~QSGAbstractRenderer() override; + // just have a warning about becoming private, ifdefing the whole class is not feasible +#if QT_DEPRECATED_SINCE(5, 15) + QT_DEPRECATED_X("QSGAbstractRenderer is no longer going to be public in Qt 6.0. QSGEngine-based workflows are expected to migrate to QQuickRenderControl instead.") +#endif void setRootNode(QSGRootNode *node); QSGRootNode *rootNode() const; void setDeviceRect(const QRect &rect); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 34027cbac7..ce3c4aac4f 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -62,6 +62,8 @@ #include "qsgopenglvisualizer_p.h" #include "qsgrhivisualizer_p.h" +#include <qtquick_tracepoints_p.h> + #include <algorithm> #ifndef GL_DOUBLE @@ -270,6 +272,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material, boo return nullptr; } + Q_TRACE_SCOPE(QSG_prepareMaterial); if (QSG_LOG_TIME_COMPILATION().isDebugEnabled()) qsg_renderer_timer.start(); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame); @@ -332,6 +335,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate return nullptr; } + Q_TRACE_SCOPE(QSG_prepareMaterial); if (QSG_LOG_TIME_COMPILATION().isDebugEnabled()) qsg_renderer_timer.start(); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame); @@ -379,6 +383,9 @@ void ShaderManager::invalidated() qDeleteAll(srbCache); srbCache.clear(); + + qDeleteAll(pipelineCache); + pipelineCache.clear(); } void ShaderManager::clearCachedRendererData() @@ -447,13 +454,13 @@ void qsg_dumpShadowRoots(Node *n) QByteArray ind(indent, ' '); if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) { - qDebug() << ind.constData() << "[X]" << n->sgNode << hex << uint(n->sgNode->flags()); + qDebug() << ind.constData() << "[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags()); qsg_dumpShadowRoots(n->rootInfo(), indent); } else { QDebug d = qDebug(); - d << ind.constData() << "[ ]" << n->sgNode << hex << uint(n->sgNode->flags()); + d << ind.constData() << "[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags()); if (n->type() == QSGNode::GeometryNodeType) - d << "order" << dec << n->element()->order; + d << "order" << Qt::dec << n->element()->order; } SHADOWNODE_TRAVERSE(n) @@ -546,7 +553,7 @@ void Updater::visitNode(Node *n) m_added = count; m_force_update = force; - n->dirtyState = nullptr; + n->dirtyState = {}; } void Updater::visitClipNode(Node *n) @@ -1024,6 +1031,7 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx) ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream"))); } + static const bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); if (!m_rhi) { // If rendering with an OpenGL Core profile context, we need to create a VAO // to hold our vertex specification state. @@ -1031,9 +1039,9 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx) m_vao = new QOpenGLVertexArrayObject(this); m_vao->create(); } - - bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); m_useDepthBuffer = useDepth && ctx->openglContext()->format().depthBufferSize() > 0; + } else { + m_useDepthBuffer = useDepth; } } @@ -1103,13 +1111,9 @@ void Renderer::destroyGraphicsResources() // are going to destroy. m_shaderManager->clearCachedRendererData(); - qDeleteAll(m_pipelines); qDeleteAll(m_samplers); - m_stencilClipCommon.reset(); - delete m_dummyTexture; - m_visualizer->releaseResources(); } @@ -1119,7 +1123,6 @@ void Renderer::releaseCachedResources() destroyGraphicsResources(); - m_pipelines.clear(); m_samplers.clear(); m_dummyTexture = nullptr; @@ -1399,12 +1402,11 @@ void Renderer::nodeWasRemoved(Node *node) m_elementsToDelete.add(e); if (m_renderNodeElements.isEmpty()) { - if (m_rhi) { - m_useDepthBuffer = true; - } else { - static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); + static const bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); + if (m_rhi) + m_useDepthBuffer = useDepth; + else m_useDepthBuffer = useDepth && m_context->openglContext()->format().depthBufferSize() > 0; - } } } } @@ -2339,7 +2341,7 @@ void Renderer::uploadBatch(Batch *b) iDump << " -- Index Data, count:" << b->indexCount; for (int i=0; i<b->indexCount; ++i) { if ((i % 24) == 0) - iDump << endl << " --- "; + iDump << Qt::endl << " --- "; iDump << id[i]; } } @@ -2352,7 +2354,7 @@ void Renderer::uploadBatch(Batch *b) iDump << " -- Index Data, count:" << b->indexCount; for (int i=0; i<b->indexCount; ++i) { if ((i % 24) == 0) - iDump << endl << " --- "; + iDump << Qt::endl << " --- "; iDump << id[i]; } } @@ -2627,7 +2629,7 @@ QRhiGraphicsPipeline *Renderer::buildStencilPipeline(const Batch *batch, bool fi QRhiGraphicsPipeline *ps = m_rhi->newGraphicsPipeline(); ps->setFlags(QRhiGraphicsPipeline::UsesStencilRef); QRhiGraphicsPipeline::TargetBlend blend; - blend.colorWrite = 0; + blend.colorWrite = {}; ps->setTargetBlends({ blend }); ps->setSampleCount(renderTarget()->sampleCount()); ps->setStencilTest(true); @@ -3237,15 +3239,17 @@ static inline bool needsBlendConstant(QRhiGraphicsPipeline::BlendFactor f) bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms) // RHI only, [prepare step] { - // In unmerged batches the srbs in the elements are all compatible layout-wise. + // In unmerged batches the srbs in the elements are all compatible + // layout-wise. Note the key's == and qHash implementations: the rp desc and + // srb are tested for (layout) compatibility, not pointer equality. const GraphicsPipelineStateKey k { m_gstate, sms, renderPassDescriptor(), e->srb }; // Note: dynamic state (viewport rect, scissor rect, stencil ref, blend // constant) is never a part of GraphicsState/QRhiGraphicsPipeline. // See if there is an existing, matching pipeline state object. - auto it = m_pipelines.constFind(k); - if (it != m_pipelines.constEnd()) { + auto it = m_shaderManager->pipelineCache.constFind(k); + if (it != m_shaderManager->pipelineCache.constEnd()) { e->ps = *it; return true; } @@ -3257,7 +3261,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms) ps->setShaderResourceBindings(e->srb); ps->setRenderPassDescriptor(renderPassDescriptor()); - QRhiGraphicsPipeline::Flags flags = 0; + QRhiGraphicsPipeline::Flags flags; if (needsBlendConstant(m_gstate.srcColor) || needsBlendConstant(m_gstate.dstColor)) flags |= QRhiGraphicsPipeline::UsesBlendConstants; if (m_gstate.usesScissor) @@ -3302,7 +3306,7 @@ bool Renderer::ensurePipelineState(Element *e, const ShaderManager::Shader *sms) return false; } - m_pipelines.insert(k, ps); + m_shaderManager->pipelineCache.insert(k, ps); e->ps = ps; return true; } @@ -3713,7 +3717,7 @@ void Renderer::renderMergedBatch(PreparedRenderBatch *renderBatch) // split prep { batch->vbo.buf, quint32(draw.vertices) }, { batch->vbo.buf, quint32(draw.zorders) } }; - cb->setVertexInput(VERTEX_BUFFER_BINDING, 2, vbufBindings, + cb->setVertexInput(VERTEX_BUFFER_BINDING, m_useDepthBuffer ? 2 : 1, vbufBindings, batch->ibo.buf, draw.indices, m_uint32IndexForRhi ? QRhiCommandBuffer::IndexUInt32 : QRhiCommandBuffer::IndexUInt16); cb->drawIndexed(draw.indexCount); @@ -3957,8 +3961,8 @@ void Renderer::setGraphicsPipeline(QRhiCommandBuffer *cb, const Batch *batch, El void Renderer::renderBatches() { if (Q_UNLIKELY(debug_render())) { - qDebug().nospace() << "Rendering:" << endl - << " -> Opaque: " << qsg_countNodesInBatches(m_opaqueBatches) << " nodes in " << m_opaqueBatches.size() << " batches..." << endl + qDebug().nospace() << "Rendering:" << Qt::endl + << " -> Opaque: " << qsg_countNodesInBatches(m_opaqueBatches) << " nodes in " << m_opaqueBatches.size() << " batches..." << Qt::endl << " -> Alpha: " << qsg_countNodesInBatches(m_alphaBatches) << " nodes in " << m_alphaBatches.size() << " batches..."; } @@ -4049,8 +4053,8 @@ void Renderer::renderBatches() m_pstate.viewportSet = false; m_pstate.scissorSet = false; - m_gstate.depthTest = true; - m_gstate.depthWrite = true; + m_gstate.depthTest = m_useDepthBuffer; + m_gstate.depthWrite = m_useDepthBuffer; m_gstate.depthFunc = QRhiGraphicsPipeline::Less; m_gstate.blending = false; @@ -4082,8 +4086,8 @@ void Renderer::renderBatches() m_gstate.blending = true; // factors never change, always set for premultiplied alpha based blending - // depth test stays enabled but no need to write out depth from the - // transparent (back-to-front) pass + // depth test stays enabled (if m_useDepthBuffer, that is) but no need + // to write out depth from the transparent (back-to-front) pass m_gstate.depthWrite = false; QVarLengthArray<PreparedRenderBatch, 64> alphaRenderBatches; @@ -4504,6 +4508,35 @@ bool Renderer::prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBat updateClipState(rd->m_clip_list, batch); + QSGNode *xform = e->renderNode->parent(); + QMatrix4x4 matrix; + QSGNode *root = rootNode(); + if (e->root) { + matrix = qsg_matrixForRoot(e->root); + root = e->root->sgNode; + } + while (xform != root) { + if (xform->type() == QSGNode::TransformNodeType) { + matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix(); + break; + } + xform = xform->parent(); + } + rd->m_matrix = &matrix; + + QSGNode *opacity = e->renderNode->parent(); + rd->m_opacity = 1.0; + while (opacity != rootNode()) { + if (opacity->type() == QSGNode::OpacityNodeType) { + rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity(); + break; + } + opacity = opacity->parent(); + } + + if (rd->m_prepareCallback) + rd->m_prepareCallback(); + renderBatch->batch = batch; renderBatch->sms = nullptr; @@ -4532,38 +4565,15 @@ void Renderer::renderRhiRenderNode(const Batch *batch) // split prepare-render ( state.m_scissorEnabled = batch->clipState.type & ClipState::ScissorClip; state.m_stencilEnabled = batch->clipState.type & ClipState::StencilClip; - QSGNode *xform = e->renderNode->parent(); - QMatrix4x4 matrix; - QSGNode *root = rootNode(); - if (e->root) { - matrix = qsg_matrixForRoot(e->root); - root = e->root->sgNode; - } - while (xform != root) { - if (xform->type() == QSGNode::TransformNodeType) { - matrix = matrix * static_cast<QSGTransformNode *>(xform)->combinedMatrix(); - break; - } - xform = xform->parent(); - } - rd->m_matrix = &matrix; - - QSGNode *opacity = e->renderNode->parent(); - rd->m_opacity = 1.0; - while (opacity != rootNode()) { - if (opacity->type() == QSGNode::OpacityNodeType) { - rd->m_opacity = static_cast<QSGOpacityNode *>(opacity)->combinedOpacity(); - break; - } - opacity = opacity->parent(); - } - const QSGRenderNode::StateFlags changes = e->renderNode->changedStates(); QRhiCommandBuffer *cb = commandBuffer(); - cb->beginExternal(); + const bool needsExternal = rd->m_needsExternalRendering; + if (needsExternal) + cb->beginExternal(); e->renderNode->render(&state); - cb->endExternal(); + if (needsExternal) + cb->endExternal(); rd->m_matrix = nullptr; rd->m_clip_list = nullptr; @@ -4643,7 +4653,7 @@ bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe { return a.state == b.state && a.sms->programRhi.program == b.sms->programRhi.program - && a.rpDesc == b.rpDesc + && a.compatibleRenderPassDescriptor->isCompatible(b.compatibleRenderPassDescriptor) && a.layoutCompatibleSrb->isLayoutCompatible(b.layoutCompatibleSrb); } @@ -4654,7 +4664,8 @@ bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKe uint qHash(const GraphicsPipelineStateKey &k, uint seed) Q_DECL_NOTHROW { - return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed) + qHash(k.rpDesc, seed); + // no srb and rp included due to their special comparison semantics and lack of hash keys + return qHash(k.state, seed) + qHash(k.sms->programRhi.program, seed); } Visualizer::Visualizer(Renderer *renderer) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index 297df2232a..878b63fc8c 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -626,27 +626,65 @@ private: QMatrix4x4 m_identityMatrix; }; +struct GraphicsState +{ + bool depthTest = false; + bool depthWrite = false; + QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less; + bool blending = false; + QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One; + QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha; + QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF); + QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None; + bool usesScissor = false; + bool stencilTest = false; + int sampleCount = 1; + QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles; + float lineWidth = 1.0f; +}; + +bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW; +bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW; +uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW; + +struct ShaderManagerShader; + +struct GraphicsPipelineStateKey +{ + GraphicsState state; + const ShaderManagerShader *sms; + const QRhiRenderPassDescriptor *compatibleRenderPassDescriptor; + const QRhiShaderResourceBindings *layoutCompatibleSrb; +}; + +bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW; +bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW; +uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW; + +struct ShaderManagerShader +{ + ~ShaderManagerShader() { + delete programRhi.program; + delete programGL.program; + } + struct { + QSGMaterialShader *program = nullptr; + int pos_order; + } programGL; + struct { + QSGMaterialRhiShader *program = nullptr; + QRhiVertexInputLayout inputLayout; + QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages; + } programRhi; + + float lastOpacity; +}; + class ShaderManager : public QObject { Q_OBJECT public: - struct Shader { - ~Shader() { - delete programRhi.program; - delete programGL.program; - } - struct { - QSGMaterialShader *program = nullptr; - int pos_order; - } programGL; - struct { - QSGMaterialRhiShader *program = nullptr; - QRhiVertexInputLayout inputLayout; - QVarLengthArray<QRhiGraphicsShaderStage, 2> shaderStages; - } programRhi; - - float lastOpacity; - }; + using Shader = ShaderManagerShader; ShaderManager(QSGDefaultRenderContext *ctx) : blitProgram(nullptr), context(ctx) { } ~ShaderManager() { @@ -657,9 +695,10 @@ public: void clearCachedRendererData(); using ShaderResourceBindingList = QVarLengthArray<QRhiShaderResourceBinding, 8>; - QRhiShaderResourceBindings *srb(const ShaderResourceBindingList &bindings); + QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> pipelineCache; + public Q_SLOTS: void invalidated(); @@ -677,39 +716,6 @@ private: QHash<ShaderResourceBindingList, QRhiShaderResourceBindings *> srbCache; }; -struct GraphicsState -{ - bool depthTest = false; - bool depthWrite = false; - QRhiGraphicsPipeline::CompareOp depthFunc = QRhiGraphicsPipeline::Less; - bool blending = false; - QRhiGraphicsPipeline::BlendFactor srcColor = QRhiGraphicsPipeline::One; - QRhiGraphicsPipeline::BlendFactor dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha; - QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF); - QRhiGraphicsPipeline::CullMode cullMode = QRhiGraphicsPipeline::None; - bool usesScissor = false; - bool stencilTest = false; - int sampleCount = 1; - QSGGeometry::DrawingMode drawMode = QSGGeometry::DrawTriangles; - float lineWidth = 1.0f; -}; - -bool operator==(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW; -bool operator!=(const GraphicsState &a, const GraphicsState &b) Q_DECL_NOTHROW; -uint qHash(const GraphicsState &s, uint seed = 0) Q_DECL_NOTHROW; - -struct GraphicsPipelineStateKey -{ - GraphicsState state; - const ShaderManager::Shader *sms; - const QRhiRenderPassDescriptor *rpDesc; - const QRhiShaderResourceBindings *layoutCompatibleSrb; -}; - -bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW; -bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) Q_DECL_NOTHROW; -uint qHash(const GraphicsPipelineStateKey &k, uint seed = 0) Q_DECL_NOTHROW; - struct RenderPassState { QRhiViewport viewport; @@ -903,7 +909,6 @@ private: GraphicsState m_gstate; RenderPassState m_pstate; QStack<GraphicsState> m_gstateStack; - QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> m_pipelines; QHash<QSGSamplerDescription, QRhiSampler *> m_samplers; QRhiTexture *m_dummyTexture = nullptr; diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index c8ae26311b..087c3c4cbf 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -153,7 +153,6 @@ static void qt_print_material_count() */ QSGMaterial::QSGMaterial() - : m_flags(nullptr) { Q_UNUSED(m_reserved); #ifndef QT_NO_DEBUG diff --git a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp index 77593591bd..c5cbd0c979 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterialrhishader.cpp @@ -97,14 +97,14 @@ static inline QRhiShaderResourceBinding::StageFlags toSrbStage(QShader::Stage st Q_UNREACHABLE(); break; } - return 0; + return { }; } void QSGMaterialRhiShaderPrivate::prepare(QShader::Variant vertexShaderVariant) { ubufBinding = -1; ubufSize = 0; - ubufStages = 0; + ubufStages = { }; memset(combinedImageSamplerBindings, 0, sizeof(combinedImageSamplerBindings)); vertexShader = fragmentShader = nullptr; masterUniformData.clear(); diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index 1976538aec..a35629d874 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -245,7 +245,6 @@ static void qt_print_node_count() */ QSGNode::QSGNode() : m_nodeFlags(OwnedByParent) - , m_dirtyState(nullptr) { init(); } @@ -264,7 +263,6 @@ QSGNode::QSGNode(NodeType type) , m_previousSibling(nullptr) , m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0) , m_nodeFlags(OwnedByParent) - , m_dirtyState(nullptr) { init(); } @@ -283,7 +281,6 @@ QSGNode::QSGNode(QSGNodePrivate &dd, NodeType type) , m_previousSibling(nullptr) , m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0) , m_nodeFlags(OwnedByParent) - , m_dirtyState(nullptr) , d_ptr(&dd) { init(); @@ -1466,7 +1463,7 @@ QDebug operator<<(QDebug d, const QSGGeometryNode *n) d << "Geometry(null)"; return d; } - d << "GeometryNode(" << hex << (const void *) n << dec; + d << "GeometryNode(" << Qt::hex << (const void *) n << Qt::dec; const QSGGeometry *g = n->geometry(); @@ -1517,7 +1514,7 @@ QDebug operator<<(QDebug d, const QSGClipNode *n) d << "ClipNode(null)"; return d; } - d << "ClipNode(" << hex << (const void *) n << dec; + d << "ClipNode(" << Qt::hex << (const void *) n << Qt::dec; if (n->childCount()) d << "children=" << n->childCount(); @@ -1540,7 +1537,7 @@ QDebug operator<<(QDebug d, const QSGTransformNode *n) } const QMatrix4x4 m = n->matrix(); d << "TransformNode("; - d << hex << (const void *) n << dec; + d << Qt::hex << (const void *) n << Qt::dec; if (m.isIdentity()) d << "identity"; else if (m.determinant() == 1 && m(0, 0) == 1 && m(1, 1) == 1 && m(2, 2) == 1) @@ -1562,7 +1559,7 @@ QDebug operator<<(QDebug d, const QSGOpacityNode *n) return d; } d << "OpacityNode("; - d << hex << (const void *) n << dec; + d << Qt::hex << (const void *) n << Qt::dec; d << "opacity=" << n->opacity() << "combined=" << n->combinedOpacity() << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); @@ -1581,7 +1578,7 @@ QDebug operator<<(QDebug d, const QSGRootNode *n) return d; } QDebugStateSaver saver(d); - d << "RootNode" << hex << (const void *) n << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); + d << "RootNode" << Qt::hex << (const void *) n << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); #ifdef QSG_RUNTIME_DESCRIPTION d << QSGNodePrivate::description(n); #endif @@ -1614,8 +1611,8 @@ QDebug operator<<(QDebug d, const QSGNode *n) d << static_cast<const QSGOpacityNode *>(n); break; case QSGNode::RenderNodeType: - d << "RenderNode(" << hex << (const void *) n << dec - << "flags=" << (int) n->flags() << dec + d << "RenderNode(" << Qt::hex << (const void *) n << Qt::dec + << "flags=" << (int) n->flags() << Qt::dec << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); #ifdef QSG_RUNTIME_DESCRIPTION d << QSGNodePrivate::description(n); @@ -1623,8 +1620,8 @@ QDebug operator<<(QDebug d, const QSGNode *n) d << ')'; break; default: - d << "Node(" << hex << (const void *) n << dec - << "flags=" << (int) n->flags() << dec + d << "Node(" << Qt::hex << (const void *) n << Qt::dec + << "flags=" << (int) n->flags() << Qt::dec << (n->isSubtreeBlocked() ? "*BLOCKED*" : ""); #ifdef QSG_RUNTIME_DESCRIPTION d << QSGNodePrivate::description(n); diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h index cb677de030..5a7faed5e0 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.h +++ b/src/quick/scenegraph/coreapi/qsgnode.h @@ -146,7 +146,7 @@ public: QT_DEPRECATED void clearDirty() { } void markDirty(DirtyState bits); - QT_DEPRECATED DirtyState dirtyState() const { return nullptr; } + QT_DEPRECATED DirtyState dirtyState() const { return { }; } virtual bool isSubtreeBlocked() const; diff --git a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp index 6c2ff0b176..9282b6c308 100644 --- a/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp +++ b/src/quick/scenegraph/coreapi/qsgopenglvisualizer.cpp @@ -202,7 +202,7 @@ void OpenGLVisualizer::visualizeChanges(Node *n) // This is because many changes don't propegate their dirty state to the // parent so the node updater will not unset these states. They are // not used for anything so, unsetting it should have no side effects. - n->dirtyState = nullptr; + n->dirtyState = {}; } SHADOWNODE_TRAVERSE(n) { diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index 7af932eeb5..90090e1cc0 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -45,6 +45,7 @@ # include <QtGui/QOpenGLFunctions> #endif #include <private/qquickprofiler_p.h> +#include <qtquick_tracepoints_p.h> #include <QtCore/QElapsedTimer> @@ -221,6 +222,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) if (!rootNode()) return; + Q_TRACE_SCOPE(QSG_renderScene); m_is_rendering = true; @@ -235,11 +237,14 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) m_bindable = &bindable; preprocess(); + Q_TRACE(QSG_binding_entry); bindable.bind(); if (profileFrames) bindTime = frameTimer.nsecsElapsed(); + Q_TRACE(QSG_binding_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame, QQuickProfiler::SceneGraphRendererBinding); + Q_TRACE(QSG_render_entry); #if QT_CONFIG(opengl) // Sanity check that attribute registers are disabled @@ -259,6 +264,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) render(); if (profileFrames) renderTime = frameTimer.nsecsElapsed(); + Q_TRACE(QSG_render_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRendererFrame, QQuickProfiler::SceneGraphRendererRender); @@ -305,6 +311,8 @@ void QSGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) void QSGRenderer::preprocess() { + Q_TRACE(QSG_preprocess_entry); + m_is_preprocessing = true; QSGRootNode *root = rootNode(); @@ -331,13 +339,16 @@ void QSGRenderer::preprocess() bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled(); if (profileFrames) preprocessTime = frameTimer.nsecsElapsed(); + Q_TRACE(QSG_preprocess_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame, QQuickProfiler::SceneGraphRendererPreprocess); + Q_TRACE(QSG_update_entry); nodeUpdater()->updateStates(root); if (profileFrames) updatePassTime = frameTimer.nsecsElapsed(); + Q_TRACE(QSG_update_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame, QQuickProfiler::SceneGraphRendererUpdate); diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp index 2892f2f966..45ad49475f 100644 --- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp +++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp @@ -77,6 +77,8 @@ QSGRenderNodePrivate::QSGRenderNodePrivate() : m_matrix(nullptr) , m_clip_list(nullptr) , m_opacity(1) + , m_needsExternalRendering(true) + , m_prepareCallback(nullptr) { } @@ -131,7 +133,7 @@ QSGRenderNodePrivate::QSGRenderNodePrivate() */ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const { - return nullptr; + return {}; } /*! @@ -311,7 +313,7 @@ void QSGRenderNode::releaseResources() */ QSGRenderNode::RenderingFlags QSGRenderNode::flags() const { - return nullptr; + return {}; } /*! diff --git a/src/quick/scenegraph/coreapi/qsgrendernode_p.h b/src/quick/scenegraph/coreapi/qsgrendernode_p.h index 5c42e55689..534d630f15 100644 --- a/src/quick/scenegraph/coreapi/qsgrendernode_p.h +++ b/src/quick/scenegraph/coreapi/qsgrendernode_p.h @@ -51,12 +51,14 @@ // We mean it. // +#include <QtQuick/private/qtquickglobal_p.h> #include <QtQuick/qsgnode.h> #include <QtQuick/qsgrendernode.h> +#include <functional> QT_BEGIN_NAMESPACE -class QSGRenderNodePrivate +class Q_QUICK_PRIVATE_EXPORT QSGRenderNodePrivate { public: QSGRenderNodePrivate(); @@ -66,6 +68,11 @@ public: const QMatrix4x4 *m_matrix; const QSGClipNode *m_clip_list; qreal m_opacity; + + // ### Qt 6: change this into a value for flags() + bool m_needsExternalRendering; + // ### Qt 6: change this into a virtual prepare() function + std::function<void()> m_prepareCallback; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp index 38d4c4440f..a0131a3f67 100644 --- a/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrhivisualizer.cpp @@ -400,7 +400,7 @@ void RhiVisualizer::ChangeVis::gather(Node *n) // This is because many changes don't propegate their dirty state to the // parent so the node updater will not unset these states. They are // not used for anything so, unsetting it should have no side effects. - n->dirtyState = nullptr; + n->dirtyState = { }; } SHADOWNODE_TRAVERSE(n) { diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp index 58b42e4094..418aaca605 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.cpp +++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp @@ -317,6 +317,34 @@ static void qt_debug_remove_texture(QSGTexture* texture) \since 5.9 */ +/*! + \class QSGTexture::NativeTexture + \brief Contains information about the underlying native resources of a texture. + \since 5.15 + */ + +/*! + \variable QSGTexture::NativeTexture::object + \brief a pointer to the native object handle. + + With OpenGL, the native handle is a GLuint value, so \c object is then a + pointer to a GLuint. With Vulkan, the native handle is a VkImage, so \c + object is a pointer to a VkImage. With Direct3D 11 and Metal \c + object is a pointer to a ID3D11Texture2D or MTLTexture pointer, respectively. + + \note Pay attention to the fact that \a object is always a pointer + to the native texture handle type, even if the native type itself is a + pointer. + */ + +/*! + \variable QSGTexture::NativeTexture::layout + \brief Specifies the current image layout for APIs like Vulkan. + + For Vulkan, \c layout contains a \c VkImageLayout value. + */ + + #ifndef QT_NO_DEBUG Q_QUICK_PRIVATE_EXPORT void qsg_set_material_failure(); #endif @@ -721,6 +749,28 @@ void QSGTexture::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUp } /*! + \return the platform-specific texture data for this texture. + + \note This is only available when running the graphics API independent + rendering path of the scene graph. Use textureId() otherwise. + + Returns an empty result (\c object is null) if there is no available + underlying native texture. + + \since 5.15 + \sa QQuickWindow::createTextureFromNativeObject() + */ +QSGTexture::NativeTexture QSGTexture::nativeTexture() const +{ + Q_D(const QSGTexture); + if (auto *tex = d->rhiTexture()) { + auto nativeTexture = tex->nativeTexture(); + return {nativeTexture.object, nativeTexture.layout}; + } + return {}; +} + +/*! \internal */ void QSGTexture::setWorkResourceUpdateBatch(QRhiResourceUpdateBatch *resourceUpdates) @@ -792,11 +842,15 @@ void QSGTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *res /*! \fn bool QSGDynamicTexture::updateTexture() - Call this function to explicitly update the dynamic texture. Calling bind() will bind - the content that was previously updated. + Call this function to explicitly update the dynamic texture. The function returns true if the texture was changed as a resul of the update; otherwise returns false. + + \note This function is typically called from QQuickItem::updatePaintNode() + or QSGNode::preprocess(), meaning during the \c{synchronization} or the + \c{node preprocessing} phases of the scenegraph. Calling it at other times + is discouraged and can lead to unexpected behavior. */ /*! diff --git a/src/quick/scenegraph/coreapi/qsgtexture.h b/src/quick/scenegraph/coreapi/qsgtexture.h index 2efdd8b7c3..207ef52f4e 100644 --- a/src/quick/scenegraph/coreapi/qsgtexture.h +++ b/src/quick/scenegraph/coreapi/qsgtexture.h @@ -80,7 +80,13 @@ public: Anisotropy16x }; + struct NativeTexture { + const void *object; + int layout; + }; + virtual int textureId() const = 0; // ### Qt 6: remove + NativeTexture nativeTexture() const; virtual QSize textureSize() const = 0; virtual bool hasAlphaChannel() const = 0; virtual bool hasMipmaps() const = 0; diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index f7b07d724a..eab0369be7 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -50,6 +50,8 @@ #include <private/qquickprofiler_p.h> #include <QElapsedTimer> +#include <qtquick_tracepoints_p.h> + QT_BEGIN_NAMESPACE static QElapsedTimer qsg_render_timer; @@ -169,10 +171,13 @@ void QSGDistanceFieldGlyphCache::update() if (m_pendingGlyphs.isEmpty()) return; + Q_TRACE_SCOPE(QSGDistanceFieldGlyphCache_update, m_pendingGlyphs.size()); + bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled(); if (profileFrames) qsg_render_timer.start(); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphAdaptationLayerFrame); + Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_entry); QList<QDistanceField> distanceFields; const int pendingGlyphsSize = m_pendingGlyphs.size(); @@ -189,8 +194,11 @@ void QSGDistanceFieldGlyphCache::update() int count = m_pendingGlyphs.size(); if (profileFrames) renderTime = qsg_render_timer.nsecsElapsed(); + + Q_TRACE(QSGDistanceFieldGlyphCache_glyphRender_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame, QQuickProfiler::SceneGraphAdaptationLayerGlyphRender); + Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_entry); m_pendingGlyphs.reset(); @@ -210,6 +218,7 @@ void QSGDistanceFieldGlyphCache::update() int(renderTime / 1000000), int((now - (renderTime / 1000000)))); } + Q_TRACE(QSGDistanceFieldGlyphCache_glyphStore_exit); Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(QQuickProfiler::SceneGraphAdaptationLayerFrame, QQuickProfiler::SceneGraphAdaptationLayerGlyphStore, (qint64)count); diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 6baee33b53..1db49feb5d 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -57,8 +57,10 @@ #include <QtCore/qrect.h> #include <QtGui/qbrush.h> #include <QtGui/qcolor.h> +#include <QtGui/qpainterpath.h> #include <QtCore/qsharedpointer.h> #include <QtGui/qglyphrun.h> +#include <QtGui/qpainterpath.h> #include <QtCore/qurl.h> #include <private/qfontengine_p.h> #include <QtGui/private/qdatabuffer_p.h> diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 17eb1e312c..e3c951e5ed 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -341,9 +341,10 @@ void QSGRenderContext::invalidate() { } -void QSGRenderContext::prepareSync(qreal devicePixelRatio) +void QSGRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb) { Q_UNUSED(devicePixelRatio); + Q_UNUSED(cb); } void QSGRenderContext::beginNextFrame(QSGRenderer *renderer, diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 244bcfabd1..d389420907 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -174,7 +174,7 @@ public: using RenderPassCallback = void (*)(void *); - virtual void prepareSync(qreal devicePixelRatio); + virtual void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb); virtual void beginNextFrame(QSGRenderer *renderer, RenderPassCallback mainPassRecordingStart, RenderPassCallback mainPassRecordingEnd, diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index 66add51c55..7dfb8488ae 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -87,7 +87,6 @@ struct QSGAdaptationBackendData }; QSGAdaptationBackendData::QSGAdaptationBackendData() - : flags(nullptr) { // Fill in the table with the built-in adaptations. builtIns.append(new QSGSoftwareAdaptation); diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 2bf4a83a8e..1d18caa0b4 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -200,9 +200,14 @@ void QSGDefaultRenderContext::invalidate() emit invalidated(); } -void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio) +void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb) { m_currentDevicePixelRatio = devicePixelRatio; + + // we store the command buffer already here, in case there is something in + // an updatePaintNode() implementation that leads to needing it (for + // example, an updateTexture() call on a QSGRhiLayer) + m_currentFrameCommandBuffer = cb; } static QBasicMutex qsg_framerender_mutex; @@ -237,14 +242,12 @@ void QSGDefaultRenderContext::beginNextRhiFrame(QSGRenderer *renderer, QRhiRende RenderPassCallback mainPassRecordingEnd, void *callbackUserData) { - Q_ASSERT(!m_currentFrameCommandBuffer); - renderer->setRenderTarget(rt); renderer->setRenderPassDescriptor(rp); renderer->setCommandBuffer(cb); renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData); - m_currentFrameCommandBuffer = cb; + m_currentFrameCommandBuffer = cb; // usually the same as what was passed to prepareSync() but cannot count on that having been called m_currentFrameRenderPass = rp; } @@ -364,7 +367,7 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri p->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader()); p->link(); if (!p->isLinked()) - qWarning() << "shader compilation failed:" << endl << p->log(); + qWarning() << "shader compilation failed:" << Qt::endl << p->log(); } else { shader->compile(); } diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h index 2fdb3a48dd..97ed681f9a 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -104,7 +104,7 @@ public: void initialize(const QSGRenderContext::InitParams *params) override; void invalidate() override; - void prepareSync(qreal devicePixelRatio) override; + void prepareSync(qreal devicePixelRatio, QRhiCommandBuffer *cb) override; void beginNextFrame(QSGRenderer *renderer, RenderPassCallback mainPassRecordingStart, RenderPassCallback mainPassRecordingEnd, diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index f609055677..94f15b55d4 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -60,6 +60,7 @@ #include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qsgrenderer_p.h> #include <private/qquickprofiler_p.h> +#include <qtquick_tracepoints_p.h> #include <private/qsgrhishadereffectnode_p.h> @@ -195,8 +196,16 @@ public: bool eventFilter(QObject *watched, QEvent *event) override; struct WindowData { + WindowData() + : updatePending(false), + grabOnly(false), + rhiDeviceLost(false), + rhiDoomed(false) + { } bool updatePending : 1; bool grabOnly : 1; + bool rhiDeviceLost : 1; + bool rhiDoomed : 1; }; QHash<QQuickWindow *, WindowData> m_windows; @@ -316,15 +325,19 @@ void QSGRenderLoop::setInstance(QSGRenderLoop *instance) s_instance = instance; } -void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window, - bool isEs) +void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window) { QString translatedMessage; QString untranslatedMessage; - QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(), + if (QSGRhiSupport::instance()->isRhiEnabled()) { + QQuickWindowPrivate::rhiCreationFailureMessage(QSGRhiSupport::instance()->rhiBackendName(), &translatedMessage, - &untranslatedMessage, - isEs); + &untranslatedMessage); + } else { + QQuickWindowPrivate::contextCreationFailureMessage(window->requestedFormat(), + &translatedMessage, + &untranslatedMessage); + } // If there is a slot connected to the error signal, emit it and leave it to // the application to do something with the message. If nothing is connected, // show a message on our own and terminate. @@ -362,10 +375,7 @@ QSGGuiThreadRenderLoop::~QSGGuiThreadRenderLoop() void QSGGuiThreadRenderLoop::show(QQuickWindow *window) { - WindowData data; - data.updatePending = false; - data.grabOnly = false; - m_windows[window] = data; + m_windows[window] = WindowData(); maybeUpdate(window); } @@ -451,8 +461,10 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss() rc->invalidate(); - for (auto it = m_windows.constBegin(), itEnd = m_windows.constEnd(); it != itEnd; ++it) + for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) { releaseSwapchain(it.key()); + it->rhiDeviceLost = true; + } delete rhi; rhi = nullptr; @@ -508,6 +520,13 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) const bool enableRhi = rhiSupport->isRhiEnabled(); if (enableRhi && !rhi) { + // This block below handles both the initial QRhi initialization and + // also the subsequent reinitialization attempts after a device lost + // (reset) situation. + + if (data.rhiDoomed) // no repeated attempts if the initial attempt failed + return; + if (!offscreenSurface) offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window); @@ -517,6 +536,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) if (rhiSupport->isProfilingRequested()) QSGRhiProfileConnection::instance()->initialize(rhi); + data.rhiDeviceLost = false; + current = true; rhi->makeThreadLocalNativeContextCurrent(); @@ -533,7 +554,11 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) rcParams.maybeSurface = window; cd->context->initialize(&rcParams); } else { - handleContextCreationFailure(window, false); + if (!data.rhiDeviceLost) { + data.rhiDoomed = true; + handleContextCreationFailure(window); + } + // otherwise no error, will retry on a subsequent rendering attempt } } else if (!enableRhi && !gl) { gl = new QOpenGLContext(); @@ -542,10 +567,9 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) if (qt_gl_global_share_context()) gl->setShareContext(qt_gl_global_share_context()); if (!gl->create()) { - const bool isEs = gl->isOpenGLES(); delete gl; gl = nullptr; - handleContextCreationFailure(window, isEs); + handleContextCreationFailure(window); } else { if (!offscreenSurface) { offscreenSurface = new QOffscreenSurface; @@ -619,7 +643,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) i++; } - // Check for context loss. + // Check for context loss. (legacy GL only) if (!current && !rhi && !gl->isValid()) { for (auto it = m_windows.constBegin() ; it != m_windows.constEnd(); it++) { QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(it.key()); @@ -657,20 +681,25 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) return; } + Q_TRACE_SCOPE(QSG_renderWindow); QElapsedTimer renderTimer; qint64 renderTime = 0, syncTime = 0, polishTime = 0; bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled(); if (profileFrames) renderTimer.start(); + Q_TRACE(QSG_polishItems_entry); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame); cd->polishItems(); if (profileFrames) polishTime = renderTimer.nsecsElapsed(); + + Q_TRACE(QSG_polishItems_exit); Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame, QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphPolishPolish); + Q_TRACE(QSG_sync_entry); emit window->afterAnimating(); @@ -725,15 +754,20 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) if (profileFrames) syncTime = renderTimer.nsecsElapsed(); + + Q_TRACE(QSG_sync_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSync); + Q_TRACE(QSG_render_entry); cd->renderSceneGraph(window->size(), effectiveOutputSize); if (profileFrames) renderTime = renderTimer.nsecsElapsed(); + Q_TRACE(QSG_render_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopRender); + Q_TRACE(QSG_swap_entry); if (data.grabOnly) { const bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255; @@ -747,7 +781,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) const bool needsPresent = alsoSwap && window->isVisible(); if (cd->swapchain) { - QRhi::EndFrameFlags flags = 0; + QRhi::EndFrameFlags flags; if (!needsPresent) flags |= QRhi::SkipPresent; QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags); @@ -767,6 +801,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) qint64 swapTime = 0; if (profileFrames) swapTime = renderTimer.nsecsElapsed(); + + Q_TRACE(QSG_swap_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSwap); diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h index 02d0b84de1..9fd0ab02f5 100644 --- a/src/quick/scenegraph/qsgrenderloop_p.h +++ b/src/quick/scenegraph/qsgrenderloop_p.h @@ -112,12 +112,11 @@ public: static void cleanup(); + void handleContextCreationFailure(QQuickWindow *window); + Q_SIGNALS: void timeToIncubate(); -protected: - void handleContextCreationFailure(QQuickWindow *window, bool isEs); - private: static QSGRenderLoop *s_instance; diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp index 757410eded..952279a3ff 100644 --- a/src/quick/scenegraph/qsgrhilayer.cpp +++ b/src/quick/scenegraph/qsgrhilayer.cpp @@ -388,7 +388,7 @@ void QSGRhiLayer::grab() m_mirrorHorizontal ? -m_rect.width() : m_rect.width(), m_mirrorVertical ? m_rect.height() : -m_rect.height()); } - QSGAbstractRenderer::MatrixTransformFlags matrixFlags = 0; + QSGAbstractRenderer::MatrixTransformFlags matrixFlags; if (!m_rhi->isYUpInNDC()) matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY; m_renderer->setProjectionMatrixToRect(mirrored, matrixFlags); diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp index 6f6544548c..e86dae7c09 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp +++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp @@ -136,7 +136,7 @@ void QSGRhiShaderLinker::linkTextureSubRects() // texture binding point. for (Constant &c : m_constants) { if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) { - if (c.value.type() == QVariant::ByteArray) { + if (c.value.userType() == QMetaType::QByteArray) { const QByteArray name = c.value.toByteArray(); if (!m_samplerNameMap.contains(name)) qWarning("ShaderEffect: qt_SubRect_%s refers to unknown source texture", name.constData()); @@ -270,7 +270,7 @@ bool QSGRhiShaderEffectMaterialShader::updateUniformData(RenderState &state, QSG memcpy(dst, f, sizeof(f)); } else if (c.specialType == QSGShaderEffectNode::VariableData::None) { changed = true; - switch (int(c.value.type())) { + switch (int(c.value.userType())) { case QMetaType::QColor: { const QColor v = qsg_premultiply_color(qvariant_cast<QColor>(c.value)); const float f[4] = { float(v.redF()), float(v.greenF()), float(v.blueF()), float(v.alphaF()) }; diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp index e2945879b1..f25bbe2d26 100644 --- a/src/quick/scenegraph/qsgrhisupport.cpp +++ b/src/quick/scenegraph/qsgrhisupport.cpp @@ -38,7 +38,10 @@ ****************************************************************************/ #include "qsgrhisupport_p.h" -#include "qsgdefaultrendercontext_p.h" +#include "qsgcontext_p.h" +#if QT_CONFIG(opengl) +# include "qsgdefaultrendercontext_p.h" +#endif #include <QtGui/qwindow.h> #if QT_CONFIG(vulkan) @@ -157,9 +160,11 @@ void QSGRhiSupport::applySettings() } else if (rhiBackend == QByteArrayLiteral("null")) { m_rhiBackend = QRhi::Null; } else { + if (!rhiBackend.isEmpty()) + qWarning("Unknown key \"%s\" for QSG_RHI_BACKEND, falling back to default backend.", qPrintable(rhiBackend)); #if defined(Q_OS_WIN) m_rhiBackend = QRhi::D3D11; -#elif defined(Q_OS_DARWIN) +#elif defined(Q_OS_MACOS) || defined(Q_OS_IOS) m_rhiBackend = QRhi::Metal; #else m_rhiBackend = QRhi::OpenGLES2; @@ -185,29 +190,10 @@ void QSGRhiSupport::applySettings() if (m_killDeviceFrameCount > 0 && m_rhiBackend == QRhi::D3D11) qDebug("Graphics device will be reset every %d frames", m_killDeviceFrameCount); - const char *backendName = "unknown"; - switch (m_rhiBackend) { - case QRhi::Null: - backendName = "Null"; - break; - case QRhi::Vulkan: - backendName = "Vulkan"; - break; - case QRhi::OpenGLES2: - backendName = "OpenGL"; - break; - case QRhi::D3D11: - backendName = "D3D11"; - break; - case QRhi::Metal: - backendName = "Metal"; - break; - default: - break; - } + const QString backendName = rhiBackendName(); qCDebug(QSG_LOG_INFO, "Using QRhi with backend %s\n graphics API debug/validation layers: %d\n QRhi profiling and debug markers: %d", - backendName, m_debugLayer, m_profile); + qPrintable(backendName), m_debugLayer, m_profile); if (m_preferSoftwareRenderer) qCDebug(QSG_LOG_INFO, "Prioritizing software renderers"); } @@ -247,6 +233,27 @@ QSGRhiSupport *QSGRhiSupport::instance() return inst; } +QString QSGRhiSupport::rhiBackendName() const +{ + if (m_enableRhi) { + switch (m_rhiBackend) { + case QRhi::Null: + return QLatin1String("Null"); + case QRhi::Vulkan: + return QLatin1String("Vulkan"); + case QRhi::OpenGLES2: + return QLatin1String("OpenGL"); + case QRhi::D3D11: + return QLatin1String("D3D11"); + case QRhi::Metal: + return QLatin1String("Metal"); + default: + return QLatin1String("Unknown"); + } + } + return QLatin1String("Unknown (RHI not enabled)"); +} + QSGRendererInterface::GraphicsApi QSGRhiSupport::graphicsApi() const { if (!m_enableRhi) @@ -350,7 +357,7 @@ static const void *qsgrhi_d3d11_rifResource(QSGRendererInterface::Resource res, } #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, const QRhiNativeHandles *nat, const QRhiNativeHandles *cbNat) { @@ -379,8 +386,15 @@ static const void *qsgrhi_mtl_rifResource(QSGRendererInterface::Resource res, co } #endif -const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const QSGDefaultRenderContext *rc) +const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, + const QSGDefaultRenderContext *rc) { +// ### This condition is a temporary workaround to allow compilation +// with -no-opengl, but Vulkan or Metal enabled, to succeed. Full +// support for RHI-capable -no-opengl builds will be available in +// Qt 6 once the direct OpenGL code path gets removed. +#if QT_CONFIG(opengl) + QRhi *rhi = rc->rhi(); if (res == QSGRendererInterface::RhiResource || !rhi) return rhi; @@ -408,7 +422,7 @@ const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const case QRhi::D3D11: return qsgrhi_d3d11_rifResource(res, nat); #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) case QRhi::Metal: { QRhiCommandBuffer *cb = rc->currentFrameCommandBuffer(); @@ -418,6 +432,12 @@ const void *QSGRhiSupport::rifResource(QSGRendererInterface::Resource res, const default: return nullptr; } + +#else + Q_UNUSED(res); + Q_UNUSED(rc); + return nullptr; +#endif } int QSGRhiSupport::chooseSampleCountForWindowWithRhi(QWindow *window, QRhi *rhi) @@ -469,7 +489,7 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf QRhi *rhi = nullptr; - QRhi::Flags flags = 0; + QRhi::Flags flags; if (isProfilingRequested()) flags |= QRhi::EnableProfiling | QRhi::EnableDebugMarkers; if (isSoftwareRendererRequested()) @@ -513,7 +533,7 @@ QRhi *QSGRhiSupport::createRhi(QWindow *window, QOffscreenSurface *offscreenSurf rhi = QRhi::create(backend, &rhiParams, flags); } #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (backend == QRhi::Metal) { QRhiMetalInitParams rhiParams; rhi = QRhi::create(backend, &rhiParams, flags); @@ -576,7 +596,7 @@ void QSGRhiProfileConnection::initialize(QRhi *rhi) profPort = 30667; qCDebug(QSG_LOG_INFO, "Sending RHI profiling output to %s:%d", qPrintable(profHost), profPort); m_profConn.reset(new QTcpSocket); - QObject::connect(m_profConn.data(), QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), m_profConn.data(), + QObject::connect(m_profConn.data(), &QAbstractSocket::errorOccurred, m_profConn.data(), [this](QAbstractSocket::SocketError socketError) { qWarning(" RHI profiler error: %d (%s)", socketError, qPrintable(m_profConn->errorString())); }); m_profConn->connectToHost(profHost, profPort); diff --git a/src/quick/scenegraph/qsgrhisupport_p.h b/src/quick/scenegraph/qsgrhisupport_p.h index d008ecd0af..0a95a09ad2 100644 --- a/src/quick/scenegraph/qsgrhisupport_p.h +++ b/src/quick/scenegraph/qsgrhisupport_p.h @@ -70,7 +70,7 @@ #include <QtGui/private/qrhid3d11_p.h> #endif -#ifdef Q_OS_DARWIN +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) #include <QtGui/private/qrhimetal_p.h> #endif @@ -109,6 +109,7 @@ public: bool isRhiEnabled() const { return m_enableRhi; } QRhi::Implementation rhiBackend() const { return m_rhiBackend; } + QString rhiBackendName() const; QSGRendererInterface::GraphicsApi graphicsApi() const; bool isDebugLayerRequested() const { return m_debugLayer; } diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index dc1f97de54..9b288029b4 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -70,6 +70,8 @@ #include <private/qsgrhishadereffectnode_p.h> #include <private/qsgdefaultrendercontext_p.h> +#include <qtquick_tracepoints_p.h> + /* Overall design: @@ -368,6 +370,9 @@ public: QSize windowSize; float dpr = 1; int rhiSampleCount = 1; + bool rhiDeviceLost = false; + bool rhiDoomed = false; + bool guiNotifiedAboutRhiFailure = false; // Local event queue stuff... bool stopEventProcessing; @@ -622,13 +627,15 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab) sgrc->initialize(&rcParams); } } - } else { + } else if (rhi) { // With the rhi making the (OpenGL) context current serves only one // purpose: to enable external OpenGL rendering connected to one of // the QQuickWindow signals (beforeSynchronizing, beforeRendering, // etc.) to function like it did on the direct OpenGL path. For our // own rendering this call would not be necessary. rhi->makeThreadLocalNativeContextCurrent(); + } else { + current = false; } if (current) { QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); @@ -653,6 +660,11 @@ void QSGRenderThread::sync(bool inExpose, bool inGrab) qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window has bad size, sync aborted"); } + // Two special cases: For grabs we do not care about blocking the gui + // (main) thread. When this is from an expose, we will keep locked until + // the frame is rendered (submitted), so in that case waking happens later + // in syncAndRender(). Otherwise, wake now and let the main thread go on + // while we render. if (!inExpose && !inGrab) { qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync complete, waking Gui"); waitCondition.wakeOne(); @@ -669,6 +681,7 @@ void QSGRenderThread::handleDeviceLoss() QQuickWindowPrivate::get(window)->cleanupNodesOnShutdown(); sgrc->invalidate(); wm->releaseSwapchain(window); + rhiDeviceLost = true; delete rhi; rhi = nullptr; } @@ -680,7 +693,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) sinceLastTime = threadTimer.nsecsElapsed(); threadTimer.start(); } + Q_TRACE_SCOPE(QSG_syncAndRender); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame); + Q_TRACE(QSG_sync_entry); QElapsedTimer waitTimer; waitTimer.start(); @@ -693,8 +708,9 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) const bool repaintRequested = (pendingUpdate & RepaintRequest) || d->customRenderStage || grabImage; const bool syncRequested = (pendingUpdate & SyncRequest) || grabImage; const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest; - pendingUpdate = 0; const bool grabRequested = grabImage != nullptr; + if (!grabRequested) + pendingUpdate = 0; QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window); // Begin the frame before syncing -> sync is where we may invoke @@ -745,13 +761,11 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) QCoreApplication::postEvent(window, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))); // Before returning we need to ensure the same wake up logic that // would have happened if beginFrame() had suceeded. - if (exposeRequested) { + if (syncRequested && !grabRequested) { + // Lock like sync() would do. Note that exposeRequested always includes syncRequested. qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui"); - waitCondition.wakeOne(); - mutex.unlock(); - } else if (syncRequested && !grabRequested) { - qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- bailing out due to failed beginFrame, wake Gui like sync would do"); mutex.lock(); + // Go ahead with waking because we will return right after this. waitCondition.wakeOne(); mutex.unlock(); } @@ -767,33 +781,46 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) if (profileFrames) syncTime = threadTimer.nsecsElapsed(); #endif + Q_TRACE(QSG_sync_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSync); - if (!syncResultedInChanges && !repaintRequested && sgrc->isValid() && !grabImage) { - if (gl || !rhi->isRecordingFrame()) { - qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted"); - int waitTime = vsyncDelta - (int) waitTimer.elapsed(); - if (waitTime > 0) - msleep(waitTime); - return; - } + if (!syncResultedInChanges + && !repaintRequested + && !(pendingUpdate & RepaintRequest) // may have been set in sync() + && sgrc->isValid() + && !grabRequested + && (gl || (rhi && !rhi->isRecordingFrame()))) + { + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted"); + int waitTime = vsyncDelta - (int) waitTimer.elapsed(); + if (waitTime > 0) + msleep(waitTime); + return; } qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started"); + Q_TRACE(QSG_render_entry); - if (animatorDriver->isRunning() && !grabImage) { + // RepaintRequest may have been set in pendingUpdate in an + // updatePaintNode() invoked from sync(). We are about to do a repaint + // right now, so reset the flag. (bits other than RepaintRequest cannot + // be set in pendingUpdate at this point) + if (!grabRequested) + pendingUpdate = 0; + + if (animatorDriver->isRunning() && !grabRequested) { d->animationController->lock(); animatorDriver->advance(); d->animationController->unlock(); } bool current = true; - if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0) { + if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0 && (gl || rhi)) { if (gl) current = gl->makeCurrent(window); - else if (rhi) + else rhi->makeThreadLocalNativeContextCurrent(); } else { current = false; @@ -811,21 +838,23 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) if (profileFrames) renderTime = threadTimer.nsecsElapsed(); + Q_TRACE(QSG_render_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopRender); + Q_TRACE(QSG_swap_entry); // With the rhi grabs can only be done by adding a readback and then // blocking in a real frame. The legacy GL path never gets here with // grabs as it rather invokes sync/render directly without going // through syncAndRender(). - if (grabImage) { + if (grabRequested) { Q_ASSERT(rhi && !gl && cd->swapchain); *grabImage = QSGRhiSupport::instance()->grabAndBlockInCurrentFrame(rhi, cd->swapchain); } if (cd->swapchain) { - QRhi::EndFrameFlags flags = 0; - if (grabImage) + QRhi::EndFrameFlags flags; + if (grabRequested) flags |= QRhi::SkipPresent; QRhi::FrameOpResult frameResult = rhi->endFrame(cd->swapchain, flags); if (frameResult != QRhi::FrameOpSuccess) { @@ -841,12 +870,13 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) gl->swapBuffers(window); } - if (!grabImage) + if (!grabRequested) d->fireFrameSwapped(); - } else { + Q_TRACE(QSG_render_exit); Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSync, 1); + Q_TRACE(QSG_swap_entry); qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window not ready, skipping render"); } @@ -858,7 +888,8 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) // has started rendering with a bad window, causing makeCurrent to // fail or if the window has a bad size. if (exposeRequested) { - qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after initial expose"); + // With expose sync() did not wake gui, do it now. + qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after expose"); waitCondition.wakeOne(); mutex.unlock(); } @@ -870,7 +901,7 @@ void QSGRenderThread::syncAndRender(QImage *grabImage) int((renderTime - syncTime) / 1000000), int(threadTimer.elapsed() - renderTime / 1000000)); - + Q_TRACE(QSG_swap_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphRenderLoopSwap); @@ -912,14 +943,21 @@ void QSGRenderThread::processEventsAndWaitForMore() void QSGRenderThread::ensureRhi() { if (!rhi) { + if (rhiDoomed) // no repeated attempts if the initial attempt failed + return; QSGRhiSupport *rhiSupport = QSGRhiSupport::instance(); rhi = rhiSupport->createRhi(window, offscreenSurface); if (rhi) { + rhiDeviceLost = false; rhiSampleCount = rhiSupport->chooseSampleCountForWindowWithRhi(window, rhi); if (rhiSupport->isProfilingRequested()) QSGRhiProfileConnection::instance()->initialize(rhi); // ### this breaks down with multiple windows } else { - qWarning("Failed to create QRhi on the render thread; scenegraph is not functional"); + if (!rhiDeviceLost) { + rhiDoomed = true; + qWarning("Failed to create QRhi on the render thread; scenegraph is not functional"); + } + // otherwise no error, will retry on a subsequent rendering attempt return; } } @@ -975,9 +1013,24 @@ void QSGRenderThread::run() if (window) { if (enableRhi) { + ensureRhi(); - if (rhi) - syncAndRender(); + + // We absolutely have to syncAndRender() here, even when QRhi + // failed to initialize otherwise the gui thread will be left + // in a blocked state. It is up to syncAndRender() to + // gracefully skip all graphics stuff when rhi is null. + + syncAndRender(); + + // Now we can do something about rhi init failures. (reinit + // failure after device reset does not count) + if (rhiDoomed && !guiNotifiedAboutRhiFailure) { + guiNotifiedAboutRhiFailure = true; + QEvent *e = new QEvent(QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure)); + QCoreApplication::postEvent(window, e); + } + } else { if (!sgrc->openglContext() && windowSize.width() > 0 && windowSize.height() > 0 && gl->makeCurrent(window)) { QSGDefaultRenderContext::InitParams rcParams; @@ -1282,10 +1335,9 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) w->thread->gl->setFormat(w->window->requestedFormat()); w->thread->gl->setScreen(w->window->screen()); if (!w->thread->gl->create()) { - const bool isEs = w->thread->gl->isOpenGLES(); delete w->thread->gl; w->thread->gl = nullptr; - handleContextCreationFailure(w->window, isEs); + handleContextCreationFailure(w->window); return; } @@ -1508,7 +1560,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) return; } - + Q_TRACE_SCOPE(QSG_polishAndSync); QElapsedTimer timer; qint64 polishTime = 0; qint64 waitTime = 0; @@ -1517,14 +1569,17 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) if (profileFrames) timer.start(); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync); + Q_TRACE(QSG_polishItems_entry); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); d->polishItems(); if (profileFrames) polishTime = timer.nsecsElapsed(); + Q_TRACE(QSG_polishItems_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncPolish); + Q_TRACE(QSG_wait_entry); w->updateDuringSync = false; @@ -1539,8 +1594,11 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) qCDebug(QSG_LOG_RENDERLOOP, "- wait for sync"); if (profileFrames) waitTime = timer.nsecsElapsed(); + Q_TRACE(QSG_wait_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncWait); + Q_TRACE(QSG_sync_entry); + w->thread->waitCondition.wait(&w->thread->mutex); m_lockedForSync = false; w->thread->mutex.unlock(); @@ -1548,8 +1606,10 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) if (profileFrames) syncTime = timer.nsecsElapsed(); + Q_TRACE(QSG_sync_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncSync); + Q_TRACE(QSG_animations_entry); if (m_animation_timer == 0 && m_animation_driver->isRunning()) { qCDebug(QSG_LOG_RENDERLOOP, "- advancing animations"); @@ -1570,6 +1630,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) << ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000 << " - (on Gui thread) " << window; + Q_TRACE(QSG_animations_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync, QQuickProfiler::SceneGraphPolishAndSyncAnimations); } diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 5b48b86568..20d7c4557f 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -60,6 +60,8 @@ #include <private/qquickopenglshadereffectnode_p.h> #endif +#include <qtquick_tracepoints_p.h> + QT_BEGIN_NAMESPACE // Single-threaded render loop with a custom animation driver. Like a @@ -180,10 +182,9 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window) m_gl->setShareContext(qt_gl_global_share_context()); bool created = m_gl->create(); if (!created) { - const bool isEs = m_gl->isOpenGLES(); delete m_gl; m_gl = nullptr; - handleContextCreationFailure(window, isEs); + handleContextCreationFailure(window); return; } @@ -393,6 +394,7 @@ bool QSGWindowsRenderLoop::event(QEvent *event) void QSGWindowsRenderLoop::render() { RLDEBUG("render"); + Q_TRACE(QSG_render_entry); bool rendered = false; for (const WindowData &wd : qAsConst(m_windows)) { if (wd.pendingUpdate) { @@ -407,10 +409,13 @@ void QSGWindowsRenderLoop::render() QThread::msleep(m_vsyncDelta); } + Q_TRACE(QSG_render_exit); + if (m_animationDriver->isRunning()) { RLDEBUG("advancing animations"); QSG_LOG_TIME_SAMPLE(time_start); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphWindowsAnimations); + Q_TRACE(QSG_animations_entry); m_animationDriver->advance(); RLDEBUG("animations advanced"); @@ -418,6 +423,7 @@ void QSGWindowsRenderLoop::render() "animations ticked in %dms", int((qsg_render_timer.nsecsElapsed() - time_start)/1000000)); + Q_TRACE(QSG_animations_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations, 1); // It is not given that animations triggered another maybeUpdate() @@ -476,15 +482,20 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window) if (!windowData(window)) return; + Q_TRACE_SCOPE(QSG_renderWindow); + QSG_LOG_TIME_SAMPLE(time_start); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame); + Q_TRACE(QSG_polishItems_entry); RLDEBUG(" - polishing"); d->polishItems(); QSG_LOG_TIME_SAMPLE(time_polished); + Q_TRACE(QSG_polishItems_exit); Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame, QQuickProfiler::SceneGraphRenderLoopFrame, QQuickProfiler::SceneGraphPolishPolish); + Q_TRACE(QSG_sync_entry); emit window->afterAnimating(); @@ -492,17 +503,22 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window) d->syncSceneGraph(); if (lastDirtyWindow) m_rc->endSync(); + Q_TRACE(QSG_sync_exit); QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced, QQuickProfiler::SceneGraphRenderLoopSync); + Q_TRACE(QSG_render_entry); RLDEBUG(" - rendering"); d->renderSceneGraph(window->size()); + Q_TRACE(QSG_render_exit); QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered, QQuickProfiler::SceneGraphRenderLoopRender); + Q_TRACE(QSG_swap_entry); RLDEBUG(" - swapping"); if (!d->customRenderStage || !d->customRenderStage->swap()) m_gl->swapBuffers(window); + Q_TRACE(QSG_swap_exit); QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped, QQuickProfiler::SceneGraphRenderLoopSwap); diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index 56d97226fb..b12f57d8ef 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -53,7 +53,6 @@ HEADERS += \ $$PWD/util/qsgengine.h \ $$PWD/util/qsgengine_p.h \ $$PWD/util/qsgplaintexture_p.h \ - $$PWD/util/qsgrhinativetextureimporter_p.h \ $$PWD/util/qsgsimplerectnode.h \ $$PWD/util/qsgsimpletexturenode.h \ $$PWD/util/qsgtextureprovider.h \ @@ -70,7 +69,6 @@ SOURCES += \ $$PWD/util/qsgareaallocator.cpp \ $$PWD/util/qsgengine.cpp \ $$PWD/util/qsgplaintexture.cpp \ - $$PWD/util/qsgrhinativetextureimporter.cpp \ $$PWD/util/qsgsimplerectnode.cpp \ $$PWD/util/qsgsimpletexturenode.cpp \ $$PWD/util/qsgtextureprovider.cpp \ diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb Binary files differindex b16da4d76a..c493996375 100644 --- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb Binary files differindex 1a12a35b49..3f8489bfe6 100644 --- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb Binary files differindex 2d0d23d813..f721207325 100644 --- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb Binary files differindex 65d9af4736..93ac0124be 100644 --- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb Binary files differindex 5753794649..33de256615 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb Binary files differindex 6026960d68..018f5aa07e 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb Binary files differindex 451ccbac5b..f64d7ac315 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb Binary files differindex 41ebc12abf..31f870df23 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb Binary files differindex 0c37ccb6ed..df7ef28add 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb Binary files differindex b92235eec3..a90beea1b3 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldshiftedtext_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb Binary files differindex 28ba15e3de..a219eb5800 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb Binary files differindex 2877ab92db..0cfdfed5a9 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldtext.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb Binary files differindex 2e6085aa39..a3998ad695 100644 --- a/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/distancefieldtext_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb Binary files differindex a528c667fd..62ffe0385e 100644 --- a/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/flatcolor.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb Binary files differindex e83de529e6..3f23fa0da1 100644 --- a/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/flatcolor.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb Binary files differindex 81c51321bb..82e302baa2 100644 --- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb Binary files differindex 6bf01658a1..39281bbda5 100644 --- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb Binary files differindex 4a9ac900a6..8ca627e6c1 100644 --- a/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/hiqsubpixeldistancefieldtext_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb Binary files differindex 76c2459edf..b05b62e968 100644 --- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb Binary files differindex 7bfa7ccd4a..92dc0bd710 100644 --- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb Binary files differindex 8f8304fb49..3303ddec7f 100644 --- a/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/loqsubpixeldistancefieldtext_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb Binary files differindex 0b4554568b..785527811a 100644 --- a/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/opaquetexture.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb Binary files differindex 2872af0200..eec3bf66b0 100644 --- a/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/opaquetexture.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb Binary files differindex 5ab92fecca..c1e81f4163 100644 --- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb Binary files differindex 96746e6b0d..b8d38bdff4 100644 --- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb Binary files differindex 6e6b1ab6c2..7e26f3775e 100644 --- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb Binary files differindex 4b08ee2ce4..16046468c2 100644 --- a/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/shadereffect.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb Binary files differindex 4a8c646a21..9365ce95c4 100644 --- a/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/shadereffect.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb Binary files differindex f99cdf1176..8a30f3eae6 100644 --- a/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/smoothcolor.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb Binary files differindex 59c4104a2c..1f187b05ac 100644 --- a/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/smoothcolor.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb Binary files differindex ffaecbb56c..780486ca29 100644 --- a/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/smoothtexture.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb Binary files differindex b7715d4dd5..76d03d4ff7 100644 --- a/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/smoothtexture.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb Binary files differindex 45d5bc14ee..2a33d577c7 100644 --- a/src/quick/scenegraph/shaders_ng/sprite.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/sprite.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb Binary files differindex b55f881734..c77612a31a 100644 --- a/src/quick/scenegraph/shaders_ng/sprite.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/sprite.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb Binary files differindex 6ae7a51f7a..b0b13a1d5a 100644 --- a/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/stencilclip.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb Binary files differindex ce2ed3c5b3..3c091ad73e 100644 --- a/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/stencilclip.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb Binary files differindex 66ebc5f827..b0461a686c 100644 --- a/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/styledtext.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb Binary files differindex d57d92bbe6..18e4685d21 100644 --- a/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/styledtext.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb Binary files differindex 9dd4137072..3d9b5a0bdd 100644 --- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb Binary files differindex b16da4d76a..cfae9575da 100644 --- a/src/quick/scenegraph/shaders_ng/textmask.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/textmask.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb Binary files differindex 99082297bf..2ea425e1c0 100644 --- a/src/quick/scenegraph/shaders_ng/textmask.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/textmask.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/texture.frag.qsb b/src/quick/scenegraph/shaders_ng/texture.frag.qsb Binary files differindex 3f4aa3713c..47c75b1e78 100644 --- a/src/quick/scenegraph/shaders_ng/texture.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/texture.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/texture.vert.qsb b/src/quick/scenegraph/shaders_ng/texture.vert.qsb Binary files differindex bf0bc7d9fa..0301a7bfa0 100644 --- a/src/quick/scenegraph/shaders_ng/texture.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/texture.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb Binary files differindex 93965a55dd..8a30f3eae6 100644 --- a/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/vertexcolor.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb Binary files differindex 98abe4ef6f..95787f647b 100644 --- a/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/vertexcolor.vert.qsb diff --git a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb Binary files differindex eadad927dc..f45b7b4488 100644 --- a/src/quick/scenegraph/shaders_ng/visualization.frag.qsb +++ b/src/quick/scenegraph/shaders_ng/visualization.frag.qsb diff --git a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb Binary files differindex 7ba27cb4b5..acb29bb0fd 100644 --- a/src/quick/scenegraph/shaders_ng/visualization.vert.qsb +++ b/src/quick/scenegraph/shaders_ng/visualization.vert.qsb diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp index 4880d98871..aec981871b 100644 --- a/src/quick/scenegraph/util/qsgengine.cpp +++ b/src/quick/scenegraph/util/qsgengine.cpp @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE +#if QT_DEPRECATED_SINCE(5, 15) /*! \class QSGEngine @@ -58,6 +59,8 @@ QT_BEGIN_NAMESPACE \inmodule QtQuick \since 5.4 + \deprecated + A QSGEngine can be used to render a tree of QSGNode directly on a QWindow or QOpenGLFramebufferObject without any integration with QML, QQuickWindow or QQuickItem and the convenience that they provide. @@ -285,6 +288,8 @@ QSGNinePatchNode *QSGEngine::createNinePatchNode() const return d->sgRenderContext->isValid() ? d->sgRenderContext->sceneGraphContext()->createNinePatchNode() : nullptr; } +#endif + QT_END_NAMESPACE #include "moc_qsgengine.cpp" diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h index c5a59b47e7..f00b7a0b6f 100644 --- a/src/quick/scenegraph/util/qsgengine.h +++ b/src/quick/scenegraph/util/qsgengine.h @@ -54,8 +54,7 @@ class QSGRectangleNode; class QSGImageNode; class QSGNinePatchNode; -// ### Qt 6: Remove or redesign. - +#if QT_DEPRECATED_SINCE(5, 15) class Q_QUICK_EXPORT QSGEngine : public QObject { Q_OBJECT @@ -73,6 +72,7 @@ public: explicit QSGEngine(QObject *parent = nullptr); ~QSGEngine() override; + QT_DEPRECATED_X("QSGEngine is going to be removed in Qt 6.0. Use QQuickRenderControl instead.") void initialize(QOpenGLContext *context); void invalidate(); @@ -84,6 +84,7 @@ public: QSGImageNode *createImageNode() const; QSGNinePatchNode *createNinePatchNode() const; }; +#endif QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgengine_p.h b/src/quick/scenegraph/util/qsgengine_p.h index c5b5c695bd..662c32d3d9 100644 --- a/src/quick/scenegraph/util/qsgengine_p.h +++ b/src/quick/scenegraph/util/qsgengine_p.h @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE class QSGContext; class QSGRenderContext; +#if QT_DEPRECATED_SINCE(5, 15) class QSGEnginePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QSGEngine) @@ -69,6 +70,7 @@ public: QScopedPointer<QSGContext> sgContext; QScopedPointer<QSGRenderContext> sgRenderContext; }; +#endif QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp index 75a874424a..18c72286d1 100644 --- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp @@ -59,6 +59,8 @@ #include <private/qquickprofiler_p.h> +#include <qtquick_tracepoints_p.h> + QT_BEGIN_NAMESPACE #ifndef GL_BGRA @@ -250,14 +252,17 @@ void AtlasBase::bind(QSGTexture::Filtering filtering) if (profileFrames) qsg_renderer_timer.start(); + Q_TRACE_SCOPE(QSG_texture_prepare); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare); // Skip bind, convert, swizzle; they're irrelevant Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, QQuickProfiler::SceneGraphTexturePrepareStart, 3); + Q_TRACE(QSG_texture_upload_entry); uploadPendingTexture(i); + Q_TRACE(QSG_texture_upload_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, QQuickProfiler::SceneGraphTexturePrepareUpload); diff --git a/src/quick/scenegraph/util/qsgplaintexture.cpp b/src/quick/scenegraph/util/qsgplaintexture.cpp index fdebe03494..f00918bb4e 100644 --- a/src/quick/scenegraph/util/qsgplaintexture.cpp +++ b/src/quick/scenegraph/util/qsgplaintexture.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qsgplaintexture_p.h" -#include "qsgrhinativetextureimporter_p.h" #include <QtQuick/private/qsgcontext_p.h> #include <qmath.h> #include <private/qquickprofiler_p.h> @@ -53,6 +52,8 @@ #endif #include <QtGui/private/qrhi_p.h> +#include <qtquick_tracepoints_p.h> + #if QT_CONFIG(opengl) static QElapsedTimer qsg_renderer_timer; #endif @@ -150,9 +151,11 @@ void QSGPlainTexture::setTextureId(int id) // legacy (GL-only) void QSGPlainTexture::bind() // legacy (GL-only) { #if QT_CONFIG(opengl) + Q_TRACE_SCOPE(QSG_texture_prepare); QOpenGLContext *context = QOpenGLContext::currentContext(); QOpenGLFunctions *funcs = context->functions(); if (!m_dirty_texture) { + Q_TRACE_SCOPE(QSG_texture_bind); funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); if (mipmapFiltering() != QSGTexture::None && !m_mipmaps_generated) { funcs->glGenerateMipmap(GL_TEXTURE_2D); @@ -174,6 +177,7 @@ void QSGPlainTexture::bind() // legacy (GL-only) if (m_image.isNull()) { if (m_texture_id && m_owns_texture) { + Q_TRACE_SCOPE(QSG_texture_delete); funcs->glDeleteTextures(1, &m_texture_id); qCDebug(QSG_LOG_TIME_TEXTURE, "plain texture deleted in %dms - %dx%d", (int) qsg_renderer_timer.elapsed(), @@ -189,6 +193,8 @@ void QSGPlainTexture::bind() // legacy (GL-only) return; } + Q_TRACE(QSG_texture_bind_entry); + if (m_texture_id == 0) funcs->glGenTextures(1, &m_texture_id); funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id); @@ -196,8 +202,10 @@ void QSGPlainTexture::bind() // legacy (GL-only) qint64 bindTime = 0; if (profileFrames) bindTime = qsg_renderer_timer.nsecsElapsed(); + Q_TRACE(QSG_texture_bind_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, QQuickProfiler::SceneGraphTexturePrepareBind); + Q_TRACE(QSG_texture_upload_entry); // ### TODO: check for out-of-memory situations... @@ -232,8 +240,10 @@ void QSGPlainTexture::bind() // legacy (GL-only) qint64 uploadTime = 0; if (profileFrames) uploadTime = qsg_renderer_timer.nsecsElapsed(); + Q_TRACE(QSG_texture_upload_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, QQuickProfiler::SceneGraphTexturePrepareUpload); + Q_TRACE(QSG_texture_mipmap_entry); if (mipmapFiltering() != QSGTexture::None) { funcs->glGenerateMipmap(GL_TEXTURE_2D); @@ -252,6 +262,7 @@ void QSGPlainTexture::bind() // legacy (GL-only) int((mipmapTime - uploadTime)/1000000), m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : ""); } + Q_TRACE(QSG_texture_mipmap_exit); Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare, QQuickProfiler::SceneGraphTexturePrepareMipmap); @@ -281,14 +292,14 @@ void QSGPlainTexture::setTextureFromNativeObject(QRhi *rhi, QQuickWindow::Native { Q_UNUSED(type); - QRhiTexture::Flags flags = 0; + QRhiTexture::Flags flags; if (mipmap) flags |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips; QRhiTexture *t = rhi->newTexture(QRhiTexture::RGBA8, size, 1, flags); // ownership of the native object is never taken - QSGRhiNativeTextureImporter::buildWrapper(rhi, t, nativeObjectPtr, nativeLayout); + t->buildFrom({nativeObjectPtr, nativeLayout}); setTexture(t); } @@ -421,7 +432,7 @@ void QSGPlainTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch } if (!q->m_texture) { - QRhiTexture::Flags f = 0; + QRhiTexture::Flags f; if (hasMipMaps) f |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips; diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp index 3dc1f5f526..6b5f1aec4f 100644 --- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp @@ -49,6 +49,9 @@ #include <private/qquickprofiler_p.h> #include <private/qsgdefaultrendercontext_p.h> #include <private/qsgtexture_p.h> + +#include <qtquick_tracepoints_p.h> + #if 0 #include <private/qsgcompressedtexture_p.h> #include <private/qsgcompressedatlastexture_p.h> @@ -197,14 +200,17 @@ void AtlasBase::updateRhiTexture(QRhiResourceUpdateBatch *resourceUpdates) if (profileFrames) qsg_renderer_timer.start(); + Q_TRACE_SCOPE(QSG_texture_prepare); Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare); // Skip bind, convert, swizzle; they're irrelevant Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, QQuickProfiler::SceneGraphTexturePrepareStart, 3); + Q_TRACE(QSG_texture_upload_entry); enqueueTextureUpload(t, resourceUpdates); + Q_TRACE(QSG_texture_upload_exit); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare, QQuickProfiler::SceneGraphTexturePrepareUpload); diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp b/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp deleted file mode 100644 index 7a7c19f587..0000000000 --- a/src/quick/scenegraph/util/qsgrhinativetextureimporter.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#include "qsgrhinativetextureimporter_p.h" -#include <private/qsgrhisupport_p.h> // to get all the relevant qrhi headers - -QT_BEGIN_NAMESPACE - -void QSGRhiNativeTextureImporter::buildWrapper(QRhi *rhi, QRhiTexture *t, - const void *nativeObjectPtr, int nativeLayout) -{ -#if !QT_CONFIG(vulkan) - Q_UNUSED(nativeLayout); -#endif -#if !QT_CONFIG(opengl) && !QT_CONFIG(vulkan) && !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN) - Q_UNUSED(nativeObjectPtr); -#endif - - switch (rhi->backend()) { - case QRhi::OpenGLES2: - { -#if QT_CONFIG(opengl) - QRhiGles2TextureNativeHandles h; - h.texture = *reinterpret_cast<const uint *>(nativeObjectPtr); - t->buildFrom(&h); -#endif - } - break; - case QRhi::Vulkan: - { -#if QT_CONFIG(vulkan) - QRhiVulkanTextureNativeHandles h; - h.image = *reinterpret_cast<const VkImage *>(nativeObjectPtr); - h.layout = VkImageLayout(nativeLayout); - t->buildFrom(&h); -#endif - } - break; - case QRhi::D3D11: - { -#ifdef Q_OS_WIN - QRhiD3D11TextureNativeHandles h; - h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr); - t->buildFrom(&h); -#endif - } - break; - case QRhi::Metal: - { -#ifdef Q_OS_DARWIN - QRhiMetalTextureNativeHandles h; - h.texture = *reinterpret_cast<void * const *>(nativeObjectPtr); - t->buildFrom(&h); -#endif - } - break; - case QRhi::Null: - t->build(); - break; - default: - qWarning("QSGRhiNativeTextureImporter: encountered an unsupported QRhi backend (%d)", - int(rhi->backend())); - t->build(); - break; - } -} - -QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h b/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h deleted file mode 100644 index e811109a94..0000000000 --- a/src/quick/scenegraph/util/qsgrhinativetextureimporter_p.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef QSGRHINATIVETEXTUREIMPORTER_P_H -#define QSGRHINATIVETEXTUREIMPORTER_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. -// - -#include <QtQuick/private/qtquickglobal_p.h> - -QT_BEGIN_NAMESPACE - -class QRhi; -class QRhiTexture; - -class QSGRhiNativeTextureImporter -{ -public: - static void buildWrapper(QRhi *rhi, QRhiTexture *t, - const void *nativeObjectPtr, int nativeLayout); -}; - -QT_END_NAMESPACE - -#endif // QSGRHINATIVETEXTUREIMPORTER_P_H diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp index 1064caccc7..4bbc2b17ba 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.cpp +++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp @@ -46,6 +46,8 @@ \inmodule QtQuick \ingroup qtquick-scenegraph-materials + \deprecated + \warning This utility class is only functional when running with the legacy OpenGL renderer of the Qt Quick scenegraph. Its usage is not recommended in new application code. @@ -234,6 +236,8 @@ /*! \class QSGSimpleMaterial + \deprecated + \inmodule QtQuick \ingroup qtquick-scenegraph-materials diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h index 79180ca8e2..78cd05f2d8 100644 --- a/src/quick/scenegraph/util/qsgsimplematerial.h +++ b/src/quick/scenegraph/util/qsgsimplematerial.h @@ -44,6 +44,8 @@ QT_BEGIN_NAMESPACE +#if QT_DEPRECATED_SINCE(5, 15) + template <typename State> class QSGSimpleMaterialShader : public QSGMaterialShader { @@ -77,6 +79,7 @@ public: void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; + QT_DEPRECATED_X("QSGSimpleMaterialShader is going to be removed in Qt 6.0. Use QSGMaterialShader instead.") virtual void updateState(const State *newState, const State *oldState) = 0; virtual void resolveUniforms() {} @@ -139,12 +142,14 @@ class QSGSimpleMaterial : public QSGMaterial { public: #ifndef Q_CLANG_QDOC + QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.") QSGSimpleMaterial(const State &aState, PtrShaderCreateFunc func) : m_state(aState) , m_func(func) { } + QT_DEPRECATED_X("QSGSimpleMaterial is going to be removed in Qt 6.0. Use QSGMaterial instead.") QSGSimpleMaterial(PtrShaderCreateFunc func) : m_func(func) { @@ -213,6 +218,8 @@ Q_INLINE_TEMPLATE void QSGSimpleMaterialShader<State>::updateState(const RenderS updateState(ns, old); } +#endif + QT_END_NAMESPACE |