116QQuickRenderControlPrivate::QQuickRenderControlPrivate(QQuickRenderControl *renderControl)
123 offscreenSurface(
nullptr),
125 frameStatus(NotRecordingFrame)
128 qAddPostRoutine(cleanup);
129 sg = QSGContext::createDefaultContext();
131 rc = sg->createRenderContext();
162QQuickRenderControl::~QQuickRenderControl()
164 Q_D(QQuickRenderControl);
168 QQuickGraphicsConfiguration config;
170 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(d->window);
171 wd->renderControl =
nullptr;
172 config = wd->graphicsConfig;
178 d->windowDestroyed();
190void QQuickRenderControlPrivate::windowDestroyed()
193 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
194 cd->cleanupNodesOnShutdown();
198 QQuickWindowPrivate::get(window)->animationController.reset();
200#if QT_CONFIG(quick_shadereffect)
201 QSGRhiShaderEffectNode::resetMaterialTypeCache(window);
299bool QQuickRenderControl::initialize()
301 Q_D(QQuickRenderControl);
303 qWarning(
"QQuickRenderControl::initialize called with no associated window");
310 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(d->window);
313 QSGDefaultRenderContext *renderContext = qobject_cast<QSGDefaultRenderContext *>(d->rc);
315 QSGDefaultRenderContext::InitParams params;
317 params.sampleCount = d->sampleCount;
318 params.initialSurfacePixelSize = d->window->size() * d->window->effectiveDevicePixelRatio();
319 params.maybeSurface = d->window;
320 renderContext->initialize(¶ms);
321 d->initialized =
true;
323 qWarning(
"QRhi is only compatible with default adaptation");
334void QQuickRenderControl::polishItems()
336 Q_D(QQuickRenderControl);
340 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
341 cd->deliveryAgentPrivate()->flushFrameSynchronousEvents(d->window);
345 emit d->window->afterAnimating();
357bool QQuickRenderControl::sync()
359 Q_D(QQuickRenderControl);
363 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
366 if (!d->rhi->isRecordingFrame()) {
367 qWarning(
"QQuickRenderControl can only sync when beginFrame() has been called");
371 qWarning(
"QQuickRenderControl cannot be used with QRhi when no QRhiCommandBuffer is provided "
372 "(perhaps beginFrame() was not called or it was unsuccessful?)");
375 cd->setCustomCommandBuffer(d->cb);
378 cd->syncSceneGraph();
401void QQuickRenderControl::invalidate()
403 Q_D(QQuickRenderControl);
407 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
408 cd->fireAboutToStop();
409 cd->cleanupNodesOnShutdown();
419 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
420 d->initialized =
false;
426void QQuickRenderControl::render()
428 Q_D(QQuickRenderControl);
432 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
435 if (!d->rhi->isRecordingFrame()) {
436 qWarning(
"QQuickRenderControl can only render when beginFrame() has been called");
440 qWarning(
"QQuickRenderControl cannot be used with QRhi when no QRhiCommandBuffer is provided");
443 cd->setCustomCommandBuffer(d->cb);
446 cd->renderSceneGraph();
471QImage QQuickRenderControlPrivate::grab()
487 }
else if (window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
488 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
490 cd->syncSceneGraph();
491 QSGSoftwareRenderer *softwareRenderer =
static_cast<QSGSoftwareRenderer *>(cd->renderer);
492 if (softwareRenderer) {
493 const qreal dpr = window->effectiveDevicePixelRatio();
494 const QSize imageSize = window->size() * dpr;
495 grabContent = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
496 grabContent.setDevicePixelRatio(dpr);
497 QPaintDevice *prevDev = softwareRenderer->currentPaintDevice();
498 softwareRenderer->setCurrentPaintDevice(&grabContent);
499 softwareRenderer->markDirty();
502 softwareRenderer->setCurrentPaintDevice(prevDev);
506 qWarning(
"QQuickRenderControl: grabs are not supported with the current Qt Quick backend");
685void QQuickRenderControl::beginFrame()
687 Q_D(QQuickRenderControl);
689 qWarning(
"QQuickRenderControl: No QRhi in beginFrame()");
692 if (d->frameStatus == QQuickRenderControlPrivate::RecordingFrame) {
693 qWarning(
"QQuickRenderControl: beginFrame() must be followed by a call to endFrame() before calling beginFrame() again");
696 if (d->rhi->isRecordingFrame()) {
697 qWarning(
"QQuickRenderControl: Attempted to beginFrame() while the QRhi is already recording a frame");
701 emit d->window->beforeFrameBegin();
703 QRhi::FrameOpResult result = d->rhi->beginOffscreenFrame(&d->cb);
706 case QRhi::FrameOpSuccess:
707 case QRhi::FrameOpSwapChainOutOfDate:
708 d->frameStatus = QQuickRenderControlPrivate::RecordingFrame;
710 case QRhi::FrameOpError:
711 d->frameStatus = QQuickRenderControlPrivate::ErrorInBeginFrame;
713 case QRhi::FrameOpDeviceLost:
714 d->frameStatus = QQuickRenderControlPrivate::DeviceLostInBeginFrame;
717 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
737void QQuickRenderControl::endFrame()
739 Q_D(QQuickRenderControl);
741 qWarning(
"QQuickRenderControl: No QRhi in endFrame()");
744 if (d->frameStatus != QQuickRenderControlPrivate::RecordingFrame) {
745 qWarning(
"QQuickRenderControl: endFrame() must only be called after a successful beginFrame()");
748 if (!d->rhi->isRecordingFrame()) {
749 qWarning(
"QQuickRenderControl: Attempted to endFrame() while the QRhi is not recording a frame");
753 d->rhi->endOffscreenFrame();
756 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
758 emit d->window->afterFrameEnd();
761bool QQuickRenderControlPrivate::initRhi()
770 QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
774 if (rhiSupport->rhiBackend() == QRhi::Vulkan && !window->vulkanInstance()) {
775 qWarning(
"QQuickRenderControl: No QVulkanInstance set for QQuickWindow, cannot initialize");
781 if (!offscreenSurface)
782 offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window);
784 QSGRhiSupport::RhiCreateResult result = rhiSupport->createRhi(window, offscreenSurface);
786 qWarning(
"QQuickRenderControl: Failed to initialize QRhi");