113QQuickRenderControlPrivate::QQuickRenderControlPrivate(QQuickRenderControl *renderControl)
120 offscreenSurface(
nullptr),
122 frameStatus(NotRecordingFrame)
125 qAddPostRoutine(cleanup);
126 sg = QSGContext::createDefaultContext();
128 rc = sg->createRenderContext();
159QQuickRenderControl::~QQuickRenderControl()
161 Q_D(QQuickRenderControl);
165 QQuickGraphicsConfiguration config;
167 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(d->window);
168 wd->renderControl =
nullptr;
169 config = wd->graphicsConfig;
175 d->windowDestroyed();
187void QQuickRenderControlPrivate::windowDestroyed()
190 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
191 cd->cleanupNodesOnShutdown();
195 QQuickWindowPrivate::get(window)->animationController.reset();
197#if QT_CONFIG(quick_shadereffect)
198 QSGRhiShaderEffectNode::resetMaterialTypeCache(window);
296bool QQuickRenderControl::initialize()
298 Q_D(QQuickRenderControl);
300 qWarning(
"QQuickRenderControl::initialize called with no associated window");
307 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(d->window);
310 QSGDefaultRenderContext *renderContext = qobject_cast<QSGDefaultRenderContext *>(d->rc);
312 QSGDefaultRenderContext::InitParams params;
314 params.sampleCount = d->sampleCount;
315 params.initialSurfacePixelSize = d->window->size() * d->window->effectiveDevicePixelRatio();
316 params.maybeSurface = d->window;
317 renderContext->initialize(¶ms);
318 d->initialized =
true;
320 qWarning(
"QRhi is only compatible with default adaptation");
331void QQuickRenderControl::polishItems()
333 Q_D(QQuickRenderControl);
337 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
338 cd->deliveryAgentPrivate()->flushFrameSynchronousEvents(d->window);
342 emit d->window->afterAnimating();
354bool QQuickRenderControl::sync()
356 Q_D(QQuickRenderControl);
360 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
363 if (!d->rhi->isRecordingFrame()) {
364 qWarning(
"QQuickRenderControl can only sync when beginFrame() has been called");
368 qWarning(
"QQuickRenderControl cannot be used with QRhi when no QRhiCommandBuffer is provided "
369 "(perhaps beginFrame() was not called or it was unsuccessful?)");
372 cd->setCustomCommandBuffer(d->cb);
375 cd->syncSceneGraph();
398void QQuickRenderControl::invalidate()
400 Q_D(QQuickRenderControl);
404 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
405 cd->fireAboutToStop();
406 cd->cleanupNodesOnShutdown();
416 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
417 d->initialized =
false;
423void QQuickRenderControl::render()
425 Q_D(QQuickRenderControl);
429 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
432 if (!d->rhi->isRecordingFrame()) {
433 qWarning(
"QQuickRenderControl can only render when beginFrame() has been called");
437 qWarning(
"QQuickRenderControl cannot be used with QRhi when no QRhiCommandBuffer is provided");
440 cd->setCustomCommandBuffer(d->cb);
443 cd->renderSceneGraph();
468QImage QQuickRenderControlPrivate::grab()
484 }
else if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
485 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
487 cd->syncSceneGraph();
488 QSGSoftwareRenderer *softwareRenderer =
static_cast<QSGSoftwareRenderer *>(cd->renderer);
489 if (softwareRenderer) {
490 const qreal dpr = window->effectiveDevicePixelRatio();
491 const QSize imageSize = window->size() * dpr;
492 grabContent = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
493 grabContent.setDevicePixelRatio(dpr);
494 QPaintDevice *prevDev = softwareRenderer->currentPaintDevice();
495 softwareRenderer->setCurrentPaintDevice(&grabContent);
496 softwareRenderer->markDirty();
499 softwareRenderer->setCurrentPaintDevice(prevDev);
503 qWarning(
"QQuickRenderControl: grabs are not supported with the current Qt Quick backend");
682void QQuickRenderControl::beginFrame()
684 Q_D(QQuickRenderControl);
686 qWarning(
"QQuickRenderControl: No QRhi in beginFrame()");
689 if (d->frameStatus == QQuickRenderControlPrivate::RecordingFrame) {
690 qWarning(
"QQuickRenderControl: beginFrame() must be followed by a call to endFrame() before calling beginFrame() again");
693 if (d->rhi->isRecordingFrame()) {
694 qWarning(
"QQuickRenderControl: Attempted to beginFrame() while the QRhi is already recording a frame");
698 emit d->window->beforeFrameBegin();
700 QRhi::FrameOpResult result = d->rhi->beginOffscreenFrame(&d->cb);
703 case QRhi::FrameOpSuccess:
704 case QRhi::FrameOpSwapChainOutOfDate:
705 d->frameStatus = QQuickRenderControlPrivate::RecordingFrame;
707 case QRhi::FrameOpError:
708 d->frameStatus = QQuickRenderControlPrivate::ErrorInBeginFrame;
710 case QRhi::FrameOpDeviceLost:
711 d->frameStatus = QQuickRenderControlPrivate::DeviceLostInBeginFrame;
714 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
734void QQuickRenderControl::endFrame()
736 Q_D(QQuickRenderControl);
738 qWarning(
"QQuickRenderControl: No QRhi in endFrame()");
741 if (d->frameStatus != QQuickRenderControlPrivate::RecordingFrame) {
742 qWarning(
"QQuickRenderControl: endFrame() must only be called after a successful beginFrame()");
745 if (!d->rhi->isRecordingFrame()) {
746 qWarning(
"QQuickRenderControl: Attempted to endFrame() while the QRhi is not recording a frame");
750 d->rhi->endOffscreenFrame();
753 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
755 emit d->window->afterFrameEnd();
758bool QQuickRenderControlPrivate::initRhi()
767 QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
771 if (rhiSupport->rhiBackend() == QRhi::Vulkan && !window->vulkanInstance()) {
772 qWarning(
"QQuickRenderControl: No QVulkanInstance set for QQuickWindow, cannot initialize");
778 if (!offscreenSurface)
779 offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window);
781 QSGRhiSupport::RhiCreateResult result = rhiSupport->createRhi(window, offscreenSurface);
783 qWarning(
"QQuickRenderControl: Failed to initialize QRhi");