5#include <QtGui/private/qwindow_p.h>
6#include <qpa/qplatformgraphicsbuffer.h>
7#include <QtCore/qfile.h>
22 m_psNoBlend =
nullptr;
25 delete m_psPremulBlend;
26 m_psPremulBlend =
nullptr;
33 m_widgetQuadData.reset();
34 for (PerQuadData &
d : m_textureQuadData)
42 QPlatformBackingStore::TextureFlags *
flags)
const
51 QPlatformBackingStore::TextureFlags *
flags)
const
59 }
else if (m_rhi != rhi) {
60 qWarning(
"QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen");
66 bool needsConversion =
false;
69 switch (
image.format()) {
86 needsConversion =
true;
91 needsConversion =
true;
94 needsConversion =
true;
98 if (
image.size().isEmpty())
101 const bool resized = !m_texture || m_texture->
pixelSize() !=
image.size();
102 if (dirtyRegion.
isEmpty() && !resized)
121 subresDesc.setSourceTopLeft(
rect.topLeft());
122 subresDesc.setSourceSize(
rect.size());
123 subresDesc.setDestinationTopLeft(
rect.topLeft());
143 if (
offset.isNull() && factor <= 1)
162 qreal x_translate = x_scale - 1 + ((relative_to_viewport.
x() /
viewport.width()) * 2);
165 y_translate = y_scale - 1 + ((relative_to_viewport.
y() /
viewport.height()) * 2);
167 y_translate = -y_scale + 1 - ((relative_to_viewport.
y() /
viewport.height()) * 2);
170 matrix(0,3) = x_translate;
171 matrix(1,3) = y_translate;
185 const QSize &textureSize,
192 qreal x_translate = topLeft.
x() / textureSize.
width();
197 y_translate = 1 - y_translate;
201 matrix(0,2) = x_translate;
202 matrix(1,2) = y_translate;
219 const QRect &deviceWindowRect,
254 qWarning(
"QBackingStoreDefaultCompositor: Could not find built-in shader %s "
255 "(is something wrong with QtGui library resources?)",
266 const float *
src =
static_cast<const float *
>(
m.constData());
268 memcpy(
dst,
src, 3 *
sizeof(
float));
269 memcpy(
dst + 4,
src + 3, 3 *
sizeof(
float));
270 memcpy(
dst + 8,
src + 6, 3 *
sizeof(
float));
320 inputLayout.
setBindings({ { 5 *
sizeof(float) } });
330 qWarning(
"QBackingStoreDefaultCompositor: Failed to build graphics pipeline");
339QBackingStoreDefaultCompositor::PerQuadData QBackingStoreDefaultCompositor::createPerQuadData(
QRhiTexture *
texture,
QRhiTexture *textureExtra)
344 if (!
d.ubuf->create())
345 qWarning(
"QBackingStoreDefaultCompositor: Failed to create uniform buffer");
352 if (!
d.srb->create())
353 qWarning(
"QBackingStoreDefaultCompositor: Failed to create srb");
358 d.srbExtra->setBindings({
362 if (!
d.srbExtra->create())
363 qWarning(
"QBackingStoreDefaultCompositor: Failed to create srb");
366 d.lastUsedTextureExtra = textureExtra;
377 if (
d->lastUsedTexture ==
texture || !
d->srb)
380 d->srb->setBindings({
389 d->srbExtra->setBindings({
395 d->lastUsedTextureExtra = textureExtra;
404 float opacity = 1.0f;
412 static const float vertexData[] = {
426 qWarning(
"QBackingStoreDefaultCompositor: Failed to create vertex buffer");
433 qWarning(
"QBackingStoreDefaultCompositor: Failed to create sampler");
436 if (!m_widgetQuadData.isValid())
437 m_widgetQuadData = createPerQuadData(m_texture);
444 if (!m_psPremulBlend)
452 qreal sourceDevicePixelRatio,
456 bool translucentBackground)
462 }
else if (m_rhi != rhi) {
463 qWarning(
"QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen");
470 qCDebug(lcQpaBackingStore) <<
"Composing and flushing" << region <<
"of" <<
window
472 <<
"via swapchain" << swapchain;
493 QPlatformBackingStore::TextureFlags
flags;
495 bool gotTextureFromGraphicsBuffer =
false;
499 const QSize size = graphicsBuffer->size();
500 QImage wrapperImage(graphicsBuffer->data(),
size.width(),
size.height(), graphicsBuffer->bytesPerLine(),
format);
502 gotTextureFromGraphicsBuffer =
true;
503 graphicsBuffer->unlock();
508 if (!gotTextureFromGraphicsBuffer)
511 ensureResources(swapchain, resourceUpdates);
513#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
539 updateUniforms(&m_widgetQuadData, resourceUpdates,
target,
source, uniformOption);
542 const int textureWidgetCount =
textures->count();
543 const int oldTextureQuadDataCount = m_textureQuadData.
size();
544 if (oldTextureQuadDataCount != textureWidgetCount) {
545 for (
int i = textureWidgetCount;
i < oldTextureQuadDataCount; ++
i)
546 m_textureQuadData[
i].
reset();
547 m_textureQuadData.
resize(textureWidgetCount);
550 for (
int i = 0;
i < textureWidgetCount; ++
i) {
556 m_textureQuadData[
i].reset();
562 if (!m_textureQuadData[
i].isValid()) {
563 m_textureQuadData[
i] = createPerQuadData(
t, tExtra);
566 updatePerQuadData(&m_textureQuadData[
i],
t, tExtra);
568 updateUniforms(&m_textureQuadData[
i], resourceUpdates,
target,
source, NoOption);
570 m_textureQuadData[
i].reset();
579 cb->resourceUpdate(resourceUpdates);
581 auto render = [&](std::optional<QRhiSwapChain::StereoTargetBuffer>
buffer = std::nullopt) {
588 cb->beginPass(
target, clearColor, { 1.0f, 0 });
590 cb->setGraphicsPipeline(m_psNoBlend);
591 cb->setViewport({ 0, 0, float(outputSizeInPixels.
width()), float(outputSizeInPixels.
height()) });
593 cb->setVertexInput(0, 1, &vbufBinding);
596 for (
int i = 0;
i < textureWidgetCount; ++
i) {
598 if (m_textureQuadData[
i].isValid()) {
602 srb = m_textureQuadData[
i].srbExtra;
604 cb->setShaderResources(srb);
610 cb->setGraphicsPipeline(premultiplied ? m_psPremulBlend : m_psBlend);
614 cb->setShaderResources(m_widgetQuadData.srb);
619 for (
int i = 0;
i < textureWidgetCount; ++
i) {
622 if (m_textureQuadData[
i].isValid()) {
624 cb->setGraphicsPipeline(m_psPremulBlend);
626 cb->setGraphicsPipeline(m_psBlend);
630 srb = m_textureQuadData[
i].srbExtra;
632 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.
void start() noexcept
Starts this timer.
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
constexpr int y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
\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 QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr QSize size() const noexcept
Returns the size 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 QPoint bottomRight() const noexcept
Returns the position of the rectangle's bottom-right corner.
constexpr int width() const noexcept
Returns the width of the rectangle.
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.
virtual bool create()=0
Creates the corresponding native graphics resources.
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.
void updateDynamicBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
Enqueues updating a region of a QRhiBuffer buf created with the type QRhiBuffer::Dynamic.
void uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data)
Enqueues updating a region of a QRhiBuffer buf created with the type QRhiBuffer::Immutable or QRhiBuf...
void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
Enqueues uploading the image data for one or more mip levels in one or more layers of the texture tex...
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf)
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
virtual bool create()=0
Creates the corresponding native graphics resources.
void setPixelSize(const QSize &sz)
Sets the texture size, specified in pixels, to sz.
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size)
QMatrix4x4 clipSpaceCorrMatrix() const
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)
const T * constData() const
void reserve(qsizetype sz)
static QWindowPrivate * get(QWindow *window)
QElapsedTimer lastComposeTime
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 QRhiGraphicsPipeline * createGraphicsPipeline(QRhi *rhi, QRhiShaderResourceBindings *srb, QRhiSwapChain *swapchain, PipelineBlend blend)
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)
#define qCDebug(category,...)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint const GLuint GLuint const GLuint * textures
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)