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");
566bool QQuickRenderControlPrivate::isFocusWindowFor(QQuickWindow *quickWindow,
const QWindow *focusWindow)
568 if (!quickWindow || !focusWindow)
571 if (isRenderWindowFor(quickWindow, focusWindow))
581 QWindow *renderWindow = QQuickRenderControl::renderWindowFor(quickWindow);
582 return renderWindow && focusWindow->isAncestorOf(renderWindow, QWindow::ExcludeTransients);
706void QQuickRenderControl::beginFrame()
708 Q_D(QQuickRenderControl);
710 qWarning(
"QQuickRenderControl: No QRhi in beginFrame()");
713 if (d->frameStatus == QQuickRenderControlPrivate::RecordingFrame) {
714 qWarning(
"QQuickRenderControl: beginFrame() must be followed by a call to endFrame() before calling beginFrame() again");
717 if (d->rhi->isRecordingFrame()) {
718 qWarning(
"QQuickRenderControl: Attempted to beginFrame() while the QRhi is already recording a frame");
722 emit d->window->beforeFrameBegin();
724 QRhi::FrameOpResult result = d->rhi->beginOffscreenFrame(&d->cb);
727 case QRhi::FrameOpSuccess:
728 case QRhi::FrameOpSwapChainOutOfDate:
729 d->frameStatus = QQuickRenderControlPrivate::RecordingFrame;
731 case QRhi::FrameOpError:
732 d->frameStatus = QQuickRenderControlPrivate::ErrorInBeginFrame;
734 case QRhi::FrameOpDeviceLost:
735 d->frameStatus = QQuickRenderControlPrivate::DeviceLostInBeginFrame;
738 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
758void QQuickRenderControl::endFrame()
760 Q_D(QQuickRenderControl);
762 qWarning(
"QQuickRenderControl: No QRhi in endFrame()");
765 if (d->frameStatus != QQuickRenderControlPrivate::RecordingFrame) {
766 qWarning(
"QQuickRenderControl: endFrame() must only be called after a successful beginFrame()");
769 if (!d->rhi->isRecordingFrame()) {
770 qWarning(
"QQuickRenderControl: Attempted to endFrame() while the QRhi is not recording a frame");
774 d->rhi->endOffscreenFrame();
777 d->frameStatus = QQuickRenderControlPrivate::NotRecordingFrame;
779 emit d->window->afterFrameEnd();
782bool QQuickRenderControlPrivate::initRhi()
791 QSGRhiSupport *rhiSupport = QSGRhiSupport::instance();
795 if (rhiSupport->rhiBackend() == QRhi::Vulkan && !window->vulkanInstance()) {
796 qWarning(
"QQuickRenderControl: No QVulkanInstance set for QQuickWindow, cannot initialize");
802 bool wantOffscreenSurface =
true;
804 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);
805 const QQuickGraphicsDevicePrivate *customDevD = QQuickGraphicsDevicePrivate::get(&wd->customDeviceObjects);
806 if (customDevD->type == QQuickGraphicsDevicePrivate::Type::Rhi) {
807 if (customDevD->u.rhi)
808 wantOffscreenSurface =
false;
811 if (wantOffscreenSurface && !offscreenSurface)
812 offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window);
814 QSGRhiSupport::RhiCreateResult result = rhiSupport->createRhi(window, offscreenSurface);
816 qWarning(
"QQuickRenderControl: Failed to initialize QRhi");