5#include <QtGui/private/qwindow_p.h>
6#include <qpa/qplatformgraphicsbuffer.h>
7#include <QtCore/qfile.h>
23 m_psPremulBlend.reset();
24 m_samplerNearest.reset();
25 m_samplerLinear.reset();
28 m_widgetQuadData.reset();
29 for (PerQuadData &
d : m_textureQuadData)
37 QPlatformBackingStore::TextureFlags *
flags)
const
46 QPlatformBackingStore::TextureFlags *
flags)
const
54 }
else if (m_rhi != rhi) {
55 qWarning(
"QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen");
61 bool needsConversion =
false;
64 switch (
image.format()) {
81 needsConversion =
true;
86 needsConversion =
true;
89 needsConversion =
true;
93 if (
image.size().isEmpty())
96 const bool resized = !m_texture || m_texture->pixelSize() !=
image.size();
97 if (dirtyRegion.
isEmpty() && !resized)
98 return m_texture.get();
109 m_texture->setPixelSize(
image.size());
111 resourceUpdates->uploadTexture(m_texture.get(),
image);
116 subresDesc.setSourceTopLeft(
rect.topLeft());
117 subresDesc.setSourceSize(
rect.size());
118 subresDesc.setDestinationTopLeft(
rect.topLeft());
120 resourceUpdates->uploadTexture(m_texture.get(), uploadDesc);
123 return m_texture.get();
138 if (
offset.isNull() && factor <= 1)
141 QVarLengthArray<QRect, 4> rects;
147 deviceRegion.
setRects(rects.constData(), rects.size());
157 qreal x_translate = x_scale - 1 + ((relative_to_viewport.x() /
viewport.width()) * 2);
160 y_translate = y_scale - 1 + ((relative_to_viewport.y() /
viewport.height()) * 2);
162 y_translate = -y_scale + 1 - ((relative_to_viewport.y() /
viewport.height()) * 2);
165 matrix(0,3) = x_translate;
166 matrix(1,3) = y_translate;
169 matrix(1,1) = (invertY ? -1.0 : 1.0) * y_scale;
180 const QSize &textureSize,
183 qreal x_scale = subTexture.width() / textureSize.
width();
184 qreal y_scale = subTexture.height() / textureSize.
height();
186 const QPointF topLeft = subTexture.topLeft();
187 qreal x_translate = topLeft.
x() / textureSize.
width();
192 y_translate = 1 - y_translate;
196 matrix(0,2) = x_translate;
197 matrix(1,2) = y_translate;
207 return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1,
208 topLeftRect.width(), topLeftRect.height());
214 const QRect &deviceWindowRect,
229 const QRect clippedRectInWindow = rectInWindow & clipRect.
translated(rectInWindow.topLeft());
249 qWarning(
"QBackingStoreDefaultCompositor: Could not find built-in shader %s "
250 "(is something wrong with QtGui library resources?)",
261 const float *
src =
static_cast<const float *
>(
m.constData());
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));
267 resourceUpdates->updateDynamicBuffer(ubuf, 64, 48,
f);
315 inputLayout.
setBindings({ { 5 *
sizeof(float) } });
325 qWarning(
"QBackingStoreDefaultCompositor: Failed to build graphics pipeline");
334QBackingStoreDefaultCompositor::PerQuadData QBackingStoreDefaultCompositor::createPerQuadData(
QRhiTexture *
texture,
QRhiTexture *textureExtra)
339 if (!
d.ubuf->create())
340 qWarning(
"QBackingStoreDefaultCompositor: Failed to create uniform buffer");
347 if (!
d.srb->create())
348 qWarning(
"QBackingStoreDefaultCompositor: Failed to create srb");
357 if (!
d.srbExtra->create())
358 qWarning(
"QBackingStoreDefaultCompositor: Failed to create srb");
361 d.lastUsedTextureExtra = textureExtra;
367 UpdateQuadDataOptions options)
374 if ((
d->lastUsedTexture ==
texture &&
d->lastUsedFilter ==
filter) || !
d->srb)
378 d->srb->setBindings({
388 d->srbExtra->setBindings({
394 d->lastUsedTextureExtra = textureExtra;
400 UpdateUniformOptions options)
402 resourceUpdates->updateDynamicBuffer(
d->ubuf, 0, 64,
target.constData());
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);
423 if (m_vbuf->create())
424 resourceUpdates->uploadStaticBuffer(m_vbuf.get(),
vertexData);
426 qWarning(
"QBackingStoreDefaultCompositor: Failed to create vertex buffer");
429 if (!m_samplerNearest) {
432 if (!m_samplerNearest->create())
433 qWarning(
"QBackingStoreDefaultCompositor: Failed to create sampler (Nearest filtering)");
436 if (!m_samplerLinear) {
439 if (!m_samplerLinear->create())
440 qWarning(
"QBackingStoreDefaultCompositor: Failed to create sampler (Linear filtering)");
443 if (!m_widgetQuadData.isValid())
444 m_widgetQuadData = createPerQuadData(m_texture.get());
451 if (!m_psPremulBlend)
459 qreal sourceDevicePixelRatio,
463 bool translucentBackground)
472 }
else if (m_rhi != rhi) {
473 qWarning(
"QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen");
480 qCDebug(lcQpaBackingStore) <<
"Composing and flushing" << region <<
"of" <<
window
482 <<
"via swapchain" << swapchain;
503 QPlatformBackingStore::TextureFlags
flags;
505 bool gotTextureFromGraphicsBuffer =
false;
509 const QSize size = graphicsBuffer->size();
510 QImage wrapperImage(graphicsBuffer->data(),
size.width(),
size.height(), graphicsBuffer->bytesPerLine(),
format);
512 gotTextureFromGraphicsBuffer =
true;
513 graphicsBuffer->unlock();
518 if (!gotTextureFromGraphicsBuffer)
523 UpdateUniformOptions uniformOptions;
524#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
526 uniformOptions |= NeedsRedBlueSwap;
529 uniformOptions |= NeedsAlphaRotate;
542 const bool needsLinearSampler = sourceWindowRect.width() > deviceWindowRect.width()
543 && sourceWindowRect.height() > deviceWindowRect.height();
545 const bool invertTargetY = !rhi->
isYUpInNDC();
553 const QRect srcRect =
toBottomLeftRect(sourceWindowRect.translated(sourceWindowOffset), m_texture->pixelSize().height());
558 updateUniforms(&m_widgetQuadData, resourceUpdates,
target,
source, uniformOptions);
559 if (needsLinearSampler)
560 updatePerQuadData(&m_widgetQuadData, m_texture.get(),
nullptr, NeedsLinearFiltering);
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);
571 for (
int i = 0;
i < textureWidgetCount; ++
i) {
573 ? !invertSource : invertSource;
577 offset, invertTargetY, invertSourceForTextureWidget,
580 m_textureQuadData[
i].reset();
586 if (!m_textureQuadData[
i].isValid())
587 m_textureQuadData[
i] = createPerQuadData(
t, tExtra);
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);
594 m_textureQuadData[
i].reset();
603 cb->resourceUpdate(resourceUpdates);
605 auto render = [&](std::optional<QRhiSwapChain::StereoTargetBuffer>
buffer = std::nullopt) {
612 cb->beginPass(
target, clearColor, { 1.0f, 0 });
614 cb->setGraphicsPipeline(m_psNoBlend.get());
615 cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
617 cb->setVertexInput(0, 1, &vbufBinding);
620 for (
int i = 0;
i < textureWidgetCount; ++
i) {
622 if (m_textureQuadData[
i].isValid()) {
626 srb = m_textureQuadData[
i].srbExtra;
628 cb->setShaderResources(srb);
634 cb->setGraphicsPipeline(premultiplied ? m_psPremulBlend.get() : m_psBlend.get());
638 cb->setShaderResources(m_widgetQuadData.srb);
643 for (
int i = 0;
i < textureWidgetCount; ++
i) {
646 if (m_textureQuadData[
i].isValid()) {
648 cb->setGraphicsPipeline(m_psPremulBlend.get());
650 cb->setGraphicsPipeline(m_psBlend.get());
654 srb = m_textureQuadData[
i].srbExtra;
656 cb->setShaderResources(srb);
~QBackingStoreDefaultCompositor()
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 ®ion, const QPoint &offset, QPlatformTextureList *textures, bool translucentBackground)
The QColor class provides colors based on RGB, HSV or CMYK values.
Format
The following image formats are available in Qt.
@ Format_RGBA8888_Premultiplied
@ Format_A2BGR30_Premultiplied
@ Format_ARGB32_Premultiplied
@ Format_A2RGB30_Premultiplied
static QImage::Format toImageFormat(QPixelFormat format) noexcept
Converts format into a QImage::Format.
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
float * data()
Returns a pointer to the raw data of this matrix.
@ NeedsPremultipliedAlphaBlending
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
constexpr int height() const noexcept
Returns the height of the rectangle.
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.
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,...
The QRegion class specifies a clip region for a painter.
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.
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
void setTargetBlends(std::initializer_list< TargetBlend > list)
Sets the list of render target blend settings.
void setShaderResourceBindings(QRhiShaderResourceBindings *srb)
Associates with srb describing the resource binding layout and the resources (QRhiBuffer,...
void setVertexInputLayout(const QRhiVertexInputLayout &layout)
Specifies the vertex input layout.
void setShaderStages(std::initializer_list< QRhiShaderStage > list)
Sets the list of shader stages.
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc)
Associates with the specified QRhiRenderPassDescriptor desc.
virtual bool create()=0
Creates the corresponding native graphics resources.
Filter
Specifies the minification, magnification, or mipmap filtering.
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
void setBindings(std::initializer_list< QRhiShaderResourceBinding > list)
Sets the list of bindings.
QSize currentPixelSize() const
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
virtual QRhiCommandBuffer * currentFrameCommandBuffer()=0
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
bool isYUpInFramebuffer() const
QRhiShaderResourceBindings * newShaderResourceBindings()
FrameOpResult beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags={})
Starts a new frame targeting the next available buffer of swapChain.
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
QRhiGraphicsPipeline * newGraphicsPipeline()
FrameOpResult endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags={})
Ends, commits, and presents a frame that was started in the last beginFrame() on swapChain.
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
FrameOpResult
Describes the result of operations that can have a soft failure.
@ FrameOpSwapChainOutOfDate
static QShader fromSerialized(const QByteArray &data)
Creates a new QShader instance from the given data.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
\macro QT_RESTRICTED_CAST_FROM_ASCII
constexpr size_type size() const noexcept
void resize(qsizetype sz)
static QWindowPrivate * get(QWindow *window)
QSurfaceFormat format() const override
Returns the actual format of this window.
Combined button and popup list for selecting options.
static QRegion scaledRegion(const QRegion ®ion, 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 qCDebug(category,...)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint const GLuint GLuint const GLuint * textures
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
GLsizei GLsizei GLchar * source
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define qPrintable(string)
Q_GUI_EXPORT QWindowPrivate * qt_window_private(QWindow *window)
view viewport() -> scroll(dx, dy, deviceRect)