Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qbackingstoredefaultcompositor.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 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
5#include <QtGui/private/qwindow_p.h>
6#include <qpa/qplatformgraphicsbuffer.h>
7#include <QtCore/qfile.h>
8
10
11using namespace Qt::StringLiterals;
12
17
19{
20 m_rhi = nullptr;
21 m_psNoBlend.reset();
22 m_psBlend.reset();
23 m_psPremulBlend.reset();
24 m_samplerNearest.reset();
25 m_samplerLinear.reset();
26 m_vbuf.reset();
27 m_texture.reset();
28 m_widgetQuadData.reset();
29 for (PerQuadData &d : m_textureQuadData)
30 d.reset();
31}
32
34 QRhi *rhi,
35 QRhiResourceUpdateBatch *resourceUpdates,
36 const QRegion &dirtyRegion,
37 QPlatformBackingStore::TextureFlags *flags) const
38{
39 return toTexture(backingStore->toImage(), rhi, resourceUpdates, dirtyRegion, flags);
40}
41
43 QRhi *rhi,
44 QRhiResourceUpdateBatch *resourceUpdates,
45 const QRegion &dirtyRegion,
46 QPlatformBackingStore::TextureFlags *flags) const
47{
48 Q_ASSERT(rhi);
49 Q_ASSERT(resourceUpdates);
51
52 if (!m_rhi) {
53 m_rhi = rhi;
54 } else if (m_rhi != rhi) {
55 qWarning("QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen");
56 return nullptr;
57 }
58
59 QImage image = sourceImage;
60
61 bool needsConversion = false;
62 *flags = {};
63
64 switch (image.format()) {
71 break;
77 break;
80 // no fast path atm
81 needsConversion = true;
82 break;
85 // no fast path atm
86 needsConversion = true;
87 break;
88 default:
89 needsConversion = true;
90 break;
91 }
92
93 if (image.size().isEmpty())
94 return nullptr;
95
96 const bool resized = !m_texture || m_texture->pixelSize() != image.size();
97 if (dirtyRegion.isEmpty() && !resized)
98 return m_texture.get();
99
100 if (needsConversion)
101 image = image.convertToFormat(QImage::Format_RGBA8888);
102 else
103 image.detach(); // if it was just wrapping data, that's no good, we need ownership, so detach
104
105 if (resized) {
106 if (!m_texture)
107 m_texture.reset(rhi->newTexture(QRhiTexture::RGBA8, image.size()));
108 else
109 m_texture->setPixelSize(image.size());
110 m_texture->create();
111 resourceUpdates->uploadTexture(m_texture.get(), image);
112 } else {
113 QRect imageRect = image.rect();
114 QRect rect = dirtyRegion.boundingRect() & imageRect;
116 subresDesc.setSourceTopLeft(rect.topLeft());
117 subresDesc.setSourceSize(rect.size());
118 subresDesc.setDestinationTopLeft(rect.topLeft());
119 QRhiTextureUploadDescription uploadDesc(QRhiTextureUploadEntry(0, 0, subresDesc));
120 resourceUpdates->uploadTexture(m_texture.get(), uploadDesc);
121 }
122
123 return m_texture.get();
124}
125
126static inline QRect scaledRect(const QRect &rect, qreal factor)
127{
128 return QRect(rect.topLeft() * factor, rect.size() * factor);
129}
130
131static inline QPoint scaledOffset(const QPoint &pt, qreal factor)
132{
133 return pt * factor;
134}
135
136static QRegion scaledRegion(const QRegion &region, qreal factor, const QPoint &offset)
137{
138 if (offset.isNull() && factor <= 1)
139 return region;
140
141 QVarLengthArray<QRect, 4> rects;
142 rects.reserve(region.rectCount());
143 for (const QRect &rect : region)
144 rects.append(scaledRect(rect.translated(offset), factor));
145
146 QRegion deviceRegion;
147 deviceRegion.setRects(rects.constData(), rects.size());
148 return deviceRegion;
149}
150
151static QMatrix4x4 targetTransform(const QRectF &target, const QRect &viewport, bool invertY)
152{
153 qreal x_scale = target.width() / viewport.width();
154 qreal y_scale = target.height() / viewport.height();
155
156 const QPointF relative_to_viewport = target.topLeft() - viewport.topLeft();
157 qreal x_translate = x_scale - 1 + ((relative_to_viewport.x() / viewport.width()) * 2);
158 qreal y_translate;
159 if (invertY)
160 y_translate = y_scale - 1 + ((relative_to_viewport.y() / viewport.height()) * 2);
161 else
162 y_translate = -y_scale + 1 - ((relative_to_viewport.y() / viewport.height()) * 2);
163
165 matrix(0,3) = x_translate;
166 matrix(1,3) = y_translate;
167
168 matrix(0,0) = x_scale;
169 matrix(1,1) = (invertY ? -1.0 : 1.0) * y_scale;
170
171 return matrix;
172}
173
176 TopLeft
177};
178
179static QMatrix3x3 sourceTransform(const QRectF &subTexture,
180 const QSize &textureSize,
182{
183 qreal x_scale = subTexture.width() / textureSize.width();
184 qreal y_scale = subTexture.height() / textureSize.height();
185
186 const QPointF topLeft = subTexture.topLeft();
187 qreal x_translate = topLeft.x() / textureSize.width();
188 qreal y_translate = topLeft.y() / textureSize.height();
189
190 if (origin == SourceTransformOrigin::TopLeft) {
191 y_scale = -y_scale;
192 y_translate = 1 - y_translate;
193 }
194
196 matrix(0,2) = x_translate;
197 matrix(1,2) = y_translate;
198
199 matrix(0,0) = x_scale;
200 matrix(1,1) = y_scale;
201
202 return matrix;
203}
204
205static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
206{
207 return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1,
208 topLeftRect.width(), topLeftRect.height());
209}
210
212 int idx,
214 const QRect &deviceWindowRect,
215 const QPoint &offset,
216 bool invertTargetY,
217 bool invertSource,
220{
221 const QRect clipRect = textures->clipRect(idx);
222 if (clipRect.isEmpty())
223 return false;
224
225 QRect rectInWindow = textures->geometry(idx);
226 // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
227 rectInWindow.translate(-offset);
228
229 const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
230 const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
231
232 *target = targetTransform(scaledRect(clippedRectInWindow, window->devicePixelRatio()),
233 deviceWindowRect,
234 invertTargetY);
235
236 *source = sourceTransform(scaledRect(srcRect, window->devicePixelRatio()),
237 scaledRect(rectInWindow, window->devicePixelRatio()).size(),
239
240 return true;
241}
242
244{
245 QFile f(name);
246 if (f.open(QIODevice::ReadOnly))
247 return QShader::fromSerialized(f.readAll());
248
249 qWarning("QBackingStoreDefaultCompositor: Could not find built-in shader %s "
250 "(is something wrong with QtGui library resources?)",
252 return QShader();
253}
254
255static void updateMatrix3x3(QRhiResourceUpdateBatch *resourceUpdates, QRhiBuffer *ubuf, const QMatrix3x3 &m)
256{
257 // mat3 is still 4 floats per column in the uniform buffer (but there is no
258 // 4th column), so 48 bytes altogether, not 36 or 64.
259
260 float f[12];
261 const float *src = static_cast<const float *>(m.constData());
262 float *dst = f;
263 memcpy(dst, src, 3 * sizeof(float));
264 memcpy(dst + 4, src + 3, 3 * sizeof(float));
265 memcpy(dst + 8, src + 6, 3 * sizeof(float));
266
267 resourceUpdates->updateDynamicBuffer(ubuf, 64, 48, f);
268}
269
270enum class PipelineBlend {
271 None,
272 Alpha,
274};
275
279 PipelineBlend blend)
280{
282
283 switch (blend) {
285 {
287 blend.enable = true;
292 ps->setTargetBlends({ blend });
293 }
294 break;
296 {
298 blend.enable = true;
303 ps->setTargetBlends({ blend });
304 }
305 break;
306 default:
307 break;
308 }
309
310 ps->setShaderStages({
311 { QRhiShaderStage::Vertex, getShader(":/qt-project.org/gui/painting/shaders/backingstorecompose.vert.qsb"_L1) },
312 { QRhiShaderStage::Fragment, getShader(":/qt-project.org/gui/painting/shaders/backingstorecompose.frag.qsb"_L1) }
313 });
314 QRhiVertexInputLayout inputLayout;
315 inputLayout.setBindings({ { 5 * sizeof(float) } });
316 inputLayout.setAttributes({
318 { 0, 1, QRhiVertexInputAttribute::Float2, quint32(3 * sizeof(float)) }
319 });
320 ps->setVertexInputLayout(inputLayout);
322 ps->setRenderPassDescriptor(rpDesc);
323
324 if (!ps->create()) {
325 qWarning("QBackingStoreDefaultCompositor: Failed to build graphics pipeline");
326 delete ps;
327 return nullptr;
328 }
329 return ps;
330}
331
332static const int UBUF_SIZE = 120;
333
334QBackingStoreDefaultCompositor::PerQuadData QBackingStoreDefaultCompositor::createPerQuadData(QRhiTexture *texture, QRhiTexture *textureExtra)
335{
336 PerQuadData d;
337
339 if (!d.ubuf->create())
340 qWarning("QBackingStoreDefaultCompositor: Failed to create uniform buffer");
341
342 d.srb = m_rhi->newShaderResourceBindings();
343 d.srb->setBindings({
346 });
347 if (!d.srb->create())
348 qWarning("QBackingStoreDefaultCompositor: Failed to create srb");
349 d.lastUsedTexture = texture;
350
351 if (textureExtra) {
352 d.srbExtra = m_rhi->newShaderResourceBindings();
353 d.srbExtra->setBindings({
356 });
357 if (!d.srbExtra->create())
358 qWarning("QBackingStoreDefaultCompositor: Failed to create srb");
359 }
360
361 d.lastUsedTextureExtra = textureExtra;
362
363 return d;
364}
365
366void QBackingStoreDefaultCompositor::updatePerQuadData(PerQuadData *d, QRhiTexture *texture, QRhiTexture *textureExtra,
367 UpdateQuadDataOptions options)
368{
369 // This whole check-if-texture-ptr-is-different is needed because there is
370 // nothing saying a QPlatformTextureList cannot return a different
371 // QRhiTexture* from the same index in a subsequent flush.
372
373 const QRhiSampler::Filter filter = options.testFlag(NeedsLinearFiltering) ? QRhiSampler::Linear : QRhiSampler::Nearest;
374 if ((d->lastUsedTexture == texture && d->lastUsedFilter == filter) || !d->srb)
375 return;
376
377 QRhiSampler *sampler = filter == QRhiSampler::Linear ? m_samplerLinear.get() : m_samplerNearest.get();
378 d->srb->setBindings({
381 });
382
384 d->lastUsedTexture = texture;
385 d->lastUsedFilter = filter;
386
387 if (textureExtra) {
388 d->srbExtra->setBindings({
391 });
392
393 d->srbExtra->updateResources(QRhiShaderResourceBindings::BindingsAreSorted);
394 d->lastUsedTextureExtra = textureExtra;
395 }
396}
397
398void QBackingStoreDefaultCompositor::updateUniforms(PerQuadData *d, QRhiResourceUpdateBatch *resourceUpdates,
399 const QMatrix4x4 &target, const QMatrix3x3 &source,
400 UpdateUniformOptions options)
401{
402 resourceUpdates->updateDynamicBuffer(d->ubuf, 0, 64, target.constData());
403 updateMatrix3x3(resourceUpdates, d->ubuf, source);
404 float opacity = 1.0f;
405 resourceUpdates->updateDynamicBuffer(d->ubuf, 112, 4, &opacity);
406 qint32 textureSwizzle = options;
407 resourceUpdates->updateDynamicBuffer(d->ubuf, 116, 4, &textureSwizzle);
408}
409
410void QBackingStoreDefaultCompositor::ensureResources(QRhiResourceUpdateBatch *resourceUpdates, QRhiRenderPassDescriptor *rpDesc)
411{
412 static const float vertexData[] = {
413 -1, -1, 0, 0, 0,
414 -1, 1, 0, 0, 1,
415 1, -1, 0, 1, 0,
416 -1, 1, 0, 0, 1,
417 1, -1, 0, 1, 0,
418 1, 1, 0, 1, 1
419 };
420
421 if (!m_vbuf) {
423 if (m_vbuf->create())
424 resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData);
425 else
426 qWarning("QBackingStoreDefaultCompositor: Failed to create vertex buffer");
427 }
428
429 if (!m_samplerNearest) {
432 if (!m_samplerNearest->create())
433 qWarning("QBackingStoreDefaultCompositor: Failed to create sampler (Nearest filtering)");
434 }
435
436 if (!m_samplerLinear) {
439 if (!m_samplerLinear->create())
440 qWarning("QBackingStoreDefaultCompositor: Failed to create sampler (Linear filtering)");
441 }
442
443 if (!m_widgetQuadData.isValid())
444 m_widgetQuadData = createPerQuadData(m_texture.get());
445
446 QRhiShaderResourceBindings *srb = m_widgetQuadData.srb; // just for the layout
447 if (!m_psNoBlend)
448 m_psNoBlend.reset(createGraphicsPipeline(m_rhi, srb, rpDesc, PipelineBlend::None));
449 if (!m_psBlend)
450 m_psBlend.reset(createGraphicsPipeline(m_rhi, srb, rpDesc, PipelineBlend::Alpha));
451 if (!m_psPremulBlend)
452 m_psPremulBlend.reset(createGraphicsPipeline(m_rhi, srb, rpDesc, PipelineBlend::PremulAlpha));
453}
454
456 QRhi *rhi,
457 QRhiSwapChain *swapchain,
459 qreal sourceDevicePixelRatio,
460 const QRegion &region,
461 const QPoint &offset,
463 bool translucentBackground)
464{
465 if (!rhi)
467
468 Q_ASSERT(textures); // may be empty if there are no render-to-texture widgets at all, but null it cannot be
469
470 if (!m_rhi) {
471 m_rhi = rhi;
472 } else if (m_rhi != rhi) {
473 qWarning("QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen");
475 }
476
477 if (!qt_window_private(window)->receivedExpose)
479
480 qCDebug(lcQpaBackingStore) << "Composing and flushing" << region << "of" << window
481 << "at offset" << offset << "with" << textures->count() << "texture(s) in" << textures
482 << "via swapchain" << swapchain;
483
484 QWindowPrivate::get(window)->lastComposeTime.start();
485
486 if (swapchain->currentPixelSize() != swapchain->surfacePixelSize())
487 swapchain->createOrResize();
488
489 // Start recording a new frame.
490 QRhi::FrameOpResult frameResult = rhi->beginFrame(swapchain);
491 if (frameResult == QRhi::FrameOpSwapChainOutOfDate) {
492 if (!swapchain->createOrResize())
494 frameResult = rhi->beginFrame(swapchain);
495 }
496 if (frameResult == QRhi::FrameOpDeviceLost)
498 if (frameResult != QRhi::FrameOpSuccess)
500
501 // Prepare resource updates.
502 QRhiResourceUpdateBatch *resourceUpdates = rhi->nextResourceUpdateBatch();
503 QPlatformBackingStore::TextureFlags flags;
504
505 bool gotTextureFromGraphicsBuffer = false;
506 if (QPlatformGraphicsBuffer *graphicsBuffer = backingStore->graphicsBuffer()) {
507 if (graphicsBuffer->lock(QPlatformGraphicsBuffer::SWReadAccess)) {
508 const QImage::Format format = QImage::toImageFormat(graphicsBuffer->format());
509 const QSize size = graphicsBuffer->size();
510 QImage wrapperImage(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), format);
511 toTexture(wrapperImage, rhi, resourceUpdates, scaledRegion(region, sourceDevicePixelRatio, offset), &flags);
512 gotTextureFromGraphicsBuffer = true;
513 graphicsBuffer->unlock();
514 if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft)
516 }
517 }
518 if (!gotTextureFromGraphicsBuffer)
519 toTexture(backingStore, rhi, resourceUpdates, scaledRegion(region, sourceDevicePixelRatio, offset), &flags);
520
521 ensureResources(resourceUpdates, swapchain->renderPassDescriptor());
522
523 UpdateUniformOptions uniformOptions;
524#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
526 uniformOptions |= NeedsRedBlueSwap;
527#else
529 uniformOptions |= NeedsAlphaRotate;
530#endif
531 const bool premultiplied = (flags & QPlatformBackingStore::TexturePremultiplied) != 0;
535
536 const qreal dpr = window->devicePixelRatio();
537 const QRect deviceWindowRect = scaledRect(QRect(QPoint(), window->size()), dpr);
538 const QRect sourceWindowRect = scaledRect(QRect(QPoint(), window->size()), sourceDevicePixelRatio);
539 // If sourceWindowRect is larger than deviceWindowRect, we are doing high
540 // DPI downscaling. In that case Linear filtering is a must, whereas for the
541 // 1:1 case Nearest must be used for Qt 5 visual compatibility.
542 const bool needsLinearSampler = sourceWindowRect.width() > deviceWindowRect.width()
543 && sourceWindowRect.height() > deviceWindowRect.height();
544
545 const bool invertTargetY = !rhi->isYUpInNDC();
546 const bool invertSource = !rhi->isYUpInFramebuffer();
547
548 if (m_texture) {
549 // The backingstore is for the entire tlw. In case of native children, offset tells the position
550 // relative to the tlw. The window rect is scaled by the source device pixel ratio to get
551 // the source rect.
552 const QPoint sourceWindowOffset = scaledOffset(offset, sourceDevicePixelRatio);
553 const QRect srcRect = toBottomLeftRect(sourceWindowRect.translated(sourceWindowOffset), m_texture->pixelSize().height());
554 const QMatrix3x3 source = sourceTransform(srcRect, m_texture->pixelSize(), origin);
555 QMatrix4x4 target; // identity
556 if (invertTargetY)
557 target.data()[5] = -1.0f;
558 updateUniforms(&m_widgetQuadData, resourceUpdates, target, source, uniformOptions);
559 if (needsLinearSampler)
560 updatePerQuadData(&m_widgetQuadData, m_texture.get(), nullptr, NeedsLinearFiltering);
561 }
562
563 const int textureWidgetCount = textures->count();
564 const int oldTextureQuadDataCount = m_textureQuadData.size();
565 if (oldTextureQuadDataCount != textureWidgetCount) {
566 for (int i = textureWidgetCount; i < oldTextureQuadDataCount; ++i)
567 m_textureQuadData[i].reset();
568 m_textureQuadData.resize(textureWidgetCount);
569 }
570
571 for (int i = 0; i < textureWidgetCount; ++i) {
572 const bool invertSourceForTextureWidget = textures->flags(i).testFlag(QPlatformTextureList::MirrorVertically)
573 ? !invertSource : invertSource;
576 if (!prepareDrawForRenderToTextureWidget(textures, i, window, deviceWindowRect,
577 offset, invertTargetY, invertSourceForTextureWidget,
578 &target, &source))
579 {
580 m_textureQuadData[i].reset();
581 continue;
582 }
583 QRhiTexture *t = textures->texture(i);
584 QRhiTexture *tExtra = textures->textureExtra(i);
585 if (t) {
586 if (!m_textureQuadData[i].isValid())
587 m_textureQuadData[i] = createPerQuadData(t, tExtra);
588 else
589 updatePerQuadData(&m_textureQuadData[i], t, tExtra);
590 updateUniforms(&m_textureQuadData[i], resourceUpdates, target, source);
591 if (needsLinearSampler)
592 updatePerQuadData(&m_textureQuadData[i], t, tExtra, NeedsLinearFiltering);
593 } else {
594 m_textureQuadData[i].reset();
595 }
596 }
597
598 // Record the render pass (with committing the resource updates).
600 const QSize outputSizeInPixels = swapchain->currentPixelSize();
601 QColor clearColor = translucentBackground ? Qt::transparent : Qt::black;
602
603 cb->resourceUpdate(resourceUpdates);
604
605 auto render = [&](std::optional<QRhiSwapChain::StereoTargetBuffer> buffer = std::nullopt) {
606 QRhiRenderTarget* target = nullptr;
607 if (buffer.has_value())
608 target = swapchain->currentFrameRenderTarget(buffer.value());
609 else
610 target = swapchain->currentFrameRenderTarget();
611
612 cb->beginPass(target, clearColor, { 1.0f, 0 });
613
614 cb->setGraphicsPipeline(m_psNoBlend.get());
615 cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
616 QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0);
617 cb->setVertexInput(0, 1, &vbufBinding);
618
619 // Textures for renderToTexture widgets.
620 for (int i = 0; i < textureWidgetCount; ++i) {
621 if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
622 if (m_textureQuadData[i].isValid()) {
623
624 QRhiShaderResourceBindings* srb = m_textureQuadData[i].srb;
625 if (buffer == QRhiSwapChain::RightBuffer && m_textureQuadData[i].srbExtra)
626 srb = m_textureQuadData[i].srbExtra;
627
628 cb->setShaderResources(srb);
629 cb->draw(6);
630 }
631 }
632 }
633
634 cb->setGraphicsPipeline(premultiplied ? m_psPremulBlend.get() : m_psBlend.get());
635
636 // Backingstore texture with the normal widgets.
637 if (m_texture) {
638 cb->setShaderResources(m_widgetQuadData.srb);
639 cb->draw(6);
640 }
641
642 // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
643 for (int i = 0; i < textureWidgetCount; ++i) {
644 const QPlatformTextureList::Flags flags = textures->flags(i);
646 if (m_textureQuadData[i].isValid()) {
648 cb->setGraphicsPipeline(m_psPremulBlend.get());
649 else
650 cb->setGraphicsPipeline(m_psBlend.get());
651
652 QRhiShaderResourceBindings* srb = m_textureQuadData[i].srb;
653 if (buffer == QRhiSwapChain::RightBuffer && m_textureQuadData[i].srbExtra)
654 srb = m_textureQuadData[i].srbExtra;
655
656 cb->setShaderResources(srb);
657 cb->draw(6);
658 }
659 }
660 }
661
662 cb->endPass();
663 };
664
665 if (swapchain->window()->format().stereo()) {
668 } else
669 render();
670
671 rhi->endFrame(swapchain);
672
674}
675
QRhiTexture * toTexture(const QPlatformBackingStore *backingStore, QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates, const QRegion &dirtyRegion, QPlatformBackingStore::TextureFlags *flags) const
QPlatformBackingStore::FlushResult flush(QPlatformBackingStore *backingStore, QRhi *rhi, QRhiSwapChain *swapchain, QWindow *window, qreal sourceDevicePixelRatio, const QRegion &region, const QPoint &offset, QPlatformTextureList *textures, bool translucentBackground)
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
Definition qfile.h:93
\inmodule QtGui
Definition qimage.h:37
Format
The following image formats are available in Qt.
Definition qimage.h:41
@ Format_RGBA8888
Definition qimage.h:59
@ Format_RGB30
Definition qimage.h:63
@ Format_RGB32
Definition qimage.h:46
@ Format_RGBA8888_Premultiplied
Definition qimage.h:60
@ Format_A2BGR30_Premultiplied
Definition qimage.h:62
@ Format_BGR30
Definition qimage.h:61
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
@ Format_A2RGB30_Premultiplied
Definition qimage.h:64
@ Format_ARGB32
Definition qimage.h:47
@ Format_RGBX8888
Definition qimage.h:58
static QImage::Format toImageFormat(QPixelFormat format) noexcept
Converts format into a QImage::Format.
Definition qimage.cpp:6401
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
float * data()
Returns a pointer to the raw data of this matrix.
The QPlatformBackingStore class provides the drawing area for top-level windows.
virtual QImage toImage() const
Implemented in subclasses to return the content of the backingstore as a QImage.
virtual QPlatformGraphicsBuffer * graphicsBuffer() const
Accessor for a backingstores graphics buffer abstraction.
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
Definition qrect.h:167
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr void translate(int dx, int dy) noexcept
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position.
Definition qrect.h:245
constexpr QRect translated(int dx, int dy) const noexcept
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis,...
Definition qrect.h:261
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
QRect boundingRect() const noexcept
Returns the bounding rectangle of this region.
int rectCount() const noexcept
void setRects(const QRect *rect, int num)
Sets the region using the array of rectangles specified by rects and number.
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
\inmodule QtGui
Definition qrhi.h:846
@ Immutable
Definition qrhi.h:849
@ Dynamic
Definition qrhi.h:851
@ VertexBuffer
Definition qrhi.h:855
@ UniformBuffer
Definition qrhi.h:857
\inmodule QtGui
Definition qrhi.h:1651
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
Definition qrhi.h:1680
\inmodule QtGui
Definition qrhi.h:1270
void setTargetBlends(std::initializer_list< TargetBlend > list)
Sets the list of render target blend settings.
Definition qrhi.h:1398
void setShaderResourceBindings(QRhiShaderResourceBindings *srb)
Associates with srb describing the resource binding layout and the resources (QRhiBuffer,...
Definition qrhi.h:1462
void setVertexInputLayout(const QRhiVertexInputLayout &layout)
Specifies the vertex input layout.
Definition qrhi.h:1459
void setShaderStages(std::initializer_list< QRhiShaderStage > list)
Sets the list of shader stages.
Definition qrhi.h:1446
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc)
Associates with the specified QRhiRenderPassDescriptor desc.
Definition qrhi.h:1465
virtual bool create()=0
Creates the corresponding native graphics resources.
\inmodule QtGui
Definition qrhi.h:1142
\inmodule QtGui
Definition qrhi.h:1158
\inmodule QtGui
Definition qrhi.h:1731
\inmodule QtGui
Definition qrhi.h:1030
Filter
Specifies the minification, magnification, or mipmap filtering.
Definition qrhi.h:1032
@ ClampToEdge
Definition qrhi.h:1040
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
Definition qrhi.cpp:5640
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
Definition qrhi.cpp:5526
\inmodule QtGui
Definition qrhi.h:1214
void setBindings(std::initializer_list< QRhiShaderResourceBinding > list)
Sets the list of bindings.
Definition qrhi.h:1218
\inmodule QtGui
Definition qrhi.h:1549
QSize currentPixelSize() const
Definition qrhi.h:1596
virtual bool createOrResize()=0
Creates the swapchain if not already done and resizes the swapchain buffers to match the current size...
virtual QRhiRenderTarget * currentFrameRenderTarget()=0
virtual QSize surfacePixelSize()=0
QRhiRenderPassDescriptor * renderPassDescriptor() const
Definition qrhi.h:1593
virtual QRhiCommandBuffer * currentFrameCommandBuffer()=0
QWindow * window() const
Definition qrhi.h:1575
\inmodule QtGui
Definition qrhi.h:716
\inmodule QtGui
Definition qrhi.h:693
\inmodule QtGui
Definition qrhi.h:895
\inmodule QtGui
Definition qrhi.h:321
void setBindings(std::initializer_list< QRhiVertexInputBinding > list)
Sets the bindings from the specified list.
Definition qrhi.h:325
void setAttributes(std::initializer_list< QRhiVertexInputAttribute > list)
Sets the attributes from the specified list.
Definition qrhi.h:337
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1804
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
Definition qrhi.cpp:10508
bool isYUpInFramebuffer() const
Definition qrhi.cpp:10030
bool isYUpInNDC() const
Definition qrhi.cpp:10044
QRhiShaderResourceBindings * newShaderResourceBindings()
Definition qrhi.cpp:10489
FrameOpResult beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags={})
Starts a new frame targeting the next available buffer of swapChain.
Definition qrhi.cpp:10745
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
Definition qrhi.cpp:10665
QRhiGraphicsPipeline * newGraphicsPipeline()
Definition qrhi.cpp:10466
FrameOpResult endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags={})
Ends, commits, and presents a frame that was started in the last beginFrame() on swapChain.
Definition qrhi.cpp:10780
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition qrhi.cpp:10562
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition qrhi.cpp:9252
FrameOpResult
Describes the result of operations that can have a soft failure.
Definition qrhi.h:1824
@ FrameOpSuccess
Definition qrhi.h:1825
@ FrameOpSwapChainOutOfDate
Definition qrhi.h:1827
@ FrameOpDeviceLost
Definition qrhi.h:1828
\inmodule QtGui
Definition qshader.h:81
static QShader fromSerialized(const QByteArray &data)
Creates a new QShader instance from the given data.
Definition qshader.cpp:540
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool stereo() const
Returns true if stereo buffering is enabled; otherwise returns false.
constexpr size_type size() const noexcept
void resize(qsizetype sz)
static QWindowPrivate * get(QWindow *window)
Definition qwindow_p.h:106
\inmodule QtGui
Definition qwindow.h:63
QSurfaceFormat format() const override
Returns the actual format of this window.
Definition qwindow.cpp:946
rect
[4]
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
@ black
Definition qnamespace.h:30
Definition image.cpp:4
static QRegion scaledRegion(const QRegion &region, qreal factor, const QPoint &offset)
static QMatrix4x4 targetTransform(const QRectF &target, const QRect &viewport, bool invertY)
static const int UBUF_SIZE
static QRect scaledRect(const QRect &rect, qreal factor)
static QMatrix3x3 sourceTransform(const QRectF &subTexture, const QSize &textureSize, SourceTransformOrigin origin)
static void updateMatrix3x3(QRhiResourceUpdateBatch *resourceUpdates, QRhiBuffer *ubuf, const QMatrix3x3 &m)
static QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
static QShader getShader(const QString &name)
static QPoint scaledOffset(const QPoint &pt, qreal factor)
static bool prepareDrawForRenderToTextureWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, const QPoint &offset, bool invertTargetY, bool invertSource, QMatrix4x4 *target, QMatrix3x3 *source)
static QRhiGraphicsPipeline * createGraphicsPipeline(QRhi *rhi, QRhiShaderResourceBindings *srb, QRhiRenderPassDescriptor *rpDesc, PipelineBlend blend)
#define Q_FALLTHROUGH()
#define qWarning
Definition qlogging.h:166
#define qCDebug(category,...)
const GLfloat * m
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint const GLuint GLuint const GLuint * textures
GLuint sampler
GLfloat GLfloat f
GLenum src
GLenum GLuint buffer
GLenum GLenum dst
GLenum target
GLbitfield flags
GLenum GLuint texture
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLenum GLuint GLintptr offset
GLuint name
GLint GLsizei GLsizei GLenum format
GLsizei GLsizei GLchar * source
GLuint GLenum matrix
GLdouble GLdouble t
Definition qopenglext.h:243
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define qPrintable(string)
Definition qstring.h:1531
unsigned int quint32
Definition qtypes.h:50
int qint32
Definition qtypes.h:49
double qreal
Definition qtypes.h:187
Q_GUI_EXPORT QWindowPrivate * qt_window_private(QWindow *window)
Definition qwindow.cpp:2950
float vertexData[]
view viewport() -> scroll(dx, dy, deviceRect)
aWidget window() -> setWindowTitle("New Window Title")
[2]
myWidget render(this)