21 Texture(QSGTexture *t,
const qint8 key)
25 MaskTextureCache::instance()->m_cache[cacheKey] =
this;
29 MaskTextureCache::instance()->m_cache.remove(cacheKey);
37 typedef QExplicitlySharedDataPointer<Texture> TextureData;
46 TextureData getTexture(QSGRenderContext *context,
float radius,
bool antialiasing)
53 qint8 to_cache_key_key = ((antialiasing << 7) | qRound(radius));
54 Texture *texture =
nullptr;
56 if (m_radiusToCacheKey.contains(to_cache_key_key)) {
57 texture = m_cache.value(m_radiusToCacheKey.value(to_cache_key_key));
62 QImage mask(QSize(qRound(radius) + 1, qRound(radius) + 1), QImage::Format_ARGB32);
63 mask.fill(Qt::transparent);
65 const QColor maskColor = Qt::white;
68 const QRect r = mask.rect();
69 pa.drawLine(r.bottomLeft(), r.bottomRight());
70 pa.drawLine(r.topRight(), r.bottomRight());
71 pa.setRenderHint(QPainter::Antialiasing, antialiasing);
73 path.moveTo(radius, radius);
74 path.arcTo(0, 0, radius * 2, radius * 2, 90, 90);
75 path.lineTo(radius, radius);
77 pa.fillPath(path, maskColor);
80 texture =
new Texture(context->createTexture(mask), to_cache_key_key);
81 texture->texture->setFiltering(QSGTexture::Nearest);
82 texture->texture->setVerticalWrapMode(QSGTexture::ClampToEdge);
83 texture->texture->setHorizontalWrapMode(QSGTexture::ClampToEdge);
85 m_radiusToCacheKey[to_cache_key_key] = texture->cacheKey;
89 TextureData data(texture);
99 QHash<qint8, Texture*> m_cache;
100 QMap<int, qint8> m_radiusToCacheKey;
102 friend class Texture;
148 DirtySourceSizeRatio = 0x1,
149 DirtyMaskTexture = 0x2,
150 DirtyMaskSizeRatio = 0x4,
151 DirtyMaskOffset = 0x8,
152 DirtyContentNode = 0x10
154 Q_DECLARE_FLAGS(DirtyState, DirtyStateBit)
164 inline void markDirtys(DirtyState states) {
165 dirtyState |= states;
167 inline void markDirty(DirtyStateBit state,
bool dirty =
true) {
171 dirtyState &= ~state;
176 void initSourceItem(QQuickItem *old, QQuickItem *item);
178 void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange data,
const QRectF &)
override;
180 inline const QVector2D &getSoureSizeRatio() {
181 if (Q_LIKELY(!dirtyState.testFlag(DirtySourceSizeRatio))) {
182 return soureSizeRatio;
185 Q_ASSERT(sourceItem);
186 markDirty(DirtySourceSizeRatio,
false);
187 const auto &sr = getSourceRect();
188 soureSizeRatio.setX(
static_cast<float>(sourceItem->width() / sr.width()));
189 soureSizeRatio.setY(
static_cast<float>(sourceItem->height() / sr.height()));
190 return soureSizeRatio;
192 inline const QVector2D &getMaskSizeRatio() {
193 if (Q_LIKELY(!dirtyState.testFlag(DirtyMaskSizeRatio))) {
194 return maskSizeRatio;
197 Q_ASSERT(radius > 0);
198 markDirty(DirtyMaskSizeRatio,
false);
199 const auto &sr = getSourceRect();
200 maskSizeRatio.setX(
static_cast<float>(sr.width() /
static_cast<qreal
>(radius)));
201 maskSizeRatio.setY(
static_cast<float>(sr.height() /
static_cast<qreal
>(radius)));
202 return maskSizeRatio;
204 inline const QVector2D &getMaskOffset() {
205 if (Q_LIKELY(!dirtyState.testFlag(DirtyMaskOffset))) {
209 Q_ASSERT(sourceItem && sourceItem->width() > 0 && sourceItem->height() > 0);
210 markDirty(DirtyMaskOffset,
false);
211 auto offset = getSourceRect().topLeft();
212 maskOffset.setX(
static_cast<float>(offset.x() / sourceItem->width()));
213 maskOffset.setY(
static_cast<float>(offset.y() / sourceItem->height()));
217 inline QSGTexture *textureForRadiusMask()
219 Q_ASSERT(radius > 0);
220 if (Q_UNLIKELY(dirtyState.testFlag(DirtyMaskTexture) || !maskTexture)) {
221 QQuickItemPrivate *d = QQuickItemPrivate::get(q_func());
222 maskTexture = MaskTextureCache::instance()->getTexture(d->sceneGraphRenderContext(),
223 static_cast<float>(radius * d->window->effectiveDevicePixelRatio()),
226 markDirty(DirtyMaskTexture,
false);
229 return maskTexture->texture;
232 inline bool needMaskNode()
const {
236 inline bool updateOffset(
const QPointF &offset) {
237 if (this->offset == offset)
239 this->offset = offset;
240 markDirty(DirtyMaskOffset);
244 inline QRectF getSourceRect()
const {
245 QRectF sr = sourceRect;
246 if (!sourceRect.isValid()) {
247 sr = QRectF(QPointF(0, 0), q_func()->size());
250 return fixed ? sr : sr.translated(offset);
254 inline void updateSourceRect(T *node)
const {
255 const QSizeF &textureSize = node->texture()->textureSize();
256 qreal xScale = textureSize.width() / sourceItem->width();
257 qreal yScale = textureSize.height() / sourceItem->height();
259 const QRectF &sourceRect = getSourceRect();
261 node->setSourceRect(QRectF(sourceRect.x() * xScale, sourceRect.y() * yScale,
262 sourceRect.width() * xScale, sourceRect.height() * yScale));
267 void updateUsePreprocess()
const;
268 void ensureTexture();
272 QPointer<QQuickItem> sourceItem;
273 QAtomicPointer<PreprocessNode> preprocessNode;
275 QVector2D soureSizeRatio;
277 MaskTextureCache::TextureData maskTexture;
279 QVector2D maskSizeRatio;
281 QVector2D maskOffset;
282 QMetaObject::Connection textureChangedConnection;
284 QPointF offset = QPointF(0, 0);
287 DirtyState dirtyState = DirtyNothing;
291 bool hideSource =
false;
292 QSGLayer *texture =
nullptr;
Definition dquickitemviewport_p.h:107
Definition dquickitemviewport_p.h:19
Definition dquickitemviewport_p.h:17