1// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
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 "qblitframebuffer.h"
5#include "qblitframebuffer_p.h"
6
7QT_BEGIN_NAMESPACE
8
9namespace Qt3DRender {
10
11/*!
12 \class Qt3DRender::QBlitFramebuffer
13 \inmodule Qt3DRender
14 \since 5.10
15 \ingroup framegraph
16 \brief FrameGraph node to transfer a rectangle of pixel values from one
17 region of a render target to another.
18
19 This node inserts a \c glBlitFrameBuffer or an equivalent into the command
20 stream. This provides a more efficient method for copying rectangles
21 between textures or surface backbuffers wrapped by QRenderTarget than
22 drawing textured quads. It also supports scaling with the specified
23 interpolation method.
24
25 \note In practice the QBlitFramebuffer node will often be used in
26 combination with QNoDraw since a blit should not involve issuing draw calls
27 for any entities.
28
29*/
30/*!
31 \enum Qt3DRender::QBlitFramebuffer::InterpolationMethod
32
33 Specifies the interpolation applied if the image is stretched.
34
35 \value Nearest
36 Nearest-neighbor interpolation.
37 \value Linear
38 Linear interpolation.
39*/
40/*!
41 \property Qt3DRender::QBlitFramebuffer::destination
42
43 Specifies the destination render target. When not set, the destination
44 is assumed to be the default framebuffer (i.e. the backbuffer of
45 the current surface), if there is one.
46
47 \note the source and destination must not refer to the same render
48 target.
49*/
50/*!
51
52 \property Qt3DRender::QBlitFramebuffer::destinationAttachmentPoint
53
54 Specifies the target attachment point.
55*/
56
57/*!
58 \property Qt3DRender::QBlitFramebuffer::destinationRect
59
60 Specifies the destination rectangle. The coordinates are assumed to follow
61 the normal Qt coordinate system, meaning Y runs from top to bottom.
62*/
63
64/*!
65 \property Qt3DRender::QBlitFramebuffer::source
66
67 Specifies the source render target. When not set, the source is assumed to
68 be the default framebuffer (i.e. the backbuffer of the current surface), if
69 there is one.
70
71 \note the source and destination must not refer to the same render target.
72
73*/
74/*!
75 \property Qt3DRender::QBlitFramebuffer::sourceAttachmentPoint
76
77 Specifies the source attachment point.
78
79*/
80/*!
81 \property Qt3DRender::QBlitFramebuffer::sourceRect
82
83 Specifies the source rectangle. The coordinates are assumed to follow the
84 normal Qt coordinate system, meaning Y runs from top to bottom.
85 */
86
87
88/*!
89 \qmltype BlitFramebuffer
90 \inqmlmodule Qt3D.Render
91 \instantiates Qt3DRender::QBlitFramebuffer
92 \inherits FrameGraphNode
93 \since 5.10
94 \brief FrameGraph node to transfer a rectangle of pixel values from one
95 region of a render target to another.
96
97 This node inserts a \c glBlitFrameBuffer or an equivalent into the command
98 stream. This provides a more efficient method for copying rectangles
99 between textures or surface backbuffers wrapped by QRenderTarget than
100 drawing textured quads. It also supports scaling with the specified
101 interpolation method.
102
103 \note In practice the BlitFramebuffer node will often be used in
104 combination with NoDraw since a blit should not involve issuing draw calls
105 for any entities.
106*/
107
108/*!
109 \qmlproperty RenderTarget BlitFramebuffer::source
110
111 Specifies the source render target. When not set, the source is assumed to
112 be the default framebuffer (i.e. the backbuffer of the current surface), if
113 there is one.
114
115 \note the source and destination must not refer to the same render target.
116 */
117
118/*!
119 \qmlproperty RenderTarget BlitFramebuffer::destination
120
121 Specifies the destination render target. When not set, the destination is
122 assumed to be the default framebuffer (i.e. the backbuffer of the current
123 surface), if there is one.
124
125 \note the source and destination must not refer to the same render target.
126 */
127
128/*!
129 \qmlproperty Rect BlitFramebuffer::sourceRect
130
131 Specifies the source rectangle. The coordinates are assumed to follow the
132 normal Qt coordinate system, meaning Y runs from top to bottom.
133 */
134
135/*!
136 \qmlproperty Rect BlitFramebuffer::destinationRect
137
138 Specifies the destination rectangle. The coordinates are assumed to follow
139 the normal Qt coordinate system, meaning Y runs from top to bottom.
140 */
141
142/*!
143 \qmlproperty RenderTargetOutput.AttachmentPoint BlitFramebuffer::sourceAttachmentPoint
144
145 Specifies the source attachment point. Defaults to
146 RenderTargetOutput.AttachmentPoint.Color0.
147 */
148
149/*!
150 \qmlproperty RenderTargetOutput.AttachmentPoint BlitFramebuffer::destinationAttachmentPoint
151
152 Specifies the source attachment point. Defaults to
153 RenderTargetOutput.AttachmentPoint.Color0.
154 */
155
156/*!
157 \qmlproperty InterpolationMethod BlitFramebuffer::interpolationMethod
158
159 Specifies the interpolation applied if the image is stretched. Defaults to Linear.
160 */
161
162QBlitFramebufferPrivate::QBlitFramebufferPrivate()
163 : QFrameGraphNodePrivate()
164 , m_source(nullptr)
165 , m_destination(nullptr)
166 , m_sourceRect(QRect())
167 , m_destinationRect(QRect())
168 , m_sourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0)
169 , m_destinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0)
170 , m_interpolationMethod(QBlitFramebuffer::Linear)
171{
172}
173
174/*!
175 Constructs a new QBlitFramebuffer with the given \a parent.
176 */
177QBlitFramebuffer::QBlitFramebuffer(QNode *parent)
178 : QFrameGraphNode(*new QBlitFramebufferPrivate, parent)
179{
180
181}
182
183/*!
184 \internal
185 */
186QBlitFramebuffer::QBlitFramebuffer(QBlitFramebufferPrivate &dd, QNode *parent)
187 : QFrameGraphNode(dd, parent)
188{
189}
190
191/*!
192 Destructor.
193 */
194QBlitFramebuffer::~QBlitFramebuffer()
195{
196
197}
198
199/*!
200 \return the source render target.
201 */
202QRenderTarget *QBlitFramebuffer::source() const
203{
204 Q_D(const QBlitFramebuffer);
205 return d->m_source;
206}
207
208/*!
209 \return the destination render target.
210 */
211QRenderTarget *QBlitFramebuffer::destination() const
212{
213 Q_D(const QBlitFramebuffer);
214 return d->m_destination;
215}
216
217/*!
218 \return the source rectangle.
219 */
220QRectF QBlitFramebuffer::sourceRect() const
221{
222 Q_D(const QBlitFramebuffer);
223 return d->m_sourceRect;
224}
225
226/*!
227 \return the destination rectangle.
228 */
229QRectF QBlitFramebuffer::destinationRect() const
230{
231 Q_D(const QBlitFramebuffer);
232 return d->m_destinationRect;
233}
234
235/*!
236 \return the source attachment point.
237 */
238Qt3DRender::QRenderTargetOutput::AttachmentPoint QBlitFramebuffer::sourceAttachmentPoint() const
239{
240 Q_D(const QBlitFramebuffer);
241 return d->m_sourceAttachmentPoint;
242}
243
244/*!
245 \return the destination attachment point.
246 */
247QRenderTargetOutput::AttachmentPoint QBlitFramebuffer::destinationAttachmentPoint() const
248{
249 Q_D(const QBlitFramebuffer);
250 return d->m_destinationAttachmentPoint;
251}
252
253/*!
254 \return the interpolation method.
255 */
256QBlitFramebuffer::InterpolationMethod QBlitFramebuffer::interpolationMethod() const
257{
258 Q_D(const QBlitFramebuffer);
259 return d->m_interpolationMethod;
260}
261
262/*!
263 Sets the source render target. The default value is nullptr, in which
264 case the source is assumed to be be the default framebuffer (i.e. the
265 backbuffer of the current surface), if there is one.
266
267 \note the source and destination must not refer to the same render target.
268
269 \note As with other nodes, \a source gets automatically parented to the
270 QBlitFramebuffer instance when no parent has been set. The lifetime is also
271 tracked, meaning the source reverts to nullptr in case the currently set
272 \a source is destroyed.
273 */
274void QBlitFramebuffer::setSource(QRenderTarget *source)
275{
276 Q_D(QBlitFramebuffer);
277 if (d->m_source != source) {
278 if (d->m_source) {
279 // Remove bookkeeping connection
280 d->unregisterDestructionHelper(node: d->m_source);
281 }
282
283 d->m_source = source;
284
285 if (d->m_source) {
286 // Ensures proper bookkeeping. Calls us back with nullptr in case the rt gets destroyed.
287 d->registerDestructionHelper(node: d->m_source, func: &QBlitFramebuffer::setSource, d->m_source);
288
289 if (!d->m_source->parent())
290 d->m_source->setParent(this);
291 }
292
293 emit sourceChanged();
294 }
295}
296
297/*!
298 Sets the destination render target. The default value is nullptr, in which
299 case the destination is assumed to be be the default framebuffer (i.e. the
300 backbuffer of the current surface), if there is one.
301
302 \note the source and destination must not refer to the same render target.
303
304 \note As with other nodes, \a destination gets automatically parented to the
305 QBlitFramebuffer instance when no parent has been set. The lifetime is also
306 tracked, meaning the destination reverts to nullptr in case the currently set
307 \a destination is destroyed.
308 */
309void QBlitFramebuffer::setDestination(QRenderTarget *destination)
310{
311 Q_D(QBlitFramebuffer);
312 if (d->m_destination != destination) {
313 if (d->m_destination) {
314 // Remove bookkeeping connection
315 d->unregisterDestructionHelper(node: d->m_destination);
316 }
317
318 d->m_destination = destination;
319
320 if (d->m_destination) {
321 // Ensures proper bookkeeping. Calls us back with nullptr in case the rt gets destroyed.
322 d->registerDestructionHelper(node: d->m_destination, func: &QBlitFramebuffer::setDestination, d->m_destination);
323
324 if (!d->m_destination->parent())
325 d->m_destination->setParent(this);
326 }
327
328 emit destinationChanged();
329 }
330}
331
332// TO DO Qt6: convert QRectF to QRect
333/*!
334 Sets the source rectangle to \a inputRect. The coordinates are assumed to
335 follow the normal Qt coordinate system, meaning Y runs from top to bottom.
336 */
337void QBlitFramebuffer::setSourceRect(const QRectF &inputRect)
338{
339 Q_D(QBlitFramebuffer);
340 if (d->m_sourceRect != inputRect) {
341 d->m_sourceRect = inputRect.toRect();
342 emit sourceRectChanged();
343 }
344}
345
346/*!
347 Sets the destination rectangle to \a outputRect. The coordinates are assumed
348 to follow the normal Qt coordinate system, meaning Y runs from top to
349 bottom.
350 */
351void QBlitFramebuffer::setDestinationRect(const QRectF &outputRect)
352{
353 Q_D(QBlitFramebuffer);
354 if (d->m_destinationRect != outputRect) {
355 d->m_destinationRect = outputRect.toRect();
356 emit destinationRectChanged();
357 }
358}
359
360/*!
361 Sets the \a sourceAttachmentPoint. Defaults to
362 Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0.
363 */
364void QBlitFramebuffer::setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint)
365{
366 Q_D(QBlitFramebuffer);
367 if (d->m_sourceAttachmentPoint != sourceAttachmentPoint) {
368 d->m_sourceAttachmentPoint = sourceAttachmentPoint;
369 emit sourceAttachmentPointChanged();
370 }
371}
372
373/*!
374 Sets the \a destinationAttachmentPoint. Defaults to
375 Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0.
376 */
377void QBlitFramebuffer::setDestinationAttachmentPoint(QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint)
378{
379 Q_D(QBlitFramebuffer);
380 if (d->m_destinationAttachmentPoint != destinationAttachmentPoint) {
381 d->m_destinationAttachmentPoint = destinationAttachmentPoint;
382 emit destinationAttachmentPointChanged();
383 }
384}
385
386/*!
387 Sets the \a interpolationMethod that is applied if the image is stretched.
388 Defaults to Linear.
389 */
390void QBlitFramebuffer::setInterpolationMethod(QBlitFramebuffer::InterpolationMethod interpolationMethod)
391{
392 Q_D(QBlitFramebuffer);
393 if (d->m_interpolationMethod != interpolationMethod) {
394 d->m_interpolationMethod = interpolationMethod;
395 emit interpolationMethodChanged();
396 }
397}
398
399} // namespace Qt3DRender
400
401QT_END_NAMESPACE
402
403#include "moc_qblitframebuffer.cpp"
404

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