1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <Qt3DRender/private/qrendercapture_p.h>
5#include <Qt3DRender/private/rendercapture_p.h>
6#include <Qt3DCore/private/qaspectmanager_p.h>
7#include <Qt3DCore/private/qaspectjobmanager_p.h>
8
9QT_BEGIN_NAMESPACE
10
11namespace Qt3DRender {
12
13namespace Render {
14
15RenderCapture::RenderCapture()
16 : FrameGraphNode(FrameGraphNode::RenderCapture, QBackendNode::ReadWrite)
17{
18
19}
20
21void RenderCapture::requestCapture(const QRenderCaptureRequest &request)
22{
23 QMutexLocker lock(&m_mutex);
24 m_requestedCaptures.push_back(t: request);
25}
26
27// called by render view initializer job
28bool RenderCapture::wasCaptureRequested() const
29{
30 QMutexLocker lock(&m_mutex);
31 return m_requestedCaptures.size() > 0 && isEnabled();
32}
33
34// called by render view initializer job
35QRenderCaptureRequest RenderCapture::takeCaptureRequest()
36{
37 Q_ASSERT(!m_requestedCaptures.isEmpty());
38 return m_requestedCaptures.takeFirst();
39}
40
41void RenderCapture::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
42{
43 const QRenderCapture *node = qobject_cast<const QRenderCapture *>(object: frontEnd);
44 if (!node)
45 return;
46
47 FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime);
48
49 const QRenderCapturePrivate *d = static_cast<const QRenderCapturePrivate *>(QFrameGraphNodePrivate::get(node));
50 const auto newPendingsCaptures = Qt3DCore::moveAndClear(data&: d->m_pendingRequests);
51 if (newPendingsCaptures.size() > 0) {
52 m_requestedCaptures.append(l: newPendingsCaptures);
53 markDirty(changes: AbstractRenderer::FrameGraphDirty);
54 }
55
56 if (firstTime)
57 markDirty(changes: AbstractRenderer::FrameGraphDirty);
58}
59
60// called by render thread
61void RenderCapture::addRenderCapture(int captureId, const QImage &image)
62{
63 QMutexLocker lock(&m_mutex);
64 auto data = RenderCaptureDataPtr::create();
65 data.data()->captureId = captureId;
66 data.data()->image = image;
67 m_renderCaptureData.push_back(t: data);
68}
69
70// called to send render capture in main thread
71void RenderCapture::syncRenderCapturesToFrontend(Qt3DCore::QAspectManager *manager)
72{
73 auto *frontend = manager->lookupNode(id: peerId());
74 if (!frontend)
75 return;
76 QRenderCapturePrivate *dfrontend = static_cast<QRenderCapturePrivate *>(Qt3DCore::QNodePrivate::get(q: frontend));
77
78 QMutexLocker lock(&m_mutex);
79 for (const RenderCaptureDataPtr &data : std::as_const(t&: m_renderCaptureData)) {
80 QPointer<QRenderCaptureReply> reply = dfrontend->takeReply(captureId: data.data()->captureId);
81 // Note: QPointer has no operator bool, we must use isNull() to check it
82 if (!reply.isNull()) {
83 dfrontend->setImage(reply, image: data.data()->image);
84 emit reply->completed();
85 }
86 }
87 m_renderCaptureData.clear();
88}
89
90} // Render
91
92} // Qt3DRender
93
94QT_END_NAMESPACE
95

source code of qt3d/src/render/framegraph/rendercapture.cpp