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
qgfxsourceproxy.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
2// Copyright (C) 2022 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qgfxsourceproxy_p.h"
6
7#include <private/qquickshadereffectsource_p.h>
8#include <private/qquickitem_p.h>
9#include <private/qquickimage_p.h>
10
12
14 : QQuickItem(parentItem)
15{
16}
17
19{
20 delete m_proxy;
21}
22
24{
25 if (m_input == input)
26 return;
27
28 if (m_input)
29 disconnect(m_input, nullptr, this, nullptr);
30 m_input = input;
31 polish();
32 if (m_input) {
33 if (QQuickImage *image = qobject_cast<QQuickImage *>(m_input)) {
34 connect(image, &QQuickImage::sourceSizeChanged, this, &QGfxSourceProxy::repolish);
35 connect(image, &QQuickImage::fillModeChanged, this, &QGfxSourceProxy::repolish);
36 }
37 connect(m_input, &QQuickItem::childrenChanged, this, &QGfxSourceProxy::repolish);
38 }
40}
41
42void QGfxSourceProxy::setOutput(QQuickItem *output)
43{
44 if (m_output == output)
45 return;
46 m_output = output;
49}
50
52{
53 if (m_sourceRect == sourceRect)
54 return;
55 m_sourceRect = sourceRect;
56 polish();
58}
59
61{
62 if (m_interpolation == i)
63 return;
64 m_interpolation = i;
65 polish();
67}
68
69void QGfxSourceProxy::useProxy()
70{
71 if (!m_proxy)
72 m_proxy = new QQuickShaderEffectSource(this);
73 m_proxy->setSourceRect(m_sourceRect);
74 m_proxy->setSourceItem(m_input);
75 m_proxy->setSmooth(m_interpolation != Interpolation::Nearest);
76 setOutput(m_proxy);
77}
78
79void QGfxSourceProxy::repolish()
80{
81 polish();
82}
83
84QObject *QGfxSourceProxy::findLayer(QQuickItem *item)
85{
86 if (!item)
87 return nullptr;
89 if (d->extra.isAllocated() && d->extra->layer) {
90 QObject *layer = qvariant_cast<QObject *>(item->property("layer"));
91 if (layer && layer->property("enabled").toBool())
92 return layer;
93 }
94 return nullptr;
95}
96
98{
99 if (!m_input) {
100 setOutput(nullptr);
101 return;
102 }
103
104 QQuickImage *image = qobject_cast<QQuickImage *>(m_input);
105 QQuickShaderEffectSource *shaderSource = qobject_cast<QQuickShaderEffectSource *>(m_input);
106 bool childless = m_input->childItems().size() == 0;
107 bool interpOk = m_interpolation == Interpolation::Any
108 || (m_interpolation == Interpolation::Linear && m_input->smooth() == true)
109 || (m_interpolation == Interpolation::Nearest && m_input->smooth() == false);
110
111 // Layers can be used in two different ways. Option 1 is when the item is
112 // used as input to a separate ShaderEffect component. In this case,
113 // m_input will be the item itself.
114 QObject *layer = findLayer(m_input);
115 if (!layer && shaderSource) {
116 // Alternatively, the effect is applied via layer.effect, and the
117 // input to the effect will be the layer's internal ShaderEffectSource
118 // item. In this case, we need to backtrack and find the item that has
119 // the layer and configure it accordingly.
120 layer = findLayer(shaderSource->sourceItem());
121 }
122
123 // A bit crude test, but we're only using source rect for
124 // blurring+transparent edge, so this is good enough.
125 bool padded = m_sourceRect.x() < 0 || m_sourceRect.y() < 0;
126
127 bool direct = false;
128
129 if (layer) {
130 // Auto-configure the layer so interpolation and padding works as
131 // expected without allocating additional FBOs. In edgecases, where
132 // this feature is undesiered, the user can simply use
133 // ShaderEffectSource rather than layer.
134 layer->setProperty("sourceRect", m_sourceRect);
135 layer->setProperty("smooth", m_interpolation != Interpolation::Nearest);
136 direct = true;
137
138 } else if (childless && interpOk) {
139 if (shaderSource) {
140 if (shaderSource->sourceRect() == m_sourceRect || m_sourceRect.isEmpty())
141 direct = true;
142
143 } else if (!padded && ((image && image->fillMode() == QQuickImage::Stretch && !image->sourceSize().isNull())
144 || (!image && m_input->isTextureProvider())
145 )
146 ) {
147 direct = true;
148 }
149 }
150
151 if (direct)
152 setOutput(m_input);
153 else
154 useProxy();
155
156 // Remove the proxy if it is not in use..
157 if (m_proxy && m_output == m_input) {
158 delete m_proxy;
159 m_proxy = nullptr;
160 }
161}
162
164
165#include "moc_qgfxsourceproxy_p.cpp"
void setSourceRect(const QRectF &sourceRect)
void setInput(QQuickItem *input)
void sourceRectChanged()
QGfxSourceProxy(QQuickItem *parentItem=nullptr)
void interpolationChanged()
QQuickItem * output
void activeChanged()
void setInterpolation(Interpolation i)
void outputChanged()
void updatePolish() override
This function should perform any layout as required for this item.
qsizetype size() const noexcept
Definition qlist.h:397
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void sourceSizeChanged()
void fillModeChanged()
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QList< QQuickItem * > childItems() const
Returns the children of this item.
void setSmooth(bool)
void childrenChanged()
bool smooth
\qmlproperty bool QtQuick::Item::smooth
Definition qquickitem.h:112
void polish()
Schedules a polish event for this item.
virtual bool isTextureProvider() const
Returns true if this item is a texture provider.
void setSourceRect(const QRectF &rect)
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
Definition qrect.h:661
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:672
constexpr qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:669
Combined button and popup list for selecting options.
Definition image.cpp:4
EGLOutputLayerEXT layer
GLenum GLenum GLenum input
#define Q_EMIT
QT_BEGIN_NAMESPACE typedef uchar * output
myObject disconnect()
[26]
QGraphicsItem * item